@essentialai/cogent-bridge
Version:
Cogent Bridge — cross-agent comms for Claude Code, OpenAI Codex and Slack. Codex users: install with `curl -fsSL https://cogent.tools/install.sh | sh`, then start with `cogent-codex` for real-time peer wake.
71 lines • 3.52 kB
TypeScript
/** One process as reported by `ps`. */
export interface ProcInfo {
pid: number;
ppid: number;
/** Milliseconds since epoch when the process started. */
startedAt: number;
/** Full command line. */
argv: string;
}
export interface ReapCandidate {
proc: ProcInfo;
/** Human-readable justification, logged before any signal is sent. */
reason: string;
}
/**
* Does this command line launch a cogent BRIDGE?
*
* Deliberately anchored on the entry-point FILE, never on the word "cogent" appearing somewhere.
* A substring match would catch this repo's own gate harnesses (`wake-dedup-matrix-test.mjs`,
* `slack-roundtrip-test.mjs`) and an editor with the source open — and a harness matching its own
* command line is a mistake this codebase has already made twice.
*/
export declare function isBridgeCommand(argv: string): boolean;
/** Best-effort version parsed out of a plugin-cache path, e.g. `/cogent/3.21.5/bridge/...`. */
export declare function versionFromArgv(argv: string): string | null;
/** Every running process, from `ps`. Returns [] on any failure — never throws. */
export declare function listProcesses(): ProcInfo[];
/**
* Resolve a process's working directory, or null when it cannot be determined.
*
* NULL IS A REFUSAL, NOT A GUESS. If we cannot prove the process is in our cwd we must not touch
* it — an unresolvable cwd is the single most likely way this reaper would kill something innocent.
*/
export declare function processCwd(pid: number): string | null;
/**
* Canonical form of a path for COMPARISON — symlinks resolved.
*
* 🔴 macOS. `lsof` reports a process's cwd already realpath'd (`/private/var/...`) while
* `process.cwd()` keeps the symlinked spelling (`/var/...`), because `/var -> /private/var`. A
* `path.resolve`-only comparison therefore NEVER matches on macOS and the reaper is silently inert
* — it fails safe, but it heals nobody, which is the whole point of it. Found by running the
* platform probe on a real Mac; no Linux test could have shown it.
*
* Falls back to `path.resolve` when the path no longer exists, so a vanished cwd degrades to a
* non-match (a refusal) rather than an exception.
*/
export declare function canonicalPath(p: string): string;
/** Every ancestor pid of `pid`, walking ppid to init. Cycle-safe. */
export declare function ancestorsOf(pid: number, procs: ProcInfo[]): Set<number>;
/**
* Which running processes are leftover bridges for `cwd` that cannot stand down by themselves?
*
* `procs` is injectable so the decision logic is unit-testable without spawning anything, and
* `cwdOf` so a test can supply cwds without /proc.
*/
export declare function findStaleBridges(cwd: string, procs?: ProcInfo[], opts?: {
selfPid?: number;
selfStartedAt?: number;
cwdOf?: (pid: number) => string | null;
announced?: Set<number>;
}): ReapCandidate[];
/** Is the reaper enabled? Default ON; opt out with a falsey COGENT_REAP_STALE_BRIDGES. */
export declare function reaperEnabled(env?: NodeJS.ProcessEnv): boolean;
/**
* SIGTERM every leftover bridge for this cwd. Returns the candidates acted on.
*
* Graceful on purpose: the bridge's SIGTERM handler stops auto-relay, disconnects the WebSocket and
* exits cleanly, so a mistargeted kill is a clean shutdown rather than a corrupted one.
*/
export declare function reapStaleBridges(cwd: string, opts?: Parameters<typeof findStaleBridges>[2]): ReapCandidate[];
//# sourceMappingURL=stale-bridge-reaper.d.ts.map