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
profile
-
- config repo
-
+ {forgeLinks.configRepo ? (
+
+ config repo
+
+ ) : null}
>
) : 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");
+});