Watch
0
0
Fork
You've already forked hyperhive
0
Commit graph hyperhive/frontend/packages/swarm-ui/src/pages/agents
Author SHA1 Message Date
iris
27c4a593bb swarm-ui: the agents page shows placeholder cards in the shape of the real ones while the roster loads
A new Skeleton (a shimmering shape, still where motion is off) and a region
that tells assistive tech once that something is loading. The agent card's
header is split into AgentCardLayout, a layout with a slot for each part: the
card fills the slots with the real icon, badges and controls, its new
AgentCardSkeleton twin fills the same slots with placeholder shapes, so the
card that replaces it lands in the same place. The agents page uses the twin in
place of its "loading…" text.
2026-11-06 00:22:58 +01:00
iris
fd51cbd19d swarm-ui: pages that only display start from the answer they last saw, then refresh behind it
usePolled takes a cache key: it saves each answer in localStorage and starts
from the saved one, so opening the agents, alerts, builds, review runs or hives
view shows the last data at once and the refresh spinner marks the update. A
saved answer is dropped after a day, when it was saved by another build of the
UI, at log out (a new onLogout of the shared user menu) and when the gateway
ends the login (a new onSessionEnded of the session guard). Pages with an
editor (schedules, notification flows, broadcast) do not use it.
2026-11-05 23:14:25 +01:00
iris
47c447409b swarm-ui: the refresh picker shows a spinner in place of its clock while its page is fetching
usePolled reports when a request is in flight (through a new onBusy of the
poller) and holds it on for at least 0.4 seconds, so a quick answer still
reads as a refresh. The picker swaps its clock for the spinner, in the same
box so its width stays, and the spinner stands still where motion is off.
Every page with a picker passes it; a page with several polled requests shows
it while any of them runs. The Jobs page fetches through shared components
and has none yet.
2026-11-05 23:09:07 +01:00
iris
4876acd02a swarm-ui: a group pane's maximize and close are icon-only badges in its top right corner
The two controls sat among the pane's header badges as a labelled badge and a
cross glyph. They are now icon badges in the top right corner, through a
`trailing` slot of the terminal preview, so the header on the left keeps the
agent, split, subagents and state badges and a narrow pane wraps less.
2026-11-05 13:33:12 +01:00
iris
d733b1e2a9 swarm-ui: choosing a subagent in the subagents menu splits its terminal in beside the agent's
The menu on an agent's terminal page used to open the subagent on a tab of
its own. It now starts a group of this terminal and the subagent's, split to
the right; in a group's pane it splits that pane. A pane's layout key is the
agent, or `agent/subagent` for a subagent's pane, so the layout operations
stay as they are and a destroyed agent takes its subagent panes with it. A
subagent already in the group shows a marker and does nothing when chosen,
and maximize opens a subagent pane's terminal on its own.
2026-11-05 12:45:35 +01:00
iris
5665bbf827 swarm-ui: a maximize button on each pane of a terminal group opens that agent's own terminal 2026-11-05 12:42:56 +01:00
iris
839dbd642a swarm-ui: groups of agent terminals: drag a terminal tab onto a terminal to split it, tmux style, with resizable panes, a split button, and a name you can edit 2026-11-05 08:24:58 +01:00
iris
0302582d1c swarm-ui: a swarm tab after agents holding the hives card and the beta notification router; /notifications redirects to it 2026-11-04 21:12:39 +01:00
iris
696c199621 swarm ui: drop a doubled line from the agents page docs; keep + agent while the roster loads or fails
The buttons sat in the filter card, which only shows once the roster
has loaded, so a failed load left no way to create an agent.
2026-11-01 13:16:13 +01:00
iris
6e5dc3dd30 swarm ui: the agents page is separate cards, not one big agents card
The filter bar is a card of its own, holding the + agent button and the
refresh picker; the hives card and each agent card sit beside it.
2026-11-01 13:16:13 +01:00
iris
2eaa02e892 swarm-ui: the agents page is one column of cards that open in place
The roster loses its second column and its table view. Selecting a card opens
its details under it as four folded sections: overview, settings, accounts and
the terminal. The status, message and wanted rows, which the card header
already shows, are gone from the details. The terminal page's details dialog
keeps the flat list.
2026-11-01 01:21:43 +01:00
iris
8f5b3a2fa8 swarm-ui: the jobs and builds cards are folded by default
Both cards on the jobs tab start shut and read nothing until opened; a link
with ?run= opens the builds card. The fold-and-build-on-first-open part of the
hives card is now one LazyDisclosure, which the hives card uses too. Docs
follow.
2026-10-26 20:09:17 +01:00
iris
209a286d7c swarm-ui: repoint the HivesPage comments at HivesCard and pin the nav filter and lazy roster 2026-10-26 17:56:10 +01:00
iris
70917b7dd0 swarm-ui: hives are a folded card on the agents page, and hide developer details also hides the components tab
The hives nav tab and route go, with no redirect; the roster is a card above
the agents panel that starts folded and is read on the first open. The
settings toggle is renamed from hide debug output to hide developer details,
as it now also drops the components tab (the page still answers at
/components); the stored preference keeps its key.
2026-10-26 17:56:10 +01:00
iris
705160c0fd swarm-ui: move the terminal preview's state badges into a state row of the agent details table
The small preview in the detail panel keeps only the connection badge and
expand, and no longer follows the agent's state stream; the full terminal
tab keeps all its badges. The table gets a state row with the turn state, a
paused badge, and the context and billed tokens (not the model, which the
inference row shows). The preview's top padding drops to one badge row, and
the showHeaderBadges prop goes since the full-tab mount is now the only one
with badges.
2026-10-25 14:52:57 +01:00
iris
8917ba27b6 swarm-ui: one polled-resource hook for the refreshing pages
Each polling page repeated its own fetch-and-set code on a fixed timer,
so a slow answer could be overtaken by the next tick, an older response
could overwrite a newer one, and nothing aborted a request when the page
went away.

