fix(tui): reserve the bottom row on legacy Win10 conhost - #291
Merged
Conversation
The v0.4.2 synchronized-update bracketing (eb690e7) stopped the frame tearing but not the Win10 conhost reports: residual shaking, and a duplicated last row under PowerShell. Both fit one mechanism the bracketing cannot address — the TUI pins its root to `height={rows}`, and the frozen inbox conhost scrolls when a full-height frame writes into its bottom row; DEC 2026 is ignored there, and a scroll is buffer movement, not tearing. Once the viewport slides one line, the repaint cursor math is off by one: the UI shakes and the row that scrolled away leaves the last row painted twice. No Windows machine was available to reproduce, so the change is the conservative guard: when the host looks like a legacy conhost (win32, and neither WT_SESSION nor TERM_PROGRAM set), `useTerminalSize` reports one row fewer, so no frame ever touches the bottom terminal row and there is nothing left to scroll. Every modern host — Windows Terminal, VS Code, anything setting those variables — keeps the full height, and non-TTY streams (tests, pipes, CI) are untouched. A one-time transcript hint on such consoles recommends Windows Terminal and names the escape hatch: ATOMIC_AGENT_CONHOST_GUARD=0 disables the guard, =1 forces it on anywhere — which is also how it was verified: a PTY+pyte run at 80x24 shows a 23-row frame, a never-written bottom row, and the hint; with the variable unset the frame is unchanged from main. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
What
Win10 reports against v0.4.1/v0.4.2 describe two symptoms the #243 synchronized-update bracketing did not close: residual "shaking" on legacy conhost, and a duplicated last row under PowerShell. Both fit one mechanism bracketing cannot address:
height={rows}, so every frame is exactly terminal-height;The fix is a conservative render guard, active only where the problem lives:
src/tui/legacy-conhost.ts):win32and neitherWT_SESSION(Windows Terminal) norTERM_PROGRAM(VS Code, mintty, …) set — i.e. a plain cmd/PowerShell conhost window.useTerminalSizereports one row fewer on such consoles (real TTY only), so no frame ever touches the bottom terminal row and there is nothing left to scroll. All modern hosts keep the full height; non-TTY streams (tests, pipes, CI) are untouched.ATOMIC_AGENT_CONHOST_GUARD=0disables the guard where the detection misfires;=1forces it on anywhere (useful for QA on any OS).No behaviour changes on macOS/Linux/Windows Terminal/VS Code: with the variable unset off-conhost, the rendered frame is unchanged from main.
Test evidence
src/tui/legacy-conhost.test.ts(detection truth table, clamp floor, hint gating) andsrc/tui/hooks/use-terminal-size.test.ts(TTY-only clamping, defaults). The clamp test was verified to fail with the guard neutered.src/tuisuite: 238 files / 2551 tests pass (the single unhandled-error notice is the known llama-server spawn EACCES noise fromlocal-models-orchestrator-auto-update.test.ts, present on main).npm run lint(tsc) clean.ATOMIC_AGENT_CONHOST_GUARD=1— frame is 23 rows, the bottom PTY row is never written during the whole run, and the startup hint renders in the transcript.Windows QA note
No Windows repro was available here, so this needs a pass on a real Win10 box — cmd/conhost and PowerShell/conhost should show no duplicated last row and no shaking with one blank bottom row + the hint; Windows Terminal must be pixel-identical to main with no hint.
ATOMIC_AGENT_CONHOST_GUARD=0on conhost reproduces main's behaviour for comparison.Reported on Discord: https://discord.com/channels/1515649306781155428/1515650562430079048/1541830173358301205 and https://discord.com/channels/1515649306781155428/1515651297691308183/1542897974445744159