◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-05-02中級

Claude Code のステータスラインを自分好みに作り変える — モデル名・残コンテキスト・Git 状態を1行で見せる設定例

現在のモデル・残コンテキスト・Gitブランチを1行で確認できるClaude Codeのステータスライン設定例を紹介します。シェルスクリプトとNode.jsの両方の実装、エラーを握りつぶして会話を壊さない工夫、アスキーで描く残コンテキストバー、プロジェクトごとの表示切り替えまで扱います。

claude-code132status-linecustomizationproductivity11settings6

長時間のコーディングセッションをこなしていると、「いま自分はどのモデルで動かしているのか」「コンテキストはあとどれくらい残っているのか」「いまどのブランチにいるのか」を、画面のどこかでさっと確認したくなる場面があります。Claude Code には、こうした情報をプロンプト下部に固定表示できる ステータスライン という仕組みがあるのですが、デフォルトの表示はかなり控えめで、はじめて触る方は「これは何を見せるための機能なのだろう?」と感じるかもしれません。

私は普段、4 つのドメインを横断して Claude Code を使っているのですが、モデルを Sonnet と Opus で切り替えながら作業することが多く、いまどのモデルが選ばれているかをひと目で確認できないと、料金感覚が狂いやすいと感じています。ここではそうした実用視点で ステータスラインに何を出すと役に立つのか、そして どう書けば壊れにくいのか を、シェルスクリプトと Node.js の 2 通りで具体的にまとめておきます。

ステータスラインとは何か — まず仕組みを 1 分で押さえる

Claude Code のステータスラインは、ユーザーが指定した 任意の実行可能ファイル を、Claude Code が会話の節目ごとに呼び出して、その標準出力をそのまま表示する仕組みです。コマンドはセッション情報を JSON として標準入力から受け取り、表示したい 1 行(または ANSI エスケープ付きの装飾文字列)を標準出力に書き出すだけ、という非常にシンプルな設計になっています。

設定方法は ~/.claude/settings.json(または各プロジェクトの .claude/settings.json)に、次のように statusLine フィールドを追加するだけです。

{
  "statusLine": {
    "type": "command",
    "command": "/Users/you/.claude/statusline.sh",
    "padding": 0
  }
}

type は現状 command のみ、command は実行ファイルへの絶対パス、padding は出力前後の空白制御です。padding: 0 にしておくと、後述するスクリプト側で自由にレイアウトを組めるようになります。

なぜカスタムステータスラインを作る価値があるのか

「ターミナルのプロンプトを派手にする」のと似た話に聞こえるかもしれませんが、私が実際に使ってみて、3 つの場面で明確にメリットを感じました。

ひとつ目は モデルの取り違え防止 です。Opus と Sonnet を切り替える運用をしていると、課金額の桁が一段違ってくるため、「いつの間にか Opus のままで雑談していた」事故を避けたくなります。ふたつ目は コンテキスト残量の早期警告 です。残量が少なくなると、ある時点を境に応答が急にぎこちなくなるのですが、ステータスラインに残量バーを出しておくと、/compact の発動タイミングを逃しにくくなります。みっつ目は 作業ブランチの可視化 で、複数の worktree を行き来する人ほど効きます。

逆に、これらを必要としていない場面では、無理にカスタムステータスラインを作る必要はありません。情報量が多すぎるステータスラインは、視線がそちらに引っ張られて、肝心の会話への集中を逆に削いでしまうこともあります。

シェルスクリプトで作る最小構成のステータスライン

まずは、外部依存がない Bash 1 ファイルで、モデル・コンテキスト残量・Git ブランチを表示する例から見ていきます。これは「動くものを 5 分で用意したい」場合の最短ルートです。

#!/usr/bin/env bash
# ~/.claude/statusline.sh
# Claude Code から呼ばれ、JSON を stdin で受け取り、1行を stdout に出す。
set -eu
 
# 1) Claude Code から渡されるセッション情報を読み取る
INPUT="$(cat)"
 
# 2) jq で必要なフィールドだけ抜き出す(jq が無い場合は次節の Node.js 版を使う)
MODEL_ID="$(echo "$INPUT" | jq -r '.model.id // "unknown"')"
MODEL_NAME="$(echo "$INPUT" | jq -r '.model.display_name // .model.id // "unknown"')"
CTX_USED="$(echo "$INPUT" | jq -r '.context.input_tokens // 0')"
CTX_LIMIT="$(echo "$INPUT" | jq -r '.context.limit // 200000')"
CWD="$(echo "$INPUT" | jq -r '.workspace.current_dir // "."')"
 
# 3) コンテキスト残量を%で算出
if [ "$CTX_LIMIT" -gt 0 ]; then
  USED_PCT=$(( (CTX_USED * 100) / CTX_LIMIT ))
else
  USED_PCT=0
fi
REMAIN_PCT=$(( 100 - USED_PCT ))
 
# 4) Git ブランチ(取得できない場合は省略)
BRANCH=""
if command -v git >/dev/null 2>&1; then
  BRANCH="$(git -C "$CWD" symbolic-ref --short -q HEAD 2>/dev/null || true)"
fi
 
