
























@@ -260,43 +260,67 @@ describe("installPluginFromNpmSpec", () => {
260260});
261261});
262262263-it("allows the official Codex npm plugin to spawn its managed app-server", async () => {
264-const npmRoot = path.join(suiteTempRootTracker.makeTempDir(), "npm");
265-const warnings: string[] = [];
266-mockNpmViewAndInstall({
263+it.each([
264+{
265+spec: "@openclaw/acpx",
266+pluginId: "acpx",
267+indexJs: `import { spawn } from "node:child_process";\nspawn("codex-acp", []);`,
268+},
269+{
267270spec: "@openclaw/codex",
268-packageName: "@openclaw/codex",
269-version: "2026.5.2",
270271pluginId: "codex",
271- npmRoot,
272272indexJs: `import { spawn } from "node:child_process";\nspawn("codex", ["app-server"]);`,
273-});
274-275-const result = await installPluginFromNpmSpec({
276-spec: "@openclaw/codex",
277-npmDir: npmRoot,
278-logger: {
279-info: () => {},
280-warn: (msg: string) => warnings.push(msg),
281-},
282-});
283-284-expect(result.ok).toBe(true);
285-if (!result.ok) {
286-return;
287-}
288-expect(result.pluginId).toBe("codex");
289-expect(
290-warnings.some((warning) =>
291-warning.includes("allowed because it is an official OpenClaw package"),
292-),
293-).toBe(true);
294-expectNpmInstallIntoRoot({
295-calls: runCommandWithTimeoutMock.mock.calls,
296- npmRoot,
297-spec: "@openclaw/codex",
298-});
299-});
273+},
274+{
275+spec: "@openclaw/google-meet",
276+pluginId: "google-meet",
277+indexJs: `import { spawnSync } from "node:child_process";\nspawnSync("node", ["bridge.js"]);`,
278+},
279+{
280+spec: "@openclaw/voice-call",
281+pluginId: "voice-call",
282+indexJs: `import { spawn } from "node:child_process";\nspawn("ngrok", ["http", "3000"]);`,
283+},
284+])(
285+"allows official npm plugin $spec with reviewed launch code",
286+async ({ spec, pluginId, indexJs }) => {
287+const npmRoot = path.join(suiteTempRootTracker.makeTempDir(), "npm");
288+const warnings: string[] = [];
289+mockNpmViewAndInstall({
290+ spec,
291+packageName: spec,
292+version: "2026.5.2",
293+ pluginId,
294+ npmRoot,
295+ indexJs,
296+});
297+298+const result = await installPluginFromNpmSpec({
299+ spec,
300+npmDir: npmRoot,
301+logger: {
302+info: () => {},
303+warn: (msg: string) => warnings.push(msg),
304+},
305+});
306+307+expect(result.ok).toBe(true);
308+if (!result.ok) {
309+return;
310+}
311+expect(result.pluginId).toBe(pluginId);
312+expect(
313+warnings.some((warning) =>
314+warning.includes("allowed because it is an official OpenClaw package"),
315+),
316+).toBe(true);
317+expectNpmInstallIntoRoot({
318+calls: runCommandWithTimeoutMock.mock.calls,
319+ npmRoot,
320+ spec,
321+});
322+},
323+);
300324301325it("rejects non-registry npm specs", async () => {
302326const result = await installPluginFromNpmSpec({ spec: "github:evil/evil" });
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。