こんにちは!
Claude Code を使っていると、「今コンテキストはどれくらい埋まっているんだろう」「このセッション、いくらくらい使っているんだろう」と気になることがあります。
/context や /usage で確認はできますが、作業のたびにコマンドを打つのは少し手間です。ターミナルの下部に、常に出ていてくれると助かるのにな、と思って調べていたところ、Status Line という機能があることがわかりました。
この記事では、Claude Code の Status Line を /statusline で設定して、コンテキスト使用率やコストを常時表示するまでの流れをご紹介します。実際に自分が設定した内容もスクリプトごと載せているので、よかったら参考にしてみてください。
この記事の前提(環境・対象)
| 項目 | 内容 |
|---|---|
| Claude Code | v2.1.252 |
| OS | macOS |
| 情報の基準日 | 2026年9月1日時点(※表示できる項目や設定は変更される可能性があります。最新情報は公式ドキュメントをご確認ください) |
| 対象 | Claude Code を使っていて、コンテキストやコストを常に見たい方 |
Status Line とは
Status Line は、Claude Code の画面下部(プロンプトの上)に表示できるカスタム行です。
会話の更新にあわせてスクリプトが動き、モデル名・コンテキスト使用率・セッションコストなどを常時表示できます。ローカルで動くので、Status Line 自体は API トークンを消費しません。
裏側では、次の2つがセットで動いています。
-
~/.claude/statusline-command.sh…/statuslineが生成・更新する表示用スクリプト -
~/.claude/settings.jsonのstatusLine… そのスクリプトを呼ぶ設定
Claude Code は設定されたコマンドにセッション情報の JSON を渡し、stdout の内容を Status Line として表示します。
なお、同じ仕組みで画面上部に表示できるコミュニティ製ツール(ccstatusline や ccusage の statusline など)もあります。今回は公式の /statusline だけで試します。
何を表示できるか
Status Line に出せる情報は、次のカテゴリに分けられます。
| ほしい情報 | 出せる内容の例 |
|---|---|
| モデル | いま使っているモデル名 |
| 作業場所 | カレントディレクトリ、起動時のプロジェクトディレクトリ、リポジトリ情報 |
| コンテキスト | 使用率・残量、トークン数、キャッシュの内訳 |
| コスト・時間 | セッション費用の目安、経過時間、API 待ち時間、追加/削除行数 |
| レート制限 | 5時間 / 7日ウィンドウの使用率とリセット時刻(Pro / Max など) |
| セッション | セッション名、Claude Code のバージョン |
| 開発状態 | git ブランチや変更状況(スクリプト側で取得)、PR / MR、worktree、vim モード、effort |
「設定できる項目」は大きく2種類あります。
- 表示内容 … 上の表どおり、「何を Status Line に出すか」
-
動き方のオプション …
settings.json側の調整(余白、更新間隔など)
2 は必須ではありません。まずは 1 を /statusline に伝えるだけで十分です。
動き方のオプションを触る場合の主な項目は次のとおりです。
| 項目 | 内容 |
|---|---|
command |
実際に動かすスクリプトやコマンド(/statusline が自動設定) |
padding |
左右の余白(文字数) |
refreshInterval |
N 秒ごとの再実行。時計表示や、アイドル中も更新したいとき向け |
hideVimModeIndicator |
自前で vim モードを出すときの二重表示防止 |
詳細な JSON フィールド名は 公式ドキュメント に一覧があります。
/statusline で設定してみた
Claude Code 上で、表示したい内容を自然言語で伝えます。
/statusline モデル名とコンテキスト使用率、セッションコストを表示して。コンテキストはプログレスバー付きで
これだけで、次のことが自動で行われます。
-
~/.claude/statusline-command.shが生成(または更新)される -
~/.claude/settings.jsonのstatusLineが、そのスクリプトを指すように更新される - 画面下部に Status Line が出る
今回の環境では、settings 側は次のようになりました。
{
"statusLine": {
"type": "command",
"command": "bash ~/.claude/statusline-command.sh"
}
}
途中でファイル編集の許可を求められたら承認します。
表示を変えたいときも、同じように頼めば大丈夫です。/statusline が statusline-command.sh を書き換えてくれます。
/statusline ディレクトリ名と git ブランチも追加して
/statusline 1行にまとめて、色付きにして
配色や並びだけ自分で直したいときは、~/.claude/statusline-command.sh を直接編集しても構いません。
消したいときは次のようにします。
/statusline clear
見た目
設定前と設定後の見た目です。

