Description
Summary
On Windows (PowerShell / conpty), exiting the TUI with Ctrl+C leaves the terminal garbled -- the last TUI frame overlaps the shell prompt (stale content bleeding onto the primary screen). cls cleans it up, so it is a terminal-restore problem on exit, not lost data.
Filed from code analysis on macOS; I cannot reproduce Windows conpty locally, so the exact trigger needs a Windows repro to confirm. Everything below is from reading the exit path.
Why (from the code)
The TUI renders into the alternate screen (\x1b[?1049h). Clean exit must leave the alt screen and reset modes exactly once, ordered before the resume hint -- otherwise the final frame / a redundant alt-screen-leave lands on the primary buffer as overlapping output.
That teardown is carefully tuned, but for POSIX:
ui-tui/packages/hermes-ink/src/ink/ink.tsx--gracefulShutdown/cleanupTerminalModes/detachForShutdownexist specifically to avoid "2-3 redundantEXIT_ALT_SCREENsequences landing on the main screen AFTERprintResumeHint()" (see thedetachForShutdowndocstring, ~L1275-1290). The ordering guarantee is validated againstsignal-exit's deferred-unmount behavior.- The only
win32branch (ink.tsx:2409) is an early return in the stdin-drain helper ("No /dev/tty on Windows; CONIN$ doesn't support O_NONBLOCK"), so Windows skips part of the POSIX cleanup path. writeSync(1, EXIT_ALT_SCREEN)(ink.tsx:~2177) and the reset inui-tui/src/lib/terminalModes.ts(TERMINAL_MODE_RESET, includes\x1b[?1049l) assume POSIX fd/ordering semantics.- There are multiple exit paths that must not double-fire: the app's
die()(ui-tui/src/app/useMainApp.ts:~392-- inkexit()+process.exit(0)),setupGracefulExit's SIGINT handler +resetTerminalModes()(ui-tui/src/entry.tsx:95-112), andsignal-exit'sonExit(this.unmount)(ink.tsx:344).
On Windows conpty these assumptions don't hold: no /dev/tty, Ctrl+C delivery in raw mode differs, and conpty's alternate-screen / cursor-restore semantics differ. The "exactly one EXIT_ALT_SCREEN, ordered before the resume hint" guarantee breaks, so a redundant/mis-ordered alt-screen-leave plus the final render bleeds onto the primary buffer -> overlapping output.
Steps to reproduce
- Windows, PowerShell (Windows Terminal or conhost).
raven(enter TUI).- Press Ctrl+C to exit.
- Prompt returns with garbled / overlapping leftover TUI output.
Expected
Exiting the TUI (Ctrl+C or otherwise) restores the primary screen cleanly, same as POSIX.
Workaround
cls (Clear-Host) clears the overlap. If input is also affected (mouse modes left on), open a fresh tab.
Suggested direction
Make the alt-screen leave + terminal reset emit exactly once and ordered before the resume hint on Windows conpty too -- i.e. give the shutdown ordering guards (detachForShutdown / isUnmounted / cancel-pending-render) a Windows path instead of relying on POSIX signal-exit timing, and cover the cleanup the win32 early-return (ink.tsx:2409) skips.
Environment
Windows, PowerShell (conpty). Reproduced by a user on Ctrl+C exit.
Activity
fix(ui-tui): stop doubled Windows IME input and a garbled exit screen (…