菜单栏状态逻辑
显示内容
- 菜单栏图标和菜单第一行状态栏展示当前 agent 的工作状态。
- 工作进行中时隐藏健康状态;所有会话空闲后恢复显示。
- 菜单中的 “Nodes” 区域仅列出设备(通过
node.list获取的已配对节点),不列出 client/presence 条目。 - 当有 provider 用量快照时,Context 下方会出现 “Usage” 区域。
状态模型
- 会话:事件携带
runId(每次运行)和载荷中的sessionKey。“main” 会话对应 keymain;缺失时回退到最近更新的会话。 - 优先级:main 始终优先。main 活跃时立即显示其状态。main 空闲时显示最近活跃的非 main 会话。活动中不来回切换;仅在当前会话空闲或 main 变为活跃时切换。
- 活动类型:
job:高级命令执行(state: started|streaming|done|error)。tool:phase: start|result,带toolName和meta/args。
IconState 枚举(Swift)
idleworkingMain(ActivityKind)workingOther(ActivityKind)overridden(ActivityKind)(调试覆盖)
ActivityKind → 图标
exec→ 💻read→ 📄write→ ✍️edit→ 📝attach→ 📎- 默认 → 🛠️
视觉映射
idle:正常小动物图标。workingMain:带图标的徽章,完整着色,腿部 “工作中” 动画。workingOther:带图标的徽章,弱化着色,无快跑动效。overridden:使用选定的图标/着色,不受活动状态影响。
状态行文字(菜单)
- 工作进行中时:
<Session role> · <activity label>- 示例:
Main · exec: pnpm test、Other · read: apps/macos/Sources/OpenClaw/AppState.swift。
- 示例:
- 空闲时:回退到健康摘要。
事件接入
- 来源:控制通道
agent事件(ControlChannel.handleAgentEvent)。 - 解析字段:
stream: "job"带data.state表示开始/结束。stream: "tool"带data.phase、name、可选meta/args。
- 标签:
exec:args.command的第一行。read/write:缩短的路径。edit:路径加上从meta/diff 计数推断的变更类型。- 兜底:工具名称。
调试覆盖
- Settings ▸ Debug ▸ “Icon override” 选择器:
System (auto)(默认)Working: main(按工具类型)Working: other(按工具类型)Idle
- 通过
@AppStorage("iconOverride")存储;映射到IconState.overridden。
测试清单
- 触发 main 会话任务:确认图标立即切换,状态行显示 main 标签。
- main 空闲时触发非 main 会话任务:图标/状态显示非 main;保持稳定直到结束。
- 非 main 活跃时启动 main:图标立即切换到 main。
- 快速工具连发:确保徽章不闪烁(工具结果有 TTL 宽限期)。
- 所有会话空闲后健康行重新出现。