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.toml 的 tui.status_line 只接受一个有序的内置 item id 列表(model、git-branch、context-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-4601、components/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 防抖合并(scheduleUpdate,StatusLine.tsx:226-235);新触发会 abort 在途执行(doUpdate 中 abortControllerRef.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-22、tools/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-name、status/run-state、context-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 Code | Codex CLI |
|---|---|---|
| 扩展模型 | 任意外部命令,stdin JSON → stdout | 内置 item id 白名单,进程内渲染 |
| 配置位置 | settings.json statusLine.command | config.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 的协议上:
- 检测:读各层 settings.json 的
statusLine字段即可发现配置;同时检查disableAllHooks与 trust 状态——这是两个最常见的"配了但不显示"根因(hooks.ts:4590-4601)。 - 校验:Yoda 可以离线"演练"用户脚本——按
buildStatusLineCommandInput的字段构造一份 mock JSON 喂 stdin,校验 5 秒内 exit 0 且 stdout 非空;超时/非零退出/空输出三种失败在 CC 里都是静默的,harness 替用户显式报错是真实价值点。 - 调试:提供"payload 录制"开关(如上面最小复现里的 tee 到临时文件),让用户看到自己脚本实际收到的字段;CC 自身只在 debug 日志里记一行结果(
hooks.ts:4648-4658)。 - 管理 Codex 侧:不要试图给 Codex 注入自定义渲染——没有入口。Yoda 作为 GUI harness 本就接管了渲染层,正确做法是订阅 Codex 事件流(token usage、git 状态自取)渲染自己的状态条,把
tui.status_line仅当作"用户在裸终端里的偏好"来读写。 - 统一抽象: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-698、codex/codex-rs/tui/src/bottom_pane/status_line_setup.rs - 社区:openai/codex issue #20244(自定义 statusline 命令诉求)