import { z } from "zod"; import { handleToolError, validateRequired } from "../helpers/errorHandler.js"; import { getCurrentProjectInfo, callLocalFileEndpoint, buildLocalFileErrorResponse } from "./helpers.js"; export function registerAcaiViewTool(server) { server.tool( "acai-view", "Read a project file with optional line ranges. Returns only the requested slice plus compact metadata for safe incremental edits.", { file_path: z.string().describe("Path relative to the project root"), start_line: z.number().int().positive().optional().describe("1-indexed start line. Defaults to 1."), end_line: z.number().int().positive().optional().describe("1-indexed end line. If omitted, the server returns a bounded chunk."), }, { readOnlyHint: true, destructiveHint: false }, async ({ file_path, start_line, end_line }) => { try { const validationError = validateRequired({ file_path }, ["file_path"], "acai-view"); if (validationError) return validationError; if (end_line !== undefined && start_line !== undefined && end_line < start_line) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: "end_line must be greater than or equal to start_line" }, null, 2) }], isError: true, }; } const { projectSlug } = getCurrentProjectInfo(); const result = await callLocalFileEndpoint("GET", "/api/files/read", null, { project: projectSlug, projectDir: getCurrentProjectInfo().projectDir, relativePath: file_path, startLine: start_line, endLine: end_line, }); if (!result.data?.success) { return buildLocalFileErrorResponse("acai-view", result, { file_path }); } const data = result.data; return { content: [{ type: "text", text: JSON.stringify({ success: true, file_path: data.filePath, start_line: data.startLine, end_line: data.endLine, total_lines: data.totalLines, sha256: data.sha256, content: data.content, truncated: data.truncated, }, null, 2), }], }; } catch (error) { return handleToolError(error, "acai-view", { file_path }); } } ); }