Add control board web page and local server (#1503)

Step 2 of the control board MVP (MOSAIC-STACK-D-001): `serve` command starts
a loopback-only local server that serves one self-contained page and re-runs
the status scanner on each /api/board request. The page lists sessions
waiting on Jason first (errors on top), then one table per project with
plain-word states, ages, last messages, expandable detail rows, per-project
hide-offline, and a 10-second auto-refresh with pause.

Tests: control-board 33/33 (10 new: loopback rules, host refusal, all routes,
per-request rescan, 500 path, CLI refusals, live serve, page escaping guard);
registry 69/69 unchanged. Receipt:
docs/plans/reviews/2026-09-12_control-board-step2-review.md.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
2026-09-12 07:58:38 -05:00
co-authored by Claude Fable 5.1
parent b9f59a5903
commit ebedd1281e
10 changed files with 914 additions and 26 deletions
+22
View File
@@ -1943,3 +1943,25 @@ Suites: control-board 23/23; registry 69/69 unchanged. Live scan writes
Corrections during the phase: pi `stopReason: "length"` was initially treated as
"working" (now "error"); an unrunnable tmux check was initially treated as alive
(now "unknown"). Registry increment 3 stays parked. Next: step 2, the web page.
## 2026-09-12 — Control board MVP step 2 (#1503)
Before: scanner and CLI only; status lived in JSON files under
`<dataRoot>/board/` with no way to look at them but `--print`.
After: `node packages/control-board/src/cli.mjs serve` starts a local,
loopback-only server (default http://127.0.0.1:7331/) that serves one
self-contained page and re-runs the scanner on every `/api/board` request.
The page lists "waiting on you" first (errors on top), then one table per
project with plain-word states, ages and last messages; rows expand to full
detail; offline rows are hidden per project by default; it refreshes every
10 seconds and can be paused. Suites: control-board 33/33 (10 new server and
page tests); registry 69/69 unchanged. Live check in Chrome with the full fleet:
18 waiting rows, 24 offline hidden, expanded detail survives a refresh.
Receipt: `docs/plans/reviews/2026-09-12_control-board-step2-review.md`.
Corrections during the phase: `startServer` first threw synchronously for a
non-loopback host (now always rejects); expanded rows first closed on every
refresh (now persisted); the browser reported a favicon 404 (now a 204 route).
The independent reviewer had no browser, so the live check was done by the
coordinator and is recorded as such. Next: step 3, Jason uses the page daily.