Compare commits

...
Author SHA1 Message Date
iris
1c4619015d docs(web-ui): document browser tab title call-count prefix 2026-06-05 13:12:33 +02:00
iris
e24cfba124 feat(dashboard): preserve call-count prefix on hive-identity title update
On refreshState, the hive-identity title update (fired once when
hive_name/swarm_name are configured) now reads any existing (N) prefix
and preserves it, so the title doesn't briefly drop back to the bare
identity string before refreshTabCounts re-applies the prefix.
2026-06-05 13:12:33 +02:00
iris
fa62417328 feat(dashboard): prefix browser tab title with pending call count
When approvals or questions are waiting, document.title is prefixed
with (N) so the operator can see activity in a background browser
tab without switching windows. Clears to the base title when zero.

Implemented in refreshTabCounts (1s tick): strips any existing
prefix before re-applying so the hive-identity title update (once
on state load) composes cleanly.
2026-06-05 13:12:33 +02:00
2 changed files with 20 additions and 1 deletions

View file

@ -26,6 +26,16 @@ swap.
`state.matrix_gui_enabled` from `/api/state`.
- **Banner-thin** (`░▒▓█▓▒░ HYPERHIVE / HIVE-C0RE / WE ARE THE WIRED ░▒▓█▓▒░`)
— sits below the tab strip.
- **Browser tab title**`hive / c0re` by default; updated to
`<swarm> / <hive>` once `hive_name` / `swarm_name` arrive in the
state snapshot. When there are pending approvals or unanswered
questions, a `(N)` prefix is prepended — `(3) pr1ma / hive-c0re`
— so the operator can see the call count in an unfocused browser
tab without opening the dashboard. The prefix is set on the
initial `/api/state` cold-load and updated live by
`approval_added` / `approval_resolved` / `question_added` /
`question_resolved` SSE events; it's preserved when
`hive_name` / `swarm_name` later replace the raw title.
The FL0W page reuses the same chrome strip but its `◆ S3TT1NGS ◆ →`
entry is a cross-page link back to the dashboard

View file

@ -3684,7 +3684,10 @@ window.marked = marked;
: hive || swarm;
hiveId.textContent = label;
hiveId.hidden = false;
document.title = label + ' // h1ve-c0re';
// Preserve any (N) call-count prefix already applied by
// refreshTabCounts so the title doesn't flicker on reload.
const existingPrefix = document.title.match(/^(\(\d+\) )/)?.[1] || '';
document.title = existingPrefix + label + ' // h1ve-c0re';
}
}
const openDetails = snapshotOpenDetails();
@ -4036,6 +4039,12 @@ window.marked = marked;
(approvalsState?.pending?.length ?? 0) +
(questionsState?.pending?.length ?? 0);
setTabCount('call', callCount);
// Browser tab title prefix — lets the operator see the pending
// call count without switching to the window. Strips any existing
// `(N) ` prefix before re-applying so identity-title updates
// (which run once on state load, not every tick) compose cleanly.
const rawTitle = document.title.replace(/^\(\d+\) /, '');
document.title = callCount > 0 ? `(${callCount}) ${rawTitle}` : rawTitle;
// SYST3M — queued + running rebuild_queue entries (terminal
// entries are kept for history but aren't 'attention').
let sysCount = 0;