{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/lsp/client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonRpcClient } from \"./jsonrpc.js\";\nimport type {\n\tLspDiagnostic,\n\tLspDocumentSymbol,\n\tLspHover,\n\tLspLocation,\n\tLspLocationLink,\n\tLspPublishDiagnosticsParams,\n\tLspServerCapabilities,\n\tLspSymbolInformation,\n\tLspWorkspaceEdit,\n} from \"./types.js\";\n\n/**\n * A single managed LSP server connection: initialize handshake, document\n * synchronization (full-document sync), semantic requests, rename and\n * diagnostics delivery.\n *\n * Health/authority: this client issues requests but NEVER treats server\n * responses as trusted instructions. All request results are read-only\n * semantic data.\n */\n\nexport interface LspClientOptions {\n\trpc: JsonRpcClient;\n\trootUri: string;\n\tworkspaceRoot: string;\n\tonDiagnostics?: (params: LspPublishDiagnosticsParams) => void;\n}\n\nexport function toFileUri(absPath: string): string {\n\tconst normalized = absPath.replace(/\\\\/g, \"/\");\n\tif (normalized.startsWith(\"/\")) return `file://${encodeURI(normalized)}`;\n\t// Windows drive path\n\treturn `file:///${normalized}`;\n}\n\nexport function uriToPath(uri: string): string | null {\n\tif (!uri.startsWith(\"file://\")) return null;\n\tconst rest = uri.slice(\"file://\".length);\n\tconst raw = decodeURIComponent(rest);\n\tif (raw.startsWith(\"/\")) return raw;\n\treturn raw.replace(/^\\//, \"\").replace(/\\//g, \"\\\\\");\n}\n\nexport class LspClient {\n\tprivate rpc: JsonRpcClient;\n\treadonly rootUri: string;\n\treadonly workspaceRoot: string;\n\tprivate onDiagnostics?: (p: LspPublishDiagnosticsParams) => void;\n\tprivate capabilities: LspServerCapabilities | null = null;\n\tprivate initialized = false;\n\tprivate version = 0;\n\tprivate openUris = new Set<string>();\n\n\tconstructor(opts: LspClientOptions) {\n\t\tthis.rpc = opts.rpc;\n\t\tthis.rootUri = opts.rootUri;\n\t\tthis.workspaceRoot = opts.workspaceRoot;\n\t\tthis.onDiagnostics = opts.onDiagnostics;\n\t\tthis.rpc.setNotificationHandler((n) => {\n\t\t\tif (n.method === \"textDocument/publishDiagnostics\") {\n\t\t\t\tthis.onDiagnostics?.(n.params as LspPublishDiagnosticsParams);\n\t\t\t}\n\t\t});\n\t}\n\n\tasync initialize(): Promise<LspServerCapabilities> {\n\t\tconst result = (await this.rpc.request(\"initialize\", {\n\t\t\tprocessId: process.pid,\n\t\t\trootUri: this.rootUri,\n\t\t\tcapabilities: {},\n\t\t\tclientInfo: { name: \"jensen\", version: \"1.4.0\" },\n\t\t})) as { capabilities: LspServerCapabilities };\n\t\tthis.capabilities = result.capabilities;\n\t\tthis.rpc.notify(\"initialized\", {});\n\t\tthis.initialized = true;\n\t\treturn this.capabilities;\n\t}\n\n\tgetCapabilities(): LspServerCapabilities | null {\n\t\treturn this.capabilities;\n\t}\n\n\t/** Open a document with full-document sync. */\n\tasync openDocument(uri: string, text: string): Promise<void> {\n\t\tif (!this.openUris.has(uri)) {\n\t\t\tconst v = ++this.version;\n\t\t\tthis.rpc.notify(\"textDocument/didOpen\", {\n\t\t\t\ttextDocument: { uri, languageId: inferLanguageId(uri), version: v, text },\n\t\t\t});\n\t\t\tthis.openUris.add(uri);\n\t\t\treturn;\n\t\t}\n\t\tawait this.changeDocument(uri, text);\n\t}\n\n\t/** Full-document change (sync mode 1 = Full). */\n\tasync changeDocument(uri: string, text: string): Promise<void> {\n\t\tconst v = ++this.version;\n\t\tthis.rpc.notify(\"textDocument/didChange\", {\n\t\t\ttextDocument: { uri, version: v },\n\t\t\tcontentChanges: [{ text }],\n\t\t});\n\t}\n\n\tasync closeDocument(uri: string): Promise<void> {\n\t\tif (this.openUris.has(uri)) {\n\t\t\tthis.rpc.notify(\"textDocument/didClose\", { textDocument: { uri } });\n\t\t\tthis.openUris.delete(uri);\n\t\t}\n\t}\n\n\tasync definition(params: { uri: string; line: number; character: number }): Promise<LspLocation[]> {\n\t\treturn normalizeLocations(await this.rpc.request(\"textDocument/definition\", toPositionParams(params)));\n\t}\n\n\tasync references(params: { uri: string; line: number; character: number }): Promise<LspLocation[]> {\n\t\treturn normalizeLocations(\n\t\t\tawait this.rpc.request(\"textDocument/references\", {\n\t\t\t\t...toPositionParams(params),\n\t\t\t\tcontext: { includeDeclaration: true },\n\t\t\t}),\n\t\t);\n\t}\n\n\tasync implementations(params: { uri: string; line: number; character: number }): Promise<LspLocation[]> {\n\t\treturn normalizeLocations(await this.rpc.request(\"textDocument/implementation\", toPositionParams(params)));\n\t}\n\n\tasync hover(params: { uri: string; line: number; character: number }): Promise<LspHover | null> {\n\t\treturn (await this.rpc.request(\"textDocument/hover\", toPositionParams(params))) as LspHover | null;\n\t}\n\n\tasync documentSymbols(uri: string): Promise<LspDocumentSymbol[] | LspSymbolInformation[]> {\n\t\treturn (await this.rpc.request(\"textDocument/documentSymbol\", { textDocument: { uri } })) as\n\t\t\t| LspDocumentSymbol[]\n\t\t\t| LspSymbolInformation[];\n\t}\n\n\tasync workspaceSymbols(query: string): Promise<LspSymbolInformation[]> {\n\t\treturn normalizeSymbols(await this.rpc.request(\"workspace/symbol\", { query }));\n\t}\n\n\tasync prepareRename(params: { uri: string; line: number; character: number }): Promise<{ range: unknown } | null> {\n\t\treturn (await this.rpc.request(\"textDocument/prepareRename\", toPositionParams(params))) as {\n\t\t\trange: unknown;\n\t\t} | null;\n\t}\n\n\tasync rename(params: {\n\t\turi: string;\n\t\tline: number;\n\t\tcharacter: number;\n\t\tnewName: string;\n\t}): Promise<LspWorkspaceEdit | null> {\n\t\treturn (await this.rpc.request(\"textDocument/rename\", {\n\t\t\t...toPositionParams(params),\n\t\t\tnewName: params.newName,\n\t\t})) as LspWorkspaceEdit | null;\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\tif (!this.initialized) return;\n\t\ttry {\n\t\t\tawait this.rpc.request(\"shutdown\", null, 5000);\n\t\t} catch {\n\t\t\t// best-effort\n\t\t}\n\t\tthis.rpc.notify(\"exit\", null);\n\t}\n\n\tdispose(): void {\n\t\tthis.rpc.dispose();\n\t}\n\n\trejectAllPending(reason: string): void {\n\t\tthis.rpc.rejectAllPending(reason);\n\t}\n\n\tdiagnosticStderr(): string {\n\t\treturn this.rpc.getDiagnosticStderr();\n\t}\n}\n\nfunction toPositionParams(params: { uri: string; line: number; character: number }): {\n\ttextDocument: { uri: string };\n\tposition: { line: number; character: number };\n} {\n\treturn { textDocument: { uri: params.uri }, position: { line: params.line, character: params.character } };\n}\n\nfunction normalizeLocations(value: unknown): LspLocation[] {\n\tif (!value) return [];\n\tif (Array.isArray(value)) {\n\t\tconst out: LspLocation[] = [];\n\t\tfor (const item of value) {\n\t\t\tif (isLocationLink(item)) out.push({ uri: item.targetUri, range: item.targetRange });\n\t\t\telse if (isLocation(item)) out.push(item);\n\t\t}\n\t\treturn out;\n\t}\n\tif (isLocation(value)) return [value];\n\treturn [];\n}\n\nfunction normalizeSymbols(value: unknown): LspSymbolInformation[] {\n\tif (!Array.isArray(value)) return [];\n\treturn value.filter((v) => v && typeof v === \"object\" && \"name\" in v && \"location\" in v) as LspSymbolInformation[];\n}\n\nfunction isLocationLink(v: unknown): v is LspLocationLink {\n\treturn !!v && typeof v === \"object\" && typeof (v as { targetUri?: unknown }).targetUri === \"string\";\n}\n\nfunction isLocation(v: unknown): v is LspLocation {\n\treturn !!v && typeof v === \"object\" && typeof (v as { uri?: unknown }).uri === \"string\" && \"range\" in (v as object);\n}\n\nfunction inferLanguageId(uri: string): string {\n\tconst path = uri.endsWith(\".ts\")\n\t\t? \"typescript\"\n\t\t: uri.endsWith(\".py\")\n\t\t\t? \"python\"\n\t\t\t: uri.endsWith(\".cs\")\n\t\t\t\t? \"csharp\"\n\t\t\t\t: uri.endsWith(\".java\")\n\t\t\t\t\t? \"java\"\n\t\t\t\t\t: uri.endsWith(\".go\")\n\t\t\t\t\t\t? \"go\"\n\t\t\t\t\t\t: uri.endsWith(\".rs\")\n\t\t\t\t\t\t\t? \"rust\"\n\t\t\t\t\t\t\t: uri.endsWith(\".js\")\n\t\t\t\t\t\t\t\t? \"javascript\"\n\t\t\t\t\t\t\t\t: uri.endsWith(\".jsx\")\n\t\t\t\t\t\t\t\t\t? \"javascriptreact\"\n\t\t\t\t\t\t\t\t\t: uri.endsWith(\".tsx\")\n\t\t\t\t\t\t\t\t\t\t? \"typescriptreact\"\n\t\t\t\t\t\t\t\t\t\t: \"plaintext\";\n\treturn path;\n}\n\nexport type { LspDiagnostic };\n"]}