Claude Code 状态栏完全指南:告别盲飞,实时掌握上下文、费用与速率限制
Claude Code 状态栏可视化
使用 Claude Code 的开发者大概都经历过这种崩溃:聊了大半个小时,回复质量突然断崖式下降,仔细一查才发现上下文窗口已经快被撑满;或者任务跑到一半突然被限流,这才意识到 5 小时额度早就用光了。
更难受的是,Claude Code 默认并不会主动告诉你这些信息。你不知道它此时此刻在用什么模型、上下文还剩多少、这轮对话花了多少钱、现在跑在哪个 Git 分支上。终端里一片空白,全程如同“盲飞”。
这篇文章就来补上这块。不只是教你“怎么配一个好看的状态栏”,而是把整个机制拆开——它怎么拿到数据的、数据里有什么、你能拿这些数据做什么。
本文接近 11000 字,建议收藏,通过本文你将搞懂:
- Status Line 的底层机制:Claude Code 怎么把数据喂给你的脚本
- 两种配置方式:零门槛的自然语言配置 vs 全掌控的手动脚本
- 从零手搓一个实用状态栏的完整过程
- 社区现成方案对比:什么时候该自己写、什么时候该用插件
Status Line 到底是什么
一句话讲透本质:Status Line 是一个可编程的底部状态栏。
你在 settings.json 里配一个脚本路径,Claude Code 启动后会定期把当前会话的 JSON 数据通过 stdin 管道喂给这个脚本。脚本解析 JSON、格式化输出,Claude Code 再把 stdout 的内容渲染在终端底部。
就这么简单。没有黑魔法,就是 Unix 管道思维——Claude Code 是生产者,你的脚本是消费者,stdin/stdout 是中间的管道。
这意味着两件事:
- 你完全掌控显示什么:模型名、上下文百分比、Git 分支、费用、速率限制额度……JSON 里有什么你就能显示什么
- 你完全掌控怎么显示:颜色、进度条、多行布局、可点击链接,只要终端支持,你就能做
两种配置方式
配置 status line 有两条路,适合不同的人。
方式一:/statusline 命令(零门槛)
直接在 Claude Code 里输入 /statusline,然后用自然语言描述你想显示什么:
/statusline 帮我做一个状态栏:左边显示模型名和 Git 分支,中间显示上下文使用百分比和进度条,右边显示费用
Claude Code 会自动帮你生成脚本文件(通常在 ~/.claude/ 目录下),并自动更新 settings.json。不满意?继续用自然语言让它改就行。

Claude Code 里输入 /statusline 做一个状态栏
不到一分钟的时间,就完成了。来,验证一下效果如下。

