Aa の ほーむぺーじ。

ステータスライン ▖▄▘▌▙▀▛█を使うアイデア

  • #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 (バーの背景色)は個人の環境に合わせて調整してください。

リファレンス

https://code.claude.com/docs/en/statusline

https://forms.gle/ZgTFJC2kJAwHhRsR6