fix: repair bundled plugin runtime deps on startup

This commit is contained in:
Peter Steinberger
2026-04-20 17:43:50 +01:00
parent 4e059035a9
commit 47d42606ac
12 changed files with 798 additions and 180 deletions

View File

@@ -30,6 +30,11 @@ import {
import { resolveUserPath } from "../utils.js";
import { buildPluginApi } from "./api-builder.js";
import { inspectBundleMcpRuntimeSupport } from "./bundle-mcp.js";
import {
ensureBundledPluginRuntimeDeps,
resolveBundledRuntimeDependencyInstallRoot,
type BundledRuntimeDepsInstallParams,
} from "./bundled-runtime-deps.js";
import { clearPluginCommands } from "./command-registry-state.js";
import {
clearCompactionProviders,
@@ -136,6 +141,7 @@ export type PluginLoadOptions = {
activate?: boolean;
loadModules?: boolean;
throwOnLoadError?: boolean;
bundledRuntimeDepsInstaller?: (params: BundledRuntimeDepsInstallParams) => void;
};
const CLI_METADATA_ENTRY_BASENAMES = [
@@ -1633,6 +1639,7 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
});
const seenIds = new Map<string, PluginRecord["origin"]>();
const bundledRuntimeDepsRetainSpecsByInstallRoot = new Map<string, string[]>();
const memorySlot = normalized.slots.memory;
let selectedMemoryPluginId: string | null = null;
let memorySlotMatched = false;
@@ -1731,9 +1738,40 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
message: record.error,
});
};
const pluginRoot = safeRealpathOrResolve(candidate.rootDir);
if (shouldLoadModules && candidate.origin === "bundled" && enableState.enabled) {
try {
const installRoot = resolveBundledRuntimeDependencyInstallRoot(pluginRoot);
const retainSpecs = bundledRuntimeDepsRetainSpecsByInstallRoot.get(installRoot) ?? [];
const installedSpecs = ensureBundledPluginRuntimeDeps({
pluginId: record.id,
pluginRoot,
env,
config: cfg,
retainSpecs,
installDeps: options.bundledRuntimeDepsInstaller,
});
if (installedSpecs.length > 0) {
bundledRuntimeDepsRetainSpecsByInstallRoot.set(
installRoot,
[...new Set([...retainSpecs, ...installedSpecs])].toSorted((left, right) =>
left.localeCompare(right),
),
);
logger.info(
`[plugins] ${record.id} installed bundled runtime deps: ${installedSpecs.join(", ")}`,
);
}
} catch (error) {
pushPluginLoadError(`failed to install bundled runtime deps: ${String(error)}`);
continue;
}
}
const registrationMode = enableState.enabled
? !validateOnly &&
? shouldLoadModules &&
!validateOnly &&
shouldLoadChannelPluginInSetupRuntime({
manifestChannels: manifestRecord.channels,
setupSource: manifestRecord.setupSource,
@@ -1904,7 +1942,6 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
continue;
}
const pluginRoot = safeRealpathOrResolve(candidate.rootDir);
const loadSource =
(registrationMode === "setup-only" || registrationMode === "setup-runtime") &&
manifestRecord.setupSource