为什么要折腾状态行?

如果你用过 Claude Code,应该注意到终端底部有一条灰色栏——那就是状态行(Status Line)。默认情况下它只显示模型名称和一些基本信息,但这条栏其实是一个完全可编程的信息面板。

你可以让它显示:

  • 上下文窗口用了多少(百分比 + 进度条)
  • 当前会话花了多少钱
  • Git 分支和文件修改状态
  • 会话运行了多久
  • 甚至任意自定义信息

这些数据是实时刷新的,每次交互后自动更新。对于重度用户来说,把关键信息放在眼前比频繁敲命令查状态要高效得多。

配置方式:两条路

方案一:用 /statusline 命令

这是最简单的方式。直接在对话中输入:

1
/statusline 显示模型名称、上下文使用百分比和进度条

Claude Code 会自动在 ~/.claude/ 目录下生成脚本文件并更新配置。你不需要手写任何代码。

方案二:手动配置

手动配置的核心是在 ~/.claude/settings.json 中添加 statusLine 字段:

1
2
3
4
5
6
7
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 2
}
}

关键参数:

  • command:可执行脚本的路径,或内联 shell 命令
  • padding:内容缩进(字符数),默认 0
  • refreshInterval:除了事件驱动更新外,每隔 N 秒强制刷新一次。最小 1 秒。当你显示时钟或后台子代理改变了 git 状态时有用
  • hideVimModeIndicator:如果你自己在状态行里渲染了 vim 模式指示器,设为 true 可以避免重复显示

command 字段也可以直接写内联命令,不需要单独创建脚本文件。例如:

1
2
3
4
5
6
{
"statusLine": {
"type": "command",
"command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'"
}
}

数据从哪里来?

Claude Code 通过标准输入(stdin)向你的脚本发送 JSON 格式的会话数据。脚本读取 JSON,提取所需字段,将结果打印到标准输出(stdout),Claude Code 就会显示这些内容。

数据量很丰富,核心字段分类如下:

模型与工作区

字段 说明
model.display_name 模型显示名称,如 “Opus”、”Sonnet”
workspace.current_dir 当前工作目录
workspace.project_dir 启动 Claude Code 的原始项目目录(会话中可能 cd 过)
workspace.git_worktree Git worktree 名称(如果当前目录在 worktree 内)
session_name 通过 --name/rename 设置的自定义会话名

上下文窗口

字段 说明
context_window.total_input_tokens 当前上下文中的输入 token 数
context_window.total_output_tokens 当前输出 token 数
context_window.context_window_size 最大上下文窗口大小,默认 200K
context_window.used_percentage 已使用百分比(预计算)
context_window.current_usage 按类别细分的 token 使用详情(输入、输出、缓存写入、缓存读取)

成本与耗时

字段 说明
cost.total_cost_usd 预估会话总费用(美元)
cost.total_duration_ms 会话总挂钟时间
cost.total_api_duration_ms 等待 API 响应的总时间
cost.total_lines_added 新增代码行数
cost.total_lines_removed 删除代码行数

速率限制(仅 Pro/Max 订阅者)

字段 说明
rate_limits.five_hour.used_percentage 5 小时滚动窗口中消耗的百分比
rate_limits.seven_day.used_percentage 7 天周期中消耗的百分比

其他

字段 说明
effort.level 当前推理工作量等级(low/medium/high/xhigh/max)
thinking.enabled 是否启用了扩展思考
vim.mode Vim 模式下的当前模式(NORMAL/INSERT/VISUAL)
agent.name 子代理名称(如果通过 --agent 运行)
worktree.name/branch/path Worktree 相关信息(仅 --worktree 会话中出现)

需要注意的 null 值

第一次 API 响应之前,context_window.used_percentagecurrent_usage 均为 null。/compact 之后也会暂时清空。脚本中建议使用 // 0or 0 做备选处理。

实用脚本示例

上下文窗口进度条

这是最实用的配置之一——实时掌握上下文用量,避免在不知道的情况下撑爆窗口。

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)

BAR_WIDTH=10
FILLED=$((PCT * BAR_WIDTH / 100))
EMPTY=$((BAR_WIDTH - FILLED))
BAR=""
[ "$FILLED" -gt 0 ] && printf -v FILL "%${FILLED}s" && BAR="${FILL// /▓}"
[ "$EMPTY" -gt 0 ] && printf -v PAD "%${EMPTY}s" && BAR="${BAR}${PAD// /░}"

echo "[$MODEL] $BAR $PCT%"

效果:[Opus] ▓▓▓▓▓▓░░░░ 60%

Git 状态 + 颜色编码

在多个分支间切换时,一眼看到当前分支和文件变更状态能避免很多误操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')

GREEN='\033[32m'; YELLOW='\033[33m'; RESET='\033[0m'

if git rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git branch --show-current 2>/dev/null)
STAGED=$(git diff --cached --numstat 2>/dev/null | wc -l | tr -d ' ')
MODIFIED=$(git diff --numstat 2>/dev/null | wc -l | tr -d ' ')

