[BUG] VS Code extension context pie pins at "100% context used" ~12k tokens before auto-compact fires; popup mislabels it as "until auto-compact"
Summary
In the VS Code extension, the context-usage pie in the input footer reads 100% context used well before auto-compact will fire, and its hover popup labels the number as "% of context remaining until auto-compact." — which it is not. The pie's denominator is contextWindow - maxOutputTokens - 13000, while the worker triggers auto-compact off its own resolved auto-compact window minus a summary buffer and precompute fraction. The two disagree by roughly 12k tokens on a 200k window, so the meter saturates at 100% while auto-compact still has real headroom.
The practical effect: the UI tells you that you are out of context and that auto-compact is imminent, auto-compact does not fire, and you have to run /compact manually. It reads as "auto-compact is broken" when it is actually working as designed.
Where
webview/index.js (extension 2.1.234). The meter is fed:
b(rot, {
usedTokens: e.usageData.value.totalTokens,
contextWindow: e.usageData.value.contextWindow
- e.usageData.value.maxOutputTokens
- 13000,
onCompact: l,
...
})
and rendered as:
let a = t > 0 ? Math.min(e / t * 100, 100) : 0; // clamped at 100
let c = 100 - a;
if (t === 0) return null;
if (c >= 50) return null; // only shows past 50% used
// title: `${Math.round(a)}% context used — click to compact`
// popup: `${Math.round(c)}% of context remaining until auto-compact.`
usageData.contextWindow / maxOutputTokens come from the SDK result message's modelUsage[currentMainLoopModel]; usageData.totalTokens is input + cache_creation + cache_read + output of the latest turn.
Numbers
Model claude-opus-5, 200k window (1M mode off via CLAUDE_CODE_DISABLE_1M_CONTEXT=1), default max_output_tokens 32000:
| | tokens |
|---|---|
| Pie denominator (200000 - 32000 - 13000) | 155,000 |
| Pie reads "100% context used" from | 155,000 |
| Worker auto-compact actually fires at | ~167,000 |
The worker figure is not a guess — across 104 compact_boundary records with trigger: "auto" in local transcripts, preTokens falls in a tight band of 167,003 – 184,721, clustered hard around 167.2k–167.9k.
So there is a ~12,000-token dead zone (larger if max_output_tokens resolves to 64000, which puts the denominator at 123,000 and widens the gap to ~44,000) in which the pie is pinned at 100%, the popup claims 0% remaining until auto-compact, and nothing happens automatically.
Repro
- VS Code extension, model Opus 5, 200k context window.
- Grow a session past ~155k tokens without crossing ~167k.
- The footer pie is full and its tooltip reads
100% context used; hovering shows0% of context remaining until auto-compact. - Keep going — no auto-compact occurs.
/compacthas to be invoked by hand.
A concrete session on my machine peaked at 157,170 tokens with zero compact_boundary entries, i.e. sat at a pinned 100% pie for the rest of its life.
Expected
Either:
- Feed the pie the worker's real numbers. The worker already computes and publishes exactly this state — the internal
autocompact_stateevent carrieseffective_window,threshold,enforcedandsource(documented in-binary as "The token count where threshold-triggered compaction fires on the worker"). Driving the meter fromthresholdwould make "100%" mean "auto-compact fires now", andenforced: falsewould let the UI stop promising a compaction that will not happen. - Or fix the label. If the pie is deliberately a "usable context" gauge rather than a countdown, the popup should not say "until auto-compact" — and it should not clamp silently at 100%, since that hides how much headroom is actually left.
Option 1 also fixes the parallel case the enforced flag exists for: when threshold compaction is not enforced, the popup's promise is wrong regardless of the denominator.
Environment
- Claude Code VS Code extension
2.1.234(anthropic.claude-code-2.1.234-darwin-arm64), native binary install - macOS (Darwin 25.5.0), arm64
- Model:
claude-opus-5 CLAUDE_CODE_DISABLE_1M_CONTEXT=1in~/.claude/settings.jsonautoCompactEnabledunset (default true); noDISABLE_AUTO_COMPACT/DISABLE_COMPACT- Custom
statusLineconfigured — note the extension panel does not render statusLine at all, so the pie is the only context indicator available in that surface
Investigated with Claude Code.