Skip to content

fix: keep tool child stdin closed and run tool commands non-interactively - #42854

Open
utk-code wants to merge 3 commits into
anomalyco:devfrom
utk-code:fix-tool-interactive-stdin
Open

fix: keep tool child stdin closed and run tool commands non-interactively#42854
utk-code wants to merge 3 commits into
anomalyco:devfrom
utk-code:fix-tool-interactive-stdin

Conversation

@utk-code

@utk-code utk-code commented Aug 16, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #42773

Type of change

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

What does this PR do?

On Windows, tool commands that prompt on stdin (e.g. npm exec asking "Ok to proceed? (y)") hang — the prompt shows but nothing typed reaches the process, because the child stdin is an open pipe nothing closes and the TUI owns the console input.

Changes:

  • Spawner default for child stdin changed from open pipe to closed ("ignore"). Callers passing explicit stdin are unaffected.
  • Shell/bash tool commands now get CI=1, npm_config_yes=true, GIT_TERMINAL_PROMPT=0, NONINTERACTIVE=1, so tools like npm skip interactive prompts.

How did you verify your code works?

Reproduced on Windows: npm exec with an open stdin pipe hangs; with CI=1 or npm_config_yes=true it completes. Checked no tests rely on the old default.

Screenshots / recordings

N/A (not a UI change)

Checklist

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

@github-actions

Copy link
Copy Markdown
Contributor

Hey! Your PR title Fix tool interactive stdin doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@utk-code utk-code changed the title Fix tool interactive stdin fix: keep tool child stdin closed and run tool commands non-interactively Aug 16, 2026
@utk-code
utk-code force-pushed the fix-tool-interactive-stdin branch from c7f218a to 0399535 Compare August 16, 2026 06:33
@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

Review of the non-interactive tool execution fix:

  1. packages/core/src/cross-spawn-spawner.ts:119 — the default stdin flips from pipe to ignore for every caller that does not pass opts.stdin — any call site relying on the old implicitly-writable pipe (e.g. feeding data or credentials to a child) now gets an instantly-closed stdin and can fail or hang confusingly — audit internal callers for stdin writes, make the new expectation explicit at those sites, and call the semantic change out in release notes.
  2. packages/core/src/tool/bash.ts:162 and packages/opencode/src/tool/shell.ts:294 — the non-interactive env quartet (CI, npm_config_yes, GIT_TERMINAL_PROMPT, NONINTERACTIVE) is defined twice across two packages — duplicate literals drift apart the first time one copy gains DEBIAN_FRONTEND=noninteractive and the other does not — extract a shared exported constant (e.g. from core) and import it in both places.
  3. packages/core/src/tool/bash.ts:162 and packages/opencode/src/tool/shell.ts:298 — npm_config_yes=true makes package installs auto-confirm inside agent-executed shells — it prevents hangs, but it also silently removes the confirmation step for actions like npm install -g that the model initiates — document this contract in the bash/shell tool descriptions, or scope auto-yes to non-global installs.
  4. packages/opencode/src/tool/shell.ts:297-308 — nonInteractiveEnv is spread last, so it overrides explicitly provided env — sessions that deliberately set CI=0 or a custom GIT_TERMINAL_PROMPT are silently clobbered — either let per-command env take precedence over the defaults or add a comment marking the override as intentional hardening.
  5. Test coverage — neither behavior change ships with tests — add cases asserting a spawned child sees immediate EOF on stdin and that all four env vars are present on both the POSIX and win32 code paths.
  6. packages/core/src/cross-spawn-spawner.ts:119 — encoding: "utf-8" is retained next to stream: "ignore" — dead config that misleads readers into thinking output transcoding still applies — drop it for the ignore case or comment why it stays.

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.

Bash tool hangs when a command asks for input (npm/npx "Ok to proceed") on Windows

2 participants