diff --git a/src/cli/run-main.test.ts b/src/cli/run-main.test.ts index c86071f7d80..a27b08103d7 100644 --- a/src/cli/run-main.test.ts +++ b/src/cli/run-main.test.ts @@ -101,6 +101,16 @@ describe("shouldSkipPluginCommandRegistration", () => { }), ).toBe(false); }); + + it("keeps plugin registration for plugin-extensible builtins like memory", () => { + expect( + shouldSkipPluginCommandRegistration({ + argv: ["node", "openclaw", "memory", "neo4j", "sleep"], + primary: "memory", + hasBuiltinPrimary: true, + }), + ).toBe(false); + }); }); describe("shouldEnsureCliPath", () => { diff --git a/src/cli/run-main.ts b/src/cli/run-main.ts index 0d0eee78250..3fe829b87fc 100644 --- a/src/cli/run-main.ts +++ b/src/cli/run-main.ts @@ -27,12 +27,20 @@ export function shouldRegisterPrimarySubcommand(argv: string[]): boolean { return !hasHelpOrVersion(argv); } +// Builtin commands that plugins are known to extend with subcommands. +// These must NOT skip plugin CLI registration even though they are builtins. +const PLUGIN_EXTENSIBLE_COMMANDS = new Set(["memory"]); + export function shouldSkipPluginCommandRegistration(params: { argv: string[]; primary: string | null; hasBuiltinPrimary: boolean; }): boolean { if (params.hasBuiltinPrimary) { + // Some builtins are extended by plugins (e.g. "memory" gains "neo4j" subcommand). + if (params.primary && PLUGIN_EXTENSIBLE_COMMANDS.has(params.primary)) { + return false; + } return true; } if (!params.primary) {