File size: 2,612 Bytes
064bfd6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 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<typeof inputSchema>
// 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<InputSchema>
// Individual edit without file_path
export type EditInput = Omit<FileEditInput, 'file_path'>
// 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<typeof outputSchema>
export type FileEditOutput = z.infer<OutputSchema>
export { inputSchema, outputSchema }
|