diff --git a/scripts/lib/official-external-channel-catalog.json b/scripts/lib/official-external-channel-catalog.json index aed3f1bfd1f..97f1f5eef54 100644 --- a/scripts/lib/official-external-channel-catalog.json +++ b/scripts/lib/official-external-channel-catalog.json @@ -18,8 +18,9 @@ "order": 45 }, "install": { - "npmSpec": "@wecom/wecom-openclaw-plugin", - "defaultChoice": "npm" + "npmSpec": "@wecom/wecom-openclaw-plugin@2026.4.23", + "defaultChoice": "npm", + "expectedIntegrity": "sha512-bnzfdIEEu1/LFvcdyjaTkyxt27w6c7dqhkPezU62OWaqmcdFsUGR3T55USK/O9pIKsNcnL1Tnu1pqKYCWHFgWQ==" } } } diff --git a/src/channels/plugins/contracts/channel-catalog.contract.test.ts b/src/channels/plugins/contracts/channel-catalog.contract.test.ts index 8159ae77970..6240bf4121e 100644 --- a/src/channels/plugins/contracts/channel-catalog.contract.test.ts +++ b/src/channels/plugins/contracts/channel-catalog.contract.test.ts @@ -39,6 +39,6 @@ describeOfficialFallbackChannelCatalogContract({ describeChannelCatalogEntryContract({ channelId: "wecom", - npmSpec: "@wecom/wecom-openclaw-plugin", + npmSpec: "@wecom/wecom-openclaw-plugin@2026.4.23", alias: "wework", }); diff --git a/test/official-channel-catalog.test.ts b/test/official-channel-catalog.test.ts index 11286e31de6..c9e186381f0 100644 --- a/test/official-channel-catalog.test.ts +++ b/test/official-channel-catalog.test.ts @@ -6,6 +6,7 @@ import { OFFICIAL_CHANNEL_CATALOG_RELATIVE_PATH, writeOfficialChannelCatalog, } from "../scripts/write-official-channel-catalog.mjs"; +import { describePluginInstallSource } from "../src/plugins/install-source-info.js"; import { bundledPluginRoot } from "./helpers/bundled-plugin-paths.js"; import { cleanupTempDirs, makeTempRepoRoot, writeJsonFile } from "./helpers/temp-repo.js"; @@ -78,8 +79,10 @@ describe("buildOfficialChannelCatalog", () => { label: "WeCom", }), install: { - npmSpec: "@wecom/wecom-openclaw-plugin", + npmSpec: "@wecom/wecom-openclaw-plugin@2026.4.23", defaultChoice: "npm", + expectedIntegrity: + "sha512-bnzfdIEEu1/LFvcdyjaTkyxt27w6c7dqhkPezU62OWaqmcdFsUGR3T55USK/O9pIKsNcnL1Tnu1pqKYCWHFgWQ==", }, }), }), @@ -106,6 +109,20 @@ describe("buildOfficialChannelCatalog", () => { ); }); + it("keeps official external catalog npm sources exactly pinned", () => { + const repoRoot = makeRepoRoot("openclaw-official-channel-catalog-policy-"); + const entries = buildOfficialChannelCatalog({ repoRoot }).entries.filter( + (entry) => entry.source === "external", + ); + + expect(entries.length).toBeGreaterThan(0); + for (const entry of entries) { + const installSource = describePluginInstallSource(entry.openclaw?.install ?? {}); + expect(installSource.warnings).toEqual([]); + expect(installSource.npm?.pinState).toBe("exact-with-integrity"); + } + }); + it("writes the official catalog under dist", () => { const repoRoot = makeRepoRoot("openclaw-official-channel-catalog-write-"); writeJson(path.join(repoRoot, "extensions", "whatsapp", "package.json"), {