Claude Code StatusBar 表示例
Claude Code StatusBar | Zenn
目次

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 の記事には、さらに詳細な実装方法とディスカッションが掲載されている。


参考:

引用元・参考リンク

免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。