import type { JinnConfig } from "../shared/types.js"; import { type PluginServerContext, type PluginWatcher } from "./backend.js"; /** * The gateway's ownership of a plugin's background task. * * A plugin never starts or stops its own watcher: it exports one, and this * decides when it runs. Everything a third party's code can do to the process — * throw on start, fail an hour later, refuse to stop — is absorbed here, because * the gateway serves every other plugin and every session from the same process. */ /** How long `stop()` gets before the gateway stops waiting on it. Shutdown has * to finish whether or not a plugin cooperates. */ export declare const WATCHER_STOP_TIMEOUT_MS = 5000; /** The first wait after a crash. Each subsequent restart doubles it. */ export declare const WATCHER_RESTART_BASE_MS = 1000; /** Restarts before the supervisor gives up for good. Past this the watcher stays * down and its health says so: a watcher that silently quit is worse than one * that is visibly dead. */ export declare const WATCHER_MAX_RESTARTS = 5; /** The `ConnectorHealth` vocabulary (shared/types.ts), plus the restart count * that is the whole point of supervising. `qr_pending` has no meaning here. */ export interface PluginWatcherHealth { status: "running" | "stopped" | "error"; detail?: string; restarts: number; } /** One version of one plugin's watcher, as loaded from its server module. */ export interface PluginWatcherIncarnation { version: string; watcher: PluginWatcher; context: PluginServerContext; } /** Supervise this incarnation of a plugin's watcher. Starting the incarnation * that is already running is a no-op; a different one replaces it, old stopped * before new started. */ export declare function startPluginWatcher(id: string, incarnation: PluginWatcherIncarnation): Promise; /** Stop a plugin's watcher and forget it. Safe to call for a plugin that has none. */ export declare function stopPluginWatcher(id: string): Promise; /** Every watcher stopped, for gateway shutdown. One that hangs delays the others * by nothing: each carries its own deadline. */ export declare function stopAllPluginWatchers(): Promise; /** How a plugin's watcher is doing, or null when the gateway has never run one * for it — which is not the same as one that is stopped, and does not answer as * if it were. */ export declare function pluginWatcherHealth(id: string): PluginWatcherHealth | null; type PluginConfig = Pick; /** * Bring the running watchers in line with what `config.yaml` and the plugins * directory now say — the one entry point for boot, for a config reload and for * an edit on disk. * * Calls do not overlap. A request that arrives mid-pass sets a flag and the pass * repeats, because a reconcile racing itself would import one plugin twice and * leave two watchers under one id. The repeat does not survive a shutdown: what * that request wanted reconciled is exactly what shutdown just took down. */ export declare function reconcilePluginWatchers(getConfig: () => PluginConfig): Promise; export {}; //# sourceMappingURL=watcher-supervisor.d.ts.map