@chances-ai/engine 24.0.0

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 (389) hide show
  1. package/dist/agents/discover.d.ts +30 -0
  2. package/dist/agents/discover.d.ts.map +1 -0
  3. package/dist/agents/discover.js +183 -0
  4. package/dist/agents/discover.js.map +1 -0
  5. package/dist/agents/index.d.ts +20 -0
  6. package/dist/agents/index.d.ts.map +1 -0
  7. package/dist/agents/index.js +52 -0
  8. package/dist/agents/index.js.map +1 -0
  9. package/dist/agents/parse.d.ts +61 -0
  10. package/dist/agents/parse.d.ts.map +1 -0
  11. package/dist/agents/parse.js +527 -0
  12. package/dist/agents/parse.js.map +1 -0
  13. package/dist/agents/types.d.ts +52 -0
  14. package/dist/agents/types.d.ts.map +1 -0
  15. package/dist/agents/types.js +8 -0
  16. package/dist/agents/types.js.map +1 -0
  17. package/dist/ai/adapters/ai-sdk-stream.d.ts +19 -0
  18. package/dist/ai/adapters/ai-sdk-stream.d.ts.map +1 -0
  19. package/dist/ai/adapters/ai-sdk-stream.js +125 -0
  20. package/dist/ai/adapters/ai-sdk-stream.js.map +1 -0
  21. package/dist/ai/adapters/ai-sdk.d.ts +56 -0
  22. package/dist/ai/adapters/ai-sdk.d.ts.map +1 -0
  23. package/dist/ai/adapters/ai-sdk.js +112 -0
  24. package/dist/ai/adapters/ai-sdk.js.map +1 -0
  25. package/dist/ai/adapters/mock.d.ts +13 -0
  26. package/dist/ai/adapters/mock.d.ts.map +1 -0
  27. package/dist/ai/adapters/mock.js +54 -0
  28. package/dist/ai/adapters/mock.js.map +1 -0
  29. package/dist/ai/adapters/openai-compatible.d.ts +23 -0
  30. package/dist/ai/adapters/openai-compatible.d.ts.map +1 -0
  31. package/dist/ai/adapters/openai-compatible.js +45 -0
  32. package/dist/ai/adapters/openai-compatible.js.map +1 -0
  33. package/dist/ai/cost.d.ts +3 -0
  34. package/dist/ai/cost.d.ts.map +1 -0
  35. package/dist/ai/cost.js +5 -0
  36. package/dist/ai/cost.js.map +1 -0
  37. package/dist/ai/index.d.ts +12 -0
  38. package/dist/ai/index.d.ts.map +1 -0
  39. package/dist/ai/index.js +11 -0
  40. package/dist/ai/index.js.map +1 -0
  41. package/dist/ai/known-models.d.ts +20 -0
  42. package/dist/ai/known-models.d.ts.map +1 -0
  43. package/dist/ai/known-models.js +129 -0
  44. package/dist/ai/known-models.js.map +1 -0
  45. package/dist/ai/registry.d.ts +12 -0
  46. package/dist/ai/registry.d.ts.map +1 -0
  47. package/dist/ai/registry.js +24 -0
  48. package/dist/ai/registry.js.map +1 -0
  49. package/dist/ai/retry.d.ts +11 -0
  50. package/dist/ai/retry.d.ts.map +1 -0
  51. package/dist/ai/retry.js +14 -0
  52. package/dist/ai/retry.js.map +1 -0
  53. package/dist/ai/router.d.ts +25 -0
  54. package/dist/ai/router.d.ts.map +1 -0
  55. package/dist/ai/router.js +36 -0
  56. package/dist/ai/router.js.map +1 -0
  57. package/dist/ai/setup.d.ts +23 -0
  58. package/dist/ai/setup.d.ts.map +1 -0
  59. package/dist/ai/setup.js +47 -0
  60. package/dist/ai/setup.js.map +1 -0
  61. package/dist/ai/summarizer.d.ts +24 -0
  62. package/dist/ai/summarizer.d.ts.map +1 -0
  63. package/dist/ai/summarizer.js +56 -0
  64. package/dist/ai/summarizer.js.map +1 -0
  65. package/dist/ai/types.d.ts +83 -0
  66. package/dist/ai/types.d.ts.map +1 -0
  67. package/dist/ai/types.js +2 -0
  68. package/dist/ai/types.js.map +1 -0
  69. package/dist/core/compaction/circuit-breaker.d.ts +32 -0
  70. package/dist/core/compaction/circuit-breaker.d.ts.map +1 -0
  71. package/dist/core/compaction/circuit-breaker.js +42 -0
  72. package/dist/core/compaction/circuit-breaker.js.map +1 -0
  73. package/dist/core/compaction/compactor.d.ts +75 -0
  74. package/dist/core/compaction/compactor.d.ts.map +1 -0
  75. package/dist/core/compaction/compactor.js +261 -0
  76. package/dist/core/compaction/compactor.js.map +1 -0
  77. package/dist/core/compaction/estimate.d.ts +39 -0
  78. package/dist/core/compaction/estimate.d.ts.map +1 -0
  79. package/dist/core/compaction/estimate.js +74 -0
  80. package/dist/core/compaction/estimate.js.map +1 -0
  81. package/dist/core/compaction/index.d.ts +5 -0
  82. package/dist/core/compaction/index.d.ts.map +1 -0
  83. package/dist/core/compaction/index.js +5 -0
  84. package/dist/core/compaction/index.js.map +1 -0
  85. package/dist/core/compaction/prune.d.ts +43 -0
  86. package/dist/core/compaction/prune.d.ts.map +1 -0
  87. package/dist/core/compaction/prune.js +51 -0
  88. package/dist/core/compaction/prune.js.map +1 -0
  89. package/dist/core/engine.d.ts +268 -0
  90. package/dist/core/engine.d.ts.map +1 -0
  91. package/dist/core/engine.js +767 -0
  92. package/dist/core/engine.js.map +1 -0
  93. package/dist/core/index.d.ts +6 -0
  94. package/dist/core/index.d.ts.map +1 -0
  95. package/dist/core/index.js +6 -0
  96. package/dist/core/index.js.map +1 -0
  97. package/dist/core/task-tool.d.ts +175 -0
  98. package/dist/core/task-tool.d.ts.map +1 -0
  99. package/dist/core/task-tool.js +901 -0
  100. package/dist/core/task-tool.js.map +1 -0
  101. package/dist/core/workspace-query.d.ts +83 -0
  102. package/dist/core/workspace-query.d.ts.map +1 -0
  103. package/dist/core/workspace-query.js +217 -0
  104. package/dist/core/workspace-query.js.map +1 -0
  105. package/dist/core/worktree/active-marker.d.ts +31 -0
  106. package/dist/core/worktree/active-marker.d.ts.map +1 -0
  107. package/dist/core/worktree/active-marker.js +109 -0
  108. package/dist/core/worktree/active-marker.js.map +1 -0
  109. package/dist/core/worktree/create.d.ts +40 -0
  110. package/dist/core/worktree/create.d.ts.map +1 -0
  111. package/dist/core/worktree/create.js +121 -0
  112. package/dist/core/worktree/create.js.map +1 -0
  113. package/dist/core/worktree/errors.d.ts +7 -0
  114. package/dist/core/worktree/errors.d.ts.map +1 -0
  115. package/dist/core/worktree/errors.js +11 -0
  116. package/dist/core/worktree/errors.js.map +1 -0
  117. package/dist/core/worktree/gc.d.ts +39 -0
  118. package/dist/core/worktree/gc.d.ts.map +1 -0
  119. package/dist/core/worktree/gc.js +146 -0
  120. package/dist/core/worktree/gc.js.map +1 -0
  121. package/dist/core/worktree/git.d.ts +53 -0
  122. package/dist/core/worktree/git.d.ts.map +1 -0
  123. package/dist/core/worktree/git.js +166 -0
  124. package/dist/core/worktree/git.js.map +1 -0
  125. package/dist/core/worktree/index.d.ts +8 -0
  126. package/dist/core/worktree/index.d.ts.map +1 -0
  127. package/dist/core/worktree/index.js +8 -0
  128. package/dist/core/worktree/index.js.map +1 -0
  129. package/dist/core/worktree/paths.d.ts +26 -0
  130. package/dist/core/worktree/paths.d.ts.map +1 -0
  131. package/dist/core/worktree/paths.js +57 -0
  132. package/dist/core/worktree/paths.js.map +1 -0
  133. package/dist/core/worktree/slug.d.ts +6 -0
  134. package/dist/core/worktree/slug.d.ts.map +1 -0
  135. package/dist/core/worktree/slug.js +21 -0
  136. package/dist/core/worktree/slug.js.map +1 -0
  137. package/dist/local-vault/file-store.d.ts +64 -0
  138. package/dist/local-vault/file-store.d.ts.map +1 -0
  139. package/dist/local-vault/file-store.js +225 -0
  140. package/dist/local-vault/file-store.js.map +1 -0
  141. package/dist/local-vault/index.d.ts +57 -0
  142. package/dist/local-vault/index.d.ts.map +1 -0
  143. package/dist/local-vault/index.js +68 -0
  144. package/dist/local-vault/index.js.map +1 -0
  145. package/dist/local-vault/keychain.d.ts +58 -0
  146. package/dist/local-vault/keychain.d.ts.map +1 -0
  147. package/dist/local-vault/keychain.js +200 -0
  148. package/dist/local-vault/keychain.js.map +1 -0
  149. package/dist/local-vault/mutex.d.ts +20 -0
  150. package/dist/local-vault/mutex.d.ts.map +1 -0
  151. package/dist/local-vault/mutex.js +44 -0
  152. package/dist/local-vault/mutex.js.map +1 -0
  153. package/dist/local-vault/passphrase.d.ts +30 -0
  154. package/dist/local-vault/passphrase.d.ts.map +1 -0
  155. package/dist/local-vault/passphrase.js +72 -0
  156. package/dist/local-vault/passphrase.js.map +1 -0
  157. package/dist/lsp/config.d.ts +34 -0
  158. package/dist/lsp/config.d.ts.map +1 -0
  159. package/dist/lsp/config.js +68 -0
  160. package/dist/lsp/config.js.map +1 -0
  161. package/dist/lsp/detect.d.ts +7 -0
  162. package/dist/lsp/detect.d.ts.map +1 -0
  163. package/dist/lsp/detect.js +78 -0
  164. package/dist/lsp/detect.js.map +1 -0
  165. package/dist/lsp/errors.d.ts +11 -0
  166. package/dist/lsp/errors.d.ts.map +1 -0
  167. package/dist/lsp/errors.js +11 -0
  168. package/dist/lsp/errors.js.map +1 -0
  169. package/dist/lsp/formatters.d.ts +147 -0
  170. package/dist/lsp/formatters.d.ts.map +1 -0
  171. package/dist/lsp/formatters.js +259 -0
  172. package/dist/lsp/formatters.js.map +1 -0
  173. package/dist/lsp/index.d.ts +31 -0
  174. package/dist/lsp/index.d.ts.map +1 -0
  175. package/dist/lsp/index.js +31 -0
  176. package/dist/lsp/index.js.map +1 -0
  177. package/dist/lsp/instance.d.ts +72 -0
  178. package/dist/lsp/instance.d.ts.map +1 -0
  179. package/dist/lsp/instance.js +489 -0
  180. package/dist/lsp/instance.js.map +1 -0
  181. package/dist/lsp/lazy-load.d.ts +27 -0
  182. package/dist/lsp/lazy-load.d.ts.map +1 -0
  183. package/dist/lsp/lazy-load.js +57 -0
  184. package/dist/lsp/lazy-load.js.map +1 -0
  185. package/dist/lsp/manager.d.ts +59 -0
  186. package/dist/lsp/manager.d.ts.map +1 -0
  187. package/dist/lsp/manager.js +242 -0
  188. package/dist/lsp/manager.js.map +1 -0
  189. package/dist/lsp/ops.d.ts +13 -0
  190. package/dist/lsp/ops.d.ts.map +1 -0
  191. package/dist/lsp/ops.js +225 -0
  192. package/dist/lsp/ops.js.map +1 -0
  193. package/dist/lsp/rpc.d.ts +47 -0
  194. package/dist/lsp/rpc.d.ts.map +1 -0
  195. package/dist/lsp/rpc.js +134 -0
  196. package/dist/lsp/rpc.js.map +1 -0
  197. package/dist/lsp/safe-uri.d.ts +18 -0
  198. package/dist/lsp/safe-uri.d.ts.map +1 -0
  199. package/dist/lsp/safe-uri.js +96 -0
  200. package/dist/lsp/safe-uri.js.map +1 -0
  201. package/dist/lsp/types.d.ts +70 -0
  202. package/dist/lsp/types.d.ts.map +1 -0
  203. package/dist/lsp/types.js +16 -0
  204. package/dist/lsp/types.js.map +1 -0
  205. package/dist/mcp/bridge.d.ts +57 -0
  206. package/dist/mcp/bridge.d.ts.map +1 -0
  207. package/dist/mcp/bridge.js +98 -0
  208. package/dist/mcp/bridge.js.map +1 -0
  209. package/dist/mcp/category.d.ts +22 -0
  210. package/dist/mcp/category.d.ts.map +1 -0
  211. package/dist/mcp/category.js +11 -0
  212. package/dist/mcp/category.js.map +1 -0
  213. package/dist/mcp/client.d.ts +228 -0
  214. package/dist/mcp/client.d.ts.map +1 -0
  215. package/dist/mcp/client.js +352 -0
  216. package/dist/mcp/client.js.map +1 -0
  217. package/dist/mcp/content.d.ts +86 -0
  218. package/dist/mcp/content.d.ts.map +1 -0
  219. package/dist/mcp/content.js +147 -0
  220. package/dist/mcp/content.js.map +1 -0
  221. package/dist/mcp/env.d.ts +19 -0
  222. package/dist/mcp/env.d.ts.map +1 -0
  223. package/dist/mcp/env.js +50 -0
  224. package/dist/mcp/env.js.map +1 -0
  225. package/dist/mcp/host.d.ts +199 -0
  226. package/dist/mcp/host.d.ts.map +1 -0
  227. package/dist/mcp/host.js +530 -0
  228. package/dist/mcp/host.js.map +1 -0
  229. package/dist/mcp/index.d.ts +18 -0
  230. package/dist/mcp/index.d.ts.map +1 -0
  231. package/dist/mcp/index.js +17 -0
  232. package/dist/mcp/index.js.map +1 -0
  233. package/dist/mcp/load-mcp-host.d.ts +32 -0
  234. package/dist/mcp/load-mcp-host.d.ts.map +1 -0
  235. package/dist/mcp/load-mcp-host.js +49 -0
  236. package/dist/mcp/load-mcp-host.js.map +1 -0
  237. package/dist/mcp/oauth/callback-server.d.ts +73 -0
  238. package/dist/mcp/oauth/callback-server.d.ts.map +1 -0
  239. package/dist/mcp/oauth/callback-server.js +280 -0
  240. package/dist/mcp/oauth/callback-server.js.map +1 -0
  241. package/dist/mcp/oauth/config-hash.d.ts +24 -0
  242. package/dist/mcp/oauth/config-hash.d.ts.map +1 -0
  243. package/dist/mcp/oauth/config-hash.js +55 -0
  244. package/dist/mcp/oauth/config-hash.js.map +1 -0
  245. package/dist/mcp/oauth/error-normalize.d.ts +39 -0
  246. package/dist/mcp/oauth/error-normalize.d.ts.map +1 -0
  247. package/dist/mcp/oauth/error-normalize.js +91 -0
  248. package/dist/mcp/oauth/error-normalize.js.map +1 -0
  249. package/dist/mcp/oauth/provider.d.ts +190 -0
  250. package/dist/mcp/oauth/provider.d.ts.map +1 -0
  251. package/dist/mcp/oauth/provider.js +305 -0
  252. package/dist/mcp/oauth/provider.js.map +1 -0
  253. package/dist/mcp/oauth/refresh-coalescer.d.ts +46 -0
  254. package/dist/mcp/oauth/refresh-coalescer.d.ts.map +1 -0
  255. package/dist/mcp/oauth/refresh-coalescer.js +77 -0
  256. package/dist/mcp/oauth/refresh-coalescer.js.map +1 -0
  257. package/dist/mcp/oauth/sdk-shapes.d.ts +77 -0
  258. package/dist/mcp/oauth/sdk-shapes.d.ts.map +1 -0
  259. package/dist/mcp/oauth/sdk-shapes.js +21 -0
  260. package/dist/mcp/oauth/sdk-shapes.js.map +1 -0
  261. package/dist/mcp/parse.d.ts +28 -0
  262. package/dist/mcp/parse.d.ts.map +1 -0
  263. package/dist/mcp/parse.js +209 -0
  264. package/dist/mcp/parse.js.map +1 -0
  265. package/dist/mcp/prompts.d.ts +31 -0
  266. package/dist/mcp/prompts.d.ts.map +1 -0
  267. package/dist/mcp/prompts.js +71 -0
  268. package/dist/mcp/prompts.js.map +1 -0
  269. package/dist/mcp/redact.d.ts +62 -0
  270. package/dist/mcp/redact.d.ts.map +1 -0
  271. package/dist/mcp/redact.js +87 -0
  272. package/dist/mcp/redact.js.map +1 -0
  273. package/dist/mcp/resources.d.ts +70 -0
  274. package/dist/mcp/resources.d.ts.map +1 -0
  275. package/dist/mcp/resources.js +170 -0
  276. package/dist/mcp/resources.js.map +1 -0
  277. package/dist/mcp/types.d.ts +123 -0
  278. package/dist/mcp/types.d.ts.map +1 -0
  279. package/dist/mcp/types.js +2 -0
  280. package/dist/mcp/types.js.map +1 -0
  281. package/dist/memory/frontmatter.d.ts +18 -0
  282. package/dist/memory/frontmatter.d.ts.map +1 -0
  283. package/dist/memory/frontmatter.js +81 -0
  284. package/dist/memory/frontmatter.js.map +1 -0
  285. package/dist/memory/index.d.ts +5 -0
  286. package/dist/memory/index.d.ts.map +1 -0
  287. package/dist/memory/index.js +5 -0
  288. package/dist/memory/index.js.map +1 -0
  289. package/dist/memory/store.d.ts +44 -0
  290. package/dist/memory/store.d.ts.map +1 -0
  291. package/dist/memory/store.js +237 -0
  292. package/dist/memory/store.js.map +1 -0
  293. package/dist/memory/tools.d.ts +11 -0
  294. package/dist/memory/tools.d.ts.map +1 -0
  295. package/dist/memory/tools.js +159 -0
  296. package/dist/memory/tools.js.map +1 -0
  297. package/dist/memory/types.d.ts +32 -0
  298. package/dist/memory/types.d.ts.map +1 -0
  299. package/dist/memory/types.js +20 -0
  300. package/dist/memory/types.js.map +1 -0
  301. package/dist/plugin-api/index.d.ts +167 -0
  302. package/dist/plugin-api/index.d.ts.map +1 -0
  303. package/dist/plugin-api/index.js +151 -0
  304. package/dist/plugin-api/index.js.map +1 -0
  305. package/dist/plugin-logger/index.d.ts +21 -0
  306. package/dist/plugin-logger/index.d.ts.map +1 -0
  307. package/dist/plugin-logger/index.js +59 -0
  308. package/dist/plugin-logger/index.js.map +1 -0
  309. package/dist/session/index.d.ts +125 -0
  310. package/dist/session/index.d.ts.map +1 -0
  311. package/dist/session/index.js +202 -0
  312. package/dist/session/index.js.map +1 -0
  313. package/dist/tools/approval.d.ts +33 -0
  314. package/dist/tools/approval.d.ts.map +1 -0
  315. package/dist/tools/approval.js +53 -0
  316. package/dist/tools/approval.js.map +1 -0
  317. package/dist/tools/builtins/_shared.d.ts +94 -0
  318. package/dist/tools/builtins/_shared.d.ts.map +1 -0
  319. package/dist/tools/builtins/_shared.js +246 -0
  320. package/dist/tools/builtins/_shared.js.map +1 -0
  321. package/dist/tools/builtins/ask-user-question.d.ts +27 -0
  322. package/dist/tools/builtins/ask-user-question.d.ts.map +1 -0
  323. package/dist/tools/builtins/ask-user-question.js +191 -0
  324. package/dist/tools/builtins/ask-user-question.js.map +1 -0
  325. package/dist/tools/builtins/bash.d.ts +3 -0
  326. package/dist/tools/builtins/bash.d.ts.map +1 -0
  327. package/dist/tools/builtins/bash.js +158 -0
  328. package/dist/tools/builtins/bash.js.map +1 -0
  329. package/dist/tools/builtins/diff.d.ts +3 -0
  330. package/dist/tools/builtins/diff.d.ts.map +1 -0
  331. package/dist/tools/builtins/diff.js +83 -0
  332. package/dist/tools/builtins/diff.js.map +1 -0
  333. package/dist/tools/builtins/edit.d.ts +3 -0
  334. package/dist/tools/builtins/edit.d.ts.map +1 -0
  335. package/dist/tools/builtins/edit.js +40 -0
  336. package/dist/tools/builtins/edit.js.map +1 -0
  337. package/dist/tools/builtins/glob.d.ts +3 -0
  338. package/dist/tools/builtins/glob.d.ts.map +1 -0
  339. package/dist/tools/builtins/glob.js +37 -0
  340. package/dist/tools/builtins/glob.js.map +1 -0
  341. package/dist/tools/builtins/grep.d.ts +3 -0
  342. package/dist/tools/builtins/grep.d.ts.map +1 -0
  343. package/dist/tools/builtins/grep.js +81 -0
  344. package/dist/tools/builtins/grep.js.map +1 -0
  345. package/dist/tools/builtins/lsp.d.ts +3 -0
  346. package/dist/tools/builtins/lsp.d.ts.map +1 -0
  347. package/dist/tools/builtins/lsp.js +102 -0
  348. package/dist/tools/builtins/lsp.js.map +1 -0
  349. package/dist/tools/builtins/pty.d.ts +64 -0
  350. package/dist/tools/builtins/pty.d.ts.map +1 -0
  351. package/dist/tools/builtins/pty.js +536 -0
  352. package/dist/tools/builtins/pty.js.map +1 -0
  353. package/dist/tools/builtins/read.d.ts +3 -0
  354. package/dist/tools/builtins/read.d.ts.map +1 -0
  355. package/dist/tools/builtins/read.js +18 -0
  356. package/dist/tools/builtins/read.js.map +1 -0
  357. package/dist/tools/builtins/web-fetch.d.ts +4 -0
  358. package/dist/tools/builtins/web-fetch.d.ts.map +1 -0
  359. package/dist/tools/builtins/web-fetch.js +353 -0
  360. package/dist/tools/builtins/web-fetch.js.map +1 -0
  361. package/dist/tools/builtins/write.d.ts +3 -0
  362. package/dist/tools/builtins/write.d.ts.map +1 -0
  363. package/dist/tools/builtins/write.js +48 -0
  364. package/dist/tools/builtins/write.js.map +1 -0
  365. package/dist/tools/builtins.d.ts +9 -0
  366. package/dist/tools/builtins.d.ts.map +1 -0
  367. package/dist/tools/builtins.js +29 -0
  368. package/dist/tools/builtins.js.map +1 -0
  369. package/dist/tools/diff.d.ts +18 -0
  370. package/dist/tools/diff.d.ts.map +1 -0
  371. package/dist/tools/diff.js +57 -0
  372. package/dist/tools/diff.js.map +1 -0
  373. package/dist/tools/index.d.ts +10 -0
  374. package/dist/tools/index.d.ts.map +1 -0
  375. package/dist/tools/index.js +9 -0
  376. package/dist/tools/index.js.map +1 -0
  377. package/dist/tools/permission.d.ts +120 -0
  378. package/dist/tools/permission.d.ts.map +1 -0
  379. package/dist/tools/permission.js +208 -0
  380. package/dist/tools/permission.js.map +1 -0
  381. package/dist/tools/registry.d.ts +12 -0
  382. package/dist/tools/registry.d.ts.map +1 -0
  383. package/dist/tools/registry.js +19 -0
  384. package/dist/tools/registry.js.map +1 -0
  385. package/dist/tools/types.d.ts +244 -0
  386. package/dist/tools/types.d.ts.map +1 -0
  387. package/dist/tools/types.js +15 -0
  388. package/dist/tools/types.js.map +1 -0
  389. package/package.json +109 -0
