Skip to content

fix(tui): stop piped stdin from breaking UI and keyboard input - #54539

Open
LordMikkel wants to merge 1 commit into
anomalyco:devfrom
LordMikkel:tui-piped-stdin
Open

LordMikkel wants to merge 1 commit into
anomalyco:devfrom
LordMikkel:tui-piped-stdin

Conversation

@LordMikkel

Copy link
Copy Markdown

Issue for this PR

Closes #42234
Closes #28538
Closes #24195
Closes #3871
Closes #6220

Related to #387 and #3930.

This is my third attempt at this fix. #28540 was closed by the stale PR bot and #34242 by the V1 cleanup, both before a maintainer review. The bug is still there in V2: I reproduced it with the current release binary and on dev. This is the port to V2.

Type of change

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

What does this PR do?

When stdin is piped (echo "hello" | opencode), the TUI renderer reads input from the pipe instead of the terminal. Keyboard control breaks completely: ANSI noise, no interaction.

opencode mini already handles this with resolveInteractiveStdin(), but the default TUI was missing it. This PR applies the same fix: open the controlling terminal (/dev/tty) and pass it to the renderer. /editor had the same problem, since the editor inherited the pipe, so it now uses the renderer's stdin too.

With no terminal at all (opencode </dev/null in docker exec without -t), it now exits with opencode requires a controlling terminal for input instead of hanging forever.

On Windows, Bun can't put a reopened CONIN$ in raw mode (setRawMode fails on any fd but stdin), so this leaves Windows unchanged for now.

How did you verify your code works?

Screenshots / recordings

From the previous PRs.

With the fix:

image image

Without the fix:

Image image

Checklist

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

With piped stdin the default TUI read keys from the pipe, so typing did
nothing. Reuse resolveInteractiveStdin() from mini to open the terminal and
pass it to the renderer and to /editor.

Windows is left as is: Bun can't put a reopened CONIN$ in raw mode.
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@LordMikkel

Copy link
Copy Markdown
Author

@simonklee this reuses resolveInteractiveStdin() from mini for the default TUI, so you're probably the best person to take a look when you have time. Thanks!

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

1 participant