dashboard: move queued reminders into SCH3DUL3S tab (closes #460)

mara wanted one place for everything that fires at a future time.
The QU3U3D R3M1ND3RS section moves out of the SYST3M tab and
lands at the bottom of the SCH3DUL3S tab, below QU3U3D SCH3DUL3S.

Pure layout change — refreshReminders() and /api/reminders
unchanged; the section just lives under a different parent now.
Reminders don't contribute to the SCH3DUL3S pill count (kept as
"active schedules" only — reminders are self-scheduled and high
cardinality; adding them would make the pill noisy).

docs/web-ui.md picks up a SCH3DUL3S tab section (the previous
docs lumped the schedules subsection under SYST3M, but the tab
has been separate since #459); reminders subsection follows
schedules in the same tab.
This commit is contained in:
iris 2026-05-26 13:39:42 +02:00
commit 4fdc061c9d
2 changed files with 53 additions and 35 deletions

View file

@ -122,15 +122,16 @@ the previous process's socket release resolves itself.
The dashboard (`/`) has a fixed chrome header at the top and a
`<main>` that shows exactly one tab pane at a time. The URL hash
(`#swarm`, `#call`, `#system`) drives which pane is active; hash
changes don't reload the page. FL0W is a separate full-page
terminal at `/flow.html` — its tab-strip entry is a cross-page
link (`◆ FL0W ◆ →`), not a pane swap.
(`#swarm`, `#call`, `#system`, `#schedules`) drives which pane is
active; hash changes don't reload the page. FL0W is a separate
full-page terminal at `/flow.html` — its tab-strip entry is a
cross-page link (`◆ FL0W ◆ →`), not a pane swap.
**Chrome header** (fixed, overlays the active tab pane):
- **Tab strip**: `◆ SW4RM ◆`, `◆ Y3R C4LL ◆`, `◆ SYST3M ◆`, and
`◆ FL0W ◆ →` (page link). Count pills on SW4RM (container count)
and Y3R C4LL (pending approvals + questions); FL0W pill mirrors
- **Tab strip**: `◆ SW4RM ◆`, `◆ Y3R C4LL ◆`, `◆ SYST3M ◆`,
`◆ SCH3DUL3S ◆`, and `◆ FL0W ◆ →` (page link). Count pills on
SW4RM (container count), Y3R C4LL (pending approvals +
questions), and SCH3DUL3S (active schedules); FL0W pill mirrors
the operator inbox length (hidden when zero).
- **Notification controls**: `🔔 enable notifications` when
permission ungranted; `🔕 mute / 🔔 unmute` toggle once granted.
@ -211,20 +212,25 @@ entries tick elapsed seconds live. Cold-loaded from
`/api/state.rebuild_queue`; live updates via `rebuild_queue_changed`
snapshot event.
**QU3U3D R3M1ND3RS** — reminders agents have scheduled for
themselves (via the `remind` tool) but not yet delivered.
Each row shows the owner, due time, and message; a `CANC3L`
button hard-deletes (`POST /cancel-reminder/{id}`) and a
`R3TRY` button re-arms one whose delivery failed
(`POST /retry-reminder/{id}`). Backed by `GET /api/reminders`.
**K3PT ST4T3** — destroyed-but-state-kept tombstones (size +
age + claude-creds badge). Two actions: `⊕ R3V1V3` (queues a
Spawn approval; existing state is reused), `PURG3` (wipes
state + applied dirs; `POST /purge-tombstone/{name}`).
**SCH3DUL3D PR0MPTS** — operator-managed scheduled prompts
(#444 / #459). Lists every schedule with its description,
targets, body, recurrence interval, next-fire time, and
per-target last-result; a `CANC3L` button cancels the whole
schedule (`POST /api/schedules/{id}/cancel`), and individual
target chips have their own cancel links. An inline creation
form lets the operator queue a new schedule directly:
### SCH3DUL3S tab
Anything that fires at a future time. Operator-set schedules
go through the creation form at the top; agent self-paced
reminders surface at the bottom as a sibling list (#460
they share enough conceptual ground to live together).
**N3W SCH3DUL3 / QU3U3D SCH3DUL3S** — operator-managed
scheduled prompts (#444 / #459). Lists every schedule with
its description, targets, body, recurrence interval, next-fire
time, and per-target last-result; a `CANC3L` button cancels
the whole schedule (`POST /api/schedules/{id}/cancel`), and
individual target chips have their own cancel links. An inline
creation form lets the operator queue a new schedule directly:
targets (multi-select checkboxes drawn from live container
names + `operator` + `manager`), prompt body (textarea),
first-fire datetime-local (pre-filled to 5 minutes from now),
@ -235,10 +241,14 @@ the count of active schedules (at least one live target not
yet cancelled). Refreshed on tab activation and after each
submit/cancel. Backed by `GET /api/schedules`.
**K3PT ST4T3** — destroyed-but-state-kept tombstones (size +
age + claude-creds badge). Two actions: `⊕ R3V1V3` (queues a
Spawn approval; existing state is reused), `PURG3` (wipes
state + applied dirs; `POST /purge-tombstone/{name}`).
**QU3U3D R3M1ND3RS** — reminders agents have scheduled for
themselves (via the `remind` tool) but not yet delivered.
Each row shows the owner, due time, and message; a `CANC3L`
button hard-deletes (`POST /cancel-reminder/{id}`) and a
`R3TRY` button re-arms one whose delivery failed
(`POST /retry-reminder/{id}`). Backed by `GET /api/reminders`.
Lives in the SCH3DUL3S tab alongside operator schedules so the
operator has one place for everything time-fired (#460).
### FL0W page (`/flow.html`)

View file

@ -104,10 +104,12 @@
</section>
<!-- SYST3M: passive / rare-interaction state. Meta inputs (lock
bumps), rebuild queue (watch only), queued reminders, kept
state from previous tombstoned agents. Headings stay; the
per-section content auto-compresses to a one-line summary
when empty (separate JS toggle). -->
bumps), rebuild queue (watch only), kept state from previous
tombstoned agents. Queued reminders moved to the SCH3DUL3S
tab in #460 — they're conceptually "fire X at time Y" too,
just self-scheduled by agents instead of operator-set.
Headings stay; the per-section content auto-compresses to a
one-line summary when empty (separate JS toggle). -->
<section class="tab-pane" id="tab-pane-system"
role="tabpanel" aria-labelledby="tab-system">
<h2>◆ M3T4 1NPUTS ◆</h2>
@ -124,13 +126,6 @@
<p class="meta">loading…</p>
</div>
<h2>◆ QU3U3D R3M1ND3RS ◆</h2>
<div class="divider">══════════════════════════════════════════════════════════════</div>
<p class="meta">reminders agents have queued for themselves but not yet delivered. cancel to drop a stuck or unwanted entry.</p>
<div id="reminders-section">
<p class="meta">loading…</p>
</div>
<h2>◆ K3PT ST4T3 ◆</h2>
<div class="divider">══════════════════════════════════════════════════════════════</div>
<div id="tombstones-section">
@ -161,6 +156,19 @@
<div id="schedules-section">
<p class="meta">loading…</p>
</div>
<!-- QU3U3D R3M1ND3RS (#460): self-scheduled agent reminders.
Moved here from the SYST3M tab so the operator has one
place for everything that fires at a future time —
operator-set schedules above, agent-self reminders here.
Backed by GET /api/reminders; refresh handled by
refreshReminders() (called from refreshState). -->
<h2>◆ QU3U3D R3M1ND3RS ◆</h2>
<div class="divider">══════════════════════════════════════════════════════════════</div>
<p class="meta">reminders agents have queued for themselves but not yet delivered. cancel to drop a stuck or unwanted entry.</p>
<div id="reminders-section">
<p class="meta">loading…</p>
</div>
</section>
<!-- FL0W: lives on its own page now (`/flow.html`). The