Skip to content

Commit c9cd34a

Browse files
phurynclaude
andauthored
fix: add windowsHide to prevent console window flashing on Windows (#401)
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>
1 parent 628991a commit c9cd34a

5 files changed

Lines changed: 10 additions & 7 deletions

File tree

src/remote-device/desktop-commander-integration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export class DesktopCommanderIntegration {
9494
// We can't run it directly as it's an stdio MCP server that waits for input
9595
const whichCommand = process.platform === 'win32' ? 'where' : 'which';
9696
console.debug('[DEBUG] Using platform command:', whichCommand, 'on platform:', process.platform);
97-
const check = spawn(whichCommand, [commandName]);
97+
const check = spawn(whichCommand, [commandName], { windowsHide: true }); // Prevent visible console windows on Windows
9898
check.on('error', (err) => {
9999
console.debug('[DEBUG] Spawn error for', whichCommand, ':', err.message);
100100
reject(err);

src/search-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export interface SearchSessionOptions {
8181
}
8282

8383
// Start ripgrep process
84-
const rgProcess = spawn(rgPath, args);
84+
const rgProcess = spawn(rgPath, args, { windowsHide: true }); // Prevent visible console windows on Windows
8585

8686
if (!rgProcess.pid) {
8787
throw new Error('Failed to start ripgrep process');

src/terminal-manager.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,10 @@ export class TerminalManager {
160160
env: {
161161
...process.env,
162162
TERM: 'xterm-256color' // Better terminal compatibility
163-
}
163+
},
164+
windowsHide: true // Prevent visible console windows on Windows
164165
};
165-
166+
166167
// Add shell option if needed (for unknown shells)
167168
if (spawnConfig.useShellOption) {
168169
spawnOptions.shell = spawnConfig.useShellOption;
@@ -179,7 +180,8 @@ export class TerminalManager {
179180
env: {
180181
...process.env,
181182
TERM: 'xterm-256color'
182-
}
183+
},
184+
windowsHide: true // Prevent visible console windows on Windows
183185
};
184186
}
185187

src/tools/improved-process-tools.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ async function executeNodeCode(code: string, timeout_ms: number = 30000): Promis
3333
const result = await new Promise<{ stdout: string; stderr: string; exitCode: number }>((resolve) => {
3434
const proc = spawn(process.execPath, [tempFile], {
3535
cwd: mcpRoot,
36-
timeout: timeout_ms
36+
timeout: timeout_ms,
37+
windowsHide: true // Prevent visible console windows on Windows
3738
});
3839

3940
let stdout = '';

src/utils/open-browser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export async function openBrowser(url: string): Promise<void> {
2626
break;
2727
case 'win32':
2828
// Windows 'start' is a shell builtin, use spawn with shell but pass URL as separate arg
29-
spawn('cmd', ['/c', 'start', '', url], { shell: false }).on('close', (code) => {
29+
spawn('cmd', ['/c', 'start', '', url], { shell: false, windowsHide: true }).on('close', (code) => {
3030
code === 0 ? resolve() : reject(new Error(`Exit code ${code}`));
3131
});
3232
break;

0 commit comments

Comments
 (0)