Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions desktop/src/features/profile/ui/UserProfilePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
9 changes: 7 additions & 2 deletions desktop/src/features/profile/ui/UserProfilePanelTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,13 @@ function ProfileInstancesSection({
onClick={() => onOpenInstance(instance.pubkey)}
type="button"
>
<span className="min-w-0 flex-1 truncate text-sm font-medium">
{instance.name}
<span className="min-w-0 flex-1">
<span className="block truncate text-sm font-medium">
{instance.name}
</span>
<span className="block truncate text-xs text-muted-foreground">
{instance.relayUrl}
</span>
</span>
<span className="text-xs capitalize text-muted-foreground">
{isCurrent ? "Current" : instance.status.replace("_", " ")}
Expand Down
5 changes: 3 additions & 2 deletions desktop/src/testing/e2eBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type MockCommandAvailability = {
type MockManagedAgentSeed = {
pubkey: string;
name: string;
relayUrl?: string;
avatarUrl?: string | null;
personaId?: string | null;
status?: RawManagedAgent["status"];
Expand Down Expand Up @@ -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"],
Expand Down Expand Up @@ -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",
],
};
Expand Down
34 changes: 30 additions & 4 deletions desktop/tests/e2e/agents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
{
Expand All @@ -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",
},
Expand All @@ -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<string, string>;
}>
>(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" });
});
19 changes: 4 additions & 15 deletions desktop/tests/e2e/edit-agent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
{
Expand Down Expand Up @@ -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);
});
});
1 change: 1 addition & 0 deletions desktop/tests/helpers/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down