From 356390befbbeb8a19b46711b70cf11274007b869 Mon Sep 17 00:00:00 2001 From: iris Date: Wed, 11 Nov 2026 00:58:15 +0100 Subject: [PATCH] swarm ui: the agent detail leaves out the config repo link for an archetype agent An agent built from an archetype has no config repo on the forge, so the link 404ed. It shows again once the agent is turned into a custom one. --- .../swarm-ui/src/agent/detail/AgentDetail.tsx | 12 ++++++++---- .../swarm-ui/src/agent/detail/forge-links.ts | 12 +++++++++--- frontend/packages/swarm-ui/test/forge-links.test.mjs | 6 ++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/frontend/packages/swarm-ui/src/agent/detail/AgentDetail.tsx b/frontend/packages/swarm-ui/src/agent/detail/AgentDetail.tsx index fda669880..8c8dafa15 100644 --- a/frontend/packages/swarm-ui/src/agent/detail/AgentDetail.tsx +++ b/frontend/packages/swarm-ui/src/agent/detail/AgentDetail.tsx @@ -117,7 +117,9 @@ function OverviewRows({ actions: AgentActions; }) { const forge = useForgeBase(); - const forgeLinks = forge ? agentForgeLinks(forge, row.name) : null; + const forgeLinks = forge + ? agentForgeLinks(forge, row.name, row.archetype === null) + : null; return ( <>
state
@@ -131,9 +133,11 @@ function OverviewRows({
forge
) : null} diff --git a/frontend/packages/swarm-ui/src/agent/detail/forge-links.ts b/frontend/packages/swarm-ui/src/agent/detail/forge-links.ts index 511c1d4a3..00bd75549 100644 --- a/frontend/packages/swarm-ui/src/agent/detail/forge-links.ts +++ b/frontend/packages/swarm-ui/src/agent/detail/forge-links.ts @@ -4,7 +4,9 @@ // `GET /api/links`, the same list the header's links menu shows. import type { MenuLink } from "@hive/shared/links-menu.js"; -export type AgentForgeLinks = { profile: string; configRepo: string }; +/** `configRepo` is null for an agent that has none: one built from an + * archetype, whose hive builds it from the archetype's module. */ +export type AgentForgeLinks = { profile: string; configRepo: string | null }; /** The forge's base URL from the swarm's service links, or null without one. */ export function forgeBase(links: MenuLink[]): string | null { @@ -13,10 +15,14 @@ export function forgeBase(links: MenuLink[]): string | null { } /** The agent's profile and config repo on the forge at `base`. */ -export function agentForgeLinks(base: string, agent: string): AgentForgeLinks { +export function agentForgeLinks( + base: string, + agent: string, + hasConfigRepo = true, +): AgentForgeLinks { const name = encodeURIComponent(agent); return { profile: `${base}/${name}`, - configRepo: `${base}/agent-configs/${name}`, + configRepo: hasConfigRepo ? `${base}/agent-configs/${name}` : null, }; } diff --git a/frontend/packages/swarm-ui/test/forge-links.test.mjs b/frontend/packages/swarm-ui/test/forge-links.test.mjs index 94389ad66..f8aade1e6 100644 --- a/frontend/packages/swarm-ui/test/forge-links.test.mjs +++ b/frontend/packages/swarm-ui/test/forge-links.test.mjs @@ -39,3 +39,9 @@ test("the agent name is encoded", () => { "https://forge.example/a%20b", ); }); + +test("an agent without a config repo, one from an archetype, has no config link", () => { + const links = agentForgeLinks("https://forge.example", "iris", false); + assert.equal(links.configRepo, null); + assert.equal(links.profile, "https://forge.example/iris"); +});