diff --git a/frontend/packages/agent/src/app.js b/frontend/packages/agent/src/app.js index 3ae0125d..2af2ab26 100644 --- a/frontend/packages/agent/src/app.js +++ b/frontend/packages/agent/src/app.js @@ -39,28 +39,24 @@ window.marked = marked; // ─── side panel (singleton drawer for inbox + loose-ends flyouts) ────── // Thin wrapper around the shared `` element (see - // @hive/shared/side-panel.js) — created and appended to lazily - // on first use, same pattern `themedToast` uses for its toast-stack - // container. This UI's `open(name, title, content)` always takes an - // owner name, so it maps straight onto the shared element's - // `openNamed`; `side-panel-body` is a plain compatibility class this - // wrapper puts on its own instance so `agent.css`'s existing - // `.side-panel-body .agent-inbox …` rules keep reaching the slotted - // content by ordinary light-DOM descendant matching. - let panelEl = null; - function ensurePanel() { - if (!panelEl) { - panelEl = document.createElement('hive-side-panel'); - panelEl.classList.add('side-panel-body'); - document.body.append(panelEl); - } - return panelEl; - } + // @hive/shared/side-panel.js) — created once, eagerly, when this + // module's IIFE runs (ES modules execute after the document is + // parsed, so `document.body` already exists; no per-call lazy-init + // guard to remember for any method, present or future). This UI's + // `open(name, title, content)` always takes an owner name, so it maps + // straight onto the shared element's `openNamed`; `side-panel-body` + // is a plain compatibility class this wrapper puts on its own + // instance so `agent.css`'s existing `.side-panel-body .agent-inbox + // …` rules keep reaching the slotted content by ordinary light-DOM + // descendant matching. + const panelEl = document.createElement('hive-side-panel'); + panelEl.classList.add('side-panel-body'); + document.body.append(panelEl); const Panel = { - open: (name, title, content) => ensurePanel().openNamed(name, title, content), - close: () => ensurePanel().close(), - refresh: (name, title, content) => ensurePanel().refresh(name, title, content), - currentOwner: () => ensurePanel().currentOwner(), + open: (name, title, content) => panelEl.openNamed(name, title, content), + close: () => panelEl.close(), + refresh: (name, title, content) => panelEl.refresh(name, title, content), + currentOwner: () => panelEl.currentOwner(), }; // Wire the header pills to open the side panel. Pre-built (vs diff --git a/frontend/packages/dashboard/src/common.js b/frontend/packages/dashboard/src/common.js index 56b5e22d..5acc6518 100644 --- a/frontend/packages/dashboard/src/common.js +++ b/frontend/packages/dashboard/src/common.js @@ -287,27 +287,23 @@ export function openBuildLogStream(id, pre, { onDone, onError } = {}) { // // Thin wrapper around the shared `` element (see // @hive/shared/side-panel.js for the chrome/behavior it owns, including -// drag-to-resize) — the instance is created and appended to -// lazily on first use, same pattern `themedToast` uses for its -// toast-stack container. `side-panel-body` is a plain compatibility +// drag-to-resize). The instance is created once, eagerly, at module +// evaluation time — ES modules run after the document is parsed (same +// timing `defer` scripts get), so `document.body` already exists here; +// no per-call lazy-init guard needed, and no easy-to-forget step for +// any new method added later. `side-panel-body` is a plain compatibility // class this wrapper puts on its own instance so `common.css`'s // existing `.side-panel-body .md …` rules keep reaching the slotted // content by ordinary light-DOM descendant matching — the shared // element itself has no idea that class name means anything. -let panelEl = null; -function ensurePanel() { - if (!panelEl) { - panelEl = document.createElement('hive-side-panel'); - panelEl.classList.add('side-panel-body'); - document.body.append(panelEl); - } - return panelEl; -} +const panelEl = document.createElement('hive-side-panel'); +panelEl.classList.add('side-panel-body'); +document.body.append(panelEl); export const Panel = { - open: (title, content) => ensurePanel().open(title, content), - openNamed: (name, title, content) => ensurePanel().openNamed(name, title, content), - refresh: (name, title, content) => ensurePanel().refresh(name, title, content), - close: () => ensurePanel().close(), + open: (title, content) => panelEl.open(title, content), + openNamed: (name, title, content) => panelEl.openNamed(name, title, content), + refresh: (name, title, content) => panelEl.refresh(name, title, content), + close: () => panelEl.close(), }; // ─── path linkification ─────────────────────────────────────────────────