Claude chats compact at 400K by default; the context ring reads that window
What
Leo, 2026-10-20, looking at the composer's context ring card ("213.1K of 1M tokens"):
I was thinking about the context window thing. This looks kind of awkward, but I also want you to switch it into, like, say, I don't know, you can look up what the best one people have is. But I think I usually have, like, 400K on my typical [Claude] sessions.
Leo-ask: ask-bb14f0302a
- acpmux: every Claude Code session acpmux starts gets
CLAUDE_CODE_AUTO_COMPACT_WINDOW=400000(harness_limits::CLAUDE_AUTOCOMPACT_WINDOW), unless the person already set a window:--autocompactin the argv,CLAUDE_CODE_AUTO_COMPACT_WINDOWorCLAUDE_AUTOCOMPACT_PCT_OVERRIDEin the profile or login env, orautoCompactWindow(or either key inenv) in settings.json. An unreadable settings.json counts as set, so acpmux leaves it alone. Before this, a[1m]model ran uncapped and compacted only near 1M. - usageStats: the session reports that cap (
autocompact: capped,autocompactCap: 400000) using the same rule (usage_stats::claude_autocompact_unset), so Session Info,acpmux ls --wideand the runaway warning match how the session really runs. - Webview: the context ring, its card, the status card and Session Info's Context section now measure usage against the autocompact window when it is smaller than the model's (
compactingUsage). Claude Code's own/contextdoes the same. Example: "213.1K of 400K, 53% used" instead of "of 1M".
Checked by hand with Claude Code 2.1.310 and opus[1m]: /context reads 50.4k / 1m without the variable and 50.4k / 400k with it. In both cases modelUsage.contextWindow in the result stays 1000000, which is why the webview has to read the cap.
Changelog
Changed: Claude chats compact at 400K tokens by default, and the context ring shows usage of that window.
Testing
bun test src/agent-session/acpmux/UsageStats.test.ts: pass (new).usage_stats_tests::acpmux_sets_the_claude_window_only_when_the_person_set_none(new): runs throughcmux-ci teston this PR.scripts/web-lint.shandprepush-gate.py: pass.
Observed / Not run
- Observed: the Claude Code
/contextcheck above. - Not run: a DEV-build session check. Not done: the native sidebar hover card (
WorkspaceHoverCardContent) still reads the model's window; that is a follow-up. - Note: a session started before this change keeps running uncapped, but after the daemon update its usage reads as capped at 400K until it restarts.
The other half of the message (Karabiner bracket keys for switching tabs) is Leo's personal Karabiner config, and he said he would send a screenshot later. It is not part of this PR.
risk: normal
Agent session: agent session
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Claude sessions started by acpmux now compact at 400K tokens by default instead of running uncapped until the model's 1M window, and the context ring and usage displays measure against that cap.
- acpmux sets
CLAUDE_CODE_AUTO_COMPACT_WINDOW=400000only when nothing the person set decides a window: no--autocompactin the argv, noCLAUDE_CODE_AUTO_COMPACT_WINDOWorCLAUDE_AUTOCOMPACT_PCT_OVERRIDEin the env, and noautoCompactWindowin settings.json. An unreadable settings.json counts as set. - The context ring, status card, and Session Info now read usage against the autocompact cap when it is under the model's window, matching Claude Code's own
/context. - Sessions started before this change keep running uncapped, but read as capped at 400K until they restart.