

















@@ -1054,6 +1054,7 @@ describe("plugins cli install", () => {
10541054const enabledCfg = createEnabledPluginConfig("discord");
1055105510561056loadConfig.mockReturnValue(cfg);
1057+findBundledPluginSourceMock.mockReturnValue(undefined);
10571058installPluginFromNpmSpec.mockResolvedValue(createNpmPluginInstallResult("discord"));
10581059enablePluginInConfig.mockReturnValue({ config: enabledCfg });
10591060recordPluginInstall.mockReturnValue(enabledCfg);
@@ -1070,11 +1071,60 @@ describe("plugins cli install", () => {
10701071expect(installPluginFromClawHub).not.toHaveBeenCalled();
10711072});
107210731074+it("uses bundled OpenClaw package specs instead of pinning stale managed npm overrides", async () => {
1075+const cfg = createEmptyPluginConfig();
1076+const enabledCfg = createEnabledPluginConfig("discord");
1077+const bundledPath = "/app/dist/extensions/discord";
1078+1079+loadConfig.mockReturnValue(cfg);
1080+findBundledPluginSourceMock.mockImplementation(
1081+({ lookup }: { lookup: { kind: "pluginId" | "npmSpec"; value: string } }) =>
1082+lookup.kind === "npmSpec" && lookup.value === "@openclaw/discord"
1083+ ? {
1084+pluginId: "discord",
1085+localPath: bundledPath,
1086+npmSpec: "@openclaw/discord",
1087+version: "2026.5.24-beta.2",
1088+}
1089+ : undefined,
1090+);
1091+enablePluginInConfig.mockReturnValue({ config: enabledCfg });
1092+recordPluginInstall.mockReturnValue(enabledCfg);
1093+applyExclusiveSlotSelection.mockReturnValue({
1094+config: enabledCfg,
1095+warnings: [],
1096+});
1097+1098+await runPluginsCommand([
1099+"plugins",
1100+"install",
1101+"@openclaw/discord@2026.5.20",
1102+"--pin",
1103+"--force",
1104+]);
1105+1106+expect(installPluginFromNpmSpec).not.toHaveBeenCalled();
1107+expect(findBundledPluginSourceMock).toHaveBeenCalledWith({
1108+lookup: { kind: "npmSpec", value: "@openclaw/discord@2026.5.20" },
1109+});
1110+expect(findBundledPluginSourceMock).toHaveBeenCalledWith({
1111+lookup: { kind: "npmSpec", value: "@openclaw/discord" },
1112+});
1113+const record = persistedInstallRecord("discord");
1114+expect(record.source).toBe("path");
1115+expect(record.spec).toBe("@openclaw/discord@2026.5.20");
1116+expect(record.sourcePath).toBe(bundledPath);
1117+expect(record.installPath).toBe(bundledPath);
1118+expect(runtimeLogsContain("ships with the current OpenClaw build")).toBe(true);
1119+expect(runtimeLogsContain("npm:@openclaw/discord@2026.5.20")).toBe(true);
1120+});
1121+10731122it("marks catalog npm package installs with alternate selectors as trusted", async () => {
10741123const cfg = createEmptyPluginConfig();
10751124const enabledCfg = createEnabledPluginConfig("wecom-openclaw-plugin");
1076112510771126loadConfig.mockReturnValue(cfg);
1127+findBundledPluginSourceMock.mockReturnValue(undefined);
10781128installPluginFromNpmSpec.mockResolvedValue(
10791129createNpmPluginInstallResult("wecom-openclaw-plugin"),
10801130);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。