@ashx-j/lunr 0.2.25 → 0.2.27

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 (729) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/LICENSE +22 -0
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -1
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +1 -1
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.d.ts +11 -1
  8. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  9. package/dist/builtin-extensions/ashxj-tui.js +6 -10
  10. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  11. package/dist/builtin-extensions/index.d.ts.map +1 -1
  12. package/dist/builtin-extensions/index.js +1 -0
  13. package/dist/builtin-extensions/index.js.map +1 -1
  14. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  15. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  16. package/dist/builtin-extensions/lunr-computer-use.js +179 -0
  17. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  18. package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
  19. package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
  20. package/dist/builtin-extensions/lunr-cron.js +94 -108
  21. package/dist/builtin-extensions/lunr-cron.js.map +1 -1
  22. package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
  23. package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
  24. package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
  25. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
  26. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
  27. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
  28. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  29. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
  30. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  31. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
  32. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
  33. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
  34. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-intercom/index.js +2 -2
  36. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  37. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
  38. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
  40. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
  41. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  42. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
  43. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  44. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
  45. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
  46. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
  47. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
  48. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
  49. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
  51. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
  52. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
  53. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
  54. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
  55. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
  56. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
  57. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
  58. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
  59. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
  60. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
  61. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
  63. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
  64. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
  65. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
  67. package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
  68. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
  69. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
  70. package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
  71. package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
  72. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
  73. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
  74. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
  75. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
  76. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
  77. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
  78. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
  80. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  81. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
  83. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  84. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
  85. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
  87. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
  88. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
  89. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
  91. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
  92. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
  93. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
  94. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
  95. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
  96. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
  98. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
  99. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  100. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
  101. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  102. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
  103. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
  104. package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
  105. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
  106. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
  107. package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
  108. package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
  109. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
  110. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
  111. package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
  112. package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
  113. package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
  114. package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
  115. package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
  116. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
  117. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  118. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
  119. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  120. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  121. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
  122. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  123. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  124. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
  125. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  126. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  127. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
  128. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  129. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
  130. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  131. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +8 -5
  132. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
  134. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +15 -31
  136. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  137. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
  139. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  140. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +1 -0
  141. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  142. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +21 -4
  143. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  144. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  145. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +11 -4
  146. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  147. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  148. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +121 -25
  149. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  150. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  151. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +25 -5
  152. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  153. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts +1 -0
  154. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts.map +1 -1
  155. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js +5 -0
  156. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js.map +1 -1
  157. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  158. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  159. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  160. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  161. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
  162. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  163. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
  164. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  165. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
  166. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  167. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
  168. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  169. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
  170. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
  171. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
  172. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
  173. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  174. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
  175. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  176. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
  177. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +1 -1
  178. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
  179. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
  180. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  181. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +22 -11
  182. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  183. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  184. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
  185. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  186. package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
  187. package/dist/builtin-extensions/pi-tps.js +20 -17
  188. package/dist/builtin-extensions/pi-tps.js.map +1 -1
  189. package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
  190. package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
  191. package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
  192. package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
  193. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
  194. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
  195. package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
  196. package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
  197. package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
  198. package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
  199. package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
  200. package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
  201. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  202. package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
  203. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  204. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
  205. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  206. package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
  207. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  208. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  209. package/dist/builtin-extensions/pi-web-access/index.js +48 -73
  210. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  211. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
  212. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
  213. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
  214. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
  215. package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
  216. package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
  217. package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
  218. package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
  219. package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
  220. package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
  221. package/dist/builtin-extensions/simple-pi-memory.js +1 -1
  222. package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
  223. package/dist/cli/install-cli.d.ts.map +1 -1
  224. package/dist/cli/install-cli.js +38 -30
  225. package/dist/cli/install-cli.js.map +1 -1
  226. package/dist/core/agent-session-runtime.d.ts +13 -0
  227. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  228. package/dist/core/agent-session-runtime.js +75 -11
  229. package/dist/core/agent-session-runtime.js.map +1 -1
  230. package/dist/core/agent-session-services.d.ts +1 -0
  231. package/dist/core/agent-session-services.d.ts.map +1 -1
  232. package/dist/core/agent-session-services.js +1 -0
  233. package/dist/core/agent-session-services.js.map +1 -1
  234. package/dist/core/agent-session.d.ts +40 -6
  235. package/dist/core/agent-session.d.ts.map +1 -1
  236. package/dist/core/agent-session.js +309 -76
  237. package/dist/core/agent-session.js.map +1 -1
  238. package/dist/core/browser/runtime.d.ts +2 -0
  239. package/dist/core/browser/runtime.d.ts.map +1 -1
  240. package/dist/core/browser/runtime.js +80 -45
  241. package/dist/core/browser/runtime.js.map +1 -1
  242. package/dist/core/browser/setup.d.ts.map +1 -1
  243. package/dist/core/browser/setup.js +12 -1
  244. package/dist/core/browser/setup.js.map +1 -1
  245. package/dist/core/computer-use/adapter.d.ts +28 -0
  246. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  247. package/dist/core/computer-use/adapter.js +138 -0
  248. package/dist/core/computer-use/adapter.js.map +1 -0
  249. package/dist/core/computer-use/image.d.ts +27 -0
  250. package/dist/core/computer-use/image.d.ts.map +1 -0
  251. package/dist/core/computer-use/image.js +84 -0
  252. package/dist/core/computer-use/image.js.map +1 -0
  253. package/dist/core/computer-use/lease.d.ts +18 -0
  254. package/dist/core/computer-use/lease.d.ts.map +1 -0
  255. package/dist/core/computer-use/lease.js +129 -0
  256. package/dist/core/computer-use/lease.js.map +1 -0
  257. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  258. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  259. package/dist/core/computer-use/macos-runtime.js +148 -0
  260. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  261. package/dist/core/computer-use/policy.d.ts +19 -0
  262. package/dist/core/computer-use/policy.d.ts.map +1 -0
  263. package/dist/core/computer-use/policy.js +67 -0
  264. package/dist/core/computer-use/policy.js.map +1 -0
  265. package/dist/core/computer-use/release.generated.d.ts +31 -0
  266. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  267. package/dist/core/computer-use/release.generated.js +36 -0
  268. package/dist/core/computer-use/release.generated.js.map +1 -0
  269. package/dist/core/computer-use/runtime.d.ts +13 -0
  270. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  271. package/dist/core/computer-use/runtime.js +158 -0
  272. package/dist/core/computer-use/runtime.js.map +1 -0
  273. package/dist/core/computer-use/schemas.d.ts +100 -0
  274. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  275. package/dist/core/computer-use/schemas.js +96 -0
  276. package/dist/core/computer-use/schemas.js.map +1 -0
  277. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  278. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  279. package/dist/core/computer-use/windows-desktop.js +48 -0
  280. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  281. package/dist/core/computer-use/workflow.d.ts +38 -0
  282. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  283. package/dist/core/computer-use/workflow.js +900 -0
  284. package/dist/core/computer-use/workflow.js.map +1 -0
  285. package/dist/core/cron/jobs.d.ts +26 -8
  286. package/dist/core/cron/jobs.d.ts.map +1 -1
  287. package/dist/core/cron/jobs.js +357 -232
  288. package/dist/core/cron/jobs.js.map +1 -1
  289. package/dist/core/cron/origin-context.d.ts +1 -0
  290. package/dist/core/cron/origin-context.d.ts.map +1 -1
  291. package/dist/core/cron/origin-context.js.map +1 -1
  292. package/dist/core/cron/scheduler.d.ts +22 -17
  293. package/dist/core/cron/scheduler.d.ts.map +1 -1
  294. package/dist/core/cron/scheduler.js +153 -73
  295. package/dist/core/cron/scheduler.js.map +1 -1
  296. package/dist/core/extensions/index.d.ts +1 -1
  297. package/dist/core/extensions/index.d.ts.map +1 -1
  298. package/dist/core/extensions/index.js.map +1 -1
  299. package/dist/core/extensions/loader.d.ts.map +1 -1
  300. package/dist/core/extensions/loader.js +4 -0
  301. package/dist/core/extensions/loader.js.map +1 -1
  302. package/dist/core/extensions/runner.d.ts +1 -0
  303. package/dist/core/extensions/runner.d.ts.map +1 -1
  304. package/dist/core/extensions/runner.js +8 -0
  305. package/dist/core/extensions/runner.js.map +1 -1
  306. package/dist/core/extensions/types.d.ts +8 -0
  307. package/dist/core/extensions/types.d.ts.map +1 -1
  308. package/dist/core/extensions/types.js.map +1 -1
  309. package/dist/core/footer-data-provider.d.ts +4 -0
  310. package/dist/core/footer-data-provider.d.ts.map +1 -1
  311. package/dist/core/footer-data-provider.js +22 -1
  312. package/dist/core/footer-data-provider.js.map +1 -1
  313. package/dist/core/large-subagent-launch.d.ts +1 -1
  314. package/dist/core/large-subagent-launch.d.ts.map +1 -1
  315. package/dist/core/large-subagent-launch.js +7 -7
  316. package/dist/core/large-subagent-launch.js.map +1 -1
  317. package/dist/core/model-registry.d.ts +2 -0
  318. package/dist/core/model-registry.d.ts.map +1 -1
  319. package/dist/core/model-registry.js +5 -0
  320. package/dist/core/model-registry.js.map +1 -1
  321. package/dist/core/model-runtime.d.ts +4 -1
  322. package/dist/core/model-runtime.d.ts.map +1 -1
  323. package/dist/core/model-runtime.js +40 -4
  324. package/dist/core/model-runtime.js.map +1 -1
  325. package/dist/core/package-manager.d.ts.map +1 -1
  326. package/dist/core/package-manager.js.map +1 -1
  327. package/dist/core/permissions.d.ts +4 -4
  328. package/dist/core/permissions.d.ts.map +1 -1
  329. package/dist/core/permissions.js +25 -38
  330. package/dist/core/permissions.js.map +1 -1
  331. package/dist/core/plan-mode.d.ts +5 -13
  332. package/dist/core/plan-mode.d.ts.map +1 -1
  333. package/dist/core/plan-mode.js +135 -116
  334. package/dist/core/plan-mode.js.map +1 -1
  335. package/dist/core/project-trust.d.ts.map +1 -1
  336. package/dist/core/project-trust.js +1 -1
  337. package/dist/core/project-trust.js.map +1 -1
  338. package/dist/core/prompt-resource-bridge.d.ts +12 -0
  339. package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
  340. package/dist/core/prompt-resource-bridge.js +9 -0
  341. package/dist/core/prompt-resource-bridge.js.map +1 -0
  342. package/dist/core/protected-targets.d.ts +6 -0
  343. package/dist/core/protected-targets.d.ts.map +1 -0
  344. package/dist/core/protected-targets.js +45 -0
  345. package/dist/core/protected-targets.js.map +1 -0
  346. package/dist/core/resource-loader.d.ts.map +1 -1
  347. package/dist/core/resource-loader.js +7 -0
  348. package/dist/core/resource-loader.js.map +1 -1
  349. package/dist/core/rollback.d.ts +19 -3
  350. package/dist/core/rollback.d.ts.map +1 -1
  351. package/dist/core/rollback.js +172 -56
  352. package/dist/core/rollback.js.map +1 -1
  353. package/dist/core/runtime-credentials.d.ts +3 -0
  354. package/dist/core/runtime-credentials.d.ts.map +1 -1
  355. package/dist/core/runtime-credentials.js +14 -1
  356. package/dist/core/runtime-credentials.js.map +1 -1
  357. package/dist/core/sdk.d.ts +3 -0
  358. package/dist/core/sdk.d.ts.map +1 -1
  359. package/dist/core/sdk.js +1 -0
  360. package/dist/core/sdk.js.map +1 -1
  361. package/dist/core/session-manager.d.ts +6 -0
  362. package/dist/core/session-manager.d.ts.map +1 -1
  363. package/dist/core/session-manager.js +95 -32
  364. package/dist/core/session-manager.js.map +1 -1
  365. package/dist/core/session-ownership.d.ts.map +1 -1
  366. package/dist/core/session-ownership.js +8 -3
  367. package/dist/core/session-ownership.js.map +1 -1
  368. package/dist/core/session-retention.d.ts.map +1 -1
  369. package/dist/core/session-retention.js +18 -7
  370. package/dist/core/session-retention.js.map +1 -1
  371. package/dist/core/session-startup-settings.d.ts +10 -0
  372. package/dist/core/session-startup-settings.d.ts.map +1 -0
  373. package/dist/core/session-startup-settings.js +70 -0
  374. package/dist/core/session-startup-settings.js.map +1 -0
  375. package/dist/core/settings-manager.d.ts +6 -0
  376. package/dist/core/settings-manager.d.ts.map +1 -1
  377. package/dist/core/settings-manager.js +19 -0
  378. package/dist/core/settings-manager.js.map +1 -1
  379. package/dist/core/subagent-event-transport.d.ts +3 -0
  380. package/dist/core/subagent-event-transport.d.ts.map +1 -0
  381. package/dist/core/subagent-event-transport.js +61 -0
  382. package/dist/core/subagent-event-transport.js.map +1 -0
  383. package/dist/core/subscriptions.d.ts +16 -7
  384. package/dist/core/subscriptions.d.ts.map +1 -1
  385. package/dist/core/subscriptions.js +96 -55
  386. package/dist/core/subscriptions.js.map +1 -1
  387. package/dist/core/trust-manager.d.ts +2 -1
  388. package/dist/core/trust-manager.d.ts.map +1 -1
  389. package/dist/core/trust-manager.js +6 -1
  390. package/dist/core/trust-manager.js.map +1 -1
  391. package/dist/core/update-check.d.ts.map +1 -1
  392. package/dist/core/update-check.js.map +1 -1
  393. package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
  394. package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
  395. package/dist/core/usage-adapters/kimi-coding.js +2 -2
  396. package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
  397. package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
  398. package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
  399. package/dist/core/usage-adapters/openai-codex.js +3 -3
  400. package/dist/core/usage-adapters/openai-codex.js.map +1 -1
  401. package/dist/core/usage-adapters/xai.d.ts +2 -2
  402. package/dist/core/usage-adapters/xai.d.ts.map +1 -1
  403. package/dist/core/usage-adapters/xai.js +3 -3
  404. package/dist/core/usage-adapters/xai.js.map +1 -1
  405. package/dist/core/usage-adapters/zai.d.ts +2 -2
  406. package/dist/core/usage-adapters/zai.d.ts.map +1 -1
  407. package/dist/core/usage-adapters/zai.js +2 -2
  408. package/dist/core/usage-adapters/zai.js.map +1 -1
  409. package/dist/core/usage-service.d.ts +9 -2
  410. package/dist/core/usage-service.d.ts.map +1 -1
  411. package/dist/core/usage-service.js +95 -50
  412. package/dist/core/usage-service.js.map +1 -1
  413. package/dist/gateway/adapters/discord.d.ts.map +1 -1
  414. package/dist/gateway/adapters/discord.js +2 -2
  415. package/dist/gateway/adapters/discord.js.map +1 -1
  416. package/dist/gateway/agent-bridge.d.ts +9 -1
  417. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  418. package/dist/gateway/agent-bridge.js +91 -37
  419. package/dist/gateway/agent-bridge.js.map +1 -1
  420. package/dist/gateway/approval.d.ts.map +1 -1
  421. package/dist/gateway/approval.js +3 -3
  422. package/dist/gateway/approval.js.map +1 -1
  423. package/dist/gateway/authz.d.ts +4 -4
  424. package/dist/gateway/authz.d.ts.map +1 -1
  425. package/dist/gateway/authz.js +8 -12
  426. package/dist/gateway/authz.js.map +1 -1
  427. package/dist/gateway/buttons.d.ts +8 -1
  428. package/dist/gateway/buttons.d.ts.map +1 -1
  429. package/dist/gateway/buttons.js +76 -18
  430. package/dist/gateway/buttons.js.map +1 -1
  431. package/dist/gateway/commands.d.ts +1 -0
  432. package/dist/gateway/commands.d.ts.map +1 -1
  433. package/dist/gateway/commands.js +12 -10
  434. package/dist/gateway/commands.js.map +1 -1
  435. package/dist/gateway/cron.d.ts +12 -11
  436. package/dist/gateway/cron.d.ts.map +1 -1
  437. package/dist/gateway/cron.js +85 -62
  438. package/dist/gateway/cron.js.map +1 -1
  439. package/dist/gateway/index.d.ts.map +1 -1
  440. package/dist/gateway/index.js +5 -4
  441. package/dist/gateway/index.js.map +1 -1
  442. package/dist/gateway/mobile-commands.d.ts +1 -0
  443. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  444. package/dist/gateway/mobile-commands.js +64 -22
  445. package/dist/gateway/mobile-commands.js.map +1 -1
  446. package/dist/gateway/presenter.d.ts +12 -2
  447. package/dist/gateway/presenter.d.ts.map +1 -1
  448. package/dist/gateway/presenter.js +74 -39
  449. package/dist/gateway/presenter.js.map +1 -1
  450. package/dist/gateway/router.d.ts +2 -2
  451. package/dist/gateway/router.d.ts.map +1 -1
  452. package/dist/gateway/router.js +22 -9
  453. package/dist/gateway/router.js.map +1 -1
  454. package/dist/gateway/service.d.ts +2 -0
  455. package/dist/gateway/service.d.ts.map +1 -1
  456. package/dist/gateway/service.js +153 -0
  457. package/dist/gateway/service.js.map +1 -1
  458. package/dist/gateway/setup.d.ts.map +1 -1
  459. package/dist/gateway/setup.js +6 -4
  460. package/dist/gateway/setup.js.map +1 -1
  461. package/dist/main.d.ts.map +1 -1
  462. package/dist/main.js +86 -33
  463. package/dist/main.js.map +1 -1
  464. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  465. package/dist/modes/interactive/components/assistant-message.js +6 -4
  466. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  467. package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
  468. package/dist/modes/interactive/components/copyable-text.js +3 -2
  469. package/dist/modes/interactive/components/copyable-text.js.map +1 -1
  470. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  471. package/dist/modes/interactive/components/extension-editor.js +1 -1
  472. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  473. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  474. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  475. package/dist/modes/interactive/components/settings-selector.js +20 -0
  476. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  477. package/dist/modes/interactive/interactive-mode.d.ts +2 -2
  478. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  479. package/dist/modes/interactive/interactive-mode.js +104 -109
  480. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  481. package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
  482. package/dist/modes/interactive/smooth-streaming.js.map +1 -1
  483. package/dist/modes/print-mode.d.ts.map +1 -1
  484. package/dist/modes/print-mode.js +9 -1
  485. package/dist/modes/print-mode.js.map +1 -1
  486. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  487. package/dist/modes/rpc/rpc-mode.js +2 -1
  488. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  489. package/dist/node-runtime/adapter-247RTYLS.js +16 -0
  490. package/dist/node-runtime/agent-session-services-KDMSPQDY.js +53 -0
  491. package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
  492. package/dist/node-runtime/{builtin-extensions-ZLAX7TUH.js → builtin-extensions-OX6KELNX.js} +9 -7
  493. package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
  494. package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
  495. package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
  496. package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
  497. package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
  498. package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
  499. package/dist/node-runtime/{chunk-NRKGMJYU.js → chunk-6O3IW3IA.js} +2 -2
  500. package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
  501. package/dist/node-runtime/chunk-A2WO6WIN.js +1197 -0
  502. package/dist/node-runtime/{chunk-ZXSGTGJ6.js → chunk-APVM5NEU.js} +169 -148
  503. package/dist/node-runtime/{chunk-RC7DMV45.js → chunk-AYHH7YSD.js} +205 -144
  504. package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
  505. package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
  506. package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
  507. package/dist/node-runtime/{chunk-KWIYUUZK.js → chunk-C3P6Q3B2.js} +469 -283
  508. package/dist/node-runtime/{chunk-YCUZEGJG.js → chunk-DQSCFU7R.js} +17 -8
  509. package/dist/node-runtime/chunk-EBLAZVSA.js +4170 -0
  510. package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-EPR2F3GU.js} +68 -20
  511. package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
  512. package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
  513. package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
  514. package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
  515. package/dist/node-runtime/chunk-FE3WZI7F.js +290 -0
  516. package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-FIRA54AC.js} +2 -5
  517. package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
  518. package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
  519. package/dist/node-runtime/chunk-FY4A63RK.js +73 -0
  520. package/dist/node-runtime/chunk-FYIFPFXE.js +98 -0
  521. package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
  522. package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
  523. package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
  524. package/dist/node-runtime/{chunk-6XL67VVY.js → chunk-HUD2RFJW.js} +17 -2
  525. package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
  526. package/dist/node-runtime/chunk-IAZSK7KK.js +108 -0
  527. package/dist/node-runtime/{chunk-2HHLJWGD.js → chunk-IHHTWSXN.js} +9 -9
  528. package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
  529. package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
  530. package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
  531. package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-JQYNHAKX.js} +1 -1
  532. package/dist/node-runtime/{chunk-WF7PGWRZ.js → chunk-JWEVT363.js} +37 -28
  533. package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
  534. package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
  535. package/dist/node-runtime/{chunk-IJIFHRTB.js → chunk-MQPKUHRN.js} +165 -85
  536. package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
  537. package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
  538. package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
  539. package/dist/node-runtime/{chunk-E4D3IGP2.js → chunk-QNVMKNNN.js} +20 -17
  540. package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
  541. package/dist/node-runtime/{chunk-7S3T6YEA.js → chunk-R4WSB2MQ.js} +5 -5
  542. package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
  543. package/dist/node-runtime/{chunk-3XPLBUEM.js → chunk-RLGY2QIL.js} +49 -59
  544. package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
  545. package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-TCT6PCUR.js} +47 -115
  546. package/dist/node-runtime/chunk-U5F4IC7R.js +53 -0
  547. package/dist/node-runtime/{chunk-OCVIXVTZ.js → chunk-UBWW2PID.js} +13 -2
  548. package/dist/node-runtime/{chunk-HFVZUPFJ.js → chunk-UNUZICC4.js} +3 -3
  549. package/dist/node-runtime/{chunk-LQP3RB67.js → chunk-UYRKUKFE.js} +1 -1
  550. package/dist/node-runtime/{chunk-DSIKTUPW.js → chunk-VSUEAI7O.js} +2993 -3820
  551. package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
  552. package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
  553. package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
  554. package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
  555. package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
  556. package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
  557. package/dist/node-runtime/{chunk-VQFSUJJG.js → chunk-ZDJUR45D.js} +430 -129
  558. package/dist/node-runtime/{chunk-YDO2F2IA.js → chunk-ZEVFBFNF.js} +95 -142
  559. package/dist/node-runtime/chunk-ZIQUS5QO.js +180 -0
  560. package/dist/node-runtime/cli-runtime.js +4 -4
  561. package/dist/node-runtime/{command-6WDOYKS6.js → command-3HMSY6W2.js} +5 -5
  562. package/dist/node-runtime/{commands-NZLSOHPE.js → commands-D6A6H4TS.js} +11 -16
  563. package/dist/node-runtime/commands-OCSSEEWJ.js +37 -0
  564. package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
  565. package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
  566. package/dist/node-runtime/{direct-tool-executor-77GW4F5P.js → direct-tool-executor-2QJXVQD2.js} +8 -10
  567. package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
  568. package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-BRWF5AHI.js} +4 -4
  569. package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
  570. package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
  571. package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
  572. package/dist/node-runtime/{gateway-INAYBF4Q.js → gateway-6623C2U3.js} +61 -53
  573. package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
  574. package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
  575. package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
  576. package/dist/node-runtime/{goal-NJEE5CTU.js → goal-AIHEDUYA.js} +5 -5
  577. package/dist/node-runtime/index.js +54 -48
  578. package/dist/node-runtime/{init-HS6NQXSK.js → init-JBQJIPYI.js} +3 -4
  579. package/dist/node-runtime/{install-cli-KL4UDDAD.js → install-cli-INGHIVBY.js} +30 -25
  580. package/dist/node-runtime/interactive-mode-FM5DNUSW.js +74 -0
  581. package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
  582. package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
  583. package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
  584. package/dist/node-runtime/lunr-computer-use-VDP2QNRQ.js +158 -0
  585. package/dist/node-runtime/{lunr-cron-LWIZJM2N.js → lunr-cron-LKVA5CZZ.js} +94 -79
  586. package/dist/node-runtime/main.js +42 -39
  587. package/dist/node-runtime/{mobile-commands-J7OJEKFO.js → mobile-commands-XT3NQXLD.js} +13 -12
  588. package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
  589. package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
  590. package/dist/node-runtime/{package-manager-cli-VYZM5WHN.js → package-manager-cli-CYM262SI.js} +20 -19
  591. package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
  592. package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
  593. package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
  594. package/dist/node-runtime/{pi-mcp-adapter-5UKBZP44.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
  595. package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
  596. package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
  597. package/dist/node-runtime/{pi-subagents-DNY7EAIG.js → pi-subagents-LT3CTO4E.js} +114 -116
  598. package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
  599. package/dist/node-runtime/{print-mode-XSFM26EL.js → print-mode-2XHN5SUA.js} +4 -3
  600. package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
  601. package/dist/node-runtime/{proxy-modes-LGEUYD7R.js → proxy-modes-VEGC6QG5.js} +9 -13
  602. package/dist/node-runtime/rpc-entry.js +42 -39
  603. package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
  604. package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
  605. package/dist/node-runtime/runtime-UGXM4NPQ.js +21 -0
  606. package/dist/node-runtime/{runtime-bridges-VRDDR73P.js → runtime-bridges-DNKMNJCF.js} +8 -7
  607. package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
  608. package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LNSPDTKY.js} +4 -4
  609. package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-YIFIAVGC.js} +3 -3
  610. package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
  611. package/dist/node-runtime/{settings-manager-J4SPQPDJ.js → settings-manager-P2TKGYTR.js} +6 -5
  612. package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
  613. package/dist/node-runtime/{setup-CQ2NLVK5.js → setup-OLQ4GXWS.js} +22 -21
  614. package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
  615. package/dist/node-runtime/{subagent-executor-KZZQGAKV.js → subagent-executor-Q5F7DBVM.js} +141 -62
  616. package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
  617. package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
  618. package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
  619. package/dist/node-runtime/{update-cli-GTFJC7XK.js → update-cli-F3XXJANQ.js} +7 -6
  620. package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
  621. package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
  622. package/dist/node-runtime/workflow-ICDI4N3J.js +767 -0
  623. package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
  624. package/dist/utils/clipboard-image.d.ts.map +1 -1
  625. package/dist/utils/clipboard-image.js.map +1 -1
  626. package/dist/utils/exif-orientation.d.ts.map +1 -1
  627. package/dist/utils/exif-orientation.js +25 -10
  628. package/dist/utils/exif-orientation.js.map +1 -1
  629. package/dist/utils/image-resize-core.d.ts +2 -0
  630. package/dist/utils/image-resize-core.d.ts.map +1 -1
  631. package/dist/utils/image-resize-core.js +12 -0
  632. package/dist/utils/image-resize-core.js.map +1 -1
  633. package/dist/utils/paths.d.ts +4 -0
  634. package/dist/utils/paths.d.ts.map +1 -1
  635. package/dist/utils/paths.js +33 -2
  636. package/dist/utils/paths.js.map +1 -1
  637. package/dist/utils/sanitize-terminal-text.d.ts +7 -0
  638. package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
  639. package/dist/utils/sanitize-terminal-text.js +67 -0
  640. package/dist/utils/sanitize-terminal-text.js.map +1 -0
  641. package/docs/browser.md +1 -1
  642. package/docs/computer-use.md +362 -0
  643. package/docs/custom-provider.md +3 -3
  644. package/docs/extensions.md +8 -4
  645. package/docs/features.md +22 -12
  646. package/docs/keybindings.md +1 -1
  647. package/docs/models.md +5 -5
  648. package/docs/packages.md +1 -1
  649. package/docs/providers.md +2 -2
  650. package/docs/rpc.md +7 -7
  651. package/docs/security.md +10 -5
  652. package/docs/sessions.md +2 -2
  653. package/docs/skills.md +1 -1
  654. package/docs/terminal-setup.md +7 -7
  655. package/docs/themes.md +1 -1
  656. package/docs/usage.md +1 -1
  657. package/examples/extensions/auto-commit-on-exit.ts +1 -1
  658. package/examples/extensions/bash-spawn-hook.ts +1 -1
  659. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  660. package/examples/extensions/claude-rules.ts +1 -1
  661. package/examples/extensions/commands.ts +1 -1
  662. package/examples/extensions/custom-compaction.ts +1 -1
  663. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  664. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  665. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  666. package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
  667. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  668. package/examples/extensions/doom-overlay/index.ts +1 -1
  669. package/examples/extensions/git-merge-and-resolve.ts +2 -2
  670. package/examples/extensions/gondolin/index.ts +1 -1
  671. package/examples/extensions/gondolin/package-lock.json +2 -2
  672. package/examples/extensions/gondolin/package.json +1 -1
  673. package/examples/extensions/hidden-thinking-label.ts +1 -1
  674. package/examples/extensions/inline-bash.ts +2 -2
  675. package/examples/extensions/input-transform-streaming.ts +2 -2
  676. package/examples/extensions/input-transform.ts +2 -2
  677. package/examples/extensions/interactive-shell.ts +1 -1
  678. package/examples/extensions/kimi-deferred-tools.ts +1 -1
  679. package/examples/extensions/mac-system-theme.ts +1 -1
  680. package/examples/extensions/minimal-mode.ts +1 -1
  681. package/examples/extensions/modal-editor.ts +1 -1
  682. package/examples/extensions/model-status.ts +1 -1
  683. package/examples/extensions/notify.ts +3 -3
  684. package/examples/extensions/overlay-qa-tests.ts +1 -1
  685. package/examples/extensions/overlay-test.ts +1 -1
  686. package/examples/extensions/pirate.ts +1 -1
  687. package/examples/extensions/preset.ts +3 -3
  688. package/examples/extensions/project-trust.ts +4 -4
  689. package/examples/extensions/prompt-customizer.ts +1 -1
  690. package/examples/extensions/rainbow-editor.ts +1 -1
  691. package/examples/extensions/rpc-demo.ts +1 -1
  692. package/examples/extensions/sandbox/index.ts +7 -7
  693. package/examples/extensions/sandbox/package-lock.json +2 -2
  694. package/examples/extensions/sandbox/package.json +1 -1
  695. package/examples/extensions/shutdown-command.ts +5 -5
  696. package/examples/extensions/ssh.ts +2 -2
  697. package/examples/extensions/subagent/README.md +3 -3
  698. package/examples/extensions/subagent/index.ts +2 -2
  699. package/examples/extensions/titlebar-spinner.ts +1 -1
  700. package/examples/extensions/tool-override.ts +1 -1
  701. package/examples/extensions/tools.ts +1 -1
  702. package/examples/extensions/with-deps/package-lock.json +2 -2
  703. package/examples/extensions/with-deps/package.json +1 -1
  704. package/examples/extensions/working-indicator.ts +1 -1
  705. package/examples/extensions/working-message-test.ts +1 -1
  706. package/examples/sdk/01-minimal.ts +1 -1
  707. package/examples/sdk/03-custom-prompt.ts +1 -1
  708. package/examples/sdk/04-skills.ts +1 -1
  709. package/examples/sdk/06-extensions.ts +2 -2
  710. package/examples/sdk/08-prompt-templates.ts +1 -1
  711. package/install-lock/package-lock.json +3841 -0
  712. package/install-lock/package.json +18 -0
  713. package/native/computer-use/LICENSE.md +21 -0
  714. package/npm-shrinkwrap.json +3858 -0
  715. package/package.json +15 -9
  716. package/dist/modes/interactive/components/exit-card.d.ts +0 -22
  717. package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
  718. package/dist/modes/interactive/components/exit-card.js +0 -69
  719. package/dist/modes/interactive/components/exit-card.js.map +0 -1
  720. package/dist/node-runtime/agent-session-services-YXXFCP5J.js +0 -49
  721. package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
  722. package/dist/node-runtime/chunk-4TLO4PO2.js +0 -3427
  723. package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
  724. package/dist/node-runtime/chunk-OVX6X377.js +0 -50
  725. package/dist/node-runtime/chunk-QTU6AKNJ.js +0 -773
  726. package/dist/node-runtime/chunk-TORR5XBV.js +0 -356
  727. package/dist/node-runtime/commands-QC6VUZJQ.js +0 -36
  728. package/dist/node-runtime/interactive-mode-Z5M7WYYZ.js +0 -72
  729. package/dist/node-runtime/mcp-auth-flow-QIXHW6QN.js +0 -32
