// — an agent's subagents, under its own terminal preview in // `AgentsPage`'s detail panel. The list is `GET /api/agents/{name}/subagents`: // the subagents the swarm queue holds terminal rows for, each with the // publish time of its newest row. Newest first, with a ticking age beside // the name; one quiet for `STALE_S` is dimmed. Subagents are spawned on // demand, so `useSubagentList` refetches it. Picking one shows its // terminal in `AgentTermPreview`, expand-to-tab included. Read-only like the // agent's own: subagents take no input. // // Mount it keyed by agent name: the refresh timer is armed once per mount. import { useState } from "preact/hooks"; import { ApiErrorPanel } from "@hive/shared/api-error-panel.js"; import { Badge } from "@hive/shared/badge.js"; import { AgentTermPreview } from "./AgentTermPreview.js"; import { STALE_S } from "./subagent-list.js"; import { useSubagentList } from "./useSubagentList.js"; import { RelativeTime } from "../../ui/relative-time/RelativeTime.js"; import "./SubagentTerms.css"; export function SubagentTerms({ agentName }: { agentName: string }) { const { subagents, error } = useSubagentList(agentName); const [selected, setSelected] = useState(null); // An agent with no subagents shows nothing here — no heading, no // "none" line — and so does the first fetch while it is in flight. A // failed fetch still shows, so the error is not swallowed. if (!error && (subagents === null || subagents.length === 0)) return null; const nowS = Date.now() / 1000; return (
subagents {subagents?.map(({ name, last_row_unix }) => { const stale = last_row_unix !== null && nowS - last_row_unix > STALE_S; return ( setSelected(name === selected ? null : name)} /> {last_row_unix !== null && ( )} ); })}
{error && ( )} {selected && ( )}
); }