From 0ea6188a6d7d2a058389fb9990b1eb78089dd38a Mon Sep 17 00:00:00 2001 From: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 Date: Mon, 13 Jul 2026 13:44:51 -0400 Subject: [PATCH] fix(desktop): trim duplicate MCP server rows Render only server rows and retain the buzz-agent empty-state message. Keep the screenshot fixture aligned with parser output so it cannot recreate duplicate rows. Co-authored-by: Will Pfleger Signed-off-by: Will Pfleger --- .../features/agents/ui/AgentConfigPanel.tsx | 2 - .../features/agents/ui/McpServersSection.tsx | 79 ++++--------------- desktop/src/testing/e2eBridge.ts | 56 ++++++------- .../e2e/config-bridge-screenshots.spec.ts | 33 +++++++- 4 files changed, 69 insertions(+), 101 deletions(-) diff --git a/desktop/src/features/agents/ui/AgentConfigPanel.tsx b/desktop/src/features/agents/ui/AgentConfigPanel.tsx index 950df90cb9..792db2e587 100644 --- a/desktop/src/features/agents/ui/AgentConfigPanel.tsx +++ b/desktop/src/features/agents/ui/AgentConfigPanel.tsx @@ -369,7 +369,6 @@ export function AgentConfigPanel({ const { normalized, advanced, extensions, runtimeId, sources, isPreSpawn } = data; const configFilePath = sources.configFilePath; - const mcpConfigFilePath = sources.mcpConfigFilePath; const normalizedEntries = ( Object.entries(normalized) as [ @@ -420,7 +419,6 @@ export function AgentConfigPanel({ 0 || configFilePath !== null; - const revealConfigFile = React.useCallback(() => { - if (!configFilePath) { - return; - } - void revealItemInDir(configFilePath); - }, [configFilePath]); - - if (!shouldRender) { + if (!isBuzzAgent && extensions.length === 0) { return null; } @@ -41,58 +29,10 @@ export function McpServersSection({ variant === "compact" ? "mt-3 pt-2" : "divide-y divide-border/50", )} > -
- - - -
-
-
-
- MCP Servers -
-
- {extensions.length > 0 - ? `${extensions.length} configured` - : isBuzzAgent - ? "No custom servers configured" - : "No servers found"} -
-
- {configFilePath ? ( - - ) : null} -
- {configFilePath ? ( -
- Edit in {configFilePath} -
- ) : null} -
-
- {isBuzzAgent && buzzAgentSlot ? buzzAgentSlot : null} {extensions.length > 0 ? ( -
+
{extensions.map((extension) => ( ))}
- ) : null} + ) : ( +

+ No custom servers configured +

+ )}
); } diff --git a/desktop/src/testing/e2eBridge.ts b/desktop/src/testing/e2eBridge.ts index b8b244bb72..6cc0cace1c 100644 --- a/desktop/src/testing/e2eBridge.ts +++ b/desktop/src/testing/e2eBridge.ts @@ -1318,37 +1318,12 @@ function buildMockConfigSurface(pubkey: string): { }, advanced: [ { - key: "extensions.developer", - label: "Extension: developer", - value: "enabled", + key: "active_provider", + label: "active_provider", + value: "openai", origin: "configFile", - schemaType: { type: "enum", options: ["enabled", "disabled"] }, - writeVia: { - type: "gooseNativeConfigWrite", - configKey: "goose.extensions.developer", - }, - }, - { - key: "extensions.web_search", - label: "Extension: web_search", - value: "enabled", - origin: "configFile", - schemaType: { type: "enum", options: ["enabled", "disabled"] }, - writeVia: { - type: "gooseNativeConfigWrite", - configKey: "goose.extensions.web_search", - }, - }, - { - key: "extensions.memory", - label: "Extension: memory", - value: "disabled", - origin: "configFile", - schemaType: { type: "enum", options: ["enabled", "disabled"] }, - writeVia: { - type: "gooseNativeConfigWrite", - configKey: "goose.extensions.memory", - }, + schemaType: { type: "string" }, + writeVia: { type: "readOnly" }, }, ], extensions: [ @@ -1685,10 +1660,25 @@ function buildMockConfigSurface(pubkey: string): { }, }; - // Map well-known test pubkeys to specific fixtures - // Synthetic agent for the multi-origin provenance showcase (not a TEST_IDENTITY). + const buzzAgentSurface = { + ...gooseSurface, + runtimeId: "buzz-agent", + runtimeLabel: "Buzz Agent", + advanced: [], + extensions: [], + sources: { + ...gooseSurface.sources, + configFilePath: null, + mcpConfigFilePath: null, + }, + }; + + // Map well-known test pubkeys to specific fixtures. + // Synthetic agents are intentionally not TEST_IDENTITIES. const PUBKEY_MULTI_ORIGIN = "abc1230000000000000000000000000000000000000000000000000000000def"; + const PUBKEY_BUZZ_AGENT = + "b0220000000000000000000000000000000000000000000000000000000000a9"; switch (pubkey) { case ALICE_PUBKEY: @@ -1701,6 +1691,8 @@ function buildMockConfigSurface(pubkey: string): { return runtimeOverrideSurface; case PUBKEY_MULTI_ORIGIN: return multiOriginSurface; + case PUBKEY_BUZZ_AGENT: + return buzzAgentSurface; default: return gooseSurface; } diff --git a/desktop/tests/e2e/config-bridge-screenshots.spec.ts b/desktop/tests/e2e/config-bridge-screenshots.spec.ts index 415d55a7fb..754c79f9c5 100644 --- a/desktop/tests/e2e/config-bridge-screenshots.spec.ts +++ b/desktop/tests/e2e/config-bridge-screenshots.spec.ts @@ -12,6 +12,8 @@ const RUNTIME_OVERRIDE_PUBKEY = TEST_IDENTITIES.outsider.pubkey; // (matches PUBKEY_MULTI_ORIGIN in e2eBridge buildMockConfigSurface). const MULTI_ORIGIN_PUBKEY = "abc1230000000000000000000000000000000000000000000000000000000def"; +const BUZZ_AGENT_PUBKEY = + "b0220000000000000000000000000000000000000000000000000000000000a9"; const MANAGED_AGENTS = [ { @@ -244,13 +246,40 @@ test.describe("config bridge screenshots", () => { const panel = await openAgentProfileFromChannel(page, "Goose Agent"); // Advanced runtime fields render directly in the profile panel's flat list. - await expect(panel.getByText("Extension: developer")).toBeVisible(); + await expect(panel.getByText("active_provider")).toBeVisible(); + // MCP servers render once each, without the removed summary row. + await expect(panel.getByText("developer", { exact: true })).toHaveCount(1); + await expect(panel.getByText("MCP Servers", { exact: true })).toHaveCount( + 0, + ); await settleAnimations(panel); await panel.screenshot({ path: `${SHOTS}/05-advanced-expanded.png` }); }); - test("06 — profile side panel — Configuration section", async ({ page }) => { + test("06 — buzz-agent empty MCP servers", async ({ page }) => { + await installMockBridge(page, { + managedAgents: [ + { + pubkey: BUZZ_AGENT_PUBKEY, + name: "Buzz Agent", + status: "running" as const, + channelNames: ["agents"], + }, + ], + }); + + const panel = await openAgentProfileFromChannel(page, "Buzz Agent"); + + await expect( + panel.getByText("No custom servers configured", { exact: true }), + ).toBeVisible(); + await expect(panel.getByText("MCP Servers", { exact: true })).toHaveCount( + 0, + ); + }); + + test("07 — profile side panel — Configuration section", async ({ page }) => { // charlie (554cef…) is the well-known test pubkey that the mock bridge // seeds as a bot owned by the test viewer, so isBot + isOwner + managedAgent // are all true — the Configuration section renders in the profile panel.