Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/docs/2-handbook/swarm/ui.md
iris 4adbc939f2 docs: the swarm UI page shrinks to an overview
The page-by-page and control-by-control description of the swarm UI moves to
4-implementation/web-ui/swarm-ui.md, with the quick-links wiring. The handbook
page keeps the route table, how to reach the UI, who may and what the browser
keeps. Links to the moved sections point at the new page.
2026-11-11 09:03:05 +01:00

130 lines
10 KiB
Markdown

# Swarm UI
The swarm's own web surface and the operator's day-to-day view: served by
the gateway on the **swarm apex** (`services.hyperhive.swarm.domain`),
readable only by operators. The per-hive dashboard, on each hive's own
domain, covers host-level detail for one hive.
## What it shows
The swarm UI is a set of pages. Each one is a card list or a table you open in
place, and every one reads from [`swarm-controller`](../../../swarm-controller/README.md):
| route | what |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/` | the start page: the swarm's name over a digital-rain backdrop with the slug (`hyperhive / we are the wired`, its shaded gradients pulsing in a wave unless reduced motion is on) at the foot, plus a paperclip offering to set up an agent while no `ruth` exists, or her hive declares her destroyed (it opens the create form with `ruth` filled in); the swarm name in the header links here |
| `/agents` | every agent as a card that opens in place (status, terminal, subagents, and settings with permissions, internet, allowed domains and accounts); create agents (with their permissions, optionally from an [archetype](archetypes.md)), link forge, matrix and GitHub accounts |
| `/swarm` | what belongs to the whole swarm: a folded **hives** card with the hive directory and each hive's last reported status, a folded **egress** card with the swarm-wide allowed and denied domains, and a folded, **beta** **notification router** card (with a warning banner) holding the router's flows: a switch for each built-in, every flow drawn as a graph, and an editor for custom flows. `/notifications` redirects here |
| `/agents/<name>/terminal` | one agent's live terminal |
| `/agents/<name>/subagents/<subagent>/terminal` | one of that agent's subagents' live terminal |
| `/reports` | three folded cards, each read only once opened: the **alerts** the swarm's Grafana holds now, the firing ones, with a button for the pending, no-data and error ones and a link to Grafana's own alert list; read through the controller with a Viewer service-account token, and a cross-repo **issues** list, and a cross-repo **pull requests** list |
| `/jobs` | the controller's job graph, where agent creation and credential mints show progress, and under it the swarm builder's recent builds (agent config PRs, and agents built from `internal/meta` before a deploy), with what nix printed when one failed, and the review classifier's recent runs, a try-out on a real PR, and its settings |
| `/messages` | the swarm-wide message feed: every message between agents, and to them from the operator, reminders and compaction, with a history window and a filter on sender or recipient; a folded **broadcast** card above the feed sends one message to more than one agent at once, and a folded **schedules** card holds the scheduled prompts: add, edit, pause, resume and remove |
An agent created here or with `swarmctl agent create` starts `paused`; set it
`up` from its card. A card shows **login needed** when the agent's claude has no
session, with a **log in** button that runs the claude login from a dialog (see
[`claude-login.md`](claude-login.md)). The **wanted** badge changes an agent's
declared state, destroy included.
Each page, its controls and what they send are in
[the swarm UI reference](../../4-implementation/web-ui/swarm-ui.md).
## Enabling
```nix
services.hyperhive.deploy.swarm-controller.enable = true; # the UI comes with it
```
The UI has no switch of its own (setting `deploy.swarm-ui.enable` or
`swarm.ui.enable` has no effect, and warns at evaluation), and doesn't follow `allSwarmServices`:
the UI is a view onto the controller's state and reaches it over that
daemon's socket, so the host that runs the controller is the host that
can serve the UI. A hive that merely _uses_ a swarm has nothing to serve.
The UI build is `deploy.swarm-controller.ui.package` (defaulted from this
flake's `swarm-ui` package). The older `deploy.swarm-ui.package` still works
and warns at evaluation.
The UI answers on `services.hyperhive.swarm.domain` and nothing else. It
shares that name with the swarm-controller it fronts — one service to a
reader and to a certificate — so there is no separate option to pin.
> The apex must differ from `services.hyperhive.domain`. The gateway's
> default server already answers for the hive domain, and two vhosts
> claiming one `server_name` don't error — nginx picks one — so this is
> an assertion rather than a runtime surprise.
## 🔑 You must be in the `admins` group
**This is the step that separates "protected" from "locked out."** The
vhost's `auth_request` asks authelia _"is there a session"_; the rule
that makes it mean _"is this an operator"_ is an `access_control` entry
requiring `group:admins`, followed by a `deny` for everyone else. An
account without that group authenticates fine and still gets bounced.
```sh
swarmctl user add <you> --email <you>@example.com --group admins
swarmctl user update <you> --add-group admins # an account that already exists
```
`--email` isn't needed for the UI, but the forge won't create your account
without one → [setup.md § 2](../../1-getting-started/setup.md#2--your-sso-account).
Why a group and not "any session": agents are authelia subjects too, so
_authenticated_ includes every agent in the swarm. The group is the only
thing standing between "an operator's page" and "anyone with a session."
## When your login ends
When the session ends while a page is open, the page's next `/api/` request (a
poll, a form, or a stream that dies) gets a plain 401 with a
`WWW-Authenticate` header from the gateway, and the page reloads. The reload
lands on the login and, after you log in, back on the same address. A page
request still gets the login redirect, and `swarmctl --swarm` still treats the
401 as a sign to log in again. The page skips a second reload within ten
seconds, so a page that keeps answering 401 can't loop.
## What the browser keeps
The vhost tells the browser what to cache. The bundle under `/static/` has
content hashes in its names, so the browser keeps it for a year. The entry
document, `/sw.js`, the manifest, the icons and the theme's `colors.css` have
fixed names, so the browser revalidates them on every load, and a deploy
reaches an open browser at its next load. A file that doesn't exist answers
404, including a `/static/` file from an older build, rather than the entry
document.
The service worker fetches its shell past the HTTP cache and refreshes the
cached entry document on each page load that reaches the network. When its
install fails, the previous worker keeps running and the browser console shows
why.
The pages carry a content security policy: scripts and connections only from
this origin, images from this origin, `data:` and https, and no framing from
another origin.
## What it costs to be reachable
hyperhive publishes the apex to the hive's resolver like every other
swarm service, so agent containers can resolve it. That's deliberate and it's
not a hole: **reachability isn't the access control here.** An agent
that resolves the name and connects still has no operator session, and
the subrequest denies it.
## Quick links
The header has one 🔗 button, on every page, that opens links to the swarm's
other services: the forge, authelia, Grafana, the metrics and log stores, the
Matrix client and the secret store's web UI. The list is
`services.hyperhive.deploy.swarm-controller.links`, which defaults to one entry
per swarm service. An empty list hides the button. The **Bao** entry admits
members of authelia's `admins` group only; see
[`credentials.md`](credentials.md#the-browser-ui). Where each URL comes from, and
the two places to wire a new swarm service name, are in
[the reference](../../4-implementation/web-ui/swarm-ui.md#quick-links).
## Cross-references
- [`sso.md`](sso.md) — the authelia instance itself, and the user store.
- [`4-implementation/networking/gateway.md`](../../4-implementation/networking/gateway.md) — the full vhost map and TLS modes.