@ai-agent-forge/plugin-lsp-diagnostics 0.85.4 → 0.85.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.lsp-diagnostics",
4
- "pluginVersion": "0.85.4",
4
+ "pluginVersion": "0.85.5",
5
5
  "apiVersion": "1",
6
6
  "minHostVersion": "0.84.4",
7
7
  "capabilityRefs": [
@@ -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,CAiDrH","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.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"]}
@@ -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 }),
@@ -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
- * The adapter is deliberately constructed without host injection: language
5
- * servers are resolved per workspace by the host, so the registered
6
- * `lsp_diagnostics` tool reports an explicit `unsupported` result until a host
7
- * binds a resolver and client through its own profile machinery (fail-closed
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").CapabilityPluginSyncFactory;
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
@@ -1 +1 @@
1
- {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;;AACH,wBAAiF","sourcesContent":["import { createLspDiagnosticsCapabilityFactoryV1 } from \"./capability.ts\";\nimport { createNodeLspAdapterV1 } from \"./node-adapter.ts\";\n\n/**\n * Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.\n *\n * The adapter is deliberately constructed without host injection: language\n * servers are resolved per workspace by the host, so the registered\n * `lsp_diagnostics` tool reports an explicit `unsupported` result until a host\n * binds a resolver and client through its own profile machinery (fail-closed\n * by design, same contract as the embedded build).\n */\nexport default createLspDiagnosticsCapabilityFactoryV1(createNodeLspAdapterV1());\n"]}
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
- * The adapter is deliberately constructed without host injection: language
7
- * servers are resolved per workspace by the host, so the registered
8
- * `lsp_diagnostics` tool reports an explicit `unsupported` result until a host
9
- * binds a resolver and client through its own profile machinery (fail-closed
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 createLspDiagnosticsCapabilityFactoryV1(createNodeLspAdapterV1());
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":"AAAA,OAAO,EAAE,uCAAuC,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAe,uCAAuC,CAAC,sBAAsB,EAAE,CAAC,CAAC","sourcesContent":["import { createLspDiagnosticsCapabilityFactoryV1 } from \"./capability.ts\";\nimport { createNodeLspAdapterV1 } from \"./node-adapter.ts\";\n\n/**\n * Default-export factory consumed by the host's `loadCapabilityPluginFromManifest`.\n *\n * The adapter is deliberately constructed without host injection: language\n * servers are resolved per workspace by the host, so the registered\n * `lsp_diagnostics` tool reports an explicit `unsupported` result until a host\n * binds a resolver and client through its own profile machinery (fail-closed\n * by design, same contract as the embedded build).\n */\nexport default createLspDiagnosticsCapabilityFactoryV1(createNodeLspAdapterV1());\n"]}
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-agent-forge/plugin-lsp-diagnostics",
3
- "version": "0.85.4",
3
+ "version": "0.85.5",
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.4",
47
+ "@agent-forge/plugin-sdk": "^0.85.5",
48
48
  "typebox": "1.3.27"
49
49
  },
50
50
  "devDependencies": {
51
- "@agent-forge/agent-forge": "^0.85.4",
51
+ "@agent-forge/agent-forge": "^0.85.5",
52
52
  "shx": "0.4.0",
53
53
  "vitest": "4.1.9"
54
54
  }
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.lsp-diagnostics",
3
- "version": "0.85.4",
3
+ "version": "0.85.5",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.84.4",