feat: live SSE updates for P3RM1SS10NS tab (capabilities + tool groups)

Add CapabilitiesChanged and ToolGroupsChanged DashboardEvent variants
so the P3RM1SS10NS tab reflects perm changes without the operator
navigating away and back.

Backend:
- DashboardEvent::CapabilitiesChanged { seq, caps, descriptions,
  assignments } — same payload shape as GET /api/capabilities
- DashboardEvent::ToolGroupsChanged { seq, groups, descriptions,
  assignments } — same payload shape as GET /api/tool-groups
- Coordinator::emit_capabilities_snapshot() and
  emit_tool_groups_snapshot() — read from the JSON files and broadcast
- rebuild_queue.rs PermChange worker: emit after each successful
  commit_capabilities / commit_tool_groups call

Frontend:
- applyCapabilitiesChanged(ev): calls renderCapabilities(root, ev)
- applyToolGroupsChanged(ev): calls renderToolGroups(root, ev)
- Both registered in MUTATION_HANDLERS
- activateTab comment updated (SSE now covers perm changes)

Docs: dashboard.md and CLAUDE.md updated.

This completes SSE coverage for all dashboard sections: SW4RM,
Y3R C4LL, SYST3M, SCH3DUL3S/reminders, and P3RM1SS10NS all
derive live updates from /dashboard/stream.
This commit is contained in:
iris 2026-06-05 10:21:37 +02:00 committed by mara
commit 2080fd3866
6 changed files with 117 additions and 5 deletions

View file

@ -857,9 +857,21 @@ payload):
reminder mutation: agent `remind` calls (`agent_server`),
operator cancel / retry (`/api/system/reminders/*`), `cancel_loose_end`
with Reminder kind, and the scheduler tick after each delivery
batch (`reminder_scheduler`). The SYST3M tab's reminders section
batch (`reminder_scheduler`). The SCH3DUL3S tab's reminders section
subscribes and calls `renderReminders` on receipt, so the list
updates live without polling.
- `capabilities_changed` (seq, caps: `Vec<str>`, descriptions: map,
assignments: `BTreeMap<String, Vec<String>>`) — full snapshot of
capability grants. Emitted from the rebuild-queue worker after a
`PermChange` / Capabilities entry commits the JSON file. Payload
matches `GET /api/capabilities` shape so `renderCapabilities` can
be called directly. P3RM1SS10NS tab subscribes; activation
re-fetch still runs as a safety net.
- `tool_groups_changed` (seq, groups: `Vec<str>`, descriptions: map,
assignments: `BTreeMap<String, Vec<String>>`) — full snapshot of
tool-group assignments. Emitted from the rebuild-queue worker after
a `PermChange` / ToolGroups entry commits the JSON file. Same
shape as `GET /api/tool-groups`; P3RM1SS10NS tab subscribes.
`/api/state` is **only fetched on cold-load and on the few
forms that mutate non-event-derived state** (PURG3 +