Claude Realtime Context Gauge
How full your Claude Code context is, and how much of your subscription you have
spent, live in the VS Code status bar — measured rather than assumed.
The reading refreshes every few seconds, and the probe files a fresh one on every
statusline render, so the number moves while you work rather than when you go
looking for it.
(dashboard) 29% (clock) 4% (calendar) 8%
A dashboard for context, a clock for the 5-hour window, a calendar for the 7-day
one. Hover for meters, reset times and cost. A percentage that had to be assumed
is prefixed ~; a measured one never is. The bar takes its colour from whichever
number is most pressing, so a nearly spent quota shows through on a fresh
context.
Why it exists
Claude Code's journal files (~/.claude/projects/**/*.jsonl) record the model as
claude-opus-5. They never record whether that session is the 200k or the 1M
variant — the [1m] suffix is dropped on the way in. Anything reading only the
journal must therefore assume the denominator, and a wrong denominator is a wrong
percentage.
Measured on a real session: 61% reported where the truth was 13%. Same tokens,
wrong window.
The figure does exist, just not in the journal. Claude Code hands its statusline
command a description of the session:
{
"model": { "id": "claude-opus-5[1m]", "display_name": "Opus 5 (1M context)" },
"context_window": {
"total_input_tokens": 130808,
"context_window_size": 1000000, // the real number
"used_percentage": 13
},
"rate_limits": { "five_hour": { ... }, "seven_day": { ... } },
"cost": { "total_cost_usd": 4.94 }
}
This extension puts a small probe there to catch it.
How it works
Exact Mode. A probe script is wired in as your Claude Code statusLine. On
every render it files two small notes under ~/.claude:
| File |
Holds |
.gauge-probe.json |
The latest reading: live session, real window, quota, cost |
.gauge-windows.json |
Windows already observed, filed per session and per model |
The window is filed against the session, not just the model id, because one id
runs at two sizes and the journal cannot tell them apart.
Journal reading, always. The statusline only runs in a terminal, never in the
VS Code Claude panel, so token counts always come from the journal:
context = input_tokens + cache_creation_input_tokens + cache_read_input_tokens
That is Claude Code's own sum, confirmed against its binary. Output tokens are
excluded because they are not resent. Sub-agent turns are skipped — their context
is not yours.
The percentage is journal tokens over the filed window, and the gauge states how
far it trusts itself:
| Shown |
Means |
29% |
measured — the window was observed for this very session |
29% |
carried — the window was last seen for this model |
~35% |
assumed — never observed; marked with ~ |
An assumption is never dressed up as a measurement. That is the whole point.
Subscription usage
The same payload carries rate_limits, so the 5-hour and 7-day windows cost
nothing extra: no network call, no credentials read, no tokens spent.
They need Exact Mode, since only a statusline render produces them. Work solely
in the VS Code Claude panel and they eventually go stale and are dropped from
the display rather than shown as a figure nobody can vouch for. Context percent
is unaffected — it comes from the journal.
Setup
- Install the extension.
- Accept the one-time offer, or run Claude Gauge: Turn On Exact Mode.
- Use Claude Code in a terminal once. The window is captured on the first render.
Turning it on copies settings.json to settings.json.gauge-backup-<timestamp>
first. An existing statusline is kept and chained — your line still renders,
the probe only rides along. Undo with Claude Gauge: Turn Off Exact Mode,
which hands back exactly what was there before.
Would rather not touch your settings? Skip Exact Mode and set
claudeGauge.contextWindowOverride to 1000000. Exact numbers, no probe, but
you must change it yourself when you switch models.
Commands
| Command |
Does |
Claude Gauge: Open Menu |
Everything below, in one list (the click action) |
Claude Gauge: Read Again |
Re-read now |
Claude Gauge: Turn On / Off Exact Mode |
Wire or unwire the statusline probe |
Claude Gauge: Pin Session |
Follow one session instead of choosing automatically |
Claude Gauge: Choose Labels |
Built-in icons, plain words, or bundled glyphs |
Claude Gauge: Choose Hover Style |
Coloured bars or monospace meters |
Claude Gauge: Copy Carry-Over Summary |
Clipboard summary for continuing elsewhere |
Claude Gauge: Show Details |
Dump the resolved reading as JSON |
Settings
| Setting |
Default |
Purpose |
claudeGauge.claudeHome |
~/.claude |
Where Claude Code keeps its data; a leading ~ is expanded |
claudeGauge.pollMs |
5000 |
How often to re-read. Unfocused windows drop to once a minute, and the probe file is watched either way |
claudeGauge.contextWindowOverride |
0 |
Fix the window; 0 works it out |
claudeGauge.limitToWorkspace |
true |
Only sessions for open folders |
claudeGauge.carryOverAt |
50 |
Percent above which Carry over appears |
claudeGauge.markAssumptions |
true |
Prefix ~ on an assumed percentage |
claudeGauge.showQuotaInBar |
true |
Quota beside the context percent |
claudeGauge.quotaStaleAfterMs |
900000 |
Drop quota older than this |
claudeGauge.labelStyle |
builtin |
builtin, words or bundled |
claudeGauge.hoverStyle |
bars |
bars for coloured meters, text for monospace |
Which session does it read?
A busy project accumulates dozens of journals, and "most recently written" lands
on the wrong one often. In order:
- A session pinned through Pin Session
- The session the probe last rendered, if under five minutes old and inside this
workspace — the one actually on screen
- The most recent journal holding a measurable turn
The hover always says which, in plain words.
Labels
The bar uses VS Code's built-in icons by default.
scripts/build-icons.js also builds a 1.9 KB subset of Lucide's official font
and contributes it through contributes.icons. It does not render. Measured
on VS Code 1.133: $(id) in status bar text resolves to a CSS class, and a
contributed icon id has no matching rule, so the glyph comes out as an empty
span — no fallback box, no error, nothing. The percentages appear with blank gaps
where the icons should be.
So claudeGauge.labelStyle defaults to builtin. bundled stays selectable in
case a future VS Code resolves them, and words needs no font at all.
npm run build:icons # rebuild the glyph subset after changing the icon list
Lucide is ISC licensed; its notice ships in media/LUCIDE-LICENSE.
The extension icon is media/icon.png (128x128, transparent corners), cropped
and scaled from the full-resolution artwork kept beside it as
media/icon-source.png.
Privacy
No network calls. No credentials read. Nothing leaves the machine — every figure
comes from files Claude Code already writes locally.
Development
npm test # 46 tests
npm run check -- "D:\path\to\workspace" # read-only run against the real ~/.claude
The suite pins the original defect: 69,411 tokens on claude-opus-5 must read 7%
against a measured window, and ~35% — marked as an assumption — without one.
Author
Lakshan Jayasinghe — lakshanjs.com
Licence
MIT