状态栏显示效果,三个区域都正常显示
完美!已经生效了。三个区域都正常显示:
- 左侧 glm-5.1 master — 模型名 + Git 分支
- 中间 ctx [#######————-] 37% — 上下文进度条和百分比
- 右侧 in:3746 out:230 — 输入/输出 token 数
非常适合不想折腾脚本、只想快速上手的人。
方式二:手动写脚本(全掌控)
在 ~/.claude/settings.json 中添加 statusLine 配置:
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 2,
"refreshInterval": 5
}
}
几个关键参数:
| 参数 | 作用 | 默认值 |
|---|---|---|
command |
脚本路径,也支持内联 shell 命令 | 无,必填 |
padding |
状态栏两侧额外留白字符数 | 0 |
refreshInterval |
定时刷新间隔(秒),不设则只在事件触发时更新 | 不定时 |
适合谁:想深度定制、对显示效果有要求的人。
许多人习惯使用手动脚本方式,因为需要精确控制颜色和布局。但说实话,如果你只是想显示个模型名和上下文百分比,方式一完全够用。
底层机制:它到底怎么工作的
搞清楚数据怎么流动的,你才能判断显示的信息靠不靠谱。
数据流
整个过程分三步:
- Claude Code 收集数据:每次 assistant 回复后(或权限模式变更、vim 模式切换时),Claude Code 把当前会话状态序列化成 JSON
- 通过 stdin 喂给脚本:这个 JSON 被管道输入到你配置的脚本
- 脚本输出到 stdout:你的脚本解析 JSON、格式化,打印结果。Claude Code 拿到 stdout 内容渲染到终端底部
有个细节:更新频率有 300 ms 的防抖。如果你连续发了多条消息,脚本不会疯狂执行,而是等操作稳定下来后统一跑一次。如果上一次脚本还没执行完,新的更新会直接取消正在跑的那次。
JSON 里有什么
Claude Code 推送的 JSON 数据非常丰富,挑几个最实用的字段讲:
模型与上下文:
| 字段 | 含义 |
|---|---|
model.display_name |
当前模型名称,如 “Opus”、“Sonnet” |
context_window.used_percentage |
上下文窗口已使用百分比 |
context_window.remaining_percentage |
上下文窗口剩余百分比 |
context_window.context_window_size |
上下文窗口大小(默认 200k,扩展模型 1M) |
费用与时间:
| 字段 | 含义 |
|---|---|
cost.total_cost_usd |
当前会话预估总费用(美元) |
cost.total_duration_ms |
会话总时长(毫秒) |
cost.total_api_duration_ms |
等待 API 响应的总时长 |
速率限制:
| 字段 | 含义 |
|---|---|
rate_limits.five_hour.used_percentage |
5 小时滚动窗口用量百分比 |
rate_limits.seven_day.used_percentage |
7 天滚动窗口用量百分比 |
工作区信息:
| 字段 | 含义 |
|---|---|
workspace.current_dir |
当前工作目录 |
workspace.project_dir |
项目启动目录 |
有一个高频盲区:rate_limits 字段只有订阅用户(Pro/Max)才能拿到。走 API Key 的用户没有速率限制概念,Claude Code 不会推送这个数据。所以如果你发现状态栏上用量信息始终不出现,先确认你的计费方式。
另外,context_window.used_percentage 和 context_window.remaining_percentage 在会话刚启动、还没发过第一条 API 请求时可能是 null。写脚本时一定要加 fallback,不然整个状态栏就空了。
实战:手搓一个能用的状态栏
理论讲完了,来写一个实际能跑的脚本。目标:显示模型名、Git 分支、上下文进度条(带颜色变化)、token 用量。
创建文件 ~/.claude/statusline.sh:
#!/bin/bash
input=$(cat)
# 解析 JSON
model=$(printf '%s' "$input" | jq -r '.model.display_name // "Unknown"')
used=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // 0')
used_i=$(printf '%.0f' "$used" 2>/dev/null || printf '0')
left=$((100 - used_i))
in_tok=$(printf '%s' "$input" | jq -r '.context_window.current_usage.input_tokens // 0')
out_tok=$(printf '%s' "$input" | jq -r '.context_window.current_usage.output_tokens // 0')
cwd=$(printf '%s' "$input" | jq -r '.workspace.current_dir // empty')
# Git 分支
branch=""
if [ -n "$cwd" ]; then
branch=$(git --no-optional-locks -C "$cwd" rev-parse --abbrev-ref HEAD 2>/dev/null)
fi
# 进度条(10 格)
fill=$((used_i / 10))
[ "$fill" -gt 10 ] && fill=10
[ "$fill" -lt 0 ] && fill=0
empty=$((10 - fill))
bar=$(printf '%*s' "$fill" '' | tr ' ' '█')
bar="$bar$(printf '%*s' "$empty" '' | tr ' ' '░')"
# 颜色:<50% 绿色,50-79% 黄色,80%+ 红色
if [ "$used_i" -ge 80 ]; then
color='31' # 红色
elif [ "$used_i" -ge 50 ]; then
color='33' # 黄色
else
color='32' # 绿色
fi
# 格式化 token 用量(超过 1k 用 k 单位)
format_tok() {
local v=$1
if [ "$v" -ge 1000 ] 2>/dev/null; then
printf '%.1fk' "$(echo "$v / 1000" | bc -l 2>/dev/null || echo "$v")"
else
printf '%d' "$v"
fi
}
in_str=$(format_tok "$in_tok")
out_str=$(format_tok "$out_tok")
# 组装输出
out="\033[1;36m${model}\033[0m"
[ -n "$branch" ] && out="${out} \033[2m·\033[0m \033[35m${branch}\033[0m"
out="${out} \033[2m·\033[0m \033[${color}mctx ${used_i}% ${bar}\033[0m \033[32m${left}%\033[0m"
out="${out} \033[2m·\033[0m \033[36m↑${in_str}\033[0m \033[33m↓${out_str}\033[0m"
printf '%b' "$out"
给脚本加上执行权限:
chmod +x ~/.claude/statusline.sh
然后在 ~/.claude/settings.json 里加上配置:
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 1
}
}
重启 Claude Code,你就能在底部看到状态栏了。效果大概是这样:
Opus · main · ctx 35% ███░░░░░░░ 65% · ↑15.2k ↓4.5k
几个设计选择解释一下:
- 颜色分级:上下文 50% 以下绿色意味着安全,50-79% 黄色意味着该注意了,80% 以上红色意味着该
/compact了。这不是装饰,是信号 - 进度条用
█░字符:10 格宽度刚好,既直观又不占太多空间 git --no-optional-locks:这个参数很重要,不加的话在大仓库里git status会触发锁竞争,拖慢整个状态栏刷新- 所有
jq解析都加了// fallback:防止 null 值导致整行崩溃
来看看我们现在的效果是什么样的,还不错吧!

手搓一个能用的状态栏效果
进阶玩法
基础版跑通之后,status line 还能做更多事情。
多行显示
前面写的脚本里每个 echo 或 printf 语句都会生成一行。所以两行状态栏只需要两次输出:
# 第一行:模型 + 目录 + Git
printf '%b' "$line1\n"
# 第二行:上下文进度条 + token 用量
printf '%b' "$line2"
效果:
glm-5.1 · main
ctx ██████░░░░ 58% 42% · ↑8.2k ↓1.7k
但有个踩坑预警:多行 + ANSI 颜色码的组合在部分终端里容易渲染错乱。如果出现乱码,先试去掉颜色看是否正常,再逐步加回来定位问题。
可点击链接
如果你的终端支持 OSC 8 协议(iTerm2、Kitty、WezTerm 都支持),可以让状态栏上的文本变成可点击的超链接,直接跳转到 GitHub 仓库。
比如把分支名变成可点击的链接,点击后直接在浏览器打开该分支页面:
# 把 Git remote URL 转成 HTTPS 格式
remote=$(git -C "$cwd" remote get-url origin 2>/dev/null | sed 's/git@github.com:/https:\/\/github.com\//')
repo=$(printf '%s' "$remote" | sed 's/\.git$//')
# OSC 8 超链接格式
printf '\033]8;;%s\033\\%s\033]8;;\033\\' "$repo" "$repo"
效果类似(分支名可点击跳转):
glm-5.1 · main · ctx 26% ██░░░░░░░░ 74% · ↑329 ↓30
macOS 上按住 Cmd 点击,Linux/Windows 上按住 Ctrl 点击就能在浏览器里打开。
Terminal.app 不支持 OSC 8,这个功能跟它无缘。
慢操作缓存
状态栏脚本执行频率不低——每次 assistant 回复后都会跑一遍。如果你的脚本里调用了 git status、git diff 这类命令,在大仓库里可能会拖慢刷新。
官方推荐的缓存策略是用 session_id 做 key,把结果缓存到临时文件:
session_id=$(printf '%s' "$input" | jq -r '.session_id')
cache_file="/tmp/claude-statusline-git-${session_id}"
# 缓存超过 5 秒才刷新
if [ ! -f "$cache_file" ] || [ $(($(date +%s) - $(stat -f %m "$cache_file" 2>/dev/null || echo 0))) -gt 5 ]; then
git --no-optional-locks -C "$cwd" status --porcelain 2>/dev/null > "$cache_file"
fi
关键细节:缓存 key 必须用 session_id,不能用 $$(进程 ID)。因为状态栏每次触发都会起新进程,$$ 每次都不同,缓存等于白做。session_id 在整个会话生命周期内是稳定的,而且不同会话之间不会冲突。
不想自己写?现成方案推荐
如果你觉得写脚本太折腾,社区已经有不少现成方案。
Claude HUD
这是之前专门写文章介绍过的方案。它本质上就是帮你把 status line 脚本写好了,额外还会去读本地的 transcript 文件(记录了工具调用、子 Agent 活动等),把两部分数据拼在一起显示。
三条命令装完:
/plugin marketplace add jarrodwatts/claude-hud
/plugin install claude-hud
/claude-hud:setup
ccstatusline
GitHub 开源项目,特点是模块化设计 + 多主题支持。支持 Powerline 风格的分隔符,视觉上更接近专业终端 prompt 的效果。
一条命令安装:
npx ccstatusline@latest
适合对颜值有要求的用户。
starship-claude
如果你已经在用 Starship 管理 shell prompt,这个方案可以让你把 Starship 的配置直接搬到 Claude Code 的 status line 里,保持视觉风格统一。
怎么选?
| 方案 | 适合谁 | 核心优势 |
|---|---|---|
| 手写脚本 | 想完全掌控的人 | 零依赖,想显示什么就显示什么 |
| Claude HUD | 想要开箱即用 + 子 Agent 追踪的人 | 安装简单,功能最全 |
| ccstatusline | 对颜值有要求的人 | Powerline 主题,视觉效果好 |
| starship-claude | Starship 用户 | 和 shell prompt 风格统一 |
目前很多开发者采用手写脚本与 Claude HUD 并行对比的方式,两者都跑了一段时间。说实话,对于大多数开发者来说,直接用 /statusline 命令让 Claude Code 帮你生成就够了。别把 TUI 搞得太复杂,反而失去了轻量和高效的初衷。
踩坑与排查
把实际遇到的坑和排查思路整理一下,帮你少走弯路。
状态栏不显示
按这个顺序排查:
- 脚本有没有执行权限:
chmod +x ~/.claude/statusline.sh - 输出是 stdout 不是 stderr:你的脚本必须把结果打印到 stdout,
echo "debug" >&2这种写 stderr 的不会被渲染 - 手动测试能不能跑:用前面给的 mock JSON 命令测一遍
- 工作区信任:status line 需要 workspace trust。如果你还没接受信任弹窗,状态栏会被跳过,你会看到 “statusline skipped · restart to fix” 的提示。重启 Claude Code 并接受信任即可
disableAllHooks配置:如果你在 settings.json 里设了"disableAllHooks": true,status line 也会被一起禁掉
字段显示 -- 或空值
这大概率是 JSON 里的 null 值导致的。在会话刚启动、还没发过第一条 API 请求时,很多字段都是 null。
解决方案:所有 jq 解析都加 fallback,比如 jq -r '.context_window.used_percentage // 0'。// 0 就是“如果是 null 就用 0”。
脚本修改后不生效
status line 的脚本变更不是热加载的。你改完脚本后,需要触发一次 Claude Code 的交互(随便发条消息),新脚本才会被加载。如果还是不生效,重启 Claude Code 最直接。
写在最后
回顾一下这篇文章的核心脉络:
Status Line 的本质就一句话——Claude Code 通过 stdin 把 JSON 喂给你,你通过 stdout 把格式化后的文本还给 Claude Code。理解了这个管道模型,剩下的就是你想显示什么、怎么显示的问题。
配置上两条路:零门槛的 /statusline 命令适合大多数人,一句话描述需求就能生成脚本;手动写脚本适合有定制需求的开发者,颜色、进度条、多行布局都可以精确控制。
实战部分带你从零搓了一个状态栏,覆盖了日常最关心的四类信息:模型名、Git 分支、上下文用量(带颜色分级)、token 用量。进度条的颜色变化不是装饰——绿色安全、黄色注意、红色该 /compact 了,这是信号。
进阶部分讲了多行显示、可点击链接、慢操作缓存。其中缓存那个细节值得再强调一遍:用 session_id 做缓存 key,不要用 $$。因为状态栏每次触发都是新进程,$$ 每次都变,缓存白做。
不想自己折腾的话,Claude HUD、ccstatusline、starship-claude 三个社区方案各有侧重,按需选择。
最后回到那个痛点:盲飞的时代该结束了。上下文快满、额度快用完、模型不对——这些信息不应该是等你踩坑了才发现的事后教训,而应该是终端底部一行随时可见的视觉信号。
花 5 分钟配一个,大概率会跟很多人一样回头纳闷:怎么没有早点装。