Status line · Claude Code

How much Claude Code have you got left?

Two lines under your prompt: both rate-limit windows, context used, prompt size, cache hit rate and session cost. Written in Go — it reads Claude Code's JSON on stdin, prints, and exits.

Simulated session

🧠 Opus 5·1M │ 📁 claude-status-line-go │ 🌿 feature/cache-stats ●3

🟡5h ░░░░░░░░░░ 0% ↺ 5h0mCTX ░░░░░░░░░░ 0%Σ0 ↓0 ⚡0%📅7d ░░░░░░░░░░ 0% ↺ 2d4h$0.00

go install github.com/williamokano/claude-status-line-go/cmd/claude-status-line-go@latest
claude-status-line-go install

Anatomy

Every glyph is doing a job.

Eight segments, left to right. Turn any of them off — the ones you keep close up the gaps.

🧠 Opus 5·1M

Model

The model Claude Code reports, then its context window — 200k or 1M. It survives a mid-turn model switch instead of going blank.

📁 claude-status-line-go

Project

The working directory's folder name, so a second window is never a guess.

🌿 feature/cache-stats ●3

Branch

Current branch, and ●3 for three files with uncommitted changes. Hide the dot count on its own with show_git_dirty.

🟡5h ████████░░ 83% ↺ 22m

5-hour window

How much of the rolling five-hour limit you've spent, and how long until it resets.

CTX ██████░░░░ 68%

Context

Share of the context window in use. Its own thresholds, separate from the rate limits — ctx_warn and ctx_crit.

Σ115k ↓277 ⚡99%

Tokens

Σ the whole prompt, tokens generated, the share of the prompt served from cache. Σ sums all three input fields — Claude Code's input_tokens counts only what missed the cache, so on a warm conversation it reads as a couple of tokens while the real prompt is 100k+.

📅7d ███████░░░ 74% ↺ 2d4h

Weekly window

Same shape as the five-hour window, same colors. It stays out of the way until it hits weekly_show_at — 60% by default — and its countdown switches to 2d4h form once the reset is more than a day out.

$7.92

Cost

What this session has cost so far.

Thresholds

Green until it isn't.

Every bar crosses the same two lines. Both rate-limit windows share limit_warn and limit_crit; context has its own pair. Move them wherever your nerve sits.

███░░░░░░░ 31%

Under 60%

Plenty of room. Nothing to do.

███████░░░ 74%

60% — limit_warn

Past the warning line. Worth knowing before you start something large.

█████████░ 91%

85% — limit_crit

Close to the ceiling. Check the reset countdown next to the bar.

Configure

Change what it shows.

A config file, an environment variable, or a format string — whichever fits how you already manage your shell. Environment variables win over the file.

Don't go hunting for the path

claude-status-line-go config init
nvim $(claude-status-line-go config path)

config init writes a fully commented file — every option, plus two ready-to-uncomment plugin examples. It's all already the default, so an untouched file changes nothing, and it won't overwrite an existing config without --force. config path prints the location on its own, which is why the second line works.

# ~/.config/claude-status-line-go/claude-status-line.yaml

show_cost:      true
show_weekly:    true
show_tokens:    true
show_git:       true
show_git_dirty: true

bar_size:       10   # characters per progress bar
limit_warn:     60   # 5-hour and weekly
limit_crit:     85
ctx_warn:       60
ctx_crit:       85
weekly_show_at: 60   # reveal the weekly bar at this %

Plugins live in this file too. Precedence runs defaults, then this file, then the environment — so a CSL_ variable always wins.

Colors also switch off with no_color, the --no-color flag, or a NO_COLOR environment variable.

Plugins

Add your own segments.

A plugin reports data — a value, an optional maximum, maybe a label — and this tool draws it. So your segment gets the same glyphs, the same bar_size and the same NO_COLOR handling as everything else on the line.

Open issues, via a plugin

🧠 Opus 5·1M │ 📁 claude-status-line-go │ 🌿 main

🟡5h ████░░░░░░ 41% ↺ 3h2mCTX ███░░░░░░░ 32%🎯 ███░░░░░░░ 31/100$2.14

Roughly this

claude-status-line.yaml
plugins:
  - name: issues
    command: >-
      printf '{"value":%s,"max":100}'
      "$(gh issue list --json number --jq 'length')"
    interval: 60s
    icon: "🎯"
    bar: true

A command never runs while the status line is drawing — its result is cached and refreshed behind you, so a 350 ms gh call costs the line nothing.

Read the full plugin guide → — both source kinds, the output contract, thresholds, hide_when, a worked example, what a slow command does turn by turn, and how to debug one that won't show up.

Install

Two commands, or one download.

Both paths end in the same place. Pick the one that matches what's already on your machine.

With Go

go install github.com/williamokano/claude-status-line-go/cmd/claude-status-line-go@latest
claude-status-line-go install

The second command writes the statusLine entry into ~/.claude/settings.json and leaves everything else in that file alone. Add --project to register it in the current repo's .claude/settings.json instead.

@latest resolves through the Go module proxy, so a freshly pushed tag can take a few minutes to appear. Check what you got with --version.

No Go toolchain

curl -fsSL https://okano.dev/claude-status-line-go/install.sh | sh

Works out your OS and architecture, resolves the newest release, checks the SHA-256 against checksums.txt, and installs to /usr/local/bin — or ~/.local/bin if that isn't yours to write to. It never calls sudo. Read it first if you'd rather.

Pin a version or pick the destination: curl -fsSL … | VERSION=1.4.0 INSTALL_DIR=~/bin sh

Prefer not to pipe into a shell?
bash
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')
VERSION=$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
  https://github.com/williamokano/claude-status-line-go/releases/latest | sed 's#.*/v##')

FILE="claude-status-line-go_${VERSION}_${OS}_${ARCH}.tar.gz"
BASE="https://github.com/williamokano/claude-status-line-go/releases/download/v${VERSION}"

curl -fsSLO "${BASE}/${FILE}"
curl -fsSLO "${BASE}/checksums.txt"
grep " ${FILE}$" checksums.txt | sha256sum -c -   # macOS: shasum -a 256 -c -

tar -xzf "$FILE" claude-status-line-go
sudo install -m 755 claude-status-line-go /usr/local/bin/

Shell completions print to stdout for bash, zsh and fish: eval "$(claude-status-line-go --completion zsh)"