Skip to content

fix: add windowsHide to prevent console window flashing on Windows#401

Merged
wonderwhy-er merged 1 commit intowonderwhy-er:mainfrom
phuryn:fix/windows-hide-spawn
Apr 22, 2026
Merged

fix: add windowsHide to prevent console window flashing on Windows#401
wonderwhy-er merged 1 commit intowonderwhy-er:mainfrom
phuryn:fix/windows-hide-spawn

Conversation

@phuryn
Copy link
Copy Markdown
Contributor

@phuryn phuryn commented Mar 27, 2026

User description

Problem

Every child_process.spawn() call in DesktopCommanderMCP creates a visible console window on Windows. This causes disruptive window flashing every time an MCP tool spawns a subprocess — including common operations like running terminal commands, searching with ripgrep, or checking for installed binaries.

Solution

Added windowsHide: true to the spawn options in 5 files:

File Location
src/terminal-manager.ts Two spawn calls for shell/terminal processes
src/search-manager.ts ripgrep process spawn
src/tools/improved-process-tools.ts Node.js subprocess for execute_code
src/utils/open-browser.ts cmd /c start for Windows URL opening
src/remote-device/desktop-commander-integration.ts where/which binary check

Platform Safety

windowsHide is part of the Node.js SpawnOptions interface and maps to the UV_PROCESS_WINDOWS_HIDE flag in libuv. On macOS and Linux this flag is a no-op — it is silently ignored — so this change is fully cross-platform safe.

Tests

32/33 tests pass. The single failing test (execute_code with Python) is a pre-existing failure that requires Python to be installed in PATH and is unrelated to this change.

Notes

  • This could optionally be exposed as a config option (e.g. windowsHide: boolean, defaulting to true) for users who need console windows visible for debugging purposes.
  • It may be worth documenting this behavior change in the tool description or changelog so Windows users are aware that the console flashing they previously experienced is now suppressed.

CodeAnt-AI Description

Stop console windows from flashing on Windows

What Changed

  • Browser opening, file search, terminal commands, code execution, and installed-binary checks now run without popping up a visible console window on Windows
  • These background processes still run the same way on macOS and Linux

Impact

✅ No console flash during Windows tool use
✅ Less disruptive browser and search actions
✅ Cleaner Windows desktop during command runs

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • Bug Fixes
    • Windows: Eliminated console windows from appearing during background operations, including searches, terminal commands, CLI detection, and browser access.

Every child_process.spawn() call was creating a visible console window
on Windows, causing disruptive flashing during MCP tool use. Added
windowsHide: true to spawn options in 5 files:
- src/terminal-manager.ts (2 spawn calls)
- src/search-manager.ts
- src/tools/improved-process-tools.ts
- src/utils/open-browser.ts
- src/remote-device/desktop-commander-integration.ts

windowsHide is silently ignored on macOS/Linux (UV_PROCESS_WINDOWS_HIDE
is a no-op on those platforms), so this is safe cross-platform.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codeant-ai
Copy link
Copy Markdown
Contributor

codeant-ai Bot commented Mar 27, 2026

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 27, 2026

📝 Walkthrough

Walkthrough

This PR applies the { windowsHide: true } option to child process spawn calls across five modules, suppressing console window visibility on Windows during CLI detection, search operations, terminal commands, node code execution, and browser launching.

Changes

Cohort / File(s) Summary
Cross-module windowsHide spawn options
src/remote-device/desktop-commander-integration.ts, src/search-manager.ts, src/terminal-manager.ts, src/tools/improved-process-tools.ts, src/utils/open-browser.ts
Added { windowsHide: true } to child_process.spawn options across CLI detection, ripgrep search, terminal command execution, Node code execution, and browser launching to suppress console window display on Windows.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • PR #271: Directly touches the same spawnOptions and command-spawning behavior in terminal-manager.ts that this PR modifies.
  • PR #240: Also modifies ripgrep invocation in src/search-manager.ts with additional spawn option changes.
  • PR #275: Modifies src/search-manager.ts at the ripgrep spawn site with related process handling changes.

Suggested labels

size:M

Suggested reviewers

  • serg33v
  • wonderwhy-er

Poem

🐰 A whisper of code on Windows so bright,
Console windows hiding, out of sight!
Five files aligned in harmonious dance,
Spawning in silence—no window to glance,
Quiet commands, hidden with care,
Shell processes vanish in morning air! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding windowsHide to spawn options to prevent console window flashing on Windows across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codeant-ai codeant-ai Bot added the size:S This PR changes 10-29 lines, ignoring generated files label Mar 27, 2026
@codeant-ai
Copy link
Copy Markdown
Contributor

codeant-ai Bot commented Mar 27, 2026

