diff --git a/app.py b/app.py index ba877de..25e91c0 100644 --- a/app.py +++ b/app.py @@ -2566,8 +2566,8 @@ def clear_history(): os.unlink(file_path) elif os.path.isdir(file_path): shutil.rmtree(file_path) - except Exception: - pass + except Exception as exc: + logger.warning("Failed to remove execution log entry %s: %s", file_path, exc) # Clear session logs if os.path.exists(SESSION_LOG_DIR): @@ -2578,8 +2578,8 @@ def clear_history(): os.unlink(file_path) elif os.path.isdir(file_path): shutil.rmtree(file_path) - except Exception: - pass + except Exception as exc: + logger.warning("Failed to remove session log entry %s: %s", file_path, exc) return jsonify({ 'success': True, diff --git a/ui/app.js b/ui/app.js index bf7725b..ef95cca 100644 --- a/ui/app.js +++ b/ui/app.js @@ -63,6 +63,7 @@ let state = { activeTerminalId: 1, nextTerminalId: 2, autoScroll: {}, // per-terminal auto-scroll toggle: { termId: bool } + terminalWordWrap: localStorage.getItem('terminal-word-wrap') !== 'false', workspaceRestored: false, workspaceProfiles: [], restoreMode: 'full', @@ -890,6 +891,7 @@ document.addEventListener('DOMContentLoaded', async () => { initResizers(); await restoreSession(); applyTerminalDensity(); + applyTerminalWordWrap(); // Initialize auto-scroll as enabled for terminal 1 state.autoScroll[1] = true; @@ -2501,6 +2503,29 @@ function updateAutoScrollBtn(termId, isOn) { persistWorkspace(); } +function applyTerminalWordWrap(enabled = state.terminalWordWrap) { + state.terminalWordWrap = enabled; + + document.querySelectorAll('.cli-body').forEach(body => { + body.classList.toggle('terminal-word-wrap-off', !enabled); + }); + + const btn = document.getElementById('btn-word-wrap'); + if (btn) { + btn.classList.toggle('active', enabled); + btn.title = enabled ? 'Word wrap: On' : 'Word wrap: Off'; + btn.setAttribute('aria-pressed', String(enabled)); + } +} + +function toggleTerminalWordWrap() { + const enabled = !state.terminalWordWrap; + localStorage.setItem('terminal-word-wrap', String(enabled)); + applyTerminalWordWrap(enabled); + persistWorkspace(); + notify(`Terminal word wrap ${enabled ? 'enabled' : 'disabled'}.`, 'info'); +} + const TERMINAL_DENSITIES = ['compact', 'normal', 'relaxed']; function getTerminalDensity() { @@ -3472,6 +3497,12 @@ function bindEvents() { updateAutoScrollBtn(state.activeTerminalId, true); } + const btnWordWrap = document.getElementById('btn-word-wrap'); + if (btnWordWrap) { + btnWordWrap.addEventListener('click', toggleTerminalWordWrap); + applyTerminalWordWrap(); + } + const densityControl = document.getElementById('terminal-density-control'); if (densityControl) { densityControl.addEventListener('click', (event) => { diff --git a/ui/index.html b/ui/index.html index 58399eb..6a98a14 100644 --- a/ui/index.html +++ b/ui/index.html @@ -339,6 +339,17 @@

Scripts

+