Release v0.51.249 — Release HQ (stage-q21) (#3523)
Some checks failed
Release & Docker / release (push) Has been cancelled

## Release v0.51.249 — Release HQ (stage-q21)

Small opt-in feature. UX-approved (screenshot of the toggle in Settings → Preferences).

### Added
| Issue | Author | Feature |
|-------|--------|---------|
| #2974 | @rodboev | **"Auto-expand terminal on output"** preference (Settings → Preferences, **off by default**). When enabled, the collapsed embedded terminal panel expands automatically the first time a running command emits output. Fires once per stream (guarded on open && collapsed — not per chunk), and uses `expandComposerTerminal({focus:false})` so it doesn't steal focus from the composer. Backend-persisted boolean mirroring the `simplified_tool_calling` pattern; default-off = no behavior change on upgrade. |

### Gate
- Full pytest suite: **7557 passed, 0 failed**
- ESLint: CLEAN · ruff: CLEAN · browser-smoke: CLEAN · screenshot vision-verified (toggle renders cleanly under "Compact tool activity", unchecked by default)
- Codex (regression): **SAFE TO SHIP** (clean first pass) — no-arg `expandComposerTerminal` callers unchanged, default-off incl. settings-load-failure path, all 5 plumb sites mirror the existing pattern

Co-authored-by: rodboev <rodboev@users.noreply.github.com>
This commit is contained in:
nesquena-hermes
2026-06-03 20:15:53 -07:00
committed by GitHub
parent d828be6daa
commit 0501564098
7 changed files with 58 additions and 2 deletions

View File

@@ -3,6 +3,11 @@
## [Unreleased]
## [v0.51.249] — 2026-06-03 — Release HQ (stage-q21 — auto-expand terminal on output toggle)
### Added
- New **"Auto-expand terminal on output"** preference (Settings → Preferences, **off by default**). When enabled, the collapsed embedded terminal panel surfaces itself automatically the first time a running command emits output, so long-running command output isn't silently collected behind a collapsed panel. The auto-expand does not steal focus from the composer, and fires once per stream (not per output chunk). Mirrors the existing `simplified_tool_calling` setting pattern; default-off means no behavior change on upgrade. (#2974, @rodboev)
## [v0.51.248] — 2026-06-03 — Release HP (stage-q20 — self-heal deleted WebUI sessions instead of bricking the chat)
### Fixed

View File

@@ -5050,6 +5050,7 @@ _SETTINGS_DEFAULTS = {
"notifications_enabled": False, # browser notification when tab is in background
"show_thinking": True, # show/hide thinking/reasoning blocks in chat view
"simplified_tool_calling": True, # render tools/thinking as compact inline timeline activity
"terminal_auto_expand_on_output": False, # auto-expand terminal panel when output arrives while collapsed
"api_redact_enabled": True, # redact sensitive data (API keys, secrets) from API responses
"dashboard_plugins": {}, # plugin_name -> bool, opt-in per plugin (default off per PF-10b)
"sidebar_density": "compact", # compact | detailed
@@ -5196,6 +5197,7 @@ _SETTINGS_BOOL_KEYS = {
"notifications_enabled",
"show_thinking",
"simplified_tool_calling",
"terminal_auto_expand_on_output",
"api_redact_enabled",
"session_jump_buttons",
"session_endless_scroll",

View File

@@ -1687,6 +1687,7 @@ function applyBotName(){
window._whatsNewSummaryEnabled=!!s.whats_new_summary_enabled;
window._showThinking=s.show_thinking!==false;
window._simplifiedToolCalling=s.simplified_tool_calling!==false;
window._terminalAutoExpandOnOutput=!!s.terminal_auto_expand_on_output;
window._activityFeedExpandedDefault=!!s.activity_feed_expanded_default;
window._sidebarDensity=(s.sidebar_density==='detailed'?'detailed':'compact');
window._pinnedSessionsLimit=parseInt(s.pinned_sessions_limit||3,10)||3;
@@ -1784,6 +1785,7 @@ function applyBotName(){
window._whatsNewSummaryEnabled=false;
window._showThinking=true;
window._simplifiedToolCalling=true;
window._terminalAutoExpandOnOutput=false;
window._sessionJumpButtonsEnabled=false;
window._sidebarDensity='compact';
window._pinnedSessionsLimit=3;

View File

@@ -1146,6 +1146,13 @@
</label>
<div style="font-size:11px;color:var(--muted);margin-top:4px">Show thinking and tool calls as compact inline activity while preserving the agent timeline.</div>
</div>
<div class="settings-field">
<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
<input type="checkbox" id="settingsTerminalAutoExpand" style="width:15px;height:15px;accent-color:var(--accent)">
<span>Auto-expand terminal on output</span>
</label>
<div style="font-size:11px;color:var(--muted);margin-top:4px">Expand the collapsed terminal panel automatically when a running command emits new output.</div>
</div>
<div class="settings-field">
<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
<input type="checkbox" id="settingsApiRedact" checked style="width:15px;height:15px;accent-color:var(--accent)">

View File

@@ -5961,6 +5961,8 @@ function _preferencesPayloadFromUi(){
if(fadeTextCb) payload.fade_text_effect=fadeTextCb.checked;
const simplifiedToolCb=$('settingsSimplifiedToolCalling');
if(simplifiedToolCb) payload.simplified_tool_calling=simplifiedToolCb.checked;
const terminalAutoExpandCb=$('settingsTerminalAutoExpand');
if(terminalAutoExpandCb) payload.terminal_auto_expand_on_output=terminalAutoExpandCb.checked;
const apiRedactCb=$('settingsApiRedact');
if(apiRedactCb) payload.api_redact_enabled=apiRedactCb.checked;
const showCliCb=$('settingsShowCliSessions');
@@ -6035,6 +6037,9 @@ async function _autosavePreferencesSettings(payload){
if(typeof clearMessageRenderCache==='function') clearMessageRenderCache();
if(typeof renderMessages==='function') renderMessages();
}
if(payload&&payload.terminal_auto_expand_on_output!==undefined){
window._terminalAutoExpandOnOutput=!!(saved&&saved.terminal_auto_expand_on_output);
}
if(payload&&Object.prototype.hasOwnProperty.call(payload,'fade_text_effect')) window._fadeTextEffect=!!payload.fade_text_effect;
if(saved&&Object.prototype.hasOwnProperty.call(saved,'pinned_sessions_limit')) window._pinnedSessionsLimit=parseInt(saved.pinned_sessions_limit,10)||3;
if(payload&&payload.show_tps!==undefined){
@@ -6265,6 +6270,8 @@ async function loadSettingsPanel(){
if(fadeTextCb){fadeTextCb.checked=!!settings.fade_text_effect;window._fadeTextEffect=fadeTextCb.checked;fadeTextCb.addEventListener('change',_schedulePreferencesAutosave,{once:false});}
const simplifiedToolCb=$('settingsSimplifiedToolCalling');
if(simplifiedToolCb){simplifiedToolCb.checked=settings.simplified_tool_calling!==false;simplifiedToolCb.addEventListener('change',_schedulePreferencesAutosave,{once:false});}
const terminalAutoExpandCb=$('settingsTerminalAutoExpand');
if(terminalAutoExpandCb){terminalAutoExpandCb.checked=!!settings.terminal_auto_expand_on_output;window._terminalAutoExpandOnOutput=terminalAutoExpandCb.checked;terminalAutoExpandCb.addEventListener('change',_schedulePreferencesAutosave,{once:false});}
const apiRedactCb=$('settingsApiRedact');
if(apiRedactCb){apiRedactCb.checked=settings.api_redact_enabled!==false;apiRedactCb.addEventListener('change',_schedulePreferencesAutosave,{once:false});}
const showCliCb=$('settingsShowCliSessions');
@@ -7322,6 +7329,7 @@ function _applySavedSettingsUi(saved, body, opts){
window._whatsNewSummaryEnabled=!!body.whats_new_summary_enabled;
window._showThinking=body.show_thinking!==false;
window._simplifiedToolCalling=body.simplified_tool_calling!==false;
window._terminalAutoExpandOnOutput=!!body.terminal_auto_expand_on_output;
window._sessionJumpButtonsEnabled=!!body.session_jump_buttons;
if(typeof _applySessionNavigationPrefs==='function') _applySessionNavigationPrefs();
window._sidebarDensity=sidebarDensity==='detailed'?'detailed':'compact';
@@ -7662,6 +7670,7 @@ async function saveSettings(andClose){
body.show_tps=showTps;
body.fade_text_effect=fadeTextEffect;
body.simplified_tool_calling=!!($('settingsSimplifiedToolCalling')||{}).checked;
body.terminal_auto_expand_on_output=!!($('settingsTerminalAutoExpand')||{}).checked;
body.api_redact_enabled=!!($('settingsApiRedact')||{}).checked;
body.show_cli_sessions=showCliSessions;
body.show_previous_messaging_sessions=showPreviousMessagingSessions;

View File

@@ -383,6 +383,7 @@ function _connectTerminalOutput(){
try{text=(JSON.parse(ev.data)||{}).text||'';}
catch(_){text=ev.data||'';}
if(TERMINAL_UI.term&&text)TERMINAL_UI.term.write(text);
if(text&&window._terminalAutoExpandOnOutput&&TERMINAL_UI.open&&TERMINAL_UI.collapsed)expandComposerTerminal({focus:false});
});
source.addEventListener('terminal_closed',()=>{
if(TERMINAL_UI.source!==source)return;
@@ -476,8 +477,9 @@ function collapseComposerTerminal(){
syncTerminalButton();
}
function expandComposerTerminal(){
function expandComposerTerminal(opts){
if(!TERMINAL_UI.open)return;
const focus = !opts || opts.focus !== false;
const {panel}= _terminalEls();
const messages=_terminalMessagesEl();
TERMINAL_UI.collapsed=false;
@@ -490,7 +492,7 @@ function expandComposerTerminal(){
_resetTerminalHeightForViewport();
requestAnimationFrame(()=>{
_fitTerminal();
focusComposerTerminalInput();
if(focus) focusComposerTerminalInput();
setTimeout(()=>{
if(panel)panel.classList.remove('is-expanding-from-dock');
if(messages)messages.classList.remove('terminal-expanding-from-dock');

View File

@@ -0,0 +1,29 @@
"""Regression tests for the terminal auto-expand-on-output setting."""
import json
def test_terminal_auto_expand_on_output_defaults_disabled_and_round_trips(monkeypatch, tmp_path):
import api.config as config
settings_path = tmp_path / "settings.json"
monkeypatch.setattr(config, "SETTINGS_FILE", settings_path)
loaded = config.load_settings()
assert loaded["terminal_auto_expand_on_output"] is False
saved = config.save_settings({"terminal_auto_expand_on_output": False})
assert saved["terminal_auto_expand_on_output"] is False
assert json.loads(settings_path.read_text(encoding="utf-8"))["terminal_auto_expand_on_output"] is False
saved = config.save_settings({"terminal_auto_expand_on_output": True})
assert saved["terminal_auto_expand_on_output"] is True
assert json.loads(settings_path.read_text(encoding="utf-8"))["terminal_auto_expand_on_output"] is True
def test_terminal_auto_expand_on_output_is_a_valid_boolean_setting():
import api.config as config
assert "terminal_auto_expand_on_output" in config._SETTINGS_DEFAULTS
assert "terminal_auto_expand_on_output" in config._SETTINGS_BOOL_KEYS
assert "terminal_auto_expand_on_output" in config._SETTINGS_ALLOWED_KEYS