command hq: web frontend v1 — nav, grid, detail
Builds the Workspace/Panel screen the design doc's "Layout, v1" described but nothing had implemented yet: /command-hq and /command-hq/:sessionId, three always-mounted panels (officerdev/src/apps/CommandHQ/) — a flat category nav filtering the grid via ?category=, a commander grid reading GET /commanders, and a detail pane that is either an empty state, the new-commander composer, or the selected commander's resumed transcript. Follows the frontend route conventions in CLAUDE.md throughout: Workspace/Panel framework (locked, three fixed panels, no standalone screen), category and session both addressable in the URL rather than a channel, real <Link>s for every row and card, a route pair (/command-hq + /command-hq/:sessionId) the same shape as /chat's. The composer reuses the exact mechanism /chat already uses to create a commander — an ordinary turn with context: 'command-hq' via useChat/ EmbeddableChat — rather than the mobile-only POST /commanders/new HTTP route. Once the harness reports a real transcript id the URL is replaced onto it (useChat's own permalink writes /chat/<id>, which is the wrong screen here, so that's done by hand). fileAsCommander always files a new commander uncategorised — it has no way to know a category was selected in the composer — so if one was, a client-side PATCH sets it after the fact, the same race POST /commanders/new already resolves server-side for mobile, just resolved here on the client instead. The detail panel's transcript resume mirrors ChatPanelWrapper's fetch-then- mount pattern (GET /chat/sessions/:id first, then useChat with resumeSessionId + initialMessages + paginate) rather than reusing it directly — Command HQ's version is simpler (no dashboard/agent-panel concerns) and scopes rename/category/disarm through Command HQ's own PATCH route rather than /chat's, since a commander lives in a different directory than an ordinary chat session. Card status is the three-state read COMMS/command-hq/mobile-4.md proposed and the design record adopted: green running, amber armed-but-not-running (the watcherArmed && !running pair that makes a silently-dead watcher visible), grey neither. Registered in AppRegistry.tsx, re-exported from officerdev's barrel (route helpers + types, per CLAUDE.md's rule for anything an officer-web screen needs), a CORE_DOCK_ITEMS tile (not in DEFAULT_DOCK_PATHS — opt-in via the Dock settings screen, same as Jobs/Monitor/Activity), and a usePageTitle rule. bunx tsgo clean, suite at its 7 pre-existing baseline failures, none of them this feature's. NOT yet clicked through against a running server — the composer's redirect-on-real-id, the disarm button, the category-race PATCH have all typechecked and nothing more. That's the next real test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+26
-10
@@ -5,14 +5,27 @@ it, kept current as answers landed.
|
||||
|
||||
**Status:** data model, the full REST API including both creation paths (web and `POST
|
||||
/commanders/new`), built and mounted 2026-08-18 (`bunx tsgo` clean, suite at its 7 pre-existing baseline
|
||||
failures — none of them this feature's). **Needs `bun db:push`** before any route answers with real data;
|
||||
without it every route throws a Postgres "relation does not exist" 500. A member also needs
|
||||
`confineUserTree` re-run once if their account predates tonight — see "A member could not reach it" under
|
||||
"Working directory". **Frontend not built yet on the web side.** The mobile side is further along —
|
||||
`apps/commandhq` exists and typechecks against this router (see `COMMS/command-hq/mobile.md`) — and as of
|
||||
this revision has what it asked for to create a commander, though it has not yet been exercised against a
|
||||
running server on either side. Every claim in this file is checked against the code, not aspirational —
|
||||
see "API reference" for what a client can call today.
|
||||
failures — none of them this feature's). `bun db:push` and a restart of `officer` have both since run
|
||||
against the dev machine, so the backend is live. A member still needs `confineUserTree` re-run once if
|
||||
their account predates that — see "A member could not reach it" under "Working directory".
|
||||
|
||||
**Web frontend v1 built 2026-08-18**, same session: `/command-hq` and `/command-hq/:sessionId`, three
|
||||
panels per "Layout, v1" below (`command-hq-categories`, `command-hq-grid`, `command-hq-detail`) under
|
||||
`officerdev/src/apps/CommandHQ/`, registered in `AppRegistry.tsx`, a `CORE_DOCK_ITEMS` tile, and a
|
||||
`usePageTitle` rule. **Not yet exercised against a running server** — typechecks and the suite is at
|
||||
baseline, but nobody has clicked through it live. The composer creates a commander the same way `/chat`
|
||||
always has (an ordinary turn with `context: 'command-hq'`); once the harness reports a transcript id the
|
||||
URL is replaced onto it, and if a category was selected when composing, a `PATCH` sets it client-side —
|
||||
`fileAsCommander` itself always files uncategorised, the same race `POST /commanders/new` resolves
|
||||
server-side for mobile, resolved here the client-side equivalent. Rename, category and disarm all go
|
||||
through Command HQ's own `PATCH` route, never `/chat`'s — the two are scoped to different directories. Tag
|
||||
UI is still deliberately absent, per "Tags — infrastructure now, UI not specified" below.
|
||||
|
||||
The mobile side is further along on live exercise — `apps/commandhq` exists and typechecks against this
|
||||
router (see `COMMS/command-hq/mobile.md`) — and as of this revision has what it asked for to create a
|
||||
commander, though it has not yet been exercised against a running server on either side either. Every claim
|
||||
in this file is checked against the code, not aspirational — see "API reference" for what a client can call
|
||||
today.
|
||||
|
||||
## API reference — build against this
|
||||
|
||||
@@ -527,5 +540,8 @@ scope for tonight."_
|
||||
## Still open
|
||||
|
||||
Nothing blocking as of this revision. `POST /command-hq/commanders/new` is built — see "How a commander is
|
||||
created" — with `prompt` required, confirmed with the owner 2026-08-18. Neither path (web or mobile) has
|
||||
been exercised against a running server yet; that is the next real test, not a design question.
|
||||
created" — with `prompt` required, confirmed with the owner 2026-08-18. The web frontend v1 is built too
|
||||
(see the status line at the top). **Neither client has actually been clicked through against a running
|
||||
server yet** — that is the next real test, not a design question, and it is the thing most likely to turn
|
||||
up something this file gets wrong: the composer's redirect-on-real-id, the watcher-disarm button, the
|
||||
category-race PATCH, none of them have run once outside a typecheck.
|
||||
|
||||
Reference in New Issue
Block a user