From 7913b3323cbbd9c8c8b4fb8fcd3bb89ef3380d42 Mon Sep 17 00:00:00 2001 From: oshtz Date: Fri, 24 Jul 2026 18:06:55 +0300 Subject: [PATCH] fix(desktop): edit the selected agent instance Signed-off-by: oshtz --- .../features/profile/ui/UserProfilePanel.tsx | 8 +++-- .../profile/ui/UserProfilePanelTabs.tsx | 9 +++-- desktop/src/testing/e2eBridge.ts | 5 +-- desktop/tests/e2e/agents.spec.ts | 34 ++++++++++++++++--- desktop/tests/e2e/edit-agent.spec.ts | 19 +++-------- desktop/tests/helpers/bridge.ts | 1 + 6 files changed, 50 insertions(+), 26 deletions(-) diff --git a/desktop/src/features/profile/ui/UserProfilePanel.tsx b/desktop/src/features/profile/ui/UserProfilePanel.tsx index c1f713d230..9c1702afd4 100644 --- a/desktop/src/features/profile/ui/UserProfilePanel.tsx +++ b/desktop/src/features/profile/ui/UserProfilePanel.tsx @@ -398,12 +398,14 @@ export function UserProfilePanel({ }); const handleEditAgent = React.useCallback(() => { + if (managedAgent) { + setEditAgentOpen(true); + return; + } if (resolvedPersona) { setPersonaDialogState(editPersonaDialogState(resolvedPersona)); - return; } - setEditAgentOpen(true); - }, [resolvedPersona]); + }, [managedAgent, resolvedPersona]); const { deleteManagedAgentRecord, deleteManagedAgentsForPersona } = useProfileAgentDeletion({ diff --git a/desktop/src/features/profile/ui/UserProfilePanelTabs.tsx b/desktop/src/features/profile/ui/UserProfilePanelTabs.tsx index 0fe4e19581..dd1d1a405c 100644 --- a/desktop/src/features/profile/ui/UserProfilePanelTabs.tsx +++ b/desktop/src/features/profile/ui/UserProfilePanelTabs.tsx @@ -401,8 +401,13 @@ function ProfileInstancesSection({ onClick={() => onOpenInstance(instance.pubkey)} type="button" > - - {instance.name} + + + {instance.name} + + + {instance.relayUrl} + {isCurrent ? "Current" : instance.status.replace("_", " ")} diff --git a/desktop/src/testing/e2eBridge.ts b/desktop/src/testing/e2eBridge.ts index 02aeeb49d2..4444e04906 100644 --- a/desktop/src/testing/e2eBridge.ts +++ b/desktop/src/testing/e2eBridge.ts @@ -68,6 +68,7 @@ type MockCommandAvailability = { type MockManagedAgentSeed = { pubkey: string; name: string; + relayUrl?: string; avatarUrl?: string | null; personaId?: string | null; status?: RawManagedAgent["status"]; @@ -1972,7 +1973,7 @@ function buildSeededManagedAgent(seed: MockManagedAgentSeed): MockManagedAgent { pubkey: seed.pubkey, name: seed.name, persona_id: seed.personaId ?? null, - relay_url: DEFAULT_RELAY_WS_URL, + relay_url: seed.relayUrl ?? DEFAULT_RELAY_WS_URL, acp_command: "buzz-acp", agent_command: "goose", agent_args: ["acp"], @@ -2004,7 +2005,7 @@ function buildSeededManagedAgent(seed: MockManagedAgentSeed): MockManagedAgent { respond_to_allowlist: seed.respondToAllowlist ?? [], private_key_nsec: `nsec1mock${seed.pubkey.slice(0, 20)}`, log_lines: [ - `buzz-acp starting: relay=${DEFAULT_RELAY_WS_URL} agent_pubkey=${seed.pubkey} parallelism=1`, + `buzz-acp starting: relay=${seed.relayUrl ?? DEFAULT_RELAY_WS_URL} agent_pubkey=${seed.pubkey} parallelism=1`, "profile created; harness not started", ], }; diff --git a/desktop/tests/e2e/agents.spec.ts b/desktop/tests/e2e/agents.spec.ts index 3c0c60d935..540d21864c 100644 --- a/desktop/tests/e2e/agents.spec.ts +++ b/desktop/tests/e2e/agents.spec.ts @@ -1634,6 +1634,8 @@ test("duplicate instances move from the agents gallery into the agent profile", const personaId = "custom:duplicate-auditor"; const primaryPubkey = TEST_IDENTITIES.alice.pubkey; const additionalPubkey = TEST_IDENTITIES.charlie.pubkey; + const primaryRelayUrl = "wss://primary.example.com"; + const additionalRelayUrl = "wss://secondary.example.com"; await installMockBridge(page, { personas: [ { @@ -1646,12 +1648,14 @@ test("duplicate instances move from the agents gallery into the agent profile", { pubkey: primaryPubkey, name: "Duplicate Auditor", + relayUrl: primaryRelayUrl, personaId, status: "running", }, { pubkey: additionalPubkey, name: "Duplicate Auditor", + relayUrl: additionalRelayUrl, personaId, status: "stopped", }, @@ -1667,11 +1671,33 @@ test("duplicate instances move from the agents gallery into the agent profile", await page.getByTestId(`persona-agent-row-${personaId}`).click(); await page.getByTestId("user-profile-instances").click(); + await expect(page.getByText(primaryRelayUrl, { exact: true })).toBeVisible(); + await expect( + page.getByText(additionalRelayUrl, { exact: true }), + ).toBeVisible(); await page.getByTestId(`user-profile-instance-${additionalPubkey}`).click(); await expect(page.getByTestId("user-profile-panel")).toBeVisible(); - await page.getByTestId("user-profile-settings-menu-trigger").click(); - await expect( - page.getByTestId(`user-profile-agent-delete-${additionalPubkey}`), - ).toBeVisible(); + await page.getByTestId("user-profile-edit-agent").click(); + const dialog = page.getByTestId("edit-agent-dialog"); + await expect(dialog).toBeVisible(); + await dialog.getByRole("button", { name: "Advanced", exact: true }).click(); + await dialog.getByTestId("env-vars-add").click(); + await dialog.getByTestId("env-vars-key").fill("CLAUDE_CONFIG_DIR"); + await dialog.getByTestId("env-vars-value").fill("C:\\buzz-secondary"); + await dialog.getByTestId("edit-agent-dialog-submit").click(); + await expect(dialog).not.toBeVisible(); + + const agents = await invokeTauri< + Array<{ + pubkey: string; + env_vars: Record; + }> + >(page, "list_managed_agents"); + expect( + agents.find((agent) => agent.pubkey === primaryPubkey)?.env_vars, + ).toEqual({}); + expect( + agents.find((agent) => agent.pubkey === additionalPubkey)?.env_vars, + ).toEqual({ CLAUDE_CONFIG_DIR: "C:\\buzz-secondary" }); }); diff --git a/desktop/tests/e2e/edit-agent.spec.ts b/desktop/tests/e2e/edit-agent.spec.ts index 95ef231556..d601403607 100644 --- a/desktop/tests/e2e/edit-agent.spec.ts +++ b/desktop/tests/e2e/edit-agent.spec.ts @@ -278,16 +278,9 @@ test.describe("edit agent dialog", () => { ).toBeVisible(); }); - test("profile Edit routes persona-linked agents to the definition editor", async ({ + test("profile Edit routes persona-linked agents to the instance editor", async ({ page, }) => { - // Routing pin for handleEditAgent (UserProfilePanel): when the agent has - // a resolvable non-built-in persona, the Edit quick action opens the - // DEFINITION editor (persona dialog), not EditAgentDialog. The instance - // editor (and its inherit-runtime toggle) is reachable for persona-linked - // agents only via the requestOpenEditAgent event (ConfigNudgeCard) — no - // plain UI path — so its inherit-toggle behavior is covered by B3b's - // component-level pinning test, not e2e. await installMockBridge(page, { managedAgents: [ { @@ -322,14 +315,10 @@ test.describe("edit agent dialog", () => { }); await page.getByTestId("user-profile-edit-agent").click(); - // Definition editor opens; the instance editor does not. - await expect(page.getByTestId("persona-dialog")).toBeVisible({ + await expect(page.getByTestId("edit-agent-dialog")).toBeVisible({ timeout: 10_000, }); - await expect(page.getByTestId("edit-agent-dialog")).not.toBeVisible(); - // And it is the persona's record that's being edited. - await expect(page.locator("#persona-display-name")).toHaveValue( - "Edit E2E Persona", - ); + await expect(page.getByTestId("persona-dialog")).not.toBeVisible(); + await expect(page.locator("#edit-agent-name")).toHaveValue(AGENT_NAME); }); }); diff --git a/desktop/tests/helpers/bridge.ts b/desktop/tests/helpers/bridge.ts index aeb2e4a7be..52b7023484 100644 --- a/desktop/tests/helpers/bridge.ts +++ b/desktop/tests/helpers/bridge.ts @@ -45,6 +45,7 @@ type MockCommandAvailability = { type MockManagedAgentSeed = { pubkey: string; name: string; + relayUrl?: string; personaId?: string | null; status?: "running" | "stopped" | "deployed" | "not_deployed"; channelNames?: string[];