@@ -20,12 +20,25 @@ const GIT_BASH_COMMON_PATHS = [
2020 'C:\\Git\\bin\\bash.exe' ,
2121]
2222
23+ // WSL bash paths that are often unreliable (VM may not be running, quote escaping issues)
24+ // These are checked last as a fallback only
25+ const WSL_BASH_PATH_PATTERNS = [
26+ 'system32' ,
27+ 'windowsapps' ,
28+ ]
29+
2330/**
2431 * Find bash executable on Windows.
2532 * Priority:
26- * 1. CODEBUFF_GIT_BASH_PATH environment variable
27- * 2. bash.exe in PATH (e.g., inside WSL or Git Bash terminal)
28- * 3. Common Git Bash installation locations
33+ * 1. CODEBUFF_GIT_BASH_PATH environment variable (user override)
34+ * 2. Common Git Bash installation locations (most reliable)
35+ * 3. Non-WSL bash in PATH (e.g., Git Bash added to PATH)
36+ * 4. WSL bash in PATH (last resort - System32, WindowsApps)
37+ *
38+ * WSL bash is deprioritized because it can fail with cryptic errors when:
39+ * - The WSL VM is not running
40+ * - Quote/argument escaping issues between Windows and Linux
41+ * - UTF-16 encoding mismatches
2942 */
3043function findWindowsBash ( env : NodeJS . ProcessEnv ) : string | null {
3144 // Check for user-specified path via environment variable
@@ -34,27 +47,48 @@ function findWindowsBash(env: NodeJS.ProcessEnv): string | null {
3447 return customPath
3548 }
3649
37- // Check if bash.exe is in PATH (works inside WSL or Git Bash)
50+ // Check common Git Bash installation locations first (most reliable)
51+ for ( const commonPath of GIT_BASH_COMMON_PATHS ) {
52+ if ( fs . existsSync ( commonPath ) ) {
53+ return commonPath
54+ }
55+ }
56+
57+ // Fall back to bash.exe in PATH, but skip WSL paths initially
3858 const pathEnv = env . PATH || env . Path || ''
3959 const pathDirs = pathEnv . split ( path . delimiter )
60+ const wslFallbackPaths : string [ ] = [ ]
4061
4162 for ( const dir of pathDirs ) {
63+ const dirLower = dir . toLowerCase ( )
64+ const isWslPath = WSL_BASH_PATH_PATTERNS . some ( pattern => dirLower . includes ( pattern ) )
65+
4266 const bashPath = path . join ( dir , 'bash.exe' )
4367 if ( fs . existsSync ( bashPath ) ) {
44- return bashPath
68+ if ( isWslPath ) {
69+ // Save WSL paths for last resort
70+ wslFallbackPaths . push ( bashPath )
71+ } else {
72+ // Non-WSL bash in PATH (e.g., Git Bash added to PATH)
73+ return bashPath
74+ }
4575 }
46- // Also check for just 'bash' (for WSL)
76+
77+ // Also check for just 'bash' (without .exe)
4778 const bashPathNoExt = path . join ( dir , 'bash' )
4879 if ( fs . existsSync ( bashPathNoExt ) ) {
49- return bashPathNoExt
80+ if ( isWslPath ) {
81+ wslFallbackPaths . push ( bashPathNoExt )
82+ } else {
83+ return bashPathNoExt
84+ }
5085 }
5186 }
5287
53- // Check common Git Bash installation locations
54- for ( const commonPath of GIT_BASH_COMMON_PATHS ) {
55- if ( fs . existsSync ( commonPath ) ) {
56- return commonPath
57- }
88+ // Last resort: use WSL bash if nothing else is available
89+ // WSL can be unreliable (VM not running, quote escaping issues, UTF-16 encoding)
90+ if ( wslFallbackPaths . length > 0 ) {
91+ return wslFallbackPaths [ 0 ]
5892 }
5993
6094 return null
0 commit comments