From 589ace3438623e8402784add6aa4e1ebc79deac9 Mon Sep 17 00:00:00 2001 From: iris Date: Wed, 2 Sep 2026 20:25:48 +0200 Subject: [PATCH] agent term: add a setting to hide debug-level output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hyperhive#4008, mara: 'add a setting to not display verbose output... like the grey colored debug stuff.' Same shape as the existing expand-tool-output preference (ExpandDetailsSetting.tsx): a new shared/src/prefs.ts key pair (getHideDebugPref/setHideDebugPref), a new settings-menu-row component owning its own state (HideDebugSetting.tsx, not a prop threaded through the shared SettingsMenu component — per mara's earlier review on the first one, more per-page options as props there is how that component accumulates cruft), mounted next to ExpandDetailsSetting in Root.tsx. Row.tsx skips (returns null for, not CSS display:none) any TermMsg whose level is 'debug' when the pref is set — matches the muted 'debug' row this issue is about (see docs/web-ui/terminal-rendering.md's Levels table). Read live per-row, same as expand-details, so toggling applies to newly streamed rows in an already-open tab without a reload; already -rendered rows are unaffected either way, same non-retroactive precedent the existing preference already sets. --- docs/web-ui/terminal-rendering.md | 5 ++++ frontend/packages/agent/src/Root.tsx | 2 ++ .../agent/src/components/HideDebugSetting.tsx | 25 ++++++++++++++++ .../packages/agent/src/components/Row.tsx | 8 ++++- frontend/packages/shared/src/prefs.ts | 29 +++++++++++++++++-- 5 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 frontend/packages/agent/src/components/HideDebugSetting.tsx diff --git a/docs/web-ui/terminal-rendering.md b/docs/web-ui/terminal-rendering.md index 35798fa0..a6e100aa 100644 --- a/docs/web-ui/terminal-rendering.md +++ b/docs/web-ui/terminal-rendering.md @@ -35,6 +35,11 @@ leading the summary text rather than the icon. | `warn` | amber, left rule | stderr, an unrecognised event shape, API retries | | `error` | red, left rule | turn failed, a tool result with `is_error: true` | +The settings menu's "hide debug output" toggle (`getHideDebugPref()`, +`@hive/shared/prefs.js`) skips `debug`-level rows entirely rather than +muting them further — client-side only, same live-read-no-reload shape +as the expand-tool-output preference above. + Per-tool icon + summary formatting (what a `Read`/`Edit`/`send` call's row actually says) lives in `stream_enrich.rs`'s `fmt_tool_use()` family — read that when you need the specifics, this doc doesn't duplicate it. diff --git a/frontend/packages/agent/src/Root.tsx b/frontend/packages/agent/src/Root.tsx index 8c29be4f..23d7fed4 100644 --- a/frontend/packages/agent/src/Root.tsx +++ b/frontend/packages/agent/src/Root.tsx @@ -12,6 +12,7 @@ import { useApplyMotionOverride } from "@hive/shared/motion-apply.js"; import { Header } from "./components/Header.js"; import { MetaNav } from "./components/MetaNav.js"; import { ExpandDetailsSetting } from "./components/ExpandDetailsSetting.js"; +import { HideDebugSetting } from "./components/HideDebugSetting.js"; import { StatusChips } from "./components/StatusChips.js"; import { LiveStream, type LiveStreamHandle } from "./components/LiveStream.js"; import { HeaderPill } from "./components/HeaderPill.js"; @@ -151,6 +152,7 @@ export function Root() { ) : null} + ); diff --git a/frontend/packages/agent/src/components/HideDebugSetting.tsx b/frontend/packages/agent/src/components/HideDebugSetting.tsx new file mode 100644 index 00000000..bff063ae --- /dev/null +++ b/frontend/packages/agent/src/components/HideDebugSetting.tsx @@ -0,0 +1,25 @@ +// Agent-terminal-only settings-menu row: "hide debug output". Same shape +// as `ExpandDetailsSetting` (its own file's header comment explains why +// this lives here rather than as a `SettingsMenu` prop) — mara: "add a +// setting to not display verbose output... like the grey colored debug +// stuff." +import { useState } from "preact/hooks"; +import { getHideDebugPref, setHideDebugPref } from "@hive/shared/prefs.js"; + +export function HideDebugSetting() { + const [hideDebug, setHideDebugState] = useState(() => getHideDebugPref()); + return ( + + ); +} diff --git a/frontend/packages/agent/src/components/Row.tsx b/frontend/packages/agent/src/components/Row.tsx index 8ff6d1ca..18ade774 100644 --- a/frontend/packages/agent/src/components/Row.tsx +++ b/frontend/packages/agent/src/components/Row.tsx @@ -10,7 +10,7 @@ import { useEffect, useRef } from "preact/hooks"; import type { TermRow } from "../lib/termMsg.js"; import { linkifyToNodes } from "../lib/linkify.js"; import { renderMarkdown } from "../lib/markdown.js"; -import { getExpandDetailsPref } from "@hive/shared/prefs.js"; +import { getExpandDetailsPref, getHideDebugPref } from "@hive/shared/prefs.js"; function MarkdownBody({ text }: { text: string }) { const ref = useRef(null); @@ -51,6 +51,12 @@ function DiffBody({ text }: { text: string }) { } export function Row({ row }: { row: TermRow }) { + // "hide debug output" is a skip, not a dimmer — a hidden debug row + // still occupies no DOM node at all, same as it never streamed, rather + // than a CSS `display: none` that would keep it in the layout/DOM for + // no benefit. + if (row.level === "debug" && getHideDebugPref()) return null; + const cssClass = "level-" + row.level; const icon = row.icon != null && row.icon !== "" && ( {row.icon} diff --git a/frontend/packages/shared/src/prefs.ts b/frontend/packages/shared/src/prefs.ts index 4e927483..4ba17362 100644 --- a/frontend/packages/shared/src/prefs.ts +++ b/frontend/packages/shared/src/prefs.ts @@ -2,8 +2,9 @@ // 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` (the per-agent page's own settings popover) is -// the only writer today; `Row.tsx` is the only reader. +// `ExpandDetailsSetting` / `HideDebugSetting` (the per-agent page's own +// settings popover rows) are the only writers today; `Row.tsx` is the +// only reader of either. const EXPAND_DETAILS_KEY = "hive-agent-expand-details"; @@ -29,3 +30,27 @@ export function setExpandDetailsPref(v: boolean): void { /* 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 */ + } +}