scripts/setup_xbrain.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
# setup_xbrain.sh — Install and configure the XBrain (GBrain) runtime for XKB
#
# Usage:
# bash scripts/setup_xbrain.sh
# bash scripts/setup_xbrain.sh --dir /opt/gbrain # custom install path
#
# What it does:
# 1. Locates or installs Bun
# 2. Clones GBrain runtime if not present
# 3. Installs dependencies and initialises the PGLite database
# 4. Uses the shared portable runtime environment (process env, or XKB_ENV_FILE)
# 5. Verifies the installation with a test query
#
# Runtime configuration is intentionally never read from or written to a
# host-specific Hermes/OpenClaw config. Pass --env-file to select a dotenv
# file for this invocation; otherwise an inherited XKB_ENV_FILE is used. The
# shared loader gives process environment variables precedence over file values.
set -euo pipefail
# ── Config ────────────────────────────────────────────────────────────────────
GBRAIN_REPO="https://github.com/garrytan/gbrain"
GBRAIN_DEFAULT_DIR="$HOME/gbrain"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ── Args ──────────────────────────────────────────────────────────────────────
GBRAIN_DIR="$GBRAIN_DEFAULT_DIR"
ENV_FILE="${XKB_ENV_FILE:-}"
while [[ $# -gt 0 ]]; do
case $1 in
--dir) GBRAIN_DIR="$2"; shift 2 ;;
--env-file) ENV_FILE="$2"; shift 2 ;;
*) echo "Unknown arg: $1"; exit 1 ;;
esac
done
if [[ -n "$ENV_FILE" && ! -f "$ENV_FILE" ]]; then
echo "❌ XKB env file not found: $ENV_FILE" >&2
echo " Provide an existing dotenv file with --env-file, or unset XKB_ENV_FILE." >&2
exit 1
fi
# Validate before any install/clone/database side effects. Use the same shared
# loader as the runtime; never print the resulting values.
echo "▶ Validating portable XKB runtime configuration..."
if [[ -n "$ENV_FILE" ]]; then
echo " Credentials/config: selected XKB env file (values not displayed)"
else
echo " Credentials/config: process environment (no host config fallback)"
fi
RUNTIME_ENV_FILE="$ENV_FILE" GBRAIN_DIR="$GBRAIN_DIR" python3 - "$SCRIPT_DIR" <<'EOF'
import os, sys
from pathlib import Path
script_dir = Path(sys.argv[1])
sys.path.insert(0, str(script_dir.parent / "tools"))
from runtime_config import runtime_env
settings = runtime_env(os.environ.get("RUNTIME_ENV_FILE") or None)
if not settings.get("GEMINI_API_KEY"):
raise SystemExit(
"XBrain verification requires GEMINI_API_KEY via process environment "
"or the selected XKB env file (process environment takes precedence)."
)
EOF
# ── 1. Find or install Bun ────────────────────────────────────────────────────
echo "▶ Checking Bun..."
if command -v bun &>/dev/null; then
BUN="bun"
elif [ -f "$HOME/.bun/bin/bun" ]; then
BUN="$HOME/.bun/bin/bun"
echo " Found at $BUN (not in PATH — that's OK)"
else
echo " Bun not found. Installing..."
curl -fsSL https://bun.sh/install | bash
BUN="$HOME/.bun/bin/bun"
echo " Installed: $BUN"
fi
echo " Bun: $($BUN --version)"
# ── 2. Clone GBrain runtime ───────────────────────────────────────────────────
echo "▶ GBrain runtime..."
if [ -f "$GBRAIN_DIR/src/cli.ts" ]; then
echo " Already present at $GBRAIN_DIR — pulling latest..."
git -C "$GBRAIN_DIR" pull --ff-only
else
echo " Cloning $GBRAIN_REPO → $GBRAIN_DIR"
git clone "$GBRAIN_REPO" "$GBRAIN_DIR"
fi
echo " Version: $(cat "$GBRAIN_DIR/VERSION" 2>/dev/null || echo 'unknown')"
# ── 3. Install dependencies ───────────────────────────────────────────────────
echo "▶ Installing dependencies..."
(cd "$GBRAIN_DIR" && "$BUN" install --frozen-lockfile 2>&1 | tail -3)
# ── 4. Initialise PGLite database ────────────────────────────────────────────
echo "▶ Initialising XBrain database..."
if (cd "$GBRAIN_DIR" && "$BUN" run src/cli.ts health 2>/dev/null | grep -q "pages"); then
echo " Database already initialised — skipping"
else
(cd "$GBRAIN_DIR" && "$BUN" run src/cli.ts init)
fi
# ── 5. Report portable runtime configuration ─────────────────────────────────
echo " gbrain_dir = $GBRAIN_DIR"
# ── 6. Verify ─────────────────────────────────────────────────────────────────
echo "▶ Verifying XBrain integration..."
RESULT=$(XKB_ENV_FILE="$ENV_FILE" GBRAIN_DIR="$GBRAIN_DIR" python3 -c "
import sys; sys.path.insert(0, '$SCRIPT_DIR')
from xbrain_recall import GBRAIN_AVAILABLE, GBRAIN_DIR, BUN
print('GBRAIN_AVAILABLE:', GBRAIN_AVAILABLE)
print('GBRAIN_DIR:', GBRAIN_DIR)
print('BUN:', BUN)
" 2>&1)
echo "$RESULT"
if echo "$RESULT" | grep -q "GBRAIN_AVAILABLE: True"; then
echo ""
echo "✅ XBrain ready. Next: push your existing cards to the index."
echo " python3 scripts/sync_cards_to_xbrain.py # (or re-run ingest)"
else
echo ""
echo "❌ XBrain not available after setup. Check errors above."
exit 1
fi