@@ -260,43 +260,67 @@ describe("installPluginFromNpmSpec", () => {
260260 } ) ;
261261 } ) ;
262262
263- 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+ {
267270 spec : "@openclaw/codex" ,
268- packageName : "@openclaw/codex" ,
269- version : "2026.5.2" ,
270271 pluginId : "codex" ,
271- npmRoot,
272272 indexJs : `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+ ) ;
300324
301325 it ( "rejects non-registry npm specs" , async ( ) => {
302326 const result = await installPluginFromNpmSpec ( { spec : "github:evil/evil" } ) ;
0 commit comments