import { type PidSessionEntry } from '../session/pid-registry.js';
import { type ReapResult, type Task } from './types.js';
/** Default idle window before an untouched task is reaped. */
export declare const DEFAULT_IDLE_MS: number;
/**
 * The slice of `BrowserService` the reaper needs. Structural, so a test drives
 * it with a stub and `BrowserService` satisfies it without an import — which
 * also keeps this module off the service's import cycle.
 */
export interface ReapableService {
    listTasks(): Array<{
        profile: string;
        task: Task;
    }>;
    recordStatus(taskName: string): Promise<{
        recording: boolean;
    }>;
    stop(taskName: string): Promise<{
        ok: boolean;
        profile?: string;
    }>;
}
/**
 * Injectable liveness sources. Same shape as `feed-post.ts`
 * (`input.listEntries ?? listPidSessionEntries`, feed-post.ts:119) — the
 * defaults are the real registry and the real process table, so a test can
 * substitute them without mocking a module.
 */
export interface ReapDeps {
    listEntries?: () => PidSessionEntry[];
    pidAlive?: (pid: number, startedAtMs?: number) => boolean;
    sessionIdOfPid?: (pid: number) => string | undefined;
    sessionLiveOnProcessTable?: (sessionId: string) => Promise<boolean>;
}
export interface ReapOptions {
    /**
     * Idle window in ms. Default {@link DEFAULT_IDLE_MS}.
     *
     * `null` is the explicit "idle reaping is off" signal
     * (`browser.task-idle-minutes=0`) — session-dead reaping below is
     * unaffected. A caller-supplied `0` is a DIFFERENT thing and still throws
     * (see the guard below): it is far likelier to be a bug (a value that
     * survived `??` unset) than an intentional "reap everything immediately."
     */
    idleMs?: number | null;
    /** Clock, injectable for tests. Default `Date.now()`. */
    now?: number;
    /** Report what would be closed without closing anything. */
    dryRun?: boolean;
    deps?: ReapDeps;
}
export interface LiveIdentities {
    sessions: Set<string>;
    launches: Set<string>;
}
/**
 * Session and launch ids belonging to a process that is alive right now.
 *
 * Built from the per-pid launch registry, filtered to live pids —
 * `isPidAlive(pid, startedAtMs)` rather than a bare existence check, so a pid
 * the OS recycled onto an unrelated process does not read as a live agent.
 * An entry with no recorded `sessionId` still contributes one when the live
 * process carries `--session-id` on its argv, which is the RUSH-2384 recovery
 * path the registry itself documents (pid-registry.ts:102-107).
 */
export declare function resolveLiveIdentities(deps?: ReapDeps): LiveIdentities;
/**
 * True when the task's owner is PROVABLY gone. The bar is proof, not absence of
 * evidence, because being wrong here closes a working agent's tabs.
 *
 * Only a `sessionId` can carry that proof. It has two independent sources — the
 * per-pid launch registry, and a live process carrying `--session-id <id>` in
 * its argv — so a session the registry missed is still caught by the process
 * table. The registry misses constantly: a wrapper pid exits, a prune sweeps
 * the entry, or the agent was never launched via `agents run`
 * (pid-registry.ts:102-107, RUSH-2384).
 *
 * A `launchId` has NO second source — the registry is its only witness, and
 * that witness is the unreliable one. So a task carrying only a `launchId` is
 * never session-reaped, exactly like a task carrying no identity at all; both
 * fall through to the idle rule. This is not a corner case: `launchId` is
 * minted for every run (`exec.ts` `resolveLaunchId`) while `AGENT_SESSION_ID`
 * is Claude-only and skipped on resume, so treating a missing registry entry as
 * proof of death would close the tabs of every live codex/droid/grok run whose
 * launch pid had already exited.
 *
 * A live `launchId` still RESCUES a task whose `sessionId` looks dead — proof of
 * life needs only one witness, unlike proof of death.
 */
export declare function taskOwnerIsGone(task: Task, live: LiveIdentities, deps?: ReapDeps): Promise<boolean>;
/**
 * Stop every task whose owner is gone or that has sat untouched past `idleMs`.
 *
 * Returns what it closed and how many it left alone. A task that is mid-
 * recording is always left alone: reaping it would truncate a capture the user
 * asked for, and an in-flight recording is itself proof the task is in use.
 */
export declare function reapAbandonedTasks(service: ReapableService, opts?: ReapOptions): Promise<ReapResult>;
