fix: attribute /clear transcript to the agent whose activity stopped, not the active terminal - #366
Open
yshyuk wants to merge 1 commit into
Open
Conversation
… not the active terminal With two sessions in the same project dir, the heuristic /clear detection claimed the new transcript for whichever agent owned the active terminal. If /clear ran in a background session while the user watched a busy one, the busy agent grabbed the cleared session's file as soon as it went idle for 2s, swapping the two characters' terminal bindings (clicking the busy character focused the cleared terminal and vice versa). Replace the active-terminal gate with pickClearClaimant(): among eligible idle internal agents, the one whose lastDataAt is closest to the new file's creation time claims it — the session that ran /clear stopped writing its old transcript at exactly that moment. This also allows /clear in a non-active terminal to be detected at all. Fixes pixel-agents-hq#251
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #251
Problem
With two Claude Code sessions in the same VS Code window (heuristic mode), running
/clearin one session can swap the two characters' terminal bindings: clicking the busy-looking character focuses the cleared terminal and vice versa. See #251 for a detailed report and reproduction.Cause
The heuristic
/cleardetection inserver/src/fileWatcher.tsgated the claim of a freshly created/cleartranscript onactiveAgentIdRef.current === agentId— i.e. whichever agent owns the active terminal claims the new file. If/clearruns in a background session while the user is focused on a busy one, the busy agent claims the cleared session's transcript as soon as it goes idle forCLEAR_IDLE_THRESHOLD_MS(2 s, e.g. between tools), rebinding itself to the other session. Both agent records end up with correct-looking statuses but crossedterminalRefs — exactly the swap described in the issue.A side effect of the old gate: a
/clearin a non-active terminal was never detected at all.Fix
Replace the active-terminal gate with
pickClearClaimant(): among the eligible agents (internal, hookless, idle past the threshold), the one whoselastDataAtis closest to the new file's creation time (birthtimeMs) claims it. The session that ran/clearstopped writing its old transcript at exactly the moment the new file was created, so file-creation-time proximity is a far more reliable attribution signal than terminal focus. Each agent's own poll makes the decision, so no new coordination is needed; a poll simply skips the file when another agent is the better match.The hooks path is unaffected — it already attributes
/clearcorrectly via the per-agentpendingClearflag onSessionEnd(reason=clear).Tests
server/__tests__/pickClearClaimant.test.ts(5 cases): single-agent claim, best-match wins over the polling agent, polling agent keeps the file when it is the best match, busy agents excluded, external/hook-driven/terminal-less agents excluded.npm run test:server— 283 passing.npm run compile(types + lint + build) clean.