@treedy/pyright-mcp 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/tools/hover.ts", "../src/lsp-client.ts", "../src/utils/position.ts", "../src/lsp/connection.ts", "../src/lsp/document-manager.ts", "../src/lsp/types.ts", "../src/tools/definition.ts", "../src/tools/references.ts", "../src/tools/completions.ts", "../src/tools/diagnostics.ts", "../src/tools/signature-help.ts", "../src/tools/rename.ts", "../src/tools/search.ts", "../src/tools/status.ts", "../src/tools/symbols.ts", "../src/tools/update-document.ts"],
4
+ "sourcesContent": [
5
+ "#!/usr/bin/env node\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\n\nimport { hover, hoverSchema } from './tools/hover.js';\nimport { definition, definitionSchema } from './tools/definition.js';\nimport { references, referencesSchema } from './tools/references.js';\nimport { completions, completionsSchema } from './tools/completions.js';\nimport { diagnostics, diagnosticsSchema } from './tools/diagnostics.js';\nimport { signatureHelp, signatureHelpSchema } from './tools/signature-help.js';\nimport { rename, renameSchema } from './tools/rename.js';\nimport { search, searchSchema } from './tools/search.js';\nimport { status, statusSchema } from './tools/status.js';\nimport { symbols, symbolsSchema } from './tools/symbols.js';\nimport { updateDocument, updateDocumentSchema } from './tools/update-document.js';\nimport { getLspClient, shutdownLspClient } from './lsp-client.js';\n\nconst server = new McpServer({\n name: 'pyright-mcp',\n version: '1.0.0',\n});\n\n// Register hover tool\nserver.tool(\n 'hover',\n 'Get type information and documentation at a specific position in a Python file',\n hoverSchema,\n async (args) => hover(args)\n);\n\n// Register definition tool\nserver.tool(\n 'definition',\n 'Go to definition of a symbol at a specific position in a Python file',\n definitionSchema,\n async (args) => definition(args)\n);\n\n// Register references tool\nserver.tool(\n 'references',\n 'Find all references to a symbol at a specific position in a Python file',\n referencesSchema,\n async (args) => references(args)\n);\n\n// Register completions tool\nserver.tool(\n 'completions',\n 'Get code completion suggestions at a specific position in a Python file',\n completionsSchema,\n async (args) => completions(args)\n);\n\n// Register diagnostics tool\nserver.tool(\n 'diagnostics',\n 'Get diagnostics (errors, warnings) for a Python file',\n diagnosticsSchema,\n async (args) => diagnostics(args)\n);\n\n// Register signature help tool\nserver.tool(\n 'signature_help',\n 'Get function signature help at a specific position in a Python file',\n signatureHelpSchema,\n async (args) => signatureHelp(args)\n);\n\n// Register rename tool\nserver.tool(\n 'rename',\n 'Preview renaming a symbol at a specific position in a Python file',\n renameSchema,\n async (args) => rename(args)\n);\n\n// Register search tool\nserver.tool(\n 'search',\n 'Search for a pattern in files and return file:line:column locations',\n searchSchema,\n async (args) => search(args)\n);\n\n// Register status tool\nserver.tool(\n 'status',\n 'Check Python/Pyright environment status for a project',\n statusSchema,\n async (args) => status(args)\n);\n\n// Register symbols tool\nserver.tool(\n 'symbols',\n 'Extract symbols (classes, functions, methods, variables) from a Python file',\n symbolsSchema,\n async (args) => symbols(args)\n);\n\n// Register update_document tool\nserver.tool(\n 'update_document',\n 'Update the content of an open Python file for incremental analysis',\n updateDocumentSchema,\n async (args) => updateDocument(args)\n);\n\n/**\n * Gracefully shutdown the server\n */\nasync function gracefulShutdown(signal: string): Promise<void> {\n console.error(`\\n[Server] Received ${signal}, shutting down gracefully...`);\n\n try {\n // Close all LSP connections\n await shutdownLspClient();\n console.error('[Server] LSP connections closed');\n\n // Close the MCP server\n await server.close();\n console.error('[Server] MCP server closed');\n\n process.exit(0);\n } catch (error) {\n console.error('[Server] Error during shutdown:', error);\n process.exit(1);\n }\n}\n\n// Handle shutdown signals\nprocess.on('SIGTERM', () => gracefulShutdown('SIGTERM'));\nprocess.on('SIGINT', () => gracefulShutdown('SIGINT'));\n\n// Start the server\nasync function main() {\n console.error(`Pyright MCP server`);\n console.error(` Workspace: auto-detected from file path`);\n\n // Initialize LSP client (lazy start on first request)\n getLspClient();\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(` Ready`);\n}\n\nmain().catch((error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n",
6
+ "import { z } from 'zod';\nimport { getLspClient } from '../lsp-client.js';\nimport { toPosition, formatRange } from '../utils/position.js';\nimport { MarkupContent } from 'vscode-languageserver-protocol';\n\nexport const hoverSchema = {\n file: z.string().describe('Absolute path to the Python file'),\n line: z.number().int().positive().describe('Line number (1-based)'),\n column: z.number().int().positive().describe('Column number (1-based)'),\n};\n\nexport async function hover(args: { file: string; line: number; column: number }) {\n console.error(`[hover] Starting hover for ${args.file}:${args.line}:${args.column}`);\n const client = getLspClient();\n const position = toPosition(args.line, args.column);\n\n console.error(`[hover] Calling LSP hover...`);\n const result = await client.hover(args.file, position);\n console.error(`[hover] Got result: ${result ? 'yes' : 'no'}`);\n\n if (!result) {\n return {\n content: [{ type: 'text' as const, text: 'No hover information available at this position.' }],\n };\n }\n\n let hoverText = '';\n\n if (typeof result.contents === 'string') {\n hoverText = result.contents;\n } else if (Array.isArray(result.contents)) {\n hoverText = result.contents\n .map((c) => (typeof c === 'string' ? c : c.value))\n .join('\\n\\n');\n } else if ('kind' in result.contents) {\n hoverText = (result.contents as MarkupContent).value;\n } else if ('value' in result.contents) {\n hoverText = result.contents.value;\n }\n\n let output = `**Hover Info** at ${args.file}:${args.line}:${args.column}\\n\\n`;\n output += hoverText;\n\n if (result.range) {\n output += `\\n\\n**Range:** ${formatRange(result.range)}`;\n }\n\n return {\n content: [{ type: 'text' as const, text: output }],\n };\n}\n",
7
+ "import * as fs from 'fs';\nimport {\n Position,\n Hover,\n Location,\n LocationLink,\n CompletionItem,\n CompletionList,\n SignatureHelp,\n WorkspaceEdit,\n Diagnostic,\n DiagnosticSeverity,\n DocumentSymbol,\n SymbolInformation,\n} from 'vscode-languageserver-protocol';\nimport { findProjectRoot } from './utils/position.js';\nimport { getConnectionManager, LspConnectionManager } from './lsp/index.js';\n\nfunction log(message: string): void {\n console.error(`[LSP] ${message}`);\n}\n\nexport class LspClient {\n private connectionManager: LspConnectionManager;\n\n constructor() {\n this.connectionManager = getConnectionManager();\n }\n\n async start(): Promise<void> {\n // Connection is created lazily on first request\n }\n\n async stop(): Promise<void> {\n await this.connectionManager.closeAll();\n }\n\n /**\n * Ensure a document is open in the LSP server\n */\n private async ensureDocumentOpen(\n workspaceRoot: string,\n filePath: string\n ): Promise<void> {\n const docManager = this.connectionManager.getDocumentManager(workspaceRoot);\n\n if (docManager.isDocumentOpen(filePath)) {\n return;\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n await this.connectionManager.openDocument(workspaceRoot, filePath, content);\n }\n\n /**\n * Get or create a connection and ensure document is open\n */\n private async prepareRequest(filePath: string): Promise<string> {\n const workspaceRoot = findProjectRoot(filePath);\n log(`Workspace root: ${workspaceRoot}`);\n\n // Get or create connection\n await this.connectionManager.getConnection({ workspaceRoot });\n\n // Ensure document is open\n await this.ensureDocumentOpen(workspaceRoot, filePath);\n\n return workspaceRoot;\n }\n\n /**\n * Get the document URI for a file path\n */\n private getDocumentUri(workspaceRoot: string, filePath: string): string {\n return this.connectionManager.getDocumentManager(workspaceRoot).filePathToUri(filePath);\n }\n\n async hover(filePath: string, position: Position): Promise<Hover | null> {\n const workspaceRoot = await this.prepareRequest(filePath);\n const uri = this.getDocumentUri(workspaceRoot, filePath);\n\n log('Sending hover request');\n return await this.connectionManager.sendRequest<Hover | null>(\n workspaceRoot,\n 'textDocument/hover',\n {\n textDocument: { uri },\n position,\n }\n );\n }\n\n async definition(\n filePath: string,\n position: Position\n ): Promise<Location | Location[] | LocationLink[] | null> {\n const workspaceRoot = await this.prepareRequest(filePath);\n const uri = this.getDocumentUri(workspaceRoot, filePath);\n\n log('Sending definition request');\n return await this.connectionManager.sendRequest<Location | Location[] | LocationLink[] | null>(\n workspaceRoot,\n 'textDocument/definition',\n {\n textDocument: { uri },\n position,\n }\n );\n }\n\n async references(\n filePath: string,\n position: Position,\n includeDeclaration = true\n ): Promise<Location[] | null> {\n const workspaceRoot = await this.prepareRequest(filePath);\n const uri = this.getDocumentUri(workspaceRoot, filePath);\n\n log('Sending references request');\n return await this.connectionManager.sendRequest<Location[] | null>(\n workspaceRoot,\n 'textDocument/references',\n {\n textDocument: { uri },\n position,\n context: { includeDeclaration },\n }\n );\n }\n\n async completions(\n filePath: string,\n position: Position\n ): Promise<CompletionItem[] | CompletionList | null> {\n const workspaceRoot = await this.prepareRequest(filePath);\n const uri = this.getDocumentUri(workspaceRoot, filePath);\n\n log('Sending completions request');\n return await this.connectionManager.sendRequest<CompletionItem[] | CompletionList | null>(\n workspaceRoot,\n 'textDocument/completion',\n {\n textDocument: { uri },\n position,\n }\n );\n }\n\n async signatureHelp(filePath: string, position: Position): Promise<SignatureHelp | null> {\n const workspaceRoot = await this.prepareRequest(filePath);\n const uri = this.getDocumentUri(workspaceRoot, filePath);\n\n log('Sending signatureHelp request');\n return await this.connectionManager.sendRequest<SignatureHelp | null>(\n workspaceRoot,\n 'textDocument/signatureHelp',\n {\n textDocument: { uri },\n position,\n }\n );\n }\n\n async rename(\n filePath: string,\n position: Position,\n newName: string\n ): Promise<WorkspaceEdit | null> {\n const workspaceRoot = await this.prepareRequest(filePath);\n const uri = this.getDocumentUri(workspaceRoot, filePath);\n\n log('Sending rename request');\n return await this.connectionManager.sendRequest<WorkspaceEdit | null>(\n workspaceRoot,\n 'textDocument/rename',\n {\n textDocument: { uri },\n position,\n newName,\n }\n );\n }\n\n async getDiagnostics(filePath: string): Promise<Diagnostic[]> {\n const workspaceRoot = await this.prepareRequest(filePath);\n const uri = this.getDocumentUri(workspaceRoot, filePath);\n\n // For diagnostics, we need to use the publishDiagnostics notification\n // But pyright-langserver doesn't support workspace/diagnostic\n // So we'll need to trigger analysis and wait for the notification\n\n // For now, we'll use a workaround: re-open the document to trigger analysis\n const content = fs.readFileSync(filePath, 'utf-8');\n const docManager = this.connectionManager.getDocumentManager(workspaceRoot);\n\n // Close and reopen to get fresh diagnostics\n if (docManager.isDocumentOpen(filePath)) {\n await this.connectionManager.closeDocument(workspaceRoot, filePath);\n }\n await this.connectionManager.openDocument(workspaceRoot, filePath, content);\n\n // Wait a bit for diagnostics\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n // Since pyright doesn't directly return diagnostics via request,\n // we need a different approach. Let's use the CLI for diagnostics.\n log('Getting diagnostics via CLI');\n return this.getDiagnosticsViaCli(filePath, workspaceRoot);\n }\n\n /**\n * Get diagnostics using pyright CLI (more reliable for batch analysis)\n */\n private getDiagnosticsViaCli(filePath: string, workspaceRoot: string): Diagnostic[] {\n const { execSync } = require('child_process');\n\n try {\n const result = execSync(`pyright --outputjson \"${filePath}\"`, {\n encoding: 'utf-8',\n cwd: workspaceRoot,\n timeout: 30000,\n maxBuffer: 10 * 1024 * 1024,\n });\n\n const parsed = JSON.parse(result);\n return this.convertPyrightDiagnostics(parsed);\n } catch (error: unknown) {\n // pyright exits with non-zero if there are errors, but still outputs JSON\n if (error && typeof error === 'object' && 'stdout' in error) {\n try {\n const parsed = JSON.parse((error as { stdout: string }).stdout);\n return this.convertPyrightDiagnostics(parsed);\n } catch {\n // Fall through to return empty\n }\n }\n return [];\n }\n }\n\n /**\n * Convert pyright CLI output to LSP diagnostics\n */\n private convertPyrightDiagnostics(output: {\n generalDiagnostics?: Array<{\n file: string;\n severity: number;\n message: string;\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n rule?: string;\n }>;\n }): Diagnostic[] {\n if (!output.generalDiagnostics) {\n return [];\n }\n\n return output.generalDiagnostics.map((d) => ({\n range: {\n start: { line: d.range.start.line, character: d.range.start.character },\n end: { line: d.range.end.line, character: d.range.end.character },\n },\n severity: d.severity as DiagnosticSeverity,\n message: d.message,\n source: 'pyright',\n code: d.rule,\n }));\n }\n\n /**\n * Get document symbols (classes, functions, methods, etc.)\n */\n async documentSymbols(\n filePath: string\n ): Promise<DocumentSymbol[] | SymbolInformation[] | null> {\n const workspaceRoot = await this.prepareRequest(filePath);\n const uri = this.getDocumentUri(workspaceRoot, filePath);\n\n log('Sending documentSymbol request');\n return await this.connectionManager.sendRequest<DocumentSymbol[] | SymbolInformation[] | null>(\n workspaceRoot,\n 'textDocument/documentSymbol',\n {\n textDocument: { uri },\n }\n );\n }\n\n /**\n * Update a document's content (for incremental updates)\n */\n async updateDocument(filePath: string, content: string): Promise<void> {\n const workspaceRoot = findProjectRoot(filePath);\n\n // Ensure connection exists\n await this.connectionManager.getConnection({ workspaceRoot });\n\n // Update document\n await this.connectionManager.updateDocument(workspaceRoot, filePath, content);\n\n log(`Updated document: ${filePath}`);\n }\n\n /**\n * Get connection status for debugging\n */\n getStatus(): { workspaceRoot: string; initialized: boolean; lastUsed: Date }[] {\n return this.connectionManager.getStatus();\n }\n}\n\nlet client: LspClient | null = null;\n\nexport function getLspClient(): LspClient {\n if (!client) {\n client = new LspClient();\n }\n return client;\n}\n\n/**\n * Gracefully shutdown the LSP client\n */\nexport async function shutdownLspClient(): Promise<void> {\n if (client) {\n await client.stop();\n client = null;\n }\n}\n",
8
+ "import { Position, Range, Location } from 'vscode-languageserver-protocol';\nimport { existsSync } from 'fs';\nimport { dirname, join, resolve } from 'path';\n\n/**\n * Convert 1-based line/column (user input) to 0-based LSP Position\n */\nexport function toPosition(line: number, column: number): Position {\n return Position.create(line - 1, column - 1);\n}\n\n/**\n * Convert 0-based LSP Position to 1-based line/column (user output)\n */\nexport function fromPosition(pos: Position): { line: number; column: number } {\n return {\n line: pos.line + 1,\n column: pos.character + 1,\n };\n}\n\n/**\n * Format a Location for display\n */\nexport function formatLocation(loc: Location): string {\n const start = fromPosition(loc.range.start);\n const end = fromPosition(loc.range.end);\n return `${loc.uri}:${start.line}:${start.column}-${end.line}:${end.column}`;\n}\n\n/**\n * Format a Range for display\n */\nexport function formatRange(range: Range): string {\n const start = fromPosition(range.start);\n const end = fromPosition(range.end);\n return `${start.line}:${start.column}-${end.line}:${end.column}`;\n}\n\n/**\n * Convert file path to URI\n */\nexport function pathToUri(filePath: string): string {\n if (filePath.startsWith('file://')) {\n return filePath;\n }\n return `file://${filePath}`;\n}\n\n/**\n * Convert URI to file path\n */\nexport function uriToPath(uri: string): string {\n if (uri.startsWith('file://')) {\n return uri.slice(7);\n }\n return uri;\n}\n\n/**\n * Find project root by looking for pyrightconfig.json or pyproject.toml\n * starting from the given file path and walking up the directory tree\n */\nexport function findProjectRoot(filePath: string): string {\n const configFiles = ['pyrightconfig.json', 'pyproject.toml', '.git'];\n let dir = dirname(resolve(filePath));\n const root = '/';\n\n while (dir !== root) {\n for (const configFile of configFiles) {\n if (existsSync(join(dir, configFile))) {\n return dir;\n }\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n // Fallback to file's directory\n return dirname(resolve(filePath));\n}\n",
9
+ "import { spawn } from 'child_process';\nimport {\n createMessageConnection,\n StreamMessageReader,\n StreamMessageWriter,\n} from 'vscode-jsonrpc/node.js';\nimport type { MessageConnection } from 'vscode-jsonrpc/node.js';\nimport type { LspConnection, ConnectionOptions } from './types.js';\nimport { DocumentManager } from './document-manager.js';\n\n/**\n * Manages persistent LSP connections to pyright-langserver.\n * Maintains one connection per workspace root.\n */\nexport class LspConnectionManager {\n private connections: Map<string, LspConnection> = new Map();\n private documentManagers: Map<string, DocumentManager> = new Map();\n private initializationPromises: Map<string, Promise<LspConnection>> = new Map();\n\n /** Default timeout for initialization */\n private static readonly DEFAULT_INIT_TIMEOUT = 10000;\n\n /** Time to wait after opening a document before it's ready for analysis */\n private static readonly DOCUMENT_READY_DELAY = 500;\n\n /**\n * Get or create a connection for the given workspace\n */\n async getConnection(options: ConnectionOptions): Promise<LspConnection> {\n const { workspaceRoot } = options;\n\n // Check for existing initialized connection\n const existing = this.connections.get(workspaceRoot);\n if (existing && existing.initialized) {\n existing.lastUsed = Date.now();\n return existing;\n }\n\n // Check if initialization is already in progress\n const pendingInit = this.initializationPromises.get(workspaceRoot);\n if (pendingInit) {\n return pendingInit;\n }\n\n // Create new connection\n const initPromise = this.createConnection(options);\n this.initializationPromises.set(workspaceRoot, initPromise);\n\n try {\n const connection = await initPromise;\n this.connections.set(workspaceRoot, connection);\n return connection;\n } finally {\n this.initializationPromises.delete(workspaceRoot);\n }\n }\n\n /**\n * Get the document manager for a workspace\n */\n getDocumentManager(workspaceRoot: string): DocumentManager {\n let manager = this.documentManagers.get(workspaceRoot);\n if (!manager) {\n manager = new DocumentManager();\n this.documentManagers.set(workspaceRoot, manager);\n }\n return manager;\n }\n\n /**\n * Create and initialize a new LSP connection\n */\n private async createConnection(options: ConnectionOptions): Promise<LspConnection> {\n const { workspaceRoot, initTimeout = LspConnectionManager.DEFAULT_INIT_TIMEOUT } = options;\n\n // Spawn pyright-langserver\n // Use 'ignore' for stderr to prevent buffer blocking since MCP uses stdio\n const pyrightProcess = spawn('pyright-langserver', ['--stdio'], {\n stdio: ['pipe', 'pipe', 'ignore'],\n cwd: workspaceRoot,\n });\n\n // Handle process errors\n pyrightProcess.on('error', (err) => {\n console.error(`[LSP] Process error for ${workspaceRoot}:`, err);\n this.closeConnection(workspaceRoot);\n });\n\n pyrightProcess.on('exit', (code, signal) => {\n console.error(`[LSP] Process exited for ${workspaceRoot}: code=${code}, signal=${signal}`);\n this.connections.delete(workspaceRoot);\n });\n\n console.error(`[LSP] Spawned pyright-langserver for ${workspaceRoot}`);\n\n // Create JSON-RPC connection\n const connection: MessageConnection = createMessageConnection(\n new StreamMessageReader(pyrightProcess.stdout!),\n new StreamMessageWriter(pyrightProcess.stdin!)\n );\n\n // Handle connection errors\n connection.onError((error) => {\n console.error(`[LSP] Connection error for ${workspaceRoot}:`, error);\n });\n\n connection.onClose(() => {\n console.error(`[LSP] Connection closed for ${workspaceRoot}`);\n });\n\n connection.listen();\n\n const connectionId = Math.random().toString(36).slice(2, 8);\n console.error(`[LSP] Created connection ${connectionId}`);\n\n const lspConnection: LspConnection = {\n connection,\n process: pyrightProcess,\n workspaceRoot,\n initialized: false,\n lastUsed: Date.now(),\n id: connectionId,\n } as LspConnection & { id: string };\n\n // Initialize the connection with timeout\n await this.initializeConnection(lspConnection, initTimeout);\n\n return lspConnection;\n }\n\n /**\n * Initialize an LSP connection\n */\n private async initializeConnection(\n lspConnection: LspConnection,\n timeout: number\n ): Promise<void> {\n const { connection, workspaceRoot } = lspConnection;\n\n const initPromise = (async () => {\n // Send initialize request\n console.error(`[LSP] Sending initialize request...`);\n const initResult = await connection.sendRequest('initialize', {\n processId: process.pid,\n rootUri: `file://${workspaceRoot}`,\n capabilities: {\n textDocument: {\n hover: { contentFormat: ['markdown', 'plaintext'] },\n completion: {\n completionItem: {\n snippetSupport: true,\n documentationFormat: ['markdown', 'plaintext'],\n },\n },\n signatureHelp: {\n signatureInformation: {\n documentationFormat: ['markdown', 'plaintext'],\n },\n },\n definition: { linkSupport: true },\n references: {},\n rename: { prepareSupport: true },\n documentSymbol: {\n hierarchicalDocumentSymbolSupport: true,\n },\n publishDiagnostics: {},\n },\n // Note: Do NOT declare workspace.workspaceFolders capability\n // pyright-langserver will send workspace/workspaceFolders requests\n // that we don't handle, causing requests to hang\n },\n workspaceFolders: [\n {\n uri: `file://${workspaceRoot}`,\n name: workspaceRoot.split('/').pop() || 'workspace',\n },\n ],\n });\n\n // Send initialized notification\n console.error(`[LSP] Sending initialized notification...`);\n await connection.sendNotification('initialized', {});\n\n console.error(`[LSP] Connection initialized successfully`);\n lspConnection.initialized = true;\n })();\n\n // Race against timeout\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`LSP initialization timed out after ${timeout}ms`)), timeout);\n });\n\n await Promise.race([initPromise, timeoutPromise]);\n }\n\n /**\n * Open a document in the LSP server\n */\n async openDocument(workspaceRoot: string, filePath: string, content: string): Promise<void> {\n const lspConnection = this.connections.get(workspaceRoot);\n if (!lspConnection || !lspConnection.initialized) {\n throw new Error(`No initialized connection for workspace: ${workspaceRoot}`);\n }\n\n const docManager = this.getDocumentManager(workspaceRoot);\n\n // Skip if already open\n if (docManager.isDocumentOpen(filePath)) {\n return;\n }\n\n // Register with document manager\n const docState = docManager.openDocument(filePath, content);\n\n // Send didOpen notification\n console.error(`[LSP] Sending didOpen for ${filePath}...`);\n await lspConnection.connection.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: docState.uri,\n languageId: docState.languageId,\n version: docState.version,\n text: docState.content,\n },\n });\n\n // Wait for analysis\n console.error(`[LSP] Waiting for analysis...`);\n await this.waitForAnalysis();\n console.error(`[LSP] Document ready: ${filePath}`);\n }\n\n /**\n * Update a document's content\n */\n async updateDocument(workspaceRoot: string, filePath: string, newContent: string): Promise<void> {\n const lspConnection = this.connections.get(workspaceRoot);\n if (!lspConnection || !lspConnection.initialized) {\n throw new Error(`No initialized connection for workspace: ${workspaceRoot}`);\n }\n\n const docManager = this.getDocumentManager(workspaceRoot);\n\n // If not open, open it instead\n if (!docManager.isDocumentOpen(filePath)) {\n await this.openDocument(workspaceRoot, filePath, newContent);\n return;\n }\n\n // Update document manager\n const newVersion = docManager.updateDocument(filePath, newContent);\n const uri = docManager.filePathToUri(filePath);\n\n // Send didChange notification (full sync)\n await lspConnection.connection.sendNotification('textDocument/didChange', {\n textDocument: {\n uri,\n version: newVersion,\n },\n contentChanges: [{ text: newContent }],\n });\n\n // Wait for analysis\n await this.waitForAnalysis();\n }\n\n /**\n * Close a document in the LSP server\n */\n async closeDocument(workspaceRoot: string, filePath: string): Promise<void> {\n const lspConnection = this.connections.get(workspaceRoot);\n if (!lspConnection || !lspConnection.initialized) {\n return;\n }\n\n const docManager = this.getDocumentManager(workspaceRoot);\n if (!docManager.isDocumentOpen(filePath)) {\n return;\n }\n\n const uri = docManager.filePathToUri(filePath);\n\n // Send didClose notification\n await lspConnection.connection.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n\n // Remove from document manager\n docManager.closeDocument(filePath);\n }\n\n /**\n * Wait for LSP analysis to complete\n */\n private async waitForAnalysis(): Promise<void> {\n await new Promise((resolve) =>\n setTimeout(resolve, LspConnectionManager.DOCUMENT_READY_DELAY)\n );\n }\n\n /**\n * Send an LSP request\n */\n async sendRequest<T>(workspaceRoot: string, method: string, params: unknown): Promise<T> {\n const lspConnection = this.connections.get(workspaceRoot);\n if (!lspConnection || !lspConnection.initialized) {\n throw new Error(`No initialized connection for workspace: ${workspaceRoot}`);\n }\n\n lspConnection.lastUsed = Date.now();\n console.error(`[LSP] sendRequest: ${method}`);\n\n // 直接发送请求,不使用 Promise.race\n const result = await lspConnection.connection.sendRequest(method, params);\n console.error(`[LSP] Request ${method} done`);\n return result as T;\n }\n\n /**\n * Close a specific connection\n */\n async closeConnection(workspaceRoot: string): Promise<void> {\n const lspConnection = this.connections.get(workspaceRoot);\n if (!lspConnection) {\n return;\n }\n\n // Close all documents\n const docManager = this.documentManagers.get(workspaceRoot);\n if (docManager) {\n docManager.closeAll();\n this.documentManagers.delete(workspaceRoot);\n }\n\n // Send shutdown request if initialized\n if (lspConnection.initialized) {\n try {\n await lspConnection.connection.sendRequest('shutdown');\n await lspConnection.connection.sendNotification('exit');\n } catch {\n // Ignore errors during shutdown\n }\n }\n\n // Dispose connection\n lspConnection.connection.dispose();\n\n // Kill process\n if (!lspConnection.process.killed) {\n lspConnection.process.kill();\n }\n\n this.connections.delete(workspaceRoot);\n }\n\n /**\n * Close all connections (for graceful shutdown)\n */\n async closeAll(): Promise<void> {\n const workspaceRoots = Array.from(this.connections.keys());\n await Promise.all(workspaceRoots.map((root) => this.closeConnection(root)));\n }\n\n /**\n * Get connection status for debugging\n */\n getStatus(): { workspaceRoot: string; initialized: boolean; lastUsed: Date }[] {\n return Array.from(this.connections.entries()).map(([root, conn]) => ({\n workspaceRoot: root,\n initialized: conn.initialized,\n lastUsed: new Date(conn.lastUsed),\n }));\n }\n}\n\n// Singleton instance\nlet connectionManagerInstance: LspConnectionManager | null = null;\n\n/**\n * Get the global connection manager instance\n */\nexport function getConnectionManager(): LspConnectionManager {\n if (!connectionManagerInstance) {\n connectionManagerInstance = new LspConnectionManager();\n }\n return connectionManagerInstance;\n}\n",
10
+ "import * as fs from 'fs';\nimport * as path from 'path';\nimport type { DocumentState } from './types.js';\n\n/**\n * Manages document state and versioning for LSP operations.\n * Tracks which documents are open and their current versions.\n */\nexport class DocumentManager {\n private documents: Map<string, DocumentState> = new Map();\n\n /**\n * Convert a file path to a file:// URI\n */\n filePathToUri(filePath: string): string {\n const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);\n return `file://${absolutePath}`;\n }\n\n /**\n * Convert a file:// URI back to a file path\n */\n uriToFilePath(uri: string): string {\n if (uri.startsWith('file://')) {\n return uri.slice(7);\n }\n return uri;\n }\n\n /**\n * Check if a document is currently open\n */\n isDocumentOpen(filePath: string): boolean {\n const uri = this.filePathToUri(filePath);\n return this.documents.has(uri);\n }\n\n /**\n * Get the current state of a document\n */\n getDocument(filePath: string): DocumentState | undefined {\n const uri = this.filePathToUri(filePath);\n return this.documents.get(uri);\n }\n\n /**\n * Register a document as open with initial content\n */\n openDocument(filePath: string, content?: string): DocumentState {\n const uri = this.filePathToUri(filePath);\n\n // Read content from file if not provided\n const actualContent = content ?? fs.readFileSync(filePath, 'utf-8');\n\n const state: DocumentState = {\n uri,\n version: 1,\n content: actualContent,\n languageId: 'python',\n };\n\n this.documents.set(uri, state);\n return state;\n }\n\n /**\n * Update a document's content and increment version\n * Returns the new version number\n */\n updateDocument(filePath: string, newContent: string): number {\n const uri = this.filePathToUri(filePath);\n const existing = this.documents.get(uri);\n\n if (!existing) {\n // Document wasn't open, open it now\n const state = this.openDocument(filePath, newContent);\n return state.version;\n }\n\n // Increment version and update content\n existing.version += 1;\n existing.content = newContent;\n\n return existing.version;\n }\n\n /**\n * Mark a document as closed\n */\n closeDocument(filePath: string): boolean {\n const uri = this.filePathToUri(filePath);\n return this.documents.delete(uri);\n }\n\n /**\n * Get all open documents\n */\n getAllOpenDocuments(): DocumentState[] {\n return Array.from(this.documents.values());\n }\n\n /**\n * Close all documents\n */\n closeAll(): void {\n this.documents.clear();\n }\n\n /**\n * Get the TextDocumentIdentifier for LSP requests\n */\n getTextDocumentIdentifier(filePath: string): { uri: string } {\n return { uri: this.filePathToUri(filePath) };\n }\n\n /**\n * Get the TextDocumentItem for didOpen notification\n */\n getTextDocumentItem(filePath: string): {\n uri: string;\n languageId: string;\n version: number;\n text: string;\n } {\n const state = this.getDocument(filePath);\n if (!state) {\n throw new Error(`Document not open: ${filePath}`);\n }\n\n return {\n uri: state.uri,\n languageId: state.languageId,\n version: state.version,\n text: state.content,\n };\n }\n\n /**\n * Get the VersionedTextDocumentIdentifier for requests that need version\n */\n getVersionedTextDocumentIdentifier(filePath: string): { uri: string; version: number } {\n const state = this.getDocument(filePath);\n if (!state) {\n throw new Error(`Document not open: ${filePath}`);\n }\n\n return {\n uri: state.uri,\n version: state.version,\n };\n }\n}\n",
11
+ "import type { MessageConnection } from 'vscode-jsonrpc/node.js';\nimport type { ChildProcess } from 'child_process';\n\n/**\n * Represents an active LSP connection to a pyright-langserver process\n */\nexport interface LspConnection {\n /** The JSON-RPC message connection */\n connection: MessageConnection;\n /** The underlying child process */\n process: ChildProcess;\n /** The workspace root this connection is for */\n workspaceRoot: string;\n /** Whether the connection is initialized */\n initialized: boolean;\n /** When this connection was last used */\n lastUsed: number;\n}\n\n/**\n * Document state tracked by the document manager\n */\nexport interface DocumentState {\n /** Document URI */\n uri: string;\n /** Current version number */\n version: number;\n /** Last known content */\n content: string;\n /** Language ID (always 'python' for us) */\n languageId: string;\n}\n\n/**\n * Options for getting/creating a connection\n */\nexport interface ConnectionOptions {\n /** Workspace root path */\n workspaceRoot: string;\n /** Timeout for initialization in ms */\n initTimeout?: number;\n}\n\n/**\n * Result of an LSP request\n */\nexport interface LspResult<T> {\n success: boolean;\n result?: T;\n error?: string;\n}\n\n/**\n * Symbol filter options for the symbols tool\n */\nexport type SymbolFilter = 'all' | 'classes' | 'functions' | 'methods' | 'variables';\n\n/**\n * Symbol kind names mapping from LSP SymbolKind enum\n */\nexport const SymbolKindNames: Record<number, string> = {\n 1: 'File',\n 2: 'Module',\n 3: 'Namespace',\n 4: 'Package',\n 5: 'Class',\n 6: 'Method',\n 7: 'Property',\n 8: 'Field',\n 9: 'Constructor',\n 10: 'Enum',\n 11: 'Interface',\n 12: 'Function',\n 13: 'Variable',\n 14: 'Constant',\n 15: 'String',\n 16: 'Number',\n 17: 'Boolean',\n 18: 'Array',\n 19: 'Object',\n 20: 'Key',\n 21: 'Null',\n 22: 'EnumMember',\n 23: 'Struct',\n 24: 'Event',\n 25: 'Operator',\n 26: 'TypeParameter',\n};\n",
12
+ "import { z } from 'zod';\nimport { getLspClient } from '../lsp-client.js';\nimport { toPosition, fromPosition, uriToPath } from '../utils/position.js';\nimport { Location, LocationLink } from 'vscode-languageserver-protocol';\n\nexport const definitionSchema = {\n file: z.string().describe('Absolute path to the Python file'),\n line: z.number().int().positive().describe('Line number (1-based)'),\n column: z.number().int().positive().describe('Column number (1-based)'),\n};\n\nexport async function definition(args: { file: string; line: number; column: number }) {\n const client = getLspClient();\n const position = toPosition(args.line, args.column);\n\n const result = await client.definition(args.file, position);\n\n if (!result) {\n return {\n content: [{ type: 'text' as const, text: 'No definition found at this position.' }],\n };\n }\n\n const locations: Array<{ file: string; line: number; column: number }> = [];\n\n if (Array.isArray(result)) {\n for (const item of result) {\n if ('targetUri' in item) {\n // LocationLink\n const link = item as LocationLink;\n const pos = fromPosition(link.targetSelectionRange.start);\n locations.push({\n file: uriToPath(link.targetUri),\n line: pos.line,\n column: pos.column,\n });\n } else {\n // Location\n const loc = item as Location;\n const pos = fromPosition(loc.range.start);\n locations.push({\n file: uriToPath(loc.uri),\n line: pos.line,\n column: pos.column,\n });\n }\n }\n } else {\n // Single Location\n const loc = result as Location;\n const pos = fromPosition(loc.range.start);\n locations.push({\n file: uriToPath(loc.uri),\n line: pos.line,\n column: pos.column,\n });\n }\n\n if (locations.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No definition found at this position.' }],\n };\n }\n\n let output = `**Definition(s)** for symbol at ${args.file}:${args.line}:${args.column}\\n\\n`;\n\n for (const loc of locations) {\n output += `- ${loc.file}:${loc.line}:${loc.column}\\n`;\n }\n\n return {\n content: [{ type: 'text' as const, text: output }],\n };\n}\n",
13
+ "import { z } from 'zod';\nimport { execSync } from 'child_process';\nimport { readFileSync } from 'fs';\nimport { findProjectRoot } from '../utils/position.js';\n\nexport const referencesSchema = {\n file: z.string().describe('Absolute path to the Python file'),\n line: z.number().int().positive().describe('Line number (1-based)'),\n column: z.number().int().positive().describe('Column number (1-based)'),\n};\n\ninterface Reference {\n file: string;\n line: number;\n column: number;\n text: string;\n isDefinition?: boolean;\n}\n\nfunction getSymbolAtPosition(filePath: string, line: number, column: number): string | null {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const lines = content.split('\\n');\n const targetLine = lines[line - 1];\n if (!targetLine) return null;\n\n // Find word at position\n const col = column - 1;\n let start = col;\n let end = col;\n\n // Expand left\n while (start > 0 && /[\\w_]/.test(targetLine[start - 1])) {\n start--;\n }\n // Expand right\n while (end < targetLine.length && /[\\w_]/.test(targetLine[end])) {\n end++;\n }\n\n const symbol = targetLine.slice(start, end);\n return symbol.length > 0 ? symbol : null;\n } catch {\n return null;\n }\n}\n\nexport async function references(args: { file: string; line: number; column: number }) {\n const { file, line, column } = args;\n\n // Get symbol name at position\n const symbol = getSymbolAtPosition(file, line, column);\n if (!symbol) {\n return {\n content: [{ type: 'text' as const, text: 'Could not identify symbol at this position.' }],\n };\n }\n\n // Find project root\n const projectRoot = findProjectRoot(file);\n\n // Use ripgrep to find all references in Python files\n // Match word boundaries to avoid partial matches\n const pattern = `\\\\b${symbol}\\\\b`;\n let rgOutput: string;\n\n try {\n // Try ripgrep first\n rgOutput = execSync(\n `rg --no-heading --line-number --column --type py \"${pattern}\" \"${projectRoot}\"`,\n {\n encoding: 'utf-8',\n maxBuffer: 10 * 1024 * 1024,\n timeout: 30000,\n }\n );\n } catch (e: unknown) {\n const error = e as { stdout?: string; status?: number };\n if (error.status === 1) {\n // No matches found\n return {\n content: [\n {\n type: 'text' as const,\n text: `No references found for symbol \\`${symbol}\\``,\n },\n ],\n };\n }\n // Try grep as fallback\n try {\n rgOutput = execSync(\n `grep -rn --include=\"*.py\" -w \"${symbol}\" \"${projectRoot}\"`,\n {\n encoding: 'utf-8',\n maxBuffer: 10 * 1024 * 1024,\n timeout: 30000,\n }\n );\n } catch {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No references found for symbol \\`${symbol}\\``,\n },\n ],\n };\n }\n }\n\n // Parse ripgrep output: file:line:column:text\n const refs: Reference[] = [];\n const lines = rgOutput.trim().split('\\n').filter(Boolean);\n\n for (const outputLine of lines) {\n // Format: /path/to/file.py:10:5: some code here\n const match = outputLine.match(/^(.+?):(\\d+):(\\d+):(.*)$/);\n if (match) {\n const [, filePath, lineNum, colNum, text] = match;\n refs.push({\n file: filePath,\n line: parseInt(lineNum, 10),\n column: parseInt(colNum, 10),\n text: text.trim(),\n isDefinition: filePath === file && parseInt(lineNum, 10) === line,\n });\n } else {\n // Fallback for grep format: /path/to/file.py:10: some code here\n const grepMatch = outputLine.match(/^(.+?):(\\d+):(.*)$/);\n if (grepMatch) {\n const [, filePath, lineNum, text] = grepMatch;\n refs.push({\n file: filePath,\n line: parseInt(lineNum, 10),\n column: 1,\n text: text.trim(),\n isDefinition: filePath === file && parseInt(lineNum, 10) === line,\n });\n }\n }\n }\n\n if (refs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No references found for symbol \\`${symbol}\\``,\n },\n ],\n };\n }\n\n // Sort: definition first, then by file and line\n refs.sort((a, b) => {\n if (a.isDefinition && !b.isDefinition) return -1;\n if (!a.isDefinition && b.isDefinition) return 1;\n if (a.file !== b.file) return a.file.localeCompare(b.file);\n return a.line - b.line;\n });\n\n // Group by file\n const byFile = new Map<string, Reference[]>();\n for (const ref of refs) {\n const list = byFile.get(ref.file) || [];\n list.push(ref);\n byFile.set(ref.file, list);\n }\n\n let output = `**References** for \\`${symbol}\\`\\n\\n`;\n output += `Found ${refs.length} reference(s) in ${byFile.size} file(s):\\n\\n`;\n\n for (const [filePath, fileRefs] of byFile) {\n output += `### ${filePath}\\n\\n`;\n for (const ref of fileRefs) {\n const marker = ref.isDefinition ? ' (definition)' : '';\n output += `- **${ref.line}:${ref.column}**${marker}: \\`${ref.text}\\`\\n`;\n }\n output += '\\n';\n }\n\n return {\n content: [{ type: 'text' as const, text: output }],\n };\n}\n",
14
+ "import { z } from 'zod';\nimport { getLspClient } from '../lsp-client.js';\nimport { toPosition } from '../utils/position.js';\nimport { CompletionItem, CompletionItemKind, CompletionList } from 'vscode-languageserver-protocol';\n\nexport const completionsSchema = {\n file: z.string().describe('Absolute path to the Python file'),\n line: z.number().int().positive().describe('Line number (1-based)'),\n column: z.number().int().positive().describe('Column number (1-based)'),\n limit: z.number().int().positive().optional().default(20).describe('Maximum number of completions to return'),\n};\n\nconst kindNames: Record<number, string> = {\n [CompletionItemKind.Text]: 'Text',\n [CompletionItemKind.Method]: 'Method',\n [CompletionItemKind.Function]: 'Function',\n [CompletionItemKind.Constructor]: 'Constructor',\n [CompletionItemKind.Field]: 'Field',\n [CompletionItemKind.Variable]: 'Variable',\n [CompletionItemKind.Class]: 'Class',\n [CompletionItemKind.Interface]: 'Interface',\n [CompletionItemKind.Module]: 'Module',\n [CompletionItemKind.Property]: 'Property',\n [CompletionItemKind.Unit]: 'Unit',\n [CompletionItemKind.Value]: 'Value',\n [CompletionItemKind.Enum]: 'Enum',\n [CompletionItemKind.Keyword]: 'Keyword',\n [CompletionItemKind.Snippet]: 'Snippet',\n [CompletionItemKind.Color]: 'Color',\n [CompletionItemKind.File]: 'File',\n [CompletionItemKind.Reference]: 'Reference',\n [CompletionItemKind.Folder]: 'Folder',\n [CompletionItemKind.EnumMember]: 'EnumMember',\n [CompletionItemKind.Constant]: 'Constant',\n [CompletionItemKind.Struct]: 'Struct',\n [CompletionItemKind.Event]: 'Event',\n [CompletionItemKind.Operator]: 'Operator',\n [CompletionItemKind.TypeParameter]: 'TypeParameter',\n};\n\nexport async function completions(args: {\n file: string;\n line: number;\n column: number;\n limit?: number;\n}) {\n const client = getLspClient();\n const position = toPosition(args.line, args.column);\n const limit = args.limit ?? 20;\n\n const result = await client.completions(args.file, position);\n\n if (!result) {\n return {\n content: [{ type: 'text' as const, text: 'No completions available at this position.' }],\n };\n }\n\n let items: CompletionItem[];\n\n if (Array.isArray(result)) {\n items = result;\n } else {\n items = (result as CompletionList).items;\n }\n\n if (items.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No completions available at this position.' }],\n };\n }\n\n const limitedItems = items.slice(0, limit);\n\n let output = `**Completions** at ${args.file}:${args.line}:${args.column}\\n\\n`;\n output += `Showing ${limitedItems.length} of ${items.length} completion(s):\\n\\n`;\n\n for (const item of limitedItems) {\n const kind = item.kind ? kindNames[item.kind] || 'Unknown' : 'Unknown';\n const detail = item.detail ? ` - ${item.detail}` : '';\n output += `- **${item.label}** (${kind})${detail}\\n`;\n }\n\n return {\n content: [{ type: 'text' as const, text: output }],\n };\n}\n",
15
+ "import { z } from 'zod';\nimport { execSync } from 'child_process';\nimport { existsSync } from 'fs';\nimport { findProjectRoot } from '../utils/position.js';\n\nexport const diagnosticsSchema = {\n path: z\n .string()\n .describe('Path to a Python file or directory to check'),\n};\n\ninterface PyrightDiagnostic {\n file: string;\n severity: string;\n message: string;\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n rule?: string;\n}\n\ninterface PyrightOutput {\n version: string;\n time: string;\n generalDiagnostics: PyrightDiagnostic[];\n summary: {\n filesAnalyzed: number;\n errorCount: number;\n warningCount: number;\n informationCount: number;\n timeInSec: number;\n };\n}\n\nexport async function diagnostics(args: { path: string }) {\n const { path } = args;\n\n // Determine project root from path\n const projectRoot = findProjectRoot(path);\n\n // Build pyright command - path can be file or directory\n const target = path;\n const cmd = `pyright \"${target}\" --outputjson`;\n\n let output: PyrightOutput;\n try {\n const result = execSync(cmd, {\n encoding: 'utf-8',\n cwd: projectRoot,\n timeout: 60000,\n maxBuffer: 10 * 1024 * 1024,\n });\n output = JSON.parse(result);\n } catch (e: unknown) {\n const error = e as { stdout?: string; stderr?: string; message?: string };\n // pyright returns non-zero exit code if there are errors\n if (error.stdout) {\n try {\n output = JSON.parse(error.stdout);\n } catch {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error running pyright: ${error.message || 'Unknown error'}`,\n },\n ],\n };\n }\n } else {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error running pyright: ${error.message || 'Unknown error'}\\n\\nMake sure pyright is installed: npm install -g pyright`,\n },\n ],\n };\n }\n }\n\n const diags = output.generalDiagnostics || [];\n const summary = output.summary;\n\n if (diags.length === 0) {\n let text = `**No issues found**\\n\\n`;\n text += `- Files analyzed: ${summary.filesAnalyzed}\\n`;\n text += `- Time: ${summary.timeInSec}s`;\n return {\n content: [{ type: 'text' as const, text }],\n };\n }\n\n // Group by file\n const byFile = new Map<string, PyrightDiagnostic[]>();\n for (const diag of diags) {\n const list = byFile.get(diag.file) || [];\n list.push(diag);\n byFile.set(diag.file, list);\n }\n\n let text = `**Diagnostics Summary**\\n\\n`;\n text += `- Errors: ${summary.errorCount}\\n`;\n text += `- Warnings: ${summary.warningCount}\\n`;\n text += `- Information: ${summary.informationCount}\\n`;\n text += `- Files analyzed: ${summary.filesAnalyzed}\\n`;\n text += `- Time: ${summary.timeInSec}s\\n\\n`;\n\n text += `---\\n\\n`;\n\n for (const [filePath, fileDiags] of byFile) {\n text += `### ${filePath}\\n\\n`;\n for (const diag of fileDiags) {\n const line = diag.range.start.line + 1;\n const col = diag.range.start.character + 1;\n const rule = diag.rule ? ` (${diag.rule})` : '';\n const icon = diag.severity === 'error' ? '❌' : diag.severity === 'warning' ? '⚠️' : 'ℹ️';\n text += `- ${icon} **${diag.severity}** at ${line}:${col}${rule}\\n`;\n text += ` ${diag.message}\\n\\n`;\n }\n }\n\n return {\n content: [{ type: 'text' as const, text }],\n };\n}\n",
16
+ "import { z } from 'zod';\nimport { getLspClient } from '../lsp-client.js';\nimport { toPosition } from '../utils/position.js';\nimport { MarkupContent } from 'vscode-languageserver-protocol';\n\nexport const signatureHelpSchema = {\n file: z.string().describe('Absolute path to the Python file'),\n line: z.number().int().positive().describe('Line number (1-based)'),\n column: z.number().int().positive().describe('Column number (1-based)'),\n};\n\nexport async function signatureHelp(args: { file: string; line: number; column: number }) {\n const client = getLspClient();\n const position = toPosition(args.line, args.column);\n\n const result = await client.signatureHelp(args.file, position);\n\n if (!result || result.signatures.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No signature help available at this position.' }],\n };\n }\n\n let output = `**Signature Help** at ${args.file}:${args.line}:${args.column}\\n\\n`;\n\n const activeIndex = result.activeSignature ?? 0;\n const activeParam = result.activeParameter ?? 0;\n\n for (let i = 0; i < result.signatures.length; i++) {\n const sig = result.signatures[i];\n const isActive = i === activeIndex;\n\n output += `${isActive ? '→ ' : ' '}**${sig.label}**\\n`;\n\n if (sig.documentation) {\n const doc =\n typeof sig.documentation === 'string'\n ? sig.documentation\n : (sig.documentation as MarkupContent).value;\n output += ` ${doc}\\n`;\n }\n\n if (sig.parameters && sig.parameters.length > 0) {\n output += `\\n Parameters:\\n`;\n for (let j = 0; j < sig.parameters.length; j++) {\n const param = sig.parameters[j];\n const isActiveParam = isActive && j === activeParam;\n const label =\n typeof param.label === 'string'\n ? param.label\n : sig.label.slice(param.label[0], param.label[1]);\n\n output += ` ${isActiveParam ? '→ ' : ' '}${label}`;\n\n if (param.documentation) {\n const paramDoc =\n typeof param.documentation === 'string'\n ? param.documentation\n : (param.documentation as MarkupContent).value;\n output += ` - ${paramDoc}`;\n }\n output += '\\n';\n }\n }\n output += '\\n';\n }\n\n return {\n content: [{ type: 'text' as const, text: output }],\n };\n}\n",
17
+ "import { z } from 'zod';\nimport { execSync } from 'child_process';\nimport { readFileSync } from 'fs';\nimport { findProjectRoot } from '../utils/position.js';\n\nexport const renameSchema = {\n file: z.string().describe('Absolute path to the Python file'),\n line: z.number().int().positive().describe('Line number (1-based)'),\n column: z.number().int().positive().describe('Column number (1-based)'),\n newName: z.string().describe('New name for the symbol'),\n};\n\ninterface RenameEdit {\n file: string;\n line: number;\n column: number;\n endColumn: number;\n oldText: string;\n newText: string;\n lineContent: string;\n}\n\nfunction getSymbolAtPosition(\n filePath: string,\n line: number,\n column: number\n): { symbol: string; start: number; end: number } | null {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const lines = content.split('\\n');\n const targetLine = lines[line - 1];\n if (!targetLine) return null;\n\n // Find word at position\n const col = column - 1;\n let start = col;\n let end = col;\n\n // Expand left\n while (start > 0 && /[\\w_]/.test(targetLine[start - 1])) {\n start--;\n }\n // Expand right\n while (end < targetLine.length && /[\\w_]/.test(targetLine[end])) {\n end++;\n }\n\n const symbol = targetLine.slice(start, end);\n return symbol.length > 0 ? { symbol, start: start + 1, end: end + 1 } : null;\n } catch {\n return null;\n }\n}\n\nexport async function rename(args: { file: string; line: number; column: number; newName: string }) {\n const { file, line, column, newName } = args;\n\n // Get symbol name at position\n const symbolInfo = getSymbolAtPosition(file, line, column);\n if (!symbolInfo) {\n return {\n content: [{ type: 'text' as const, text: 'Could not identify symbol at this position.' }],\n };\n }\n\n const { symbol: oldName } = symbolInfo;\n\n if (oldName === newName) {\n return {\n content: [{ type: 'text' as const, text: 'New name is the same as the old name.' }],\n };\n }\n\n // Find project root\n const projectRoot = findProjectRoot(file);\n\n // Use ripgrep to find all references in Python files\n const pattern = `\\\\b${oldName}\\\\b`;\n let rgOutput: string;\n\n try {\n rgOutput = execSync(\n `rg --no-heading --line-number --column --type py \"${pattern}\" \"${projectRoot}\"`,\n {\n encoding: 'utf-8',\n maxBuffer: 10 * 1024 * 1024,\n timeout: 30000,\n }\n );\n } catch (e: unknown) {\n const error = e as { status?: number };\n if (error.status === 1) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No references found for symbol \\`${oldName}\\``,\n },\n ],\n };\n }\n // Try grep as fallback\n try {\n rgOutput = execSync(`grep -rn --include=\"*.py\" -w \"${oldName}\" \"${projectRoot}\"`, {\n encoding: 'utf-8',\n maxBuffer: 10 * 1024 * 1024,\n timeout: 30000,\n });\n } catch {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No references found for symbol \\`${oldName}\\``,\n },\n ],\n };\n }\n }\n\n // Parse output and create edits\n const edits: RenameEdit[] = [];\n const outputLines = rgOutput.trim().split('\\n').filter(Boolean);\n\n for (const outputLine of outputLines) {\n // Format: /path/to/file.py:10:5: some code here\n const match = outputLine.match(/^(.+?):(\\d+):(\\d+):(.*)$/);\n if (match) {\n const [, filePath, lineNum, colNum, lineContent] = match;\n const col = parseInt(colNum, 10);\n edits.push({\n file: filePath,\n line: parseInt(lineNum, 10),\n column: col,\n endColumn: col + oldName.length,\n oldText: oldName,\n newText: newName,\n lineContent: lineContent.trim(),\n });\n }\n }\n\n if (edits.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No references found for symbol \\`${oldName}\\``,\n },\n ],\n };\n }\n\n // Group by file\n const byFile = new Map<string, RenameEdit[]>();\n for (const edit of edits) {\n const list = byFile.get(edit.file) || [];\n list.push(edit);\n byFile.set(edit.file, list);\n }\n\n let output = `**Rename Preview**\\n\\n`;\n output += `- Symbol: \\`${oldName}\\` → \\`${newName}\\`\\n`;\n output += `- Found ${edits.length} occurrence(s) in ${byFile.size} file(s)\\n\\n`;\n output += `---\\n\\n`;\n\n for (const [filePath, fileEdits] of byFile) {\n output += `### ${filePath}\\n\\n`;\n for (const edit of fileEdits) {\n const preview = edit.lineContent.replace(\n new RegExp(`\\\\b${oldName}\\\\b`),\n `~~${oldName}~~ **${newName}**`\n );\n output += `- Line ${edit.line}: ${preview}\\n`;\n }\n output += '\\n';\n }\n\n output += `---\\n\\n`;\n output += `**Note:** This is a preview only. To apply the rename, use your editor's rename feature or run:\\n`;\n output += `\\`\\`\\`bash\\n`;\n output += `# Using sed (backup recommended)\\n`;\n output += `find \"${projectRoot}\" -name \"*.py\" -exec sed -i '' 's/\\\\b${oldName}\\\\b/${newName}/g' {} +\\n`;\n output += `\\`\\`\\``;\n\n return {\n content: [{ type: 'text' as const, text: output }],\n };\n}\n",
18
+ "import { z } from 'zod';\nimport { execSync } from 'child_process';\nimport * as path from 'path';\n\nexport const searchSchema = {\n pattern: z.string().describe('The regex pattern to search for'),\n path: z.string().optional().describe('Directory or file to search in (defaults to current working directory)'),\n glob: z.string().optional().describe('Glob pattern to filter files (e.g., \"*.py\", \"**/*.ts\")'),\n caseSensitive: z.boolean().optional().default(true).describe('Whether the search is case sensitive'),\n maxResults: z.number().int().positive().optional().default(50).describe('Maximum number of results to return'),\n};\n\ninterface SearchResult {\n file: string;\n line: number;\n column: number;\n text: string;\n match: string;\n}\n\nexport async function search(args: {\n pattern: string;\n path?: string;\n glob?: string;\n caseSensitive?: boolean;\n maxResults?: number;\n}): Promise<{ content: Array<{ type: 'text'; text: string }> }> {\n const searchPath = args.path || process.cwd();\n const caseSensitive = args.caseSensitive ?? true;\n const maxResults = args.maxResults ?? 50;\n\n // Build rg command\n const rgArgs: string[] = [\n '--json',\n '--line-number',\n '--column',\n ];\n\n if (!caseSensitive) {\n rgArgs.push('--ignore-case');\n }\n\n if (args.glob) {\n rgArgs.push('--glob', args.glob);\n }\n\n rgArgs.push('--', args.pattern, searchPath);\n\n try {\n const result = execSync(`rg ${rgArgs.map(a => `'${a}'`).join(' ')}`, {\n encoding: 'utf-8',\n maxBuffer: 10 * 1024 * 1024, // 10MB\n });\n\n const results: SearchResult[] = [];\n const lines = result.split('\\n').filter(Boolean);\n\n for (const line of lines) {\n if (results.length >= maxResults) break;\n\n try {\n const json = JSON.parse(line);\n if (json.type === 'match') {\n const data = json.data;\n const filePath = data.path.text;\n const lineNumber = data.line_number;\n const lineText = data.lines.text.trimEnd();\n\n // Get all matches in this line\n for (const submatch of data.submatches) {\n if (results.length >= maxResults) break;\n results.push({\n file: path.resolve(filePath),\n line: lineNumber,\n column: submatch.start + 1, // Convert to 1-based\n text: lineText,\n match: submatch.match.text,\n });\n }\n }\n } catch {\n // Skip non-JSON lines\n }\n }\n\n if (results.length === 0) {\n return {\n content: [{ type: 'text', text: `No matches found for pattern: ${args.pattern}` }],\n };\n }\n\n let output = `**Search Results** for \\`${args.pattern}\\`\\n\\n`;\n output += `Found ${results.length} match(es)${results.length >= maxResults ? ` (limited to ${maxResults})` : ''}:\\n\\n`;\n\n for (const r of results) {\n output += `**${r.file}:${r.line}:${r.column}**\\n`;\n output += ` \\`${r.text}\\`\\n`;\n output += ` Match: \\`${r.match}\\`\\n\\n`;\n }\n\n return {\n content: [{ type: 'text', text: output }],\n };\n } catch (err: unknown) {\n const error = err as { status?: number; message?: string };\n if (error.status === 1) {\n // rg returns 1 when no matches found\n return {\n content: [{ type: 'text', text: `No matches found for pattern: ${args.pattern}` }],\n };\n }\n return {\n content: [{ type: 'text', text: `Search error: ${error.message || 'Unknown error'}` }],\n };\n }\n}\n",
19
+ "import { z } from 'zod';\nimport { execSync } from 'child_process';\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { findProjectRoot } from '../utils/position.js';\n\nexport const statusSchema = {\n file: z.string().describe('A Python file path to check the project status for'),\n};\n\ntype StatusArgs = {\n file: string;\n};\n\nexport async function status(args: StatusArgs): Promise<{ content: Array<{ type: 'text'; text: string }> }> {\n const { file } = args;\n const lines: string[] = [];\n\n // Find project root\n const projectRoot = findProjectRoot(file);\n lines.push(`## Project Root`);\n lines.push(`\\`${projectRoot}\\``);\n lines.push('');\n\n // Check pyright installation\n lines.push(`## Pyright`);\n try {\n const pyrightVersion = execSync('pyright --version', { encoding: 'utf-8' }).trim();\n lines.push(`- Version: ${pyrightVersion}`);\n } catch {\n lines.push(`- ⚠️ **Not installed or not in PATH**`);\n lines.push(` Install with: \\`npm install -g pyright\\``);\n }\n lines.push('');\n\n // Check pyright config\n lines.push(`## Pyright Config`);\n const pyrightConfigPath = join(projectRoot, 'pyrightconfig.json');\n const pyprojectPath = join(projectRoot, 'pyproject.toml');\n\n if (existsSync(pyrightConfigPath)) {\n lines.push(`- Config file: \\`pyrightconfig.json\\``);\n try {\n const config = JSON.parse(readFileSync(pyrightConfigPath, 'utf-8'));\n if (config.pythonVersion) {\n lines.push(`- Python version: ${config.pythonVersion}`);\n }\n if (config.pythonPlatform) {\n lines.push(`- Platform: ${config.pythonPlatform}`);\n }\n if (config.venvPath) {\n lines.push(`- Venv path: ${config.venvPath}`);\n }\n if (config.venv) {\n lines.push(`- Venv: ${config.venv}`);\n }\n if (config.typeCheckingMode) {\n lines.push(`- Type checking mode: ${config.typeCheckingMode}`);\n }\n if (config.include) {\n lines.push(`- Include: ${JSON.stringify(config.include)}`);\n }\n if (config.exclude) {\n lines.push(`- Exclude: ${JSON.stringify(config.exclude)}`);\n }\n } catch (e) {\n lines.push(`- ⚠️ Failed to parse config: ${e}`);\n }\n } else if (existsSync(pyprojectPath)) {\n lines.push(`- Config file: \\`pyproject.toml\\` (may contain [tool.pyright] section)`);\n } else {\n lines.push(`- ⚠️ No pyrightconfig.json or pyproject.toml found`);\n lines.push(` Pyright will use default settings`);\n }\n lines.push('');\n\n // Check Python environment\n lines.push(`## Python Environment`);\n try {\n const pythonVersion = execSync('python3 --version', { encoding: 'utf-8' }).trim();\n lines.push(`- System Python: ${pythonVersion}`);\n } catch {\n try {\n const pythonVersion = execSync('python --version', { encoding: 'utf-8' }).trim();\n lines.push(`- System Python: ${pythonVersion}`);\n } catch {\n lines.push(`- ⚠️ Python not found in PATH`);\n }\n }\n\n // Check for virtual environment\n const venvPaths = ['.venv', 'venv', '.env', 'env'];\n for (const venv of venvPaths) {\n const venvPath = join(projectRoot, venv);\n if (existsSync(venvPath)) {\n lines.push(`- Virtual env found: \\`${venv}/\\``);\n // Try to get venv python version\n const venvPython = join(venvPath, 'bin', 'python');\n if (existsSync(venvPython)) {\n try {\n const venvVersion = execSync(`\"${venvPython}\" --version`, { encoding: 'utf-8' }).trim();\n lines.push(` - ${venvVersion}`);\n } catch {\n // ignore\n }\n }\n break;\n }\n }\n lines.push('');\n\n // Quick pyright check on the file\n lines.push(`## File Check`);\n lines.push(`- File: \\`${file}\\``);\n if (existsSync(file)) {\n lines.push(`- Exists: ✅`);\n try {\n const result = execSync(`pyright \"${file}\" --outputjson`, {\n encoding: 'utf-8',\n cwd: projectRoot,\n timeout: 30000,\n });\n const output = JSON.parse(result);\n const errors = output.generalDiagnostics?.filter((d: { severity: string }) => d.severity === 'error')?.length || 0;\n const warnings = output.generalDiagnostics?.filter((d: { severity: string }) => d.severity === 'warning')?.length || 0;\n lines.push(`- Diagnostics: ${errors} errors, ${warnings} warnings`);\n } catch (e: unknown) {\n // pyright returns non-zero exit code if there are errors\n const error = e as { stdout?: string };\n if (error.stdout) {\n try {\n const output = JSON.parse(error.stdout);\n const errors = output.generalDiagnostics?.filter((d: { severity: string }) => d.severity === 'error')?.length || 0;\n const warnings = output.generalDiagnostics?.filter((d: { severity: string }) => d.severity === 'warning')?.length || 0;\n lines.push(`- Diagnostics: ${errors} errors, ${warnings} warnings`);\n } catch {\n lines.push(`- ⚠️ Could not run pyright check`);\n }\n } else {\n lines.push(`- ⚠️ Could not run pyright check`);\n }\n }\n } else {\n lines.push(`- Exists: ❌ File not found`);\n }\n\n return {\n content: [{ type: 'text', text: lines.join('\\n') }],\n };\n}\n",
20
+ "import { z } from 'zod';\nimport { getLspClient } from '../lsp-client.js';\nimport { DocumentSymbol, SymbolKind } from 'vscode-languageserver-protocol';\nimport { SymbolKindNames, SymbolFilter } from '../lsp/types.js';\n\nexport const symbolsSchema = {\n file: z.string().describe('Absolute path to the Python file'),\n filter: z\n .enum(['all', 'classes', 'functions', 'methods', 'variables'])\n .optional()\n .default('all')\n .describe('Filter symbols by type'),\n includeChildren: z\n .boolean()\n .optional()\n .default(true)\n .describe('Include nested symbols (e.g., methods inside classes)'),\n};\n\n/**\n * Get the symbol kind name from the SymbolKind enum value\n */\nfunction getSymbolKindName(kind: SymbolKind): string {\n return SymbolKindNames[kind] || 'Unknown';\n}\n\n/**\n * Check if a symbol matches the filter\n */\nfunction matchesFilter(kind: SymbolKind, filter: SymbolFilter): boolean {\n if (filter === 'all') {\n return true;\n }\n\n switch (filter) {\n case 'classes':\n return kind === SymbolKind.Class;\n case 'functions':\n return kind === SymbolKind.Function;\n case 'methods':\n return kind === SymbolKind.Method;\n case 'variables':\n return kind === SymbolKind.Variable || kind === SymbolKind.Constant;\n default:\n return true;\n }\n}\n\n/**\n * Format a symbol and its children recursively\n */\nfunction formatSymbol(\n symbol: DocumentSymbol,\n filter: SymbolFilter,\n includeChildren: boolean,\n indent: number = 0\n): string[] {\n const lines: string[] = [];\n const indentStr = ' '.repeat(indent);\n const kindName = getSymbolKindName(symbol.kind);\n const line = symbol.range.start.line + 1; // Convert to 1-based\n\n // Check if this symbol matches the filter\n const symbolMatches = matchesFilter(symbol.kind, filter);\n\n if (symbolMatches) {\n lines.push(`${indentStr}- **${symbol.name}** (${kindName}) at line ${line}`);\n }\n\n // Process children\n if (includeChildren && symbol.children && symbol.children.length > 0) {\n for (const child of symbol.children) {\n const childLines = formatSymbol(\n child,\n filter,\n includeChildren,\n symbolMatches ? indent + 1 : indent\n );\n lines.push(...childLines);\n }\n }\n\n return lines;\n}\n\n/**\n * Check if result is DocumentSymbol array (has 'range' property)\n */\nfunction isDocumentSymbolArray(\n result: unknown\n): result is DocumentSymbol[] {\n return (\n Array.isArray(result) &&\n result.length > 0 &&\n 'range' in result[0]\n );\n}\n\nexport async function symbols(args: {\n file: string;\n filter?: SymbolFilter;\n includeChildren?: boolean;\n}) {\n const filter = args.filter || 'all';\n const includeChildren = args.includeChildren !== false;\n\n console.error(`[symbols] Getting symbols for ${args.file} (filter: ${filter})`);\n const client = getLspClient();\n\n const result = await client.documentSymbols(args.file);\n console.error(`[symbols] Got result: ${result ? `${(result as unknown[]).length} symbols` : 'no'}`);\n\n if (!result || (Array.isArray(result) && result.length === 0)) {\n return {\n content: [{ type: 'text' as const, text: `No symbols found in ${args.file}` }],\n };\n }\n\n let output = `**Symbols** in ${args.file}\\n\\n`;\n\n if (isDocumentSymbolArray(result)) {\n // DocumentSymbol[] - hierarchical\n const lines: string[] = [];\n for (const symbol of result) {\n lines.push(...formatSymbol(symbol, filter, includeChildren));\n }\n\n if (lines.length === 0) {\n output += `No ${filter} symbols found.`;\n } else {\n output += lines.join('\\n');\n }\n } else {\n // SymbolInformation[] - flat list\n const filteredSymbols = result.filter((s) => matchesFilter(s.kind, filter));\n\n if (filteredSymbols.length === 0) {\n output += `No ${filter} symbols found.`;\n } else {\n for (const symbol of filteredSymbols) {\n const kindName = getSymbolKindName(symbol.kind);\n const line = symbol.location.range.start.line + 1;\n output += `- **${symbol.name}** (${kindName}) at line ${line}\\n`;\n }\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: output.trim() }],\n };\n}\n",
21
+ "import { z } from 'zod';\nimport { getLspClient } from '../lsp-client.js';\n\nexport const updateDocumentSchema = {\n file: z.string().describe('Absolute path to the Python file'),\n content: z.string().describe('New content for the file'),\n};\n\nexport async function updateDocument(args: { file: string; content: string }) {\n console.error(`[updateDocument] Updating ${args.file}`);\n const client = getLspClient();\n\n await client.updateDocument(args.file, args.content);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Document updated: ${args.file}`,\n },\n ],\n };\n}\n"
22
+ ],
23
+ "mappings": "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",
24
+ "debugId": "6646DB737E47BEFC64756E2164756E21",
25
+ "names": []
26
+ }
@@ -0,0 +1,71 @@
1
+ import type { LspConnection, ConnectionOptions } from './types.js';
2
+ import { DocumentManager } from './document-manager.js';
3
+ /**
4
+ * Manages persistent LSP connections to pyright-langserver.
5
+ * Maintains one connection per workspace root.
6
+ */
7
+ export declare class LspConnectionManager {
8
+ private connections;
9
+ private documentManagers;
10
+ private initializationPromises;
11
+ /** Default timeout for initialization */
12
+ private static readonly DEFAULT_INIT_TIMEOUT;
13
+ /** Time to wait after opening a document before it's ready for analysis */
14
+ private static readonly DOCUMENT_READY_DELAY;
15
+ /**
16
+ * Get or create a connection for the given workspace
17
+ */
18
+ getConnection(options: ConnectionOptions): Promise<LspConnection>;
19
+ /**
20
+ * Get the document manager for a workspace
21
+ */
22
+ getDocumentManager(workspaceRoot: string): DocumentManager;
23
+ /**
24
+ * Create and initialize a new LSP connection
25
+ */
26
+ private createConnection;
27
+ /**
28
+ * Initialize an LSP connection
29
+ */
30
+ private initializeConnection;
31
+ /**
32
+ * Open a document in the LSP server
33
+ */
34
+ openDocument(workspaceRoot: string, filePath: string, content: string): Promise<void>;
35
+ /**
36
+ * Update a document's content
37
+ */
38
+ updateDocument(workspaceRoot: string, filePath: string, newContent: string): Promise<void>;
39
+ /**
40
+ * Close a document in the LSP server
41
+ */
42
+ closeDocument(workspaceRoot: string, filePath: string): Promise<void>;
43
+ /**
44
+ * Wait for LSP analysis to complete
45
+ */
46
+ private waitForAnalysis;
47
+ /**
48
+ * Send an LSP request
49
+ */
50
+ sendRequest<T>(workspaceRoot: string, method: string, params: unknown): Promise<T>;
51
+ /**
52
+ * Close a specific connection
53
+ */
54
+ closeConnection(workspaceRoot: string): Promise<void>;
55
+ /**
56
+ * Close all connections (for graceful shutdown)
57
+ */
58
+ closeAll(): Promise<void>;
59
+ /**
60
+ * Get connection status for debugging
61
+ */
62
+ getStatus(): {
63
+ workspaceRoot: string;
64
+ initialized: boolean;
65
+ lastUsed: Date;
66
+ }[];
67
+ }
68
+ /**
69
+ * Get the global connection manager instance
70
+ */
71
+ export declare function getConnectionManager(): LspConnectionManager;
@@ -0,0 +1,67 @@
1
+ import type { DocumentState } from './types.js';
2
+ /**
3
+ * Manages document state and versioning for LSP operations.
4
+ * Tracks which documents are open and their current versions.
5
+ */
6
+ export declare class DocumentManager {
7
+ private documents;
8
+ /**
9
+ * Convert a file path to a file:// URI
10
+ */
11
+ filePathToUri(filePath: string): string;
12
+ /**
13
+ * Convert a file:// URI back to a file path
14
+ */
15
+ uriToFilePath(uri: string): string;
16
+ /**
17
+ * Check if a document is currently open
18
+ */
19
+ isDocumentOpen(filePath: string): boolean;
20
+ /**
21
+ * Get the current state of a document
22
+ */
23
+ getDocument(filePath: string): DocumentState | undefined;
24
+ /**
25
+ * Register a document as open with initial content
26
+ */
27
+ openDocument(filePath: string, content?: string): DocumentState;
28
+ /**
29
+ * Update a document's content and increment version
30
+ * Returns the new version number
31
+ */
32
+ updateDocument(filePath: string, newContent: string): number;
33
+ /**
34
+ * Mark a document as closed
35
+ */
36
+ closeDocument(filePath: string): boolean;
37
+ /**
38
+ * Get all open documents
39
+ */
40
+ getAllOpenDocuments(): DocumentState[];
41
+ /**
42
+ * Close all documents
43
+ */
44
+ closeAll(): void;
45
+ /**
46
+ * Get the TextDocumentIdentifier for LSP requests
47
+ */
48
+ getTextDocumentIdentifier(filePath: string): {
49
+ uri: string;
50
+ };
51
+ /**
52
+ * Get the TextDocumentItem for didOpen notification
53
+ */
54
+ getTextDocumentItem(filePath: string): {
55
+ uri: string;
56
+ languageId: string;
57
+ version: number;
58
+ text: string;
59
+ };
60
+ /**
61
+ * Get the VersionedTextDocumentIdentifier for requests that need version
62
+ */
63
+ getVersionedTextDocumentIdentifier(filePath: string): {
64
+ uri: string;
65
+ version: number;
66
+ };
67
+ }
@@ -0,0 +1,3 @@
1
+ export { LspConnectionManager, getConnectionManager } from './connection.js';
2
+ export { DocumentManager } from './document-manager.js';
3
+ export * from './types.js';
@@ -0,0 +1,55 @@
1
+ import type { MessageConnection } from 'vscode-jsonrpc/node.js';
2
+ import type { ChildProcess } from 'child_process';
3
+ /**
4
+ * Represents an active LSP connection to a pyright-langserver process
5
+ */
6
+ export interface LspConnection {
7
+ /** The JSON-RPC message connection */
8
+ connection: MessageConnection;
9
+ /** The underlying child process */
10
+ process: ChildProcess;
11
+ /** The workspace root this connection is for */
12
+ workspaceRoot: string;
13
+ /** Whether the connection is initialized */
14
+ initialized: boolean;
15
+ /** When this connection was last used */
16
+ lastUsed: number;
17
+ }
18
+ /**
19
+ * Document state tracked by the document manager
20
+ */
21
+ export interface DocumentState {
22
+ /** Document URI */
23
+ uri: string;
24
+ /** Current version number */
25
+ version: number;
26
+ /** Last known content */
27
+ content: string;
28
+ /** Language ID (always 'python' for us) */
29
+ languageId: string;
30
+ }
31
+ /**
32
+ * Options for getting/creating a connection
33
+ */
34
+ export interface ConnectionOptions {
35
+ /** Workspace root path */
36
+ workspaceRoot: string;
37
+ /** Timeout for initialization in ms */
38
+ initTimeout?: number;
39
+ }
40
+ /**
41
+ * Result of an LSP request
42
+ */
43
+ export interface LspResult<T> {
44
+ success: boolean;
45
+ result?: T;
46
+ error?: string;
47
+ }
48
+ /**
49
+ * Symbol filter options for the symbols tool
50
+ */
51
+ export type SymbolFilter = 'all' | 'classes' | 'functions' | 'methods' | 'variables';
52
+ /**
53
+ * Symbol kind names mapping from LSP SymbolKind enum
54
+ */
55
+ export declare const SymbolKindNames: Record<number, string>;
@@ -1,9 +1,21 @@
1
- import { Position, Hover, Location, LocationLink, CompletionItem, CompletionList, SignatureHelp, WorkspaceEdit, Diagnostic } from 'vscode-languageserver-protocol';
1
+ import { Position, Hover, Location, LocationLink, CompletionItem, CompletionList, SignatureHelp, WorkspaceEdit, Diagnostic, DocumentSymbol, SymbolInformation } from 'vscode-languageserver-protocol';
2
2
  export declare class LspClient {
3
+ private connectionManager;
3
4
  constructor();
4
5
  start(): Promise<void>;
5
6
  stop(): Promise<void>;
6
- private runWorker;
7
+ /**
8
+ * Ensure a document is open in the LSP server
9
+ */
10
+ private ensureDocumentOpen;
11
+ /**
12
+ * Get or create a connection and ensure document is open
13
+ */
14
+ private prepareRequest;
15
+ /**
16
+ * Get the document URI for a file path
17
+ */
18
+ private getDocumentUri;
7
19
  hover(filePath: string, position: Position): Promise<Hover | null>;
8
20
  definition(filePath: string, position: Position): Promise<Location | Location[] | LocationLink[] | null>;
9
21
  references(filePath: string, position: Position, includeDeclaration?: boolean): Promise<Location[] | null>;
@@ -11,5 +23,33 @@ export declare class LspClient {
11
23
  signatureHelp(filePath: string, position: Position): Promise<SignatureHelp | null>;
12
24
  rename(filePath: string, position: Position, newName: string): Promise<WorkspaceEdit | null>;
13
25
  getDiagnostics(filePath: string): Promise<Diagnostic[]>;
26
+ /**
27
+ * Get diagnostics using pyright CLI (more reliable for batch analysis)
28
+ */
29
+ private getDiagnosticsViaCli;
30
+ /**
31
+ * Convert pyright CLI output to LSP diagnostics
32
+ */
33
+ private convertPyrightDiagnostics;
34
+ /**
35
+ * Get document symbols (classes, functions, methods, etc.)
36
+ */
37
+ documentSymbols(filePath: string): Promise<DocumentSymbol[] | SymbolInformation[] | null>;
38
+ /**
39
+ * Update a document's content (for incremental updates)
40
+ */
41
+ updateDocument(filePath: string, content: string): Promise<void>;
42
+ /**
43
+ * Get connection status for debugging
44
+ */
45
+ getStatus(): {
46
+ workspaceRoot: string;
47
+ initialized: boolean;
48
+ lastUsed: Date;
49
+ }[];
14
50
  }
15
51
  export declare function getLspClient(): LspClient;
52
+ /**
53
+ * Gracefully shutdown the LSP client
54
+ */
55
+ export declare function shutdownLspClient(): Promise<void>;
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ import { SymbolFilter } from '../lsp/types.js';
3
+ export declare const symbolsSchema: {
4
+ file: z.ZodString;
5
+ filter: z.ZodDefault<z.ZodOptional<z.ZodEnum<["all", "classes", "functions", "methods", "variables"]>>>;
6
+ includeChildren: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
7
+ };
8
+ export declare function symbols(args: {
9
+ file: string;
10
+ filter?: SymbolFilter;
11
+ includeChildren?: boolean;
12
+ }): Promise<{
13
+ content: {
14
+ type: "text";
15
+ text: string;
16
+ }[];
17
+ }>;
@@ -0,0 +1,14 @@
1
+ import { z } from 'zod';
2
+ export declare const updateDocumentSchema: {
3
+ file: z.ZodString;
4
+ content: z.ZodString;
5
+ };
6
+ export declare function updateDocument(args: {
7
+ file: string;
8
+ content: string;
9
+ }): Promise<{
10
+ content: {
11
+ type: "text";
12
+ text: string;
13
+ }[];
14
+ }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treedy/pyright-mcp",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "MCP server exposing Pyright LSP features for Python code intelligence",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,13 +11,14 @@
11
11
  "dist"
12
12
  ],
13
13
  "scripts": {
14
- "build": "tsc && cp src/pyright-worker.mjs dist/",
15
- "prepublishOnly": "npm run build",
16
- "start": "node dist/index.js",
17
- "dev": "tsc --watch",
18
- "test:pyright": "node test/test-pyright-direct.mjs",
19
- "test:mcp": "node test/test-mcp.mjs",
20
- "inspector": "npx @modelcontextprotocol/inspector node dist/index.js"
14
+ "build": "bun run build.ts",
15
+ "build:tsc": "tsc",
16
+ "prepublishOnly": "bun run build",
17
+ "start": "bun dist/index.js",
18
+ "dev": "bun --watch src/index.ts",
19
+ "test:pyright": "bun test/test-pyright-direct.mjs",
20
+ "test:mcp": "bun test/test-mcp.mjs",
21
+ "inspector": "bunx @modelcontextprotocol/inspector bun dist/index.js"
21
22
  },
22
23
  "keywords": [
23
24
  "mcp",