From 9c80d717bcb496ac1aebc49e6613bcdde599a33d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Mon, 16 Mar 2026 18:40:50 -0700 Subject: [PATCH] Tests: pin loader command activation semantics --- src/plugins/loader.test.ts | 62 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/plugins/loader.test.ts b/src/plugins/loader.test.ts index d9fc2308412..808ba4c8cb7 100644 --- a/src/plugins/loader.test.ts +++ b/src/plugins/loader.test.ts @@ -713,6 +713,68 @@ module.exports = { id: "skipped", register() { throw new Error("skipped plugin s expect(getGlobalHookRunner()).toBeNull(); }); + it("only publishes plugin commands to the global registry during activating loads", async () => { + useNoBundledPlugins(); + const plugin = writePlugin({ + id: "command-plugin", + filename: "command-plugin.cjs", + body: `module.exports = { + id: "command-plugin", + register(api) { + api.registerCommand({ + name: "pair", + description: "Pair device", + acceptsArgs: true, + handler: async ({ args }) => ({ text: \`paired:\${args ?? ""}\` }), + }); + }, + };`, + }); + const { clearPluginCommands, getPluginCommandSpecs } = await import("./commands.js"); + + clearPluginCommands(); + + const scoped = loadOpenClawPlugins({ + cache: false, + activate: false, + workspaceDir: plugin.dir, + config: { + plugins: { + load: { paths: [plugin.file] }, + allow: ["command-plugin"], + }, + }, + onlyPluginIds: ["command-plugin"], + }); + + expect(scoped.plugins.find((entry) => entry.id === "command-plugin")?.status).toBe("loaded"); + expect(scoped.commands.map((entry) => entry.command.name)).toEqual(["pair"]); + expect(getPluginCommandSpecs("telegram")).toEqual([]); + + const active = loadOpenClawPlugins({ + cache: false, + workspaceDir: plugin.dir, + config: { + plugins: { + load: { paths: [plugin.file] }, + allow: ["command-plugin"], + }, + }, + onlyPluginIds: ["command-plugin"], + }); + + expect(active.plugins.find((entry) => entry.id === "command-plugin")?.status).toBe("loaded"); + expect(getPluginCommandSpecs("telegram")).toEqual([ + { + name: "pair", + description: "Pair device", + acceptsArgs: true, + }, + ]); + + clearPluginCommands(); + }); + it("throws when activate:false is used without cache:false", () => { expect(() => loadOpenClawPlugins({ activate: false })).toThrow( "activate:false requires cache:false",