/** * power/linux-logind.ts, the Linux implementation of the power seam. * * Inhibitors are held by spawning `systemd-inhibit` (the stock unprivileged * logind D-Bus client, it calls org.freedesktop.login1.Manager.Inhibit and * holds the returned fd for the life of its child). No root, no sudo, ever: * an unprivileged user can always hold idle/sleep inhibitors; a lid-switch * block may be refused by polkit, which surfaces as an honest per-class * denial rather than a fake grant. Requesting classes individually is what * makes the per-class grant/deny split observable. * * The sleep edge is the logind PrepareForSleep signal, watched with a * long-lived `dbus-monitor --system` subscription (read-only; no privileges * required for signal watching). */ import { type ChildProcess } from 'node:child_process'; import type { PowerInhibitClass, PowerPlatformSeam } from './types.js'; /** * Injectable spawner for the sleep-edge monitor child so unit tests can drive * the watcher's subscribe/parse/reap contract without launching a real * dbus-monitor. The default spawns the real read-only system-bus monitor. */ export type SleepWatchSpawner = (command: string, args: readonly string[]) => ChildProcess; /** Injectable process-table seams so the reaper is fixture-testable. */ export interface OrphanReaperDeps { /** List candidate processes: pid + full command line. Default: Linux /proc scan. */ readonly listProcesses?: (() => ReadonlyArray<{ pid: number; args: string; }>) | undefined; readonly isAlive?: ((pid: number) => boolean) | undefined; readonly kill?: ((pid: number) => void) | undefined; readonly selfPid?: number | undefined; } /** * Kill goodvibes-owned power children whose stamped owner pid is DEAD (a * crashed owner: nothing will ever release them). Covers both the sleep/idle * inhibitors (`systemd-inhibit`, which otherwise block host sleep with no * owner) and the sleep-edge watchers (`dbus-monitor`, which otherwise pile up * against the system bus's per-uid connection quota). Matches only processes * carrying this module's own owner-pid stamp, never anything else. Returns the * number reaped. */ export declare function reapOrphanedInhibitors(who: string, deps?: OrphanReaperDeps): Promise; /** * The exact argv for one inhibitor child. `--no-ask-password` is load-bearing: * when polkit requires authentication for an inhibit class (a tmux/SSH session * logind does not count as an active seat), systemd-inhibit would otherwise * register an interactive auth agent on the CONTROLLING TERMINAL, /dev/tty * writes that stdio 'ignore' cannot suppress, painted straight over a * fullscreen UI. With the flag, denial is an immediate silent non-zero exit, * which lands in the deniedClasses path like any other refusal. */ export declare function inhibitChildArgs(cls: PowerInhibitClass, who: string, why: string): string[]; export declare function createLinuxLogindSeam(options?: { readonly who?: string | undefined; readonly spawnMonitor?: SleepWatchSpawner | undefined; }): PowerPlatformSeam; //# sourceMappingURL=linux-logind.d.ts.map