Skip to main content
Glama
terminal-catastrophic-failure-debug.test.ts7.91 kB
/** * Terminal Catastrophic Failure Debug Test * * Using Villenele framework to capture and analyze complete terminal failure: * 1. No typing echo - user can't see what they type * 2. Double command echo - commands appear twice * 3. Mangled output formatting - weird spacing and corruption * 4. Architectural protocol failures */ import { JestTestUtilities } from './integration/terminal-history-framework/jest-test-utilities'; describe('Terminal Catastrophic Failure Debug', () => { const testUtils = JestTestUtilities.setupJestEnvironment('terminal-catastrophic-failure-debug'); it('should capture exact failure patterns with typing and echo issues', async () => { // Test configuration to reproduce the exact failure scenario const config = { preWebSocketCommands: [ 'ssh_connect {"name": "debug-session", "host": "localhost", "username": "jsbattig", "keyFilePath": "/home/jsbattig/.ssh/id_ed25519"}' ], postWebSocketCommands: [ // Type "ls" command to test typing echo and command execution 'ssh_exec {"sessionName": "debug-session", "command": "ls"}' ], workflowTimeout: 30000, sessionName: 'debug-session' }; const result = await testUtils.runTerminalHistoryTest(config); // Capture exact WebSocket messages for analysis console.log('=== EXACT WEBSOCKET MESSAGES ==='); console.log('Length:', result.concatenatedResponses.length); // Split messages to analyze each one const messages = result.concatenatedResponses.split(/(?=\[jsbattig@localhost)/); messages.forEach((msg, idx) => { console.log(`\n--- Message ${idx + 1} ---`); // Show with visible control characters console.log('Raw:', JSON.stringify(msg)); console.log('Clean:', msg); // Check for specific failure patterns if (msg.includes('ls')) { console.log('FOUND "ls" command in message'); // Count occurrences of "ls" to detect double echo const lsCount = (msg.match(/\bls\b/g) || []).length; console.log(`"ls" appears ${lsCount} times`); if (lsCount > 1) { console.log('❌ DOUBLE ECHO DETECTED!'); } } // Check for mangled spacing (20+ spaces indicates a problem, 8 is a normal tab) const weirdSpacing = /\s{20,}/.test(msg); if (weirdSpacing) { console.log('❌ MANGLED SPACING DETECTED!'); // Show where the excessive spacing is const matches = msg.match(/[^\s]+\s{20,}[^\s]+/g); if (matches) { console.log('Excessive spacing found in:', matches[0]); } } }); // Analyze terminal protocol issues console.log('\n=== TERMINAL PROTOCOL ANALYSIS ==='); // Check for CRLF line endings (required for xterm.js) const hasCRLF = result.concatenatedResponses.includes('\r\n'); console.log('Has CRLF endings:', hasCRLF); // Check for command echo patterns const commandEchoPattern = /\$ ls\r?\n/; const hasCommandEcho = commandEchoPattern.test(result.concatenatedResponses); console.log('Has command echo after prompt:', hasCommandEcho); // Check for duplicate command output const outputLines = result.concatenatedResponses.split(/\r?\n/); const lsOutputPattern = /Applications|package\.json|bun\.lock/; const lsOutputLines = outputLines.filter(line => lsOutputPattern.test(line)); console.log('Number of lines with ls output:', lsOutputLines.length); if (lsOutputLines.length > 1) { console.log('❌ DUPLICATE OUTPUT DETECTED!'); lsOutputLines.forEach((line, idx) => { console.log(` Output ${idx + 1}:`, line.substring(0, 100)); }); } // Check for prompt patterns const promptPattern = /\[jsbattig@localhost[^\]]*\]\$/g; const prompts = result.concatenatedResponses.match(promptPattern) || []; console.log('Number of prompts found:', prompts.length); prompts.forEach((prompt, idx) => { console.log(` Prompt ${idx + 1}:`, prompt); }); // Precise assertions to validate failures // 1. Check for typing echo (should see "ls" after prompt) const typingEchoPattern = /\]\$ ls/; const hasTypingEcho = typingEchoPattern.test(result.concatenatedResponses); // 2. Check for double command echo const commandOccurrences = (result.concatenatedResponses.match(/\bls\b/g) || []).length; const hasDoubleEcho = commandOccurrences > 1; // 3. Check for mangled output (excessive spacing) const hasMangledOutput = /\s{20,}/.test(result.concatenatedResponses); // 4. Check for proper CRLF endings const hasProperLineEndings = result.concatenatedResponses.includes('\r\n'); // Report findings console.log('\n=== FAILURE ANALYSIS SUMMARY ==='); console.log('1. Typing Echo Present:', hasTypingEcho, hasTypingEcho ? '✅' : '❌ MISSING'); console.log('2. Double Command Echo:', hasDoubleEcho, hasDoubleEcho ? '❌ FAILURE' : '✅'); console.log('3. Mangled Output:', hasMangledOutput, hasMangledOutput ? '❌ FAILURE' : '✅'); console.log('4. CRLF Line Endings:', hasProperLineEndings, hasProperLineEndings ? '✅' : '❌ MISSING'); // These assertions will help identify the exact failures expect(hasTypingEcho).toBe(true); // Should see typed command expect(hasDoubleEcho).toBe(false); // Should not have double echo expect(hasMangledOutput).toBe(false); // Should not have mangled spacing expect(hasProperLineEndings).toBe(true); // Should have CRLF for xterm.js }); it('should analyze terminal input handler behavior', async () => { // This test specifically checks the browser-side terminal input handling const config = { preWebSocketCommands: [ 'ssh_connect {"name": "input-test", "host": "localhost", "username": "jsbattig", "keyFilePath": "/home/jsbattig/.ssh/id_ed25519"}' ], postWebSocketCommands: [ // Send multiple commands to test input handling 'ssh_exec {"sessionName": "input-test", "command": "echo test1"}', 'ssh_exec {"sessionName": "input-test", "command": "echo test2"}' ], workflowTimeout: 30000, sessionName: 'input-test' }; const result = await testUtils.runTerminalHistoryTest(config); console.log('\n=== INPUT HANDLER ANALYSIS ==='); // Check for echo patterns in each command const echoTest1Pattern = /echo test1/g; const echoTest1Count = (result.concatenatedResponses.match(echoTest1Pattern) || []).length; console.log('Occurrences of "echo test1":', echoTest1Count); const echoTest2Pattern = /echo test2/g; const echoTest2Count = (result.concatenatedResponses.match(echoTest2Pattern) || []).length; console.log('Occurrences of "echo test2":', echoTest2Count); // Check for command results const test1ResultPattern = /test1(?!\s*echo)/; // test1 not followed by echo const hasTest1Result = test1ResultPattern.test(result.concatenatedResponses); console.log('Has test1 result:', hasTest1Result); const test2ResultPattern = /test2(?!\s*echo)/; // test2 not followed by echo const hasTest2Result = test2ResultPattern.test(result.concatenatedResponses); console.log('Has test2 result:', hasTest2Result); // Terminal protocol check - look for specific patterns const lines = result.concatenatedResponses.split(/\r?\n/); lines.forEach((line, idx) => { if (line.includes('echo') || line.includes('test')) { console.log(`Line ${idx}:`, JSON.stringify(line)); } }); // Assertions expect(echoTest1Count).toBe(1); // Command should appear once expect(echoTest2Count).toBe(1); // Command should appear once expect(hasTest1Result).toBe(true); // Should see result expect(hasTest2Result).toBe(true); // Should see result }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/LightspeedDMS/ssh-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server