# 5) ANSI 装飾を付けて 1 行で出力
RESET=$'\033[0m'
DIM=$'\033[2m'
CYAN=$'\033[36m'
GREEN=$'\033[32m'
YELLOW=$'\033[33m'
RED=$'\033[31m'
 
# 残量で色を変える(30% 未満は赤、60% 未満は黄色、それ以上は緑)
if [ "$REMAIN_PCT" -lt 30 ]; then COLOR="$RED";
elif [ "$REMAIN_PCT" -lt 60 ]; then COLOR="$YELLOW";
else COLOR="$GREEN"; fi
 
LINE="${CYAN}${MODEL_NAME}${RESET}"
LINE="${LINE} ${DIM}|${RESET} ctx ${COLOR}${REMAIN_PCT}%${RESET}"
[ -n "$BRANCH" ] && LINE="${LINE} ${DIM}|${RESET} ${BRANCH}"
 
printf '%s' "$LINE"

これを chmod +x ~/.claude/statusline.sh で実行可能にして、settings.json に登録すれば動きます。期待される出力は、たとえば以下のような 1 行です。

Sonnet 4.5 | ctx 73% | feature/auth-refactor

私の経験では、残量を%で見せる のがいちばん運用に乗りやすかったです。トークン数の生値(例: 47,231)はピンとこない一方、%は「半分は使ったな」「あと少しで /compact だな」という判断と直結します。

Node.js で作るバージョン — jq が無い環境向け

会社の貸与マシンや CI 環境など、jq が入っていない PC で動かしたい場合は、Node.js だけで完結させるのが楽です。Node 18 以降なら、外部パッケージなしで書けます。

#!/usr/bin/env node
// ~/.claude/statusline.mjs
// stdin で受け取った JSON を整形して 1 行で stdout に出す。
 
import { execSync } from "node:child_process";
 
async function main() {
  // stdin を全部読む
  const chunks = [];
  for await (const chunk of process.stdin) chunks.push(chunk);
  let input = {};
  try {
    input = JSON.parse(Buffer.concat(chunks).toString("utf8") || "{}");
  } catch {
    // パース失敗時は控えめに何も出さない(セッション開始時など空入力のケース)
    process.stdout.write("");
    return;
  }
 
  const modelName = input?.model?.display_name || input?.model?.id || "unknown";
  const used = Number(input?.context?.input_tokens || 0);
  const limit = Number(input?.context?.limit || 200000);
  const cwd = input?.workspace?.current_dir || process.cwd();
 
  const usedPct = limit > 0 ? Math.floor((used * 100) / limit) : 0;
  const remainPct = 100 - usedPct;
 
  // Git ブランチ取得(失敗しても落とさない)
  let branch = "";
  try {
    branch = execSync("git symbolic-ref --short -q HEAD", {
      cwd,
      stdio: ["ignore", "pipe", "ignore"],
    })
      .toString()
      .trim();
  } catch {
    branch = "";
  }
 
  const c = (code, s) => `\x1b[${code}m${s}\x1b[0m`;
  const cyan = (s) => c(36, s);
  const dim = (s) => c(2, s);
  const color =
    remainPct < 30 ? 31 : remainPct < 60 ? 33 : 32; // red / yellow / green
 
  let line = `${cyan(modelName)} ${dim("|")} ctx ${c(color, `${remainPct}%`)}`;
  if (branch) line += ` ${dim("|")} ${branch}`;
 
  process.stdout.write(line);
}
 
main().catch(() => {
  // 最終的なエラーも握りつぶし、ステータスラインを壊さない
  process.stdout.write("");
});

