edit_file
Surgically edit files by finding and replacing exact text, ensuring precise modifications for revenue tracking and business management workflows.
Instructions
Surgically edit a file by finding and replacing exact text. 50% more efficient than read+write. Use after read_file to ensure exact match. Errors if text not found or appears multiple times. Creates backup automatically.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Full file path | |
| find | Yes | Exact text to find (must match exactly including whitespace) | |
| replace_with | Yes | Text to replace it with |
Implementation Reference
- index.js:749-824 (handler)Main execution logic for edit_file tool: validates path, checks file existence, ensures unique find text match, creates backup, performs string replacement, and returns detailed change info.case "edit_file": { const { path, find, replace_with } = args; if (!isPathAllowed(path)) { throw new Error(`Access denied: Path not in allowed directories`); } if (!fs.existsSync(path)) { throw new Error(`File not found: ${path}`); } // Read current content const content = fs.readFileSync(path, 'utf8'); const lines = content.split('\n'); // Count occurrences const occurrences = (content.match(new RegExp(find.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')) || []).length; if (occurrences === 0) { throw new Error(`Text not found in file. Search text: "${find.substring(0, 100)}..."`); } if (occurrences > 1) { throw new Error(`Text appears ${occurrences} times in file. Must be unique for safety. Search text: "${find.substring(0, 100)}..."`); } // Find the line numbers where the change occurs const findLines = find.split('\n'); const changedLines = []; let foundAtLine = -1; for (let i = 0; i < lines.length; i++) { if (lines[i].includes(findLines[0])) { // Check if this is the full match let isMatch = true; for (let j = 0; j < findLines.length; j++) { if (i + j >= lines.length || !lines[i + j].includes(findLines[j])) { isMatch = false; break; } } if (isMatch) { foundAtLine = i + 1; // 1-indexed for humans for (let j = 0; j < findLines.length; j++) { changedLines.push(i + j + 1); } break; } } } // Create backup const backupPath = `${path}.backup-${Date.now()}`; fs.copyFileSync(path, backupPath); debugLog(`Created backup: ${backupPath}`); // Perform replacement const newContent = content.replace(find, replace_with); fs.writeFileSync(path, newContent, 'utf8'); result = { success: true, path: path, changes: { linesModified: changedLines, totalLines: changedLines.length, startLine: changedLines[0], endLine: changedLines[changedLines.length - 1], before: find.substring(0, 200) + (find.length > 200 ? '...' : ''), after: replace_with.substring(0, 200) + (replace_with.length > 200 ? '...' : ''), }, backupCreated: backupPath, message: `Successfully edited ${changedLines.length} line(s) at lines ${changedLines.join(', ')}` }; break; }
- index.js:555-576 (registration)Tool registration in ListTools handler, including name, description, and input schema definition.{ name: "edit_file", description: "Surgically edit a file by finding and replacing exact text. 50% more efficient than read+write. Use after read_file to ensure exact match. Errors if text not found or appears multiple times. Creates backup automatically.", inputSchema: { type: "object", properties: { path: { type: "string", description: "Full file path" }, find: { type: "string", description: "Exact text to find (must match exactly including whitespace)" }, replace_with: { type: "string", description: "Text to replace it with" } }, required: ["path", "find", "replace_with"] } },
- index.js:558-575 (schema)Input schema defining parameters for the edit_file tool: path, find, replace_with.inputSchema: { type: "object", properties: { path: { type: "string", description: "Full file path" }, find: { type: "string", description: "Exact text to find (must match exactly including whitespace)" }, replace_with: { type: "string", description: "Text to replace it with" } }, required: ["path", "find", "replace_with"] }
- index.js:58-63 (helper)Helper function to validate if a file path is within allowed directories, used in edit_file handler for security.function isPathAllowed(filePath) { const normalized = filePath.replace(/\//g, '\\'); return ALLOWED_PATHS.some(allowedPath => normalized.startsWith(allowedPath) ); }