import { IEventBus, IScopedLogger } from '@camstack/types';
/**
 * Kernel-level addon health monitor.
 *
 * Tracks load + initialize + crash failures across the addon population
 * and drives an aggressive auto-retry loop independent of any single
 * addon's logic. Mirrors the spec the operator approved:
 *
 *   - Boot grace: 5 minutes from `start()`. Failures during this window
 *     are silently retried (slow-starting addons must have a chance to
 *     come up before alarming).
 *   - Retry cadence: 60s after first failure, 120s after second, then
 *     300s for every subsequent attempt — never gives up.
 *   - Tick interval: 30s. Faster than the shortest retry interval (60s)
 *     so a scheduled retry never waits more than ~30s past its target.
 *   - Post-grace alerting: emits `AddonLoadFailed` exactly once per
 *     failure-streak; AlertCenter consumes the event to create a
 *     persistent operator-visible alert. Recovery emits
 *     `AddonLoadRecovered` so the alert can dismiss itself.
 *   - In-memory state only. Server restart resets the grace window
 *     (operator's call — they want a clean slate after a manual restart).
 *
 * The monitor never restarts addons itself: it knows nothing about
 * tarball install / dist paths / dependency injection. It calls a
 * caller-injected `retryFn(packageName)` which is the AddonRegistry's
 * existing reload path — the monitor is just the scheduler + alert
 * gate. This keeps the kernel package addon-agnostic.
 *
 * Group-runner / fork crashes: `process-service.ts` already respawns
 * crashed children with exponential backoff. The monitor doesn't
 * duplicate that loop — it only marks the addon `failed` when the
 * crash supervisor reports it (via `recordFailure`) and clears it on
 * `READY:<nodeId>` recovery (via `recordSuccess`). The kernel's
 * spawn handler wires both edges.
 */
export declare const HEALTH_MONITOR_TICK_MS = 30000;
export declare const HEALTH_MONITOR_GRACE_PERIOD_MS: number;
/** Retry intervals after each failure (capped — never stops). */
export declare const HEALTH_MONITOR_RETRY_INTERVALS_MS: readonly number[];
export type AddonHealthPhase = 'pending' | 'healthy' | 'failed';
export interface AddonHealthState {
    readonly packageName: string;
    readonly addonId?: string;
    phase: AddonHealthPhase;
    retryCount: number;
    firstFailureAt: number | null;
    lastAttemptAt: number | null;
    lastError: {
        readonly message: string;
        readonly stack?: string;
    } | null;
    nextRetryAt: number | null;
    /** True once `AddonLoadFailed` has been emitted for the current streak. */
    alertEmitted: boolean;
    /** True if a retry attempt is currently in flight. */
    retrying: boolean;
}
export interface AddonHealthSnapshot {
    readonly packageName: string;
    readonly addonId?: string;
    readonly phase: AddonHealthPhase;
    readonly retryCount: number;
    readonly firstFailureAt: number | null;
    readonly lastAttemptAt: number | null;
    readonly lastError: {
        readonly message: string;
        readonly stack?: string;
    } | null;
    readonly nextRetryAt: number | null;
    readonly alertEmitted: boolean;
    readonly retrying: boolean;
    /** Whether the boot grace window is still open (suppresses alerts). */
    readonly inGracePeriod: boolean;
}
export interface AddonHealthMonitorOptions {
    readonly eventBus: IEventBus;
    readonly logger: IScopedLogger;
    /**
     * Called by the monitor's tick loop when a failed package is due
     * for a retry attempt. Should perform the actual reload (tarball
     * extract + addon-loader re-import + initialize). Returns true on
     * success; throws on failure (the monitor records the new error).
     */
    readonly retryFn: (packageName: string) => Promise<void>;
    /** Override for tests. Defaults to `HEALTH_MONITOR_TICK_MS`. */
    readonly tickIntervalMs?: number;
    /** Override for tests. Defaults to `HEALTH_MONITOR_GRACE_PERIOD_MS`. */
    readonly gracePeriodMs?: number;
    /** Override for tests. Defaults to `HEALTH_MONITOR_RETRY_INTERVALS_MS`. */
    readonly retryIntervalsMs?: readonly number[];
    /** Override clock for deterministic tests. */
    readonly now?: () => number;
}
export declare class AddonHealthMonitor {
    private readonly state;
    private readonly bootAt;
    private readonly tickIntervalMs;
    private readonly gracePeriodMs;
    private readonly retryIntervalsMs;
    private readonly eventBus;
    private readonly logger;
    private readonly retryFn;
    private readonly now;
    private timer;
    private graceEmittedFor;
    constructor(opts: AddonHealthMonitorOptions);
    /** True while we're still inside the post-boot grace window. */
    inGracePeriod(): boolean;
    /**
     * Record a successful load/init/recovery for a package. Clears any
     * existing failure state and emits `AddonLoadRecovered` if the
     * package was previously in `failed` state with an alert emitted.
     */
    recordSuccess(packageName: string, addonId?: string): void;
    /**
     * Record a load/init/crash failure. Schedules the next retry per
     * `retryIntervalsMs` and (post-grace) emits `AddonLoadFailed` if
     * this is the first alert for the current streak.
     */
    recordFailure(packageName: string, err: unknown, addonId?: string): void;
    /**
     * Force an immediate retry attempt for a package, resetting the
     * counter back to 0 (next failure goes to the 60s interval again).
     * Used by the user-facing `addons.retryLoad` tRPC procedure and by
     * the explicit reinstall path.
     */
    retryNow(packageName: string): Promise<void>;
    /** Snapshot of all tracked packages (read-only, for tRPC list / UI). */
    getHealthSnapshot(): readonly AddonHealthSnapshot[];
    /** Get health for a single package (or null if unknown). */
    getHealth(packageName: string): AddonHealthSnapshot | null;
    /**
     * Drop tracking for a package (used on uninstall — we don't want
     * the monitor to keep retrying a package the user explicitly removed).
     */
    forget(packageName: string): void;
    /** Begin the retry tick loop. Idempotent. */
    start(): void;
    /** Stop the retry loop (cleanup on shutdown). */
    stop(): void;
    /**
     * Public for tests. Production callers go through `start()`.
     *
     * Each tick:
     *   1. If grace JUST ended on this tick, emit `AddonLoadFailed` for
     *      every package still in `failed` state that hasn't alerted yet.
     *   2. For every `failed` package whose `nextRetryAt` <= now, run
     *      `retryFn`. On success, recordSuccess; on failure, recordFailure
     *      (which recomputes the next interval).
     */
    tick(): Promise<void>;
    private attemptRetry;
    private emit;
}
//# sourceMappingURL=addon-health-monitor.d.ts.map