Claude chats compact at 400K by default; the context ring reads that window

TE
3d ago
+132-6

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: --autocompact in the argv, CLAUDE_CODE_AUTO_COMPACT_WINDOW or CLAUDE_AUTOCOMPACT_PCT_OVERRIDE in the profile or login env, or autoCompactWindow (or either key in env) 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 --wide and 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 /context does 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 through cmux-ci test on this PR.
  • scripts/web-lint.sh and prepush-gate.py: pass.

Observed / Not run

  • Observed: the Claude Code /context check 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 Autofix with [code]smith
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=400000 only when nothing the person set decides a window: no --autocompact in the argv, no CLAUDE_CODE_AUTO_COMPACT_WINDOW or CLAUDE_AUTOCOMPACT_PCT_OVERRIDE in the env, and no autoCompactWindow in 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.