この記事についてClaude(Anthropic)との共同編集により作成されました。
要約
- ターミナルのClaude Codeだと5時間/7日のリミット消化率がどこにも出ない。確認のたびに公式アプリを開き直していた
- ステータスライン機能を入れたら、その往復が丸ごと消えた。ローカル実行なのでAPIトークンは一切消費しない
- 設定は
/statuslineで叩き台を作り、あとはClaudeに直させるのが一番速い。筆者も2〜3回言い直して今の形にした。他人の.shを探してコピペするより早く自分好みになるrate_limitsはPro/Maxのサブスク契約でしか降ってこない。APIキー課金だと表示されないので// emptyのフォールバックが要る
はじめに
筆者が検索窓に打ち込んだワードは「claude code 使用量 ターミナル 確認」だった。
Claude Codeはターミナルで使っている。エディタでもブラウザでもなく、ターミナルがメインだ。それ自体には何の不満もない。ただ一点、今どれくらいリミットを消化したのかが画面上のどこにも出ない。
Claude Codeには5時間のローリングウィンドウと7日間のウィンドウ、2種類のリミットがある。長めのセッションを回していると「これ、5時間枠あとどれくらい残ってるんだ」が気になり始める。気になったところで、ターミナルには何も出ていない。
そこで筆者が何をしていたかというと、公式のデスクトップアプリを開いて、設定から使用量の画面を出し、それを表示させたまま放置していた。ターミナルで作業しながら、数字を見たいときだけそっちのウィンドウに視線を移す。ウィンドウを1枚、数字を見るためだけに常駐させていたわけである。
これが地味に面倒だった。作業しているのはターミナルなのに、状態を知るための情報だけ別のアプリにある。この分断が解消されたのがステータスライン機能だった。
ステータスラインが解決すること
ステータスラインは、Claude Codeの下部で自分の書いたシェルスクリプトを実行し、その標準出力をそのまま表示する仕組みだ^1。組み込みのフッターバッジを置き換えるのではなく、その上に独立した行としてレンダリングされる。
仕組みはシンプルで、Claude Codeがスクリプトの標準入力にセッション情報のJSONを流し込む。スクリプト側はそこから欲しいものを抜いて、好きな形に整形してechoするだけ。
今回の目的にとって決定的なのは、そのJSONにレート制限が含まれていることだった^1。
"rate_limits": { "five_hour": { "used_percentage": 23.5, "resets_at": 1738425600 }, "seven_day": { "used_percentage": 41.2, "resets_at": 1738857600 }}つまり、アプリを開いて見ていたあの数字は、ターミナル側にもちゃんと来ていた。ただ表示していなかっただけだった。
もうひとつ、推す理由として大きいのがステータスラインはローカルで実行され、APIトークンを消費しないという点だ^1。これは公式ドキュメントに明記されている。常時表示される情報を増やしても、それ自体がリミットを削ることはない。使用量を見るための仕組みが使用量を食っていたら本末転倒なので、ここは安心して盛れる。
まず /statusline で叩き台を作る
手順としては、公式ドキュメントを一度読んで、/statuslineを叩くのが正解だと思う。
/statuslineは自然言語の指示を受け付けるスラッシュコマンドで、Claude Codeが~/.claude/にスクリプトファイルを生成し、settings.jsonの更新まで自動でやってくれる^1。
/statusline show model name and context percentage with a progress bar日本語で書いても通る。
/statusline モデル名とディレクトリ、コンテキスト使用率をプログレスバーで出してこれを打った時点で、もう動くステータスラインが手元にできている。公式ドキュメントに載っている出来上がりの例がこれだ^1。

