Skip to content

fix: suppress stdout/stderr leak into TUI by using pipe instead of inherit#2423

Open
i010542 wants to merge 1 commit intocode-yeongyu:devfrom
i010542:fix/suppress-inherit-stdout-leak
Open

fix: suppress stdout/stderr leak into TUI by using pipe instead of inherit#2423
i010542 wants to merge 1 commit intocode-yeongyu:devfrom
i010542:fix/suppress-inherit-stdout-leak

Conversation

@i010542
Copy link

@i010542 i010542 commented Mar 10, 2026

Problem

When oh-my-opencode runs as an OpenCode plugin, the plugin is loaded via import() in the same process as the TUI. This means all spawned subprocesses share the same process.stdout and process.stderr file descriptors, which are being used by the TUI's alternate screen mode (@opentui/solid).

Using stdout: "inherit" and stderr: "inherit" in spawnWithWindowsHide() calls causes subprocess output to write directly to the terminal fd, rendering garbage text over the TUI interface.

Symptoms

  • bun install output (triggered by auto-update-checker) appears as random text in the TUI
  • On-complete hook output leaks into the TUI display
  • Users see garbled characters below the status bar

Fix

Changed stdout and stderr from "inherit" to "pipe" in two files:

src/cli/config-manager/bun-install.ts

  const proc = spawnWithWindowsHide(["bun", "install"], {
    cwd: cacheDir,
-   stdout: "inherit",
-   stderr: "inherit",
+   stdout: "pipe",
+   stderr: "pipe",
  })

src/cli/run/on-complete-hook.ts

  const proc = spawnWithWindowsHide(["sh", "-c", trimmedCommand], {
    env: { ... },
-   stdout: "inherit",
-   stderr: "inherit",
+   stdout: "pipe",
+   stderr: "pipe",
  })

Impact

  • Subprocess output is silently captured via pipes instead of leaking to the terminal
  • The bun install result is already checked via proc.exitCode, so the output is not needed
  • The on-complete hook exit code is already checked and logged via console.error
  • No functional behavior change — only visual output suppression when running inside a TUI

Summary by cubic

Pipe subprocess stdout/stderr to stop output leaking into the TUI’s alternate screen when running as an OpenCode plugin. Prevents bun install and on-complete hook output from rendering over the UI.

  • Bug Fixes
    • Changed spawn options from "inherit" to "pipe" in src/cli/config-manager/bun-install.ts and src/cli/run/on-complete-hook.ts to isolate subprocess output.

Written for commit 759c900. Summary will update on new commits.

…herit

When oh-my-opencode runs as an OpenCode plugin, it shares the same
process and terminal fd as the TUI. Using stdout/stderr: "inherit" in
spawned subprocesses (bun install, on-complete hooks) causes their
output to leak directly into the TUI's alternate screen, rendering
garbage text over the UI.

This changes all subprocess spawn calls that used "inherit" to use
"pipe" instead, silencing their output when running inside the TUI.

Affected files:
- src/cli/config-manager/bun-install.ts: bun install output leak
- src/cli/run/on-complete-hook.ts: on-complete hook output leak
@github-actions
Copy link
Contributor

Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement (CLA).

To sign the CLA, please comment on this PR with:

I have read the CLA Document and I hereby sign the CLA

This is a one-time requirement. Once signed, all your future contributions will be automatically accepted.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 2 files

Confidence score: 2/5

  • High-confidence, high-severity findings indicate a real regression risk: both subprocess call sites use "pipe" while discarding output, which can deadlock when buffers fill and cause commands to hang.
  • In src/cli/config-manager/bun-install.ts, using "pipe" instead of "ignore" can stall install-related child processes under normal output volume, creating user-facing freezes.
  • Pay close attention to src/cli/config-manager/bun-install.ts and src/cli/run/on-complete-hook.ts - both need stdio set to "ignore" (or streams drained) to avoid permanent subprocess hangs.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/cli/config-manager/bun-install.ts">

<violation number="1" location="src/cli/config-manager/bun-install.ts:34">
P1: Custom agent: **Opencode Compatibility**

Use `"ignore"` instead of `"pipe"` to safely suppress output and prevent the child process from deadlocking when the OS pipe buffer fills up.</violation>
</file>

<file name="src/cli/run/on-complete-hook.ts">

<violation number="1" location="src/cli/run/on-complete-hook.ts:29">
P1: Custom agent: **Opencode Compatibility**

Use `"ignore"` instead of `"pipe"` when discarding subprocess output. Leaving the streams as `"pipe"` without draining them will cause the subprocess to permanently hang if its output exceeds the OS pipe buffer size.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

cwd: cacheDir,
stdout: "inherit",
stderr: "inherit",
stdout: "pipe",
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Custom agent: Opencode Compatibility

Use "ignore" instead of "pipe" to safely suppress output and prevent the child process from deadlocking when the OS pipe buffer fills up.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/config-manager/bun-install.ts, line 34:

<comment>Use `"ignore"` instead of `"pipe"` to safely suppress output and prevent the child process from deadlocking when the OS pipe buffer fills up.</comment>

<file context>
@@ -31,8 +31,8 @@ export async function runBunInstallWithDetails(): Promise<BunInstallResult> {
       cwd: cacheDir,
-      stdout: "inherit",
-      stderr: "inherit",
+      stdout: "pipe",
+      stderr: "pipe",
     })
</file context>
Fix with Cubic

Comment on lines +29 to +30
stdout: "pipe",
stderr: "pipe",
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Custom agent: Opencode Compatibility

Use "ignore" instead of "pipe" when discarding subprocess output. Leaving the streams as "pipe" without draining them will cause the subprocess to permanently hang if its output exceeds the OS pipe buffer size.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/run/on-complete-hook.ts, line 29:

<comment>Use `"ignore"` instead of `"pipe"` when discarding subprocess output. Leaving the streams as `"pipe"` without draining them will cause the subprocess to permanently hang if its output exceeds the OS pipe buffer size.</comment>

<file context>
@@ -26,8 +26,8 @@ export async function executeOnCompleteHook(options: {
       },
-      stdout: "inherit",
-      stderr: "inherit",
+      stdout: "pipe",
+      stderr: "pipe",
     })
</file context>
Suggested change
stdout: "pipe",
stderr: "pipe",
stdout: "ignore",
stderr: "ignore",
Fix with Cubic

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.

1 participant