Claude Code statusline 本质上是一个本地命令:Claude Code 把当前会话 JSON 送进 stdin,你的命令把要显示的内容写到 stdout,底部那一行就是这个输出。想快速有一个个人版本,就先用 /statusline;需要可审查、可测试、能被团队复用的行为,再手动配置 statusLine;只有当命令对所有协作者都安全时,才把它放进项目设置。

安全顺序不是先挑样式,而是先定路线、确认命令合同、选择设置作用域,然后再决定显示哪些字段。statusline 可以显示模型、目录、Git 分支、context 用量、cost 估算、部分账号可见的 rate limit 数据,但脚本必须把所有字段都当成“可能缺失”来处理。
| 路线 | 适合场景 | 第一个证明 |
|---|---|---|
/statusline | 想让 Claude Code 快速生成个人初版 | 底部行能出现,并且生成脚本能读懂 |
手动 statusLine | 需要审查脚本、控制兜底和团队约定 | 脚本能在 Claude Code 外用 mock JSON 跑通 |
| 项目设置 | 同一个非敏感行为要在仓库里复用 | 每个人都能安全运行同一命令路径 |
| 第三方 formatter | 样式、主题或复杂布局值得引入依赖 | 代码来源、安装范围和本地执行边界都可接受 |
先弄清 statusline 运行合同
statusline 不是终端主题,也不是一次额外 API 调用。它是 Claude Code 界面里的一条本地命令通道。Claude Code 启动你配置的命令,把当前会话状态作为 JSON 写入 stdin,然后读取 stdout,把那段文本渲染成界面底部的状态行。
这个合同带来三个直接后果。第一,命令在本机执行。它可以调用 git,读取工作区文件,也可以运行你放在 home 目录里的脚本。这很方便,但共享项目设置一旦执行本地 shell 行为,就必须先过信任边界。
第二,脚本要防守式写法。JSON 里可能有 model、workspace、git、cost、context、session、version、output style、vim、agent、worktree、rate limit 等数据,但不同版本、账号和路线不一定都会给。好脚本应该打印 ctx:?、git:- 这样的兜底,而不是因为字段为 null 就报错。
第三,stdout 就是用户看到的产品界面。开发时的调试日志应该去 stderr,真正显示的那一行要短、稳、快。越像一个庞大的仪表盘,越容易慢、乱、没人看。
需要初版时先用 /statusline
个人探索阶段,最省心的做法是在 Claude Code 里直接运行:
text/statusline
给 Claude Code 一个清晰但不过度复杂的说明:
text显示 model、当前目录、git branch、context 百分比和 cost 估算。保持一行,字段缺失时要兜底。
生成后不要马上把它当团队标准。先打开脚本看看它到底执行了什么。你批准的是一个本地命令,不只是一个颜色样式。如果脚本里有绝对路径、网络请求、私有 endpoint 或慢命令,就不适合直接放进仓库。
/statusline 适合快速找感觉:你想知道一行里放哪些信息、如何排版、哪些字段对自己有帮助。等它变成团队行为时,应当回到手动 statusLine,把路径、兜底、信任和性能都写清楚。
需要控制时手动配置 statusLine
手动配置适合可重复交付。设置是一个 command 对象,通常写在 Claude Code settings 文件里:
json{ "statusLine": { "type": "command", "command": "~/.claude/statusline/statusline.js", "refreshInterval": 5 } }
最关键的是 type 和 command。refreshInterval 是可选项,不是默认必需。只有当状态行里有时钟类数据、外部缓存状态,或者确实需要固定刷新时才加。多数工作流里,Claude Code 的事件驱动更新已经足够;刷新太频繁,只会把慢脚本的问题放大。
个人脚本可以放在 ~/.claude/。团队脚本如果要放进仓库,建议放在 .claude/statusline/ 之类的路径,并且像普通代码一样 review。不要把某个人机器上的绝对路径写进共享 .claude/settings.json。
先用 mock JSON 测脚本

