extra-forges: fully dashboard-provisioned, no host config

Per mara's feedback on PR #2407 ("better: you can also provide url in
dashboard, same as with matrix, no host config"), drops
services.hyperhive.extraForges and the admin-API mint/revoke flow
entirely. The operator now creates a token on the external forge
themselves and pastes a label + base URL + access token into the
dashboard's FORGES tab, the same shape as the GitHub PAT flow plus the
base-URL field from the matrix extra-account flow. hive-c0re only ever
writes/deletes two local files per account (forge-<label>-token,
forge-<label>.json sidecar for the URL) via hive-priv — no remote
account creation, no admin token, no revoke-on-the-remote-side, no nix
config to enumerate.

- nix/host-modules/hive-forge/default.nix: removed the extraForges
  option, its label-format assertion, and the HYPERHIVE_EXTRA_FORGES
  env forwarding.
- hive-c0re/src/forge/extra.rs: deleted (REST admin-API provisioning,
  no longer needed).
- hive-c0re/src/dashboard/extra_forges.rs: GET /api/extra-forges?
  agent= lists an agent's stored forges by scanning its state dir
  (mirrors matrix_accounts.rs's filename-scan listing), POST
  /api/extra-forge-account (agent/label/base_url/token/
  action=add|remove) stores or removes an account.
- hive-sh4re/priv_proto.rs + hive-priv/main.rs: new
  WriteAgentExtraForgeAccount/DeleteAgentExtraForgeAccount priv
  requests (adds base_url, writes/deletes a JSON sidecar alongside the
  token).
- hive-c0re/src/priv_client.rs: matching wrapper functions.
- frontend/packages/dashboard/src/credentials.{html,js}: FORGES tab is
  a per-agent list + add-account paste form (label/base_url/token), no
  grant/revoke-from-catalog UI.
- docs/web-ui/dashboard.md: FORGES tab section rewritten.

Supersedes the design in PR #2407 (already approved+green on the old
admin-API model) — opening as a fresh PR against the same issues
rather than force-pushing over the approved one.
This commit is contained in:
iris 2026-07-14 18:11:47 +02:00 committed by mara
commit dbf880ac66
10 changed files with 558 additions and 2 deletions

View file

@ -283,7 +283,7 @@ on the H0M3 hub, same minimal chrome as `/logs.html` (a `← home` back-link
than `/core.html`'s plain title. Its own esbuild bundle
(`credentials.js`); no SSE — it reads `/api/state` once for the (shared)
agent picker and otherwise works off purpose-built endpoints per tab.
Two sub-tabs:
Three sub-tabs:
### MATRIX tab
@ -354,6 +354,32 @@ regardless of outcome. The account list reflects what is *provisioned*
(an account with a stored token), so a config-declared-but-unprovisioned
account appears only once it has been provisioned through the form.
### FORGES tab
Store a **label + base URL + access token** for an external Forgejo/Gitea/
Codeberg-compatible forge, per agent. Entirely dashboard-provisioned —
there is no host-side nix config for this (no `services.hyperhive.
extraForges` option). The operator creates the token on the external forge
themselves (however that forge lets them — PAT UI, a teammate with admin,
whatever) and pastes label/URL/token into the form; hive-c0re never talks
to the external forge's API and never creates an account there.
The selected agent's stored forges come from `GET /api/extra-forges?
agent=<name>` → `{ forges: [{ label, base_url }] }`, derived by scanning
the agent's state dir for `forge-<label>-token` files (mirrors the MATRIX
tab's filename-scan listing) with `base_url` backfilled from a sibling
`forge-<label>.json` sidecar. Submitting the add form posts `POST /api/
extra-forge-account` (form-encoded `agent, label, base_url, token,
action=add`) → `200 { ok: true }`, which writes both files through the
same privileged write path as the other tabs. Each row's `remove` button
opens a themed confirm dialog, then posts the same endpoint with
`action=remove`, deleting both local files — nothing changes on the
remote forge. The token is never echoed back in either direction.
A per-forge `hive-forge --forge <label>` CLI selector (to make `hive-forge`
target one of these accounts instead of the internal forge) is a
deliberate non-goal of this tab — tracked separately.
## P3RM1SS10NS tab
Per-agent permission configuration. Two sections, each rendered as a