Every limit, cost and agent, live under your prompt in Claude Code and GitHub Copilot CLI. Plus every other AI subscription you pay for.
Install • Demos • Providers • Copilot CLI • Themes • Widgets • Agents • Flags • Changelog
Tip
One minute from zero to a live bar: /plugin install usage-pulse --marketplace NoobyGains/usage-pulse, then /usage-pulse:setup, then restart Claude Code.
Note
Works in GitHub Copilot CLI too (3.9.0). One command puts the same bar, in your theme, in Copilot CLI's footer, with your plan budget: premium requests or AI credits used, the allowance, what is left and when it resets. It reads only what Copilot CLI already keeps on your machine: no token, no network call. Claude Code is not required. See Inside GitHub Copilot CLI.
Plan ━━━───────── 23% 69/300 req · 231 left · R:1 Dec Pro | Session 3 req | Context ━━━━━─────── 42% | GPT-5.4 · medium | main
| The 5-hour and weekly bars, the countdowns, context and cost all come from what Claude Code already pipes to the status line. No key, no polling, nothing to rate limit. | A second Claude account, Codex, GitHub Copilot, Gemini / Antigravity, MiniMax or any JSON file gets its own row, found for you and drawn in the same theme. | API-equivalent spend per session in your currency, priced per model for Fable 5.2, Opus 5.5, Sonnet 5.5 and Haiku 5.5, with budget, 7-day and all-time views. |
| How many subagents are running and spawned against the cap, agent-team task progress, and a row per subagent in the agent panel with model, effort, context and time. | 10 themes, 5 animations, 8 bar styles, 5 sizes, 4 layouts and 48 widgets, all chosen in a full-screen wizard with live previews. You never edit JSON. |
A single Python script, zero dependencies, Python 3.8+, Windows, macOS and Linux. The same file drives Claude Code and GitHub Copilot CLI. Installs in a minute, updates itself with --update.
|
As a Claude Code plugin
/plugin install usage-pulse --marketplace NoobyGains/usage-pulse
/usage-pulse:setup
A plugin cannot register a status line by itself, so /usage-pulse:setup writes it into settings.json with safe defaults. Afterwards /usage-pulse:pulse setup chooses hooks, providers, theme and widgets. On Claude Code older than 2.1.275, add the marketplace first with /plugin marketplace add NoobyGains/usage-pulse, then /plugin install usage-pulse.
One line
# macOS, Linux, Git Bash
curl -fsSL https://raw.githubusercontent.com/NoobyGains/usage-pulse/main/install.sh | bash# Windows PowerShell
irm https://raw.githubusercontent.com/NoobyGains/usage-pulse/main/install.ps1 | iexBoth clone the repo to ~/.usage-pulse and open the setup wizard. Then restart Claude Code.
GitHub Copilot CLI
With usage-pulse installed any of the ways above, add the bar to Copilot CLI's footer and restart Copilot CLI:
python3 ~/.usage-pulse/claude_status.py --install-copilotInside Claude Code, /pulse copilot does the same. If you only use Copilot CLI, the clone under "By hand" below followed by this command is all you need: nothing of Claude Code's is read or written. What each kind of account shows is under Inside GitHub Copilot CLI.
By hand, installer variables, and what the plugin's hook does
git clone https://github.com/NoobyGains/usage-pulse.git ~/.usage-pulse
python3 ~/.usage-pulse/claude_status.py --setupUSAGE_PULSE_DIRpicks another install folder,USAGE_PULSE_REPO_URLanother source, andUSAGE_PULSE_NONINTERACTIVE=1(dotfiles, CI) takes the defaults without a terminal. The olderCLAUDE_PULSE_*names still work.- An install from before the rename stays in
~/.claude-pulse; the installers update it in place. - The plugin ships exactly one hook, on
SessionStart: plugin updates land in a new version folder and Claude Code deletes the old one two weeks later, so the hook re-pointssettings.jsonat the current folder when it is stale. It never touches a git or manual install and prints nothing otherwise. python3 ~/.usage-pulse/claude_status.py --updatebrings the next release to a git install; plugin installs update with/plugin update usage-pulse.
--setup is a full-screen wizard with 14 screens. It reports what it found (Python, Claude Code, your config folder, a status line it can replace), then walks through hooks, the providers on this machine, per-model caps, theme, bar size, bar style, layout, currency, clock, effort format and widgets. Every choice that changes the look has a live preview, nothing is written until you confirm the summary, Esc anywhere changes nothing, and settings.json is backed up before the first write. Inside Claude Code, /pulse offers the same choices as a menu, and /pulse setup, /pulse providers, /pulse hooks, /pulse show and /pulse ocean jump straight to a part.
Bars shift from each theme's low colour through mid to high as a window fills. The rainbow, pulse, glow and shift animations advance on every repaint, so the bar keeps moving while you think.
Switch any widget on or off, reorder by priority, split the bar over two rows, and it still fits a narrow terminal by dropping the least important widgets first.
The counter and the team segment come from two optional hook groups. The agent panel rows need no hook at all: Claude Code asks Usage Pulse to draw each subagent's row.
Once an hour the bar checks for a new Usage Pulse release and a new Claude Code release. --update pulls the new version, verifies the commit against GitHub, rolls back if they differ and prints what changed.
Session ━━━───────── 27% 2h 53m | Weekly ━━━━━━━━━─── 73% R:Fri 3pm | Context ━━━━──────── 35% | $38.75 | +142 -37 | Opus 5.5 | Effort: XHigh | ⚡fast | main
- Session: the 5-hour window, with the time until it resets.
- Weekly: the 7-day window, with the day and time it resets.
- Context: how full the context window is. A
⚠ Contextlabel appears above 90%, or above 70% while it fills quickly. - Cost: what this session would cost at API prices, in your currency.
- Lines changed, Model, Effort, Fast mode and Branch.
That is the default. Everything on it can be hidden, reordered or swapped for one of the widgets below.
Providers add one row per other subscription under the main line. --detect-providers lists what this machine has, and the wizard or /pulse providers switches rows on.
| What | Id | Where it is read from |
|---|---|---|
| Other Claude Code accounts | claude:default, claude:<suffix> (for example claude:b for ~/.claude-b) |
Every ~/.claude* folder that holds a .credentials.json |
| Codex CLI | codex |
ChatGPT's usage API with the Codex CLI's own login (~/.codex/auth.json); the session files under ~/.codex when that is not possible |
| Google Antigravity (Gemini) | gemini, gemini:<suffix> |
statusline_last_live.json under ~/.gemini/antigravity-cli* |
| GitHub Copilot CLI | copilot |
Copilot CLI's own record of the signed-in account, a local file. No token, no network call |
| MiniMax | minimax |
The mmx CLI on your PATH. Never switched on automatically |
| Anything else | file:<name> |
A JSON file that any tool can write |
python3 ~/.usage-pulse/claude_status.py --detect-providers # what is here
python3 ~/.usage-pulse/claude_status.py --providers enable claude:b,codex
python3 ~/.usage-pulse/claude_status.py --providers label claude:b Work
python3 ~/.usage-pulse/claude_status.py --providers listThe sub-commands are list, detect, enable, disable, label, remove and add-file. --detect-providers --json gives machine-readable output. Labels are 24 characters at most, up to 8 providers can be configured and at most 6 rows are shown.
- Rows use the main line's theme, bar style and size. With
providers_label_mainon (the default) the main line'sSessionlabel becomesClaude (<label>) 5hso everything lines up. - Another Claude account uses that account's own token, read from its
.credentials.json. It is never refreshed, stored or logged. At most one usage-API call per account everyproviders_refresh_seconds(300 by default, 60 at the lowest), never more than one a minute, with back-off on 429 and a 15-minute pause on 401 or 403. Each window also saves its own account's numbers from stdin, so with both windows open no API call is made at all. - Codex asks
chatgpt.com/backend-api/wham/usage, the endpoint the Codex CLI itself uses, with the login in~/.codex/auth.json: at most one call everyproviders_refresh_seconds, never more than one a minute, with the same back-off as the Claude rows. Codex limits are shared with ChatGPT on the web and with every other machine on the account, so the local session files alone fall behind whenever Codex is used elsewhere; they remain the fallback when the token has expired or the call fails. The token is never refreshed, stored or logged; the Codex CLI renews it on its next use. - Gemini rows are read from local files only: the last values seen, never a network call.
- Copilot has a monthly plan budget instead of 5-hour and weekly windows, so its row is one
Planbar with what is used, the allowance, what is left and the reset date:Copilot Plan ━━━───── 23% | 69/300 req · 231 left · R:1 Dec. It is read from the record Copilot CLI keeps on disk, so it is as fresh as Copilot's last start; older than a day it is drawn dim. See Inside GitHub Copilot CLI for what each kind of account shows. - MiniMax runs
mmxto read its quota, which is why it is never on by default, and it is hidden while the window itself runs on MiniMax. - A row whose data is more than 30 minutes old is drawn dim with a
~in front of the number, such as~29%.
Your own provider from a JSON file
--providers add-file <id> <path> [label] adds a row read from a file. A ten-line script that polls any other service can feed it. The id is stored as file:<id>.
{"label": "Kimi",
"five_hour": {"used_percentage": 42, "resets_at": 1792386351},
"seven_day": {"used_percentage": 7, "resets_at": "2026-10-26T10:00:00Z"}}The two windows may sit at the top level or inside a rate_limits object (Claude Code's own shape), utilization is accepted for used_percentage, resets_at may be epoch seconds, epoch milliseconds or ISO 8601, either window may be missing, and the file may be 1 MB at most.
Two or more Claude accounts on one machine
Claude Code's pattern is one config folder per account, CLAUDE_CONFIG_DIR=~/.claude-work claude. Run --setup once per account with that variable set:
CLAUDE_CONFIG_DIR=~/.claude-work python3 ~/.usage-pulse/claude_status.py --setupState that belongs to one account (usage cache, stdin context, history, sessions, heatmap, cost caches) lives in <state folder>/accounts/<name>-<hash>/, so two windows on two accounts never overwrite each other. config.json stays shared.
The same bar can be Copilot CLI's status line too, with your theme, bar style and layout:
python3 ~/.usage-pulse/claude_status.py --install-copilot # --uninstall-copilot takes it out againPlan ━━━───────── 23% 69/300 req · 231 left · R:1 Dec Pro | Session 3 req | Context ━━━━━─────── 42% | GPT-5.4 · medium | main
It writes one statusLine entry into Copilot CLI's settings.json (~/.copilot, or $COPILOT_HOME), keeps every other setting and a backup, and touches nothing of Claude Code's. Restart Copilot CLI to see it.
| Account | What the Plan segment shows |
|---|---|
| Pro, Pro+, Max, Business or Enterprise with a budget | The bar, then used / allowance, what is left, any extra usage, the reset date and the plan name. Counted in AI credits (AIC), or in premium requests (req) on the legacy billing platform |
| Enterprise or Business seat with no budget of its own | Plan no limit |
| Copilot Free | Its monthly chat allowance (0/200 chat · 200 left): Free has no premium allowance |
| Signed in without a Copilot licence | no licence |
Sessionis what this session has cost so far, in the unit the account is billed in.- Context, model, branch and lines changed come from what Copilot CLI pipes in. Widgets that only mean something in Claude Code (the 5-hour and weekly windows, cost in dollars, hooks, agents, streaks) are left out.
- The plan figures come from the record Copilot CLI itself keeps on disk for the signed-in account. No token is read and nothing is sent anywhere, so they change when Copilot refreshes that record, not after every prompt. Copilot's own Session and Weekly rate-limit bars (
/usage) are not in that record or in what it pipes in, so they are not shown. - Business and Enterprise figures follow the record's documented shape and Copilot CLI's own test data; they have not been checked against a live licensed seat yet. Reports welcome.
10 themes: default, ocean, sunset, mono, neon, pride, frost, ember, candy and rainbow. --theme ocean, /pulse ocean, or --pick-theme for an arrow-key picker with a live preview.
5 animation modes with --animate <mode>:
| Mode | Effect |
|---|---|
off |
Static, no animation |
rainbow |
A flowing rainbow gradient across the whole bar |
pulse |
Bars cycle through vivid colours (cyan, blue, purple, pink, gold, green) |
glow |
A per-character gradient that shifts across the bar each frame |
shift |
A bright highlight that slides across the bar |
--animation-speed takes slow, normal or fast. Animation needs repaints, so setup writes a 2-second refreshInterval while animation is on.
8 bar styles with --bar-style <name>: classic, block, shade, pipe, dot, square, star, braille. If Unicode looks wrong in your terminal, block is the safe one. Bar sizes: small, small-medium, medium, medium-large, large (--bar-size). A named size is exactly that wide whatever the window does; --bar-size auto shrinks the bars to fit a narrow window instead, and --wrap auto moves what does not fit onto extra rows, up to four.
Layouts (--layout): standard has full labels, compact one-letter labels, minimal no labels, and percent-first puts the number before the bar. --max-width sets the share of the terminal the bar may use and --wrap auto wraps onto up to four rows instead of cutting the line. A line that still does not fit loses whole widgets from the end and finishes with a dim …. For a deliberate two-row split, set line2_widgets (these go to row 2) or line1_widgets (an allowlist for row 1, the rest flows to row 2) in config.json.
Switch any of them with --show and --hide, or tick them in the wizard. Most read fields Claude Code already pipes in, so they cost nothing.
All 48 widgets and their defaults
| Id | Default | What it shows |
|---|---|---|
session |
on | The 5-hour window as a bar, with percentage |
timer |
on | Time until the session window resets |
weekly |
on | The 7-day window as a bar |
weekly_timer |
on | When the weekly window resets (--weekly-timer-format, --weekly-timer-prefix) |
session_bar, weekly_bar, context_bar |
on | The bars themselves. --hide weekly_bar keeps that window's percentage and timer and drops the bar |
context |
on | Context window usage, as a percentage or in tokens (--context-format) |
context_warning |
on | The ⚠ Context label and a fast-rising arrow as the window fills |
cost |
on | Session cost at API prices, in your currency |
model |
on | The active model |
branch |
on | The current git branch |
effort |
on | Reasoning effort, such as Effort: XHigh (--effort-format) |
fast_mode |
on | ⚡fast while Opus fast mode is on |
agent |
on | ▸name of the active subagent |
worktree |
on | The worktree branch, when you work in one |
lines |
on | +142 -37, lines added and removed this session |
subagents |
on | agents 3 live · 47/200, needs the agents hook |
team |
on | team 3 · tasks 4/7, needs the team hooks |
budget |
on | A spend bar against the amount from --budget. Appears once a budget is set |
spend_limit |
on | spend $12.40/$50 wk, only when a Claude apps gateway reports a spend limit |
providers |
on | The extra rows for other subscriptions |
pomodoro |
on | The focus timer, while one is running (--focus start 25) |
staleness |
on | (5m ago) when the data on screen is old |
update |
on | ↑ Pulse Update when a new Usage Pulse release exists |
claude_update |
on | ↑ Claude Update when a newer Claude Code is out on your release channel (latest, or stable if your autoUpdatesChannel says so); ↻ Restart Claude when that version is already installed and only a restart applies it |
opus, sonnet, fable |
off | Per-model weekly cap bars. These call the usage API, see below |
plan |
off | Your plan as it is sold (Ultra, Max, Pro), read from your profile once a day; the credentials file's tier (Max 20x) is the fallback |
extra |
off | Extra-usage (bonus) credits, in your currency. Appears by itself if you have any (--extra-display), refreshes with the per-model caps, and shows (stale) or (3d ago) when the figure is old |
thinking |
off | think or no-think |
cache |
off | Share of input served from the prompt cache |
cache_warm |
off | Prompt-cache warmth, such as ♨ 92% · 3m |
pr |
off | Clickable #123 pull request badge with review state. GitLab merge requests show as !123 |
repo |
off | owner/name of the current repository |
session_name |
off | The name you gave the session with /rename |
weekly_cost |
off | Rolling 7-day API-equivalent cost. Fills in a few seconds after you first switch it on |
cumulative_cost |
off | API-equivalent cost across all sessions. Fills in a few seconds after you first switch it on |
burn_rate |
off | How fast the window is filling, such as ↑3%/hr |
runway |
off | Estimated time until the window is full |
sparkline |
off | A small chart of recent session usage |
status_message |
off | Replaces the Session label with a short message such as Cruising |
pace |
off | ↑ or ↓ after the percentage: usage ahead of or behind the window's clock, doubled when it is well off the pace, → when on track (--pace-style). Provider rows get the same arrows |
streak |
off | Days in a row you have used Claude Code (--streak-style) |
sessions |
off | +2 sessions when other windows are open |
git_drift |
off | Commits behind and ahead of upstream |
files_changed |
off | Count of uncommitted files |
heartbeat |
off | Spinner, and this session's tool count and elapsed time. Needs the heartbeat hook |
last_tool |
off | The last tool Claude used in this session. Needs the heartbeat hook |
Order is set by priority numbers: --priority lists them, and --priority model=5,cost=15 moves the model first and the cost after the session. Lower is further left.
The opus, sonnet and fable bars show your weekly cap for each model, when your plan reports one. Claude Code's own input carries only the 5-hour and 7-day windows, so these three come from the usage API with your Claude Code login, which is why they are opt-in: --show fable, or the wizard's model caps screen. Each refresh is one API call, at most every model_caps_refresh_seconds (300 by default, 60 at the lowest), and a failed attempt waits 60 seconds. Claude Pro reports no model-scoped windows, so no bar appears there. Contributed by @thedanielmay in PR #53.
| Model | Per million tokens (in / out) |
|---|---|
| Fable 5.2 | $8 / $40 |
| Opus 5.5 | $4 / $20 |
| Sonnet 5.5 | $2 / $10 |
| Haiku 5.5 | $0.10 / $0.50 up to 100K prompt tokens, $0.50 / $2.50 above |
All four have a 1M-token context window. Mythos 5.2 costs the same as Fable 5.2, and older models (Fable 5.1, Mythos 5.1, Opus 5, Sonnet 5 and earlier) are priced at their own list rates too. Costs are API-equivalent: a figure to compare sessions by, not your bill. --currency £ converts from USD at a daily exchange rate; give a symbol or any ISO code the rate service lists, such as --currency DKK, NOK or SEK (shown as DKK68.50). A bare kr follows your machine's country: Danish kroner in Denmark, Norwegian in Norway, Swedish elsewhere. The 7-day and all-time cost widgets are worked out by a background process, so they appear a few seconds after you first switch them on. --budget 25 draws a spend bar against the number you give Claude Code's --max-budget-usd, which the status line cannot read by itself.
Three optional hook groups feed the bar. Install the ones you want with --install-hooks, or tick them in the wizard, and restart Claude Code:
python3 ~/.usage-pulse/claude_status.py --install-hooks # all three
python3 ~/.usage-pulse/claude_status.py --install-hooks --only agents,team # just these| Group | Claude Code events | What it drives | What it costs |
|---|---|---|---|
agents |
SubagentStart, SubagentStop | The live agent counter, agents 3 live · 47/200 |
A short Python run when a subagent starts or stops |
team |
TeammateIdle, TaskCreated, TaskCompleted | The agent-team segment, team 3 · tasks 4/7 |
A short Python run on each of those events |
heartbeat |
PostToolUse | The spinner and this session's tool count, plus last_tool |
A Python run after every tool call, and it keeps the repaint timer alive, which is why it is off by default |
The agent panel rows need no hook: --setup registers subagentStatusLine, and Claude Code then asks Usage Pulse to draw each subagent's row with its status, model, effort, a context bar and elapsed time. --limits subagent_spawns=200,subagent_concurrent=20,web_searches=200 sets the denominators, since Claude Code enforces those caps but does not report them.
Hooks never block Claude. Every installed hook command ends in ; exit 0. For the events where exit code 2 would steer Claude Code (SubagentStop, TeammateIdle, TaskCreated, TaskCompleted) that means even a moved or deleted script cannot keep a subagent running or refuse a task, and for the others it means no hook error after each tool call. --install-hooks refuses to touch a settings.json that is not valid JSON, and your other hooks are left alone.
Agent team requirements and limits
Agent teams need CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1, and task counts need Claude Code's Task tools, which newer models only get with CLAUDE_CODE_ENABLE_TODO_TOOLS=1. The team segment only knows what the three hooks tell it, so:
- It shows how many teammates have appeared, not how many are busy: claiming or doing work fires no hook.
- A task deleted with
TaskUpdatestays open, since deleting fires no hook. - It records an event before any quality-gate hook of yours decides, so a creation your hook blocks still counts as open.
- Split-pane teammates (tmux, iTerm2) run as separate sessions with their own id and do not appear in the lead's segment. In-process teammates, the default, do.
- A session's team state is swept after six hours of silence, open tasks included.
/pulse and --setup cover everything below. The flags do the same from a shell.
--theme ocean # default, ocean, sunset, mono, neon, pride, frost, ember, candy, rainbow
--animate rainbow # off, rainbow, pulse, glow, shift
--bar-size large # small, small-medium, medium, medium-large, large, auto
--bar-style block # classic, block, shade, pipe, dot, square, star, braille
--layout compact # standard, compact, minimal, percent-first
--currency £ # $, £, €, ¥, C$, A$, ₹, kr, and 20+ more; or an ISO code such as DKK, NOK, SEK
--clock-format 12h # 12h or 24h
--effort-format labeled # labeled 'Effort: Medium', full 'Medium', short 'med'
--budget 25 # spend bar; use the number you pass to Claude Code's --max-budget-usd
--show cache,pr # turn widgets on
--hide cost # turn a widget off
--preset minimal # a compact bundle; --preset default is a factory reset
--focus start 25 # focus timer; --focus stop, --focus status
--config # print the current configuration
--stats # usage statistics and streaks
--heatmap # activity heatmap
--update # update a git install
--uninstall # remove the status line, hooks and /pulse from Claude Code's settingsWhere things live, config.json keys, and the refresh timer
| What | Windows | macOS / Linux |
|---|---|---|
config.json |
%LOCALAPPDATA%\claude-status\ |
~/.config/claude-status/ (or $XDG_CONFIG_HOME) |
| State and caches | %LOCALAPPDATA%\claude-status\ |
~/.cache/claude-status/ (or $XDG_CACHE_HOME) |
| Settings backups | <state folder>/settings-backups/ |
<state folder>/settings-backups/ |
Claude Code's settings.json |
$CLAUDE_CONFIG_DIR or ~/.claude |
$CLAUDE_CONFIG_DIR or ~/.claude |
| Key | Meaning |
|---|---|
theme, animate, animation_speed, text_color |
Colours and animation |
bar_size, bar_style, layout, max_width, wrap |
Shape of the bars and line |
show |
Widget on/off map |
widget_priority |
Widget order, for example {"model": 5} |
line1_widgets, line2_widgets |
Two-row split |
currency, budget_usd, limits |
Cost display |
clock_format, effort_format, context_format, extra_display, streak_style, pace_style |
Number and time formats |
weekly_timer_format, weekly_timer_prefix |
The weekly reset timer |
providers |
List of {id, type, enabled, label?, dir or path, bucket?}. Manage it with --providers |
providers_label_main |
true by default. Names the main line Claude (<label>) 5h on the standard layout |
providers_refresh_seconds |
Poll interval for other Claude accounts. Default 300, minimum 60 |
model_caps_refresh_seconds |
Poll interval for the per-model caps. Default 300, minimum 60 |
config.json is read as UTF-8 (a byte-order mark is fine) or UTF-16, so Notepad's "UTF-8 with BOM" and "Unicode" saves both work. A file in another encoding, such as ANSI with a £ in it, cannot be read and is skipped: the defaults apply until you save it as UTF-8.
The refresh timer. Claude Code repaints the status line on its own events (a prompt, a tool call). Anything that moves with the clock, such as animation frames, the focus countdown or the heartbeat's elapsed time, needs a timer as well. Setup writes statusLine.refreshInterval into settings.json for this: 2 seconds while animating, 15 seconds for time-based widgets, and nothing at all for a static bar. It is kept in sync whenever you change a setting.
This is the output of python claude_status.py --help:
usage-pulse 3.9.1 — usage status line for Claude Code
Usage: python claude_status.py [flag [args]]
With no flag and JSON on stdin (how Claude Code runs it) it prints the status line.
Setup
--setup [--non-interactive] Guided setup: status line, hooks, providers, theme, widgets
--install Install the status line, agent-panel rows and /pulse (no questions)
--update Update a git install to the latest release
--uninstall Remove the status line, hooks and /pulse from Claude Code's settings
--help Show this list (also -h)
--install-copilot Use this bar as GitHub Copilot CLI's status line (writes ~/.copilot/settings.json)
--uninstall-copilot Remove the bar from GitHub Copilot CLI's settings
Look
--theme <name> Set the colour theme (see --themes)
--pick-theme Arrow-key theme picker with a live preview
--pick Same as --pick-theme
--themes List themes
--themes-demo Preview the status line in every theme
--show-themes Theme previews in their accent colours
--show-colors List text colours
--show-all --show-themes and --show-colors together
--text-color <name|auto> Colour for labels and percentages
--animate <off|rainbow|pulse|glow|shift>
Bar animation
--animation-speed <slow|normal|fast>
Animation speed
--bar-size <small|small-medium|medium|medium-large|large|auto>
Bar width (auto shrinks to fit)
--bar-style <name> Bar characters (classic, block, dot, braille, ...)
--layout <standard|compact|minimal|percent-first>
How labels, bars and numbers are arranged
--max-width <20-100> Percent of the terminal width to use
--wrap <off|auto> Wrap onto up to 4 rows instead of truncating
--preset <minimal|default> Apply a bundle of settings (default = factory reset)
Widgets
--show <parts> Turn widgets on (comma-separated)
--hide <parts> Turn widgets off (comma-separated)
--priority <widget=N,...> Reorder widgets (lower = further left)
--currency <symbol|code> Currency for cost widgets: a symbol or ISO code such as DKK (converted from USD)
--clock-format <12h|24h> Clock for reset times
--effort-format <labeled|full|short>
How reasoning effort is written
--context-format <percent|tokens> Context window as a percentage or tokens
--extra-display <auto|full|amount> How extra-usage credits are shown
--weekly-timer-format <auto|countdown|date|full>
Weekly reset timer style
--weekly-timer-prefix <text> Text before the weekly reset time (e.g. R:)
--streak-style <fire|text> Usage streak style
--pace-style <arrows|percent> Pace widget: arrows against the clock, or the elapsed share
--budget <amount|off> Spend budget to match --max-budget-usd
--limits [key=N,...] Subagent and web-search caps used as denominators
--focus <start [min]|stop|status> Focus (pomodoro) timer
Providers
--detect-providers [--json] Find other Claude accounts, Codex, Gemini, Copilot and MiniMax on this machine
--providers <list|detect|enable|disable|label|remove|add-file> [...]
Manage the extra status rows: --providers help lists the sub-commands
Hooks
--install-hooks [--only heartbeat,agents,team]
Install hooks (all three groups unless --only)
Info
--config Print the current configuration
--stats Usage statistics and streaks
--heatmap Usage heatmap
--debug-stdin Save and parse the JSON Claude Code pipes in
Internal
--host copilot Status line for GitHub Copilot CLI (run by Copilot CLI)
--subagent-status-line Agent-panel rows (run by Claude Code)
--hook-refresh [tool] PostToolUse hook
--hook-subagent-start SubagentStart hook
--hook-subagent-stop SubagentStop hook
--hook-teammate-idle TeammateIdle hook
--hook-task-created TaskCreated hook
--hook-task-completed TaskCompleted hook
--sync-install-path Plugin SessionStart hook: re-point settings.json after a plugin update
Inside Claude Code: /pulse (or /pulse setup) does all of this by asking you.
┌───────────────────────────────────────────────┐
│ Claude Code │
│ Pipes JSON via stdin on every status refresh │
│ (model, context, cost, rate_limits, effort, │
│ fast_mode, agent, pr, prompt_cache, repo) │
├───────────────────────────────────────────────┤
│ claude_status.py │
│ Reads stdin → builds the ANSI status line │
│ No API calls for the main bars (v2.1.80+) │
├───────────────────────────────────────────────┤
│ Hooks (optional) │
│ Agents, team, heartbeat: write small state │
│ files that the next repaint reads │
├───────────────────────────────────────────────┤
│ Provider rows (optional) │
│ Local files for Gemini and JSON files; one │
│ cached usage call per other Claude account │
│ and for Codex (chatgpt.com) │
├───────────────────────────────────────────────┤
│ Cache layer │
│ Exchange rates (24h) · update checks (1h) │
│ cumulative + weekly cost (5m) · 429 backoff │
│ animation state · history │
└───────────────────────────────────────────────┘
Claude Code sends rate_limits on stdin, so the main bars need no OAuth call and cannot be rate limited. The usage API is used for three optional things: extra (bonus) credits, the per-model caps you opted into, and the rows for other Claude accounts when none of their windows is open. A 429 backs off exponentially instead of retrying on every repaint. A truncated or hand-edited cache or settings file degrades to a cache miss instead of blanking the bar.
Security
- No API calls for the main usage bars. They come straight from Claude Code's stdin.
- Each token goes to its own service only. Claude OAuth tokens are sent only to
api.anthropic.com(usage) andplatform.claude.com(renewing your own expired token, kept in memory and never written back). The Codex CLI's token, only while the Codex row is on, goes tochatgpt.comalone and is never refreshed. Hardcoded allowlists enforce both, and redirects to any other host are blocked. - Other accounts' tokens are read, never changed. For a provider row the token is read from that account's
.credentials.jsonand is never refreshed, stored or logged. Refreshing it would rotate the refresh token and sign that account out. - Only the plan's name is read from your profile. With the
planwidget or provider tiers on, the OAuth profile is asked once a day fororganization.plan_display_name; the e-mail and account name in that reply are discarded, never stored. Labels come from your config or from the folder name. - Settings are backed up before Usage Pulse first writes
settings.json, and--install-hooksrefuses to replace a file that is not valid JSON. - All file writes are atomic with 0o600 permissions, every piece of external data (provider labels and files included) is stripped of ANSI escapes, hyperlink targets are limited to
http(s)without control characters, no subprocess usesshell=True, and the exchange-rate API (frankfurter.dev) is read-only, unauthenticated and cached for 24 hours.
Requirements: Python 3.8+ with nothing to pip install, Claude Code 2.1.80+ with a Pro or Max subscription (Fable reporting needs 2.1.170+), and no API key, since it uses Claude Code's existing login.
Common fixes
| Issue | Fix |
|---|---|
| No status line visible | Run --setup (or /usage-pulse:setup for the plugin) and restart Claude Code |
| Status line vanished after a plugin update | Start a new session: the plugin's SessionStart hook re-points settings.json at the new version folder. Or run /usage-pulse:setup again |
--setup says it used the defaults |
It found no interactive terminal. Run it in Windows Terminal, PowerShell or a normal shell, not Git Bash's mintty |
Setup says settings.json is invalid |
Fix the JSON it names and run setup again. Nothing was changed |
| Replaced my old status line by mistake | Setup prints the old command. Earlier copies of settings.json are in settings-backups/ in the state folder |
| A provider row is missing | --providers list shows what is configured and --detect-providers what exists. Check that the providers widget is on |
A Claude, Codex or MiniMax row shows ~29% with dim bars |
The data is more than 30 minutes old. Use that account once, or wait for the next refresh. For Codex it usually means the login has expired: run any codex command |
A provider row shows -- |
The source could not be read yet: no token, a missing file, or no rate-limit data in the newest Codex session |
| No bar in GitHub Copilot CLI | Run --install-copilot and restart Copilot CLI. In Copilot's /statusline picker, check that custom is ticked |
Copilot's Plan shows -- |
Copilot CLI has not saved a record for the signed-in account yet. Start Copilot CLI once while signed in |
Copilot's Plan numbers look behind |
They come from the record Copilot CLI keeps on disk, which it refreshes itself, not after every prompt. Session is live |
| "Rate limited" message | The main bars read stdin, so they keep working. API-backed parts back off before retrying |
--update says it cannot reach GitHub |
Both the GitHub API and git ls-remote failed. Check the network; the unauthenticated API alone is not needed since 3.4.1 |
| The bars are two characters wide | --bar-size auto is on, or the version is older than 3.6.0, which shrank bars to fit the window. Set a named size with --bar-size large; in a narrow window, --wrap auto puts the rest of the line on extra rows |
| Animation or timer frozen when idle | Run --setup again. The real setting is statusLine.refreshInterval |
| Opus/Sonnet/Fable bar missing | They are off by default (--show fable). They also render only when your plan reports that cap, and Claude Pro returns none |
| Heartbeat not showing | Run --install-hooks --only heartbeat, switch the widget on with --show heartbeat, and restart Claude Code. It shows after the first tool call |
| Settings error after hook install | Run /doctor. Hooks need the nested format {matcher, hooks: [{type, command}]} |
| Unicode characters broken | Try --bar-style block |
Note
Renamed from claude-pulse in October 2026 (3.5.0): Anthropic's plugin directory reserves names that start with claude-, and a different "Claude Pulse" is already listed there. The old GitHub address redirects here. Git and one-liner installs keep working as they are. Marketplace installs need one reinstall: /plugin uninstall claude-pulse, then /plugin install usage-pulse --marketplace NoobyGains/usage-pulse; the new plugin's hook moves the status line over on the next session start.
Per-model weekly caps came from @thedanielmay in PR #53, the per-bar toggles started in @lucachitayat's fork, and the project has picked up more ideas from its forks and issue reporters along the way. Bug reports and pull requests are welcome; the test suite (python -m unittest discover -s tests) runs in about a minute, and python tests/test_readme_claims.py keeps this page honest. What changed in each release is in CHANGELOG.md.
If Usage Pulse earns its place under your prompt, star the repo, tell someone who lives in Claude Code, or buy me a coffee.
Source Available. See LICENSE.









