A specific --host=ADDR binds only that address, so localhost health-check and window-open failed. Derive REACH_HOST from the bind (localhost for unset/0.0.0.0, else the bound IP) and use it for web_up + PANEL_URL. Verified: gate works with a real passcode (401 unauth, 200 with cookie). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| app.sh | ||
| install.sh | ||
| lib.sh | ||
| make-tray.sh | ||
| migrate.sh | ||
| README.md | ||
| stop.sh | ||
| tray.applescript | ||
scripts — local install & run
One-command setup and launch for the prospector operator app on this machine.
All are reachable through ./run (preferred) or by direct execution.
| Script | ./run |
Purpose |
|---|---|---|
install.sh |
./run install |
Deps → env files → DB + migrations → build API + web → tray app → MCP. Idempotent. --launch opens the app after. Skip steps with SKIP_DB/SKIP_TRAY/SKIP_MCP. |
app.sh |
./run app |
Start API + the vite-preview front door, health-check, open Chrome as an app window. --build rebuilds first; --detach runs in the background (used by the tray). Reuses an already-running instance. |
stop.sh |
./run stop |
Stop the detached app — kills only the PIDs in .run/app.pids, never a blanket node kill. |
make-tray.sh |
./run tray |
Build the Prospector.app menu-bar tray (~/Applications): ❖ status icon with Open / Stop / Quit. AppleScript-ObjC + built-in icon tooling, no Swift/deps. |
migrate.sh |
./run db:migrate |
Apply pending migrations/*.sql, tracked in a _prospector_migrations ledger (each file runs once). |
lib.sh |
— | Shared helpers (logging, .env.local loading, psql locating). Sourced, not run. |
mcp/install-mcp.sh |
./run install:mcp |
Register the agent/coworker MCP ("prospector") into Claude Desktop + global ~/.claude/mcp-config.json (for Claude Code / desktop coworker). Builds the mcp package, handles secrets from .env or vault, safe edits. |
Quick start
./run install --launch # set up everything and open the app
# or, step by step:
./run install # set up
./run app # launch + open the Chrome app window
./run install:mcp # (separate) register the prospector MCP for agents in Claude
Requirements
- Node 20+ and npm.
- PostgreSQL reachable per
.env.local(PROSPECTOR_DB_*). The installer findspsqlon PATH or in common macOS installs (Homebrew, Postgres.app); setPSQL=/path/to/psqlto override. No psql → DB step is skipped with a hint. - Google Chrome for the app-window experience (falls back to default browser).
How the pieces fit
- The API (
dist/main.js) listens onPROSPECTOR_API_PORT(3210) and owns its Postgres DB. Routes are guarded by a bearer service token. - The panel is the built
web/dist, served byvite preview, which proxies/api/*→ the API and injects the token (so it never lives in browser JS). This is the same proxyviteuses in dev — seeweb/vite.config.ts. app.shstarts both, waits for/health, then openshttp://localhost:<web>/#/marketsas a Chrome--appwindow. Ctrl-C stops only the processes it started (never a blanket node kill).
Env files (created by the installer if absent)
.env.local— API config (port,PROSPECTOR_DB_*, service token, upstreams).web/.env.local—PROSPECTOR_API_URL+PROSPECTOR_SERVICE_TOKENfor the panel proxy. Keep its token equal to the API's.
Re-running install never overwrites existing env files.
Remote / mesh access (optional, gated)
By default the panel binds localhost only — not reachable from the mesh. To
use it from another mesh host (this laptop is 10.9.0.3 on the WG mesh):
- Set a passcode in
web/.env.local— the panel has no login of its own, so this gate is required before exposing it:
Empty = gate off (localhost-only). The passcode is checked by thePROSPECTOR_PANEL_PASSCODE=your-passcodevite previewfront door (HMAC cookie, HttpOnly); the service token is never injected until a valid session exists. - Bind beyond localhost and relaunch:
Then open./run stop && ./run app --host # all interfaces (mesh + LAN) ./run app --host=10.9.0.3 # mesh IP onlyhttp://10.9.0.3:4173/#/marketsfrom the other host and enter the passcode../run app --hostwithout a passcode set prints a loud warning.
The API itself (:3210) is bearer-guarded regardless; only the panel front door
needs the passcode. The API does not need to be mesh-exposed — the panel proxies
to it over localhost.