diff --git a/src/web/public/app.js b/src/web/public/app.js index 41a953ff..b636f9fc 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -265,12 +265,14 @@ class ClaudemanApp { const data = JSON.parse(e.data); this.sessions.delete(data.id); this.terminalBuffers.delete(data.id); + this.innerStates.delete(data.id); // Clean up inner state for this session if (this.activeSessionId === data.id) { this.activeSessionId = null; this.terminal.clear(); this.showWelcome(); } this.renderSessionTabs(); + this.renderInnerStatePanel(); // Update inner panel after session deleted }); this.eventSource.addEventListener('session:terminal', (e) => { @@ -718,6 +720,7 @@ class ClaudemanApp { } else { this.terminal.clear(); this.showWelcome(); + this.renderInnerStatePanel(); // Clear inner panel when no sessions } } @@ -1970,8 +1973,24 @@ class ClaudemanApp { } toggleInnerStatePanel() { + // Preserve xterm scroll position to prevent jump when panel height changes + const xtermViewport = this.terminal?.element?.querySelector('.xterm-viewport'); + const scrollTop = xtermViewport?.scrollTop; + this.innerStatePanelCollapsed = !this.innerStatePanelCollapsed; this.renderInnerStatePanel(); + + // Restore scroll position and refit terminal after layout change + requestAnimationFrame(() => { + // Restore xterm scroll position + if (xtermViewport && scrollTop !== undefined) { + xtermViewport.scrollTop = scrollTop; + } + // Refit terminal to new container size + if (this.terminal && this.fitAddon) { + this.fitAddon.fit(); + } + }); } toggleRalphDetach() { @@ -2099,14 +2118,6 @@ class ClaudemanApp { // Update stats this.updateRalphStats(state?.loop, completed, total); - // Update phrase preview - const phrasePreview = this.$('ralphPhrasePreview'); - if (phrasePreview && state?.loop?.completionPhrase) { - phrasePreview.innerHTML = `${this.escapeHtml(state.loop.completionPhrase)}`; - } else if (phrasePreview) { - phrasePreview.textContent = ''; - } - // Handle collapsed/expanded state if (this.innerStatePanelCollapsed) { panel.classList.add('collapsed'); diff --git a/src/web/public/styles.css b/src/web/public/styles.css index fdc84b9b..451d91af 100644 --- a/src/web/public/styles.css +++ b/src/web/public/styles.css @@ -462,6 +462,7 @@ body { flex-shrink: 0; overflow: hidden; position: relative; + overflow-anchor: none; /* Prevent scroll anchoring when expanding/collapsing */ } /* Mini Progress Ring (in summary) */ @@ -557,23 +558,6 @@ body { 50% { opacity: 0.6; transform: scale(1.2); } } -.ralph-phrase-preview { - color: var(--text-dim); - font-size: 0.7rem; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 200px; -} - -.ralph-phrase-preview code { - background: var(--bg-input); - padding: 0.1rem 0.3rem; - border-radius: 2px; - font-family: 'SF Mono', Monaco, monospace; - font-size: 0.65rem; -} - /* Summary Stats */ .ralph-summary-stats { display: flex;