Watch
0
0
Fork
You've already forked hyperhive
0
Commit graph hyperhive/frontend/packages/swarm-ui/test
Author SHA1 Message Date
iris
f6acc1e976 swarm-ui: keep the issue report's table, errors and repo filter consistent
A failed report dropped its error under the previous repo's rows, the
repo list and the report shared one error slot, a remembered repo that
the list lacked left the select on all repos, and the report URL did not
encode the repo path. Each request now has its own error, a failed report
clears the rows, the remembered repo keeps an option, and the path parts
are encoded.
2026-10-21 22:58:51 +02:00
iris
ef156d9d23 swarm-ui link-account forms: keep the sent name, drop secrets, one word for forge
The success line of both link forms read the live text field, so editing
the name after a link changed the sentence. The result now carries the
name that was sent.

The matrix form held the typed token and password after a failed submit,
and kept them across a switch of credential mode. It now drops them when
the request ends and when the mode changes.

The linked-accounts list and the delete dialog said forgejo where the
link menu and forms say forge; they now say forge.
2026-10-21 22:06:49 +02:00
iris
e03bd4caa4 swarm-ui try-out: stable live region, reasons for disabled buttons
The running line is a live region whose text changed every second, so a
screen reader announced the counter again each time. The sentence is now
stable and the elapsed seconds sit outside it.

The run and open-a-PR buttons point at the hint that says why they are
off, and add-a-classification says why it is off at the cap.
2026-10-21 21:45:05 +02:00
iris
16c9e0ae3b swarm-ui: keep the table filter popover inside the window 2026-10-21 21:31:00 +02:00
iris
c2f17799fc swarm-ui: only the newest start's late stop ends a claude login 2026-10-21 21:14:53 +02:00
iris
41cc2f5e8e swarm-ui: stop a claude login whose dialog closed while it was starting 2026-10-21 21:14:53 +02:00
iris
393213054d swarm-ui: close a subagent terminal when its subagent leaves the list 2026-10-21 21:12:00 +02:00
iris
bdeec3f744 swarm-ui: key message rows on an arrival id and follow the tail on it
At the 2000-message cap the count stops changing, so the page stopped
following the newest message, and every row's index key shifted on each
arrival, remounting all of them. Each message now gets an id when it
arrives; the rows key on it and the scroll follows the newest id. Rows
are memoised on the message, and the events of one frame join the list
in a single update.
2026-10-18 18:39:11 +02:00
iris
447498fef7 swarm-ui: add a messages page for the swarm-wide message feed
/messages reads GET /api/messages/stream. A history select picks the window
(live only up to 24 hours) and a filter keeps the messages whose sender or
recipient contains the text. Each message is a row of the terminal list an
agent's terminal uses: one summary line with the time, the two parties and
the start of the body, and the whole body under it. The list follows the
newest message and holds the last 2000.

The feed has no event id, so a reconnect sends the history again. The page
empties its list each time the connection opens and fills it from the
replay, where the terminal stream hook, which keeps its rows across a
reconnect, would list every message twice.

The stream URL, filter, cap and row logic is in its own module with tests,
and docs/swarm/ui.md describes the page.
2026-10-18 18:19:30 +02:00
iris
30ba34f411 swarm-ui: let the create-agent form set the new agent's initial AGENTS.md
The form gets a collapsed "instructions" section with a plain text box. Its
text goes in the optional agents_md field of the create request, and is left
out while the box is empty or only whitespace. The controller's size refusal
shows under the box instead of in the form's general error panel. The text
box empties after a successful create.

