「Auto Compacting.....」
Claude Code を使っていると、以下のことが気になります。
- コンテキストは今どれくらい使ったのか? そろそろ
/compactしたほうがいい? - 5 時間の使用枠、あとどれくらい残ってる?
- 今週の枠は大丈夫?
/context や /usage を使えば分かりますが、
毎回コマンドを打つのは面倒ですよね。
そこでステータスライン(入力欄の下の表示領域)に、これらの項目を表示しておくことにしました。
一度設定すれば自動で更新されるので、一回一回聞かなくて済みます。
この記事ではステータスラインの設定手順を簡単に説明します。
ステータスラインの仕組み
Claude Code の入力欄の下に常駐する、1〜数行の表示領域です。
基本的には以下の 3 ステップで表示されます。
- Claude Code がセッション情報を JSON で渡す — モデル名・コンテキスト使用率・使用量・作業ディレクトリなどが、スクリプトの標準入力に流し込まれる
- スクリプトが必要な値を取り出して文字列を組み立てる — ここが自分で書く部分
- その標準出力がそのまま描画される — 色(ANSI エスケープ)も改行も、出力したとおりに反映される
そして 表示が更新されるたびに 1〜3 が実行されるので、値は常に最新になります。
表示項目例
| 表示 | 内容 |
|---|---|
CTX: バー |
コンテキスト消費率 |
Usage: バー |
5時間枠の使用量とリセットまでの時間 |
Weekly: バー |
7日枠の使用量とリセットまでの時間 |
Opus 5 (1M context) |
使用中のモデル |
📁 dev-setup
|
作業ディレクトリ名 |
🌿 main
|
git ブランチ |
設定方法は 2 つ
公式ドキュメント(Set up a status line)が挙げているのは「/statusline コマンドに生成させる」か「自分で書く」かの 2 つです。
どちらも最終的にスクリプトファイルと settings.json の statusLine を作る点は同じです。
1.まず試すなら /statusline
/statusline は組み込みのスラッシュコマンドです。
やりたいことを日本語で投げれば、スクリプトを生成して設定まで済ませてくれます。
/statusline モデル名とコンテキスト使用率をプログレスバーで表示して
ファイル編集の許可を求められたら承認します。消したいときも同じコマンドで、/statusline delete と頼めば settings.json から消してくれます。
以降は自分で書く方法です。表示を細かく詰めたい、設定をリポジトリで管理して他の端末に配りたい、という場合はこちら。
2.自分でセットアップ
手順 1: スクリプトを置く
~/.claude/statusline.sh として保存します。
JSON のパースには jq を使うので、無ければ入れてください。
sudo apt update && sudo apt install -y jq
スクリプトはこちら
#!/usr/bin/env bash
# Claude Code のステータスライン:コンテキスト消費率とレート制限の使用量を表示する
# JSON のパースに jq が必要(Ubuntu: apt install jq)
input=$(cat)
# jq の呼び出し 1 回で必要な値をまとめて取り出す。
# ステータスラインは表示更新ごとに実行されるので、プロセス起動回数がそのまま体感差になる。
# 値が無い/null は空文字にする。呼び出し側の [ -n ... ] で行ごと省くため。
#
# 区切りが空白でなく \x1f(unit separator)なのは、空フィールドを保つため。
# IFS にタブや空白を使うと bash が「連続する区切りを 1 つに詰める・前後を捨てる」扱いをするので、
# rate_limits が無い(= 空文字が続く)ときに値が 1 つずつずれて別の変数に入ってしまう。
# @tsv ではなく join を使うのは、@tsv がタブしか出せないため。
IFS=$'\x1f' read -r cwd model used_pct five_hour_pct five_hour_resets seven_day_pct seven_day_resets <<<"$(
printf '%s' "$input" | jq -r '
# 残り秒 -> "1h23m" / "23m"。null は空文字のまま通す
def hm:
if . == null then ""
else . as $s
| if $s > 3600 then "\($s / 3600 | floor)h\(($s % 3600) / 60 | floor)m"
else "\($s / 60 | floor)m"
end
end;
# 残り秒 -> "2d3h"。1 日を超えない場合は hm に委ねる(7 日枠用)
def dh:
if . == null then ""
else . as $s
| if $s > 86400 then "\($s / 86400 | floor)d\(($s % 86400) / 3600 | floor)h"
else ($s | hm)
end
end;
# resets_at(epoch 秒) -> 残り秒。すでに過ぎていたら 0 に丸める
def left:
if . == null then null else ([. - now, 0] | max | floor) end;
# 小数で来ることがあるので floor で整数に落とす(bash の算術は小数を扱えない)
def pct:
if . == null then "" else (floor | tostring) end;
[ (.workspace.current_dir // .cwd // "") # workspace.current_dir が公式推奨。古い形式の cwd にフォールバック
, (.model.display_name // "")
, (.context_window.used_percentage | pct)
, (.rate_limits.five_hour.used_percentage | pct)
, (.rate_limits.five_hour.resets_at | left | hm)
, (.rate_limits.seven_day.used_percentage | pct)
, (.rate_limits.seven_day.resets_at | left | dh)
] | join("\u001f")
' 2>/dev/null
)"
CYAN=$'\033[01;36m'
YELLOW=$'\033[01;33m'
GREEN=$'\033[00;32m'
ORANGE=$'\033[00;33m'
RED=$'\033[00;31m'
BLUE=$'\033[01;34m'
GRAY=$'\033[00;37m'
BOLD_MAGENTA=$'\033[01;35m'
NC=$'\033[00m'
if [ -n "$cwd" ]; then
dir_name="$(basename "$cwd")"
else
dir_name="$(basename "$PWD")"
fi
git_branch=""
if [ -n "$cwd" ]; then
git_branch=$(git -C "$cwd" --no-optional-locks branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
fi
# 1行目: コンテキスト消費率・モデル・ディレクトリ・ブランチ
out=""
if [ -n "$used_pct" ]; then
filled=$(( used_pct / 10 ))
empty=$(( 10 - filled ))
bar=""
for ((i=0; i<filled; i++)); do bar+="█"; done
for ((i=0; i<empty; i++)); do bar+="░"; done
if [ "$used_pct" -ge 80 ]; then bar_color="$RED"
elif [ "$used_pct" -ge 50 ]; then bar_color="$ORANGE"
else bar_color="$GREEN"
fi
out+="${CYAN}$(printf '%-7s' 'CTX:')${NC} ${bar_color}${bar}$(printf '%3d' ${used_pct})%${NC} ${BLUE}│${NC} "
fi
[ -n "$model" ] && out+="${YELLOW}${model}${NC} "
out+="📁 ${BOLD_MAGENTA}${dir_name}${NC}"
[ -n "$git_branch" ] && out+=" 🌿 ${GRAY}${git_branch}${NC}"
# 2行目: 5時間枠の使用量バー
make_bar() {
local pct=$1
local filled=$(( pct / 10 ))
local empty=$(( 10 - filled ))
local bar=""
for ((i=0; i<filled; i++)); do bar+="█"; done
for ((i=0; i<empty; i++)); do bar+="░"; done
echo "$bar"
}
if [ -n "$five_hour_pct" ]; then
bar=$(make_bar "$five_hour_pct")
if [ "$five_hour_pct" -ge 80 ]; then bar_color="$RED"
elif [ "$five_hour_pct" -ge 50 ]; then bar_color="$ORANGE"
else bar_color="$GREEN"
fi
out+=$'\n'"${CYAN}$(printf '%-7s' 'Usage:')${NC} ${bar_color}${bar}$(printf '%3d' ${five_hour_pct})%${NC}"
[ -n "$five_hour_resets" ] && out+=" (reset: ${five_hour_resets})"
fi
# 3行目: 7日枠の使用量バー
if [ -n "$seven_day_pct" ]; then
bar=$(make_bar "$seven_day_pct")
if [ "$seven_day_pct" -ge 80 ]; then bar_color="$RED"
elif [ "$seven_day_pct" -ge 50 ]; then bar_color="$ORANGE"
else bar_color="$GREEN"
fi
out+=$'\n'"${CYAN}$(printf '%-7s' 'Weekly:')${NC} ${bar_color}${bar}$(printf '%3d' ${seven_day_pct})%${NC}"
[ -n "$seven_day_resets" ] && out+=" (reset: ${seven_day_resets})"
fi
printf "%s" "$out"
実行権限を付けます。 これを忘れると何も表示されず、エラーも出ないので気づきにくいです。
chmod +x ~/.claude/statusline.sh
手順 2: settings.json に登録する
~/.claude/settings.json(ユーザー設定=全プロジェクト共通)に追記します。
{
"statusLine": {
"type": "command",
"command": "bash ~/.claude/statusline.sh"
}
}
動作確認
サンプル JSON を食わせれば、再起動しなくても単体で確認できます。
echo '{
"workspace": {"current_dir": "'"$PWD"'"},
"model": {"display_name": "Opus 5 (1M context)"},
"context_window": {"used_percentage": 42},
"rate_limits": {
"five_hour": {"used_percentage": 55, "resets_at": '$(( $(date +%s) + 2940 ))'},
"seven_day": {"used_percentage": 85, "resets_at": '$(( $(date +%s) + 77940 ))'}
}
}' | bash ~/.claude/statusline.sh
緑・黄・赤の 3 色が出れば成功です。
CTX: ████░░░░░░ 42% │ Opus 5 (1M context) 📁 dev-setup 🌿 main
Usage: █████░░░░░ 55% (reset: 48m)
Weekly: ████████░░ 85% (reset: 21h38m)
表示されないとき
| 症状 | 確認すること |
|---|---|
| 何も出ない | スクリプトに実行権限があるか(ls -l ~/.claude/statusline.sh) |
| 何も出ない |
jq が入っているか(command -v jq) |
| 何も出ない |
settings.json の command のパスが合っているか |
| 値が別の項目の位置に出る | jq の出力と read の変数の対応がずれている |
色が出ずに [01;36m と表示される |
端末が ANSI 非対応 |
Usage / Weekly が出ない |
Pro/Max 以外は rate_limits が渡ってこない(仕様) |
おわりに
この設定をすることで、一目でコンテキストや使用量が把握できるようになりました。
/statusline コマンドを使えば 1 行の指示で試せるので、まずそこからでも。
