dashboard: matrix-accounts page — provision/login per-agent external matrix accounts

New standalone H0M3 page (/matrix-accounts.html) and tile. An agent
picker drives a list of that agent's configured matrix accounts (name,
homeserver, token-stored status) and a provision form that logs in by
password or stores an existing token.

Frontend half of the per-agent external matrix-account provisioning
work. Built against the v1 backend contract:
  GET  /matrix-accounts?agent=<name>
       -> { accounts: [ { name, homeserver, token_present } ] }
  POST /matrix-account-login  (x-www-form-urlencoded, operator-auth)
       fields: agent, account, homeserver, mode=password|token,
               user_id?, password?, token?
       -> 2xx { ok, user_id } | 4xx { error }

The token is never echoed back; secret inputs are cleared on submit.
Token-status dot reflects token-stored, not live session (a true
up/down indicator needs the daemon account registry, a follow-up). The
form carries an experimental notice pending per-account failure
isolation on the matrix daemon.

Blocked from merge on the backend endpoints and the daemon
failure-isolation fix; opening for review + to pin the UI/backend wire
contract.
This commit is contained in:
iris 2026-06-15 23:17:32 +02:00 committed by mara
commit 9293fe3ac9
6 changed files with 394 additions and 3 deletions

View file

@ -200,6 +200,37 @@ omitted — agents share the host netns, so there is no per-container net
counter (per-agent network needs the netns-isolation roadmap in
`docs/network.md`).
## M4TR1X ACC0UNTS page (`/matrix-accounts.html`)
Operator surface to provision / log in a per-agent **external** matrix
account and store its access token, without editing the agent's config
repo. Standalone page reached from the **Matrix accounts** tile on the
H0M3 hub, same minimal chrome as `/core.html` (a `← home` back-link +
title). Its own esbuild bundle (`matrix-accounts.js`); no SSE — it reads
`/api/state` once for the agent picker and otherwise works off two
purpose-built endpoints.
An agent picker (populated from `state.agents`) drives a list of that
agent's configured accounts — name, homeserver, and a token-status dot —
read from `GET /matrix-accounts?agent=<name>`
`{ accounts: [ { name, homeserver, token_present } ] }`. The status
reflects only whether a token is **stored** (labelled "token stored",
not "online"); a true live up/down indicator needs the matrix daemon's
account registry and is a follow-up.
The provision form (account name, homeserver, login method) posts
`POST /matrix-account-login` (`x-www-form-urlencoded`, operator-auth):
fields `agent, account, homeserver, mode=password|token, user_id?,
password?, token?` → `2xx { ok, user_id }` on success or
`4xx { error }` on failure. The host coordinator performs the login
(password) or validates the token (`whoami`) and writes the bearer to
the agent's `matrixAccounts.<account>.tokenFile` via the same
privileged write path as the hive-internal `matrix-token`; the token is
**never** echoed back, and the page clears the secret inputs on submit
regardless of outcome. Because a bad credential can currently disturb
the agent's whole matrix session until per-account failure isolation
lands on the daemon, the form carries an explicit experimental notice.
## P3RM1SS10NS tab
Per-agent permission configuration. Two sections, each rendered as a