From d76742ff88d58288a5591a19713858822faf99ff Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 24 Feb 2026 03:56:27 +0000 Subject: [PATCH] fix: normalize manifest plugin ids during install --- src/plugins/install.test.ts | 37 +++++++++++++++++++++++++++++++++++++ src/plugins/install.ts | 4 +++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/plugins/install.test.ts b/src/plugins/install.test.ts index 1bc7a359b85..9f67e69430b 100644 --- a/src/plugins/install.test.ts +++ b/src/plugins/install.test.ts @@ -557,6 +557,43 @@ describe("installPluginFromDir", () => { ), ).toBe(true); }); + + it("normalizes scoped manifest ids to unscoped install keys", async () => { + const { pluginDir, extensionsDir } = setupPluginInstallDirs(); + fs.mkdirSync(path.join(pluginDir, "dist"), { recursive: true }); + fs.writeFileSync( + path.join(pluginDir, "package.json"), + JSON.stringify({ + name: "@openclaw/cognee-openclaw", + version: "0.0.1", + openclaw: { extensions: ["./dist/index.js"] }, + }), + "utf-8", + ); + fs.writeFileSync(path.join(pluginDir, "dist", "index.js"), "export {};", "utf-8"); + fs.writeFileSync( + path.join(pluginDir, "openclaw.plugin.json"), + JSON.stringify({ + id: "@team/memory-cognee", + configSchema: { type: "object", properties: {} }, + }), + "utf-8", + ); + + const res = await installPluginFromDir({ + dirPath: pluginDir, + extensionsDir, + expectedPluginId: "memory-cognee", + logger: { info: () => {}, warn: () => {} }, + }); + + expect(res.ok).toBe(true); + if (!res.ok) { + return; + } + expect(res.pluginId).toBe("memory-cognee"); + expect(res.targetDir).toBe(path.join(extensionsDir, "memory-cognee")); + }); }); describe("installPluginFromNpmSpec", () => { diff --git a/src/plugins/install.ts b/src/plugins/install.ts index 49ce72dcd07..baf3eb690ad 100644 --- a/src/plugins/install.ts +++ b/src/plugins/install.ts @@ -158,7 +158,9 @@ async function installPluginFromPackageDir(params: { // uses the manifest id as the authoritative key, so the config entry must match it. const ocManifestResult = loadPluginManifest(params.packageDir); const manifestPluginId = - ocManifestResult.ok && ocManifestResult.manifest.id ? ocManifestResult.manifest.id : undefined; + ocManifestResult.ok && ocManifestResult.manifest.id + ? unscopedPackageName(ocManifestResult.manifest.id) + : undefined; const pluginId = manifestPluginId ?? npmPluginId; const pluginIdError = validatePluginId(pluginId);