216 lines
5.9 KiB
TypeScript
216 lines
5.9 KiB
TypeScript
import { z } from 'zod/v4'
|
|
import { lazySchema } from '../../utils/lazySchema.js'
|
|
|
|
/**
|
|
* Discriminated union of all LSP operations
|
|
* Uses 'operation' as the discriminator field
|
|
*/
|
|
export const lspToolInputSchema = lazySchema(() => {
|
|
/**
|
|
* Go to Definition operation
|
|
* Finds the definition location of a symbol at the given position
|
|
*/
|
|
const goToDefinitionSchema = z.strictObject({
|
|
operation: z.literal('goToDefinition'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
/**
|
|
* Find References operation
|
|
* Finds all references to a symbol at the given position
|
|
*/
|
|
const findReferencesSchema = z.strictObject({
|
|
operation: z.literal('findReferences'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
/**
|
|
* Hover operation
|
|
* Gets hover information (documentation, type info) for a symbol at the given position
|
|
*/
|
|
const hoverSchema = z.strictObject({
|
|
operation: z.literal('hover'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
/**
|
|
* Document Symbol operation
|
|
* Gets all symbols (functions, classes, variables) in a document
|
|
*/
|
|
const documentSymbolSchema = z.strictObject({
|
|
operation: z.literal('documentSymbol'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
/**
|
|
* Workspace Symbol operation
|
|
* Searches for symbols across the entire workspace
|
|
*/
|
|
const workspaceSymbolSchema = z.strictObject({
|
|
operation: z.literal('workspaceSymbol'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
/**
|
|
* Go to Implementation operation
|
|
* Finds the implementation locations of an interface or abstract method
|
|
*/
|
|
const goToImplementationSchema = z.strictObject({
|
|
operation: z.literal('goToImplementation'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
/**
|
|
* Prepare Call Hierarchy operation
|
|
* Prepares a call hierarchy item at the given position (first step for call hierarchy)
|
|
*/
|
|
const prepareCallHierarchySchema = z.strictObject({
|
|
operation: z.literal('prepareCallHierarchy'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
/**
|
|
* Incoming Calls operation
|
|
* Finds all functions/methods that call the function at the given position
|
|
*/
|
|
const incomingCallsSchema = z.strictObject({
|
|
operation: z.literal('incomingCalls'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
/**
|
|
* Outgoing Calls operation
|
|
* Finds all functions/methods called by the function at the given position
|
|
*/
|
|
const outgoingCallsSchema = z.strictObject({
|
|
operation: z.literal('outgoingCalls'),
|
|
filePath: z.string().describe('The absolute or relative path to the file'),
|
|
line: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The line number (1-based, as shown in editors)'),
|
|
character: z
|
|
.number()
|
|
.int()
|
|
.positive()
|
|
.describe('The character offset (1-based, as shown in editors)'),
|
|
})
|
|
|
|
return z.discriminatedUnion('operation', [
|
|
goToDefinitionSchema,
|
|
findReferencesSchema,
|
|
hoverSchema,
|
|
documentSymbolSchema,
|
|
workspaceSymbolSchema,
|
|
goToImplementationSchema,
|
|
prepareCallHierarchySchema,
|
|
incomingCallsSchema,
|
|
outgoingCallsSchema,
|
|
])
|
|
})
|
|
|
|
/**
|
|
* TypeScript type for LSPTool input
|
|
*/
|
|
export type LSPToolInput = z.infer<ReturnType<typeof lspToolInputSchema>>
|
|
|
|
/**
|
|
* Type guard to check if an operation is a valid LSP operation
|
|
*/
|
|
export function isValidLSPOperation(
|
|
operation: string,
|
|
): operation is LSPToolInput['operation'] {
|
|
return [
|
|
'goToDefinition',
|
|
'findReferences',
|
|
'hover',
|
|
'documentSymbol',
|
|
'workspaceSymbol',
|
|
'goToImplementation',
|
|
'prepareCallHierarchy',
|
|
'incomingCalls',
|
|
'outgoingCalls',
|
|
].includes(operation)
|
|
}
|