目次
2026 年 3 月、Zenn の suthio 氏が**「Claude Code の/usage の内容を StatusBar に表示する」**方法を公開した。
この記事では、Claude Code のステータスラインを以下の仕様で設定する方法が紹介されている。
表示仕様(3 行構成)
🤖 Opus 4.6 │ 📊 0% │ ✏️ +42/-1 │ 🔀 main
⏱ 5h ▰▱▱▱▱▱▱▱▱▱ 13% Resets 4pm (Asia/Tokyo)
📅 7d ▰▰▰▰▰▱▱▱▱▱ 55% Resets Mar 6 at 1pm (Asia/Tokyo)
各行の詳細
| 行 | 内容 |
|---|---|
| 1 行目 | モデル名、コンテキストウィンドウ使用率、追加/削除行数、git ブランチ名 |
| 2 行目 | 5 時間レートリミットの使用率をプログレスバーで表示 |
| 3 行目 | 7 日間レートリミットの使用率をプログレスバーで表示 |
カラーリング
使用率に応じて色が変わる。
| 使用率 | 色 |
|---|---|
| 0-49% | 緑 #97C9C3 |
| 50-79% | 黄 #E5C07B |
| 80-100% | 赤 #E06C75 |
| 区切り文字 | グレー #4A585C |
レートリミット情報の取得方法
macOS
macOS キーチェーンから Claude Code-credentials の OAuth トークンを取得し、API を呼び出す。
# OAuth トークンの取得
token=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null || true)
# API 呼び出し
curl -sf --max-time 5 \
-H "Authorization: Bearer ${access_token}" \
-H "anthropic-beta: oauth-2025-04-20" \
"https://api.anthropic.com/api/oauth/usage"
Windows
Windows では $env:USERPROFILE\.claude\.credentials.json からアクセス トークンを取得する。
# OAuth トークンの取得
$creds = Get-Content "$env:USERPROFILE\.claude\.credentials.json" | ConvertFrom-Json
$token = $creds.access_token
# API 呼び出し
Invoke-RestMethod -Uri "https://api.anthropic.com/api/oauth/usage" `
-Headers @{ Authorization = "Bearer $token" }
キャッシュ
結果はキャッシュされて、API 呼び出しを最小限に抑える。
| プラットフォーム | キャッシュファイル | TTL |
|---|---|---|
| macOS | /tmp/claude-usage-cache.json |
360 秒 |
| Windows | $env:TEMP\claude-usage-cache.json |
360 秒 |
実装方法
macOS 用 bash スクリプト
~/.claude/statusline-command.sh に以下のスクリプトを配置する。
#!/usr/bin/env bash
# Claude Code Statusline
# 3-line display: session info, 5h usage, 7d usage
set -euo pipefail
input=$(cat)
# ── Colors ──
GREEN="\033[38;2;151;201;195m"
YELLOW="\033[38;2;229;192;123m"
RED="\033[38;2;224;108;117m"
GRAY="\033[38;2;74;88;92m"
RESET="\033[0m"
color_for_pct() {
local pct=$1
if (( pct >= 80 )); then
printf '%s' "$RED"
elif (( pct >= 50 )); then
printf '%s' "$YELLOW"
else
printf '%s' "$GREEN"
fi
}
# ── Progress bar (10 segments) ──
progress_bar() {
local pct=$1
local filled=$(( pct / 10 ))
local empty=$(( 10 - filled ))
local color
color=$(color_for_pct "$pct")
local bar=""
for ((i=0; i<filled; i++)); do bar+="▰"; done
for ((i=0; i<empty; i++)); do bar+="▱"; done
printf '%b%s%b' "$color" "$bar" "$RESET"
}
# ── Line 1: Session info ──
model=$(echo "$input" | jq -r '.model.display_name // ""')
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
lines_added=$(echo "$input" | jq -r '.cost.total_lines_added // 0')
lines_removed=$(echo "$input" | jq -r '.cost.total_lines_removed // 0')
cwd=$(echo "$input" | jq -r '.workspace.current_dir // ""')
# Context percentage (integer)
ctx_int=0
if [ -n "$used_pct" ]; then
printf -v ctx_int "%.0f" "$used_pct" 2>/dev/null || ctx_int="${used_pct%%.*}"
fi
ctx_color=$(color_for_pct "$ctx_int")
# Git branch
git_branch=""
if [ -n "$cwd" ] && git -C "$cwd" rev-parse --git-dir > /dev/null 2>&1; then
git_branch=$(git -C "$cwd" symbolic-ref --short HEAD 2>/dev/null || git -C "$cwd" rev-parse --short HEAD 2>/dev/null)
fi
sep="${GRAY} │ ${RESET}"
line1="🤖 ${model}${sep}${ctx_color}📊 ${ctx_int}%${RESET}${sep}✏️ +${lines_added}/-${lines_removed}"
if [ -n "$git_branch" ]; then
line1+="${sep}🔀 ${git_branch}"
fi
# ── Usage API (OAuth, cached 60s) ──
CACHE_FILE="/tmp/claude-usage-cache.json"
CACHE_TTL=360
fetch_usage() {
# Get OAuth token from macOS Keychain
local token
token=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null || true)
if [ -z "$token" ]; then
return 1
fi
# Token is stored as JSON with nested structure
local access_token
access_token=$(echo "$token" | jq -r '.claudeAiOauth.accessToken // .accessToken // .access_token // empty' 2>/dev/null || true)
if [ -z "$access_token" ]; then
return 1
fi
local response
response=$(curl -sf --max-time 5 \
-H "Authorization: Bearer ${access_token}" \
-H "anthropic-beta: oauth-2025-04-20" \
"https://api.anthropic.com/api/oauth/usage" 2>/dev/null) || return 1
# Write cache with timestamp
local now
now=$(date +%s)
echo "$response" | jq --arg ts "$now" '. + {cached_at: ($ts | tonumber)}' > "$CACHE_FILE" 2>/dev/null
echo "$response"
}
get_usage() {
local now
now=$(date +%s)
# Check cache
if [ -f "$CACHE_FILE" ]; then
local cached_at
cached_at=$(jq -r '.cached_at // 0' "$CACHE_FILE" 2>/dev/null || echo "0")
local age=$(( now - cached_at ))
if (( age < CACHE_TTL )); then
jq -r 'del(.cached_at)' "$CACHE_FILE" 2>/dev/null
return 0
fi
fi
fetch_usage
}
# Convert ISO 8601 to epoch seconds (macOS compatible)
iso_to_epoch() {
local iso_time=$1
local stripped="${iso_time%%.*}"
TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%S" "$stripped" +%s 2>/dev/null || echo ""
}
# Format reset time for 5h window: "Resets 5pm (Asia/Tokyo)"
format_5h_reset() {
local iso_time=$1
local epoch
epoch=$(iso_to_epoch "$iso_time")
[ -z "$epoch" ] && return
LC_ALL=en_US.UTF-8 TZ="Asia/Tokyo" date -r "$epoch" +"Resets %-l%p (Asia/Tokyo)" 2>/dev/null | sed 's/AM/am/;s/PM/pm/'
}
# Format reset time for 7d window: "Resets Mar 6 at 12pm (Asia/Tokyo)"
format_7d_reset() {
local iso_time=$1
local epoch
epoch=$(iso_to_epoch "$iso_time")
[ -z "$epoch" ] && return
LC_ALL=en_US.UTF-8 TZ="Asia/Tokyo" date -r "$epoch" +"Resets %b %-d at %-l%p (Asia/Tokyo)" 2>/dev/null | sed 's/AM/am/;s/PM/pm/'
}
line2=""
line3=""
usage_json=$(get_usage 2>/dev/null || true)
if [ -n "$usage_json" ]; then
five_util=$(echo "$usage_json" | jq -r '.five_hour.utilization // empty' 2>/dev/null)
five_reset=$(echo "$usage_json" | jq -r '.five_hour.resets_at // empty' 2>/dev/null)
seven_util=$(echo "$usage_json" | jq -r '.seven_day.utilization // empty' 2>/dev/null)
seven_reset=$(echo "$usage_json" | jq -r '.seven_day.resets_at // empty' 2>/dev/null)
if [ -n "$five_util" ]; then
printf -v five_int "%.0f" "$five_util" 2>/dev/null || five_int="${five_util%%.*}"
five_color=$(color_for_pct "$five_int")
five_bar=$(progress_bar "$five_int")
five_reset_str=""
if [ -n "$five_reset" ]; then
five_reset_str=$(format_5h_reset "$five_reset")
fi
line2="${five_color}⏱ 5h${RESET} ${five_bar} ${five_color}${five_int}%${RESET}"
if [ -n "$five_reset_str" ]; then
line2+=" ${GRAY}${five_reset_str}${RESET}"
fi
fi
if [ -n "$seven_util" ]; then
printf -v seven_int "%.0f" "$seven_util" 2>/dev/null || seven_int="${seven_util%%.*}"
seven_color=$(color_for_pct "$seven_int")
seven_bar=$(progress_bar "$seven_int")
seven_reset_str=""
if [ -n "$seven_reset" ]; then
seven_reset_str=$(format_7d_reset "$seven_reset")
fi
line3="${seven_color}📅 7d${RESET} ${seven_bar} ${seven_color}${seven_int}%${RESET}"
if [ -n "$seven_reset_str" ]; then
line3+=" ${GRAY}${seven_reset_str}${RESET}"
fi
fi
fi
# ── Output ──
printf '%b' "$line1"
if [ -n "$line2" ]; then
printf '\n%b' "$line2"
fi
if [ -n "$line3" ]; then
printf '\n%b' "$line3"
fi
Windows 用 PowerShell スクリプト
$env:USERPROFILE\.claude\statusline.ps1 に PowerShell 版のスクリプトを配置する。
# Claude Code Statusline for Windows
# 3-line display: session info, 5h usage, 7d usage
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
try {
$input = Get-Content -Raw -Path 0
# Colors
$GREEN = "`e[38;2;151;201;195m"
$YELLOW = "`e[38;2;229;192;123m"
$RED = "`e[38;2;224;108;117m"
$GRAY = "`e[38;2;74;88;92m"
$RESET = "`e[0m"
function Get-ColorForPct {
param([int]$pct)
if ($pct -ge 80) { return $RED }
elseif ($pct -ge 50) { return $YELLOW }
else { return $GREEN }
}
function Get-ProgressBar {
param([int]$pct)
$filled = [Math]::Floor($pct / 10)
$empty = 10 - $filled
$color = Get-ColorForPct -pct $pct
$bar = ("▰" * $filled) + ("▱" * $empty)
return "${color}${bar}${RESET}"
}
# Line 1: Session info
$json = $input | ConvertFrom-Json
$model = $json.model.display_name
$usedPct = [Math]::Round($json.context_window.used_percentage)
$linesAdded = $json.cost.total_lines_added
$linesRemoved = $json.cost.total_lines_removed
# Git branch
$gitBranch = "-"
try {
$gitBranch = git symbolic-ref --short HEAD 2>$null
} catch {}
$sep = "${GRAY} │ ${RESET}"
$ctxColor = Get-ColorForPct -pct $usedPct
$line1 = "🤖 ${model}${sep}${ctxColor}📊 ${usedPct}%${RESET}${sep}✏️ +${linesAdded}/-${linesRemoved}${sep}🔀 ${gitBranch}"
# Lines 2-3: Usage API
# ... (API 呼び出し部分)
# Output
Write-Host -NoNewline $line1
if ($line2) { Write-Host -NoNewline "`n$line2" }
if ($line3) { Write-Host -NoNewline "`n$line3" }
} catch {
# エラー時も 1 行は出力
Write-Host "⚠ エラーが発生しました"
}
settings.json への設定
macOS
~/.claude/settings.json に以下を追加:
{
"statusLine": {
"type": "command",
"command": "bash ~/.claude/statusline-command.sh"
}
}
Windows
~/.claude/settings.json に以下を追加:
{
"statusLine": {
"type": "command",
"command": "pwsh -NoProfile -ExecutionPolicy Bypass -File \"%USERPROFILE%\\.claude\\statusline.ps1\""
}
}
エラーハンドリング
スクリプトには以下のエラーハンドリングが含まれている。
- 認証情報なし: 2・3 行目を「⚠ 認証情報なし」と表示
- API 呼び出し失敗: キャッシュがあれば使用、なければ「⚠ 取得失敗」と表示
- git コマンド失敗: ブランチ表示を「-」にフォールバック
- stdin の JSON フィールドが null: 0 やハイフンでフォールバック
結論:使用量を可視化して効率的に
この StatusBar 表示により、Claude Code の使用量をリアルタイムで可視化できる。
- レートリミットの可視化 - 使いすぎを防止
- コンテキスト使用率の可視化 - コンテキストウィンドウの効率的な使用
- git ブランチの表示 - 現在の作業ブランチを常時確認
Zenn の記事には、さらに詳細な実装方法とディスカッションが掲載されている。
参考:
引用元・参考リンク
免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。