Expand description
claude -p --output-format stream-json subprocess client.
Unit 9 substrate: drive a claude subprocess, parse its stream-json
output, reconstruct assistant text into lines, and capture the
concatenated text to .omne/var/runs/<run_id>/nodes/<node_id>.out.
The sentinel scanner (Unit 10) and node executor (Unit 11) consume
the reconstructed-line iterator exposed here.
The module is intentionally split into two layers:
StreamParser— a genericBufRead→AssistantLineiterator. Unit tests and downstream reuse (future replay/inspection tooling) drive this directly with canned fixtures; no subprocess required.ClaudeProcess— the subprocess wrapper that owns aChild, drains its stderr on a background thread (so the pipe buffer can never deadlock a long-runningclaude -pon a quiet run), and delegates iteration to aStreamParser<BufReader<ChildStdout>>.
Reconstruction contract (plan R8, spike 2026-04-15):
- Each stream-json line is one envelope. We only care about
{"type":"assistant", "message": { "id": ..., "content": [...] }}entries. All other top-level types are skipped — includingsystem.hook_response, which SessionStart hooks emit under-p(spike-confirmed noise) and which must never leak into the sentinel scanner. claude -pmay split a single logical message across multiple envelopes that sharemessage.id. Text blocks are therefore accumulated into a per-idbuffer and flushed when a new id is observed or the stream ends. Flushing splits the buffer on\n, trims each line, drops empties, and yields them in order.- All received text blocks are written verbatim to the capture file
as they arrive. No per-line rewriting: the capture is the raw
concatenation of every
textblock from every assistant message, which matches the plan’s “concatenated assistant text” contract.
Structs§
- Assistant
Line - One reconstructed line of assistant text.
- Child
Killer - Cloneable handle that can kill a live
ClaudeProcess. - Claude
Process - Subprocess wrapper around a live
claude -pChildthat yieldsAssistantLinevalues and, onClaudeProcess::finish, returns the child’s exit status and captured stderr. - Spawn
Opts - Arguments used to build a
claude -pinvocation. - Stream
Parser - Parses stream-json envelopes from any
BufReadand yieldsAssistantLinevalues, while capturing all reconstructed text to a backing file.
Enums§
- Capture
Mode - How
StreamParseropens the capture file. - Error
- Errors surfaced by the
claude -psubprocess client. - Session
- Session lifecycle for one
claude -pinvocation.
Constants§
- DEFAULT_
BIN - Default binary name probed on
PATH. - PREFLIGHT_
TIMEOUT - Wall-clock budget for
preflight(i.e.claude --version). Long enough for a slow Windows process spawn; short enough to fail fast when the host binary is wedged. Runtime invocations (stream) have no timeout at this layer — Unit 11’s executor owns node-level deadlines.
Functions§
- build_
command - Build the
Commandthatspawnwould launch. Exposed so tests and Unit 11’s executor can inspect / adjust the argv without actually spawning. - preflight
- Run
claude --versionand return the reported version string. - spawn
- Spawn
claude -pperSpawnOptsand return theChild. - stream
- Wire a live
Childinto aClaudeProcessthat yieldsAssistantLinevalues and writes the reconstructed text tocapture_path(truncating any prior content).