UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

155 lines (154 loc) • 9.15 kB
import { k as withPluginCache, s as createPluginCache } from "./plugin-cache-CfBhQFSN.mjs"; import { r as isPathInside } from "./path-guards-CH7noY0Z.mjs"; import { n as isArtifactPreservingStateRead } from "./artifact-preserving-state-reads-BQnQLAJR.mjs"; import { a as resolveUpdateRehearsalRoot } from "./update-rehearsal-paths-FgHeU_TR.mjs"; import { r as cloneEnvWithPlatformSemantics } from "./config-env-vars-BzUE_dOh.mjs"; import { f as withOpenClawStateDatabaseReadSnapshot } from "./openclaw-state-db-readonly-ywwvuxdQ.mjs"; import { l as createBlockedPluginDiagnosticLookup } from "./discovery-D42cUZXk.mjs"; import { u as normalizePluginsConfig } from "./config-state-Ba1MVBAI.mjs"; import { t as resolvePluginDoctorContractArtifact } from "./doctor-contract-artifact-CYaLHhX6.mjs"; import { r as getOfficialExternalPluginCatalogEntry } from "./official-external-plugin-catalog-BKfROutK.mjs"; import { n as resolveInstalledPluginIndexStateDatabaseOptions } from "./installed-plugin-index-store-path-CUbUiRdU.mjs"; import { g as resolveOfficialExternalPluginId } from "./official-external-plugin-catalog-source-8hS3NARf.mjs"; import { n as isTrustedOfficialCatalogLookupDuplicate } from "./official-external-install-records-CLRWqPnV.mjs"; import { l as withPluginMetadataSnapshotScope } from "./current-plugin-metadata-snapshot-DpeEPkbV.mjs"; import { r as resolveConfigWidePluginMetadataSnapshot } from "./io.plugin-metadata-MbATaIAW.mjs"; import { i as passesManifestOwnerBasePolicy } from "./manifest-owner-policy-Cqbh_mxQ.mjs"; import { o as resolveDeferredPluginMigrationConfigPaths } from "./deferred-plugin-migration-config-CohVpj3v.mjs"; import { c as loadManifestMetadataSnapshot } from "./manifest-contract-eligibility-P_yAPTzd.mjs"; import { t as createInstalledPluginIndexScopeLookup } from "./installed-plugin-index-scope-lookup-zVHC9Dq8.mjs"; import { n as isPayloadMissing } from "./payload-verification-DvsDjVkq.mjs"; import { a as collectConfiguredChannelIds, i as collectBlockedPluginIds, n as collectUpdateDeferredPluginIds, o as collectConfiguredPluginIds, r as resolveConfiguredPluginInstallContext } from "./missing-configured-plugin-install.candidates-qmENeuGS.mjs"; import { n as collectConfiguredRuntimeIds } from "./configured-runtime-plugin-installs-BKipzX1E.mjs"; //#region src/commands/doctor/shared/plugin-migration-availability.ts /** Inspect the selected package generation without importing its Doctor contract. */ async function inspectPluginMigrationAvailability(params) { const artifactPreserving = isArtifactPreservingStateRead(); const env = artifactPreserving ? cloneEnvWithPlatformSemantics(params.env) : params.env; const rehearsalRoot = resolveUpdateRehearsalRoot(env); const inspect = () => withPluginCache(createPluginCache(), async () => { const metadata = params.installRecords !== void 0 ? resolveConfigWidePluginMetadataSnapshot({ config: params.cfg, env, installRecords: params.installRecords, allowCurrent: false }) : loadManifestMetadataSnapshot({ config: params.cfg, env }); return withPluginMetadataSnapshotScope(metadata, async () => { const configuredPluginIds = collectConfiguredPluginIds(params.cfg, env); const configuredChannelIds = collectConfiguredChannelIds(params.cfg, env); const blockedPluginIds = collectBlockedPluginIds(params.cfg); const context = await resolveConfiguredPluginInstallContext({ cfg: params.cfg, env, configuredPluginIds, configuredChannelIds, blockedPluginIds, baselineRecords: params.installRecords }); const selected = collectUpdateDeferredPluginIds({ cfg: params.cfg, env, configuredPluginIds, configuredChannelIds, configuredChannelOwnerPluginIds: context.configuredChannelOwnerPluginIds, blockedPluginIds }); const findBlockedPluginDiagnostic = createBlockedPluginDiagnosticLookup({ diagnostics: metadata.diagnostics, config: params.cfg, env }); const inspectedIds = /* @__PURE__ */ new Set([...selected, ...params.retainedPluginIds ?? []]); const requiredPluginIds = []; const inspectionRequiredPluginIds = []; const statelessCandidates = /* @__PURE__ */ new Set(); for (const plugin of metadata.plugins) { if (!inspectedIds.has(plugin.id)) continue; const declaration = plugin.doctorContract?.stateMigrations; const artifact = resolvePluginDoctorContractArtifact(plugin); const legacySetup = declaration !== true && !Array.isArray(declaration) && plugin.origin !== "bundled" && plugin.channels.length > 0 && plugin.setupSource; if (declaration === true || Array.isArray(declaration) && declaration.length > 0) requiredPluginIds.push(plugin.id); else if (legacySetup || artifact && (!plugin.doctorContract || Array.isArray(declaration))) inspectionRequiredPluginIds.push(plugin.id); else statelessCandidates.add(plugin.id); } const requiredIds = new Set(requiredPluginIds); const inspectionRequiredIds = new Set(inspectionRequiredPluginIds); const statelessPlugins = []; const unavailablePluginIds = []; const discoveryBlockedPluginIds = []; const normalizedConfig = normalizePluginsConfig(params.cfg.plugins); const pending = [...inspectedIds].toSorted().flatMap((pluginId) => { if (!passesManifestOwnerBasePolicy({ plugin: { id: pluginId }, normalizedConfig })) { unavailablePluginIds.push(pluginId); return []; } const plugin = metadata.plugins.find((candidate) => candidate.id === pluginId); const bundled = context.bundledPluginsById.has(pluginId); const blocked = plugin ? void 0 : findBlockedPluginDiagnostic(pluginId); if (blocked) discoveryBlockedPluginIds.push(pluginId); const unavailable = Boolean(blocked) || !context.knownIds.has(pluginId) || Object.hasOwn(context.records, pluginId) && isPayloadMissing(env, context.records[pluginId]?.installPath) || context.installedPluginIdsWithRepairablePackages.has(pluginId) || context.configuredPluginIdsWithStaleDescriptors.has(pluginId); if (unavailable || !plugin) unavailablePluginIds.push(pluginId); const available = bundled && !blocked || plugin?.origin === "config" && rehearsalRoot !== void 0 && isPathInside(rehearsalRoot, plugin.rootDir) && !unavailable || !params.deferInstallation && !unavailable; if (available && plugin && statelessCandidates.has(pluginId)) statelessPlugins.push({ id: pluginId, version: plugin.packageVersion ?? plugin.version }); if (!selected.has(pluginId) || available) return []; return [{ pluginId, ...requiredIds.has(pluginId) ? { requiresStateMigration: true } : {}, ...inspectionRequiredIds.has(pluginId) ? { requiresDoctorInspection: true } : {}, ...resolveDeferredPluginMigrationConfigPaths({ config: params.cfg, pluginId, compatibilityMigrationPaths: plugin?.configContracts?.compatibilityMigrationPaths }), reason: blocked ? "The configured plugin is present but blocked. Fix the blocked plugin path before retrying its data/settings upgrade." : params.deferInstallation ? "Package convergence must wait until the updating parent releases its install records." : "The configured plugin package is missing or has not converged.", command: blocked ? "openclaw doctor --fix" : "openclaw update repair" }]; }); const lookup = createInstalledPluginIndexScopeLookup(metadata.index); const replacementPluginIds = {}; for (const pluginId of unavailablePluginIds) { const entry = getOfficialExternalPluginCatalogEntry(pluginId); const replacementPluginId = entry && resolveOfficialExternalPluginId(entry); if (replacementPluginId && metadata.plugins.some((plugin) => plugin.id === replacementPluginId && plugin.trustedOfficialInstall === true) && isTrustedOfficialCatalogLookupDuplicate({ pluginId, replacementPluginId, replacementRecord: context.records[replacementPluginId] })) replacementPluginIds[pluginId] = replacementPluginId; } const statelessIds = new Set(statelessPlugins.map((plugin) => plugin.id)); const runtimePluginAliases = collectConfiguredRuntimeIds(params.cfg).filter((runtime) => { if (selected.has(runtime) || lookup.hasInstalledPluginIds([runtime]) || Object.hasOwn(context.records, runtime) || Object.hasOwn(params.cfg.plugins?.entries ?? {}, runtime)) return false; const owners = /* @__PURE__ */ new Set(); lookup.addAgentHarnessOwners(owners, [runtime]); return owners.size > 0 && [...owners].every((owner) => statelessIds.has(owner)); }); return { pending, requiredPluginIds: requiredPluginIds.toSorted(), inspectionRequiredPluginIds: inspectionRequiredPluginIds.toSorted(), statelessPlugins, runtimePluginAliases, discoveryBlockedPluginIds, ...!params.deferInstallation ? { unavailablePluginIds, replacementPluginIds } : {} }; }, { config: params.cfg, env }); }); return artifactPreserving ? withOpenClawStateDatabaseReadSnapshot(inspect, resolveInstalledPluginIndexStateDatabaseOptions({ env })) : inspect(); } //#endregion export { inspectPluginMigrationAvailability as t };