the handoff watcher was built and never rendered

BackgroundJobDialog offers three fire behaviours and gates the third, `handoff` — exit, act, re-arm — on
an `isCommander` prop. Nothing ever passed it. So it defaulted to false everywhere and the option
appeared NOWHERE, including inside a Command HQ commander, where the dialog's own code makes it the
default.

Everything else was there: the fire rule, `handoffContract`, `armWatcher` reaching the server, and a note
recording that it had run for hours self-re-arming without failure. Only the radio button was missing,
which made a working mechanism look unbuilt — and it is the one a deploy watcher needs, since
`keep-going` never hands back to an agent at all.

Found while telling the owner how to start the deploy commander: the dialog in a commander showed two
options where I had said there would be three.

The fix is two lines and no new concept. `useEmbeddableChat` already receives `context` and passed it
into `useChat`; it now also returns it, and InputArea gives the dialog `isCommander={context ===
'command-hq'}`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 18:30:14 +00:00
co-authored by Claude Opus 5
parent 240d8adbd3
commit 7a46612f41
2 changed files with 14 additions and 0 deletions
@@ -575,6 +575,10 @@ export function useEmbeddableChat(params: UseEmbeddableChatParams, onMessageComp
}, [autoSend, isConnected, messages.length, input]);
return {
// Surfaced so the composer can offer what only makes sense here. The Command HQ context is the one
// place a `handoff` watcher can be promised — see BackgroundJobDialog — and it was invisible to the
// composer, so the option was never rendered anywhere at all.
context: params.context,
messages,
historicalCount,
streamingText,
@@ -173,6 +173,16 @@ export const InputArea = ({ manager }: InputAreaProps) => {
open={jobDialogOpen}
onOpenChange={setJobDialogOpen}
cwd={cwd}
/*
`handoff` — exit, act, re-arm — is only offered inside a Command HQ commander, because it is a
promise the platform has to keep rather than only a sentence in the prompt.
This prop was never passed by anybody, so `isCommander` defaulted to false everywhere and the
option was rendered NOWHERE — including in a commander, where the dialog's own code makes it the
default. The whole mechanism existed: the fire behaviour, the contract, `armWatcher` reaching the
server. Only the radio button was missing, so the feature looked unbuilt.
*/
isCommander={manager.context === 'command-hq'}
onSubmit={(intent, preamble, armWatcher) => {
// Claimed by the next job to start, which is how the preview tells this one apart from the
// background jobs an agent starts on its own.