
ステータスライン ▖▄▘▌▙▀▛█を使うアイデア
- #Claude Code
- #AI
ステータスラインとは
Claude Codeの画面下部に、コンテキスト使用量、コスト、Gitの状態などを常時表示できるカスタマイズ可能なバーです。設定した任意のシェルスクリプトやコマンドの実行結果(標準出力)を表示します。
https://code.claude.com/docs/ja/statusline
今回のアイデア
Opus | 12.3K | ████▛ 45% (2h30m) | ▛▀▀▘ 8% (4d12h)モデル名:Opus とか Sonnet とか コンテキスト使用量:現在のコンテキストの入力トークン数 5時間の利用制限:上下のバー + 使用率% 7日間の利用制限:上下のバー + 使用率%
バーは二段になっていて、上は利用枠の時間経過率、下は使用率を表しています。
「時間は経ってるのに使用率が低い」→「まだ余裕ある」といった判断ができて便利です。
利用するJSONデータ
実際にスクリプトに渡されるJSONデータは、以下のような構造になっています(関連する部分のみ)。
{
"model": {
"display_name": "Opus"
},
"context_window": {
"current_usage": {
"input_tokens": 8500,
"output_tokens": 1200,
"cache_creation_input_tokens": 5000,
"cache_read_input_tokens": 2000
}
},
"rate_limits": {
"five_hour": {
"used_percentage": 23.5,
"resets_at": 1738425600
},
"seven_day": {
"used_percentage": 41.2,
"resets_at": 1738857600
}
}
}設定方法
Claude Code に以下のように指示することで導入できます。
/statusline https://note.com/c45/n/n30cfd6e55d0f を作ってコード
~/.claude/settings.json
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.py",
"refreshInterval": 10
}
}~/.claude/statusline.py
#!/usr/bin/env python3
from __future__ import annotations
import json
import sys
import time
WIDTH = 10
CELLS = WIDTH * 2
BAR_GLYPHS = " ▖▄▘▌▙▀▛█"
ESC_BG = "\033[40m"
ESC_RESET = "\033[0m"
CONTEXT_TOKEN_FIELDS = (
"input_tokens",
"cache_creation_input_tokens",
"cache_read_input_tokens",
)
WINDOW_5H = 5 * 60 * 60
WINDOW_7D = 7 * 24 * 60 * 60
def clamp(value: float, lo: float, hi: float) -> float:
return max(lo, min(hi, value))
def round_half_up(value: float) -> int:
return int(value + 0.5)
def dual_bar(top: float, bottom: float) -> str:
top_cols = int(top)
bottom_cols = int(bottom)
glyphs = "".join(
BAR_GLYPHS[clamp(top_cols - 2 * i, 0, 2) * 3 + clamp(bottom_cols - 2 * i, 0, 2)]
for i in range(WIDTH)
)
return f"{ESC_BG}{glyphs}{ESC_RESET}"
def format_remaining(resets_at: float | None, now: float) -> str:
if resets_at is None:
return "--"
remaining = resets_at - now
if remaining <= 0:
return "--"
minutes = int(remaining + 59) // 60
hours, minutes = divmod(minutes, 60)
if hours >= 24:
days, hours = divmod(hours, 24)
return f"{days}d{hours}h"
if hours:
return f"{hours}h{minutes}m"
return f"{minutes}m"
def format_section(section: dict | None, window_seconds: int, now: float) -> str:
section = section or {}
resets_at = section.get("resets_at")
if resets_at is None:
elapsed_pct = 0.0
else:
elapsed_pct = clamp((window_seconds - (resets_at - now)) / window_seconds * 100, 0, 100)
elapsed_cells = elapsed_pct / 100 * CELLS
used_pct = section.get("used_percentage")
used_cells = (used_pct or 0) / 100 * CELLS
bar = dual_bar(elapsed_cells, used_cells)
used_label = "-" if used_pct is None else str(round_half_up(used_pct))
return f"{bar} {used_label}% ({format_remaining(resets_at, now)})"
def main() -> None:
data = json.load(sys.stdin)
now = time.time()
usage = (data.get("context_window") or {}).get("current_usage") or {}
context_tokens = sum(usage.get(field) or 0 for field in CONTEXT_TOKEN_FIELDS)
model = (data.get("model") or {}).get("display_name") or "Claude"
rate_limits = data.get("rate_limits") or {}
line = (
f"{model} | "
f"{context_tokens // 100 / 10}K | "
f"{format_section(rate_limits.get('five_hour'), WINDOW_5H, now)} | "
f"{format_section(rate_limits.get('seven_day'), WINDOW_7D, now)}"
)
sys.stdout.write(line)
if __name__ == "__main__":
main()※ ESC_BG (バーの背景色)は個人の環境に合わせて調整してください。