The panel has no login of its own, so binding it beyond localhost was unsafe. Add a passcode gate to the vite preview front door (HMAC-of-passcode HttpOnly cookie, constant-time compare, inline login page; serves 401 to unauthenticated API/XHR, login page to navigations). Gate is off when PROSPECTOR_PANEL_PASSCODE is unset — the safe local default. app.sh --host[=addr] binds the panel (warns loudly if exposing without a passcode). Fix web_up health check to treat any HTTP response as up (the gate answers 401 to curl's */* Accept, which -f wrongly treated as down). install.sh seeds the passcode var in web/.env.local. README documents the mesh flow. Verified: login→cookie→/prospector 200, no-cookie 401, wrong passcode 401, localhost still works gate-off, web tsc + build green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
128 lines
5.3 KiB
Bash
Executable file
128 lines
5.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# One-shot local installer for the prospector operator app: dependencies, env
|
|
# files, database + migrations, and a production build of the API + web panel.
|
|
# Idempotent — safe to re-run after a pull.
|
|
#
|
|
# scripts/install.sh full setup
|
|
# scripts/install.sh --launch setup, then open the app (Chrome PWA window)
|
|
# ./run install (preferred entrypoint)
|
|
#
|
|
# Flags / env:
|
|
# --launch run scripts/app.sh at the end
|
|
# SKIP_DB=1 skip database creation + migrations
|
|
# PSQL=/path use a specific psql binary
|
|
set -euo pipefail
|
|
|
|
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
|
|
LAUNCH=0
|
|
[[ "${1:-}" == "--launch" ]] && LAUNCH=1
|
|
|
|
echo -e "${BLUE}prospector${NC} — local installer"
|
|
echo ""
|
|
|
|
# 1. Preflight ────────────────────────────────────────────────────────────────
|
|
info "checking prerequisites"
|
|
command -v node >/dev/null 2>&1 || die "node not found (need Node 20+). Install: brew install node"
|
|
command -v npm >/dev/null 2>&1 || die "npm not found."
|
|
node_major="$(node -p 'process.versions.node.split(".")[0]')"
|
|
[[ "$node_major" -ge 20 ]] || warn "Node $(node -v) detected; 20+ recommended."
|
|
ok "node $(node -v)"
|
|
|
|
# 2. Dependencies (root install also covers the web workspace) ─────────────────
|
|
info "installing dependencies (root + web workspace)"
|
|
( cd "$REPO_ROOT" && npm install )
|
|
ok "dependencies installed"
|
|
|
|
# 3. Env files (create from sane localhost defaults if absent) ─────────────────
|
|
if [[ ! -f "$REPO_ROOT/.env.local" ]]; then
|
|
info "creating .env.local (localhost defaults)"
|
|
cat > "$REPO_ROOT/.env.local" <<'ENV'
|
|
NODE_ENV=development
|
|
PROSPECTOR_API_PORT=3210
|
|
PROSPECTOR_DB_HOST=127.0.0.1
|
|
PROSPECTOR_DB_PORT=5432
|
|
PROSPECTOR_DB_NAME=prospector
|
|
PROSPECTOR_DB_USER=postgres
|
|
PROSPECTOR_DB_PASSWORD=
|
|
PROSPECTOR_DB_SSL=false
|
|
PROSPECTOR_DB_POOL_MAX=10
|
|
PROSPECTOR_SERVICE_TOKEN=devtoken
|
|
PEOPLE_BASE_URL=http://127.0.0.1:3061
|
|
PEOPLE_SERVICE_TOKEN=devtoken
|
|
MACSYNC_BASE_URL=http://127.0.0.1:9999
|
|
MACSYNC_SERVICE_TOKEN=dummy
|
|
MACSYNC_DEVICE_ID=dummy
|
|
MRNUMBER_BASE_URL=http://127.0.0.1:9999
|
|
MRNUMBER_SERVICE_TOKEN=dummy
|
|
ENV
|
|
ok "wrote .env.local — review DB credentials before first run"
|
|
else
|
|
ok ".env.local present (left untouched)"
|
|
fi
|
|
|
|
if [[ ! -f "$REPO_ROOT/web/.env.local" ]]; then
|
|
info "creating web/.env.local"
|
|
# Keep the panel's proxy token in sync with the API's service token.
|
|
load_env
|
|
cat > "$REPO_ROOT/web/.env.local" <<ENV
|
|
PROSPECTOR_API_URL=http://127.0.0.1:${PROSPECTOR_API_PORT:-3210}
|
|
PROSPECTOR_SERVICE_TOKEN=${PROSPECTOR_SERVICE_TOKEN:-devtoken}
|
|
# Set a passcode to gate the panel before exposing it on the mesh (./run app --host).
|
|
# Empty = no gate (safe only for localhost-only use).
|
|
PROSPECTOR_PANEL_PASSCODE=
|
|
ENV
|
|
ok "wrote web/.env.local"
|
|
else
|
|
ok "web/.env.local present (left untouched)"
|
|
fi
|
|
|
|
# 4. Database + migrations ─────────────────────────────────────────────────────
|
|
if [[ "${SKIP_DB:-0}" == "1" ]]; then
|
|
warn "SKIP_DB=1 — skipping database setup. Run './run db:migrate' later."
|
|
elif [[ -z "$(find_psql)" ]]; then
|
|
warn "psql not found — skipping database setup."
|
|
warn "Install PostgreSQL (brew install postgresql@16 && brew services start postgresql@16),"
|
|
warn "then run './run db:migrate'."
|
|
else
|
|
info "setting up database + migrations"
|
|
"$REPO_ROOT/scripts/migrate.sh"
|
|
fi
|
|
|
|
# 5. Build API + web panel ─────────────────────────────────────────────────────
|
|
info "building API"
|
|
( cd "$REPO_ROOT" && npm run build )
|
|
ok "API built → dist/"
|
|
info "building web panel"
|
|
( cd "$REPO_ROOT/web" && npm run build )
|
|
ok "web built → web/dist/"
|
|
|
|
# 6. Menu-bar tray app ─────────────────────────────────────────────────────────
|
|
if [[ "${SKIP_TRAY:-0}" == "1" ]]; then
|
|
warn "SKIP_TRAY=1 — skipping the tray app. Build later with './run tray'."
|
|
else
|
|
info "building the menu-bar tray app"
|
|
"$REPO_ROOT/scripts/make-tray.sh" || warn "tray build failed (non-fatal) — retry with './run tray'."
|
|
fi
|
|
|
|
# 7. Claude MCP (agent/coworker interface) ─────────────────────────────────────
|
|
if [[ "${SKIP_MCP:-0}" == "1" ]]; then
|
|
warn "SKIP_MCP=1 — skipping Claude MCP registration. Install later with './run install:mcp'."
|
|
else
|
|
info "registering the prospector MCP in Claude (Desktop + global)"
|
|
# Non-invasive: don't quit/relaunch Claude here; edits apply on next restart.
|
|
SKIP_QUIT=1 NO_RELAUNCH=1 "$REPO_ROOT/mcp/install-mcp.sh" \
|
|
|| warn "MCP registration failed (non-fatal) — retry with './run install:mcp'."
|
|
fi
|
|
|
|
echo ""
|
|
ok "install complete."
|
|
echo ""
|
|
if [[ "$LAUNCH" == "1" ]]; then
|
|
exec "$REPO_ROOT/scripts/app.sh"
|
|
else
|
|
echo "Next:"
|
|
echo -e " ${GREEN}./run app${NC} launch + open as a Chrome app window"
|
|
echo -e " open the ${GREEN}Prospector${NC} tray app (~/Applications) for a menu-bar launcher"
|
|
echo -e " ${GREEN}./run start:dev${NC} API with watch (then 'npm --prefix web run dev' for the panel)"
|
|
fi
|