@mrclrchtr/supi-code-intelligence 4.10.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/README.md +4 -3
  2. package/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  3. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  4. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  6. package/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  8. package/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  9. package/node_modules/@mrclrchtr/supi-core/package.json +2 -2
  10. package/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
  11. package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  12. package/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  13. package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -6
  14. package/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
  15. package/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
  16. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  17. package/node_modules/@mrclrchtr/supi-lsp/README.md +111 -5
  18. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  19. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  20. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  21. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  22. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  23. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  24. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  25. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +2 -2
  26. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
  27. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  28. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  29. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -6
  30. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
  31. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
  32. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  33. package/node_modules/@mrclrchtr/supi-lsp/package.json +7 -6
  34. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +22 -1
  35. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +245 -0
  36. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +78 -0
  37. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +171 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +413 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +15 -0
  40. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +214 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +62 -0
  42. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +690 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +9 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +97 -16
  45. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +206 -0
  46. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +448 -298
  47. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +70 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +231 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-file-state.ts +25 -0
  50. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +529 -119
  51. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +161 -33
  52. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +12 -3
  53. package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +5 -5
  54. package/node_modules/@mrclrchtr/supi-lsp/src/config/defaults.json +1 -1
  55. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +3 -0
  56. package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-extends.ts +68 -0
  57. package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-path.ts +8 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +176 -24
  59. package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +45 -0
  60. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +42 -0
  61. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +46 -10
  62. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +79 -9
  63. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +17 -7
  64. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +350 -26
  65. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +5 -2
  66. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +586 -96
  67. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-refactor-provider.ts +130 -0
  68. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +45 -329
  69. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +57 -120
  70. package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-edit-normalizer.ts +320 -0
  71. package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +207 -0
  72. package/node_modules/@mrclrchtr/supi-lsp/src/session/readiness.ts +72 -2
  73. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +151 -26
  74. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +42 -0
  75. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +92 -0
  76. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +165 -118
  77. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +49 -0
  78. package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +102 -0
  79. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +17 -7
  80. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  81. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  82. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  83. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  84. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  85. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  86. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  87. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +2 -2
  88. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -6
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/LICENSE +21 -0
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/README.md +258 -0
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/babel.cjs +257 -0
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/jiti.cjs +1 -0
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-cli.mjs +34 -0
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-hooks.mjs +124 -0
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-native.mjs +121 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.d.mts +1 -0
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.mjs +4 -0
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-static.mjs +23 -0
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.cjs +30 -0
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.cts +8 -0
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.mts +8 -0
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.mjs +29 -0
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/types.d.ts +420 -0
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/package.json +146 -0
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -3
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +0 -9
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -8
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +16 -12
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +65 -87
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +47 -95
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-timing.ts +147 -0
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client-lifecycle.ts +39 -0
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +561 -0
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-message-size.ts +24 -0
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +452 -0
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +4 -2
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +12 -4
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +4 -2
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/imports.ts +4 -2
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +5 -3
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +33 -12
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/blocking-test-bootstrap.mjs +34 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/bootstrap.mjs +8 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store-helpers.ts +23 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +400 -0
  132. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/request-control.ts +48 -0
  133. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-parser-helpers.ts +24 -0
  134. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-query-helpers.ts +43 -0
  135. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +421 -0
  136. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +116 -0
  137. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +201 -0
  138. package/package.json +5 -5
  139. package/src/analysis/health/diagnostics.ts +221 -77
  140. package/src/analysis/health/file-scope.ts +184 -0
  141. package/src/analysis/health/recovery.ts +14 -3
  142. package/src/analysis/provider.ts +58 -0
  143. package/src/analysis/readiness.ts +34 -9
  144. package/src/analysis/refactor/apply.ts +45 -1
  145. package/src/analysis/refactor/mutation-authority.ts +143 -0
  146. package/src/analysis/relations/callees.ts +9 -1
  147. package/src/analysis/relations/types.ts +5 -2
  148. package/src/analysis/search/ast-scan-timing.ts +9 -2
  149. package/src/analysis/search/ast-scan.ts +5 -2
  150. package/src/analysis/search/deadline.ts +2 -2
  151. package/src/analysis/search/pattern-analysis.ts +54 -33
  152. package/src/analysis/search/pattern.ts +18 -3
  153. package/src/analysis/target/anchored.ts +20 -11
  154. package/src/analysis/target/file.ts +18 -11
  155. package/src/analysis/target/identity.ts +19 -3
  156. package/src/analysis/target/symbol.ts +36 -15
  157. package/src/api.ts +4 -0
  158. package/src/config.ts +35 -1
  159. package/src/diagnostics/evidence.ts +51 -0
  160. package/src/extension.ts +57 -14
  161. package/src/overview/overview-data.ts +9 -2
  162. package/src/overview/overview.ts +49 -30
  163. package/src/overview/types.ts +2 -0
  164. package/src/session/capability-adapter.ts +12 -3
  165. package/src/session/find-types.ts +2 -2
  166. package/src/session/find-workflow.ts +20 -9
  167. package/src/session/graph/collect.ts +18 -2
  168. package/src/session/graph-workflow.ts +19 -12
  169. package/src/session/health-refresh.ts +175 -0
  170. package/src/session/health-types.ts +43 -15
  171. package/src/session/health-workflow.ts +69 -54
  172. package/src/session/input/workflows.ts +2 -2
  173. package/src/session/inspect/collect.ts +20 -3
  174. package/src/session/inspect-workflow.ts +12 -6
  175. package/src/session/orientation/collect.ts +12 -3
  176. package/src/session/orientation/context-facts.ts +3 -1
  177. package/src/session/orientation/context-sections.ts +20 -7
  178. package/src/session/orientation/gather.ts +17 -11
  179. package/src/session/orientation-types.ts +4 -1
  180. package/src/session/orientation-workflow.ts +23 -10
  181. package/src/session/refactor-plans.ts +2 -0
  182. package/src/session/refactor-workflow.ts +61 -15
  183. package/src/session/session.ts +29 -2
  184. package/src/session/target-workflow.ts +54 -23
  185. package/src/session/workflow-control.ts +7 -3
  186. package/src/substrate/lsp/lifecycle.ts +26 -46
  187. package/src/substrate/lsp/maintenance.ts +284 -28
  188. package/src/substrate/lsp/recovery.ts +11 -5
  189. package/src/substrate/lsp/state.ts +2 -2
  190. package/src/substrate/workspace-provider-host.ts +25 -3
  191. package/src/tool/{find → code_find}/execute.ts +2 -16
  192. package/src/tool/code_find/guidance.ts +8 -0
  193. package/src/tool/{find → code_find}/render.ts +21 -4
  194. package/src/tool/{result/find.ts → code_find/result.ts} +78 -9
  195. package/src/tool/code_find/spec.ts +37 -0
  196. package/src/tool/code_find/tui.ts +41 -0
  197. package/src/tool/code_graph/execute.ts +24 -0
  198. package/src/tool/code_graph/guidance.ts +6 -0
  199. package/src/tool/{graph → code_graph}/markdown.ts +1 -1
  200. package/src/tool/{result/graph.ts → code_graph/result.ts} +111 -3
  201. package/src/tool/code_graph/spec.ts +39 -0
  202. package/src/tool/code_graph/tui.ts +117 -0
  203. package/src/tool/{health → code_health}/execute.ts +2 -13
  204. package/src/tool/code_health/guidance.ts +8 -0
  205. package/src/tool/{health → code_health}/markdown.ts +119 -27
  206. package/src/tool/code_health/refresh-status.ts +105 -0
  207. package/src/tool/{result/health.ts → code_health/result.ts} +80 -3
  208. package/src/tool/code_health/spec.ts +41 -0
  209. package/src/tool/{health → code_health}/tui.ts +95 -98
  210. package/src/tool/{inspect → code_inspect}/execute.ts +2 -16
  211. package/src/tool/code_inspect/guidance.ts +6 -0
  212. package/src/tool/{inspect → code_inspect}/markdown.ts +1 -1
  213. package/src/tool/{result/inspect.ts → code_inspect/result.ts} +143 -2
  214. package/src/tool/code_inspect/spec.ts +25 -0
  215. package/src/tool/code_inspect/tui.ts +44 -0
  216. package/src/tool/code_orientation/execute.ts +25 -0
  217. package/src/tool/code_orientation/guidance.ts +9 -0
  218. package/src/tool/{orientation → code_orientation}/markdown.ts +1 -1
  219. package/src/tool/code_orientation/result.ts +248 -0
  220. package/src/tool/code_orientation/spec.ts +25 -0
  221. package/src/tool/{orientation → code_orientation}/tui.ts +51 -35
  222. package/src/tool/code_refactor_apply/execute.ts +17 -0
  223. package/src/tool/code_refactor_apply/guidance.ts +5 -0
  224. package/src/tool/{refactor-apply/execute.ts → code_refactor_apply/result.ts} +8 -11
  225. package/src/tool/code_refactor_apply/spec.ts +26 -0
  226. package/src/tool/code_refactor_apply/tui.ts +73 -0
  227. package/src/tool/code_refactor_plan/execute.ts +27 -0
  228. package/src/tool/code_refactor_plan/guidance.ts +8 -0
  229. package/src/tool/{refactor-plan/execute.ts → code_refactor_plan/result.ts} +13 -22
  230. package/src/tool/code_refactor_plan/spec.ts +25 -0
  231. package/src/tool/code_refactor_plan/tui.ts +54 -0
  232. package/src/tool/code_resolve/execute.ts +19 -0
  233. package/src/tool/code_resolve/guidance.ts +8 -0
  234. package/src/tool/{resolve → code_resolve}/markdown.ts +1 -1
  235. package/src/tool/{result/resolve.ts → code_resolve/result.ts} +79 -29
  236. package/src/tool/code_resolve/spec.ts +25 -0
  237. package/src/tool/code_resolve/tui.ts +60 -0
  238. package/src/tool/guidance.ts +71 -52
  239. package/src/tool/infra/truncate.ts +40 -0
  240. package/src/tool/infra/workflow-control.ts +8 -0
  241. package/src/tool/{refactor-plan/markdown.ts → refactor-markdown.ts} +4 -7
  242. package/src/tool/register.ts +105 -88
  243. package/src/tool/result/display.ts +107 -0
  244. package/src/tool/result/errors.ts +20 -17
  245. package/src/tool/result/refactor.ts +37 -8
  246. package/src/tool/result/types.ts +20 -0
  247. package/src/tool/schemas.ts +26 -157
  248. package/src/tool/specs.ts +40 -126
  249. package/src/types/execution.ts +18 -5
  250. package/src/types/index.ts +8 -1
  251. package/src/ui/status-command.ts +5 -3
  252. package/src/ui/status-overlay.ts +4 -0
  253. package/src/ui/tui/common.ts +108 -10
  254. package/src/ui/tui/display.ts +48 -0
  255. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime.ts +0 -351
  256. package/src/tool/find/tui.ts +0 -39
  257. package/src/tool/graph/execute.ts +0 -62
  258. package/src/tool/graph/tui.ts +0 -104
  259. package/src/tool/inspect/tui.ts +0 -36
  260. package/src/tool/orientation/execute.ts +0 -62
  261. package/src/tool/refactor-apply/tui.ts +0 -55
  262. package/src/tool/refactor-plan/tui.ts +0 -41
  263. package/src/tool/resolve/execute.ts +0 -36
  264. package/src/tool/resolve/tui.ts +0 -42
  265. package/src/tool/result/orientation.ts +0 -132
  266. /package/src/tool/{find → code_find}/ast-kinds.ts +0 -0
  267. /package/src/tool/{find → code_find}/markdown.ts +0 -0
  268. /package/src/tool/{find → code_find}/modes.ts +0 -0
  269. /package/src/tool/{health → code_health}/semantic-state.ts +0 -0
