UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

142 lines (141 loc) 5.65 kB
import { i as getRuntimeConfig, u as readConfigFileSnapshot } from "./io-Gi7-pyU-.js"; import "./config-C9RxTsn1.js"; import { a as registerLazyCommandGroup, n as getCommandGroupNames, o as removeCommandGroupNames, t as findCommandGroupEntry } from "./register-command-groups-DKyoKsjD.js"; import { o as loadPluginCliRegistrationEntriesWithDefaults, r as loadPluginCliDescriptors, t as createPluginCliLogger } from "./cli-registry-loader-Bg_pYpki.js"; //#region src/plugins/register-plugin-cli-command-groups.ts function canRegisterPluginCliLazily(entry) { if (entry.placeholders.length === 0) return false; const descriptorNames = new Set(entry.placeholders.map((descriptor) => descriptor.name)); return getCommandGroupNames(entry).every((command) => descriptorNames.has(command)); } function findCommandByPath(program, path) { let current = program; for (const segment of path) { const next = current.commands.find((command) => command.name() === segment || command.aliases().includes(segment)); if (!next) return null; current = next; } return current; } function commandNamesFor(program) { return new Set(program.commands.flatMap((command) => [command.name(), ...command.aliases()])); } async function registerPluginCliCommandGroups(program, entries, params) { for (const entry of entries) { const parentPath = entry.parentPath ?? []; const targetProgram = findCommandByPath(program, parentPath); if (!targetProgram) { params.logger.debug?.(`plugin CLI register skipped (${entry.pluginId}): parent command missing (${parentPath.join(" ")})`); continue; } const existingCommands = parentPath.length === 0 ? params.existingCommands : commandNamesFor(targetProgram); const registerEntry = async () => { await entry.register(targetProgram); for (const command of getCommandGroupNames(entry)) existingCommands.add(command); }; if (params.primary && (parentPath[0] === params.primary || findCommandGroupEntry([entry], params.primary))) { removeCommandGroupNames(targetProgram, entry); await registerEntry(); continue; } const overlaps = getCommandGroupNames(entry).filter((command) => existingCommands.has(command)); if (overlaps.length > 0) { params.logger.debug?.(`plugin CLI register skipped (${entry.pluginId}): command already registered (${overlaps.join(", ")})`); continue; } try { if (params.mode === "lazy" && canRegisterPluginCliLazily(entry)) { for (const placeholder of entry.placeholders) registerLazyCommandGroup(targetProgram, entry, placeholder); continue; } if (params.mode === "lazy" && entry.placeholders.length > 0) params.logger.debug?.(`plugin CLI lazy register fallback to eager (${entry.pluginId}): descriptors do not cover all command roots`); await registerEntry(); } catch (error) { params.logger.warn(`plugin CLI register failed (${entry.pluginId}): ${String(error)}`); } } } //#endregion //#region src/plugins/cli.ts const PLUGIN_CLI_ENTRIES_CACHE_KEY = Symbol.for("openclaw.plugin-cli-registration-entries-cache"); const logger = createPluginCliLogger(); const loaderOptionIds = /* @__PURE__ */ new WeakMap(); let nextLoaderOptionId = 1; const quietDescriptorLogger = { info: () => {}, warn: () => {}, error: () => {}, debug: () => {} }; function stableJsonKey(value) { if (value === void 0) return "undefined"; try { return JSON.stringify(value, (_key, entry) => { if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry; return Object.fromEntries(Object.entries(entry).toSorted(([left], [right]) => left.localeCompare(right))); }); } catch { return "unserializable"; } } function loaderOptionsKey(loaderOptions) { if (!loaderOptions) return "undefined"; const existing = loaderOptionIds.get(loaderOptions); if (existing) return String(existing); const id = nextLoaderOptionId; nextLoaderOptionId += 1; loaderOptionIds.set(loaderOptions, id); return String(id); } const loadValidatedConfigForPluginRegistration = async () => { if (!(await readConfigFileSnapshot()).valid) return null; return getRuntimeConfig(); }; async function getPluginCliCommandDescriptors(cfg, env, loaderOptions) { return loadPluginCliDescriptors({ cfg, env, loaderOptions, logger: quietDescriptorLogger }); } async function registerPluginCliCommands(program, cfg, env, loaderOptions, options) { const mode = options?.mode ?? "eager"; const primary = options?.primary ?? void 0; const inputKey = [ stableJsonKey(cfg), stableJsonKey(env), loaderOptionsKey(loaderOptions) ].join("\0"); const programWithCache = program; const cached = programWithCache[PLUGIN_CLI_ENTRIES_CACHE_KEY]; let entries; if (cached && cached.primary === primary && cached.inputKey === inputKey) entries = cached.entries; else { entries = await loadPluginCliRegistrationEntriesWithDefaults({ cfg, env, loaderOptions, primaryCommand: primary }); programWithCache[PLUGIN_CLI_ENTRIES_CACHE_KEY] = { primary, inputKey, entries }; } await registerPluginCliCommandGroups(program, entries, { mode, primary, existingCommands: new Set(program.commands.map((cmd) => cmd.name())), logger }); } async function registerPluginCliCommandsFromValidatedConfig(program, env, loaderOptions, options) { const config = await loadValidatedConfigForPluginRegistration(); if (!config) return null; await registerPluginCliCommands(program, config, env, loaderOptions, options); return config; } //#endregion export { registerPluginCliCommandsFromValidatedConfig as i, loadValidatedConfigForPluginRegistration as n, registerPluginCliCommands as r, getPluginCliCommandDescriptors as t };