diff --git a/tests/test_tui_gateway_server.py b/tests/test_tui_gateway_server.py index dacc55df5b..84877ae2e9 100644 --- a/tests/test_tui_gateway_server.py +++ b/tests/test_tui_gateway_server.py @@ -879,6 +879,36 @@ def test_config_set_statusbar_survives_non_dict_display(tmp_path, monkeypatch): assert saved["display"]["tui_statusbar"] == "bottom" +def test_config_set_details_mode_pins_all_sections(tmp_path, monkeypatch): + import yaml + + cfg_path = tmp_path / "config.yaml" + cfg_path.write_text( + yaml.safe_dump( + {"display": {"sections": {"tools": "expanded", "activity": "hidden"}}} + ) + ) + monkeypatch.setattr(server, "_hermes_home", tmp_path) + + resp = server.handle_request( + { + "id": "1", + "method": "config.set", + "params": {"key": "details_mode", "value": "collapsed"}, + } + ) + + assert resp["result"] == {"key": "details_mode", "value": "collapsed"} + saved = yaml.safe_load(cfg_path.read_text()) + assert saved["display"]["details_mode"] == "collapsed" + assert saved["display"]["sections"] == { + "thinking": "collapsed", + "tools": "collapsed", + "subagents": "collapsed", + "activity": "collapsed", + } + + def test_config_set_section_writes_per_section_override(tmp_path, monkeypatch): import yaml diff --git a/tui_gateway/server.py b/tui_gateway/server.py index fee8e9550e..6b8ce6b267 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -3130,7 +3130,15 @@ def _(rid, params: dict) -> dict: allowed_dm = frozenset({"hidden", "collapsed", "expanded"}) if nv not in allowed_dm: return _err(rid, 4002, f"unknown details_mode: {value}") - _write_config_key("display.details_mode", nv) + cfg = _load_cfg() + display = cfg.get("display") if isinstance(cfg.get("display"), dict) else {} + sections = display.get("sections") if isinstance(display.get("sections"), dict) else {} + display["details_mode"] = nv + for section in ("thinking", "tools", "subagents", "activity"): + sections[section] = nv + display["sections"] = sections + cfg["display"] = display + _save_cfg(cfg) return _ok(rid, {"key": key, "value": nv}) if key.startswith("details_mode."): diff --git a/ui-tui/src/__tests__/createSlashHandler.test.ts b/ui-tui/src/__tests__/createSlashHandler.test.ts index 3ec340b8a2..6c38b52734 100644 --- a/ui-tui/src/__tests__/createSlashHandler.test.ts +++ b/ui-tui/src/__tests__/createSlashHandler.test.ts @@ -141,6 +141,12 @@ describe('createSlashHandler', () => { expect(createSlashHandler(ctx)('/details toggle')).toBe(true) expect(getUiState().detailsMode).toBe('expanded') expect(getUiState().detailsModeCommandOverride).toBe(true) + expect(getUiState().sections).toEqual({ + thinking: 'expanded', + tools: 'expanded', + subagents: 'expanded', + activity: 'expanded' + }) expect(ctx.gateway.rpc).toHaveBeenCalledWith('config.set', { key: 'details_mode', value: 'expanded' diff --git a/ui-tui/src/app/slash/commands/core.ts b/ui-tui/src/app/slash/commands/core.ts index 1b29366361..f9b54c34c1 100644 --- a/ui-tui/src/app/slash/commands/core.ts +++ b/ui-tui/src/app/slash/commands/core.ts @@ -266,7 +266,9 @@ export const coreCommands: SlashCommand[] = [ return transcript.sys(DETAILS_USAGE) } - patchUiState({ detailsMode: next, detailsModeCommandOverride: true }) + const sections = Object.fromEntries(SECTION_NAMES.map(section => [section, next])) + + patchUiState({ detailsMode: next, detailsModeCommandOverride: true, sections }) gateway.rpc('config.set', { key: 'details_mode', value: next }).catch(() => {}) transcript.sys(`details: ${next}`) }