@@ -8,23 +8,14 @@
8
8
  import type { CapabilityWarningReport } from "../../analysis/capability/capability-warnings.ts";
9
9
  import type {
10
10
  HealthData,
11
+ HealthDiagnosticObservation,
11
12
  HealthDiagnosticScope,
12
13
  HealthRefreshAttempt,
13
14
  HealthResultAssembly,
14
15
  HealthSection,
15
- } from "../result/health.ts";
16
+ } from "./result.ts";
16
17
  import { formatSemanticHealthState } from "./semantic-state.ts";
17
18
 
18
- export type {
19
- HealthData,
20
- HealthDiagnosticObservation,
21
- HealthDiagnosticScope,
22
- HealthRefreshAttempt,
23
- HealthRefreshState,
24
- HealthSection,
25
- SemanticHealthState,
26
- } from "../result/health.ts";
27
-
28
19
  export function renderHealthResult(result: HealthResultAssembly, cwd: string): string {
29
20
  const data = result.data;
30
21
  const lines: string[] = ["## Code Health", ""];
@@ -51,25 +42,33 @@ function renderRefreshStatus(
51
42
 
52
43
  switch (data.refresh.kind) {
53
44
  case "completed":
54
- lines.push(`**Diagnostic refresh**: ${completedRefreshText(data.refresh)}.`);
55
- lines.push(`**Stale assessment**: ${staleAssessmentText(data.refresh)}.`);
45
+ lines.push(
46
+ `**${refreshAttemptLabel(data.refresh)}**: ${asSentence(completedRefreshText(data.refresh))}`,
47
+ );
48
+ lines.push(`**Stale assessment**: ${asSentence(staleAssessmentText(data.refresh))}`);
56
49
  lines.push("");
57
50
  return;
58
- case "failed":
59
- lines.push(`**Diagnostic refresh**: failed — ${data.refresh.reason}`);
51
+ case "failed": {
52
+ const evidence = data.refresh.diagnosticEvidence
53
+ ? `; ${formatDiagnosticEvidence(data.refresh.diagnosticEvidence)}`
54
+ : "";
55
+ lines.push(
56
+ `**${refreshAttemptLabel(data.refresh)}**: failed — ${data.refresh.reason}${evidence}`,
57
+ );
60
58
  lines.push("");
61
59
  return;
60
+ }
62
61
  case "not-attempted":
63
- lines.push(`**Diagnostic refresh**: not attempted — ${data.refresh.reason}`);
62
+ lines.push(`**Diagnostic refresh attempt**: not started — ${data.refresh.reason}`);
64
63
  if (data.refresh.lastAttempt) renderLastAttempt(lines, data.refresh.lastAttempt, cwd);
65
64
  lines.push("");
66
65
  return;
67
66
  case "not-requested":
68
67
  if (data.refresh.lastAttempt) {
69
- renderLastAttempt(lines, data.refresh.lastAttempt, cwd);
68
+ renderRetainedAttempt(lines, data.refresh.lastAttempt, cwd);
70
69
  } else {
71
70
  lines.push(
72
- "**Diagnostic refresh**: not attempted this session. Use `refresh: true` to try one.",
71
+ "**Diagnostic refresh attempt**: not requested this session. Use `refresh: true` to try one.",
73
72
  );
74
73
  }
75
74
  lines.push("");
@@ -79,10 +78,19 @@ function renderRefreshStatus(
79
78
  function completedRefreshText(
80
79
  attempt: Extract<HealthRefreshAttempt, { kind: "completed" }>,
81
80
  ): string {
82
- if (attempt.attemptedActiveClients === 0 && attempt.restartedClients === 0) {
83
- return "completed no-op no active clients were targeted";
84
- }
85
- return `completed — ${attempt.attemptedActiveClients} active client${plural(attempt.attemptedActiveClients)} targeted, ${attempt.restartedClients} restarted`;
81
+ const base =
82
+ attempt.attemptedActiveClients === 0 && attempt.restartedClients === 0
83
+ ? "completed no-op — no active clients were targeted"
84
+ : `completed — ${attempt.attemptedActiveClients} active client${plural(attempt.attemptedActiveClients)} targeted, ${attempt.restartedClients} restarted`;
85
+ return attempt.operationScope === "workspace-runtime"
86
+ ? `${base}; ${formatDiagnosticEvidence(attempt.diagnosticEvidence)}`
87
+ : base;
88
+ }
89
+
90
+ function refreshAttemptLabel(attempt: Pick<HealthRefreshAttempt, "operationScope">): string {
91
+ return attempt.operationScope === "file-runtime"
92
+ ? "File LSP maintenance attempt"
93
+ : "Diagnostic refresh attempt";
86
94
  }
87
95
 
88
96
  function staleAssessmentText(
@@ -90,19 +98,40 @@ function staleAssessmentText(
90
98
  ): string {
91
99
  if (attempt.staleAssessment.warning) return attempt.staleAssessment.warning;
92
100
  const matches = `${attempt.staleAssessment.matchedFileCount} file${plural(attempt.staleAssessment.matchedFileCount)} match the stale-module heuristic`;
101
+ if (attempt.staleAssessment.scope === "file") {
102
+ return `${matches} in the requested file; workspace clustering was not assessed`;
103
+ }
93
104
  return attempt.staleAssessment.suspected
94
105
  ? `${matches}; a clustered stale-module pattern is suspected`
95
106
  : `${matches}; no clustered stale-module pattern is suspected`;
96
107
  }
97
108
 
98
109
  function renderLastAttempt(lines: string[], attempt: HealthRefreshAttempt, cwd: string): void {
99
- const outcome =
100
- attempt.kind === "completed" ? completedRefreshText(attempt) : `failed — ${attempt.reason}`;
110
+ const outcome = refreshAttemptOutcome(attempt);
111
+ const label = refreshAttemptLabel(attempt);
112
+ lines.push(
113
+ `**Previous ${label.toLowerCase()}**: ${asSentence(outcome)} Started ${formatElapsed(Date.now() - attempt.attemptedAt)}; requested ${formatDiagnosticScope(attempt.requestedDiagnosticScope, cwd)}; operation scope: ${refreshOperationScopeText(attempt)}.`,
114
+ );
115
+ }
116
+
117
+ function renderRetainedAttempt(lines: string[], attempt: HealthRefreshAttempt, cwd: string): void {
118
+ const label =
119
+ attempt.operationScope === "file-runtime" ? "File LSP maintenance" : "Diagnostic refresh";
101
120
  lines.push(
102
- `**Last diagnostic refresh attempt**: ${outcome}, started ${formatElapsed(Date.now() - attempt.attemptedAt)}; requested ${formatDiagnosticScope(attempt.requestedDiagnosticScope, cwd)}; operation scope: workspace runtime.`,
121
+ `**${label}**: not requested for this call. Previous attempt ${asSentence(refreshAttemptOutcome(attempt))} Started ${formatElapsed(Date.now() - attempt.attemptedAt)}; requested ${formatDiagnosticScope(attempt.requestedDiagnosticScope, cwd)}; operation scope: ${refreshOperationScopeText(attempt)}.`,
103
122
  );
104
123
  }
105
124
 
125
+ function refreshAttemptOutcome(attempt: HealthRefreshAttempt): string {
126
+ return attempt.kind === "completed"
127
+ ? completedRefreshText(attempt)
128
+ : `failed — ${attempt.reason}${attempt.diagnosticEvidence ? `; ${formatDiagnosticEvidence(attempt.diagnosticEvidence)}` : ""}`;
129
+ }
130
+
131
+ function refreshOperationScopeText(attempt: HealthRefreshAttempt): string {
132
+ return attempt.operationScope === "file-runtime" ? "file runtime" : "workspace runtime";
133
+ }
134
+
106
135
  function formatElapsed(milliseconds: number): string {
107
136
  const seconds = Math.max(0, Math.round(milliseconds / 1_000));
108
137
  if (seconds < 60) return `${seconds}s ago`;
@@ -143,6 +172,12 @@ function renderDiagnosticsSection(lines: string[], data: HealthData, cwd: string
143
172
  lines.push("Diagnostics were not requested.");
144
173
  } else {
145
174
  lines.push(`**Evidence scope**: ${formatDiagnosticScope(observation.scope, cwd)}.`);
175
+ renderFileScopeStatus(lines, observation, cwd);
176
+ // The evidence line is bounded by the client's tracked documents; a file
177
+ // created after the last refresh is pulled on the next pass. Labeling the
178
+ // bound prevents misreading a first-call partial as an exclusion verdict.
179
+ const bound = observation.scope.kind === "tracked-files" ? " (tracked-file bound)" : "";
180
+ lines.push(`**Evidence coverage**: ${formatDiagnosticEvidence(observation.evidence)}${bound}.`);
146
181
  lines.push("");
147
182
  renderDiagnosticObservation(lines, data, cwd);
148
183
  }
@@ -150,15 +185,68 @@ function renderDiagnosticsSection(lines: string[], data: HealthData, cwd: string
150
185
  lines.push("");
151
186
  }
152
187
 
188
+ /**
189
+ * Render the tsconfig coverage verdict for a single-file health request.
190
+ *
191
+ * Written in plain vocabulary (no basis terms) so a reader without tsconfig
192
+ * background can act on it: the sentence names the deciding config and states
193
+ * whether the file's errors are part of workspace diagnostics. The structured
194
+ * decision basis stays in the diagnostics.scope debug event.
195
+ */
196
+ function renderFileScopeStatus(
197
+ lines: string[],
198
+ observation: Extract<
199
+ HealthDiagnosticObservation,
200
+ { kind: "completed" | "partial" | "unavailable" }
201
+ >,
202
+ cwd: string,
203
+ ): void {
204
+ if (observation.scope.kind !== "file" || !observation.scopeStatus) return;
205
+
206
+ const decision = observation.scopeStatus;
207
+ switch (decision.status) {
208
+ case "included":
209
+ lines.push(
210
+ `**Tsconfig**: covered by ${formatConfigPath(decision.configPath, cwd)} — part of workspace diagnostics.`,
211
+ );
212
+ return;
213
+ case "excluded":
214
+ lines.push(
215
+ `**Tsconfig**: NOT covered by ${formatConfigPath(decision.configPath, cwd)} — not part of workspace diagnostics.`,
216
+ );
217
+ return;
218
+ case "no-config":
219
+ lines.push("**Tsconfig**: no tsconfig.json or jsconfig.json found — nothing filtered.");
220
+ return;
221
+ case "out-of-tree":
222
+ lines.push("**Tsconfig**: outside the project root — not part of workspace diagnostics.");
223
+ }
224
+ }
225
+
226
+ function formatConfigPath(configPath: string | null, cwd: string): string {
227
+ if (!configPath) return "no config";
228
+ return `\`${makeRelative(cwd, configPath)}\``;
229
+ }
230
+
231
+ function formatDiagnosticEvidence(evidence: {
232
+ requested: number;
233
+ confirmed: number;
234
+ unconfirmed: number;
235
+ failed: number;
236
+ removed: number;
237
+ }): string {
238
+ return `${evidence.requested} requested, ${evidence.confirmed} confirmed, ${evidence.unconfirmed} unconfirmed, ${evidence.failed} failed, ${evidence.removed} removed`;
239
+ }
240
+
153
241
  function renderDiagnosticObservation(lines: string[], data: HealthData, cwd: string): void {
154
242
  const observation = data.diagnostics;
155
243
  if (observation.kind === "not-requested") return;
156
244
  if (observation.kind === "unavailable") {
157
- lines.push(`Diagnostics unavailable — ${observation.reason}.`);
245
+ lines.push(`Diagnostics unavailable — ${asSentence(observation.reason)}`);
158
246
  return;
159
247
  }
160
248
  if (observation.kind === "partial") {
161
- lines.push(`Diagnostics partially collected — ${observation.reason}.`);
249
+ lines.push(`Diagnostics partially collected — ${asSentence(observation.reason)}`);
162
250
  if (observation.entries.length > 0) {
163
251
  lines.push("");
164
252
  lines.push("Partial results:");
@@ -173,6 +261,10 @@ function renderDiagnosticObservation(lines: string[], data: HealthData, cwd: str
173
261
  renderDiagnosticEntries(lines, data, cwd);
174
262
  }
175
263
 
264
+ function asSentence(text: string): string {
265
+ return /[.!?]$/.test(text) ? text : `${text}.`;
266
+ }
267
+
176
268
  function emptyDiagnosticText(scope: HealthDiagnosticScope, cwd: string): string {
177
269
  if (scope.kind === "file") {
178
270
  return `No errors or warnings found for \`${makeRelative(cwd, scope.path)}\`.`;
@@ -0,0 +1,105 @@
1
+ /** Render current and retained health refresh status for the TUI. */
2
+
3
+ export function readRefreshStatus(data: Record<string, unknown> | null): string | null {
4
+ const refresh = readRecord(data?.refresh);
5
+ if (!refresh) return null;
6
+
7
+ switch (refresh.kind) {
8
+ case "completed": {
9
+ const attempted = readNumber(refresh.attemptedActiveClients);
10
+ const restarted = readNumber(refresh.restartedClients);
11
+ const stale = readRecord(refresh.staleAssessment);
12
+ const noOp = attempted === 0 && restarted === 0;
13
+ const label = refreshAttemptLabel(refresh);
14
+ const base = noOp
15
+ ? `${label} completed no-op`
16
+ : `${label} completed: ${attempted} clients targeted, ${restarted} restarted`;
17
+ const evidence = formatDiagnosticEvidence(readRecord(refresh.diagnosticEvidence));
18
+ const withEvidence = evidence ? `${base}; ${evidence}` : base;
19
+ return stale?.suspected === true
20
+ ? `${withEvidence}; stale pattern suspected in ${readNumber(stale.matchedFileCount)} files`
21
+ : withEvidence;
22
+ }
23
+ case "failed": {
24
+ const evidence = formatDiagnosticEvidence(readRecord(refresh.diagnosticEvidence));
25
+ return `${refreshAttemptLabel(refresh)} failed${typeof refresh.reason === "string" ? `: ${refresh.reason}` : ""}${evidence ? `; ${evidence}` : ""}`;
26
+ }
27
+ case "not-attempted":
28
+ return `refresh attempt not started${formatLastRefreshSuffix(refresh)}`;
29
+ case "not-requested":
30
+ return `refresh not requested${formatLastRefreshSuffix(refresh)}`;
31
+ default:
32
+ return null;
33
+ }
34
+ }
35
+
36
+ export function readPreviousRefreshStatus(data: Record<string, unknown> | null): string | null {
37
+ const refresh = readRecord(data?.refresh);
38
+ if (!refresh || (refresh.kind !== "not-requested" && refresh.kind !== "not-attempted")) {
39
+ return null;
40
+ }
41
+ const attempt = readRecord(refresh.lastAttempt);
42
+ if (!attempt) return null;
43
+ const evidence = formatCompactDiagnosticEvidence(readRecord(attempt.diagnosticEvidence));
44
+ if (attempt.kind === "failed") {
45
+ return `last ${refreshAttemptLabel(attempt)} failed${evidence ? ` (${evidence})` : ""}`;
46
+ }
47
+ if (attempt.kind === "completed") {
48
+ return `last ${refreshAttemptLabel(attempt)} completed${evidence ? ` (${evidence})` : ""}`;
49
+ }
50
+ return null;
51
+ }
52
+
53
+ function refreshAttemptLabel(attempt: Record<string, unknown>): string {
54
+ return attempt.operationScope === "file-runtime" ? "file maintenance attempt" : "refresh attempt";
55
+ }
56
+
57
+ function formatLastRefreshSuffix(refresh: Record<string, unknown>): string {
58
+ const attempt = readRecord(refresh.lastAttempt);
59
+ if (!attempt) return "";
60
+ const evidence = formatDiagnosticEvidence(readRecord(attempt.diagnosticEvidence));
61
+ if (attempt.kind === "failed") {
62
+ const reason = typeof attempt.reason === "string" ? `: ${attempt.reason}` : "";
63
+ return `; last ${refreshAttemptLabel(attempt)} failed${reason}${evidence ? `; ${evidence}` : ""}`;
64
+ }
65
+ if (attempt.kind === "completed") {
66
+ return `; last ${refreshAttemptLabel(attempt)} completed${evidence ? `; ${evidence}` : ""}`;
67
+ }
68
+ return "";
69
+ }
70
+
71
+ function formatCompactDiagnosticEvidence(evidence: Record<string, unknown> | null): string | null {
72
+ const counts = readEvidenceCounts(evidence);
73
+ if (!counts) return null;
74
+ return `req ${counts[0]} · conf ${counts[1]} · unconf ${counts[2]} · failed ${counts[3]} · removed ${counts[4]}`;
75
+ }
76
+
77
+ function formatDiagnosticEvidence(evidence: Record<string, unknown> | null): string | null {
78
+ const counts = readEvidenceCounts(evidence);
79
+ if (!counts) return null;
80
+ return `${counts[0]} requested, ${counts[1]} confirmed, ${counts[2]} unconfirmed, ${counts[3]} failed, ${counts[4]} removed`;
81
+ }
82
+
83
+ function readEvidenceCounts(evidence: Record<string, unknown> | null): number[] | null {
84
+ if (!evidence) return null;
85
+ const counts = [
86
+ evidence.requested,
87
+ evidence.confirmed,
88
+ evidence.unconfirmed,
89
+ evidence.failed,
90
+ evidence.removed,
91
+ ];
92
+ return counts.every(isEvidenceCount) ? counts : null;
93
+ }
94
+
95
+ function isEvidenceCount(value: unknown): value is number {
96
+ return typeof value === "number" && Number.isInteger(value) && value >= 0;
97
+ }
98
+
99
+ function readRecord(value: unknown): Record<string, unknown> | null {
100
+ return typeof value === "object" && value !== null ? (value as Record<string, unknown>) : null;
101
+ }
102
+
103
+ function readNumber(value: unknown): number {
104
+ return typeof value === "number" ? value : 0;
105
+ }
@@ -5,8 +5,9 @@ import {
5
5
  type ResultProvenance,
6
6
  type ResultSection,
7
7
  type ToolResultAssembly,
8
- } from "./assembly.ts";
9
- import type { HealthDetails, HealthSectionDetails } from "./types.ts";
8
+ } from "../result/assembly.ts";
9
+ import { createToolDisplaySection, truncateDisplayText } from "../result/display.ts";
10
+ import type { HealthDetails, HealthSectionDetails, ToolDisplaySection } from "../result/types.ts";
10
11
 
11
12
  export type {
12
13
  HealthData,
@@ -20,12 +21,13 @@ export type {
20
21
  HealthStaleAssessment,
21
22
  SemanticHealthState,
22
23
  } from "../../session/health-types.ts";
23
- export type { HealthSectionDetails } from "./types.ts";
24
+ export type { HealthSectionDetails } from "../result/types.ts";
24
25
 
25
26
  export interface HealthResultAssembly {
26
27
  data: HealthData;
27
28
  assembled: ToolResultAssembly<HealthData>;
28
29
  details: HealthDetails;
30
+ displaySections: readonly ToolDisplaySection[];
29
31
  }
30
32
 
31
33
  const SECTION_TITLES: Record<HealthSection, string> = {
@@ -53,9 +55,12 @@ export function assembleHealthResult(data: HealthData): HealthResultAssembly {
53
55
  provenance,
54
56
  });
55
57
 
58
+ const displaySections = buildHealthDisplaySections(data);
59
+
56
60
  return {
57
61
  data,
58
62
  assembled,
63
+ displaySections,
59
64
  details: {
60
65
  includedSections: [...data.includedSections],
61
66
  sections: sectionDetails,
@@ -78,6 +83,53 @@ export function assembleHealthResult(data: HealthData): HealthResultAssembly {
78
83
  };
79
84
  }
80
85
 
86
+ function buildHealthDisplaySections(data: HealthData): ToolDisplaySection[] {
87
+ const sections: ToolDisplaySection[] = [];
88
+
89
+ if (data.includedSections.includes("diagnostics") && data.diagnostics.entries.length > 0) {
90
+ sections.push(
91
+ createToolDisplaySection({
92
+ key: "health.diagnostics",
93
+ title: "Diagnostics",
94
+ items: data.diagnostics.entries,
95
+ totalCount: data.diagnostics.kind === "completed" ? data.diagnostics.entries.length : null,
96
+ omittedCount: data.diagnostics.kind === "completed" ? 0 : null,
97
+ partialReason: diagnosticPartialReason(data),
98
+ format: formatDiagnosticEntry,
99
+ }),
100
+ );
101
+ }
102
+
103
+ if (data.includedSections.includes("servers") && data.servers.length > 0) {
104
+ sections.push(
105
+ createToolDisplaySection({
106
+ key: "health.servers",
107
+ title: "Servers",
108
+ items: data.servers,
109
+ totalCount: data.servers.length,
110
+ format: (server) => `${server.name} (${server.fileTypes.join(", ")}) — ${server.status}`,
111
+ }),
112
+ );
113
+ }
114
+
115
+ return sections;
116
+ }
117
+
118
+ function diagnosticPartialReason(data: HealthData): string | null {
119
+ return data.diagnostics.kind === "partial" || data.diagnostics.kind === "unavailable"
120
+ ? data.diagnostics.reason
121
+ : null;
122
+ }
123
+
124
+ function formatDiagnosticEntry(entry: HealthData["diagnostics"]["entries"][number]): string {
125
+ const summary = `${entry.file} — ${entry.errors} error${entry.errors === 1 ? "" : "s"}, ${entry.warnings} warning${entry.warnings === 1 ? "" : "s"}`;
126
+ const messages = entry.messages?.map(
127
+ (message) =>
128
+ ` ${message.severity} L${message.line}${message.source ? ` [${message.source}]` : ""}: ${truncateDisplayText(message.message, 200)}`,
129
+ );
130
+ return messages && messages.length > 0 ? [summary, ...messages].join("\n") : summary;
131
+ }
132
+
81
133
  interface HealthSectionFacts {
82
134
  status: "complete" | "partial" | "unavailable";
83
135
  available: boolean;
@@ -189,3 +241,28 @@ function uniqueProvenance(provenance: readonly ResultProvenance[]): ResultProven
189
241
  return true;
190
242
  });
191
243
  }
244
+
245
+ import type { CodeIntelResult, CodeIntelToolExecCtx } from "../../types/index.ts";
246
+ import { healthErrorResult } from "../result/errors.ts";
247
+ import { renderHealthResult } from "./markdown.ts";
248
+
249
+ type HealthOutcome = Awaited<ReturnType<CodeIntelToolExecCtx["session"]["health"]>>;
250
+
251
+ /** Assemble the final model-visible code_health result for one workflow outcome. */
252
+ export function finishHealthResult(outcome: HealthOutcome, cwd: string): CodeIntelResult {
253
+ if (outcome.kind === "unavailable") throw new Error(outcome.reason);
254
+ if (outcome.kind === "invalid-input") {
255
+ return healthErrorResult(`**Error:** ${outcome.message}`, outcome.message);
256
+ }
257
+
258
+ const assembly = assembleHealthResult(outcome.data);
259
+ return {
260
+ content: renderHealthResult(assembly, cwd),
261
+ details: {
262
+ type: "health",
263
+ data: assembly.details,
264
+ status: "completed",
265
+ displaySections: assembly.displaySections,
266
+ },
267
+ };
268
+ }
@@ -0,0 +1,41 @@
1
+ import { StringEnum } from "@earendil-works/pi-ai";
2
+ import { Type } from "typebox";
3
+ import type { CodeIntelToolExecCtx } from "../../types/index.ts";
4
+ import { ScopeParam } from "../schemas.ts";
5
+ import { executeHealthTool } from "./execute.ts";
6
+ import { renderHealthCall, renderHealthResult } from "./tui.ts";
7
+
8
+ export const CODE_HEALTH_TOOL_NAME = "code_health";
9
+ export const CODE_HEALTH_TOOL_LABEL = "Code Health";
10
+
11
+ /** Canonical provider-facing metadata for the code_health tool. */
12
+ export const codeHealthSpec = {
13
+ name: CODE_HEALTH_TOOL_NAME,
14
+ label: CODE_HEALTH_TOOL_LABEL,
15
+ parameters: Type.Object(
16
+ {
17
+ scope: Type.Optional(ScopeParam),
18
+ refresh: Type.Optional(
19
+ Type.Boolean({
20
+ description: "Attempt diagnostic recovery before collecting; result reports the outcome.",
21
+ }),
22
+ ),
23
+ include: Type.Optional(
24
+ Type.Array(StringEnum(["diagnostics", "servers"]), {
25
+ description: "Requested health-signal sections.",
26
+ uniqueItems: true,
27
+ }),
28
+ ),
29
+ level: Type.Optional(
30
+ StringEnum(["summary", "detailed"], {
31
+ description: "Detail level for the health report.",
32
+ }),
33
+ ),
34
+ },
35
+ { additionalProperties: false },
36
+ ),
37
+ run: (params: unknown, ctx: CodeIntelToolExecCtx) =>
38
+ executeHealthTool(params as Parameters<typeof executeHealthTool>[0], ctx),
39
+ renderCall: renderHealthCall,
40
+ renderResult: renderHealthResult,
41
+ } as const;