@@ -1 +1 @@
1
- {"version":3,"file":"lsp-client.d.ts","sourceRoot":"","sources":["../../../../src/builtin-extensions/pi-lsp-extension/src/lsp-client.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * LSP Client — JSON-RPC client for LSP servers.\n *\n * Supports two modes:\n * - **Direct**: spawns LSP server as child process (stdio)\n * - **Socket**: connects to an LSP daemon via Unix domain socket\n *\n * Uses vscode-jsonrpc (bundled with vscode-languageserver-protocol) for\n * JSON-RPC message framing and transport.\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { connect as netConnect, type Socket } from \"node:net\";\nimport { pathToFileURL } from \"node:url\";\nimport {\n createMessageConnection,\n StreamMessageReader,\n StreamMessageWriter,\n SocketMessageReader,\n SocketMessageWriter,\n type MessageConnection,\n} from \"vscode-languageserver-protocol/node\";\nimport type {\n InitializeParams,\n InitializeResult,\n ServerCapabilities,\n Diagnostic,\n PublishDiagnosticsParams,\n} from \"vscode-languageserver-protocol\";\n\nexport interface LspClientOptions {\n /** Command to start the LSP server */\n command: string;\n /** Arguments for the command */\n args: string[];\n /** Root directory of the workspace */\n rootDir: string;\n /** Language ID this server handles */\n languageId: string;\n /** Extra environment variables */\n env?: Record<string, string>;\n /** Additional workspace folders (e.g. for multi-package workspaces) */\n workspaceFolders?: { uri: string; name: string }[];\n /** Connect to existing daemon socket instead of spawning a new process */\n socketPath?: string;\n /** LSP initializationOptions (e.g. jdtls settings for Lombok) */\n initializationOptions?: Record<string, unknown>;\n /** Settings returned by workspace/configuration handler (keyed by section, e.g. { intelephense: {...} }) */\n settings?: Record<string, unknown>;\n /** Called when the server exits unexpectedly (not from user-initiated shutdown) */\n onUnexpectedExit?: (code: number | null) => void;\n}\n\nexport class LspClient {\n private process: ChildProcess | null = null;\n private socket: Socket | null = null;\n private connection: MessageConnection | null = null;\n private _serverCapabilities: ServerCapabilities | null = null;\n private _diagnostics: Map<string, Diagnostic[]> = new Map();\n private _initialized = false;\n private _disposed = false;\n /** True if connected to a daemon socket (server init handled by daemon) */\n private _isDaemonClient = false;\n\n readonly languageId: string;\n readonly command: string;\n readonly rootDir: string;\n\n constructor(private options: LspClientOptions) {\n this.languageId = options.languageId;\n this.command = options.command;\n this.rootDir = options.rootDir;\n }\n\n get initialized(): boolean {\n return this._initialized;\n }\n\n get disposed(): boolean {\n return this._disposed;\n }\n\n get serverCapabilities(): ServerCapabilities | null {\n return this._serverCapabilities;\n }\n\n /** Get cached diagnostics for a URI */\n getDiagnostics(uri: string): Diagnostic[] {\n return this._diagnostics.get(uri) ?? [];\n }\n\n /** Get all cached diagnostics */\n getAllDiagnostics(): Map<string, Diagnostic[]> {\n return new Map(this._diagnostics);\n }\n\n /** Start the LSP server and perform the initialize handshake */\n async start(): Promise<void> {\n if (this._initialized || this._disposed) return;\n\n if (this.options.socketPath) {\n await this.connectToSocket(this.options.socketPath);\n } else {\n await this.spawnDirect();\n }\n }\n\n /** Register shared connection handlers (diagnostics, workspace/configuration, errors) */\n private registerConnectionHandlers(): void {\n if (!this.connection) return;\n\n // Listen for published diagnostics\n this.connection.onNotification(\n \"textDocument/publishDiagnostics\",\n (params: PublishDiagnosticsParams) => {\n this._diagnostics.set(params.uri, params.diagnostics);\n }\n );\n\n // Handle workspace/configuration requests from the server.\n // Servers like Intelephense request their settings via this method.\n // Return settings from options if configured, otherwise empty defaults.\n this.connection.onRequest(\n \"workspace/configuration\",\n (params: { items: { section?: string }[] }) => {\n const settings = this.options.settings;\n return params.items.map((item) => {\n if (item.section && settings && item.section in settings) {\n return settings[item.section];\n }\n return {};\n });\n }\n );\n\n // Handle connection-level errors to prevent unhandled exceptions\n this.connection.onError(([err]) => {\n console.error(`[LSP ${this.languageId}] Connection error: ${err.message}`);\n });\n\n this.connection.onClose(() => {\n if (!this._disposed) {\n this._initialized = false;\n }\n });\n }\n\n /** Connect to an existing LSP daemon via Unix socket (no init handshake needed) */\n private async connectToSocket(socketPath: string): Promise<void> {\n this._isDaemonClient = true;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n const settle = (fn: () => void) => {\n if (!settled) { settled = true; fn(); }\n };\n\n const socket = netConnect(socketPath, () => {\n this.socket = socket;\n\n const reader = new SocketMessageReader(socket);\n const writer = new SocketMessageWriter(socket);\n this.connection = createMessageConnection(reader, writer);\n\n this.registerConnectionHandlers();\n\n this.connection.listen();\n this._initialized = true;\n settle(() => resolve());\n });\n\n socket.on(\"error\", (err) => {\n if (!this._initialized) {\n settle(() => reject(new Error(`Failed to connect to LSP daemon: ${err.message}`)));\n } else {\n this._initialized = false;\n }\n });\n\n socket.on(\"close\", () => {\n if (!this._disposed) {\n this._initialized = false;\n this.options.onUnexpectedExit?.(null);\n }\n });\n\n // Timeout\n setTimeout(() => {\n if (!settled) {\n socket.destroy();\n settle(() => reject(new Error(\"Timeout connecting to LSP daemon socket\")));\n }\n }, 10_000);\n });\n }\n\n /** Spawn LSP server directly as child process with stdio */\n private async spawnDirect(): Promise<void> {\n const env = { ...process.env, ...this.options.env };\n\n this.process = spawn(this.options.command, this.options.args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n cwd: this.rootDir,\n });\n\n if (!this.process.stdout || !this.process.stdin) {\n throw new Error(`Failed to spawn LSP server: ${this.options.command}`);\n }\n\n // Wait for the process to successfully spawn before setting up the connection.\n // spawn() is async — ENOENT and other errors arrive on the 'error' event.\n // If we don't wait, we'll try to write to a destroyed stdin and crash.\n await new Promise<void>((resolve, reject) => {\n const onSpawn = () => { cleanup(); resolve(); };\n const onError = (err: Error) => {\n cleanup();\n reject(new Error(`Failed to spawn LSP server \"${this.options.command}\": ${err.message}`));\n };\n const cleanup = () => {\n this.process?.removeListener(\"spawn\", onSpawn);\n this.process?.removeListener(\"error\", onError);\n };\n this.process!.on(\"spawn\", onSpawn);\n this.process!.on(\"error\", onError);\n });\n\n // Discard stderr to prevent blocking\n this.process.stderr?.resume();\n\n // Patch stdin.write to silently drop writes when the stream is destroyed.\n // StreamMessageWriter wraps stdin and calls write() which returns a Promise.\n // If the stream is destroyed (process exited), write() throws ERR_STREAM_DESTROYED\n // inside the Promise constructor, creating a rejection that propagates through\n // the writer's semaphore and becomes unhandled (notifications are fire-and-forget).\n // No amount of error handlers on the stream or connection can catch this.\n const stdin = this.process.stdin!;\n const originalWrite = stdin.write;\n stdin.write = function (this: typeof stdin, ...args: any[]): boolean {\n if (this.destroyed || this.writableEnded || this.writableFinished) {\n // Call the callback (last arg) so the Promise resolves instead of rejecting\n const cb = args[args.length - 1];\n if (typeof cb === \"function\") process.nextTick(cb);\n return false;\n }\n try {\n return originalWrite.apply(this, args as any);\n } catch (err: any) {\n // Catch EPIPE synchronously — process exited between our check and the write\n if (err?.code === \"EPIPE\" || err?.code === \"ERR_STREAM_DESTROYED\") {\n const cb = args[args.length - 1];\n if (typeof cb === \"function\") process.nextTick(cb);\n return false;\n }\n throw err;\n }\n } as any;\n\n // Catch EPIPE on the stdin stream itself to prevent unhandled error events\n stdin.on(\"error\", (err: any) => {\n if (err?.code === \"EPIPE\") return; // expected when server exits\n console.error(`[LSP ${this.languageId}] stdin error: ${err.message}`);\n });\n\n this.process.on(\"error\", (err) => {\n console.error(`[LSP ${this.languageId}] Process error: ${err.message}`);\n this._initialized = false;\n this.disposeConnection();\n });\n\n this.process.on(\"exit\", (code) => {\n if (!this._disposed) {\n console.error(`[LSP ${this.languageId}] Server exited with code ${code}`);\n this._initialized = false;\n this.disposeConnection();\n this.options.onUnexpectedExit?.(code);\n }\n });\n\n const reader = new StreamMessageReader(this.process.stdout);\n const writer = new StreamMessageWriter(this.process.stdin);\n this.connection = createMessageConnection(reader, writer);\n\n this.registerConnectionHandlers();\n\n this.connection.listen();\n\n // Initialize handshake\n const rootUri = pathToFileURL(this.rootDir).toString();\n const defaultFolder = { uri: rootUri, name: this.rootDir.split(\"/\").pop() ?? \"workspace\" };\n\n // Use provided workspace folders or fall back to single root\n const workspaceFolders = this.options.workspaceFolders && this.options.workspaceFolders.length > 0\n ? this.options.workspaceFolders\n : [defaultFolder];\n\n const initParams: InitializeParams = {\n processId: process.pid,\n capabilities: {\n textDocument: {\n synchronization: {\n didSave: true,\n dynamicRegistration: false,\n },\n hover: {\n contentFormat: [\"plaintext\", \"markdown\"],\n },\n definition: {},\n references: {},\n documentSymbol: {\n hierarchicalDocumentSymbolSupport: true,\n },\n rename: {\n prepareSupport: false,\n },\n publishDiagnostics: {\n relatedInformation: true,\n },\n completion: {\n completionItem: {\n snippetSupport: false,\n },\n },\n },\n workspace: {\n workspaceFolders: true,\n symbol: {},\n configuration: true,\n },\n },\n rootUri,\n workspaceFolders,\n ...(this.options.initializationOptions\n ? { initializationOptions: this.options.initializationOptions }\n : {}),\n };\n\n const result: InitializeResult = await this.connection.sendRequest(\n \"initialize\",\n initParams\n );\n this._serverCapabilities = result.capabilities;\n\n // Send initialized notification\n this.connection.sendNotification(\"initialized\", {});\n this._initialized = true;\n }\n\n /** Safely dispose the connection without throwing */\n private disposeConnection(): void {\n try {\n if (this.connection) {\n this.connection.dispose();\n }\n } catch {\n // Already disposed or stream destroyed — ignore\n }\n this.connection = null;\n }\n\n /** Send a request to the LSP server */\n async sendRequest<R>(method: string, params: unknown): Promise<R> {\n if (!this.connection || !this._initialized) {\n throw new Error(`LSP ${this.languageId} not initialized`);\n }\n return this.connection.sendRequest(method, params) as Promise<R>;\n }\n\n /** Send a notification to the LSP server */\n sendNotification(method: string, params: unknown): void {\n if (!this.connection || !this._initialized) return;\n this.connection.sendNotification(method, params);\n }\n\n /** Notify server of a newly opened document */\n didOpen(uri: string, languageId: string, version: number, text: string): void {\n this.sendNotification(\"textDocument/didOpen\", {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /** Notify server of a document change (full content sync) */\n didChange(uri: string, version: number, text: string): void {\n this.sendNotification(\"textDocument/didChange\", {\n textDocument: { uri, version },\n contentChanges: [{ text }],\n });\n }\n\n /** Notify server of a closed document */\n didClose(uri: string): void {\n this.sendNotification(\"textDocument/didClose\", {\n textDocument: { uri },\n });\n }\n\n /** Gracefully shut down or disconnect from the server */\n async shutdown(): Promise<void> {\n if (this._disposed) return;\n this._disposed = true;\n this._initialized = false;\n\n if (this._isDaemonClient) {\n // Socket client: just disconnect — daemon keeps the server alive\n this.disposeConnection();\n if (this.socket) {\n this.socket.destroy();\n }\n this.socket = null;\n return;\n }\n\n // Direct mode: shut down the server we own\n try {\n if (this.connection) {\n // Race shutdown request against a timeout. Catch the request separately\n // so if the timeout wins, the abandoned sendRequest rejection doesn't\n // become an unhandled promise rejection.\n const shutdownReq = this.connection.sendRequest(\"shutdown\").catch(() => {});\n await Promise.race([\n shutdownReq,\n new Promise((resolve) => setTimeout(resolve, 3000)),\n ]);\n try { this.connection.sendNotification(\"exit\"); } catch {}\n }\n } catch {\n // Server may already be dead\n }\n this.disposeConnection();\n\n if (this.process) {\n this.process.kill(\"SIGTERM\");\n // Force kill after 2s\n setTimeout(() => {\n if (this.process && !this.process.killed) {\n this.process.kill(\"SIGKILL\");\n }\n }, 2000);\n }\n\n this.process = null;\n }\n}\n"]}
1
+ {"version":3,"file":"lsp-client.d.ts","sourceRoot":"","sources":["../../../../src/builtin-extensions/pi-lsp-extension/src/lsp-client.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * LSP Client — JSON-RPC client for LSP servers.\n *\n * Supports two modes:\n * - **Direct**: spawns LSP server as child process (stdio)\n * - **Socket**: connects to an LSP daemon via Unix domain socket\n *\n * Uses vscode-jsonrpc (bundled with vscode-languageserver-protocol) for\n * JSON-RPC message framing and transport.\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { connect as netConnect, type Socket } from \"node:net\";\nimport { pathToFileURL } from \"node:url\";\nimport {\n createMessageConnection,\n StreamMessageReader,\n StreamMessageWriter,\n SocketMessageReader,\n SocketMessageWriter,\n type MessageConnection,\n} from \"vscode-languageserver-protocol/node\";\nimport type {\n InitializeParams,\n InitializeResult,\n ServerCapabilities,\n Diagnostic,\n PublishDiagnosticsParams,\n} from \"vscode-languageserver-protocol\";\n\nexport interface LspClientOptions {\n /** Command to start the LSP server */\n command: string;\n /** Arguments for the command */\n args: string[];\n /** Root directory of the workspace */\n rootDir: string;\n /** Language ID this server handles */\n languageId: string;\n /** Extra environment variables */\n env?: Record<string, string>;\n /** Additional workspace folders (e.g. for multi-package workspaces) */\n workspaceFolders?: { uri: string; name: string }[];\n /** Connect to existing daemon socket instead of spawning a new process */\n socketPath?: string;\n /** LSP initializationOptions (e.g. jdtls settings for Lombok) */\n initializationOptions?: Record<string, unknown>;\n /** Settings returned by workspace/configuration handler (keyed by section, e.g. { intelephense: {...} }) */\n settings?: Record<string, unknown>;\n /** Called when the server exits unexpectedly (not from user-initiated shutdown) */\n onUnexpectedExit?: (code: number | null) => void;\n}\n\nexport class LspClient {\n private process: ChildProcess | null = null;\n private socket: Socket | null = null;\n private connection: MessageConnection | null = null;\n private _serverCapabilities: ServerCapabilities | null = null;\n private _diagnostics: Map<string, Diagnostic[]> = new Map();\n private _initialized = false;\n private _disposed = false;\n /** True if connected to a daemon socket (server init handled by daemon) */\n private _isDaemonClient = false;\n\n private readonly stop = new AbortController();\n private startPromise: Promise<void> | null = null;\n private shutdownPromise: Promise<void> | null = null;\n\n readonly languageId: string;\n readonly command: string;\n readonly rootDir: string;\n\n constructor(private options: LspClientOptions) {\n this.languageId = options.languageId;\n this.command = options.command;\n this.rootDir = options.rootDir;\n }\n\n get initialized(): boolean {\n return this._initialized;\n }\n\n get disposed(): boolean {\n return this._disposed;\n }\n\n get serverCapabilities(): ServerCapabilities | null {\n return this._serverCapabilities;\n }\n\n /** Get cached diagnostics for a URI */\n getDiagnostics(uri: string): Diagnostic[] {\n return this._diagnostics.get(uri) ?? [];\n }\n\n /** Get all cached diagnostics */\n getAllDiagnostics(): Map<string, Diagnostic[]> {\n return new Map(this._diagnostics);\n }\n\n /** Start the LSP server and perform the initialize handshake */\n start(): Promise<void> {\n if (this._disposed) return Promise.reject(new Error(\"LSP client shut down\"));\n if (this.startPromise) return this.startPromise;\n this.startPromise = (this.options.socketPath\n ? this.connectToSocket(this.options.socketPath)\n : this.spawnDirect()).catch(async (error: unknown) => {\n await this.shutdown();\n throw error;\n });\n return this.startPromise;\n }\n\n /** Cancel an owned handshake without waiting for the remote server. */\n private waitForStart<T>(pending: Promise<T>): Promise<T> {\n const signal = this.stop.signal;\n signal.throwIfAborted();\n return new Promise<T>((resolve, reject) => {\n const aborted = () => reject(signal.reason);\n signal.addEventListener(\"abort\", aborted, { once: true });\n pending.then(resolve, reject).finally(() => signal.removeEventListener(\"abort\", aborted));\n });\n }\n\n /** Register shared connection handlers (diagnostics, workspace/configuration, errors) */\n private registerConnectionHandlers(): void {\n if (!this.connection) return;\n\n // Listen for published diagnostics\n this.connection.onNotification(\n \"textDocument/publishDiagnostics\",\n (params: PublishDiagnosticsParams) => {\n this._diagnostics.set(params.uri, params.diagnostics);\n }\n );\n\n // Handle workspace/configuration requests from the server.\n // Servers like Intelephense request their settings via this method.\n // Return settings from options if configured, otherwise empty defaults.\n this.connection.onRequest(\n \"workspace/configuration\",\n (params: { items: { section?: string }[] }) => {\n const settings = this.options.settings;\n return params.items.map((item) => {\n if (item.section && settings && item.section in settings) {\n return settings[item.section];\n }\n return {};\n });\n }\n );\n\n // Handle connection-level errors to prevent unhandled exceptions\n this.connection.onError(([err]) => {\n console.error(`[LSP ${this.languageId}] Connection error: ${err.message}`);\n });\n\n this.connection.onClose(() => {\n if (!this._disposed) {\n this._initialized = false;\n }\n });\n }\n\n /** Connect to an existing LSP daemon via Unix socket (no init handshake needed) */\n private async connectToSocket(socketPath: string): Promise<void> {\n this._isDaemonClient = true;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n let connected = false;\n let timeout: ReturnType<typeof setTimeout>;\n const settle = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n this.stop.signal.removeEventListener(\"abort\", aborted);\n if (error) reject(error);\n else resolve();\n };\n const aborted = () => {\n settle(new Error(\"LSP client shut down\"));\n socket.destroy();\n };\n const socket = netConnect(socketPath, () => {\n if (this._disposed || settled) { socket.destroy(); return; }\n try {\n const reader = new SocketMessageReader(socket);\n const writer = new SocketMessageWriter(socket);\n this.connection = createMessageConnection(reader, writer);\n this.registerConnectionHandlers();\n this.connection.listen();\n this._initialized = true;\n connected = true;\n settle();\n } catch (error) {\n settle(error instanceof Error ? error : new Error(String(error)));\n socket.destroy();\n }\n });\n // Capture even a connecting socket so shutdown can close it.\n this.socket = socket;\n socket.on(\"error\", (err) => {\n settle(new Error(`Failed to connect to LSP daemon: ${err.message}`));\n this._initialized = false;\n });\n socket.on(\"close\", () => {\n settle(new Error(\"LSP daemon socket closed during startup\"));\n if (!this._disposed) {\n this._initialized = false;\n if (connected) this.options.onUnexpectedExit?.(null);\n }\n });\n timeout = setTimeout(() => {\n settle(new Error(\"Timeout connecting to LSP daemon socket\"));\n socket.destroy();\n }, 10_000);\n this.stop.signal.addEventListener(\"abort\", aborted, { once: true });\n if (this.stop.signal.aborted) aborted();\n });\n }\n\n /** Spawn LSP server directly as child process with stdio */\n private async spawnDirect(): Promise<void> {\n const env = { ...process.env, ...this.options.env };\n\n this.process = spawn(this.options.command, this.options.args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n cwd: this.rootDir,\n });\n\n const child = this.process;\n // Error listeners belong to this child and its streams, never the host process.\n for (const stream of [child.stdin, child.stdout, child.stderr]) {\n stream?.on(\"error\", (err: Error) => {\n if (!this._disposed) console.error(`[LSP ${this.languageId}] Transport error: ${err.message}`);\n });\n }\n child.on(\"error\", (err) => {\n if (!this._disposed) console.error(`[LSP ${this.languageId}] Process error: ${err.message}`);\n this._initialized = false;\n this.disposeConnection();\n });\n let wasInitialized = false;\n child.on(\"exit\", (code) => {\n if (!this._disposed) {\n this._initialized = false;\n this.disposeConnection();\n // A failed handshake is handled by the pending start, not auto-restart.\n if (wasInitialized) this.options.onUnexpectedExit?.(code);\n }\n });\n if (!child.stdout || !child.stdin) {\n throw new Error(`Failed to spawn LSP server: ${this.options.command}`);\n }\n\n await this.waitForStart(new Promise<void>((resolve, reject) => {\n const onSpawn = () => { cleanup(); resolve(); };\n const onError = (err: Error) => {\n cleanup();\n reject(new Error(`Failed to spawn LSP server \"${this.options.command}\": ${err.message}`));\n };\n const cleanup = () => {\n child.removeListener(\"spawn\", onSpawn);\n child.removeListener(\"error\", onError);\n this.stop.signal.removeEventListener(\"abort\", cleanup);\n };\n child.once(\"spawn\", onSpawn);\n child.once(\"error\", onError);\n this.stop.signal.addEventListener(\"abort\", cleanup, { once: true });\n }));\n this.stop.signal.throwIfAborted();\n child.stderr?.resume();\n\n const reader = new StreamMessageReader(child.stdout);\n const writer = new StreamMessageWriter(child.stdin);\n this.connection = createMessageConnection(reader, writer);\n\n this.registerConnectionHandlers();\n\n this.connection.listen();\n\n // Initialize handshake\n const rootUri = pathToFileURL(this.rootDir).toString();\n const defaultFolder = { uri: rootUri, name: this.rootDir.split(\"/\").pop() ?? \"workspace\" };\n\n // Use provided workspace folders or fall back to single root\n const workspaceFolders = this.options.workspaceFolders && this.options.workspaceFolders.length > 0\n ? this.options.workspaceFolders\n : [defaultFolder];\n\n const initParams: InitializeParams = {\n processId: process.pid,\n capabilities: {\n textDocument: {\n synchronization: {\n didSave: true,\n dynamicRegistration: false,\n },\n hover: {\n contentFormat: [\"plaintext\", \"markdown\"],\n },\n definition: {},\n references: {},\n documentSymbol: {\n hierarchicalDocumentSymbolSupport: true,\n },\n rename: {\n prepareSupport: false,\n },\n publishDiagnostics: {\n relatedInformation: true,\n },\n completion: {\n completionItem: {\n snippetSupport: false,\n },\n },\n },\n workspace: {\n workspaceFolders: true,\n symbol: {},\n configuration: true,\n },\n },\n rootUri,\n workspaceFolders,\n ...(this.options.initializationOptions\n ? { initializationOptions: this.options.initializationOptions }\n : {}),\n };\n\n const result: InitializeResult = await this.waitForStart(this.connection.sendRequest(\n \"initialize\",\n initParams\n ));\n this.stop.signal.throwIfAborted();\n this._serverCapabilities = result.capabilities;\n\n // Send initialized notification\n await this.waitForStart(this.connection.sendNotification(\"initialized\", {}));\n this.stop.signal.throwIfAborted();\n this._initialized = true;\n wasInitialized = true;\n }\n\n /** Safely dispose the connection without throwing */\n private disposeConnection(): void {\n try {\n if (this.connection) {\n this.connection.dispose();\n }\n } catch {\n // Already disposed or stream destroyed — ignore\n }\n this.connection = null;\n }\n\n /** Send a request to the LSP server */\n async sendRequest<R>(method: string, params: unknown): Promise<R> {\n if (!this.connection || !this._initialized) {\n throw new Error(`LSP ${this.languageId} not initialized`);\n }\n return this.connection.sendRequest(method, params) as Promise<R>;\n }\n\n /** Send a notification to the LSP server */\n sendNotification(method: string, params: unknown): void {\n if (!this.connection || !this._initialized) return;\n const report = (error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n if (!this._disposed) console.error(`[LSP ${this.languageId}] Notification failed: ${message}`);\n };\n try {\n void this.connection.sendNotification(method, params).catch(report);\n } catch (error) {\n report(error);\n }\n }\n\n /** Notify server of a newly opened document */\n didOpen(uri: string, languageId: string, version: number, text: string): void {\n this.sendNotification(\"textDocument/didOpen\", {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /** Notify server of a document change (full content sync) */\n didChange(uri: string, version: number, text: string): void {\n this.sendNotification(\"textDocument/didChange\", {\n textDocument: { uri, version },\n contentChanges: [{ text }],\n });\n }\n\n /** Notify server of a closed document */\n didClose(uri: string): void {\n this.sendNotification(\"textDocument/didClose\", {\n textDocument: { uri },\n });\n }\n\n /** Gracefully shut down or disconnect from the server */\n shutdown(): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n const initialized = this._initialized;\n this._disposed = true;\n this._initialized = false;\n this.stop.abort(new Error(\"LSP client shut down\"));\n this.shutdownPromise = this.shutdownOwnedTransport(initialized);\n return this.shutdownPromise;\n }\n\n private async shutdownOwnedTransport(initialized: boolean): Promise<void> {\n const child = this.process;\n const connection = this.connection;\n this.process = null;\n if (this._isDaemonClient) {\n // Shared daemon ownership ends at this session's socket.\n this.disposeConnection();\n this.socket?.destroy();\n this.socket = null;\n return;\n }\n\n if (connection && initialized) {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n try {\n const graceful = async () => {\n await connection.sendRequest(\"shutdown\").catch(() => {});\n await connection.sendNotification(\"exit\").catch(() => {});\n };\n await Promise.race([\n graceful().catch(() => {}),\n new Promise<void>((resolve) => { timeout = setTimeout(resolve, 3000); }),\n ]);\n } catch {\n // The owned transport may have closed during shutdown.\n } finally {\n clearTimeout(timeout);\n }\n }\n this.disposeConnection();\n if (!child || child.exitCode !== null || child.signalCode !== null) return;\n\n // Signal delivery does not mean exit. Keep the captured child through escalation.\n await new Promise<void>((resolve, reject) => {\n let forceTimer: ReturnType<typeof setTimeout>;\n let exitTimer: ReturnType<typeof setTimeout>;\n const cleanup = () => {\n clearTimeout(forceTimer);\n clearTimeout(exitTimer);\n child.removeListener(\"exit\", exited);\n };\n const exited = () => { cleanup(); resolve(); };\n const signalChild = (signal: NodeJS.Signals) => {\n try { child.kill(signal); }\n catch (error) { cleanup(); reject(error); }\n };\n child.once(\"exit\", exited);\n forceTimer = setTimeout(() => {\n if (child.exitCode !== null || child.signalCode !== null) { exited(); return; }\n exitTimer = setTimeout(() => {\n cleanup();\n reject(new Error(`LSP ${this.languageId} process did not exit after SIGKILL`));\n }, 1000);\n signalChild(\"SIGKILL\");\n }, 2000);\n signalChild(\"SIGTERM\");\n });\n }\n}\n"]}
@@ -24,6 +24,9 @@ export class LspClient {
24
24
  _disposed = false;
25
25
  /** True if connected to a daemon socket (server init handled by daemon) */
26
26
  _isDaemonClient = false;
27
+ stop = new AbortController();
28
+ startPromise = null;
29
+ shutdownPromise = null;
27
30
  languageId;
28
31
  command;
29
32
  rootDir;
@@ -51,15 +54,28 @@ export class LspClient {
51
54
  return new Map(this._diagnostics);
52
55
  }
53
56
  /** Start the LSP server and perform the initialize handshake */
54
- async start() {
55
- if (this._initialized || this._disposed)
56
- return;
57
- if (this.options.socketPath) {
58
- await this.connectToSocket(this.options.socketPath);
59
- }
60
- else {
61
- await this.spawnDirect();
62
- }
57
+ start() {
58
+ if (this._disposed)
59
+ return Promise.reject(new Error("LSP client shut down"));
60
+ if (this.startPromise)
61
+ return this.startPromise;
62
+ this.startPromise = (this.options.socketPath
63
+ ? this.connectToSocket(this.options.socketPath)
64
+ : this.spawnDirect()).catch(async (error) => {
65
+ await this.shutdown();
66
+ throw error;
67
+ });
68
+ return this.startPromise;
69
+ }
70
+ /** Cancel an owned handshake without waiting for the remote server. */
71
+ waitForStart(pending) {
72
+ const signal = this.stop.signal;
73
+ signal.throwIfAborted();
74
+ return new Promise((resolve, reject) => {
75
+ const aborted = () => reject(signal.reason);
76
+ signal.addEventListener("abort", aborted, { once: true });
77
+ pending.then(resolve, reject).finally(() => signal.removeEventListener("abort", aborted));
78
+ });
63
79
  }
64
80
  /** Register shared connection handlers (diagnostics, workspace/configuration, errors) */
65
81
  registerConnectionHandlers() {
@@ -96,43 +112,64 @@ export class LspClient {
96
112
  this._isDaemonClient = true;
97
113
  return new Promise((resolve, reject) => {
98
114
  let settled = false;
99
- const settle = (fn) => {
100
- if (!settled) {
101
- settled = true;
102
- fn();
103
- }
115
+ let connected = false;
116
+ let timeout;
117
+ const settle = (error) => {
118
+ if (settled)
119
+ return;
120
+ settled = true;
121
+ clearTimeout(timeout);
122
+ this.stop.signal.removeEventListener("abort", aborted);
123
+ if (error)
124
+ reject(error);
125
+ else
126
+ resolve();
127
+ };
128
+ const aborted = () => {
129
+ settle(new Error("LSP client shut down"));
130
+ socket.destroy();
104
131
  };
105
132
  const socket = netConnect(socketPath, () => {
106
- this.socket = socket;
107
- const reader = new SocketMessageReader(socket);
108
- const writer = new SocketMessageWriter(socket);
109
- this.connection = createMessageConnection(reader, writer);
110
- this.registerConnectionHandlers();
111
- this.connection.listen();
112
- this._initialized = true;
113
- settle(() => resolve());
114
- });
115
- socket.on("error", (err) => {
116
- if (!this._initialized) {
117
- settle(() => reject(new Error(`Failed to connect to LSP daemon: ${err.message}`)));
133
+ if (this._disposed || settled) {
134
+ socket.destroy();
135
+ return;
118
136
  }
119
- else {
120
- this._initialized = false;
137
+ try {
138
+ const reader = new SocketMessageReader(socket);
139
+ const writer = new SocketMessageWriter(socket);
140
+ this.connection = createMessageConnection(reader, writer);
141
+ this.registerConnectionHandlers();
142
+ this.connection.listen();
143
+ this._initialized = true;
144
+ connected = true;
145
+ settle();
121
146
  }
147
+ catch (error) {
148
+ settle(error instanceof Error ? error : new Error(String(error)));
149
+ socket.destroy();
150
+ }
151
+ });
152
+ // Capture even a connecting socket so shutdown can close it.
153
+ this.socket = socket;
154
+ socket.on("error", (err) => {
155
+ settle(new Error(`Failed to connect to LSP daemon: ${err.message}`));
156
+ this._initialized = false;
122
157
  });
123
158
  socket.on("close", () => {
159
+ settle(new Error("LSP daemon socket closed during startup"));
124
160
  if (!this._disposed) {
125
161
  this._initialized = false;
126
- this.options.onUnexpectedExit?.(null);
162
+ if (connected)
163
+ this.options.onUnexpectedExit?.(null);
127
164
  }
128
165
  });
129
- // Timeout
130
- setTimeout(() => {
131
- if (!settled) {
132
- socket.destroy();
133
- settle(() => reject(new Error("Timeout connecting to LSP daemon socket")));
134
- }
166
+ timeout = setTimeout(() => {
167
+ settle(new Error("Timeout connecting to LSP daemon socket"));
168
+ socket.destroy();
135
169
  }, 10_000);
170
+ this.stop.signal.addEventListener("abort", aborted, { once: true });
171
+ if (this.stop.signal.aborted)
172
+ aborted();
136
173
  });
137
174
  }
138
175
  /** Spawn LSP server directly as child process with stdio */
@@ -143,78 +180,52 @@ export class LspClient {
143
180
  env,
144
181
  cwd: this.rootDir,
145
182
  });
146
- if (!this.process.stdout || !this.process.stdin) {
147
- throw new Error(`Failed to spawn LSP server: ${this.options.command}`);
183
+ const child = this.process;
184
+ // Error listeners belong to this child and its streams, never the host process.
185
+ for (const stream of [child.stdin, child.stdout, child.stderr]) {
186
+ stream?.on("error", (err) => {
187
+ if (!this._disposed)
188
+ console.error(`[LSP ${this.languageId}] Transport error: ${err.message}`);
189
+ });
148
190
  }
149
- // Wait for the process to successfully spawn before setting up the connection.
150
- // spawn() is async — ENOENT and other errors arrive on the 'error' event.
151
- // If we don't wait, we'll try to write to a destroyed stdin and crash.
152
- await new Promise((resolve, reject) => {
153
- const onSpawn = () => { cleanup(); resolve(); };
154
- const onError = (err) => {
155
- cleanup();
156
- reject(new Error(`Failed to spawn LSP server "${this.options.command}": ${err.message}`));
157
- };
158
- const cleanup = () => {
159
- this.process?.removeListener("spawn", onSpawn);
160
- this.process?.removeListener("error", onError);
161
- };
162
- this.process.on("spawn", onSpawn);
163
- this.process.on("error", onError);
164
- });
165
- // Discard stderr to prevent blocking
166
- this.process.stderr?.resume();
167
- // Patch stdin.write to silently drop writes when the stream is destroyed.
168
- // StreamMessageWriter wraps stdin and calls write() which returns a Promise.
169
- // If the stream is destroyed (process exited), write() throws ERR_STREAM_DESTROYED
170
- // inside the Promise constructor, creating a rejection that propagates through
171
- // the writer's semaphore and becomes unhandled (notifications are fire-and-forget).
172
- // No amount of error handlers on the stream or connection can catch this.
173
- const stdin = this.process.stdin;
174
- const originalWrite = stdin.write;
175
- stdin.write = function (...args) {
176
- if (this.destroyed || this.writableEnded || this.writableFinished) {
177
- // Call the callback (last arg) so the Promise resolves instead of rejecting
178
- const cb = args[args.length - 1];
179
- if (typeof cb === "function")
180
- process.nextTick(cb);
181
- return false;
182
- }
183
- try {
184
- return originalWrite.apply(this, args);
185
- }
186
- catch (err) {
187
- // Catch EPIPE synchronously — process exited between our check and the write
188
- if (err?.code === "EPIPE" || err?.code === "ERR_STREAM_DESTROYED") {
189
- const cb = args[args.length - 1];
190
- if (typeof cb === "function")
191
- process.nextTick(cb);
192
- return false;
193
- }
194
- throw err;
195
- }
196
- };
197
- // Catch EPIPE on the stdin stream itself to prevent unhandled error events
198
- stdin.on("error", (err) => {
199
- if (err?.code === "EPIPE")
200
- return; // expected when server exits
201
- console.error(`[LSP ${this.languageId}] stdin error: ${err.message}`);
202
- });
203
- this.process.on("error", (err) => {
204
- console.error(`[LSP ${this.languageId}] Process error: ${err.message}`);
191
+ child.on("error", (err) => {
192
+ if (!this._disposed)
193
+ console.error(`[LSP ${this.languageId}] Process error: ${err.message}`);
205
194
  this._initialized = false;
206
195
  this.disposeConnection();
207
196
  });
208
- this.process.on("exit", (code) => {
197
+ let wasInitialized = false;
198
+ child.on("exit", (code) => {
209
199
  if (!this._disposed) {
210
- console.error(`[LSP ${this.languageId}] Server exited with code ${code}`);
211
200
  this._initialized = false;
212
201
  this.disposeConnection();
213
- this.options.onUnexpectedExit?.(code);
202
+ // A failed handshake is handled by the pending start, not auto-restart.
203
+ if (wasInitialized)
204
+ this.options.onUnexpectedExit?.(code);
214
205
  }
215
206
  });
216
- const reader = new StreamMessageReader(this.process.stdout);
217
- const writer = new StreamMessageWriter(this.process.stdin);
207
+ if (!child.stdout || !child.stdin) {
208
+ throw new Error(`Failed to spawn LSP server: ${this.options.command}`);
209
+ }
210
+ await this.waitForStart(new Promise((resolve, reject) => {
211
+ const onSpawn = () => { cleanup(); resolve(); };
212
+ const onError = (err) => {
213
+ cleanup();
214
+ reject(new Error(`Failed to spawn LSP server "${this.options.command}": ${err.message}`));
215
+ };
216
+ const cleanup = () => {
217
+ child.removeListener("spawn", onSpawn);
218
+ child.removeListener("error", onError);
219
+ this.stop.signal.removeEventListener("abort", cleanup);
220
+ };
221
+ child.once("spawn", onSpawn);
222
+ child.once("error", onError);
223
+ this.stop.signal.addEventListener("abort", cleanup, { once: true });
224
+ }));
225
+ this.stop.signal.throwIfAborted();
226
+ child.stderr?.resume();
227
+ const reader = new StreamMessageReader(child.stdout);
228
+ const writer = new StreamMessageWriter(child.stdin);
218
229
  this.connection = createMessageConnection(reader, writer);
219
230
  this.registerConnectionHandlers();
220
231
  this.connection.listen();
@@ -265,11 +276,14 @@ export class LspClient {
265
276
  ? { initializationOptions: this.options.initializationOptions }
266
277
  : {}),
267
278
  };
268
- const result = await this.connection.sendRequest("initialize", initParams);
279
+ const result = await this.waitForStart(this.connection.sendRequest("initialize", initParams));
280
+ this.stop.signal.throwIfAborted();
269
281
  this._serverCapabilities = result.capabilities;
270
282
  // Send initialized notification
271
- this.connection.sendNotification("initialized", {});
283
+ await this.waitForStart(this.connection.sendNotification("initialized", {}));
284
+ this.stop.signal.throwIfAborted();
272
285
  this._initialized = true;
286
+ wasInitialized = true;
273
287
  }
274
288
  /** Safely dispose the connection without throwing */
275
289
  disposeConnection() {
@@ -294,7 +308,17 @@ export class LspClient {
294
308
  sendNotification(method, params) {
295
309
  if (!this.connection || !this._initialized)
296
310
  return;
297
- this.connection.sendNotification(method, params);
311
+ const report = (error) => {
312
+ const message = error instanceof Error ? error.message : String(error);
313
+ if (!this._disposed)
314
+ console.error(`[LSP ${this.languageId}] Notification failed: ${message}`);
315
+ };
316
+ try {
317
+ void this.connection.sendNotification(method, params).catch(report);
318
+ }
319
+ catch (error) {
320
+ report(error);
321
+ }
298
322
  }
299
323
  /** Notify server of a newly opened document */
300
324
  didOpen(uri, languageId, version, text) {
@@ -316,51 +340,82 @@ export class LspClient {
316
340
  });
317
341
  }
318
342
  /** Gracefully shut down or disconnect from the server */
319
- async shutdown() {
320
- if (this._disposed)
321
- return;
343
+ shutdown() {
344
+ if (this.shutdownPromise)
345
+ return this.shutdownPromise;
346
+ const initialized = this._initialized;
322
347
  this._disposed = true;
323
348
  this._initialized = false;
349
+ this.stop.abort(new Error("LSP client shut down"));
350
+ this.shutdownPromise = this.shutdownOwnedTransport(initialized);
351
+ return this.shutdownPromise;
352
+ }
353
+ async shutdownOwnedTransport(initialized) {
354
+ const child = this.process;
355
+ const connection = this.connection;
356
+ this.process = null;
324
357
  if (this._isDaemonClient) {
325
- // Socket client: just disconnect — daemon keeps the server alive
358
+ // Shared daemon ownership ends at this session's socket.
326
359
  this.disposeConnection();
327
- if (this.socket) {
328
- this.socket.destroy();
329
- }
360
+ this.socket?.destroy();
330
361
  this.socket = null;
331
362
  return;
332
363
  }
333
- // Direct mode: shut down the server we own
334
- try {
335
- if (this.connection) {
336
- // Race shutdown request against a timeout. Catch the request separately
337
- // so if the timeout wins, the abandoned sendRequest rejection doesn't
338
- // become an unhandled promise rejection.
339
- const shutdownReq = this.connection.sendRequest("shutdown").catch(() => { });
364
+ if (connection && initialized) {
365
+ let timeout;
366
+ try {
367
+ const graceful = async () => {
368
+ await connection.sendRequest("shutdown").catch(() => { });
369
+ await connection.sendNotification("exit").catch(() => { });
370
+ };
340
371
  await Promise.race([
341
- shutdownReq,
342
- new Promise((resolve) => setTimeout(resolve, 3000)),
372
+ graceful().catch(() => { }),
373
+ new Promise((resolve) => { timeout = setTimeout(resolve, 3000); }),
343
374
  ]);
344
- try {
345
- this.connection.sendNotification("exit");
346
- }
347
- catch { }
348
375
  }
349
- }
350
- catch {
351
- // Server may already be dead
376
+ catch {
377
+ // The owned transport may have closed during shutdown.
378
+ }
379
+ finally {
380
+ clearTimeout(timeout);
381
+ }
352
382
  }
353
383
  this.disposeConnection();
354
- if (this.process) {
355
- this.process.kill("SIGTERM");
356
- // Force kill after 2s
357
- setTimeout(() => {
358
- if (this.process && !this.process.killed) {
359
- this.process.kill("SIGKILL");
384
+ if (!child || child.exitCode !== null || child.signalCode !== null)
385
+ return;
386
+ // Signal delivery does not mean exit. Keep the captured child through escalation.
387
+ await new Promise((resolve, reject) => {
388
+ let forceTimer;
389
+ let exitTimer;
390
+ const cleanup = () => {
391
+ clearTimeout(forceTimer);
392
+ clearTimeout(exitTimer);
393
+ child.removeListener("exit", exited);
394
+ };
395
+ const exited = () => { cleanup(); resolve(); };
396
+ const signalChild = (signal) => {
397
+ try {
398
+ child.kill(signal);
360
399
  }
400
+ catch (error) {
401
+ cleanup();
402
+ reject(error);
403
+ }
404
+ };
405
+ child.once("exit", exited);
406
+ forceTimer = setTimeout(() => {
407
+ if (child.exitCode !== null || child.signalCode !== null) {
408
+ exited();
409
+ return;
410
+ }
411
+ exitTimer = setTimeout(() => {
412
+ cleanup();
413
+ reject(new Error(`LSP ${this.languageId} process did not exit after SIGKILL`));
414
+ }, 1000);
415
+ signalChild("SIGKILL");
361
416
  }, 2000);
362
- }
363
- this.process = null;
417
+ signalChild("SIGTERM");
418
+ });
364
419
  }
365
420
  }
366
421
  //# sourceMappingURL=lsp-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lsp-client.js","sourceRoot":"","sources":["../../../../src/builtin-extensions/pi-lsp-extension/src/lsp-client.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * LSP Client — JSON-RPC client for LSP servers.\n *\n * Supports two modes:\n * - **Direct**: spawns LSP server as child process (stdio)\n * - **Socket**: connects to an LSP daemon via Unix domain socket\n *\n * Uses vscode-jsonrpc (bundled with vscode-languageserver-protocol) for\n * JSON-RPC message framing and transport.\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { connect as netConnect, type Socket } from \"node:net\";\nimport { pathToFileURL } from \"node:url\";\nimport {\n createMessageConnection,\n StreamMessageReader,\n StreamMessageWriter,\n SocketMessageReader,\n SocketMessageWriter,\n type MessageConnection,\n} from \"vscode-languageserver-protocol/node\";\nimport type {\n InitializeParams,\n InitializeResult,\n ServerCapabilities,\n Diagnostic,\n PublishDiagnosticsParams,\n} from \"vscode-languageserver-protocol\";\n\nexport interface LspClientOptions {\n /** Command to start the LSP server */\n command: string;\n /** Arguments for the command */\n args: string[];\n /** Root directory of the workspace */\n rootDir: string;\n /** Language ID this server handles */\n languageId: string;\n /** Extra environment variables */\n env?: Record<string, string>;\n /** Additional workspace folders (e.g. for multi-package workspaces) */\n workspaceFolders?: { uri: string; name: string }[];\n /** Connect to existing daemon socket instead of spawning a new process */\n socketPath?: string;\n /** LSP initializationOptions (e.g. jdtls settings for Lombok) */\n initializationOptions?: Record<string, unknown>;\n /** Settings returned by workspace/configuration handler (keyed by section, e.g. { intelephense: {...} }) */\n settings?: Record<string, unknown>;\n /** Called when the server exits unexpectedly (not from user-initiated shutdown) */\n onUnexpectedExit?: (code: number | null) => void;\n}\n\nexport class LspClient {\n private process: ChildProcess | null = null;\n private socket: Socket | null = null;\n private connection: MessageConnection | null = null;\n private _serverCapabilities: ServerCapabilities | null = null;\n private _diagnostics: Map<string, Diagnostic[]> = new Map();\n private _initialized = false;\n private _disposed = false;\n /** True if connected to a daemon socket (server init handled by daemon) */\n private _isDaemonClient = false;\n\n readonly languageId: string;\n readonly command: string;\n readonly rootDir: string;\n\n constructor(private options: LspClientOptions) {\n this.languageId = options.languageId;\n this.command = options.command;\n this.rootDir = options.rootDir;\n }\n\n get initialized(): boolean {\n return this._initialized;\n }\n\n get disposed(): boolean {\n return this._disposed;\n }\n\n get serverCapabilities(): ServerCapabilities | null {\n return this._serverCapabilities;\n }\n\n /** Get cached diagnostics for a URI */\n getDiagnostics(uri: string): Diagnostic[] {\n return this._diagnostics.get(uri) ?? [];\n }\n\n /** Get all cached diagnostics */\n getAllDiagnostics(): Map<string, Diagnostic[]> {\n return new Map(this._diagnostics);\n }\n\n /** Start the LSP server and perform the initialize handshake */\n async start(): Promise<void> {\n if (this._initialized || this._disposed) return;\n\n if (this.options.socketPath) {\n await this.connectToSocket(this.options.socketPath);\n } else {\n await this.spawnDirect();\n }\n }\n\n /** Register shared connection handlers (diagnostics, workspace/configuration, errors) */\n private registerConnectionHandlers(): void {\n if (!this.connection) return;\n\n // Listen for published diagnostics\n this.connection.onNotification(\n \"textDocument/publishDiagnostics\",\n (params: PublishDiagnosticsParams) => {\n this._diagnostics.set(params.uri, params.diagnostics);\n }\n );\n\n // Handle workspace/configuration requests from the server.\n // Servers like Intelephense request their settings via this method.\n // Return settings from options if configured, otherwise empty defaults.\n this.connection.onRequest(\n \"workspace/configuration\",\n (params: { items: { section?: string }[] }) => {\n const settings = this.options.settings;\n return params.items.map((item) => {\n if (item.section && settings && item.section in settings) {\n return settings[item.section];\n }\n return {};\n });\n }\n );\n\n // Handle connection-level errors to prevent unhandled exceptions\n this.connection.onError(([err]) => {\n console.error(`[LSP ${this.languageId}] Connection error: ${err.message}`);\n });\n\n this.connection.onClose(() => {\n if (!this._disposed) {\n this._initialized = false;\n }\n });\n }\n\n /** Connect to an existing LSP daemon via Unix socket (no init handshake needed) */\n private async connectToSocket(socketPath: string): Promise<void> {\n this._isDaemonClient = true;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n const settle = (fn: () => void) => {\n if (!settled) { settled = true; fn(); }\n };\n\n const socket = netConnect(socketPath, () => {\n this.socket = socket;\n\n const reader = new SocketMessageReader(socket);\n const writer = new SocketMessageWriter(socket);\n this.connection = createMessageConnection(reader, writer);\n\n this.registerConnectionHandlers();\n\n this.connection.listen();\n this._initialized = true;\n settle(() => resolve());\n });\n\n socket.on(\"error\", (err) => {\n if (!this._initialized) {\n settle(() => reject(new Error(`Failed to connect to LSP daemon: ${err.message}`)));\n } else {\n this._initialized = false;\n }\n });\n\n socket.on(\"close\", () => {\n if (!this._disposed) {\n this._initialized = false;\n this.options.onUnexpectedExit?.(null);\n }\n });\n\n // Timeout\n setTimeout(() => {\n if (!settled) {\n socket.destroy();\n settle(() => reject(new Error(\"Timeout connecting to LSP daemon socket\")));\n }\n }, 10_000);\n });\n }\n\n /** Spawn LSP server directly as child process with stdio */\n private async spawnDirect(): Promise<void> {\n const env = { ...process.env, ...this.options.env };\n\n this.process = spawn(this.options.command, this.options.args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n cwd: this.rootDir,\n });\n\n if (!this.process.stdout || !this.process.stdin) {\n throw new Error(`Failed to spawn LSP server: ${this.options.command}`);\n }\n\n // Wait for the process to successfully spawn before setting up the connection.\n // spawn() is async — ENOENT and other errors arrive on the 'error' event.\n // If we don't wait, we'll try to write to a destroyed stdin and crash.\n await new Promise<void>((resolve, reject) => {\n const onSpawn = () => { cleanup(); resolve(); };\n const onError = (err: Error) => {\n cleanup();\n reject(new Error(`Failed to spawn LSP server \"${this.options.command}\": ${err.message}`));\n };\n const cleanup = () => {\n this.process?.removeListener(\"spawn\", onSpawn);\n this.process?.removeListener(\"error\", onError);\n };\n this.process!.on(\"spawn\", onSpawn);\n this.process!.on(\"error\", onError);\n });\n\n // Discard stderr to prevent blocking\n this.process.stderr?.resume();\n\n // Patch stdin.write to silently drop writes when the stream is destroyed.\n // StreamMessageWriter wraps stdin and calls write() which returns a Promise.\n // If the stream is destroyed (process exited), write() throws ERR_STREAM_DESTROYED\n // inside the Promise constructor, creating a rejection that propagates through\n // the writer's semaphore and becomes unhandled (notifications are fire-and-forget).\n // No amount of error handlers on the stream or connection can catch this.\n const stdin = this.process.stdin!;\n const originalWrite = stdin.write;\n stdin.write = function (this: typeof stdin, ...args: any[]): boolean {\n if (this.destroyed || this.writableEnded || this.writableFinished) {\n // Call the callback (last arg) so the Promise resolves instead of rejecting\n const cb = args[args.length - 1];\n if (typeof cb === \"function\") process.nextTick(cb);\n return false;\n }\n try {\n return originalWrite.apply(this, args as any);\n } catch (err: any) {\n // Catch EPIPE synchronously — process exited between our check and the write\n if (err?.code === \"EPIPE\" || err?.code === \"ERR_STREAM_DESTROYED\") {\n const cb = args[args.length - 1];\n if (typeof cb === \"function\") process.nextTick(cb);\n return false;\n }\n throw err;\n }\n } as any;\n\n // Catch EPIPE on the stdin stream itself to prevent unhandled error events\n stdin.on(\"error\", (err: any) => {\n if (err?.code === \"EPIPE\") return; // expected when server exits\n console.error(`[LSP ${this.languageId}] stdin error: ${err.message}`);\n });\n\n this.process.on(\"error\", (err) => {\n console.error(`[LSP ${this.languageId}] Process error: ${err.message}`);\n this._initialized = false;\n this.disposeConnection();\n });\n\n this.process.on(\"exit\", (code) => {\n if (!this._disposed) {\n console.error(`[LSP ${this.languageId}] Server exited with code ${code}`);\n this._initialized = false;\n this.disposeConnection();\n this.options.onUnexpectedExit?.(code);\n }\n });\n\n const reader = new StreamMessageReader(this.process.stdout);\n const writer = new StreamMessageWriter(this.process.stdin);\n this.connection = createMessageConnection(reader, writer);\n\n this.registerConnectionHandlers();\n\n this.connection.listen();\n\n // Initialize handshake\n const rootUri = pathToFileURL(this.rootDir).toString();\n const defaultFolder = { uri: rootUri, name: this.rootDir.split(\"/\").pop() ?? \"workspace\" };\n\n // Use provided workspace folders or fall back to single root\n const workspaceFolders = this.options.workspaceFolders && this.options.workspaceFolders.length > 0\n ? this.options.workspaceFolders\n : [defaultFolder];\n\n const initParams: InitializeParams = {\n processId: process.pid,\n capabilities: {\n textDocument: {\n synchronization: {\n didSave: true,\n dynamicRegistration: false,\n },\n hover: {\n contentFormat: [\"plaintext\", \"markdown\"],\n },\n definition: {},\n references: {},\n documentSymbol: {\n hierarchicalDocumentSymbolSupport: true,\n },\n rename: {\n prepareSupport: false,\n },\n publishDiagnostics: {\n relatedInformation: true,\n },\n completion: {\n completionItem: {\n snippetSupport: false,\n },\n },\n },\n workspace: {\n workspaceFolders: true,\n symbol: {},\n configuration: true,\n },\n },\n rootUri,\n workspaceFolders,\n ...(this.options.initializationOptions\n ? { initializationOptions: this.options.initializationOptions }\n : {}),\n };\n\n const result: InitializeResult = await this.connection.sendRequest(\n \"initialize\",\n initParams\n );\n this._serverCapabilities = result.capabilities;\n\n // Send initialized notification\n this.connection.sendNotification(\"initialized\", {});\n this._initialized = true;\n }\n\n /** Safely dispose the connection without throwing */\n private disposeConnection(): void {\n try {\n if (this.connection) {\n this.connection.dispose();\n }\n } catch {\n // Already disposed or stream destroyed — ignore\n }\n this.connection = null;\n }\n\n /** Send a request to the LSP server */\n async sendRequest<R>(method: string, params: unknown): Promise<R> {\n if (!this.connection || !this._initialized) {\n throw new Error(`LSP ${this.languageId} not initialized`);\n }\n return this.connection.sendRequest(method, params) as Promise<R>;\n }\n\n /** Send a notification to the LSP server */\n sendNotification(method: string, params: unknown): void {\n if (!this.connection || !this._initialized) return;\n this.connection.sendNotification(method, params);\n }\n\n /** Notify server of a newly opened document */\n didOpen(uri: string, languageId: string, version: number, text: string): void {\n this.sendNotification(\"textDocument/didOpen\", {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /** Notify server of a document change (full content sync) */\n didChange(uri: string, version: number, text: string): void {\n this.sendNotification(\"textDocument/didChange\", {\n textDocument: { uri, version },\n contentChanges: [{ text }],\n });\n }\n\n /** Notify server of a closed document */\n didClose(uri: string): void {\n this.sendNotification(\"textDocument/didClose\", {\n textDocument: { uri },\n });\n }\n\n /** Gracefully shut down or disconnect from the server */\n async shutdown(): Promise<void> {\n if (this._disposed) return;\n this._disposed = true;\n this._initialized = false;\n\n if (this._isDaemonClient) {\n // Socket client: just disconnect — daemon keeps the server alive\n this.disposeConnection();\n if (this.socket) {\n this.socket.destroy();\n }\n this.socket = null;\n return;\n }\n\n // Direct mode: shut down the server we own\n try {\n if (this.connection) {\n // Race shutdown request against a timeout. Catch the request separately\n // so if the timeout wins, the abandoned sendRequest rejection doesn't\n // become an unhandled promise rejection.\n const shutdownReq = this.connection.sendRequest(\"shutdown\").catch(() => {});\n await Promise.race([\n shutdownReq,\n new Promise((resolve) => setTimeout(resolve, 3000)),\n ]);\n try { this.connection.sendNotification(\"exit\"); } catch {}\n }\n } catch {\n // Server may already be dead\n }\n this.disposeConnection();\n\n if (this.process) {\n this.process.kill(\"SIGTERM\");\n // Force kill after 2s\n setTimeout(() => {\n if (this.process && !this.process.killed) {\n this.process.kill(\"SIGKILL\");\n }\n }, 2000);\n }\n\n this.process = null;\n }\n}\n"]}
1
+ {"version":3,"file":"lsp-client.js","sourceRoot":"","sources":["../../../../src/builtin-extensions/pi-lsp-extension/src/lsp-client.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * LSP Client — JSON-RPC client for LSP servers.\n *\n * Supports two modes:\n * - **Direct**: spawns LSP server as child process (stdio)\n * - **Socket**: connects to an LSP daemon via Unix domain socket\n *\n * Uses vscode-jsonrpc (bundled with vscode-languageserver-protocol) for\n * JSON-RPC message framing and transport.\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { connect as netConnect, type Socket } from \"node:net\";\nimport { pathToFileURL } from \"node:url\";\nimport {\n createMessageConnection,\n StreamMessageReader,\n StreamMessageWriter,\n SocketMessageReader,\n SocketMessageWriter,\n type MessageConnection,\n} from \"vscode-languageserver-protocol/node\";\nimport type {\n InitializeParams,\n InitializeResult,\n ServerCapabilities,\n Diagnostic,\n PublishDiagnosticsParams,\n} from \"vscode-languageserver-protocol\";\n\nexport interface LspClientOptions {\n /** Command to start the LSP server */\n command: string;\n /** Arguments for the command */\n args: string[];\n /** Root directory of the workspace */\n rootDir: string;\n /** Language ID this server handles */\n languageId: string;\n /** Extra environment variables */\n env?: Record<string, string>;\n /** Additional workspace folders (e.g. for multi-package workspaces) */\n workspaceFolders?: { uri: string; name: string }[];\n /** Connect to existing daemon socket instead of spawning a new process */\n socketPath?: string;\n /** LSP initializationOptions (e.g. jdtls settings for Lombok) */\n initializationOptions?: Record<string, unknown>;\n /** Settings returned by workspace/configuration handler (keyed by section, e.g. { intelephense: {...} }) */\n settings?: Record<string, unknown>;\n /** Called when the server exits unexpectedly (not from user-initiated shutdown) */\n onUnexpectedExit?: (code: number | null) => void;\n}\n\nexport class LspClient {\n private process: ChildProcess | null = null;\n private socket: Socket | null = null;\n private connection: MessageConnection | null = null;\n private _serverCapabilities: ServerCapabilities | null = null;\n private _diagnostics: Map<string, Diagnostic[]> = new Map();\n private _initialized = false;\n private _disposed = false;\n /** True if connected to a daemon socket (server init handled by daemon) */\n private _isDaemonClient = false;\n\n private readonly stop = new AbortController();\n private startPromise: Promise<void> | null = null;\n private shutdownPromise: Promise<void> | null = null;\n\n readonly languageId: string;\n readonly command: string;\n readonly rootDir: string;\n\n constructor(private options: LspClientOptions) {\n this.languageId = options.languageId;\n this.command = options.command;\n this.rootDir = options.rootDir;\n }\n\n get initialized(): boolean {\n return this._initialized;\n }\n\n get disposed(): boolean {\n return this._disposed;\n }\n\n get serverCapabilities(): ServerCapabilities | null {\n return this._serverCapabilities;\n }\n\n /** Get cached diagnostics for a URI */\n getDiagnostics(uri: string): Diagnostic[] {\n return this._diagnostics.get(uri) ?? [];\n }\n\n /** Get all cached diagnostics */\n getAllDiagnostics(): Map<string, Diagnostic[]> {\n return new Map(this._diagnostics);\n }\n\n /** Start the LSP server and perform the initialize handshake */\n start(): Promise<void> {\n if (this._disposed) return Promise.reject(new Error(\"LSP client shut down\"));\n if (this.startPromise) return this.startPromise;\n this.startPromise = (this.options.socketPath\n ? this.connectToSocket(this.options.socketPath)\n : this.spawnDirect()).catch(async (error: unknown) => {\n await this.shutdown();\n throw error;\n });\n return this.startPromise;\n }\n\n /** Cancel an owned handshake without waiting for the remote server. */\n private waitForStart<T>(pending: Promise<T>): Promise<T> {\n const signal = this.stop.signal;\n signal.throwIfAborted();\n return new Promise<T>((resolve, reject) => {\n const aborted = () => reject(signal.reason);\n signal.addEventListener(\"abort\", aborted, { once: true });\n pending.then(resolve, reject).finally(() => signal.removeEventListener(\"abort\", aborted));\n });\n }\n\n /** Register shared connection handlers (diagnostics, workspace/configuration, errors) */\n private registerConnectionHandlers(): void {\n if (!this.connection) return;\n\n // Listen for published diagnostics\n this.connection.onNotification(\n \"textDocument/publishDiagnostics\",\n (params: PublishDiagnosticsParams) => {\n this._diagnostics.set(params.uri, params.diagnostics);\n }\n );\n\n // Handle workspace/configuration requests from the server.\n // Servers like Intelephense request their settings via this method.\n // Return settings from options if configured, otherwise empty defaults.\n this.connection.onRequest(\n \"workspace/configuration\",\n (params: { items: { section?: string }[] }) => {\n const settings = this.options.settings;\n return params.items.map((item) => {\n if (item.section && settings && item.section in settings) {\n return settings[item.section];\n }\n return {};\n });\n }\n );\n\n // Handle connection-level errors to prevent unhandled exceptions\n this.connection.onError(([err]) => {\n console.error(`[LSP ${this.languageId}] Connection error: ${err.message}`);\n });\n\n this.connection.onClose(() => {\n if (!this._disposed) {\n this._initialized = false;\n }\n });\n }\n\n /** Connect to an existing LSP daemon via Unix socket (no init handshake needed) */\n private async connectToSocket(socketPath: string): Promise<void> {\n this._isDaemonClient = true;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n let connected = false;\n let timeout: ReturnType<typeof setTimeout>;\n const settle = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n this.stop.signal.removeEventListener(\"abort\", aborted);\n if (error) reject(error);\n else resolve();\n };\n const aborted = () => {\n settle(new Error(\"LSP client shut down\"));\n socket.destroy();\n };\n const socket = netConnect(socketPath, () => {\n if (this._disposed || settled) { socket.destroy(); return; }\n try {\n const reader = new SocketMessageReader(socket);\n const writer = new SocketMessageWriter(socket);\n this.connection = createMessageConnection(reader, writer);\n this.registerConnectionHandlers();\n this.connection.listen();\n this._initialized = true;\n connected = true;\n settle();\n } catch (error) {\n settle(error instanceof Error ? error : new Error(String(error)));\n socket.destroy();\n }\n });\n // Capture even a connecting socket so shutdown can close it.\n this.socket = socket;\n socket.on(\"error\", (err) => {\n settle(new Error(`Failed to connect to LSP daemon: ${err.message}`));\n this._initialized = false;\n });\n socket.on(\"close\", () => {\n settle(new Error(\"LSP daemon socket closed during startup\"));\n if (!this._disposed) {\n this._initialized = false;\n if (connected) this.options.onUnexpectedExit?.(null);\n }\n });\n timeout = setTimeout(() => {\n settle(new Error(\"Timeout connecting to LSP daemon socket\"));\n socket.destroy();\n }, 10_000);\n this.stop.signal.addEventListener(\"abort\", aborted, { once: true });\n if (this.stop.signal.aborted) aborted();\n });\n }\n\n /** Spawn LSP server directly as child process with stdio */\n private async spawnDirect(): Promise<void> {\n const env = { ...process.env, ...this.options.env };\n\n this.process = spawn(this.options.command, this.options.args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n cwd: this.rootDir,\n });\n\n const child = this.process;\n // Error listeners belong to this child and its streams, never the host process.\n for (const stream of [child.stdin, child.stdout, child.stderr]) {\n stream?.on(\"error\", (err: Error) => {\n if (!this._disposed) console.error(`[LSP ${this.languageId}] Transport error: ${err.message}`);\n });\n }\n child.on(\"error\", (err) => {\n if (!this._disposed) console.error(`[LSP ${this.languageId}] Process error: ${err.message}`);\n this._initialized = false;\n this.disposeConnection();\n });\n let wasInitialized = false;\n child.on(\"exit\", (code) => {\n if (!this._disposed) {\n this._initialized = false;\n this.disposeConnection();\n // A failed handshake is handled by the pending start, not auto-restart.\n if (wasInitialized) this.options.onUnexpectedExit?.(code);\n }\n });\n if (!child.stdout || !child.stdin) {\n throw new Error(`Failed to spawn LSP server: ${this.options.command}`);\n }\n\n await this.waitForStart(new Promise<void>((resolve, reject) => {\n const onSpawn = () => { cleanup(); resolve(); };\n const onError = (err: Error) => {\n cleanup();\n reject(new Error(`Failed to spawn LSP server \"${this.options.command}\": ${err.message}`));\n };\n const cleanup = () => {\n child.removeListener(\"spawn\", onSpawn);\n child.removeListener(\"error\", onError);\n this.stop.signal.removeEventListener(\"abort\", cleanup);\n };\n child.once(\"spawn\", onSpawn);\n child.once(\"error\", onError);\n this.stop.signal.addEventListener(\"abort\", cleanup, { once: true });\n }));\n this.stop.signal.throwIfAborted();\n child.stderr?.resume();\n\n const reader = new StreamMessageReader(child.stdout);\n const writer = new StreamMessageWriter(child.stdin);\n this.connection = createMessageConnection(reader, writer);\n\n this.registerConnectionHandlers();\n\n this.connection.listen();\n\n // Initialize handshake\n const rootUri = pathToFileURL(this.rootDir).toString();\n const defaultFolder = { uri: rootUri, name: this.rootDir.split(\"/\").pop() ?? \"workspace\" };\n\n // Use provided workspace folders or fall back to single root\n const workspaceFolders = this.options.workspaceFolders && this.options.workspaceFolders.length > 0\n ? this.options.workspaceFolders\n : [defaultFolder];\n\n const initParams: InitializeParams = {\n processId: process.pid,\n capabilities: {\n textDocument: {\n synchronization: {\n didSave: true,\n dynamicRegistration: false,\n },\n hover: {\n contentFormat: [\"plaintext\", \"markdown\"],\n },\n definition: {},\n references: {},\n documentSymbol: {\n hierarchicalDocumentSymbolSupport: true,\n },\n rename: {\n prepareSupport: false,\n },\n publishDiagnostics: {\n relatedInformation: true,\n },\n completion: {\n completionItem: {\n snippetSupport: false,\n },\n },\n },\n workspace: {\n workspaceFolders: true,\n symbol: {},\n configuration: true,\n },\n },\n rootUri,\n workspaceFolders,\n ...(this.options.initializationOptions\n ? { initializationOptions: this.options.initializationOptions }\n : {}),\n };\n\n const result: InitializeResult = await this.waitForStart(this.connection.sendRequest(\n \"initialize\",\n initParams\n ));\n this.stop.signal.throwIfAborted();\n this._serverCapabilities = result.capabilities;\n\n // Send initialized notification\n await this.waitForStart(this.connection.sendNotification(\"initialized\", {}));\n this.stop.signal.throwIfAborted();\n this._initialized = true;\n wasInitialized = true;\n }\n\n /** Safely dispose the connection without throwing */\n private disposeConnection(): void {\n try {\n if (this.connection) {\n this.connection.dispose();\n }\n } catch {\n // Already disposed or stream destroyed — ignore\n }\n this.connection = null;\n }\n\n /** Send a request to the LSP server */\n async sendRequest<R>(method: string, params: unknown): Promise<R> {\n if (!this.connection || !this._initialized) {\n throw new Error(`LSP ${this.languageId} not initialized`);\n }\n return this.connection.sendRequest(method, params) as Promise<R>;\n }\n\n /** Send a notification to the LSP server */\n sendNotification(method: string, params: unknown): void {\n if (!this.connection || !this._initialized) return;\n const report = (error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n if (!this._disposed) console.error(`[LSP ${this.languageId}] Notification failed: ${message}`);\n };\n try {\n void this.connection.sendNotification(method, params).catch(report);\n } catch (error) {\n report(error);\n }\n }\n\n /** Notify server of a newly opened document */\n didOpen(uri: string, languageId: string, version: number, text: string): void {\n this.sendNotification(\"textDocument/didOpen\", {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /** Notify server of a document change (full content sync) */\n didChange(uri: string, version: number, text: string): void {\n this.sendNotification(\"textDocument/didChange\", {\n textDocument: { uri, version },\n contentChanges: [{ text }],\n });\n }\n\n /** Notify server of a closed document */\n didClose(uri: string): void {\n this.sendNotification(\"textDocument/didClose\", {\n textDocument: { uri },\n });\n }\n\n /** Gracefully shut down or disconnect from the server */\n shutdown(): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n const initialized = this._initialized;\n this._disposed = true;\n this._initialized = false;\n this.stop.abort(new Error(\"LSP client shut down\"));\n this.shutdownPromise = this.shutdownOwnedTransport(initialized);\n return this.shutdownPromise;\n }\n\n private async shutdownOwnedTransport(initialized: boolean): Promise<void> {\n const child = this.process;\n const connection = this.connection;\n this.process = null;\n if (this._isDaemonClient) {\n // Shared daemon ownership ends at this session's socket.\n this.disposeConnection();\n this.socket?.destroy();\n this.socket = null;\n return;\n }\n\n if (connection && initialized) {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n try {\n const graceful = async () => {\n await connection.sendRequest(\"shutdown\").catch(() => {});\n await connection.sendNotification(\"exit\").catch(() => {});\n };\n await Promise.race([\n graceful().catch(() => {}),\n new Promise<void>((resolve) => { timeout = setTimeout(resolve, 3000); }),\n ]);\n } catch {\n // The owned transport may have closed during shutdown.\n } finally {\n clearTimeout(timeout);\n }\n }\n this.disposeConnection();\n if (!child || child.exitCode !== null || child.signalCode !== null) return;\n\n // Signal delivery does not mean exit. Keep the captured child through escalation.\n await new Promise<void>((resolve, reject) => {\n let forceTimer: ReturnType<typeof setTimeout>;\n let exitTimer: ReturnType<typeof setTimeout>;\n const cleanup = () => {\n clearTimeout(forceTimer);\n clearTimeout(exitTimer);\n child.removeListener(\"exit\", exited);\n };\n const exited = () => { cleanup(); resolve(); };\n const signalChild = (signal: NodeJS.Signals) => {\n try { child.kill(signal); }\n catch (error) { cleanup(); reject(error); }\n };\n child.once(\"exit\", exited);\n forceTimer = setTimeout(() => {\n if (child.exitCode !== null || child.signalCode !== null) { exited(); return; }\n exitTimer = setTimeout(() => {\n cleanup();\n reject(new Error(`LSP ${this.languageId} process did not exit after SIGKILL`));\n }, 1000);\n signalChild(\"SIGKILL\");\n }, 2000);\n signalChild(\"SIGTERM\");\n });\n }\n}\n"]}