OASIS_MOBILE/AUTOMATIZACION/09_SCRIPTS.md
SITO 3a3563f2a0 feat: merge Oasis 0.7.6 upstream — Graphos, E2E, peers/stats, AUTOMATIZACION
Cambios aplicados desde epsylon/oasis 3d46340 (0.7.6):

NUEVO MÓDULO Graphos (mapa interactivo de la red):
- src/views/graphos_view.js (nuevo)

LÓGICA:
- src/backend/nameCache.js (nuevo) — NameAuthor resolver
- src/models/chats_model.js — encriptación E2E
- src/models/calendars_model.js — E2E + calendar invites con códigos
- src/models/maps_model.js — E2E + CLOSED enforcement
- src/models/tribes_model.js — sub-tribe access control (PRESERVA nuestro inviteLog)
- src/models/tribe_crypto.js — soporte E2E
- src/models/main_models.js — refactor (PRESERVA nuestro pub-invite SSB msg)
- src/models/{activity,banking,pads,search,stats,tags,tribes_content}_model.js
- src/backend/backend.js — searchModel constructor + new helpers (errorView, safeRefererRedirect)
- src/backend/blobHandler.js, renderTextWithStyles.js
- src/views/main_views.js — añadido userLink/userLinkLabel + nameCache import (mantiene nuestro hamburger menu)

VISUAL:
- 31 views actualizadas con refactor a userLink helper
- src/views/peers_view.js — tabla con keys clicables
- src/views/stats_view.js — dashboard avanzado
- src/client/assets/styles/style.css — merge (preserva nuestras adiciones QR/mobile)
- Temas desktop: Clear, Dark, Matrix, Purple
- Translations 11 idiomas (ar, de, en, es, eu, fr, hi, it, pt, ru, zh)
- src/configs/{config-manager,oasis-config}, server/SSB_server.js, oasis_client.js

SKIPS (intencionalmente):
- OasisMobile.css del upstream (mantenemos NUESTRO mobile.css y theme)
- main_views.js menu reorganization (mantenemos hamburger nav)
- @xenova/transformers (LLM, no viable mobile)
- node-llama-cpp (build nativo no soportado en arm64 mobile)
- pdfjs-dist (pendiente probar luego)
- AI/embedder.js + AI/routes_index.js (dependen de las libs LLM)

server/package.json: version 0.7.5 → 0.7.6

AUTOMATIZACIÓN:
- Nueva carpeta AUTOMATIZACION/ con 10 archivos:
  - 4 opciones (cron simple, multi-agente, GitHub Actions, webhook)
  - Setup Debian completo paso a paso
  - Scripts bash listos: scout, merger, builder, notify-telegram
  - Prompts listos para los agentes
  - Sección /testing-app para 0asis.net
  - Human-in-the-loop: archivos prohibidos para auto-merge

PENDIENTE: build APK (el bash tool tuvo timeouts; usar comandos
de CONTEXT/cambio_apk_repack.txt manualmente).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 19:41:45 +02:00

7.5 KiB

Scripts bash listos para usar

Copia a /opt/scripts/ en el VPS Debian.

oasis-scout.sh

#!/bin/bash
set -euo pipefail
REPO=/opt/oasis_mobile
REPORTS=/var/oasis-auto/reports
mkdir -p "$REPORTS"

cd "$REPO"
git fetch upstream 2>&1
DATE=$(date +%Y-%m-%d)

claude -p "$(cat /opt/scripts/prompts/scout.md)" \
  --allowed-tools "Read,Write,Bash" \
  > "$REPORTS/$DATE-scout-claude.log" 2>&1

# El reporte JSON y MD se generan por claude
if [ -f "$REPORTS/$DATE-scout.json" ]; then
  bash /opt/scripts/notify-telegram.sh "📊 Scout listo para $DATE. Ver: https://0asis.net/admin/reports/$DATE"
else
  bash /opt/scripts/notify-telegram.sh "❌ Scout falló para $DATE. Log: $REPORTS/$DATE-scout-claude.log"
  exit 1
fi

oasis-merger.sh

#!/bin/bash
set -euo pipefail
REPO=/opt/oasis_mobile
REPORTS=/var/oasis-auto/reports
DATE=$(date +%Y-%m-%d)
THRESHOLD=${AUTO_APPROVE_THRESHOLD:-1.0}

cd "$REPO"