usePolled skips a tick while a request is in flight, aborts on unmount
or refresh, ignores answers from dropped requests, and keeps the last
good data under an error. The alerts, hives, agents, schedules, builds,
review runs and broadcast pages and the subagent list use it.
2026-10-21 23:05:35 +02:00
atlas
738dd1c95b swarm-controller: split main.rs into jobq, routes and startup modules
no behaviour change: a pure move of items and tests into new modules, plus
visibility edits (pub(crate)) and path updates in sibling modules that named
crate-root items. same routes, same OpenAPI, 561 tests before and after.

why: #5470, new features stop landing in one 6.4k-line file by default.

files outside swarm-controller/src: docs/agent-lifecycle/agent-roster.md,
swarm-ui JobsPage.tsx and AgentsPage.tsx, nix/host-modules/swarm-controller.nix
and swarm-grafana.nix hold comments that named main.rs for items that moved.
2026-10-18 13:44:43 +02:00
iris
ef507b8912 swarm-ui: the subagents menu resets per agent and closes when an entry is picked 2026-10-18 01:46:49 +02:00
iris
664409c87f swarm-ui: a running-subagents menu in the full-screen terminal header
An N running subagents badge opens a list of the agent's subagents, each a
link to its terminal, so you can switch without going back to the agents page.
A subagent counts as running when it published a row in the last 15 minutes;
the quiet ones are listed below it, dimmed. The list under the preview and the
menu now share one fetch hook and one definition of running.
2026-10-18 01:46:49 +02:00
iris
f957e19d0d swarm-ui: show an agent's details in a popover, not a modal dialog
The details open under the agent badge without dimming or blocking the page; a click outside or Escape closes it. New ui/popover primitive (anchored, portal, no backdrop) with a sample on the components page. A confirm or link dialog opened from inside it stays modal, and the popover ignores clicks and Escape that belong to that dialog. AgentDetailDialog becomes AgentDetailPopover.
2026-10-12 00:19:33 +02:00
iris
74e588415b swarm-ui: split pages/agents into two pages and the agent components
pages/agents held the roster page, the terminal page and every component under them. It keeps the two pages; the components move to src/agent, by concern: roster (card, wanted menu, actions), detail (panel body, dialog, inference, linked accounts, link menu) and terminal (preview, input, subagents, stream hooks, favicon), with the shared row type and icon at the top. Moves and import rewrites only.
2026-10-12 00:19:33 +02:00
iris
fd6953ed7c swarm-ui: show a failed wanted-state change in the agent details
The failure was recorded but only the roster card drew it, so the details dialog on a terminal page said nothing when a declaration failed. AgentDetail now shows it under the wanted menu, which the roster's detail panel gets too.
2026-10-12 00:19:33 +02:00
iris
103c842890 swarm-ui: open an agent's details in a dialog from its terminal tab
The terminal page gets an agent badge (icon and name) that opens the agent's detail panel in a dialog over the terminal, without the terminal preview. The panel body and the actions on an agent (declare a wanted state, link an account, with their confirm and form dialogs) move out of the agent roster page into AgentDetail and useAgentActions, so the roster and the dialog share them. AgentIcon moves to its own file for the same reason.
2026-10-12 00:19:33 +02:00
iris
9761ffa24a swarm-ui: a terminal tab takes its agent's icon as the browser-tab icon
The agent terminal page swaps the page's favicon for the agent's icon while it is mounted, so tabs of different agents tell apart. A subagent terminal shows its agent's icon. An agent with no icon, or an unreachable controller, keeps the hyperhive mark; leaving the page restores the page's own icon.
2026-10-12 00:18:10 +02:00
atlas
ae9ca4331e swarm: keep an agent's terminal rows and replay them on attach
swarm-controller now creates `term-main-<agent>` for every live agent, in
the same one-minute pass and with the same config style as
`term-sub-<agent>` (#4897): subjects `$SWARM.term.<agent>` only, max_age
24h, max_bytes 64 MiB, discard Old, max_message_size from the queue's
max_payload. An existing stream is opened as it is. The agent keeps its
plain publish on `$SWARM.term.<agent>` and gets no JetStream subject.

`GET /api/agents/{name}/term/stream` creates an ephemeral push consumer on
that stream starting 100 rows back, so a swarm-ui terminal opens with
recent history and then follows new rows, in order, from one
subscription. Each SSE event carries the row's stream sequence as its id,
and a reconnect's Last-Event-ID resumes after it. Without the stream the
route falls back to the live core subscription it used before.

The stream is `term-main-<agent>`, not `term-<agent>`: an agent may be
named `sub-x`, whose `term-<agent>` would be agent `x`'s subagent stream.
Its one literal subject cannot match `$SWARM.term.<agent>.sub.>`, which
needs more tokens, so the two streams never overlap.

The reader gains `$JS.API.CONSUMER.CREATE.*.*.$SWARM.term.*`, the
extended create form whose last tokens are the consumer's filter. Checked
against nats-server 2.14.4, the trailing `*` also admits a literal `*` or
`>` filter, so a consumer under it reaches any terminal row, main or
subagent; those are rows the reader already subscribes to and reads with
`STREAM.MSG.GET.*`.

Closes #4826
2026-10-11 12:35:31 +02:00
atlas
4719395b31 docs, comments: drop references to the removed model/effort picker
subagent.md no longer says the web UI's model picker offers
availableModels, and the comments in Dropdown, ComponentsPage and
WantedMenu no longer point at the deleted per-agent Picker.
2026-10-11 01:54:23 +02:00
iris
0d04bd7295 swarm-ui: per-agent inference panel and editor on the agents page
The agent detail panel shows the model and effort an agent runs on with
where each comes from, plus the swarm's subagent model list. An edit
dialog sets the swarm value (PUT) and a clear action removes it (DELETE).
Reads the configured/effective view, and shows the stored values alone
until an agent has reported what it runs on.
2026-10-10 18:51:55 +02:00
atlas
19a045a401 hive-agent: re-send the turn-state header once a minute
The header on `$SWARM.agent-state.<agent>` went out only when a bus event
changed it, and the core subject keeps nothing for a late subscriber. An
idle agent therefore said nothing to a reader that attached after its
last change: swarm-controller after a restart showed `effective: null`
for that agent until its next turn, which can be hours.

The publish loop now also wakes every 60 s and re-sends the current
header through the same `publish` path (clearing the dedup state first).
Transitions still go out as they happen. Same subject, same grant.

An agent whose queue connection is down now logs `swarm agent state:
publish skipped` once a minute even while idle, so the
`hh-swarm-agent-state-publish-skipped` alert also fires for idle
disconnected agents, not only busy ones.

Refs #5034
2026-10-10 17:37:23 +02:00
atlas
d723fac0be swarm: show each agent's effective model and effort, and where they came from
Each agent now reports the model and effort it runs on, and where each
comes from (`swarm`, `agent_nix`, `local_file` or `default`), in its
turn-state header on `$SWARM.agent-state.<agent>`: `effort`,
`model_source` and `effort_source` join `model`. The shared
`swarm_queue_client::agent_inference::{Effective, Source}` types spell
those fields for both ends.

The Bus keeps a source next to the model and effort. `Bus::new` takes it
from the local fallback chain (`harness_state::local_model` /
`local_effort`, which now return the source with the value), a `/model`
or `/effort` pick sets `local_file`, and the swarm poller sets `swarm`
or, on a clear, the local chain's source. A swarm value equal to the one
the agent already runs is now applied once, so the source moves to
`swarm` and the header is republished; before, `next()` skipped it as
unchanged.

swarm-controller subscribes to every agent's header with the reader
grant it already holds for the state relay, and keeps the latest
inference fields per agent in memory (`inference::Reported`).
`GET /api/agents/{name}/inference` now answers
`{configured, effective}`, `effective` being `null` until the agent's
first header with these fields since the controller started.
`swarmctl agent inference get` prints both; `set` reads `configured`.

Refs #5034
2026-10-10 17:37:23 +02:00
iris
7f597f5c43 swarm-ui: size every preview badge like the expand trigger, make room for two rows
All badges in the floating row take the interactive 2.75em height so the
state badges match live and expand. The embedded preview wraps them onto a
second row in the narrow details panel, so its top padding now fits two
rows (and the preview cap grows to match); the full tab keeps one row.
2026-10-04 17:29:48 +02:00
iris
51da879db6 swarm-ui: expand trigger on the right, connection badge as tall as it
The floating row over the terminal now spans its top edge: the state
badges (connection first, then the turn-state ones, which move over from
the top-right corner) on the left, the expand trigger on the right.
The connection badge takes the trigger's height. The row passes pointer
events through its empty middle.
2026-10-04 17:29:48 +02:00
iris
9064d8fbd2 swarm-ui: connection badge and expand trigger float inside the terminal preview
They sat in a toolbar row above the terminal box. They now float in
its top-left corner, next to the turn-state badges in the top-right,
and the toolbar row is gone. The full-tab mount keeps the connection
badge and, being the destination already, has no expand trigger.
2026-10-04 17:29:48 +02:00
iris
84c89de71c swarm-ui: show how recent each subagent is in the details panel
The subagent list endpoint now returns {name, last_row_unix} per
subagent, the publish time of its newest terminal row, read from the
queue controller-side so agents publish nothing new. The panel sorts
newest first, shows a ticking age beside each name, and dims one quiet
for 15 minutes.

Closes #4928
2026-10-04 17:24:25 +02:00
iris
2c1a9fa488 swarm-ui: one link-account menu, and no subagents section without subagents
The three link-account badges were wider than the agent detail panel and
spilled out of it; they are now a single badge opening a dropdown of the
three kinds. The subagents row, heading included, is not rendered for an
agent that has none.
2026-10-04 16:35:06 +02:00
iris
66df552f68 swarm-ui: terminal tab fills the viewport below the header
The agent terminal tab now takes the whole window except the header bar,
full width and height, instead of sitting in the padded content column.
The connection badge floats inside the terminal's top-left corner and the
toolbar row above it is gone on this route.
2026-10-04 16:15:06 +02:00
atlas
48ac4ac423 swarm UI: send a message to an agent, without its hive
The agent view in the swarm UI gets a message box. The text reaches the
agent's harness straight from swarm-controller over the swarm queue and
becomes an inbox turn from the operator's authelia username. hive-c0re is
not in the path.

- gateway: `/api/` forwards authelia's `Remote-User`, replacing any the
  client sent.
- swarm-controller: `POST /api/agents/{name}/input` takes that header as
  the sender (401 without it) and sends `{from, body}` as a NATS request
  on `$SWARM.input.<agent>`. No subscriber is a 503.
- swarm-nats-auth: the controller is granted publish on `$SWARM.input.*`;
  no hive or agent grant names the family, so the harness can trust
  `from`.
- hive-agent: a task subscribes to the agent's own input subject and
  pushes each message into the serve loop's existing reminder channel,
  renamed `local_msg_*` since it now carries both.

The harness does not reply to the request: no agent grant covers a reply
subject. The controller therefore answers 202 once the request times out
(2s) and 503 on the server's no-responders status.

Closes #4828
2026-10-04 03:02:14 +02:00
atlas
d6f94e5247 swarm: show subagent terminals in the swarm UI
An agent's subagent daemon publishes each subagent's output as terminal
rows on `$SWARM.term.<agent>.sub.<subagent>`, as the agent, into a
per-agent stream it creates itself; swarm-controller lists an agent's
subagents from that stream's subjects and relays one subagent's rows as
SSE; the swarm UI lists them under the agent's terminal preview and
reuses AgentTermPreview, full-screen tab included, with no input.

- swarm-nats.nix: the agent token may also publish
  `$SWARM.term.{agent}.sub.>` and `$JS.API.STREAM.CREATE|INFO` on
  `term-sub-{agent}`, and nothing else of JetStream. A module-eval arm
  pins the agent-token grant as an exact list.
- mcp.nix: hive-subagent-daemon loads the agent's store identity
  (`hive-agent-bao-cert/-key/-server-ca`, the ones hive-agent loads)
  whenever the agent has a store, not only on the opencode preset. The
  agent's own queue secret lives in the store, so this is the credential
  the harness connects with.
- hive-subagent-mcp: `swarm_term` reads the agent's queue secret under
  that identity, connects with the agent token, opens or creates
  `term-sub-<agent>` (max_age 24h), and publishes classified rows from
  the sink every subagent line already passes through. The sink only
  queues (bounded, drop-and-count); a missing store, refused credential,
  failed stream create or failed publish is a log line.
- The stream-json classifier (`stream_enrich`) and the `TermMsg` row
  types plus `fit` move from the hive-agent binary into hive-sh4re, so
  the subagent daemon publishes the rows AgentTermPreview already
  renders. hive-agent keeps its LiveEvent classifier on top.
- swarm-controller: `GET /api/agents/{name}/subagents` and
  `GET /api/agents/{name}/subagents/{subagent}/term/stream`.
- docs/swarm: what the UI shows and what the queue carries.

Closes #4827
2026-10-03 01:34:01 +02:00
atlas
b90be9e65e swarm UI: delete linked accounts — R2 fixes
Addresses argus review comment 90297 on PR #4899:

- swarm-controller/README.md: list the three DELETE routes (including
  matrix's ?revoke=true) beside the PUT/GET ones already documented.
- LinkedAccounts.tsx: a delete answering 404 means the account is
  already gone, so treat it as the delete's end state — re-fetch and
  close the dialog instead of showing an error.
- matrix_account.rs: matrix_logout treats a 401 M_UNKNOWN_TOKEN as the
  token already being revoked and proceeds with the delete; every
  other logout failure still keeps the account. Adds unit tests and
  updates docs/swarm/ui.md to match.
2026-10-03 00:56:39 +02:00
atlas
bbf931207f swarm UI: delete linked accounts
Each row of an agent's linked accounts, except its own `main` matrix
account, gets a delete action. swarm-controller serves DELETE beside each
PUT (matrix-accounts/{account}, forge-accounts/{label}, github-account),
answers 404 for an account the store does not hold, refuses `main`, and
removes every version through `delete_all_versions`.

The matrix confirmation has a revoke checkbox, off by default: the
controller logs the stored token out at its homeserver first, and keeps
the account when that fails or no homeserver is stored.

The controller's policy gains `delete` on each agent's
`metadata/.../matrix/+`, `forge/+` and `github-token`, pinned in
bao-grants.nix.

Refs #4855
2026-10-03 00:56:39 +02:00
atlas
9224c0bd15 swarm UI: fetch linked accounts only for the opened agent
The detail panel makes one request for the agent it shows,
GET /api/hives/{hive}/agents/{agent}/linked-accounts, which returns every
matrix, forge and github account of that agent as names and hosts. The
all-agents route and the table's matrix-column rows are removed, so the
table makes no linked-accounts request. The panel stays keyed by
hive/agent. The bao grant is unchanged.

Refs #4855
2026-10-02 22:36:11 +02:00
atlas
7ccde4647b swarm UI: one request for every agent's linked accounts
GET /api/agents/linked-accounts returns one entry per agent that
/api/agents/status has a row for, as {hive, agent, accounts}, from one
store login. The agents page fetches it once (and again when a link dialog
closes) and hands each table row and the detail panel its agent's slice,
so the page makes no per-agent request. The per-agent route had no caller
left and is removed. The bao grant is unchanged: the same list on each
agent's matrix and forge metadata directories.

Refs #4855
2026-10-02 21:20:40 +02:00
atlas
4fd1380a5f swarm UI: key LinkedAccounts by hive and agent
Selecting another agent kept the previous agent's rows on screen until
the new fetch landed. Keying both mounts by hive/agent remounts the
component on an agent change; a version bump still refetches in place.

Refs #4855
2026-10-02 21:20:40 +02:00
atlas
3380c1915f swarm UI: show the accounts linked to each agent
GET /api/hives/{hive}/agents/{agent}/linked-accounts returns one row per
account linked to the agent, as kind, name and host: each matrix account
under swarm/agents/<agent>/matrix (with its homeserver, and the agent's own
`main` marked reserved), each forge label under swarm/agents/<agent>/forge
(with its url), and github when swarm/agents/<agent>/github-token exists
(host github.com, which is not stored). No credential field is in the
response type.

Listing those two directories needs a new controller grant: `list` on
secret/metadata/swarm/agents/+/matrix and .../+/forge only, pinned in
bao-grants.nix as the only metadata stanzas under agents/ beside the queue
revocation. Checked against a dev OpenBao 2.6.3: the grant lists those two
directories and is refused on agents/, agents/<agent>/, and a leaf.

The swarm UI agent detail panel shows all rows under "accounts"; the table
view's matrix column shows the matrix rows. The link badges stay.

Refs #4855
2026-10-02 21:20:40 +02:00
atlas
8e23feb01b github: PATs live in swarm bao; the agent fetches them itself
An operator links an agent's GitHub personal access token in the swarm UI
(LinkGithubAccountForm, "link github account" on /agents). swarm-controller's
PUT /api/hives/{hive}/agents/{agent}/github-account stores it at
swarm/agents/<agent>/github-token (swarm_secret_client::github), a flat leaf
under the agent's prefix that the agent's existing read grant already covers:
no policy change, and no list grant, since there is one token per agent.

In the agent, hive-agent-github-token (oneshot + 2-minute timer, as the agent
user, under its own store certificate, ordered before hive-github-notify)
reads that path and writes <state>/github-token, 0600 and agent-owned, the
file the gh wrapper, git credential helper and hive-github-notify already
read. It replaces the file by rename only when the bytes changed and never
deletes it: a hive-written github-token stays until a token is linked in the
swarm UI. It is installed only with a store address and
services.hyperhive.agent.github.enable.

Removed: the dashboard's CR3D3NTIALS page (credentials.html/js/css, its
build entries and H0M3 tile; GITHUB was its only tab), hive-c0re's
dashboard/matrix_accounts.rs with GET/POST /api/github-account,
priv_client::write_agent_github_token, the host socket's
SetAgentGithubToken and `hivectl github set-token`, and hive-priv's
WriteAgentGithubToken with write_agent_state_file, its only caller gone.

Docs: integrations/github.md and swarm/ui.md describe the swarm path,
swarm/credentials.md gains the store-path row, and the hive UI docs,
hivectl docs and security.md's hive-priv table drop the removed pieces.

Closes #4347
2026-10-02 17:48:27 +02:00
atlas
2c7e586f47 forge: external forge accounts live in swarm bao; the agent fetches them itself
An operator now links an agent's external forge account (label, base URL,
token) in the swarm UI. swarm-controller stores it at
swarm/agents/<agent>/forge/<label>. There is no index: the store's
listing of the agent's forge/ directory is the set of accounts.

