@yemi33/squad 0.1.15 → 0.1.16
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/dashboard.js +48 -0
- package/package.json +1 -1
package/dashboard.js
CHANGED
|
@@ -1394,6 +1394,54 @@ server.listen(PORT, '127.0.0.1', () => {
|
|
|
1394
1394
|
console.log(` Could not auto-open browser: ${e.message}`);
|
|
1395
1395
|
console.log(` Please open http://localhost:${PORT} manually.`);
|
|
1396
1396
|
}
|
|
1397
|
+
|
|
1398
|
+
// ─── Engine Watchdog ─────────────────────────────────────────────────────
|
|
1399
|
+
// Every 30s, check if engine PID is alive. If dead but control.json says
|
|
1400
|
+
// running, auto-restart it. Prevents silent engine death.
|
|
1401
|
+
const { execSync, spawn: cpSpawn } = require('child_process');
|
|
1402
|
+
setInterval(() => {
|
|
1403
|
+
try {
|
|
1404
|
+
const control = getEngineState();
|
|
1405
|
+
if (control.state !== 'running' || !control.pid) return;
|
|
1406
|
+
|
|
1407
|
+
// Check if PID is alive
|
|
1408
|
+
let alive = false;
|
|
1409
|
+
try {
|
|
1410
|
+
if (process.platform === 'win32') {
|
|
1411
|
+
const out = execSync(`tasklist /FI "PID eq ${control.pid}" /NH`, { encoding: 'utf8', timeout: 3000 });
|
|
1412
|
+
alive = out.includes(String(control.pid));
|
|
1413
|
+
} else {
|
|
1414
|
+
process.kill(control.pid, 0); // signal 0 = check existence
|
|
1415
|
+
alive = true;
|
|
1416
|
+
}
|
|
1417
|
+
} catch { alive = false; }
|
|
1418
|
+
|
|
1419
|
+
if (!alive) {
|
|
1420
|
+
console.log(`[watchdog] Engine PID ${control.pid} is dead — auto-restarting...`);
|
|
1421
|
+
|
|
1422
|
+
// Set state to stopped first
|
|
1423
|
+
const controlPath = path.join(SQUAD_DIR, 'engine', 'control.json');
|
|
1424
|
+
safeWrite(controlPath, { state: 'stopped', pid: null, crashed_at: new Date().toISOString() });
|
|
1425
|
+
|
|
1426
|
+
// Restart engine
|
|
1427
|
+
const childEnv = { ...process.env };
|
|
1428
|
+
for (const key of Object.keys(childEnv)) {
|
|
1429
|
+
if (key === 'CLAUDECODE' || key.startsWith('CLAUDE_CODE') || key.startsWith('CLAUDECODE_')) delete childEnv[key];
|
|
1430
|
+
}
|
|
1431
|
+
const engineProc = cpSpawn(process.execPath, [path.join(SQUAD_DIR, 'engine.js'), 'start'], {
|
|
1432
|
+
cwd: SQUAD_DIR,
|
|
1433
|
+
stdio: 'ignore',
|
|
1434
|
+
detached: true,
|
|
1435
|
+
env: childEnv,
|
|
1436
|
+
});
|
|
1437
|
+
engineProc.unref();
|
|
1438
|
+
console.log(`[watchdog] Engine restarted (new PID: ${engineProc.pid})`);
|
|
1439
|
+
}
|
|
1440
|
+
} catch (e) {
|
|
1441
|
+
console.error(`[watchdog] Error: ${e.message}`);
|
|
1442
|
+
}
|
|
1443
|
+
}, 30000);
|
|
1444
|
+
console.log(` Engine watchdog: active (checks every 30s)`);
|
|
1397
1445
|
});
|
|
1398
1446
|
|
|
1399
1447
|
server.on('error', e => {
|
package/package.json
CHANGED