/ docs / agents / file-operations.md
file-operations.md
  1  # File Operations Module
  2  
  3  Safe file reading/writing with backup/restore capabilities for the agent system.
  4  
  5  ## Overview
  6  
  7  The File Operations module (`src/agents/utils/file-operations.js`) provides a comprehensive set of tools for agents to safely interact with the codebase. All operations include built-in safety features to prevent data loss and maintain code integrity.
  8  
  9  ## Key Features
 10  
 11  ### 1. Safety Features
 12  
 13  - **Automatic Backups**: Every write operation creates a backup before modifying files
 14  - **Atomic Writes**: Uses temp file → move pattern to prevent partial writes
 15  - **Path Traversal Prevention**: Whitelist-based validation (src/, tests/, docs/, scripts/, prompts/)
 16  - **Blacklist Protection**: Prevents modification of sensitive files (.env, package-lock.json)
 17  - **Syntax Validation**: Validates JavaScript syntax before writing
 18  - **Diff Generation**: Provides unified diffs for all edits
 19  
 20  ### 2. Backup Management
 21  
 22  - Backups stored in `.backups/` directory with timestamps
 23  - Restore from any backup
 24  - List all backups for a file
 25  - Cleanup old backups (keep N most recent)
 26  
 27  ### 3. Context Awareness
 28  
 29  - Extract imports and dependencies from files
 30  - Find related test files automatically
 31  - Identify npm package dependencies
 32  
 33  ## API Reference
 34  
 35  ### Core Functions
 36  
 37  #### `readFile(filePath)`
 38  
 39  Read a file and return its content with metadata.
 40  
 41  ```javascript
 42  import { readFile } from './utils/file-operations.js';
 43  
 44  const file = await readFile('src/utils/logger.js');
 45  console.log(file.content); // File content as string
 46  console.log(file.size); // File size in bytes
 47  console.log(file.lastModified); // Date object
 48  ```
 49  
 50  **Returns**: `{content: string, path: string, size: number, lastModified: Date}`
 51  
 52  #### `writeFile(filePath, content, options)`
 53  
 54  Write content to a file with automatic backup and validation.
 55  
 56  ```javascript
 57  import { writeFile } from './utils/file-operations.js';
 58  
 59  const result = await writeFile('src/test.js', 'const x = 1;', {
 60    backup: true, // Create backup before writing (default: true)
 61    validate: true, // Validate JS syntax (default: true for .js files)
 62  });
 63  
 64  console.log(result.backupPath); // Path to backup file
 65  console.log(result.diff); // Unified diff of changes
 66  ```
 67  
 68  **Returns**: `{success: boolean, backupPath?: string, diff?: string}`
 69  
 70  #### `editFile(filePath, changes)`
 71  
 72  Edit a file by replacing specific content.
 73  
 74  ```javascript
 75  import { editFile } from './utils/file-operations.js';
 76  
 77  const result = await editFile('src/test.js', {
 78    oldContent: 'const x = 1;',
 79    newContent: 'const x = 2;',
 80  });
 81  
 82  console.log(result.diff); // Shows what changed
 83  ```
 84  
 85  **Returns**: `{success: boolean, backupPath: string, diff: string}`
 86  
 87  #### `backupFile(filePath)`
 88  
 89  Create a backup of a file.
 90  
 91  ```javascript
 92  import { backupFile } from './utils/file-operations.js';
 93  
 94  const backupPath = await backupFile('src/important.js');
 95  console.log(`Backup created at: ${backupPath}`);
 96  ```
 97  
 98  **Returns**: `string` (path to backup file)
 99  