In the agent, hive-agent-forge-accounts (oneshot + 2-minute timer, as
the agent user, under its own store certificate) lists
swarm/agents/<agent>/forge/ with the `list` #4866 grants an agent on its
own metadata subtree, reads each account, and writes
<state>/forge-<label>-token and forge-<label>.json in the names and shape
hive-forge -f already reads. An empty listing (a 404, which `bao kv list
-format=json` answers with `{}` and an empty stderr) is zero accounts; a
denial or an unreachable store fails the unit. It never deletes: files
for labels not listed, including ones the hive wrote, stay as they are.

Removed: the dashboard FORGES tab (credentials.js/html section and its
CSS), hive-c0re's extra_forges.rs and its routes, priv_client's
extra-forge calls, and hive-priv's WriteAgentExtraForgeAccount /
DeleteAgentExtraForgeAccount with their helpers. The GITHUB tab and
WriteAgentGithubToken stay.

Also: persistence.md's matrix avatar note names the exit-75 restart on a
changed account listing, not the dashboard, as what brings a linked
account up.

Refs #4348
2026-10-01 18:05:33 +02:00
iris
7bf4cfbc4c swarm-ui: fix specificity claim in AgentTermPreview.css comment
argus's review on PR #4784 caught a wrong technical claim: the
comment said the .ui-agent-term-preview-full override rules relied
on source order because they had equal specificity to the
un-modified rules above. They don't — each override selector adds
one more class (the .ui-agent-term-preview-full prefix) than what it
overrides, so they're strictly more specific and win regardless of
file order. Corrected the comment to say so.
2026-09-28 23:17:44 +02:00
iris
c460e91bd1 swarm-ui: full-tab agent terminal (#4506)
Adds a full, non-capped agent terminal reachable from a new expand
trigger on the embedded AgentTermPreview (the detail-panel preview on
AgentsPage stays as-is, just gains the trigger). Opens
/agents/:name/terminal in a new dynamic tab in Shell's header, next to
the static nav row — tabs persist across a reload via useDynamicTabs,
a small localStorage-backed hook built on @hive/shared's existing
settings-storage primitive.

AgentTermPreview gains two new props to support both mounts from one
component: fullHeight (drops the 12em preview cap, fills its page)
and showHeaderBadges (default true — lets a future caller that
already shows turn_state/model/ctx/cost elsewhere suppress this
cluster; AgentsPage doesn't use it, see below).

Deviation from the originally posted plan (issue comment 80596): that
plan proposed AgentsPage's embedded preview pass showHeaderBadges as
false, reasoning the detail panel already duplicates that info.
Checked the actual code before implementing — it doesn't; AgentRow/
AgentTypes.ts carry none of turn_state/model/ctx/cost, and
AgentTermPreview's own floating badges are the only place swarm-ui
shows them. Left the badges visible there instead of shipping a
regression the plan's own stated justification didn't hold up to.

Also fixed a same-tab pub/sub race found by actually rendering a cold
load of /agents/:name/terminal (headless chromium, not just reasoning
about the code): useLocalSetting subscribes inside a useEffect, and
mount effects fire children-before-parents, so a descendant's
mount-time write (AgentTerminalPage registering its own tab) can beat
an ancestor's (Shell's) subscription into existence, leaving Shell's
tab row silently empty on a direct/reload load. Fixed by having
useDynamicTabs re-sync from storage on every location change, not
just on notify() — the fix lives in the new hook itself, not in the
shared settings-storage primitive theme/motion overrides also use.
2026-09-28 23:17:44 +02:00
atlas
3b8df27dcf swarm-ui: show each agent's icon on its card
Each agent card now leads with the agent's icon, loaded as an `<img>`
from `GET /api/agents/<name>/icon`: the same 5em square, background and
fallback as the hive dashboard's container row. An agent with no icon
(the route's 404), or any other failed load, shows the dimmed hyperhive
mark (`/favicon.svg`) instead of a broken image.

Only ever an `<img>`, never inline markup: the body is an agent-authored
SVG, and an image load does not run its script.
2026-09-28 13:47:37 +02:00
iris
d9c8b7ca8f swarm-ui: floating turn-state/model/ctx/cost badges on the agent term preview
Header-bar parity for the swarm-level agent terminal, per mara's ruling
"dont make it a header though - make it floating elements on top of the
terminal". Adds useSwarmAgentStateStream (SSE consumer for
swarm-controller's GET /api/agents/{name}/state/stream) and renders a
small read-only Badge cluster absolutely positioned in
AgentTermPreview's terminal box corner, reusing the same anchor pattern
@hive/shared/terminal.css's .tail-pill already uses.

Shows turn_state always, agent_state only when it isn't the boring "up"
case, model (with resolved-model tooltip), and ctx/cost usage. No badge
renders until the first header event lands - the swarm queue's
agent-state subject is transition-only with no seed/replay, and no
swarm-level endpoint today can seed turn_state/model/ctx/cost
synchronously.

Vocabulary (state tones, token-total/format helpers) ported from
@hive/agent's Root.tsx/lib/format.ts rather than imported, matching the
existing "small helper, not worth a cross-package hop" call
useSwarmTermStream's own appendRow already made.

Verified by rendering the real component tree against a stubbed
EventSource and screenshotting the result - the badge cluster initially
overlapped the terminal's first row of text, fixed by giving this
preview's own .live.terminal extra top padding.
2026-09-18 17:30:59 +02:00
iris
08aee4b704 swarm-ui: fix agent term preview box-sizing causing content to bleed past its wrap 2026-09-13 22:01:40 +02:00