/**
 * ChannelLifecycleSupervisor — owns the start/stop/restart state machine for
 * every channel plugin.
 *
 * Concerns:
 *   - `initialize()` — call each plugin's `init(...)` once and remember success
 *   - Two-phase `start()` + `startDeferredConnects()` for channels whose
 *     `meta.deferConnectUntilAfterListen` is true (HTTP listener has to be up
 *     before they dial out)
 *   - Per-channel manual stop / start (UI-driven; suppresses auto-restart)
 *   - Exponential restart backoff via {@link CHANNEL_RESTART_POLICY}
 *   - Soft restart (called from heartbeat) — stop + startPlugin, manual-stop guarded
 *
 * Heartbeat probes themselves live in {@link ChannelHeartbeatScheduler}; this
 * supervisor schedules them via `onPluginStarted` / `onPluginStopped` callbacks
 * passed in by the caller.
 *
 * Extracted from `ChannelManager` so the manager can be a thin composition root.
 */
import type { Config } from '../config/schema.js';
import type { MessageBus } from '../infra/bus/index.js';
import type { ChannelPlugin, ChannelPluginSessionModelHooks } from './plugin-types.js';
import type { ChannelPluginRegistry } from './plugin-registry.js';
export interface ChannelLifecycleSupervisorOptions {
    bus: MessageBus;
    registry: ChannelPluginRegistry;
    /** Effective config snapshot (per-channel `channels.<id>.*`). */
    getConfig: () => Config;
    /** Hooks for sub-classes / external observers: heartbeat scheduling, etc. */
    onPluginStarted?: (plugin: ChannelPlugin) => void;
    onPluginStopped?: (pluginId: string) => void;
    /** Optional session-model hooks forwarded into `plugin.init()`. */
    getSessionModelHooks?: () => ChannelPluginSessionModelHooks | undefined;
}
export declare class ChannelLifecycleSupervisor {
    private readonly opts;
    /** Plugin ids whose `init()` completed (used by start/stop loops). */
    private readonly initializedPluginIds;
    private readonly restartAttempts;
    /** When set, failed-start auto-restart is suppressed for that channel id. */
    private readonly manuallyStopped;
    /** Plugins that skipped `start()` until `startDeferredConnects()`. */
    private readonly deferredConnectPending;
    private initialized;
    private running;
    constructor(opts: ChannelLifecycleSupervisorOptions);
    isInitialized(pluginId: string): boolean;
    snapshot(): {
        initialized: boolean;
        running: boolean;
        initializedPluginIds: string[];
        manuallyStopped: string[];
        restartAttempts: Record<string, number>;
    };
    /** Channel ids that would run and declare `meta.deferConnectUntilAfterListen` (for logging / metrics). */
    listDeferConnectChannelIds(cfg: Config): string[];
    initialize(): Promise<void>;
    /** Phase 1: start every enabled channel except those in `deferConnectPluginIds`. */
    start(options?: {
        deferConnectPluginIds?: ReadonlySet<string>;
    }): Promise<void>;
    /** Phase 2: `start()` for channels deferred at Phase 1. No-op if none pending. */
    startDeferredConnects(): Promise<void>;
    stop(): Promise<void>;
    /** Stop one channel and suppress automatic restart until `startChannel` is called. */
    stopChannel(channelId: string): Promise<void>;
    /** Clear manual-stop and start one channel (requires prior `initialize()`). */
    startChannel(channelId: string): Promise<void>;
    /** Called by heartbeat: stop + start without clearing manualStop. No-op if user stopped it. */
    softRestart(channelId: string): Promise<void>;
    /** Forward a config snapshot to every initialised plugin's `onConfigUpdated` hook. */
    forwardConfigUpdate(cfg: Config): Promise<void>;
    /**
     * Builtin channels require `channels.<id>.enabled`. Extension-managed channels
     * run unless explicitly disabled.
     */
    private shouldRunChannelPlugin;
    private initializePlugin;
    private startPlugin;
    private stopPlugin;
}
