diff --git a/frontend/packages/dashboard/src/call.js b/frontend/packages/dashboard/src/call.js index c0b478ff..83d205c2 100644 --- a/frontend/packages/dashboard/src/call.js +++ b/frontend/packages/dashboard/src/call.js @@ -22,9 +22,17 @@ import { questionsState, QUESTION_HISTORY_LIMIT } from './state.js'; // Registered by the dashboard entry at boot; defaults to a no-op so the // module is safe to call before wiring. let onCountsChanged = () => {}; +// Re-render the SW4RM container rows (their per-agent question-count badges +// read questionsState). `renderContainersFromState` is a tabs.js closure-local +// — not in this module's scope — so the entry injects it here via `initCall`, +// same pattern as `onCountsChanged`. Referencing it directly threw +// `ReferenceError: renderContainersFromState is not defined` and aborted the +// `question_added` / `question_resolved` SSE handlers. +let onContainersDirty = () => {}; export function initCall(opts = {}) { if (typeof opts.onCountsChanged === 'function') onCountsChanged = opts.onCountsChanged; + if (typeof opts.onContainersDirty === 'function') onContainersDirty = opts.onContainersDirty; } // ─── operator inbox — unread agent→operator messages ──────────── @@ -438,7 +446,7 @@ export function applyQuestionAdded(ev) { question_refs: ev.question_refs || [], }); renderQuestions(); - renderContainersFromState(); + onContainersDirty(); } export function applyQuestionResolved(ev) { const idx = questionsState.pending.findIndex((q) => q.id === ev.id); @@ -468,7 +476,7 @@ export function applyQuestionResolved(ev) { } } renderQuestions(); - renderContainersFromState(); + onContainersDirty(); } // Filter selection for the questions section. Persisted so the // operator's preferred view (all / operator-targeted / peer) diff --git a/frontend/packages/dashboard/src/tabs.js b/frontend/packages/dashboard/src/tabs.js index 0b3325cd..c35e036f 100644 --- a/frontend/packages/dashboard/src/tabs.js +++ b/frontend/packages/dashboard/src/tabs.js @@ -1592,7 +1592,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 }); + initCall({ onCountsChanged: refreshTabCounts, onContainersDirty: renderContainersFromState }); // Tab count pills — pure derived data from the existing state