図2. /statusline でモデル・コンテキスト・コストを表示
画面下部に、作業中のモデルやコンテキスト使用率が常に見えるようになりました。/context を打たなくても「そろそろコンパクトした方がよさそう」と判断しやすくなります。
実際に設定した最終形
ここまでの流れで実際に自分が組み上げた Status Line を、実例として置いておきます。
最終的な表示
2行構成にして、こんな見た目になりました。
各項目の説明
| 表示 | 内容 |
|---|---|
Dir: |
カレントディレクトリ名 |
Branch: |
git ブランチ名。末尾の +3 は未コミット・未追跡の変更ファイル数(git status --porcelain の行数)。クリーンなら非表示 |
Model: |
使用中のモデル名 |
Time: |
セッションの経過時間(1h23m のような表記) |
Diff: |
セッション中に増減した行数(緑が追加、赤が削除) |
Cost: |
セッションの推定コスト(USD) |
Ctx: |
コンテキスト使用率とプログレスバー(緑→黄→赤で閾値表示) |
5h: / 7d:
|
5時間 / 週次のレート制限使用率とプログレスバー、()内はリセット時刻 |
1行目に「今どこで何をしているか」、2行目に「上限にどれだけ近いか」をまとめる形に落ち着きました。
statusline-command.sh の中身
実際に使っているスクリプトを、この記事の一番最後(付録スクリプト全文)に全文掲載しています。コピーしてそのまま使えます。
同じ設定にするには
以下の方法で反映できます。
方法1: 手動で配置する
- 記事末尾のスクリプトをコピーして
~/.claude/statusline-command.shとして保存する -
~/.claude/settings.jsonに次の設定を追記する(すでにstatusLineがある場合は書き換える)
{
"statusLine": {
"type": "command",
"command": "bash ~/.claude/statusline-command.sh"
}
}
- Claude Code を再起動するか、次のプロンプトを送信すると反映される
方法2: チャットで頼む
Claude Code 上で、記事末尾のスクリプトを貼り付けて一言頼むだけでも設定できます。
/statusline このスクリプトと同じ内容で status line を設定して
(↑に記事末尾のスクリプトを貼り付け)
/statusline が ~/.claude/statusline-command.sh の作成と ~/.claude/settings.json の更新をまとめてやってくれます。
カスタマイズしたくなったら
このスクリプトはあくまで一例なので、自分好みに変えたくなったら、そのまま Claude Code のチャットに指示を出すだけで調整できます。例えばこんな感じです。
/statusline Branchの表示はいらないから消して
/statusline CtxとCostの表示順を入れ替えて
/statusline 色をもっとシンプルにして
自分でシェルスクリプトを読み書きできなくても、日本語で「こうしたい」と伝えるだけで statusline-command.sh を書き換えてくれるので、気軽にいじれます。
まとめ・所感
よかった点
-
/contextや/usageを打たなくても、コンテキストとコストを常時確認できる -
/statuslineに日本語で伝えるだけで、statusline-command.shの生成から settings 更新まで完結する - 細かく直したくなったら、生成された
~/.claude/statusline-command.shを編集すればよい - Status Line 自体はローカル実行なので、表示のために API を追加消費しない
注意点
- セッション開始直後など、初回 API 応答前はコンテキストやコストが空になることがある
- Status Line を有効にすると、フッターの一部キーボードヒントが非表示になる
- Status Line は CLI(ターミナル)専用の機能。VS Code 拡張・JetBrains 拡張・デスクトップアプリ・Web 版(claude.ai/code)には表示されない
こんな方におすすめ
- Claude Code のコンテキスト残量を意識しながら長く作業したい方
- セッションコストを感覚ではなく数字で把握したい方
- ターミナル下部にモデル名や作業ディレクトリを常時出したい方
「気になったらコマンドで確認する」から、「見えている前提で作業する」に変わるのは、思ったより快適でした。
記事の最後に載せているスクリプトをそのまま使ってもらっても大丈夫です。
よかったら参考にしてみてください。
参考リンク
付録スクリプト全文
「実際に設定した最終形」で紹介したスクリプトの全文です。~/.claude/statusline-command.sh にそのまま保存するか、Claude Code のチャットに貼り付けるだけで設定できます。
#!/bin/bash
# Claude Code status line (2 lines)
# Line 1: current dir | git branch (+dirty count) | model name
# | session duration | lines added/removed | session cost
# Line 2: context usage (with progress bar) | 5h rate limit (with progress bar)
# | 7d rate limit (with progress bar)
input=$(cat)
model=$(printf '%s' "$input" | jq -r '.model.display_name // "Claude"')
used_pct=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // empty')
cost=$(printf '%s' "$input" | jq -r '.cost.total_cost_usd // empty')
duration_ms=$(printf '%s' "$input" | jq -r '.cost.total_duration_ms // empty')
lines_added=$(printf '%s' "$input" | jq -r '.cost.total_lines_added // empty')
lines_removed=$(printf '%s' "$input" | jq -r '.cost.total_lines_removed // empty')
current_dir=$(printf '%s' "$input" | jq -r '.workspace.current_dir // .cwd // empty')
five_hour_pct=$(printf '%s' "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
five_hour_reset=$(printf '%s' "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
seven_day_pct=$(printf '%s' "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
seven_day_reset=$(printf '%s' "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')
RESET="\033[0m"
DIM="\033[2m"
CYAN="\033[36m"
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
GRAY="\033[90m"
MAGENTA="\033[35m"
# Renders a 10-segment progress bar (colored by thresholds) for a given
# integer percentage. Result is written to the global $bar_out variable.
render_bar() {
pct_int=$1
width=10
filled=$(( pct_int * width / 100 ))
[ "$filled" -gt "$width" ] && filled=$width
[ "$filled" -lt 0 ] && filled=0
empty=$(( width - filled ))
if [ "$pct_int" -ge 80 ]; then
bar_color=$RED
elif [ "$pct_int" -ge 50 ]; then
bar_color=$YELLOW
else
bar_color=$GREEN
fi
filled_str=""
i=0
while [ "$i" -lt "$filled" ]; do filled_str="${filled_str}█"; i=$((i+1)); done
empty_str=""
i=0
while [ "$i" -lt "$empty" ]; do empty_str="${empty_str}░"; i=$((i+1)); done
bar_out="${bar_color}${filled_str}${GRAY}${empty_str}${RESET}"
}
# Formats a unix epoch (seconds) as an absolute local-time "reset at" string,
# e.g. "15:00" if it resets later today, or "9/3 15:00" if it resets on a
# different day. Result is written to $reset_out.
format_reset() {
reset_epoch=$(printf '%.0f' "$1" 2>/dev/null)
[ -z "$reset_epoch" ] && { reset_out=""; return; }
time_str=$(date -r "$reset_epoch" +%H:%M 2>/dev/null)
[ -z "$time_str" ] && { reset_out=""; return; }
today_str=$(date +%Y-%m-%d)
reset_day_str=$(date -r "$reset_epoch" +%Y-%m-%d 2>/dev/null)
if [ "$reset_day_str" = "$today_str" ]; then
reset_out="$time_str"
else
md_str=$(date -r "$reset_epoch" +%m/%d 2>/dev/null)
month=${md_str%%/*}
day=${md_str##*/}
month=$((10#$month))
day=$((10#$day))
reset_out="${month}/${day} ${time_str}"
fi
}
# Formats a duration in milliseconds as a short string, e.g. "45m" if under
# an hour, or "1h23m" if an hour or more. Result is written to $duration_out.
format_duration() {
ms=$(printf '%.0f' "$1" 2>/dev/null)
[ -z "$ms" ] && { duration_out=""; return; }
total_min=$(( ms / 60000 ))
[ "$total_min" -lt 0 ] && total_min=0
hours=$(( total_min / 60 ))
mins=$(( total_min % 60 ))
if [ "$hours" -gt 0 ]; then
duration_out="${hours}h${mins}m"
else
duration_out="${mins}m"
fi
}
# Current directory name
if [ -n "$current_dir" ]; then
dir_name=$(basename "$current_dir")
printf "${DIM}Dir:${RESET} ${GREEN}%s${RESET}" "$dir_name"
fi
# Git branch name
if [ -n "$current_dir" ]; then
branch=$(git --no-optional-locks -C "$current_dir" branch --show-current 2>/dev/null)
if [ -n "$branch" ]; then
printf " ${DIM}|${RESET} ${DIM}Branch:${RESET} ${MAGENTA}%s${RESET}" "$branch"
# Dirty state: number of changed/untracked files (git status --porcelain)
dirty_count=$(git --no-optional-locks -C "$current_dir" status --porcelain 2>/dev/null | wc -l | tr -d ' ')
if [ -n "$dirty_count" ] && [ "$dirty_count" -gt 0 ]; then
printf " ${YELLOW}+%d${RESET}" "$dirty_count"
fi
fi
fi
# Model name
printf " ${DIM}|${RESET} ${DIM}Model:${RESET} ${CYAN}%s${RESET}" "$model"
# Session elapsed time
if [ -n "$duration_ms" ]; then
format_duration "$duration_ms"
if [ -n "$duration_out" ]; then
printf " ${DIM}|${RESET} ${DIM}Time:${RESET} ${DIM}%s${RESET}" "$duration_out"
fi
fi
# Lines added/removed
if [ -n "$lines_added" ] || [ -n "$lines_removed" ]; then
added=${lines_added:-0}
removed=${lines_removed:-0}
printf " ${DIM}|${RESET} ${DIM}Diff:${RESET} ${GREEN}+%d${RESET}${DIM}/${RESET}${RED}-%d${RESET}" "$added" "$removed"
fi
# Session cost
if [ -n "$cost" ]; then
printf " ${DIM}|${RESET} ${DIM}Cost:${RESET} ${DIM}\$%.4f${RESET}" "$cost"
fi
printf "\n"
line2_started=0
# Context usage with progress bar
if [ -n "$used_pct" ]; then
pct_int=$(printf '%.0f' "$used_pct")
render_bar "$pct_int"
printf "${DIM}Ctx:${RESET} %b ${DIM}%d%%${RESET}" "$bar_out" "$pct_int"
line2_started=1
fi
# 5-hour rate limit usage with progress bar (only shown when reported, e.g.
# for Claude.ai Pro/Max subscribers or behind a gateway spend limit)
if [ -n "$five_hour_pct" ]; then
pct_int=$(printf '%.0f' "$five_hour_pct")
render_bar "$pct_int"
reset_str=""
if [ -n "$five_hour_reset" ]; then
format_reset "$five_hour_reset"
[ -n "$reset_out" ] && reset_str=" ${DIM}(rst ${reset_out})${RESET}"
fi
[ "$line2_started" -eq 1 ] && printf " ${DIM}|${RESET} "
printf "${DIM}5h:${RESET} %b ${DIM}%d%%${RESET}%b" "$bar_out" "$pct_int" "$reset_str"
line2_started=1
fi
# 7-day rate limit usage with progress bar (only shown when reported)
if [ -n "$seven_day_pct" ]; then
pct_int=$(printf '%.0f' "$seven_day_pct")
render_bar "$pct_int"
reset_str=""
if [ -n "$seven_day_reset" ]; then
format_reset "$seven_day_reset"
[ -n "$reset_out" ] && reset_str=" ${DIM}(rst ${reset_out})${RESET}"
fi
[ "$line2_started" -eq 1 ] && printf " ${DIM}|${RESET} "
printf "${DIM}7d:${RESET} %b ${DIM}%d%%${RESET}%b" "$bar_out" "$pct_int" "$reset_str"
line2_started=1
fi
printf "\n"

