/**
 * `agents doctor` — diagnostic readout across the install.
 *
 * Two modes:
 *
 *   1. Overview (no target): three sections —
 *      - CLI availability (which agent binaries can be invoked).
 *      - Sync status per default version (fresh / stale / never-synced).
 *      - Orphans per default version per resource type.
 *
 *   2. Target mode: `agents doctor <agent>[@version]` — full per-resource
 *      diff for a single (agent, version) against the current cwd's resolved
 *      sources. Reports ok / DIFF / MISS / EXTRA per resource with the source
 *      layer (project, user, system, extra repo). With `--diff`, renders a
 *      unified diff body for each divergent file. Mirrors the resolution that
 *      the shim drives at runtime: project > user > system > extras.
 *
 * Read-only always: doctor diagnoses, it never mutates. To fix the gaps it
 * finds — install missing resources, repair Claude-invalid plugin manifests,
 * refresh stale plugins, reconcile drift, repair hook runtime shims — run
 * `agents sync <agent>@all` (the one fixer, a superset of the old `doctor
 * --fix`). Run `agents prune cleanup` to act on orphan readouts. `--fix` is a
 * deprecated no-op that now errors with a pointer to `agents sync`.
 */
import type { Command } from 'commander';
import { type FleetInventory } from '../lib/devices/fleet-divergence.js';
import { type DoctorFinding } from '../lib/devices/doctor-findings.js';
import { type VersionResourceReport } from '../lib/doctor-diff.js';
import { type DuplicateVersionHook } from '../lib/hooks/install.js';
import { type SyncStatusRow, type OrphanRow } from '../lib/drift.js';
import { type FetchStatusMarker } from '../lib/auto-pull.js';
export declare function wrapLine(prefix: string, text: string, width?: number): string[];
export declare function asRemoteSecretFindings(raw: unknown, device: string): DoctorFinding[];
/**
 * Fetch a device's harness inventory by running its top-level `agents doctor
 * --json` (which carries the `fleet` field, RUSH-2027). Separate from
 * {@link probeFleetTarget} — that forwards `teams doctor --json` for per-agent
 * readiness, a different payload. Returns the parsed {@link FleetInventory} or
 * null (unreachable, non-zero exit, unparseable, or an older CLI with no
 * `fleet` field); a null is skipped by the comparator, never a false gap.
 */
/**
 * How long one remote `doctor --json` probe may take.
 *
 * 180s, matching `ChildProcess.doctorTimeout`, which was set to 180 for this
 * same command for this same reason. The previous 30s sat BELOW the command's
 * real cost — 56s measured on `yosemite-m0`, 136s on an idle box — so every slow
 * device silently contributed nothing at all: no inventory, no sign-in, no
 * divergence, no secret findings. A ceiling under the true cost does not make a
 * probe cheap, it makes it always fail.
 *
 * This does not multiply by device count: `fanOutDevices` is `Promise.all`, so
 * whole-fleet wall time is bounded near the slowest box, not 180s x N.
 */
export declare const FLEET_INVENTORY_TIMEOUT_MS = 180000;
/**
 * Narrow a remote `doctor --json` `.fleet` payload to a usable inventory, or null.
 *
 * The remote runs ITS OWN agents-cli, whose version we do not control, so the
 * payload is untrusted input rather than a typed value — a cast alone let a
 * partial object (`{"fleet":{}}` from a skewed or truncated remote) reach
 * `compareFleetInventories`, which indexes `inv.resources[kind]` and
 * `Object.keys(inv.agentVersions)` unconditionally and throws. Returning null
 * routes that device into the existing "older agents-cli / no inventory" path,
 * which is honest and already rendered, instead of aborting the whole fan-out.
 *
 * This validates EVERY field of {@link FleetInventory} that anything downstream
 * reads — `resources`, `agentVersions`, `repos` and each optional `signIn` row.
 * It was tightened four times during review, each round finding the next
 * unvalidated layer, so treat partial validation here as a bug: a field added to
 * the inventory must be checked here in the same change.
 */
export declare function asFleetInventory(value: unknown): FleetInventory | null;
export type IssueSeverity = 'critical' | 'warning' | 'info';
/**
 * One triaged health finding. `severity`/`category`/`subject`/`impact`/`fix` are
 * the triage backbone the human report renders and `--json` carries; `text`/`color`
 * stay the terse combined label older readers used, so the shape is additive.
 *
 * Severity model (agent-agnostic — applies to every agent doctor inspects):
 *   - critical (silent breakage): an unwired hook, a missing/unparseable
 *     settings.json, a MISSING hook or plugin.
 *   - warning (stale / drift): a source layer behind origin, a DIVERGENT resource,
 *     a stale / never-synced version, a MISSING resource of any other kind
 *     (see `missingResourceSeverity`, which reads this split from
 *     `FINDING_SEVERITY` — RUSH-2947).
 *   - info (orphan): an EXTRA resource → `agents prune cleanup`.
 */
export interface VerdictIssue {
    severity: IssueSeverity;
    /** machine-stable class: unwired-hook | settings-missing | settings-unparseable
     *  | missing | source-behind | divergent | extra | stale | never-synced | orphan */
    category: string;
    /** the hook / resource / layer / version the finding is about */
    subject: string;
    /** one-line plain-English consequence */
    impact: string;
    /** exact remediation command */
    fix: string;
    /** terse combined label (legacy) */
    text: string;
    color: 'yellow' | 'red' | 'magenta';
}
export interface DoctorVerdict {
    healthy: boolean;
    issues: VerdictIssue[];
    /** Resources (target) / versions (overview) reconciled clean — drives the
     *  healthy line's count. */
    reconciled: number;
}
export declare function verdictIsAutoFixable(v: DoctorVerdict): boolean;
/**
 * Fold a version report's divergences into a triaged verdict — one severity-tagged
 * finding per unwired hook, missing/divergent/extra resource, and behind-origin
 * source layer, each carrying its subject, plain-English impact, and exact fix. An
 * UNWIRED hook or a stale source is as unhealthy as a divergent file, not a
 * footnote. Pure so the health rollup is unit-testable without a version home.
 */
export declare function computeVerdict(report: VersionResourceReport): DoctorVerdict;
/**
 * Build the lines of a triaged health block: a single green ✓ line when healthy,
 * otherwise a severity-counted ✗ header followed by one row per finding (icon ·
 * severity · subject — impact, then the exact fix under it) and an optional heal
 * footer. Pure — returns the lines so the rendered output is unit-testable. Shared
 * by target mode and the bare overview so both read the same way.
 */
export declare function healthBlockLines(verdict: DoctorVerdict, opts: {
    healthySummary: string;
    healFix?: string;
}): string[];
/**
 * Aggregate the bare `agents doctor` overview into the same triaged verdict target
 * mode uses — folding per-version wiring/sync drift, behind-origin source layers,
 * and orphan resources into severity-tagged findings. Agent-agnostic: every
 * installed version is classified the same way. Pure, so it is unit-testable.
 */
export declare function computeOverviewHealth(syncRows: SyncStatusRow[], orphanRows: OrphanRow[], repoBehindMarkers: FetchStatusMarker[], duplicateHooks?: DuplicateVersionHook[]): DoctorVerdict;
export declare function registerDoctorCommand(program: Command): void;
