From 5acd56a5e38cb22c0802c97e90e164c60e6bb9e6 Mon Sep 17 00:00:00 2001 From: Miroslav Drbal Date: Tue, 31 Mar 2026 22:03:03 +0200 Subject: [PATCH] fix(coding-agent): only shadow user entry when project install is enabled listInstalledPlugins() was marking user-scope entries as shadowedBy: "project" based on plugin ID presence in the project registry alone. A disabled project copy (enabled: false) is not active in discovery, so the user copy is the effective install and must not appear shadowed. activeProjectIds now only includes project plugins where the first entry does not have enabled: false. --- .../src/extensibility/plugins/marketplace/manager.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/coding-agent/src/extensibility/plugins/marketplace/manager.ts b/packages/coding-agent/src/extensibility/plugins/marketplace/manager.ts index 1a6da7864..f020aee4e 100644 --- a/packages/coding-agent/src/extensibility/plugins/marketplace/manager.ts +++ b/packages/coding-agent/src/extensibility/plugins/marketplace/manager.ts @@ -447,7 +447,15 @@ export class MarketplaceManager { ? await readInstalledPluginsRegistry(this.#opts.projectInstalledRegistryPath) : null; - const projectIds = new Set(projectReg ? Object.keys(projectReg.plugins) : []); + // Only enabled project installs shadow user installs — a disabled project copy leaves + // the user entry as the active one and must not be reported as shadowed. + const activeProjectIds = new Set( + projectReg + ? Object.entries(projectReg.plugins) + .filter(([, entries]) => entries.length > 0 && entries[0].enabled !== false) + .map(([id]) => id) + : [], + ); const results: InstalledPluginSummary[] = []; // Project entries first @@ -462,7 +470,7 @@ export class MarketplaceManager { id, scope: "user", entries, - ...(projectIds.has(id) ? { shadowedBy: "project" as const } : {}), + ...(activeProjectIds.has(id) ? { shadowedBy: "project" as const } : {}), }); } return results;