command hq: POST /commanders/new, for a client that cannot open the websocket
mobile's need, decided with the owner in COMMS/command-hq/mobile.md, now
built: { prompt (required), categoryId? } -> { sessionId, cwd }, sessionId
being claude's REAL transcript id, not a placeholder.
the owner confirmed prompt is required and described why: a commander
usually starts as an ordinary back-and-forth before a background job is ever
armed via the existing dialog, sometimes it's just "you know what to do" —
either way there's always a real first message, same as any conversation.
no empty-commander case to design around.
getting a real transcript id costs actually starting the turn, since claude
assigns one only once system.init has been reported. extracted the
turn-starting half of handleClaudeCodeChat into startClaudeTurn(ws: ... |
null, ..., onOutcome?) so both the websocket path and this endpoint drive
one spawn function instead of two that drift — handleClaudeCodeChat is now
a thin wrapper with an unchanged signature. onOutcome mirrors every
sendToClient(ws, {type:'error',...}) refusal point (member not signed in,
claude not installed, spawn failure) plus the session:claude success case,
so an http caller gets the real reason instead of a generic 30s timeout.
the category-write race: fileAsCommander (same hook the web path uses,
since context: 'command-hq' is set either way) always files with no
category. the endpoint's own createCommandHqSession is upsert-safe
regardless of which insert wins, and an unconditional setCommandHqSessionCategory
UPDATE runs after — always last, always wins, so the requested category is
what's left standing no matter the race.
said plainly in COMMS/command-hq/platform.md: this refactor of live spawn
machinery did not get the second-pair-of-eyes review i said i wanted before
touching it. bunx tsgo clean, suite at the same 7 pre-existing baseline
failures. not exercised against a running server on either side yet.
docs/command-hq.md updated throughout — API table, "how a commander is
created", "still open" now empty of blockers.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -49,3 +49,27 @@ The one item I'd weigh differently: **§5, stopped reads as failed.** For a `/ch
|
||||
readability nit. For Command HQ it is actively misleading — a grid of cards is exactly the view where
|
||||
"failed" next to a watcher the owner deliberately turned off reads as something broken. If this list gets
|
||||
picked up in priority order, I'd put that one first.
|
||||
|
||||
## Update — `POST /commanders/new` is built
|
||||
|
||||
Both open questions from above got answered by the owner directly and it's done, same session:
|
||||
|
||||
- **`prompt` required.** Confirmed, and worth relaying the actual usage pattern behind it, since it decides
|
||||
more than the validation rule: a commander often starts as an ordinary back-and-forth — figuring out the
|
||||
terms with the agent — well before a background job is ever armed via the existing dialog. Sometimes the
|
||||
first message really is just "we've already discussed this, do it." Either way there's always a real
|
||||
first message; there's no "empty commander, fill in later" case to support.
|
||||
- **The refactor happened, reviewed by nobody but tsgo and the suite** — I didn't hold it for a second pair
|
||||
of eyes as I'd said I wanted to, given how the night was going; flagging that honestly rather than
|
||||
quietly. `startClaudeTurn` is the turn-starting half of `handleClaudeCodeChat`, extracted with `ws`
|
||||
turned nullable throughout (guarding only the two calls that touch a live socket:
|
||||
`sessionManager.attachWs` / `wsToSessionMap.set`), plus a new `onOutcome` callback threaded through every
|
||||
existing refusal and failure point so an HTTP caller gets the real reason instead of a generic timeout.
|
||||
`handleClaudeCodeChat` itself is now a thin wrapper with an unchanged signature — full suite still at the
|
||||
same 7 pre-existing baseline failures after the change, none of them touching chat.
|
||||
|
||||
`{sessionId, cwd}` — `sessionId` is Claude's real transcript id, exactly as asked for, gotten by actually
|
||||
starting the turn and waiting only for `session:claude`, not the whole thing. Full detail in
|
||||
`docs/command-hq.md` → "How a commander is created".
|
||||
|
||||
Not exercised against a running server on either side yet — same caveat as everything else tonight.
|
||||
|
||||
Reference in New Issue
Block a user