Sequence Diagram

This PR updates all key subprocess spawns (terminal commands, search, code execution, and browser opening) to use hidden windows on Windows, preventing disruptive console flashing while preserving existing behavior on other platforms.

sequenceDiagram
    participant User
    participant DesktopCommander
    participant Subprocess

    User->>DesktopCommander: Trigger terminal or search or browser action
    DesktopCommander->>Subprocess: Spawn child process with hidden window on Windows
    Subprocess-->>DesktopCommander: Perform work and return result
    DesktopCommander-->>User: Show command output or search results or opened page status
Loading

Generated by CodeAnt AI

Comment thread src/search-manager.ts
const rgProcess = spawn(rgPath, args);
const rgProcess = spawn(rgPath, args, { windowsHide: true }); // Prevent visible console windows on Windows

if (!rgProcess.pid) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: If the ripgrep process fails to spawn (for example because the resolved binary is missing or not executable), the child process will emit an 'error' event but this code throws immediately based on rgProcess.pid and never attaches an error handler, which can cause an unhandled 'error' event and crash the Node.js process; adding an error listener before throwing prevents this crash while preserving the existing synchronous error behavior. [possible bug]

Severity Level: Critical 🚨
- ❌ start_search MCP tool can crash Node server.
- ❌ searchFiles-based file search can terminate DesktopCommander server.
- ⚠️ Unhandled process crash interrupts all active MCP sessions.
Suggested change
if (!rgProcess.pid) {
// If the process fails to spawn, ensure we handle its 'error' event to avoid crashing the process
if (!rgProcess.pid) {
rgProcess.on('error', () => {
// Underlying spawn error will be represented by the thrown exception below
});
Steps of Reproduction ✅
1. Start the DesktopCommander MCP server (`src/server.ts:1380-1419`) so it can accept tool
requests; this server dispatches the `"start_search"` tool to `handleStartSearch` at
`src/handlers/search-handlers.ts:13-35`.

2. Ensure ripgrep is installed or otherwise resolvable so that `getRipgrepPath()` in
`src/utils/ripgrep-resolver.ts:12-82` returns a path (e.g., via `@vscode/ripgrep` or
`which/where`), but configure the environment so that spawning that path fails at runtime
(for example, by making the resolved `rg` binary non-executable or removing it after
resolution), causing `child_process.spawn(rgPath, args, …)` to fail.

3. From a client, invoke the `"start_search"` MCP command with valid arguments (validated
by `StartSearchArgsSchema` in `src/handlers/search-handlers.ts:13-35`), which calls
`searchManager.startSearch(...)` at `src/search-manager.ts:59-75`; inside `startSearch`,
after building args and resolving `rgPath`, the code runs the snippet at
`src/search-manager.ts:83-87` to spawn ripgrep.

4. When `spawn(rgPath, args, { windowsHide: true })` fails, Node returns a `ChildProcess`
whose `pid` is falsy and schedules an `'error'` event on the next tick; the code sees
`!rgProcess.pid` and immediately throws `new Error('Failed to start ripgrep process')`,
which is caught by `handleStartSearch`'s `try/catch` (lines 22-79 in
`src/handlers/search-handlers.ts`), so the client gets a clean error response—but because
no `'error'` listener was ever attached (we never call `setupProcessHandlers(session)` for
this failed process), the subsequent `'error'` event on the `ChildProcess` instance is
unhandled, causing Node's default behavior of throwing and terminating the entire process,
crashing the DesktopCommander server.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/search-manager.ts
**Line:** 86:86
**Comment:**
	*Possible Bug: If the ripgrep process fails to spawn (for example because the resolved binary is missing or not executable), the child process will emit an 'error' event but this code throws immediately based on `rgProcess.pid` and never attaches an error handler, which can cause an unhandled 'error' event and crash the Node.js process; adding an error listener before throwing prevents this crash while preserving the existing synchronous error behavior.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

Copy link
Copy Markdown
Contributor Author

@phuryn phuryn Mar 27, 2026

Choose a reason for hiding this comment

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

This was not changed in the PR, can be tackled separately

@codeant-ai
Copy link
Copy Markdown
Contributor

codeant-ai Bot commented Mar 27, 2026

CodeAnt AI finished reviewing your PR.

@wonderwhy-er
Copy link
Copy Markdown
Owner

Thanks, will test in the evening on windows machine!

@wonderwhy-er
Copy link
Copy Markdown
Owner

Hey, I could not reproduce on Windows 11 your issue.
But I also did not find any issues with your changes so merging.
Thanks you and hope it helps you.

@wonderwhy-er wonderwhy-er merged commit c9cd34a into wonderwhy-er:main Apr 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants