agent term: move expand-tool-output setting into its own settings popup
mara, #3778: the toggle lived on the separate hive-dashboard's /settings.html even though it's agent-terminal-only. Moved it into SettingsMenu (shared with swarm-ui) behind an opt-in showExpandDetails prop — only the agent page passes it, matching her caution that the component is shared but this setting isn't. Also found and fixed a real regression while touching this: the Preact rewrite's classifyEvent.ts hardcodes defaultOpen: true only for the always-open markdown-bearing rows (send/ask/answer/recv) and never reads the preference at all for the rows it's actually meant to control (diffs, plain tool output, long errors) — so the toggle currently has zero effect on the live page. Wired getExpandDetailsPref() into those four sites; the always-open rows are untouched, matching the documented pre-rewrite behavior. Converted prefs.js to prefs.ts (TS couldn't resolve types for a plain .js import) — same public @hive/shared/prefs.js export path, matching how badge.js/icons.js etc. already map a .js export name to a .tsx/.ts source file.
This commit is contained in:
parent
22db09ec66
commit
385d4b6fd7
7 changed files with 70 additions and 43 deletions
|
|
@ -13,15 +13,20 @@ const EXPAND_DETAILS_KEY = 'hive-agent-expand-details';
|
|||
// 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 on /settings.html applies to the next
|
||||
// rendered row in any already-open agent tab without a reload.
|
||||
export function getExpandDetailsPref() {
|
||||
try { return localStorage.getItem(EXPAND_DETAILS_KEY) === '1'; }
|
||||
catch { return false; }
|
||||
// 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) {
|
||||
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 */ }
|
||||
} catch {
|
||||
/* localStorage unavailable — preference is session-only */
|
||||
}
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@ import { Badge } from '../badge/Badge.js';
|
|||
import { GearIcon } from '../icons.js';
|
||||
import { useThemeOverride, type ThemeOverride } from './theme-apply.js';
|
||||
import { useMotionOverride, type MotionOverride } from './motion-apply.js';
|
||||
import { getExpandDetailsPref, setExpandDetailsPref } from '../prefs.js';
|
||||
import './SettingsMenu.css';
|
||||
|
||||
const THEME_OPTIONS: ThemeOverride[] = ['system', 'light', 'dark'];
|
||||
|
|
@ -36,13 +37,29 @@ const MOTION_OPTIONS: MotionOverride[] = ['system', 'allow', 'reduce'];
|
|||
export interface SettingsMenuProps {
|
||||
themeKey: string;
|
||||
motionKey: string;
|
||||
/**
|
||||
* Show the "expand tool output panels" toggle — agent-terminal-only,
|
||||
* formerly its own section on the (separate) hive dashboard's
|
||||
* `/settings.html`. `SettingsMenu` is shared with swarm-ui too, which
|
||||
* has no terminal to apply this to (mara: "settigs dropdown is
|
||||
* shared component, but the setting is only in the agent term") — so
|
||||
* it's opt-in per consumer rather than always rendered. Only the
|
||||
* agent page passes this; swarm-ui's `Shell` doesn't.
|
||||
*/
|
||||
showExpandDetails?: boolean;
|
||||
}
|
||||
|
||||
export function SettingsMenu({ themeKey, motionKey }: SettingsMenuProps) {
|
||||
export function SettingsMenu({ themeKey, motionKey, showExpandDetails }: SettingsMenuProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
const [theme, setTheme] = useThemeOverride(themeKey);
|
||||
const [motion, setMotion] = useMotionOverride(motionKey);
|
||||
// Plain localStorage read, not a hook-managed override like theme/motion
|
||||
// above — `getExpandDetailsPref`/`setExpandDetailsPref` (`../prefs.js`)
|
||||
// are the existing shared-storage-key pair the terminal itself already
|
||||
// reads live (no round-trip needed here beyond re-rendering this menu's
|
||||
// own checkbox state on toggle).
|
||||
const [expandDetails, setExpandDetailsState] = useState(() => getExpandDetailsPref());
|
||||
|
||||
// Close on an outside click or Escape — only listens while open.
|
||||
useEffect(() => {
|
||||
|
|
@ -98,6 +115,20 @@ export function SettingsMenu({ themeKey, motionKey }: SettingsMenuProps) {
|
|||
))}
|
||||
</select>
|
||||
</label>
|
||||
{showExpandDetails ? (
|
||||
<label class="settings-menu-row">
|
||||
<span>expand tool output</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={expandDetails}
|
||||
onChange={(e) => {
|
||||
const v = (e.target as HTMLInputElement).checked;
|
||||
setExpandDetailsPref(v);
|
||||
setExpandDetailsState(v);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue