Skip to main content
Glama
ps1-export-silence-validation.test.ts7.48 kB
/** * VILLENELE VALIDATION: PS1 Export Command Silence Test * * This test validates that PS1 export commands are executed silently * and do not appear as visible output in the terminal display. * * ROOT ISSUE FIXED: export PS1='[\u@\h \W]\$ ' commands were appearing * as visible terminal output instead of executing silently. * * SOLUTION: Added >/dev/null 2>&1 to redirect output and make commands silent. */ import { JestTestUtilities } from './integration/terminal-history-framework/jest-test-utilities.js'; describe('PS1 Export Silence Validation - Villenele Framework', () => { const testSessionName = 'ps1-export-silence-test'; const testUtils = JestTestUtilities.setupJestEnvironment('ps1-export-silence-validation'); describe('CRITICAL FIX: Silent PS1 Export Commands', () => { it('should NOT display export PS1 commands as visible terminal output', async () => { // This test validates that PS1 configuration happens silently during initialization const config = { preWebSocketCommands: [ 'ssh_connect {"name": "' + testSessionName + '", "host": "localhost", "username": "jsbattig", "keyFilePath": "~/.ssh/id_ed25519"}', ], postWebSocketCommands: [ 'ssh_exec {"sessionName": "' + testSessionName + '", "command": "echo \\"test command output\\""}', 'ssh_exec {"sessionName": "' + testSessionName + '", "command": "pwd"}' ], workflowTimeout: 30000, sessionName: testSessionName }; const result = await testUtils.runTerminalHistoryTest(config); console.log('=== PS1 EXPORT SILENCE VALIDATION ==='); console.log('Full terminal output:'); console.log(JSON.stringify(result.concatenatedResponses)); console.log('====================================='); // CRITICAL ASSERTION: Must NOT contain visible export PS1 commands const exportPs1Pattern = /export PS1=.*[\r\n]/g; const exportMatches = result.concatenatedResponses.match(exportPs1Pattern); if (exportMatches) { console.log('❌ VISIBLE EXPORT COMMANDS DETECTED:'); exportMatches.forEach((match, i) => { console.log(` ${i + 1}. "${match.trim()}"`); }); console.log(' Expected: No visible export commands'); console.log(' Actual: Export commands visible in terminal output'); } else { console.log('✅ PS1 EXPORT COMMANDS: Silent (not visible in output)'); } // POSITIVE ASSERTION: Should contain clean bracket format prompts const bracketPromptPattern = /\[jsbattig@localhost [^\]]+\]\$/g; const bracketMatches = result.concatenatedResponses.match(bracketPromptPattern); console.log('✅ BRACKET PROMPT ANALYSIS:'); if (bracketMatches) { console.log(` Found ${bracketMatches.length} bracket format prompts:`); bracketMatches.forEach((match, i) => { console.log(` ${i + 1}. "${match}"`); }); } else { console.log(' ⚠️ No bracket format prompts detected'); } // COMMAND OUTPUT VALIDATION: Should contain actual command results const commandOutputPatterns = [ 'test command output', '/home/jsbattig' ]; console.log('📝 COMMAND OUTPUT VALIDATION:'); for (const expectedOutput of commandOutputPatterns) { if (result.concatenatedResponses.includes(expectedOutput)) { console.log(` ✅ Found expected output: "${expectedOutput}"`); } else { console.log(` ❌ Missing expected output: "${expectedOutput}"`); } } // MAIN ASSERTIONS // 1. NO VISIBLE EXPORT COMMANDS: Must not show PS1 export commands expect(result.concatenatedResponses).not.toMatch(exportPs1Pattern); // 2. BRACKET PROMPTS PRESENT: Must have clean bracket format prompts expect(result.concatenatedResponses).toMatch(bracketPromptPattern); // 3. COMMAND RESULTS PRESENT: Must show actual command output expect(result.concatenatedResponses).toContain('test command output'); expect(result.concatenatedResponses).toContain('/home/jsbattig'); // 4. CLEAN TERMINAL FLOW: Should have proper command/response separation const lines = result.concatenatedResponses.split(/\r?\n/); let hasCleanFlow = false; for (let i = 0; i < lines.length - 1; i++) { const line = lines[i]; const nextLine = lines[i + 1]; // Look for pattern: bracket prompt + command, followed by result if (line.includes('[jsbattig@localhost') && line.includes('echo') && nextLine && nextLine.includes('test command output')) { hasCleanFlow = true; console.log('✅ CLEAN TERMINAL FLOW: Command and response properly separated'); console.log(` Command line: "${line}"`); console.log(` Response line: "${nextLine}"`); break; } } expect(hasCleanFlow).toBe(true); console.log('✅ All PS1 export silence validation tests PASSED'); }, 45000); it('should maintain bracket prompt format consistency without visible configuration', async () => { // Test multiple command sequence to ensure consistent prompt format // without any visible PS1 configuration commands const config = { preWebSocketCommands: [ 'ssh_connect {"name": "' + testSessionName + '-multi", "host": "localhost", "username": "jsbattig", "keyFilePath": "~/.ssh/id_ed25519"}', ], postWebSocketCommands: [ 'ssh_exec {"sessionName": "' + testSessionName + '-multi", "command": "whoami"}', 'ssh_exec {"sessionName": "' + testSessionName + '-multi", "command": "date"}', 'ssh_exec {"sessionName": "' + testSessionName + '-multi", "command": "ls | head -3"}' ], workflowTimeout: 45000, sessionName: testSessionName + '-multi' }; const result = await testUtils.runTerminalHistoryTest(config); console.log('=== PROMPT CONSISTENCY VALIDATION ==='); // Extract all prompts from the output const allPrompts = result.concatenatedResponses.match(/\[jsbattig@localhost [^\]]+\]\$/g) || []; console.log(`Found ${allPrompts.length} total prompts:`); allPrompts.forEach((prompt, i) => { console.log(` ${i + 1}. "${prompt}"`); }); // Check for any visible export commands const visibleExports = result.concatenatedResponses.match(/export PS1=/g) || []; console.log(`Visible export commands: ${visibleExports.length}`); if (visibleExports.length > 0) { console.log('❌ CONFIGURATION LEAK: PS1 exports are visible'); visibleExports.forEach((exp, i) => { console.log(` ${i + 1}. Found: "${exp}"`); }); } else { console.log('✅ SILENT CONFIGURATION: No visible PS1 exports'); } // Assertions expect(allPrompts.length).toBeGreaterThan(2); // Should have multiple consistent prompts expect(visibleExports.length).toBe(0); // Should have zero visible export commands expect(result.concatenatedResponses).toContain('jsbattig'); // whoami result expect(result.concatenatedResponses).toMatch(/\d{4}/); // date result should contain year console.log('✅ Prompt consistency validation PASSED'); }, 60000); }); });

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