You're mid-session, deep in a refactor, and Claude stops responding. Was that the rate limit? How much context is left? You scroll up trying to remember which model you're on. The built-in status bar says "claude-fable-5-1" and nothing else.
This replaces it with everything you actually need to see at a glance. The essentials β model, thinking effort, git branch, rate limits, context β sit together on the top row; anything optional (session meta, live speed, cost) drops to a second row only when you enable it:
claude-fable-5-1 β π§ high β π myrepo πΏ main ~+ β 5h:42% π₯ [1h20m] β 7d:8% π [3d4h] β ctx: [ββββββββββ] 38%
π¨ 142β 87β/s β style:learning β π a1b2c3 β v2.6.0 β $1.23
Rate limits, context window fullness, thinking effort, git branch β color-coded and updated every turn. Each row is a continuous, pipe-separated group rendered flush-left; when a row is wider than your terminal it wraps onto another line rather than truncating. See Layout & width.
| Segment | What you see |
|---|---|
| π€ Account | Opt-in: which login this session bills to: plan and email domain (π€ Max Β· example.com). Orange for individual plans, blue for Team/Enterprise or a cloud provider, red with ACCOUNT_WORK_DOMAINS. Follows a mid-session /login. Enable with /statusline-account, see Account badge below. |
| π Handoff | Work this session handed to another session, such as a helper on a second account: π Enterprise: working 1m05s while it runs (working Γ2 when several run at once), π Enterprise Γ3 Β· 4m ago afterwards, red when it fails. Hidden until used. On by default; toggle with /statusline-handoff. See Handoffs below. |
| Model name | Which model is active for this session |
| π§ Thinking level | Current effort setting (low through max), color-coded gray to orange as it increases |
| β‘ Fast mode | A β‘ fast badge on the top row while Claude Code's Fast mode is active. Auto-hides otherwise. On by default β toggle with /statusline-fast-mode. |
| Git repo + branch | Repo name and current branch. ~ (yellow) unstaged changes, + (green) staged, ? (gray) untracked files β these stack, so ~+ means you have both. βN (green) when you have commits to push, βN (yellow) when commits are waiting to pull β reads cached remote refs, no network hit. When you're in a linked worktree, the folder icon swaps to a worktree-specific glyph (toggleable with /statusline-worktree). !N (red) appears next to the dirty indicators when there are unresolved merge conflicts (/statusline-conflicts). |
| Git diff stats | Opt-in β +N green / -N red insertion and deletion totals across staged + unstaged. Enable with /statusline-git-diff-stats. |
| PR link | Opt-in β clickable PR#1234 (the whole label is an OSC8 hyperlink) when the current branch has an associated GitHub PR. Color-coded by state (open/draft/merged/closed). Requires gh CLI. Cache-only render, never blocks. Enable with /statusline-pr. |
| Output style | Opt-in β dim style:explanatory / style:learning label on the second row. Enable with /statusline-output-style. |
| Session ID | Opt-in β id-tagged 6-char prefix of the session UUID (π a1b2c3). Enable with /statusline-session-id. |
| Claude Code version | Opt-in β trailing vX.Y.Z (the host app's version). Enable with /statusline-claude-version. |
| CWD | Opt-in β fish-style abbreviated path (~/D/c/claude-statusline) on row 1, alongside the repo segment. Surfaces deep-subdir context the repo basename alone misses, and still shows the path when you're outside a repo. Enable with /statusline-cwd. |
| Extra usage | Opt-in β pay-as-you-go overage spend (+$12.50 (25%)) when enabled on your account. Auto-hides otherwise. Enable with /statusline-extra-usage. |
| 5h / 7d rate limits | How much of your token budget you've used, how long until it resets, and whether you're burning through it faster than the clock would suggest (π₯ burning fast, β‘οΈ on track, π relaxed) |
| π Per-model weekly | Opt-in per-model weekly cap (π fable:16%), separate from the combined 7-day limit. Anthropic enforces a model-specific weekly limit on Pro/Max plans (currently Fable). Enable with /statusline-model-usage β see Per-model usage below. |
| Session cost | Estimated spend for the current session, calculated from the session JSONL file using Anthropic's published pricing. Opt-in β off by default. Set SHOW_COST=true in .statusline.conf (API plan users only; Pro/Max/Teams users don't need this) |
| π Tokens today | Opt-in β every token used since local midnight, across all sessions, projects, and subagents (π 297.3M today). Sums input, output, cache writes, and cache reads; cache reads are usually most of it, so read it as tokens processed, not tokens billed at the full rate. Enable with /statusline-daily-tokens β see Tokens today below. |
| β± Session duration | Opt-in β how long the current session has been running, from the first message timestamp in the JSONL. Enable with /statusline-session-duration |
| π¨ Token speed | Opt-in β last assistant turn's inputβ / outputβ tokens per second. Useful for spotting tool-call latency vs. generation speed. Enable with /statusline-token-speed |
| π§ Prompt cache | Opt-in next to the context bar: share of input read from cache (π§ 94%) and, while the cache is warm, time until it goes cold (warm 3m, yellow in the last minute). cold means the next turn re-reads the whole conversation. Enable with /statusline-cache. |
| Context window | A 10-block progress bar β green below 50%, yellow to 70%, red above β so you know when compaction is coming |
| β context warning | A red β >Nk badge once the context reaches CONTEXT_WARNING_TOKENS (default 200000 β the long-context pricing line). The label tracks the threshold (>200k, >150k, >1.5M). On by default β set the threshold with /statusline-context-warning 150k, toggle with /statusline-context-warning off. |
| π Compaction counter | Opt-in β appears next to the context bar after one or more auto-compactions in the current session. Enable with /statusline-compaction |
| π― /goal indicator | On by default β renders the active condition on row 1 while a /goal is running (π― all tests in test/auth passβ¦). Suppresses entirely when no goal is active or the evaluator just confirmed it met. Toggle with /statusline-goal. |
| π /loop indicator | On by default β renders schedule on row 1 while a /loop cron is active (π Every 10 minutes, or π N loops when multiple). Suppresses when none scheduled. Toggle with /statusline-loop. |
| π AI session title | Opt-in β the auto-generated humanized session name (e.g. π Statusline not showing current folder) on row 2. Useful when juggling multiple terminal tabs. Truncates at AI_TITLE_MAX_CHARS (default 40). Enable with /statusline-ai-title. |
The statusline renders as up to two rows, split by importance rather than by alignment:
- Row 1 β the core. Model, thinking effort, fast-mode badge, git repo/branch, CWD (opt-in, sits beside the repo segment), goal/loop indicators when active, the 5h / 7d / per-model rate limits, the context bar (with compaction counter), and the >200k warning. Everything you almost always want.
- Row 2 β the extras. Token speed, session duration, AI session title, output style, session ID, version, extra usage, session cost. Each is opt-in, and the whole row is suppressed when none are enabled β so a lean config is a single line with no trailing blank.
Within a row, segments are a continuous group separated by β and rendered flush-left. There's no left/right spread: the first segment starts at column zero and the rest follow.
When a row is wider than your terminal, it wraps onto another line at a β boundary rather than truncating at the edge β so nothing important falls off-screen, it just flows downward. (A single segment wider than the whole terminal still takes its own line; there's nothing smaller to break on.)
Width comes from $COLUMNS, which Claude Code sets to the terminal's width before each run. Claude Code also indents the status line, adds your statusLine.padding, and shows notifications at the right end of the same row, so rows are packed a few columns short of the edge (4 by default, plus your padding). Without that margin a row that "fits" spills over and the terminal breaks it mid-segment. Tune it, or pin the width exactly, in .statusline.conf:
WRAP_MARGIN=6 # columns kept free at the right edge (default 4)
COLS=160 # fixed width; skips the margin
Claude Code re-runs the status line on events: a new message, /compact, a permission-mode change. While it's idle, nothing changes on screen, so a countdown or a "working 43s" timer would freeze. The installer sets statusLine.refreshInterval to 5 seconds so time-based segments keep moving; a render takes about 150 ms. Change or remove it in your Claude Code settings.json.
Recent Claude Code versions send the session name, duration, cost estimate, open PR with its review state, and prompt-cache stats with every render. The status line uses those directly and only falls back to reading the session transcript or calling gh on versions that don't send them.
bash <(curl -fsSL https://raw.githubusercontent.com/Flagrare/claude-statusline/main/install.sh)The installer checks for jq (the only hard dependency), offers to install it if missing, and wires up ~/.claude/settings.json. It opens with a choice:
- Quick β recommended defaults; just asks emoji-vs-Nerd-Font icons and whether to show cost.
- Advanced β drops you into the interactive configurator to pick the icon mode and tick exactly the features you want.
You can switch later with no reinstall: run /statusline-config (the same checklist) anytime. Restart Claude Code after installing.
Files are placed in ~/.claude/statusline/ and slash commands in ~/.claude/commands/. No git clone required.
Four rendering modes, switchable at any time without restarting:
| Mode | What renders | When to use |
|---|---|---|
| emoji (default) | π§ π₯ π β‘οΈ π πΏ | The colorful default. Works in most modern terminals. Some terminals (notably Warp with its default font) render emoji at width 1, making them look tiny β use unicode instead. |
| nerd | Nerd Font PUA glyphs | Crisper single-width icons, but your terminal font must be set to a Nerd Font (JetBrainsMono Nerd Font, FiraCode Nerd Font, etc.) or they'll render as tofu. |
| unicode | Geometric Unicode (β« βΌ β‘ β» β β β΄ βΎ) |
All text-presentation symbols (no emoji VS16 selector), so they render at proper monospace width even in terminals that mis-size emoji. Recommended for Warp. |
| ascii | Pure 7-bit ASCII (!! ~~ == [*] [D] |- ^ v) |
Maximum compatibility β works in any terminal, including non-UTF8 environments. Color still does the visual work for rate limits. |
Switch via slash command in Claude Code (cycles emoji β nerd β unicode β ascii β emoji with no arg):
/statusline-icons # cycle to next mode
/statusline-icons nerd # set explicitly
/statusline-icons emoji
/statusline-icons unicode
/statusline-icons ascii
The change takes effect on the next status bar refresh.
Almost always a mode mismatch, not a bug β the script only emits a codepoint; the terminal and font decide how it looks.
- Nerd-mode icons look tiny / monochrome next to big text. That's nerd mode working as designed: Nerd Font glyphs are single-cell, monochrome symbols (e.g. the effort icon is
nf-fa-graduation_cap, not a π§ emoji). If you wanted big and colorful, switch with/statusline-icons emoji. If you wanted crisp-but-flat,/statusline-icons unicoderenders at full text size with no font dependency. - Nerd-mode icons render as blank boxes (tofu). Your terminal font isn't a Nerd Font. Set it to a patched build β e.g. in Ghostty,
font-family = "JetBrainsMono Nerd Font". Watch the exact name:JetBrainsMono NFMis not a valid family; the real one isJetBrainsMono Nerd Font(or⦠Nerd Font Mono). - Nerd-mode icons render but feel too small even with the right font. Some terminals shrink Private-Use glyphs to one cell. Ghostty exposes
adjust-icon-height(try115%) to nudge them up. This is a terminal setting; the statusline can't scale glyphs. - Emoji look tiny / width-1 (notably Warp). The terminal is rendering emoji in text presentation. Use
/statusline-icons unicodeinstead.
On Ghostty specifically β two things are easy to conflate, and only one is font-dependent:
- Whether glyphs render at all (tofu vs. glyph) β font-dependent. Ghostty ships a built-in symbols-only Nerd Font, so with
font-familyunset, nerd glyphs always render. If someone setsfont-familyto a name that doesn't resolve (e.g.JetBrainsMono NFMinstead ofJetBrainsMono Nerd Font Mono), glyphs fall back to tofu until the exact name is fixed. - How big the glyphs are β not font-dependent on Ghostty 1.2.0+. Ghostty auto-resizes Nerd Font symbols to the cell the same way the official patcher does, whether they come from the built-in symbols or an explicit patched font. We verified this live on Ghostty 1.3.1: forcing
font-family = "β¦Nerd Font Mono"changed the icon size not at all. So a patched font buys you nothing for size β Ghostty's docs say as much.
So if your nerd icons feel small, it's almost never the font β it's simply that cell-sized monochrome glyphs look smaller than big color emoji, which is the nature of nerd mode. Want bigger and colorful? /statusline-icons emoji. Want to keep nerd but nudge the scale? adjust-icon-height = 115%. (Only on Ghostty < 1.2.0, which lacked auto-resize, did a non-Mono β¦Nerd Font build actually render larger β there, the fix is to upgrade Ghostty.)
Sources & live-test notes: docs/research/ghostty-nerd-font-sizing.md.
When in doubt, cycle through the four modes with /statusline-icons and keep whichever looks right in your terminal β there's no single correct answer across terminals and fonts.
Claude Code's statusline JSON only exposes the combined 7-day rate limit. But on Pro/Max plans Anthropic enforces a separate weekly cap per model (currently Fable) β visible in /usage but not in the status bar. This package fills that gap.
Enable with:
/statusline-model-usage # toggle
/statusline-model-usage on
/statusline-model-usage off
Once enabled you'll see extra segments:
... β 7d:96% π₯ [4d15h] β π fable:12% π [11h13m] β ...
A small background poller (usage-poller.sh) calls https://api.anthropic.com/api/oauth/usage every ~5 minutes using the OAuth token Claude Code stores for its own /usage command β the same endpoint, no third parties. The response is cached at ~/.claude/.statusline-usage-cache.json and the statusline reads from the cache on every render.
One segment appears for each model the endpoint reports a scoped weekly cap for, labelled with that model's name, so when Anthropic moves the cap to a different model the segment follows without an update. Responses from before the change (seven_day_sonnet / seven_day_opus) still render as sonnet: / opus:. Before v2.13.0 this toggle was /statusline-sonnet (config key SHOW_SONNET_LIMIT); /statusline-update carries your setting over.
The first time the poller runs, macOS will show:
claude-statusline wants to use your confidential information stored in 'Claude Code-credentials'.
Click Always Allow so you don't see it again. The token never leaves your machine except in the request to api.anthropic.com.
- API plan users β the endpoint returns
nullfor these fields, so no extra segments render. - Free plan users β same as above.
- Token expired β the poller silently waits; Claude Code refreshes the keychain entry on its next API call and the next poll picks it up.
/statusline-daily-tokens adds π 297.3M today to the second row: the running total for the local day, across every Claude Code session on the machine.
A day of session logs can reach hundreds of MB, so the statusline never reads them during a render. A background script (daily-tokens.sh) refreshes the total at most once a minute and reads only the lines appended since its last pass, keeping a byte offset per log in ~/.claude/.statusline-state/daily-tokens. Claude Code logs each content block of a reply as its own line with the same usage attached, so the script counts each API request once. The first pass of the day reads everything written so far and can take a few seconds; the segment appears on the next render after it finishes. The total resets at local midnight.
The number is input + output + cache writes + cache reads. Cache reads (the conversation re-read from the prompt cache on each turn) are usually most of it. No network calls.
/statusline-account puts the session's login at the start of the top row, e.g. π€ Max Β· example.com. It helps when you keep more than one account, such as a personal subscription in one config directory and a company seat in another (CLAUDE_CONFIG_DIR), and want to see at a glance which one a session is spending.
The badge reads the login Claude Code saved in ~/.claude.json, or in $CLAUDE_CONFIG_DIR/.claude.json when that variable is set, so it changes as soon as you run /login with another account. When CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX or CLAUDE_CODE_USE_FOUNDRY is set, the provider outranks any login, and the badge shows the provider instead.
To catch a session on the wrong account, list the domains your work logins use in .statusline.conf, comma-separated with no spaces:
ACCOUNT_WORK_DOMAINS=example.com,example.org
A login outside those domains renders red with
/statusline-subagents replaces Claude Code's default row in the agent panel below the prompt with one that shows what each subagent is doing and what it costs:
β Explore Β· Reading the PR templateβ¦ Β· sonnet high Β· 1m12s Β· 48k (24%) ββββββ
β reviewer Β· Review diff Β· opus Β· 6m40s Β· 1.5M
The mark is the status (β running, β done, β failed, β stopped). After the task come the model and effort, elapsed time, tokens with the share of the subagent's context window, and a sparkline of its token use over the last few refreshes, so a subagent that's stuck or burning through context stands out. The task text is trimmed to fit the row. It sets subagentStatusLine in your Claude Code settings.json; running the command again removes it.
Some setups let one session hand a task to another, for example a session on a personal subscription asking a helper session on a company account to look something up in tools only that account can reach. The handoff segment shows that traffic so you can see which account is doing the work.
The status line doesn't run handoffs itself. Whatever runs them (an MCP server, a script, a hook) writes one JSON file per calling session:
$CLAUDE_DIR/.statusline-state/handoff-<session_id>.json
$CLAUDE_DIR is CLAUDE_CONFIG_DIR when set, else ~/.claude. <session_id> is the calling session's ID (Claude Code passes it to child processes as CLAUDE_CODE_SESSION_ID). Fields, all optional:
| Field | Meaning |
|---|---|
label |
Who the work went to, e.g. Enterprise |
status |
working, idle, or error |
task |
Short description of the current task |
started_at, finished_at |
Unix epoch seconds |
calls |
Tasks completed in this session |
error |
Reason for the last failure |
last_task |
Short description of the last task that finished. For 5 minutes after it finishes, the segment shows π Enterprise β <last_task> Β· just now |
active |
Tasks running at the same time. Above 1, the segment shows working Γ2, timed from the oldest |
Write the file atomically (write a temp file, then rename) so a render never reads half of it.
If you run Claude Code with more than one config directory, such as alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude', each profile's status line reads only its own directory: the session transcript, the per-model usage cache, the tokens-today total, and the account badge. The per-model usage poller uses that profile's login (on macOS, the keychain entry Claude Code keys to the directory). When it can't find that login, it shows nothing instead of another account's numbers.
The 5h and 7d limits come from Claude Code itself, which sends them only for Pro, Max, and Ultra plans. On a Team or Enterprise seat, either one can be missing, and the status line shows whatever Claude Code sends.
Three extra segments are derived from the current session's transcript JSONL under ~/.claude/projects/<encoded-cwd>/. All three default to off and have their own toggle.
| Command | Segment | What it shows |
|---|---|---|
/statusline-session-duration |
β± 1h23m |
Elapsed time since the first message in the active session |
/statusline-token-speed |
π¨ 142β 87β/s |
Last assistant turn's input/output tokens per second |
/statusline-compaction |
π2 next to the context bar |
Counts auto-compaction events detected during the session |
All three are pure local reads β no network calls. Token speed and session duration cost one bounded read (head -1 + tail -200) of the JSONL on each render; compaction maintains a tiny per-session state file under ~/.claude/.statusline-state/.
Thirty-one Claude Code slash commands are available after install:
| Command | What it does |
|---|---|
/statusline-icons |
Toggles between emoji and nerd mode. Pass a mode name to set directly: /statusline-icons nerd |
/statusline-cost |
Toggles session cost display. Pass on/off to set directly. API plan users only. |
/statusline-daily-tokens |
Toggles the tokens-used-today segment. Pass on/off to set directly. |
/statusline-model-usage |
Toggles the per-model weekly usage segment (currently Fable). Pass on/off to set directly. Pro/Max only. |
/statusline-session-duration |
Toggles the session duration segment. Pass on/off to set directly. |
/statusline-token-speed |
Toggles the token speed segment. Pass on/off to set directly. |
/statusline-compaction |
Toggles the compaction counter. Pass on/off to set directly. |
/statusline-git-diff-stats |
Toggles the +N -N diff totals next to the dirty indicators. Off by default. |
/statusline-pr |
Toggles the clickable GitHub PR number for the current branch. Off by default; requires gh. |
/statusline-worktree |
Toggles the worktree-specific folder icon when inside a linked git worktree. On by default. |
/statusline-conflicts |
Toggles the !N red marker for unresolved merge conflicts. On by default. |
/statusline-fast-mode |
Toggles the β‘ fast badge shown while Fast mode is active. On by default; auto-hides when Fast mode is off. |
/statusline-context-warning |
Toggles the context-warning badge, or sets its token threshold: on/off, or a count like 150000 / 150k / 2m. Default on at 200000. |
/statusline-config |
Opens the interactive configurator (icon mode + every feature in one checklist). Uses gum for arrow-key checkboxes when installed; falls back to a numbered checklist otherwise. Run it in your own terminal β it's interactive. |
/statusline-output-style |
Toggles the style:β¦ label on the second row. Off by default. |
/statusline-session-id |
Toggles the trailing 6-char session ID. Off by default. |
/statusline-claude-version |
Toggles the trailing Claude Code (host app) version badge. Off by default. |
/statusline-cwd |
Toggles the fish-style abbreviated path on row 1, alongside the repo segment. Off by default. |
/statusline-cache |
Toggles the prompt-cache segment. Pass on/off to set directly. |
/statusline-subagents |
Turns the custom subagent rows on or off. Pass on/off to set directly. |
/statusline-handoff |
Toggles the handoff segment (on by default, hidden until used). Pass on/off to set directly. |
/statusline-account |
Toggles the account badge (plan + email domain). Pass on/off to set directly. |
/statusline-extra-usage |
Toggles the pay-as-you-go overage segment. Off by default; auto-hides when not enabled on your account. |
/statusline-goal |
Toggles the /goal indicator on row 1. On by default; segment is silent unless a goal is active. |
/statusline-loop |
Toggles the /loop indicator on row 1. On by default; segment is silent unless a loop is scheduled. |
/statusline-ai-title |
Toggles the AI-generated session title on row 2. Off by default. |
/statusline-version |
Prints the installed claude-statusline version and checks GitHub for a newer one. |
/statusline-update |
Pulls the latest version from GitHub. Re-downloads all files, preserves your config. |
| Dependency | Purpose | Required? |
|---|---|---|
jq |
Parses the JSON that Claude Code pipes to the script each turn | Yes β installer offers to install it |
python3 or jq |
Edits settings.json during install |
One of them β both ship with macOS and most Linux distros |
| Nerd Font | Only needed if you choose nerd icon mode |
No |
/statusline-updateOr manually: bash <(curl -fsSL https://raw.githubusercontent.com/Flagrare/claude-statusline/main/update.sh)
bash <(curl -fsSL https://raw.githubusercontent.com/Flagrare/claude-statusline/main/uninstall.sh)This removes the statusLine key from ~/.claude/settings.json, deletes ~/.claude/statusline/, and removes the slash command files.
MIT

