@@ -208,36 +208,53 @@ function ensureClaudeOnboarding(): void {
208208 } catch ( err ) { logger . warn ( `Failed to write ~/.claude.json: ${ String ( err ) } ` ) ; }
209209}
210210
211+ const IS_WIN = process . platform === "win32" ;
212+ const PATH_SEP = IS_WIN ? ";" : ":" ;
213+
211214function ensureEnv ( ) : void {
212215 if ( ! process . env . HOME ) process . env . HOME = os . homedir ( ) ;
216+ if ( IS_WIN ) return ;
213217 try {
214218 const shellPath = execSync ( "bash -lc 'echo $PATH' 2>/dev/null" , { timeout : 3000 } ) . toString ( ) . trim ( ) ;
215219 if ( shellPath ) process . env . PATH = shellPath ;
216220 } catch { }
217221}
218222
219223function ensureClaudeInPath ( ) : void {
220- const commonPaths = [
221- "/usr/local/bin" , "/usr/bin" ,
222- `${ os . homedir ( ) } /.npm-global/bin` , `${ os . homedir ( ) } /.local/bin` ,
223- "/opt/homebrew/bin" , "/home/linuxbrew/.linuxbrew/bin" ,
224- ] ;
224+ const commonPaths = IS_WIN
225+ ? [
226+ path . join ( process . env . APPDATA ?? "" , "npm" ) ,
227+ path . join ( process . env . LOCALAPPDATA ?? "" , "Programs" , "claude" ) ,
228+ ]
229+ : [
230+ "/usr/local/bin" , "/usr/bin" ,
231+ `${ os . homedir ( ) } /.npm-global/bin` , `${ os . homedir ( ) } /.local/bin` ,
232+ "/opt/homebrew/bin" , "/home/linuxbrew/.linuxbrew/bin" ,
233+ ] ;
234+
235+ const findCmd = IS_WIN ? "where claude 2>nul" : "which claude 2>/dev/null || command -v claude 2>/dev/null" ;
236+ const shellOpt = IS_WIN ? { } : { shell : "/bin/bash" } ;
237+
225238 try {
226- const claudePath = execSync ( "which claude 2>/dev/null || command -v claude 2>/dev/null" , {
227- shell : "/bin/bash" ,
228- env : { ...process . env , PATH : [ ...commonPaths , process . env . PATH ?? "" ] . join ( ":" ) } ,
229- } ) . toString ( ) . trim ( ) ;
239+ const claudePath = execSync ( findCmd , {
240+ ...shellOpt ,
241+ encoding : "utf8" ,
242+ timeout : 5000 ,
243+ env : { ...process . env , PATH : [ ...commonPaths , process . env . PATH ?? "" ] . join ( PATH_SEP ) } ,
244+ } ) . trim ( ) ;
230245 if ( claudePath ) {
231- const dir = path . dirname ( claudePath ) ;
232- if ( ! process . env . PATH ?. includes ( dir ) ) process . env . PATH = `${ dir } :${ process . env . PATH } ` ;
233- logger . dim ( `claude found: ${ claudePath } ` ) ;
246+ const resolved = claudePath . split ( / [ \r \n ] / ) [ 0 ] ;
247+ const dir = path . dirname ( resolved ) ;
248+ if ( ! process . env . PATH ?. includes ( dir ) ) process . env . PATH = `${ dir } ${ PATH_SEP } ${ process . env . PATH } ` ;
249+ logger . dim ( `claude found: ${ resolved } ` ) ;
234250 return ;
235251 }
236252 } catch { }
237253 for ( const dir of commonPaths ) {
238- if ( fs . existsSync ( path . join ( dir , "claude" ) ) ) {
239- if ( ! process . env . PATH ?. includes ( dir ) ) process . env . PATH = `${ dir } :${ process . env . PATH } ` ;
240- logger . dim ( `claude found: ${ dir } /claude` ) ;
254+ const binName = IS_WIN ? "claude.cmd" : "claude" ;
255+ if ( fs . existsSync ( path . join ( dir , binName ) ) || fs . existsSync ( path . join ( dir , "claude" ) ) ) {
256+ if ( ! process . env . PATH ?. includes ( dir ) ) process . env . PATH = `${ dir } ${ PATH_SEP } ${ process . env . PATH } ` ;
257+ logger . dim ( `claude found: ${ dir } ` ) ;
241258 return ;
242259 }
243260 }
0 commit comments