// Wire types for a classified terminal row — mirrors hive-agent's // `term_msg.rs`/`web_ui/stream.rs` field-for-field. The frontend renders // a `TermMsg` close to as-is (see Row.tsx); there's no separate // client-side row model or classification step any more — mara: // "StreamRow should now match what the server sends in TermMsg." // // Shared between `@hive/agent` (the per-hive local stream, wrapped in // `TermEnvelope`s) and `@hive/swarm-ui` (the swarm relay's `GET // /api/agents/{name}/term/stream`, which forwards one bare `TermMsg` // per SSE event — no envelope, no `seq`, no history endpoint). export type Level = "debug" | "info" | "warn" | "error"; export interface TermMsg { /** When the event this row came from happened — ISO 8601 UTC, e.g. * "2026-09-13T12:35:03Z". The source event's own time, so a row replayed * from history reads as when it happened rather than when it was fetched. */ ts: string; icon?: string; level: Level; summary: string; body?: string; body_format?: "markdown" | "diff"; coalesce_key?: string; } /** One SSE frame / history array entry — `hive-agent`'s `TermEnvelope`. * `seq` is the live per-event dedup counter (`BusEvent::seq`); absent on * history-replayed envelopes, see useLiveStream.ts's backfill dance. It is * the only field left: the event's time rides on each row's own `ts`, where * a consumer reading a bare row (the swarm queue's) can also see it. * * Local to the per-hive stream — the swarm relay carries no envelope. */ export interface TermEnvelope { seq?: number; msgs: TermMsg[]; } /** A `TermMsg` plus the bookkeeping Preact needs to render a list — * stable identity for coalescing/keys, and whether it came from history * replay vs. the live tail. Not a separate model: everything content-wise * is still exactly the wire shape. */ export interface TermRow extends Omit { /** Absent on the rows the client invents for itself — the history/live * separators, the connection note, a locally echoed prompt — which answer * to no server event and so have no event time to carry. */ ts?: string; key: string; fromHistory: boolean; }