@@ -0,0 +1,59 @@
1
+ import { LspServerInstance, type InstanceOptions } from "./instance.js";
2
+ import type { Logger, LspPermissionResolver, ResolvedServer } from "./types.js";
3
+ export interface LspHostOptions {
4
+ servers: readonly ResolvedServer[];
5
+ cwd: string;
6
+ logger: Logger;
7
+ maxInstances?: number;
8
+ permissionResolver?: LspPermissionResolver;
9
+ /** Test seam — replace the instance factory. */
10
+ instanceFactory?: (opts: InstanceOptions) => LspServerInstance;
11
+ /** Test seam — replace the now() clock. */
12
+ now?: () => number;
13
+ /** Test seam — disable the background sweep timer. */
14
+ disableIdleSweep?: boolean;
15
+ }
16
+ export declare class LspHost {
17
+ private readonly opts;
18
+ private readonly cache;
19
+ /** Approved `(name, command, cwd)` triples — positive decisions cached. */
20
+ private readonly approved;
21
+ /** In-flight `getOrCreate` calls keyed by cache key. Two parallel
22
+ * callers for the same key wait on the same promise so we never spawn
23
+ * duplicate processes (codex Round-2 MUST-FIX #3). */
24
+ private readonly inflight;
25
+ private sweepTimer?;
26
+ private disposed;
27
+ /** Late-bound resolver hook so `buildEngine` can wire the gate after
28
+ * host construction (codex Round-2 MUST-FIX #1). When set after some
29
+ * approvals have already been recorded, those stay; the new
30
+ * resolver only fires for unapproved tuples. */
31
+ private resolver?;
32
+ constructor(opts: LspHostOptions);
33
+ get servers(): readonly ResolvedServer[];
34
+ /** Picks the server that handles `filePath` based on its extension.
35
+ * Returns undefined when no enabled server claims the extension. */
36
+ pickServerForPath(filePath: string): ResolvedServer | undefined;
37
+ /** Late-bind a permission resolver. `buildEngine` calls this so the
38
+ * resolver can route through `PermissionGate.check` with a custom
39
+ * per-server summary. (codex Round-2 MUST-FIX #1.) */
40
+ setPermissionResolver(resolver: LspPermissionResolver | undefined): void;
41
+ /** Returns a started instance for `(server, cwd)`. Spawns when not
42
+ * cached; refuses with `LSP_MAX_INSTANCES` when the cap is reached
43
+ * AND every cached instance is active. Two parallel callers for
44
+ * the same key share an inflight promise (codex Round-2 MUST-FIX
45
+ * #3). */
46
+ getOrCreate(server: ResolvedServer, cwd: string, signal: AbortSignal): Promise<LspServerInstance>;
47
+ private createInstance;
48
+ /** Idempotent — removes the instance from the cache and disposes
49
+ * it. Skips when activeRequests > 0 (caller serialises). */
50
+ private evict;
51
+ /** Resets a server entry — disposes its instance(s) AND invalidates
52
+ * cached permission approvals so the next call re-prompts. */
53
+ restart(name: string): Promise<void>;
54
+ private idleSweep;
55
+ /** Disposes every instance + clears timers. Subsequent calls are
56
+ * no-ops. */
57
+ dispose(): Promise<void>;
58
+ }
59
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/lsp/manager.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGxE,OAAO,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMhF,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,qBAAqB,CAAC;IAC3C,gDAAgD;IAChD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,iBAAiB,CAAC;IAC/D,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwC;IAC9D,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C;;2DAEuD;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiD;IAC1E,OAAO,CAAC,UAAU,CAAC,CAAiC;IACpD,OAAO,CAAC,QAAQ,CAAS;IACzB;;;qDAGiD;IACjD,OAAO,CAAC,QAAQ,CAAC,CAAwB;gBAE7B,IAAI,EAAE,cAAc;IAahC,IAAI,OAAO,IAAI,SAAS,cAAc,EAAE,CAEvC;IAED;yEACqE;IACrE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAO/D;;2DAEuD;IACvD,qBAAqB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,GAAG,IAAI;IAIxE;;;;eAIW;IACL,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC;YA0BzF,cAAc;IA2E5B;iEAC6D;YAC/C,KAAK;IAcnB;mEAC+D;IACzD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAY5B,SAAS;IAsBvB;kBACc;IACR,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAU/B"}
@@ -0,0 +1,242 @@
1
+ /**
2
+ * (4.2) LspHost — per-host manager owning every LspServerInstance.
3
+ *
4
+ * Cache key: `${command}\0${cwd}`. Two cwds with the same command
5
+ * get two instances (so 4.1 worktree isolation works).
6
+ *
7
+ * Folded codex Round-1 findings:
8
+ * - MUST-FIX #5: idle sweep skips instances with activeRequests > 0.
9
+ * - MUST-FIX #6: `maxInstances` cap; LRU eviction of IDLE only;
10
+ * LSP_MAX_INSTANCES refusal when all active; sticky-failed /
11
+ * missing slots don't count.
12
+ * - MUST-FIX #4: `permissionResolver` consulted once per
13
+ * `(name, command, cwd)`; positive decisions cached for the
14
+ * session; `restart(name)` invalidates the cached decisions
15
+ * for that name.
16
+ */
17
+ import { LspError } from "./errors.js";
18
+ import { LspServerInstance } from "./instance.js";
19
+ import { detectBinary } from "./detect.js";
20
+ import { pickServerForExtension } from "./config.js";
21
+ const IDLE_TTL_MS = 10 * 60 * 1000;
22
+ const SWEEP_INTERVAL_MS = 60 * 1000;
23
+ const DEFAULT_MAX_INSTANCES = 8;
24
+ export class LspHost {
25
+ opts;
26
+ cache = new Map();
27
+ /** Approved `(name, command, cwd)` triples — positive decisions cached. */
28
+ approved = new Set();
29
+ /** In-flight `getOrCreate` calls keyed by cache key. Two parallel
30
+ * callers for the same key wait on the same promise so we never spawn
31
+ * duplicate processes (codex Round-2 MUST-FIX #3). */
32
+ inflight = new Map();
33
+ sweepTimer;
34
+ disposed = false;
35
+ /** Late-bound resolver hook so `buildEngine` can wire the gate after
36
+ * host construction (codex Round-2 MUST-FIX #1). When set after some
37
+ * approvals have already been recorded, those stay; the new
38
+ * resolver only fires for unapproved tuples. */
39
+ resolver;
40
+ constructor(opts) {
41
+ this.opts = opts;
42
+ this.resolver = opts.permissionResolver;
43
+ if (!opts.disableIdleSweep) {
44
+ this.sweepTimer = setInterval(() => {
45
+ // void: any throw inside the sweep would crash the host.
46
+ this.idleSweep().catch((e) => this.opts.logger.warn(`lsp idle sweep: ${e.message}`));
47
+ }, SWEEP_INTERVAL_MS);
48
+ // Don't keep the process alive just for the sweep.
49
+ this.sweepTimer?.unref?.();
50
+ }
51
+ }
52
+ get servers() {
53
+ return this.opts.servers;
54
+ }
55
+ /** Picks the server that handles `filePath` based on its extension.
56
+ * Returns undefined when no enabled server claims the extension. */
57
+ pickServerForPath(filePath) {
58
+ const idx = filePath.lastIndexOf(".");
59
+ if (idx < 0)
60
+ return undefined;
61
+ const ext = filePath.slice(idx);
62
+ return pickServerForExtension(this.opts.servers, ext);
63
+ }
64
+ /** Late-bind a permission resolver. `buildEngine` calls this so the
65
+ * resolver can route through `PermissionGate.check` with a custom
66
+ * per-server summary. (codex Round-2 MUST-FIX #1.) */
67
+ setPermissionResolver(resolver) {
68
+ this.resolver = resolver;
69
+ }
70
+ /** Returns a started instance for `(server, cwd)`. Spawns when not
71
+ * cached; refuses with `LSP_MAX_INSTANCES` when the cap is reached
72
+ * AND every cached instance is active. Two parallel callers for
73
+ * the same key share an inflight promise (codex Round-2 MUST-FIX
74
+ * #3). */
75
+ async getOrCreate(server, cwd, signal) {
76
+ if (this.disposed)
77
+ throw new LspError("DISABLED", "LSP host disposed");
78
+ const command = server.config.command;
79
+ const key = cacheKey(server.name, command, cwd);
80
+ const existing = this.cache.get(key);
81
+ if (existing) {
82
+ await existing.ensureStarted(signal);
83
+ return existing;
84
+ }
85
+ const pending = this.inflight.get(key);
86
+ if (pending) {
87
+ // Concurrent first-use — both callers join the same spawn.
88
+ return pending;
89
+ }
90
+ const created = this.createInstance(server, cwd, key, signal);
91
+ this.inflight.set(key, created);
92
+ try {
93
+ return await created;
94
+ }
95
+ finally {
96
+ // Only clear the inflight slot if this attempt is still the one
97
+ // registered — a later restart() may have replaced it.
98
+ if (this.inflight.get(key) === created)
99
+ this.inflight.delete(key);
100
+ }
101
+ }
102
+ async createInstance(server, cwd, key, signal) {
103
+ const command = server.config.command;
104
+ // Permission gate — first use of this (name, command, cwd).
105
+ const approvalKey = `${server.name}\u0000${command}\u0000${cwd}`;
106
+ if (this.resolver && !this.approved.has(approvalKey)) {
107
+ const ok = await this.resolver({
108
+ serverName: server.name,
109
+ command,
110
+ args: server.config.args ?? [],
111
+ cwd,
112
+ });
113
+ if (!ok)
114
+ throw new LspError("DISABLED", `Permission denied for LSP server ${server.name}`);
115
+ this.approved.add(approvalKey);
116
+ }
117
+ // Instance-cap check. Live instances are running OR starting OR
118
+ // error-with-retries-left. failed and disposed instances don't
119
+ // count toward the cap.
120
+ const maxInstances = clamp(this.opts.maxInstances ?? DEFAULT_MAX_INSTANCES, 1, 32);
121
+ const live = Array.from(this.cache.values()).filter((i) => i.state !== "failed" && i.state !== "stopped");
122
+ if (live.length >= maxInstances) {
123
+ // Try to LRU-evict an idle instance first.
124
+ const idle = live.filter((i) => i.isIdle()).sort((a, b) => a.lastActivityAt - b.lastActivityAt);
125
+ const victim = idle[0];
126
+ if (!victim) {
127
+ throw new LspError("MAX_INSTANCES", `${maxInstances} LSP servers active; retry when one finishes`);
128
+ }
129
+ // Evict the LRU idle one to make room.
130
+ await this.evict(victim);
131
+ }
132
+ // Resolve binary path before spawning so we surface a clean
133
+ // BINARY_MISSING rather than a hard-to-debug spawn ENOENT.
134
+ // (codex Round-2 SHOULD-FIX #5) Use the SAME environment the
135
+ // spawn will see — config.env.PATH override would otherwise be
136
+ // invisible to the detection step.
137
+ const spawnEnv = { ...process.env, ...(server.config.env ?? {}) };
138
+ const resolved = server.resolvedCommand ?? detectBinary(command, cwd, spawnEnv);
139
+ if (!resolved) {
140
+ throw new LspError("BINARY_MISSING", `${command} not on PATH (cwd=${cwd}); install it or set lsp.servers.${server.name}.enabled = false`);
141
+ }
142
+ const factory = this.opts.instanceFactory ?? ((opts) => new LspServerInstance(opts));
143
+ const instance = factory({
144
+ name: server.name,
145
+ command: resolved,
146
+ args: server.config.args ?? [],
147
+ cwd,
148
+ config: server.config,
149
+ logger: this.opts.logger,
150
+ });
151
+ this.cache.set(key, instance);
152
+ try {
153
+ await instance.ensureStarted(signal);
154
+ }
155
+ catch (e) {
156
+ // Spawn / initialize failed. The instance is now in
157
+ // 'error' or 'failed' — leave it in the cache so subsequent
158
+ // calls hit the same sticky state instead of re-spawning
159
+ // forever. The cap check above skips 'failed'.
160
+ throw e;
161
+ }
162
+ return instance;
163
+ }
164
+ /** Idempotent — removes the instance from the cache and disposes
165
+ * it. Skips when activeRequests > 0 (caller serialises). */
166
+ async evict(instance) {
167
+ // Find the cache key by identity match — the recorded
168
+ // `opts.command` may be the resolved binary path, while the
169
+ // cache key uses (name, configured-command, cwd). Identity
170
+ // match is the safest invariant.
171
+ for (const [k, v] of this.cache.entries()) {
172
+ if (v === instance) {
173
+ this.cache.delete(k);
174
+ break;
175
+ }
176
+ }
177
+ await instance.dispose();
178
+ }
179
+ /** Resets a server entry — disposes its instance(s) AND invalidates
180
+ * cached permission approvals so the next call re-prompts. */
181
+ async restart(name) {
182
+ const victims = [];
183
+ for (const instance of this.cache.values()) {
184
+ if (instance.opts.name === name)
185
+ victims.push(instance);
186
+ }
187
+ for (const v of victims)
188
+ await this.evict(v);
189
+ // Drop approvals for this name (any cwd, any args variant).
190
+ for (const k of Array.from(this.approved)) {
191
+ if (k.startsWith(`${name}\u0000`))
192
+ this.approved.delete(k);
193
+ }
194
+ }
195
+ async idleSweep() {
196
+ if (this.disposed)
197
+ return;
198
+ const now = this.opts.now ? this.opts.now() : Date.now();
199
+ const victims = [];
200
+ for (const instance of this.cache.values()) {
201
+ // codex Round-1 MUST-FIX #5: ignore instances with in-flight
202
+ // requests, regardless of how long ago lastActivityAt was.
203
+ if (instance.activeRequests > 0)
204
+ continue;
205
+ if (instance.state !== "running")
206
+ continue;
207
+ if (now - instance.lastActivityAt < IDLE_TTL_MS)
208
+ continue;
209
+ victims.push(instance);
210
+ }
211
+ for (const v of victims) {
212
+ try {
213
+ await this.evict(v);
214
+ this.opts.logger.debug(`[lsp] idle-evicted ${v.opts.name}@${v.opts.cwd}`);
215
+ }
216
+ catch (e) {
217
+ this.opts.logger.warn(`[lsp] idle evict failed: ${e.message}`);
218
+ }
219
+ }
220
+ }
221
+ /** Disposes every instance + clears timers. Subsequent calls are
222
+ * no-ops. */
223
+ async dispose() {
224
+ if (this.disposed)
225
+ return;
226
+ this.disposed = true;
227
+ if (this.sweepTimer)
228
+ clearInterval(this.sweepTimer);
229
+ const all = Array.from(this.cache.values());
230
+ this.cache.clear();
231
+ // Dispose in parallel — each has its own deadline so we're not
232
+ // worse than the slowest.
233
+ await Promise.allSettled(all.map((i) => i.dispose()));
234
+ }
235
+ }
236
+ function clamp(n, lo, hi) {
237
+ return Math.max(lo, Math.min(hi, n));
238
+ }
239
+ function cacheKey(name, command, cwd) {
240
+ return `${name}\u0000${command}\u0000${cwd}`;
241
+ }
242
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/lsp/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { LspHost } from "./manager.js";
2
+ import type { LspOp, LspOpRequest, LspOpResult } from "./types.js";
3
+ /** Executes one op against the host. Routes:
4
+ * - resolve server by extension
5
+ * - get/create instance (per-(command, cwd) cache + cap + permission)
6
+ * - ensure doc open (skipped for workspaceSymbol)
7
+ * - issue request through the instance's request() (pending map + retry)
8
+ * - format the result
9
+ */
10
+ export declare function executeOp(host: LspHost, req: LspOpRequest, workspaceRoot: string): Promise<LspOpResult>;
11
+ /** Re-exported for the host-level `execute(op, req)` shape. */
12
+ export declare const LSP_OPS: readonly LspOp[];
13
+ //# sourceMappingURL=ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/lsp/ops.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAoBnE;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAiL7G;AAiDD,+DAA+D;AAC/D,eAAO,MAAM,OAAO,EAAE,SAAS,KAAK,EAUnC,CAAC"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * (4.2) Op dispatcher. The LspHost gets one `execute(req)` method
3
+ * per op, delegating to the appropriate LSP method and formatter.
4
+ * All ops route through the single per-instance `request()` so the
5
+ * pending-map / cancellation / retry contract is uniform.
6
+ *
7
+ * The dispatch table is data-driven so adding an op = one row.
8
+ */
9
+ import { readFileSync, statSync } from "node:fs";
10
+ import { pathToFileURL } from "node:url";
11
+ import { AppError, ErrorCode } from "@chances-ai/runtime";
12
+ import { LspError } from "./errors.js";
13
+ import { formatCallHierarchyItems, formatHover, formatIncomingCalls, formatLocations, formatOutgoingCalls, formatSingleLocation, formatSymbols, normalizeLocations, } from "./formatters.js";
14
+ const FILE_SIZE_CAP_BYTES = 10 * 1024 * 1024;
15
+ /** Executes one op against the host. Routes:
16
+ * - resolve server by extension
17
+ * - get/create instance (per-(command, cwd) cache + cap + permission)
18
+ * - ensure doc open (skipped for workspaceSymbol)
19
+ * - issue request through the instance's request() (pending map + retry)
20
+ * - format the result
21
+ */
22
+ export async function executeOp(host, req, workspaceRoot) {
23
+ const requireFile = req.op !== "workspaceSymbol";
24
+ if (requireFile && !req.filePath) {
25
+ return { ok: false, output: `lsp ${req.op} requires filePath` };
26
+ }
27
+ if (!requireFile && (!req.query || req.query.trim() === "")) {
28
+ return { ok: false, output: "workspaceSymbol requires a non-empty query" };
29
+ }
30
+ let server;
31
+ if (req.filePath) {
32
+ server = host.pickServerForPath(req.filePath);
33
+ if (!server) {
34
+ return { ok: false, output: `No LSP server registered for ${extOf(req.filePath)}` };
35
+ }
36
+ try {
37
+ const st = statSync(req.filePath);
38
+ if (st.size > FILE_SIZE_CAP_BYTES) {
39
+ const mb = (st.size / 1024 / 1024).toFixed(1);
40
+ return { ok: false, output: `LSP file too large for analysis (${mb} MB exceeds 10 MB limit)` };
41
+ }
42
+ }
43
+ catch (e) {
44
+ const err = e;
45
+ if (err.code === "ENOENT")
46
+ return { ok: false, output: `lsp: no such file ${req.filePath}` };
47
+ // Other stat errors propagate.
48
+ }
49
+ }
50
+ else {
51
+ // workspaceSymbol: pick any enabled server. We pick the first that
52
+ // resolves a binary so a misconfigured one doesn't block the call.
53
+ server = host.servers.find((s) => s.config.enabled !== false);
54
+ if (!server)
55
+ return { ok: false, output: "No enabled LSP server available for workspaceSymbol" };
56
+ }
57
+ let instance;
58
+ try {
59
+ instance = await host.getOrCreate(server, req.cwd, req.signal);
60
+ }
61
+ catch (e) {
62
+ return classifyError(e, req.op);
63
+ }
64
+ // Open the doc when the op needs file-level context.
65
+ if (req.filePath && req.op !== "workspaceSymbol") {
66
+ try {
67
+ await instance.ensureDocOpen(req.filePath, req.signal);
68
+ }
69
+ catch (e) {
70
+ return classifyError(e, req.op);
71
+ }
72
+ }
73
+ try {
74
+ switch (req.op) {
75
+ case "goToDefinition": {
76
+ // (codex Round-2 MUST-FIX #4) `linkSupport: true` means the server
77
+ // may return `LocationLink[]` — normalise before formatting.
78
+ const result = await instance.request("textDocument/definition", definitionParams(req), req.signal);
79
+ const list = normalizeLocations(result);
80
+ const single = list.length === 1 ? list[0] : undefined;
81
+ if (single) {
82
+ return { ok: true, output: formatSingleLocation(single, workspaceRoot, "Defined", safeRead) };
83
+ }
84
+ return { ok: true, output: formatLocations(list, workspaceRoot, "Definitions") };
85
+ }
86
+ case "findReferences": {
87
+ const result = await instance.request("textDocument/references", { ...definitionParams(req), context: { includeDeclaration: true } }, req.signal);
88
+ return { ok: true, output: formatLocations(result ?? [], workspaceRoot, "References") };
89
+ }
90
+ case "goToImplementation": {
91
+ // (codex Round-2 MUST-FIX #4) Same LocationLink handling as goToDefinition.
92
+ const result = await instance.request("textDocument/implementation", definitionParams(req), req.signal);
93
+ const list = normalizeLocations(result);
94
+ return { ok: true, output: formatLocations(list, workspaceRoot, "Implementations") };
95
+ }
96
+ case "hover": {
97
+ const result = await instance.request("textDocument/hover", definitionParams(req), req.signal);
98
+ return { ok: true, output: formatHover(result?.contents) };
99
+ }
100
+ case "documentSymbol": {
101
+ const fileUri = pathToFileURL(req.filePath).toString();
102
+ const result = await instance.request("textDocument/documentSymbol", { textDocument: { uri: fileUri } }, req.signal);
103
+ // (codex Round-2 SHOULD-FIX #4) `DocumentSymbol` nodes carry
104
+ // `range` but no `uri`; attach the request file URI to every
105
+ // node so the formatter can render `file:line:char` instead of
106
+ // "(no location)".
107
+ return { ok: true, output: formatSymbols(attachUriToSymbols(result ?? [], fileUri), workspaceRoot, "Document symbols") };
108
+ }
109
+ case "workspaceSymbol": {
110
+ // (codex Round-2 SHOULD-FIX #3) The previous "pick first enabled"
111
+ // could route the call to a server with a missing binary, surfacing
112
+ // BINARY_MISSING. Iterate enabled servers and try each until one
113
+ // starts; return failure only when all candidates fail.
114
+ const candidates = host.servers.filter((s) => s.config.enabled !== false);
115
+ const failures = [];
116
+ for (const candidate of candidates) {
117
+ try {
118
+ const instance2 = await host.getOrCreate(candidate, req.cwd, req.signal);
119
+ const result = await instance2.request("workspace/symbol", { query: req.query }, req.signal);
120
+ return { ok: true, output: formatSymbols(result ?? [], workspaceRoot, `Workspace symbols (via ${candidate.name})`) };
121
+ }
122
+ catch (e) {
123
+ if (e instanceof AppError && e.code === ErrorCode.Cancelled)
124
+ throw e;
125
+ if (e instanceof LspError && e.code === "DISABLED")
126
+ throw e; // user denied — surface immediately
127
+ const msg = e instanceof Error ? e.message : String(e);
128
+ failures.push(`${candidate.name}: ${msg}`);
129
+ }
130
+ }
131
+ return {
132
+ ok: false,
133
+ output: failures.length === 0
134
+ ? "No enabled LSP server available for workspaceSymbol"
135
+ : `workspaceSymbol failed on every enabled server: ${failures.join("; ")}`,
136
+ };
137
+ }
138
+ case "prepareCallHierarchy": {
139
+ const items = await instance.request("textDocument/prepareCallHierarchy", definitionParams(req), req.signal);
140
+ return { ok: true, output: formatCallHierarchyItems(items ?? [], workspaceRoot) };
141
+ }
142
+ case "incomingCalls": {
143
+ const items = await instance.request("textDocument/prepareCallHierarchy", definitionParams(req), req.signal);
144
+ if (!items || items.length === 0)
145
+ return { ok: true, output: "No call hierarchy items at this position" };
146
+ const incoming = await instance.request("callHierarchy/incomingCalls", { item: items[0] }, req.signal);
147
+ return { ok: true, output: formatIncomingCalls(incoming ?? [], workspaceRoot) };
148
+ }
149
+ case "outgoingCalls": {
150
+ const items = await instance.request("textDocument/prepareCallHierarchy", definitionParams(req), req.signal);
151
+ if (!items || items.length === 0)
152
+ return { ok: true, output: "No call hierarchy items at this position" };
153
+ const outgoing = await instance.request("callHierarchy/outgoingCalls", { item: items[0] }, req.signal);
154
+ return { ok: true, output: formatOutgoingCalls(outgoing ?? [], workspaceRoot) };
155
+ }
156
+ default:
157
+ return { ok: false, output: `Unknown lsp op: ${req.op}` };
158
+ }
159
+ }
160
+ catch (e) {
161
+ return classifyError(e, req.op);
162
+ }
163
+ }
164
+ function definitionParams(req) {
165
+ if (!req.filePath || req.line === undefined || req.character === undefined) {
166
+ throw new LspError("REQUEST_FAILED", `${req.op}: filePath/line/character required`);
167
+ }
168
+ return {
169
+ textDocument: { uri: pathToFileURL(req.filePath).toString() },
170
+ position: { line: req.line - 1, character: req.character - 1 },
171
+ };
172
+ }
173
+ function toArray(x) {
174
+ if (x === null || x === undefined)
175
+ return [];
176
+ return Array.isArray(x) ? x : [x];
177
+ }
178
+ /** (codex Round-2 SHOULD-FIX #4) Attach the document's file URI to every
179
+ * node + child in a `DocumentSymbol` tree so the formatter can render
180
+ * `file:line:char` instead of "(no location)". The tree is rewritten
181
+ * immutably to keep the input from the server untouched. */
182
+ function attachUriToSymbols(symbols, uri) {
183
+ return symbols.map((s) => attachUriToSymbol(s, uri));
184
+ }
185
+ function attachUriToSymbol(sym, uri) {
186
+ const location = sym.location ?? (sym.range ? { uri, range: sym.range } : undefined);
187
+ return {
188
+ ...sym,
189
+ ...(location ? { location } : {}),
190
+ children: sym.children ? attachUriToSymbols(sym.children, uri) : undefined,
191
+ };
192
+ }
193
+ function extOf(p) {
194
+ const idx = p.lastIndexOf(".");
195
+ return idx < 0 ? "(no extension)" : p.slice(idx);
196
+ }
197
+ function safeRead(abs) {
198
+ try {
199
+ return readFileSync(abs, "utf8");
200
+ }
201
+ catch {
202
+ return undefined;
203
+ }
204
+ }
205
+ function classifyError(e, op) {
206
+ if (e instanceof AppError && e.code === ErrorCode.Cancelled)
207
+ throw e; // propagate to engine
208
+ if (e instanceof LspError)
209
+ return { ok: false, output: `LSP ${e.code}: ${e.message}` };
210
+ const msg = e instanceof Error ? e.message : String(e);
211
+ return { ok: false, output: `LSP ${op} failed: ${msg}` };
212
+ }
213
+ /** Re-exported for the host-level `execute(op, req)` shape. */
214
+ export const LSP_OPS = [
215
+ "goToDefinition",
216
+ "findReferences",
217
+ "hover",
218
+ "documentSymbol",
219
+ "workspaceSymbol",
220
+ "goToImplementation",
221
+ "prepareCallHierarchy",
222
+ "incomingCalls",
223
+ "outgoingCalls",
224
+ ];
225
+ //# sourceMappingURL=ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops.js","sourceRoot":"","sources":["../../src/lsp/ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /** Minimum cancellation surface — matches vscode-jsonrpc's
2
+ * `CancellationToken` shape. Anything that exposes `.cancel()` works. */
3
+ export interface CancellationTokenSource {
4
+ readonly token: unknown;
5
+ cancel(): void;
6
+ dispose(): void;
7
+ }
8
+ /** Minimum surface the RPC layer needs from `vscode-jsonrpc`. The
9
+ * `sendRequest` overload takes an optional cancellation token; the
10
+ * real `MessageConnection` honours it and emits `$/cancelRequest`
11
+ * with the correct wire-level id. Test fakes ignore the token and
12
+ * use the registry's `rejectLast` / `rejectAll` for control. */
13
+ export interface Connection {
14
+ sendRequest<R = unknown>(method: string, params: unknown, token?: unknown): Promise<R>;
15
+ sendNotification(method: string, params: unknown): void;
16
+ onNotification(method: string, handler: (params: unknown) => void): void;
17
+ dispose(): void;
18
+ listen?(): void;
19
+ }
20
+ /** Tracks in-flight requests for an LSP instance. One per
21
+ * LspServerInstance. */
22
+ export declare class PendingRegistry {
23
+ private readonly entries;
24
+ private nextId;
25
+ /** Optional factory for cancellation token sources. Set by
26
+ * `LspServerInstance` when it knows vscode-jsonrpc is loaded; null
27
+ * in tests so the FakeConnection path stays simple. */
28
+ private ctsFactory?;
29
+ setCancellationFactory(factory: (() => CancellationTokenSource) | undefined): void;
30
+ get activeRequests(): number;
31
+ /** Issues a request through the underlying connection, registering
32
+ * ownership BEFORE the wire write so cancellation is always safe.
33
+ * Cancellation propagates through the optional CancellationToken so
34
+ * vscode-jsonrpc emits `$/cancelRequest` with the correct id. */
35
+ send<R>(opts: {
36
+ connection: Connection;
37
+ method: string;
38
+ params: unknown;
39
+ signal: AbortSignal;
40
+ requestTimeoutMs: number;
41
+ }): Promise<R>;
42
+ /** Rejects every pending request with `cause`. Used on connection
43
+ * close so a subsequent restart can never resurrect a stale id.
44
+ * (codex Round-1 MUST-FIX #5.) */
45
+ rejectAll(cause: Error): void;
46
+ }
47
+ //# sourceMappingURL=rpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../src/lsp/rpc.ts"],"names":[],"mappings":"AAsBA;0EAC0E;AAC1E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;iEAIiE;AACjE,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvF,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IACzE,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,CAAC,IAAI,IAAI,CAAC;CACjB;AAeD;yBACyB;AACzB,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,MAAM,CAAK;IACnB;;4DAEwD;IACxD,OAAO,CAAC,UAAU,CAAC,CAAgC;IAEnD,sBAAsB,CAAC,OAAO,EAAE,CAAC,MAAM,uBAAuB,CAAC,GAAG,SAAS,GAAG,IAAI;IAIlF,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED;;;sEAGkE;IAC5D,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE;QAClB,UAAU,EAAE,UAAU,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,WAAW,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,CAAC,CAAC;IAoEd;;uCAEmC;IACnC,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAc9B"}