Claude Code を使っていて一番困ったのが、いつの間にか利用上限に達して止まることでした。そこで、残りがどれくらいかを画面に常に出しておくことにしました。これも作ったのは Claude です。私は「こういう表示がほしい」と頼んだだけです。
前回の記事:Claude Code はフォルダ分けから始める
なぜ表示したいのか
Claude の有料プランには、使える量の上限があります。「5時間ごと」と「1週間ごと」の2種類です。上限に達すると、リセットされるまで待つしかありません。
もう1つ気になるのが、会話の長さです。Claude が一度に覚えておける量(コンテキスト)にも限りがあり、長くなると古い内容から要約されていきます。
どちらも、知りたいときに /usage などで確認はできます。でも、毎回打つのは面倒です。そこでステータスライン(入力欄のすぐ下に出る1行の表示)に、常に出しておくことにしました。
できあがった表示
[Opus 5.5] ctx 7% | 5h 3% (4h51m) | 7d 59% (2d14h)
| 表示 | 意味 |
|---|---|
| [Opus 5.5] | 使っているモデル |
| ctx 7% | 会話の長さ(コンテキスト)の使用率 |
| 5h 3% (4h51m) | 5時間ごとの上限の使用率(リセットまでの残り時間) |
| 7d 59% (2d14h) | 1週間ごとの上限の使用率(リセットまでの残り時間) |
「7d 59%」なのに、リセットまで2日以上ある。こういうときは、重い作業を控えようと判断できます。
※ 利用上限(5h・7d)の表示は、Pro・Max プランで、会話で最初の返答が来たあとに出ます。
しくみ
Claude Code は、返答のたびに「今のモデル」「会話の長さ」「利用上限」などのデータを、指定したスクリプト(小さなプログラム)に渡します。スクリプトがそれを1行の文字にして返すと、入力欄の下に表示されます。
どのスクリプトを使うかは、設定ファイル(%USERPROFILE%\.claude\settings.json)に書きます。
"statusLine": {
"type": "command",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File C:/GenerativeAi/Setting/statusline.ps1"
}
スクリプトは、前回作った Setting フォルダに置いています。
コピペで頼む
Claude Code を起動して、次の指示文を貼り付けます。
ステータスラインを設定してください。
表示したいもの:
- 使っているモデル名
- 会話の長さ(コンテキスト)の使用率
- 5時間ごと・1週間ごとの利用上限の使用率と、リセットまでの残り時間
表示の例: [Opus 5.5] ctx 7% | 5h 3% (4h51m) | 7d 59% (2d14h)
条件:
- Windows の PowerShell スクリプトで作り、C:\GenerativeAi\Setting\statusline.ps1 に保存する
- スクリプトは英数字だけで書く(日本語を入れない)
- 受け取るデータは UTF-8 として読む
- 実行ポリシーで止められないように、-ExecutionPolicy Bypass を付けて呼び出す
- ユーザー設定(settings.json)の既存の内容は消さずに、statusLine を追加する
最後に、テスト用のデータを渡して表示を確認してください。
「条件」の後半は、私が実際につまずいたところです。最初から書いておくと、同じ失敗をせずに済みます。
もっと手軽に試すなら、Claude Code に /statusline と打ち、続けて表示したいものを日本語で書くだけでも作ってくれます。
つまずいたところ
どれも Claude が原因を調べて直してくれました。同じ症状が出たときの参考にしてください。
何も表示されない → 実行ポリシー
Windows は、初期設定で PowerShell のスクリプトの実行を止めていることがあります(実行ポリシー)。そのままだとスクリプトが動かず、ステータスラインは空のままです。呼び出すときに -ExecutionPolicy Bypass を付けると動きます。
スクリプトが壊れる → 文字コード
Windows に標準で入っている PowerShell(5.1)は、ファイルの文字コードによっては日本語を正しく読めません。スクリプトの中に日本語のコメントがあると文字化けして、動かなくなりました。そこで、スクリプトは英数字だけで書くことにしました。
急に消えた → 受け取るデータの文字化け
しばらく使っていると、ステータスラインが突然消えました。会話に日本語のタイトルが付いたことで、受け取ったデータが文字化けし、読めなくなっていたのが原因です。データを UTF-8 として読むように直して解決しました。
原因を調べやすくするため、スクリプトは受け取ったデータを statusline-input.json というファイルに保存するようにしてあります。表示がおかしいときは、Claude に「statusline-input.json を見て原因を調べて」と頼めます。
動作の確認
ターミナルで次の1行を実行すると、テスト用のデータで表示を確かめられます。
'{"model":{"display_name":"Opus 5.5"},"context_window":{"used_percentage":42},"rate_limits":{"five_hour":{"used_percentage":30},"seven_day":{"used_percentage":12}}}' | powershell -NoProfile -ExecutionPolicy Bypass -File C:/GenerativeAi/Setting/statusline.ps1
[Opus 5.5] ctx 42% | 5h 30% | 7d 12% と出れば成功です。Claude Code の画面に出ないときは、Claude Code を起動し直してください。
参考:できあがったスクリプト
Claude が作ったスクリプトの全文です。自分で作る場合は、Claude に頼むほうが確実ですが、中身が気になる人のために載せておきます。
# Claude Code status line: [Model] ctx N% | 5h N% | 7d N%
# NOTE: keep this file ASCII-only (PowerShell 5.1 misreads BOM-less UTF-8).
# Read stdin as UTF-8 (default console encoding garbles non-ASCII text such as session_name and breaks the JSON)
$reader = New-Object IO.StreamReader([Console]::OpenStandardInput(), (New-Object Text.UTF8Encoding($false)))
$raw = $reader.ReadToEnd()
# Save the latest input JSON (to check which fields Claude Code sends)
try { [IO.File]::WriteAllText("$PSScriptRoot\statusline-input.json", $raw) } catch {}
try { $j = $raw | ConvertFrom-Json } catch { exit 0 }
$model = $j.model.display_name
if (-not $model) { $model = 'Claude' }
$out = "[$model]"
# Context window usage
$pct = $null
$cw = $j.context_window
if ($cw) {
if ($null -ne $cw.used_percentage) {
$pct = [double]$cw.used_percentage
} elseif ($cw.context_window_size -and $cw.current_usage) {
$u = $cw.current_usage
$tok = [double]$u.input_tokens + [double]$u.cache_creation_input_tokens + [double]$u.cache_read_input_tokens
$pct = $tok / [double]$cw.context_window_size * 100
}
}
if ($null -ne $pct) { $out += " ctx " + [math]::Round($pct).ToString() + "%" }
# Time left until reset (resets_at is Unix seconds), e.g. "2d3h", "1h05m", "12m"
function Format-Remaining($resetsAt) {
if ($null -eq $resetsAt) { return $null }
$now = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
$sec = [long]$resetsAt - $now
if ($sec -lt 0) { $sec = 0 }
$d = [math]::Floor($sec / 86400)
$h = [math]::Floor(($sec % 86400) / 3600)
$m = [math]::Floor(($sec % 3600) / 60)
if ($d -gt 0) { return "${d}d${h}h" }
if ($h -gt 0) { return "${h}h" + $m.ToString('00') + "m" }
return "${m}m"
}
# Plan rate limits (shown only when provided)
$rl = $j.rate_limits
if ($rl) {
foreach ($k in @(@('5h', $rl.five_hour), @('7d', $rl.seven_day))) {
$label = $k[0]; $lim = $k[1]
if ($null -eq $lim -or $null -eq $lim.used_percentage) { continue }
$out += " | $label " + [math]::Round([double]$lim.used_percentage).ToString() + "%"
$left = Format-Remaining $lim.resets_at
if ($left) { $out += " ($left)" }
}
}
[Console]::Out.Write($out)
使ってみて
- 上限で急に止まらなくなった。減り具合を見ながら、重い作業をいつやるか決められる。
- 会話を区切る目安になる。ctx が大きくなってきたら、新しい会話に切り替える。
- モデルの取り違えがない。今どのモデルで動いているかが、ひと目でわかる。
次の記事:起動メニューで迷わず始める
シリーズの一覧:Claude Code の環境づくり まとめ

コメント