@mrclrchtr/supi-code-intelligence 1.16.1 → 2.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 (344) hide show
  1. package/README.md +373 -63
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  9. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  10. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  11. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  12. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  13. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  14. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  15. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  16. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  17. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  18. package/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  19. package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  20. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  21. package/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  22. package/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  23. package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  24. package/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  25. package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  26. package/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  27. package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  28. package/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  29. package/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  30. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  31. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  32. package/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  33. package/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  34. package/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/README.md +44 -56
  36. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  37. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  40. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  42. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  45. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  46. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  47. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  50. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  51. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  52. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  53. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  54. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  55. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  56. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  57. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  59. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  60. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  61. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  62. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  63. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  64. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  65. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  66. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  67. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  68. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  69. package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -31
  70. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +27 -0
  71. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +5 -0
  72. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +246 -1
  73. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +4 -0
  74. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +3 -0
  75. package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +4 -2
  76. package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +102 -0
  77. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +59 -0
  78. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +4 -0
  79. package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +11 -0
  80. package/node_modules/@mrclrchtr/supi-lsp/src/manager/capability-index.ts +1 -1
  81. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +2 -1
  82. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +115 -26
  83. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +177 -134
  84. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +214 -0
  85. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +320 -0
  86. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +26 -5
  87. package/node_modules/@mrclrchtr/supi-lsp/src/session/service-registry.ts +81 -4
  88. package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +2 -0
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +18 -37
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/LICENSE +21 -0
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/README.md +265 -0
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs +4661 -0
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs.map +7 -0
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js +4605 -0
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js.map +7 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +57 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +100 -0
  132. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs +4063 -0
  133. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs.map +7 -0
  134. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts +1025 -0
  135. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts.map +58 -0
  136. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1025 -0
  137. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +58 -0
  138. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js +4007 -0
  139. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js.map +7 -0
  140. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  141. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +55 -0
  142. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -12
  143. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +29 -0
  144. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +28 -0
  145. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -0
  146. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +14 -2
  147. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +157 -0
  148. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +8 -1
  149. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +86 -0
  150. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +35 -16
  151. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +1 -0
  152. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +10 -0
  153. package/package.json +14 -9
  154. package/src/{model.ts → analysis/architecture/discovery.ts} +15 -72
  155. package/src/analysis/architecture/model.ts +76 -0
  156. package/src/analysis/brief/directory.ts +324 -0
  157. package/src/analysis/brief/enrich.ts +157 -0
  158. package/src/analysis/brief/file.ts +84 -0
  159. package/src/analysis/brief/inventory.ts +177 -0
  160. package/src/analysis/brief/main.ts +176 -0
  161. package/src/analysis/brief/models.ts +75 -0
  162. package/src/{brief.ts → analysis/brief/public-brief.ts} +21 -26
  163. package/src/analysis/brief/summarize.ts +208 -0
  164. package/src/analysis/brief/types.ts +27 -0
  165. package/src/{use-case/generate-brief.ts → analysis/brief/use-case.ts} +67 -144
  166. package/src/analysis/coverage/coverage-warnings.ts +224 -0
  167. package/src/analysis/evidence.ts +91 -0
  168. package/src/{semantic-action-helpers.ts → analysis/helpers.ts} +4 -4
  169. package/src/analysis/provider.ts +186 -0
  170. package/src/analysis/read-next.ts +126 -0
  171. package/src/analysis/readiness.ts +73 -0
  172. package/src/{refactor → analysis/refactor}/safety.ts +1 -1
  173. package/src/{use-case/support/semantic-references.ts → analysis/references/semantic-refs.ts} +58 -26
  174. package/src/analysis/search/pattern.ts +345 -0
  175. package/src/analysis/search/ripgrep.ts +473 -0
  176. package/src/{git-context.ts → analysis/signals/git.ts} +20 -7
  177. package/src/{prioritization-signals.ts → analysis/signals/project.ts} +33 -19
  178. package/src/analysis/target/anchored.ts +349 -0
  179. package/src/analysis/target/bridge.ts +152 -0
  180. package/src/analysis/target/file-resolution.ts +125 -0
  181. package/src/{targeting/resolve-file.ts → analysis/target/file.ts} +40 -20
  182. package/src/{planner → analysis/target}/planner.ts +30 -20
  183. package/src/{targeting → analysis/target}/query.ts +17 -3
  184. package/src/analysis/target/resolve-common.ts +115 -0
  185. package/src/analysis/target/service.ts +229 -0
  186. package/src/analysis/target/symbol.ts +196 -0
  187. package/src/{targeting → analysis/target}/types.ts +17 -1
  188. package/src/analysis/tests/likely-tests.ts +174 -0
  189. package/src/analysis/tests/test-discovery.ts +540 -0
  190. package/src/analysis/tests/vitest.ts +87 -0
  191. package/src/api.ts +34 -41
  192. package/src/app/app.ts +125 -0
  193. package/src/app/manager.ts +65 -0
  194. package/src/extension.ts +132 -1
  195. package/src/index.ts +1 -57
  196. package/src/session/refactor-plans.ts +82 -0
  197. package/src/session/session.ts +300 -0
  198. package/src/session/target-store.ts +293 -0
  199. package/src/substrate/lsp/diagnostic-injection.ts +218 -0
  200. package/src/substrate/lsp/lifecycle.ts +66 -0
  201. package/src/substrate/lsp/overrides.ts +132 -0
  202. package/src/substrate/lsp/recovery.ts +55 -0
  203. package/src/substrate/lsp/settings.ts +286 -0
  204. package/src/substrate/lsp/state.ts +46 -0
  205. package/src/substrate/lsp/utils.ts +17 -0
  206. package/src/substrate/tree-sitter/lifecycle.ts +52 -0
  207. package/src/tool/find/execute.ts +118 -0
  208. package/src/{presentation/markdown/pattern.ts → tool/find/markdown.ts} +102 -53
  209. package/src/{use-case/generate-pattern.ts → tool/find/orchestrate.ts} +67 -33
  210. package/src/tool/find/semantic-search.ts +114 -0
  211. package/src/tool/find/tui.ts +39 -0
  212. package/src/tool/graph/callees.ts +87 -0
  213. package/src/tool/graph/calls-md.ts +54 -0
  214. package/src/tool/graph/collect-relation.ts +371 -0
  215. package/src/tool/graph/execute.ts +95 -0
  216. package/src/tool/graph/implementations-md.ts +79 -0
  217. package/src/tool/graph/implementations.ts +76 -0
  218. package/src/tool/graph/markdown-base.ts +243 -0
  219. package/src/tool/graph/orchestrate.ts +285 -0
  220. package/src/tool/graph/references-md.ts +34 -0
  221. package/src/tool/graph/references.ts +81 -0
  222. package/src/tool/graph/tui.ts +120 -0
  223. package/src/tool/graph/types.ts +97 -0
  224. package/src/tool/guidance.ts +96 -49
  225. package/src/tool/health/execute.ts +76 -0
  226. package/src/tool/health/markdown.ts +280 -0
  227. package/src/tool/health/orchestrate.ts +159 -0
  228. package/src/tool/health/sections/diagnostics.ts +182 -0
  229. package/src/tool/health/sections/recovery.ts +89 -0
  230. package/src/tool/health/sections/signals.ts +89 -0
  231. package/src/tool/health/tui.ts +137 -0
  232. package/src/tool/impact/analysis.ts +247 -0
  233. package/src/tool/impact/change-set-impact.ts +151 -0
  234. package/src/tool/impact/execute.ts +98 -0
  235. package/src/tool/impact/file-level-impact.ts +81 -0
  236. package/src/tool/impact/markdown.ts +283 -0
  237. package/src/tool/impact/orchestrate.ts +97 -0
  238. package/src/tool/impact/result.ts +21 -0
  239. package/src/tool/impact/single-impact.ts +89 -0
  240. package/src/tool/impact/tui.ts +39 -0
  241. package/src/tool/impact/types.ts +34 -0
  242. package/src/tool/infra/cross-field.ts +335 -0
  243. package/src/tool/infra/error-results.ts +199 -0
  244. package/src/tool/infra/pipeline.ts +311 -0
  245. package/src/tool/infra/progress.ts +21 -0
  246. package/src/tool/infra/readiness-message.ts +5 -0
  247. package/src/tool/infra/truncate.ts +49 -0
  248. package/src/tool/inspect/execute.ts +76 -0
  249. package/src/tool/inspect/markdown.ts +169 -0
  250. package/src/tool/inspect/orchestrate.ts +156 -0
  251. package/src/tool/inspect/tui.ts +36 -0
  252. package/src/tool/orientation/deps.ts +63 -0
  253. package/src/tool/orientation/execute.ts +50 -0
  254. package/src/tool/orientation/markdown.ts +35 -0
  255. package/src/tool/orientation/mode.ts +88 -0
  256. package/src/tool/orientation/orchestrate.ts +478 -0
  257. package/src/tool/orientation/precise-target.ts +257 -0
  258. package/src/tool/orientation/tui.ts +131 -0
  259. package/src/{refactor/apply-workspace-edit.ts → tool/refactor-apply/apply.ts} +39 -16
  260. package/src/tool/refactor-apply/execute.ts +20 -0
  261. package/src/tool/refactor-apply/markdown.ts +118 -0
  262. package/src/tool/refactor-apply/orchestrate.ts +89 -0
  263. package/src/tool/refactor-apply/tui.ts +51 -0
  264. package/src/tool/refactor-plan/execute.ts +73 -0
  265. package/src/tool/refactor-plan/markdown.ts +118 -0
  266. package/src/tool/refactor-plan/orchestrate.ts +363 -0
  267. package/src/tool/refactor-plan/tui.ts +42 -0
  268. package/src/tool/register.ts +123 -0
  269. package/src/tool/resolve/execute.ts +82 -0
  270. package/src/tool/resolve/markdown.ts +150 -0
  271. package/src/tool/resolve/orchestrate.ts +134 -0
  272. package/src/tool/resolve/tui.ts +40 -0
  273. package/src/tool/schemas.ts +337 -0
  274. package/src/tool/specs.ts +257 -0
  275. package/src/types/details.ts +188 -0
  276. package/src/types/execution.ts +60 -0
  277. package/src/types/index.ts +28 -0
  278. package/src/{intent/types.ts → types/tool-names.ts} +15 -14
  279. package/src/ui/footer.ts +52 -0
  280. package/src/ui/markdown/brief.ts +218 -0
  281. package/src/ui/markdown/gather.ts +177 -0
  282. package/src/{use-case/build-overview.ts → ui/markdown/overview-data.ts} +2 -2
  283. package/src/{presentation → ui}/markdown/overview.ts +2 -2
  284. package/src/ui/markdown/types.ts +80 -0
  285. package/{node_modules/@mrclrchtr/supi-lsp/src/ui/renderer.ts → src/ui/message-renderer.ts} +11 -10
  286. package/src/ui/status-command.ts +260 -0
  287. package/src/ui/status-overlay.ts +500 -0
  288. package/src/ui/tui/common.ts +220 -0
  289. package/src/ui/tui/index.ts +37 -0
  290. package/node_modules/@mrclrchtr/supi-lsp/src/extension.ts +0 -1
  291. package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +0 -373
  292. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/diagnostic-injection.ts +0 -182
  293. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/session-lifecycle.ts +0 -149
  294. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/status-command.ts +0 -38
  295. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/workspace-recovery.ts +0 -92
  296. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +0 -37
  297. package/node_modules/@mrclrchtr/supi-lsp/src/session/lsp-state.ts +0 -93
  298. package/node_modules/@mrclrchtr/supi-lsp/src/session/settings-registration.ts +0 -296
  299. package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +0 -75
  300. package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +0 -69
  301. package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +0 -27
  302. package/node_modules/@mrclrchtr/supi-lsp/src/tool/overrides.ts +0 -204
  303. package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +0 -69
  304. package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +0 -399
  305. package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +0 -248
  306. package/node_modules/@mrclrchtr/supi-lsp/src/ui/ui.ts +0 -360
  307. package/node_modules/@mrclrchtr/supi-lsp/src/workspace-change.ts +0 -40
  308. package/node_modules/@mrclrchtr/supi-tree-sitter/src/extension.ts +0 -1
  309. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/formatting.ts +0 -104
  310. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +0 -35
  311. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/handlers.ts +0 -196
  312. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/register-tools.ts +0 -107
  313. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/tool-specs.ts +0 -117
  314. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +0 -47
  315. package/src/brief-focused.ts +0 -563
  316. package/src/code-intelligence.ts +0 -70
  317. package/src/pattern-structured.ts +0 -194
  318. package/src/presentation/markdown/affected.ts +0 -170
  319. package/src/presentation/markdown/brief.ts +0 -174
  320. package/src/presentation/markdown/map.ts +0 -54
  321. package/src/presentation/markdown/refactor.ts +0 -27
  322. package/src/presentation/markdown/relations.ts +0 -121
  323. package/src/resolve-target.ts +0 -130
  324. package/src/search-helpers.ts +0 -303
  325. package/src/substrates/types.ts +0 -30
  326. package/src/target-resolution.ts +0 -122
  327. package/src/targeting/resolve-anchored.ts +0 -80
  328. package/src/targeting/resolve-symbol.ts +0 -110
  329. package/src/tool/execute-affected.ts +0 -71
  330. package/src/tool/execute-brief.ts +0 -59
  331. package/src/tool/execute-map.ts +0 -35
  332. package/src/tool/execute-pattern.ts +0 -29
  333. package/src/tool/execute-refactor.ts +0 -101
  334. package/src/tool/execute-relations.ts +0 -79
  335. package/src/tool/register-tools.ts +0 -32
  336. package/src/tool/tool-specs.ts +0 -190
  337. package/src/tool/validation.ts +0 -43
  338. package/src/types.ts +0 -169
  339. package/src/use-case/generate-affected.ts +0 -297
  340. package/src/use-case/generate-map.ts +0 -176
  341. package/src/use-case/generate-relations.ts +0 -438
  342. package/src/use-case/types.ts +0 -43
  343. package/src/workspace/request-context.ts +0 -139
  344. /package/src/{query-params.ts → tool/params.ts} +0 -0
