fix: add windowsHide to prevent console window flashing on Windows#401
Conversation
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 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 · |
📝 WalkthroughWalkthroughThis PR applies the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Sequence DiagramThis 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
Generated by CodeAnt AI |
| const rgProcess = spawn(rgPath, args); | ||
| const rgProcess = spawn(rgPath, args, { windowsHide: true }); // Prevent visible console windows on Windows | ||
|
|
||
| if (!rgProcess.pid) { |
There was a problem hiding this comment.
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.| 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.There was a problem hiding this comment.
This was not changed in the PR, can be tackled separately
|
CodeAnt AI finished reviewing your PR. |
|
Thanks, will test in the evening on windows machine! |
|
Hey, I could not reproduce on Windows 11 your issue. |
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: trueto the spawn options in 5 files:src/terminal-manager.tssrc/search-manager.tssrc/tools/improved-process-tools.tsexecute_codesrc/utils/open-browser.tscmd /c startfor Windows URL openingsrc/remote-device/desktop-commander-integration.tswhere/whichbinary checkPlatform Safety
windowsHideis part of the Node.jsSpawnOptionsinterface and maps to theUV_PROCESS_WINDOWS_HIDEflag 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_codewith Python) is a pre-existing failure that requires Python to be installed inPATHand is unrelated to this change.Notes
windowsHide: boolean, defaulting totrue) for users who need console windows visible for debugging purposes.CodeAnt-AI Description
Stop console windows from flashing on Windows
What Changed
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:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
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:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
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