GIT_STATUS=""
[ "$STAGED" -gt 0 ] && GIT_STATUS="${GREEN}+${STAGED}${RESET}"
[ "$MODIFIED" -gt 0 ] && GIT_STATUS="${GIT_STATUS}${YELLOW}~${MODIFIED}${RESET}"

echo -e "[$MODEL] 📁 ${DIR##*/} | 🌿 $BRANCH $GIT_STATUS"
else
echo "[$MODEL] 📁 ${DIR##*/}"
fi

成本与时长追踪

对 API 敏感的人来说,实时看到花了多少钱有助于控制使用节奏。

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')

COST_FMT=$(printf '$%.2f' "$COST")
DURATION_SEC=$((DURATION_MS / 1000))
MINS=$((DURATION_SEC / 60))
SECS=$((DURATION_SEC % 60))

echo "[$MODEL] 💰 $COST_FMT | ⏱️ ${MINS}m ${SECS}s"

多行组合

以上功能可以组合成多行状态行,第一行显示模型和 git 信息,第二行显示进度条、成本和时长。每个 echo 就是一行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')

CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; RESET='\033[0m'

# 进度条颜色:90%+ 红色,70-89% 黄色,70% 以下绿色
if [ "$PCT" -ge 90 ]; then BAR_COLOR="$RED"
elif [ "$PCT" -ge 70 ]; then BAR_COLOR="$YELLOW"
else BAR_COLOR="$GREEN"; fi

FILLED=$((PCT / 10)); EMPTY=$((10 - FILLED))
printf -v FILL "%${FILLED}s"; printf -v PAD "%${EMPTY}s"
BAR="${FILL// /█}${PAD// /░}"

MINS=$((DURATION_MS / 60000)); SECS=$(((DURATION_MS % 60000) / 1000))

BRANCH=""
git rev-parse --git-dir > /dev/null 2>&1 && BRANCH=" | 🌿 $(git branch --show-current 2>/dev/null)"

echo -e "${CYAN}[$MODEL]${RESET} 📁 ${DIR##*/}$BRANCH"
COST_FMT=$(printf '$%.2f' "$COST")
echo -e "${BAR_COLOR}${BAR}${RESET} ${PCT}% | ${YELLOW}${COST_FMT}${RESET} | ⏱️ ${MINS}m ${SECS}s"

Windows 上怎么配

在 Windows 上,Claude Code 优先通过 Git Bash 运行状态行命令。如果没有 Git Bash,则走 PowerShell。推荐的配置方式是通过 powershell 调用脚本:

1
2
3
4
5
6
{
"statusLine": {
"type": "command",
"command": "powershell -NoProfile -File C:/Users/username/.claude/statusline.ps1"
}
}

PowerShell 脚本示例:

1
2
3
4
$input_json = $input | Out-String | ConvertFrom-Json
$model = $input_json.model.display_name
$used = $input_json.context_window.used_percentage
echo "$model ctx: $used%"

性能优化:缓存慢操作

状态行脚本在活跃会话中会频繁运行。git statusgit diff 在大仓库中可能很慢。解决方案是缓存并设置过期时间:

1
2
3
4
5
6
7
CACHE_FILE="/tmp/statusline-git-cache-$SESSION_ID"
CACHE_MAX_AGE=5 # 5 秒内不重复执行

if cache_is_stale; then
# 执行 git 命令,写入缓存
fi
# 从缓存读取

缓存文件名要用 session_id 区分,避免并发会话互相干扰。脚本每次调用时 PID 都会变,所以不能用 $$ 做缓存 key。

注意事项

状态行不消耗 API Token。 它完全在本地运行,不用担心额外的费用。

更新机制。 状态行在每条新助手消息后、/compact 完成后、权限模式变更或 vim 模式切换时触发。更新有 300ms 的防抖。如果脚本正在运行时又触发了新更新,正在运行的进程会被取消。

调试技巧。 可以用模拟输入独立测试脚本,不用进入 Claude Code 会话:

1
echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/home/user/project"},"context_window":{"used_percentage":25},"session_id":"test"}' | ./statusline.sh

状态行不出现? 检查脚本是否有执行权限、是否输出到了 stderr 而非 stdout、disableAllHooks 是否被设为 true。运行 claude --debug 可以查看状态行调用的退出码和 stderr 输出。

社区资源

如果不想自己写脚本,社区有现成的预构建配置:

我的建议

如果你刚开始用 Claude Code,推荐从 /statusline 命令开始,用自然语言描述你想要的内容让模型帮你生成。用熟了之后再手动调整脚本,把真正关心的信息组合到一起。

我个人觉得最有价值的是上下文进度条 + Git 分支 + 成本这三个信息。上下文进度条让你在开发时对”还能聊多久”心里有数,Git 分支避免在错误的分支上操作,成本追踪则帮你控制预算。三个信息组合成两行状态行,既不占空间又覆盖了核心需求。