6.6 KiB
History State JSON Schema
This document captures the canonical JSON schema for the serialized history
state used by the TUI. Each record stored in HistoryState.records is a
tagged HistoryRecord enum. The schema follows the common structure below:
{
"id": <number>,
"type": <string>,
"payload": <variant specific object>
}
id— 64-bit unsigned integer derived fromHistoryId.type— string enum discriminant (e.g."plain_message").payload— variant data described in the sections that follow.
All timestamps are serialized as RFC 3339 strings, durations as ISO 8601 duration strings, and enums as snake_case strings unless otherwise noted.
Variant Reference
PlainMessage
type:"plain_message"payload:role:"system" | "user" | "assistant" | "tool" | "error" | "background_event"kind:"plain" | "user" | "assistant" | "tool" | "error" | "background" | "notice"header: optional object{ "label": string, "badge": string? }lines: array ofMessageLineobjectsmetadata: optionalMessageMetadata
MessageLine objects:
kind:"paragraph" | "bullet" | "code" | "quote" | "separator" | "metadata" | "blank"spans: array of{ "text": string, "tone": TextTone, "emphasis": Emphasis, "entity": Entity? }
MessageMetadata:
citations: array of citation stringstoken_usage: optional{ "prompt": number, "completion": number, "total": number }
TextTone: "default" | "dim" | "primary" | "success" | "warning" | "error" | "info"
Emphasis: { "bold": bool, "italic": bool, "dim": bool, "strike": bool, "underline": bool }
Entity: null | { "type": "link", "href": string } | { "type": "code" }
WaitStatus
type:"wait_status"payload:header:{ "title": string, "title_tone": TextTone, "summary": string?, "summary_tone": TextTone }details: array of{ "label": string, "value": string?, "tone": TextTone }
Loading
type:"loading"payload:{ "message": string }
RunningTool
type:"running_tool"payload:title: stringstarted_at: timestamparguments:ToolArgument[]wait_cap_ms: number?wait_has_target: boolwait_has_call_id: bool
ToolCall
type:"tool_call"payload:status:"running" | "success" | "failed"title: stringduration_ms: number?arguments:ToolArgument[]result_preview:{ "lines": string[], "truncated": bool }?error_message: string?
ToolArgument:
{ "name": string, "value": Text | Json | Secret }Text:{ "type": "text", "text": string }Json:{ "type": "json", "value": any }Secret:{ "type": "secret" }
PlanUpdate
type:"plan_update"payload:name: stringicon:"light_bulb" | "rocket" | "clipboard" | { "custom": string }progress:{ "completed": number, "total": number }steps: array of{ "description": string, "status": StepStatus }
StepStatus: "pending" | "in_progress" | "complete" | "skipped"
UpgradeNotice
type:"upgrade_notice"payload:{ "current_version": string, "latest_version": string, "message": string }
Reasoning
type:"reasoning"payload:in_progress: boolsections: array of{ "heading": string?, "summary": InlineSpan[], "blocks": ReasoningBlock[] }hide_when_collapsed: bool
ReasoningBlock: one of
{ "type": "paragraph", "spans": InlineSpan[] }{ "type": "bullet", "indent": number, "marker": string, "spans": InlineSpan[] }{ "type": "code", "language": string?, "content": string }{ "type": "quote", "spans": InlineSpan[] }{ "type": "separator" }
Exec
type:"exec"payload:call_id: string?command: string[]parsed: array ofParsedCommandaction:"read" | "search" | "list" | "run"status:"running" | "success" | "error"stdout_chunks: array of{ "offset": number, "content": string }stderr_chunks: array of{ "offset": number, "content": string }exit_code: number?wait_total_ms: number?wait_active: boolwait_notes: array of{ "message": string, "tone": TextTone, "timestamp": timestamp }started_at: timestampcompleted_at: timestamp?
ParsedCommand mirrors the parsed shell command structure emitted by
codex_core::parse_command.
AssistantStream
type:"assistant_stream"payload:stream_id: stringpreview_markdown: stringdeltas: array of{ "delta": string, "sequence": number?, "received_at": timestamp }citations: string[]metadata:MessageMetadata?in_progress: boollast_updated_at: timestamp
AssistantMessage
type:"assistant_message"payload:stream_id: string?markdown: stringcitations: string[]metadata:MessageMetadata?token_usage:{ "prompt": number, "completion": number, "total": number }?created_at: timestamp
Diff
type:"diff"payload:hunks: array of{ "header": string, "lines": DiffLine[] }
DiffLine: { "kind": "context" | "added" | "removed", "text": string }
Image
type:"image"payload:{ "path": string, "caption": string?, "metadata": object? }
Explore
type:"explore"payload:{ "entries": ExploreEntry[], "trailing": bool }
ExploreEntry: { "command": string[], "cwd": string?, "status": ExploreStatus }
ExploreStatus: "running" | "success" | "not_found" | { "error": { "exit_code": number? } }
RateLimits
type:"rate_limits"payload: mirrorsRateLimitSnapshotEventwith primary/secondary usage percentages and reset timestamps.
Patch
type:"patch"payload:event:"apply_begin" | "apply_success" | "apply_failure" | "proposed"auto_approved: bool?changes: map of path →FileChangefailure:{ "message": string, "stdout_excerpt": string?, "stderr_excerpt": string? }?
BackgroundEvent
type:"background_event"payload:{ "title": string, "description": string }
Notice
type:"notice"payload:{ "title": string?, "body": MessageLine[] }
Snapshot Structure
A serialized history snapshot is the object returned by
HistoryState::snapshot():
{
"records": [ <HistoryRecord>... ],
"next_id": <number>,
"exec_call_lookup": { "call_id": HistoryId },
"tool_call_lookup": { "call_id": HistoryId },
"stream_lookup": { "stream_id": HistoryId }
}
Applications consuming the schema should treat unknown fields as forward compatible extensions and must not rely on enum ordering.