import { spawn } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { expandHome } from './expand.js'; export function spawnUnit(unit, { logDir } = {}) { const cwd = expandHome(unit.cwd || process.cwd()); const cmd = unit.command?.[0]; if (!cmd) throw new Error(`unit ${unit.id} has no command`); const args = unit.command.slice(1); fs.mkdirSync(cwd, { recursive: true }); let stdout = 'ignore'; let stderr = 'ignore'; if (logDir) { fs.mkdirSync(logDir, { recursive: true }); const log = fs.openSync(path.join(logDir, `${unit.id}.log`), 'a'); stdout = log; stderr = log; } const child = spawn(cmd, args, { cwd, env: { ...process.env, ...(unit.env || {}) }, detached: true, stdio: ['ignore', stdout, stderr], }); child.unref(); return { pid: child.pid, child }; } export function killPid(pid, signal = 'SIGTERM') { if (!pid) return false; try { process.kill(Number(pid), signal); return true; } catch { return false; } } export function pidAlive(pid) { if (!pid) return false; try { process.kill(Number(pid), 0); return true; } catch { return false; } }