praxis-agent 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +534 -0
  3. package/dist/application/background-agent-manager.d.ts +66 -0
  4. package/dist/application/background-agent-manager.d.ts.map +1 -0
  5. package/dist/application/background-agent-manager.js +362 -0
  6. package/dist/application/background-agent-manager.js.map +1 -0
  7. package/dist/application/background-bash-manager.d.ts +54 -0
  8. package/dist/application/background-bash-manager.d.ts.map +1 -0
  9. package/dist/application/background-bash-manager.js +354 -0
  10. package/dist/application/background-bash-manager.js.map +1 -0
  11. package/dist/application/background-task-id.d.ts +5 -0
  12. package/dist/application/background-task-id.d.ts.map +1 -0
  13. package/dist/application/background-task-id.js +25 -0
  14. package/dist/application/background-task-id.js.map +1 -0
  15. package/dist/application/claude-project-purge.d.ts +50 -0
  16. package/dist/application/claude-project-purge.d.ts.map +1 -0
  17. package/dist/application/claude-project-purge.js +459 -0
  18. package/dist/application/claude-project-purge.js.map +1 -0
  19. package/dist/application/managed-worktree.d.ts +15 -0
  20. package/dist/application/managed-worktree.d.ts.map +1 -0
  21. package/dist/application/managed-worktree.js +127 -0
  22. package/dist/application/managed-worktree.js.map +1 -0
  23. package/dist/application/model-compactor.d.ts +8 -0
  24. package/dist/application/model-compactor.d.ts.map +1 -0
  25. package/dist/application/model-compactor.js +70 -0
  26. package/dist/application/model-compactor.js.map +1 -0
  27. package/dist/application/scheduled-prompt-manager.d.ts +69 -0
  28. package/dist/application/scheduled-prompt-manager.d.ts.map +1 -0
  29. package/dist/application/scheduled-prompt-manager.js +387 -0
  30. package/dist/application/scheduled-prompt-manager.js.map +1 -0
  31. package/dist/application/session-service.d.ts +142 -0
  32. package/dist/application/session-service.d.ts.map +1 -0
  33. package/dist/application/session-service.js +1690 -0
  34. package/dist/application/session-service.js.map +1 -0
  35. package/dist/application/session-worktree.d.ts +55 -0
  36. package/dist/application/session-worktree.d.ts.map +1 -0
  37. package/dist/application/session-worktree.js +311 -0
  38. package/dist/application/session-worktree.js.map +1 -0
  39. package/dist/application/subagent-service.d.ts +98 -0
  40. package/dist/application/subagent-service.d.ts.map +1 -0
  41. package/dist/application/subagent-service.js +1305 -0
  42. package/dist/application/subagent-service.js.map +1 -0
  43. package/dist/application/tool-use-summary.d.ts +8 -0
  44. package/dist/application/tool-use-summary.d.ts.map +1 -0
  45. package/dist/application/tool-use-summary.js +53 -0
  46. package/dist/application/tool-use-summary.js.map +1 -0
  47. package/dist/application/top-level-agent-manager.d.ts +58 -0
  48. package/dist/application/top-level-agent-manager.d.ts.map +1 -0
  49. package/dist/application/top-level-agent-manager.js +907 -0
  50. package/dist/application/top-level-agent-manager.js.map +1 -0
  51. package/dist/application/workflow-manager.d.ts +61 -0
  52. package/dist/application/workflow-manager.d.ts.map +1 -0
  53. package/dist/application/workflow-manager.js +582 -0
  54. package/dist/application/workflow-manager.js.map +1 -0
  55. package/dist/application/workflow-meta.d.ts +18 -0
  56. package/dist/application/workflow-meta.d.ts.map +1 -0
  57. package/dist/application/workflow-meta.js +146 -0
  58. package/dist/application/workflow-meta.js.map +1 -0
  59. package/dist/application/workflow-runtime.d.ts +29 -0
  60. package/dist/application/workflow-runtime.d.ts.map +1 -0
  61. package/dist/application/workflow-runtime.js +176 -0
  62. package/dist/application/workflow-runtime.js.map +1 -0
  63. package/dist/application/workflow-worktree.d.ts +9 -0
  64. package/dist/application/workflow-worktree.d.ts.map +1 -0
  65. package/dist/application/workflow-worktree.js +11 -0
  66. package/dist/application/workflow-worktree.js.map +1 -0
  67. package/dist/cli/agents-dashboard.d.ts +37 -0
  68. package/dist/cli/agents-dashboard.d.ts.map +1 -0
  69. package/dist/cli/agents-dashboard.js +408 -0
  70. package/dist/cli/agents-dashboard.js.map +1 -0
  71. package/dist/cli/controls.d.ts +15 -0
  72. package/dist/cli/controls.d.ts.map +1 -0
  73. package/dist/cli/controls.js +219 -0
  74. package/dist/cli/controls.js.map +1 -0
  75. package/dist/cli/debug.d.ts +13 -0
  76. package/dist/cli/debug.d.ts.map +1 -0
  77. package/dist/cli/debug.js +37 -0
  78. package/dist/cli/debug.js.map +1 -0
  79. package/dist/cli/interactive.d.ts +63 -0
  80. package/dist/cli/interactive.d.ts.map +1 -0
  81. package/dist/cli/interactive.js +600 -0
  82. package/dist/cli/interactive.js.map +1 -0
  83. package/dist/cli/protocol.d.ts +251 -0
  84. package/dist/cli/protocol.d.ts.map +1 -0
  85. package/dist/cli/protocol.js +2146 -0
  86. package/dist/cli/protocol.js.map +1 -0
  87. package/dist/cli.d.ts +116 -0
  88. package/dist/cli.d.ts.map +1 -0
  89. package/dist/cli.js +3901 -0
  90. package/dist/cli.js.map +1 -0
  91. package/dist/compatibility/claude/compaction.d.ts +19 -0
  92. package/dist/compatibility/claude/compaction.d.ts.map +1 -0
  93. package/dist/compatibility/claude/compaction.js +82 -0
  94. package/dist/compatibility/claude/compaction.js.map +1 -0
  95. package/dist/compatibility/claude/context.d.ts +24 -0
  96. package/dist/compatibility/claude/context.d.ts.map +1 -0
  97. package/dist/compatibility/claude/context.js +92 -0
  98. package/dist/compatibility/claude/context.js.map +1 -0
  99. package/dist/compatibility/claude/dynamic-context.d.ts +20 -0
  100. package/dist/compatibility/claude/dynamic-context.d.ts.map +1 -0
  101. package/dist/compatibility/claude/dynamic-context.js +168 -0
  102. package/dist/compatibility/claude/dynamic-context.js.map +1 -0
  103. package/dist/compatibility/claude/file-history.d.ts +14 -0
  104. package/dist/compatibility/claude/file-history.d.ts.map +1 -0
  105. package/dist/compatibility/claude/file-history.js +340 -0
  106. package/dist/compatibility/claude/file-history.js.map +1 -0
  107. package/dist/compatibility/claude/file-resources.d.ts +28 -0
  108. package/dist/compatibility/claude/file-resources.d.ts.map +1 -0
  109. package/dist/compatibility/claude/file-resources.js +168 -0
  110. package/dist/compatibility/claude/file-resources.js.map +1 -0
  111. package/dist/compatibility/claude/fork.d.ts +9 -0
  112. package/dist/compatibility/claude/fork.d.ts.map +1 -0
  113. package/dist/compatibility/claude/fork.js +225 -0
  114. package/dist/compatibility/claude/fork.js.map +1 -0
  115. package/dist/compatibility/claude/history.d.ts +4 -0
  116. package/dist/compatibility/claude/history.d.ts.map +1 -0
  117. package/dist/compatibility/claude/history.js +86 -0
  118. package/dist/compatibility/claude/history.js.map +1 -0
  119. package/dist/compatibility/claude/ownership.d.ts +87 -0
  120. package/dist/compatibility/claude/ownership.d.ts.map +1 -0
  121. package/dist/compatibility/claude/ownership.js +100 -0
  122. package/dist/compatibility/claude/ownership.js.map +1 -0
  123. package/dist/compatibility/claude/paths.d.ts +17 -0
  124. package/dist/compatibility/claude/paths.d.ts.map +1 -0
  125. package/dist/compatibility/claude/paths.js +54 -0
  126. package/dist/compatibility/claude/paths.js.map +1 -0
  127. package/dist/compatibility/claude/pr-links.d.ts +25 -0
  128. package/dist/compatibility/claude/pr-links.d.ts.map +1 -0
  129. package/dist/compatibility/claude/pr-links.js +80 -0
  130. package/dist/compatibility/claude/pr-links.js.map +1 -0
  131. package/dist/compatibility/claude/projection.d.ts +11 -0
  132. package/dist/compatibility/claude/projection.d.ts.map +1 -0
  133. package/dist/compatibility/claude/projection.js +325 -0
  134. package/dist/compatibility/claude/projection.js.map +1 -0
  135. package/dist/compatibility/claude/schema.d.ts +18 -0
  136. package/dist/compatibility/claude/schema.d.ts.map +1 -0
  137. package/dist/compatibility/claude/schema.js +983 -0
  138. package/dist/compatibility/claude/schema.js.map +1 -0
  139. package/dist/compatibility/claude/shared-resources.d.ts +51 -0
  140. package/dist/compatibility/claude/shared-resources.d.ts.map +1 -0
  141. package/dist/compatibility/claude/shared-resources.js +382 -0
  142. package/dist/compatibility/claude/shared-resources.js.map +1 -0
  143. package/dist/compatibility/claude/sidechain.d.ts +50 -0
  144. package/dist/compatibility/claude/sidechain.d.ts.map +1 -0
  145. package/dist/compatibility/claude/sidechain.js +90 -0
  146. package/dist/compatibility/claude/sidechain.js.map +1 -0
  147. package/dist/compatibility/claude/tool-links.d.ts +13 -0
  148. package/dist/compatibility/claude/tool-links.d.ts.map +1 -0
  149. package/dist/compatibility/claude/tool-links.js +61 -0
  150. package/dist/compatibility/claude/tool-links.js.map +1 -0
  151. package/dist/compatibility/claude/translation.d.ts +71 -0
  152. package/dist/compatibility/claude/translation.d.ts.map +1 -0
  153. package/dist/compatibility/claude/translation.js +443 -0
  154. package/dist/compatibility/claude/translation.js.map +1 -0
  155. package/dist/compatibility/claude/workflow-replay.d.ts +10 -0
  156. package/dist/compatibility/claude/workflow-replay.d.ts.map +1 -0
  157. package/dist/compatibility/claude/workflow-replay.js +66 -0
  158. package/dist/compatibility/claude/workflow-replay.js.map +1 -0
  159. package/dist/compatibility/claude/workflow.d.ts +33 -0
  160. package/dist/compatibility/claude/workflow.d.ts.map +1 -0
  161. package/dist/compatibility/claude/workflow.js +76 -0
  162. package/dist/compatibility/claude/workflow.js.map +1 -0
  163. package/dist/core/compaction.d.ts +16 -0
  164. package/dist/core/compaction.d.ts.map +1 -0
  165. package/dist/core/compaction.js +2 -0
  166. package/dist/core/compaction.js.map +1 -0
  167. package/dist/core/context-budget.d.ts +28 -0
  168. package/dist/core/context-budget.d.ts.map +1 -0
  169. package/dist/core/context-budget.js +108 -0
  170. package/dist/core/context-budget.js.map +1 -0
  171. package/dist/core/context.d.ts +16 -0
  172. package/dist/core/context.d.ts.map +1 -0
  173. package/dist/core/context.js +13 -0
  174. package/dist/core/context.js.map +1 -0
  175. package/dist/core/runtime.d.ts +394 -0
  176. package/dist/core/runtime.d.ts.map +1 -0
  177. package/dist/core/runtime.js +507 -0
  178. package/dist/core/runtime.js.map +1 -0
  179. package/dist/core/usage.d.ts +26 -0
  180. package/dist/core/usage.d.ts.map +1 -0
  181. package/dist/core/usage.js +133 -0
  182. package/dist/core/usage.js.map +1 -0
  183. package/dist/extensions/claude-extension-tools.d.ts +16 -0
  184. package/dist/extensions/claude-extension-tools.d.ts.map +1 -0
  185. package/dist/extensions/claude-extension-tools.js +78 -0
  186. package/dist/extensions/claude-extension-tools.js.map +1 -0
  187. package/dist/extensions/claude-extensions.d.ts +41 -0
  188. package/dist/extensions/claude-extensions.d.ts.map +1 -0
  189. package/dist/extensions/claude-extensions.js +270 -0
  190. package/dist/extensions/claude-extensions.js.map +1 -0
  191. package/dist/hooks/claude-hook-tools.d.ts +26 -0
  192. package/dist/hooks/claude-hook-tools.d.ts.map +1 -0
  193. package/dist/hooks/claude-hook-tools.js +129 -0
  194. package/dist/hooks/claude-hook-tools.js.map +1 -0
  195. package/dist/hooks/claude-hooks.d.ts +87 -0
  196. package/dist/hooks/claude-hooks.d.ts.map +1 -0
  197. package/dist/hooks/claude-hooks.js +411 -0
  198. package/dist/hooks/claude-hooks.js.map +1 -0
  199. package/dist/maintenance/doctor.d.ts +33 -0
  200. package/dist/maintenance/doctor.d.ts.map +1 -0
  201. package/dist/maintenance/doctor.js +391 -0
  202. package/dist/maintenance/doctor.js.map +1 -0
  203. package/dist/maintenance/self-update.d.ts +31 -0
  204. package/dist/maintenance/self-update.d.ts.map +1 -0
  205. package/dist/maintenance/self-update.js +81 -0
  206. package/dist/maintenance/self-update.js.map +1 -0
  207. package/dist/mcp/claude-mcp-management.d.ts +28 -0
  208. package/dist/mcp/claude-mcp-management.d.ts.map +1 -0
  209. package/dist/mcp/claude-mcp-management.js +169 -0
  210. package/dist/mcp/claude-mcp-management.js.map +1 -0
  211. package/dist/mcp/claude-mcp-oauth.d.ts +113 -0
  212. package/dist/mcp/claude-mcp-oauth.d.ts.map +1 -0
  213. package/dist/mcp/claude-mcp-oauth.js +1053 -0
  214. package/dist/mcp/claude-mcp-oauth.js.map +1 -0
  215. package/dist/mcp/claude-mcp-tools.d.ts +98 -0
  216. package/dist/mcp/claude-mcp-tools.d.ts.map +1 -0
  217. package/dist/mcp/claude-mcp-tools.js +1246 -0
  218. package/dist/mcp/claude-mcp-tools.js.map +1 -0
  219. package/dist/mcp/praxis-mcp-server.d.ts +35 -0
  220. package/dist/mcp/praxis-mcp-server.d.ts.map +1 -0
  221. package/dist/mcp/praxis-mcp-server.js +520 -0
  222. package/dist/mcp/praxis-mcp-server.js.map +1 -0
  223. package/dist/permissions/claude-auto-classifier.d.ts +20 -0
  224. package/dist/permissions/claude-auto-classifier.d.ts.map +1 -0
  225. package/dist/permissions/claude-auto-classifier.js +140 -0
  226. package/dist/permissions/claude-auto-classifier.js.map +1 -0
  227. package/dist/permissions/claude-permission-resolver.d.ts +30 -0
  228. package/dist/permissions/claude-permission-resolver.d.ts.map +1 -0
  229. package/dist/permissions/claude-permission-resolver.js +334 -0
  230. package/dist/permissions/claude-permission-resolver.js.map +1 -0
  231. package/dist/persistence/claude-job-store.d.ts +68 -0
  232. package/dist/persistence/claude-job-store.d.ts.map +1 -0
  233. package/dist/persistence/claude-job-store.js +311 -0
  234. package/dist/persistence/claude-job-store.js.map +1 -0
  235. package/dist/persistence/claude-scheduled-task-store.d.ts +29 -0
  236. package/dist/persistence/claude-scheduled-task-store.d.ts.map +1 -0
  237. package/dist/persistence/claude-scheduled-task-store.js +163 -0
  238. package/dist/persistence/claude-scheduled-task-store.js.map +1 -0
  239. package/dist/persistence/claude-sidechain-store.d.ts +18 -0
  240. package/dist/persistence/claude-sidechain-store.d.ts.map +1 -0
  241. package/dist/persistence/claude-sidechain-store.js +107 -0
  242. package/dist/persistence/claude-sidechain-store.js.map +1 -0
  243. package/dist/persistence/claude-task-store.d.ts +72 -0
  244. package/dist/persistence/claude-task-store.d.ts.map +1 -0
  245. package/dist/persistence/claude-task-store.js +440 -0
  246. package/dist/persistence/claude-task-store.js.map +1 -0
  247. package/dist/persistence/claude-transcript-store.d.ts +85 -0
  248. package/dist/persistence/claude-transcript-store.d.ts.map +1 -0
  249. package/dist/persistence/claude-transcript-store.js +385 -0
  250. package/dist/persistence/claude-transcript-store.js.map +1 -0
  251. package/dist/persistence/claude-workflow-store.d.ts +41 -0
  252. package/dist/persistence/claude-workflow-store.d.ts.map +1 -0
  253. package/dist/persistence/claude-workflow-store.js +263 -0
  254. package/dist/persistence/claude-workflow-store.js.map +1 -0
  255. package/dist/persistence/in-memory-sidechain-store.d.ts +12 -0
  256. package/dist/persistence/in-memory-sidechain-store.d.ts.map +1 -0
  257. package/dist/persistence/in-memory-sidechain-store.js +30 -0
  258. package/dist/persistence/in-memory-sidechain-store.js.map +1 -0
  259. package/dist/persistence/in-memory-transcript-store.d.ts +15 -0
  260. package/dist/persistence/in-memory-transcript-store.d.ts.map +1 -0
  261. package/dist/persistence/in-memory-transcript-store.js +95 -0
  262. package/dist/persistence/in-memory-transcript-store.js.map +1 -0
  263. package/dist/platform/atomic-write.d.ts +5 -0
  264. package/dist/platform/atomic-write.d.ts.map +1 -0
  265. package/dist/platform/atomic-write.js +25 -0
  266. package/dist/platform/atomic-write.js.map +1 -0
  267. package/dist/platform/bounded-process-runner.d.ts +28 -0
  268. package/dist/platform/bounded-process-runner.d.ts.map +1 -0
  269. package/dist/platform/bounded-process-runner.js +209 -0
  270. package/dist/platform/bounded-process-runner.js.map +1 -0
  271. package/dist/platform/claude-version.d.ts +5 -0
  272. package/dist/platform/claude-version.d.ts.map +1 -0
  273. package/dist/platform/claude-version.js +17 -0
  274. package/dist/platform/claude-version.js.map +1 -0
  275. package/dist/platform/command-shell.d.ts +3 -0
  276. package/dist/platform/command-shell.d.ts.map +1 -0
  277. package/dist/platform/command-shell.js +15 -0
  278. package/dist/platform/command-shell.js.map +1 -0
  279. package/dist/platform/exclusive-file-lease.d.ts +15 -0
  280. package/dist/platform/exclusive-file-lease.d.ts.map +1 -0
  281. package/dist/platform/exclusive-file-lease.js +265 -0
  282. package/dist/platform/exclusive-file-lease.js.map +1 -0
  283. package/dist/platform/sensitive-data.d.ts +8 -0
  284. package/dist/platform/sensitive-data.d.ts.map +1 -0
  285. package/dist/platform/sensitive-data.js +138 -0
  286. package/dist/platform/sensitive-data.js.map +1 -0
  287. package/dist/platform/tmux-worktree.d.ts +30 -0
  288. package/dist/platform/tmux-worktree.d.ts.map +1 -0
  289. package/dist/platform/tmux-worktree.js +138 -0
  290. package/dist/platform/tmux-worktree.js.map +1 -0
  291. package/dist/plugins/claude-plugin-eval-discovery.d.ts +20 -0
  292. package/dist/plugins/claude-plugin-eval-discovery.d.ts.map +1 -0
  293. package/dist/plugins/claude-plugin-eval-discovery.js +128 -0
  294. package/dist/plugins/claude-plugin-eval-discovery.js.map +1 -0
  295. package/dist/plugins/claude-plugin-eval-graders.d.ts +49 -0
  296. package/dist/plugins/claude-plugin-eval-graders.d.ts.map +1 -0
  297. package/dist/plugins/claude-plugin-eval-graders.js +137 -0
  298. package/dist/plugins/claude-plugin-eval-graders.js.map +1 -0
  299. package/dist/plugins/claude-plugin-eval-runner.d.ts +50 -0
  300. package/dist/plugins/claude-plugin-eval-runner.d.ts.map +1 -0
  301. package/dist/plugins/claude-plugin-eval-runner.js +189 -0
  302. package/dist/plugins/claude-plugin-eval-runner.js.map +1 -0
  303. package/dist/plugins/claude-plugin-eval-schema.d.ts +80 -0
  304. package/dist/plugins/claude-plugin-eval-schema.d.ts.map +1 -0
  305. package/dist/plugins/claude-plugin-eval-schema.js +436 -0
  306. package/dist/plugins/claude-plugin-eval-schema.js.map +1 -0
  307. package/dist/plugins/claude-plugin-eval.d.ts +66 -0
  308. package/dist/plugins/claude-plugin-eval.d.ts.map +1 -0
  309. package/dist/plugins/claude-plugin-eval.js +438 -0
  310. package/dist/plugins/claude-plugin-eval.js.map +1 -0
  311. package/dist/plugins/claude-plugin-maintenance.d.ts +39 -0
  312. package/dist/plugins/claude-plugin-maintenance.d.ts.map +1 -0
  313. package/dist/plugins/claude-plugin-maintenance.js +336 -0
  314. package/dist/plugins/claude-plugin-maintenance.js.map +1 -0
  315. package/dist/plugins/claude-plugin-marketplace.d.ts +97 -0
  316. package/dist/plugins/claude-plugin-marketplace.d.ts.map +1 -0
  317. package/dist/plugins/claude-plugin-marketplace.js +1433 -0
  318. package/dist/plugins/claude-plugin-marketplace.js.map +1 -0
  319. package/dist/plugins/claude-plugin-mcpb.d.ts +71 -0
  320. package/dist/plugins/claude-plugin-mcpb.d.ts.map +1 -0
  321. package/dist/plugins/claude-plugin-mcpb.js +885 -0
  322. package/dist/plugins/claude-plugin-mcpb.js.map +1 -0
  323. package/dist/plugins/claude-plugin-runtime.d.ts +120 -0
  324. package/dist/plugins/claude-plugin-runtime.d.ts.map +1 -0
  325. package/dist/plugins/claude-plugin-runtime.js +1263 -0
  326. package/dist/plugins/claude-plugin-runtime.js.map +1 -0
  327. package/dist/providers/anthropic-compatible.d.ts +35 -0
  328. package/dist/providers/anthropic-compatible.d.ts.map +1 -0
  329. package/dist/providers/anthropic-compatible.js +733 -0
  330. package/dist/providers/anthropic-compatible.js.map +1 -0
  331. package/dist/providers/environment.d.ts +14 -0
  332. package/dist/providers/environment.d.ts.map +1 -0
  333. package/dist/providers/environment.js +67 -0
  334. package/dist/providers/environment.js.map +1 -0
  335. package/dist/providers/fallback-provider.d.ts +17 -0
  336. package/dist/providers/fallback-provider.d.ts.map +1 -0
  337. package/dist/providers/fallback-provider.js +70 -0
  338. package/dist/providers/fallback-provider.js.map +1 -0
  339. package/dist/providers/openai-compatible.d.ts +30 -0
  340. package/dist/providers/openai-compatible.d.ts.map +1 -0
  341. package/dist/providers/openai-compatible.js +409 -0
  342. package/dist/providers/openai-compatible.js.map +1 -0
  343. package/dist/tools/claude-interactive-tools.d.ts +58 -0
  344. package/dist/tools/claude-interactive-tools.d.ts.map +1 -0
  345. package/dist/tools/claude-interactive-tools.js +390 -0
  346. package/dist/tools/claude-interactive-tools.js.map +1 -0
  347. package/dist/tools/claude-lsp-formatters.d.ts +2 -0
  348. package/dist/tools/claude-lsp-formatters.d.ts.map +1 -0
  349. package/dist/tools/claude-lsp-formatters.js +291 -0
  350. package/dist/tools/claude-lsp-formatters.js.map +1 -0
  351. package/dist/tools/claude-lsp-tool.d.ts +22 -0
  352. package/dist/tools/claude-lsp-tool.d.ts.map +1 -0
  353. package/dist/tools/claude-lsp-tool.js +744 -0
  354. package/dist/tools/claude-lsp-tool.js.map +1 -0
  355. package/dist/tools/claude-scheduled-tools.d.ts +20 -0
  356. package/dist/tools/claude-scheduled-tools.d.ts.map +1 -0
  357. package/dist/tools/claude-scheduled-tools.js +344 -0
  358. package/dist/tools/claude-scheduled-tools.js.map +1 -0
  359. package/dist/tools/claude-task-tools.d.ts +30 -0
  360. package/dist/tools/claude-task-tools.d.ts.map +1 -0
  361. package/dist/tools/claude-task-tools.js +503 -0
  362. package/dist/tools/claude-task-tools.js.map +1 -0
  363. package/dist/tools/claude-user-message.d.ts +16 -0
  364. package/dist/tools/claude-user-message.d.ts.map +1 -0
  365. package/dist/tools/claude-user-message.js +98 -0
  366. package/dist/tools/claude-user-message.js.map +1 -0
  367. package/dist/tools/claude-workflow-tools.d.ts +27 -0
  368. package/dist/tools/claude-workflow-tools.d.ts.map +1 -0
  369. package/dist/tools/claude-workflow-tools.js +257 -0
  370. package/dist/tools/claude-workflow-tools.js.map +1 -0
  371. package/dist/tools/claude-worktree-tools.d.ts +17 -0
  372. package/dist/tools/claude-worktree-tools.d.ts.map +1 -0
  373. package/dist/tools/claude-worktree-tools.js +135 -0
  374. package/dist/tools/claude-worktree-tools.js.map +1 -0
  375. package/dist/tools/filtered-tool-registry.d.ts +16 -0
  376. package/dist/tools/filtered-tool-registry.d.ts.map +1 -0
  377. package/dist/tools/filtered-tool-registry.js +51 -0
  378. package/dist/tools/filtered-tool-registry.js.map +1 -0
  379. package/dist/tools/glob.d.ts +9 -0
  380. package/dist/tools/glob.d.ts.map +1 -0
  381. package/dist/tools/glob.js +88 -0
  382. package/dist/tools/glob.js.map +1 -0
  383. package/dist/tools/local-tools.d.ts +47 -0
  384. package/dist/tools/local-tools.d.ts.map +1 -0
  385. package/dist/tools/local-tools.js +1082 -0
  386. package/dist/tools/local-tools.js.map +1 -0
  387. package/dist/tools/notebook.d.ts +22 -0
  388. package/dist/tools/notebook.d.ts.map +1 -0
  389. package/dist/tools/notebook.js +154 -0
  390. package/dist/tools/notebook.js.map +1 -0
  391. package/dist/tools/web.d.ts +48 -0
  392. package/dist/tools/web.d.ts.map +1 -0
  393. package/dist/tools/web.js +726 -0
  394. package/dist/tools/web.js.map +1 -0
  395. package/package.json +145 -0
