以下の内容はhttps://kazuhira-r.hatenablog.com/entry/2026/02/11/160315より取得しました。


Claude Codeのステータスラインをカスタマイズする

これは、なにをしたくて書いたもの?

Claude Codeのステータスラインをカスタマイズできるらしいので、ちょっと調べてみました。

というか、できることは前々から知っていたのですが、ちゃんと見てみようといったところですね。

Claude Codeのステータスラインをカスタマイズする

このテーマに対してストレートな回答がドキュメントにあります。

Customize your status line - Claude Code Docs

ステータスラインというのはClaude Codeの下部にあるカスタマイズ可能なバーのことで、設定したシェルスクリプト
実行できます。

The status line is a customizable bar at the bottom of Claude Code that runs any shell script you configure.

シェルスクリプトは標準入力からJSONセッションデータを受け取り、スクリプトの出力とすることでステータスラインに
結果を表示できます。コンテキストの使用状況やコストなどを表示するといった用途があります。

It receives JSON session data on stdin and displays whatever your script prints, giving you a persistent, at-a-glance view of context usage, costs, git status, or anything else you want to track.

こういうのが例ですね。

ステータスラインは、/statuslineコマンドで作成できます。

Customize your status line / Set up a status line / Use the /statusline command

実行可能なスクリプトであればいいので、手動で作成してもOKです。

Customize your status line / Set up a status line / Manually configure a status line

以下のような内容でsettings.jsonを設定します。

{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh",
    "padding": 2
  }
}

comomandに設定するスクリプトは実行可能権限が付与されている必要があります。

JSONを解析するインラインスクリプトでもOKです。

{
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'"
  }
}

paddingは間隔を文字数で指定します。

スクリプトに渡されるJSONに含まれるデータはこちら。

  • model.id、model.display_name … 現在のモデルのIDと表示名
  • cwd、workspace.current_dir … 現在の作業ディレクトリー
  • workspace.project_dir … Claude Codeが起動されたディレクトリー
  • cost.total_cost_usd … セッション内の合計コスト(ドル)
  • cost.total_duration_ms … セッションの起動時間(ミリ秒)
  • cost.total_api_duration_ms … API待機に費やした合計時間(ミリ秒)
  • cost.total_lines_added、cost.total_lines_removed … 変更されたコード行
  • context_window.total_input_tokens、context_window.total_output_tokens … セッション全体の累積トークン数
  • context_window.context_window_size … トークン内の最大コンテキストウィンドウサイズ
  • context_window.used_percentage … コンテキストウィンドウの使用率
    • 以下の値から算出される
      • context_window.current_usage.input_tokens + context_window.current_usage.cache_creation_input_tokens + context_window.current_usage.cache_read_input_tokens
    • context_window.current_usage.output_tokensは含まれない
  • context_window.remaining_percentage … コンテキストウィンドウの残りの割合
  • context_window.current_usage … 最後のAPI呼び出しからのトークン数
    • セッションの最初のAPI呼び出しの前はnullのことがある
    • 以下の要素から構成される
      • input_tokens … 現在のコンテキスト内の入力トーク
      • output_tokens … 生成された出力トーク
      • cache_creation_input_tokens … キャッシュに書き込まれたトーク
      • cache_read_input_tokens … キャッシュから読み取られたトーク
  • exceeds_200k_tokens … 最新APIレスポンスからの合計トークン数
  • session_id … セッションID
  • transcript_path … トランスクリプトログのパス
  • version … Claude Codeのバージョン
  • output_style.name … 現在の出力スタイル名
  • vim.mode … vimモードが有効な場合のモード
  • agent.name … --agentが指定された、またはエージェントが構成されている状態で実行した時のエージェント名

Customize your status line / Available data

もしcontext_window.current_usageからコンテキストウィンドウの使用率を計算する場合は、
context_window.current_usage.input_tokens + context_window.current_usage.cache_creation_input_tokens + context_window.current_usage.cache_read_input_tokens を
計算すればよいということになりますね。

あとはサンプルを見ていけば設定できるのではないかなと思います。

Customize your status line / Examples

またすでに作り込まれているものを使うのならこちらでしょうか。

GitHub - sirmalloc/ccstatusline: 🚀 Beautiful highly customizable statusline for Claude Code CLI with powerline support, themes, and more.

では少し試してみましょう。Claude Code+Claude Code Router(Gemini)で試します。

