Events
Cline runs with cline --json and emits a line-delimited JSON stream
(EventFormat::Cline) on standard output, which the harness layer translates
into the normalized harness events. Cline 3.x wraps
every record in a top-level type; older versions emit a flat say/ask stream.
Both shapes are handled.
The session id is captured from a sessionId, session_id, or id field. The
taskId/task_id fields name the in-memory conversation, not the session, and
are never captured.
Raw event stream
Section titled “Raw event stream”Each non-empty line is a complete JSON object dispatched on its top-level type:
Top-level type | Handling |
|---|---|
hook_event | Lifecycle bookkeeping. Consumed; no event. |
run_result | The terminal record; its final text and usage are consumed elsewhere. No event. |
agent_event | Agent activity nested in the record’s event object (see below). |
| anything else | Treated as a legacy say/ask record (see below). |
Within an agent_event, the nested event object’s type and contentType
drive the mapping. An agent_event with no nested event becomes an
unknown event.
-
iteration_start,iteration_end,usage, anddoneare consumed; totals come from therun_resultrecord instead. -
content_startrecords a tool call’s input (atoolcontentType, keyed bytoolCallId) for later resolution. A text block’s streaming delta is consumed here because the matchingcontent_endcarries the complete text. -
content_endresolves the block: atextblock emits an agent message (from the record’stext, falling back tocontent; empty text emits nothing), areasoning(orthinking) block emits a reasoning event the same way, and atoolblock resolves the recorded tool into its event(s). A tool whosecontent_startwas missed is still classified from thecontent_endalone when it restates thetoolNameandinput. Any othercontentTypebecomes an unknown event.Note that whether reasoning arrives as its own
reasoningblock depends on the model and provider: some models (for example Gemini routed through OpenRouter) fold their reasoning into the visibletextrather than emitting a separate block, in which case it is reported as part of the agent message with no reasoning event.
A tool’s success is read from its content_end output: a success flag, or —
for a batch (output array or output.results array) — every item succeeding.
Older Cline versions emit a flat say/ask stream. It is handled conservatively: a
say of text or completion_result, and an ask of followup, become agent
messages when they carry non-empty text; say reasoning becomes a
reasoning event; say
error or api_req_failed becomes an
error event. Everything else —
including legacy tool activity, which is not reconstructed — becomes an unknown
event.
Normalized mapping
Section titled “Normalized mapping”| Raw record | Normalized event |
|---|---|
hook_event | consumed |
run_result | consumed (text and usage) |
agent_event → iteration_start / iteration_end / usage / done | consumed |
agent_event → content_start | consumed (records tool input or text delta) |
agent_event → content_end (text) | agent |
agent_event → content_end (reasoning / thinking) | reasoning |
agent_event → content_end (tool) | per the tool mapping |
legacy say text / completion_result, ask followup | agent |
legacy say reasoning | reasoning |
legacy say error / api_req_failed | error |
agent_event with no nested event, unrecognized contentType, legacy tool activity, anything else | unknown |
Tool mapping
Section titled “Tool mapping”A tool content_end is classified by its toolName:
| Cline tool | Event |
|---|---|
run_commands, execute_command, bash | command (one per command — a commands array or single string) |
read_files, read_file | read (one per file — a files array or single path) |
editor, write_to_file, replace_in_file, new_rule | write |
apply_patch | write (one per file named by the patch markers) |
search_files, search_codebase | search |
list_files | list |
skills, use_skill | skill |
| any other tool | unknown |
See Harness Events for the normalized event types these map onto.