Skip to content

✨ fix(stdio): hide console window on windows - #91

Merged
zoedsoupe merged 4 commits into
zoedsoupe:mainfrom
matteing:users/sergiomattei/FixHideWindows
Feb 26, 2026
Merged

zoedsoupe merged 4 commits into
zoedsoupe:mainfrom
matteing:users/sergiomattei/FixHideWindows

Conversation

@matteing

@matteing matteing commented Feb 24, 2026 •

Copy link
Copy Markdown
Contributor

Hi! Thank you for creating this project, it's been a lifesaver for implementing MCP on my personal coding agent, Opal.

A little quirk on Windows: when running stdio MCP tools, open_port with spawn_executable opens a visible console window for each spawned process on Windows, which is a bit awkward.

This PR adds the optional hide flag which suppresses this problem.

Thank you and cheers!

Summary by CodeRabbit

  • Bug Fixes
    • On Windows, spawned background processes no longer reveal a console window, producing a quieter, cleaner experience when launching external tools. Existing non-Windows behavior is unchanged.

Erlang open_port with spawn_executable opens a visible console window
for each spawned process on Windows. Pass hide: true in port options
on win32 to suppress these background windows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Feb 24, 2026 •

Copy link
Copy Markdown

Walkthrough

Adds Windows-specific process hiding to the stdio transport by prepending {:hide, true} to the Erlang port spawn options when running on Windows NT. The change ensures the options list includes :hide for Windows while preserving existing options for other platforms. No exported signatures or error handling were changed.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Review Notes

P0 – Correctness: Verify {:hide, true} is supported for the targeted OTP versions on Windows (per Erlang docs this is the expected option). ✅

P1 – Safety: The implementation prepends the tuple, preserving other options; confirm order has no side effects for any existing options.

P2 – Tests / CI: Consider a small platform-conditioned test or CI matrix note to ensure behavior on Windows remains covered.

P3 – Commit message: Add a brief rationale (e.g., suppress console on Windows) for future readers.

Nice and tidy change — looks idiomatic Elixir and OTP-friendly. 😎

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding Windows-specific console window hiding to stdio transport, which aligns with the code modifications.
Description check ✅ Passed The description explains the problem (visible console windows on Windows) and solution (hide flag), but lacks a formal Rationale section as specified in the template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Erlang open_port with spawn_executable opens a visible console window
for each spawned process on Windows. Pass hide: true in port options
on win32 to suppress these background windows.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/anubis/transport/stdio.ex`:
- Line 279: The Windows hide option is being passed as the tuple {:hide, true}
which is invalid for open_port; update the pipeline call (the expression using
then/&if in lib/anubis/transport/stdio.ex) to insert the bare atom :hide when
:os.type() == {:win32, :nt} so the options list contains :hide (not {:hide,
true}), ensuring open_port/2 receives the correct option; adjust any surrounding
variable names or the open_port invocation if needed to use the corrected
options list.

ℹ️ Review info

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2074ed6 and 3174208.

📒 Files selected for processing (1)
  • lib/anubis/transport/stdio.ex

Comment thread lib/anubis/transport/stdio.ex

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
lib/anubis/transport/stdio.ex (1)

274-281: ⚠️ Potential issue | 🔴 Critical

P0: Remove invalid {:hide, true} — bare :hide atom is the only valid format.
Erlang's open_port/2 accepts :hide as a bare atom only; the tuple form {:hide, true} is undocumented and will trigger :badarg on Windows. Since you already have :hide in the initial list and it's ignored on non-Windows systems anyway, drop the Windows-specific conditional entirely.

✅ Proposed fix
    opts =
      [:hide, :binary]
      |> then(&if is_nil(state.args), do: &1, else: Enum.concat(&1, args: state.args))
      |> then(&if is_nil(state.env), do: &1, else: Enum.concat(&1, env: env))
      |> then(&if is_nil(state.cwd), do: &1, else: Enum.concat(&1, cd: state.cwd))
-      |> then(&if :os.type() == {:win32, :nt}, do: [{:hide, true} | &1], else: &1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/anubis/transport/stdio.ex` around lines 274 - 281, The opts building adds
an undocumented {:hide, true} tuple for Windows which is invalid for Erlang's
open_port/2; remove the final then branch that checks :os.type() and prepends
{:hide, true} so opts only contains the bare :hide atom and any args/env/cd
built from state (refer to the opts variable and the state.args, state.env,
state.cwd transformations), ensuring open_port/2 is only given :hide as the
atom.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@lib/anubis/transport/stdio.ex`:
- Around line 274-281: The opts building adds an undocumented {:hide, true}
tuple for Windows which is invalid for Erlang's open_port/2; remove the final
then branch that checks :os.type() and prepends {:hide, true} so opts only
contains the bare :hide atom and any args/env/cd built from state (refer to the
opts variable and the state.args, state.env, state.cwd transformations),
ensuring open_port/2 is only given :hide as the atom.

ℹ️ Review info

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3174208 and d55c3d1.

📒 Files selected for processing (1)
  • lib/anubis/transport/stdio.ex

@zoedsoupe

Copy link
Copy Markdown
Owner

oh, thanks

@zoedsoupe
zoedsoupe merged commit 5a61c65 into zoedsoupe:main Feb 26, 2026
10 checks passed
This was referenced Jul 16, 2026
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.

2 participants