@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
package/README.md CHANGED
@@ -24,12 +24,13 @@ After installation, keep asking Pi normal coding questions. The agent can:
24
24
  - **Map an unfamiliar repository** — understand workspaces, packages, entry points, dependencies, and local `CLAUDE.md` or `AGENTS.md` instructions before editing.
25
25
  - **Navigate precisely with LSP** — identify the exact symbol at a source location and inspect its type, definition, enclosing declaration, and nearby diagnostics.
26
26
  - **Follow relationships across LSP and AST evidence** — find references, implementations, and outgoing calls without guessing from matching text.
27
- - **Search parsed code structure** — query AST definitions, types, interfaces, classes, methods, enums, imports, exports, and call sites.
27
+ - **Search parsed code structure** — query AST definitions, types, interfaces, classes, methods, enums, imports, exports, and call sites. One owned Structural Worker keeps Pi responsive. Tool cancellation and the shared AST deadline propagate through an atomic cancellation flag into Worker reads, parser progress, and query progress.
28
+ - **Correlate diagnostics** — each public `code_*` call gets one session-local opaque Debug Operation ID. Directly owned workflow, LSP, AST Scan, and Structural Worker events share it without changing normal Tool results.
28
29
  - **Check live project health** — inspect language-server status and current errors or warnings, with an option to refresh stale diagnostics.
29
30
  - **Refactor safely** — preview language-aware renames and extractions before applying them. Plans are rejected if the files changed in the meantime.
30
31
  - **See uncertainty clearly** — results distinguish “nothing found” from incomplete or unavailable analysis and disclose omitted matches.
31
32
 
32
- When Pi recognizes a workspace, the agent also receives an architecture overview near the start of the session, so it can orient before spending turns opening files.
33
+ When Pi recognizes a workspace, the agent also receives a compact architecture overview near the start of the session, so it can orient before spending turns opening files. The overview contains manifest facts (module names, one-line descriptions, declared topology, declared entrypoints, and detected languages), is labeled as untrusted repository evidence, and is controlled by the `code-intelligence.overviewEnabled` setting in `/supi-settings`.
33
34
 
34
35
  ## Example requests
35
36
 
@@ -126,7 +127,7 @@ Open the status view to see detected languages, running or missing servers, and
126
127
  /supi-ci-status
