import { z } from 'zod'; import { readFile } from 'node:fs/promises'; import type { ToolDef, ToolContext } from './types.js'; import { resolveWritePath } from '../write_guard.js'; import { lspManager } from '../lsp/server-manager.js'; import { gotoDefinition } from '../lsp/operations.js'; const LspGotoDefinitionInput = z.object({ file_path: z.string().describe('Path to the source file'), line: z.number().int().nonnegative().describe('0-based line number'), character: z.number().int().nonnegative().describe('0-based character offset'), }); type InputT = z.infer; export const lspGotoDefinitionTool: ToolDef = { name: 'lsp_goto_definition', description: 'Find the definition of a symbol at a given position in a file.', inputSchema: LspGotoDefinitionInput, jsonSchema: { type: 'function', function: { name: 'lsp_goto_definition', description: 'Find definition of symbol at position', parameters: { type: 'object', properties: { file_path: { type: 'string' }, line: { type: 'number' }, character: { type: 'number' }, }, required: ['file_path', 'line', 'character'], }, }, }, async execute(input: InputT, projectRoot: string, _context: ToolContext): Promise { const resolved = await resolveWritePath(projectRoot, input.file_path); const content = await readFile(resolved, 'utf8'); const client = await lspManager.getClient(resolved); if (!client) return { error: 'Unsupported file type' }; const loc = await gotoDefinition(client, resolved, content, input.line, input.character); if (!loc) return { result: 'No definition found.' }; return { result: `Defined at ${loc.uri}:${loc.range.start.line + 1}:${loc.range.start.character + 1}` }; }, };