edit_file
Surgically edit files by finding and replacing exact text for revenue tracking and business management operations. Automatically creates backups and ensures precise text matching.
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 |
|---|---|---|---|
| find | Yes | Exact text to find (must match exactly including whitespace) | |
| path | Yes | Full file path | |
| replace_with | Yes | Text to replace it with |
Implementation Reference
- index.js:749-824 (handler)Handler for the 'edit_file' tool. Performs a safe, single-occurrence find-and-replace in the specified file, creates a timestamped backup, validates path access, ensures unique match, identifies changed lines, and returns detailed change information.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)Registration of the 'edit_file' tool in the listTools response, 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-576 (schema)Input schema definition for the 'edit_file' tool, specifying parameters: 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"] } },