UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

173 lines (172 loc) 6.91 kB
import { l as normalizeStringEntries } from "./string-normalization-WNUDCpXX.js"; import { p as resolveUserPath } from "./utils-CCC-BEJH.js"; import { p as tryReadJsonSync } from "./json-files-2umMHm0W.js"; import { i as loadPluginManifest } from "./manifest-BcY4wyAU.js"; import { a as listOfficialExternalPluginCatalogEntries, c as resolveOfficialExternalPluginInstall, s as resolveOfficialExternalPluginId } from "./official-external-plugin-catalog-h7dZZiYs.js"; import { t as findBundledPluginSource } from "./bundled-sources-C3sNzxQs.js"; import { d as resolveFileNpmSpecToLocalPath, l as parseNpmPrefixSpec } from "./plugins-command-helpers-BMTwD7oF.js"; import fs from "node:fs"; import path from "node:path"; //#region src/cli/plugin-install-config-policy.ts function isPluginInstallCommand(commandPath) { return commandPath[0] === "plugins" && commandPath[1] === "install"; } function readBundledInstallRecoveryMetadata(rootDir) { const packageJsonPath = path.join(rootDir, "package.json"); if (!fs.existsSync(packageJsonPath)) return { allowInvalidConfigRecovery: false }; const manifest = loadPluginManifest(rootDir, false); const pluginId = manifest.ok ? manifest.manifest.id : void 0; const parsed = tryReadJsonSync(packageJsonPath); return { ...pluginId ? { pluginId } : {}, allowInvalidConfigRecovery: parsed?.openclaw?.install?.allowInvalidConfigRecovery === true }; } function resolveBundledInstallRecoveryMetadata(request) { if (request.marketplace) return {}; if (request.resolvedPath && fs.existsSync(path.join(request.resolvedPath, "package.json"))) { const direct = readBundledInstallRecoveryMetadata(request.resolvedPath); if (direct.pluginId || direct.allowInvalidConfigRecovery) return direct; } const rawNpmPrefixSpec = parseNpmPrefixSpec(request.rawSpec); const normalizedNpmPrefixSpec = parseNpmPrefixSpec(request.normalizedSpec); for (const value of [ request.rawSpec.trim(), request.normalizedSpec.trim(), rawNpmPrefixSpec ?? "", normalizedNpmPrefixSpec ?? "" ]) { if (!value) continue; const bundled = findBundledPluginSource({ lookup: { kind: "npmSpec", value } }); if (!bundled) continue; const recovered = readBundledInstallRecoveryMetadata(bundled.localPath); return { pluginId: recovered.pluginId ?? bundled.pluginId, allowInvalidConfigRecovery: recovered.allowInvalidConfigRecovery }; } return {}; } function resolveOfficialExternalInstallRecoveryMetadata(request) { if (request.marketplace) return {}; const rawNpmPrefixSpec = parseNpmPrefixSpec(request.rawSpec); const normalizedNpmPrefixSpec = parseNpmPrefixSpec(request.normalizedSpec); const values = new Set(normalizeStringEntries([ request.rawSpec, request.normalizedSpec, rawNpmPrefixSpec ?? "", normalizedNpmPrefixSpec ?? "" ])); if (values.size === 0) return {}; for (const entry of listOfficialExternalPluginCatalogEntries()) { const install = resolveOfficialExternalPluginInstall(entry); const npmSpec = install?.npmSpec?.trim() || entry.name?.trim(); if (!npmSpec || !values.has(npmSpec)) continue; const pluginId = resolveOfficialExternalPluginId(entry); return { ...pluginId ? { pluginId } : {}, allowInvalidConfigRecovery: install?.allowInvalidConfigRecovery === true }; } return {}; } function resolvePluginInstallArgvTokens(commandPath, argv) { const args = argv.slice(2); let cursor = 0; for (const segment of commandPath) { while (cursor < args.length && args[cursor] !== segment) cursor += 1; if (cursor >= args.length) return []; cursor += 1; } return args.slice(cursor); } function resolvePluginInstallArgvRequest(commandPath, argv) { if (!isPluginInstallCommand(commandPath)) return null; const tokens = resolvePluginInstallArgvTokens(commandPath, argv); let rawSpec = null; let marketplace; for (let index = 0; index < tokens.length; index += 1) { const token = tokens[index]; if (token.startsWith("--marketplace=")) { marketplace = token.slice(14); continue; } if (token === "--marketplace") { const value = tokens[index + 1]; if (typeof value === "string") { marketplace = value; index += 1; } continue; } if (token.startsWith("-")) continue; rawSpec ??= token; } return rawSpec ? { rawSpec, marketplace } : null; } /** Resolve install metadata from the raw spec before Commander action handlers mutate config. */ function resolvePluginInstallRequestContext(params) { if (params.marketplace) return { ok: true, request: { rawSpec: params.rawSpec, normalizedSpec: params.rawSpec, marketplace: params.marketplace } }; const fileSpec = resolveFileNpmSpecToLocalPath(params.rawSpec); if (fileSpec && !fileSpec.ok) return { ok: false, error: fileSpec.error }; const normalizedSpec = fileSpec && fileSpec.ok ? fileSpec.path : params.rawSpec; const bundledRecovered = resolveBundledInstallRecoveryMetadata({ rawSpec: params.rawSpec, normalizedSpec, resolvedPath: resolveUserPath(normalizedSpec), marketplace: params.marketplace }); const officialRecovered = resolveOfficialExternalInstallRecoveryMetadata({ rawSpec: params.rawSpec, normalizedSpec, marketplace: params.marketplace }); const recovered = officialRecovered.pluginId || officialRecovered.allowInvalidConfigRecovery !== void 0 ? officialRecovered : bundledRecovered; return { ok: true, request: { rawSpec: params.rawSpec, normalizedSpec, resolvedPath: resolveUserPath(normalizedSpec), ...recovered.pluginId ? { bundledPluginId: recovered.pluginId } : {}, ...recovered.allowInvalidConfigRecovery !== void 0 ? { allowInvalidConfigRecovery: recovered.allowInvalidConfigRecovery } : {} } }; } /** Recover the plugin install request from Commander state plus raw argv fallback parsing. */ function resolvePluginInstallPreactionRequest(params) { if (!isPluginInstallCommand(params.commandPath)) return null; const argvRequest = resolvePluginInstallArgvRequest(params.commandPath, params.argv); const opts = params.actionCommand.opts(); const marketplace = (typeof opts.marketplace === "string" && opts.marketplace.trim() ? opts.marketplace : argvRequest?.marketplace) || void 0; const rawSpec = (typeof params.actionCommand.processedArgs?.[0] === "string" ? params.actionCommand.processedArgs[0] : argvRequest?.rawSpec) ?? null; if (!rawSpec) return null; const request = resolvePluginInstallRequestContext({ rawSpec, marketplace }); return request.ok ? request.request : null; } /** Decide whether invalid config should block a command before plugin recovery can run. */ function resolvePluginInstallInvalidConfigPolicy(request) { if (!request) return "deny"; return request.allowInvalidConfigRecovery === true ? "allow-plugin-recovery" : "deny"; } //#endregion export { resolvePluginInstallPreactionRequest as n, resolvePluginInstallRequestContext as r, resolvePluginInstallInvalidConfigPolicy as t };