dashboard: remove the Y3R C4LL questions pane (ask/answer removal, frontend)

This commit is contained in:
damocles 2026-08-29 20:32:34 +02:00 committed by mara
commit ff0a6660aa
16 changed files with 74 additions and 680 deletions

View file

@ -38,14 +38,12 @@ import {
refreshOperatorInbox, operatorInboxAppendFromEvent, operatorInboxCount,
syncApprovalsFromSnapshot, applyApprovalAdded, applyApprovalResolved,
renderApprovals, activeApprovalCount,
syncQuestionsFromSnapshot, applyQuestionAdded, applyQuestionResolved,
renderQuestions, activeQuestionCount,
} from './call.js';
import {
initJobqRollup, syncTransientsFromSnapshot,
applyRebuildQueueChanged, applyContainerStateChanged, applyContainerRemoved,
applyTransientSet, applyTransientCleared,
renderContainers, renderContainersFromState,
renderContainers,
renderSelectionBar,
} from './swarm.js';
@ -59,21 +57,18 @@ window.marked = marked;
// doesn't re-fire for the same row. Keyed by stable ids; reset only
// when the page reloads.
const seenApprovals = new Set();
const seenQuestions = new Set();
let seededNotify = false;
function notifyDeltas(s) {
const approvals = s.approvals || [];
const questions = s.questions || [];
if (!seededNotify) {
// First render after page load — fill the "seen" sets without
// First render after page load — fill the "seen" set without
// firing notifications. We only want to notify on NEW items
// that arrived while the page is open. The inbox no longer
// needs seeding here: it's derived from the broker stream which
// does its own per-event notification on live arrival, and
// history-replayed events are silent by virtue of `fromHistory`.
for (const a of approvals) seenApprovals.add(a.id);
for (const q of questions) seenQuestions.add(q.id);
seededNotify = true;
return;
}
@ -86,14 +81,6 @@ window.marked = marked;
NOTIF.show('◆ approval #' + a.id, `${verb} for ${a.agent}`,
'hyperhive:approval:' + a.id);
}
for (const q of questions) {
if (seenQuestions.has(q.id)) continue;
seenQuestions.add(q.id);
const targetLabel = q.target || 'operator';
NOTIF.show(`${q.asker}${targetLabel} asks`,
q.question.slice(0, 120),
'hyperhive:question:' + q.id);
}
}
// ─── async forms ────────────────────────────────────────────────────────
@ -137,7 +124,6 @@ window.marked = marked;
// tick (or a manual action) will pick it up after they blur.
const MANAGED_SECTION_IDS = [
'containers-section',
'questions-section',
'inbox-section',
'approvals-section',
'schedules-section',
@ -239,12 +225,9 @@ window.marked = marked;
// mount's own effect handles the actual fetch.
initJobqRollup();
renderContainers(s);
// Sync the derived approvals + questions stores from the
// snapshot, then render. Live `*_added` / `*_resolved` events
// mutate the stores directly and re-render without a snapshot
// refetch.
syncQuestionsFromSnapshot(s);
renderQuestions();
// Sync the derived approvals store from the snapshot, then
// render. Live `*_added` / `*_resolved` events mutate the store
// directly and re-render without a snapshot refetch.
// (renderInbox now lives in ./flow.js — dashboard has no
// #inbox-section element to render into.)
syncApprovalsFromSnapshot(s);
@ -255,7 +238,7 @@ window.marked = marked;
// No periodic refresh timer. Phase 6 covers every container
// mutation with `ContainerStateChanged` / `ContainerRemoved`
// (lifecycle ops, destroy, rebuild, crash_watch's 10s poll);
// approvals + questions + transients have their own events;
// approvals + transients have their own events;
// broker traffic flows through the SSE channel. The only
// /api/state fetches are the initial cold load and the
// post-submit refetch on forms without `data-no-refresh`
@ -275,8 +258,8 @@ window.marked = marked;
// operator opens the tab. Live updates arrive via the broker stream.
refreshOperatorInbox();
// NOTIF.bind() (the enable/mute/unmute toggle UI) moved to /settings.html
// with the S3TT1NGS page. The dashboard keeps NOTIF.show() for approval/
// question notifications — it reads the browser permission + localStorage
// with the S3TT1NGS page. The dashboard keeps NOTIF.show() for approval
// notifications — it reads the browser permission + localStorage
// mute flag the settings page sets, so no bind() is needed here. The
// side panel (<hive-side-panel>) wires its own internals in
// connectedCallback — no bind() step needed either.
@ -300,8 +283,6 @@ window.marked = marked;
const MUTATION_HANDLERS = {
approval_added: applyApprovalAdded,
approval_resolved: applyApprovalResolved,
question_added: applyQuestionAdded,
question_resolved: applyQuestionResolved,
transient_set: applyTransientSet,
transient_cleared: applyTransientCleared,
container_state_changed: applyContainerStateChanged,
@ -327,13 +308,13 @@ window.marked = marked;
//
// kinds= matches MUTATION_HANDLERS below verbatim, plus `sent`
// (checked separately, just above, for the operator inbox) —
// narrows this from all 17 wire kinds down to the 13 this page
// narrows this from all 17 wire kinds down to the 11 this page
// actually acts on. This page was one of 4 unfiltered
// `/api/dashboard/stream` subscribers before this (subscription
// discipline, part 1 of the dashboard-event-stream-split issue).
const es = openStream(
'/api/dashboard/stream?kinds=sent,approval_added,approval_resolved,' +
'question_added,question_resolved,transient_set,transient_cleared,' +
'transient_set,transient_cleared,' +
'container_state_changed,container_removed,rebuild_queue_changed,' +
'schedules_changed,capabilities_changed,tool_groups_changed',
);
@ -414,7 +395,7 @@ window.marked = marked;
// Register the Y3R C4LL domain's count callback (call.js) — its live
// mutations (inbox stream append, mark-read) trigger a tab-count refresh
// through this instead of reaching back into the coordinator directly.
initCall({ onCountsChanged: refreshTabCounts, onContainersDirty: renderContainersFromState });
initCall({ onCountsChanged: refreshTabCounts });
// Tab count pills — pure derived data from the existing state
@ -443,11 +424,9 @@ window.marked = marked;
if (c.needs_update) swarm++;
}
setTabCount('swarm', swarm);
// Y3R C4LL — pending approvals + operator-targeted questions +
// unread agent->operator messages.
// Y3R C4LL — pending approvals + unread agent->operator messages.
const callCount =
activeApprovalCount() +
activeQuestionCount() +
operatorInboxCount();
setTabCount('call', callCount);
// Browser tab title prefix — lets the operator see the pending