Skip to content

Events

Claude Code is run with claude --print --output-format stream-json --verbose, which emits a line-delimited JSON stream on standard output. Each non-empty line is a complete JSON object carrying a top-level type. The harness layer parses that stream into the normalized harness events every caller consumes.

The stream is stateful. An assistant event introduces a tool use, and the operation it requested becomes a normalized event only once the matching tool-result arrives in a later user event. Pairing the requested operation with its observed result is what lets a file read report both the path the agent asked for and whether the read succeeded. Any event may carry a session_id; the first non-empty one seen is the session ID for the stream.

Top-level type values are recognized as follows:

Claude Code eventHandling
systemSession lifecycle metadata. The init event’s cwd is captured to resolve relative paths. The init, status, and thinking_tokens subtypes emit no event; any other subtype becomes an unknown event.
assistantText content becomes activity; tool-use content is recorded for later correlation.
userTool-result content resolves a recorded tool use. Echoed prompt or injected-context text emits no event.
rate_limit_eventCredential state, consumed. A status other than allowed becomes a warning.
resultThe terminal event. Its usage and final output are consumed for metrics; a reported terminal error becomes an event.
stream_eventLower-level partial telemetry that the completed assistant and user events restate, so it is consumed.
any other typeAn unknown event, so the stream stays lossless.

A non-JSON line is a diagnostic printed outside the stream and is surfaced as a warning. Output on standard error is surfaced as a warning as well.

Raw stream inputNormalized event
assistant text blocks, joined per messageagent
assistant thinking blocks, joined per messagereasoning
assistant redacted_thinking blockconsumed, since it carries no readable text
assistant tool_use blockrecorded, and resolved when its tool-result arrives
user tool_result blockthe recorded tool use’s event(s)
user text blockconsumed as echoed prompt or injected context
rate_limit_event with a non-allowed statuswarning
terminal result reporting an errorerror
system recognized subtypes, stream_event, allowed rate_limit_event, successful resultconsumed
unrecognized outputunknown

Reasoning is emitted ahead of the agent message it leads into, so a thought split across blocks is reported once. An unrecognized tool, a malformed tool-use block, and an unrecognized system subtype each become unknown events, so nothing is dropped. Claude Code has no orchestration source.

Each recognized tool use is paired with its tool-result by a unique tool_use_id, and the result’s error and interruption flags set the success field. An ambiguous id match becomes an unknown event rather than a guess. A read result that arrives with no recorded tool use is recovered as a read event from the file metadata it carries; any other unpaired result becomes an unknown event.

Claude Code toolNormalized event
Readread, with the line range derived from the offset and limit input
Write, Edit, MultiEdit, NotebookEditwrite
Grep, Globsearch
LSlist
Bashcommand, or a recognized file operation reclassified into read, search, or list from the command, exactly as a Codex command is
Skillskill, with the path synthesized as skills/<name>/SKILL.md under the workspace
StructuredOutputNative delivery of --json-schema output; it produces no event
any other toolunknown

Claude Code reports no stable exit code for Bash results, so a command event carries success without an exit code.