下面是一个保守的 Node.js 起点。它只读 stdin,不假设字段一定存在,并把调试错误放到 stderr:
js#!/usr/bin/env node let input = ""; process.stdin.setEncoding("utf8"); process.stdin.on("data", (chunk) => { input += chunk; }); process.stdin.on("end", () => { let data = {}; try { data = input.trim() ? JSON.parse(input) : {}; } catch (error) { console.error(`statusline JSON parse failed: ${error.message}`); } const model = data.model?.display_name || data.model?.id || "model?"; const cwd = data.workspace?.current_dir || data.cwd || ""; const dir = cwd ? cwd.split("/").filter(Boolean).pop() : "workspace?"; const branch = data.git?.branch ? `git:${data.git.branch}` : "git:-"; const context = typeof data.context_window?.percentage === "number" ? `ctx:${Math.round(data.context_window.percentage)}%` : "ctx:?"; const cost = typeof data.cost?.total_cost_usd === "number" ? `$${data.cost.total_cost_usd.toFixed(2)} est` : "$? est"; process.stdout.write(`${model} | ${dir} | ${branch} | ${context} | ${cost}`); });
保存为 ~/.claude/statusline/statusline.js,先在终端里测试:
bashchmod +x ~/.claude/statusline/statusline.js printf '%s' '{ "model": {"display_name": "Claude Sonnet"}, "workspace": {"current_dir": "/Users/me/project"}, "git": {"branch": "main"}, "context_window": {"percentage": 42}, "cost": {"total_cost_usd": 0.18} }' | ~/.claude/statusline/statusline.js
你要看到的是一行干净输出:
textClaude Sonnet | project | git:main | ctx:42% | $0.18 est
如果这个命令在 Claude Code 外部都跑不通,就先修脚本。不要把问题归咎于 Claude Code,也不要急着切换 settings 文件。
字段选择要为工作服务

statusline 的价值是减少切换视线,而不是把所有字段都塞进去。先回答一个实时工作问题:我在哪个项目?用哪个模型?当前 Git 状态是否干净?context 还有多少?本轮 cost 大概到哪里?
| 字段组 | 适合显示 | 注意点 |
|---|---|---|
| Model | 当前模型名或短 id | 名字太长会挤压整行 |
| Workspace | 目录 basename 或 workspace 名 | 不要显示完整绝对路径 |
| Git | 分支、dirty 状态、worktree 信号 | 大仓库里要缓存慢命令 |
| Context window | 百分比或剩余信号 | 字段形态会变,必须兜底 |
| Cost | 会话估算 | 只是估算,不是账单真相 |
| Rate limits | 可见时显示剩余/重置 | 不是所有路线和账号都有 |
| Session/version | 会话、版本、output style | 适合排障,不一定适合日常 |
| Agent/worktree/vim | 模式相关状态 | 只在工作流真的依赖时显示 |
一个可读的一行通常包含四段:身份、位置、状态、风险。例如:
textSonnet | api-docs | main* | ctx:42% | $0.18 est
main* 可以表示分支有改动,ctx 和 cost 是风险信号。如果你并不需要 cost,就删掉;如果 Git 状态检查太慢,就只显示分支。
设置作用域决定能不能共享
Claude Code settings 有多个作用域。statusline 应该放在命令能被安全执行的地方,而不是随手写进最显眼的文件。
| 作用域 | 适合放什么 | 风险 |
|---|---|---|
| User settings | 个人跨项目默认 statusline | 别人的机器没有你的路径 |
| Local project settings | 某台机器的项目覆盖 | 同事复现时容易看不到 |
| Shared project settings | 团队共享的非敏感行为 | 不能含 secrets 和私人路径 |
| Managed settings | 组织策略 | 不适合个人样式实验 |
| 命令行/session 覆盖 | 临时测试 | 不适合写进文档 |
团队模式可以这样写:
json{ "statusLine": { "type": "command", "command": "./.claude/statusline/statusline.js" } }
但是只有脚本被 review、没有 secrets、不依赖私人目录、失败时能降级输出时,才适合提交。共享 settings 里描述行为,本地 env 或 local-only 文件处理机器差异。
保持更新足够快
statusline 命令会被反复调用。它不应该每次都跑一串昂贵逻辑。如果你的脚本每次都执行 git status、读大型元数据、访问网络,再拼一个很长的摘要,Claude Code 体验会变差。
三条规则足够实用:
- 优先使用 Claude Code 已经传进 JSON 的字段。
- 对大仓库的 Git 状态、外部检查和耗时计算做缓存。
- 只有确实需要定时刷新时才设置
refreshInterval。
可以直接测脚本耗时:
bashtime printf '{}' | ~/.claude/statusline/statusline.js
如果终端直接运行都慢,先缩短脚本。如果终端运行很快,但 Claude Code 里卡住,再看 trust、hooks、路径和刷新触发。
Windows 和终端显示要单独验证
Windows 上最常见的问题不是字段,而是 shell 和 path。你用 Git Bash、PowerShell、WSL 还是 Node,都要用 Claude Code 实际会调用的同一条命令测试。
跨平台脚本通常比复杂 shell one-liner 更稳。Node 和 Python 更容易统一路径和 JSON 解析。颜色、powerline 字符、OSC 8 链接都应该最后加。先让纯文本版本稳定工作,再考虑样式。
如果 statusline 在 macOS 正常、Windows 空白,先检查解释器路径、可执行权限、引号、换行和当前 cwd。不要先怀疑 Claude Code 字段。
第三方 formatter 什么时候值得用
第三方工具适合你确实需要主题、powerline 布局、更丰富的字段格式或团队统一视觉。它不是 statusline 的事实来源,只是本地命令的一个实现。
使用前至少检查这些点:
| 检查项 | 为什么重要 |
|---|---|
| 代码来源和维护者可接受 | 它会在本地执行 |
| 安装范围清楚 | 全局工具会影响多个项目 |
| 读取官方 stdin JSON | 私有 usage endpoint 容易失效 |
| 字段缺失能兜底 | 你的账号不一定暴露全部字段 |
| 速度足够快 | statusline 会重复运行 |
| 容易关闭 | 排障时不能被工具绑架 |
如果你解释不清它执行了什么,就先保留自己的小脚本。
空白、跳过、卡住时按这个顺序排

