lsp_goto_definition, lsp_find_references, lsp_diagnostics, lsp_rename) that compose withLspClient helpers with exported plugin schema definitions (see src/tools/lsp/tools.ts).LSPServerManager in src/tools/lsp/client.ts is a singleton connection pool that keys clients by <workspace-root>::<server-id>, tracks reference counts, and evicts idle or dead processes.LSPClient wears responsibility for spawning the underlying language server (bun.spawn), wiring vscode-jsonrpc streams, maintaining opened documents, collecting diagnostics notifications, and gracefully shutting down/ restarting when needed.src/tools/lsp/utils.ts keep formatting, severity mapping, diagnostic filtering, workspace root discovery, URI translation, and workspace-edit application consolidated; they also host withLspClient, which orchestrates server lookup, client acquisition/release, and retry messaging when initialization is still in progress.src/tools/lsp/constants.ts, src/tools/lsp/config.ts) define the supported servers, extension-to-language mappings, install hints, and runtime checks for whether the configured binaries exist, so the tools never start a missing server.src/tools/lsp/types.ts mirror the vscode-languageserver-protocol definitions that both the client and tools consume.lsp_find_references) calls withLspClient with a file path; withLspClient resolves the extension using findServerForExtension and either throws an install/configuration error or proceeds.withLspClient asks lspManager for a client tied to the workspace root; the manager either reuses an existing LSPClient or starts/initializes a new one, waiting on the init promise before handing it back, and increments the reference count.LSPClient ensures the file is open via textDocument/didOpen (loading the text, waiting for the server) before sending requests such as textDocument/definition, references, diagnostic, or rename; diagnostics request also waits for pending publishDiagnostics notifications when the server cannot answer directly.vscode-jsonrpc and are formatted/filtered by utils (formatLocation, filterDiagnosticsBySeverity, formatDiagnostic, etc.), and in the rename path the returned WorkspaceEdit is applied locally, with results reported via formatApplyResult.withLspClient releases the client reference; the manager later tears down idle clients or when the process exits.src/tools/lsp/index.ts re-exports the manager and the defined tools/types so other pieces of the CLI can import the LSP surface without touching implementation details.@opencode-ai/plugin/tool; the exported ToolDefinition instances declare arguments, descriptions, and error formatting using helpers from src/tools/lsp/utils.ts.client.ts depends on config.ts and constants.ts for language IDs, server configuration, and install hints; utils.ts depends on the same modules for severity maps, findServerForExtension, and lspManager.