@arnilo/prism-tools 0.0.0-stage → 0.13.1

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.
Files changed (331) hide show
  1. package/CHANGELOG.md +418 -0
  2. package/LICENSE +21 -0
  3. package/README.md +44 -2
  4. package/browser/README.md +98 -0
  5. package/browser/skills/browser-automation/SKILL.md +14 -0
  6. package/browser/src/actions/cdp.ts +131 -0
  7. package/browser/src/actions/dialog.ts +25 -0
  8. package/browser/src/actions/download_release.ts +22 -0
  9. package/browser/src/actions/index.ts +37 -0
  10. package/browser/src/actions/locator.ts +70 -0
  11. package/browser/src/actions/navigate.ts +23 -0
  12. package/browser/src/actions/screenshot.ts +27 -0
  13. package/browser/src/actions/scroll.ts +24 -0
  14. package/browser/src/actions/select_page.ts +21 -0
  15. package/browser/src/actions/types.ts +114 -0
  16. package/browser/src/actions/upload.ts +44 -0
  17. package/browser/src/actions/wait.ts +45 -0
  18. package/browser/src/browser.ts +197 -0
  19. package/browser/src/cdp.ts +178 -0
  20. package/browser/src/checkpoint.ts +189 -0
  21. package/browser/src/config.ts +72 -0
  22. package/browser/src/downloads.ts +253 -0
  23. package/browser/src/errors.ts +31 -0
  24. package/browser/src/evaluate.ts +101 -0
  25. package/browser/src/index.ts +129 -0
  26. package/browser/src/limits.ts +271 -0
  27. package/browser/src/manager.ts +730 -0
  28. package/browser/src/network.ts +263 -0
  29. package/browser/src/observe.ts +178 -0
  30. package/browser/src/policy.ts +133 -0
  31. package/browser/src/screenshot.ts +107 -0
  32. package/browser/src/shared-sandbox.ts +53 -0
  33. package/browser/src/snapshot.ts +99 -0
  34. package/browser/src/targets.ts +165 -0
  35. package/browser/src/tools.ts +480 -0
  36. package/browser/src/types.ts +316 -0
  37. package/browser/src/uploads.ts +174 -0
  38. package/coding/README.md +337 -0
  39. package/coding/src/agent/acp-operations.ts +146 -0
  40. package/coding/src/agent/artifacts.ts +38 -0
  41. package/coding/src/agent/ask-user-decision.ts +623 -0
  42. package/coding/src/agent/atomic-write.ts +23 -0
  43. package/coding/src/agent/bounded-file.ts +21 -0
  44. package/coding/src/agent/checks.ts +301 -0
  45. package/coding/src/agent/coding-checkpoint.ts +828 -0
  46. package/coding/src/agent/delete.ts +237 -0
  47. package/coding/src/agent/diagnostics-tool.ts +163 -0
  48. package/coding/src/agent/diagnostics.ts +262 -0
  49. package/coding/src/agent/edit-diff.ts +382 -0
  50. package/coding/src/agent/edit.ts +322 -0
  51. package/coding/src/agent/effects.ts +102 -0
  52. package/coding/src/agent/env.ts +28 -0
  53. package/coding/src/agent/execution-policy.ts +89 -0
  54. package/coding/src/agent/file-mutation-queue.ts +72 -0
  55. package/coding/src/agent/forge/github.ts +603 -0
  56. package/coding/src/agent/forge/index.ts +16 -0
  57. package/coding/src/agent/forge/types.ts +185 -0
  58. package/coding/src/agent/git-aware-repository.ts +305 -0
  59. package/coding/src/agent/git-exec.ts +326 -0
  60. package/coding/src/agent/git-status.ts +177 -0
  61. package/coding/src/agent/git-tools.ts +360 -0
  62. package/coding/src/agent/git.ts +1074 -0
  63. package/coding/src/agent/glob-match.ts +146 -0
  64. package/coding/src/agent/glob.ts +182 -0
  65. package/coding/src/agent/goal-verify.ts +385 -0
  66. package/coding/src/agent/grep-worker.ts +74 -0
  67. package/coding/src/agent/grep.ts +459 -0
  68. package/coding/src/agent/identity.ts +48 -0
  69. package/coding/src/agent/index.ts +676 -0
  70. package/coding/src/agent/language/client.ts +429 -0
  71. package/coding/src/agent/language/framing.ts +190 -0
  72. package/coding/src/agent/language/index.ts +23 -0
  73. package/coding/src/agent/language/intelligence.ts +682 -0
  74. package/coding/src/agent/language/types.ts +187 -0
  75. package/coding/src/agent/lifecycle-events.ts +121 -0
  76. package/coding/src/agent/lifecycle.ts +166 -0
  77. package/coding/src/agent/limits.ts +214 -0
  78. package/coding/src/agent/move.ts +178 -0
  79. package/coding/src/agent/mutation-path.ts +52 -0
  80. package/coding/src/agent/output-accumulator.ts +304 -0
  81. package/coding/src/agent/path-utils.ts +120 -0
  82. package/coding/src/agent/process/index.ts +58 -0
  83. package/coding/src/agent/process/recovery.ts +508 -0
  84. package/coding/src/agent/process/sessions-host.ts +222 -0
  85. package/coding/src/agent/process/sessions-monitor.ts +141 -0
  86. package/coding/src/agent/process/sessions-recovery.ts +241 -0
  87. package/coding/src/agent/process/sessions-spawn.ts +613 -0
  88. package/coding/src/agent/process/sessions-teardown.ts +281 -0
  89. package/coding/src/agent/process/sessions.ts +30 -0
  90. package/coding/src/agent/process/types.ts +358 -0
  91. package/coding/src/agent/read-path-set.ts +126 -0
  92. package/coding/src/agent/read.ts +713 -0
  93. package/coding/src/agent/repository/glob.ts +147 -0
  94. package/coding/src/agent/repository/indexed-search.ts +480 -0
  95. package/coding/src/agent/repository/list.ts +131 -0
  96. package/coding/src/agent/repository/operations.ts +22 -0
  97. package/coding/src/agent/repository/path.ts +98 -0
  98. package/coding/src/agent/repository/search.ts +277 -0
  99. package/coding/src/agent/repository/types.ts +243 -0
  100. package/coding/src/agent/repository/walk.ts +126 -0
  101. package/coding/src/agent/repository.ts +12 -0
  102. package/coding/src/agent/shell-background.ts +264 -0
  103. package/coding/src/agent/shell-output.ts +75 -0
  104. package/coding/src/agent/shell.ts +526 -0
  105. package/coding/src/agent/todo.ts +399 -0
  106. package/coding/src/agent/truncate.ts +251 -0
  107. package/coding/src/agent/write.ts +170 -0
  108. package/coding/src/ask-user-host.ts +48 -0
  109. package/coding/src/config.ts +278 -0
  110. package/coding/src/hard-deny.ts +97 -0
  111. package/coding/src/index.ts +318 -0
  112. package/coding/src/principal-guard.ts +84 -0
  113. package/coding/src/sandbox.ts +92 -0
  114. package/coding/src/security/approval.ts +144 -0
  115. package/coding/src/security/command-rules.ts +57 -0
  116. package/coding/src/security/docker-cli.ts +222 -0
  117. package/coding/src/security/docker-sandbox.ts +1205 -0
  118. package/coding/src/security/e2b-sandbox.ts +853 -0
  119. package/coding/src/security/egress/dns-pin.ts +88 -0
  120. package/coding/src/security/egress/index.ts +32 -0
  121. package/coding/src/security/egress/limits.ts +57 -0
  122. package/coding/src/security/egress/policy.ts +137 -0
  123. package/coding/src/security/egress/proxy.ts +599 -0
  124. package/coding/src/security/egress/types.ts +30 -0
  125. package/coding/src/security/index.ts +199 -0
  126. package/coding/src/security/native-sandbox.ts +639 -0
  127. package/coding/src/security/path-containment.ts +55 -0
  128. package/coding/src/security/sandbox-coding-operations.ts +392 -0
  129. package/coding/src/security/sandbox-fs-operations.ts +644 -0
  130. package/coding/src/security/sandbox-limits.ts +147 -0
  131. package/coding/src/security/sandbox-tar.ts +308 -0
  132. package/coding/src/security/sandbox.ts +179 -0
  133. package/coding/src/security/semaphore.ts +55 -0
  134. package/coding/src/targets.ts +110 -0
  135. package/coding/src/workspace/diff.ts +78 -0
  136. package/coding/src/workspace/errors.ts +29 -0
  137. package/coding/src/workspace/index.ts +5 -0
  138. package/coding/src/workspace/merge.ts +151 -0
  139. package/coding/src/workspace/routing.ts +76 -0
  140. package/coding/src/workspace/service.ts +584 -0
  141. package/computer-use/README.md +105 -0
  142. package/computer-use/skills/computer-use-linux/SKILL.md +17 -0
  143. package/computer-use/src/classify.ts +53 -0
  144. package/computer-use/src/command.ts +29 -0
  145. package/computer-use/src/config.ts +69 -0
  146. package/computer-use/src/create.ts +170 -0
  147. package/computer-use/src/devices.ts +247 -0
  148. package/computer-use/src/env.ts +28 -0
  149. package/computer-use/src/index.ts +157 -0
  150. package/computer-use/src/skill.ts +21 -0
  151. package/openapi/README.md +97 -0
  152. package/openapi/src/compile.ts +386 -0
  153. package/openapi/src/config.ts +73 -0
  154. package/openapi/src/errors.ts +16 -0
  155. package/openapi/src/execute.ts +241 -0
  156. package/openapi/src/index.ts +124 -0
  157. package/openapi/src/limits.ts +63 -0
  158. package/openapi/src/specs.ts +86 -0
  159. package/openapi/src/tools.ts +60 -0
  160. package/openapi/src/types.ts +61 -0
  161. package/package.json +171 -4
  162. package/research/README.md +72 -0
  163. package/research/skills/research-report/SKILL.md +12 -0
  164. package/research/skills/research-scoping/SKILL.md +10 -0
  165. package/research/skills/research-synthesis/SKILL.md +10 -0
  166. package/research/skills/source-triage/SKILL.md +10 -0
  167. package/research/src/check.ts +71 -0
  168. package/research/src/config.ts +41 -0
  169. package/research/src/index.ts +147 -0
  170. package/research/src/ledger.ts +157 -0
  171. package/research/src/urls.ts +21 -0
  172. package/web/README.md +287 -0
  173. package/web/skills/web-research/SKILL.md +17 -0
  174. package/web/src/brave.ts +66 -0
  175. package/web/src/cache.ts +151 -0
  176. package/web/src/config.ts +210 -0
  177. package/web/src/controls.ts +128 -0
  178. package/web/src/domains.ts +114 -0
  179. package/web/src/exa.ts +60 -0
  180. package/web/src/firecrawl.ts +160 -0
  181. package/web/src/index.ts +387 -0
  182. package/web/src/kagi.ts +73 -0
  183. package/web/src/limits.ts +55 -0
  184. package/web/src/native/convert.ts +84 -0
  185. package/web/src/native/fetch.ts +226 -0
  186. package/web/src/normalize.ts +131 -0
  187. package/web/src/obscura/cdp.ts +201 -0
  188. package/web/src/obscura/classify.ts +35 -0
  189. package/web/src/obscura/cli.ts +254 -0
  190. package/web/src/obscura/errors.ts +8 -0
  191. package/web/src/obscura/index.ts +59 -0
  192. package/web/src/obscura/limits.ts +92 -0
  193. package/web/src/obscura/mcp.ts +104 -0
  194. package/web/src/obscura/playwright.ts +133 -0
  195. package/web/src/obscura/process.ts +235 -0
  196. package/web/src/obscura/search-profile.ts +73 -0
  197. package/web/src/obscura/types.ts +48 -0
  198. package/web/src/obscura/web.ts +419 -0
  199. package/web/src/prompt-fetch.ts +88 -0
  200. package/web/src/render.ts +75 -0
  201. package/web/src/searxng.ts +78 -0
  202. package/web/src/slice.ts +139 -0
  203. package/web/src/tavily.ts +77 -0
  204. package/web/src/tools.ts +182 -0
  205. package/web/src/transport.ts +310 -0
  206. package/web/src/types.ts +199 -0
  207. package/work/README.md +77 -0
  208. package/work/THIRD_PARTY_NOTICES +24 -0
  209. package/work/docling/ocr.py +150 -0
  210. package/work/sandbox/Dockerfile +36 -0
  211. package/work/sandbox/soffice.sh +12 -0
  212. package/work/src/command.ts +29 -0
  213. package/work/src/config.ts +138 -0
  214. package/work/src/connectors/cli.ts +343 -0
  215. package/work/src/connectors/drafts.ts +647 -0
  216. package/work/src/connectors/errors.ts +8 -0
  217. package/work/src/connectors/file-bytes.ts +149 -0
  218. package/work/src/connectors/google-workspace-http.ts +399 -0
  219. package/work/src/connectors/google-workspace.ts +465 -0
  220. package/work/src/connectors/gws-tools.ts +378 -0
  221. package/work/src/connectors/http.ts +123 -0
  222. package/work/src/connectors/idempotency.ts +235 -0
  223. package/work/src/connectors/identity.ts +34 -0
  224. package/work/src/connectors/index.ts +93 -0
  225. package/work/src/connectors/limits.ts +50 -0
  226. package/work/src/connectors/m365-tools.ts +308 -0
  227. package/work/src/connectors/microsoft365-http.ts +428 -0
  228. package/work/src/connectors/microsoft365.ts +402 -0
  229. package/work/src/connectors/normalize.ts +120 -0
  230. package/work/src/connectors/tool-helpers.ts +398 -0
  231. package/work/src/connectors/tools.ts +42 -0
  232. package/work/src/connectors/types.ts +399 -0
  233. package/work/src/diagrams/canonicalize.ts +166 -0
  234. package/work/src/diagrams/caps.ts +52 -0
  235. package/work/src/diagrams/embed.ts +340 -0
  236. package/work/src/diagrams/errors.ts +76 -0
  237. package/work/src/diagrams/index.ts +81 -0
  238. package/work/src/diagrams/messages.ts +150 -0
  239. package/work/src/diagrams/origin.ts +52 -0
  240. package/work/src/diagrams/telemetry.ts +34 -0
  241. package/work/src/diagrams/xml.ts +267 -0
  242. package/work/src/document-extraction/index.ts +563 -0
  243. package/work/src/document-reader/ambient.d.ts +2 -0
  244. package/work/src/document-reader/errors.ts +7 -0
  245. package/work/src/document-reader/index.ts +181 -0
  246. package/work/src/document-reader/mistral-ocr.ts +318 -0
  247. package/work/src/document-reader/parsers.ts +171 -0
  248. package/work/src/documents/caps.ts +135 -0
  249. package/work/src/documents/diff.ts +269 -0
  250. package/work/src/documents/errors.ts +44 -0
  251. package/work/src/documents/fidelity.ts +98 -0
  252. package/work/src/documents/generate.ts +96 -0
  253. package/work/src/documents/hash.ts +8 -0
  254. package/work/src/documents/index.ts +14 -0
  255. package/work/src/documents/model-schema.ts +639 -0
  256. package/work/src/documents/parse.ts +252 -0
  257. package/work/src/documents/patch-history.ts +81 -0
  258. package/work/src/documents/patch.ts +476 -0
  259. package/work/src/documents/preview-html.ts +245 -0
  260. package/work/src/documents/preview.ts +227 -0
  261. package/work/src/documents/telemetry.ts +36 -0
  262. package/work/src/documents/translate/docx.ts +292 -0
  263. package/work/src/documents/translate/pptx.ts +304 -0
  264. package/work/src/documents/translate/xlsx.ts +137 -0
  265. package/work/src/documents/types.ts +188 -0
  266. package/work/src/index.ts +311 -0
  267. package/work/src/runtime/worker-pool-entry.ts +102 -0
  268. package/work/src/runtime/worker-pool.ts +267 -0
  269. package/work/src/sandbox/composition.ts +212 -0
  270. package/work/src/sandbox/image.ts +6 -0
  271. package/work/src/sandbox/index.ts +14 -0
  272. package/work/src/sheets/caps.ts +68 -0
  273. package/work/src/sheets/csv.ts +351 -0
  274. package/work/src/sheets/decimal.ts +388 -0
  275. package/work/src/sheets/errors.ts +52 -0
  276. package/work/src/sheets/index.ts +62 -0
  277. package/work/src/sheets/inference.ts +378 -0
  278. package/work/src/sheets/telemetry.ts +34 -0
  279. package/work/src/sheets/types.ts +162 -0
  280. package/work/src/sheets/xlsx.ts +388 -0
  281. package/work/src/skills/index.ts +8 -0
  282. package/work/src/skills/load.ts +43 -0
  283. package/work/src/tools/filesystem.ts +21 -0
  284. package/work/src/tools/index.ts +1 -0
  285. package/work/src/tools/local-filesystem.ts +33 -0
  286. package/work/src/tools/office.ts +311 -0
  287. package/work/vendor/hermes-agent/LICENSE +21 -0
  288. package/work/vendor/hermes-agent/skills/productivity/docx/LICENSE +21 -0
  289. package/work/vendor/hermes-agent/skills/productivity/docx/SKILL.md +196 -0
  290. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_comments.py +289 -0
  291. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_common.py +94 -0
  292. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_create.py +177 -0
  293. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_edit.py +250 -0
  294. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_read.py +149 -0
  295. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_revisions.py +147 -0
  296. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_template.py +70 -0
  297. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_validate.py +156 -0
  298. package/work/vendor/hermes-agent/skills/productivity/pdf/LICENSE +21 -0
  299. package/work/vendor/hermes-agent/skills/productivity/pdf/SKILL.md +125 -0
  300. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/_raster.py +76 -0
  301. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/extract_marker.py +88 -0
  302. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/extract_pymupdf.py +101 -0
  303. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_create.py +130 -0
  304. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_fill_form.py +97 -0
  305. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_form_layout.py +168 -0
  306. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_make_form.py +145 -0
  307. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_merge.py +50 -0
  308. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_meta.py +115 -0
  309. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_page_image.py +99 -0
  310. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_read.py +153 -0
  311. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_secure.py +71 -0
  312. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_split.py +84 -0
  313. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_stamp.py +143 -0
  314. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_watermark.py +51 -0
  315. package/work/vendor/hermes-agent/skills/productivity/powerpoint/LICENSE +21 -0
  316. package/work/vendor/hermes-agent/skills/productivity/powerpoint/SKILL.md +220 -0
  317. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_create.py +214 -0
  318. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_edit.py +436 -0
  319. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_from_template.py +88 -0
  320. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_read.py +131 -0
  321. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_render.py +93 -0
  322. package/work/vendor/hermes-agent/skills/productivity/xlsx/LICENSE +21 -0
  323. package/work/vendor/hermes-agent/skills/productivity/xlsx/SKILL.md +196 -0
  324. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/csv_to_xlsx.py +104 -0
  325. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_create.py +259 -0
  326. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_edit.py +263 -0
  327. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_read.py +160 -0
  328. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_recalc.py +111 -0
  329. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_restructure.py +337 -0
  330. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_to_csv.py +69 -0
  331. package/work/vendor-lock.json +11 -0
