UNPKG

naisys

Version:

NAISYS - Autonomous AI agent runner with built-in context management and cost tracking

79 lines 3.02 kB
import { spawn } from "child_process"; /** 75 = EX_TEMPFAIL, reused here as an internal "restart requested" exit code. */ export const RESTART_EXIT_CODE = 75; export const RESTART_WRAPPER_ACTIVE_ENV = "NAISYS_RESTART_WRAPPER_ACTIVE"; export const RESTART_WRAPPER_CHILD_ENV = "NAISYS_RESTART_WRAPPER_CHILD"; export const DISABLE_RESTART_WRAPPER_ENV = "NAISYS_DISABLE_RESTART_WRAPPER"; /** Flags that should only apply to the first invocation and be dropped on auto-update restarts. */ const ONE_SHOT_FLAGS = ["--setup"]; export function stripOneShotFlags(args) { return args.filter((arg) => !ONE_SHOT_FLAGS.some((flag) => arg === flag || arg.startsWith(`${flag}=`))); } const POSIX_FORWARD_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"]; const WINDOWS_FORWARD_SIGNALS = ["SIGINT", "SIGTERM"]; const SIGNAL_EXIT_CODES = { SIGHUP: 129, SIGINT: 130, SIGTERM: 143, }; export function isRestartWrapperActive(env = process.env) { return env[RESTART_WRAPPER_ACTIVE_ENV] === "1"; } export function shouldUseRestartWrapper(argv = process.argv, env = process.env) { const usesHub = argv.some((arg) => arg === "--hub" || arg.startsWith("--hub=")) || argv.includes("--integrated-hub"); const autoUpdateDisabled = argv.includes("--no-auto-update"); return (usesHub && !autoUpdateDisabled && !env.pm_id && env[RESTART_WRAPPER_CHILD_ENV] !== "1" && env[DISABLE_RESTART_WRAPPER_ENV] !== "1"); } export function getRestartWrapperSignals(platform = process.platform) { return platform === "win32" ? WINDOWS_FORWARD_SIGNALS : POSIX_FORWARD_SIGNALS; } export function getExitCodeForSignal(signal) { if (!signal) return 1; return SIGNAL_EXIT_CODES[signal] ?? 1; } export async function runWithRestartWrapper() { let activeChild = null; const forwardSignal = (signal) => { if (activeChild && activeChild.exitCode === null) { activeChild.kill(signal); } }; for (const signal of getRestartWrapperSignals()) { process.on(signal, () => forwardSignal(signal)); } let childArgs = process.argv.slice(1); while (true) { activeChild = spawn(process.argv[0], childArgs, { cwd: process.cwd(), stdio: "inherit", env: { ...process.env, [RESTART_WRAPPER_ACTIVE_ENV]: "1", [RESTART_WRAPPER_CHILD_ENV]: "1", }, }); const exitCode = await waitForExit(activeChild); activeChild = null; if (exitCode === RESTART_EXIT_CODE) { console.log("[NAISYS] Restarting..."); childArgs = stripOneShotFlags(childArgs); continue; } return exitCode; } } function waitForExit(child) { return new Promise((resolve, reject) => { child.once("error", reject); child.once("exit", (code, signal) => { resolve(code ?? getExitCodeForSignal(signal)); }); }); } //# sourceMappingURL=restartManager.js.map