Yoda
参考Agent 设计指南UI 外显

Statusline

CC 用「外部命令 + stdin JSON」把状态栏完全外包给用户脚本;Codex 用内置 item 白名单做声明式拼装,不支持自定义命令

Statusline

结论

Claude Code 与 Codex CLI 在状态栏上是两种哲学的标本:CC 把状态栏做成一个"反向 hook"——settings.json 里配一条 shell 命令,CC 在每次状态变化时把一大包会话 JSON 喂给它的 stdin,stdout 打印什么就显示什么(支持多行、ANSI 颜色、OSC 8 链接);Codex 则是声明式白名单——config.tomltui.status_line 只接受一个有序的内置 item id 列表(modelgit-branchcontext-remaining 等 26 种),由 TUI 进程内渲染,不存在执行外部命令的入口(社区诉求见 issue #20244)。对 harness 而言:CC 的协议值得直接复用为内部接口(stdin JSON 的字段就是一份现成的"会话状态快照 schema"),而对 Codex 只能自己监听事件流另行渲染。

研究问题

  • CC statusline 的协议(stdin JSON 字段、stdout 约定)与刷新时机是什么?
  • Codex 内置 status_line 有哪些 item,为什么不支持自定义外部命令?
  • harness 如何检测、校验、调试用户的 statusline 配置?

各 Agent 设计与实现

Claude Code

配置入口:用户/项目 settings 的 statusLine 字段,schema 为 { type: 'command', command: string, padding?: number }([一手源码] src_2026-03-31/utils/settings/types.ts:550-557)。线上文档另有 refreshInterval(定时重跑,最小 1 秒)与 hideVimModeIndicator 两个字段([一手文档] claude-code-docs/docs/statusline.md,2026-03-31 源码快照中尚不存在——版本滞后所致)。

执行协议executeStatusLineCommand() 把结构化状态序列化为 JSON 写入子进程 stdin,超时 5 秒,exit 0 时取 stdout(逐行 trim、去空行)作为显示文本([一手源码] src_2026-03-31/utils/hooks.ts:4584-4666)。statusline 被当作一种 hook 对待:受 disableAllHooks 和 workspace trust 双重门禁——未通过信任对话框时直接跳过并给出 statusline skipped · restart to fix 提示(utils/hooks.ts:4594-4601components/StatusLine.tsx)。

stdin JSON 字段buildStatusLineCommandInput,[一手源码] components/StatusLine.tsx:36-127):

session_id / transcript_path / cwd / permission_mode      ← createBaseHookInput (hooks.ts:301-328)
session_name, version
model: { id, display_name }
workspace: { current_dir, project_dir, added_dirs }
output_style: { name }
cost: { total_cost_usd, total_duration_ms, total_api_duration_ms,
        total_lines_added, total_lines_removed }
context_window: { total_input_tokens, total_output_tokens, context_window_size,
                  current_usage, used_percentage, remaining_percentage }
exceeds_200k_tokens
rate_limits: { five_hour?: { used_percentage, resets_at }, seven_day?: {...} }
vim: { mode }            ← 仅 vim mode 开启时
agent: { name } / remote: { session_id } / worktree: { name, path, branch, ... }

刷新时机:事件驱动 + 防抖。触发条件是四个值之一变化——最后一条 assistant 消息 id、permission mode、vim mode、主循环模型(StatusLine.tsx:237-249);变化后 300ms 防抖合并(scheduleUpdateStatusLine.tsx:226-235);新触发会 abort 在途执行(doUpdateabortControllerRef.current?.abort())。文档补充:/compact 完成后也触发,空闲期靠 refreshInterval 兜底([一手文档] statusline.md "How status lines work")。渲染层面用 memo + ref 避免无谓重渲染(StatusLine.tsx:319-324)。

