Skip to content

fix(terminal): a Windows terminal read no longer shows PowerShell's history suggestion as typed input - #29415

Merged
nwparker merged 3 commits into
mainfrom
nwparker/paired-windows-wrong-terminal
Oct 16, 2026
Merged

nwparker merged 3 commits into
mainfrom
nwparker/paired-windows-wrong-terminal

Conversation

@nwparker

@nwparker nwparker commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 5 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​95 $\color{#cf222e}{\Huge{\mathbf{−}}}$​1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​94
Prod 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​69 $\color{#cf222e}{\Huge{\mathbf{−}}}$​3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​66

ELI5

On Windows, PowerShell suggests a command while you type. It takes that suggestion from a history file that every PowerShell window on the machine shares, and draws it in faint grey after your cursor. Orca's default orca terminal read kept that grey suggestion as if someone had typed it. A fresh terminal could therefore look as if another agent's command had been typed into it. Nothing was actually sent to the wrong terminal. The read now returns what the terminal really shows.

What Changed

Before: on a Windows host, a pwsh terminal created with orca terminal create could give a default orca terminal read like this, after an agent typed only Write-Output OWN_MARKER:

PS C:\...> Write-Output FOREIGN_LANE_COMMAND; Get-FileHash C:/elsewhere/other.pyWrite-Output FOREIGN_LANE_COMMAND; Get-FileHash C:/elsewhere/other.pyWrite-Output OWN_MARKER

FOREIGN_LANE_COMMAND … is a command another PowerShell session on the same Windows account ran. PSReadLine (PredictionSource History, InlineView, which is the pwsh 7 default) showed it as a suggestion and then erased it as the user kept typing.

After: the same read returns PS C:\...> Write-Output OWN_MARKER, OWN_MARKER, PS C:\...>. The --screen read already returned this.

Mechanism: on Windows, ConPTY does not pass the shell's text through. It re-sends the terminal as screen updates and moves the cursor with absolute positions (ESC[row;colH) and erase-characters (ESC[nX). The text-stream tail behind a default read throws those away, so text that was drawn and then overwritten stays in the stream. That is how the old suggestion ended up joined in front of the real command. For default reads of a native Windows ConPTY terminal, withVisibleSnapshotFallback (src/main/runtime/terminal/output/provider-buffer-capture.ts) now returns the rendered tail instead. The source is the host's live terminal emulator, which already parses every byte, with scrollback up to the read limit. If that model is stale or still loading, the source is the terminal provider's snapshot. The result is labelled source: 'screen'. The alternate-screen and blank-tail paths are unchanged. If no rendered rows are available, the read falls back to the stream. Reads on non-ConPTY terminals and --cursor reads are unchanged.

Why

The ticket listed three possible causes: wrong output routing, history redraw corruption, or input delivered to the wrong terminal. I tested each on the paired Windows host named in the ticket (runtime cf6d1083):

  • In a new pwsh terminal, a default read showed another lane's full Get-CimInstance … Get-Process … command glued in front of my own input. --screen on the same handle showed only my input.
  • That shell's PSReadLine settings were PredictionSource=HistoryAndPlugin, PredictionViewStyle=InlineView, HistorySaveStyle=SaveIncrementally. The shared history file contains the ticket's XFERWIN_DONE command 10 times.
  • I then recorded the raw ConPTY bytes with config/scripts/capture-agent-pty-transcript.mjs, against a throwaway one-line history file. The recording now lives in src/main/runtime/__fixtures__/. The suggestion is drawn in faint italic (ESC[97m ESC[2m ESC[3m) and erased with ESC[1;65H and ESC[13X.

So the terminal handle, the pane, the subscription and the input path all target the right terminal. Only the default read misreports what is on screen. The foreign text is always a command and never its output, and it always starts with the prefix the agent had already typed. That pattern fits a history suggestion, not misrouting.

Alternatives considered:

  • Teach the stream tail about absolute cursor moves. The tail tracks logical lines only. It knows neither the screen row nor the column width, and ConPTY wraps long lines without sending a newline. In the recording the suggestion wraps onto a second row, so a "same row only" version would still keep a fragment of the other path, and a wrong row guess would delete real output. This would mean building a second terminal emulator inside a performance-critical path.
  • Strip faint (SGR 2) text. This is heuristic, and it would also hide real dimmed output.
  • Turn off PSReadLine prediction in Orca-spawned shells. That changes the user's shell. It also would not fix other ConPTY repaint leftovers, such as the cclclecleaclear-style stacking.

The host's emulator already sees every byte in order, and the --screen and alternate-screen reads already depend on it, so using it here adds no new mechanism.

Residual, unchanged: --cursor reads page through completed stream lines, which is a separate contract, so on ConPTY they can still include an erased suggestion. On a terminal reattached after an Orca restart, the ConPTY mark may not be set again, and those reads keep the old stream behavior.

Linked Issue

Resolves Linear STA-10739 (seen while validating #29292; this PR does not change #29292).

Visual Proof

N/A. This changes the text that orca terminal read returns, not the UI. The before and after reads are above, and the test asserts them from the recorded bytes.

Testing

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

  • New src/main/runtime/orca-runtime-tests/conpty-stream-read.spec.ts feeds the recorded pwsh 7.6 ConPTY bytes into the runtime, then does a default read. It fails on main with the foreign command in front of Write-Output OWN_MARKER, and passes with this change. A control case confirms that a non-ConPTY terminal still returns source: 'stream' output.

  • src/main/runtime/orca-runtime.test.ts: 1388 passed, 1 skipped.

  • pnpm tc:node and pnpm run check:code-quality:changed pass.

  • Windows: reproduced and recorded on the paired Windows host (pwsh 7.6.7). The probe terminal used a temporary history file and is now closed.

Review

Codex review (gpt-6.1-sol, high) results are in a PR comment.

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • SSH and paired hosts: the execution host serves the read from its own emulator. No wire change. The read result already has the optional source: 'screen' value, which older clients ignore.
  • Performance: a default read already awaited the host emulator on this path (the alternate-screen check). The added projection is bounded by the read limit.
  • macOS and Linux: unchanged. The path is gated on the native Windows ConPTY spawn mark.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 7 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: defbb2bb-962d-40c7-a1b1-c35b6cdb1c99
📥 Commits

Reviewing files that changed from the base of the PR and between a8f2c65 and 55186f5.

📒 Files selected for processing: 6
  • src/main/daemon/serialize-grid-transcript-replay.test.ts
  • src/main/runtime/__fixtures__/pwsh-7-6-psreadline-history-prediction-conpty.meta.json
  • src/main/runtime/__fixtures__/pwsh-7-6-psreadline-history-prediction-conpty.txt
  • src/main/runtime/orca-runtime-tests/conpty-stream-read.spec.ts
  • src/main/runtime/orca-runtime.test.ts
  • src/main/runtime/terminal/output/provider-buffer-capture.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nwparker
nwparker force-pushed the nwparker/paired-windows-wrong-terminal branch from 3140ed7 to 7d0370c Compare October 16, 2026 04:45
@nwparker

Copy link
Copy Markdown
Contributor Author

Codex review (gpt-6.1-sol, high). Round 1 found 3 P2 issues, all fixed in 7d0370c: (1) visible-only TUI-idle probes now get the visible screen, not scrollback; (2) the provider fallback is bounded by the 750 ms visible-snapshot timeout; (3) the projection over-fetches by one screen of rows, so blank rows below the prompt don't consume the line limit (new test). Round 2 on 7d0370c: no actionable issues.

@nwparker
nwparker force-pushed the nwparker/paired-windows-wrong-terminal branch from 7d0370c to 55186f5 Compare October 16, 2026 05:31
@nwparker
nwparker merged commit ee31691 into main Oct 16, 2026
36 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant