2026-06-29 08:23:32 -04:00
# 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 |
|--------|---------|---------|
feat(install): tray app + MCP step + detached run; fix local prod token proxy
./run install now also builds the Prospector.app menu-bar tray (~/Applications:
❖ Open/Stop/Quit, AppleScript-ObjC + sips/iconutil, no Swift/deps) and registers
the prospector MCP in Claude (Desktop + global, non-invasive). New ./run stop and
./run tray; SKIP_DB/SKIP_TRAY/SKIP_MCP escape hatches.
app.sh: --detach (background, for the tray), reuse an already-running instance
instead of colliding, fail loudly if a process we started dies, pidfile in .run/.
Fix the local front door: a prod build calls /prospector/* (api.ts API_BASE), so
vite preview now proxies /prospector (passthrough) while dev keeps /api (rewrite),
both injecting the bearer token. find_psql handles keg-only postgresql@N.
Verified end-to-end: ./run install (deps/env/DB+5 migrations/build/tray/MCP),
./run app serves markets through the token proxy (200; 401 without token), tray
launches resident, web tsc + 160 backend tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:49:53 -04:00
| `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. |
2026-06-29 08:23:32 -04:00
| `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. |
2026-06-29 08:37:13 -04:00
| `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. |
2026-06-29 08:23:32 -04:00
## Quick start
```bash
./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
2026-06-29 08:37:13 -04:00
./run install:mcp # (separate) register the prospector MCP for agents in Claude
2026-06-29 08:23:32 -04:00
```
## Requirements
- **Node 20+** and **npm** .
- **PostgreSQL** reachable per `.env.local` (`PROSPECTOR_DB_*` ). The installer
finds `psql` on PATH or in common macOS installs (Homebrew, Postgres.app); set
`PSQL=/path/to/psql` to 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 on `PROSPECTOR_API_PORT` (3210) and owns
its Postgres DB. Routes are guarded by a bearer service token.
- The **panel** is the built `web/dist` , served by `vite preview` , which proxies
`/api/*` → the API and injects the token (so it never lives in browser JS).
This is the same proxy `vite` uses in dev — see `web/vite.config.ts` .
- `app.sh` starts both, waits for `/health` , then opens
`http://localhost:<web>/#/markets` as a Chrome `--app` window. 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_TOKEN` for the
panel proxy. Keep its token equal to the API's.
Re-running `install` never overwrites existing env files.
2026-06-29 09:44:53 -04:00
## 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):
1. **Set a passcode** in `web/.env.local` — the panel has no login of its own,
so this gate is required before exposing it:
```
PROSPECTOR_PANEL_PASSCODE=your-passcode
```
Empty = gate off (localhost-only). The passcode is checked by the `vite
preview` front door (HMAC cookie, HttpOnly); the service token is never
injected until a valid session exists.
2. **Bind beyond localhost** and relaunch:
```
./run stop & & ./run app --host # all interfaces (mesh + LAN)
./run app --host=10.9.0.3 # mesh IP only
```
Then open `http://10.9.0.3:4173/#/markets` from the other host and enter the
passcode. `./run app --host` without 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.