Skip to main content
Glama
terminal-protocol-mismatch-reproduction.test.ts5.17 kB
/** * Terminal Protocol Mismatch Reproduction Test * * CRITICAL TEST: Reproduces the protocol mismatch between client JavaScript and server * that prevents the Interactive Terminal Epic from functioning properly. * * ROOT CAUSE: JavaScript sends {data: "command\r"}, server expects {command: "command", commandId: "cmd_123"} */ import { readFileSync } from 'fs'; import { join } from 'path'; describe('Terminal Protocol Mismatch Reproduction', () => { const projectRoot = process.cwd(); const jsHandlerPath = join(projectRoot, 'static', 'terminal-input-handler.js'); const tsHandlerPath = join(projectRoot, 'static', 'terminal-input-handler.ts'); test('FIXED: JavaScript client now uses correct protocol format', () => { const jsContent = readFileSync(jsHandlerPath, 'utf8'); // Check if JavaScript now uses correct protocol (after fix) const usesCommandField = jsContent.includes('command:'); const hasCommandId = jsContent.includes('commandId:'); const hasCommandIdGeneration = jsContent.includes('cmd_') && jsContent.includes('Date.now()'); // This test verifies the protocol is now correct expect(usesCommandField).toBe(true); // Now correctly sends 'command' expect(hasCommandId).toBe(true); // Has 'commandId' field expect(hasCommandIdGeneration).toBe(true); // Generates unique commandId // Verify the exact correct protocol structure const submitCommandMatch = jsContent.match(/webSocket\.send\(JSON\.stringify\(([\s\S]*?)\)\);/); if (submitCommandMatch) { const messageStructure = submitCommandMatch[1]; expect(messageStructure).toContain('command:'); expect(messageStructure).toContain('commandId:'); expect(messageStructure).not.toContain('data:'); // Should not use 'data' anymore } }); test('TypeScript source has correct protocol format', () => { const tsContent = readFileSync(tsHandlerPath, 'utf8'); // Verify TypeScript has the correct protocol expect(tsContent).toContain('command:'); expect(tsContent).toContain('commandId:'); expect(tsContent).toContain('type: \'terminal_input\''); expect(tsContent).toContain('sessionName:'); // Verify proper commandId generation expect(tsContent).toContain('cmd_${Date.now()}_${'); expect(tsContent).toContain('this.commandCounter'); }); test('PROTOCOL REQUIREMENTS: Define expected message structure', () => { // This test documents the required protocol structure const expectedProtocol = { type: 'terminal_input', sessionName: 'test-session', command: 'pwd', // NOT 'data' commandId: 'cmd_1730000000000_1', // REQUIRED for tracking timestamp: '2024-10-27T12:00:00.000Z' // OPTIONAL but good practice }; // Document requirements for fixing the JavaScript expect(expectedProtocol).toHaveProperty('type', 'terminal_input'); expect(expectedProtocol).toHaveProperty('sessionName'); expect(expectedProtocol).toHaveProperty('command'); // NOT 'data' expect(expectedProtocol).toHaveProperty('commandId'); // CRITICAL for server tracking expect(expectedProtocol.commandId).toMatch(/^cmd_\d+_\d+$/); }); test('CRITICAL FIX REQUIREMENTS: JavaScript must match TypeScript protocol', () => { // This test will fail until JavaScript is fixed to match TypeScript const jsContent = readFileSync(jsHandlerPath, 'utf8'); // After fix, JavaScript should match TypeScript protocol const hasCorrectProtocol = ( jsContent.includes('command:') && // Uses 'command' not 'data' jsContent.includes('commandId:') && // Has commandId for tracking jsContent.includes('type: \'terminal_input\'') && // Correct message type jsContent.includes('sessionName:') // Has session identification ); const hasCommandIdGeneration = ( jsContent.includes('cmd_') && jsContent.includes('Date.now()') && jsContent.includes('Math.random()') ); const removesTrailingCarriageReturn = !jsContent.includes('command + \'\\r\''); // These assertions will fail initially, then pass after the fix expect(hasCorrectProtocol).toBe(true); expect(hasCommandIdGeneration).toBe(true); expect(removesTrailingCarriageReturn).toBe(true); }); test('INTEGRATION REQUIREMENT: Verify server protocol expectations', () => { // Check that server-side code expects the correct protocol // This is a documentation test to ensure we understand server requirements const serverExpectations = { messageType: 'terminal_input', requiredFields: ['type', 'sessionName', 'command', 'commandId'], commandFieldName: 'command', // Server expects 'command' not 'data' commandIdPattern: /^cmd_\d+_\d+$/, noTrailingCR: true // Server adds \r, client should not }; // Document what the server expects expect(serverExpectations.requiredFields).toContain('command'); expect(serverExpectations.requiredFields).toContain('commandId'); expect(serverExpectations.commandFieldName).toBe('command'); expect(serverExpectations.noTrailingCR).toBe(true); }); });

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