配置生成/statusline 是一个 prompt 型命令,实际派发名为 statusline-setup 的内置子 agent,允许的工具被收窄为 Read(~/**) + Edit(~/.claude/settings.json)([一手源码] commands/statusline.tsx:4-22tools/AgentTool/built-in/statuslineSetup.ts)——"用 agent 写 agent 的配置"是 CC 的惯用模式。

Codex CLI

配置入口config.toml[tui]status_line: Option<Vec<String>>——一个有序 item id 列表;未设置时默认 model-with-reasoning + current-dir;另有 status_line_use_colors(默认 true,按语法主题着色)([一手源码] codex-rs/config/src/types.rs:688-698)。

Item 白名单StatusLineItem 枚举共 26 个变体,kebab-case 序列化,含别名(如 model/model-namestatus/run-statecontext-used/context-usage 兼容旧值)([一手源码] codex-rs/tui/src/bottom_pane/status_line_setup.rs:55-142)。代表性 item:

model-with-reasoning / current-dir / project-name / git-branch
pull-request-number / branch-changes / run-state / permissions / approval-mode
context-remaining / context-used / five-hour-limit / weekly-limit
used-tokens / total-input-tokens / total-output-tokens
thread-id / thread-title / task-progress (update_plan 进度) / fast-mode / raw-output

条件显示:git 类 item 仅在仓库内出现、限额类仅在 API 返回数据后出现(status_line_setup.rs:48-52 注释)。

渲染与缓存:完全在 TUI 进程内渲染,ChatWidget 为 git branch / git summary / project root 维护缓存与 pending 标记([一手源码] codex-rs/tui/src/chatwidget.rs:698-714),无效 item id 只警告一次(chatwidget.rs:499)。/statusline slash command 打开交互式多选配置器(codex-rs/tui/src/slash_command.rs:51,105),写回 config.toml(core/src/config/edit.rs)。

没有自定义命令入口:config schema 中 status_line 仅是字符串数组,整个 tui crate 不存在为状态栏 spawn 外部进程的代码路径([一手源码] 对 codex-rs/tui 全量检索)。社区对"CC 式自定义脚本"的诉求记录在 openai/codex issue #20244([一手文档] 研究简报提供,未本地验证 issue 内容)。

差异矩阵

维度Claude CodeCodex CLI
扩展模型任意外部命令,stdin JSON → stdout内置 item id 白名单,进程内渲染
配置位置settings.json statusLine.commandconfig.toml tui.status_line = [...]
可显示内容无限制(脚本自由发挥)26 种内置 item,条件显隐
刷新机制事件驱动 + 300ms 防抖 + 可选定时器每帧随 TUI 渲染,数据各自缓存
执行安全5s 超时、trust 门禁、disableAllHooks 可禁无外部执行,无安全面
多行/颜色多行 + ANSI + OSC 8 链接单行,主题色
配置辅助/statusline 派发专用子 agent 写脚本/statusline 交互式多选器
失败表现静默隐藏(exit≠0 / 超时 / 空输出)无效 id 警告一次后忽略

最小复现

# CC:最小 statusline 脚本(观察 stdin 全量字段)
cat > ~/.claude/statusline.sh <<'EOF'
#!/bin/bash
input=$(cat)
echo "$input" > /tmp/statusline-last-input.json   # 调试:留存完整 payload
echo "[$(echo "$input" | jq -r .model.display_name)] $(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)%"
EOF
chmod +x ~/.claude/statusline.sh
# settings.json: { "statusLine": { "type": "command", "command": "~/.claude/statusline.sh" } }

# Codex:config.toml
# [tui]
# status_line = ["model-with-reasoning", "git-branch", "context-remaining"]

Harness 接入建议(Yoda 实践)

Yoda roadmap 中的「statusline 检测、校验、调试与管理」可以全部锚定在 CC 的协议上:

  1. 检测:读各层 settings.json 的 statusLine 字段即可发现配置;同时检查 disableAllHooks 与 trust 状态——这是两个最常见的"配了但不显示"根因(hooks.ts:4590-4601)。
  2. 校验:Yoda 可以离线"演练"用户脚本——按 buildStatusLineCommandInput 的字段构造一份 mock JSON 喂 stdin,校验 5 秒内 exit 0 且 stdout 非空;超时/非零退出/空输出三种失败在 CC 里都是静默的,harness 替用户显式报错是真实价值点。
  3. 调试:提供"payload 录制"开关(如上面最小复现里的 tee 到临时文件),让用户看到自己脚本实际收到的字段;CC 自身只在 debug 日志里记一行结果(hooks.ts:4648-4658)。
  4. 管理 Codex 侧:不要试图给 Codex 注入自定义渲染——没有入口。Yoda 作为 GUI harness 本就接管了渲染层,正确做法是订阅 Codex 事件流(token usage、git 状态自取)渲染自己的状态条,把 tui.status_line 仅当作"用户在裸终端里的偏好"来读写。
  5. 统一抽象:CC 的 stdin JSON 字段集(model/workspace/cost/context_window/rate_limits)可直接作为 Yoda 内部"会话状态快照"的 schema 基线,两家 runtime 都向它归一。

失效条件

  • CC 调整 StatusLineCommandInput 字段或防抖/超时参数(300ms/5s 为硬编码,无配置项)——需回归 mock payload
  • CC 源码快照(2026-03-31)落后线上约 2 个月:refreshInterval/hideVimModeIndicator 已仅见于文档,后续字段差异需以文档+实测为准
  • Codex 若响应 #20244 增加自定义命令支持,本章"无外部命令"结论作废
  • Codex StatusLineItem 枚举随版本增删(如 task-progress 是近期新增),白名单清单需随 b89ce9a 之后版本更新

参考资料

  • [一手源码] claude-code-source-code/src_2026-03-31/components/StatusLine.tsx(重建源码,仅作架构描述与短引用)
  • [一手源码] claude-code-source-code/src_2026-03-31/utils/hooks.ts:4584-4666
  • [一手文档] claude-code-docs/docs/statusline.md(字段全表、刷新时机、COLUMNS/LINES 环境变量)
  • [一手源码] codex/codex-rs/config/src/types.rs:688-698codex/codex-rs/tui/src/bottom_pane/status_line_setup.rs
  • 社区:openai/codex issue #20244(自定义 statusline 命令诉求)

On this page