fix: address PR review feedback for subprocess cleanup and binary resolution

Wrap SDK query loop in try/finally so subprocess cleanup runs on error paths.
Swap Chroma binary check order to try project-level .bin first (common case).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-02-15 23:24:00 -05:00
parent 67ba17cc8a
commit 055888e181
3 changed files with 183 additions and 179 deletions
File diff suppressed because one or more lines are too long
+6 -5
View File
@@ -115,14 +115,15 @@ export class ChromaServerManager {
try {
// chromadb package installs a 'chroma' bin entry
const chromaBinDir = path.dirname(require.resolve('chromadb/package.json'));
const chromaBin = path.join(chromaBinDir, 'node_modules', '.bin', isWindows ? 'chroma.cmd' : 'chroma');
// Fallback: check project-level .bin
// Check project-level .bin first (most common npm/bun installation layout)
const projectBin = path.join(chromaBinDir, '..', '.bin', isWindows ? 'chroma.cmd' : 'chroma');
// Fallback: nested node_modules .bin (rare — pnpm or workspace hoisting)
const nestedBin = path.join(chromaBinDir, 'node_modules', '.bin', isWindows ? 'chroma.cmd' : 'chroma');
if (existsSync(chromaBin)) {
command = chromaBin;
} else if (existsSync(projectBin)) {
if (existsSync(projectBin)) {
command = projectBin;
} else if (existsSync(nestedBin)) {
command = nestedBin;
} else {
// Last resort: npx with explicit cwd
command = isWindows ? 'npx.cmd' : 'npx';
+6 -3
View File
@@ -141,7 +141,9 @@ export class SDKAgent {
}
});
// Process SDK messages
// Process SDK messages — cleanup in finally ensures subprocess termination
// even if the loop throws (e.g., context overflow, invalid API key)
try {
for await (const message of queryResult) {
// Capture or update memory session ID from SDK message
// IMPORTANT: The SDK may return a DIFFERENT session_id on resume than what we sent!
@@ -271,12 +273,13 @@ export class SDKAgent {
// Usage telemetry is captured at SDK level
}
}
// Ensure subprocess is terminated after query completes
} finally {
// Ensure subprocess is terminated after query completes (or on error)
const tracked = getProcessBySession(session.sessionDbId);
if (tracked && !tracked.process.killed && tracked.process.exitCode === null) {
await ensureProcessExit(tracked, 5000);
}
}
// Mark session complete
const sessionDuration = Date.now() - session.startTime;