





























@@ -1,6 +1,7 @@
11import fs from "node:fs";
22import os from "node:os";
33import path from "node:path";
4+import { pathToFileURL } from "node:url";
45import { importFreshModule } from "openclaw/plugin-sdk/test-fixtures";
56import { afterEach, describe, expect, it, vi } from "vitest";
67import { loadPluginManifestRegistry } from "../../plugins/manifest-registry.js";
@@ -651,6 +652,102 @@ describe("bundled channel entry shape guards", () => {
651652}
652653});
653654655+it("does not load bundled runtime entries through external staged runtime deps during discovery", async () => {
656+const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-runtime-deps-"));
657+const stageRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-stage-"));
658+const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
659+const previousPluginStageDir = process.env.OPENCLAW_PLUGIN_STAGE_DIR;
660+const pluginDir = path.join(root, "dist", "extensions", "alpha");
661+const testGlobal = globalThis as typeof globalThis & {
662+__bundledRuntimeDepMarker?: string;
663+};
664+fs.mkdirSync(pluginDir, { recursive: true });
665+fs.writeFileSync(
666+path.join(root, "package.json"),
667+JSON.stringify({ name: "openclaw", version: "2026.4.21" }),
668+"utf8",
669+);
670+fs.writeFileSync(
671+path.join(pluginDir, "package.json"),
672+JSON.stringify({
673+name: "@openclaw/alpha",
674+version: "2026.4.21",
675+type: "module",
676+dependencies: {
677+"alpha-runtime-dep": "1.0.0",
678+},
679+}),
680+"utf8",
681+);
682+fs.writeFileSync(
683+path.join(pluginDir, "plugin.js"),
684+[
685+"import { marker } from 'alpha-runtime-dep';",
686+"globalThis.__bundledRuntimeDepMarker = marker;",
687+"export default { id: 'alpha', meta: { label: marker }, config: {} };",
688+"",
689+].join("\n"),
690+"utf8",
691+);
692+fs.writeFileSync(
693+path.join(pluginDir, "index.js"),
694+[
695+`import { defineBundledChannelEntry } from ${JSON.stringify(pathToFileURL(path.resolve("src/plugin-sdk/channel-entry-contract.ts")).href)};`,
696+"export default defineBundledChannelEntry({",
697+" id: 'alpha',",
698+" name: 'Alpha',",
699+" description: 'Alpha',",
700+" importMetaUrl: import.meta.url,",
701+" plugin: { specifier: './plugin.js' },",
702+"});",
703+"",
704+].join("\n"),
705+"utf8",
706+);
707+708+process.env.OPENCLAW_PLUGIN_STAGE_DIR = stageRoot;
709+const { resolveBundledRuntimeDependencyInstallRoot } =
710+await import("../../plugins/bundled-runtime-deps.js");
711+const installRoot = resolveBundledRuntimeDependencyInstallRoot(pluginDir);
712+const depRoot = path.join(installRoot, "node_modules", "alpha-runtime-dep");
713+fs.mkdirSync(depRoot, { recursive: true });
714+fs.writeFileSync(
715+path.join(depRoot, "package.json"),
716+JSON.stringify({
717+name: "alpha-runtime-dep",
718+version: "1.0.0",
719+type: "module",
720+main: "index.js",
721+}),
722+"utf8",
723+);
724+fs.writeFileSync(path.join(depRoot, "index.js"), "export const marker = 'staged-alpha';\n");
725+726+mockAlphaDistExtensionRuntime();
727+728+try {
729+process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = path.join(root, "dist", "extensions");
730+731+const bundled = await importFreshModule<typeof import("./bundled.js")>(
732+import.meta.url,
733+"./bundled.js?scope=bundled-runtime-deps",
734+);
735+736+expect(bundled.getBundledChannelPlugin("alpha")).toBeUndefined();
737+expect(testGlobal.__bundledRuntimeDepMarker).toBeUndefined();
738+} finally {
739+restoreBundledPluginsDir(previousBundledPluginsDir);
740+if (previousPluginStageDir === undefined) {
741+delete process.env.OPENCLAW_PLUGIN_STAGE_DIR;
742+} else {
743+process.env.OPENCLAW_PLUGIN_STAGE_DIR = previousPluginStageDir;
744+}
745+fs.rmSync(root, { recursive: true, force: true });
746+fs.rmSync(stageRoot, { recursive: true, force: true });
747+delete testGlobal.__bundledRuntimeDepMarker;
748+}
749+});
750+654751it("swallows and caches bundled plugin and setup load failures", async () => {
655752const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-load-failure-"));
656753const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。