# Verificar que existe scout reciente
if [ ! -f "$REPORTS/$DATE-scout.json" ]; then
  bash /opt/scripts/notify-telegram.sh "⚠️ Merger: no hay scout.json para $DATE. Saltando."
  exit 0
fi

# Leer conflict_score
SCORE=$(jq -r '.conflict_score' "$REPORTS/$DATE-scout.json")
APPROVED=$(jq -r '.approved // false' "$REPORTS/$DATE-scout.json")

if [ "$APPROVED" != "true" ] && (( $(echo "$SCORE > $THRESHOLD" | bc -l) )); then
  bash /opt/scripts/notify-telegram.sh "⏸ Merger: conflict_score $SCORE > $THRESHOLD, esperando aprobación manual."
  exit 0
fi

# Procede con merge
claude -p "$(cat /opt/scripts/prompts/merger.md)" \
  --allowed-tools "Read,Write,Edit,Bash" \
  > "$REPORTS/$DATE-merger-claude.log" 2>&1

if [ $? -eq 0 ]; then
  bash /opt/scripts/notify-telegram.sh "✅ Merger OK para $DATE. Lista para build."
else
  bash /opt/scripts/notify-telegram.sh "❌ Merger falló para $DATE."
fi

oasis-builder.sh

#!/bin/bash
set -euo pipefail
REPO=/opt/oasis_mobile
APKS=/var/www/0asis.net/testing-app
DATE=$(date +%Y%m%d)
mkdir -p "$APKS"

cd "$REPO"

# Verificar working tree limpio
if [ -n "$(git status --porcelain)" ]; then
  bash /opt/scripts/notify-telegram.sh "⚠️ Builder: working tree no limpio. Saltando."
  exit 1
fi

# Verificar no hay markers de conflicto
if grep -rn "<<<<<<< HEAD" "$REPO/nodejs-project/" 2>/dev/null; then
  bash /opt/scripts/notify-telegram.sh "❌ Builder: hay conflictos sin resolver."
  exit 1
fi

# Build zip
cd "$REPO/nodejs-project"
zip -0 -r /tmp/nodejs-project-new.zip nodejs-project/ \
  -x "*.apk" "*/.git/*" > /tmp/zip.log 2>&1

# Build APK
mkdir -p /tmp/assets
cp /tmp/nodejs-project-new.zip /tmp/assets/nodejs-project.zip
cp /opt/oasis-base/oasis-v0.6.8.apk /tmp/oasis-temp.apk
zip -d /tmp/oasis-temp.apk "META-INF/*" >/dev/null
cd /tmp && zip -0 oasis-temp.apk assets/nodejs-project.zip >/dev/null

SDK=/opt/android-sdk/build-tools/35.0.1
$SDK/zipalign -f -p 4 /tmp/oasis-temp.apk /tmp/oasis-aligned.apk
$SDK/apksigner sign \
  --ks /opt/secrets/oasis-release-key.jks \
  --ks-pass pass:oasis123 \
  --key-pass pass:oasis123 \
  --ks-key-alias oasis \
  /tmp/oasis-aligned.apk

$SDK/apksigner verify /tmp/oasis-aligned.apk || {
  bash /opt/scripts/notify-telegram.sh "❌ APK signature inválida."
  exit 1
}

# Detectar versión del package.json
VERSION=$(jq -r '.version' "$REPO/nodejs-project/nodejs-project/src/server/package.json")

# Borrar pruebas anteriores y copiar
rm -f "$APKS/oasis-*-pruebas.apk"
NAME="oasis-v$VERSION-$DATE-pruebas.apk"
cp /tmp/oasis-aligned.apk "$APKS/$NAME"
ln -sf "$NAME" "$APKS/latest.apk"

SIZE=$(du -h "$APKS/$NAME" | cut -f1)
bash /opt/scripts/notify-telegram.sh "📱 APK $NAME ($SIZE) lista: https://0asis.net/testing-app/$NAME"

notify-telegram.sh

#!/bin/bash
TOKEN="${TELEGRAM_BOT_TOKEN:-}"
CHAT="${TELEGRAM_CHAT_ID:-}"
MSG="${1:-empty}"

if [ -z "$TOKEN" ] || [ -z "$CHAT" ]; then
  echo "Telegram no configurado, mensaje:"
  echo "$MSG"
  exit 0
fi

curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
  -d "chat_id=$CHAT" \
  -d "text=$MSG" \
  -d "parse_mode=Markdown" > /dev/null

/etc/cron.d/oasis-auto

# Oasis Mobile auto-update pipeline
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxx
TELEGRAM_BOT_TOKEN=123456789:AAxxxx
TELEGRAM_CHAT_ID=-1001234567890
AUTO_APPROVE_THRESHOLD=0.5

0  3 * * 1 oasis /opt/scripts/oasis-scout.sh
0  4 * * 1 oasis /opt/scripts/oasis-merger.sh
0  5 * * 1 oasis /opt/scripts/oasis-builder.sh

Webhook receiver (Python Flask)

# /opt/oasis-webhook/app.py
from flask import Flask, request, abort
import hmac, hashlib, subprocess, os

app = Flask(__name__)
SECRET = os.environ['WEBHOOK_SECRET'].encode()

@app.post("/api/oasis-release")
def release():
    sig = request.headers.get("X-Hub-Signature-256", "")
    mac = hmac.new(SECRET, request.data, hashlib.sha256)
    expected = "sha256=" + mac.hexdigest()
    if not hmac.compare_digest(sig, expected):
        abort(401)

    event = request.headers.get("X-GitHub-Event")
    if event != "release":
        return "skip", 200

    payload = request.json
    if payload.get("action") == "published":
        tag = payload["release"]["tag_name"]
        subprocess.Popen([
            "sudo", "-u", "oasis",
            "/opt/scripts/oasis-scout.sh",
            "--tag", tag, "--reason", "webhook"
        ])

    return "ok", 200

/etc/systemd/system/oasis-webhook.service

[Unit]
Description=Oasis webhook receiver
After=network.target

[Service]
User=oasis
WorkingDirectory=/opt/oasis-webhook
EnvironmentFile=/opt/secrets/webhook.env
ExecStart=/usr/bin/python3 -m gunicorn -b 127.0.0.1:5000 app:app
Restart=always

[Install]
WantedBy=multi-user.target

/etc/caddy/Caddyfile

0asis.net {
  encode gzip zstd

  handle /api/oasis-release {
    reverse_proxy 127.0.0.1:5000
  }

  handle_path /testing-app/* {
    root * /var/www/0asis.net/testing-app
    file_server browse
    @apk path *.apk
    header @apk Content-Disposition "attachment"
  }

  handle {
    root * /var/www/0asis.net
    file_server
    try_files {path} {path}/ /index.html
  }
}

Setup inicial — bootstrap.sh

#!/bin/bash
# Ejecutar UNA vez al preparar el VPS Debian
set -euo pipefail

# 1. User dedicado
useradd -m -s /bin/bash oasis || true

# 2. Directorios
mkdir -p /opt/oasis_mobile /opt/scripts /opt/secrets /opt/oasis-base
mkdir -p /var/oasis-auto/reports /var/www/0asis.net/testing-app

# 3. Dependencias del sistema
apt update
apt install -y git curl jq bc python3-pip nginx-light \
  openjdk-17-jdk-headless zip unzip cron

# 4. Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/setup.deb.sh' | bash
apt install -y caddy

# 5. Android SDK build-tools
mkdir -p /opt/android-sdk
cd /opt/android-sdk
curl -L -o cmdline-tools.zip \
  "https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"
unzip cmdline-tools.zip
cmdline-tools/bin/sdkmanager --sdk_root=/opt/android-sdk \
  "build-tools;35.0.1"

# 6. Claude Code
curl -fsSL https://claude.ai/install.sh | bash

# 7. Permisos
chown -R oasis:oasis /opt/oasis_mobile /var/oasis-auto /opt/scripts

# 8. Clonar repo (necesita SSH key configurada)
sudo -u oasis git clone git@code.03c8.net:s1to/oasis_mobile.git /opt/oasis_mobile
cd /opt/oasis_mobile
sudo -u oasis git remote add upstream https://github.com/epsylon/oasis.git

echo "Bootstrap completo. Configura:"
echo "  - /opt/secrets/oasis-release-key.jks (keystore)"
echo "  - /etc/cron.d/oasis-auto (con tu ANTHROPIC_API_KEY)"
echo "  - DNS de 0asis.net apuntando a este server"
echo "  - /etc/caddy/Caddyfile"
echo "  - systemctl enable --now oasis-webhook"