@ai-agent-forge/plugin-lsp-diagnostics 0.85.4 → 0.85.6
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.
- package/agent-forge.json +1 -1
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js +4 -1
- package/dist/capability.js.map +1 -1
- package/dist/entry.d.ts +5 -6
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +14 -6
- package/dist/entry.js.map +1 -1
- package/dist/node-lsp-real-host.d.ts.map +1 -1
- package/dist/node-lsp-real-host.js +14 -2
- package/dist/node-lsp-real-host.js.map +1 -1
- package/package.json +3 -3
- package/plugin.json +1 -1
package/agent-forge.json
CHANGED
package/dist/capability.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAO3E,OAAO,KAAK,EAAE,uBAAuB,EAA0B,MAAM,YAAY,CAAC;AAuKlF,6FAA6F;AAC7F,wBAAgB,uCAAuC,CAAC,OAAO,EAAE,uBAAuB,GAAG,2BAA2B,
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAO3E,OAAO,KAAK,EAAE,uBAAuB,EAA0B,MAAM,YAAY,CAAC;AAuKlF,6FAA6F;AAC7F,wBAAgB,uCAAuC,CAAC,OAAO,EAAE,uBAAuB,GAAG,2BAA2B,CAqDrH","sourcesContent":["import type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tLSP_DIAGNOSTICS_MAX_OPERATION_ID_CHARS_V1,\n\tprojectLspDiagnosticsResultV1,\n\tsanitizeLspDiagnosticsTextV1,\n} from \"./node-adapter.ts\";\nimport type { LspDiagnosticsAdapterV1, LspDiagnosticsResultV1 } from \"./types.ts\";\n\nconst requestSchema = Type.Object(\n\t{\n\t\tworkspaceRef: Type.String({ minLength: 1, maxLength: 256, pattern: \"^[A-Za-z0-9][A-Za-z0-9._:-]*$\" }),\n\t\tlanguage: Type.String({ minLength: 1, maxLength: 64, pattern: \"^[A-Za-z][A-Za-z0-9_.+-]*$\" }),\n\t\tdocumentRef: Type.String({ minLength: 1, maxLength: 256, pattern: \"^[A-Za-z0-9][A-Za-z0-9._:-]*$\" }),\n\t\tdocumentPath: Type.Optional(\n\t\t\tType.String({ minLength: 1, maxLength: 512, pattern: \"^[A-Za-z0-9_][A-Za-z0-9._/-]*$\" }),\n\t\t),\n\t\tdiagnosticsLimit: Type.Optional(Type.Integer({ minimum: 1, maximum: 128 })),\n\t},\n\t{ additionalProperties: false },\n);\n\nfunction objectInput(first: unknown, second: unknown): Record<string, unknown> {\n\tconst value = second === undefined ? first : second;\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value))\n\t\tthrow new Error(\"LSP input must be an object\");\n\treturn value as Record<string, unknown>;\n}\n\nfunction invocation(\n\tfirst: unknown,\n\tsecond: unknown,\n): { readonly input: Record<string, unknown>; readonly operationId: string } {\n\tconst candidate = typeof first === \"string\" && first.trim() !== \"\" ? first : \"profile-runtime-tool-call\";\n\treturn {\n\t\tinput: objectInput(first, second),\n\t\toperationId:\n\t\t\tcandidate.length <= LSP_DIAGNOSTICS_MAX_OPERATION_ID_CHARS_V1 ? candidate : \"profile-runtime-tool-call\",\n\t};\n}\n\nfunction signalFrom(value: unknown): AbortSignal | undefined {\n\treturn value instanceof AbortSignal ? value : undefined;\n}\n\nfunction emptySummary(): LspDiagnosticsResultV1[\"summary\"] {\n\treturn { total: 0, error: 0, warning: 0, info: 0, hint: 0 };\n}\n\nfunction cancelled(operationId: string): LspDiagnosticsResultV1 {\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: \"cancelled\",\n\t\tsummary: emptySummary(),\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\terror: { version: 1, code: \"cancelled\", message: \"LSP diagnostics were cancelled\" },\n\t};\n}\n\nfunction adapterFailed(operationId: string): LspDiagnosticsResultV1 {\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: \"failed\",\n\t\tsummary: emptySummary(),\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\terror: { version: 1, code: \"adapter_failed\", message: \"LSP adapter returned an invalid result\" },\n\t};\n}\n\nfunction validSummary(value: unknown): boolean {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst summary = value as Record<string, unknown>;\n\tconst keys = [\"total\", \"error\", \"warning\", \"info\", \"hint\"];\n\tif (Object.keys(summary).some((key) => !keys.includes(key)) || keys.some((key) => !(key in summary))) return false;\n\tconst counts = keys.map((key) => summary[key]);\n\tif (counts.some((count) => !Number.isSafeInteger(count) || (count as number) < 0 || (count as number) > 10_000_000))\n\t\treturn false;\n\treturn (counts[1] as number) + (counts[2] as number) + (counts[3] as number) + (counts[4] as number) === counts[0];\n}\n\nfunction validError(value: unknown): boolean {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst error = value as Record<string, unknown>;\n\tconst keys = [\"version\", \"code\", \"message\", \"causeCode\"];\n\tif (Object.keys(error).some((key) => !keys.includes(key))) return false;\n\tif (error.version !== 1 || typeof error.code !== \"string\" || !/^[a-z][a-z0-9_]{0,127}$/u.test(error.code))\n\t\treturn false;\n\tif (typeof error.message !== \"string\" || error.message.trim() === \"\" || error.message.length > 512) return false;\n\treturn (\n\t\terror.causeCode === undefined ||\n\t\t(typeof error.causeCode === \"string\" && /^[a-z][a-z0-9_]{0,127}$/u.test(error.causeCode))\n\t);\n}\n\nfunction validReportArtifactRef(value: unknown): value is string {\n\treturn value === undefined || (typeof value === \"string\" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u.test(value));\n}\n\nfunction boundedResult(value: unknown, operationId: string): LspDiagnosticsResultV1 {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return adapterFailed(operationId);\n\tconst result = value as Record<string, unknown>;\n\tif (result.status === \"succeeded\")\n\t\treturn projectLspDiagnosticsResultV1(result, operationId) ?? adapterFailed(operationId);\n\tif (\n\t\tresult.version !== 1 ||\n\t\tresult.operationId !== operationId ||\n\t\t![\"failed\", \"cancelled\", \"needs_user\", \"unsupported\"].includes(result.status as string) ||\n\t\t!Array.isArray(result.diagnostics) ||\n\t\tresult.diagnostics.length !== 0 ||\n\t\tresult.diagnosticsTruncated !== false ||\n\t\tresult.error === undefined\n\t)\n\t\treturn adapterFailed(operationId);\n\tif (\n\t\tObject.keys(result).some(\n\t\t\t(key) =>\n\t\t\t\t![\n\t\t\t\t\t\"version\",\n\t\t\t\t\t\"operationId\",\n\t\t\t\t\t\"status\",\n\t\t\t\t\t\"summary\",\n\t\t\t\t\t\"diagnostics\",\n\t\t\t\t\t\"diagnosticsTruncated\",\n\t\t\t\t\t\"reportArtifactRef\",\n\t\t\t\t\t\"error\",\n\t\t\t\t].includes(key),\n\t\t)\n\t)\n\t\treturn adapterFailed(operationId);\n\tif (!validSummary(result.summary) || !validError(result.error) || !validReportArtifactRef(result.reportArtifactRef))\n\t\treturn adapterFailed(operationId);\n\tconst error = result.error as {\n\t\treadonly version: 1;\n\t\treadonly code: string;\n\t\treadonly message: string;\n\t\treadonly causeCode?: string;\n\t};\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: result.status as LspDiagnosticsResultV1[\"status\"],\n\t\tsummary: result.summary as LspDiagnosticsResultV1[\"summary\"],\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\t...(result.reportArtifactRef === undefined ? {} : { reportArtifactRef: result.reportArtifactRef }),\n\t\terror: {\n\t\t\tversion: 1,\n\t\t\tcode: error.code,\n\t\t\tmessage: sanitizeLspDiagnosticsTextV1(error.message),\n\t\t\t...(error.causeCode === undefined ? {} : { causeCode: error.causeCode }),\n\t\t},\n\t};\n}\n\nconst CANCELLATION_V1 = Symbol(\"lsp-capability-cancelled\");\n\nfunction runWithCancellation(\n\trun: () => Promise<LspDiagnosticsResultV1>,\n\tsignal: AbortSignal | undefined,\n): Promise<LspDiagnosticsResultV1 | typeof CANCELLATION_V1> {\n\tif (signal === undefined) return run();\n\tlet onAbort!: () => void;\n\tconst cancellation = new Promise<typeof CANCELLATION_V1>((resolve) => {\n\t\tonAbort = () => resolve(CANCELLATION_V1);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n\tconst pending = run();\n\treturn Promise.race([pending, cancellation]).finally(() => signal.removeEventListener(\"abort\", onAbort));\n}\n\n/** Registers read-only language diagnostics using only host-owned refs and a host client. */\nexport function createLspDiagnosticsCapabilityFactoryV1(runtime: LspDiagnosticsAdapterV1): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tapi.registerTool({\n\t\t\tname: \"lsp_diagnostics\",\n\t\t\tlabel: \"LSP diagnostics\",\n\t\t\tdescription:\n\t\t\t\t\"Read bounded diagnostics from a host-bound language server; documentPath names the workspace-relative file to open\",\n\t\t\tparameters: Type.Object({ request: requestSchema }, { additionalProperties: false }),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tlet invocationResult: { readonly input: Record<string, unknown>; readonly operationId: string };\n\t\t\t\ttry {\n\t\t\t\t\tinvocationResult = invocation(first, second);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(\"profile-runtime-tool-call\");\n\t\t\t\t}\n\t\t\t\tconst { input, operationId } = invocationResult;\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted) return cancelled(operationId);\n\t\t\t\tlet requestInput: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\trequestInput = objectInput(input.request, undefined);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(operationId);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst output = await runWithCancellation(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\truntime.run(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\t\t\tworkspaceRef: requestInput.workspaceRef as string,\n\t\t\t\t\t\t\t\t\tlanguage: requestInput.language as string,\n\t\t\t\t\t\t\t\t\tdocumentRef: requestInput.documentRef as string,\n\t\t\t\t\t\t\t\t\t...(requestInput.documentPath === undefined\n\t\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t\t: { documentPath: requestInput.documentPath as string }),\n\t\t\t\t\t\t\t\t\t...(requestInput.diagnosticsLimit === undefined\n\t\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t\t: { diagnosticsLimit: requestInput.diagnosticsLimit as number }),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t);\n\t\t\t\t\tif (output === CANCELLATION_V1) return cancelled(operationId);\n\t\t\t\t\treturn boundedResult(output, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(operationId);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
|
package/dist/capability.js
CHANGED
|
@@ -139,7 +139,7 @@ export function createLspDiagnosticsCapabilityFactoryV1(runtime) {
|
|
|
139
139
|
api.registerTool({
|
|
140
140
|
name: "lsp_diagnostics",
|
|
141
141
|
label: "LSP diagnostics",
|
|
142
|
-
description: "Read bounded diagnostics from a host-bound language server",
|
|
142
|
+
description: "Read bounded diagnostics from a host-bound language server; documentPath names the workspace-relative file to open",
|
|
143
143
|
parameters: Type.Object({ request: requestSchema }, { additionalProperties: false }),
|
|
144
144
|
execute: async (first, second, third) => {
|
|
145
145
|
let invocationResult;
|
|
@@ -167,6 +167,9 @@ export function createLspDiagnosticsCapabilityFactoryV1(runtime) {
|
|
|
167
167
|
workspaceRef: requestInput.workspaceRef,
|
|
168
168
|
language: requestInput.language,
|
|
169
169
|
documentRef: requestInput.documentRef,
|
|
170
|
+
...(requestInput.documentPath === undefined
|
|
171
|
+
? {}
|
|
172
|
+
: { documentPath: requestInput.documentPath }),
|
|
170
173
|
...(requestInput.diagnosticsLimit === undefined
|
|
171
174
|
? {}
|
|
172
175
|
: { diagnosticsLimit: requestInput.diagnosticsLimit }),
|
package/dist/capability.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tLSP_DIAGNOSTICS_MAX_OPERATION_ID_CHARS_V1,\n\tprojectLspDiagnosticsResultV1,\n\tsanitizeLspDiagnosticsTextV1,\n} from \"./node-adapter.ts\";\nimport type { LspDiagnosticsAdapterV1, LspDiagnosticsResultV1 } from \"./types.ts\";\n\nconst requestSchema = Type.Object(\n\t{\n\t\tworkspaceRef: Type.String({ minLength: 1, maxLength: 256, pattern: \"^[A-Za-z0-9][A-Za-z0-9._:-]*$\" }),\n\t\tlanguage: Type.String({ minLength: 1, maxLength: 64, pattern: \"^[A-Za-z][A-Za-z0-9_.+-]*$\" }),\n\t\tdocumentRef: Type.String({ minLength: 1, maxLength: 256, pattern: \"^[A-Za-z0-9][A-Za-z0-9._:-]*$\" }),\n\t\tdocumentPath: Type.Optional(\n\t\t\tType.String({ minLength: 1, maxLength: 512, pattern: \"^[A-Za-z0-9_][A-Za-z0-9._/-]*$\" }),\n\t\t),\n\t\tdiagnosticsLimit: Type.Optional(Type.Integer({ minimum: 1, maximum: 128 })),\n\t},\n\t{ additionalProperties: false },\n);\n\nfunction objectInput(first: unknown, second: unknown): Record<string, unknown> {\n\tconst value = second === undefined ? first : second;\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value))\n\t\tthrow new Error(\"LSP input must be an object\");\n\treturn value as Record<string, unknown>;\n}\n\nfunction invocation(\n\tfirst: unknown,\n\tsecond: unknown,\n): { readonly input: Record<string, unknown>; readonly operationId: string } {\n\tconst candidate = typeof first === \"string\" && first.trim() !== \"\" ? first : \"profile-runtime-tool-call\";\n\treturn {\n\t\tinput: objectInput(first, second),\n\t\toperationId:\n\t\t\tcandidate.length <= LSP_DIAGNOSTICS_MAX_OPERATION_ID_CHARS_V1 ? candidate : \"profile-runtime-tool-call\",\n\t};\n}\n\nfunction signalFrom(value: unknown): AbortSignal | undefined {\n\treturn value instanceof AbortSignal ? value : undefined;\n}\n\nfunction emptySummary(): LspDiagnosticsResultV1[\"summary\"] {\n\treturn { total: 0, error: 0, warning: 0, info: 0, hint: 0 };\n}\n\nfunction cancelled(operationId: string): LspDiagnosticsResultV1 {\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: \"cancelled\",\n\t\tsummary: emptySummary(),\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\terror: { version: 1, code: \"cancelled\", message: \"LSP diagnostics were cancelled\" },\n\t};\n}\n\nfunction adapterFailed(operationId: string): LspDiagnosticsResultV1 {\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: \"failed\",\n\t\tsummary: emptySummary(),\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\terror: { version: 1, code: \"adapter_failed\", message: \"LSP adapter returned an invalid result\" },\n\t};\n}\n\nfunction validSummary(value: unknown): boolean {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst summary = value as Record<string, unknown>;\n\tconst keys = [\"total\", \"error\", \"warning\", \"info\", \"hint\"];\n\tif (Object.keys(summary).some((key) => !keys.includes(key)) || keys.some((key) => !(key in summary))) return false;\n\tconst counts = keys.map((key) => summary[key]);\n\tif (counts.some((count) => !Number.isSafeInteger(count) || (count as number) < 0 || (count as number) > 10_000_000))\n\t\treturn false;\n\treturn (counts[1] as number) + (counts[2] as number) + (counts[3] as number) + (counts[4] as number) === counts[0];\n}\n\nfunction validError(value: unknown): boolean {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst error = value as Record<string, unknown>;\n\tconst keys = [\"version\", \"code\", \"message\", \"causeCode\"];\n\tif (Object.keys(error).some((key) => !keys.includes(key))) return false;\n\tif (error.version !== 1 || typeof error.code !== \"string\" || !/^[a-z][a-z0-9_]{0,127}$/u.test(error.code))\n\t\treturn false;\n\tif (typeof error.message !== \"string\" || error.message.trim() === \"\" || error.message.length > 512) return false;\n\treturn (\n\t\terror.causeCode === undefined ||\n\t\t(typeof error.causeCode === \"string\" && /^[a-z][a-z0-9_]{0,127}$/u.test(error.causeCode))\n\t);\n}\n\nfunction validReportArtifactRef(value: unknown): value is string {\n\treturn value === undefined || (typeof value === \"string\" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u.test(value));\n}\n\nfunction boundedResult(value: unknown, operationId: string): LspDiagnosticsResultV1 {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return adapterFailed(operationId);\n\tconst result = value as Record<string, unknown>;\n\tif (result.status === \"succeeded\")\n\t\treturn projectLspDiagnosticsResultV1(result, operationId) ?? adapterFailed(operationId);\n\tif (\n\t\tresult.version !== 1 ||\n\t\tresult.operationId !== operationId ||\n\t\t![\"failed\", \"cancelled\", \"needs_user\", \"unsupported\"].includes(result.status as string) ||\n\t\t!Array.isArray(result.diagnostics) ||\n\t\tresult.diagnostics.length !== 0 ||\n\t\tresult.diagnosticsTruncated !== false ||\n\t\tresult.error === undefined\n\t)\n\t\treturn adapterFailed(operationId);\n\tif (\n\t\tObject.keys(result).some(\n\t\t\t(key) =>\n\t\t\t\t![\n\t\t\t\t\t\"version\",\n\t\t\t\t\t\"operationId\",\n\t\t\t\t\t\"status\",\n\t\t\t\t\t\"summary\",\n\t\t\t\t\t\"diagnostics\",\n\t\t\t\t\t\"diagnosticsTruncated\",\n\t\t\t\t\t\"reportArtifactRef\",\n\t\t\t\t\t\"error\",\n\t\t\t\t].includes(key),\n\t\t)\n\t)\n\t\treturn adapterFailed(operationId);\n\tif (!validSummary(result.summary) || !validError(result.error) || !validReportArtifactRef(result.reportArtifactRef))\n\t\treturn adapterFailed(operationId);\n\tconst error = result.error as {\n\t\treadonly version: 1;\n\t\treadonly code: string;\n\t\treadonly message: string;\n\t\treadonly causeCode?: string;\n\t};\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: result.status as LspDiagnosticsResultV1[\"status\"],\n\t\tsummary: result.summary as LspDiagnosticsResultV1[\"summary\"],\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\t...(result.reportArtifactRef === undefined ? {} : { reportArtifactRef: result.reportArtifactRef }),\n\t\terror: {\n\t\t\tversion: 1,\n\t\t\tcode: error.code,\n\t\t\tmessage: sanitizeLspDiagnosticsTextV1(error.message),\n\t\t\t...(error.causeCode === undefined ? {} : { causeCode: error.causeCode }),\n\t\t},\n\t};\n}\n\nconst CANCELLATION_V1 = Symbol(\"lsp-capability-cancelled\");\n\nfunction runWithCancellation(\n\trun: () => Promise<LspDiagnosticsResultV1>,\n\tsignal: AbortSignal | undefined,\n): Promise<LspDiagnosticsResultV1 | typeof CANCELLATION_V1> {\n\tif (signal === undefined) return run();\n\tlet onAbort!: () => void;\n\tconst cancellation = new Promise<typeof CANCELLATION_V1>((resolve) => {\n\t\tonAbort = () => resolve(CANCELLATION_V1);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n\tconst pending = run();\n\treturn Promise.race([pending, cancellation]).finally(() => signal.removeEventListener(\"abort\", onAbort));\n}\n\n/** Registers read-only language diagnostics using only host-owned refs and a host client. */\nexport function createLspDiagnosticsCapabilityFactoryV1(runtime: LspDiagnosticsAdapterV1): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tapi.registerTool({\n\t\t\tname: \"lsp_diagnostics\",\n\t\t\tlabel: \"LSP diagnostics\",\n\t\t\tdescription: \"Read bounded diagnostics from a host-bound language server\",\n\t\t\tparameters: Type.Object({ request: requestSchema }, { additionalProperties: false }),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tlet invocationResult: { readonly input: Record<string, unknown>; readonly operationId: string };\n\t\t\t\ttry {\n\t\t\t\t\tinvocationResult = invocation(first, second);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(\"profile-runtime-tool-call\");\n\t\t\t\t}\n\t\t\t\tconst { input, operationId } = invocationResult;\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted) return cancelled(operationId);\n\t\t\t\tlet requestInput: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\trequestInput = objectInput(input.request, undefined);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(operationId);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst output = await runWithCancellation(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\truntime.run(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\t\t\tworkspaceRef: requestInput.workspaceRef as string,\n\t\t\t\t\t\t\t\t\tlanguage: requestInput.language as string,\n\t\t\t\t\t\t\t\t\tdocumentRef: requestInput.documentRef as string,\n\t\t\t\t\t\t\t\t\t...(requestInput.diagnosticsLimit === undefined\n\t\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t\t: { diagnosticsLimit: requestInput.diagnosticsLimit as number }),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t);\n\t\t\t\t\tif (output === CANCELLATION_V1) return cancelled(operationId);\n\t\t\t\t\treturn boundedResult(output, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(operationId);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport {\n\tLSP_DIAGNOSTICS_MAX_OPERATION_ID_CHARS_V1,\n\tprojectLspDiagnosticsResultV1,\n\tsanitizeLspDiagnosticsTextV1,\n} from \"./node-adapter.ts\";\nimport type { LspDiagnosticsAdapterV1, LspDiagnosticsResultV1 } from \"./types.ts\";\n\nconst requestSchema = Type.Object(\n\t{\n\t\tworkspaceRef: Type.String({ minLength: 1, maxLength: 256, pattern: \"^[A-Za-z0-9][A-Za-z0-9._:-]*$\" }),\n\t\tlanguage: Type.String({ minLength: 1, maxLength: 64, pattern: \"^[A-Za-z][A-Za-z0-9_.+-]*$\" }),\n\t\tdocumentRef: Type.String({ minLength: 1, maxLength: 256, pattern: \"^[A-Za-z0-9][A-Za-z0-9._:-]*$\" }),\n\t\tdocumentPath: Type.Optional(\n\t\t\tType.String({ minLength: 1, maxLength: 512, pattern: \"^[A-Za-z0-9_][A-Za-z0-9._/-]*$\" }),\n\t\t),\n\t\tdiagnosticsLimit: Type.Optional(Type.Integer({ minimum: 1, maximum: 128 })),\n\t},\n\t{ additionalProperties: false },\n);\n\nfunction objectInput(first: unknown, second: unknown): Record<string, unknown> {\n\tconst value = second === undefined ? first : second;\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value))\n\t\tthrow new Error(\"LSP input must be an object\");\n\treturn value as Record<string, unknown>;\n}\n\nfunction invocation(\n\tfirst: unknown,\n\tsecond: unknown,\n): { readonly input: Record<string, unknown>; readonly operationId: string } {\n\tconst candidate = typeof first === \"string\" && first.trim() !== \"\" ? first : \"profile-runtime-tool-call\";\n\treturn {\n\t\tinput: objectInput(first, second),\n\t\toperationId:\n\t\t\tcandidate.length <= LSP_DIAGNOSTICS_MAX_OPERATION_ID_CHARS_V1 ? candidate : \"profile-runtime-tool-call\",\n\t};\n}\n\nfunction signalFrom(value: unknown): AbortSignal | undefined {\n\treturn value instanceof AbortSignal ? value : undefined;\n}\n\nfunction emptySummary(): LspDiagnosticsResultV1[\"summary\"] {\n\treturn { total: 0, error: 0, warning: 0, info: 0, hint: 0 };\n}\n\nfunction cancelled(operationId: string): LspDiagnosticsResultV1 {\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: \"cancelled\",\n\t\tsummary: emptySummary(),\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\terror: { version: 1, code: \"cancelled\", message: \"LSP diagnostics were cancelled\" },\n\t};\n}\n\nfunction adapterFailed(operationId: string): LspDiagnosticsResultV1 {\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: \"failed\",\n\t\tsummary: emptySummary(),\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\terror: { version: 1, code: \"adapter_failed\", message: \"LSP adapter returned an invalid result\" },\n\t};\n}\n\nfunction validSummary(value: unknown): boolean {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst summary = value as Record<string, unknown>;\n\tconst keys = [\"total\", \"error\", \"warning\", \"info\", \"hint\"];\n\tif (Object.keys(summary).some((key) => !keys.includes(key)) || keys.some((key) => !(key in summary))) return false;\n\tconst counts = keys.map((key) => summary[key]);\n\tif (counts.some((count) => !Number.isSafeInteger(count) || (count as number) < 0 || (count as number) > 10_000_000))\n\t\treturn false;\n\treturn (counts[1] as number) + (counts[2] as number) + (counts[3] as number) + (counts[4] as number) === counts[0];\n}\n\nfunction validError(value: unknown): boolean {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst error = value as Record<string, unknown>;\n\tconst keys = [\"version\", \"code\", \"message\", \"causeCode\"];\n\tif (Object.keys(error).some((key) => !keys.includes(key))) return false;\n\tif (error.version !== 1 || typeof error.code !== \"string\" || !/^[a-z][a-z0-9_]{0,127}$/u.test(error.code))\n\t\treturn false;\n\tif (typeof error.message !== \"string\" || error.message.trim() === \"\" || error.message.length > 512) return false;\n\treturn (\n\t\terror.causeCode === undefined ||\n\t\t(typeof error.causeCode === \"string\" && /^[a-z][a-z0-9_]{0,127}$/u.test(error.causeCode))\n\t);\n}\n\nfunction validReportArtifactRef(value: unknown): value is string {\n\treturn value === undefined || (typeof value === \"string\" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u.test(value));\n}\n\nfunction boundedResult(value: unknown, operationId: string): LspDiagnosticsResultV1 {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) return adapterFailed(operationId);\n\tconst result = value as Record<string, unknown>;\n\tif (result.status === \"succeeded\")\n\t\treturn projectLspDiagnosticsResultV1(result, operationId) ?? adapterFailed(operationId);\n\tif (\n\t\tresult.version !== 1 ||\n\t\tresult.operationId !== operationId ||\n\t\t![\"failed\", \"cancelled\", \"needs_user\", \"unsupported\"].includes(result.status as string) ||\n\t\t!Array.isArray(result.diagnostics) ||\n\t\tresult.diagnostics.length !== 0 ||\n\t\tresult.diagnosticsTruncated !== false ||\n\t\tresult.error === undefined\n\t)\n\t\treturn adapterFailed(operationId);\n\tif (\n\t\tObject.keys(result).some(\n\t\t\t(key) =>\n\t\t\t\t![\n\t\t\t\t\t\"version\",\n\t\t\t\t\t\"operationId\",\n\t\t\t\t\t\"status\",\n\t\t\t\t\t\"summary\",\n\t\t\t\t\t\"diagnostics\",\n\t\t\t\t\t\"diagnosticsTruncated\",\n\t\t\t\t\t\"reportArtifactRef\",\n\t\t\t\t\t\"error\",\n\t\t\t\t].includes(key),\n\t\t)\n\t)\n\t\treturn adapterFailed(operationId);\n\tif (!validSummary(result.summary) || !validError(result.error) || !validReportArtifactRef(result.reportArtifactRef))\n\t\treturn adapterFailed(operationId);\n\tconst error = result.error as {\n\t\treadonly version: 1;\n\t\treadonly code: string;\n\t\treadonly message: string;\n\t\treadonly causeCode?: string;\n\t};\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: result.status as LspDiagnosticsResultV1[\"status\"],\n\t\tsummary: result.summary as LspDiagnosticsResultV1[\"summary\"],\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\t...(result.reportArtifactRef === undefined ? {} : { reportArtifactRef: result.reportArtifactRef }),\n\t\terror: {\n\t\t\tversion: 1,\n\t\t\tcode: error.code,\n\t\t\tmessage: sanitizeLspDiagnosticsTextV1(error.message),\n\t\t\t...(error.causeCode === undefined ? {} : { causeCode: error.causeCode }),\n\t\t},\n\t};\n}\n\nconst CANCELLATION_V1 = Symbol(\"lsp-capability-cancelled\");\n\nfunction runWithCancellation(\n\trun: () => Promise<LspDiagnosticsResultV1>,\n\tsignal: AbortSignal | undefined,\n): Promise<LspDiagnosticsResultV1 | typeof CANCELLATION_V1> {\n\tif (signal === undefined) return run();\n\tlet onAbort!: () => void;\n\tconst cancellation = new Promise<typeof CANCELLATION_V1>((resolve) => {\n\t\tonAbort = () => resolve(CANCELLATION_V1);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n\tconst pending = run();\n\treturn Promise.race([pending, cancellation]).finally(() => signal.removeEventListener(\"abort\", onAbort));\n}\n\n/** Registers read-only language diagnostics using only host-owned refs and a host client. */\nexport function createLspDiagnosticsCapabilityFactoryV1(runtime: LspDiagnosticsAdapterV1): CapabilityPluginSyncFactory {\n\treturn (api) => {\n\t\tapi.registerTool({\n\t\t\tname: \"lsp_diagnostics\",\n\t\t\tlabel: \"LSP diagnostics\",\n\t\t\tdescription:\n\t\t\t\t\"Read bounded diagnostics from a host-bound language server; documentPath names the workspace-relative file to open\",\n\t\t\tparameters: Type.Object({ request: requestSchema }, { additionalProperties: false }),\n\t\t\texecute: async (first: unknown, second?: unknown, third?: unknown) => {\n\t\t\t\tlet invocationResult: { readonly input: Record<string, unknown>; readonly operationId: string };\n\t\t\t\ttry {\n\t\t\t\t\tinvocationResult = invocation(first, second);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(\"profile-runtime-tool-call\");\n\t\t\t\t}\n\t\t\t\tconst { input, operationId } = invocationResult;\n\t\t\t\tconst signal = signalFrom(third);\n\t\t\t\tif (signal?.aborted) return cancelled(operationId);\n\t\t\t\tlet requestInput: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\trequestInput = objectInput(input.request, undefined);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(operationId);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst output = await runWithCancellation(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\truntime.run(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\t\t\t\toperationId,\n\t\t\t\t\t\t\t\t\tworkspaceRef: requestInput.workspaceRef as string,\n\t\t\t\t\t\t\t\t\tlanguage: requestInput.language as string,\n\t\t\t\t\t\t\t\t\tdocumentRef: requestInput.documentRef as string,\n\t\t\t\t\t\t\t\t\t...(requestInput.documentPath === undefined\n\t\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t\t: { documentPath: requestInput.documentPath as string }),\n\t\t\t\t\t\t\t\t\t...(requestInput.diagnosticsLimit === undefined\n\t\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t\t: { diagnosticsLimit: requestInput.diagnosticsLimit as number }),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t);\n\t\t\t\t\tif (output === CANCELLATION_V1) return cancelled(operationId);\n\t\t\t\t\treturn boundedResult(output, operationId);\n\t\t\t\t} catch {\n\t\t\t\t\treturn adapterFailed(operationId);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
|
package/dist/entry.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* by design, same contract as the embedded build).
|
|
4
|
+
* Hosts that declare the `workspaceDirectory` host service get the real
|
|
5
|
+
* language-server host (tsserver/pyright/clangd resolved from that workspace);
|
|
6
|
+
* hosts without it keep the fail-closed adapter and the registered
|
|
7
|
+
* `lsp_diagnostics` tool reports an explicit `unsupported` result.
|
|
9
8
|
*/
|
|
10
|
-
declare const _default: import("@agent-forge/plugin-sdk").
|
|
9
|
+
declare const _default: (api: import("@agent-forge/plugin-sdk").CapabilityAPI) => void | import("@agent-forge/plugin-sdk").CapabilityPluginSyncInstance;
|
|
11
10
|
export default _default;
|
|
12
11
|
//# sourceMappingURL=entry.d.ts.map
|
package/dist/entry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;;AACH,wBASyC","sourcesContent":["import type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { createLspDiagnosticsCapabilityFactoryV1 } from \"./capability.ts\";\nimport { createNodeLspAdapterV1 } from \"./node-adapter.ts\";\nimport { createNodeLspRealHostV1 } from \"./node-lsp-real-host.ts\";\n\n/**\n * Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.\n *\n * Hosts that declare the `workspaceDirectory` host service get the real\n * language-server host (tsserver/pyright/clangd resolved from that workspace);\n * hosts without it keep the fail-closed adapter and the registered\n * `lsp_diagnostics` tool reports an explicit `unsupported` result.\n */\nexport default ((api) => {\n\t// An empty string is not a usable workspace (the real host would resolve\n\t// against process.cwd()); treat it as absent and stay fail-closed.\n\tconst workspaceDirectory = api.host.workspaceDirectory === \"\" ? undefined : api.host.workspaceDirectory;\n\tconst adapter =\n\t\tworkspaceDirectory === undefined\n\t\t\t? createNodeLspAdapterV1()\n\t\t\t: createNodeLspAdapterV1(createNodeLspRealHostV1({ workspaceDirectory }));\n\treturn createLspDiagnosticsCapabilityFactoryV1(adapter)(api);\n}) satisfies CapabilityPluginSyncFactory;\n"]}
|
package/dist/entry.js
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { createLspDiagnosticsCapabilityFactoryV1 } from "./capability.js";
|
|
2
2
|
import { createNodeLspAdapterV1 } from "./node-adapter.js";
|
|
3
|
+
import { createNodeLspRealHostV1 } from "./node-lsp-real-host.js";
|
|
3
4
|
/**
|
|
4
5
|
* Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* by design, same contract as the embedded build).
|
|
7
|
+
* Hosts that declare the `workspaceDirectory` host service get the real
|
|
8
|
+
* language-server host (tsserver/pyright/clangd resolved from that workspace);
|
|
9
|
+
* hosts without it keep the fail-closed adapter and the registered
|
|
10
|
+
* `lsp_diagnostics` tool reports an explicit `unsupported` result.
|
|
11
11
|
*/
|
|
12
|
-
export default
|
|
12
|
+
export default ((api) => {
|
|
13
|
+
// An empty string is not a usable workspace (the real host would resolve
|
|
14
|
+
// against process.cwd()); treat it as absent and stay fail-closed.
|
|
15
|
+
const workspaceDirectory = api.host.workspaceDirectory === "" ? undefined : api.host.workspaceDirectory;
|
|
16
|
+
const adapter = workspaceDirectory === undefined
|
|
17
|
+
? createNodeLspAdapterV1()
|
|
18
|
+
: createNodeLspAdapterV1(createNodeLspRealHostV1({ workspaceDirectory }));
|
|
19
|
+
return createLspDiagnosticsCapabilityFactoryV1(adapter)(api);
|
|
20
|
+
});
|
|
13
21
|
//# sourceMappingURL=entry.js.map
|
package/dist/entry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uCAAuC,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;;;;GAOG;AACH,eAAe,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC;IACxB,yEAAyE;IACzE,mEAAmE;IACnE,MAAM,kBAAkB,GAAG,GAAG,CAAC,IAAI,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;IACxG,MAAM,OAAO,GACZ,kBAAkB,KAAK,SAAS;QAC/B,CAAC,CAAC,sBAAsB,EAAE;QAC1B,CAAC,CAAC,sBAAsB,CAAC,uBAAuB,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAC5E,OAAO,uCAAuC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;AAAA,CAC7D,CAAuC,CAAC","sourcesContent":["import type { CapabilityPluginSyncFactory } from \"@agent-forge/plugin-sdk\";\nimport { createLspDiagnosticsCapabilityFactoryV1 } from \"./capability.ts\";\nimport { createNodeLspAdapterV1 } from \"./node-adapter.ts\";\nimport { createNodeLspRealHostV1 } from \"./node-lsp-real-host.ts\";\n\n/**\n * Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.\n *\n * Hosts that declare the `workspaceDirectory` host service get the real\n * language-server host (tsserver/pyright/clangd resolved from that workspace);\n * hosts without it keep the fail-closed adapter and the registered\n * `lsp_diagnostics` tool reports an explicit `unsupported` result.\n */\nexport default ((api) => {\n\t// An empty string is not a usable workspace (the real host would resolve\n\t// against process.cwd()); treat it as absent and stay fail-closed.\n\tconst workspaceDirectory = api.host.workspaceDirectory === \"\" ? undefined : api.host.workspaceDirectory;\n\tconst adapter =\n\t\tworkspaceDirectory === undefined\n\t\t\t? createNodeLspAdapterV1()\n\t\t\t: createNodeLspAdapterV1(createNodeLspRealHostV1({ workspaceDirectory }));\n\treturn createLspDiagnosticsCapabilityFactoryV1(adapter)(api);\n}) satisfies CapabilityPluginSyncFactory;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-lsp-real-host.d.ts","sourceRoot":"","sources":["../src/node-lsp-real-host.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACX,WAAW,EAIX,oBAAoB,EAEpB,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;CAC7B;AAuBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC5C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CAClC,GAAG,cAAc,CAmBjB;AAuTD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAChD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CAClC,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CA2C5E","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { sanitizeLspDiagnosticsTextV1 } from \"./node-adapter.ts\";\nimport type {\n\tLspClientV1,\n\tLspDiagnosticsRequestV1,\n\tLspDiagnosticV1,\n\tLspHostDiagnosticResultV1,\n\tLspSessionResolverV1,\n\tLspSessionV1,\n} from \"./types.ts\";\n\nconst LSP_DIAGNOSTICS_STABLE_MS_V1 = 300;\nconst LSP_DIAGNOSTICS_TIMEOUT_MS_V1 = 15_000;\nconst TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1 = 15_000;\nconst MAX_SERVER_STDOUT_BYTES_V1 = 8 * 1024 * 1024;\n\nexport interface LspServerSpecV1 {\n\treadonly command: string;\n\treadonly args: readonly string[];\n}\n\nexport interface LspServerMapV1 {\n\treadonly typescript?: LspServerSpecV1;\n\treadonly python?: LspServerSpecV1;\n\treadonly c?: LspServerSpecV1;\n}\n\nconst SERVER_LANGUAGE_V1: Record<string, keyof LspServerMapV1> = {\n\ttypescript: \"typescript\",\n\tjavascript: \"typescript\",\n\tpython: \"python\",\n\tc: \"c\",\n\tcpp: \"c\",\n};\n\nfunction pathExecutableV1(name: string, pathEnv: string | undefined): string | undefined {\n\tif (typeof pathEnv !== \"string\" || pathEnv.trim() === \"\") return undefined;\n\tconst names = process.platform === \"win32\" ? [`${name}.exe`, `${name}.cmd`] : [name];\n\tfor (const directory of pathEnv.split(process.platform === \"win32\" ? \";\" : \":\")) {\n\t\tif (directory.trim() === \"\") continue;\n\t\tfor (const candidate of names) {\n\t\t\tconst resolved = join(directory, candidate);\n\t\t\tif (existsSync(resolved)) return resolved;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Host-owned language-server resolution: tsserver from the workspace-local\n * TypeScript install, pyright from the workspace-local npm package or PATH,\n * clangd from PATH. Unresolved languages stay absent so the wiring fails\n * closed; `servers` injects deterministic overrides for tests.\n */\nexport function resolveLspServersV1(options: {\n\treadonly workspaceDirectory: string;\n\treadonly pathEnv?: string;\n\treadonly servers?: LspServerMapV1;\n}): LspServerMapV1 {\n\tif (options.servers !== undefined) return options.servers;\n\tconst pathEnv = options.pathEnv ?? process.env.PATH;\n\tconst map: {\n\t\ttypescript?: LspServerSpecV1;\n\t\tpython?: LspServerSpecV1;\n\t\tc?: LspServerSpecV1;\n\t} = {};\n\tconst tsserver = join(options.workspaceDirectory, \"node_modules\", \"typescript\", \"lib\", \"tsserver.js\");\n\tif (isAbsolute(options.workspaceDirectory) && existsSync(tsserver))\n\t\tmap.typescript = { command: process.execPath, args: [tsserver] };\n\tconst pyrightLocal = join(options.workspaceDirectory, \"node_modules\", \"pyright\", \"dist\", \"pyright-langserver.js\");\n\tif (isAbsolute(options.workspaceDirectory) && existsSync(pyrightLocal))\n\t\tmap.python = { command: process.execPath, args: [pyrightLocal, \"--stdio\"] };\n\tconst pyrightPath = pathExecutableV1(\"pyright-langserver\", pathEnv);\n\tif (map.python === undefined && pyrightPath !== undefined) map.python = { command: pyrightPath, args: [\"--stdio\"] };\n\tconst clangd = pathExecutableV1(\"clangd\", pathEnv);\n\tif (clangd !== undefined) map.c = { command: clangd, args: [] };\n\treturn map;\n}\n\ninterface BoundedDiagnosticV1 {\n\treadonly file: string;\n\treadonly range: LspDiagnosticV1[\"range\"];\n\treadonly severity: LspDiagnosticV1[\"severity\"];\n\treadonly code?: string | number;\n\treadonly source?: string;\n\treadonly message: string;\n}\n\nfunction lspSeverityV1(value: unknown): LspDiagnosticV1[\"severity\"] {\n\tif (value === 1) return \"error\";\n\tif (value === 2) return \"warning\";\n\tif (value === 3) return \"info\";\n\tif (value === 4) return \"hint\";\n\treturn \"info\";\n}\n\nfunction tsserverCategoryV1(value: unknown): LspDiagnosticV1[\"severity\"] {\n\tif (value === \"error\") return \"error\";\n\tif (value === \"warning\") return \"warning\";\n\tif (value === \"suggestion\") return \"hint\";\n\treturn \"info\";\n}\n\ninterface SpawnedServerV1 {\n\treadonly stdout: AsyncIterable<Buffer>;\n\treadonly write: (chunk: string) => void;\n\treadonly kill: () => void;\n\treadonly exit: Promise<void>;\n}\n\nfunction spawnServerV1(spec: LspServerSpecV1, signal: AbortSignal): SpawnedServerV1 | undefined {\n\tconst child = spawn(spec.command, spec.args, {\n\t\tshell: false,\n\t\twindowsHide: true,\n\t\tstdio: [\"pipe\", \"pipe\", \"ignore\"],\n\t\tsignal,\n\t});\n\tif (child.stdout === null || child.stdin === null) {\n\t\tchild.kill();\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tstdout: child.stdout,\n\t\twrite: (chunk) => child.stdin!.write(chunk),\n\t\tkill: () => child.kill(),\n\t\texit: new Promise((resolveExit) => {\n\t\t\tchild.once(\"exit\", () => resolveExit());\n\t\t\tchild.once(\"error\", () => resolveExit());\n\t\t}),\n\t};\n}\n\n/** Frame reader over stdio: either Content-Length framed (LSP) or line-delimited JSON (tsserver). */\nasync function* readMessagesV1(server: SpawnedServerV1, framed: boolean): AsyncGenerator<string> {\n\tlet buffer = \"\";\n\tfor await (const chunk of server.stdout) {\n\t\tbuffer += chunk.toString(\"utf8\");\n\t\tif (buffer.length > MAX_SERVER_STDOUT_BYTES_V1) return;\n\t\tif (framed) {\n\t\t\tfor (;;) {\n\t\t\t\tconst headerEnd = buffer.indexOf(\"\\r\\n\\r\\n\");\n\t\t\t\tif (headerEnd === -1) break;\n\t\t\t\tconst header = buffer.slice(0, headerEnd);\n\t\t\t\tconst lengthMatch = header.match(/Content-Length:\\s*(\\d+)/i);\n\t\t\t\tif (lengthMatch === null) return;\n\t\t\t\tconst length = Number(lengthMatch[1]);\n\t\t\t\tconst bodyStart = headerEnd + 4;\n\t\t\t\tif (buffer.length < bodyStart + length) break;\n\t\t\t\tyield buffer.slice(bodyStart, bodyStart + length);\n\t\t\t\tbuffer = buffer.slice(bodyStart + length);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (;;) {\n\t\t\t\tconst lineEnd = buffer.indexOf(\"\\n\");\n\t\t\t\tif (lineEnd === -1) break;\n\t\t\t\tconst line = buffer.slice(0, lineEnd).trim();\n\t\t\t\tbuffer = buffer.slice(lineEnd + 1);\n\t\t\t\tif (line !== \"\") yield line;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction safePositionV1(value: unknown): number {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 ? value : 0;\n}\n\nfunction parseLspDiagnosticsV1(documentPath: string, params: unknown): BoundedDiagnosticV1[] {\n\tif (typeof params !== \"object\" || params === null) return [];\n\tconst diagnostics = (params as { diagnostics?: unknown }).diagnostics;\n\tif (!Array.isArray(diagnostics)) return [];\n\tconst projected: BoundedDiagnosticV1[] = [];\n\tfor (const raw of diagnostics) {\n\t\tif (typeof raw !== \"object\" || raw === null) continue;\n\t\tconst item = raw as {\n\t\t\trange?: { start?: { line?: unknown; character?: unknown }; end?: { line?: unknown; character?: unknown } };\n\t\t\tseverity?: unknown;\n\t\t\tcode?: unknown;\n\t\t\tsource?: unknown;\n\t\t\tmessage?: unknown;\n\t\t};\n\t\tconst message = typeof item.message === \"string\" ? sanitizeLspDiagnosticsTextV1(item.message) : \"\";\n\t\tif (message === \"\") continue;\n\t\tconst line = safePositionV1(item.range?.start?.line);\n\t\tconst column = safePositionV1(item.range?.start?.character);\n\t\tconst endLine = Math.max(line, safePositionV1(item.range?.end?.line));\n\t\tconst endColumn =\n\t\t\tendLine === line\n\t\t\t\t? Math.max(column, safePositionV1(item.range?.end?.character))\n\t\t\t\t: safePositionV1(item.range?.end?.character);\n\t\tprojected.push({\n\t\t\tfile: documentPath,\n\t\t\trange: { start: { line, column }, end: { line: endLine, column: endColumn } },\n\t\t\tseverity: lspSeverityV1(item.severity),\n\t\t\t...(typeof item.code === \"string\" || (typeof item.code === \"number\" && Number.isSafeInteger(item.code))\n\t\t\t\t? { code: item.code }\n\t\t\t\t: {}),\n\t\t\t...(typeof item.source === \"string\" ? { source: sanitizeLspDiagnosticsTextV1(item.source, 128) } : {}),\n\t\t\tmessage,\n\t\t});\n\t}\n\treturn projected;\n}\n\nfunction parseTsserverDiagnosticsV1(documentPath: string, body: unknown): BoundedDiagnosticV1[] {\n\tif (typeof body !== \"object\" || body === null) return [];\n\tconst diagnostics = (body as { diagnostics?: unknown }).diagnostics;\n\tif (!Array.isArray(diagnostics)) return [];\n\tconst projected: BoundedDiagnosticV1[] = [];\n\tfor (const raw of diagnostics) {\n\t\tif (typeof raw !== \"object\" || raw === null) continue;\n\t\tconst item = raw as {\n\t\t\tstart?: { line?: unknown; offset?: unknown };\n\t\t\tend?: { line?: unknown; offset?: unknown };\n\t\t\ttext?: unknown;\n\t\t\tcode?: unknown;\n\t\t\tcategory?: unknown;\n\t\t};\n\t\tconst message = typeof item.text === \"string\" ? sanitizeLspDiagnosticsTextV1(item.text) : \"\";\n\t\tif (message === \"\") continue;\n\t\t// tsserver positions are 1-based; normalize to the 0-based public shape.\n\t\tconst line = Math.max(0, safePositionV1(item.start?.line) - 1);\n\t\tconst column = Math.max(0, safePositionV1(item.start?.offset) - 1);\n\t\tconst endLine = Math.max(line, Math.max(0, safePositionV1(item.end?.line) - 1));\n\t\tconst endColumn =\n\t\t\tendLine === line\n\t\t\t\t? Math.max(column, Math.max(0, safePositionV1(item.end?.offset) - 1))\n\t\t\t\t: Math.max(0, safePositionV1(item.end?.offset) - 1);\n\t\tprojected.push({\n\t\t\tfile: documentPath,\n\t\t\trange: { start: { line, column }, end: { line: endLine, column: endColumn } },\n\t\t\tseverity: tsserverCategoryV1(item.category),\n\t\t\t...(typeof item.code === \"number\" && Number.isSafeInteger(item.code) ? { code: item.code } : {}),\n\t\t\tmessage,\n\t\t});\n\t}\n\treturn projected;\n}\n\n/**\n * LSP push client: initialize → didOpen → collect publishDiagnostics →\n * shutdown. The server stream is consumed by exactly one loop — breaking out\n * of a for-await over a Node stream destroys it, so phase transitions happen\n * inside the loop and the stability window resolves the shared promise\n * without interrupting the iteration.\n */\nasync function diagnoseWithLspServerV1(\n\tspec: LspServerSpecV1,\n\trelativePath: string,\n\tabsolutePath: string,\n\tlanguage: string,\n\ttext: string,\n\tsignal: AbortSignal,\n): Promise<BoundedDiagnosticV1[] | undefined> {\n\tconst server = spawnServerV1(spec, signal);\n\tif (server === undefined) return undefined;\n\tlet sequence = 0;\n\tconst nextId = () => ++sequence;\n\tconst send = (message: Record<string, unknown>): void => {\n\t\tconst payload = Buffer.from(JSON.stringify(message), \"utf8\");\n\t\tserver.write(`Content-Length: ${payload.byteLength}\\r\\n\\r\\n${payload.toString(\"utf8\")}`);\n\t};\n\tconst uri = pathToFileURL(absolutePath).href;\n\ttry {\n\t\tconst consumed = new Promise<BoundedDiagnosticV1[] | undefined>((resolveConsume) => {\n\t\t\tlet stableTimer: NodeJS.Timeout | undefined;\n\t\t\tlet latest: BoundedDiagnosticV1[] | undefined;\n\t\t\t// The stability window arms only after the first push so cold-start\n\t\t\t// servers are not cut off before their first diagnostics.\n\t\t\tconst arm = () => {\n\t\t\t\tclearTimeout(stableTimer);\n\t\t\t\tstableTimer = setTimeout(() => resolveConsume(latest), LSP_DIAGNOSTICS_STABLE_MS_V1);\n\t\t\t};\n\t\t\tvoid (async () => {\n\t\t\t\tsend({ jsonrpc: \"2.0\", id: nextId(), method: \"initialize\", params: { processId: null, capabilities: {} } });\n\t\t\t\tlet initialized = false;\n\t\t\t\tfor await (const raw of readMessagesV1(server, true)) {\n\t\t\t\t\tlet message: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tmessage = JSON.parse(raw) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (message.id !== undefined && message.method === undefined) {\n\t\t\t\t\t\tif (!initialized) {\n\t\t\t\t\t\t\tinitialized = true;\n\t\t\t\t\t\t\tsend({ jsonrpc: \"2.0\", method: \"initialized\", params: {} });\n\t\t\t\t\t\t\tsend({\n\t\t\t\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\t\t\t\tmethod: \"textDocument/didOpen\",\n\t\t\t\t\t\t\t\tparams: { textDocument: { uri, languageId: language, version: 1, text } },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (message.method === \"textDocument/publishDiagnostics\") {\n\t\t\t\t\t\tconst pushed = parseLspDiagnosticsV1(relativePath, message.params);\n\t\t\t\t\t\tif (pushed.length > 0) {\n\t\t\t\t\t\t\tlatest = pushed;\n\t\t\t\t\t\t\tarm();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresolveConsume(latest);\n\t\t\t})().catch(() => resolveConsume(latest));\n\t\t});\n\t\tconst timeout = new Promise<undefined>((resolveTimeout) => {\n\t\t\tsetTimeout(() => resolveTimeout(undefined), LSP_DIAGNOSTICS_TIMEOUT_MS_V1);\n\t\t});\n\t\tconst result = await Promise.race([consumed, timeout]);\n\t\tsend({ jsonrpc: \"2.0\", id: nextId(), method: \"shutdown\", params: null });\n\t\tsend({ jsonrpc: \"2.0\", method: \"exit\" });\n\t\treturn result;\n\t} finally {\n\t\tserver.kill();\n\t\tawait server.exit;\n\t}\n}\n\n/** tsserver client: configure → open → geterr → syntaxDiag/semanticDiag events. */\nasync function diagnoseWithTsserverV1(\n\tspec: LspServerSpecV1,\n\trelativePath: string,\n\tabsolutePath: string,\n\ttext: string,\n\tsignal: AbortSignal,\n): Promise<BoundedDiagnosticV1[] | undefined> {\n\tconst server = spawnServerV1(spec, signal);\n\tif (server === undefined) return undefined;\n\tlet sequence = 0;\n\tconst send = (command: string, argumentsValue: Record<string, unknown>): void => {\n\t\tserver.write(`${JSON.stringify({ seq: ++sequence, type: \"request\", command, arguments: argumentsValue })}\\n`);\n\t};\n\tconst collected: BoundedDiagnosticV1[] = [];\n\tconst received = { syntax: false, semantic: false };\n\ttry {\n\t\tsend(\"configure\", { hostInfo: \"agent-forge\" });\n\t\tsend(\"open\", { file: absolutePath, fileContent: text });\n\t\tsend(\"geterr\", { file: absolutePath, delay: 0 });\n\t\tconst timeout = new Promise<undefined>((resolveTimeout) => {\n\t\t\tsetTimeout(() => resolveTimeout(undefined), TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1);\n\t\t});\n\t\tconst collectedPromise = (async () => {\n\t\t\tfor await (const raw of readMessagesV1(server, false)) {\n\t\t\t\tlet message: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tmessage = JSON.parse(raw) as Record<string, unknown>;\n\t\t\t\t} catch {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (message.type !== \"event\") continue;\n\t\t\t\tif (message.event === \"syntaxDiag\" || message.event === \"syntacticDiag\") {\n\t\t\t\t\tcollected.push(...parseTsserverDiagnosticsV1(relativePath, message.body));\n\t\t\t\t\treceived.syntax = true;\n\t\t\t\t}\n\t\t\t\tif (message.event === \"semanticDiag\") {\n\t\t\t\t\tcollected.push(...parseTsserverDiagnosticsV1(relativePath, message.body));\n\t\t\t\t\treceived.semantic = true;\n\t\t\t\t}\n\t\t\t\tif (received.syntax && received.semantic) break;\n\t\t\t}\n\t\t\treturn collected;\n\t\t})().catch(() => collected);\n\t\tconst result = await Promise.race([collectedPromise, timeout]);\n\t\tsend(\"exit\", {});\n\t\treturn result;\n\t} finally {\n\t\tserver.kill();\n\t\tawait server.exit;\n\t}\n}\n\nfunction resolveDocumentPathV1(workspaceDirectory: string, request: LspDiagnosticsRequestV1): string | undefined {\n\tconst documentPath = request.documentPath;\n\tif (typeof documentPath !== \"string\" || documentPath.trim() === \"\" || !isAbsolute(workspaceDirectory))\n\t\treturn undefined;\n\tconst absolute = resolve(workspaceDirectory, documentPath);\n\tconst root = resolve(workspaceDirectory);\n\tif (!absolute.startsWith(root + (root.endsWith(\"\\\\\") || root.endsWith(\"/\") ? \"\" : \"\\\\\")) && absolute !== root)\n\t\treturn undefined;\n\ttry {\n\t\tif (!existsSync(absolute) || !statSync(absolute).isFile()) return undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn absolute;\n}\n\n/**\n * Real language-server host over one workspace directory: resolves servers per\n * language (tsserver/pyright/clangd), opens the requested workspace-relative\n * document, collects push diagnostics over LSP or the tsserver protocol, and\n * never returns server argv, cwd, environment, or absolute paths. Servers are\n * injected per resolution; a workspace without a resolvable server reports\n * `unsupported`.\n */\nexport function createNodeLspRealHostV1(options: {\n\treadonly workspaceDirectory: string;\n\treadonly pathEnv?: string;\n\treadonly servers?: LspServerMapV1;\n}): { readonly resolver: LspSessionResolverV1; readonly client: LspClientV1 } {\n\tconst workspaceDirectory = resolve(options.workspaceDirectory);\n\tconst servers = resolveLspServersV1({\n\t\tworkspaceDirectory,\n\t\t...(options.pathEnv === undefined ? {} : { pathEnv: options.pathEnv }),\n\t\t...(options.servers === undefined ? {} : { servers: options.servers }),\n\t});\n\treturn {\n\t\tresolver: {\n\t\t\tasync resolve(request: LspDiagnosticsRequestV1): Promise<LspSessionV1 | undefined> {\n\t\t\t\tconst language = SERVER_LANGUAGE_V1[request.language];\n\t\t\t\tif (language === undefined) return undefined;\n\t\t\t\tif (servers[language] === undefined) return undefined;\n\t\t\t\treturn { sessionRef: `lsp-${language}` };\n\t\t\t},\n\t\t},\n\t\tclient: {\n\t\t\tasync diagnose({ request }, signal): Promise<LspHostDiagnosticResultV1> {\n\t\t\t\tconst language = SERVER_LANGUAGE_V1[request.language];\n\t\t\t\tconst spec = language === undefined ? undefined : servers[language];\n\t\t\t\tif (spec === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst documentPath = resolveDocumentPathV1(workspaceDirectory, request);\n\t\t\t\tif (documentPath === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst abortSignal = signal ?? new AbortController().signal;\n\t\t\t\tconst text = await readFile(documentPath, \"utf8\").catch(() => undefined);\n\t\t\t\tif (text === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst relativePath = request.documentPath ?? request.documentRef;\n\t\t\t\tconst diagnostics =\n\t\t\t\t\tlanguage === \"typescript\"\n\t\t\t\t\t\t? await diagnoseWithTsserverV1(spec, relativePath, documentPath, text, abortSignal)\n\t\t\t\t\t\t: await diagnoseWithLspServerV1(\n\t\t\t\t\t\t\t\tspec,\n\t\t\t\t\t\t\t\trelativePath,\n\t\t\t\t\t\t\t\tdocumentPath,\n\t\t\t\t\t\t\t\trequest.language,\n\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\tabortSignal,\n\t\t\t\t\t\t\t);\n\t\t\t\tif (diagnostics === undefined) return { status: \"unsupported\" };\n\t\t\t\treturn { status: \"completed\", diagnostics };\n\t\t\t},\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"node-lsp-real-host.d.ts","sourceRoot":"","sources":["../src/node-lsp-real-host.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACX,WAAW,EAIX,oBAAoB,EAEpB,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;CAC7B;AAuBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC5C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CAClC,GAAG,cAAc,CAmBjB;AAqUD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAChD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CAClC,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CA2C5E","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { sanitizeLspDiagnosticsTextV1 } from \"./node-adapter.ts\";\nimport type {\n\tLspClientV1,\n\tLspDiagnosticsRequestV1,\n\tLspDiagnosticV1,\n\tLspHostDiagnosticResultV1,\n\tLspSessionResolverV1,\n\tLspSessionV1,\n} from \"./types.ts\";\n\nconst LSP_DIAGNOSTICS_STABLE_MS_V1 = 300;\nconst LSP_DIAGNOSTICS_TIMEOUT_MS_V1 = 15_000;\nconst TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1 = 15_000;\nconst MAX_SERVER_STDOUT_BYTES_V1 = 8 * 1024 * 1024;\n\nexport interface LspServerSpecV1 {\n\treadonly command: string;\n\treadonly args: readonly string[];\n}\n\nexport interface LspServerMapV1 {\n\treadonly typescript?: LspServerSpecV1;\n\treadonly python?: LspServerSpecV1;\n\treadonly c?: LspServerSpecV1;\n}\n\nconst SERVER_LANGUAGE_V1: Record<string, keyof LspServerMapV1> = {\n\ttypescript: \"typescript\",\n\tjavascript: \"typescript\",\n\tpython: \"python\",\n\tc: \"c\",\n\tcpp: \"c\",\n};\n\nfunction pathExecutableV1(name: string, pathEnv: string | undefined): string | undefined {\n\tif (typeof pathEnv !== \"string\" || pathEnv.trim() === \"\") return undefined;\n\tconst names = process.platform === \"win32\" ? [`${name}.exe`, `${name}.cmd`] : [name];\n\tfor (const directory of pathEnv.split(process.platform === \"win32\" ? \";\" : \":\")) {\n\t\tif (directory.trim() === \"\") continue;\n\t\tfor (const candidate of names) {\n\t\t\tconst resolved = join(directory, candidate);\n\t\t\tif (existsSync(resolved)) return resolved;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Host-owned language-server resolution: tsserver from the workspace-local\n * TypeScript install, pyright from the workspace-local npm package or PATH,\n * clangd from PATH. Unresolved languages stay absent so the wiring fails\n * closed; `servers` injects deterministic overrides for tests.\n */\nexport function resolveLspServersV1(options: {\n\treadonly workspaceDirectory: string;\n\treadonly pathEnv?: string;\n\treadonly servers?: LspServerMapV1;\n}): LspServerMapV1 {\n\tif (options.servers !== undefined) return options.servers;\n\tconst pathEnv = options.pathEnv ?? process.env.PATH;\n\tconst map: {\n\t\ttypescript?: LspServerSpecV1;\n\t\tpython?: LspServerSpecV1;\n\t\tc?: LspServerSpecV1;\n\t} = {};\n\tconst tsserver = join(options.workspaceDirectory, \"node_modules\", \"typescript\", \"lib\", \"tsserver.js\");\n\tif (isAbsolute(options.workspaceDirectory) && existsSync(tsserver))\n\t\tmap.typescript = { command: process.execPath, args: [tsserver] };\n\tconst pyrightLocal = join(options.workspaceDirectory, \"node_modules\", \"pyright\", \"dist\", \"pyright-langserver.js\");\n\tif (isAbsolute(options.workspaceDirectory) && existsSync(pyrightLocal))\n\t\tmap.python = { command: process.execPath, args: [pyrightLocal, \"--stdio\"] };\n\tconst pyrightPath = pathExecutableV1(\"pyright-langserver\", pathEnv);\n\tif (map.python === undefined && pyrightPath !== undefined) map.python = { command: pyrightPath, args: [\"--stdio\"] };\n\tconst clangd = pathExecutableV1(\"clangd\", pathEnv);\n\tif (clangd !== undefined) map.c = { command: clangd, args: [] };\n\treturn map;\n}\n\ninterface BoundedDiagnosticV1 {\n\treadonly file: string;\n\treadonly range: LspDiagnosticV1[\"range\"];\n\treadonly severity: LspDiagnosticV1[\"severity\"];\n\treadonly code?: string | number;\n\treadonly source?: string;\n\treadonly message: string;\n}\n\nfunction lspSeverityV1(value: unknown): LspDiagnosticV1[\"severity\"] {\n\tif (value === 1) return \"error\";\n\tif (value === 2) return \"warning\";\n\tif (value === 3) return \"info\";\n\tif (value === 4) return \"hint\";\n\treturn \"info\";\n}\n\nfunction tsserverCategoryV1(value: unknown): LspDiagnosticV1[\"severity\"] {\n\tif (value === \"error\") return \"error\";\n\tif (value === \"warning\") return \"warning\";\n\tif (value === \"suggestion\") return \"hint\";\n\treturn \"info\";\n}\n\ninterface SpawnedServerV1 {\n\treadonly stdout: AsyncIterable<Buffer>;\n\treadonly write: (chunk: string) => void;\n\treadonly kill: () => void;\n\treadonly exit: Promise<void>;\n}\n\nfunction spawnServerV1(spec: LspServerSpecV1, signal: AbortSignal): SpawnedServerV1 | undefined {\n\tconst child = spawn(spec.command, spec.args, {\n\t\tshell: false,\n\t\twindowsHide: true,\n\t\tstdio: [\"pipe\", \"pipe\", \"ignore\"],\n\t\tsignal,\n\t});\n\tif (child.stdout === null || child.stdin === null) {\n\t\tchild.kill();\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tstdout: child.stdout,\n\t\twrite: (chunk) => child.stdin!.write(chunk),\n\t\tkill: () => child.kill(),\n\t\texit: new Promise((resolveExit) => {\n\t\t\tchild.once(\"exit\", () => resolveExit());\n\t\t\tchild.once(\"error\", () => resolveExit());\n\t\t}),\n\t};\n}\n\n/** Frame reader over stdio: either Content-Length framed (LSP) or line-delimited JSON (tsserver). */\nasync function* readMessagesV1(server: SpawnedServerV1, framed: boolean): AsyncGenerator<string> {\n\tlet buffer = \"\";\n\tfor await (const chunk of server.stdout) {\n\t\tbuffer += chunk.toString(\"utf8\");\n\t\tif (buffer.length > MAX_SERVER_STDOUT_BYTES_V1) return;\n\t\tif (framed) {\n\t\t\tfor (;;) {\n\t\t\t\tconst headerEnd = buffer.indexOf(\"\\r\\n\\r\\n\");\n\t\t\t\tif (headerEnd === -1) break;\n\t\t\t\tconst header = buffer.slice(0, headerEnd);\n\t\t\t\tconst lengthMatch = header.match(/Content-Length:\\s*(\\d+)/i);\n\t\t\t\tif (lengthMatch === null) return;\n\t\t\t\tconst length = Number(lengthMatch[1]);\n\t\t\t\tconst bodyStart = headerEnd + 4;\n\t\t\t\tif (buffer.length < bodyStart + length) break;\n\t\t\t\tyield buffer.slice(bodyStart, bodyStart + length);\n\t\t\t\tbuffer = buffer.slice(bodyStart + length);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (;;) {\n\t\t\t\tconst lineEnd = buffer.indexOf(\"\\n\");\n\t\t\t\tif (lineEnd === -1) break;\n\t\t\t\tconst line = buffer.slice(0, lineEnd).trim();\n\t\t\t\tbuffer = buffer.slice(lineEnd + 1);\n\t\t\t\tif (line !== \"\") yield line;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction safePositionV1(value: unknown): number {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 ? value : 0;\n}\n\nfunction parseLspDiagnosticsV1(documentPath: string, params: unknown): BoundedDiagnosticV1[] {\n\tif (typeof params !== \"object\" || params === null) return [];\n\tconst diagnostics = (params as { diagnostics?: unknown }).diagnostics;\n\tif (!Array.isArray(diagnostics)) return [];\n\tconst projected: BoundedDiagnosticV1[] = [];\n\tfor (const raw of diagnostics) {\n\t\tif (typeof raw !== \"object\" || raw === null) continue;\n\t\tconst item = raw as {\n\t\t\trange?: { start?: { line?: unknown; character?: unknown }; end?: { line?: unknown; character?: unknown } };\n\t\t\tseverity?: unknown;\n\t\t\tcode?: unknown;\n\t\t\tsource?: unknown;\n\t\t\tmessage?: unknown;\n\t\t};\n\t\tconst message = typeof item.message === \"string\" ? sanitizeLspDiagnosticsTextV1(item.message) : \"\";\n\t\tif (message === \"\") continue;\n\t\tconst line = safePositionV1(item.range?.start?.line);\n\t\tconst column = safePositionV1(item.range?.start?.character);\n\t\tconst endLine = Math.max(line, safePositionV1(item.range?.end?.line));\n\t\tconst endColumn =\n\t\t\tendLine === line\n\t\t\t\t? Math.max(column, safePositionV1(item.range?.end?.character))\n\t\t\t\t: safePositionV1(item.range?.end?.character);\n\t\tprojected.push({\n\t\t\tfile: documentPath,\n\t\t\trange: { start: { line, column }, end: { line: endLine, column: endColumn } },\n\t\t\tseverity: lspSeverityV1(item.severity),\n\t\t\t...(typeof item.code === \"string\" || (typeof item.code === \"number\" && Number.isSafeInteger(item.code))\n\t\t\t\t? { code: item.code }\n\t\t\t\t: {}),\n\t\t\t...(typeof item.source === \"string\" ? { source: sanitizeLspDiagnosticsTextV1(item.source, 128) } : {}),\n\t\t\tmessage,\n\t\t});\n\t}\n\treturn projected;\n}\n\nfunction parseTsserverDiagnosticsV1(documentPath: string, body: unknown): BoundedDiagnosticV1[] {\n\tif (typeof body !== \"object\" || body === null) return [];\n\tconst diagnostics = (body as { diagnostics?: unknown }).diagnostics;\n\tif (!Array.isArray(diagnostics)) return [];\n\tconst projected: BoundedDiagnosticV1[] = [];\n\tfor (const raw of diagnostics) {\n\t\tif (typeof raw !== \"object\" || raw === null) continue;\n\t\tconst item = raw as {\n\t\t\tstart?: { line?: unknown; offset?: unknown };\n\t\t\tend?: { line?: unknown; offset?: unknown };\n\t\t\ttext?: unknown;\n\t\t\tcode?: unknown;\n\t\t\tcategory?: unknown;\n\t\t};\n\t\tconst message = typeof item.text === \"string\" ? sanitizeLspDiagnosticsTextV1(item.text) : \"\";\n\t\tif (message === \"\") continue;\n\t\t// tsserver positions are 1-based; normalize to the 0-based public shape.\n\t\tconst line = Math.max(0, safePositionV1(item.start?.line) - 1);\n\t\tconst column = Math.max(0, safePositionV1(item.start?.offset) - 1);\n\t\tconst endLine = Math.max(line, Math.max(0, safePositionV1(item.end?.line) - 1));\n\t\tconst endColumn =\n\t\t\tendLine === line\n\t\t\t\t? Math.max(column, Math.max(0, safePositionV1(item.end?.offset) - 1))\n\t\t\t\t: Math.max(0, safePositionV1(item.end?.offset) - 1);\n\t\tprojected.push({\n\t\t\tfile: documentPath,\n\t\t\trange: { start: { line, column }, end: { line: endLine, column: endColumn } },\n\t\t\tseverity: tsserverCategoryV1(item.category),\n\t\t\t...(typeof item.code === \"number\" && Number.isSafeInteger(item.code) ? { code: item.code } : {}),\n\t\t\tmessage,\n\t\t});\n\t}\n\treturn projected;\n}\n\n/**\n * LSP push client: initialize → didOpen → collect publishDiagnostics →\n * shutdown. The server stream is consumed by exactly one loop — breaking out\n * of a for-await over a Node stream destroys it, so phase transitions happen\n * inside the loop and the stability window resolves the shared promise\n * without interrupting the iteration.\n */\nasync function diagnoseWithLspServerV1(\n\tspec: LspServerSpecV1,\n\trelativePath: string,\n\tabsolutePath: string,\n\tlanguage: string,\n\ttext: string,\n\tsignal: AbortSignal,\n): Promise<BoundedDiagnosticV1[] | undefined> {\n\tconst server = spawnServerV1(spec, signal);\n\tif (server === undefined) return undefined;\n\tlet sequence = 0;\n\tconst nextId = () => ++sequence;\n\tconst send = (message: Record<string, unknown>): void => {\n\t\tconst payload = Buffer.from(JSON.stringify(message), \"utf8\");\n\t\tserver.write(`Content-Length: ${payload.byteLength}\\r\\n\\r\\n${payload.toString(\"utf8\")}`);\n\t};\n\tconst uri = pathToFileURL(absolutePath).href;\n\ttry {\n\t\tconst consumed = new Promise<BoundedDiagnosticV1[] | undefined>((resolveConsume) => {\n\t\t\tlet stableTimer: NodeJS.Timeout | undefined;\n\t\t\tlet latest: BoundedDiagnosticV1[] | undefined;\n\t\t\t// The stability window arms only after the first push so cold-start\n\t\t\t// servers are not cut off before their first diagnostics.\n\t\t\tconst arm = () => {\n\t\t\t\tclearTimeout(stableTimer);\n\t\t\t\tstableTimer = setTimeout(() => resolveConsume(latest), LSP_DIAGNOSTICS_STABLE_MS_V1);\n\t\t\t};\n\t\t\tvoid (async () => {\n\t\t\t\tsend({ jsonrpc: \"2.0\", id: nextId(), method: \"initialize\", params: { processId: null, capabilities: {} } });\n\t\t\t\tlet initialized = false;\n\t\t\t\tfor await (const raw of readMessagesV1(server, true)) {\n\t\t\t\t\tlet message: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tmessage = JSON.parse(raw) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (message.id !== undefined && message.method === undefined) {\n\t\t\t\t\t\tif (!initialized) {\n\t\t\t\t\t\t\tinitialized = true;\n\t\t\t\t\t\t\tsend({ jsonrpc: \"2.0\", method: \"initialized\", params: {} });\n\t\t\t\t\t\t\tsend({\n\t\t\t\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\t\t\t\tmethod: \"textDocument/didOpen\",\n\t\t\t\t\t\t\t\tparams: { textDocument: { uri, languageId: language, version: 1, text } },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (message.method === \"textDocument/publishDiagnostics\") {\n\t\t\t\t\t\tconst pushed = parseLspDiagnosticsV1(relativePath, message.params);\n\t\t\t\t\t\tif (pushed.length > 0) {\n\t\t\t\t\t\t\tlatest = pushed;\n\t\t\t\t\t\t\tarm();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresolveConsume(latest);\n\t\t\t})().catch(() => resolveConsume(latest));\n\t\t});\n\t\tconst timeout = new Promise<undefined>((resolveTimeout) => {\n\t\t\tsetTimeout(() => resolveTimeout(undefined), LSP_DIAGNOSTICS_TIMEOUT_MS_V1);\n\t\t});\n\t\tconst result = await Promise.race([consumed, timeout]);\n\t\tsend({ jsonrpc: \"2.0\", id: nextId(), method: \"shutdown\", params: null });\n\t\tsend({ jsonrpc: \"2.0\", method: \"exit\" });\n\t\treturn result;\n\t} finally {\n\t\tserver.kill();\n\t\tawait server.exit;\n\t}\n}\n\n/** tsserver client: configure → open → geterr → syntaxDiag/semanticDiag events. */\nasync function diagnoseWithTsserverV1(\n\tspec: LspServerSpecV1,\n\trelativePath: string,\n\tabsolutePath: string,\n\ttext: string,\n\tsignal: AbortSignal,\n): Promise<BoundedDiagnosticV1[] | undefined> {\n\tconst server = spawnServerV1(spec, signal);\n\tif (server === undefined) return undefined;\n\tlet sequence = 0;\n\tconst send = (command: string, argumentsValue: Record<string, unknown>): number => {\n\t\tconst seq = ++sequence;\n\t\tserver.write(`${JSON.stringify({ seq, type: \"request\", command, arguments: argumentsValue })}\\n`);\n\t\treturn seq;\n\t};\n\tconst collected: BoundedDiagnosticV1[] = [];\n\tconst received = { syntax: false, semantic: false };\n\ttry {\n\t\tsend(\"configure\", { hostInfo: \"agent-forge\" });\n\t\tsend(\"open\", { file: absolutePath, fileContent: text });\n\t\t// Real tsserver's geterr takes `files: string[]`; a scalar `file`\n\t\t// field is never read, the request fails internally, and no diagnostic\n\t\t// events are emitted. The requestCompleted event for the geterr\n\t\t// sequence is the server's own completion signal, so a missing diag\n\t\t// event (e.g. a file no project claims) cannot stall until the\n\t\t// timeout.\n\t\tconst geterrSeq = send(\"geterr\", { delay: 0, files: [absolutePath] });\n\t\tconst timeout = new Promise<undefined>((resolveTimeout) => {\n\t\t\tsetTimeout(() => resolveTimeout(undefined), TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1);\n\t\t});\n\t\tconst collectedPromise = (async () => {\n\t\t\tfor await (const raw of readMessagesV1(server, false)) {\n\t\t\t\tlet message: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tmessage = JSON.parse(raw) as Record<string, unknown>;\n\t\t\t\t} catch {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (message.type !== \"event\") continue;\n\t\t\t\tif (message.event === \"syntaxDiag\" || message.event === \"syntacticDiag\") {\n\t\t\t\t\tcollected.push(...parseTsserverDiagnosticsV1(relativePath, message.body));\n\t\t\t\t\treceived.syntax = true;\n\t\t\t\t}\n\t\t\t\tif (message.event === \"semanticDiag\") {\n\t\t\t\t\tcollected.push(...parseTsserverDiagnosticsV1(relativePath, message.body));\n\t\t\t\t\treceived.semantic = true;\n\t\t\t\t}\n\t\t\t\tif (received.syntax && received.semantic) break;\n\t\t\t\tif (\n\t\t\t\t\tmessage.event === \"requestCompleted\" &&\n\t\t\t\t\t(message.body as { request_seq?: unknown } | undefined)?.request_seq === geterrSeq\n\t\t\t\t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn collected;\n\t\t})().catch(() => collected);\n\t\tconst result = await Promise.race([collectedPromise, timeout]);\n\t\tsend(\"exit\", {});\n\t\treturn result;\n\t} finally {\n\t\tserver.kill();\n\t\tawait server.exit;\n\t}\n}\n\nfunction resolveDocumentPathV1(workspaceDirectory: string, request: LspDiagnosticsRequestV1): string | undefined {\n\tconst documentPath = request.documentPath;\n\tif (typeof documentPath !== \"string\" || documentPath.trim() === \"\" || !isAbsolute(workspaceDirectory))\n\t\treturn undefined;\n\tconst absolute = resolve(workspaceDirectory, documentPath);\n\tconst root = resolve(workspaceDirectory);\n\tif (!absolute.startsWith(root + (root.endsWith(\"\\\\\") || root.endsWith(\"/\") ? \"\" : \"\\\\\")) && absolute !== root)\n\t\treturn undefined;\n\ttry {\n\t\tif (!existsSync(absolute) || !statSync(absolute).isFile()) return undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn absolute;\n}\n\n/**\n * Real language-server host over one workspace directory: resolves servers per\n * language (tsserver/pyright/clangd), opens the requested workspace-relative\n * document, collects push diagnostics over LSP or the tsserver protocol, and\n * never returns server argv, cwd, environment, or absolute paths. Servers are\n * injected per resolution; a workspace without a resolvable server reports\n * `unsupported`.\n */\nexport function createNodeLspRealHostV1(options: {\n\treadonly workspaceDirectory: string;\n\treadonly pathEnv?: string;\n\treadonly servers?: LspServerMapV1;\n}): { readonly resolver: LspSessionResolverV1; readonly client: LspClientV1 } {\n\tconst workspaceDirectory = resolve(options.workspaceDirectory);\n\tconst servers = resolveLspServersV1({\n\t\tworkspaceDirectory,\n\t\t...(options.pathEnv === undefined ? {} : { pathEnv: options.pathEnv }),\n\t\t...(options.servers === undefined ? {} : { servers: options.servers }),\n\t});\n\treturn {\n\t\tresolver: {\n\t\t\tasync resolve(request: LspDiagnosticsRequestV1): Promise<LspSessionV1 | undefined> {\n\t\t\t\tconst language = SERVER_LANGUAGE_V1[request.language];\n\t\t\t\tif (language === undefined) return undefined;\n\t\t\t\tif (servers[language] === undefined) return undefined;\n\t\t\t\treturn { sessionRef: `lsp-${language}` };\n\t\t\t},\n\t\t},\n\t\tclient: {\n\t\t\tasync diagnose({ request }, signal): Promise<LspHostDiagnosticResultV1> {\n\t\t\t\tconst language = SERVER_LANGUAGE_V1[request.language];\n\t\t\t\tconst spec = language === undefined ? undefined : servers[language];\n\t\t\t\tif (spec === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst documentPath = resolveDocumentPathV1(workspaceDirectory, request);\n\t\t\t\tif (documentPath === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst abortSignal = signal ?? new AbortController().signal;\n\t\t\t\tconst text = await readFile(documentPath, \"utf8\").catch(() => undefined);\n\t\t\t\tif (text === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst relativePath = request.documentPath ?? request.documentRef;\n\t\t\t\tconst diagnostics =\n\t\t\t\t\tlanguage === \"typescript\"\n\t\t\t\t\t\t? await diagnoseWithTsserverV1(spec, relativePath, documentPath, text, abortSignal)\n\t\t\t\t\t\t: await diagnoseWithLspServerV1(\n\t\t\t\t\t\t\t\tspec,\n\t\t\t\t\t\t\t\trelativePath,\n\t\t\t\t\t\t\t\tdocumentPath,\n\t\t\t\t\t\t\t\trequest.language,\n\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\tabortSignal,\n\t\t\t\t\t\t\t);\n\t\t\t\tif (diagnostics === undefined) return { status: \"unsupported\" };\n\t\t\t\treturn { status: \"completed\", diagnostics };\n\t\t\t},\n\t\t},\n\t};\n}\n"]}
|
|
@@ -282,14 +282,22 @@ async function diagnoseWithTsserverV1(spec, relativePath, absolutePath, text, si
|
|
|
282
282
|
return undefined;
|
|
283
283
|
let sequence = 0;
|
|
284
284
|
const send = (command, argumentsValue) => {
|
|
285
|
-
|
|
285
|
+
const seq = ++sequence;
|
|
286
|
+
server.write(`${JSON.stringify({ seq, type: "request", command, arguments: argumentsValue })}\n`);
|
|
287
|
+
return seq;
|
|
286
288
|
};
|
|
287
289
|
const collected = [];
|
|
288
290
|
const received = { syntax: false, semantic: false };
|
|
289
291
|
try {
|
|
290
292
|
send("configure", { hostInfo: "agent-forge" });
|
|
291
293
|
send("open", { file: absolutePath, fileContent: text });
|
|
292
|
-
|
|
294
|
+
// Real tsserver's geterr takes `files: string[]`; a scalar `file`
|
|
295
|
+
// field is never read, the request fails internally, and no diagnostic
|
|
296
|
+
// events are emitted. The requestCompleted event for the geterr
|
|
297
|
+
// sequence is the server's own completion signal, so a missing diag
|
|
298
|
+
// event (e.g. a file no project claims) cannot stall until the
|
|
299
|
+
// timeout.
|
|
300
|
+
const geterrSeq = send("geterr", { delay: 0, files: [absolutePath] });
|
|
293
301
|
const timeout = new Promise((resolveTimeout) => {
|
|
294
302
|
setTimeout(() => resolveTimeout(undefined), TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1);
|
|
295
303
|
});
|
|
@@ -314,6 +322,10 @@ async function diagnoseWithTsserverV1(spec, relativePath, absolutePath, text, si
|
|
|
314
322
|
}
|
|
315
323
|
if (received.syntax && received.semantic)
|
|
316
324
|
break;
|
|
325
|
+
if (message.event === "requestCompleted" &&
|
|
326
|
+
message.body?.request_seq === geterrSeq) {
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
317
329
|
}
|
|
318
330
|
return collected;
|
|
319
331
|
})().catch(() => collected);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-lsp-real-host.js","sourceRoot":"","sources":["../src/node-lsp-real-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { sanitizeLspDiagnosticsTextV1 } from \"./node-adapter.ts\";\nimport type {\n\tLspClientV1,\n\tLspDiagnosticsRequestV1,\n\tLspDiagnosticV1,\n\tLspHostDiagnosticResultV1,\n\tLspSessionResolverV1,\n\tLspSessionV1,\n} from \"./types.ts\";\n\nconst LSP_DIAGNOSTICS_STABLE_MS_V1 = 300;\nconst LSP_DIAGNOSTICS_TIMEOUT_MS_V1 = 15_000;\nconst TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1 = 15_000;\nconst MAX_SERVER_STDOUT_BYTES_V1 = 8 * 1024 * 1024;\n\nexport interface LspServerSpecV1 {\n\treadonly command: string;\n\treadonly args: readonly string[];\n}\n\nexport interface LspServerMapV1 {\n\treadonly typescript?: LspServerSpecV1;\n\treadonly python?: LspServerSpecV1;\n\treadonly c?: LspServerSpecV1;\n}\n\nconst SERVER_LANGUAGE_V1: Record<string, keyof LspServerMapV1> = {\n\ttypescript: \"typescript\",\n\tjavascript: \"typescript\",\n\tpython: \"python\",\n\tc: \"c\",\n\tcpp: \"c\",\n};\n\nfunction pathExecutableV1(name: string, pathEnv: string | undefined): string | undefined {\n\tif (typeof pathEnv !== \"string\" || pathEnv.trim() === \"\") return undefined;\n\tconst names = process.platform === \"win32\" ? [`${name}.exe`, `${name}.cmd`] : [name];\n\tfor (const directory of pathEnv.split(process.platform === \"win32\" ? \";\" : \":\")) {\n\t\tif (directory.trim() === \"\") continue;\n\t\tfor (const candidate of names) {\n\t\t\tconst resolved = join(directory, candidate);\n\t\t\tif (existsSync(resolved)) return resolved;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Host-owned language-server resolution: tsserver from the workspace-local\n * TypeScript install, pyright from the workspace-local npm package or PATH,\n * clangd from PATH. Unresolved languages stay absent so the wiring fails\n * closed; `servers` injects deterministic overrides for tests.\n */\nexport function resolveLspServersV1(options: {\n\treadonly workspaceDirectory: string;\n\treadonly pathEnv?: string;\n\treadonly servers?: LspServerMapV1;\n}): LspServerMapV1 {\n\tif (options.servers !== undefined) return options.servers;\n\tconst pathEnv = options.pathEnv ?? process.env.PATH;\n\tconst map: {\n\t\ttypescript?: LspServerSpecV1;\n\t\tpython?: LspServerSpecV1;\n\t\tc?: LspServerSpecV1;\n\t} = {};\n\tconst tsserver = join(options.workspaceDirectory, \"node_modules\", \"typescript\", \"lib\", \"tsserver.js\");\n\tif (isAbsolute(options.workspaceDirectory) && existsSync(tsserver))\n\t\tmap.typescript = { command: process.execPath, args: [tsserver] };\n\tconst pyrightLocal = join(options.workspaceDirectory, \"node_modules\", \"pyright\", \"dist\", \"pyright-langserver.js\");\n\tif (isAbsolute(options.workspaceDirectory) && existsSync(pyrightLocal))\n\t\tmap.python = { command: process.execPath, args: [pyrightLocal, \"--stdio\"] };\n\tconst pyrightPath = pathExecutableV1(\"pyright-langserver\", pathEnv);\n\tif (map.python === undefined && pyrightPath !== undefined) map.python = { command: pyrightPath, args: [\"--stdio\"] };\n\tconst clangd = pathExecutableV1(\"clangd\", pathEnv);\n\tif (clangd !== undefined) map.c = { command: clangd, args: [] };\n\treturn map;\n}\n\ninterface BoundedDiagnosticV1 {\n\treadonly file: string;\n\treadonly range: LspDiagnosticV1[\"range\"];\n\treadonly severity: LspDiagnosticV1[\"severity\"];\n\treadonly code?: string | number;\n\treadonly source?: string;\n\treadonly message: string;\n}\n\nfunction lspSeverityV1(value: unknown): LspDiagnosticV1[\"severity\"] {\n\tif (value === 1) return \"error\";\n\tif (value === 2) return \"warning\";\n\tif (value === 3) return \"info\";\n\tif (value === 4) return \"hint\";\n\treturn \"info\";\n}\n\nfunction tsserverCategoryV1(value: unknown): LspDiagnosticV1[\"severity\"] {\n\tif (value === \"error\") return \"error\";\n\tif (value === \"warning\") return \"warning\";\n\tif (value === \"suggestion\") return \"hint\";\n\treturn \"info\";\n}\n\ninterface SpawnedServerV1 {\n\treadonly stdout: AsyncIterable<Buffer>;\n\treadonly write: (chunk: string) => void;\n\treadonly kill: () => void;\n\treadonly exit: Promise<void>;\n}\n\nfunction spawnServerV1(spec: LspServerSpecV1, signal: AbortSignal): SpawnedServerV1 | undefined {\n\tconst child = spawn(spec.command, spec.args, {\n\t\tshell: false,\n\t\twindowsHide: true,\n\t\tstdio: [\"pipe\", \"pipe\", \"ignore\"],\n\t\tsignal,\n\t});\n\tif (child.stdout === null || child.stdin === null) {\n\t\tchild.kill();\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tstdout: child.stdout,\n\t\twrite: (chunk) => child.stdin!.write(chunk),\n\t\tkill: () => child.kill(),\n\t\texit: new Promise((resolveExit) => {\n\t\t\tchild.once(\"exit\", () => resolveExit());\n\t\t\tchild.once(\"error\", () => resolveExit());\n\t\t}),\n\t};\n}\n\n/** Frame reader over stdio: either Content-Length framed (LSP) or line-delimited JSON (tsserver). */\nasync function* readMessagesV1(server: SpawnedServerV1, framed: boolean): AsyncGenerator<string> {\n\tlet buffer = \"\";\n\tfor await (const chunk of server.stdout) {\n\t\tbuffer += chunk.toString(\"utf8\");\n\t\tif (buffer.length > MAX_SERVER_STDOUT_BYTES_V1) return;\n\t\tif (framed) {\n\t\t\tfor (;;) {\n\t\t\t\tconst headerEnd = buffer.indexOf(\"\\r\\n\\r\\n\");\n\t\t\t\tif (headerEnd === -1) break;\n\t\t\t\tconst header = buffer.slice(0, headerEnd);\n\t\t\t\tconst lengthMatch = header.match(/Content-Length:\\s*(\\d+)/i);\n\t\t\t\tif (lengthMatch === null) return;\n\t\t\t\tconst length = Number(lengthMatch[1]);\n\t\t\t\tconst bodyStart = headerEnd + 4;\n\t\t\t\tif (buffer.length < bodyStart + length) break;\n\t\t\t\tyield buffer.slice(bodyStart, bodyStart + length);\n\t\t\t\tbuffer = buffer.slice(bodyStart + length);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (;;) {\n\t\t\t\tconst lineEnd = buffer.indexOf(\"\\n\");\n\t\t\t\tif (lineEnd === -1) break;\n\t\t\t\tconst line = buffer.slice(0, lineEnd).trim();\n\t\t\t\tbuffer = buffer.slice(lineEnd + 1);\n\t\t\t\tif (line !== \"\") yield line;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction safePositionV1(value: unknown): number {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 ? value : 0;\n}\n\nfunction parseLspDiagnosticsV1(documentPath: string, params: unknown): BoundedDiagnosticV1[] {\n\tif (typeof params !== \"object\" || params === null) return [];\n\tconst diagnostics = (params as { diagnostics?: unknown }).diagnostics;\n\tif (!Array.isArray(diagnostics)) return [];\n\tconst projected: BoundedDiagnosticV1[] = [];\n\tfor (const raw of diagnostics) {\n\t\tif (typeof raw !== \"object\" || raw === null) continue;\n\t\tconst item = raw as {\n\t\t\trange?: { start?: { line?: unknown; character?: unknown }; end?: { line?: unknown; character?: unknown } };\n\t\t\tseverity?: unknown;\n\t\t\tcode?: unknown;\n\t\t\tsource?: unknown;\n\t\t\tmessage?: unknown;\n\t\t};\n\t\tconst message = typeof item.message === \"string\" ? sanitizeLspDiagnosticsTextV1(item.message) : \"\";\n\t\tif (message === \"\") continue;\n\t\tconst line = safePositionV1(item.range?.start?.line);\n\t\tconst column = safePositionV1(item.range?.start?.character);\n\t\tconst endLine = Math.max(line, safePositionV1(item.range?.end?.line));\n\t\tconst endColumn =\n\t\t\tendLine === line\n\t\t\t\t? Math.max(column, safePositionV1(item.range?.end?.character))\n\t\t\t\t: safePositionV1(item.range?.end?.character);\n\t\tprojected.push({\n\t\t\tfile: documentPath,\n\t\t\trange: { start: { line, column }, end: { line: endLine, column: endColumn } },\n\t\t\tseverity: lspSeverityV1(item.severity),\n\t\t\t...(typeof item.code === \"string\" || (typeof item.code === \"number\" && Number.isSafeInteger(item.code))\n\t\t\t\t? { code: item.code }\n\t\t\t\t: {}),\n\t\t\t...(typeof item.source === \"string\" ? { source: sanitizeLspDiagnosticsTextV1(item.source, 128) } : {}),\n\t\t\tmessage,\n\t\t});\n\t}\n\treturn projected;\n}\n\nfunction parseTsserverDiagnosticsV1(documentPath: string, body: unknown): BoundedDiagnosticV1[] {\n\tif (typeof body !== \"object\" || body === null) return [];\n\tconst diagnostics = (body as { diagnostics?: unknown }).diagnostics;\n\tif (!Array.isArray(diagnostics)) return [];\n\tconst projected: BoundedDiagnosticV1[] = [];\n\tfor (const raw of diagnostics) {\n\t\tif (typeof raw !== \"object\" || raw === null) continue;\n\t\tconst item = raw as {\n\t\t\tstart?: { line?: unknown; offset?: unknown };\n\t\t\tend?: { line?: unknown; offset?: unknown };\n\t\t\ttext?: unknown;\n\t\t\tcode?: unknown;\n\t\t\tcategory?: unknown;\n\t\t};\n\t\tconst message = typeof item.text === \"string\" ? sanitizeLspDiagnosticsTextV1(item.text) : \"\";\n\t\tif (message === \"\") continue;\n\t\t// tsserver positions are 1-based; normalize to the 0-based public shape.\n\t\tconst line = Math.max(0, safePositionV1(item.start?.line) - 1);\n\t\tconst column = Math.max(0, safePositionV1(item.start?.offset) - 1);\n\t\tconst endLine = Math.max(line, Math.max(0, safePositionV1(item.end?.line) - 1));\n\t\tconst endColumn =\n\t\t\tendLine === line\n\t\t\t\t? Math.max(column, Math.max(0, safePositionV1(item.end?.offset) - 1))\n\t\t\t\t: Math.max(0, safePositionV1(item.end?.offset) - 1);\n\t\tprojected.push({\n\t\t\tfile: documentPath,\n\t\t\trange: { start: { line, column }, end: { line: endLine, column: endColumn } },\n\t\t\tseverity: tsserverCategoryV1(item.category),\n\t\t\t...(typeof item.code === \"number\" && Number.isSafeInteger(item.code) ? { code: item.code } : {}),\n\t\t\tmessage,\n\t\t});\n\t}\n\treturn projected;\n}\n\n/**\n * LSP push client: initialize → didOpen → collect publishDiagnostics →\n * shutdown. The server stream is consumed by exactly one loop — breaking out\n * of a for-await over a Node stream destroys it, so phase transitions happen\n * inside the loop and the stability window resolves the shared promise\n * without interrupting the iteration.\n */\nasync function diagnoseWithLspServerV1(\n\tspec: LspServerSpecV1,\n\trelativePath: string,\n\tabsolutePath: string,\n\tlanguage: string,\n\ttext: string,\n\tsignal: AbortSignal,\n): Promise<BoundedDiagnosticV1[] | undefined> {\n\tconst server = spawnServerV1(spec, signal);\n\tif (server === undefined) return undefined;\n\tlet sequence = 0;\n\tconst nextId = () => ++sequence;\n\tconst send = (message: Record<string, unknown>): void => {\n\t\tconst payload = Buffer.from(JSON.stringify(message), \"utf8\");\n\t\tserver.write(`Content-Length: ${payload.byteLength}\\r\\n\\r\\n${payload.toString(\"utf8\")}`);\n\t};\n\tconst uri = pathToFileURL(absolutePath).href;\n\ttry {\n\t\tconst consumed = new Promise<BoundedDiagnosticV1[] | undefined>((resolveConsume) => {\n\t\t\tlet stableTimer: NodeJS.Timeout | undefined;\n\t\t\tlet latest: BoundedDiagnosticV1[] | undefined;\n\t\t\t// The stability window arms only after the first push so cold-start\n\t\t\t// servers are not cut off before their first diagnostics.\n\t\t\tconst arm = () => {\n\t\t\t\tclearTimeout(stableTimer);\n\t\t\t\tstableTimer = setTimeout(() => resolveConsume(latest), LSP_DIAGNOSTICS_STABLE_MS_V1);\n\t\t\t};\n\t\t\tvoid (async () => {\n\t\t\t\tsend({ jsonrpc: \"2.0\", id: nextId(), method: \"initialize\", params: { processId: null, capabilities: {} } });\n\t\t\t\tlet initialized = false;\n\t\t\t\tfor await (const raw of readMessagesV1(server, true)) {\n\t\t\t\t\tlet message: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tmessage = JSON.parse(raw) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (message.id !== undefined && message.method === undefined) {\n\t\t\t\t\t\tif (!initialized) {\n\t\t\t\t\t\t\tinitialized = true;\n\t\t\t\t\t\t\tsend({ jsonrpc: \"2.0\", method: \"initialized\", params: {} });\n\t\t\t\t\t\t\tsend({\n\t\t\t\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\t\t\t\tmethod: \"textDocument/didOpen\",\n\t\t\t\t\t\t\t\tparams: { textDocument: { uri, languageId: language, version: 1, text } },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (message.method === \"textDocument/publishDiagnostics\") {\n\t\t\t\t\t\tconst pushed = parseLspDiagnosticsV1(relativePath, message.params);\n\t\t\t\t\t\tif (pushed.length > 0) {\n\t\t\t\t\t\t\tlatest = pushed;\n\t\t\t\t\t\t\tarm();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresolveConsume(latest);\n\t\t\t})().catch(() => resolveConsume(latest));\n\t\t});\n\t\tconst timeout = new Promise<undefined>((resolveTimeout) => {\n\t\t\tsetTimeout(() => resolveTimeout(undefined), LSP_DIAGNOSTICS_TIMEOUT_MS_V1);\n\t\t});\n\t\tconst result = await Promise.race([consumed, timeout]);\n\t\tsend({ jsonrpc: \"2.0\", id: nextId(), method: \"shutdown\", params: null });\n\t\tsend({ jsonrpc: \"2.0\", method: \"exit\" });\n\t\treturn result;\n\t} finally {\n\t\tserver.kill();\n\t\tawait server.exit;\n\t}\n}\n\n/** tsserver client: configure → open → geterr → syntaxDiag/semanticDiag events. */\nasync function diagnoseWithTsserverV1(\n\tspec: LspServerSpecV1,\n\trelativePath: string,\n\tabsolutePath: string,\n\ttext: string,\n\tsignal: AbortSignal,\n): Promise<BoundedDiagnosticV1[] | undefined> {\n\tconst server = spawnServerV1(spec, signal);\n\tif (server === undefined) return undefined;\n\tlet sequence = 0;\n\tconst send = (command: string, argumentsValue: Record<string, unknown>): void => {\n\t\tserver.write(`${JSON.stringify({ seq: ++sequence, type: \"request\", command, arguments: argumentsValue })}\\n`);\n\t};\n\tconst collected: BoundedDiagnosticV1[] = [];\n\tconst received = { syntax: false, semantic: false };\n\ttry {\n\t\tsend(\"configure\", { hostInfo: \"agent-forge\" });\n\t\tsend(\"open\", { file: absolutePath, fileContent: text });\n\t\tsend(\"geterr\", { file: absolutePath, delay: 0 });\n\t\tconst timeout = new Promise<undefined>((resolveTimeout) => {\n\t\t\tsetTimeout(() => resolveTimeout(undefined), TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1);\n\t\t});\n\t\tconst collectedPromise = (async () => {\n\t\t\tfor await (const raw of readMessagesV1(server, false)) {\n\t\t\t\tlet message: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tmessage = JSON.parse(raw) as Record<string, unknown>;\n\t\t\t\t} catch {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (message.type !== \"event\") continue;\n\t\t\t\tif (message.event === \"syntaxDiag\" || message.event === \"syntacticDiag\") {\n\t\t\t\t\tcollected.push(...parseTsserverDiagnosticsV1(relativePath, message.body));\n\t\t\t\t\treceived.syntax = true;\n\t\t\t\t}\n\t\t\t\tif (message.event === \"semanticDiag\") {\n\t\t\t\t\tcollected.push(...parseTsserverDiagnosticsV1(relativePath, message.body));\n\t\t\t\t\treceived.semantic = true;\n\t\t\t\t}\n\t\t\t\tif (received.syntax && received.semantic) break;\n\t\t\t}\n\t\t\treturn collected;\n\t\t})().catch(() => collected);\n\t\tconst result = await Promise.race([collectedPromise, timeout]);\n\t\tsend(\"exit\", {});\n\t\treturn result;\n\t} finally {\n\t\tserver.kill();\n\t\tawait server.exit;\n\t}\n}\n\nfunction resolveDocumentPathV1(workspaceDirectory: string, request: LspDiagnosticsRequestV1): string | undefined {\n\tconst documentPath = request.documentPath;\n\tif (typeof documentPath !== \"string\" || documentPath.trim() === \"\" || !isAbsolute(workspaceDirectory))\n\t\treturn undefined;\n\tconst absolute = resolve(workspaceDirectory, documentPath);\n\tconst root = resolve(workspaceDirectory);\n\tif (!absolute.startsWith(root + (root.endsWith(\"\\\\\") || root.endsWith(\"/\") ? \"\" : \"\\\\\")) && absolute !== root)\n\t\treturn undefined;\n\ttry {\n\t\tif (!existsSync(absolute) || !statSync(absolute).isFile()) return undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn absolute;\n}\n\n/**\n * Real language-server host over one workspace directory: resolves servers per\n * language (tsserver/pyright/clangd), opens the requested workspace-relative\n * document, collects push diagnostics over LSP or the tsserver protocol, and\n * never returns server argv, cwd, environment, or absolute paths. Servers are\n * injected per resolution; a workspace without a resolvable server reports\n * `unsupported`.\n */\nexport function createNodeLspRealHostV1(options: {\n\treadonly workspaceDirectory: string;\n\treadonly pathEnv?: string;\n\treadonly servers?: LspServerMapV1;\n}): { readonly resolver: LspSessionResolverV1; readonly client: LspClientV1 } {\n\tconst workspaceDirectory = resolve(options.workspaceDirectory);\n\tconst servers = resolveLspServersV1({\n\t\tworkspaceDirectory,\n\t\t...(options.pathEnv === undefined ? {} : { pathEnv: options.pathEnv }),\n\t\t...(options.servers === undefined ? {} : { servers: options.servers }),\n\t});\n\treturn {\n\t\tresolver: {\n\t\t\tasync resolve(request: LspDiagnosticsRequestV1): Promise<LspSessionV1 | undefined> {\n\t\t\t\tconst language = SERVER_LANGUAGE_V1[request.language];\n\t\t\t\tif (language === undefined) return undefined;\n\t\t\t\tif (servers[language] === undefined) return undefined;\n\t\t\t\treturn { sessionRef: `lsp-${language}` };\n\t\t\t},\n\t\t},\n\t\tclient: {\n\t\t\tasync diagnose({ request }, signal): Promise<LspHostDiagnosticResultV1> {\n\t\t\t\tconst language = SERVER_LANGUAGE_V1[request.language];\n\t\t\t\tconst spec = language === undefined ? undefined : servers[language];\n\t\t\t\tif (spec === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst documentPath = resolveDocumentPathV1(workspaceDirectory, request);\n\t\t\t\tif (documentPath === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst abortSignal = signal ?? new AbortController().signal;\n\t\t\t\tconst text = await readFile(documentPath, \"utf8\").catch(() => undefined);\n\t\t\t\tif (text === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst relativePath = request.documentPath ?? request.documentRef;\n\t\t\t\tconst diagnostics =\n\t\t\t\t\tlanguage === \"typescript\"\n\t\t\t\t\t\t? await diagnoseWithTsserverV1(spec, relativePath, documentPath, text, abortSignal)\n\t\t\t\t\t\t: await diagnoseWithLspServerV1(\n\t\t\t\t\t\t\t\tspec,\n\t\t\t\t\t\t\t\trelativePath,\n\t\t\t\t\t\t\t\tdocumentPath,\n\t\t\t\t\t\t\t\trequest.language,\n\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\tabortSignal,\n\t\t\t\t\t\t\t);\n\t\t\t\tif (diagnostics === undefined) return { status: \"unsupported\" };\n\t\t\t\treturn { status: \"completed\", diagnostics };\n\t\t\t},\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"node-lsp-real-host.js","sourceRoot":"","sources":["../src/node-lsp-real-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { sanitizeLspDiagnosticsTextV1 } from \"./node-adapter.ts\";\nimport type {\n\tLspClientV1,\n\tLspDiagnosticsRequestV1,\n\tLspDiagnosticV1,\n\tLspHostDiagnosticResultV1,\n\tLspSessionResolverV1,\n\tLspSessionV1,\n} from \"./types.ts\";\n\nconst LSP_DIAGNOSTICS_STABLE_MS_V1 = 300;\nconst LSP_DIAGNOSTICS_TIMEOUT_MS_V1 = 15_000;\nconst TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1 = 15_000;\nconst MAX_SERVER_STDOUT_BYTES_V1 = 8 * 1024 * 1024;\n\nexport interface LspServerSpecV1 {\n\treadonly command: string;\n\treadonly args: readonly string[];\n}\n\nexport interface LspServerMapV1 {\n\treadonly typescript?: LspServerSpecV1;\n\treadonly python?: LspServerSpecV1;\n\treadonly c?: LspServerSpecV1;\n}\n\nconst SERVER_LANGUAGE_V1: Record<string, keyof LspServerMapV1> = {\n\ttypescript: \"typescript\",\n\tjavascript: \"typescript\",\n\tpython: \"python\",\n\tc: \"c\",\n\tcpp: \"c\",\n};\n\nfunction pathExecutableV1(name: string, pathEnv: string | undefined): string | undefined {\n\tif (typeof pathEnv !== \"string\" || pathEnv.trim() === \"\") return undefined;\n\tconst names = process.platform === \"win32\" ? [`${name}.exe`, `${name}.cmd`] : [name];\n\tfor (const directory of pathEnv.split(process.platform === \"win32\" ? \";\" : \":\")) {\n\t\tif (directory.trim() === \"\") continue;\n\t\tfor (const candidate of names) {\n\t\t\tconst resolved = join(directory, candidate);\n\t\t\tif (existsSync(resolved)) return resolved;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Host-owned language-server resolution: tsserver from the workspace-local\n * TypeScript install, pyright from the workspace-local npm package or PATH,\n * clangd from PATH. Unresolved languages stay absent so the wiring fails\n * closed; `servers` injects deterministic overrides for tests.\n */\nexport function resolveLspServersV1(options: {\n\treadonly workspaceDirectory: string;\n\treadonly pathEnv?: string;\n\treadonly servers?: LspServerMapV1;\n}): LspServerMapV1 {\n\tif (options.servers !== undefined) return options.servers;\n\tconst pathEnv = options.pathEnv ?? process.env.PATH;\n\tconst map: {\n\t\ttypescript?: LspServerSpecV1;\n\t\tpython?: LspServerSpecV1;\n\t\tc?: LspServerSpecV1;\n\t} = {};\n\tconst tsserver = join(options.workspaceDirectory, \"node_modules\", \"typescript\", \"lib\", \"tsserver.js\");\n\tif (isAbsolute(options.workspaceDirectory) && existsSync(tsserver))\n\t\tmap.typescript = { command: process.execPath, args: [tsserver] };\n\tconst pyrightLocal = join(options.workspaceDirectory, \"node_modules\", \"pyright\", \"dist\", \"pyright-langserver.js\");\n\tif (isAbsolute(options.workspaceDirectory) && existsSync(pyrightLocal))\n\t\tmap.python = { command: process.execPath, args: [pyrightLocal, \"--stdio\"] };\n\tconst pyrightPath = pathExecutableV1(\"pyright-langserver\", pathEnv);\n\tif (map.python === undefined && pyrightPath !== undefined) map.python = { command: pyrightPath, args: [\"--stdio\"] };\n\tconst clangd = pathExecutableV1(\"clangd\", pathEnv);\n\tif (clangd !== undefined) map.c = { command: clangd, args: [] };\n\treturn map;\n}\n\ninterface BoundedDiagnosticV1 {\n\treadonly file: string;\n\treadonly range: LspDiagnosticV1[\"range\"];\n\treadonly severity: LspDiagnosticV1[\"severity\"];\n\treadonly code?: string | number;\n\treadonly source?: string;\n\treadonly message: string;\n}\n\nfunction lspSeverityV1(value: unknown): LspDiagnosticV1[\"severity\"] {\n\tif (value === 1) return \"error\";\n\tif (value === 2) return \"warning\";\n\tif (value === 3) return \"info\";\n\tif (value === 4) return \"hint\";\n\treturn \"info\";\n}\n\nfunction tsserverCategoryV1(value: unknown): LspDiagnosticV1[\"severity\"] {\n\tif (value === \"error\") return \"error\";\n\tif (value === \"warning\") return \"warning\";\n\tif (value === \"suggestion\") return \"hint\";\n\treturn \"info\";\n}\n\ninterface SpawnedServerV1 {\n\treadonly stdout: AsyncIterable<Buffer>;\n\treadonly write: (chunk: string) => void;\n\treadonly kill: () => void;\n\treadonly exit: Promise<void>;\n}\n\nfunction spawnServerV1(spec: LspServerSpecV1, signal: AbortSignal): SpawnedServerV1 | undefined {\n\tconst child = spawn(spec.command, spec.args, {\n\t\tshell: false,\n\t\twindowsHide: true,\n\t\tstdio: [\"pipe\", \"pipe\", \"ignore\"],\n\t\tsignal,\n\t});\n\tif (child.stdout === null || child.stdin === null) {\n\t\tchild.kill();\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tstdout: child.stdout,\n\t\twrite: (chunk) => child.stdin!.write(chunk),\n\t\tkill: () => child.kill(),\n\t\texit: new Promise((resolveExit) => {\n\t\t\tchild.once(\"exit\", () => resolveExit());\n\t\t\tchild.once(\"error\", () => resolveExit());\n\t\t}),\n\t};\n}\n\n/** Frame reader over stdio: either Content-Length framed (LSP) or line-delimited JSON (tsserver). */\nasync function* readMessagesV1(server: SpawnedServerV1, framed: boolean): AsyncGenerator<string> {\n\tlet buffer = \"\";\n\tfor await (const chunk of server.stdout) {\n\t\tbuffer += chunk.toString(\"utf8\");\n\t\tif (buffer.length > MAX_SERVER_STDOUT_BYTES_V1) return;\n\t\tif (framed) {\n\t\t\tfor (;;) {\n\t\t\t\tconst headerEnd = buffer.indexOf(\"\\r\\n\\r\\n\");\n\t\t\t\tif (headerEnd === -1) break;\n\t\t\t\tconst header = buffer.slice(0, headerEnd);\n\t\t\t\tconst lengthMatch = header.match(/Content-Length:\\s*(\\d+)/i);\n\t\t\t\tif (lengthMatch === null) return;\n\t\t\t\tconst length = Number(lengthMatch[1]);\n\t\t\t\tconst bodyStart = headerEnd + 4;\n\t\t\t\tif (buffer.length < bodyStart + length) break;\n\t\t\t\tyield buffer.slice(bodyStart, bodyStart + length);\n\t\t\t\tbuffer = buffer.slice(bodyStart + length);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (;;) {\n\t\t\t\tconst lineEnd = buffer.indexOf(\"\\n\");\n\t\t\t\tif (lineEnd === -1) break;\n\t\t\t\tconst line = buffer.slice(0, lineEnd).trim();\n\t\t\t\tbuffer = buffer.slice(lineEnd + 1);\n\t\t\t\tif (line !== \"\") yield line;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction safePositionV1(value: unknown): number {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 ? value : 0;\n}\n\nfunction parseLspDiagnosticsV1(documentPath: string, params: unknown): BoundedDiagnosticV1[] {\n\tif (typeof params !== \"object\" || params === null) return [];\n\tconst diagnostics = (params as { diagnostics?: unknown }).diagnostics;\n\tif (!Array.isArray(diagnostics)) return [];\n\tconst projected: BoundedDiagnosticV1[] = [];\n\tfor (const raw of diagnostics) {\n\t\tif (typeof raw !== \"object\" || raw === null) continue;\n\t\tconst item = raw as {\n\t\t\trange?: { start?: { line?: unknown; character?: unknown }; end?: { line?: unknown; character?: unknown } };\n\t\t\tseverity?: unknown;\n\t\t\tcode?: unknown;\n\t\t\tsource?: unknown;\n\t\t\tmessage?: unknown;\n\t\t};\n\t\tconst message = typeof item.message === \"string\" ? sanitizeLspDiagnosticsTextV1(item.message) : \"\";\n\t\tif (message === \"\") continue;\n\t\tconst line = safePositionV1(item.range?.start?.line);\n\t\tconst column = safePositionV1(item.range?.start?.character);\n\t\tconst endLine = Math.max(line, safePositionV1(item.range?.end?.line));\n\t\tconst endColumn =\n\t\t\tendLine === line\n\t\t\t\t? Math.max(column, safePositionV1(item.range?.end?.character))\n\t\t\t\t: safePositionV1(item.range?.end?.character);\n\t\tprojected.push({\n\t\t\tfile: documentPath,\n\t\t\trange: { start: { line, column }, end: { line: endLine, column: endColumn } },\n\t\t\tseverity: lspSeverityV1(item.severity),\n\t\t\t...(typeof item.code === \"string\" || (typeof item.code === \"number\" && Number.isSafeInteger(item.code))\n\t\t\t\t? { code: item.code }\n\t\t\t\t: {}),\n\t\t\t...(typeof item.source === \"string\" ? { source: sanitizeLspDiagnosticsTextV1(item.source, 128) } : {}),\n\t\t\tmessage,\n\t\t});\n\t}\n\treturn projected;\n}\n\nfunction parseTsserverDiagnosticsV1(documentPath: string, body: unknown): BoundedDiagnosticV1[] {\n\tif (typeof body !== \"object\" || body === null) return [];\n\tconst diagnostics = (body as { diagnostics?: unknown }).diagnostics;\n\tif (!Array.isArray(diagnostics)) return [];\n\tconst projected: BoundedDiagnosticV1[] = [];\n\tfor (const raw of diagnostics) {\n\t\tif (typeof raw !== \"object\" || raw === null) continue;\n\t\tconst item = raw as {\n\t\t\tstart?: { line?: unknown; offset?: unknown };\n\t\t\tend?: { line?: unknown; offset?: unknown };\n\t\t\ttext?: unknown;\n\t\t\tcode?: unknown;\n\t\t\tcategory?: unknown;\n\t\t};\n\t\tconst message = typeof item.text === \"string\" ? sanitizeLspDiagnosticsTextV1(item.text) : \"\";\n\t\tif (message === \"\") continue;\n\t\t// tsserver positions are 1-based; normalize to the 0-based public shape.\n\t\tconst line = Math.max(0, safePositionV1(item.start?.line) - 1);\n\t\tconst column = Math.max(0, safePositionV1(item.start?.offset) - 1);\n\t\tconst endLine = Math.max(line, Math.max(0, safePositionV1(item.end?.line) - 1));\n\t\tconst endColumn =\n\t\t\tendLine === line\n\t\t\t\t? Math.max(column, Math.max(0, safePositionV1(item.end?.offset) - 1))\n\t\t\t\t: Math.max(0, safePositionV1(item.end?.offset) - 1);\n\t\tprojected.push({\n\t\t\tfile: documentPath,\n\t\t\trange: { start: { line, column }, end: { line: endLine, column: endColumn } },\n\t\t\tseverity: tsserverCategoryV1(item.category),\n\t\t\t...(typeof item.code === \"number\" && Number.isSafeInteger(item.code) ? { code: item.code } : {}),\n\t\t\tmessage,\n\t\t});\n\t}\n\treturn projected;\n}\n\n/**\n * LSP push client: initialize → didOpen → collect publishDiagnostics →\n * shutdown. The server stream is consumed by exactly one loop — breaking out\n * of a for-await over a Node stream destroys it, so phase transitions happen\n * inside the loop and the stability window resolves the shared promise\n * without interrupting the iteration.\n */\nasync function diagnoseWithLspServerV1(\n\tspec: LspServerSpecV1,\n\trelativePath: string,\n\tabsolutePath: string,\n\tlanguage: string,\n\ttext: string,\n\tsignal: AbortSignal,\n): Promise<BoundedDiagnosticV1[] | undefined> {\n\tconst server = spawnServerV1(spec, signal);\n\tif (server === undefined) return undefined;\n\tlet sequence = 0;\n\tconst nextId = () => ++sequence;\n\tconst send = (message: Record<string, unknown>): void => {\n\t\tconst payload = Buffer.from(JSON.stringify(message), \"utf8\");\n\t\tserver.write(`Content-Length: ${payload.byteLength}\\r\\n\\r\\n${payload.toString(\"utf8\")}`);\n\t};\n\tconst uri = pathToFileURL(absolutePath).href;\n\ttry {\n\t\tconst consumed = new Promise<BoundedDiagnosticV1[] | undefined>((resolveConsume) => {\n\t\t\tlet stableTimer: NodeJS.Timeout | undefined;\n\t\t\tlet latest: BoundedDiagnosticV1[] | undefined;\n\t\t\t// The stability window arms only after the first push so cold-start\n\t\t\t// servers are not cut off before their first diagnostics.\n\t\t\tconst arm = () => {\n\t\t\t\tclearTimeout(stableTimer);\n\t\t\t\tstableTimer = setTimeout(() => resolveConsume(latest), LSP_DIAGNOSTICS_STABLE_MS_V1);\n\t\t\t};\n\t\t\tvoid (async () => {\n\t\t\t\tsend({ jsonrpc: \"2.0\", id: nextId(), method: \"initialize\", params: { processId: null, capabilities: {} } });\n\t\t\t\tlet initialized = false;\n\t\t\t\tfor await (const raw of readMessagesV1(server, true)) {\n\t\t\t\t\tlet message: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tmessage = JSON.parse(raw) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (message.id !== undefined && message.method === undefined) {\n\t\t\t\t\t\tif (!initialized) {\n\t\t\t\t\t\t\tinitialized = true;\n\t\t\t\t\t\t\tsend({ jsonrpc: \"2.0\", method: \"initialized\", params: {} });\n\t\t\t\t\t\t\tsend({\n\t\t\t\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\t\t\t\tmethod: \"textDocument/didOpen\",\n\t\t\t\t\t\t\t\tparams: { textDocument: { uri, languageId: language, version: 1, text } },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (message.method === \"textDocument/publishDiagnostics\") {\n\t\t\t\t\t\tconst pushed = parseLspDiagnosticsV1(relativePath, message.params);\n\t\t\t\t\t\tif (pushed.length > 0) {\n\t\t\t\t\t\t\tlatest = pushed;\n\t\t\t\t\t\t\tarm();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresolveConsume(latest);\n\t\t\t})().catch(() => resolveConsume(latest));\n\t\t});\n\t\tconst timeout = new Promise<undefined>((resolveTimeout) => {\n\t\t\tsetTimeout(() => resolveTimeout(undefined), LSP_DIAGNOSTICS_TIMEOUT_MS_V1);\n\t\t});\n\t\tconst result = await Promise.race([consumed, timeout]);\n\t\tsend({ jsonrpc: \"2.0\", id: nextId(), method: \"shutdown\", params: null });\n\t\tsend({ jsonrpc: \"2.0\", method: \"exit\" });\n\t\treturn result;\n\t} finally {\n\t\tserver.kill();\n\t\tawait server.exit;\n\t}\n}\n\n/** tsserver client: configure → open → geterr → syntaxDiag/semanticDiag events. */\nasync function diagnoseWithTsserverV1(\n\tspec: LspServerSpecV1,\n\trelativePath: string,\n\tabsolutePath: string,\n\ttext: string,\n\tsignal: AbortSignal,\n): Promise<BoundedDiagnosticV1[] | undefined> {\n\tconst server = spawnServerV1(spec, signal);\n\tif (server === undefined) return undefined;\n\tlet sequence = 0;\n\tconst send = (command: string, argumentsValue: Record<string, unknown>): number => {\n\t\tconst seq = ++sequence;\n\t\tserver.write(`${JSON.stringify({ seq, type: \"request\", command, arguments: argumentsValue })}\\n`);\n\t\treturn seq;\n\t};\n\tconst collected: BoundedDiagnosticV1[] = [];\n\tconst received = { syntax: false, semantic: false };\n\ttry {\n\t\tsend(\"configure\", { hostInfo: \"agent-forge\" });\n\t\tsend(\"open\", { file: absolutePath, fileContent: text });\n\t\t// Real tsserver's geterr takes `files: string[]`; a scalar `file`\n\t\t// field is never read, the request fails internally, and no diagnostic\n\t\t// events are emitted. The requestCompleted event for the geterr\n\t\t// sequence is the server's own completion signal, so a missing diag\n\t\t// event (e.g. a file no project claims) cannot stall until the\n\t\t// timeout.\n\t\tconst geterrSeq = send(\"geterr\", { delay: 0, files: [absolutePath] });\n\t\tconst timeout = new Promise<undefined>((resolveTimeout) => {\n\t\t\tsetTimeout(() => resolveTimeout(undefined), TSSERVER_DIAGNOSTICS_TIMEOUT_MS_V1);\n\t\t});\n\t\tconst collectedPromise = (async () => {\n\t\t\tfor await (const raw of readMessagesV1(server, false)) {\n\t\t\t\tlet message: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tmessage = JSON.parse(raw) as Record<string, unknown>;\n\t\t\t\t} catch {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (message.type !== \"event\") continue;\n\t\t\t\tif (message.event === \"syntaxDiag\" || message.event === \"syntacticDiag\") {\n\t\t\t\t\tcollected.push(...parseTsserverDiagnosticsV1(relativePath, message.body));\n\t\t\t\t\treceived.syntax = true;\n\t\t\t\t}\n\t\t\t\tif (message.event === \"semanticDiag\") {\n\t\t\t\t\tcollected.push(...parseTsserverDiagnosticsV1(relativePath, message.body));\n\t\t\t\t\treceived.semantic = true;\n\t\t\t\t}\n\t\t\t\tif (received.syntax && received.semantic) break;\n\t\t\t\tif (\n\t\t\t\t\tmessage.event === \"requestCompleted\" &&\n\t\t\t\t\t(message.body as { request_seq?: unknown } | undefined)?.request_seq === geterrSeq\n\t\t\t\t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn collected;\n\t\t})().catch(() => collected);\n\t\tconst result = await Promise.race([collectedPromise, timeout]);\n\t\tsend(\"exit\", {});\n\t\treturn result;\n\t} finally {\n\t\tserver.kill();\n\t\tawait server.exit;\n\t}\n}\n\nfunction resolveDocumentPathV1(workspaceDirectory: string, request: LspDiagnosticsRequestV1): string | undefined {\n\tconst documentPath = request.documentPath;\n\tif (typeof documentPath !== \"string\" || documentPath.trim() === \"\" || !isAbsolute(workspaceDirectory))\n\t\treturn undefined;\n\tconst absolute = resolve(workspaceDirectory, documentPath);\n\tconst root = resolve(workspaceDirectory);\n\tif (!absolute.startsWith(root + (root.endsWith(\"\\\\\") || root.endsWith(\"/\") ? \"\" : \"\\\\\")) && absolute !== root)\n\t\treturn undefined;\n\ttry {\n\t\tif (!existsSync(absolute) || !statSync(absolute).isFile()) return undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn absolute;\n}\n\n/**\n * Real language-server host over one workspace directory: resolves servers per\n * language (tsserver/pyright/clangd), opens the requested workspace-relative\n * document, collects push diagnostics over LSP or the tsserver protocol, and\n * never returns server argv, cwd, environment, or absolute paths. Servers are\n * injected per resolution; a workspace without a resolvable server reports\n * `unsupported`.\n */\nexport function createNodeLspRealHostV1(options: {\n\treadonly workspaceDirectory: string;\n\treadonly pathEnv?: string;\n\treadonly servers?: LspServerMapV1;\n}): { readonly resolver: LspSessionResolverV1; readonly client: LspClientV1 } {\n\tconst workspaceDirectory = resolve(options.workspaceDirectory);\n\tconst servers = resolveLspServersV1({\n\t\tworkspaceDirectory,\n\t\t...(options.pathEnv === undefined ? {} : { pathEnv: options.pathEnv }),\n\t\t...(options.servers === undefined ? {} : { servers: options.servers }),\n\t});\n\treturn {\n\t\tresolver: {\n\t\t\tasync resolve(request: LspDiagnosticsRequestV1): Promise<LspSessionV1 | undefined> {\n\t\t\t\tconst language = SERVER_LANGUAGE_V1[request.language];\n\t\t\t\tif (language === undefined) return undefined;\n\t\t\t\tif (servers[language] === undefined) return undefined;\n\t\t\t\treturn { sessionRef: `lsp-${language}` };\n\t\t\t},\n\t\t},\n\t\tclient: {\n\t\t\tasync diagnose({ request }, signal): Promise<LspHostDiagnosticResultV1> {\n\t\t\t\tconst language = SERVER_LANGUAGE_V1[request.language];\n\t\t\t\tconst spec = language === undefined ? undefined : servers[language];\n\t\t\t\tif (spec === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst documentPath = resolveDocumentPathV1(workspaceDirectory, request);\n\t\t\t\tif (documentPath === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst abortSignal = signal ?? new AbortController().signal;\n\t\t\t\tconst text = await readFile(documentPath, \"utf8\").catch(() => undefined);\n\t\t\t\tif (text === undefined) return { status: \"unsupported\" };\n\t\t\t\tconst relativePath = request.documentPath ?? request.documentRef;\n\t\t\t\tconst diagnostics =\n\t\t\t\t\tlanguage === \"typescript\"\n\t\t\t\t\t\t? await diagnoseWithTsserverV1(spec, relativePath, documentPath, text, abortSignal)\n\t\t\t\t\t\t: await diagnoseWithLspServerV1(\n\t\t\t\t\t\t\t\tspec,\n\t\t\t\t\t\t\t\trelativePath,\n\t\t\t\t\t\t\t\tdocumentPath,\n\t\t\t\t\t\t\t\trequest.language,\n\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\tabortSignal,\n\t\t\t\t\t\t\t);\n\t\t\t\tif (diagnostics === undefined) return { status: \"unsupported\" };\n\t\t\t\treturn { status: \"completed\", diagnostics };\n\t\t\t},\n\t\t},\n\t};\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-agent-forge/plugin-lsp-diagnostics",
|
|
3
|
-
"version": "0.85.
|
|
3
|
+
"version": "0.85.6",
|
|
4
4
|
"description": "LSP diagnostics capability plugin for Agent Forge (read-only lsp_diagnostics tool)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"node": ">=22.19.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@agent-forge/plugin-sdk": "^0.85.
|
|
47
|
+
"@agent-forge/plugin-sdk": "^0.85.6",
|
|
48
48
|
"typebox": "1.3.27"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@agent-forge/agent-forge": "^0.85.
|
|
51
|
+
"@agent-forge/agent-forge": "^0.85.6",
|
|
52
52
|
"shx": "0.4.0",
|
|
53
53
|
"vitest": "4.1.9"
|
|
54
54
|
}
|