/**
 * Post-reconcile repair — the shared "make it whole" pass `agents sync` runs
 * after its prune+write, so sync is a true superset of the old `doctor --fix`.
 *
 * `syncResourcesToVersion` reconciles resource FILES (and, with a caller
 * selection, prunes orphans). It does NOT: fill live-home gaps the staleness
 * manifest can't see, generate/repair the managed hook runtime shims, or re-wire
 * a present-but-unwired hook into settings.json. `doctor --fix` used to do all of
 * that; now sync does, by calling this one routine at the tail of every reconcile.
 * (The destructive stale-CLI purge `doctor --fix` also ran is NOT automatic here
 * — it runs only via the explicit `agents sync --prune-clis`, see `pruneClis`.)
 *
 * Ordering matters: sync's own prune+write happens FIRST (unchanged), THEN this
 * repair pass. Prune stays sync's job; heal only FILLS and FIXES (never deletes),
 * so the two never fight. Pure of stdout — returns a structured report;
 * `renderRepairAfterSync` prints it only when the caller is neither `--json` nor
 * `--quiet`.
 */
import type { AgentId } from './types.js';
import { type HealResult } from './heal.js';
import { type HookRuntimeRepairReport } from './hooks/install.js';
import { type RemediateStaleInstallsResult, type FindAgentsCliInstallsOptions } from './self-update.js';
export interface HookRewireResult {
    agent: AgentId;
    version: string;
    /** Hooks newly wired into settings.json by this pass. */
    rewired: number;
    /** Hooks still unwired after re-registering (source/home mismatch). */
    remaining: number;
    /** Stable failure class; never expose a generated temporary shim pathname. */
    failure?: 'register-failed';
}
export interface RepairAfterSyncReport {
    heal: HealResult;
    hookRewire: HookRewireResult[];
    hookRuntimeRepair: HookRuntimeRepairReport;
    /** Only populated on the umbrella (no-agent) path; null otherwise. */
    staleInstallPurge: RemediateStaleInstallsResult | null;
}
/**
 * Test/override hook that scopes the destructive stale-CLI purge to injected
 * paths so it NEVER touches real machine installs. `findAgentsCliInstalls`
 * hard-codes `/usr/local/lib/node_modules` et al. when `globalNodeModulesDirs` is
 * absent, so a purge is unsafe to run unscoped in a test — inject sandbox paths.
 */
export interface PurgeInjection {
    runningRoot?: string;
    runningVersion?: string;
    pathEnv?: string;
    findOpts?: FindAgentsCliInstallsOptions;
    dryRun?: boolean;
}
export interface RepairAfterSyncOptions {
    /** Scope the repair to one agent; omit for the umbrella sweep across all
     *  installed agents. (The purge is NOT tied to this — see `pruneClis`.) */
    agent?: AgentId;
    /** The versions of `agent` the sync just reconciled. Passing them scopes
     *  heal + rewire + runtime-repair to exactly those homes; omitting lets heal
     *  apply its own non-isolated sweep. */
    versions?: string[];
    /** Resolution cwd for heal's diff. Defaults to heal's neutral home dir. */
    cwd?: string;
    /** Run the DESTRUCTIVE machine-wide stale-CLI purge (`fs.rmSync`s other
     *  agents-cli installs). Default false — the purge is NEVER automatic; it runs
     *  only on the umbrella (no-agent) path AND only when the caller passed
     *  `agents sync --prune-clis`. */
    pruneClis?: boolean;
    /** Scope the purge scan+delete to injected paths (tests only). */
    purgeInjection?: PurgeInjection;
}
/**
 * Run the post-reconcile repair pass over the agents/versions a sync just
 * touched: heal live-home gaps (mode 'full', matching the old `doctor --fix`),
 * re-wire hooks the diff-driven heal leaves behind, run one bounded managed-hook
 * runtime repair, and — ONLY when `pruneClis` is set on the umbrella (no-agent)
 * path — purge stale/legacy agents-cli copies. The purge is never automatic.
 * Returns a full account; never writes to stdout.
 */
export declare function repairAfterSync(opts: RepairAfterSyncOptions): Promise<RepairAfterSyncReport>;
/** True when the repair pass changed (or attempted to change) anything. */
export declare function repairChangedAnything(report: RepairAfterSyncReport): boolean;
/**
 * True when the RECONCILE repair left a per-version problem a human must fix — an
 * unresolvable managed hook runtime shim, or a hook that could not be re-wired.
 * These gate a sync's `ok`/exit code (the yosemite-s1 class the old
 * `doctor --fix` surfaced).
 *
 * The machine-wide stale-CLI purge is deliberately EXCLUDED: a purge that could
 * not delete a system-wide install (typically `EACCES` on `/usr/local/...`, which
 * needs sudo) is a hygiene issue unrelated to whether the reconcile succeeded, so
 * it must not flip a fleet peer's `agents sync --json` to `ok: false`. Purge
 * failures stay fully visible — in the JSON `repair.staleInstallPurge.failed` and
 * the rendered `hold`/`manual` lines.
 */
export declare function repairHadFailures(report: RepairAfterSyncReport): boolean;
/**
 * Serialize the repair pass for a `--json` sync payload — the machine surface the
 * deleted `doctor --fix --json` used to carry (heal detail + hook rewire + hook
 * runtime repair + the umbrella stale-CLI purge). Attached under the `repair` key
 * so fleet fan-out sees what the reconcile fixed and whether anything still needs
 * a human (mirror `repairHadFailures`).
 */
export declare function repairAfterSyncJson(report: RepairAfterSyncReport): Record<string, unknown>;
/**
 * Print the repair pass's human-readable detail. Sync calls this only on the
 * interactive / non-json path; the header is emitted only when something actually
 * changed, so a clean sync stays quiet.
 */
export declare function renderRepairAfterSync(report: RepairAfterSyncReport, log?: (s: string) => void): void;
