Repository navigation
fix(terminal): do not answer replayed terminal queries again - #455
Merged
Merged
Conversation
When a terminal's xterm instance is recreated, its history is replayed into the new instance. Queries in that history (OSC colour queries, cursor position and device attribute requests) were answered a second time, and the replies were typed into whatever ran in the shell by then (zsh: "command not found: 11"). Replayed snapshots now drop query sequences before they reach xterm; live output still gets its answers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 of 9 tasks
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.
💡 Change Scope
📝 What Does This PR Do?
Fixes stale terminal replies being typed into the shell after a terminal's xterm instance is recreated.
When OpenCove recreates a terminal's xterm instance (switching the terminal theme mode, restoring a terminal, and — with the upcoming transparent terminals — switching the terminal background), it replays the terminal's history into the new instance. If that history contains queries a program sent earlier — OSC colour queries (
ESC ] 11 ; ?), cursor position reports (ESC [ 6n), device attributes (ESC [ c) — the new instance answers them again, and the answer arrives in the PTY as input to whatever runs now. Found while writing the transparent-terminal E2E: after a recreation, zsh receivedESC ] 11 ; rgb:0909/0e0e/1212 BELand printedcommand not found: 11.stripTerminalQuerySequences(src/shared/terminal/automaticTerminalSequences.ts) removes the CSI queries the input bridge already recognises plus OSC 4 / 10–19 colour queries, and keeps everything else (colour sets, titles, cursor movement, styles).hydrateFromSnapshotstrips replayed snapshots before writing them to xterm. Live output that arrives during hydration keeps its existing routing, so programs that ask while a terminal hydrates still get answers.🏗️ Large Change Spec (Required if "Large Change" is checked)
Not a Large change: one pure function and one call site in the replay path.
Invariant: replayed history never produces input to the PTY; live queries are still answered.
✅ Delivery & Compliance Checklist
pnpm verify:quick/pnpm pre-commitis green; any additional focused tests are reported above.CLA.md).DEVELOPMENT.mdarchitectural boundaries.Unit:
automaticTerminalSequences.spec.ts(each query kind removed; colour sets, titles, cursor movement and styles kept). The end-to-end proof is the transparent-terminal E2E in the follow-up PR, which recreates xterm after an OSC 11 query and checks the next command runs cleanly (it failed before this fix).Local (macOS arm64):
pnpm verify:quickpassed with this change (related Vitest 330 files / 1563 tests, native contracts 6 / 9, representative E2E 18 tests, run together with the follow-up); on this branch alone the hydration and sequence unit tests (28 files / 178 tests) and the terminal, recovery and reattach E2E files (45 files: 65 passed, 6 skipped, 1 failed). The failure wasworkspace-canvas.terminal-agent-restart.spec.ts:39(codex): the restored sentinel appeared and then the screen was redrawn blank. Instrumenting the stripper showed it removes nothing in that test, so the replayed data is identical to main; across repeats it failed 2 of 13 times on this branch and passed 12 of 12 on main, which reads as a rare timing flake that this change does not touch. CI will show if it recurs.Full CI on the final revision
8bf03a56: all 11 checks passed (run 38828073866, attempt 2). Attempt 1 failed only inweb-canvas-continuity-ubuntu:workerWebCanvas.terminal-live-reattach-geometry.spec.ts:10could not seed its state (sync.writeState failed: persistence.invalid_state), before any terminal output was replayed; it passed on the rerun.workspace-canvas.terminal-agent-restartpassed on all three macOS shards.📸 Screenshots / Visual Evidence
No UI change.
🤖 Generated with Claude Code