// Tiny browser-local (localStorage) preference helper, in `@hive/shared` // so a future second consumer (e.g. swarm-ui's own terminal) gets the // exact same key name for free via the browser's shared per-origin // storage, rather than an independent copy that could drift. // `ExpandDetailsSetting` / `HideDebugSetting` (the settings popover rows // of the per-agent page and of the swarm UI) are the only writers today; // `Row.tsx` is the only reader of either. const EXPAND_DETAILS_KEY = "hive-agent-expand-details"; // Whether a per-agent terminal's otherwise-collapsed `
` panels // (long tool-results, Write/Edit diffs, …) should default open. Pure // client-side — no backend field, nothing round-trips through // `/api/*`. Read live (not cached) by the shared terminal factory's // `expandDetails` option — see docs/web-ui/shape.md::Shared terminal // pane — so a preference change applies to the next rendered row in // any already-open agent tab without a reload. export function getExpandDetailsPref(): boolean { try { return localStorage.getItem(EXPAND_DETAILS_KEY) === "1"; } catch { return false; } } export function setExpandDetailsPref(v: boolean): void { try { if (v) localStorage.setItem(EXPAND_DETAILS_KEY, "1"); else localStorage.removeItem(EXPAND_DETAILS_KEY); } catch { /* localStorage unavailable — preference is session-only */ } } const HIDE_DEBUG_KEY = "hive-agent-hide-debug"; // Whether a per-agent terminal's `debug`-level rows (thinking, coalesced // ticks, ambient harness chatter — see docs/web-ui/terminal-rendering.md's // Levels table) should be skipped entirely rather than rendered muted. // Same shape as `getExpandDetailsPref` above: pure client-side, no // backend field, read live (not cached) so a change applies to the next // rendered row without a reload. export function getHideDebugPref(): boolean { try { return localStorage.getItem(HIDE_DEBUG_KEY) === "1"; } catch { return false; } } export function setHideDebugPref(v: boolean): void { try { if (v) localStorage.setItem(HIDE_DEBUG_KEY, "1"); else localStorage.removeItem(HIDE_DEBUG_KEY); } catch { /* localStorage unavailable — preference is session-only */ } for (const listener of hideDebugListeners) listener(); } const hideDebugListeners = new Set<() => void>(); // Calls `listener` whenever the preference changes: in this tab through // `setHideDebugPref`, in another tab of the same origin through the // browser's `storage` event. Returns the unsubscribe. This is what lets a // terminal that is already showing rows follow the toggle, instead of only // the rows that arrive after it. export function subscribeHideDebugPref(listener: () => void): () => void { hideDebugListeners.add(listener); const onStorage = (e: StorageEvent) => { if (e.key === HIDE_DEBUG_KEY || e.key === null) listener(); }; window.addEventListener("storage", onStorage); return () => { hideDebugListeners.delete(listener); window.removeEventListener("storage", onStorage); }; }