※画像はClaude Code公式ドキュメント^1より引用
1行目にモデル名とディレクトリとブランチ、2行目にコンテキスト使用率のバーとコストと経過時間。ここまでは公式の手順そのままで、特に工夫は要らない。
なお、消したくなったときも同じコマンドでいい。/statusline deleteのように削除を指示すれば設定から外れる^1。
そこからClaudeに直させる(.shをコピーするより速い)
ここからが本題で、この記事で一番言いたいところでもある。
ステータスラインの設定について調べると、たいてい「このスクリプトをコピーして~/.claude/statusline.shに置いてください」という情報にたどり着く。公式ドキュメントにもBash/Python/Node.jsの完成品サンプルが並んでいる。それをコピペするのが普通のやり方だ。
でも実際にやってみて、コピペして自分で調整するより、Claudeに直させるほうが速かった。すでに/statuslineが生成したスクリプトが~/.claude/にあるので、あとはそのファイルを指して「こう直して」と言うだけでいい。
ただし、一発で今の形になったわけではない。実際には2〜3回やり取りしている。ここは正直に書いておきたい。
まず本命の5h/7dを足させた。
~/.claude/statusline-command.sh に5時間と7日のリミット消化率を足して。どっちもプログレスバーでこれで数字自体は出た。ただしリミット系が独立した3行目に置かれて、ステータスラインが3行になった。情報としては正しいのだが、ターミナルの下部が3行も占有されるのは嵩張る。使用量まわりはもともと2行目にあるので、そこに畳んでしまえばいい。
リミットの行が嵩張るから、独立した3行目じゃなくて2行目の右側に続けて出してそのあとも、実際に表示を眺めながら気になったところを潰していった。バーが全部同じ色だと「やばい」が一目で分からないし、ディレクトリ名は周りの文字に埋もれて視線が引っかからない。
バーの色を使用率で変えて。70%未満は緑、70〜89%は黄、90%以上は赤ディレクトリ名を青くして。フルパスじゃなくてフォルダ名だけでいい3行を2行に畳んだのも、フォルダ名を青くしたのも、最初から狙って設計したものではなく、出てきたものを見て「ここが気に入らない」と言い直した結果である。この往復が軽いことが、そのまま速さになっている。
なぜコピペより速いのか、理由は3つある。
1. JSONのフィールド名を覚えなくていい
context_window.used_percentage、cost.total_duration_ms、rate_limits.seven_day.used_percentage。この手のパス名を正確に思い出しながらjqのクエリを書くのは、地味に消耗する作業だ。「7日のリミット」と日本語で言えば正しいフィールドに変換される、というだけでかなり違う。
2. 不在フィールドの処理を勝手にやってくれる
これが実は一番大きい。rate_limitsはClaude.aiのサブスクライバー(Pro/Max)で、かつセッションの最初のAPIレスポンスの後にしか存在しない^1。素直に書くとセッション開始直後に表示が崩れる。
正しくは// emptyでフォールバックし、値がないときはセパレータごと出さない、という書き方が要る。
# "// empty" は rate_limits が不在の場合、出力を生成しませんFIVE_H=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')こういう「知らないと踏む」条件を、指示していないのに勝手に織り込んでくる。自分でサンプルをコピペしていたら、たぶん一度は崩れた表示を見てから気づくことになったと思う。
3. 気に入らなければ差分で言い直せる
前述のとおり、筆者の場合も2〜3回の往復で今の形に落ち着いた。ここがコピペ方式との一番の差だと思う。
コピペ方式だと、微調整のたびに自分でBashを読んで書き換えることになる。printf -vでパディングを作って${var// /█}で置換する、みたいなコードを毎回追うのはしんどい。1回目はやる気が出ても、2回目・3回目はたいてい面倒になって諦める。
「バーを10文字じゃなく15文字にして」「経過時間は要らないから消して」と1行言うだけで済むなら、そっちのほうがいい。ステータスラインは自分が毎日見るものなので、細かい好みが必ず出る。しかもその好みは、実際に表示されたものを見るまで自分でも分からない。最初の完成度より、直すコストの低さのほうが効いてくるのはそのためだ。
正直に言うと、他人の.shを探してコピペする手順を書くより、この「Claudeに投げろ」を書いたほうが読んだ人の役に立つと思っている。
できあがった設定
参考までに、筆者の環境で最終的に落ち着いた形を全部載せておく。ただし前述のとおり、これをコピペするより自分のClaudeに作らせたほうが速いと思う。あくまで「こういうものができる」という例として見てほしい。
~/.claude/settings.jsonはこれだけ。
{ "statusLine": { "type": "command", "command": "bash ~/.claude/statusline-command.sh" }}本体の~/.claude/statusline-command.sh。コメントもClaudeが書いたものをそのまま残している。
#!/bin/bashinput=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')DIR=$(echo "$input" | jq -r '.workspace.current_dir')COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
CYAN='\033[36m'; BLUE='\033[38;5;39m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; RESET='\033[0m'
# 使用率(0-100)からバーの色を選びますbar_color() { if [ "$1" -ge 90 ]; then printf '%s' "$RED" elif [ "$1" -ge 70 ]; then printf '%s' "$YELLOW" else printf '%s' "$GREEN"; fi}
# 使用率(0-100)から10文字のバーを組み立てますmake_bar() { local filled=$(($1 / 10)) empty=$((10 - $1 / 10)) fill pad printf -v fill "%${filled}s"; printf -v pad "%${empty}s" printf '%s' "${fill// /█}${pad// /░}"}
MINS=$((DURATION_MS / 60000)); SECS=$(((DURATION_MS % 60000) / 1000))
BRANCH=""git rev-parse --git-dir > /dev/null 2>&1 && BRANCH=" | 🌿 $(git branch --show-current 2>/dev/null)"
# カレントディレクトリのフォルダ名だけを表示しますDIR_DISP="${DIR##*/}"echo -e "${CYAN}[$MODEL]${RESET} 📁 ${BLUE}${DIR_DISP}${RESET}$BRANCH"
# "// empty" は rate_limits が不在の場合、出力を生成しませんFIVE_H=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')WEEK=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
LIMITS=""if [ -n "$FIVE_H" ]; then P=$(printf '%.0f' "$FIVE_H") LIMITS="5h $(bar_color "$P")$(make_bar "$P")${RESET} ${P}%"fiif [ -n "$WEEK" ]; then P=$(printf '%.0f' "$WEEK") LIMITS="${LIMITS:+$LIMITS | }7d $(bar_color "$P")$(make_bar "$P")${RESET} ${P}%"fi
COST_FMT=$(printf '$%.2f' "$COST")# レート表示は独立した行ではなく、2行目の右側に続けて表示しますecho -e "ctx $(bar_color "$PCT")$(make_bar "$PCT")${RESET} ${PCT}% | ${YELLOW}${COST_FMT}${RESET} | ⏱️ ${MINS}m ${SECS}s${LIMITS:+ | $LIMITS}"
exit 0終盤にある# レート表示は独立した行ではなく、2行目の右側に続けて表示しますというコメントが、さっき書いた3行→2行の調整の痕跡である。言い直した内容がそのままコメントとして残るので、あとから読んでも「なぜこうなっているか」が分かるのは地味にありがたい。
jqが要るので、入っていなければ先に入れておく。
brew install jqこんな表記になる
5h/7dのバーを足した時点の見た目がこれ(このあとさらに手を入れるので、最終形は記事の後半で載せる)。

色を落として構造だけ書くとこうなっている。
[Opus 5 (1M context)] 📁 blog_workspace | 🌿 mainctx ░░░░░░░░░░ 8% | $2.16 | ⏱️ 14m 2s | 5h ░░░░░░░░░░ 3% | 7d ██████░░░░ 65%1行目が「今どこにいるか」、2行目が「今どれだけ使ったか」という分担になっている。読み方は次のとおり。
| 表示 | 中身 | 元のフィールド |
|---|---|---|
[Opus 5 (1M context)] | 現在のモデル(シアン) | model.display_name |
📁 blog_workspace | 作業ディレクトリ名だけ(青) | workspace.current_dir |
🌿 main | gitブランチ。リポジトリ外では消える | git branch --show-current |
ctx バー | コンテキストウィンドウ使用率 | context_window.used_percentage |
$2.16 | セッションの推定コスト(黄) | cost.total_cost_usd |
⏱️ 14m 2s | セッション開始からの経過時間 | cost.total_duration_ms |
5h バー | 5時間ウィンドウの消化率 | rate_limits.five_hour.used_percentage |
7d バー | 7日ウィンドウの消化率 | rate_limits.seven_day.used_percentage |
3つのバーは共通の閾値で色が変わる。
| 使用率 | 色 |
|---|---|
| 〜69% | 緑 |
| 70〜89% | 黄 |
| 90%〜 | 赤 |
結果として何が起きたかというと、アプリを開かなくなった。それだけといえばそれだけだが、体感の差は大きい。「今5h枠が6割か、じゃあもう一本重いタスク回せるな」という判断が、視線を動かさずにできる。
使ってみて分かった注意点
いいことばかり書いてもフェアではないので、引っかかった点も並べておく。
rate_limitsはサブスク限定
繰り返しになるが、rate_limitsはClaude.aiのサブスクライバー(Pro/Max)でしか降ってこない^1。APIキー課金で使っている場合は存在しないので、5h/7dの表示は出ない。この記事の一番おいしい部分が丸ごと消えるので、そこは先に書いておく。
バーは10分割なので細かい変化は見えない
make_barが使用率を10で割っているだけなので、1マス=10%。上のスクショでもctxが8%、5hが3%で、どちらもバーは1マスも埋まっていない。逆に95%でも9マスまでしか行かない。細かい変化はマス数ではなく数値と色で見ることになる。もっと解像度が欲しければ「バーを20文字にして」と言えばいい。
更新はイベント駆動
スクリプトが走るのは、新しいアシスタントメッセージの後、/compact完了後、パーミッションモード変更時、vimモード切替時で、300msでデバウンスされる^1。つまりClaudeが黙っている間は更新されない。時計のような時間ベースの表示を足したいなら、refreshInterval(秒、最小1)を設定して固定タイマーでも再実行させる必要がある。
{ "statusLine": { "type": "command", "command": "bash ~/.claude/statusline-command.sh", "refreshInterval": 5 }}重い処理を入れると表示が止まる
スクリプトが遅いと、完了するまでステータスラインの更新がブロックされる^1。git statusやgit diffは大きいリポジトリだと普通に重いので、盛るならsession_idをキーにした一時ファイルへのキャッシュが公式推奨になっている。筆者のスクリプトはgit branch --show-currentだけなので今のところ素で問題ない。
ワークスペースを信頼していないと動かない
ステータスラインはシェルコマンドを実行するので、フックと同じトラストのゲートがかかる。そのディレクトリの信頼ダイアログを受け入れていないと、出力の代わりにstatusline skipped · restart to fixと出る^1。
出力は短く保つ
MCPサーバのエラーや自動更新の通知は、ステータスラインと同じ行の右側に出る^1。欲張って情報を詰め込むと、狭いターミナルでは通知に押されて切り詰められる。筆者の2行構成でもそこそこ長いので、これ以上は足していない。
次に足すとしたら
まだ使っていないフィールドもけっこうある^1。同じ要領で「ここにこれ足して」と言えば済むので、気が向いたら足そうと思っているものを挙げておく。
| フィールド | 何が出せるか |
|---|---|
rate_limits.five_hour.resets_at | リミットがリセットされるUnix時刻。「あと何分でリセット」を出せる |
effort.level | 現在の推論努力レベル(low〜max) |
pr.number / pr.review_state | 現在のブランチのオープンPR番号とレビュー状態 |
agent.name | --agent指定時のエージェント名 |
session_name | --nameや/renameで付けたセッション名 |
workspace.repo.owner / .name | originから解析されたリポジトリ識別子 |
個人的にはresets_atが一番効きそうだと思っている。消化率だけだと「あとどれくらい待てば戻るのか」が分からないので、そこが出れば判断がもう一段速くなる。
……と書いたそばから足したので、その結果を次に載せておく。
追記:effort levelとリセット残り時間を足した最終形
上の表で挙げたresets_atとeffort.levelを、実際に取り込んでみた。これも同じで、ファイルを指して「ここにこれ足して」と言っただけである。何を足すかだけでなく、どこに出すかまで指定するのがコツで、置き場所を任せると勝手に行が増えたりする。
~/.claude/statusline-command.sh に effort level を足して。1行目のモデル名の隣に5h/7d はリセットまでの残り時間も出して。それぞれの隣に言ったのはこれだけである。結果がこれ。

[Opus 5 (1M context)] [high] 📁 blog_workspace | 🌿 mainctx ██░░░░░░░░ 16% | $10.27 | 5h (4h33m) ░░░░░░░░░░ 7% | 7d (2h53m) ██████░░░░ 67%見ての通り、[high]のブラケットも(4h33m)の括弧もこちらは指示していない。指定したのは「何を」と「どこに」だけで、見せ方は既存の表記に馴染む形で勝手に整えてきた。ここは任せてよかったところである。場所さえ決めておけば、表記の細部はだいたい良い感じに寄せてくる。
変わったのは3点。
1. モデルの隣に[high]が出るようになった
effort.levelをそのまま黄色で並べている。/effortで変えたときにもライブで追従するので、「今どの努力レベルで回しているか」を意識しないまま重い設定で走らせ続ける事故が減る。
EFFORT=$(echo "$input" | jq -r '.effort.level // empty')echo -e "${CYAN}[$MODEL]${RESET}${EFFORT:+ ${YELLOW}[$EFFORT]${RESET}} 📁 ${BLUE}${DIR_DISP}${RESET}$BRANCH"effortはモデルが推論努力パラメータに対応していないと存在しない^1ので、ここも// emptyで受けて、無ければ${EFFORT:+...}ごと出さないようにしてある。
2. 5h (4h33m)のようにリセットまでの残り時間が出る
resets_atはUnixエポック秒なので、現在時刻との差をXh00m形式に整形している。
NOW=$(date +%s)
# resets_at(エポック秒)から「残り時間」を "Xh Ym" 形式に変換しますfmt_remaining() { local diff=$(( $1 - NOW )) if [ "$diff" -lt 0 ]; then diff=0; fi local h=$((diff / 3600)) m=$(((diff % 3600) / 60)) printf '%dh%02dm' "$h" "$m"}これが想像以上に効いた。消化率だけだと「7%か、まだ余裕だな」で終わるが、残り時間が並ぶと**「あと4時間半でこの枠は戻る」まで一目で分かる**。枠を使い切りそうなときに、粘るか待つかの判断が速くなる。
なお、この表示はrefreshIntervalを設定していないとイベント駆動でしか更新されない。Claudeが黙っている間、残り時間は止まったままになる。厳密な残量を追いたいならrefreshIntervalを足すべきだが、筆者は「だいたい何時間」が分かれば十分なので入れていない。
3. 経過時間(⏱️)を消した
残り時間を足したぶん2行目が長くなったので、優先度の低いものを落とした。セッションの経過時間は、あって困りはしないが見て何かを判断していたわけでもない。
スクリプトのコメントも# レート表示は独立した行ではなく、2行目の右側に続けて表示します(時計表示は削除)という具合に、消したことごと記録されている。
読み方に足すとこうなる。
| 表示 | 中身 | 元のフィールド |
|---|---|---|
[high] | 現在の推論努力レベル(黄) | effort.level |
5h (4h33m) | 5時間枠がリセットされるまでの残り | rate_limits.five_hour.resets_at |
7d (2h53m) | 7日枠がリセットされるまでの残り | rate_limits.seven_day.resets_at |
結局ここでも、足す・消す・並べ替えるを言葉で回しただけで最終形にたどり着いている。自分でBashを書き換えていたら、経過時間を消すかどうかで悩んで、たぶんそのまま3行に戻していたと思う。
まとめ
- ターミナル運用でリミット残量が見えない問題は、ステータスラインで完全に解決する。使用量を見るためにアプリを開く生活は終わる
- ステータスラインはローカル実行でAPIトークンを消費しない。表示を盛ってもリミットは減らない
- まず
/statuslineで叩き台を作り、あとは生成されたスクリプトをClaudeに直させる。他人の.shを探すより速く、自分好みになる - 一発で決まると思わなくていい。3行を2行に畳んだのも色分けも、出てきたものを見て言い直した結果。この往復が軽いことが速さの正体
rate_limitsはPro/Maxのサブスク限定かつ最初のAPIレスポンス後。// emptyのフォールバックが必須- スクリプトが遅いと表示が止まる。重いgit操作を入れるならキャッシュを噛ませる
resets_atは消化率とセットで効く。「7%」だけより「7%・あと4時間半で戻る」のほうが判断が速い
一番よかったのは、表示される情報が増えたことそのものではなく、状態を知るためのコンテキストスイッチが消えたことだった。作業している画面に、判断に必要な数字が全部載っている。たったそれだけのことなのだが、思っていたよりずっと効いた。
設定方法を検索して誰かの.shを探すより、公式ドキュメントを一度眺めてから/statuslineに投げるほうが早い。まだ入れていない人は、今日中に終わる作業なので試してみてほしい。
参考文献
- Claude Code 公式ドキュメント「ステータスラインをカスタマイズする」 https://code.claude.com/docs/ja/statusline
- Claude Code 公式ドキュメント「Claude Code settings」 https://code.claude.com/docs/ja/settings