/**
 * AgentWorktreeReaper — reclaims stale CLI-created agent worktrees under
 * `~/.instar/agents/<agent>/.worktrees/`.
 *
 * Distinct from WorktreeReaper (which manages WorktreeManager *bindings* under
 * `.instar/worktrees/` via the state-reconciliation matrix): the `.worktrees/`
 * worktrees created by `instar worktree create` are UNMANAGED — nothing prunes
 * them, so they accumulate (measured: ~120 / ~55GB), which is both a disk drain
 * and the macOS-indexing CPU drain that the Spotlight-exclusion marker mitigates.
 *
 * THE hard requirement: NEVER delete unmerged or dirty work. A worktree is
 * reap-eligible ONLY when ALL of these hold:
 *   - not in use (no live session/index lock AND no running process whose cwd is
 *     inside the worktree), and
 *   - clean (no uncommitted or untracked changes), and
 *   - merged (its branch's content is already in the default branch — including
 *     single-commit squash-merges, detected via `git cherry` patch-id).
 * When all three hold, removing the worktree loses NOTHING: the branch and its
 * commits remain in the repo (merged ⇒ content is in main; clean ⇒ no uncommitted
 * work), so only the working-dir checkout is reclaimed (re-creatable on demand.)
 * Staleness is deliberately NOT a gate: on a high-velocity fleet every branch is
 * rebased onto recent main, so commit/dir timestamps are uniformly "recent" and
 * cannot distinguish abandoned from active — "in use" (lock + live process cwd)
 * is the real signal. Any ambiguity → KEEP. Ships OFF + dry-run by default (the
 * only worktree path that deletes on a heuristic). Part of the Responsible
 * Resource Usage standard (OS resource hygiene).
 */
import { EventEmitter } from 'node:events';
export interface AgentWorktreeReaperConfig {
    enabled: boolean;
    dryRun: boolean;
    reapIntervalMs: number;
    /** Bounded blast radius per pass. */
    maxReapsPerPass: number;
}
export declare const DEFAULT_AGENT_WORKTREE_REAPER_CONFIG: AgentWorktreeReaperConfig;
export interface WorktreeInfo {
    path: string;
    branch: string | null;
    headSha: string;
}
export type Verdict = 'keep' | 'reap-eligible';
export interface WorktreeEvaluation {
    path: string;
    branch: string | null;
    verdict: Verdict;
    /** The gate that forced KEEP, or 'merged-clean-idle' when reap-eligible. */
    reason: string;
}
/**
 * All signal sources injected so the classifier is unit-testable without git/fs.
 * Production wiring supplies git-backed implementations via SafeGitExecutor.
 */
export interface AgentWorktreeReaperDeps {
    /** Worktrees under the agent's `.worktrees/` (excludes the main checkout). */
    listWorktrees: () => WorktreeInfo[];
    /** True when the worktree has NO uncommitted or untracked changes. */
    isClean: (path: string) => boolean;
    /** True when the branch's content is already in the default branch. */
    isMerged: (info: WorktreeInfo) => boolean;
    /** True when the worktree is in use: a live session/index lock OR a running
     *  process whose cwd is inside it. The real "don't yank it" signal. */
    isInUse: (path: string) => boolean;
    /** Remove the worktree (git worktree remove). Only called when killsEnabled. */
    removeWorktree: (path: string) => void;
    now?: () => number;
}
export declare class AgentWorktreeReaper extends EventEmitter {
    private readonly cfg;
    private readonly deps;
    private readonly now;
    private timer?;
    private running;
    private lastPassAt;
    private reapedLastPass;
    constructor(deps: AgentWorktreeReaperDeps, cfg?: Partial<AgentWorktreeReaperConfig>);
    start(): void;
    stop(): void;
    private get killsEnabled();
    /**
     * Pure, stateless per-worktree classifier. Returns KEEP unless EVERY safety
     * gate clears. Order: cheap protect-gates first (short-circuit on the first
     * KEEP) — never evaluate `isMerged` (a git call) on a dirty/active worktree.
     */
    evaluate(info: WorktreeInfo): WorktreeEvaluation;
    /** One reap pass. Returns the per-worktree evaluations + what was reaped. */
    reap(): Promise<{
        ts: number;
        evaluations: WorktreeEvaluation[];
        reaped: string[];
        dryRun: boolean;
    }>;
    /** Observability snapshot for GET /worktrees/agent-reaper (no side effects). */
    snapshot(): {
        enabled: boolean;
        dryRun: boolean;
        lastPassAt: number;
        reapedLastPass: number;
        worktrees: WorktreeEvaluation[];
        reclaimable: number;
    };
}
//# sourceMappingURL=AgentWorktreeReaper.d.ts.map