UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

127 lines (126 loc) 5.58 kB
import { l as normalizePluginsConfig, u as resolveEffectiveEnableState } from "./config-state-BkU1frVq.js"; import { c as resolveOpenClawReleaseCohortVersion, o as parseRegistryNpmSpec } from "./npm-registry-spec-CM_p1_uq.js"; import { t as parseClawHubPluginSpec } from "./clawhub-spec-Er3Np6VI.js"; import { l as resolveTrustedSourceLinkedOfficialNpmSpec, o as resolveTrustedSourceLinkedOfficialClawHubInstall } from "./official-external-install-records-DClkub0e.js"; import { t as fetchNpmPackageTargetStatus } from "./update-check-package-target-Dqu75aaM.js"; //#region src/plugins/plugin-version-drift.ts function resolveExactNpmPinPackageName(entry) { if (entry.source !== "npm" || !entry.spec) return; const parsed = parseRegistryNpmSpec(entry.spec); if (parsed?.selectorKind !== "exact-version") return; return parsed.name; } /** Exact npm pins need a registry-confirmed package@version target; id-only updates preserve pins. */ function resolvePluginVersionDriftUpdateCommand(entry) { const exactNpmPackageName = resolveExactNpmPinPackageName(entry); if (exactNpmPackageName) { if (entry.targetResolution?.status !== "resolved" || entry.targetResolution.packageName !== exactNpmPackageName || entry.targetResolution.requestedTarget !== resolveOpenClawReleaseCohortVersion(entry.gatewayVersion)) return; const exactNpmTarget = `${exactNpmPackageName}@${entry.targetResolution.version}`; if (parseRegistryNpmSpec(exactNpmTarget)?.selectorKind === "exact-version") return `openclaw plugins update ${exactNpmTarget}`; return; } return `openclaw plugins update ${entry.pluginId}`; } async function resolveEntryTarget(entry) { const packageName = resolveExactNpmPinPackageName(entry); if (!packageName) return entry; const requestedTarget = resolveOpenClawReleaseCohortVersion(entry.gatewayVersion); const requestedSpec = `${packageName}@${requestedTarget}`; const result = parseRegistryNpmSpec(requestedSpec)?.selectorKind === "exact-version" ? await fetchNpmPackageTargetStatus({ packageName, target: requestedTarget }) : { version: null, error: "gateway release cohort is not an exact npm version" }; const targetResolution = result.version === requestedTarget ? { status: "resolved", packageName, requestedTarget, version: requestedTarget } : { status: "unresolved", packageName, requestedTarget, error: `npm registry did not resolve ${requestedSpec}: ${result.error ?? `returned ${JSON.stringify(result.version)}`}` }; return { ...entry, targetResolution }; } /** Resolve exact npm repair targets only for diagnostics that display repair guidance. */ async function resolvePluginVersionDriftTargets(report) { return { ...report, drifts: await Promise.all(report.drifts.map(resolveEntryTarget)) }; } function isPluginEnabled(config, pluginId) { const normalizedPluginConfig = normalizePluginsConfig(config?.plugins); return resolveEffectiveEnableState({ id: pluginId, origin: "global", config: normalizedPluginConfig, rootConfig: config }).enabled; } function shouldCompareOfficialInstallToGateway(params) { const officialNpmSpec = resolveTrustedSourceLinkedOfficialNpmSpec(params); if (officialNpmSpec) return parseRegistryNpmSpec(officialNpmSpec)?.selectorKind !== "exact-version"; const officialClawHubInstall = resolveTrustedSourceLinkedOfficialClawHubInstall(params); if (officialClawHubInstall) { if (officialClawHubInstall.clawhubSpec) return !parseClawHubPluginSpec(officialClawHubInstall.clawhubSpec)?.version; return parseRegistryNpmSpec(officialClawHubInstall.npmSpec ?? "")?.selectorKind !== "exact-version"; } return false; } function hasOfficialPluginVersionCandidates(params) { return Object.entries(params.installRecords).some(([pluginId, record]) => Boolean(record) && isPluginEnabled(params.config, pluginId) && shouldCompareOfficialInstallToGateway({ pluginId, record })); } /** * Compare active official external plugin installs against an OpenClaw host * version and return any mismatches. * * @param params.gatewayVersion The host version the plugins must match. * @param params.installRecords The full set of recorded plugin installs (as * produced by `loadInstalledPluginIndexInstallRecords`). * @param params.config The merged daemon-side OpenClawConfig (optional). * Plugins inactive under the effective activation policy are skipped. * * The returned `drifts` list is sorted by `pluginId` for stable output. */ function detectPluginVersionDrift(params) { const { gatewayVersion, installRecords, config } = params; const normalizedGateway = resolveOpenClawReleaseCohortVersion(gatewayVersion); const drifts = []; for (const [pluginId, record] of Object.entries(installRecords)) { if (!record) continue; if (!isPluginEnabled(config, pluginId)) continue; if (!shouldCompareOfficialInstallToGateway({ pluginId, record })) continue; const installedVersion = record.resolvedVersion ?? record.version; if (!installedVersion) continue; if (resolveOpenClawReleaseCohortVersion(installedVersion) === normalizedGateway) continue; drifts.push({ pluginId, installedVersion, gatewayVersion, source: record.source, ...record.resolvedName ? { packageName: record.resolvedName } : {}, ...record.spec ? { spec: record.spec } : {} }); } drifts.sort((a, b) => a.pluginId.localeCompare(b.pluginId)); return { gatewayVersion, drifts }; } //#endregion export { resolvePluginVersionDriftUpdateCommand as i, hasOfficialPluginVersionCandidates as n, resolvePluginVersionDriftTargets as r, detectPluginVersionDrift as t };