@openlife/cli 1.7.12 → 1.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/orchestrator/Brain.js +40 -1
- package/package.json +1 -1
|
@@ -288,7 +288,46 @@ class Brain {
|
|
|
288
288
|
const commandArgs = process.platform === 'win32'
|
|
289
289
|
? args
|
|
290
290
|
: ['-k', '2s', `${timeoutSeconds}s`, 'codex', ...args];
|
|
291
|
-
|
|
291
|
+
// Codex CLI reads stdin when invoked without a TTY. The promisified
|
|
292
|
+
// execFile doesn't expose stdio, so it keeps the child's stdin
|
|
293
|
+
// attached to our (open) pipe — codex then waits forever for input
|
|
294
|
+
// and our outer timeout fires. Use spawn with `stdio: ['ignore', ...]`
|
|
295
|
+
// to close stdin explicitly. Fixes ~30s phantom timeouts when the
|
|
296
|
+
// daemon (non-TTY) calls codex.
|
|
297
|
+
const stdout = await new Promise((resolve, reject) => {
|
|
298
|
+
const child = child_process.spawn(command, commandArgs, {
|
|
299
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
300
|
+
});
|
|
301
|
+
let stdoutBuf = '';
|
|
302
|
+
let stderrBuf = '';
|
|
303
|
+
let killed = false;
|
|
304
|
+
const watchdog = setTimeout(() => {
|
|
305
|
+
killed = true;
|
|
306
|
+
try {
|
|
307
|
+
child.kill('SIGKILL');
|
|
308
|
+
}
|
|
309
|
+
catch { /* ignore */ }
|
|
310
|
+
}, timeoutMs + 3000);
|
|
311
|
+
child.stdout.on('data', (d) => { stdoutBuf += String(d); });
|
|
312
|
+
child.stderr.on('data', (d) => { stderrBuf += String(d); });
|
|
313
|
+
child.on('error', (err) => { clearTimeout(watchdog); reject(err); });
|
|
314
|
+
child.on('close', (code, signal) => {
|
|
315
|
+
clearTimeout(watchdog);
|
|
316
|
+
if (killed || code === 124 || (signal && killed)) {
|
|
317
|
+
const e = new Error('ETIMEDOUT');
|
|
318
|
+
e.code = 'ETIMEDOUT';
|
|
319
|
+
reject(e);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
if (code !== 0) {
|
|
323
|
+
const e = new Error(`codex exited with code ${code}: ${stderrBuf.slice(-300)}`);
|
|
324
|
+
e.code = String(code);
|
|
325
|
+
reject(e);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
resolve(stdoutBuf);
|
|
329
|
+
});
|
|
330
|
+
});
|
|
292
331
|
const lastMessage = fs.existsSync(outputFile) ? fs.readFileSync(outputFile, 'utf-8').trim() : '';
|
|
293
332
|
try {
|
|
294
333
|
fs.unlinkSync(outputFile);
|