diff --git a/frontend/packages/swarm-ui/src/agent/detail/allowed-domains.ts b/frontend/packages/swarm-ui/src/agent/detail/allowed-domains.ts index 477ab51d..7bb24704 100644 --- a/frontend/packages/swarm-ui/src/agent/detail/allowed-domains.ts +++ b/frontend/packages/swarm-ui/src/agent/detail/allowed-domains.ts @@ -83,3 +83,12 @@ export function entryBody( const name = domain.trim(); return forSwarm ? { domain: name } : { domain: name, agent }; } + +/** + * The entries that hold for every agent, which the swarm page's egress card + * lists: not an agent's own, and not an automatic one (kept by the controller + * from an environment or account, so nothing to remove). + */ +export function swarmWideEntries(entries: AllowedDomain[]): AllowedDomain[] { + return entries.filter((e) => e.agent === undefined && e.derived !== true); +} diff --git a/frontend/packages/swarm-ui/src/pages/swarm/EgressCard.tsx b/frontend/packages/swarm-ui/src/pages/swarm/EgressCard.tsx index 285bccd0..4ac307ac 100644 --- a/frontend/packages/swarm-ui/src/pages/swarm/EgressCard.tsx +++ b/frontend/packages/swarm-ui/src/pages/swarm/EgressCard.tsx @@ -12,6 +12,7 @@ import { useState } from "preact/hooks"; import { ApiErrorPanel } from "@hive/shared/api-error-panel.js"; import { Badge } from "@hive/shared/badge.js"; import { AddForm } from "../../agent/detail/AllowedDomains.js"; +import { swarmWideEntries } from "../../agent/detail/allowed-domains.js"; import { useAllowedDomains } from "../../agent/detail/useAllowedDomains.js"; import { Button } from "../../ui/button/Button.js"; import { LazyDisclosure } from "../../ui/disclosure/LazyDisclosure.js"; @@ -44,9 +45,7 @@ function EgressBody() { ); } - const swarmWide = entries.filter( - (e) => e.agent === undefined && e.derived !== true, - ); + const swarmWide = swarmWideEntries(entries); return ( <> {errorPanel} diff --git a/frontend/packages/swarm-ui/test/allowed-domains.test.mjs b/frontend/packages/swarm-ui/test/allowed-domains.test.mjs index ee15228a..25db44a6 100644 --- a/frontend/packages/swarm-ui/test/allowed-domains.test.mjs +++ b/frontend/packages/swarm-ui/test/allowed-domains.test.mjs @@ -5,6 +5,7 @@ import { test } from "node:test"; import { allowedSummary, entryGroups, + swarmWideEntries, entriesFor, entryBody, } from "../src/agent/detail/allowed-domains.ts"; @@ -85,3 +86,21 @@ test("entries are grouped by source, empty sources left out", () => { ); assert.deepEqual(entryGroups([]), []); }); + +test("the egress card lists only the entries that hold for every agent", () => { + const entries = [ + { domain: "crates.io" }, + { domain: "docs.rs", agent: "iris" }, + { domain: "api.example.com", derived: true }, + { domain: "github.com" }, + ]; + assert.deepEqual( + swarmWideEntries(entries).map((e) => e.domain), + ["crates.io", "github.com"], + ); + assert.deepEqual(swarmWideEntries([]), []); +}); + +test("an add from the swarm page, with no agent, is a swarm-wide entry", () => { + assert.deepEqual(entryBody("github.com", true, ""), { domain: "github.com" }); +});