mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-31 06:12:26 +00:00
88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
import z from "zod"
|
|
import { Tool } from "./tool"
|
|
import path from "path"
|
|
import { LSP } from "../lsp"
|
|
import DESCRIPTION from "./lsp.txt"
|
|
import { Instance } from "../project/instance"
|
|
import { pathToFileURL } from "url"
|
|
|
|
const operations = [
|
|
"goToDefinition",
|
|
"findReferences",
|
|
"hover",
|
|
"documentSymbol",
|
|
"workspaceSymbol",
|
|
"goToImplementation",
|
|
"prepareCallHierarchy",
|
|
"incomingCalls",
|
|
"outgoingCalls",
|
|
] as const
|
|
|
|
export const LspTool = Tool.define("lsp", {
|
|
description: DESCRIPTION,
|
|
parameters: z.object({
|
|
operation: z.enum(operations).describe("The LSP operation to perform"),
|
|
filePath: z.string().describe("The absolute or relative path to the file"),
|
|
line: z.number().int().min(1).describe("The line number (1-based, as shown in editors)"),
|
|
character: z.number().int().min(1).describe("The character offset (1-based, as shown in editors)"),
|
|
}),
|
|
execute: async (args) => {
|
|
const file = path.isAbsolute(args.filePath) ? args.filePath : path.join(Instance.directory, args.filePath)
|
|
const uri = pathToFileURL(file).href
|
|
const position = {
|
|
file,
|
|
line: args.line - 1,
|
|
character: args.character - 1,
|
|
}
|
|
|
|
const relPath = path.relative(Instance.worktree, file)
|
|
const title = `${args.operation} ${relPath}:${args.line}:${args.character}`
|
|
|
|
const exists = await Bun.file(file).exists()
|
|
if (!exists) {
|
|
throw new Error(`File not found: ${file}`)
|
|
}
|
|
|
|
const available = await LSP.hasClients(file)
|
|
if (!available) {
|
|
throw new Error("No LSP server available for this file type.")
|
|
}
|
|
|
|
await LSP.touchFile(file, true)
|
|
|
|
const result: unknown[] = await (async () => {
|
|
switch (args.operation) {
|
|
case "goToDefinition":
|
|
return LSP.definition(position)
|
|
case "findReferences":
|
|
return LSP.references(position)
|
|
case "hover":
|
|
return LSP.hover(position)
|
|
case "documentSymbol":
|
|
return LSP.documentSymbol(uri)
|
|
case "workspaceSymbol":
|
|
return LSP.workspaceSymbol("")
|
|
case "goToImplementation":
|
|
return LSP.implementation(position)
|
|
case "prepareCallHierarchy":
|
|
return LSP.prepareCallHierarchy(position)
|
|
case "incomingCalls":
|
|
return LSP.incomingCalls(position)
|
|
case "outgoingCalls":
|
|
return LSP.outgoingCalls(position)
|
|
}
|
|
})()
|
|
|
|
const output = (() => {
|
|
if (result.length === 0) return `No results found for ${args.operation}`
|
|
return JSON.stringify(result, null, 2)
|
|
})()
|
|
|
|
return {
|
|
title,
|
|
metadata: { result },
|
|
output,
|
|
}
|
|
},
|
|
})
|