The previous dumb stub just execd the applescript. Now the bin (still used as the bundle executable and for double-click) supports CLI features/subcommands while preserving default tray UI behavior:
- no arg / tray / menu: launch tray UI (status item + menu)
- launch / open / app: start services (delegates to launch.sh, matches menu "Open Prospector")
- stop: stop services (matches menu "Stop services")
- help: list features
Updated post-build messaging, tray.applescript header comment, scripts/README.md table, and ./run usage. Tested via TRAY_DEST=/tmp/... build + direct bin help invocation (and full make-tray success).
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>
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>
./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>
Add scripts/ (install/app/migrate + shared lib) wired into ./run:
./run install [--launch] deps -> env -> DB+migrations -> build
./run app [--build] start API + vite-preview front door, open Chrome --app
./run db:migrate ledger-tracked SQL migrations (each file once)
migrate.sh creates the DB and tracks applied files in _prospector_migrations.
app.sh health-checks the API, opens http://localhost:<web>/#/markets as a Chrome
app window, and cleans up only its own PIDs (never a blanket node kill). Make
vite preview a token-injecting front door (shared proxy in web/vite.config.ts)
so the installed app serves a real build, not a dev server. scripts/README.md
documents it (filesystem-as-docs).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>