From 92f943c3e6b3a04cdfa5848c8a4f56fbb617b787 Mon Sep 17 00:00:00 2001 From: Augustin Date: Fri, 24 Apr 2026 15:53:13 +0200 Subject: [PATCH] fix(shell): add debug logging for tab tracking and WebSocket state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track which tab messages belong to via _tabId field to ensure AI responses are sent to the correct terminal tab. Add console.log in initTerminal, sendToTerminal for troubleshooting tab lifecycle issues. 💘 Generated with Crush Assisted-by: MiniMax-M2.7 via Crush --- web/src/components/Shell.jsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/web/src/components/Shell.jsx b/web/src/components/Shell.jsx index c24ebf8..50493b9 100644 --- a/web/src/components/Shell.jsx +++ b/web/src/components/Shell.jsx @@ -408,9 +408,11 @@ export default function Shell({ api }) { const bufferSaveInterval = setInterval(() => { if (!disposed) saveBuffer() }, 5000) + console.log(`[Shell] initTerminal tab=${tabId} type=${tab.type} container=${!!container}`) tabsRef.current[tabId] = { term, fitAddon, ws, resizeObserver, onResize, bufferSaveInterval, saveBuffer, disposed: () => disposed } const origDispose = () => { disposed = true } tabsRef.current[tabId]._markDisposed = origDispose + console.log(`[Shell] initTerminal tab=${tabId} done, tabsRef keys:`, Object.keys(tabsRef.current)) }, []) useEffect(() => { @@ -601,13 +603,14 @@ export default function Shell({ api }) { const targetId = tabId || activeTab const entry = tabsRef.current[targetId] if (!entry) { - console.warn('sendToTerminal: no terminal initialized for tab', targetId) + console.warn(`[Shell] sendToTerminal: tab ${targetId} not in tabsRef. Available:`, Object.keys(tabsRef.current), 'activeTab:', activeTab, 'requested tabId:', tabId) return } if (!entry.ws || entry.ws.readyState !== WebSocket.OPEN) { - console.warn('sendToTerminal: WebSocket not ready for tab', targetId) + console.warn(`[Shell] sendToTerminal: WebSocket not ready for tab ${targetId}, state:`, entry.ws?.readyState) return } + console.log(`[Shell] sendToTerminal: sending code to tab ${targetId} (${code.length} chars)`) entry.ws.send(JSON.stringify({ type: 'input', data: code + '\r' })) }, [activeTab]) @@ -646,7 +649,8 @@ export default function Shell({ api }) { return } - setAiMessages(prev => [...prev, { role: 'user', content: trimmed }]) + const currentTab = activeTab + setAiMessages(prev => [...prev, { role: 'user', content: trimmed, _tabId: currentTab }]) setAiLoading(true) try { @@ -655,13 +659,13 @@ export default function Shell({ api }) { accumulated = partial setAiMessages(prev => { const filtered = prev.filter(m => !m._streaming) - return [...filtered, { role: 'assistant', content: partial, _streaming: true }] + return [...filtered, { role: 'assistant', content: partial, _streaming: true, _tabId: currentTab }] }) }) setAiMessages(prev => { const filtered = prev.filter(m => !m._streaming) - return [...filtered, { role: 'assistant', content: accumulated }] + return [...filtered, { role: 'assistant', content: accumulated, _tabId: currentTab }] }) api.getShellChatHistory().then(d => { setAiTokens(d.tokens || 0) @@ -858,7 +862,7 @@ export default function Shell({ api }) {
{aiMessages.map((msg, i) => ( - + ))} {aiLoading &&
}