pub enum DecodedLine {
Message(Box<Message>),
Control(Box<ControlRequest>),
ControlCancel {
request_id: String,
},
ControlResponse {
request_id: String,
raw: Value,
},
Unknown {
type_str: String,
raw: Value,
},
Malformed {
line: u64,
reason: String,
},
}Expand description
A single stream-json line from the subprocess - either a regular message or a control request.
Variants§
Message(Box<Message>)
An assistant/user/system/result message.
Boxed: a Message is 536 bytes and every other variant here is a
fraction of that (clippy::large_enum_variant). The value is decoded
once per line and moved straight into the reader, so the
indirection costs one allocation and saves the enum being 536
bytes wherever a line is passed around.
Control(Box<ControlRequest>)
A control request (e.g. permission check, MCP message, hook callback).
Boxed for the same reason as Self::Message: it is 312 bytes of
its own and is dispatched once and dropped.
ControlCancel
The CLI has withdrawn a previously-issued control_request - the
handler matching request_id should be cancelled if still in flight.
Wire shape {"type":"control_cancel_request","request_id":"..."}
.
ControlResponse
The CLI is responding to an outbound control_request we sent
(initialize, interrupt, set_permission_mode, …). These arrive on
stdout and are normally consumed synchronously by the client’s
outbound-control wait loop - the read-dispatch loop in
the events stream returned by Client::spawn never sees them.
Represented here so downstream tools (the wire-conformance replay
harness, debug captures) can recognise and categorise the frame
instead of mis-flagging it as Unknown.
Fields
Unknown
Forward-compat fallback: the CLI emitted a frame with an unrecognised
top-level type field. Forge-sdk doesn’t crash on these - it logs
a warning via tracing::warn! in the dispatch path and lets the
reader continue. Callers (like the wire-conformance harness) can
detect and report these explicitly by matching this variant.
type_str is the raw type field value the CLI sent; raw is the
full JSON object for inspection / logging / replay. Neither is
typed - by definition, we don’t know what this frame is.
Fields
Malformed
A line that failed to decode: not valid JSON, or valid JSON that
matched no message shape. Typed rather than an Err so the read
loop skips the line and continues - a per-line decode failure
must not end the session, the same rule Unknown applies to
unknown types. The reader warns with the line number, reason and
a 160-char excerpt, and answers a corrupt control_request that
carries a request_id.