Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/frontend/packages/shared/src/prefs.ts
iris 6739bb903d docs: sort the top-level directories into five sections by what the reader wants
Every docs directory moves under 1-getting-started, 2-handbook,
4-implementation or 5-project; the options reference (section 3) comes from
the website and has no directory here. trust-boundary stays whole under the
handbook for now. web-ui, swarm and tools split between handbook and
implementation, and the command-line references move to
2-handbook/reference. Links, path references in code and nix, and the docs
index follow the moves; no page content changes.
2026-11-06 18:46:57 +01:00

76 lines
3 KiB
TypeScript

// 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 `<details>` 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/4-implementation/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/4-implementation/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);
};
}