127
128
  ```
128
129
 
129
- Use `/supi-settings` to disable language servers you do not need or change the instruction filenames surfaced during directory orientation. The defaults are `CLAUDE.md` and `AGENTS.md`.
130
+ Use `/supi-settings` to disable language servers you do not need, change the instruction filenames surfaced during directory orientation (defaults `CLAUDE.md` and `AGENTS.md`), or disable the first-turn architecture overview with `overviewEnabled`.
130
131
 
131
132
  [workspace-orientation]: https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-code-intelligence/assets/workspace-orientation.png
132
133
  [symbol-inspection]: https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-code-intelligence/assets/symbol-inspection.png
@@ -22,6 +22,8 @@ Read-only provider methods return `CodeQueryResult<T>`:
22
22
 
23
23
  This keeps successful zero-result facts distinct from routing, transport, and provider failures.
24
24
 
25
+ Semantic and structural provider methods also accept optional `CodeRequestControl` metadata. It contains a caller `AbortSignal`, an absolute Unix-epoch deadline, and an optional opaque Debug Operation ID. Adapters preserve the same object. The ID does not change cancellation semantics. Canonical helpers identify cancellation and deadline expiry across bundled package copies. Cooperative structural substrates apply the control; unsupported substrates can preserve it without applying behavior.
26
+
25
27
  ## License
26
28
 
27
29
  MIT
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-code-runtime",
3
- "version": "4.10.0",
3
+ "version": "6.0.0",
4
4
  "description": "Shared workspace context and capability contracts for code intelligence",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,6 +9,7 @@
9
9
  // Capability interfaces and availability states
10
10
  export type {
11
11
  CapabilityState,
12
+ CodeRequestControl,
12
13
  SemanticProvider,
13
14
  StructuralProvider,
14
15
  StructuralResult,
@@ -21,6 +22,13 @@ export {
21
22
  partialCodeQuery,
22
23
  unavailableCodeQuery,
23
24
  } from "./query-result.ts";
25
+ export {
26
+ CodeRequestDeadlineError,
27
+ isCodeRequestDeadlineError,
28
+ isCodeRequestInterrupted,
29
+ isCodeRequestInterruption,
30
+ throwIfCodeRequestInterrupted,
31
+ } from "./request-control.ts";
24
32
  // Shared canonical types
25
33
  export type {
26
34
  CalleeDepth,
@@ -34,6 +42,7 @@ export type {
34
42
  DeclarationNesting,
35
43
  DisambiguationCandidate,
36
44
  DocumentCodeSymbol,
45
+ DocumentEditPrecondition,
37
46
  ExportData,
38
47
  FileEdit,
39
48
  ImportData,
@@ -43,6 +43,16 @@ export type CapabilityState =
43
43
 
44
44
  // ── Provider interfaces ────────────────────────────────────────────────
45
45
 
46
+ /** Request control that adapters preserve and cooperative providers apply. */
47
+ export interface CodeRequestControl {
48
+ /** Opaque Debug Operation ID for work directly owned by one public Tool call. */
49
+ readonly operationId?: string;
50
+ /** Caller cancellation signal, when one exists. */
51
+ readonly signal?: AbortSignal;
52
+ /** Absolute wall-clock deadline in Unix epoch milliseconds. */
53
+ readonly deadline?: number;
54
+ }
55
+
46
56
  /**
47
57
  * Semantic analysis capability backed by a language server (LSP).
48
58
  *
@@ -51,16 +61,31 @@ export type CapabilityState =
51
61
  * null values are completed observations rather than capability failures.
52
62
  */
53
63
  export interface SemanticProvider {
54
- references(filePath: string, position: CodePosition): Promise<CodeQueryResult<CodeLocation[]>>;
64
+ references(
65
+ filePath: string,
66
+ position: CodePosition,
67
+ control?: CodeRequestControl,
68
+ ): Promise<CodeQueryResult<CodeLocation[]>>;
55
69
  implementation(
56
70
  filePath: string,
57
71
  position: CodePosition,
72
+ control?: CodeRequestControl,
58
73
  ): Promise<CodeQueryResult<CodeLocation[]>>;
59
- documentSymbols(filePath: string): Promise<CodeQueryResult<DocumentCodeSymbol[]>>;
60
- workspaceSymbols(query: string): Promise<CodeQueryResult<CodeSymbol[]>>;
74
+ documentSymbols(
75
+ filePath: string,
76
+ control?: CodeRequestControl,
77
+ ): Promise<CodeQueryResult<DocumentCodeSymbol[]>>;
78
+ workspaceSymbols(
79
+ query: string,
80
+ control?: CodeRequestControl,
81
+ ): Promise<CodeQueryResult<CodeSymbol[]>>;
61
82
 
62
83
  /** Optional definition capability with explicit completed-empty semantics. */
63
- definition?(filePath: string, position: CodePosition): Promise<CodeQueryResult<CodeLocation[]>>;
84
+ definition?(
85
+ filePath: string,
86
+ position: CodePosition,
87
+ control?: CodeRequestControl,
88
+ ): Promise<CodeQueryResult<CodeLocation[]>>;
64
89
 
65
90
  /**
66
91
  * Optional hover capability. A completed `null` data value means the
@@ -69,6 +94,7 @@ export interface SemanticProvider {
69
94
  hover?(
70
95
  filePath: string,
71
96
  position: CodePosition,
97
+ control?: CodeRequestControl,
72
98
  ): Promise<CodeQueryResult<{ contents: string; range?: SourceRange } | null>>;
73
99
 
74
100
  /**
@@ -79,7 +105,7 @@ export interface SemanticProvider {
79
105
  * organize imports, dead-code cleanup, etc.) without exposing that branching
80
106
  * to callers.
81
107
  */
82
- refactor?(request: RefactorRequest): Promise<RefactorResult>;
108
+ refactor?(request: RefactorRequest, control?: CodeRequestControl): Promise<RefactorResult>;
83
109
 
84
110
  /**
85
111
  * Optional rename capability. When present, the provider supports
@@ -88,7 +114,12 @@ export interface SemanticProvider {
88
114
  * This remains a lower-level substrate helper for providers that expose
89
115
  * symbol rename independently of their general refactor planner.
90
116
  */
91
- rename?(file: string, position: CodePosition, newName: string): Promise<RefactorResult>;
117
+ rename?(
118
+ file: string,
119
+ position: CodePosition,
120
+ newName: string,
121
+ control?: CodeRequestControl,
122
+ ): Promise<RefactorResult>;
92
123
 
93
124
  /**
94
125
  * Optional code actions capability. When present, the provider
@@ -96,7 +127,11 @@ export interface SemanticProvider {
96
127
  *
97
128
  * Kept as a low-level substrate helper and for lightweight introspection.
98
129
  */
99
- codeActions?(file: string, position: CodePosition): Promise<RefactorResult[]>;
130
+ codeActions?(
131
+ file: string,
132
+ position: CodePosition,
133
+ control?: CodeRequestControl,
134
+ ): Promise<RefactorResult[]>;
100
135
  }
101
136
 
102
137
  /**
@@ -111,14 +146,19 @@ export interface StructuralProvider {
111
146
  file: string,
112
147
  line: number,
113
148
  character: number,
114
- depth?: CalleeDepth,
149
+ depthOrOptions?: CalleeDepth | { depth?: CalleeDepth; control?: CodeRequestControl },
115
150
  ): Promise<CodeResult<CalleesData>>;
116
- exports(file: string): Promise<CodeResult<ExportData[]>>;
117
- outline(file: string): Promise<CodeResult<OutlineData[]>>;
118
- imports(file: string): Promise<CodeResult<ImportData[]>>;
119
- nodeAt(file: string, line: number, character: number): Promise<CodeResult<NodeAtData>>;
151
+ exports(file: string, control?: CodeRequestControl): Promise<CodeResult<ExportData[]>>;
152
+ outline(file: string, control?: CodeRequestControl): Promise<CodeResult<OutlineData[]>>;
153
+ imports(file: string, control?: CodeRequestControl): Promise<CodeResult<ImportData[]>>;
154
+ nodeAt(
155
+ file: string,
156
+ line: number,
157
+ character: number,
158
+ control?: CodeRequestControl,
159
+ ): Promise<CodeResult<NodeAtData>>;
120
160
  /** Find all call-site identifiers in a file. Returns name + start line for each match. */
121
- callSites(file: string): Promise<CodeResult<CallSite[]>>;
161
+ callSites(file: string, control?: CodeRequestControl): Promise<CodeResult<CallSite[]>>;
122
162
  }
123
163
 
124
164
  /** Convenience alias for `CodeResult` used in structural contexts. */
@@ -0,0 +1,47 @@
1
+ import type { CodeRequestControl } from "./capability/types.ts";
2
+
3
+ /** Error raised when an absolute code-request deadline has elapsed. */
4
+ export class CodeRequestDeadlineError extends Error {
5
+ constructor() {
6
+ super("Code request deadline exceeded");
7
+ this.name = "CodeRequestDeadlineError";
8
+ }
9
+ }
10
+
11
+ /** Test whether request cancellation or its absolute deadline has elapsed. */
12
+ export function isCodeRequestInterrupted(
13
+ control: CodeRequestControl | undefined,
14
+ now: () => number = Date.now,
15
+ ): boolean {
16
+ return (
17
+ control?.signal?.aborted === true ||
18
+ (control?.deadline !== undefined && now() >= control.deadline)
19
+ );
20
+ }
21
+
22
+ /** Throw the caller abort reason or a canonical absolute-deadline error. */
23
+ export function throwIfCodeRequestInterrupted(
24
+ control: CodeRequestControl | undefined,
25
+ now: () => number = Date.now,
26
+ ): void {
27
+ control?.signal?.throwIfAborted();
28
+ if (control?.deadline !== undefined && now() >= control.deadline) {
29
+ throw new CodeRequestDeadlineError();
30
+ }
31
+ }
32
+
33
+ /** Identify an absolute-deadline error across bundled package copies. */
34
+ export function isCodeRequestDeadlineError(error: unknown): error is Error {
35
+ return (
36
+ error instanceof CodeRequestDeadlineError ||
37
+ (error instanceof Error && error.name === "CodeRequestDeadlineError")
38
+ );
39
+ }
40
+
41
+ /** Identify an error caused by the supplied request control. */
42
+ export function isCodeRequestInterruption(
43
+ error: unknown,
44
+ control: CodeRequestControl | undefined,
45
+ ): boolean {
46
+ return isCodeRequestDeadlineError(error) || control?.signal?.aborted === true;
47
+ }
@@ -149,11 +149,18 @@ export interface FileEdit {
149
149
  newText: string;
150
150
  }
151
151
 
152
+ /** A document-state precondition established when semantic edits are normalized. */
153
+ export type DocumentEditPrecondition =
154
+ | { file: string; kind: "open-document-version"; version: number }
155
+ | { file: string; kind: "disk-content" };
156
+
152
157
  /**
153
158
  * A precise workspace edit — one or more file edits to apply atomically.
154
159
  */
155
160
  export interface WorkspaceEdit {
156
161
  edits: FileEdit[];
162
+ /** Document state that the semantic provider validated before it made this plan. */
163
+ documentPreconditions?: DocumentEditPrecondition[];
157
164
  }
158
165
 
159
166
  /**
@@ -202,7 +209,12 @@ export interface DisambiguationCandidate {
202
209
  * - `unavailable`: refactoring not possible
203
210
  */
204
211
  export type RefactorResult =
205
- | { kind: "precise"; edits: WorkspaceEdit }
212
+ | {
213
+ kind: "precise";
214
+ edits: WorkspaceEdit;
215
+ /** Provider roots authorized by the semantic route. Consumers canonicalize before storage. */
216
+ authorizedMutationRoots: string[];
217
+ }
206
218
  | { kind: "ambiguous"; candidates: DisambiguationCandidate[] }
207
219
  | { kind: "unavailable"; reason: string };
208
220
 
@@ -28,6 +28,7 @@ pnpm add @mrclrchtr/supi-core
28
28
  - `loadSupiConfig()` — merged config with resolution order `defaults <- global <- project`
29
29
  - `loadSupiConfigForScope()` — load one scope at a time for settings UIs
30
30
  - `writeSupiConfig()` — persist values
31
+ - `replaceSupiConfigSection()` — replace one nested section while preserving other sections
31
32
  - `removeSupiConfigKey()` — remove a key or override
32
33
 
33
34
  Config file locations:
@@ -49,6 +50,7 @@ Config file locations:
49
50
 
50
51
  - context-provider registry for `/supi-context`
51
52
  - debug-event registry and monotonic phase timers for producers that want shared debug capture
53
+ - optional Debug Operation IDs for exact, directly owned public Tool-call correlation; ambient events stay uncorrelated
52
54
  - settings registry used by `/supi-settings`
53
55
 
54
56
  ### Project and session helpers
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "4.10.0",
3
+ "version": "6.0.0",
4
4
  "description": "Shared settings, configuration, reporting, and session infrastructure",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -53,7 +53,7 @@
53
53
  "./api": "./src/api.ts",
54
54
  "./config": "./src/config.ts",
55
55
  "./context": "./src/context.ts",
56
- "./debug": "./src/debug-registry.ts",
56
+ "./debug": "./src/debug.ts",
57
57
  "./evidence-badge": "./src/evidence-badge.ts",
58
58
  "./footer-registry": "./src/footer-registry.ts",
59
59
  "./llm": "./src/llm.ts",
@@ -11,7 +11,7 @@ export * from "./config.ts";
11
11
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
12
12
  export * from "./context.ts";
13
13
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
14
- export * from "./debug-registry.ts";
14
+ export * from "./debug.ts";
15
15
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
16
16
  export * from "./evidence-badge.ts";
17
17
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
@@ -148,6 +148,37 @@ export function writeSupiConfig(
148
148
  fs.writeFileSync(configPath, `${JSON.stringify(existing, null, 2)}\n`, "utf-8");
149
149
  }
150
150
 
151
+ /**
152
+ * Replace one complete config section while preserving other sections.
153
+ *
154
+ * This is useful for nested settings that must remove stale keys as part of
155
+ * one update. An empty section is removed from the config file.
156
+ */
157
+ export function replaceSupiConfigSection(
158
+ loc: SupiConfigLocation,
159
+ value: Record<string, unknown>,
160
+ options?: SupiConfigOptions,
161
+ ): void {
162
+ const configPath = getSupiConfigPath(loc.scope, loc.cwd, options);
163
+ const existing = readJsonFile(configPath) ?? {};
164
+
165
+ if (Object.keys(value).length > 0) existing[loc.section] = value;
166
+ else delete existing[loc.section];
167
+
168
+ const content = Object.keys(existing).length > 0 ? `${JSON.stringify(existing, null, 2)}\n` : "";
169
+ if (content) {
170
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
171
+ fs.writeFileSync(configPath, content, "utf-8");
172
+ return;
173
+ }
174
+
175
+ try {
176
+ fs.unlinkSync(configPath);
177
+ } catch {
178
+ // File may not exist.
179
+ }
180
+ }
181
+
151
182
  /**
152
183
  * Remove a key from a config section.
153
184
  * Used by `interval default` to remove the project override.
@@ -1,10 +1,12 @@
1
1
  // supi-core config domain — config loading.
2
2
  export type { SupiConfigLocation, SupiConfigOptions } from "./config/config.ts";
3
3
  export {
4
+ getSupiConfigPath,
4
5
  loadSupiConfig,
5
6
  loadSupiConfigForScope,
6
7
  loadSupiConfigSectionForScope,
7
8
  readJsonFile,
8
9
  removeSupiConfigKey,
10
+ replaceSupiConfigSection,
9
11
  writeSupiConfig,
10
12
  } from "./config/config.ts";
@@ -4,9 +4,6 @@
4
4
  // supi-debug extension owns policy/configuration and exposes events through a
5
5
  // command/tool while this module stays dependency-free for producers.
6
6
 
7
- // biome-ignore lint/performance/noReExportAll: preserve the stable debug domain entry point
8
- export * from "./debug-timing.ts";
9
-
10
7
  export type DebugLevel = "debug" | "info" | "warning" | "error";
11
8
  export type DebugAgentAccess = "off" | "sanitized" | "raw";
12
9
  export interface DebugRegistryConfig {
@@ -25,6 +22,8 @@ export const DEBUG_REGISTRY_DEFAULTS: DebugRegistryConfig = {
25
22
  };
26
23
 
27
24
  export interface DebugEventInput {
25
+ /** Opaque identity for events directly owned by one public Tool call. */
26
+ operationId?: string;
28
27
  source: string;
29
28
  level: DebugLevel;
30
29
  category: string;
@@ -42,6 +41,8 @@ export interface DebugEvent extends DebugEventInput {
42
41
  }
43
42
 
44
43
  export interface DebugEventQuery {
44
+ /** Match one exact Debug Operation ID. */
45
+ operationId?: string;
45
46
  source?: string;
46
47
  level?: DebugLevel;
47
48
  category?: string;
@@ -53,6 +54,7 @@ export interface DebugEventQuery {
53
54
  export interface DebugEventView {
54
55
  id: number;
55
56
  timestamp: number;
57
+ operationId?: string;
56
58
  source: string;
57
59
  level: DebugLevel;
58
60
  category: string;
@@ -84,6 +86,7 @@ interface DebugRegistryState {
84
86
  }
85
87
 
86
88
  const REGISTRY_KEY = Symbol.for("@mrclrchtr/supi-core/debug-registry");
89
+ const DEBUG_OPERATION_ID_RE = /^op-[A-Za-z0-9_-]{21}[AQgw]$/;
87
90
  const SECRET_KEY_RE = /(?:token|password|passwd|secret|api[_-]?key|authorization|credential)/i;
88
91
  const ENV_SECRET_RE =
89
92
  /\b([A-Za-z0-9_]*(?:token|password|passwd|secret|api[_-]?key|authorization|credential)[A-Za-z0-9_]*)=(?:'[^']*'|"[^"]*"|\S+)/gi;
@@ -135,11 +138,17 @@ export function isDebugLevel(value: unknown): value is DebugLevel {
135
138
  return value === "debug" || value === "info" || value === "warning" || value === "error";
136
139
  }
137
140
 
138
- /** Match a debug event against the supported source, level, and category filters. */
141
+ /** Return whether a value has the exact 16-byte base64url Debug Operation ID form. */
142
+ export function isDebugOperationId(value: unknown): value is string {
143
+ return typeof value === "string" && DEBUG_OPERATION_ID_RE.test(value);
144
+ }
145
+
146
+ /** Match a debug event against the supported exact filters. */
139
147
  export function matchesDebugEventQuery(
140
- event: Pick<DebugEventView, "source" | "level" | "category">,
141
- query: Pick<DebugEventQuery, "source" | "level" | "category">,
148
+ event: Pick<DebugEventView, "operationId" | "source" | "level" | "category">,
149
+ query: Pick<DebugEventQuery, "operationId" | "source" | "level" | "category">,
142
150
  ): boolean {
151
+ if (query.operationId && event.operationId !== query.operationId) return false;
143
152
  if (query.source && event.source !== query.source) return false;
144
153
  if (query.level && event.level !== query.level) return false;
145
154
  if (query.category && event.category !== query.category) return false;
@@ -197,6 +206,7 @@ function toSanitizedView(event: DebugEvent): DebugEventView {
197
206
  return {
198
207
  id: event.id,
199
208
  timestamp: event.timestamp,
209
+ operationId: event.operationId,
200
210
  source: event.source,
201
211
  level: event.level,
202
212
  category: event.category,
@@ -216,6 +226,9 @@ export function subscribeDebugEvents(listener: DebugEventListener): () => void {
216
226
  /** Record a session-local debug event if debugging is enabled. */
217
227
  export function recordDebugEvent(input: DebugEventInput): DebugEvent | null {
218
228
  const state = getState();
229
+ if (input.operationId !== undefined && !isDebugOperationId(input.operationId)) {
230
+ return null;
231
+ }
219
232
  if (!state.config.enabled) {
220
233
  return null;
221
234
  }
@@ -0,0 +1,9 @@
1
+ // Debug domain entry for `@mrclrchtr/supi-core/debug`.
2
+ //
3
+ // Kept separate from debug-registry.ts so debug-timing.ts can import the
4
+ // registry without creating an import cycle through the barrel re-export.
5
+
6
+ // biome-ignore lint/performance/noReExportAll: preserve the stable debug domain entry point
7
+ export * from "./debug-registry.ts";
8
+ // biome-ignore lint/performance/noReExportAll: preserve the stable debug domain entry point
9
+ export * from "./debug-timing.ts";
@@ -11,7 +11,7 @@ export * from "./config.ts";
11
11
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
12
12
  export * from "./context.ts";
13
13
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
14
- export * from "./debug-registry.ts";
14
+ export * from "./debug.ts";
15
15
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
16
16
  export * from "./footer-registry.ts";
17
17
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
@@ -41,7 +41,10 @@ export interface SettingsApplyResult {
41
41
  */
42
42
  export interface SettingsModule {
43
43
  id: string;
44
+ /** Human-readable section label shown in the UI. */
44
45
  label: string;
46
+ /** Optional label that groups this module within its section. */
47
+ subsection?: string;
45
48
  read(context: SettingsContext): Promise<SettingsSnapshot>;
46
49
  apply(request: SettingsActionRequest): Promise<SettingsApplyResult>;
47
50
  }
@@ -16,9 +16,97 @@ This package is library-only. It registers no model-callable tools; `@mrclrchtr/
16
16
  npm install @mrclrchtr/supi-lsp
