From 99ca1305527ed67df0440ff630cb9febbca2e5c7 Mon Sep 17 00:00:00 2001 From: iris Date: Tue, 10 Nov 2026 18:09:20 +0100 Subject: [PATCH] swarm ui: the freshness badge moves from the agent card onto the status panel The card header carried a fresh/stale badge with the report's age. It now sits in the status row of the opened card, which already showed it, and the card header keeps the name, the message and the controls. --- docs/2-handbook/swarm/ui.md | 4 ++-- .../swarm-ui/src/agent/detail/AgentDetail.tsx | 5 +++++ .../swarm-ui/src/agent/roster/AgentCard.tsx | 22 ------------------- 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/docs/2-handbook/swarm/ui.md b/docs/2-handbook/swarm/ui.md index 9456d2f85..70d3c5794 100644 --- a/docs/2-handbook/swarm/ui.md +++ b/docs/2-handbook/swarm/ui.md @@ -78,7 +78,7 @@ action that asks first. `/agents` is a column of separate cards: a filter card, then one card per agent, none of them inside a bigger card. A card's -header shows its icon, name, freshness, the status message, a **terminal** +header shows its icon, name, the status message, a **terminal** button that opens the agent's terminal tab, the **wanted** menu (up, offline, paused, destroy), a **paused by hive** badge when the agent's own harness paused its turn loop (hover for the reason; set the agent **up** to resume it), and a @@ -94,7 +94,7 @@ when the data arrives. The placeholders stand still where motion is off. An opened card has four sections, and each reads nothing until you open it. **status** and **terminal** start open, the other two folded: -- **status**: the agent's turn state, context and cost, its hive, links to its +- **status**: how fresh the agent's last report is (with its age), its turn state, context and cost, its hive, links to its profile and its config repo on the swarm's forge (built from the forge entry of `GET /api/links`; the row stays hidden when the swarm lists none), and its open config PR. diff --git a/frontend/packages/swarm-ui/src/agent/detail/AgentDetail.tsx b/frontend/packages/swarm-ui/src/agent/detail/AgentDetail.tsx index f265b1648..9990c1c31 100644 --- a/frontend/packages/swarm-ui/src/agent/detail/AgentDetail.tsx +++ b/frontend/packages/swarm-ui/src/agent/detail/AgentDetail.tsx @@ -61,6 +61,11 @@ function HeaderRows({
{label} diff --git a/frontend/packages/swarm-ui/src/agent/roster/AgentCard.tsx b/frontend/packages/swarm-ui/src/agent/roster/AgentCard.tsx index d14411e09..24d4ea5ca 100644 --- a/frontend/packages/swarm-ui/src/agent/roster/AgentCard.tsx +++ b/frontend/packages/swarm-ui/src/agent/roster/AgentCard.tsx @@ -17,14 +17,12 @@ import { useState } from "preact/hooks"; import { Badge } from "@hive/shared/badge.js"; import { TerminalIcon } from "@hive/shared/icons.js"; import { Card } from "../../ui/card/Card.js"; -import { RelativeTime } from "../../ui/relative-time/RelativeTime.js"; import { useDynamicTabs } from "../../shell/useDynamicTabs.js"; import { AgentIcon } from "../AgentIcon.js"; import { ClaudeLoginDialog } from "../claude-login/ClaudeLoginDialog.js"; import { AgentDetail } from "../detail/AgentDetail.js"; import { termPaths } from "../terminal/term-paths.js"; import { - FRESHNESS, hivePauseReason, showsLoginNeeded, type AgentRow, @@ -41,7 +39,6 @@ export function AgentCard({ row: AgentRow; actions: AgentActions; }) { - const { tone, label } = FRESHNESS[row.freshness]; const [loggingIn, setLoggingIn] = useState(false); const [open, setOpen] = useState(false); const error = actions.actionErrors.get(row.name); @@ -68,25 +65,6 @@ export function AgentCard({ name={{row.name}} status={ <> - - {label} - {row.last_seen_unix !== null ? ( - <> - {" "} - () - - ) : null} - - } - /> {hivePauseReason(row) !== null ? (