pub struct HarnessRuntimeTerminalFrameV1 {
pub sequence: u64,
pub size: HarnessRuntimeTerminalSizeV1,
pub cursor_row: u16,
pub cursor_column: u16,
pub formatted: Vec<u8>,
pub scrollback_formatted: Vec<Vec<u8>>,
pub alternate_screen: bool,
pub mouse_protocol_enabled: bool,
pub mouse_protocol_encoding: HarnessRuntimeMouseProtocolEncodingV1,
pub produced_at_unix_ms: u64,
pub screen_state: Option<PtyScreenStateV1>,
pub bracketed_paste: Option<bool>,
}Fields§
§sequence: u64§size: HarnessRuntimeTerminalSizeV1§cursor_row: u16§cursor_column: u16§formatted: Vec<u8>§scrollback_formatted: Vec<Vec<u8>>§alternate_screen: bool§mouse_protocol_enabled: bool§mouse_protocol_encoding: HarnessRuntimeMouseProtocolEncodingV1§produced_at_unix_ms: u64Unix-epoch milliseconds when the source TerminalFrame was
materialized (gate4agent_types::TerminalFrame::produced_at_unix_ms,
stamped once at the PTY snapshot and carried unchanged through every
relay hop, including the harness’s own terminal ring buffer). An
operator computing an age from this must account for clock skew
between the node host and its own, not just transit/queue delay.
#[serde(default)] so an operator client built before this field
existed still decodes the frame – it just can’t answer “how stale”.
screen_state: Option<PtyScreenStateV1>The screen classification stamped at the instant this frame’s screen
was materialized. Always populated – Unknown is a real
classification, not an absence marker – so Some is the only value
ever actually sent; Option-wrapped only so a decoder never has to
special-case a missing key.
bracketed_paste: Option<bool>Mirrors gate4agent_types::TerminalFrame::bracketed_paste onto the
operator wire unconditionally. None here means only “the node
hasn’t captured a value yet” – the source field’s own genuine
absence – never a wire-version gate.