事件

CLI-JAW 的浏览器 UI 使用 SSE-first 事件通道。Provider 输出会先通过内部 NDJSON/stream-json parser 规范化,public Web 事件通过 GET /api/events 传递。

SSE 事件通道

GET /api/events
Accept: text/event-stream
Last-Event-ID: <last-seen-id>

/api/events 是 data-only SSE stream。服务器不设置 SSE event: 字段,而是在 JSON data: payload 中携带 topicevent

行为契约
Replay cursorLast-Event-ID header 或 ?lastEventId= query
Replay buffersrc/core/event-bus.ts 中最近 1000 个事件
Listener cap最多 256 个活跃 SSE listener;超出返回 503 {"error":"SSE_CAPACITY"}
Heartbeat每 15 秒发送 comment ping
Replay gap{"topic":"system","event":"replay_gap"}
FallbackWebSocket 只在 /api/events 从未打开的 pre-X-01 server 上作为 client/TUI fallback
Transient drop UX快速 SSE 重连会静默恢复;只有持续超过 8 秒的断线才显示 disconnected 消息

主要事件

事件载荷说明
message{id, role, content}已保存的聊天消息
agent_tool{traceId, name, input}Agent 工具调用
agent_output{traceId, content}Agent 文本输出片段
agent_done{traceId, status}Agent 执行结束
queue_update{pending, active}消息队列状态
orc_state{phase, status}PABCD 编排状态
steer_started{prompt}Steer 提示注入
goal_done{goalId}目标完成
goal_done_rejected{reason}目标完成请求被拒绝
goal_pause_detected{reason}检测到目标暂停
goal_pause_gate_pending{reason}首次审计 pause armed;抑制自动 goal continuation
session_switched{sessionId}活动会话切换
agent:claude-e:*{event}Claude employee 运行时事件命名空间

Provider NDJSON 流

消息发送和命令执行由 REST 请求启动,provider 输出以换行分隔的 JSON 事件流返回。规范化后的事件经过 src/core/bus.ts:public 事件发布到 SSE event bus,同时 fan-out 给 collector/forwarder 使用的 internal listener。

POST /api/message
POST /api/command

{"type":"thinking","content":"..."}
{"type":"text","content":"Hello! "}
{"type":"tool","name":"Bash","input":{...}}
{"type":"done","status":"ok"}

Manager worker SSE

jaw dashboard serve 的 React manager app 使用 manager HTTP endpoint polling。Worker instance 的 live progress 由 manager server 通过 src/manager/worker-events.tssrc/manager/worker-sse-client.ts 在 server-side 订阅各 worker 的 GET /api/events,并更新 latest-message cache。

Trace 文件

会话 trace 以 NDJSON 文件格式保存到 ~/.cli-jaw/traces/。每一行都是带时间戳和 trace ID 的事件。