settings.json の command には node /Users/you/.claude/statusline.mjs のように Node 経由で起動するパスを書きます。シバン (#!/usr/bin/env node) を活かすなら、chmod +x してから絶対パスを直接書いても構いません。

失敗しても会話を壊さない — エラーの握りつぶしが必須

実装で見落としがちなのが、ステータスラインのスクリプトが失敗したとき、Claude Code 本体の会話に悪影響を与えないようにする という観点です。Claude Code はステータスラインスクリプトの非ゼロ終了や stderr を、デフォルトでは表示エラーとしてレンダリングしません。ですが、長時間タイムアウトしたりプロセスがハングすると、ステータスライン更新がブロックされて違和感のある体験になります。

私が必ず入れているのは次の 4 つです。第一に、外部コマンド呼び出しはすべて try で包んで失敗を握りつぶします。git が無い環境でも 1 行は出るようにしておきます。第二に、入力 JSON のパースエラーでも空文字を返します。セッション初期化直後にスキーマが揺れた場合でも、ステータスラインが「壊れた」と認識されないようにします。第三に、外部 API を叩きません。たとえば「現在の Anthropic 残クレジットを取得」みたいな処理は、ネットワーク遅延がそのまま体感を悪化させるので、別のスクリプトに切り出して定期実行で更新したファイルから読む形が無難です。第四に、処理時間の予算を 50ms 程度に収めます。これを超え始めると、明らかに「描画がカクつく」感覚が出てきます。

残コンテキストバーをアスキーで描いて視認性を上げる

%表示で慣れてくると、もう一段「視覚的に」残量を把握したくなる時があります。私は次のような単純な 10 文字バーを足して、ターミナル上で視線がそちらに向くようにしました。

# 残量%を 10 段階のバーに変換する関数
make_bar() {
  local pct="$1"
  local filled=$(( pct / 10 ))
  local empty=$(( 10 - filled ))
  local bar=""
  for ((i=0; i<filled; i++)); do bar="${bar}█"; done
  for ((i=0; i<empty; i++)); do bar="${bar}░"; done
  printf '%s' "$bar"
}
 
BAR="$(make_bar "$REMAIN_PCT")"
LINE="${LINE} ${DIM}[${RESET}${COLOR}${BAR}${RESET}${DIM}]${RESET}"

たとえば残量 73% なら ███████░░░ のように見えます。/compact を打つかどうかの判断が、数字を読まなくても瞬時にできるようになるので、長時間セッションでは特に効きます。

プロジェクトごとに表示を変える — 設定の優先順位を理解する

Claude Code の settings.json は、ユーザー全体(~/.claude/settings.json)と、プロジェクトごと(<repo>/.claude/settings.json)の 2 階層で管理できます。プロジェクト側の設定が優先される ため、特定のリポジトリだけ別のステータスラインを使いたい、というカスタマイズが可能です。

私が実際にやっているのは、本番運用しているプロダクト用のリポジトリにだけ「環境名(dev/staging/prod)」を表示するステータスラインを差し込む、という運用です。プロジェクトの環境変数(CLAUDE_ENV など)を読んで色を変えるだけで、「いまうっかり prod を触っていないか?」というヒヤリを減らせます。

# ~/projects/your-app/.claude/settings.json (プロジェクト固有)
{
  "statusLine": {
    "type": "command",
    "command": "/Users/you/.claude/statusline-prod-aware.sh",
    "padding": 0
  }
}

このように、全体は控えめにしておき、特に注意したいプロジェクトだけ強めの表示にする のがバランスが良いと感じています。すべてのプロジェクトで派手な表示にすると、強調表示が「強調」として機能しなくなります。

押さえておきたい落とし穴

最後に、設定時にハマりやすいポイントを 3 つだけまとめておきます。

ひとつ目は 絶対パス指定 です。command に ~/.claude/statusline.sh のようにチルダ展開を期待した書き方をすると、環境によっては展開されず実行ファイルが見つからない、というケースがあります。必ず /Users/you/... のような絶対パスで書くのが安全です。

ふたつ目は 改行を出力しない こと。echo をそのまま使うと末尾に改行が付き、ステータスラインの行が崩れて見えることがあります。シェルなら printf '%s'、Node なら process.stdout.write を使い、明示的に改行を入れない実装にしてください。

みっつ目は 長過ぎる出力 です。ターミナル幅によっては折り返されて 2 行になり、レイアウトが崩れます。50 〜 70 文字以内に収める、長くなりそうな項目は省略表示(...)にする、といった配慮を入れておくと安心です。

ステータスラインは、はじめは「あれば便利」程度のものに見えますが、設定を 30 分かけて整えるだけで、長時間セッション中の 小さな迷い が大幅に減るのを実感できると思います。まずは本記事のシェルスクリプトをそのまま ~/.claude/statusline.sh として置いて、settings.json から呼び出してみてください。動かしながら自分の運用に合う情報を 1 つずつ足していくのが、いちばん早く納得のいく設定にたどり着く道筋だと感じています。

このあたりの設定をさらに突き詰めたい方は、Claude Code の挙動全体をフックで包む話とも相性が良いので、Claude Code Hooks 自動化マスターガイド や Claude Code 環境変数と起動フラグの完全リファレンス も合わせて目を通しておくと、ステータスラインに「何を出すか」の引き出しが一気に増えます。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⟐ Claude Code2026-08-28
名前に混ざった見えない文字を、プラグインを入れる前に洗い出す小さなスクリプト
プラグインやスキルの名前に不可視文字や制御文字が混ざっていても、ターミナルの一覧では見分けがつきません。実際に6つの紛らわしい名前を並べて ls の出力を比べ、導入前に走らせる点検スクリプトと、その点検が拾えない範囲までを整理しました。
⟐ Claude Code2026-08-26
キャッシュのTTLを1時間に延ばすかは、離席の長さではなく戻る場所で決めています
Claude Code v2.1.242 で promptCacheTtl と subagentPromptCacheTtl が追加されました。1時間キャッシュが効く条件は離席時間ではなく、同じ作業ディレクトリと同じ git 状態へ戻るかどうかです。判断の順番と、効いているかを確かめる手順を書き残します。
⟐ Claude Code2026-06-12
Android の戻るボタン広告ゲートを入れ子から並列独立構造へ — Claude Code と進めた終了フロー再設計の記録
戻るボタンの広告が「出ない」と「出すぎる」を同時に起こした原因は、入れ子分岐に埋め込まれた暗黙の優先度でした。壁紙アプリ v2.1.0 で広告ゲートを並列独立構造へ作り直した過程を、Kotlin実装・Claude Codeへの依頼内容・テストまで含めて記録します。