Skip to content

fix(web): send /clear without compacting a stale thread first - #31100

Open
HoneyPaptan wants to merge 5 commits into
pingdotgg:mainfrom
HoneyPaptan:fix/clear-skips-compact
Open

HoneyPaptan wants to merge 5 commits into
pingdotgg:mainfrom
HoneyPaptan:fix/clear-skips-compact

Conversation

@HoneyPaptan

Copy link
Copy Markdown
Contributor

Problem

Fixes #31092.

On a Claude thread that has gone idle past its cache TTL (the "Compact" chip is showing), typing /clear sends /compact first and then /clear. The compaction re-reads the whole cold context (345K uncached tokens in the report) to write a summary that /clear discards a moment later.

Change

planComposerTurn already skips compact-before-send for a typed /compact. The same pattern now also matches /clear, so it is sent on its own. Matching is the same as for /compact: case-insensitive, the command must be the whole first word (/clearly ... still compacts first).

Not included: hiding the "Compact" chip while the composer holds /clear. That's a UI follow-up and the chip no longer causes a compaction for this message.

Scope and approval

A very small, focused fix for an obvious bug: the exact case the reporter hit, with the code path they pointed to. One regular expression and its comment, plus test cases.

Verification

  • Extended the existing planComposerTurn test in ChatView.logic.test.ts: /clear and /Clear no longer set compactBeforeSend or queue behind a compaction, while hello, /compactfoo and /clearly not a command still do. vp test run --project unit src/components/ChatView.logic.test.ts: 47 passed.
  • effect-tsgo typecheck of apps/web, plus vp fmt --check and vp lint on the changed files: clean.
  • Not checked: a live idle Claude thread in the app. The send path in useComposerSend.ts reads compactBeforeSend from this plan and is unchanged.

Model and harness: Claude Opus 5.5 (claude-opus-5-5) in Claude Code.

Compact-before-send only exempted /compact, so /clear on an idle Claude thread ran a full compaction of the old context and then discarded it.

Fixes pingdotgg#31092
@github-actions github-actions Bot added vouch:unvouched Author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Nov 4, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at c5e235d

Macroscope's review found this PR approvable — Explicit /clear commands now skip unnecessary stale-thread compaction, avoiding wasted work before context is discarded. Ordinary messages and existing queue safeguards retain their behavior.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The composer now skips pre-send compaction when the message begins with /clear or /compact at a command boundary. Tests cover /clear bypassing compaction and command-like prefixes that do not match.

Changes: Stale-session command handling

Layer / File(s) Summary
Command exclusion and validation
packages/client-runtime/src/state/contextWindow.ts, apps/web/src/components/ChatView.logic.ts, packages/client-runtime/src/state/contextWindow.test.ts, apps/web/src/components/ChatView.logic.test.ts
The shared pattern matches /clear and /compact, case-insensitively, when followed by whitespace or the end of the message. Pre-send compaction checks use this pattern. Tests cover /clear bypassing compaction and command-like prefixes that do not match.

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • pingdotgg/t3code#30097: This issue concerns idle background compaction after /clear; this change addresses the separate send-time compaction path.

Suggested reviewers: shivamhwp, juliusmarminge

Merge Risk: Minimal · up to e1e9b

Clear and compact commands bypass pre-send compaction. No material merge-blocking issue is established.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: preventing /clear from compacting a stale thread first.
Description check Passed The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the bug, implementation, scope decision, tests, validation results, and unchecked live…
Linked Issues check Passed [ #31092 ] NO_COMPACT_BEFORE_COMMAND_PATTERN matches /clear case-insensitively only at the first-word boundary. planComposerTurn and shared shouldCompactBeforeSend use this pattern, so `/clear…
Out of Scope Changes check Passed [ #31092 ] The changed runtime pattern, web composer logic, mobile/shared compaction logic, and focused tests all support the requested command behavior. No unrelated change is established by the pull…
Full details: Description check

Explanation

The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the bug, implementation, scope decision, tests, validation results, and unchecked live-thread verification.

Full details: Linked Issues check

Explanation

[ #31092 ] NO_COMPACT_BEFORE_COMMAND_PATTERN matches /clear case-insensitively only at the first-word boundary. planComposerTurn and shared shouldCompactBeforeSend use this pattern, so /clear does not trigger compact-before-send on a stale thread. Tests cover /clear and non-matching inputs such as /clearly not a command. The Compact chip UI is explicitly outside the issue requirement for this fix.

Full details: Out of Scope Changes check

Explanation

[ #31092 ] The changed runtime pattern, web composer logic, mobile/shared compaction logic, and focused tests all support the requested command behavior. No unrelated change is established by the pull request summary.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 5e75c64 and e1e9b42.

Files selected for processing: 2

  • apps/web/src/components/ChatView.logic.test.ts
  • apps/web/src/components/ChatView.logic.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

# Conflicts:
#	apps/web/src/components/ChatView.logic.ts
@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by claude-opus-5-5 on behalf of Maria

Merged current main (merge commit, no rebase) to clear the conflict in ChatView.logic.ts.

main moved the /compact exemption into packages/client-runtime/src/state/contextWindow.ts (#27935) so web and mobile share it. I resolved the conflict by moving this PR's pattern there as NO_COMPACT_BEFORE_COMMAND_PATTERN and importing it in ChatView.logic.ts. Mobile's shouldCompactBeforeSend now also skips compaction for /clear, with one added row in its existing contextWindow.test.ts table.

vp run check:changed passes (format, lint, knip, typecheck, tests).

@github-actions github-actions Bot added size:S 10-29 changed lines (additions + deletions). and removed size:XS 0-9 changed lines (additions + deletions). labels Nov 5, 2026
HoneyPaptan and others added 3 commits November 6, 2026 12:52
…lear-skips-compact

# Conflicts:
#	apps/web/src/components/ChatView.logic.ts
AI-assisted; verified with the tests and tools listed above.

Copy link
Copy Markdown
Member

Evidence

Web client, Chromium, 1280×800, light theme, separate fresh databases, real Claude connection, identical synthetic histories reporting 660,789 context tokens.

Connect without freshContext, advance the client clock past the cache TTL, leave Compact 661k enabled, type /clear, dismiss suggestions, restore the clock, and press Enter. Base sends /compact then queues /clear; head sends only /clear.

Before After
b3fdf2b10f e1e9b42a6b
Before: compaction occurred before clear After: clear completed without compaction
Before recording After recording

Reproduction instructions · Seed driver · Settings setup · Browser preparation · Compatibility proxy · Command audit

Controlled setup: the client clock was accelerated; no natural one-hour idle wait was performed. The proxy omitted freshContext to simulate an older server advertisement while forwarding real app traffic. Runtime model identifiers were excluded from evidence. Both recordings and stills were visually inspected.

AI-assisted; verified with the tests and tools listed above.

Not shown:

  • Natural prompt-cache expiry was not observed: client time was accelerated instead of waiting one hour.
  • An installed historical server release was not exercised: its missing freshContext advertisement was simulated by the compatibility proxy.
  • Provider billing and desktop/mobile surfaces were not measured; this proof demonstrates the web client's command ordering.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched Author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Sending /clear on a stale Claude thread compacts the old context first, then clears

3 participants