@@ -183,40 +183,58 @@ async function startBackend(): Promise<void> {
183183 // Production: tell the backend where packaged resources live
184184 process . env . ELISA_RESOURCES_PATH = process . resourcesPath ;
185185
186- // MinGit: set up bundled Git + bash for Windows so Claude Code CLI works
187- // without a system Git installation.
186+ // Set up bundled tool fallbacks on Windows.
187+ // Prefer system installations when available; fall back to bundled tools
188+ // only when the system doesn't have them. This avoids breaking npm/npx
189+ // on developer machines that already have Node.js installed.
188190 if ( process . platform === 'win32' ) {
189191 const fs = require ( 'fs' ) as typeof import ( 'fs' ) ;
190192 const os = require ( 'os' ) as typeof import ( 'os' ) ;
191- const mingitDir = path . join ( process . resourcesPath , 'mingit' ) ;
192- const bashExe = path . join ( mingitDir , 'usr' , 'bin' , 'bash.exe' ) ;
193- if ( fs . existsSync ( bashExe ) ) {
194- process . env . CLAUDE_CODE_GIT_BASH_PATH = bashExe ;
195- const gitCmd = path . join ( mingitDir , 'cmd' ) ;
196- const gitUsrBin = path . join ( mingitDir , 'usr' , 'bin' ) ;
197- process . env . PATH = `${ gitCmd } ;${ gitUsrBin } ;${ process . env . PATH } ` ;
193+ const { execSync } = require ( 'child_process' ) as typeof import ( 'child_process' ) ;
194+
195+ const hasCommand = ( cmd : string ) : boolean => {
196+ try { execSync ( `where ${ cmd } ` , { stdio : 'ignore' } ) ; return true ; } catch { return false ; }
197+ } ;
198+
199+ // Git + bash: use system Git if available, otherwise bundled MinGit
200+ if ( ! hasCommand ( 'git' ) ) {
201+ const mingitDir = path . join ( process . resourcesPath , 'mingit' ) ;
202+ const bashExe = path . join ( mingitDir , 'usr' , 'bin' , 'bash.exe' ) ;
203+ if ( fs . existsSync ( bashExe ) ) {
204+ const gitCmd = path . join ( mingitDir , 'cmd' ) ;
205+ const gitUsrBin = path . join ( mingitDir , 'usr' , 'bin' ) ;
206+ process . env . PATH = `${ process . env . PATH } ;${ gitCmd } ;${ gitUsrBin } ` ;
207+ console . log ( '[main] Using bundled MinGit (no system git found)' ) ;
208+ }
198209 }
199210
200- // Create a node.exe shim so agents and test runners can execute JS.
201- // Hardlink Elisa.exe -> node.exe (zero disk cost on NTFS).
202- // ELECTRON_RUN_AS_NODE=1 makes it behave as plain Node.js.
203- const nodeShimDir = path . join ( os . tmpdir ( ) , 'elisa-node' ) ;
204- const shimNodeExe = path . join ( nodeShimDir , 'node.exe' ) ;
205- try {
206- fs . mkdirSync ( nodeShimDir , { recursive : true } ) ;
207- try { fs . unlinkSync ( shimNodeExe ) ; } catch { /* may not exist */ }
208- try {
209- fs . linkSync ( process . execPath , shimNodeExe ) ;
210- } catch {
211- fs . copyFileSync ( process . execPath , shimNodeExe ) ;
211+ // Claude Code needs bash.exe. Set CLAUDE_CODE_GIT_BASH_PATH if not
212+ // already resolvable (system Git puts it in PATH automatically).
213+ if ( ! hasCommand ( 'bash' ) ) {
214+ const mingitBash = path . join ( process . resourcesPath , 'mingit' , 'usr' , 'bin' , 'bash.exe' ) ;
215+ if ( fs . existsSync ( mingitBash ) ) {
216+ process . env . CLAUDE_CODE_GIT_BASH_PATH = mingitBash ;
212217 }
213- process . env . PATH = `${ nodeShimDir } ;${ process . env . PATH } ` ;
214- } catch ( err ) {
215- console . error ( 'Failed to create node.exe shim:' , err ) ;
216218 }
217219
218- // Let all child processes use the Electron binary as Node.js.
219- process . env . ELECTRON_RUN_AS_NODE = '1' ;
220+ // Node.js: use system node if available, otherwise create Electron shim.
221+ if ( ! hasCommand ( 'node' ) ) {
222+ const nodeShimDir = path . join ( os . tmpdir ( ) , 'elisa-node' ) ;
223+ const shimNodeExe = path . join ( nodeShimDir , 'node.exe' ) ;
224+ try {
225+ fs . mkdirSync ( nodeShimDir , { recursive : true } ) ;
226+ try { fs . unlinkSync ( shimNodeExe ) ; } catch { /* may not exist */ }
227+ try { fs . linkSync ( process . execPath , shimNodeExe ) ; }
228+ catch { fs . copyFileSync ( process . execPath , shimNodeExe ) ; }
229+ process . env . PATH = `${ process . env . PATH } ;${ nodeShimDir } ` ;
230+ // ELECTRON_RUN_AS_NODE makes the Electron binary act as Node.js.
231+ // Only set when using the shim; system node doesn't need it.
232+ process . env . ELECTRON_RUN_AS_NODE = '1' ;
233+ console . log ( '[main] Using Electron node.exe shim (no system node found)' ) ;
234+ } catch ( err ) {
235+ console . error ( '[main] Failed to create node.exe shim:' , err ) ;
236+ }
237+ }
220238 }
221239
222240 const backendDist = path . join ( process . resourcesPath , 'backend-dist' ) ;
0 commit comments