demo-file-operations.js
1 #!/usr/bin/env node 2 /** 3 * Demo: File Operations Module 4 * 5 * Demonstrates safe file operations with backup/restore capabilities. 6 * This script creates a test file, edits it, and shows various features. 7 */ 8 9 import { 10 readFile, 11 writeFile, 12 editFile, 13 backupFile, 14 restoreBackup, 15 validateJavaScript, 16 getFileContext, 17 listBackups, 18 cleanupBackups, 19 } from '../src/agents/utils/file-operations.js'; 20 import fs from 'fs/promises'; 21 22 const TEST_FILE = 'tests/agents/fixtures/demo-file.js'; 23 24 async function demo() { 25 console.log('='.repeat(60)); 26 console.log('File Operations Module Demo'); 27 console.log('='.repeat(60)); 28 console.log(); 29 30 // Ensure fixtures directory exists 31 await fs.mkdir('tests/agents/fixtures', { recursive: true }); 32 33 try { 34 // Step 1: Create initial file 35 console.log('Step 1: Creating initial file...'); 36 const initialCode = `const greet = (name) => { 37 return 'Hello, ' + name; 38 }; 39 40 export default greet; 41 `; 42 43 const result1 = await writeFile(TEST_FILE, initialCode); 44 console.log('✓ File created successfully'); 45 console.log(` Backup: ${result1.backupPath || 'N/A (new file)'}`); 46 console.log(); 47 48 // Step 2: Read file and get context 49 console.log('Step 2: Reading file and analyzing context...'); 50 const file = await readFile(TEST_FILE); 51 console.log(`✓ File size: ${file.size} bytes`); 52 console.log(`✓ Last modified: ${file.lastModified.toISOString()}`); 53 54 const context = await getFileContext(TEST_FILE); 55 console.log(`✓ Imports: ${context.imports.length}`); 56 console.log(`✓ Dependencies: ${context.dependencies.length}`); 57 console.log(); 58 59 // Step 3: Edit file 60 console.log('Step 3: Editing file (fixing string concatenation)...'); 61 const result2 = await editFile(TEST_FILE, { 62 oldContent: "return 'Hello, ' + name;", 63 newContent: 'return `Hello, ${name}!`;', 64 }); 65 66 console.log('✓ File edited successfully'); 67 console.log('✓ Diff:'); 68 console.log( 69 result2.diff 70 .split('\n') 71 .slice(0, 10) 72 .map(line => ` ${line}`) 73 .join('\n') 74 ); 75 console.log(); 76 77 // Step 4: Validate JavaScript 78 console.log('Step 4: Validating syntax...'); 79 const { content } = await readFile(TEST_FILE); 80 const validation = await validateJavaScript(content); 81 console.log(`✓ Valid: ${validation.valid}`); 82 console.log(`✓ Errors: ${validation.errors.length}`); 83 console.log(); 84 85 // Step 5: List backups 86 console.log('Step 5: Listing backups...'); 87 const backups = await listBackups(TEST_FILE); 88 console.log(`✓ Found ${backups.length} backup(s)`); 89 backups.forEach((backup, i) => { 90 console.log(` ${i + 1}. ${backup}`); 91 }); 92 console.log(); 93 94 // Step 6: Create multiple backups 95 console.log('Step 6: Creating multiple backups...'); 96 for (let i = 0; i < 3; i++) { 97 await new Promise(resolve => setTimeout(resolve, 100)); 98 await backupFile(TEST_FILE); 99 } 100 const allBackups = await listBackups(TEST_FILE); 101 console.log(`✓ Now have ${allBackups.length} backup(s)`); 102 console.log(); 103 104 // Step 7: Cleanup old backups 105 console.log('Step 7: Cleaning up old backups (keep 2)...'); 106 const deleted = await cleanupBackups(TEST_FILE, 2); 107 console.log(`✓ Deleted ${deleted} old backup(s)`); 108 const remainingBackups = await listBackups(TEST_FILE); 109 console.log(`✓ Remaining: ${remainingBackups.length} backup(s)`); 110 console.log(); 111 112 // Step 8: Restore from backup 113 console.log('Step 8: Restoring from most recent backup...'); 114 if (remainingBackups.length > 0) { 115 await restoreBackup(remainingBackups[0]); 116 console.log('✓ Restored successfully'); 117 } 118 console.log(); 119 120 // Step 9: Attempt invalid operation (will fail safely) 121 console.log('Step 9: Testing error handling (invalid syntax)...'); 122 try { 123 await writeFile(TEST_FILE, 'const x = ;'); // Syntax error 124 console.log('✗ Should have failed!'); 125 } catch (error) { 126 console.log('✓ Correctly rejected invalid syntax'); 127 console.log(` Error: ${error.message.split('\n')[0]}`); 128 129 // Verify file was restored from backup 130 const restoredContent = await readFile(TEST_FILE); 131 console.log('✓ Original content preserved (restored from backup)'); 132 } 133 console.log(); 134 135 // Final summary 136 console.log('='.repeat(60)); 137 console.log('Demo Complete!'); 138 console.log('='.repeat(60)); 139 console.log(); 140 console.log('Key Features Demonstrated:'); 141 console.log(' ✓ Safe file writing with automatic backups'); 142 console.log(' ✓ Atomic writes (temp file → move)'); 143 console.log(' ✓ Syntax validation before writing'); 144 console.log(' ✓ Diff generation for all edits'); 145 console.log(' ✓ Context awareness (imports, dependencies)'); 146 console.log(' ✓ Backup management (list, cleanup, restore)'); 147 console.log(' ✓ Error handling with automatic rollback'); 148 console.log(); 149 } catch (error) { 150 console.error('Demo failed:', error); 151 process.exit(1); 152 } 153 } 154 155 demo();