按证明顺序排,不要乱改:
| 症状 | 快速证明 | 修复方向 |
|---|---|---|
| 完全不显示 | 直接运行命令 | 修路径、解释器、可执行权限 |
| 外部可跑,Claude Code 里不行 | 喂 mock JSON,看 trust 提示 | 批准可信项目命令或移到 user scope |
| 输出空白 | 检查 stdout/stderr | 最终状态必须写 stdout |
出现 undefined 或崩溃 | 用缺字段 JSON 测 | 给 optional 字段加兜底 |
| 输出陈旧 | 移除慢命令,看刷新需求 | 缓存或设置有边界的 refreshInterval |
| 频繁 skipped | 用 debug 输出看命令失败 | 修 trust、hooks 或命令错误 |
| macOS 正常 Windows 不行 | 用同一 shell 和路径测 | 显式解释器,避免平台路径 |
| 颜色/链接错乱 | 退回纯文本 | 最后再加终端特性 |
如果你启用了 disableAllHooks,把它也纳入排障面。它不是“随便开关”,可能影响你以为会运行的 hook 类行为。
相关 Claude Code 配置路径
如果你刚开始定制 Claude Code,可以按这个顺序补齐周边:
- 还没安装 CLI,先看 Claude Code 安装指南。
- 不清楚 API key、订阅、gateway 谁在生效,看 Claude Code API 配置指南。
- 担心 API key 和订阅计费混淆,看 Claude Code API key vs subscription billing。
- statusline 稳定后,再看 Claude Code memory。
- 想把工作流固化成可复用单元,再看 Claude Code best skills。
常见问题
statusline 和 statusLine 是一回事吗?
不是同一个写法。statusline 是常见说法,/statusline 是 slash command,statusLine 是 settings 里的 JSON key。写配置时必须用精确大小写。
statusline 会消耗 API token 吗?
statusline 命令本身在本地运行,不会额外消耗 API token。它可以显示 Claude Code 提供的 cost 或 context 数据,但打印这些数据不是一次模型请求。
能不能显示 rate limit?
可以,但前提是当前路线和账号把相关数据暴露给 statusline 输入。脚本必须处理 rate_limits 不存在的情况,不要把它写成必有字段。
statusline 脚本可以提交到项目吗?
只有在对所有协作者都安全时才提交。共享脚本要快、无 secrets、无私人路径、能降级、容易关闭,并且像普通代码一样被 review。
为什么会显示 undefined?
脚本假设某个字段一定存在。用缺字段 mock JSON 测一次,然后给每个 optional 字段加 fallback。正确降级应该是 ctx:? 或 git:-,不是抛异常。
第一版 statusline 应该显示什么?
先显示模型、工作目录 basename、Git 分支、context 百分比和 cost 估算。等这些稳定后,再加颜色、powerline、rate limit 或复杂 formatter。