From c30e7bb2f79ef2015f2ba18d47fa574e5447ae67 Mon Sep 17 00:00:00 2001 From: Tushar Magar Date: Thu, 5 Mar 2026 17:49:32 +0530 Subject: [PATCH] fix: Use Git Bash on Windows instead of hardcoded /bin/sh for command execution --- .../src/application/lib/command-executor.ts | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/apps/x/packages/core/src/application/lib/command-executor.ts b/apps/x/packages/core/src/application/lib/command-executor.ts index 870f6a0c..427e0c3c 100644 --- a/apps/x/packages/core/src/application/lib/command-executor.ts +++ b/apps/x/packages/core/src/application/lib/command-executor.ts @@ -1,8 +1,22 @@ import { exec, execSync, spawn, ChildProcess } from 'child_process'; +import { existsSync } from 'fs'; import { promisify } from 'util'; import { getSecurityAllowList } from '../../config/security.js'; const execPromise = promisify(exec); + +function getShell(): string { + if (process.platform !== 'win32') return '/bin/sh'; + // On Windows, try Git Bash first, then fall back to cmd.exe + const gitBashPaths = [ + 'C:\\Program Files\\Git\\bin\\bash.exe', + 'C:\\Program Files (x86)\\Git\\bin\\bash.exe', + ]; + for (const p of gitBashPaths) { + if (existsSync(p)) return p; + } + return 'cmd.exe'; +} const COMMAND_SPLIT_REGEX = /(?:\|\||&&|;|\||\n|`|\$\(|\(|\))/; const ENV_ASSIGNMENT_REGEX = /^[A-Za-z_][A-Za-z0-9_]*=.*/; const WRAPPER_COMMANDS = new Set(['sudo', 'env', 'time', 'command']); @@ -85,7 +99,7 @@ export async function executeCommand( cwd: options?.cwd, timeout: options?.timeout, maxBuffer: options?.maxBuffer || 1024 * 1024, // default 1MB - shell: '/bin/sh', // use sh for cross-platform compatibility + shell: getShell(), // use sh for cross-platform compatibility }); return { @@ -159,7 +173,7 @@ export function executeCommandAbortable( } const proc = spawn(command, [], { - shell: '/bin/sh', + shell: getShell(), cwd: options?.cwd, detached: process.platform !== 'win32', // Create process group on Unix stdio: ['ignore', 'pipe', 'pipe'], @@ -273,7 +287,7 @@ export function executeCommandSync( cwd: options?.cwd, timeout: options?.timeout, encoding: 'utf-8', - shell: '/bin/sh', + shell: getShell(), }); return {