自製 Claude Code 狀態列:即時顯示 Context 用量、成本與 Session 統計


用 Claude Code 跑久了,最怕兩件事:context 快滿了卻不知道(突然 auto-compact,思路被打斷),和這個 session 到底花了多少錢(帳單來了才驚覺)。

Claude Code 支援自訂 status line——終端機底部那一行狀態。我用一個 235 行的 Python 腳本,讓它即時顯示:context 用量百分比(彩色進度條)、這個 session 的花費、執行時間、改了幾行。這篇拆解這個 status line 怎麼運作、怎麼設定。


status line 是什麼

Claude Code 會在每次更新時,把 session 的狀態資料以 JSON 從 stdin 傳給你指定的程式,程式印出一行字,就成為終端機底部的狀態列。

設定在 settings.json

{
  "statusLine": {
    "type": "command",
    "command": "python .claude/scripts/context-monitor.py"
  }
}

每次狀態更新,Claude Code 就跑一次這個 Python,把結果顯示在底部。


Claude Code 傳進來的資料

status line 程式從 stdin 收到的 JSON:

data = json.load(sys.stdin)

model_name = data.get('model', {}).get('display_name', 'Claude')
workspace = data.get('workspace', {})        # current_dir, project_dir
transcript_path = data.get('transcript_path', '')  # 對話紀錄檔路徑
cost_data = data.get('cost', {})             # 花費、時間、行數

關鍵欄位:

  • model.display_name — 當前模型
  • workspace — 目前目錄 / 專案目錄
  • transcript_path對話紀錄檔(context 用量的關鍵)
  • cost — 花費、執行時間、增刪行數

核心:從 transcript 算 context 用量

Claude Code 沒有直接傳 context 百分比,但有傳 transcript_path——對話紀錄的 JSONL 檔。每一行是一筆訊息,裡面有 token 用量。解析它就能算出 context 用了多少:

def parse_context_from_transcript(transcript_path):
    with open(transcript_path, 'r', encoding='utf-8', errors='replace') as f:
        lines = f.readlines()

    # 只看最後 15 行(最新狀態)
    recent_lines = lines[-15:] if len(lines) > 15 else lines

    for line in reversed(recent_lines):
        data = json.loads(line.strip())

        # 方法 1:從 assistant 訊息的 usage 算
        if data.get('type') == 'assistant':
            usage = data.get('message', {}).get('usage', {})
            if usage:
                total = (usage.get('input_tokens', 0)
                       + usage.get('cache_read_input_tokens', 0)
                       + usage.get('cache_creation_input_tokens', 0))
                if total > 0:
                    percent = min(100, (total / 200000) * 100)
                    return {'percent': percent, 'tokens': total, 'method': 'usage'}

關鍵洞察:context 用量 = input_tokens + cache_read + cache_creation。這三個加起來就是這一輪送進模型的總 token,除以 context window(這裡假設 200k)就是百分比。

從最後一行往回找

for line in reversed(recent_lines) ——從最新的訊息往回找第一個有 usage 的。因為最新一輪的 token 數才反映當前 context 狀態,舊的訊息 usage 是歷史值。

第二種來源:系統警告

# 方法 2:解析系統的 context 警告訊息
elif data.get('type') == 'system_message':
    content = data.get('content', '')
    match = re.search(r'Context left until auto-compact: (\d+)%', content)
    if match:
        return {'percent': 100 - int(match.group(1)), 'warning': 'auto-compact'}

Claude Code 接近 auto-compact 時會發系統訊息,直接抓那個百分比更準。兩種方法都試,哪個有就用哪個。


視覺化:彩色進度條 + 警示

光有數字不夠,要一眼看出「危險程度」。用顏色 + 進度條:

def get_context_display(context_info):
    percent = context_info.get('percent', 0)

    # 依用量決定顏色和圖示
    if percent >= 95:
        icon, color, alert = "🚨", "\033[31;1m", "CRIT"    # 閃紅
    elif percent >= 90:
        icon, color, alert = "🔴", "\033[31m", "HIGH"      # 紅
    elif percent >= 75:
        icon, color, alert = "🟠", "\033[91m", ""          # 橙
    elif percent >= 50:
        icon, color, alert = "🟡", "\033[33m", ""          # 黃
    else:
        icon, color, alert = "🟢", "\033[32m", ""          # 綠

    # 8 格進度條
    segments = 8
    filled = int((percent / 100) * segments)
    bar = "█" * filled + "▁" * (segments - filled)

    return f"{icon}{color}{bar}\033[0m {percent:.0f}%{alert_str}"

效果(終端機底部):

[Claude] 📁 blog 🧠 🟡████▁▁▁▁ 52% | 💰 $0.34 ⏱ 12m 📝 +156
  • 🟢 0-50% 綠(安全)
  • 🟡 50-75% 黃(注意)
  • 🟠 75-90% 橙(該考慮收尾)
  • 🔴 90-95% 紅(快滿)
  • 🚨 95%+ 閃紅 + CRIT(馬上要 compact)