@@ -0,0 +1,429 @@
1
+ /**
2
+ * Minimal JSON-RPC LSP client over child stdio (LSP 3.17 framing).
3
+ * Lazy start; bounded pending requests, message bytes, timeout, restart budget.
4
+ */
5
+
6
+ import { type ChildProcessWithoutNullStreams, spawn } from "node:child_process";
7
+ import { buildChildEnv, DEFAULT_CHILD_ENV_INHERIT } from "../env.js";
8
+ import { encodeLspFrame, LspFrameError, LspFrameReader } from "./framing.js";
9
+ import { LanguageIntelligenceError, type ResolvedLanguageIntelligenceLimits } from "./types.js";
10
+
11
+ export interface LspServerSpec {
12
+ readonly name: string;
13
+ readonly command: string;
14
+ readonly args: readonly string[];
15
+ readonly env?: Readonly<Record<string, string>>;
16
+ readonly cwd: string;
17
+ readonly rootUri: string;
18
+ }
19
+
20
+ type Pending = {
21
+ readonly resolve: (value: unknown) => void;
22
+ readonly reject: (error: Error) => void;
23
+ readonly timer: ReturnType<typeof setTimeout>;
24
+ readonly abortHandler?: () => void;
25
+ readonly signal?: AbortSignal;
26
+ };
27
+
28
+ /** Socket-loss codes Node reports when the peer dies between the writable check and the write. */
29
+ const SOCKET_LOSS_CODES = new Set(["EPIPE", "ECONNRESET", "ERR_STREAM_DESTROYED", "ERR_STREAM_WRITE_AFTER_END"]);
30
+
31
+ /**
32
+ * A write to a server that died is a server error, not an unknown transport crash: hosts switch on
33
+ * LanguageIntelligenceError codes, and an unclassified socket error escapes as an uncaught `write
34
+ * EPIPE` (plan 071 Task 13). Typed errors and unrelated failures pass through unchanged.
35
+ */
36
+ function classifySocketLoss(error: unknown, serverName: string): Error {
37
+ if (error instanceof LanguageIntelligenceError) return error;
38
+ const code = typeof error === "object" && error !== null && "code" in error ? error.code : undefined;
39
+ if (typeof code === "string" && SOCKET_LOSS_CODES.has(code)) {
40
+ return new LanguageIntelligenceError("ERR_PRISM_LSP_SERVER", `LSP server ${serverName} stdin write failed (${code})`);
41
+ }
42
+ return error instanceof Error ? error : new Error(String(error));
43
+ }
44
+
45
+ export class LspClient {
46
+ private child: ChildProcessWithoutNullStreams | undefined;
47
+ private reader: LspFrameReader;
48
+ private nextId = 1;
49
+ private pending = new Map<number, Pending>();
50
+ private startPromise: Promise<void> | undefined;
51
+ private disposed = false;
52
+ private shuttingDown = false;
53
+ private capabilities: Record<string, unknown> = {};
54
+ /** file URI → latest diagnostics payload from publishDiagnostics */
55
+ readonly diagnosticsByUri = new Map<string, unknown>();
56
+ /** file URI → monotonic document version (didOpen=1, each didChange += 1) */
57
+ readonly documentVersions = new Map<string, number>();
58
+ /** file URI → last pull-diagnostic resultId (textDocument/diagnostic) */
59
+ readonly pullResultIds = new Map<string, string>();
60
+ private readonly onUnexpectedExit: () => void;
61
+
62
+ constructor(
63
+ readonly spec: LspServerSpec,
64
+ private readonly limits: ResolvedLanguageIntelligenceLimits,
65
+ hooks?: { onUnexpectedExit?: () => void },
66
+ ) {
67
+ this.reader = new LspFrameReader(limits.maxMessageBytes);
68
+ this.onUnexpectedExit = hooks?.onUnexpectedExit ?? (() => {});
69
+ }
70
+
71
+ get started(): boolean {
72
+ return this.child !== undefined && !this.disposed;
73
+ }
74
+
75
+ async ensureStarted(signal?: AbortSignal): Promise<void> {
76
+ if (this.disposed) {
77
+ throw new LanguageIntelligenceError("ERR_PRISM_LSP_SERVER", `LSP server ${this.spec.name} is disposed`);
78
+ }
79
+ if (this.child) return;
80
+ if (!this.startPromise) {
81
+ this.startPromise = this.spawnAndInitialize(signal).finally(() => {
82
+ this.startPromise = undefined;
83
+ });
84
+ }
85
+ await this.startPromise;
86
+ }
87
+
88
+ async request(method: string, params: unknown, signal?: AbortSignal): Promise<unknown> {
89
+ await this.ensureStarted(signal);
90
+ if (this.pending.size >= this.limits.maxPendingRequests) {
91
+ throw new LanguageIntelligenceError("ERR_PRISM_LSP_LIMIT", `LSP pending requests exceed ${this.limits.maxPendingRequests}`);
92
+ }
93
+ const id = this.nextId++;
94
+ const payload = { jsonrpc: "2.0", id, method, params };
95
+ return new Promise<unknown>((resolve, reject) => {
96
+ const timer = setTimeout(() => {
97
+ this.pending.delete(id);
98
+ cleanupAbort();
99
+ reject(
100
+ new LanguageIntelligenceError("ERR_PRISM_LSP_TIMEOUT", `LSP request ${method} timed out after ${this.limits.requestTimeoutMs}ms`),
101
+ );
102
+ }, this.limits.requestTimeoutMs);
103
+
104
+ const abortHandler = () => {
105
+ this.pending.delete(id);
106
+ clearTimeout(timer);
107
+ reject(new LanguageIntelligenceError("ERR_PRISM_LSP_TIMEOUT", "LSP request aborted"));
108
+ };
109
+ const cleanupAbort = () => {
110
+ if (signal && abortHandler) signal.removeEventListener("abort", abortHandler);
111
+ };
112
+
113
+ if (signal) {
114
+ if (signal.aborted) {
115
+ clearTimeout(timer);
116
+ reject(new LanguageIntelligenceError("ERR_PRISM_LSP_TIMEOUT", "LSP request aborted"));
117
+ return;
118
+ }
119
+ signal.addEventListener("abort", abortHandler, { once: true });
120
+ }
121
+
122
+ this.pending.set(id, { resolve, reject, timer, abortHandler, signal });
123
+ try {
124
+ this.write(payload);
125
+ } catch (error) {
126
+ this.pending.delete(id);
127
+ clearTimeout(timer);
128
+ cleanupAbort();
129
+ reject(error instanceof Error ? error : new Error(String(error)));
130
+ }
131
+ });
132
+ }
133
+
134
+ notify(method: string, params: unknown): void {
135
+ if (!this.child) return;
136
+ this.write({ jsonrpc: "2.0", method, params });
137
+ }
138
+
139
+ /**
140
+ * Full-content textDocument/didChange (LSP 3.17; protocol-valid, no diff
141
+ * engine needed). Monotonic version: didOpen stamps 1, each didChange
142
+ * increments. No-op when the document was never opened.
143
+ */
144
+ didChange(uri: string, text: string): void {
145
+ const version = (this.documentVersions.get(uri) ?? 0) + 1;
146
+ this.documentVersions.set(uri, version);
147
+ this.notify("textDocument/didChange", {
148
+ textDocument: { uri, version },
149
+ contentChanges: [{ text }],
150
+ });
151
+ }
152
+
153
+ /** true when the server advertises textDocument/diagnostic (pull diagnostics). */
154
+ hasPullDiagnostics(): boolean {
155
+ const provider = this.capabilities.diagnosticProvider;
156
+ if (!provider || provider === false) return false;
157
+ return true;
158
+ }
159
+
160
+ /**
161
+ * Pull diagnostics for one opened document (textDocument/diagnostic) with
162
+ * resultId reuse: `kind: "full"` replaces the set, `kind: "unchanged"`
163
+ * reuses the previous payload. Returns the version at request time so the
164
+ * caller can drop stale responses. Falls back to the push cache when the
165
+ * server has no pull support.
166
+ */
167
+ async pullDiagnostics(
168
+ uri: string,
169
+ signal?: AbortSignal,
170
+ ): Promise<{
171
+ kind: "full" | "unchanged";
172
+ diagnostics: unknown;
173
+ resultId?: string;
174
+ version: number;
175
+ }> {
176
+ const version = this.documentVersions.get(uri) ?? 1;
177
+ if (!this.hasPullDiagnostics()) {
178
+ return { kind: "full", diagnostics: this.diagnosticsByUri.get(uri) ?? [], version };
179
+ }
180
+ const previousResultId = this.pullResultIds.get(uri);
181
+ const result = (await this.request(
182
+ "textDocument/diagnostic",
183
+ { textDocument: { uri }, ...(previousResultId === undefined ? {} : { previousResultId }) },
184
+ signal,
185
+ )) as { kind?: string; items?: unknown; resultId?: string } | undefined;
186
+ if (!result || typeof result !== "object") {
187
+ return { kind: "full", diagnostics: this.diagnosticsByUri.get(uri) ?? [], version };
188
+ }
189
+ if (result.kind === "unchanged") {
190
+ const cached = this.diagnosticsByUri.get(uri) ?? [];
191
+ if (typeof result.resultId === "string") this.pullResultIds.set(uri, result.resultId);
192
+ return { kind: "unchanged", diagnostics: cached, resultId: result.resultId, version };
193
+ }
194
+ const items = Array.isArray(result.items) ? result.items : [];
195
+ this.diagnosticsByUri.set(uri, items);
196
+ if (typeof result.resultId === "string") this.pullResultIds.set(uri, result.resultId);
197
+ return { kind: "full", diagnostics: items, resultId: result.resultId, version };
198
+ }
199
+
200
+ hasCapability(key: string): boolean {
201
+ return this.capabilities[key] !== undefined && this.capabilities[key] !== false;
202
+ }
203
+
204
+ async dispose(): Promise<void> {
205
+ this.disposed = true;
206
+ this.shuttingDown = true;
207
+ this.rejectAll(new LanguageIntelligenceError("ERR_PRISM_LSP_SERVER", `LSP server ${this.spec.name} disposed`));
208
+ const child = this.child;
209
+ this.child = undefined;
210
+ if (!child) return;
211
+ try {
212
+ child.stdin.end();
213
+ } catch {
214
+ /* ignore */
215
+ }
216
+ if (!child.killed) {
217
+ child.kill("SIGTERM");
218
+ }
219
+ await new Promise<void>((resolve) => {
220
+ if (child.exitCode !== null) {
221
+ resolve();
222
+ return;
223
+ }
224
+ const t = setTimeout(() => {
225
+ child.kill("SIGKILL");
226
+ resolve();
227
+ }, 2_000);
228
+ child.once("exit", () => {
229
+ clearTimeout(t);
230
+ resolve();
231
+ });
232
+ });
233
+ }
234
+
235
+ private write(message: unknown): void {
236
+ if (!this.child?.stdin.writable) {
237
+ throw new LanguageIntelligenceError("ERR_PRISM_LSP_SERVER", `LSP server ${this.spec.name} stdin closed`);
238
+ }
239
+ const frame = encodeLspFrame(message);
240
+ if (frame.length > this.limits.maxMessageBytes + 64) {
241
+ // header overhead small; body already sized by JSON
242
+ throw new LanguageIntelligenceError("ERR_PRISM_LSP_LIMIT", "Outgoing LSP frame exceeds message byte cap");
243
+ }
244
+ try {
245
+ this.child.stdin.write(frame);
246
+ } catch (error) {
247
+ // Some platforms throw the socket loss synchronously instead of emitting it; both shapes are
248
+ // the same server error to a host.
249
+ throw classifySocketLoss(error, this.spec.name);
250
+ }
251
+ }
252
+
253
+ private async spawnAndInitialize(signal?: AbortSignal): Promise<void> {
254
+ if (signal?.aborted) {
255
+ throw new LanguageIntelligenceError("ERR_PRISM_LSP_TIMEOUT", "LSP start aborted");
256
+ }
257
+ this.reader = new LspFrameReader(this.limits.maxMessageBytes);
258
+ const child = spawn(this.spec.command, [...this.spec.args], {
259
+ cwd: this.spec.cwd,
260
+ env: buildChildEnv({ inherit: DEFAULT_CHILD_ENV_INHERIT, set: this.spec.env }), // allow-list; never pass process.env through
261
+ stdio: ["pipe", "pipe", "pipe"],
262
+ windowsHide: true,
263
+ });
264
+ this.child = child;
265
+
266
+ child.stdout.on("data", (chunk: Buffer) => {
267
+ try {
268
+ for (const msg of this.reader.push(chunk)) this.onMessage(msg);
269
+ } catch (error) {
270
+ this.failTransport(error);
271
+ }
272
+ });
273
+ child.stdin.on("error", (error) => {
274
+ // The peer's death lands here, not in the write's call stack: Node reports the failed pipe
275
+ // write asynchronously on the socket (which still reads as `writable`). Reject pending
276
+ // requests with the typed server error and let the exit handler do the restart accounting —
277
+ // disposing here would skip onUnexpectedExit and the restart budget would never trip.
278
+ this.rejectAll(classifySocketLoss(error, this.spec.name));
279
+ });
280
+ child.stderr.on("data", () => {
281
+ /* discard; hosts can redirect via env if needed */
282
+ });
283
+ child.on("error", (error) => {
284
+ this.failTransport(new LanguageIntelligenceError("ERR_PRISM_LSP_SERVER", `LSP spawn failed: ${error.message}`));
285
+ });
286
+ child.on("exit", (code, signalName) => {
287
+ if (this.disposed || this.shuttingDown) return;
288
+ this.child = undefined;
289
+ this.rejectAll(
290
+ new LanguageIntelligenceError("ERR_PRISM_LSP_SERVER", `LSP server ${this.spec.name} exited (code=${code}, signal=${signalName})`),
291
+ );
292
+ this.onUnexpectedExit();
293
+ });
294
+
295
+ try {
296
+ const initResult = (await this.requestUnlocked(
297
+ "initialize",
298
+ {
299
+ processId: process.pid,
300
+ rootUri: this.spec.rootUri,
301
+ capabilities: {
302
+ workspace: { applyEdit: true },
303
+ textDocument: {
304
+ hover: { contentFormat: ["plaintext", "markdown"] },
305
+ publishDiagnostics: {},
306
+ diagnostic: { dynamicRegistration: false },
307
+ },
308
+ },
309
+ workspaceFolders: [{ uri: this.spec.rootUri, name: "workspace" }],
310
+ },
311
+ signal,
312
+ )) as { capabilities?: Record<string, unknown> };
313
+
314
+ this.capabilities = initResult?.capabilities ?? {};
315
+ this.notify("initialized", {});
316
+ } catch (error) {
317
+ this.shuttingDown = true;
318
+ this.child = undefined;
319
+ try {
320
+ child.kill("SIGKILL");
321
+ } catch {
322
+ /* ignore */
323
+ }
324
+ throw error;
325
+ }
326
+ }
327
+
328
+ /** Internal request used during initialize before ensureStarted recursion. */
329
+ private requestUnlocked(method: string, params: unknown, signal?: AbortSignal): Promise<unknown> {
330
+ if (this.pending.size >= this.limits.maxPendingRequests) {
331
+ throw new LanguageIntelligenceError("ERR_PRISM_LSP_LIMIT", `LSP pending requests exceed ${this.limits.maxPendingRequests}`);
332
+ }
333
+ const id = this.nextId++;
334
+ const payload = { jsonrpc: "2.0", id, method, params };
335
+ return new Promise<unknown>((resolve, reject) => {
336
+ const timer = setTimeout(() => {
337
+ this.pending.delete(id);
338
+ cleanupAbort();
339
+ reject(
340
+ new LanguageIntelligenceError("ERR_PRISM_LSP_TIMEOUT", `LSP request ${method} timed out after ${this.limits.requestTimeoutMs}ms`),
341
+ );
342
+ }, this.limits.requestTimeoutMs);
343
+
344
+ const abortHandler = () => {
345
+ this.pending.delete(id);
346
+ clearTimeout(timer);
347
+ reject(new LanguageIntelligenceError("ERR_PRISM_LSP_TIMEOUT", "LSP request aborted"));
348
+ };
349
+ const cleanupAbort = () => {
350
+ if (signal) signal.removeEventListener("abort", abortHandler);
351
+ };
352
+
353
+ if (signal) {
354
+ if (signal.aborted) {
355
+ clearTimeout(timer);
356
+ reject(new LanguageIntelligenceError("ERR_PRISM_LSP_TIMEOUT", "LSP request aborted"));
357
+ return;
358
+ }
359
+ signal.addEventListener("abort", abortHandler, { once: true });
360
+ }
361
+
362
+ this.pending.set(id, { resolve, reject, timer, abortHandler, signal });
363
+ try {
364
+ this.write(payload);
365
+ } catch (error) {
366
+ this.pending.delete(id);
367
+ clearTimeout(timer);
368
+ cleanupAbort();
369
+ reject(error instanceof Error ? error : new Error(String(error)));
370
+ }
371
+ });
372
+ }
373
+
374
+ private onMessage(msg: unknown): void {
375
+ if (!msg || typeof msg !== "object") {
376
+ throw new LspFrameError("ERR_PRISM_LSP_FRAMING", "LSP message is not an object");
377
+ }
378
+ const m = msg as {
379
+ id?: number | string;
380
+ method?: string;
381
+ params?: unknown;
382
+ result?: unknown;
383
+ error?: { message?: string; code?: number };
384
+ };
385
+
386
+ if (m.method && m.id === undefined) {
387
+ if (m.method === "textDocument/publishDiagnostics" && m.params && typeof m.params === "object") {
388
+ const p = m.params as { uri?: string; diagnostics?: unknown };
389
+ if (typeof p.uri === "string") this.diagnosticsByUri.set(p.uri, p.diagnostics ?? []);
390
+ }
391
+ return;
392
+ }
393
+
394
+ if (m.id === undefined) return;
395
+ const id = typeof m.id === "number" ? m.id : Number(m.id);
396
+ const pending = this.pending.get(id);
397
+ if (!pending) return;
398
+ this.pending.delete(id);
399
+ clearTimeout(pending.timer);
400
+ if (pending.signal && pending.abortHandler) {
401
+ pending.signal.removeEventListener("abort", pending.abortHandler);
402
+ }
403
+ if (m.error) {
404
+ pending.reject(new LanguageIntelligenceError("ERR_PRISM_LSP_SERVER", m.error.message ?? `LSP error code ${m.error.code}`));
405
+ return;
406
+ }
407
+ pending.resolve(m.result);
408
+ }
409
+
410
+ private failTransport(error: unknown): void {
411
+ const err =
412
+ error instanceof LanguageIntelligenceError
413
+ ? error
414
+ : error instanceof LspFrameError
415
+ ? new LanguageIntelligenceError(error.code, error.message)
416
+ : new LanguageIntelligenceError("ERR_PRISM_LSP_FRAMING", error instanceof Error ? error.message : String(error));
417
+ this.rejectAll(err);
418
+ void this.dispose();
419
+ }
420
+
421
+ private rejectAll(error: Error): void {
422
+ for (const [, p] of this.pending) {
423
+ clearTimeout(p.timer);
424
+ if (p.signal && p.abortHandler) p.signal.removeEventListener("abort", p.abortHandler);
425
+ p.reject(error);
426
+ }
427
+ this.pending.clear();
428
+ }
429
+ }
@@ -0,0 +1,190 @@
1
+ /**
2
+ * LSP 3.17 Content-Length framing over stdio (JSON-RPC body).
3
+ * No vscode-languageserver-protocol dependency.
4
+ */
5
+
6
+ export type LspFrameErrorCode = "ERR_PRISM_LSP_FRAMING" | "ERR_PRISM_LSP_LIMIT";
7
+
8
+ export class LspFrameError extends Error {
9
+ readonly code: LspFrameErrorCode;
10
+ constructor(code: LspFrameErrorCode, message: string) {
11
+ super(message);
12
+ this.name = "LspFrameError";
13
+ this.code = code;
14
+ }
15
+ }
16
+
17
+ /** Encode one JSON-RPC message as an LSP frame. */
18
+ export function encodeLspFrame(message: unknown): Buffer {
19
+ const body = Buffer.from(JSON.stringify(message), "utf8");
20
+ const header = `Content-Length: ${body.length}\r\n\r\n`;
21
+ return Buffer.concat([Buffer.from(header, "ascii"), body]);
22
+ }
23
+
24
+ /**
25
+ * Incremental Content-Length frame reader.
26
+ * Rejects malformed headers, non-decimal Content-Length, and oversized bodies.
27
+ */
28
+ export class LspFrameReader {
29
+ // ponytail: chunk-array accumulator — O(1) append per push, no whole-buffer re-concat
30
+ // (the 0.2.4 `this.buf = Buffer.concat([this.buf, chunk])` was O(input * chunks)).
31
+ // A completed frame copies only its header+body region (bounded by maxMessageBytes),
32
+ // so total copying is O(input). The header separator scan peeks min(retained, 64KiB)
33
+ // per unparsed frame; for the rare many-frames-per-large-chunk case that is a 64KiB-
34
+ // per-frame copy (linear, 64x constant) — upgrade to a streaming separator search
35
+ // if pipelined-frame throughput matters. A separator beyond the 64KiB header bound
36
+ // is rejected (stricter DoS guard than 0.2.4, which accepted it; no test exercises
37
+ // >64KiB headers — the bound exists precisely to reject unbounded header growth).
38
+ private chunks: Buffer[] = [];
39
+ private offset = 0; // consumed prefix bytes in chunks[0]
40
+ private retained = 0; // total unconsumed bytes
41
+ private cachedBodyStart = -1; // -1 = header not yet parsed; else body starts at this absolute unconsumed offset
42
+ private cachedContentLength = 0;
43
+ private readonly maxMessageBytes: number;
44
+
45
+ constructor(maxMessageBytes: number) {
46
+ this.maxMessageBytes = maxMessageBytes;
47
+ }
48
+
49
+ /** Push stdout/stderr chunk; return complete parsed JSON values (order preserved). */
50
+ push(chunk: Buffer): unknown[] {
51
+ if (chunk.length === 0) return [];
52
+ this.chunks.push(chunk);
53
+ this.retained += chunk.length;
54
+ const out: unknown[] = [];
55
+ for (;;) {
56
+ const parsed = this.tryParseOne();
57
+ if (parsed === undefined) break;
58
+ out.push(parsed);
59
+ }
60
+ return out;
61
+ }
62
+
63
+ /** Copy `n` unconsumed bytes starting at absolute unconsumed offset `start` (no advance). */
64
+ private peekAt(start: number, n: number): Buffer {
65
+ const out = Buffer.allocUnsafe(n);
66
+ let written = 0;
67
+ let i = 0;
68
+ let off = this.offset;
69
+ let skip = start;
70
+ while (skip > 0) {
71
+ const c = this.chunks[i];
72
+ const avail = c.length - off;
73
+ if (skip >= avail) {
74
+ skip -= avail;
75
+ i++;
76
+ off = 0;
77
+ } else {
78
+ off += skip;
79
+ skip = 0;
80
+ }
81
+ }
82
+ while (written < n) {
83
+ const c = this.chunks[i];
84
+ const take = Math.min(c.length - off, n - written);
85
+ c.copy(out, written, off, off + take);
86
+ written += take;
87
+ i++;
88
+ off = 0;
89
+ }
90
+ return out;
91
+ }
92
+
93
+ /** Advance the unconsumed cursor by `n` (drop fully-consumed chunks). */
94
+ private drop(n: number): void {
95
+ let remaining = n;
96
+ while (remaining > 0 && this.chunks.length > 0) {
97
+ const first = this.chunks[0];
98
+ const avail = first.length - this.offset;
99
+ if (remaining >= avail) {
100
+ remaining -= avail;
101
+ this.chunks.shift();
102
+ this.offset = 0;
103
+ } else {
104
+ this.offset += remaining;
105
+ remaining = 0;
106
+ }
107
+ }
108
+ this.retained -= n;
109
+ }
110
+
111
+ private tryParseOne(): unknown | undefined {
112
+ if (this.retained === 0) return undefined;
113
+ const headerBound = Math.min(this.maxMessageBytes, 64 * 1024);
114
+
115
+ if (this.cachedBodyStart < 0) {
116
+ // Bound header scan buffer so a missing separator cannot grow forever.
117
+ const scanLen = Math.min(this.retained, headerBound);
118
+ const view = this.peekAt(0, scanLen);
119
+ const sep = indexOfHeaderSep(view);
120
+ if (sep < 0) {
121
+ if (this.retained > headerBound) {
122
+ throw new LspFrameError("ERR_PRISM_LSP_FRAMING", "LSP header exceeds bound without separator");
123
+ }
124
+ return undefined;
125
+ }
126
+ const headerText = view.subarray(0, sep).toString("ascii");
127
+ const contentLength = parseContentLength(headerText);
128
+ if (contentLength > this.maxMessageBytes) {
129
+ throw new LspFrameError("ERR_PRISM_LSP_LIMIT", `LSP message body ${contentLength} exceeds maxMessageBytes ${this.maxMessageBytes}`);
130
+ }
131
+ this.cachedBodyStart = sep + 4;
132
+ this.cachedContentLength = contentLength;
133
+ }
134
+
135
+ const bodyEnd = this.cachedBodyStart + this.cachedContentLength;
136
+ if (this.retained < bodyEnd) return undefined;
137
+
138
+ const body = this.peekAt(this.cachedBodyStart, this.cachedContentLength);
139
+ this.drop(bodyEnd);
140
+ this.cachedBodyStart = -1;
141
+ this.cachedContentLength = 0;
142
+ let value: unknown;
143
+ try {
144
+ value = JSON.parse(body.toString("utf8"));
145
+ } catch {
146
+ throw new LspFrameError("ERR_PRISM_LSP_FRAMING", "LSP message body is not valid JSON");
147
+ }
148
+ return value;
149
+ }
150
+ }
151
+
152
+ function indexOfHeaderSep(buf: Buffer): number {
153
+ for (let i = 0; i + 3 < buf.length; i++) {
154
+ if (buf[i] === 0x0d && buf[i + 1] === 0x0a && buf[i + 2] === 0x0d && buf[i + 3] === 0x0a) {
155
+ return i;
156
+ }
157
+ }
158
+ return -1;
159
+ }
160
+
161
+ function parseContentLength(headerText: string): number {
162
+ const lines = headerText.split("\r\n");
163
+ let contentLength: number | undefined;
164
+ for (const line of lines) {
165
+ if (line.length === 0) continue;
166
+ const colon = line.indexOf(":");
167
+ if (colon <= 0) {
168
+ throw new LspFrameError("ERR_PRISM_LSP_FRAMING", `Malformed LSP header line: ${line}`);
169
+ }
170
+ const name = line.slice(0, colon).trim().toLowerCase();
171
+ const value = line.slice(colon + 1).trim();
172
+ if (name === "content-length") {
173
+ if (!/^\d+$/.test(value)) {
174
+ throw new LspFrameError("ERR_PRISM_LSP_FRAMING", `Invalid Content-Length: ${value}`);
175
+ }
176
+ if (contentLength !== undefined) {
177
+ throw new LspFrameError("ERR_PRISM_LSP_FRAMING", "Duplicate Content-Length header");
178
+ }
179
+ contentLength = Number(value);
180
+ if (!Number.isSafeInteger(contentLength) || contentLength < 0) {
181
+ throw new LspFrameError("ERR_PRISM_LSP_FRAMING", `Invalid Content-Length: ${value}`);
182
+ }
183
+ }
184
+ // Content-Type and other headers ignored; reject CR/LF injection already split by lines.
185
+ }
186
+ if (contentLength === undefined) {
187
+ throw new LspFrameError("ERR_PRISM_LSP_FRAMING", "Missing Content-Length header");
188
+ }
189
+ return contentLength;
190
+ }
@@ -0,0 +1,23 @@
1
+ export { LspClient } from "./client.js";
2
+ export { encodeLspFrame, LspFrameError, LspFrameReader } from "./framing.js";
3
+ export {
4
+ applyTextEdits,
5
+ createLanguageIntelligence,
6
+ LanguageIntelligenceError,
7
+ languageIdForPath,
8
+ resolveLanguageIntelligenceLimits,
9
+ } from "./intelligence.js";
10
+ export type {
11
+ CreateLanguageIntelligenceOptions,
12
+ LanguageDiagnostic,
13
+ LanguageDiagnosticDeltaRequest,
14
+ LanguageDiagnosticDeltaResult,
15
+ LanguageFileDiagnostics,
16
+ LanguageIntelligence,
17
+ LanguageIntelligenceLimits,
18
+ LanguageLocation,
19
+ LanguageServerSpec,
20
+ LanguageSymbol,
21
+ LanguageTextEdit,
22
+ LanguageWorkspaceEdit,
23
+ } from "./types.js";