import { z } from 'zod/v4' import { lazySchema } from '../../utils/lazySchema.js' import { semanticBoolean } from '../../utils/semanticBoolean.js' // The input schema with optional replace_all const inputSchema = lazySchema(() => z.strictObject({ file_path: z.string().describe('The absolute path to the file to modify'), old_string: z.string().describe('The text to replace'), new_string: z .string() .describe( 'The text to replace it with (must be different from old_string)', ), replace_all: semanticBoolean( z.boolean().default(false).optional(), ).describe('Replace all occurrences of old_string (default false)'), }), ) type InputSchema = ReturnType // Parsed output — what call() receives. z.output not z.input: with // semanticBoolean the input side is unknown (preprocess accepts anything). export type FileEditInput = z.output // Individual edit without file_path export type EditInput = Omit // Runtime version where replace_all is always defined export type FileEdit = { old_string: string new_string: string replace_all: boolean } export const hunkSchema = lazySchema(() => z.object({ oldStart: z.number(), oldLines: z.number(), newStart: z.number(), newLines: z.number(), lines: z.array(z.string()), }), ) export const gitDiffSchema = lazySchema(() => z.object({ filename: z.string(), status: z.enum(['modified', 'added']), additions: z.number(), deletions: z.number(), changes: z.number(), patch: z.string(), repository: z .string() .nullable() .optional() .describe('GitHub owner/repo when available'), }), ) // Output schema for FileEditTool const outputSchema = lazySchema(() => z.object({ filePath: z.string().describe('The file path that was edited'), oldString: z.string().describe('The original string that was replaced'), newString: z.string().describe('The new string that replaced it'), originalFile: z .string() .describe('The original file contents before editing'), structuredPatch: z .array(hunkSchema()) .describe('Diff patch showing the changes'), userModified: z .boolean() .describe('Whether the user modified the proposed changes'), replaceAll: z.boolean().describe('Whether all occurrences were replaced'), gitDiff: gitDiffSchema().optional(), }), ) type OutputSchema = ReturnType export type FileEditOutput = z.infer export { inputSchema, outputSchema }