docs(web-ui/dashboard): fix wrong API paths and add missing build-log + schedule endpoints

Several paths in the dashboard docs had bugs:

- /dashboard/stream and /dashboard/history were missing the /api/
  prefix (7 occurrences). Verified correct paths from frontend source:
  flow.js:212 ('/api/dashboard/history'), core.js:305, tabs.js:1517,
  builds.js:624 (all '/api/dashboard/stream'); backend routes match.
- GET /api/build-logs/stream/{id} was wrong; the actual route (and
  what common.js:323 calls) is GET /api/build-logs/id/{id}/stream.

Also adds two missing endpoint entries to the API reference section:

- GET /api/build-logs/id/{id}/stream (the live SSE stream)
- GET /api/build-logs/id/{id}/raw (the plain-text download link)
- POST /api/schedules/{id}/pause and /resume (mentioned in prose at
  the SCH3DUL3S section but absent from the endpoint list)

The POST /meta-update prefix fix is already in-flight on a separate
branch; left untouched here to avoid conflict.
This commit is contained in:
iris 2026-07-02 22:14:25 +02:00 committed by mara
commit e5916f95a3

View file

@ -129,7 +129,7 @@ standalone page reached from the **Core** tile on the H0M3 hub (served at
back-link + a `createTabStrip` sub-tab nav (**R3BU1LD QU3U3** default, back-link + a `createTabStrip` sub-tab nav (**R3BU1LD QU3U3** default,
then **M3T4 1NPUTS**, **K3PT ST4T3**, **C0NT41N3R L04D**). The page is its then **M3T4 1NPUTS**, **K3PT ST4T3**, **C0NT41N3R L04D**). The page is its
own esbuild bundle (`core.js`) that cold-loads `/api/state` and subscribes own esbuild bundle (`core.js`) that cold-loads `/api/state` and subscribes
to `/dashboard/stream` for the same live events as the dashboard to `/api/dashboard/stream` for the same live events as the dashboard
(`rebuild_queue_changed`, `meta_inputs_changed`, `meta_update_running`, (`rebuild_queue_changed`, `meta_inputs_changed`, `meta_update_running`,
`tombstones_changed`). The dashboard keeps the rebuild-queue *state* (it `tombstones_changed`). The dashboard keeps the rebuild-queue *state* (it
drives the "building…" badges on SW4RM agent cards) but no longer renders drives the "building…" badges on SW4RM agent cards) but no longer renders
@ -570,8 +570,8 @@ dashboard's Y3R C4LL tab (◆ 1NB0X ◆ section, with per-message and
mark-all read). FL0W stays the pure event firehose. mark-all read). FL0W stays the pure event firehose.
**MESS4GE FL0W** — live broker tail wrapped in a `.terminal-wrap`. **MESS4GE FL0W** — live broker tail wrapped in a `.terminal-wrap`.
Cold load backfills the last ~200 messages from `/dashboard/history`; Cold load backfills the last ~200 messages from `/api/dashboard/history`;
live frames arrive on `/dashboard/stream`. Each row is one broker live frames arrive on `/api/dashboard/stream`. Each row is one broker
event — `sent` or `delivered` — with `from → to: body`. When a `sent` event — `sent` or `delivered` — with `from → to: body`. When a `sent`
and `delivered` event for the same message arrive within 3 seconds and `delivered` event for the same message arrive within 3 seconds
(immediate delivery to a live recipient), the row is upgraded in place (immediate delivery to a live recipient), the row is upgraded in place
@ -636,7 +636,7 @@ Expanding a row fetches the full stdout+stderr via
A live in-progress build shows a `live` badge with an elapsed-time A live in-progress build shows a `live` badge with an elapsed-time
chip that ticks every second (updated by a `setInterval` on the chip that ticks every second (updated by a `setInterval` on the
row; cleared when the build finishes or the stream errors). Expanding row; cleared when the build finishes or the stream errors). Expanding
a live row streams its output via `GET /api/build-logs/stream/{id}` a live row streams its output via `GET /api/build-logs/id/{id}/stream`
(newline-delimited JSON frames) with **sticky-bottom auto-scroll**: (newline-delimited JSON frames) with **sticky-bottom auto-scroll**:
the stream scrolls to keep the latest output visible as long as the the stream scrolls to keep the latest output visible as long as the
operator hasn't scrolled up manually; once the operator scrolls up, operator hasn't scrolled up manually; once the operator scrolls up,
@ -680,7 +680,7 @@ execution failure. `ts_unix` is an RFC 3339 string; a 30 s ticker keeps the
relative "ago" column honest while the tab is in view. The backing relative "ago" column honest while the tab is in view. The backing
`audit_log` store records every privileged-action attempt (ok / err / `audit_log` store records every privileged-action attempt (ok / err /
denied). New entries live-append without a refresh: an `audit_entry_added` denied). New entries live-append without a refresh: an `audit_entry_added`
event on `/dashboard/stream` (the flattened row) is prepended to the table event on `/api/dashboard/stream` (the flattened row) is prepended to the table
and the "latest N of M" count bumped, de-duped by id against the cold and the "latest N of M" count bumped, de-duped by id against the cold
fetch. fetch.
@ -1086,6 +1086,14 @@ that's a browser-level decision, not ours.
`BuildLogFull` (JSON): all header fields plus `stdout` and `BuildLogFull` (JSON): all header fields plus `stdout` and
`stderr` as plain text (newline-terminated lines, utf-8). HTTP `stderr` as plain text (newline-terminated lines, utf-8). HTTP
404 when the row is missing (vacuum-reaped or stale id). 404 when the row is missing (vacuum-reaped or stale id).
- `GET /api/build-logs/id/{id}/stream` — live SSE stream of
stdout+stderr for an in-progress build (newline-delimited JSON
frames). Used by the expanding live-row view in BU1LDS. The
stream closes when the build finishes or errors.
- `GET /api/build-logs/id/{id}/raw` — raw concatenated
stdout+stderr as `text/plain`. Used by the `↓ raw` / `↓ download
raw` links in BU1LDS. Works on both finished and in-progress
build logs.
- `GET /api/journal/{name}?unit=&lines=` — journalctl viewer for - `GET /api/journal/{name}?unit=&lines=` — journalctl viewer for
a managed container; rendered in the side panel. a managed container; rendered in the side panel.
- `GET /api/audit-log` — agent-initiated privileged-action audit - `GET /api/audit-log` — agent-initiated privileged-action audit
@ -1119,7 +1127,7 @@ that's a browser-level decision, not ours.
so directories, missing files, and forbidden subtrees never so directories, missing files, and forbidden subtrees never
become anchors. No probe endpoint, no client-side regex become anchors. No probe endpoint, no client-side regex
heuristics. Historical messages get the same treatment on heuristics. Historical messages get the same treatment on
`/dashboard/history` backfill. `/api/dashboard/history` backfill.
- `GET /api/reminders` — list pending reminders for the - `GET /api/reminders` — list pending reminders for the
dashboard's queued-reminders panel. dashboard's queued-reminders panel.
- `GET /api/stats-hive?window=<1h|4h|24h|3d|7d|30d|all>` — hive-wide - `GET /api/stats-hive?window=<1h|4h|24h|3d|7d|30d|all>` — hive-wide
@ -1211,18 +1219,23 @@ that's a browser-level decision, not ours.
Per-target `last_result` is annotated as a manual fire so Per-target `last_result` is annotated as a manual fire so
the audit trail distinguishes scheduled fires from operator- the audit trail distinguishes scheduled fires from operator-
triggered ones. triggered ones.
- `POST /api/schedules/{id}/pause` — pause a recurring or
one-shot schedule. A paused schedule does not fire regardless
of `next_fire_at`; the row gains a `⏸ paused` badge.
- `POST /api/schedules/{id}/resume` — resume a paused schedule.
Clears the pause flag without adjusting `next_fire_at`.
- `POST /api/meta-update``nix flake update` the selected - `POST /api/meta-update``nix flake update` the selected
`meta/flake.lock` inputs, then rebuild the affected agents. `meta/flake.lock` inputs, then rebuild the affected agents.
- `GET /dashboard/stream` — unified live event channel: - `GET /api/dashboard/stream` — unified live event channel:
broker `sent` / `delivered`, plus the mutation events listed broker `sent` / `delivered`, plus the mutation events listed
below. Each frame carries `seq`. below. Each frame carries `seq`.
- `GET /dashboard/history` — last ~200 broker messages - `GET /api/dashboard/history` — last ~200 broker messages
(wrapped as `{ seq, events }`) for the message-flow (wrapped as `{ seq, events }`) for the message-flow
terminal's backfill on page load. terminal's backfill on page load.
## Dashboard event channel ## Dashboard event channel
Wire vocabulary on `/dashboard/stream` (kind tag is in the JSON Wire vocabulary on `/api/dashboard/stream` (kind tag is in the JSON
payload): payload):
- `sent` / `delivered` — broker traffic, mirrored from the - `sent` / `delivered` — broker traffic, mirrored from the
@ -1302,7 +1315,7 @@ forms that mutate non-event-derived state** (PURG3 +
meta-update, since tombstones + meta_inputs aren't event- meta-update, since tombstones + meta_inputs aren't event-
shaped yet). Every other section — approvals, questions, shaped yet). Every other section — approvals, questions,
transients, containers, operator inbox, message flow — transients, containers, operator inbox, message flow —
derives from `/dashboard/stream` after the initial snapshot, derives from `/api/dashboard/stream` after the initial snapshot,
maintaining its own client-side store and applying events on maintaining its own client-side store and applying events on
top. The 5s periodic poll is gone. top. The 5s periodic poll is gone.