diff --git a/ccw/src/commands/cli.ts b/ccw/src/commands/cli.ts index 1de7e568..01769b5f 100644 --- a/ccw/src/commands/cli.ts +++ b/ccw/src/commands/cli.ts @@ -43,6 +43,7 @@ function notifyDashboard(data: Record): void { port: Number(DASHBOARD_PORT), path: '/api/hook', method: 'POST', + timeout: 2000, // 2 second timeout to prevent hanging headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) @@ -53,6 +54,10 @@ function notifyDashboard(data: Record): void { req.on('error', (err) => { if (process.env.DEBUG) console.error('[Dashboard] CLI notification failed:', err.message); }); + req.on('timeout', () => { + req.destroy(); + if (process.env.DEBUG) console.error('[Dashboard] CLI notification timed out'); + }); req.write(payload); req.end(); } diff --git a/ccw/src/tools/cli-executor.ts b/ccw/src/tools/cli-executor.ts index ef052a90..7b986c92 100644 --- a/ccw/src/tools/cli-executor.ts +++ b/ccw/src/tools/cli-executor.ts @@ -796,7 +796,7 @@ async function executeCliTool( }); // Handle completion - child.on('close', (code) => { + child.on('close', async (code) => { const endTime = Date.now(); const duration = endTime - startTime; @@ -942,29 +942,28 @@ async function executeCliTool( } } - // Track native session after execution (async, non-blocking) + // Track native session after execution (awaited to prevent process hang) // Pass prompt for precise matching in parallel execution scenarios - trackNewSession(tool, new Date(startTime), workingDir, prompt) - .then((nativeSession) => { - if (nativeSession) { - // Save native session mapping - try { - store.saveNativeSessionMapping({ - ccw_id: conversationId, - tool, - native_session_id: nativeSession.sessionId, - native_session_path: nativeSession.filePath, - project_hash: nativeSession.projectHash, - created_at: new Date().toISOString() - }); - } catch (err) { - console.error('[CLI Executor] Failed to save native session mapping:', (err as Error).message); - } + try { + const nativeSession = await trackNewSession(tool, new Date(startTime), workingDir, prompt); + if (nativeSession) { + // Save native session mapping + try { + store.saveNativeSessionMapping({ + ccw_id: conversationId, + tool, + native_session_id: nativeSession.sessionId, + native_session_path: nativeSession.filePath, + project_hash: nativeSession.projectHash, + created_at: new Date().toISOString() + }); + } catch (err) { + console.error('[CLI Executor] Failed to save native session mapping:', (err as Error).message); } - }) - .catch((err) => { - console.error('[CLI Executor] Failed to track native session:', (err as Error).message); - }); + } + } catch (err) { + console.error('[CLI Executor] Failed to track native session:', (err as Error).message); + } // Create legacy execution record for backward compatibility const execution: ExecutionRecord = {