在 Claude Code 顯示即時額度:Status Line 使用量監控實作指南
在 Claude Code 顯示即時額度:Status Line 使用量監控實作指南 透過 OAuth API 在 Claude Code 的 status line 顯示 5 小時 session 額度、7 天 weekly 使用量與重置倒數。適合所有 Claude Code CLI 使用者。
在 Claude Code 顯示即時額度:Status Line 使用量監控實作指南
適用技術棧 :Bash、Claude Code CLI、macOS Keychain、Anthropic OAuth API
最近用 Claude Code 用量越來越大,常常用到一半才發現 5 小時額度快爆了。後來研究了一下,發現可以透過 Anthropic 的 OAuth API 拿到即時的使用量百分比,直接顯示在 Claude Code 的 status line 上。這篇整理了完整的實作方式,包含 API 怎麼打、cache 怎麼做、429 rate limit 怎麼處理。
1. 這個系統做什麼
概覽
在 Claude Code CLI 底部的 status line 顯示即時的使用額度資訊,包含 5 小時 session 用量百分比與重置倒數,以及 7 天 weekly 用量百分比與重置倒數。
解決什麼問題
Claude Code 的 Max/Pro 方案有兩層使用限制:5 小時滾動窗口和 7 天滾動窗口。官方的 status line stdin JSON 只提供 context window 和 cost 資訊,不包含 plan-level 的額度。這個功能填補了這個缺口,讓你在 CLI 裡就能即時看到還剩多少額度。
功能邊界(Scope)
包含 :5h session 用量% 與重置倒數、7d weekly 用量% 與重置倒數、當前模型、context window%
不包含 :Sonnet/Opus 分開的 per-model 限制(API 有回傳但此版本未顯示)、extra usage 計費
2. 整體架構與資料流
資料流
Claude Code 執行 statusline.sh
│
├─ stdin ──→ 解析 model / context window %
│
├─ 檢查 /tmp/claude/statusline-usage-cache.json(5 min TTL)
│ │
│ ├─ cache 有效 → 直接讀取
│ └─ cache 過期 → 檢查 backoff
│ │
│ ├─ backoff 存在(< 10 min)→ 跳過 API
│ └─ 可以呼叫 → Keychain 取 OAuth token
│ │
│ └─→ GET /api/oauth/usage
│ │
│ ├─ 200 → 寫入 cache
│ └─ 429 → 寫入 backoff 檔
│
└─ 組合輸出 → stdout → Claude Code 顯示
外部依賴
GEEKAZ Design engineering from Taipei. Building courses, tools, and resources for designers who code.
jqCLI 工具 解析 JSON curlCLI 工具 HTTP 請求 security(macOS)系統工具 從 Keychain 讀取 OAuth token
核心 API Endpoint: GET https://api.anthropic.com/api/oauth/usage
Authorization: Bearer <oauth-token>
anthropic-beta: oauth-2025-04-20
User-Agent: claude-code/2.1.76
anthropic-beta: oauth-2025-04-20 是關鍵,少了這個會拿到 401 authentication error。
{
"five_hour": {
"utilization": 39.0,
"resets_at": "2026-03-14T11:00:00.265456+00:00"
},
"seven_day": {
"utilization": 10.0,
"resets_at": "2026-03-20T11:00:00.265474+00:00"
},
"seven_day_sonnet": {
"utilization": 1.0,
"resets_at": "2026-03-20T14:00:00.265482+00:00"
},
"extra_usage": {
"is_enabled": false,
"monthly_limit": null,
"used_credits": null,
"utilization": null
}
}
欄位 說明 five_hour.utilization5h session 已用百分比(整數,例如 39 = 39%) five_hour.resets_atsession 重置時間(ISO 8601) seven_day.utilization7 天 all models 已用百分比 seven_day.resets_atweekly 重置時間 seven_day_sonnetSonnet 專屬的週限制(可選顯示) extra_usage額外用量計費(Max 方案可能啟用)
3. 資料結構與型別定義
Claude Code stdin JSON Claude Code 每次更新 status line 時,會把以下 JSON 灌入 script 的 stdin:
{
"model": {
"id": "claude-opus-4-6",
"display_name": "Opus 4.6 (1M context)"
},
"context_window": {
"used_percentage": 42,
"context_window_size": 1000000,
"current_usage": {
"input_tokens": 50000,
"cache_creation_input_tokens": 30000,
"cache_read_input_tokens": 10000
}
},
"session": {
"start_time": "2026-03-14T08:30:00Z"
},
"cwd": "/path/to/project",
"cost": {
"total_cost_usd": 1.23
}
}
settings.json 設定格式 {
"statusLine": {
"type": "command",
"command": "bash \"$HOME/.claude/statusline.sh\""
}
}
注意 statusLine 必須是物件格式(type + command),不能直接傳字串。
4. 一步步實作 坦白說整個功能最容易踩坑的地方不是 script 本身,而是 OAuth token 的取得和 rate limit 的處理。
Step 1:建立 statusline.sh 目的 :建立主要的 status line script,放在 ~/.claude/statusline.sh。
#!/bin/bash
set -f
input=$(cat)
[ -z "$input" ] && exit 0
# ── 顏色定義(統一灰色調)──
fg='\033[38;2;160;160;160m'
bright='\033[38;2;200;200;200m'
dim='\033[2m'
reset='\033[0m'
sep=" ${dim}│${reset} "
# ── 進度條 ──
build_bar() {
local pct=$1 width=$2
[ "$pct" -lt 0 ] 2>/dev/null && pct=0
[ "$pct" -gt 100 ] 2>/dev/null && pct=100
local filled=$(( pct * width / 100 ))
local empty=$(( width - filled ))
local f="" e=""
for ((i=0; i<filled; i++)); do f+="━"; done
for ((i=0; i<empty; i++)); do e+="─"; done
printf "${bright}${f}${dim}${e}${reset}"
}
# ── ISO 時間轉倒數 ──
iso_countdown() {
local iso="$1"
[ -z "$iso" ] || [ "$iso" = "null" ] && return
local stripped="${iso%%.*}"
stripped="${stripped%%Z}"
stripped="${stripped%%+*}"
local epoch
# macOS
epoch=$(env TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%S" "$stripped" +%s 2>/dev/null)
# Linux fallback
[ -z "$epoch" ] && epoch=$(date -d "$iso" +%s 2>/dev/null)
[ -z "$epoch" ] && return
local diff=$(( epoch - $(date +%s) ))
[ "$diff" -le 0 ] && { printf "now"; return; }
if [ "$diff" -ge 86400 ]; then
printf "%dd%dh%02dm" $(( diff / 86400 )) $(( (diff % 86400) / 3600 )) $(( (diff % 3600) / 60 ))
elif [ "$diff" -ge 3600 ]; then
printf "%dh%02dm" $(( diff / 3600 )) $(( (diff % 3600) / 60 ))
else
printf "%dm" $(( diff / 60 ))
fi
}
# ── 解析 stdin ──
model=$(echo "$input" | jq -r '.model.display_name // "Claude"' | awk '{print $1}')
ctx_pct=$(echo "$input" | jq -r '.context_window.used_percentage // 0')
# ── 取得 OAuth Token ──
get_token() {
[ -n "$CLAUDE_CODE_OAUTH_TOKEN" ] && { echo "$CLAUDE_CODE_OAUTH_TOKEN"; return; }
# macOS Keychain
if command -v security >/dev/null 2>&1; then
local t
t=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null \
| jq -r '.claudeAiOauth.accessToken // empty' 2>/dev/null)
[ -n "$t" ] && [ "$t" != "null" ] && { echo "$t"; return; }
fi
# 檔案 fallback
local f="$HOME/.claude/.credentials.json"
[ -f "$f" ] && { jq -r '.claudeAiOauth.accessToken // empty' "$f" 2>/dev/null; return; }
}
# ── 取得使用量(5 分鐘 cache + 429 退避)──
cache_dir="/tmp/claude"
cache="$cache_dir/statusline-usage-cache.json"
backoff="$cache_dir/statusline-backoff"
mkdir -p "$cache_dir"
usage=""
refresh=true
# 檢查 cache(5 分鐘 TTL)
if [ -f "$cache" ]; then
age=$(( $(date +%s) - $(stat -f %m "$cache" 2>/dev/null \
|| stat -c %Y "$cache" 2>/dev/null || echo 0) ))
[ "$age" -lt 300 ] && { refresh=false; usage=$(cat "$cache"); }
fi
# 檢查 backoff(429 後 10 分鐘不再打 API)
if $refresh && [ -f "$backoff" ]; then
backoff_age=$(( $(date +%s) - $(stat -f %m "$backoff" 2>/dev/null \
|| stat -c %Y "$backoff" 2>/dev/null || echo 0) ))
[ "$backoff_age" -lt 600 ] && refresh=false
fi
if $refresh; then
tok=$(get_token)
if [ -n "$tok" ]; then
http_code=$(curl -s -o "$cache_dir/resp.tmp" -w "%{http_code}" --max-time 5 \
-H "Accept: application/json" \
-H "Authorization: Bearer $tok" \
-H "anthropic-beta: oauth-2025-04-20" \
-H "User-Agent: claude-code/2.1.76" \
"https://api.anthropic.com/api/oauth/usage" 2>/dev/null)
if [ "$http_code" = "200" ] && jq -e '.five_hour' "$cache_dir/resp.tmp" >/dev/null 2>&1; then
cp "$cache_dir/resp.tmp" "$cache"
rm -f "$backoff"
usage=$(cat "$cache")
elif [ "$http_code" = "429" ]; then
touch "$backoff"
fi
rm -f "$cache_dir/resp.tmp"
fi
[ -z "$usage" ] && [ -f "$cache" ] && usage=$(cat "$cache")
fi
# ── 組合輸出 ──
out="${bright}${model}${reset}"
out+="${sep}${fg}Context ${bright}${ctx_pct}%${reset}"
if [ -n "$usage" ] && echo "$usage" | jq -e '.five_hour' >/dev/null 2>&1; then
h5_pct=$(echo "$usage" | jq -r '.five_hour.utilization // 0' | awk '{printf "%.0f", $1}')
h5_reset=$(iso_countdown "$(echo "$usage" | jq -r '.five_hour.resets_at // empty')")
out+="${sep}${fg}5h${reset} $(build_bar "$h5_pct" 8) ${bright}${h5_pct}%${reset}"
[ -n "$h5_reset" ] && out+=" ${dim}${h5_reset}${reset}"
d7_pct=$(echo "$usage" | jq -r '.seven_day.utilization // 0' | awk '{printf "%.0f", $1}')
d7_reset=$(iso_countdown "$(echo "$usage" | jq -r '.seven_day.resets_at // empty')")
out+="${sep}${fg}7d${reset} $(build_bar "$d7_pct" 8) ${bright}${d7_pct}%${reset}"
[ -n "$d7_reset" ] && out+=" ${dim}${d7_reset}${reset}"
fi
printf "%b" "$out"
exit 0
display_name 會回傳完整名稱如 Opus 4.6 (1M context),用 awk '{print $1}' 只取第一個字
進度條用 ━(填充)和 ─(空白),視覺上比圓點更像長條圖
整體配色用灰色調,不花俏
Step 2:設定 settings.json 目的 :告訴 Claude Code 使用這個 script 作為 status line。
在 ~/.claude/settings.json 加入:
{
"statusLine": {
"type": "command",
"command": "bash \"$HOME/.claude/statusline.sh\""
}
}
Step 3:處理 OAuth Token 目的 :取得 Anthropic 的 OAuth token 來呼叫 usage API。
Token 儲存在 macOS Keychain 的 Claude Code-credentials 條目中,結構如下:
{
"claudeAiOauth": {
"accessToken": "sk-ant-oat01-...",
"refreshToken": "sk-ant-ort01-...",
"expiresAt": 1773505357396,
"scopes": ["user:inference", "user:profile", "user:sessions:claude_code"],
"subscriptionType": "max",
"rateLimitTier": "default_claude_max_5x"
}
}
security find-generic-password -s "Claude Code-credentials" -w \
| jq -r '.claudeAiOauth.accessToken'
Token 會定期過期(通常 6 小時),Claude Code 會自動 refresh
如果遇到持續 429,執行 /login 重新登入可以拿到新 token 立即解除
Step 4:Cache 與 Rate Limit 處理 目的 :避免頻繁打 API 觸發 rate limit。
機制 說明 Cache TTL 5 分鐘 額度數據變化不快,5 分鐘刷新一次足夠 Backoff 檔案 收到 429 後寫入 /tmp/claude/statusline-backoff,10 分鐘內不再打 API Stale cache fallback 即使 cache 過期 + API 失敗,舊資料還是會繼續顯示 共用 cache 多個終端共用同一個 /tmp/claude/statusline-usage-cache.json,避免重複呼叫
實測下來,正常使用(5 分鐘一次)一小時最多 12 次 API call,不會觸發 rate limit。之前踩坑是因為短時間內手動測試打了 15+ 次。
5. 快速開始
前提條件
實作步驟
建立 script 檔案
# 把 Step 1 的完整 script 寫入這個路徑
vim ~/.claude/statusline.sh
chmod +x ~/.claude/statusline.sh
設定 settings.json
# 編輯 ~/.claude/settings.json,加入 statusLine 設定
# 如果檔案已存在,只需加入 statusLine 欄位
{
"statusLine": {
"type": "command",
"command": "bash \"$HOME/.claude/statusline.sh\""
}
}
重新登入取得 fresh token
# 在 Claude Code 中執行
/login
這步很重要。新安裝後或如果額度資訊沒出現,執行 /login 重新登入可以確保 OAuth token 有效,額度資訊就會立即顯示。
重啟 Claude Code
# 關閉並重新開啟 Claude Code
# Status line 會在第一次 assistant 回覆後出現
驗證
顯示效果 Opus │ Context 42% │ 5h ━━━───── 39% 3h56m │ 7d ──────── 10% 5d20h56m
6. 不同技術棧的調整方式 如果你的環境跟上面不完全一樣,這邊整理了需要調整的部分。
高度通用的部分(直接用)
API endpoint 和 headers 是通用的
Cache + backoff 邏輯是通用的
進度條和輸出格式是通用的
需要客製化的部分 部分 原實作 新環境需要調整 Token 取得 macOS security 指令 Linux 用 secret-tool,或讀 ~/.claude/.credentials.json 日期解析 date -j -f(macOS BSD)Linux 用 date -d(GNU date) Cache 路徑 /tmp/claude/任何可寫入的暫存目錄 stat 時間stat -f %m(macOS)Linux 用 stat -c %Y
Linux Token 取得 # 方法 1:secret-tool(GNOME Keyring)
secret-tool lookup service "Claude Code-credentials" | jq -r '.claudeAiOauth.accessToken'
# 方法 2:直接讀檔案
jq -r '.claudeAiOauth.accessToken' ~/.claude/.credentials.json
整體來說,這個做法跑起來比預期穩定。核心就是一個 bash script 加上一個 API call,再用 cache 和 backoff 避免打太多次。如果額度資訊沒出現,先跑一次 /login 重新登入就好。
© 2026 GEEKAZ. All Rights Reserved.