/** * Process-level shutdown handlers. * * OpenCode does not reliably await plugin `dispose()` before Node exits, and * host-level SIGTERM/SIGINT propagate to our `aft` children through the process * group. Without explicit cleanup, children see SIGTERM, their `exit` handler * fires, and (before the sibling fix in bridge.ts) they would auto-restart into * orphaned processes. Even with that fixed, we still want orderly shutdown so * pending requests get rejected and the bridges terminate before Node is gone. * * Each plugin instance (and there can be several per Node process when OpenCode * loads the plugin from multiple contexts) registers its cleanup callback here. * We install the OS-level signal handlers exactly once per Node process via a * `globalThis` guard — otherwise each plugin reload would stack another SIGTERM * listener and fire duplicate shutdowns. */ type Cleanup = () => Promise | void; export declare function runCleanups(reason: string): Promise; /** Conventional exit codes for fatal signals (128 + signal number). */ export declare const SIGNAL_EXIT_CODES: { readonly SIGINT: 130; readonly SIGTERM: 143; readonly SIGHUP: 129; }; /** * Decide whether AFT's handler must terminate the process after cleanup. * * Registering ANY listener for SIGINT/SIGTERM/SIGHUP disables Node/Bun's * default terminate-on-signal behavior. If AFT's listener is the only one, * the default was suppressed solely by us, so we must exit or the host hangs * forever (OpenCode serve + Desktop /event SSE hung on Ctrl-C until SIGKILL). * If the host or another plugin also listens, terminating is THEIR call — * forcing an exit here would race a host's graceful shutdown. */ export declare function shouldForceExit(otherListenerCount: number): boolean; /** * Register a shutdown cleanup. Call from plugin initialization; returned * function unregisters (use in `dispose` so plugin reloads don't leak). */ export declare function registerShutdownCleanup(fn: Cleanup): () => void; export {}; //# sourceMappingURL=shutdown-hooks.d.ts.map