/** * Single-instance lock, keyed by launch directory (like the channel registry). * * Two servers running from the same directory share the same registry + the * `telegram-group` config, and each starts its own Telegram bridge on the same * bot. Concurrent writes corrupt the config (a bound board group id once leaked * in from a stale instance, then reconcile deleted every channel). A per-dir * lock makes the second instance refuse to start instead of fighting. */ /** The lock file for the instance launched in `cwd` (default: process.cwd()). */ export declare function instanceLockPath(cwd?: string): string; /** * Pure: the process state letter from a `/proc//stat` line, or null when * the line is unusable. * * Read from the LAST `)`: the second field is the command name, parenthesised * and arbitrary, so it may itself contain spaces and brackets. Splitting from * the left mis-parses every process whose name has one. */ export declare function stateFromProcStat(contents: string): string | null; /** How `pidAlive` looks a process up; injected in tests. */ export type ProcStatReader = (pid: number) => string | null; /** * Whether a process with `pid` is currently running. * * A **zombie** answers signal 0: it has exited, but nobody has reaped it, so * its pid entry survives. That is the normal case in a container, where pid 1 * is the application rather than an init that reaps — so a stopped instance * held its launch directory's lock forever, and every later start was refused * while naming a pid that no longer existed. `/proc` is Linux-only; where it is * absent the signal's answer stands. */ export declare function pidAlive(pid: number, procStat?: ProcStatReader): boolean; /** * Try to become the single instance for this launch dir. Returns { ok: true } * when the lock is held, or { ok: false, pid } when a LIVE instance already * holds it. A stale lock (dead holder) is reclaimed. */ export declare function acquireInstanceLock(lockPath?: string, procStat?: ProcStatReader): { ok: true; } | { ok: false; pid: number; }; /** Release our lock (best effort) — only if we still hold it. */ export declare function releaseInstanceLock(lockPath?: string): void;