@@ -0,0 +1,89 @@
1
+ // Coverage, unused, and server collection for code_health.
2
+ // Extracted from orchestrate.ts.
3
+
4
+ import { existsSync } from "node:fs";
5
+ import { resolve } from "node:path";
6
+ import { isWithinOrEqual } from "@mrclrchtr/supi-core/api";
7
+ import type { SessionLspService } from "@mrclrchtr/supi-lsp/api";
8
+ import { gatherGitContext } from "../../../analysis/signals/git.ts";
9
+ import type { LoadedSignals } from "../../../analysis/signals/project.ts";
10
+ import type {
11
+ HealthCoverageData,
12
+ HealthData,
13
+ HealthSection,
14
+ HealthUnusedData,
15
+ } from "../markdown.ts";
16
+
17
+ // ── Servers ───────────────────────────────────────────────────────────
18
+
19
+ export function collectServers(
20
+ service: SessionLspService | null,
21
+ included: string[],
22
+ ): HealthData["servers"] {
23
+ if (!included.includes("servers") || !service) return [];
24
+
25
+ return service.getProjectServers().map((s) => ({
26
+ name: s.name,
27
+ root: s.root,
28
+ fileTypes: s.fileTypes,
29
+ status: s.status,
30
+ }));
31
+ }
32
+
33
+ // ── Coverage ──────────────────────────────────────────────────────────
34
+
35
+ export function needsPrioritizationSignals(included: HealthSection[]): boolean {
36
+ return included.includes("coverage") || included.includes("unused");
37
+ }
38
+
39
+ export function collectCoverageSection(
40
+ loaded: LoadedSignals | null,
41
+ cwd: string,
42
+ scopeFilter: string | null,
43
+ coveragePath?: string,
44
+ ): HealthCoverageData {
45
+ const reportPath = resolve(cwd, coveragePath ?? "coverage/coverage-summary.json");
46
+ if (!existsSync(reportPath) || !loaded) {
47
+ return { available: false, entries: [] };
48
+ }
49
+
50
+ const entries = [...loaded.coverageByFile.entries()]
51
+ .filter(([file, pct]) => pct < 50 && isWithinOptionalScope(scopeFilter, file))
52
+ .sort((left, right) => left[1] - right[1] || left[0].localeCompare(right[0]))
53
+ .map(([file, pct]) => ({ file, pct }));
54
+
55
+ return { available: true, entries };
56
+ }
57
+
58
+ export function collectUnusedSection(
59
+ loaded: LoadedSignals | null,
60
+ cwd: string,
61
+ scopeFilter: string | null,
62
+ unusedPath?: string,
63
+ ): HealthUnusedData {
64
+ const reportPath = resolve(cwd, unusedPath ?? "knip.json");
65
+ if (!existsSync(reportPath) || !loaded) {
66
+ return { available: false, files: [], exports: [] };
67
+ }
68
+
69
+ const files = [...loaded.unusedFiles]
70
+ .filter((file) => isWithinOptionalScope(scopeFilter, file))
71
+ .sort((left, right) => left.localeCompare(right));
72
+ const exports = loaded.unusedExports
73
+ .filter((entry) => isWithinOptionalScope(scopeFilter, entry.file))
74
+ .sort((left, right) => left.name.localeCompare(right.name));
75
+
76
+ return { available: true, files, exports };
77
+ }
78
+
79
+ // ── Git context ───────────────────────────────────────────────────────
80
+
81
+ export function collectGitContext(included: string[], cwd: string) {
82
+ return included.includes("dirty") ? gatherGitContext(cwd) : null;
83
+ }
84
+
85
+ // ── Helpers ───────────────────────────────────────────────────────────
86
+
87
+ function isWithinOptionalScope(scopeFilter: string | null, file: string): boolean {
88
+ return !scopeFilter || isWithinOrEqual(scopeFilter, file);
89
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * TUI renderer for code_health — renderCall + renderResult.
3
+ */
4
+
5
+ import type { Theme } from "@earendil-works/pi-coding-agent";
6
+ import { Container, Spacer, Text } from "@earendil-works/pi-tui";
7
+ import { formatEvidenceBadge } from "@mrclrchtr/supi-code-runtime/api";
8
+ import {
9
+ type EvidenceEntry,
10
+ type ResultOptios,
11
+ renderEvidenceLines,
12
+ renderMarkdownDetail,
13
+ renderPartial,
14
+ type ToolResult,
15
+ } from "../../ui/tui/common.ts";
16
+ import type { CodeHealthToolParams } from "./execute.ts";
17
+
18
+ /** ── renderCall ────────────────────────────────────────────────── */
19
+
20
+ export function renderHealthCall(args: unknown, theme: Theme, _context: unknown): Text {
21
+ const params = (args ?? {}) as CodeHealthToolParams;
22
+ const sections = params.include?.length ? params.include.join(", ") : "diag, servers";
23
+
24
+ let content = theme.fg("toolTitle", "code_health");
25
+ content += ` ${theme.fg("accent", sections)}`;
26
+
27
+ if (params.scope) {
28
+ content += ` ${theme.fg("dim", params.scope)}`;
29
+ }
30
+
31
+ return new Text(content, 0, 0);
32
+ }
33
+
34
+ /** ── renderResult ──────────────────────────────────────────────── */
35
+
36
+ export function renderHealthResult(
37
+ result: ToolResult,
38
+ options: ResultOptios,
39
+ theme: Theme,
40
+ _context: unknown,
41
+ ): Container | Text {
42
+ if (options.isPartial) {
43
+ return renderPartial("Gathering workspace health…", theme);
44
+ }
45
+
46
+ const container = new Container();
47
+ const data =
48
+ result.details?.type === "health" ? (result.details.data as Record<string, unknown>) : null;
49
+
50
+ if (result.isError) {
51
+ container.addChild(new Text(theme.fg("error", "code_health failed"), 0, 0));
52
+ return container;
53
+ }
54
+
55
+ if (!options.expanded) {
56
+ container.addChild(buildCompactSummary(data, theme));
57
+ return container;
58
+ }
59
+
60
+ // Expanded view
61
+ container.addChild(buildStatusBar(data, theme));
62
+ container.addChild(new Spacer(1));
63
+ container.addChild(buildDiagnosticSummary(data, theme));
64
+
65
+ const lists = data?.evidenceLists as EvidenceEntry[] | undefined;
66
+ if (lists && lists.length > 0) {
67
+ container.addChild(new Spacer(1));
68
+ renderEvidenceLines(container, lists, theme);
69
+ }
70
+
71
+ renderMarkdownDetail(container, result, theme);
72
+
73
+ return container;
74
+ }
75
+
76
+ /** ── Helpers ───────────────────────────────────────────────────── */
77
+
78
+ function buildCompactSummary(data: Record<string, unknown> | null, theme: Theme): Text {
79
+ if (!data) {
80
+ return new Text(theme.fg("dim", "No health data"), 0, 0);
81
+ }
82
+
83
+ const diagCount = (data.diagnosticFileCount as number) ?? 0;
84
+ const serverCount = (data.serverCount as number) ?? 0;
85
+ const lspStatus = (data.lspStatus as string) ?? "unknown";
86
+
87
+ const statusColor = lspStatus === "ready" ? "success" : "warning";
88
+ const dot = theme.fg("dim", "·");
89
+
90
+ const segments = [
91
+ `${theme.fg("dim", "diag")} ${theme.fg("success", theme.bold(`${diagCount}`))}${theme.fg("muted", " with issues")}`,
92
+ `${theme.fg("dim", "servers")} ${theme.fg("muted", `${serverCount}`)}`,
93
+ `${theme.fg("dim", "lsp")} ${theme.fg(statusColor, lspStatus)}`,
94
+ ];
95
+
96
+ return new Text(segments.join(` ${dot} `), 0, 0);
97
+ }
98
+
99
+ function buildStatusBar(data: Record<string, unknown> | null, theme: Theme): Text {
100
+ if (!data) return new Text("", 0, 0);
101
+
102
+ const lspStatus = (data.lspStatus as string) ?? "unknown";
103
+ const structuralStatus = (data.structuralStatus as string) ?? "unknown";
104
+ const recovered = data.recovered;
105
+
106
+ const lspColor = lspStatus.startsWith("ready") ? "success" : "warning";
107
+ const structuralColor = structuralStatus === "ready" ? "success" : "muted";
108
+
109
+ const lspLabel =
110
+ lspStatus.includes("(recovered)") || !recovered ? lspStatus : `${lspStatus} (recovered)`;
111
+
112
+ const lines: string[] = [
113
+ `LSP: ${theme.fg(lspColor, lspLabel)}`,
114
+ `Tree-sitter: ${theme.fg(structuralColor, structuralStatus)}`,
115
+ ];
116
+
117
+ return new Text(lines.join(" "), 0, 0);
118
+ }
119
+
120
+ function buildDiagnosticSummary(data: Record<string, unknown> | null, theme: Theme): Text {
121
+ if (!data) return new Text("", 0, 0);
122
+
123
+ const diagCount = (data.diagnosticFileCount as number) ?? 0;
124
+ if (diagCount === 0) {
125
+ return new Text(theme.fg("success", "No diagnostics found"), 0, 0);
126
+ }
127
+
128
+ const badge = formatEvidenceBadge({
129
+ shownCount: diagCount,
130
+ totalCount: diagCount,
131
+ omittedCount: 0,
132
+ partialReason: null,
133
+ label: "files with issues",
134
+ });
135
+
136
+ return new Text(theme.fg("warning", theme.bold(badge)), 0, 0);
137
+ }
@@ -0,0 +1,247 @@
1
+ // Impact analysis — shared analysis functions for impact orchestration.
2
+ // Extracted from orchestrate.ts to keep per-mode files focused.
3
+
4
+ import * as path from "node:path";
5
+ import type { buildArchitectureModel } from "../../analysis/architecture/discovery.ts";
6
+ import { findModuleForPath, getDependents } from "../../analysis/architecture/model.ts";
7
+ import type { EvidenceListMetadata } from "../../analysis/evidence.ts";
8
+ import type { CodeProvider } from "../../analysis/provider.ts";
9
+ import type { ReferenceCollection } from "../../analysis/references/semantic-refs.ts";
10
+ import type { ResolvedTargetData } from "../../analysis/target/types.ts";
11
+ import {
12
+ buildLikelyTestCommands,
13
+ buildTestAnchorMap,
14
+ type ChangeSetFileEntry,
15
+ collectLikelyTests,
16
+ type TestAnchorMap,
17
+ } from "../../analysis/tests/likely-tests.ts";
18
+ import { buildTestSurfaceDetails } from "../../analysis/tests/test-discovery.ts";
19
+ import type { AffectedDetails, ImpactDetails } from "../../types/index.ts";
20
+ import type { ImpactAnalysis } from "./types.ts";
21
+
22
+ // ── Shared analysis ────────────────────────────────────────────────────
23
+
24
+ /** Seed files parameter is explicit for testability. */
25
+ // biome-ignore lint/complexity/useMaxParams: explicit params for testability
26
+ export async function analyzeReferenceImpact(
27
+ result: ReferenceCollection,
28
+ model: Awaited<ReturnType<typeof buildArchitectureModel>>,
29
+ cwd: string,
30
+ includeTests: boolean,
31
+ references: CodeProvider["references"] | undefined,
32
+ seedFiles?: string[],
33
+ testAnchors?: TestAnchorMap,
34
+ outline?: CodeProvider["outline"],
35
+ ): Promise<ImpactAnalysis> {
36
+ const affectedFiles = new Set(result.refs.map((r) => path.resolve(cwd, r.file)));
37
+
38
+ // Seed the target file(s) so zero-reference targets still have affected evidence
39
+ if (seedFiles) {
40
+ for (const f of seedFiles) {
41
+ affectedFiles.add(path.resolve(cwd, f));
42
+ }
43
+ }
44
+
45
+ const { affectedModules, checkNext, downstreamCount } = analyzeModelImpact(
46
+ affectedFiles,
47
+ model,
48
+ cwd,
49
+ );
50
+
51
+ const likelyTestsResult = includeTests
52
+ ? await collectLikelyTests(affectedFiles, cwd, references, testAnchors, undefined, outline)
53
+ : null;
54
+ const likelyTests = likelyTestsResult?.paths ?? [];
55
+ const likelyTestCommands = buildLikelyTestCommands(cwd, likelyTests);
56
+ const tests =
57
+ likelyTestsResult === null
58
+ ? undefined
59
+ : buildTestSurfaceDetails(
60
+ {
61
+ status: likelyTestsResult.files.length > 0 ? "found" : "empty",
62
+ provenance: likelyTestsResult.provenance,
63
+ files: likelyTestsResult.files,
64
+ },
65
+ cwd,
66
+ );
67
+
68
+ return {
69
+ confidence: result.confidence,
70
+ affectedFiles,
71
+ affectedModules,
72
+ downstreamCount,
73
+ checkNext,
74
+ likelyTests,
75
+ likelyTestCommands,
76
+ tests,
77
+ riskLevel: assessRisk(
78
+ result.refs.length + result.externalCount,
79
+ affectedModules.size,
80
+ downstreamCount,
81
+ ),
82
+ externalRefs: result.externalCount,
83
+ };
84
+ }
85
+
86
+ export interface AnalyzeChangeSetOptions {
87
+ changeSetFiles: ChangeSetFileEntry[];
88
+ model: Awaited<ReturnType<typeof buildArchitectureModel>>;
89
+ cwd: string;
90
+ includeTests: boolean;
91
+ semanticImpact: ChangeSetSemanticImpact | null;
92
+ }
93
+
94
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: change-set impact merges structural, semantic, test, and risk evidence in one staged result.
95
+ export async function analyzeChangeSet(options: AnalyzeChangeSetOptions): Promise<ImpactAnalysis> {
96
+ const { changeSetFiles, model, cwd, includeTests, semanticImpact } = options;
97
+ const affectedFiles = new Set(changeSetFiles.map((entry) => entry.absPath));
98
+ if (semanticImpact) {
99
+ for (const ref of semanticImpact.refs.refs) {
100
+ affectedFiles.add(path.resolve(cwd, ref.file));
101
+ }
102
+ }
103
+
104
+ const { affectedModules, checkNext, downstreamCount } = analyzeModelImpact(
105
+ affectedFiles,
106
+ model,
107
+ cwd,
108
+ );
109
+
110
+ const likelyTestsResult = includeTests
111
+ ? await collectLikelyTests(
112
+ affectedFiles,
113
+ cwd,
114
+ semanticImpact?.references,
115
+ semanticImpact ? buildTestAnchorMap(semanticImpact.targets) : undefined,
116
+ semanticImpact ? undefined : "conventions-only",
117
+ semanticImpact?.outline,
118
+ )
119
+ : null;
120
+ const likelyTests = likelyTestsResult?.paths ?? [];
121
+ const likelyTestCommands = buildLikelyTestCommands(cwd, likelyTests);
122
+ const tests =
123
+ likelyTestsResult === null
124
+ ? undefined
125
+ : buildTestSurfaceDetails(
126
+ {
127
+ status: likelyTestsResult.files.length > 0 ? "found" : "empty",
128
+ provenance: likelyTestsResult.provenance,
129
+ files: likelyTestsResult.files,
130
+ },
131
+ cwd,
132
+ );
133
+
134
+ const semanticRefCount = semanticImpact ? semanticImpact.refs.refs.length : 0;
135
+ const externalRefs = semanticImpact ? semanticImpact.refs.externalCount : 0;
136
+ const semanticRefFiles = semanticImpact ? collectUniqueRefFiles(semanticImpact.refs) : undefined;
137
+
138
+ return {
139
+ confidence: semanticImpact ? "semantic" : "structural",
140
+ affectedFiles,
141
+ affectedModules,
142
+ downstreamCount,
143
+ checkNext,
144
+ likelyTests,
145
+ likelyTestCommands,
146
+ tests,
147
+ riskLevel: assessRisk(
148
+ changeSetFiles.length + semanticRefCount,
149
+ affectedModules.size,
150
+ downstreamCount,
151
+ ),
152
+ externalRefs,
153
+ semanticRefFiles,
154
+ };
155
+ }
156
+
157
+ export interface ChangeSetSemanticImpact {
158
+ targets: ResolvedTargetData[];
159
+ refs: ReferenceCollection;
160
+ references: CodeProvider["references"];
161
+ outline?: CodeProvider["outline"];
162
+ }
163
+
164
+ export function collectUniqueRefFiles(refs: ReferenceCollection): string[] {
165
+ return [...new Set(refs.refs.map((ref) => ref.file))].sort((a, b) => a.localeCompare(b));
166
+ }
167
+
168
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: module-impact traversal keeps affected/downstream/check-next logic together
169
+ export function analyzeModelImpact(
170
+ affectedFiles: Set<string>,
171
+ model: Awaited<ReturnType<typeof buildArchitectureModel>>,
172
+ cwd: string,
173
+ ): Pick<ImpactAnalysis, "affectedModules" | "checkNext" | "downstreamCount"> {
174
+ const affectedModules = new Set<string>();
175
+ const checkNext: string[] = [];
176
+ let downstreamCount = 0;
177
+
178
+ if (model) {
179
+ for (const file of affectedFiles) {
180
+ const mod = findModuleForPath(model, path.resolve(cwd, file));
181
+ if (mod) affectedModules.add(mod.name);
182
+ }
183
+
184
+ const downstreamModules = new Set<string>();
185
+ const queue = [...affectedModules];
186
+ while (queue.length > 0) {
187
+ const modName = queue.shift() as string;
188
+ for (const dep of getDependents(model, modName)) {
189
+ if (!affectedModules.has(dep.name) && !downstreamModules.has(dep.name)) {
190
+ downstreamModules.add(dep.name);
191
+ queue.push(dep.name);
192
+ }
193
+ }
194
+ }
195
+ downstreamCount = downstreamModules.size;
196
+
197
+ for (const modName of [...affectedModules, ...downstreamModules].slice(0, 3)) {
198
+ const mod = model.modules.find((m) => m.name === modName);
199
+ if (mod) checkNext.push(`${mod.name.replace(/^@[^/]+\//, "")} (\`${mod.relativePath}\`)`);
200
+ }
201
+ }
202
+
203
+ return { affectedModules, checkNext, downstreamCount };
204
+ }
205
+
206
+ export function assessRisk(
207
+ totalRefs: number,
208
+ moduleCount: number,
209
+ downstreamCount: number,
210
+ ): "low" | "medium" | "high" {
211
+ if (totalRefs > 10 || moduleCount > 3 || downstreamCount > 1) return "high";
212
+ if (totalRefs > 3 || moduleCount > 1 || downstreamCount >= 1) return "medium";
213
+ return "low";
214
+ }
215
+
216
+ export function computeOmittedCount(
217
+ externalRefs: number,
218
+ affectedFileCount: number,
219
+ maxResults?: number,
220
+ ): number {
221
+ return externalRefs + Math.max(0, affectedFileCount - (maxResults ?? 8));
222
+ }
223
+
224
+ // biome-ignore lint/complexity/useMaxParams: detail assembly keeps shared counts, queries, and signals explicit for both surfaces
225
+ export function buildDetailsData(
226
+ analysis: ImpactAnalysis,
227
+ directCount: number,
228
+ omittedCount: number,
229
+ nextQueries: string[],
230
+ prioritySignals: AffectedDetails["prioritySignals"],
231
+ evidenceLists: EvidenceListMetadata[] = [],
232
+ ): AffectedDetails | ImpactDetails {
233
+ return {
234
+ confidence: analysis.confidence,
235
+ directCount,
236
+ downstreamCount: analysis.downstreamCount,
237
+ riskLevel: analysis.riskLevel,
238
+ checkNext: analysis.checkNext,
239
+ likelyTests: analysis.likelyTests,
240
+ likelyTestCommands: analysis.likelyTestCommands,
241
+ omittedCount,
242
+ evidenceLists,
243
+ nextQueries,
244
+ prioritySignals,
245
+ tests: analysis.tests,
246
+ };
247
+ }
@@ -0,0 +1,151 @@
1
+ // Change-set impact execution.
2
+ // Extracted from orchestrate.ts.
3
+
4
+ import { buildArchitectureModel } from "../../analysis/architecture/discovery.ts";
5
+ import type { CodeProvider } from "../../analysis/provider.ts";
6
+ import { aggregatePerTarget, collectReferences } from "../../analysis/references/semantic-refs.ts";
7
+ import { summarizePrioritySignalsForFiles } from "../../analysis/signals/project.ts";
8
+ import { resolveFileTargetGroup } from "../../analysis/target/file.ts";
9
+ import type { ResolvedTargetData } from "../../analysis/target/types.ts";
10
+ import type { ChangeSetFileEntry } from "../../analysis/tests/likely-tests.ts";
11
+ import { normalizeChangeSet } from "../../analysis/tests/likely-tests.ts";
12
+ import type { CodeIntelResult } from "../../types/index.ts";
13
+ import { analyzeChangeSet, buildDetailsData, type ChangeSetSemanticImpact } from "./analysis.ts";
14
+ import { renderChangeSetImpact } from "./markdown.ts";
15
+ import { unavailableImpactResult } from "./result.ts";
16
+ import type { ImpactAnalysis, ImpactInput } from "./types.ts";
17
+
18
+ export async function executeChangeSetImpact(
19
+ input: ImpactInput,
20
+ cwd: string,
21
+ provider: CodeProvider | null,
22
+ lspService: import("@mrclrchtr/supi-lsp/api").SessionLspServiceState,
23
+ ): Promise<CodeIntelResult> {
24
+ const changeSetFiles = normalizeChangeSet(input.changeSetFiles ?? [], cwd);
25
+ if (changeSetFiles.length === 0) {
26
+ return unavailableImpactResult(
27
+ "**Unavailable:** No readable change-set files were provided for impact analysis.",
28
+ [
29
+ "Provide `changeSetFiles` with workspace-relative file paths",
30
+ "Use `code_resolve` when you want symbol-level impact instead",
31
+ ],
32
+ );
33
+ }
34
+
35
+ const model = await buildArchitectureModel(cwd);
36
+ const semanticImpact = await collectChangeSetSemanticImpact(changeSetFiles, cwd, provider);
37
+ const analysis = await analyzeChangeSet({
38
+ changeSetFiles,
39
+ model,
40
+ cwd,
41
+ includeTests: input.includeTests === true,
42
+ semanticImpact,
43
+ });
44
+ const prioritySignals = summarizePrioritySignalsForFiles(
45
+ cwd,
46
+ changeSetFiles.map((entry) => entry.absPath),
47
+ lspService,
48
+ );
49
+ const nextQueries = buildChangeSetNextQueries(changeSetFiles, analysis, semanticImpact);
50
+ const upgradeSuggestion = buildSemanticUpgradeSuggestion(changeSetFiles, semanticImpact);
51
+ const evidenceNote =
52
+ analysis.confidence === "semantic"
53
+ ? "\n**Evidence: semantic+structural** — semantic references for symbols defined in change-set files were merged with file-level module analysis and bounded test discovery.\n"
54
+ : `\n**Evidence: structural** — impact limited to file-level module analysis and path-based test discovery.\n${upgradeSuggestion}\n`;
55
+ const content =
56
+ renderChangeSetImpact({
57
+ changeSetFiles: changeSetFiles.map((entry) => entry.relPath),
58
+ analysis,
59
+ prioritySignals,
60
+ }) + evidenceNote;
61
+
62
+ const detailsData = buildDetailsData(
63
+ analysis,
64
+ changeSetFiles.length,
65
+ 0,
66
+ nextQueries,
67
+ prioritySignals,
68
+ );
69
+
70
+ return {
71
+ content,
72
+ details: {
73
+ type: "impact",
74
+ data: detailsData,
75
+ },
76
+ };
77
+ }
78
+
79
+ async function collectChangeSetSemanticImpact(
80
+ changeSetFiles: ChangeSetFileEntry[],
81
+ cwd: string,
82
+ provider: CodeProvider | null,
83
+ ): Promise<ChangeSetSemanticImpact | null> {
84
+ if (!provider?.references) return null;
85
+
86
+ const targets: ResolvedTargetData[] = [];
87
+ for (const entry of changeSetFiles) {
88
+ try {
89
+ const outcome = await resolveFileTargetGroup(entry.relPath, cwd, {
90
+ semantic: provider,
91
+ structural: provider,
92
+ });
93
+ if (outcome.kind === "resolved") {
94
+ targets.push(...outcome.group.targets);
95
+ }
96
+ } catch {
97
+ // Keep change-set analysis best-effort: structural impact still applies.
98
+ }
99
+ }
100
+
101
+ const cappedTargets = targets.slice(0, 25);
102
+ if (cappedTargets.length === 0) return null;
103
+
104
+ const refs = await aggregatePerTarget(cappedTargets, (target) =>
105
+ collectReferences(target, cwd, provider),
106
+ );
107
+ if (refs.confidence !== "semantic" || (refs.refs.length === 0 && refs.externalCount === 0)) {
108
+ return null;
109
+ }
110
+
111
+ return {
112
+ targets: cappedTargets,
113
+ refs,
114
+ references: provider.references,
115
+ outline: provider.outline,
116
+ };
117
+ }
118
+
119
+ function buildChangeSetNextQueries(
120
+ changeSetFiles: ChangeSetFileEntry[],
121
+ analysis: ImpactAnalysis,
122
+ semanticImpact: ChangeSetSemanticImpact | null,
123
+ ): string[] {
124
+ const firstFile = changeSetFiles[0]?.relPath;
125
+ const next: string[] = [];
126
+ if (firstFile) {
127
+ next.push(
128
+ `\`code_orientation\` with \`focus: "${firstFile}"\` for focused orientation on the change-set file`,
129
+ );
130
+ }
131
+ if (analysis.checkNext.length > 0) {
132
+ next.push("`code_orientation` on the most-affected module for broader orientation");
133
+ }
134
+ if (analysis.confidence !== "semantic" && firstFile) {
135
+ const symbolHint = semanticImpact?.targets[0]?.name ?? "<primary exported symbol>";
136
+ next.push(
137
+ `For semantic impact, run \`code_resolve(query="${symbolHint}", scope="${firstFile}")\` then \`code_impact(targetId="<result>", change="<your change>")\``,
138
+ );
139
+ }
140
+ return next;
141
+ }
142
+
143
+ function buildSemanticUpgradeSuggestion(
144
+ changeSetFiles: ChangeSetFileEntry[],
145
+ semanticImpact: ChangeSetSemanticImpact | null,
146
+ ): string {
147
+ const firstFile = changeSetFiles[0]?.relPath;
148
+ if (!firstFile) return "";
149
+ const symbolHint = semanticImpact?.targets[0]?.name ?? "<primary exported symbol>";
150
+ return `For semantic impact, run \`code_resolve(query="${symbolHint}", scope="${firstFile}")\` then \`code_impact(targetId="<result>", change="<your change>")\`.`;
151
+ }