import { ptree } from "@gajae-code/utils"; import { type LinuxProcPidProbeResult } from "../gjc-runtime/linux-proc"; /** Whether an unreadable `/proc` entry might still describe a running process. */ export declare function procEntryMayStillBeRunning(error: unknown): boolean; /** Whether a process-group leader still has the spawn-time identity we own. */ export declare function groupLeaderIdentityMatches(expectedStartTime: string | undefined, leader: LinuxProcPidProbeResult): boolean; /** Options for {@link spawnOwnedProcess}. */ export interface SpawnOwnedOptions { cwd?: string; env?: Record; /** stdin mode passed through to the child. Defaults to `"ignore"`. */ stdin?: "pipe" | "ignore"; /** When aborted, the owned process tree is disposed (escalating kill). */ signal?: AbortSignal; /** Grace period (ms) between SIGTERM and SIGKILL on dispose. Default 2000. */ gracefulMs?: number; /** * Spawn the child as its own process-group leader so the whole descendant * tree can be signalled on dispose. Defaults to `true` on POSIX. Has no * effect on Windows, where teardown falls back to single-process kill. */ processGroup?: boolean; /** Label used in diagnostics. */ name?: string; } /** Result of a bounded {@link OwnedProcess.awaitExit}. */ export interface AwaitExitResult { /** `true` when the process has exited; `false` when the timeout fired first. */ exited: boolean; /** Exit code if known, else `null`. */ code: number | null; } /** The observed outcome of an owned-process teardown attempt. */ export type OwnedProcessTeardownStatus = "terminated" | "still_running" | "identity_unverified"; /** Result of {@link OwnedProcess.dispose}. */ export interface OwnedProcessTeardownResult { status: OwnedProcessTeardownStatus; } /** A spawned child process owned by the runtime with guaranteed teardown. */ export interface OwnedProcess { readonly child: ptree.ChildProcess; readonly pid: number | undefined; /** Resolves/rejects when the root child exits (mirrors ptree's `exited`). */ readonly exited: Promise; /** `true` once `dispose()` has started. */ readonly disposed: boolean; /** * Wait for the root child to exit, optionally bounded by `timeoutMs`. With no * timeout it resolves only when the child exits. Never rejects. */ awaitExit(opts?: { timeoutMs?: number; }): Promise; /** * Idempotently terminate the owned process *group*: SIGTERM the group, wait * `gracefulMs`, then SIGKILL, polling group liveness throughout. Removes the * abort listener and deregisters from the live-owner set only after teardown * has completed. Repeated/concurrent calls return the same in-flight promise. */ dispose(): Promise; } /** * Spawn a child process owned by the runtime. The returned {@link OwnedProcess} * is registered for postmortem cleanup and tears down its whole process group * on dispose/abort. */ export declare function spawnOwnedProcess(cmd: string[], opts?: SpawnOwnedOptions): OwnedProcess; /** Number of currently live owned processes. Exposed for leak assertions/tests. */ export declare function liveOwnedProcessCount(): number; /** Dispose every live owned process. For owner-scoped teardown and tests. */ export declare function disposeAllOwnedProcesses(): Promise; type ResourceDisposer = () => void | Promise; /** * Register a non-process resource for postmortem/fatal-exit cleanup. * * Idempotent by `name`: re-registering the same name replaces the prior * disposer (last wins). Returns an unregister function that removes the owner * only while it is still the active registration for that name. */ export declare function registerResourceOwner(name: string, disposer: ResourceDisposer): () => void; /** Number of registered resource owners. Exposed for leak assertions/tests. */ export declare function resourceOwnerCount(): number; /** * Run and clear every registered resource disposer. Attempts all disposers even * if some throw, then surfaces the failures as an `AggregateError` so callers * can distinguish "all closed" from "a resource may still be alive". */ export declare function disposeAllResourceOwners(): Promise; export {};