8 格進度條 + 顏色 + emoji 三重編碼,餘光掃一眼就知道還剩多少 context,不用停下來算。


Session 統計:花費、時間、行數

cost 資料裡有這個 session 的累計統計,也做進狀態列:

def get_session_metrics(cost_data):
    metrics = []

    # 花費(依金額變色)
    cost_usd = cost_data.get('total_cost_usd', 0)
    if cost_usd > 0:
        if cost_usd >= 0.10: cost_color = "\033[31m"   # 紅(貴)
        elif cost_usd >= 0.05: cost_color = "\033[33m" # 黃
        else: cost_color = "\033[32m"                  # 綠(便宜)
        cost_str = f"{cost_usd*100:.0f}¢" if cost_usd < 0.01 else f"${cost_usd:.3f}"
        metrics.append(f"{cost_color}💰 {cost_str}\033[0m")

    # 執行時間(超過 30 分鐘變黃)
    duration_ms = cost_data.get('total_duration_ms', 0)
    if duration_ms > 0:
        minutes = duration_ms / 60000
        duration_str = f"{duration_ms//1000}s" if minutes < 1 else f"{minutes:.0f}m"
        metrics.append(f"⏱ {duration_str}")

    # 增刪行數(淨值,正綠負紅)
    net = cost_data.get('total_lines_added', 0) - cost_data.get('total_lines_removed', 0)
    sign = "+" if net >= 0 else ""
    metrics.append(f"📝 {sign}{net}")

    return " | " + " ".join(metrics) if metrics else ""
  • 💰 花費:< 5¢ 綠、5-10¢ 黃、> 10¢ 紅——一眼知道這個 session 燒了多少
  • ⏱ 時間:超過 30 分鐘變黃,提醒這是長 session
  • 📝 淨行數:增刪相抵的淨值,正綠負紅

組合 + 防呆

def main():
    try:
        data = json.load(sys.stdin)
        # ... 組合各部分
        status_line = f"{model_display} 📁 {directory} 🧠 {context_display}{session_metrics}"
        print(status_line)
    except Exception as e:
        # 任何錯誤都要 fallback,不能讓狀態列整個消失
        print(f"[Claude] 📁 {os.path.basename(os.getcwd())} 🧠 [Error: {str(e)[:20]}]")

關鍵:整個包在 try/except 裡。status line 每次更新都跑,如果某次 transcript 格式怪、JSON parse 失敗,不能讓狀態列整個消失或噴錯——fallback 印一個最小狀態。status line 壞掉不該影響工作

連 model 名稱也跟著 context 變色:

# context 越滿,model 名稱越紅
if percent >= 90: model_color = "\033[31m"      # 紅
elif percent >= 75: model_color = "\033[33m"    # 黃
else: model_color = "\033[32m"                  # 綠

整行的視覺重心隨危險程度移動。


為什麼這值得做

Claude Code 內建會在快滿時提示,但那是「事件式」的——跳出來才知道。status line 是「持續可見」的:

沒有 status line有 status line
context 突然 auto-compact,思路被打斷隨時看到 % ,75% 就開始準備收尾
session 結束才知道花多少即時看到 💰,貴了自己踩煞車
不知道改了多少行📝 淨行數一直在眼前

最有價值的是主動收尾:看到 🟠 75%,就知道該把當前任務做個段落、必要時開新 session,而不是衝到 🚨 被動 compact。


怎麼設定你自己的

  1. 把腳本放在 .claude/scripts/context-monitor.py(或任何路徑)
  2. settings.json 加:
{
  "statusLine": {
    "type": "command",
    "command": "python .claude/scripts/context-monitor.py"
  }
}
  1. 重點實作:
    • 從 stdin 讀 JSON,拿 transcript_path
    • 讀 transcript 最後幾行,從 usageinput + cache_read + cache_creation
    • 除以你的 context window(200k)算百分比
    • 用 ANSI 顏色碼 + emoji 視覺化
    • 整個包 try/except,壞掉要有 fallback

注意事項

  • 效能:status line 更新頻繁,腳本要快。這個版本只讀 transcript 最後 15 行,不讀整個檔——大檔案也快
  • context window 數字:腳本寫死 200k,不同模型不同,要自己對應
  • ANSI 顏色:在不支援的終端機會變亂碼,但大部分現代終端機都支援

結語

status line 是 Claude Code 最被低估的客製點。它不改變 AI 的行為,但改變你的行為——當 context 用量、花費一直在眼前,你會更早收尾、更注意成本,而不是等系統提示或帳單來了才反應。

235 行 Python,核心其實就一件事:從 transcript 算出 context 百分比,用顏色讓你一眼看懂。如果你常跑長 session,這個投資很值——它把「看不見的 context 消耗」變成「隨時可見的儀表板」。