import type { NodeMeta, NodeStatus } from '../canvas/types.js'; /** Statuses a node lands in DELIBERATELY: a worker that finished its own work * (`done`) or a node a human closed/reaped (`canceled`). The daemon never * auto-revives these (see reapDeadResidue in crtrd.ts), and revive-all leaves * them alone too — resurrecting finished and closed conversations en masse would * flood the canvas with work nobody asked to reopen. `dead` is NOT here: a crash * is involuntary, so it is swept. (Silas, 2026-06-13: no opt-in to include these * — the exclusion is unconditional.) */ export declare const TERMINAL_BY_CHOICE: readonly NodeStatus[]; /** True when `meta` has no natural future cycle ahead of it — either its own * work is finished (`final_report` set) or it landed deliberately in one of * TERMINAL_BY_CHOICE. Nothing in the runtime (daemon supervision, the live * inbox watcher's own hold-and-flush) ever brings such a node back on its * own — only an explicit revive/reopen does. Shared by `isDisconnected` * (mass-revive scope, below) and `node message send --tier deferred`'s terminal-edge * rejection (gh #341) — a deferred entry appended to such a target would * never be delivered, so that doorway rejects instead of silently holding * it forever. */ export declare function hasNoNaturalCycle(meta: Pick): boolean; /** True when `meta`'s engine is NOT running but it has a resumable saved session * — the precise "disconnected" predicate (gh #9). * * - engine not running: no live `pi_pid` (a dead/absent broker pid). * - reconnectable: a captured pi session marker (`pi_session_file` or * `pi_session_id`) — without one there is nothing to reopen. reviveNode * resumes by the `.jsonl` path when it still exists, else relaunches fresh (a * bare `pi_session_id` alone no longer resumes — the broker preflight rejects * it — so such a node comes back fresh). * - `human`-kind rows are the `crtr human` bridge, never a pi engine, so they * are never "disconnected" (mirrors the daemon's superviseTick carve-out). * - terminal-by-choice (`done`/`canceled`) is always excluded. * - a node that already pushed its FINAL REPORT (`final_report` set) FINISHED * its own work — it is excluded regardless of status. A crash mid-reap can * leave it `dead` (not terminal-by-choice) with its report already committed; * resurrecting it as `active` strands it re-reviving forever and cannot * re-reap (the stuck-node incident). Mass revive must never resurrect * finished work; an explicit `node lifecycle revive ` still can. * * Pure: the liveness probe is injected so scope is unit-testable without real * processes. */ export declare function isDisconnected(meta: NodeMeta, isAlive: (pid: number | null | undefined) => boolean): boolean; /** Every disconnected node on the canvas — the set a revive-all WOULD relaunch. * This is the PREVIEW: it has no side effects, so the command can list the * candidates and gate on confirmation before any engine is launched. */ export declare function listDisconnected(): NodeMeta[]; export interface ReviveAllResult { /** Node ids whose broker engine reviveAll relaunched (RESUME). */ revived: string[]; /** Per-node failures — reviveNode threw (its launch failed). One bad node * never aborts the sweep. */ failed: { node_id: string; error: string; }[]; } /** RESUME every disconnected node. reviveNode is the ONLY sanctioned launcher * and self-guards the double-spawn (a node whose broker pid is already live is a * no-op), so this is a thin orchestrator over `listDisconnected`: revive each * with resume:true. One failing node never aborts the sweep — its error is * collected and the rest proceed. */ export declare function reviveAll(): ReviveAllResult;