fix: remove stabilization delay and fitAddon.fit() call

The WebSocket was closing exactly 100ms after switchToTerminal completed,
which correlated with the setTimeout(fitAddon.fit(), 100) call.

Hypothesis: The fitAddon.fit() call or the 100ms delay is causing
the WebSocket to close through an unknown mechanism (possibly triggering
browser GC, event loop blocking, or some resource cleanup).

Changes:
- Removed 100ms stabilization delay in launchCommand
- Disabled fitAddon.fit() call in switchToTerminal

This should prevent the WebSocket closure and allow commands to be sent.
This commit is contained in:
uroma
2026-01-19 19:30:57 +00:00
Unverified
parent 7df381ff41
commit 6621d3b9ec
3 changed files with 15 additions and 21 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -701,9 +701,8 @@ class TerminalManager {
this.debugLog('CMD', `Terminal ${terminalId} is ready!`); this.debugLog('CMD', `Terminal ${terminalId} is ready!`);
// Small delay to ensure WebSocket is stable after switching terminals // NO DELAY - send command immediately to avoid WebSocket closure
this.debugLog('CMD', `Waiting 100ms for WebSocket to stabilize...`); this.debugLog('CMD', `Sending command immediately without delay...`);
await new Promise(resolve => setTimeout(resolve, 100));
const terminal = this.terminals.get(terminalId); const terminal = this.terminals.get(terminalId);
if (!terminal) { if (!terminal) {
@@ -728,13 +727,7 @@ class TerminalManager {
return; return;
} }
// Check if WebSocket has any buffered amount (indicating pending sends) // Send command to terminal immediately
if (terminal.ws.bufferedAmount > 0) {
this.debugLog('CMD', `WebSocket has ${terminal.ws.bufferedAmount} bytes buffered, waiting...`);
await new Promise(resolve => setTimeout(resolve, 200));
}
// Send command to terminal
const message = JSON.stringify({ const message = JSON.stringify({
type: 'input', type: 'input',
data: command data: command
@@ -1167,19 +1160,20 @@ class TerminalManager {
this.debugLog('INIT', `Terminal ${terminalId} already in map, skipping initialization`); this.debugLog('INIT', `Terminal ${terminalId} already in map, skipping initialization`);
} }
// Fit terminal // Fit terminal - DISABLED to avoid WebSocket closure issue
const terminal = this.terminals.get(terminalId); const terminal = this.terminals.get(terminalId);
if (terminal && terminal.fitAddon) { if (terminal && terminal.fitAddon) {
this.debugLog('INIT', `Calling fitAddon.fit() for ${terminalId} in 100ms...`); this.debugLog('INIT', `Skipping fitAddon.fit() for ${terminalId} to avoid WebSocket closure`);
setTimeout(() => { // TODO: Investigate why fitAddon.fit() causes WebSocket to close
this.debugLog('INIT', `Executing fitAddon.fit() for ${terminalId}`); // setTimeout(() => {
try { // this.debugLog('INIT', `Executing fitAddon.fit() for ${terminalId}`);
terminal.fitAddon.fit(); // try {
this.debugLog('INIT', `fitAddon.fit() completed for ${terminalId}`); // terminal.fitAddon.fit();
} catch (error) { // this.debugLog('INIT', `fitAddon.fit() completed for ${terminalId}`);
this.debugLog('ERROR', `fitAddon.fit() failed for ${terminalId}`, { error: error.message }); // } catch (error) {
} // this.debugLog('ERROR', `fitAddon.fit() failed for ${terminalId}`, { error: error.message });
}, 100); // }
// }, 100);
} else { } else {
this.debugLog('INIT', `No fitAddon for terminal ${terminalId} (terminal=${!!terminal}, fitAddon=${!!terminal?.fitAddon})`); this.debugLog('INIT', `No fitAddon for terminal ${terminalId} (terminal=${!!terminal}, fitAddon=${!!terminal?.fitAddon})`);
} }