Skip to content

fix(tui): force terminal reset on exit for Windows ConPTY - #48878

Open
kraso wants to merge 1 commit into
anomalyco:devfrom
kraso:terminal-reset-conpty
Open

kraso wants to merge 1 commit into
anomalyco:devfrom
kraso:terminal-reset-conpty

Conversation

@kraso

@kraso kraso commented Sep 14, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #48776

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

On Windows ConPTY stacks (Alacritty + zellij), exiting opencode left the terminal
in a raw/corrupted state and, in some setups, terminated the parent shell/pane.

Two things caused it:

  • @opentui/core's native renderer teardown closes the shared console handle on
    Windows, which kills the parent shell / zellij pane. The OS releases that
    handle when the process exits, so the call is skipped on win32.
  • The exit reset emitted \x1b[?1049l (leave alternate screen), which races with
    process teardown on ConPTY and can also kill the pane. It is replaced with
    \x1b[2J\x1b[H (clear screen + home) instead.

The reset now also runs synchronously via fs.writeSync on every exit path
(/exit, SIGHUP, SIGTERM, and process.on("exit")).

How did you verify your code works?

  • bun typecheck in packages/tui — no new errors (baseline and patched trees
    report identical counts).
  • bun run lint (oxlint) — no new findings.
  • Built opencode-windows-x64 with the repo-pinned bun (script/build.ts --single),
    smoke test (--version) passed.
  • Manual test on Windows with Alacritty + zellij (0.43.1): consecutive
    open//exit cycles leave zellij intact and the screen clean, and the session
    epilogue still prints.

Screenshots / recordings

If this is a UI change, please include a screenshot or recording.

Recording from the earlier repro/discussion on the same stack:
https://github.com/user-attachments/assets/8c574259-de03-4b0c-a6db-089e671562dc

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@kraso

kraso commented Sep 21, 2026

Copy link
Copy Markdown
Author

Hi! Quick follow-up on this one. The fix is validated on Windows (Alacritty + zellij 0.43.1): consecutive open/exit cycles leave zellij intact, screen clean, and the session epilogue prints. CI checks are green and the diff is limited to the two TUI files.

Happy to adjust the approach if the maintainers would rather handle the ConPTY teardown differently (e.g. upstream in @opentui/core).

@kraso

kraso commented Sep 24, 2026

Copy link
Copy Markdown
Author

Thanks for the queue time here. Rather than another ping, I'd like to ask one concrete thing about the approach, so I can put the effort in the right place.

Question: should this live in the TUI, or upstream in @opentui/core? The reset is implemented in packages/tui/src/util/renderer.ts. If the preferred direction is for @opentui/core's teardown to disable the modes it enabled, I'd rather close this and open it there than keep pushing a patch in the wrong layer.

Why I'm asking instead of just waiting: the bug reproduces on Windows + Alacritty + zellij (ConPTY) and is tracked in #48776. #49089 was an independent attempt by another contributor that touched the same two files and referenced the same issue — it was closed by the compliance bot, not on review. There's also a longer history of teardown fixes that never landed (#29596, #21278, #20377, #32364, #24789, #28379). That pattern is why I think the open question is "which layer", not "whether this is valid".

Why it matters to me in practice: I use opencode daily on this exact setup, and without the fix exiting the TUI takes down the zellij pane — so I run a locally built, patched binary. In my experience some Zen models only unlock on the latest released build, so staying on an older patched version isn't an option for me. The result is rebuilding and redeploying the patch on every release, just to keep using opencode normally. Landing something upstream would end that loop.

Happy to rework this patch into whatever shape you prefer, or move it to @opentui/core — a steer on the direction would unblock it.

This branch has not been deployed

No deployments
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.

TUI leaves terminal in raw/corrupted state on /exit under Alacritty + zellij-windows (Windows ConPTY)

1 participant