The send and refusal logic sits in its own module with tests, and
docs/swarm/ui.md describes the field.
2026-10-18 15:59:19 +02:00
iris
f0a6d6c042 swarm-ui: add a button to the alerts page that shows the pending, no-data and error instances
The page opens on the firing ones. The button lists every instance again,
with the state filter and the tones back, so the table's filtering is
visible. The saved-filters key goes back to its original name, since the
state column is a filter again.
2026-10-18 13:29:52 +02:00
iris
b39e095aa8 swarm-ui: test which alert instances the alerts page lists
The firing-only filter and the helpers beside it move out of the page
component into a plain module, with tests for the state match, the
never-active time and the row key.
2026-10-18 13:29:52 +02:00
iris
b5d2e310ba swarm-ui: an editor for an agent's AGENTS.md that saves as a diff
The instructions row of the agent detail panel gets an edit button that
opens the agent's AGENTS.md, as the harness last published it, in a text
box. Save sends a unified diff against the revision that was loaded; when
the agent changed the file meanwhile the editor keeps the operator's text,
shows the agent's version and offers to save over it or take it. An unsaved
edit survives closing the dialog.

The diff is built in the browser (LCS over lines, three lines of context,
git's no-newline marker) and was checked against git apply on 600 random
before/after pairs.
2026-10-18 13:17:52 +02:00
iris
f65364759f swarm-ui: retrying a broadcast shows the agents that failed, even ones the filter hides 2026-10-18 02:40:10 +02:00
iris
89b20a5a50 swarm-ui: a broadcast page that sends one message to several agents
Pick agents from a grid of their icons (running or all), type the text, send.
The page posts the names and the text to the controller and shows what
happened to each agent, with a retry that selects just the ones that failed.
The selection rules and the controller's answer are read by plain functions
with tests.
2026-10-18 02:40:10 +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
0e77d61a9f swarm-ui: a builds page for the swarm builder's runs, and the status links to it
/builds lists the builder's recent builds newest first, one card each with how
it ended, and opens a failed build's nix tail. /builds?run=<id> opens that
build's card and scrolls to it. The swarm-builder commit status now links
there instead of to the raw JSON record.
2026-10-18 01:26:45 +02:00
atlas
553ed8376c archetypes: build an archetype agent from its archetype's module on the hive
The hive reads the agent-archetype key when it provisions and rebuilds an
agent and keeps it in swarm-agent-archetypes.json. For an archetype agent
the meta flake has no agent-<name> input and mkAgent imports
hyperhive.hyperhiveArchetypes.<name>.module; provisioning, rebuilds, the
meta-input cascade, a deploy's rev and the startup migration skip the
config repos. The harness gets HIVE_ARCHETYPE and the system prompt says
the agent has no config repo. The create form sends the picked archetype.
Adds the android-dev built-in.

Refs #5386
2026-10-17 16:27:21 +02:00
atlas
51035eac1d archetypes: prefill the create form from flake-declared agent archetypes
A flake declares agent archetypes in its `hyperhiveArchetypes` output,
`<name> = { module; meta; }`. The hyperhive flake ships `reviewer`
(default permissions without `execution`).

swarm-builder answers `$SWARM.builder.archetypes` with the `meta` of
every archetype its own hyperhive source declares. swarm-controller asks
once the queue connects and every 10 minutes, checks each archetype as
`POST /api/agents` checks its settings, and stores the result in the
`agent-archetypes` KV bucket when it changed. `GET /api/archetypes`
serves it, and the create form's archetype select prefills permissions,
resource caps and inference from it.

The agent created is an ordinary agent with its own config repo; the
archetype's module is not applied yet.

Refs #5386
2026-10-17 12:57:20 +02:00
atlas
7b5400ecb8 grant manage_root_agent by stored permission only, not by the name ruth
Permission::default_for and hive-sh4re's MANAGER_AGENT are gone: every
agent with no permissions key holds Permission::DEFAULT, ruth included.
The agent-name parameters that only fed default_for go with it
(permissions::effective, HiveCopy::before_read/after_read and their
callers).

swarm-controller seeds the grant ruth held by name: at start, a declared
ruth whose permissions are unset gets DEFAULT plus manage_root_agent
written into her key, once, logged. A set key is never touched. It is a
one-shot to delete once every swarm has passed it.

The swarm UI setup assistant opens the create form with
manage_root_agent checked, so a new ruth is created with the grant.
permissions_import no longer adds ruth to the import or splits her
default. Docs and help text no longer say ruth holds the grant by
default; swarmctl-cli.md regenerated.
2026-10-17 08:10:08 +02:00
damocles
a1f99c77f8 allow a max_subagents of 0: no subagents for the agent 2026-10-15 22:00:00 +02:00
damocles
8bf53f7ed9 swarm-ui: start page setup assistant offers to create ruth 2026-10-15 20:20:05 +02:00
iris
89efda5ea2 swarm-ui: give every tab the wide body
The shell had two body widths, a 60em readable column and a 90em wide body
that a short list of table routes opted into. Every route now gets the
90em body, and the opt-in route list, its modifier class and its test go
away.
2026-10-15 18:34:59 +02:00
atlas
f0844f6da3 agent permissions: one set, tool groups included, set at agent creation
mara on #5170: "dont split caps and perms. its all perms. / dont include
the now empty tool groups / nothing set -> default / also add perms to
agent creation screen".

- hive-sh4re: one `Permission` enum (messaging, meta, inbox, execution,
  web_tools, manage_root_agent) replaces `ToolGroup` and `Capability`;
  `lifecycle`/`forge` are gone. `Permission::default_for` is the default
  for an agent the swarm sets nothing for.
- The record is `{ "permissions": [...] }`. Missing key, unset field or
  no successful read yet = default; `[]` = none; a failed read after a
  good one keeps the last value.
- hive-agent reads its own key every 10s and builds each turn's --tools,
  --allowedTools and MCP config (rewritten before every turn) from it;
  the subagent daemon reads it on each start/continue. Agents get a
  read-only grant on their own key.
- hive-c0re restarts an agent only when its manage_root_agent changes.
  The import now merges meta/capabilities.json and meta/tool-groups.json
  into one list per agent and deletes both; the "import pending, don't
  read" decision is `ImportOutcome::read_allowed`, table-tested.
- swarm-controller: `GET /api/permissions` (names + default) and an
  optional `permissions` on `POST /api/agents`, stored before the job is
  queued. swarm-ui's create-agent form gets a permissions field.
- Deleted: HIVE_TOOL_GROUPS and its forward to the subagent daemon,
  tool_groups.rs, ruth's tool-group seed, the permissions rebuild job
  (PermPayload/WritePermFile/perm_change), the dashboard permissions tab
  and its stale-entries panel.

Part of #5170.
2026-10-15 18:01:40 +02:00
atlas
d5de1e4943 swarm UI: log an agent into claude from its card; the credentials go to bao and the agent picks them up
A new swarm service, `swarm-claude-login`, in its own container on the host
that sets `deploy.claude-login.enable` (defaulted on by `allSwarmServices`
where the host has the minter's store leaf, like the review classifier).

- swarm-ui: an agent card showing "login needed" gets a "log in" button.
  Its dialog starts the login, shows the URL claude printed, and takes the
  pasted code.
- swarm-controller: `POST/DELETE /api/agents/{name}/claude-login` and
  `POST /api/agents/{name}/claude-login/code`, behind the swarm UI's
  authelia-gated `/api/`, relay the steps to the minter as requests on
  `$SWARM.claude-login.request`.
- swarm-claude-login: runs `claude auth login` over piped stdio with HOME
  and CLAUDE_CONFIG_DIR in a per-login scratch dir, scrapes the first
  https URL, writes the code to stdin, and stores the `.credentials.json`
  at `swarm/agents/<agent>/claude-credentials` with a KV v2 write, a new
  version over any earlier one. The scratch dir goes on every exit path; a
  login waits 15 minutes for its code.
- hive-agent: while parked in `wait_for_login`, reads that leaf every 30 s
  under the agent's own cert and installs it only when its KV version is
  newer than the one recorded in `<harness>/claude-credentials-version`.
  An equal or older version is never put back, because claude rotates the
  refresh token and the stored copy is stale after the first refresh.
- swarm-secret-client: `claude_login` paths and `SecretStore::read_versioned`.
- Credentials: a `claude-login` store leaf minted by glue-bao-tls, a
  `swarm-claude-login` policy (create/update on
  `swarm/agents/+/claude-credentials`, read on its own queue client
  secret), an authelia machine client, and a `--claude-login-client`
  grant in the queue's auth-callout responder. The unit runs as a static
  system user.

The hive's own web-UI login is unchanged.

Refs #5268
2026-10-15 13:26:29 +02:00
iris
a68d73fa74 swarm ui: one review page
The two review tabs, runs and try-out, are one: /review. It is a column of
three sections: try a classification and the classifier settings, each a
folded bar (the settings' bar says what they are now), then the recent runs,
always open. The settings had been pinned under the try-out form; they are now
a section of their own. A new Disclosure primitive is the folding bar, a
native details wearing the Panel's classes, so the folded and open sections
read as the same surface.

/review-runs and /review-tryout are gone, with no redirect.
2026-10-15 03:38:48 +02:00
atlas
afeb0f9794 swarm UI: an agent that needs a Claude login shows it on its card
The agent's turn-state header ($SWARM.agent-state.<agent>) gains
`needs_login`, set by hive-agent from its own LoginState, so the flag
reaches the swarm without hive-c0re (mara on #5268: "id prefer the agent
container sending the info it needs login without hive").

- swarm-queue-client: `agent_login::Login`, the shared wire type, beside
  `agent_inference::Effective`. `needs_login: Option<bool>` with
  `#[serde(default)]`: a header from an older agent decodes as `None`
  (unknown), never as "needs login" or "logged in".
- hive-agent: the header publisher reads the shared LoginState cell.
  Every writer of that cell emits a status on the bus afterwards, so a
  login change goes out on the next rebuild, not the 60 s refresh.
- swarm-controller: `agent_login::Reported` follows every agent's header
  and keeps the latest flag; `GET /api/agents/status` merges it into each
  row as `needs_login` (null when unknown).
- swarm-ui: AgentCard shows a warning-tone "login needed" badge when the
  row's `needs_login` is true.

Refs #5268
2026-10-14 20:07:46 +02:00
iris
83b5f0bd89 swarm-ui: the start page's rain follows the app's motion setting
The rain read only the OS reduced-motion query, once, at mount. The settings
menu's motion override (data-motion on the document) wins over the OS in
either direction everywhere else, and the shell applies it from an effect
that runs after this one. Whether the rain may move is now rainAllowed(), and
the component re-evaluates it on mount, on every document attribute change
and on the media query's change, starting or stopping the interval and
clearing the canvas.
2026-10-14 18:36:52 +02:00
iris
e32b4172e4 swarm-ui: test the rain arithmetic and the swarm name loader
The rain's column maths and fade colour move from MatrixRain into
shell/rain.ts, and the request-once swarm name loader from useSwarmName
into shell/swarm-name.ts. Both are plain functions with their input
passed in, so tests cover them; the components keep the DOM and canvas
work.
2026-10-14 18:36:52 +02:00
iris
01e58219cf swarm-ui: move the shell's route layout predicates out and test them
isFullBleedRoute and isWideBodyRoute are plain functions of a path, so
they move from Shell.tsx to shell/routes.ts, where the new tests cover
the start page, the hive directory's move to /hives, the terminal
paths and the wide-body routes.
2026-10-14 18:36:52 +02:00
atlas
be2e64fa89 review try-out: show why the open-PR button is disabled
The form's one hint put the PR number first, so with the PR field empty
(which opening a PR doesn't need) it hid the repo or row problem that
was actually disabling the open-PR button. runProblem now checks the
rows first and the PR number last, and is tested.

Refs #5259
2026-10-14 18:36:36 +02:00
atlas
36c3f38717 swarm-ui: test the review try-out form's pure logic
The try-out page's checks and request body get tests under the
package's node runner: the repo check, a row's checks in their order,
a shared name, and the open-a-PR gate (repo, then each row in order,
then a shared name, with no PR number). Also the row a request sends,
and the row a loaded rule becomes.

Refs #5259
2026-10-14 18:36:36 +02:00
iris
93ae435287 swarm-ui: drop an unused export and test the classifier settings logic
The runtime list was exported but only its type was used, so the type is
now written out. The form's pure logic (draft, checks, request body,
change detection) gets tests under node's built-in runner, run by the
existing swarm-ui check.
2026-10-14 16:20:37 +02:00