UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

42 lines (41 loc) • 2.52 kB
import { shutdownDebug } from "../../core/shutdown-debug.js"; export { shutdownDebug }; export type KillProcessTreeOptions = { graceMs?: number; detached?: boolean; force?: boolean; /** * 1.296 件2 — identity anchor for the graceful SIGKILL escalation. A pid is a NAME, not an * identity: when the original process (group) exits within the grace window and the OS re-uses * the pid (small pid_max containers + fork-heavy build workloads make the window real), the * pid-liveness recheck reads the STRANGER as "still alive" and the SIGKILL lands on an unrelated * process. When provided, the escalation leg consults this callback FIRST — it must return true * only while the ORIGINAL process is known not to have exited (e.g. a retained ChildProcess * handle with `exitCode === null && signalCode === null`); the pid probe remains only an * auxiliary check. Absent ⇒ the pre-existing pid-only behavior (callers without a process handle). * * (1.296.1) — `false` cancels the DIRECT-pid escalation (that is where pid-reuse risk * lives), but on the group-kill lane it no longer cancels the GROUP leg: the anchor only knows * the LEADER — a detached shell that honors SIGTERM and exits while its TERM-ignoring descendants * (run89's build workers) keep the group alive. While ANY original member lives, POSIX reserves * the pgid for this group, so a group-scoped SIGKILL cannot land on a stranger; the group leg * therefore probes group liveness and fires group-only. (Residual window — the WHOLE group died * AND the pid was recycled as a NEW group leader inside the grace window — is the same one every * `kill -- -PGID` accepts, documented not closed.) */ stillRunning?: () => boolean; }; /** * Best-effort process-tree termination with graceful shutdown. * - Windows: use taskkill /T to include descendants. Sends SIGTERM-equivalent * first (without /F), then force-kills if process survives. * - Unix: send SIGTERM to process group first, wait grace period, then SIGKILL. * * When the child was spawned with `detached: false`, pass `detached: false` to * skip the Unix `process.kill(-pid, ...)` group-kill. That avoids signaling the * gateway's own process group. */ export declare function killProcessTree(pid: number, opts?: KillProcessTreeOptions): void; export declare function signalProcessTree(pid: number, signal: "SIGTERM" | "SIGKILL", opts?: { detached?: boolean; }): void;