Skip to content

About

Context-window meter for Claude Code: tokens used / capacity / percentage in your status line

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

claude-code-statusline

A context-window meter for Claude Code. Shows how much of the model's context window the current session has consumed — tokens used, capacity, and percentage — in a status line under the input box.

Opus 5  my-project  main  [=======...] 134k/200k (67%)  $0.42

Colour-coded: green under 60%, yellow 60–85%, red above 85%.

Two implementations are included. statusline.sh is the one you want — it's the default, it's ~5× faster, and it has fewer ways to fail. statusline.ps1 exists for Windows machines with no git bash (see Which script).


Why this exists

Claude Code has a /context command that gives a detailed one-off breakdown. This is the always-on version: a single line that tells you at a glance whether you're about to hit a compaction, without typing anything.

It reads real numbers reported by Claude Code, not an estimate. Since v2.1.x the status line receives a context_window object on stdin:

{
  "context_window": {
    "total_input_tokens": 130000,
    "total_output_tokens": 4000,
    "context_window_size": 200000,
    "current_usage": { "input_tokens": 2, "cache_read_input_tokens": 42978, "...": "..." },
    "used_percentage": 67.0,
    "remaining_percentage": 33.0
  }
}

Capacity tracks the actual model, so it reads 1M on a 1M-context model and 200k on a standard one, with no configuration.


Requirements

  • Claude Code v2.1.x or newer (developed against 2.1.220; the context_window payload doesn't exist in older versions — see Compatibility)
  • statusline.sh: POSIX sh + awk. On Windows these come with git bash, which you almost certainly already have if you use Claude Code there. macOS/Linux: built in.
  • statusline.ps1: PowerShell 7+ (pwsh).

Install

Automatic

# Windows
git clone https://github.com/amarashi/claude-code-statusline.git
cd claude-code-statusline
.\install.ps1
# macOS / Linux
git clone https://github.com/amarashi/claude-code-statusline.git
cd claude-code-statusline
./install.sh

The installer copies the script to ~/.claude/, backs up your settings.json, and merges in the statusLine key without touching your other settings.

Manual

  1. Copy statusline.sh to ~/.claude/statusline.sh.

  2. Add this to ~/.claude/settings.json (create the file with {} if it doesn't exist):

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

    On Windows, use an absolute path with forward slashes:

    "command": "sh C:/Users/YOURNAME/.claude/statusline.sh"
  3. Restart Claude Code. settings.json is read only at startup — there is no reload.

Do not run /statusline to "apply" this. That slash command launches a setup agent that rewrites your statusLine config, overwriting what you just installed.


Which script

On Windows, Claude Code picks the shell it runs your status line command in like this (decompiled from 2.1.220):

function Dp() { if (platform() !== "windows") return true; return findGitBash() !== null }
function YRt() { return Dp() ? "bash" : "powershell" }

If git bash is installed, your command runs under bash — even on Windows, and even if you live in PowerShell. So the sh script is the native fit; a PowerShell command there means spawning a nested pwsh inside bash, which adds two failure modes for no benefit:

  • stdin has to survive two process hops
  • if pwsh came from the Microsoft Store, the only stable-path entry is a 0-byte App Execution Alias (%LOCALAPPDATA%\Microsoft\WindowsApps\pwsh.exe), which frequently fails to spawn from non-shell process launchers

Use statusline.ps1 only if sh genuinely isn't available on the machine.

statusline.sh statusline.ps1
Runtime POSIX sh + awk PowerShell 7+
Measured render ~54 ms ~284 ms
Windows shell hops 0 1 (nested pwsh)

Timings measured on one Windows 11 machine; treat them as a ratio, not a benchmark.


Customising

Both scripts are short and have no dependencies — edit them directly.

  • Colour thresholds — in statusline.sh, the line col = (pct >= 85) ? "91" : (pct >= 60) ? "93" : "92" (ANSI codes: 91 red, 93 yellow, 92 green).
  • Bar width — change slots = 10.
  • Drop the cost / branch / directory — delete the relevant chunk of the line = sprintf(...) assembly.

Other fields available on stdin include model.display_name, workspace.current_dir, version, output_style.name, exceeds_200k_tokens, cost.*, and rate_limits.* (five_hour / seven_day utilisation).

Supported statusLine settings

The full schema Claude Code accepts — there is no shell or args option on statusLine (unlike hooks), so the command is always a shell command line:

Key Type Notes
type "command" required, only valid value
command string required
padding number 0 = flush left
refreshInterval number (≥1) re-run every N seconds on top of event-driven updates
hideVimModeIndicator boolean hide the built-in -- INSERT -- line

Troubleshooting

The single most common cause: you didn't restart. settings.json is read at startup only.

It shows nothing and --debug shows no error

This is expected, and it's the reason this section exists. Claude Code swallows status line failures silently:

let a = s.stderr.trim();
if (a) w(`StatusLine [...] stderr: ${a}`);                          // needs non-empty stderr
if (s.status === 0) { ... }
else if (r) w(`StatusLine [...] completed with status ${s.status}`) // needs verbose

A spawn failure produces no stderr and doesn't log unless verbose is on. So "no error" tells you nothing. Get ground truth instead:

CLAUDE_STATUSLINE_DEBUG=1 claude      # then, after it starts:
cat ~/.claude/statusline.last
  • File exists → the command ran. Your problem is rendering or trust, not the script.
  • File missing → Claude Code never invoked it. See the gates below.

Test the script outside Claude Code

Any failure reproduces here, with visible errors:

printf '%s' '{"model":{"display_name":"Opus 5"},"workspace":{"current_dir":"/tmp/x"},"cost":{"total_cost_usd":1.5},"context_window":{"total_input_tokens":130000,"total_output_tokens":4000,"context_window_size":200000}}' \
  | sh ~/.claude/statusline.sh

Expect exit 0, one line of output, and empty stderr.

If you build this test command yourself, quote the JSON with printf '%s' and single quotes. Using echo "$VAR" with backslashes in the JSON mangles the escapes and produces invalid JSON — which looks exactly like a broken script. (Yes, this cost us a detour.)

Other gates that silently disable it

Reading the execution path, these all cause a silent skip:

Gate Meaning Fix
Workspace trust not accepted logs Skipping StatusLine command execution - workspace trust not accepted accept the trust prompt for the directory
disableAllHooks: true disables hooks and status line together remove it from settings
Managed policySettings an admin policy file overrides your statusLine entirely check C:\ProgramData\ClaudeCode\managed-settings.json or the managed settings path on your OS
Empty stdout a command that succeeds but prints nothing renders nothing check your edits

Windows path gotcha

On Windows with a non-PowerShell shell, Claude Code rewrites \ → / in the command string. Write the path with forward slashes to begin with so the rewrite is a no-op, and prefer an absolute path.


Compatibility

Developed and verified against Claude Code 2.1.220 on Windows 11. The behaviours documented here — the context_window payload, the statusLine schema, shell selection, silent failure — were confirmed by inspecting that build. They are internal details and may change between versions.

On a version without context_window, the scripts degrade to [..........] 0/0 (0%) rather than crashing. If you see that, your Claude Code is too old — upgrade.

macOS and Linux should work (the sh path is the native one there) but are untested — reports welcome.


Licence

MIT — see LICENSE.

About

Context-window meter for Claude Code: tokens used / capacity / percentage in your status line

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages