@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
@@ -0,0 +1,245 @@
1
+ import type { PublishDiagnosticsParams } from "../config/types.ts";
2
+ import { uriToFile } from "../utils.ts";
3
+ import {
4
+ type DiagnosticCacheEntry,
5
+ isTentativePushEntry,
6
+ isValidPublishDiagnosticsParams,
7
+ } from "./client-diagnostic-evidence.ts";
8
+ import type { ClientDiagnosticSnapshot, OpenDocumentState } from "./client-document-state.ts";
9
+ import { hasCurrentDiagnosticEvidence } from "./client-document-state.ts";
10
+ import { getDiagnosticFileState } from "./client-file-state.ts";
11
+
12
+ interface ApplyPushOptions {
13
+ store: Map<string, DiagnosticCacheEntry>;
14
+ openDocuments: ReadonlyMap<string, OpenDocumentState>;
15
+ params: PublishDiagnosticsParams;
16
+ evidenceRevision: number;
17
+ /** Client-side sync moment for the URI, or undefined when never synchronized. */
18
+ unversionedSyncMoment: number | undefined;
19
+ /** Whether a lifecycle close marked this URI fail-closed for versioned pushes. */
20
+ closedVersionedBarrier: boolean;
21
+ }
22
+
23
+ /**
24
+ * Apply one valid push publication.
25
+ *
26
+ * Returns whether the publication was accepted and whether it promoted a
27
+ * tentative entry to confirmed. Fail-closed policy (ADR 0020): unversioned
28
+ * pushes are rejected for closed and untracked URIs and for arrivals before
29
+ * the URI's sync moment; versioned pushes for a URI closed by a lifecycle
30
+ * operation are rejected because their version cannot be verified. An
31
+ * unversioned push that arrives after the sync moment of an open document
32
+ * is accepted and re-stamped with that document's current synchronization
33
+ * state. The first valid publication for a synchronization is tentative; a
34
+ * later valid publication for the same synchronization ID and evidence
35
+ * revision promotes the cache to confirmed (ADR 0021).
36
+ */
37
+ export function applyPushDiagnostics(options: ApplyPushOptions): {
38
+ accepted: boolean;
39
+ promoted: boolean;
40
+ } {
41
+ if (!isValidPublishDiagnosticsParams(options.params)) return { accepted: false, promoted: false };
42
+ const openDocument = options.openDocuments.get(options.params.uri);
43
+ if (options.params.version !== undefined) {
44
+ if (!Number.isInteger(options.params.version)) return { accepted: false, promoted: false };
45
+ if (openDocument && options.params.version !== openDocument.version) {
46
+ return { accepted: false, promoted: false };
47
+ }
48
+ if (!openDocument && options.closedVersionedBarrier)
49
+ return { accepted: false, promoted: false };
50
+ }
51
+ if (!Array.isArray(options.params.diagnostics)) return { accepted: false, promoted: false };
52
+ if (!acceptUnversionedPush(options, openDocument)) return { accepted: false, promoted: false };
53
+ const entry = buildPushCacheEntry(options, openDocument);
54
+ const previous = options.store.get(options.params.uri);
55
+ const promoted =
56
+ entry.source === "push" &&
57
+ entry.publications !== undefined &&
58
+ entry.publications >= 2 &&
59
+ isTentativePushEntry(previous);
60
+ options.store.set(options.params.uri, entry);
61
+ return { accepted: true, promoted };
62
+ }
63
+
64
+ /** Gate one unversioned push publication against the sync-moment policy. */
65
+ function acceptUnversionedPush(
66
+ options: ApplyPushOptions,
67
+ openDocument: OpenDocumentState | undefined,
68
+ ): boolean {
69
+ if (options.params.version !== undefined) return true;
70
+ if (!openDocument) return false;
71
+ return !(
72
+ options.unversionedSyncMoment !== undefined && Date.now() < options.unversionedSyncMoment
73
+ );
74
+ }
75
+
76
+ /**
77
+ * Build the stored entry for one accepted push publication.
78
+ *
79
+ * Time-gated unversioned acceptance re-stamps the entry with the open
80
+ * document's current synchronization state, so the push proves that
81
+ * document's synchronization. Versioned pushes keep the current-revision
82
+ * check: a version match alone does not prove a current generation.
83
+ */
84
+ function buildPushCacheEntry(
85
+ options: ApplyPushOptions,
86
+ openDocument: OpenDocumentState | undefined,
87
+ ): DiagnosticCacheEntry {
88
+ const currentRevision = openDocument?.evidenceRevision === options.evidenceRevision;
89
+ const unversioned = options.params.version === undefined && openDocument !== undefined;
90
+ const synchronizationId =
91
+ unversioned || currentRevision ? openDocument?.synchronizationId : undefined;
92
+ const evidenceRevision = openDocument?.evidenceRevision;
93
+ const previous = options.store.get(options.params.uri);
94
+ // A later valid publication for the same synchronization ID and evidence
95
+ // revision continues the entry's publication count: a confirmed pull
96
+ // entry keeps the synchronization confirmed, and a tentative push entry
97
+ // is promoted. Any other publication starts a fresh count.
98
+ const sameSynchronization =
99
+ synchronizationId !== undefined &&
100
+ previous?.synchronizationId === synchronizationId &&
101
+ previous.evidenceRevision === evidenceRevision;
102
+ const publications = sameSynchronization ? Math.min((previous.publications ?? 1) + 1, 2) : 1;
103
+ return {
104
+ diagnostics: options.params.diagnostics,
105
+ receivedAt: Date.now(),
106
+ source: "push",
107
+ synchronizationId,
108
+ evidenceRevision,
109
+ version: options.params.version,
110
+ publications,
111
+ };
112
+ }
113
+
114
+ /** Build one client snapshot without dropping empty-cache freshness. */
115
+ export function buildClientDiagnosticSnapshot(options: {
116
+ store: ReadonlyMap<string, DiagnosticCacheEntry>;
117
+ openDocuments: ReadonlyMap<string, OpenDocumentState>;
118
+ failedDocuments: ReadonlySet<string>;
119
+ evidenceRevision: number;
120
+ }): ClientDiagnosticSnapshot {
121
+ const documents = collectDocumentFreshness(options);
122
+ const cache = collectCachedDiagnostics(options);
123
+ return {
124
+ entries: cache.entries,
125
+ documents,
126
+ current: cache.current && documents.every((document) => document.current),
127
+ };
128
+ }
129
+
130
+ function collectDocumentFreshness(options: {
131
+ openDocuments: ReadonlyMap<string, OpenDocumentState>;
132
+ failedDocuments: ReadonlySet<string>;
133
+ store: ReadonlyMap<string, DiagnosticCacheEntry>;
134
+ evidenceRevision: number;
135
+ }): ClientDiagnosticSnapshot["documents"] {
136
+ const open = collectOpenDocumentFreshness(options);
137
+ return [
138
+ ...open.documents,
139
+ ...collectFailedDocumentFreshness(options.failedDocuments, open.uris),
140
+ ...collectUntrackedCacheFreshness(options.store, open.uris, options.failedDocuments),
141
+ ];
142
+ }
143
+
144
+ function collectOpenDocumentFreshness(options: {
145
+ openDocuments: ReadonlyMap<string, OpenDocumentState>;
146
+ failedDocuments: ReadonlySet<string>;
147
+ store: ReadonlyMap<string, DiagnosticCacheEntry>;
148
+ evidenceRevision: number;
149
+ }): { documents: ClientDiagnosticSnapshot["documents"]; uris: ReadonlySet<string> } {
150
+ const documents: ClientDiagnosticSnapshot["documents"] = [];
151
+ const uris = new Set<string>();
152
+ for (const [uri, document] of options.openDocuments) {
153
+ uris.add(uri);
154
+ const entry = options.store.get(uri);
155
+ const fileState = getDiagnosticFileState(uriToFile(uri));
156
+ const current = hasCurrentDiagnosticEvidence(document, entry, options.evidenceRevision);
157
+ const failed = options.failedDocuments.has(uri);
158
+ // A current tentative push maps to unconfirmed, not to a new public
159
+ // status: it matches the synchronization but cannot confirm it yet, so
160
+ // it must not claim current snapshot or document state (issue #351).
161
+ const tentative = current && isTentativePushEntry(entry);
162
+ documents.push({
163
+ uri,
164
+ current: fileState === "present" && current && !failed && !tentative,
165
+ status: statusForDocument(fileState, current, failed, tentative),
166
+ });
167
+ }
168
+ return { documents, uris };
169
+ }
170
+
171
+ function collectFailedDocumentFreshness(
172
+ failedDocuments: ReadonlySet<string>,
173
+ openUris: ReadonlySet<string>,
174
+ ): ClientDiagnosticSnapshot["documents"] {
175
+ return Array.from(failedDocuments)
176
+ .filter((uri) => !openUris.has(uri))
177
+ .map((uri) => ({
178
+ uri,
179
+ current: false,
180
+ status:
181
+ getDiagnosticFileState(uriToFile(uri)) === "removed"
182
+ ? ("removed" as const)
183
+ : ("failed" as const),
184
+ }));
185
+ }
186
+
187
+ function collectUntrackedCacheFreshness(
188
+ store: ReadonlyMap<string, DiagnosticCacheEntry>,
189
+ openUris: ReadonlySet<string>,
190
+ failedDocuments: ReadonlySet<string>,
191
+ ): ClientDiagnosticSnapshot["documents"] {
192
+ return Array.from(store.keys())
193
+ .filter((uri) => !openUris.has(uri) && !failedDocuments.has(uri))
194
+ .map((uri) => ({
195
+ uri,
196
+ current: false,
197
+ status:
198
+ getDiagnosticFileState(uriToFile(uri)) === "removed"
199
+ ? ("removed" as const)
200
+ : getDiagnosticFileState(uriToFile(uri)) === "unreadable"
201
+ ? ("failed" as const)
202
+ : ("unconfirmed" as const),
203
+ }));
204
+ }
205
+
206
+ function statusForDocument(
207
+ fileState: ReturnType<typeof getDiagnosticFileState>,
208
+ current: boolean,
209
+ failed: boolean,
210
+ tentative: boolean,
211
+ ): "confirmed" | "unconfirmed" | "failed" | "removed" {
212
+ if (fileState === "removed") return "removed";
213
+ if (fileState === "unreadable" || failed) return "failed";
214
+ if (tentative || !current) return "unconfirmed";
215
+ return "confirmed";
216
+ }
217
+
218
+ function collectCachedDiagnostics(options: {
219
+ store: ReadonlyMap<string, DiagnosticCacheEntry>;
220
+ openDocuments: ReadonlyMap<string, OpenDocumentState>;
221
+ evidenceRevision: number;
222
+ }): {
223
+ entries: ClientDiagnosticSnapshot["entries"];
224
+ current: boolean;
225
+ } {
226
+ const entries: ClientDiagnosticSnapshot["entries"] = [];
227
+ let current = true;
228
+ for (const [uri, entry] of options.store) {
229
+ if (getDiagnosticFileState(uriToFile(uri)) === "removed") continue;
230
+ const entryCurrent = hasCurrentDiagnosticEvidence(
231
+ options.openDocuments.get(uri),
232
+ entry,
233
+ options.evidenceRevision,
234
+ );
235
+ // A current tentative error is useful partial evidence. Keep its entry
236
+ // non-current so it cannot establish a clean or settled result (ADR 0021).
237
+ const tentative = entryCurrent && isTentativePushEntry(entry);
238
+ const confirmed = entryCurrent && !tentative;
239
+ current &&= confirmed;
240
+ if (entry.diagnostics.length > 0) {
241
+ entries.push({ uri, diagnostics: entry.diagnostics, current: confirmed });
242
+ }
243
+ }
244
+ return { entries, current };
245
+ }
@@ -0,0 +1,78 @@
1
+ // Client-side diagnostic capability state — static (initialize result) and
2
+ // dynamic (client/registerCapability) tracking with fail-closed validation.
3
+ //
4
+ // Static state lives on the client's initialize-result capabilities; dynamic
5
+ // state lives in the per-instance `ClientDynamicRegistrations` below. Pull
6
+ // support is enabled only while the static provider shape is valid or the
7
+ // dynamic set for `textDocument/diagnostic` is non-empty.
8
+
9
+ /** LSP method for document diagnostic pulls. */
10
+ export const DOCUMENT_DIAGNOSTIC_METHOD = "textDocument/diagnostic";
11
+
12
+ function isRecord(value: unknown): value is Record<string, unknown> {
13
+ return typeof value === "object" && value !== null && !Array.isArray(value);
14
+ }
15
+
16
+ /**
17
+ * Validate one untrusted `DiagnosticOptions` / `DiagnosticRegistrationOptions`
18
+ * value from a static initialize result or a dynamic registration.
19
+ *
20
+ * Required per the LSP specification: boolean `interFileDependencies` and
21
+ * `workspaceDiagnostics`. Optional: string `identifier`, and `documentSelector`
22
+ * (absent, null, or an array of string selectors / document-filter records).
23
+ * Unknown fields such as kotlin-lsp's `workDoneProgress` are tolerated.
24
+ */
25
+ export function isValidDiagnosticOptions(value: unknown): boolean {
26
+ if (!isRecord(value)) return false;
27
+ if (typeof value.interFileDependencies !== "boolean") return false;
28
+ if (typeof value.workspaceDiagnostics !== "boolean") return false;
29
+ if (value.identifier !== undefined && typeof value.identifier !== "string") return false;
30
+ if (value.documentSelector !== undefined && value.documentSelector !== null) {
31
+ if (!Array.isArray(value.documentSelector)) return false;
32
+ if (!value.documentSelector.every((entry) => typeof entry === "string" || isRecord(entry))) {
33
+ return false;
34
+ }
35
+ }
36
+ return true;
37
+ }
38
+
39
+ /**
40
+ * Dynamic capability registrations for one client instance.
41
+ *
42
+ * A replacement client starts with an empty instance, so late registrations
43
+ * on a superseded instance never affect the replacement. Unregistration
44
+ * removes one id; pull stays enabled until the last id is removed.
45
+ */
46
+ export class ClientDynamicRegistrations {
47
+ private readonly idsByMethod = new Map<string, Set<string>>();
48
+
49
+ /** Record one registration id for a method. Duplicate ids are harmless. */
50
+ register(method: string, id: string): void {
51
+ let ids = this.idsByMethod.get(method);
52
+ if (ids === undefined) {
53
+ ids = new Set();
54
+ this.idsByMethod.set(method, ids);
55
+ }
56
+ ids.add(id);
57
+ }
58
+
59
+ /** Remove one registration id; unknown ids are harmless no-ops. */
60
+ unregister(method: string, id: string): void {
61
+ this.idsByMethod.get(method)?.delete(id);
62
+ }
63
+
64
+ /** Whether any registration id remains active for a method. */
65
+ has(method: string): boolean {
66
+ return (this.idsByMethod.get(method)?.size ?? 0) > 0;
67
+ }
68
+
69
+ /** Snapshot of the active registration ids for a method. */
70
+ ids(method: string): readonly string[] {
71
+ return [...(this.idsByMethod.get(method) ?? [])];
72
+ }
73
+
74
+ /** Drop all registrations — capability loss on shutdown, crash, or disposal. */
75
+ clear(): void {
76
+ this.idsByMethod.clear();
77
+ }
78
+ }
@@ -0,0 +1,171 @@
1
+ import {
2
+ type CodeQueryResult,
3
+ type CodeRequestControl,
4
+ completedCodeQuery,
5
+ isCodeRequestInterruption,
6
+ partialCodeQuery,
7
+ throwIfCodeRequestInterrupted,
8
+ unavailableCodeQuery,
9
+ } from "@mrclrchtr/supi-code-runtime/api";
10
+ import type { Diagnostic } from "../config/types.ts";
11
+ import { TENTATIVE_PUSH_UNAVAILABLE_REASON } from "../diagnostics/evidence.ts";
12
+ import {
13
+ type DiagnosticSynchronization,
14
+ incompleteDiagnosticResult,
15
+ raceDiagnosticPull,
16
+ } from "./client-diagnostic-evidence.ts";
17
+ import type { DiagnosticObserver, DiagnosticPushWaitOutcome } from "./client-diagnostic-timing.ts";
18
+ import type { DiagnosticWaitRegistry } from "./client-diagnostic-waiters.ts";
19
+
20
+ interface FileDiagnosticCollectionOptions {
21
+ readonly supportsPull: boolean;
22
+ readonly syncStart: number;
23
+ readonly maxWaitMs: number;
24
+ readonly request: DiagnosticSynchronization;
25
+ readonly cachedDiagnostics: Diagnostic[] | null;
26
+ readonly observer: DiagnosticObserver;
27
+ readonly waiters: DiagnosticWaitRegistry;
28
+ readonly current: () => boolean;
29
+ readonly freshPush: () => boolean;
30
+ /** Receive time of a current tentative push that is already cached. */
31
+ readonly currentPushReceivedAt: () => number | undefined;
32
+ readonly diagnostics: () => Diagnostic[];
33
+ readonly pullDiagnostics: (timeoutMs: number, signal: AbortSignal) => Promise<boolean>;
34
+ /** Observe the push wait outcome without finishing the observer; the caller finishes once. */
35
+ readonly onPushWait?: (outcome: DiagnosticPushWaitOutcome) => void;
36
+ }
37
+
38
+ type PullCollectionOutcome = "failed" | "pull" | "push" | "released";
39
+
40
+ /** Collect fresh pull or push evidence for one synchronized document. */
41
+ export async function collectSynchronizedFileDiagnostics(
42
+ options: FileDiagnosticCollectionOptions,
43
+ control?: CodeRequestControl,
44
+ ): Promise<CodeQueryResult<Diagnostic[]>> {
45
+ throwIfCodeRequestInterrupted(control);
46
+ if (options.supportsPull) {
47
+ const pullOutcome = await collectPullEvidence(options, control);
48
+ if (pullOutcome === "pull" || pullOutcome === "push") {
49
+ return completedCodeQuery(options.diagnostics());
50
+ }
51
+ }
52
+
53
+ throwIfCodeRequestInterrupted(control);
54
+ if (!options.current()) {
55
+ options.observer.pushWaitCompleted(1, "released");
56
+ return unavailableCodeQuery(
57
+ "Diagnostic collection ended before the current document synchronization was confirmed.",
58
+ );
59
+ }
60
+ if (options.freshPush()) {
61
+ options.observer.pushWaitCompleted(1, "published");
62
+ return completedCodeQuery(options.diagnostics());
63
+ }
64
+
65
+ const push = await waitForConfirmedPush(options, control);
66
+ if (options.onPushWait) options.onPushWait(push);
67
+ else options.observer.pushWaitCompleted(1, push);
68
+ if (push === "published") {
69
+ return completedCodeQuery(options.diagnostics());
70
+ }
71
+ if (push === "tentative") {
72
+ // A current tentative error is useful partial evidence, but an empty
73
+ // publication cannot establish that the document is clean (ADR 0021).
74
+ const diagnostics = options.diagnostics();
75
+ return diagnostics.length > 0
76
+ ? partialCodeQuery(diagnostics, TENTATIVE_PUSH_UNAVAILABLE_REASON)
77
+ : unavailableCodeQuery(TENTATIVE_PUSH_UNAVAILABLE_REASON);
78
+ }
79
+ return incompleteDiagnosticResult(
80
+ options.cachedDiagnostics,
81
+ push === "released" ? "released" : "timed-out",
82
+ );
83
+ }
84
+
85
+ /**
86
+ * Wait until a confirmed push publication settles the synchronization.
87
+ *
88
+ * Every accepted publication releases the waiter. A confirmed push ends the
89
+ * wait as "published". A publication that stays tentative (no republish
90
+ * arrived for the same synchronization) ends as "tentative" when the budget
91
+ * expires. A wait with no publication at all keeps the waiter's
92
+ * "timed-out", and a lifecycle release stays "released".
93
+ */
94
+ async function waitForConfirmedPush(
95
+ options: FileDiagnosticCollectionOptions,
96
+ control?: CodeRequestControl,
97
+ ): Promise<DiagnosticPushWaitOutcome> {
98
+ // A tentative publication may already sit in the cache when the wait
99
+ // starts (ADR 0021). Do not grant repeated callers a new full wait window:
100
+ // bound them by the first operation window or the cached publication age.
101
+ const initialPushReceivedAt = options.currentPushReceivedAt();
102
+ const waitDeadline = Math.min(
103
+ options.syncStart + options.maxWaitMs,
104
+ initialPushReceivedAt === undefined
105
+ ? Number.POSITIVE_INFINITY
106
+ : initialPushReceivedAt + options.maxWaitMs,
107
+ );
108
+ let observedPublication = initialPushReceivedAt !== undefined;
109
+ for (;;) {
110
+ throwIfCodeRequestInterrupted(control);
111
+ // A republish can arrive after the previous wait released but before the
112
+ // next waiter registers; re-check the store on every loop pass.
113
+ if (options.freshPush()) return "published";
114
+ const push = await options.waiters.waitForPush(
115
+ options.request.uri,
116
+ Math.max(0, waitDeadline - Date.now()),
117
+ control,
118
+ );
119
+ // A lifecycle release ends the wait definitively: a tentative
120
+ // publication observed earlier must not reclassify the release.
121
+ if (push === "released") return "released";
122
+ // A promotion can land while the timed-out waiter tears down; the cache
123
+ // must complete the wait before the timeout classifies the outcome.
124
+ if (options.freshPush()) return "published";
125
+ if (push === "timed-out") {
126
+ return observedPublication || options.currentPushReceivedAt() !== undefined
127
+ ? "tentative"
128
+ : "timed-out";
129
+ }
130
+ observedPublication = true;
131
+ }
132
+ }
133
+
134
+ async function collectPullEvidence(
135
+ options: FileDiagnosticCollectionOptions,
136
+ control?: CodeRequestControl,
137
+ ): Promise<PullCollectionOutcome> {
138
+ const remaining = options.maxWaitMs - (Date.now() - options.syncStart);
139
+ if (remaining <= 0) {
140
+ options.observer.pullTimedOut();
141
+ return "failed";
142
+ }
143
+
144
+ try {
145
+ const controller = new AbortController();
146
+ // Link the caller's cancellation to the local pull controller so an
147
+ // in-flight pull receives protocol cancellation and stops promptly.
148
+ const onAbort = () => controller.abort(control?.signal?.reason);
149
+ if (control?.signal?.aborted) onAbort();
150
+ else control?.signal?.addEventListener("abort", onAbort, { once: true });
151
+ try {
152
+ const outcome = await raceDiagnosticPull({
153
+ pull: options.pullDiagnostics(remaining, controller.signal),
154
+ waitForChange: () => options.waiters.waitForChange(),
155
+ freshPush: options.freshPush,
156
+ current: options.current,
157
+ });
158
+ if (outcome !== "pull") controller.abort();
159
+ if (outcome === "pull") options.observer.pullCompleted(1);
160
+ else options.observer.pullFailed(undefined);
161
+ if (outcome === "push") options.observer.pushWaitCompleted(1, "published");
162
+ return outcome;
163
+ } finally {
164
+ control?.signal?.removeEventListener("abort", onAbort);
165
+ }
166
+ } catch (error) {
167
+ if (isCodeRequestInterruption(error, control)) throw error;
168
+ options.observer.pullFailed(error);
169
+ return "failed";
170
+ }
171
+ }