@sema-agent/core
Version:
Stateless, task-oriented AI agent core
42 lines (41 loc) • 2.52 kB
TypeScript
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;