import { z } from "zod"; import { handleToolError, validateRequired } from "../helpers/errorHandler.js"; import { getCurrentProjectInfo, callLocalFileEndpoint, buildLocalFileErrorResponse } from "./helpers.js"; export function registerAcaiLineReplaceTool(server) { server.tool( "acai-line-replace", "Replace a validated line block in an existing file. Preferred for editing existing files while minimizing token usage.", { file_path: z.string().describe("Path relative to the project root"), first_replaced_line: z.number().int().positive().describe("1-indexed first line of the target block"), last_replaced_line: z.number().int().positive().describe("1-indexed last line of the target block"), search: z.string().describe("Expected current content for validation. Must match the selected block exactly."), replace: z.string().describe("Replacement content for the selected block"), expected_sha256: z.string().optional().describe("Optional full-file sha check from a prior acai-view"), }, { readOnlyHint: false, destructiveHint: false }, async ({ file_path, first_replaced_line, last_replaced_line, search, replace, expected_sha256 }) => { try { const validationError = validateRequired( { file_path, first_replaced_line, last_replaced_line, search }, ["file_path", "first_replaced_line", "last_replaced_line", "search"], "acai-line-replace" ); if (validationError) return validationError; const { projectSlug, projectDir } = getCurrentProjectInfo(); const result = await callLocalFileEndpoint("POST", "/api/files/line-replace", { project: projectSlug, projectDir: projectDir, relativePath: file_path, firstLine: first_replaced_line, lastLine: last_replaced_line, search, replace, expectedSha256: expected_sha256 || "", }); if (!result.data?.success) { return buildLocalFileErrorResponse("acai-line-replace", result, { file_path, first_replaced_line, last_replaced_line, }); } const data = result.data; return { content: [{ type: "text", text: JSON.stringify({ success: true, file_path: data.filePath, first_replaced_line: data.firstLine, last_replaced_line: data.lastLine, new_sha256: data.newSha256, changed: data.changed, compiled: data.compiled || false, compile_result: data.compileResult || null, }, null, 2), }], }; } catch (error) { return handleToolError(error, "acai-line-replace", { file_path, first_replaced_line, last_replaced_line }); } } ); }