command hq: the api, mounted and documented
full REST surface for categories, tags and commanders. core permission (personal: ['/'], no grant to hold — every query is scoped to the caller's own user_id at the sql layer regardless). registered in the permission registry and PROTECTED_MOUNTS together, so totality holds by construction. GET /commanders is the grid endpoint: everything /chat/sessions already returns per session, plus categoryId/tagIds/running. `running` is derived live off collectRunningTasks (now exported from websocket.ts) folded over chat_session_events — not a stored column, on purpose, matching the design doc's stance that a status field would go stale exactly when a sidecar restart silently kills a watcher. GET /commanders/:sessionId deliberately does NOT duplicate the transcript — that stays GET /chat/sessions/:id, unchanged. a client calls both. /chat/sessions now excludes anything filed as a commander (listCommandHqSessionIds, .catch()'d so a hiccup on this feature can't take the whole chat list down) — the other half of the one predicate this whole design turns on. there is deliberately no POST /commanders/new: creation is an ordinary chat turn in the commanders directory, which is the next commit. docs/command-hq.md gains an API reference table for the mobile dev, and a status line at the top saying plainly what is real and what is not yet: needs `bun db:push` before any route returns real data, frontend not started. bunx tsgo clean. suite at baseline (same 7 pre-existing failures, all registry/totality drift and the pty socket test — none touch this router). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1185,8 +1185,12 @@ export function decideResume(knownModel: string | undefined, claimedModel: strin
|
||||
* status — so started-minus-notified is the answer, and a Map keyed by taskId keeps the last word on each.
|
||||
* There is no third event: a task the agent abandoned without notifying stays here until the log is pruned,
|
||||
* which is the honest reading of the record rather than a bug to paper over.
|
||||
*
|
||||
* Exported for `api/command-hq/router.ts`, which uses it the same way and for the same reason: a commander's
|
||||
* liveness is derived from this fold rather than a stored column, so it cannot go stale independently of the
|
||||
* log it is read from. Do not reimplement this elsewhere — reuse it.
|
||||
*/
|
||||
function collectRunningTasks(events: ServerMessage[]): RunningTask[] {
|
||||
export function collectRunningTasks(events: ServerMessage[]): RunningTask[] {
|
||||
const running = new Map<string, RunningTask>();
|
||||
for (const event of events) {
|
||||
if (event.type === 'task:started') {
|
||||
|
||||
Reference in New Issue
Block a user