100  #### `restoreBackup(backupPath)`
101  
102  Restore a file from a backup.
103  
104  ```javascript
105  import { restoreBackup } from './utils/file-operations.js';
106  
107  await restoreBackup('/path/to/.backups/src_important.js.2026-02-15.backup');
108  ```
109  
110  **Returns**: `boolean` (true if successful)
111  
112  #### `validateJavaScript(code)`
113  
114  Validate JavaScript syntax using ESLint.
115  
116  ```javascript
117  import { validateJavaScript } from './utils/file-operations.js';
118  
119  const result = await validateJavaScript('const x = 1;');
120  if (!result.valid) {
121    console.error('Syntax errors:', result.errors);
122  }
123  ```
124  
125  **Returns**: `{valid: boolean, errors: Array<{line, column, message}>}`
126  
127  #### `getFileContext(filePath)`
128  
129  Get file context: imports, dependencies, related test files.
130  
131  ```javascript
132  import { getFileContext } from './utils/file-operations.js';
133  
134  const context = await getFileContext('src/utils/logger.js');
135  console.log('Imports:', context.imports); // All imports
136  console.log('NPM deps:', context.dependencies); // Just npm packages
137  console.log('Tests:', context.testFiles); // Related test files
138  ```
139  
140  **Returns**: `{imports: string[], dependencies: string[], testFiles: string[]}`
141  
142  #### `listBackups(filePath)`
143  
144  List all backups for a file, sorted by date (newest first).
145  
146  ```javascript
147  import { listBackups } from './utils/file-operations.js';
148  
149  const backups = await listBackups('src/utils/logger.js');
150  console.log('Available backups:', backups);
151  ```
152  
153  **Returns**: `string[]` (array of backup file paths)
154  
155  #### `cleanupBackups(filePath, keepCount)`
156  
157  Delete old backups, keeping only the most recent N backups.
158  
159  ```javascript
160  import { cleanupBackups } from './utils/file-operations.js';
161  
162  const deleted = await cleanupBackups('src/utils/logger.js', 5);
163  console.log(`Deleted ${deleted} old backups`);
164  ```
165  
166  **Returns**: `number` (number of backups deleted)
167  
168  ## Usage Examples
169  
170  ### Example 1: Developer Agent Fixing a Bug
171  
172  ```javascript
173  import { readFile, editFile, getFileContext } from './utils/file-operations.js';
174  
175  // Read the buggy file
176  const file = await readFile('src/utils/helper.js');
177  
178  // Get context to understand dependencies
179  const context = await getFileContext('src/utils/helper.js');
180  console.log('Dependencies:', context.dependencies);
181  console.log('Test files:', context.testFiles);
182  
183  // Fix the bug
184  const result = await editFile('src/utils/helper.js', {
185    oldContent: 'return x + y',
186    newContent: 'return Number(x) + Number(y)',
187  });
188  
189  console.log('Changes made:');
190  console.log(result.diff);
191  console.log('Backup at:', result.backupPath);
192  ```
193  
194  ### Example 2: QA Agent Verifying Changes
195  
196  ```javascript
197  import { listBackups, restoreBackup, readFile } from './utils/file-operations.js';
198  
199  // List all backups for a file
200  const backups = await listBackups('src/utils/helper.js');
201  
202  // Compare current version with backup
203  const current = await readFile('src/utils/helper.js');
204  const backup = await readFile(backups[0]);
205  
206  // If changes are bad, restore from backup
207  if (testsFailed) {
208    await restoreBackup(backups[0]);
209    console.log('Restored from backup after failed tests');
210  }
211  ```
212  
213  ### Example 3: Architect Agent Refactoring
214  
215  ```javascript
216  import { getFileContext, writeFile } from './utils/file-operations.js';
217  
218  // Analyze file to understand its role
219  const context = await getFileContext('src/utils/old-module.js');
220  
221  // Create new refactored version
222  const newCode = `
223  import ${context.dependencies.join(', ')} from 'packages';
224  
225  // Refactored implementation
226  export default function newModule() {
227    // ...
228  }
229  `;
230  
231  // Write new version (creates backup automatically)
232  const result = await writeFile('src/utils/new-module.js', newCode);
233  
234  console.log('Refactoring complete');
235  console.log('Tests to update:', context.testFiles);
236  ```
237  
238  ## Security
239  
240  ### Allowed Directories (Whitelist)
241  
242  Only files in these directories can be modified:
243  
244  - `src/` - Source code
245  - `tests/` - Test files
246  - `docs/` - Documentation
247  - `scripts/` - Scripts
248  - `prompts/` - Prompt templates
249  
250  ### Blacklisted Files
251  
252  These files can never be modified:
253  
254  - `.env`, `.env.local`, `.env.production` - Environment variables
255  - `package-lock.json` - Dependency lock file
256  
257  ### Path Traversal Protection
258  
259  All paths are validated to prevent traversal attacks:
260  
261  ```javascript
262  // BLOCKED: Path traversal
263  await readFile('../../../etc/passwd');
264  // Error: Path traversal detected
265  
266  // BLOCKED: Outside allowed directories
267  await writeFile('/tmp/evil.js', 'malicious code');
268  // Error: Path not in allowed directories
269  
270  // BLOCKED: Blacklisted file
271  await writeFile('src/.env', 'API_KEY=stolen');
272  // Error: File is blacklisted
273  ```
274  
275  ## Error Handling
276  
277  All functions throw descriptive errors:
278  
279  ```javascript
280  try {
281    await writeFile('src/test.js', 'const x = ;'); // Syntax error
282  } catch (error) {
283    console.error(error.message);
284    // JavaScript syntax errors:
285    //   Line 1: Parsing error: Unexpected token ;
286  }
287  ```
288  
289  On write failures, backups are automatically restored:
290  
291  ```javascript
292  // File contains: const x = 1;
293  try {
294    await writeFile('src/test.js', 'const x = ;'); // Will fail
295  } catch (error) {
296    // File is automatically restored to: const x = 1;
297  }
298  ```
299  
300  ## Testing
301  
302  Comprehensive test suite in `tests/agents/file-operations.test.js`:
303  
304  - 33 tests covering all functionality
305  - 85%+ code coverage
306  - Tests for security vulnerabilities
307  - Integration tests for backup/restore cycles
308  
309  Run tests:
310  
311  ```bash
312  npm test tests/agents/file-operations.test.js
313  ```
314  
315  ## Best Practices
316  
317  ### 1. Always Use Backups
318  
319  ```javascript
320  // Good: Backup enabled (default)
321  await writeFile('src/important.js', newCode);
322  
323  // Risky: Backup disabled
324  await writeFile('src/important.js', newCode, { backup: false });
325  ```
326  
327  ### 2. Validate Syntax
328  
329  ```javascript
330  // Good: Validate before writing
331  const validation = await validateJavaScript(generatedCode);
332  if (validation.valid) {
333    await writeFile('src/generated.js', generatedCode);
334  }
335  
336  // Risky: Skip validation
337  await writeFile('src/generated.js', generatedCode, { validate: false });
338  ```
339  
340  ### 3. Use Context for Awareness
341  
342  ```javascript
343  // Good: Understand file context first
344  const context = await getFileContext('src/module.js');
345  console.log('This will affect tests:', context.testFiles);
346  await editFile('src/module.js', changes);
347  
348  // Bad: Modify blindly
349  await editFile('src/module.js', changes);
350  ```
351  
352  ### 4. Cleanup Old Backups
353  
354  ```javascript
355  // Prevent backup directory from growing indefinitely
356  await cleanupBackups('src/frequently-edited.js', 10);
357  ```
358  
359  ## Integration with Agent System
360  
361  File operations integrate with the agent workflow:
362  
363  1. **Developer Agent**: Uses `editFile()` to fix bugs
364  2. **QA Agent**: Uses `listBackups()` and `restoreBackup()` to rollback failed changes
365  3. **Architect Agent**: Uses `getFileContext()` to understand code structure
366  4. **Security Agent**: Benefits from built-in path traversal protection
367  
368  See `docs/06-automation/agent-system.md` for full agent system documentation.