17
17
  ```
18
18
 
19
+ ## Language-server support
20
+
21
+ The runtime starts an installed server when the project contains a matching file type and, where configured, a root marker. Some built-in servers use extension-based discovery without a root marker. Built-in command names must be on `PATH`; a configured absolute command path is also supported. This table describes diagnostic support, not the full semantic feature set. A push server can still provide hover, definitions, references, symbols, and refactors.
22
+
23
+ The table records an initialize-handshake audit performed on 2026-08-21 against the locally installed server versions. The handshake is authoritative and can report a different mode after an upgrade; treat rows marked `unverified` as unknown until a probe confirms them. Pull-capability facts come from the official LSP specification (pull diagnostics are a 3.17 feature; 3.18 is the current specification at microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification).
24
+
25
+ | Language | Server binary | Pull diagnostics (probe) | Built-in SuPi mode | Notes |
26
+ |---|---|---|---|---|
27
+ | TypeScript / JavaScript | `typescript-language-server` 5.3.0 | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
28
+ | Python | `pyright-langserver` 1.1.411 | Dynamic-only pull (confirmed) | Pull | No static `diagnosticProvider` in the initialize result; registers `textDocument/diagnostic` dynamically after `initialized`. The #320 handshake inspected only the initialize result and missed the registration. |
29
+ | Rust | `rust-analyzer` 0.0.0 (2026-08-10) | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
30
+ | Go | `gopls` v0.23.0 | Conditional (confirmed) | Push | Default is push; `initializationOptions.pullDiagnostics: true` makes gopls advertise `diagnosticProvider`. Keep push while golang/go#70199 stays open; initial pull support tracked in golang/go#53275. gopls v0.23.0 pull reports omit the `kind` discriminator (`""`) and `resultId`; SuPi tolerates the empty-kind full report. |
31
+ | C / C++ | `clangd` 21.0.0 | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
32
+ | Ruby | `ruby-lsp` 0.26.10 | No (confirmed) | Push | No `diagnosticProvider`. The server also refuses to start in a project that has a `Gemfile` without a `Gemfile.lock`. |
33
+ | Java | `jdtls` | Unverified | Push | Probe limitation: the wrapper needs a workspace launch configuration; the version probe did not respond. |
34
+ | Kotlin | `kotlin-lsp` LS-262.9593.0 | Static pull (confirmed) | Pull | Statically advertises `diagnosticProvider` in the initialize result, but only when started with `--stdio`; the built-in configuration provides the argument. |
35
+ | Bash | `bash-language-server` 5.6.0 | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
36
+ | HTML | `vscode-html-language-server` | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
37
+ | SQL | `sql-language-server` 1.7.1 | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
38
+ | R | `R` 4.6.1 (languageserver) | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
39
+
40
+ SuPi advertises static and dynamic pull support. It advertises server-requested refresh support too:
41
+
42
+ - `textDocument.diagnostic.dynamicRegistration: true`
43
+ - `workspace.diagnostics.refreshSupport: true`
44
+
45
+ A server gets pull diagnostics when it declares a valid `diagnosticProvider` during initialization. A server also gets pull diagnostics after it registers `textDocument/diagnostic`. The pull support stays active until the server removes the registration. SuPi validates registration parameters. Invalid parameters do not enable pull support. SuPi ignores other registration methods.
46
+
47
+ When a server sends `workspace/diagnostic/refresh`, SuPi returns `null` immediately. It then refreshes the owning client's tracked documents in the background. The refresh covers open, cached, and failed tracked documents. SuPi does not add workspace-wide `workspace/diagnostic` pulls.
48
+
49
+ Protocol support is separate from the configured mode. A server may support pull diagnostics and still use SuPi's push mode because the built-in configuration does not enable pull mode.
50
+
51
+ The LSP 3.18 specification adds `Diagnostic.message` markup content, guarded by the client capability `textDocument.diagnostic.markupMessageSupport`; SuPi's validator already accepts plaintext and markdown messages but does not advertise the capability. Other 3.18 features (snippet text edits, inline completion, folding-range refresh, multi-range formatting) are outside the diagnostic surface and are not implemented.
52
+
53
+ Pull diagnostics use `textDocument/diagnostic`, so the client can tie a report to the current request. Push diagnostics are asynchronous and can omit a document version. After a workspace change, SuPi may report push-only diagnostics as partial or unavailable when it cannot prove that the result matches the current document. It does not treat missing fresh evidence as a clean file.
54
+
55
+ Unversioned pushes are accepted for an open document when they arrive after the document's sync moment (the client-side instant the `didChange` or `didOpen` that produced them was sent) and are re-stamped with the current synchronization; unversioned pushes for closed or untracked URIs, and pushes that arrive before a sync moment, stay fail-closed. On push-only routes, the first valid publication for a synchronization is tentative. A later valid publication for the same synchronization confirms it, and every publication restarts the quiet period. If no publication arrives, the existing bounded reopen path may ask the server to publish on `didOpen`; a tentative timeout does not reopen that document. In a mixed batch, silent documents can still use the reopen path. Non-empty tentative diagnostics are visible as partial evidence, but they do not enter the confirmed path. An empty tentative publication cannot establish a clean file and stays unavailable until a diagnostic republish arrives. Repeated unchanged queries share the tentative publication's wait age instead of starting a new full wait. A late republish promotes the cache without a new refresh.
56
+
57
+ Server readiness follows LSP work-done progress: a created progress token is pending and never blocks readiness; an observed `begin` marks active work and makes the client not ready until its `end` or the bounded per-token timeout.
58
+
59
+ A workspace diagnostic refresh returns exact coverage counts for requested, confirmed, unconfirmed, failed, and removed tracked documents. `code_health` marks tracked-file diagnostics as complete when each requested document is confirmed or known to be removed. It shows non-empty tentative diagnostics as partial entries, reports the same coverage counts in summary and detailed views, and explains when a diagnostic republish is needed. A refresh attempt does not prove fresh evidence by itself. A removed file is reported by the refresh that finds it and is not retained in later tracked-file snapshots.
60
+
61
+ An explicit recovery pass restarts a push-only client only on a protocol-stall signal (a readiness stall, or repeated JSON-RPC request failures) — never on unconfirmed evidence alone, because the reopen-resync fallback recovers unconfirmed documents without discarding warm server state. It never restarts a pull-capable client because push evidence is absent, and it never restarts a client during passive health display. Each client route restarts at most once per workspace invalidation generation. The replacement process has a fixed startup bound of 5 seconds; exceeding the bound fails closed as start-failed without retry. Recovery telemetry records the outcome, elapsed time, attempted clients, restart count, the bounded server names involved, and the stall signal that triggered a restart, without changing the evidence semantics of the result.
62
+
63
+ ### Optional diagnostic configuration
64
+
65
+ Configuration overrides merge with the built-in server definitions. Use `.pi/supi/config.json` for one project or `~/.pi/agent/supi/config.json` for all projects:
66
+
67
+ ```json
68
+ {
69
+ "lsp": {
70
+ "servers": {
71
+ "go": {
72
+ "initializationOptions": {
73
+ "pullDiagnostics": true
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ Gopls pull diagnostics stay opt-in while golang/go#70199 is open; without the option the built-in Go configuration stays in push mode. Kotlin's `--stdio` argument is already part of the built-in configuration and needs no override.
82
+
83
+ ### Custom server configuration
84
+
85
+ A custom server needs a command and at least one file type:
86
+
87
+ ```json
88
+ {
89
+ "lsp": {
90
+ "servers": {
91
+ "custom": {
92
+ "command": "custom-lsp",
93
+ "args": ["--stdio"],
94
+ "fileTypes": ["custom"],
95
+ "env": { "CUSTOM_LSP_LOG": "debug" },
96
+ "initializationOptions": { "mode": "project" }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ File types do not include a leading dot. If `rootMarkers` is omitted, the server uses the session root.
104
+
105
+ The `lsp.enabled` and `lsp.active` settings are deprecated and ignored. Disable one language with `lsp.servers.<language>.enabled: false`. Use `/supi-ci-status` from `@mrclrchtr/supi-code-intelligence` to see detected, running, and missing servers.
106
+
19
107
  ## What it provides
20
108
 
21
- - `LspRuntimeController` for workspace lifecycle and status
109
+ - `LspRuntimeController` for workspace lifecycle, status, and transition subscriptions
22
110
  - `WorkspaceLspRuntime` for routing, readiness, semantic operations, tracked files, diagnostics, and recovery
23
111
  - explicit ready, pending, inactive, disabled, and unavailable registry states
24
112
  - a `SemanticProvider` adapter for `supi-code-runtime`
@@ -33,7 +121,8 @@ Clients, `LspManager`, and the default runtime implementation remain internal.
33
121
  - language-server detection and startup
34
122
  - shutdown
35
123
  - settings and missing-server inventory
36
- - publishing workspace runtime state
124
+ - publishing workspace runtime state and aggregate lifecycle transitions
125
+ - projecting concrete client readiness into semantic capability state
37
126
 
38
127
  `WorkspaceLspRuntime` owns:
39
128
 
@@ -43,7 +132,21 @@ Clients, `LspManager`, and the default runtime implementation remain internal.
43
132
  - diagnostics, summaries, refresh, and recovery
44
133
  - project-server inventory and file support checks
45
134
 
46
- This separation keeps lifecycle/status distinct from workspace operations.
135
+ This separation keeps lifecycle and status distinct from workspace operations. Each controller transition has a monotonic generation and an aggregate server snapshot. Semantic capability is ready while at least one concrete client is ready. A crash or late progress event moves capability back to pending only after the final ready client is lost. The ready runtime owner stays available for lazy routing.
136
+
137
+ ### LSP debug telemetry identity
138
+
139
+ Retained and persisted LSP debug events may identify local workspaces, servers, files, and requests for protocol diagnosis. All LSP producers share one identity vocabulary:
140
+
141
+ - `cwd` — absolute workspace root (event level)
142
+ - `server` — configured server name, e.g. `typescript`
143
+ - `file` — workspace-relative path
144
+ - `method` — exact LSP method, e.g. `textDocument/hover`
145
+ - `root` — server root, absolute where present
146
+
147
+ `runtime.transition` events carry `cwd` and a bounded `servers` array (name, status, ready; at most 16 entries) alongside the aggregate counts. `readiness.*` events carry `cwd`, `server`, and `root`; their messages and data never embed raw progress-token values. `request.timing` events carry the exact `method`, `server`, and `cwd`, plus the JSON-RPC error code: the server-reported code for failed requests, and the defined constant `-32095` (`LSP_REQUEST_TIMEOUT_ERROR_CODE`) for local timeouts; cancellations carry no code. `diagnostics.timing` events carry `cwd`, `server`, and a workspace-relative `file` for `sync-file` operations; `refresh-open` stays aggregate. `runtime.recovery` events carry `cwd` and bounded attempted/restarted server names; a cancelled pass records the server names still running at cancellation, while restart identity requires the pass result. `capability.transition` events fire only on semantic ready↔pending transitions and carry `cwd` and the ready state — never for initialize, registration, or unregistration traffic. Code-intelligence events (`code-operation.*`, `workflow.timing`, `ast-scan.timing`) carry `cwd` only.
148
+
149
+ Identity strings — `cwd`, `server`, `file`, `method`, and `root` — are bounded to 512 UTF-16 code units (marker included; truncation appends `…`) and server lists to 16 entries. No raw protocol dumps, request/response params, diagnostic text, progress tokens, or unbounded file lists are recorded; `openFiles` stays a count. Identity fields are intentionally **not** secret-redacted — the debug registry still redacts secret keys and values, but server names, workspace-relative files, and method names pass through unredacted so local protocol failures stay diagnosable. The supi-debug package documents this disclosure for retained and persisted events.
47
150
 
48
151
  ## Example
49
152
 
@@ -65,6 +168,8 @@ if (state.kind === "ready") {
65
168
 
66
169
  Runtime methods use raw 0-based LSP positions. `toLspPosition()` converts user-facing 1-based coordinates. Read-only semantic and diagnostic methods return `CodeQueryResult<T>` so completed empty protocol responses remain distinct from partial or unavailable requests. A ready runtime owner may contain only lazy routes: workspace semantic readiness requires at least one active ready client, while file readiness requires the routed client for that file to start successfully. Empty client sets and failed routes are unavailable, not vacuously ready.
67
170
 
171
+ Semantic and explicit diagnostic operations accept optional shared `CodeRequestControl` metadata. The semantic adapter preserves the exact value through `WorkspaceLspRuntime`. The signal maps to LSP protocol cancellation (`$/cancelRequest`) and the absolute deadline bounds every request and readiness wait. The opaque Debug Operation ID reaches sanitized request and diagnostic timing events. Ambient readiness, lifecycle, capability, and push-diagnostic events have no Debug Operation ID.
172
+
68
173
  ## Startup performance
69
174
 
70
175
  Detected servers start concurrently. In a polyglot workspace, disable unneeded languages in `.pi/supi/config.json` or `~/.pi/agent/supi/config.json`:
@@ -110,6 +215,7 @@ See [`docs/adr/0016-workspace-lsp-runtime-interface.md`](../../docs/adr/0016-wor
110
215
  - `src/config/` — server configuration and protocol types
111
216
  - `src/diagnostics/` — stale diagnostics and workspace sentinels
112
217
  - `src/manager/` — package-internal server pool and routing, diagnostic, and recovery mechanics
113
- - `src/provider/` — semantic and refactor adapters
218
+ - `src/provider/` — semantic, mapping, and refactor adapters
114
219
  - `src/session/runtime-controller.ts` — lifecycle/status
115
- - `src/session/runtime-registry.ts` — `WorkspaceLspRuntime` and registry
220
+ - `src/session/workspace-lsp-runtime.ts` — `WorkspaceLspRuntime` contracts
221
+ - `src/session/runtime-registry.ts` — runtime implementation and registry