same compare for edit and dry run

This commit is contained in:
Marc Goodner
2024-12-03 16:45:04 -08:00
parent de49769034
commit dc9f56720f

View File

@@ -111,13 +111,13 @@ const EditOperation = z.object({
oldText: z.string().describe('Text to search for - can be a substring of the target'), oldText: z.string().describe('Text to search for - can be a substring of the target'),
// The new text to replace with // The new text to replace with
newText: z.string().describe('Text to replace the found text with'), newText: z.string().describe('Text to replace the found text with'),
// Optional: preview changes without applying them
dryRun: z.boolean().default(false).describe('Preview changes using git-style diff format')
}); });
const EditFileArgsSchema = z.object({ const EditFileArgsSchema = z.object({
path: z.string(), path: z.string(),
edits: z.array(EditOperation), edits: z.array(EditOperation),
// Optional: preview changes without applying them
dryRun: z.boolean().default(false).describe('Preview changes using git-style diff format')
}); });
const CreateDirectoryArgsSchema = z.object({ const CreateDirectoryArgsSchema = z.object({
@@ -225,7 +225,7 @@ interface EditPreview {
} }
// File editing utilities // File editing utilities
async function applyFileEdits(filePath: string, edits: z.infer<typeof EditOperation>[]): Promise<string | EditPreview[]> { async function applyFileEdits(filePath: string, edits: Array<{oldText: string, newText: string}>, dryRun: boolean = false): Promise<string | EditPreview[]> {
let content = await fs.readFile(filePath, 'utf-8'); let content = await fs.readFile(filePath, 'utf-8');
const previews: EditPreview[] = []; const previews: EditPreview[] = [];
@@ -237,38 +237,29 @@ async function applyFileEdits(filePath: string, edits: z.infer<typeof EditOperat
); );
} }
// Calculate line number for reporting
const lineNumber = content.slice(0, pos).split(/\r?\n/).length; const lineNumber = content.slice(0, pos).split(/\r?\n/).length;
const preview = [
`@@ line ${lineNumber} @@`,
'<<<<<<< ORIGINAL',
edit.oldText,
'=======',
edit.newText,
'>>>>>>> MODIFIED'
].join('\n');
if (edit.dryRun) { previews.push({
// Create git-style diff preview original: edit.oldText,
const preview = [ modified: edit.newText,
`@@ line ${lineNumber} @@`, lineNumber,
'<<<<<<< ORIGINAL', preview
edit.oldText, });
'=======',
edit.newText, if (!dryRun) {
'>>>>>>> MODIFIED' content = content.slice(0, pos) + edit.newText + content.slice(pos + edit.oldText.length);
].join('\n');
previews.push({
original: edit.oldText,
modified: edit.newText,
lineNumber,
preview
});
continue;
} }
// Apply the edit
content = content.slice(0, pos) + edit.newText + content.slice(pos + edit.oldText.length);
} }
if (edits.some(e => e.dryRun)) { return dryRun ? previews : content;
return previews;
}
return content;
} }
// Tool handlers // Tool handlers
@@ -430,18 +421,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
throw new Error(`Invalid arguments for edit_file: ${parsed.error}`); throw new Error(`Invalid arguments for edit_file: ${parsed.error}`);
} }
const validPath = await validatePath(parsed.data.path); const validPath = await validatePath(parsed.data.path);
const result = await applyFileEdits(validPath, parsed.data.edits); const result = await applyFileEdits(validPath, parsed.data.edits, parsed.data.dryRun);
// If it's a dry run, format the previews // If it's a dry run, format the previews
if (Array.isArray(result)) { if (parsed.data.dryRun) {
const previewText = result.map(preview => preview.preview).join('\n\n'); const previewText = (result as EditPreview[]).map(preview => preview.preview).join('\n\n');
return { return {
content: [{ type: "text", text: `Edit preview:\n${previewText}` }], content: [{ type: "text", text: `Edit preview:\n${previewText}` }],
}; };
} }
// Otherwise write the changes await fs.writeFile(validPath, result as string, "utf-8");
await fs.writeFile(validPath, result, "utf-8");
return { return {
content: [{ type: "text", text: `Successfully applied edits to ${parsed.data.path}` }], content: [{ type: "text", text: `Successfully applied edits to ${parsed.data.path}` }],
}; };