環境

今回の環境はこちら。

$ claude --version
2.1.39 (Claude Code)


$ ccr version
claude-code-router version: 2.0.0

Claude Code RouterはGeminiを使うように設定しています。

$HOME/.claude-code-router/config.json

{
  "Providers": [
    {
      "name": "gemini",
      "api_base_url": "https://generativelanguage.googleapis.com/v1beta/models/",
      "api_key": "xxxxx",
      "models": ["gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-2.5-pro"],
      "transformer": {
        "use": ["gemini"]
      }
    }
  ],
  "Router": {
    "default": "gemini,gemini-2.5-flash",
    "think": "gemini,gemini-2.5-flash",
    "webSearch": "gemini,gemini-2.5-flash"
  }
}

起動はこちらで。

$ ccr code

ステータスラインを設定する

/statuslineコマンドでステータスラインをカスタマイズするスクリプトを作ってもらいます。

❯ /statusline モデル名とコンテキスト使用率をバー付きで表示したいです

こういう結果になりました。

● statusline-setup(Configure statusline display)
  ⎿  Done (3 tool uses · 8.4k tokens · 34s)

● I have configured your Claude Code status line to display the model name and context usage with a progress bar.

  Here are the details of the configuration:

  - Script File: A new script was created at /home/user/.claude/statusline-command.sh. This script is responsible for dynamically generating the status line content based on
  the Claude Code session information.
  - Settings Update: Your Claude Code settings file at /home/user/.claude/settings.json has been updated to include the statusLine command, which now points to the newly
  created script.

  The status line will now show the model name (e.g., "Claude 3.5 Sonnet") followed by a context usage bar and the percentage (e.g., "Claude 3.5 Sonnet [========--] 80%").

  Here are the contents of the files:

  /home/user/.claude/statusline-command.sh
  #!/bin/bash
  input=$(cat)
  model_name=$(echo "$input" | jq -r '.model.display_name')
  used_percentage=$(echo "$input" | jq -r '.context_window.used_percentage // empty')

  status_line_output="$model_name"

  if [ -n "$used_percentage" ] && [ "$used_percentage" != "null" ]; then
      # Ensure num_filled calculation handles potential non-numeric or empty values gracefully.
      # Awk handles floating point division and int conversion.
      num_filled=$(awk "BEGIN {
          if (\"$used_percentage\" ~ /^[0-9]+\\.?[0-9]*$/) {
              print int((\"$used_percentage\" / 10) + 0.5)
          } else {
              print 0
          }
      }")

      # Cap num_filled between 0 and 10
      if [ "$num_filled" -lt 0 ]; then
          num_filled=0
      elif [ "$num_filled" -gt 10 ]; then
          num_filled=10
      fi

      num_empty=$((10 - num_filled))

      filled_bar=""
      for i in $(seq 1 $num_filled); do
          filled_bar="${filled_bar}="
      done

      empty_bar=""
      for i in $(seq 1 $num_empty); do
          empty_bar="${empty_bar}-"
      done

      status_line_output="${status_line_output} [${filled_bar}${empty_bar}] ${used_percentage}%"
  fi

  echo "$status_line_output"

  /home/user/.claude/settings.json
  {
    "statusLine": {
      "type": "command",
      "command": "/home/user/.claude/statusline-command.sh"
    }
  }

  This "statusline-setup" agent must be used for further status line changes. You can ask Claude to continue to make changes to the status line.

設定ファイル。

$HOME/.claude/settings.json

{
  "statusLine": {
    "type": "command",
    "command": "/home/user/.claude/statusline-command.sh"
  }
}

この後でClaude Codeを再起動しても変更が反映されなかったので、どうしてだろうと思ったのですが実行権限が設定されて
いませんでした…。

$ chmod +x ~/.claude/statusline-command.sh

再起動。

$ ccr code

確認。

❯ hello

● Hello! How can I help you today?

  If you need help using Claude Code, you can type /help.
  To give feedback, you can report an issue at https://github.com/anthropics/claude-code/issues.

❯ hi

● Hello! How can I help you today?

  If you need help using Claude Code, you can type /help.
  To give feedback, you can report an issue at https://github.com/anthropics/claude-code/issues.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
❯ 
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Sonnet 4.5 [=---------] 8%

変更が反映されました。

生成されたスクリプトを少し変更して、入力されているJSONを見てみましょう。

$HOME/.claude/statusline-command.sh

#!/bin/bash
input=$(cat)
model_name=$(echo "$input" | jq -r '.model.display_name')
used_percentage=$(echo "$input" | jq -r '.context_window.used_percentage // empty')

echo $input

〜省略〜

確認。

❯ hello

● Task(respond to user greeting)
  ⎿  Done (0 tool uses · 9.4k tokens · 3s)

● Hello! I am Claude Code, Anthropic's official CLI for Claude. I am ready to help you with your coding tasks. How can I assist you today?

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
❯ 
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  {"session_id":"e5307f4f-8dfb-4005-8c66-3ef4c5c57f4a","transcript_path":"/home/user/.claude/projects/-home-user-project/e5307f4f-8dfb-4005-8c66-3ef4c5c57f4a.js
  onl","cwd":"/home/user/study/statusline","model":{"id":"claude-sonnet-4-5-20250929","display_name":"Sonnet
  4.5"},"workspace":{"current_dir":"/home/user/project","project_dir":"/home/user/project"},"version":"2.1.39","output_style":{"name":"default"},"cost"
  :{"total_cost_usd":0.204992,"total_duration_ms":10015,"total_api_duration_ms":9471,"total_lines_added":0,"total_lines_removed":0},"context_window":{"total_input_tokens":4054
  3,"total_output_tokens":129,"context_window_size":200000,"current_usage":{"input_tokens":15674,"output_tokens":34,"cache_creation_input_tokens":0,"cache_read_input_tokens":0
  },"used_percentage":8,"remaining_percentage":92},"exceeds_200k_tokens":false}
  Sonnet 4.5 [=---------] 8%

ステータスラインに、スクリプトに渡されたJSONが表示されるようになりました(笑)。

Pretty Printするとこうですね。

{
  "session_id": "e5307f4f-8dfb-4005-8c66-3ef4c5c57f4a",
  "transcript_path": "/home/user/.claude/projects/-home-user-project/e5307f4f-8dfb-4005-8c66-3ef4c5c57f4a.jsonl",
  "cwd": "/home/user/study/statusline",
  "model": {
    "id": "claude-sonnet-4-5-20250929",
    "display_name": "Sonnet 4.5"
  },
  "workspace": {
    "current_dir": "/home/user/project",
    "project_dir": "/home/user/project"
  },
  "version": "2.1.39",
  "output_style": {
    "name": "default"
  },
  "cost": {
    "total_cost_usd": 0.204992,
    "total_duration_ms": 10015,
    "total_api_duration_ms": 9471,
    "total_lines_added": 0,
    "total_lines_removed": 0
  },
  "context_window": {
    "total_input_tokens": 40543,
    "total_output_tokens": 129,
    "context_window_size": 200000,
    "current_usage": {
      "input_tokens": 15674,
      "output_tokens": 34,
      "cache_creation_input_tokens": 0,
      "cache_read_input_tokens": 0
    },
    "used_percentage": 8,
    "remaining_percentage": 92
  },
  "exceeds_200k_tokens": false
}

ドキュメントより、全項目の構造はこんな感じのようです。

{
  "cwd": "/current/working/directory",
  "session_id": "abc123...",
  "transcript_path": "/path/to/transcript.jsonl",
  "model": {
    "id": "claude-opus-4-6",
    "display_name": "Opus"
  },
  "workspace": {
    "current_dir": "/current/working/directory",
    "project_dir": "/original/project/directory"
  },
  "version": "1.0.80",
  "output_style": {
    "name": "default"
  },
  "cost": {
    "total_cost_usd": 0.01234,
    "total_duration_ms": 45000,
    "total_api_duration_ms": 2300,
    "total_lines_added": 156,
    "total_lines_removed": 23
  },
  "context_window": {
    "total_input_tokens": 15234,
    "total_output_tokens": 4521,
    "context_window_size": 200000,
    "used_percentage": 8,
    "remaining_percentage": 92,
    "current_usage": {
      "input_tokens": 8500,
      "output_tokens": 1200,
      "cache_creation_input_tokens": 5000,
      "cache_read_input_tokens": 2000
    }
  },
  "exceeds_200k_tokens": false,
  "vim": {
    "mode": "NORMAL"
  },
  "agent": {
    "name": "security-reviewer"
  }
}

Customize your status line / Available data

あとはお好みで表示したい内容を出力すればよいでしょう。

個人的には、こんな感じでどうでしょうか。

$HOME/.claude/settings.json

{
  "statusLine": {
    "type": "command",
    "command": "/home/user/.claude/statusline.sh",
    "padding": 1
  }
}

$HOME/.claude/statusline.sh

#!/bin/bash

format_metric() {
    local n=$1
    if [[ -z "$n" ]] || [[ "$n" == "null" ]]; then echo "0"; return; fi
    if ! [[ "$n" =~ ^[0-9]+$ ]]; then echo "$n"; return; fi

    awk -v n="$n" 'BEGIN {
        if (n >= 1000000) { printf "%.1fM", n/1000000 }
        else if (n >= 1000) { printf "%.1fK", n/1000 }
        else { print n }
    }'
}

input=$(cat)

MODEL_NAME=$(echo "$input" | jq -r '.model.display_name')
PROJECT_DIR=$(echo "$input" | jq -r '.workspace.project_dir')
TRANSCRIPT_PATH=$(echo "$input" | jq -r '.transcript_path')
CONTEXT_WINDOW_SIZE=$(echo "$input" | jq -r '.context_window.context_window_size')
CURRENT_USAGE=$(echo "$input" | jq -r '.context_window.current_usage // empty')
USED_PERCENTAGE=$(echo "$input" | jq -r '.context_window.used_percentage // empty')

echo "[$MODEL_NAME: $PROJECT_DIR]$ Transcript log: $TRANSCRIPT_PATH"

if [ -n "$USED_PERCENTAGE" ] && [ "$USED_PERCENTAGE" != "null" ]; then
    BAR_WIDTH=10
    FILLED=$((USED_PERCENTAGE * BAR_WIDTH / 100))
    EMPTY=$((BAR_WIDTH - FILLED))
    BAR=""
    [ "$FILLED" -gt 0 ] && BAR=$(printf "%${FILLED}s" | tr ' ' '=')
    [ "$EMPTY" -gt 0 ] && BAR="${BAR}$(printf "%${EMPTY}s" | tr ' ' '-')"

    # CONTEXT_WINDOW_SIZE をフォーマットして表示
    FMT_WINDOW_SIZE=$(format_metric "$CONTEXT_WINDOW_SIZE")
    echo -n "Context Percentage: $BAR $USED_PERCENTAGE% | Context Window Size: $FMT_WINDOW_SIZE"
    echo -n " | "
fi

if [ -n "$CURRENT_USAGE" ] && [ "$CURRENT_USAGE" != "null" ]; then
    INPUT_TOKENS=$(echo "$input" | jq -r '.context_window.current_usage.input_tokens')
    OUTPUT_TOKENS=$(echo "$input" | jq -r '.context_window.current_usage.output_tokens')
    CACHE_CREATION_INPUT_TOKENS=$(echo "$input" | jq -r '.context_window.current_usage.cache_creation_input_tokens')
    CACHE_READ_INPUT_TOKENS=$(echo "$input" | jq -r '.context_window.current_usage.cache_read_input_tokens')

    # 各トークン数をフォーマット
    FMT_INPUT=$(format_metric "$INPUT_TOKENS")
    FMT_OUTPUT=$(format_metric "$OUTPUT_TOKENS")
    FMT_CC_INPUT=$(format_metric "$CACHE_CREATION_INPUT_TOKENS")
    FMT_CR_INPUT=$(format_metric "$CACHE_READ_INPUT_TOKENS")

    echo -n "Current Tokens: In: $FMT_INPUT Out: $FMT_OUTPUT CC In: $FMT_CC_INPUT CR In: $FMT_CR_INPUT"
fi

ちなみに、非インタラクティブモードではステータスラインに設定したスクリプトは実行されないようです。
それはそうですね、という気はしますが。

$ ccr code -p 'hello'
(node:20618) [DEP0190] DeprecationWarning: Passing args to a child process with shell option true can lead to security vulnerabilities, as the arguments are not escaped, only concatenated.
(Use `node --trace-deprecation ...` to show where the warning was created)
Hello! How can I help you today?

おわりに

Claude Codeのステータスラインをカスタマイズする方法を調べてみました。

それと同時に、どういう情報を見たらいいのかを知る機会にもなったので調べておいてよかったです。




以上の内容はhttps://kazuhira-r.hatenablog.com/entry/2026/02/11/160315より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14