fix(web): suppress xterm.js terminal query auto-responses#272
Conversation
Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: ProverCoderAI#271
xterm.js answers TUI capability probes (OSC 4/10/11/12 color queries, DA1/DA2/DA3 device attributes, DSR/CPR) by emitting reply bytes through onData. Those bytes were forwarded to the PTY as if the user had typed them, so Claude Code rendered the raw escape sequences inside its prompt. Install a parser shim right after constructing the Terminal that consumes color queries (while letting set-color commands fall through) and always consumes device-attribute and cursor-position queries. The shim is returned as a disposable so tests can roll it back. Fixes ProverCoderAI#271
Working session summaryCI is running. Done — committed the fix, pushed, updated PR #272's title/body, and marked it ready for review. PR: #272 Summary of changes shipped on
CI is currently pending across all jobs. This summary was automatically extracted from the AI working session output. |
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost: $5.497444📊 Context and tokens usage:Claude Opus 4.7: (2 sub-sessions)
Total: (2.0K new + 134.5K cache writes + 7.3M cache reads) input tokens, 35.7K output tokens, $5.405814 cost Claude Haiku 4.5:
Total: (593 new + 40.3K cache writes + 241.6K cache reads) input tokens, 3.3K output tokens, $0.091631 cost 🤖 Models used:
📎 Log file uploaded as Gist (2959KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
🔄 Auto-restart triggered (iteration 1)Reason: CI failures detected Starting new session to address the issues. Auto-restart-until-mergeable mode is active. This run will stop after 5 restart iterations. |
The Lint Effect-TS check forbids `as`/`<T>` casts outside src/core/axioms.ts, and the new tests for terminal-query-suppression cast a mock to `Terminal` via `as never`. Replace the parameter type with a structural `TerminalQuerySuppressionTarget` that the real xterm `Terminal` already satisfies, so the mock can be passed directly without any cast.
Working session summaryAll 15 PR checks are SUCCESS — including the previously failing Lint Effect-TS. SummaryThe Lint Effect-TS check was failing because the new test file Fix (commit Verified locally: PR: #272 This summary was automatically extracted from the AI working session output. |
🔄 Auto-restart-until-mergeable Log (iteration 1)This log file contains the complete execution trace of the AI solution draft process. 💰 Cost: $2.200154📊 Context and tokens usage:
Total: (52 new + 78.3K cache writes + 2.8M cache reads) input tokens, 12.6K output tokens, $2.200154 cost 🤖 Models used:
📎 Log file uploaded as Gist (4076KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
🔄 Auto-restart triggered (iteration 2)Reason: Uncommitted changes detected Starting new session to address the issues. Auto-restart-until-mergeable mode is active. This run will stop after 5 restart iterations. |
Working session summaryEverything is in order:
PR: #272 This summary was automatically extracted from the AI working session output. |
🔄 Auto-restart-until-mergeable Log (iteration 2)This log file contains the complete execution trace of the AI solution draft process. 💰 Cost: $0.828325📊 Context and tokens usage:
Total: (34 new + 52.1K cache writes + 787.8K cache reads) input tokens, 4.3K output tokens, $0.828325 cost 🤖 Models used:
📎 Log file uploaded as Gist (4639KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
✅ Ready to mergeThis pull request is now ready to be merged:
Monitored by hive-mind with --auto-restart-until-mergeable flag |
This reverts commit 4ac09cf.
Summary
Fixes #271 — the web terminal was showing raw escape sequences such as
^[]10;rgb:f4f4/f7f7/fbfb^[\and^[[?1;2cinside Claude Code's prompt, breaking navigation and rendering.Root cause
xterm.js@5.3.0answers TUI capability probes out of the box:OSC 4/10/11/12color queries (\x1b]10;?\x1b\\, etc.)CSI ... cdevice attributes — DA1, DA2, DA3CSI ... ndevice status / cursor position reportsThe replies are emitted via
Terminal.onData, which the web frontend forwards to the host PTY as if the user typed them. Claude Code (and other TUIs) read those bytes as keystrokes inside their prompt loop and render them verbatim — exactly what the screenshot in the issue shows.Fix
A new module (
packages/app/src/web/terminal-query-suppression.ts) installs custom OSC/CSI handlers immediately after theTerminalis constructed increateTerminalRuntime:OSC 4/10/11/12the handler returnstrueonly when the payload contains a?segment (a query). Plain set-color payloads returnfalseso the default theme-change handler still applies.CSI ... c(DA1/DA2/DA3) andCSI ... n(DSR/CPR) the handler always returnstrueso xterm never reports back to the PTY.Handlers are tracked as disposables, so callers (and the unit tests) can roll the registration back without touching xterm's internal parser state.
Test plan
bun run --bun vitest run tests/docker-git/terminal-query-suppression.test.ts— 7 new unit tests covering query detection, handler registration order, OSC fall-through for set commands, CSI consumption, and disposal cleanup.bun run typecheckpasses.bun run build:websucceeds.printf "\\033]10;?\\033\\\\"— no echoed garbage in the prompt.Files
packages/app/src/web/terminal-query-suppression.ts(new) — suppression modulepackages/app/src/web/terminal-panel-runtime-core.ts— wire suppression intocreateTerminalRuntimepackages/app/tests/docker-git/terminal-query-suppression.test.ts(new) — unit testsexperiments/terminal-query-suppression.md— root-cause notesexperiments/verify-suppression.html— manual browser verification scaffoldFixes #271