| |
| |
| |
| |
| |
| |
|
|
| import { createSubsystemLogger } from "../logging/subsystem.js"; |
| import { createHookRunner, type HookRunner } from "./hooks.js"; |
| import type { PluginRegistry } from "./registry.js"; |
| import type { PluginHookGatewayContext, PluginHookGatewayStopEvent } from "./types.js"; |
|
|
| const log = createSubsystemLogger("plugins"); |
|
|
| type HookRunnerGlobalState = { |
| hookRunner: HookRunner | null; |
| registry: PluginRegistry | null; |
| }; |
|
|
| const hookRunnerGlobalStateKey = Symbol.for("openclaw.plugins.hook-runner-global-state"); |
|
|
| function getHookRunnerGlobalState(): HookRunnerGlobalState { |
| const globalStore = globalThis as typeof globalThis & { |
| [hookRunnerGlobalStateKey]?: HookRunnerGlobalState; |
| }; |
| return (globalStore[hookRunnerGlobalStateKey] ??= { |
| hookRunner: null, |
| registry: null, |
| }); |
| } |
|
|
| |
| |
| |
| |
| export function initializeGlobalHookRunner(registry: PluginRegistry): void { |
| const state = getHookRunnerGlobalState(); |
| state.registry = registry; |
| state.hookRunner = createHookRunner(registry, { |
| logger: { |
| debug: (msg) => log.debug(msg), |
| warn: (msg) => log.warn(msg), |
| error: (msg) => log.error(msg), |
| }, |
| catchErrors: true, |
| }); |
|
|
| const hookCount = registry.hooks.length; |
| if (hookCount > 0) { |
| log.info(`hook runner initialized with ${hookCount} registered hooks`); |
| } |
| } |
|
|
| |
| |
| |
| |
| export function getGlobalHookRunner(): HookRunner | null { |
| return getHookRunnerGlobalState().hookRunner; |
| } |
|
|
| |
| |
| |
| |
| export function getGlobalPluginRegistry(): PluginRegistry | null { |
| return getHookRunnerGlobalState().registry; |
| } |
|
|
| |
| |
| |
| export function hasGlobalHooks(hookName: Parameters<HookRunner["hasHooks"]>[0]): boolean { |
| return getHookRunnerGlobalState().hookRunner?.hasHooks(hookName) ?? false; |
| } |
|
|
| export async function runGlobalGatewayStopSafely(params: { |
| event: PluginHookGatewayStopEvent; |
| ctx: PluginHookGatewayContext; |
| onError?: (err: unknown) => void; |
| }): Promise<void> { |
| const hookRunner = getGlobalHookRunner(); |
| if (!hookRunner?.hasHooks("gateway_stop")) { |
| return; |
| } |
| try { |
| await hookRunner.runGatewayStop(params.event, params.ctx); |
| } catch (err) { |
| if (params.onError) { |
| params.onError(err); |
| return; |
| } |
| log.warn(`gateway_stop hook failed: ${String(err)}`); |
| } |
| } |
|
|
| |
| |
| |
| export function resetGlobalHookRunner(): void { |
| const state = getHookRunnerGlobalState(); |
| state.hookRunner = null; |
| state.registry = null; |
| } |
|
|