@@ -163,10 +163,16 @@ function isCommandAvailable(command) {
163163 return false ;
164164 }
165165 try {
166- execSync ( 'which ' + command , { stdio : 'ignore' } ) ;
166+ execSync ( 'which' , [ command ] , { stdio : 'ignore' } ) ;
167167 return true ;
168168 } catch {
169- return false ;
169+ // which 명령어 배열 형식이 지원되지 않는 경우 shell 호출
170+ try {
171+ execSync ( `command -v ${ command } ` , { stdio : 'ignore' , shell : true } ) ;
172+ return true ;
173+ } catch {
174+ return false ;
175+ }
170176 }
171177}
172178
@@ -180,8 +186,7 @@ function escapeAppleScript(str) {
180186 . replace ( / \\ / g, '\\\\' )
181187 . replace ( / " / g, '\\"' )
182188 . replace ( / \n / g, '\\n' )
183- . replace ( / \r / g, '\\r' )
184- . replace ( / ` / g, "'" ) ;
189+ . replace ( / \r / g, '\\r' ) ;
185190}
186191
187192/**
@@ -307,13 +312,12 @@ function completeTask(sessionId, result = {}) {
307312 const commit = getLastCommitInfo ( ) ;
308313 const endTime = new Date ( ) ;
309314 const durationMs = endTime - new Date ( state . startTime ) ;
310- const durationSec = Math . round ( durationMs / 1000 ) ;
311315
312316 const title = '✅ Claude 작업 완료' ;
313317 const message = [
314318 `📁 ${ state . repo } /${ state . branch } ` ,
315319 `📝 ${ state . taskType } ` ,
316- `⏱️ ${ durationSec } 초` ,
320+ `⏱️ ${ Math . round ( durationMs / 1000 ) } 초` ,
317321 commit . message !== 'unknown' ? `💬 ${ commit . message } ` : ''
318322 ] . filter ( Boolean ) . join ( '\n' ) ;
319323
@@ -322,17 +326,16 @@ function completeTask(sessionId, result = {}) {
322326 state . status = 'completed' ;
323327 state . endTime = endTime . toISOString ( ) ;
324328 state . durationMs = durationMs ;
325- state . durationSec = durationSec ;
326329 state . result = result ;
327330 state . commit = commit ;
328331 saveSessionState ( sessionId , state ) ;
329332
330- console . log ( `[Claude Task] 작업 완료: ${ state . taskType } (${ durationSec } 초)` ) ;
333+ console . log ( `[Claude Task] 작업 완료: ${ state . taskType } (${ Math . round ( durationMs / 1000 ) } 초)` ) ;
331334
332- // 완료된 세션 정리 (지연 )
333- setTimeout ( ( ) => {
335+ // 완료된 세션 정리 (비동기, 프로세스 종료 차단 안 함 )
336+ setImmediate ( ( ) => {
334337 deleteSessionState ( sessionId ) ;
335- } , 5000 ) ;
338+ } ) ;
336339}
337340
338341/**
@@ -349,7 +352,6 @@ function failTask(sessionId, error) {
349352
350353 const endTime = new Date ( ) ;
351354 const durationMs = endTime - new Date ( state . startTime ) ;
352- const durationSec = Math . round ( durationMs / 1000 ) ;
353355
354356 const title = '❌ Claude 작업 실패' ;
355357 const message = [
@@ -363,16 +365,15 @@ function failTask(sessionId, error) {
363365 state . status = 'failed' ;
364366 state . endTime = endTime . toISOString ( ) ;
365367 state . durationMs = durationMs ;
366- state . durationSec = durationSec ;
367368 state . error = error ;
368369 saveSessionState ( sessionId , state ) ;
369370
370371 console . log ( `[Claude Task] 작업 실패: ${ state . taskType } - ${ error } ` ) ;
371372
372- // 실패한 세션 정리 (지연 )
373- setTimeout ( ( ) => {
373+ // 실패한 세션 정리 (비동기, 프로세스 종료 차단 안 함 )
374+ setImmediate ( ( ) => {
374375 deleteSessionState ( sessionId ) ;
375- } , 5000 ) ;
376+ } ) ;
376377}
377378
378379/**
0 commit comments