Skip to content

Status Line:自定义底部状态栏

Status Line 是 Claude Code 底部可以完全自定义的信息栏。它运行你配置的任何 shell 脚本,把 JSON 会话数据传入脚本,把脚本输出内容显示出来。

常见用途:

  • 实时监控上下文窗口使用量(避免突然被压缩)
  • 追踪会话费用
  • 多会话并行时显示当前会话信息
  • 始终显示 git 分支和状态

快速上手

方法一(推荐):用 /statusline 命令自动生成

直接描述你想显示什么,Claude Code 会自动生成脚本文件并更新 settings:

text
/statusline show model name and context percentage with a progress bar
/statusline 显示模型名、目录、git 分支和上下文进度条

方法二:手动配置

~/.claude/settings.json(或项目设置)中添加:

json
{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh",
    "padding": 2
  }
}

或者直接内联命令(用 jq 解析 JSON):

json
{
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'"
  }
}

删除 Status Line:运行 /statusline delete(或 clear/remove),或手动删除 settings.json 里的 statusLine 字段。


工作原理

Claude Code 运行你的脚本,通过 stdin 传入 JSON 会话数据,显示脚本打印到 stdout 的内容。

  • 更新时机:每次 Claude 回复后、权限模式变更时、vim 模式切换时(有 300ms 防抖)
  • 多行输出:每行 echo 对应一行显示
  • 颜色:支持 ANSI 转义码
  • 链接:支持 OSC 8 转义序列(可点击链接,需终端支持)
  • Status Line 在本地运行,不消耗 API token

可用数据字段

脚本通过 stdin 接收的 JSON:

字段说明
model.id, model.display_name当前模型 ID 和显示名称
workspace.current_dir当前工作目录(推荐用此字段)
workspace.project_dirClaude Code 启动时的目录(可能与 cwd 不同)
cwd当前工作目录(同 workspace.current_dir
cost.total_cost_usd会话总费用(美元)
cost.total_duration_ms会话总时长(毫秒)
cost.total_api_duration_ms等待 API 响应的总时长(毫秒)
cost.total_lines_added/removed代码增删行数
context_window.used_percentage上下文窗口使用百分比(预计算好的)
context_window.remaining_percentage剩余百分比
context_window.context_window_size最大上下文大小(token 数,默认 200000,1M 上下文时为 1000000)
context_window.total_input_tokens会话累计输入 token
context_window.total_output_tokens会话累计输出 token
context_window.current_usage最近一次 API 调用的 token 明细(见下方)
exceeds_200k_tokens是否超过 20 万 token(固定阈值)
rate_limits.five_hour.used_percentage5 小时限额使用百分比(0-100)
rate_limits.seven_day.used_percentage7 天限额使用百分比(0-100)
rate_limits.five_hour.resets_at5 小时窗口重置时间(Unix 秒)
session_id会话唯一标识
transcript_path对话记录文件路径
versionClaude Code 版本
output_style.name当前输出风格名称
vim.modeVim 模式(NORMAL/INSERT,仅启用 vim 模式时存在)
agent.nameAgent 名称(使用 --agent 时存在)
worktree.name/path/branchWorktree 信息(worktree 会话时存在)

current_usage 字段说明

json
{
  "input_tokens": 8500,
  "output_tokens": 1200,
  "cache_creation_input_tokens": 5000,
  "cache_read_input_tokens": 2000
}

used_percentage 只基于输入 token 计算:input_tokens + cache_creation_input_tokens + cache_read_input_tokens,不含 output_tokens。


实用示例

以下示例保存为脚本后需要 chmod +x 赋权,再在 settings.json 中配置路径。

上下文进度条(Bash)

bash
#!/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%"

Git 状态 + 颜色(Python)

python
#!/usr/bin/env python3
import json, sys, subprocess, os

data = json.load(sys.stdin)
model = data['model']['display_name']
directory = os.path.basename(data['workspace']['current_dir'])

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

try:
    subprocess.check_output(['git', 'rev-parse', '--git-dir'], stderr=subprocess.DEVNULL)
    branch = subprocess.check_output(['git', 'branch', '--show-current'], text=True).strip()
    staged_output = subprocess.check_output(['git', 'diff', '--cached', '--numstat'], text=True).strip()
    modified_output = subprocess.check_output(['git', 'diff', '--numstat'], text=True).strip()
    staged = len(staged_output.split('\n')) if staged_output else 0
    modified = len(modified_output.split('\n')) if modified_output else 0

    git_status = f"{GREEN}+{staged}{RESET}" if staged else ""
    git_status += f"{YELLOW}~{modified}{RESET}" if modified else ""

    print(f"[{model}] 📁 {directory} | 🌿 {branch} {git_status}")
except:
    print(f"[{model}] 📁 {directory}")

费用 + 时长(Node.js)

javascript
#!/usr/bin/env node
let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
    const data = JSON.parse(input);
    const model = data.model.display_name;
    const cost = data.cost?.total_cost_usd || 0;
    const durationMs = data.cost?.total_duration_ms || 0;

    const mins = Math.floor(durationMs / 60000);
    const secs = Math.floor((durationMs % 60000) / 1000);

    console.log(`[${model}] 💰 $${cost.toFixed(2)} | ⏱️ ${mins}m ${secs}s`);
});

