/** * Idle auto-release for scheduler-launched client servers. * * Opt-in per allocation: when the compute-node client server is started with * NEBULA_IDLE_EXIT_MINUTES=, it watches its own kernel and terminal * activity and exits its process after n idle minutes. The batch job then * completes and the allocation ends naturally — no scancel plumbing, no * scheduler-side state. * * "Idle" means all of: * - no kernel session is busy (or still starting up), AND * - the most recent kernel activity (execution start/finish, restart) is * older than the timeout, AND * - the most recent terminal (pty) activity is older than the timeout. * * The monitor's own start time is the initial activity baseline, so a fresh * allocation gets the full timeout before anything has run on it. */ /** * Pure idleness decision — should the client server exit now? * * @param nowMs current time (ms since epoch) * @param lastKernelActivityMs most recent kernel activity (ms), or null if no signal * @param anyKernelBusy true when any kernel session is 'busy' or 'starting' * @param lastPtyActivityMs most recent terminal activity (ms), or null if no signal * @param timeoutMinutes idle timeout; <= 0 disables (never exit) */ export declare function shouldIdleExit(nowMs: number, lastKernelActivityMs: number | null, anyKernelBusy: boolean, lastPtyActivityMs: number | null, timeoutMinutes: number): boolean; export interface IdleExitMonitorOptions { /** Idle minutes before self-exit (from NEBULA_IDLE_EXIT_MINUTES). */ timeoutMinutes: number; /** Kernel-side activity snapshot (kernelService.getIdleSnapshot). */ getKernelSnapshot: () => { anyBusy: boolean; lastActivityMs: number | null; }; /** Most recent terminal activity across pty sessions (null = none). */ getLastPtyActivityMs: () => number | null; /** Called once when ~WARN_LEAD_MINUTES remain (re-armed if activity resumes). */ onWarn: (minutesLeft: number) => void; /** Called once when the idle timeout is reached. */ onIdleExit: () => void | Promise; /** Check interval; default 60s. Exposed for tests. */ intervalMs?: number; /** Activity baseline; default Date.now() (start of monitoring). */ startedAtMs?: number; } /** * Start the periodic idleness check. Returns a stop function. * The interval is unref()ed so it never keeps an exiting process alive. */ export declare function startIdleExitMonitor(opts: IdleExitMonitorOptions): () => void;