Type Alias: AgentDocumentCommand
agentmux / agent-document-store / AgentDocumentCommand
AgentDocumentCommand = {
at:number;type:"SessionStart"; } | {at:number;type:"SessionEnd"; } | {nodes:DocumentNode[];type:"HistoryLoaded"; } | {fromSnapshot:true;nodes:DocumentNode[];type:"HistoryRestored"; } | {newNodes:DocumentNode[];type:"StreamFlush";updatedNodes:DocumentNode[]; } | {chunk:ToolLogChunk;toolId:string;type:"ToolChunkAppend"; } | {node:ShellNode;type:"ShellNodeCreate"; } | {chunk:ToolLogChunk;shellId:string;type:"ShellChunkAppend"; } | {exitCode?:number;exitedAt:number;shellId:string;status:ShellNode["status"];type:"ShellStatusUpdate"; } | {reason:string;type:"StreamTruncate"; } | {type:"UserClear"; } | {at:number;scope?:"tools-only";type:"ScrubOrphanedInProgress"; } | {nodeId:string;type:"ForceCancelToolNode"; } | {keepIds?:ReadonlySet<string>;keepTurns:number;maxFinishedBytes?:number;pinned:boolean;type:"RollOff";visibleIds:ReadonlySet<string>; } | {keepIds:ReadonlySet<string>;type:"UnloadToolResults"; } | {nodeId:string;result:ToolResult;type:"ResultLoaded"; }
Defined in: agent-document/types.ts:66
Hooks emit these. The reducer decides what to do based on current state + invariants.
Union Members
Section titled “Union Members”Type Literal
Section titled “Type Literal”{ at: number; type: "SessionStart"; }
Hook signal: live stream subscription is up.
Type Literal
Section titled “Type Literal”{ at: number; type: "SessionEnd"; }
Hook signal: subscription torn down (cleanup).
Type Literal
Section titled “Type Literal”{ nodes: DocumentNode[]; type: "HistoryLoaded"; }
Persisted history (older messages from blockfile) — prepended.
Type Literal
Section titled “Type Literal”{ fromSnapshot: true; nodes: DocumentNode[]; type: "HistoryRestored"; }
Restore from a snapshot file (output.state.json). Semantically
identical to HistoryLoaded (prepend with id-dedup), with one
additional effect: sessionPhase jumps directly to "active"
because the snapshot represents the full pre-close history —
there is no further history to page in.
Why prepend (not full-replace): useAgentStream may dispatch
StreamFlush during the async snapshot read window. A full
replace would wipe those live arrivals. Existing nodes (live
arrivals) win on id collision; the snapshot version is dropped.
fromSnapshot: true is a discriminator field per spec §4.5 — the
view layer reads it from the audit event (history-restored) to
distinguish snapshot restore from partial HistoryLoaded prepend.
Spec: docs/specs/SPEC_AGENT_PANE_STATE_PERSISTENCE_2026_05_15.md §4.5.
Type Literal
Section titled “Type Literal”{ newNodes: DocumentNode[]; type: "StreamFlush"; updatedNodes: DocumentNode[]; }
Generic merge: newNodes are appends (with dedup against existing
IDs — collisions route to in-place update), updatedNodes are
targeted mutations against existing IDs. The primary caller is the
stream’s RAF flush, but any frontend-local mutation that needs to
append or update document nodes (e.g. optimistic decision-update,
login-success row) routes through the same command so slot.state
stays authoritative.
Type Literal
Section titled “Type Literal”{ chunk: ToolLogChunk; toolId: string; type: "ToolChunkAppend"; }
Append one streaming chunk to a tool’s live-log buffer
(ToolNode.log.chunks). Append-only, idempotent on the timestamp
- content dedup key. Dispatched at high frequency from
useAgentStreamfortool_chunkstream events — kept distinct fromStreamFlushso chunk traffic doesn’t re-trigger memos that watch the full node array length. See SPEC_TOOL_BLOCK_LIVE_LOG_2026_05_11.md §3.3.
Type Literal
Section titled “Type Literal”{ node: ShellNode; type: "ShellNodeCreate"; }
Create a new ShellNode in the document (fired on shell_node_create MPS event).
Type Literal
Section titled “Type Literal”{ chunk: ToolLogChunk; shellId: string; type: "ShellChunkAppend"; }
Append a streaming chunk to a ShellNode’s live-log.
Type Literal
Section titled “Type Literal”{ exitCode?: number; exitedAt: number; shellId: string; status: ShellNode["status"]; type: "ShellStatusUpdate"; }
Update a ShellNode’s terminal status (exit, stop).
Type Literal
Section titled “Type Literal”{ reason: string; type: "StreamTruncate"; }
Backend fileop=truncate arrived on the file subject. The reducer
decides whether to honor (initialization, legitimate clear) or
suppress (stale event after socket reconnect — this is the bug we’re
fixing).
Type Literal
Section titled “Type Literal”{ type: "UserClear"; }
User invoked /clear — always honored.
Type Literal
Section titled “Type Literal”{ at: number; scope?: "tools-only"; type: "ScrubOrphanedInProgress"; }
Scrub orphaned in-progress nodes. Walks nodes[] and:
- flips any markdown with
metadata.thinking === truetometadata.canceled === true(clearing the thinking flag). - flips any
toolwithstatus === "running"tostatus: "canceled".
Dispatched as a side-effect of SessionEnd (clean exits)
and HistoryRestored / HistoryLoaded (resumed sessions
where the kill happened before SessionEnd ever fired).
Idempotent — running it twice is a no-op against the
already-scrubbed state.
scope: "tools-only" narrows the sweep to tool nodes with
status === "running" — dispatched shortly after every TurnEnd
(agent-view.tsx): a foreground tool call cannot outlive its turn
(it blocks it) and a backgrounded harness call resolves its
ToolNode immediately, so a running tool node observed after the
turn ended is provably an orphan (rejected call / dropped
tool_result). Thinking markdown, shells (turn-independent — a
live MCP shell legitimately spans turns), and awaiting_answer
questions are deliberately untouched in this scope; their
lifecycles are session-bounded, not turn-bounded.
Spec: docs/specs/SPEC_ORPHAN_THINKING_NODES_2026_05_27.md.
Type Literal
Section titled “Type Literal”{ nodeId: string; type: "ForceCancelToolNode"; }
Force one specific ToolNode to status: "canceled", regardless of
how long it’s been running or whether a session boundary has
happened. Dispatched when a dock:clear MPS event arrives (a
muxspect dock clear request for this pane’s block) — the manual
escape hatch for a stuck node, distinct from ScrubOrphanedInProgress’s
blanket sweep. No-op (empty events) if nodeId isn’t a currently
tracked tool node — already resolved, or a stale/duplicate event.
Spec: docs/specs/SPEC_MUXSPECT_DOCK_DIAGNOSIS_AND_REMEDIATION_2026_08_06.md §3.2.
Type Literal
Section titled “Type Literal”{ keepIds?: ReadonlySet<string>; keepTurns: number; maxFinishedBytes?: number; pinned: boolean; type: "RollOff"; visibleIds: ReadonlySet<string>; }
Roll finished turns off the live feed (spec
SPEC_AGENT_PANE_BOUNDED_LIVE_WINDOW_MIGRATION_2026_09_23.md §6.9). The
reducer plans against its CURRENT nodes (planRollOff), so what the
pane saw when it scheduled the pass can’t be stale; the pane supplies
only what the reducer can’t know — what is on screen, and whether the
reader follows the bottom. The removed turns stay in the transcript,
where History shows them.
keepIds?
Section titled “keepIds?”
optionalkeepIds?:ReadonlySet<string>
Nodes the user pinned: their turns stay, like visible ones.
keepTurns
Section titled “keepTurns”keepTurns:
number
maxFinishedBytes?
Section titled “maxFinishedBytes?”
optionalmaxFinishedBytes?:number
pinned
Section titled “pinned”pinned:
boolean
type:
"RollOff"
visibleIds
Section titled “visibleIds”visibleIds:
ReadonlySet<string>
Type Literal
Section titled “Type Literal”{ keepIds: ReadonlySet<string>; type: "UnloadToolResults"; }
Unload collapsed tool results the reducer plans against its current
nodes (planUnload): each becomes a stub until it’s read back.
SPEC_AGENT_PANE_TOOL_RESULT_UNLOADING_2026_10_01.md §3.3.
Type Literal
Section titled “Type Literal”{ nodeId: string; result: ToolResult; type: "ResultLoaded"; }
A tool’s unloaded result, read back from the transcript (§3.4).