双行状态栏(颜色进度条 + git)

bash
#!/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'

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 PowerShell 配置

json
{
  "statusLine": {
    "type": "command",
    "command": "powershell -NoProfile -File C:/Users/username/.claude/statusline.ps1"
  }
}
powershell
$input_json = $input | Out-String | ConvertFrom-Json
$model = $input_json.model.display_name
$cwd = $input_json.cwd
$used = $input_json.context_window.used_percentage
$dirname = Split-Path $cwd -Leaf

if ($used) {
    Write-Host "$dirname [$model] ctx: $used%"
} else {
    Write-Host "$dirname [$model]"
}

性能技巧:缓存慢操作

Status line 频繁触发。git status 在大型仓库里可能很慢。用缓存文件避免每次都运行:

bash
CACHE_FILE="/tmp/statusline-git-cache"
CACHE_MAX_AGE=5  # 秒

# 检查缓存是否过期
if [ ! -f "$CACHE_FILE" ] || [ $(($(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || stat -c %Y "$CACHE_FILE"))) -gt $CACHE_MAX_AGE ]; then
    # 更新缓存
    git rev-parse --git-dir > /dev/null 2>&1 && echo "$(git branch --show-current)" > "$CACHE_FILE" || echo "" > "$CACHE_FILE"
fi

BRANCH=$(cat "$CACHE_FILE")

使用固定文件名(如 /tmp/statusline-git-cache),不要用 $$PID——每次 status line 调用是新进程,PID 每次不同,缓存永远不会被复用。


调试技巧

手动测试脚本:

bash
echo '{"model":{"display_name":"Opus"},"context_window":{"used_percentage":25},"cost":{"total_cost_usd":0.05},"workspace":{"current_dir":"/home/user/project"}}' | ~/.claude/statusline.sh

常见问题:

  • 不显示:确认脚本有执行权限(chmod +x);确认脚本输出到 stdout;disableAllHooks: true 时 status line 也会禁用
  • 显示 -- 或空值:第一次 API 响应前某些字段为 null,用 // 0 提供回退值
  • 上下文百分比异常:用 used_percentage 而非累计 token 数计算;累计 token 可能超过上下文窗口大小
  • OSC 8 链接不可点击:需要 iTerm2、Kitty、WezTerm 等支持 OSC 8 的终端;Terminal.app 不支持
  • ANSI 转义码显示乱码:简化为纯文本输出,多行 + 转义码更容易出现渲染问题
  • 工作区信任:未接受工作区信任对话框时,status line 不会运行,显示 statusline skipped · restart to fix

相关文档