@@ -0,0 +1,744 @@
1
+ import { execFile, spawn, } from 'node:child_process';
2
+ import { readFile, realpath, stat } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import { extname, resolve, sep } from 'node:path';
5
+ import { pathToFileURL } from 'node:url';
6
+ import { promisify } from 'node:util';
7
+ import { redactSensitiveText, sanitizeChildEnvironment, sensitiveEnvironmentValues, } from '../platform/sensitive-data.js';
8
+ import { formatClaudeLspResult } from './claude-lsp-formatters.js';
9
+ const MAX_MESSAGE_BYTES = 8 * 1024 * 1024;
10
+ const MAX_RESULT_CHARS = 512 * 1024;
11
+ const MAX_FILE_BYTES = 10_000_000;
12
+ const REQUEST_TIMEOUT_MS = 15_000;
13
+ const execFileAsync = promisify(execFile);
14
+ const NO_CALL_HIERARCHY = Symbol('no-call-hierarchy');
15
+ function lspSensitiveValues(definition) {
16
+ return [
17
+ ...new Set([
18
+ ...sensitiveEnvironmentValues(definition.env),
19
+ ...(definition.sensitiveValues ?? []),
20
+ ]),
21
+ ]
22
+ .filter((value) => value.length > 0)
23
+ .sort((left, right) => right.length - left.length);
24
+ }
25
+ const LSP_DEFINITION = {
26
+ name: 'LSP',
27
+ description: `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
28
+
29
+ Supported operations:
30
+ - goToDefinition: Find where a symbol is defined
31
+ - findReferences: Find all references to a symbol
32
+ - hover: Get hover information (documentation, type info) for a symbol
33
+ - documentSymbol: Get all symbols (functions, classes, variables) in a document
34
+ - workspaceSymbol: Search for symbols matching a query across the entire workspace
35
+ - goToImplementation: Find implementations of an interface or abstract method
36
+ - prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)
37
+ - incomingCalls: Find all functions/methods that call the function at a position
38
+ - outgoingCalls: Find all functions/methods called by the function at a position
39
+
40
+ All operations require:
41
+ - filePath: The file to operate on
42
+ - line: The line number (1-based, as shown in editors)
43
+ - character: The character offset (1-based, as shown in editors)
44
+
45
+ The workspaceSymbol operation also takes:
46
+ - query: The symbol name or partial name to search for. Always provide it — most language servers return no results for an empty query.
47
+
48
+ Note: LSP servers must be configured for the file type. If no server is available, an error will be returned.`,
49
+ inputSchema: {
50
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
51
+ type: 'object',
52
+ properties: {
53
+ operation: {
54
+ description: 'The LSP operation to perform',
55
+ type: 'string',
56
+ enum: [
57
+ 'goToDefinition',
58
+ 'findReferences',
59
+ 'hover',
60
+ 'documentSymbol',
61
+ 'workspaceSymbol',
62
+ 'goToImplementation',
63
+ 'prepareCallHierarchy',
64
+ 'incomingCalls',
65
+ 'outgoingCalls',
66
+ ],
67
+ },
68
+ filePath: {
69
+ description: 'The absolute or relative path to the file',
70
+ type: 'string',
71
+ },
72
+ line: {
73
+ description: 'The line number (1-based, as shown in editors)',
74
+ type: 'integer',
75
+ exclusiveMinimum: 0,
76
+ maximum: Number.MAX_SAFE_INTEGER,
77
+ },
78
+ character: {
79
+ description: 'The character offset (1-based, as shown in editors)',
80
+ type: 'integer',
81
+ exclusiveMinimum: 0,
82
+ maximum: Number.MAX_SAFE_INTEGER,
83
+ },
84
+ query: {
85
+ description: 'The symbol name or partial name to search for (workspaceSymbol only). Most language servers return no results for an empty query, so always provide it when using workspaceSymbol.',
86
+ type: 'string',
87
+ },
88
+ },
89
+ required: ['operation', 'filePath', 'line', 'character'],
90
+ additionalProperties: false,
91
+ },
92
+ };
93
+ const OPERATIONS = new Set(LSP_DEFINITION.inputSchema.properties.operation.enum);
94
+ class LspResponseError extends Error {
95
+ code;
96
+ constructor(code, message) {
97
+ super(message);
98
+ this.code = code;
99
+ }
100
+ }
101
+ function inputFrom(value) {
102
+ const allowed = new Set([
103
+ 'operation',
104
+ 'filePath',
105
+ 'line',
106
+ 'character',
107
+ 'query',
108
+ ]);
109
+ for (const key of Object.keys(value)) {
110
+ if (!allowed.has(key))
111
+ throw new Error(`Unknown LSP input field ${key}`);
112
+ }
113
+ if (typeof value.operation !== 'string' || !OPERATIONS.has(value.operation)) {
114
+ throw new Error('LSP operation is invalid');
115
+ }
116
+ if (typeof value.filePath !== 'string' ||
117
+ value.filePath.trim().length === 0) {
118
+ throw new Error('LSP filePath must be a non-empty string');
119
+ }
120
+ for (const key of ['line', 'character']) {
121
+ if (!Number.isSafeInteger(value[key]) || Number(value[key]) <= 0) {
122
+ throw new Error(`LSP ${key} must be a positive integer`);
123
+ }
124
+ }
125
+ if (value.operation === 'workspaceSymbol' &&
126
+ (typeof value.query !== 'string' || value.query.trim().length === 0)) {
127
+ throw new Error('LSP workspaceSymbol requires a non-empty query');
128
+ }
129
+ if (value.query !== undefined && typeof value.query !== 'string') {
130
+ throw new Error('LSP query must be a string');
131
+ }
132
+ return {
133
+ operation: value.operation,
134
+ filePath: value.filePath.trim(),
135
+ line: Number(value.line),
136
+ character: Number(value.character),
137
+ ...(value.query === undefined ? {} : { query: value.query }),
138
+ };
139
+ }
140
+ function framed(value) {
141
+ const body = Buffer.from(JSON.stringify(value), 'utf8');
142
+ return Buffer.concat([
143
+ Buffer.from(`Content-Length: ${body.length}\r\n\r\n`, 'ascii'),
144
+ body,
145
+ ]);
146
+ }
147
+ function resultUri(operation, value) {
148
+ if (!value || typeof value !== 'object')
149
+ return undefined;
150
+ const item = value;
151
+ if (operation === 'workspaceSymbol') {
152
+ const location = item.location;
153
+ return location && typeof location === 'object'
154
+ ? location.uri
155
+ : undefined;
156
+ }
157
+ if (typeof item.targetUri === 'string')
158
+ return item.targetUri;
159
+ return typeof item.uri === 'string' ? item.uri : undefined;
160
+ }
161
+ function uriPath(uri) {
162
+ let path = uri.replace(/^file:\/\//u, '');
163
+ if (/^\/[A-Za-z]:/u.test(path))
164
+ path = path.slice(1);
165
+ try {
166
+ return decodeURIComponent(path);
167
+ }
168
+ catch {
169
+ return path;
170
+ }
171
+ }
172
+ async function gitIgnoredPaths(paths, cwd) {
173
+ const ignored = new Set();
174
+ for (let index = 0; index < paths.length; index += 50) {
175
+ const batch = paths.slice(index, index + 50);
176
+ try {
177
+ const { stdout } = await execFileAsync('git', ['check-ignore', ...batch], { cwd, timeout: 5_000, maxBuffer: 1024 * 1024 });
178
+ for (const line of stdout.split('\n')) {
179
+ if (line.trim())
180
+ ignored.add(line.trim());
181
+ }
182
+ }
183
+ catch (error) {
184
+ const result = error;
185
+ for (const line of (result.stdout ?? '').split('\n')) {
186
+ if (line.trim())
187
+ ignored.add(line.trim());
188
+ }
189
+ }
190
+ }
191
+ return ignored;
192
+ }
193
+ async function filterGitIgnoredResult(operation, result, cwd) {
194
+ if (!Array.isArray(result) ||
195
+ ![
196
+ 'findReferences',
197
+ 'goToDefinition',
198
+ 'goToImplementation',
199
+ 'workspaceSymbol',
200
+ ].includes(operation)) {
201
+ return result;
202
+ }
203
+ const pathsByUri = new Map();
204
+ for (const value of result) {
205
+ const uri = resultUri(operation, value);
206
+ if (uri && !pathsByUri.has(uri))
207
+ pathsByUri.set(uri, uriPath(uri));
208
+ }
209
+ const ignored = await gitIgnoredPaths([...new Set(pathsByUri.values())], cwd);
210
+ if (ignored.size === 0)
211
+ return result;
212
+ return result.filter((value) => {
213
+ const uri = resultUri(operation, value);
214
+ const path = uri ? pathsByUri.get(uri) : undefined;
215
+ return !path || !ignored.has(path);
216
+ });
217
+ }
218
+ class LspConnection {
219
+ definition;
220
+ cwd;
221
+ child;
222
+ nextId = 1;
223
+ buffer = Buffer.alloc(0);
224
+ pending = new Map();
225
+ documents = new Map();
226
+ stderr = '';
227
+ exited = false;
228
+ initialized = false;
229
+ constructor(definition, cwd, child) {
230
+ this.definition = definition;
231
+ this.cwd = cwd;
232
+ this.child = child;
233
+ child.stdout.on('data', (chunk) => this.onData(chunk));
234
+ child.stdin.on('error', (error) => this.fail(error));
235
+ child.stderr.on('data', (chunk) => {
236
+ this.stderr = `${this.stderr}${chunk.toString('utf8')}`.slice(-64 * 1024);
237
+ });
238
+ child.once('error', (error) => this.fail(error));
239
+ child.once('close', (code, signal) => {
240
+ this.exited = true;
241
+ this.fail(new Error(`LSP server ${definition.name} exited${signal ? ` with ${signal}` : ` with code ${code ?? 'unknown'}`}${this.stderr ? `: ${this.redactedStderr()}` : ''}`));
242
+ });
243
+ }
244
+ redactedStderr() {
245
+ return redactSensitiveText(this.stderr, lspSensitiveValues(this.definition));
246
+ }
247
+ isRunning() {
248
+ return !this.exited;
249
+ }
250
+ fail(error) {
251
+ for (const [id, pending] of this.pending) {
252
+ this.cleanupPending(id, pending);
253
+ pending.reject(error);
254
+ }
255
+ }
256
+ cleanupPending(id, pending) {
257
+ clearTimeout(pending.timer);
258
+ if (pending.signal && pending.abort) {
259
+ pending.signal.removeEventListener('abort', pending.abort);
260
+ }
261
+ this.pending.delete(id);
262
+ }
263
+ onData(chunk) {
264
+ this.buffer = Buffer.concat([this.buffer, chunk]);
265
+ if (this.buffer.length > MAX_MESSAGE_BYTES) {
266
+ this.fail(new Error(`LSP server ${this.definition.name} output exceeded 8 MiB`));
267
+ this.child.kill('SIGTERM');
268
+ return;
269
+ }
270
+ while (true) {
271
+ const headerEnd = this.buffer.indexOf('\r\n\r\n');
272
+ if (headerEnd < 0)
273
+ return;
274
+ const header = this.buffer.subarray(0, headerEnd).toString('ascii');
275
+ const length = /(?:^|\r\n)Content-Length:\s*(\d+)/iu.exec(header)?.[1];
276
+ if (!length) {
277
+ this.fail(new Error(`LSP server ${this.definition.name} sent invalid headers`));
278
+ this.child.kill('SIGTERM');
279
+ return;
280
+ }
281
+ const bytes = Number(length);
282
+ if (!Number.isSafeInteger(bytes) || bytes > MAX_MESSAGE_BYTES) {
283
+ this.fail(new Error(`LSP server ${this.definition.name} message is too large`));
284
+ this.child.kill('SIGTERM');
285
+ return;
286
+ }
287
+ const bodyStart = headerEnd + 4;
288
+ if (this.buffer.length < bodyStart + bytes)
289
+ return;
290
+ const body = this.buffer.subarray(bodyStart, bodyStart + bytes);
291
+ this.buffer = this.buffer.subarray(bodyStart + bytes);
292
+ let message;
293
+ try {
294
+ message = JSON.parse(body.toString('utf8'));
295
+ }
296
+ catch {
297
+ this.fail(new Error(`LSP server ${this.definition.name} sent invalid JSON`));
298
+ this.child.kill('SIGTERM');
299
+ return;
300
+ }
301
+ this.onMessage(message);
302
+ }
303
+ }
304
+ onMessage(message) {
305
+ if (!message || typeof message !== 'object' || Array.isArray(message))
306
+ return;
307
+ const value = message;
308
+ if (value.id !== undefined && typeof value.method === 'string') {
309
+ const result = value.method === 'workspace/configuration' &&
310
+ value.params &&
311
+ typeof value.params === 'object' &&
312
+ Array.isArray(value.params.items)
313
+ ? value.params.items.map(() => null)
314
+ : null;
315
+ this.send({ jsonrpc: '2.0', id: value.id, result });
316
+ return;
317
+ }
318
+ if (typeof value.id === 'number' && this.pending.has(value.id)) {
319
+ const pending = this.pending.get(value.id);
320
+ if (!pending)
321
+ return;
322
+ this.cleanupPending(value.id, pending);
323
+ if (value.error && typeof value.error === 'object') {
324
+ const error = value.error;
325
+ pending.reject(new LspResponseError(typeof error.code === 'number' ? error.code : undefined, `LSP ${this.definition.name} error ${String(error.code ?? '')}: ${String(error.message ?? 'unknown error')}`));
326
+ }
327
+ else
328
+ pending.resolve(value.result);
329
+ return;
330
+ }
331
+ }
332
+ send(value) {
333
+ if (this.exited || !this.child.stdin.writable) {
334
+ throw new Error(`LSP server ${this.definition.name} is not running`);
335
+ }
336
+ this.child.stdin.write(framed(value));
337
+ }
338
+ request(method, params, signal, timeoutMs = REQUEST_TIMEOUT_MS) {
339
+ if (signal?.aborted)
340
+ return Promise.reject(new Error('LSP request cancelled'));
341
+ const id = this.nextId++;
342
+ return new Promise((resolveRequest, rejectRequest) => {
343
+ const pending = {
344
+ resolve: resolveRequest,
345
+ reject: rejectRequest,
346
+ timer: setTimeout(() => {
347
+ this.cleanupPending(id, pending);
348
+ try {
349
+ this.send({
350
+ jsonrpc: '2.0',
351
+ method: '$/cancelRequest',
352
+ params: { id },
353
+ });
354
+ }
355
+ catch {
356
+ // Timeout remains the terminal result if the server also exited.
357
+ }
358
+ rejectRequest(new Error(`LSP ${method} timed out after ${timeoutMs}ms`));
359
+ }, timeoutMs),
360
+ ...(signal ? { signal } : {}),
361
+ };
362
+ if (signal) {
363
+ pending.abort = () => {
364
+ this.cleanupPending(id, pending);
365
+ try {
366
+ this.send({
367
+ jsonrpc: '2.0',
368
+ method: '$/cancelRequest',
369
+ params: { id },
370
+ });
371
+ }
372
+ catch {
373
+ // Process exit already provides the terminal outcome.
374
+ }
375
+ rejectRequest(new Error('LSP request cancelled'));
376
+ };
377
+ signal.addEventListener('abort', pending.abort, { once: true });
378
+ }
379
+ this.pending.set(id, pending);
380
+ try {
381
+ this.send({ jsonrpc: '2.0', id, method, params });
382
+ }
383
+ catch (error) {
384
+ this.cleanupPending(id, pending);
385
+ rejectRequest(error instanceof Error ? error : new Error(String(error)));
386
+ }
387
+ });
388
+ }
389
+ notify(method, params) {
390
+ this.send({ jsonrpc: '2.0', method, params });
391
+ }
392
+ async operationRequest(method, params, signal) {
393
+ for (let attempt = 0;; attempt += 1) {
394
+ try {
395
+ return await this.request(method, params, signal);
396
+ }
397
+ catch (error) {
398
+ if (!(error instanceof LspResponseError) ||
399
+ error.code !== -32801 ||
400
+ attempt >= 3) {
401
+ throw error;
402
+ }
403
+ await new Promise((resolveDelay, rejectDelay) => {
404
+ const finish = () => {
405
+ signal?.removeEventListener('abort', abort);
406
+ resolveDelay();
407
+ };
408
+ const timer = setTimeout(finish, 500 * 2 ** attempt);
409
+ const abort = () => {
410
+ clearTimeout(timer);
411
+ signal?.removeEventListener('abort', abort);
412
+ rejectDelay(new Error('LSP request cancelled'));
413
+ };
414
+ if (signal?.aborted)
415
+ abort();
416
+ else
417
+ signal?.addEventListener('abort', abort, { once: true });
418
+ });
419
+ }
420
+ }
421
+ }
422
+ async initialize(signal) {
423
+ if (this.initialized)
424
+ return;
425
+ const rootUri = pathToFileURL(this.cwd).href;
426
+ await this.request('initialize', {
427
+ processId: process.pid,
428
+ rootPath: this.cwd,
429
+ rootUri,
430
+ workspaceFolders: [{ uri: rootUri, name: this.cwd.split(sep).at(-1) }],
431
+ capabilities: {
432
+ workspace: {
433
+ configuration: false,
434
+ workspaceFolders: false,
435
+ },
436
+ textDocument: {
437
+ synchronization: {
438
+ dynamicRegistration: false,
439
+ willSave: false,
440
+ willSaveWaitUntil: false,
441
+ didSave: true,
442
+ },
443
+ publishDiagnostics: {
444
+ relatedInformation: true,
445
+ tagSupport: { valueSet: [1, 2] },
446
+ versionSupport: false,
447
+ codeDescriptionSupport: true,
448
+ dataSupport: false,
449
+ },
450
+ hover: {
451
+ dynamicRegistration: false,
452
+ contentFormat: ['markdown', 'plaintext'],
453
+ },
454
+ definition: { dynamicRegistration: false, linkSupport: true },
455
+ references: { dynamicRegistration: false },
456
+ documentSymbol: {
457
+ dynamicRegistration: false,
458
+ hierarchicalDocumentSymbolSupport: true,
459
+ },
460
+ callHierarchy: { dynamicRegistration: false },
461
+ },
462
+ general: { positionEncodings: ['utf-16'] },
463
+ },
464
+ initializationOptions: this.definition.initializationOptions ?? {},
465
+ }, signal, this.definition.startupTimeout ?? REQUEST_TIMEOUT_MS);
466
+ this.notify('initialized', {});
467
+ if (this.definition.settings !== undefined) {
468
+ this.notify('workspace/didChangeConfiguration', {
469
+ settings: this.definition.settings,
470
+ });
471
+ }
472
+ this.initialized = true;
473
+ }
474
+ async openDocument(filePath, languageId) {
475
+ const text = await readFile(filePath, 'utf8');
476
+ const current = this.documents.get(filePath);
477
+ const uri = pathToFileURL(filePath).href;
478
+ if (!current) {
479
+ this.documents.set(filePath, { text, version: 1 });
480
+ this.notify('textDocument/didOpen', {
481
+ textDocument: { uri, languageId, version: 1, text },
482
+ });
483
+ return;
484
+ }
485
+ if (current.text === text)
486
+ return;
487
+ const version = current.version + 1;
488
+ this.documents.set(filePath, { text, version });
489
+ this.notify('textDocument/didChange', {
490
+ textDocument: { uri, version },
491
+ contentChanges: [{ text }],
492
+ });
493
+ }
494
+ async execute(input, filePath, signal) {
495
+ const uri = pathToFileURL(filePath).href;
496
+ const position = { line: input.line - 1, character: input.character - 1 };
497
+ const textDocument = { uri };
498
+ const positional = { textDocument, position };
499
+ switch (input.operation) {
500
+ case 'goToDefinition':
501
+ return this.operationRequest('textDocument/definition', positional, signal);
502
+ case 'findReferences':
503
+ return this.operationRequest('textDocument/references', { ...positional, context: { includeDeclaration: true } }, signal);
504
+ case 'hover':
505
+ return this.operationRequest('textDocument/hover', positional, signal);
506
+ case 'documentSymbol':
507
+ return this.operationRequest('textDocument/documentSymbol', { textDocument }, signal);
508
+ case 'workspaceSymbol':
509
+ return this.operationRequest('workspace/symbol', { query: input.query }, signal);
510
+ case 'goToImplementation':
511
+ return this.operationRequest('textDocument/implementation', positional, signal);
512
+ case 'prepareCallHierarchy':
513
+ return this.operationRequest('textDocument/prepareCallHierarchy', positional, signal);
514
+ case 'incomingCalls':
515
+ case 'outgoingCalls': {
516
+ const prepared = await this.operationRequest('textDocument/prepareCallHierarchy', positional, signal);
517
+ if (!Array.isArray(prepared) || prepared.length === 0)
518
+ return NO_CALL_HIERARCHY;
519
+ const method = `callHierarchy/${input.operation}`;
520
+ return this.operationRequest(method, { item: prepared[0] }, signal);
521
+ }
522
+ default:
523
+ throw new Error(`Unsupported LSP operation ${input.operation}`);
524
+ }
525
+ }
526
+ async close() {
527
+ if (this.exited)
528
+ return;
529
+ const exited = new Promise((resolveExit) => {
530
+ this.child.once('close', () => resolveExit());
531
+ });
532
+ try {
533
+ if (this.initialized)
534
+ await this.request('shutdown', null, undefined, 1_000);
535
+ this.notify('exit', null);
536
+ }
537
+ catch {
538
+ // Forced termination below is the bounded fallback.
539
+ }
540
+ const voluntary = await Promise.race([
541
+ exited.then(() => true),
542
+ new Promise((resolveTimeout) => setTimeout(() => resolveTimeout(false), 100)),
543
+ ]);
544
+ if (voluntary)
545
+ return;
546
+ if (!this.exited)
547
+ this.child.kill('SIGTERM');
548
+ const graceful = await Promise.race([
549
+ exited.then(() => true),
550
+ new Promise((resolveTimeout) => setTimeout(() => resolveTimeout(false), 500)),
551
+ ]);
552
+ if (!graceful && !this.exited) {
553
+ this.child.kill('SIGKILL');
554
+ await exited;
555
+ }
556
+ }
557
+ }
558
+ export class ClaudeLspToolManager {
559
+ options;
560
+ connections = new Map();
561
+ initializing = new Map();
562
+ restartCounts = new Map();
563
+ constructor(options) {
564
+ this.options = options;
565
+ }
566
+ registry(base) {
567
+ return new ClaudeLspToolRegistry(base, this);
568
+ }
569
+ async validatedFile(inputPath) {
570
+ const cwd = this.options.cwdProvider();
571
+ const expanded = inputPath === '~'
572
+ ? homedir()
573
+ : inputPath.startsWith('~/')
574
+ ? resolve(homedir(), inputPath.slice(2))
575
+ : inputPath;
576
+ const filePath = resolve(cwd, expanded);
577
+ const canonicalPath = await realpath(filePath);
578
+ const roots = await Promise.all(this.options.roots().map(async (root) => {
579
+ try {
580
+ return await realpath(resolve(root));
581
+ }
582
+ catch {
583
+ return resolve(root);
584
+ }
585
+ }));
586
+ if (!roots.some((root) => canonicalPath === root || canonicalPath.startsWith(`${root}${sep}`))) {
587
+ throw new Error(`LSP path is outside allowed roots: ${inputPath}`);
588
+ }
589
+ const info = await stat(canonicalPath);
590
+ if (!info.isFile()) {
591
+ throw new Error(`LSP path is not a file: ${inputPath}`);
592
+ }
593
+ return { filePath, canonicalPath, size: info.size };
594
+ }
595
+ candidates(filePath) {
596
+ const extension = extname(filePath).toLowerCase();
597
+ return this.options.servers.filter((server) => Object.keys(server.extensionToLanguage).some((candidate) => candidate.toLowerCase() === extension));
598
+ }
599
+ languageId(definition, filePath) {
600
+ const extension = extname(filePath).toLowerCase();
601
+ return (Object.entries(definition.extensionToLanguage).find(([candidate]) => candidate.toLowerCase() === extension)?.[1] ?? '');
602
+ }
603
+ async connection(definition, signal) {
604
+ const runtimeCwd = await realpath(this.options.cwdProvider());
605
+ const serverCwd = await realpath(definition.workspaceFolder ?? runtimeCwd);
606
+ const key = `${runtimeCwd}\0${definition.pluginName}\0${definition.name}`;
607
+ const stale = [...this.connections.entries()].filter(([candidate]) => !candidate.startsWith(`${runtimeCwd}\0`));
608
+ for (const [candidate, connection] of stale) {
609
+ this.connections.delete(candidate);
610
+ this.initializing.delete(candidate);
611
+ this.restartCounts.delete(candidate);
612
+ await connection.close();
613
+ }
614
+ const initializing = this.initializing.get(key);
615
+ if (initializing)
616
+ return initializing;
617
+ const connection = this.connections.get(key);
618
+ if (connection?.isRunning())
619
+ return connection;
620
+ this.connections.delete(key);
621
+ const previousStarts = this.restartCounts.get(key);
622
+ const restartCount = previousStarts === undefined ? 0 : previousStarts + 1;
623
+ const maxRestarts = definition.maxRestarts ?? 3;
624
+ if (restartCount > maxRestarts) {
625
+ throw new Error(`LSP server '${definition.pluginName}:${definition.name}' exceeded max crash recovery attempts (${maxRestarts})`);
626
+ }
627
+ this.restartCounts.set(key, restartCount);
628
+ const starting = (async () => {
629
+ const child = spawn(definition.command, [...definition.args], {
630
+ cwd: serverCwd,
631
+ env: sanitizeChildEnvironment(definition.env, this.options.environment ?? process.env),
632
+ stdio: ['pipe', 'pipe', 'pipe'],
633
+ });
634
+ const created = new LspConnection(definition, serverCwd, child);
635
+ this.connections.set(key, created);
636
+ try {
637
+ await created.initialize(signal);
638
+ return created;
639
+ }
640
+ catch (error) {
641
+ if (this.connections.get(key) === created)
642
+ this.connections.delete(key);
643
+ await created.close();
644
+ throw error;
645
+ }
646
+ })();
647
+ this.initializing.set(key, starting);
648
+ try {
649
+ return await starting;
650
+ }
651
+ finally {
652
+ if (this.initializing.get(key) === starting)
653
+ this.initializing.delete(key);
654
+ }
655
+ }
656
+ async execute(call, context) {
657
+ try {
658
+ const input = inputFrom(call.input);
659
+ const cwd = await realpath(this.options.cwdProvider());
660
+ const { filePath, canonicalPath, size } = await this.validatedFile(input.filePath);
661
+ if (size > MAX_FILE_BYTES) {
662
+ return {
663
+ content: `File too large for LSP analysis (${Math.ceil(size / 1_000_000)}MB exceeds 10MB limit)`,
664
+ isError: false,
665
+ accessedPaths: [canonicalPath],
666
+ };
667
+ }
668
+ const candidates = this.candidates(filePath);
669
+ if (candidates.length === 0) {
670
+ return {
671
+ content: `No LSP server available for file type: ${extname(filePath)}`,
672
+ isError: false,
673
+ accessedPaths: [canonicalPath],
674
+ };
675
+ }
676
+ const failures = [];
677
+ for (const definition of candidates) {
678
+ try {
679
+ const connection = await this.connection(definition, context.signal);
680
+ await connection.openDocument(filePath, this.languageId(definition, filePath));
681
+ const result = await connection.execute(input, filePath, context.signal);
682
+ const filtered = await filterGitIgnoredResult(input.operation, result, cwd);
683
+ const content = redactSensitiveText(filtered === NO_CALL_HIERARCHY
684
+ ? 'No call hierarchy item found at this position'
685
+ : formatClaudeLspResult(input.operation, filtered, cwd), lspSensitiveValues(definition));
686
+ return {
687
+ content: content.length <= MAX_RESULT_CHARS
688
+ ? content
689
+ : `${content.slice(0, MAX_RESULT_CHARS)}\n… LSP result truncated`,
690
+ isError: false,
691
+ accessedPaths: [canonicalPath],
692
+ };
693
+ }
694
+ catch (error) {
695
+ const message = redactSensitiveText(error instanceof Error ? error.message : String(error), lspSensitiveValues(definition));
696
+ failures.push(`${definition.pluginName}:${definition.name}: ${message}`);
697
+ }
698
+ }
699
+ return {
700
+ content: `Error performing ${input.operation}: ${failures.join('; ')}`,
701
+ isError: false,
702
+ accessedPaths: [canonicalPath],
703
+ };
704
+ }
705
+ catch (error) {
706
+ return {
707
+ content: error instanceof Error ? error.message : String(error),
708
+ isError: true,
709
+ };
710
+ }
711
+ }
712
+ async close() {
713
+ const connections = [...this.connections.values()];
714
+ this.connections.clear();
715
+ this.initializing.clear();
716
+ this.restartCounts.clear();
717
+ const results = await Promise.allSettled(connections.map((connection) => connection.close()));
718
+ const failure = results.find((result) => result.status === 'rejected');
719
+ if (failure)
720
+ throw failure.reason;
721
+ }
722
+ }
723
+ class ClaudeLspToolRegistry {
724
+ base;
725
+ manager;
726
+ constructor(base, manager) {
727
+ this.base = base;
728
+ this.manager = manager;
729
+ }
730
+ definitions() {
731
+ return [...this.base.definitions(), LSP_DEFINITION];
732
+ }
733
+ prepare(call, context) {
734
+ return call.name === 'LSP'
735
+ ? Promise.resolve(call)
736
+ : this.base.prepare(call, context);
737
+ }
738
+ execute(call, context) {
739
+ return call.name === 'LSP'
740
+ ? this.manager.execute(call, context)
741
+ : this.base.execute(call, context);
742
+ }
743
+ }
744
+ //# sourceMappingURL=claude-lsp-tool.js.map