


























@@ -85,6 +85,17 @@ describe("parsePluginReleaseArgs", () => {
8585});
8686});
878788+function externalPluginContract(version: string) {
89+return {
90+compat: {
91+pluginApi: `>=${version}`,
92+},
93+build: {
94+openclawVersion: version,
95+},
96+};
97+}
98+8899describe("collectPublishablePluginPackageErrors", () => {
89100it("accepts a valid publishable plugin package candidate", () => {
90101expect(
@@ -100,6 +111,7 @@ describe("collectPublishablePluginPackageErrors", () => {
100111},
101112openclaw: {
102113extensions: ["./index.ts"],
114+ ...externalPluginContract("2026.3.15"),
103115install: {
104116npmSpec: "@openclaw/zalo",
105117},
@@ -123,6 +135,7 @@ describe("collectPublishablePluginPackageErrors", () => {
123135private: true,
124136openclaw: {
125137extensions: [""],
138+ ...externalPluginContract("2026.3.15"),
126139install: {
127140npmSpec: " ",
128141},
@@ -152,6 +165,7 @@ describe("collectPublishablePluginPackageErrors", () => {
152165version: "2026.5.1-beta.1",
153166openclaw: {
154167extensions: ["./index.ts"],
168+ ...externalPluginContract("2026.5.1-beta.1"),
155169install: {
156170npmSpec: "@openclaw/twitch",
157171},
@@ -180,6 +194,7 @@ describe("collectPublishablePluginPackageErrors", () => {
180194},
181195openclaw: {
182196extensions: ["./index.ts"],
197+ ...externalPluginContract("2026.5.1-beta.1"),
183198release: {
184199publishToNpm: true,
185200},
@@ -188,6 +203,35 @@ describe("collectPublishablePluginPackageErrors", () => {
188203}),
189204).toEqual(["openclaw.install.npmSpec must be a non-empty string for publishable plugins."]);
190205});
206+207+it("requires the external plugin package compatibility contract for npm publish", () => {
208+expect(
209+collectPublishablePluginPackageErrors({
210+extensionId: "voice-call",
211+packageDir: bundledPluginRoot("voice-call"),
212+packageJson: {
213+name: "@openclaw/voice-call",
214+version: "2026.5.1-beta.1",
215+repository: {
216+type: "git",
217+url: OPENCLAW_PLUGIN_NPM_REPOSITORY_URL,
218+},
219+openclaw: {
220+extensions: ["./index.ts"],
221+install: {
222+npmSpec: "@openclaw/voice-call",
223+},
224+release: {
225+publishToNpm: true,
226+},
227+},
228+},
229+}),
230+).toEqual([
231+"openclaw.compat.pluginApi is required for external code plugin packages.",
232+"openclaw.build.openclawVersion is required for external code plugin packages.",
233+]);
234+});
191235});
192236193237describe("collectPublishablePluginPackages", () => {
@@ -224,6 +268,7 @@ describe("collectPublishablePluginPackages", () => {
224268},
225269openclaw: {
226270extensions: ["./index.ts"],
271+ ...externalPluginContract("2026.4.10"),
227272install: {
228273npmSpec: "@openclaw/demo-plugin",
229274},
@@ -258,6 +303,7 @@ describe("collectPublishablePluginPackages", () => {
258303},
259304openclaw: {
260305extensions: ["./index.ts"],
306+ ...externalPluginContract("2026.4.10-beta.1"),
261307install: {
262308npmSpec: "@openclaw/demo-plugin",
263309},
@@ -273,6 +319,7 @@ describe("collectPublishablePluginPackages", () => {
273319private: true,
274320openclaw: {
275321extensions: ["./index.ts"],
322+ ...externalPluginContract("2026.4.10-beta.1"),
276323install: {
277324npmSpec: "@openclaw/private-plugin",
278325},
@@ -308,6 +355,7 @@ describe("collectPublishablePluginPackages", () => {
308355private: true,
309356openclaw: {
310357extensions: ["./index.ts"],
358+ ...externalPluginContract("2026.4.10-beta.1"),
311359release: {
312360publishToNpm: true,
313361},
@@ -333,6 +381,7 @@ describe("collectPublishablePluginPackages", () => {
333381},
334382openclaw: {
335383extensions: ["./index.ts"],
384+ ...externalPluginContract("2026.4.10-alpha.1"),
336385install: {
337386npmSpec: "@openclaw/demo-plugin",
338387},
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。