From 8c448315c1c0a1e10aa84f970ed5955c221b2271 Mon Sep 17 00:00:00 2001 From: uroma Date: Mon, 19 Jan 2026 18:43:20 +0000 Subject: [PATCH] fix: initialize xterm.js before connecting WebSocket Critical fix for completely broken terminal (blinking cursor, no input). Root Cause: The WebSocket was being connected before xterm.js was initialized, causing the WebSocket reference to be lost because this.terminals map didn't have the entry yet. Broken Flow: 1. createTerminalUI() - Creates DOM elements only 2. connectTerminal() - Tries to store ws in terminal, but terminal = null 3. WebSocket reference lost immediately 4. No input/output possible Fixed Flow: 1. createTerminalUI() - Creates DOM elements 2. initializeXTerm() - Creates xterm.js instance AND stores in map 3. connectTerminal() - Now finds terminal in map, stores ws successfully 4. switchToTerminal() - Terminal works! Changes: - Add explicit initializeXTerm() call before connectTerminal() - Add error checking in connectTerminal() to verify terminal exists - Add comments enforcing ordering requirements Resolves: "All I see is blinging | and nothing else, no claude cli, no commands, i cant type in anything. terminal is not woring." Co-Authored-By: Claude Sonnet 4.5 --- public/claude-ide/terminal.js | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/public/claude-ide/terminal.js b/public/claude-ide/terminal.js index 66041a0b..123470e0 100644 --- a/public/claude-ide/terminal.js +++ b/public/claude-ide/terminal.js @@ -213,7 +213,11 @@ class TerminalManager { // Create terminal UI await this.createTerminalUI(terminalId, selectedDir, mode); - // Connect WebSocket + // Initialize xterm.js FIRST (before connecting WebSocket) + // This ensures this.terminals map has the entry ready + await this.initializeXTerm(terminalId); + + // NOW connect WebSocket (terminal entry exists in map) await this.connectTerminal(terminalId); // Switch to new terminal @@ -773,6 +777,19 @@ class TerminalManager { ws.onopen = () => { console.log(`[TerminalManager] Connected to terminal ${terminalId}`); + + // Store WebSocket in terminal entry + // NOTE: This assumes initializeXTerm() has already been called + // and this.terminals has the entry + const terminal = this.terminals.get(terminalId); + if (terminal) { + terminal.ws = ws; + } else { + console.error(`[TerminalManager] CRITICAL: Terminal ${terminalId} not found in map! WebSocket connection will be lost.`); + reject(new Error(`Terminal ${terminalId} not initialized`)); + return; + } + resolve(); }; @@ -789,12 +806,6 @@ class TerminalManager { ws.onclose = () => { console.log(`[TerminalManager] WebSocket closed for terminal ${terminalId}`); }; - - // Store WebSocket - const terminal = this.terminals.get(terminalId); - if (terminal) { - terminal.ws = ws; - } } catch (error) { console.error('[TerminalManager] Error connecting WebSocket:', error); reject(error); @@ -908,11 +919,12 @@ class TerminalManager { this.sendTerminalResize(terminalId, cols, rows); }); - // Store terminal instance + // Store terminal instance in map + // This MUST happen before connectTerminal() is called this.terminals.set(terminalId, { terminal, fitAddon, - ws: null, + ws: null, // Will be set by connectTerminal() container, mode: 'mixed' });