mirror of
https://github.com/tiennm99/ccs.git
synced 2026-08-09 16:23:58 +00:00
fix(targets): harden adapter lifecycle and droid model edge cases
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
import { spawn, spawnSync, ChildProcess } from 'child_process';
|
||||
import { ErrorManager } from './error-manager';
|
||||
import { getWebSearchHookEnv } from './websearch-manager';
|
||||
import { forwardSignals } from './signal-forwarder';
|
||||
import { wireChildProcessSignals } from './signal-forwarder';
|
||||
|
||||
/**
|
||||
* Strip ANTHROPIC_* env vars from an environment object.
|
||||
@@ -128,16 +128,7 @@ export function execClaude(
|
||||
});
|
||||
}
|
||||
|
||||
const cleanupSignalHandlers = forwardSignals(child);
|
||||
|
||||
child.on('exit', (code, signal) => {
|
||||
cleanupSignalHandlers();
|
||||
if (signal) process.kill(process.pid, signal as NodeJS.Signals);
|
||||
else process.exit(code || 0);
|
||||
});
|
||||
|
||||
child.on('error', async (err: NodeJS.ErrnoException) => {
|
||||
cleanupSignalHandlers();
|
||||
wireChildProcessSignals(child, async (err: NodeJS.ErrnoException) => {
|
||||
if (err.code === 'EACCES') {
|
||||
console.error(`[X] Claude CLI is not executable: ${claudeCli}`);
|
||||
console.error(' Check file permissions and executable bit.');
|
||||
|
||||
@@ -31,3 +31,47 @@ export function forwardSignals(child: ChildProcess): () => void {
|
||||
process.removeListener('SIGHUP', forwardSighup);
|
||||
};
|
||||
}
|
||||
|
||||
export type ChildProcessErrorHandler = (err: NodeJS.ErrnoException) => void | Promise<void>;
|
||||
export type ChildProcessExitHandler = (code: number | null, signal: NodeJS.Signals | null) => void;
|
||||
|
||||
function defaultExitHandler(code: number | null, signal: NodeJS.Signals | null): void {
|
||||
if (signal) process.kill(process.pid, signal);
|
||||
else process.exit(code || 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach shared signal-forwarding lifecycle handlers to a child process.
|
||||
* Ensures signal listeners are always cleaned up on child exit/error.
|
||||
*/
|
||||
export function wireChildProcessSignals(
|
||||
child: ChildProcess,
|
||||
onError: ChildProcessErrorHandler,
|
||||
onExit: ChildProcessExitHandler = defaultExitHandler
|
||||
): void {
|
||||
const cleanupSignalHandlers = forwardSignals(child);
|
||||
let settled = false;
|
||||
|
||||
const settle = (): boolean => {
|
||||
if (settled) return false;
|
||||
settled = true;
|
||||
cleanupSignalHandlers();
|
||||
return true;
|
||||
};
|
||||
|
||||
child.on('exit', (code, signal) => {
|
||||
if (!settle()) return;
|
||||
onExit(code, signal);
|
||||
});
|
||||
|
||||
child.on('error', async (err: NodeJS.ErrnoException) => {
|
||||
if (!settle()) return;
|
||||
try {
|
||||
await onError(err);
|
||||
} catch (handlerErr) {
|
||||
const message = handlerErr instanceof Error ? handlerErr.message : String(handlerErr);
|
||||
console.error(`[X] Failed to handle child process error: ${message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user