Fix focus-gated needs-input flicker in live emulator query-response forwarding - #950
Merged
Merged
Conversation
…delivery The live PTY emulator's OSC 10/11 query-response forwarder delivered via Session.WriteInput, which stamps lastUserInput exactly like a real keystroke. idle-detection's clear-on-input logic reads that timestamp to decide the user answered a pending prompt, so a still-focused pane's periodic capability-query response falsely cleared the "(?)" needs-input flag every ~1s, producing a moon/(?) bounce for as long as the pane stayed focused. Route the forward through WriteInputSystem instead, mirroring the existing reliable-notify delivery pattern that exists for exactly this reason. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
4 tasks
…igin (#952) WriteInput (human keystroke) and WriteInputSystem (argus-injected input) are genuinely distinct semantics the needs-input heuristics depend on (BUG-034) - not tech debt to collapse. But nothing structurally forced a caller to pick the right one, and picking the wrong one has now happened twice (BUG-034 itself, then fix-live-emulator-writeinput). Replace both with WriteInput(p []byte, origin agentview.InputOrigin), a mandatory second parameter with no default, across agent.SessionHandle, agentview.TerminalAdapter, notify.SessionHandleIface, daemon/client.RemoteSession, and apiclient.Session. Also threads origin across the daemon RPC (WriteReq.Origin, ProtocolVersion 4->5, zero-value-safe both directions since OriginUser is the zero value) and the REST /input path (X-Input-Origin header, defaulting to user), closing the gap where a system-origin write silently degraded to user-input semantics once it crossed a process boundary. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
Merging this branch changes the coverage (3 decrease, 3 increase)
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files
|
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.
Summary
(?)→ then bounce between(?)and moon roughly every second for as long as the pane stayed focused, with static/unresized/non-restarted content. Unfocusing settled it to moon and it stayed there.forwardEmulatorResponse, added by the recent OSC 10/11 color-query feature) delivered responses viaSession.WriteInput, which stampslastUserInputexactly like a real keystroke.idle-detection's clear-on-input logic (NeedsInputClear) reads that timestamp to decide "the user answered," so it falsely cleared a still-unanswered(?)flag every time the agent CLI's own periodic redraw re-triggered a capability-query response — which only happens on the currently-focused pane's live (non-discard) emulator, and recurs on roughly the same ~1s cadence as the app's needs-input detection ticker.Session.WriteInputSysteminstead — it advances only the work-cycle timestamp, mirroring the existing reliable-notify delivery pattern (internal/notify) that exists for exactly this reason.agentview.TerminalAdaptergained aWriteInputSystemmethod for this; real session types already implemented it, test fakes got a stub.ClearedMarkerstale-recandidacy suppression (BUG-063/BUG-067) legitimately recognizing unchanged content as already-cleared once no more live emulator exists to keep perturbing it. No change needed there; documented in the gotcha.Process
fix-live-emulator-writeinput), archived atomically in this same PR (openspec/changes/archive/2026-08-22-fix-live-emulator-writeinput/, base specterminal-renderingupdated).context/knowledge/gotchas/pty-terminal.md(and updated the index) documenting the invariant.Test plan
WriteInputSystem, notWriteInput(TestTerminalPane_ForwardEmulatorResponse_ForwardsToSession,_DropsStaleOwner, the pre-existingTestTerminalPane_LiveEmulatorForwardsQueryResponseToSession).*agent.SessionprovesLastUserInputstays zero whileLastInputadvances (TestTerminalPane_ForwardEmulatorResponse_DoesNotAdvanceLastUserInput).make pre-prgreen exceptgovulncheck(stdlib CVEs, advisory-only — CI itself runs this step withcontinue-on-error: true, same result on master).-raceon all touched packages green; two known pre-existing, unrelated local flakes confirmed independent of this change (internal/agentARGUS_* env leakage in this sandbox,internal/selfupdate1Password gpg-signing).🤖 Generated with Claude Code