@mrclrchtr/supi-code-intelligence 1.16.1 → 2.0.1

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,98 @@
1
+ /**
2
+ * Tool executor for code_impact — blast radius and downstream impact.
3
+ */
4
+
5
+ import type { CodeIntelResult, CodeIntelToolExecCtx } from "../../types/index.ts";
6
+ import { focusedToolRules } from "../infra/cross-field.ts";
7
+ import { impactErrorResult } from "../infra/error-results.ts";
8
+ import {
9
+ expandTargetId,
10
+ gateCapability,
11
+ gateSemanticReadiness,
12
+ runPipe,
13
+ validateParams,
14
+ } from "../infra/pipeline.ts";
15
+ import { emitToolProgress } from "../infra/progress.ts";
16
+ import { renderSemanticReadinessTimeout } from "../infra/readiness-message.ts";
17
+ import { executeImpact } from "./orchestrate.ts";
18
+
19
+ export interface CodeImpactToolParams {
20
+ targetId?: string;
21
+ file?: string;
22
+ line?: number;
23
+ character?: number;
24
+ symbol?: string;
25
+ exportedOnly?: boolean;
26
+ maxResults?: number;
27
+ change?: string;
28
+ changeSetFiles?: string[];
29
+ includeTests?: boolean;
30
+ }
31
+
32
+ /** Execute the public code_impact tool. */
33
+ export async function executeImpactTool(
34
+ params: CodeImpactToolParams,
35
+ ctx: CodeIntelToolExecCtx,
36
+ ): Promise<CodeIntelResult> {
37
+ emitToolProgress(ctx.onUpdate, "code_impact: analyzing blast radius...");
38
+
39
+ const hasChangeSetInputs = (params.changeSetFiles?.length ?? 0) > 0 || Boolean(params.change);
40
+
41
+ return runPipe(
42
+ params,
43
+ ctx,
44
+ [
45
+ expandTargetId((msg) =>
46
+ impactErrorResult(msg, { nextQueries: ["Use `code_resolve` to resolve a target first"] }),
47
+ ),
48
+ validateParams(focusedToolRules(), (msg) =>
49
+ impactErrorResult(msg, { nextQueries: ["Fix the input parameters and retry"] }),
50
+ ),
51
+ // Semantic readiness and capability only for target-based (non-changeSet) impact
52
+ ...(!hasChangeSetInputs
53
+ ? [
54
+ gateSemanticReadiness("code_impact", {
55
+ fileParam: "file",
56
+ onTimeout: () =>
57
+ impactErrorResult(renderSemanticReadinessTimeout("code_impact", 15_000), {
58
+ nextQueries: ["Check `code_health` for LSP status"],
59
+ }),
60
+ onUnavailable: () =>
61
+ impactErrorResult(
62
+ "**Error:** No semantic analysis provider is available for this workspace. Check `code_health` for LSP status or enable an LSP server.",
63
+ {
64
+ nextQueries: [
65
+ "Use `code_resolve` to resolve a target first",
66
+ "Check `code_health` for LSP status or enable an LSP server.",
67
+ ],
68
+ },
69
+ ),
70
+ }),
71
+ gateCapability("code_impact"),
72
+ ]
73
+ : []),
74
+ ],
75
+ async (p, c) => {
76
+ if (!p.file && !p.symbol && !hasChangeSetInputs) {
77
+ return impactErrorResult(
78
+ "**Error:** Impact analysis currently requires either anchored coordinates (`file`, `line`, `character`) or a `symbol` for discovery.",
79
+ { nextQueries: ["Use `code_resolve` to resolve a target first"] },
80
+ );
81
+ }
82
+
83
+ const providerState = c.session.getProviders();
84
+ const provider = providerState.kind === "ready" ? providerState.provider : null;
85
+ const lspService =
86
+ providerState.kind === "ready"
87
+ ? providerState.lspService
88
+ : { kind: "unavailable" as const, reason: "No provider" };
89
+
90
+ if (hasChangeSetInputs) {
91
+ emitToolProgress(c.onUpdate, "code_impact: analyzing impact input...");
92
+ } else {
93
+ emitToolProgress(c.onUpdate, "code_impact: sweeping references...");
94
+ }
95
+ return executeImpact(p, { cwd: c.cwd, provider, lspService });
96
+ },
97
+ );
98
+ }
@@ -0,0 +1,81 @@
1
+ // File-level target-group 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 type { ResolvedTargetGroupData } from "../../analysis/target/types.ts";
9
+ import { buildTestAnchorMap } from "../../analysis/tests/likely-tests.ts";
10
+ import type { CodeIntelResult } from "../../types/index.ts";
11
+ import { analyzeReferenceImpact, buildDetailsData, computeOmittedCount } from "./analysis.ts";
12
+ import { renderImpactFileLevel } from "./markdown.ts";
13
+ import type { ImpactInput } from "./types.ts";
14
+
15
+ // biome-ignore lint/complexity/useMaxParams: shared impact orchestration keeps related substrate inputs explicit
16
+ export async function executeFileLevelImpact(
17
+ targetGroup: ResolvedTargetGroupData,
18
+ input: ImpactInput,
19
+ cwd: string,
20
+ semantic: CodeProvider,
21
+ lspService: import("@mrclrchtr/supi-lsp/api").SessionLspServiceState,
22
+ ): Promise<CodeIntelResult> {
23
+ const perTarget = await Promise.all(
24
+ targetGroup.targets.map(async (t) => ({
25
+ target: t,
26
+ refs: await collectReferences(t, cwd, semantic),
27
+ })),
28
+ );
29
+
30
+ const aggregated = await aggregatePerTarget(targetGroup.targets, (t) =>
31
+ collectReferences(t, cwd, semantic),
32
+ );
33
+
34
+ const model = await buildArchitectureModel(cwd);
35
+ const analysis = await analyzeReferenceImpact(
36
+ aggregated,
37
+ model,
38
+ cwd,
39
+ input.includeTests === true,
40
+ semantic.references,
41
+ targetGroup.targets.map((t) => t.file), // seed all target files
42
+ buildTestAnchorMap(targetGroup.targets.map((t) => ({ file: t.file, position: t.position }))),
43
+ semantic.outline,
44
+ );
45
+
46
+ const prioritySignals = summarizePrioritySignalsForFiles(
47
+ cwd,
48
+ analysis.affectedFiles.size > 0 ? [...analysis.affectedFiles] : [targetGroup.file],
49
+ lspService,
50
+ );
51
+
52
+ const maxResults = input.maxResults ?? 8;
53
+ const content = renderImpactFileLevel({
54
+ targetGroup,
55
+ perTarget,
56
+ aggregated,
57
+ analysis,
58
+ maxResults,
59
+ prioritySignals,
60
+ cwd,
61
+ });
62
+
63
+ const detailsData = buildDetailsData(
64
+ analysis,
65
+ aggregated.refs.length,
66
+ computeOmittedCount(analysis.externalRefs, analysis.affectedFiles.size, input.maxResults),
67
+ [
68
+ "`code_orientation` on the most-affected module for deeper orientation",
69
+ "Use `code_inspect` with file + line + character to inspect one exported target precisely",
70
+ ],
71
+ prioritySignals,
72
+ );
73
+
74
+ return {
75
+ content,
76
+ details: {
77
+ type: "impact",
78
+ data: detailsData,
79
+ },
80
+ };
81
+ }
@@ -0,0 +1,283 @@
1
+ // Impact markdown renderer — consumes analysis data and produces markdown content.
2
+
3
+ import * as path from "node:path";
4
+ import { readNextAround, renderReadNextSection } from "../../analysis/read-next.ts";
5
+ import type { ReferenceCollection } from "../../analysis/references/semantic-refs.ts";
6
+ import { formatReferenceList } from "../../analysis/references/semantic-refs.ts";
7
+ import type { PrioritySignalsSummary } from "../../analysis/signals/project.ts";
8
+ import { appendPrioritySignalsSection } from "../../analysis/signals/project.ts";
9
+ import type { ResolvedTargetData, ResolvedTargetGroupData } from "../../analysis/target/types.ts";
10
+ import type { TestSurfaceDetails } from "../../analysis/tests/test-discovery.ts";
11
+
12
+ // ── Types ────────────────────────────────────────────────────────────
13
+
14
+ export interface ImpactAnalysis {
15
+ confidence: "semantic" | "structural" | "heuristic" | "unavailable";
16
+ affectedFiles: Set<string>;
17
+ affectedModules: Set<string>;
18
+ downstreamCount: number;
19
+ checkNext: string[];
20
+ likelyTests: string[];
21
+ likelyTestCommands: string[];
22
+ riskLevel: "low" | "medium" | "high";
23
+ externalRefs: number;
24
+ semanticRefFiles?: string[];
25
+ tests?: TestSurfaceDetails;
26
+ }
27
+
28
+ interface RenderSingleParams {
29
+ symbolName: string;
30
+ refs: ReferenceCollection;
31
+ analysis: ImpactAnalysis;
32
+ maxResults: number;
33
+ prioritySignals: PrioritySignalsSummary | null;
34
+ target: ResolvedTargetData;
35
+ cwd: string;
36
+ }
37
+
38
+ // ── Single target renderer ───────────────────────────────────────────
39
+
40
+ export function renderImpactSingle(params: RenderSingleParams): string {
41
+ const { symbolName, refs, analysis, maxResults, prioritySignals } = params;
42
+ const totalRefs = refs.refs.length + analysis.externalRefs;
43
+ const lines: string[] = [];
44
+
45
+ lines.push(`# Impact: \`${symbolName}\``);
46
+ lines.push("");
47
+
48
+ const refSummary =
49
+ analysis.externalRefs > 0
50
+ ? `${totalRefs} refs (${refs.refs.length} direct + ${analysis.externalRefs} external)`
51
+ : `${totalRefs} ref${totalRefs !== 1 ? "s" : ""}`;
52
+ lines.push(
53
+ `**Risk: ${analysis.riskLevel.toUpperCase()}** | ${refSummary} | ${analysis.affectedFiles.size} file${analysis.affectedFiles.size !== 1 ? "s" : ""} | ${analysis.affectedModules.size} module${analysis.affectedModules.size !== 1 ? "s" : ""} | ${analysis.downstreamCount} downstream (${analysis.confidence})`,
54
+ );
55
+ if (analysis.externalRefs > 0) {
56
+ lines.push(
57
+ "_External references are not listed individually (node_modules, .pnpm, or out-of-tree)_",
58
+ );
59
+ }
60
+ lines.push("");
61
+
62
+ addRiskSection(lines, analysis, totalRefs);
63
+ formatReferenceList(lines, refs.refs, maxResults);
64
+ lines.push(
65
+ ...renderReadNextSection([
66
+ readNextAround(
67
+ path.relative(params.cwd, params.target.file) || params.target.file,
68
+ params.target.displayLine,
69
+ "inspect the target before editing",
70
+ ),
71
+ ...refs.refs
72
+ .slice(0, Math.min(2, maxResults))
73
+ .map((ref) => readNextAround(ref.file, ref.line, "inspect a reference site")),
74
+ ]),
75
+ );
76
+ appendPrioritySignalsSection(lines, prioritySignals);
77
+ addCheckNextSection(lines, analysis.checkNext);
78
+ addTestsSection(lines, analysis.likelyTests, analysis.tests);
79
+ addLikelyTestCommandsSection(lines, analysis.likelyTestCommands);
80
+
81
+ return lines.join("\n");
82
+ }
83
+
84
+ // ── File-level target group renderer ─────────────────────────────────
85
+
86
+ interface RenderFileLevelParams {
87
+ targetGroup: ResolvedTargetGroupData;
88
+ perTarget: Array<{ target: ResolvedTargetData; refs: ReferenceCollection }>;
89
+ aggregated: ReferenceCollection;
90
+ analysis: ImpactAnalysis;
91
+ maxResults: number;
92
+ prioritySignals: PrioritySignalsSummary | null;
93
+ cwd: string;
94
+ }
95
+
96
+ export function renderImpactFileLevel(params: RenderFileLevelParams): string {
97
+ const { targetGroup, perTarget, aggregated, analysis, maxResults, prioritySignals, cwd } = params;
98
+ const totalRefs = aggregated.refs.length + aggregated.externalCount;
99
+ const refSummary =
100
+ aggregated.externalCount > 0
101
+ ? `${totalRefs} refs (${aggregated.refs.length} direct + ${aggregated.externalCount} external)`
102
+ : `${totalRefs} ref${totalRefs !== 1 ? "s" : ""}`;
103
+
104
+ const lines: string[] = [];
105
+ lines.push(`# Impact: \`${targetGroup.displayName}\``);
106
+ lines.push("");
107
+ lines.push(
108
+ `**Risk: ${analysis.riskLevel.toUpperCase()}** | ${targetGroup.targets.length} exported target${targetGroup.targets.length !== 1 ? "s" : ""} | ${refSummary} | ${analysis.affectedFiles.size} file${analysis.affectedFiles.size !== 1 ? "s" : ""} | ${analysis.affectedModules.size} module${analysis.affectedModules.size !== 1 ? "s" : ""} | ${analysis.downstreamCount} downstream (${analysis.confidence})`,
109
+ );
110
+ lines.push("");
111
+
112
+ lines.push("## Exported Targets");
113
+ for (const entry of perTarget) {
114
+ lines.push(
115
+ `- \`${entry.target.name ?? "symbol"}\` — ${entry.refs.refs.length} ref${entry.refs.refs.length !== 1 ? "s" : ""}`,
116
+ );
117
+ }
118
+ lines.push("");
119
+
120
+ addRiskSection(lines, analysis, totalRefs);
121
+ formatReferenceList(lines, aggregated.refs, maxResults);
122
+ lines.push(
123
+ ...renderReadNextSection([
124
+ readNextAround(
125
+ path.relative(cwd, targetGroup.file) || targetGroup.file,
126
+ 1,
127
+ "inspect the target file exports before editing",
128
+ ),
129
+ ...aggregated.refs
130
+ .slice(0, Math.min(2, maxResults))
131
+ .map((ref) => readNextAround(ref.file, ref.line, "inspect a reference site")),
132
+ ]),
133
+ );
134
+ appendPrioritySignalsSection(lines, prioritySignals);
135
+ addCheckNextSection(lines, analysis.checkNext);
136
+ addTestsSection(lines, analysis.likelyTests, analysis.tests);
137
+ addLikelyTestCommandsSection(lines, analysis.likelyTestCommands);
138
+
139
+ return lines.join("\n");
140
+ }
141
+
142
+ // ── Change-set renderer ──────────────────────────────────────────────
143
+
144
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: shared change-set renderer combines risk, files, tests, and priority signals in one function
145
+ export function renderChangeSetImpact(params: {
146
+ changeSetFiles: string[];
147
+ analysis: ImpactAnalysis;
148
+ prioritySignals: PrioritySignalsSummary | null;
149
+ }): string {
150
+ const lines: string[] = [];
151
+
152
+ lines.push("# Impact: change set");
153
+ lines.push("");
154
+
155
+ lines.push(
156
+ `**Risk: ${params.analysis.riskLevel.toUpperCase()}** | ${params.changeSetFiles.length} change-set file${params.changeSetFiles.length !== 1 ? "s" : ""} | ${params.analysis.affectedModules.size} module${params.analysis.affectedModules.size !== 1 ? "s" : ""} | ${params.analysis.downstreamCount} downstream (${params.analysis.confidence})`,
157
+ );
158
+ lines.push("");
159
+
160
+ lines.push("## Change Set Files");
161
+ for (const file of params.changeSetFiles) {
162
+ lines.push(`- \`${file}\``);
163
+ }
164
+ lines.push("");
165
+
166
+ lines.push(
167
+ ...renderReadNextSection(
168
+ params.changeSetFiles
169
+ .slice(0, 3)
170
+ .map((file) => readNextAround(file, 1, "inspect the change-set file before editing")),
171
+ ),
172
+ );
173
+
174
+ if (params.analysis.checkNext.length > 0) {
175
+ lines.push("## Check Next");
176
+ for (const item of params.analysis.checkNext.slice(0, 3)) {
177
+ lines.push(`- ${item}`);
178
+ }
179
+ lines.push("");
180
+ }
181
+
182
+ if (params.analysis.semanticRefFiles && params.analysis.semanticRefFiles.length > 0) {
183
+ lines.push("## Semantic Reference Files");
184
+ for (const file of params.analysis.semanticRefFiles.slice(0, 5)) {
185
+ lines.push(`- \`${file}\``);
186
+ }
187
+ if (params.analysis.semanticRefFiles.length > 5) {
188
+ lines.push(`- _+${params.analysis.semanticRefFiles.length - 5} more_`);
189
+ }
190
+ lines.push("");
191
+ }
192
+
193
+ if (params.analysis.likelyTests.length > 0) {
194
+ const testHeading = params.analysis.tests?.provenance
195
+ ? `Likely Tests (${params.analysis.tests.provenance})`
196
+ : "Likely Tests";
197
+ lines.push(`## ${testHeading}`);
198
+ for (const file of params.analysis.likelyTests) {
199
+ lines.push(`- \`${file}\``);
200
+ }
201
+ lines.push("");
202
+ } else if (params.analysis.tests) {
203
+ // Test discovery was explicitly requested but found nothing.
204
+ lines.push("## Likely Tests");
205
+ lines.push("No likely tests found by bounded companion/package discovery.");
206
+ lines.push("");
207
+ }
208
+
209
+ if (params.analysis.likelyTestCommands.length > 0) {
210
+ lines.push("## Likely Test Commands");
211
+ for (const cmd of params.analysis.likelyTestCommands.slice(0, 3)) {
212
+ lines.push(`- \`${cmd}\``);
213
+ }
214
+ lines.push("");
215
+ }
216
+
217
+ appendPrioritySignalsSection(lines, params.prioritySignals);
218
+
219
+ return lines.join("\n");
220
+ }
221
+
222
+ // ── Shared formatting helpers ────────────────────────────────────────
223
+
224
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: risk-level formatting with branching per level is clearer as one function
225
+ function addRiskSection(lines: string[], analysis: ImpactAnalysis, directCount: number): void {
226
+ lines.push("## Risk Assessment");
227
+ const { riskLevel, affectedFiles, affectedModules, downstreamCount } = analysis;
228
+ if (riskLevel === "low") {
229
+ lines.push(
230
+ `\`low\` — ${directCount} ref${directCount !== 1 ? "s" : ""}, local, no downstream dependents.`,
231
+ );
232
+ } else if (riskLevel === "medium") {
233
+ lines.push(
234
+ `\`medium\` — ${directCount} ref${directCount !== 1 ? "s" : ""} across ${affectedFiles.size} file${affectedFiles.size !== 1 ? "s" : ""}${downstreamCount > 0 ? `, ${downstreamCount} downstream` : ""}.`,
235
+ );
236
+ } else {
237
+ lines.push(
238
+ `\`high\` — ${directCount} ref${directCount !== 1 ? "s" : ""} across ${affectedFiles.size} file${affectedFiles.size !== 1 ? "s" : ""} in ${affectedModules.size} module${affectedModules.size !== 1 ? "s" : ""}${downstreamCount > 0 ? `, ${downstreamCount} downstream` : ""}.`,
239
+ );
240
+ }
241
+ lines.push("");
242
+ }
243
+
244
+ function addCheckNextSection(lines: string[], checkNext: string[]): void {
245
+ if (checkNext.length === 0) return;
246
+ lines.push("## Check Next");
247
+ for (const item of checkNext.slice(0, 3)) {
248
+ lines.push(`- ${item}`);
249
+ }
250
+ lines.push("");
251
+ }
252
+
253
+ function addTestsSection(lines: string[], tests: string[], details?: TestSurfaceDetails): void {
254
+ if (tests.length > 0) {
255
+ const heading = details?.provenance
256
+ ? `## Likely Tests (${details.provenance})`
257
+ : "## Likely Tests";
258
+ lines.push(heading);
259
+ for (const t of tests.slice(0, 3)) {
260
+ lines.push(`- \`${t}\``);
261
+ }
262
+ lines.push("");
263
+ return;
264
+ }
265
+
266
+ // When test discovery was explicitly requested but found nothing,
267
+ // render an honest note instead of silently omitting test information.
268
+ if (details) {
269
+ lines.push("## Likely Tests");
270
+ lines.push("No likely tests found by bounded companion/package discovery.");
271
+ lines.push("");
272
+ }
273
+ }
274
+
275
+ /** Render the Likely Test Commands section when commands are available. */
276
+ function addLikelyTestCommandsSection(lines: string[], commands: string[]): void {
277
+ if (commands.length === 0) return;
278
+ lines.push("## Likely Test Commands");
279
+ for (const cmd of commands.slice(0, 3)) {
280
+ lines.push(`- \`${cmd}\``);
281
+ }
282
+ lines.push("");
283
+ }
@@ -0,0 +1,97 @@
1
+ // Impact orchestration use-case — workflow-oriented blast-radius analysis.
2
+ //
3
+ // Thin dispatcher: validates input, resolves targets, and delegates to
4
+ // per-mode execution modules. Analysis functions live in ./analysis.ts;
5
+ // per-mode execution in ./single-impact.ts, ./file-level-impact.ts,
6
+ // and ./change-set-impact.ts.
7
+
8
+ import { existsSync } from "node:fs";
9
+ import * as path from "node:path";
10
+ import { isResolvedTargetGroup } from "../../analysis/helpers.ts";
11
+ import { resolveTarget } from "../../analysis/target/bridge.ts";
12
+ import { isTestFilePath } from "../../analysis/tests/test-discovery.ts";
13
+ import type { CodeIntelResult } from "../../types/index.ts";
14
+ import { executeChangeSetImpact } from "./change-set-impact.ts";
15
+ import { executeFileLevelImpact } from "./file-level-impact.ts";
16
+ import { unavailableImpactResult } from "./result.ts";
17
+ import { executeSingleImpact } from "./single-impact.ts";
18
+ import type { ImpactDeps, ImpactInput } from "./types.ts";
19
+
20
+ // ── Legacy helper ───────────────────────────────────────────────────────
21
+
22
+ /** Exported for backward-compatible unit-test access. Prefer `discoverTestFilesForSource` from tests.ts. */
23
+ export function findLikelyTests(
24
+ affectedFiles: Set<string>,
25
+ _cwd: string,
26
+ ): Array<{ path: string; provenance: string }> {
27
+ const seen = new Set<string>();
28
+ const results: Array<{ path: string; provenance: string }> = [];
29
+
30
+ for (const file of affectedFiles) {
31
+ if (isTestFilePath(file)) {
32
+ seen.add(file);
33
+ results.push({ path: file, provenance: "name heuristic" });
34
+ }
35
+ }
36
+
37
+ const remaining = [...affectedFiles].filter((f) => !seen.has(f));
38
+ for (const sourceFile of remaining) {
39
+ const ext = path.extname(sourceFile);
40
+ const stem = sourceFile.slice(0, ext.length > 0 ? -ext.length : undefined);
41
+ for (const suffix of [".test", ".spec"]) {
42
+ const candidate = `${stem}${suffix}${ext}`;
43
+ if (!seen.has(candidate) && existsSync(candidate)) {
44
+ seen.add(candidate);
45
+ results.push({ path: candidate, provenance: "companion file" });
46
+ }
47
+ }
48
+ }
49
+
50
+ results.sort((a, b) => a.path.localeCompare(b.path));
51
+ return results.slice(0, 3);
52
+ }
53
+
54
+ // ── Main dispatch ───────────────────────────────────────────────────────
55
+
56
+ /** Execute the shared impact use-case. */
57
+ export async function executeImpact(
58
+ input: ImpactInput,
59
+ deps: ImpactDeps,
60
+ ): Promise<CodeIntelResult> {
61
+ if (input.changeSetFiles && input.changeSetFiles.length > 0) {
62
+ return executeChangeSetImpact(input, deps.cwd, deps.provider, deps.lspService);
63
+ }
64
+
65
+ if (input.change && !input.file && !input.symbol) {
66
+ return unavailableImpactResult(
67
+ "**Unavailable:** `code_impact` has insufficient evidence for a change-only request. Provide `changeSetFiles` or resolve a target with `code_resolve` first.",
68
+ [
69
+ "Use `code_resolve` to resolve a precise target first",
70
+ "Provide `changeSetFiles` with the workspace-relative files in the change set",
71
+ ],
72
+ );
73
+ }
74
+
75
+ const semantic = deps.provider;
76
+
77
+ if (!semantic) {
78
+ return unavailableImpactResult(
79
+ "**Error:** Impact analysis requires an active code provider (LSP). Enable LSP and retry.",
80
+ ["Use `code_resolve` to resolve a target first"],
81
+ );
82
+ }
83
+
84
+ const target = await resolveTarget(input, deps.cwd, semantic);
85
+
86
+ if (typeof target === "string") {
87
+ return unavailableImpactResult(target, ["Use `code_resolve` to resolve a target first"]);
88
+ }
89
+
90
+ if (isResolvedTargetGroup(target)) {
91
+ return executeFileLevelImpact(target, input, deps.cwd, semantic, deps.lspService);
92
+ }
93
+
94
+ const symbolName =
95
+ target.name ?? `symbol at ${path.relative(deps.cwd, target.file)}:${target.displayLine}`;
96
+ return executeSingleImpact(target, symbolName, input, deps.cwd, semantic, deps.lspService);
97
+ }
@@ -0,0 +1,21 @@
1
+ import type { CodeIntelResult } from "../../types/index.ts";
2
+
3
+ export function unavailableImpactResult(content: string, nextQueries: string[]): CodeIntelResult {
4
+ return {
5
+ content,
6
+ details: {
7
+ type: "impact",
8
+ data: {
9
+ confidence: "unavailable",
10
+ directCount: 0,
11
+ downstreamCount: 0,
12
+ riskLevel: "low" as const,
13
+ checkNext: [],
14
+ likelyTests: [],
15
+ likelyTestCommands: [],
16
+ omittedCount: 0,
17
+ nextQueries,
18
+ },
19
+ },
20
+ };
21
+ }
@@ -0,0 +1,89 @@
1
+ // Single-target impact execution.
2
+ // Extracted from orchestrate.ts.
3
+
4
+ import * as path from "node:path";
5
+ import { buildArchitectureModel } from "../../analysis/architecture/discovery.ts";
6
+ import { createEvidenceList } from "../../analysis/evidence.ts";
7
+ import type { CodeProvider } from "../../analysis/provider.ts";
8
+ import { collectReferences } from "../../analysis/references/semantic-refs.ts";
9
+ import { summarizePrioritySignalsForFiles } from "../../analysis/signals/project.ts";
10
+ import type { ResolvedTargetData } from "../../analysis/target/types.ts";
11
+ import { buildTestAnchorMap } from "../../analysis/tests/likely-tests.ts";
12
+ import type { CodeIntelResult } from "../../types/index.ts";
13
+ import { analyzeReferenceImpact, buildDetailsData, computeOmittedCount } from "./analysis.ts";
14
+ import { renderImpactSingle } from "./markdown.ts";
15
+ import type { ImpactInput } from "./types.ts";
16
+
17
+ // biome-ignore lint/complexity/useMaxParams: shared impact orchestration keeps substrate inputs explicit
18
+ export async function executeSingleImpact(
19
+ target: ResolvedTargetData,
20
+ symbolName: string,
21
+ input: ImpactInput,
22
+ cwd: string,
23
+ semantic: CodeProvider,
24
+ lspService: import("@mrclrchtr/supi-lsp/api").SessionLspServiceState,
25
+ ): Promise<CodeIntelResult> {
26
+ const refs = await collectReferences(target, cwd, semantic);
27
+ const model = await buildArchitectureModel(cwd);
28
+ const analysis = await analyzeReferenceImpact(
29
+ refs,
30
+ model,
31
+ cwd,
32
+ input.includeTests === true,
33
+ semantic.references,
34
+ [target.file], // seed the target file itself as affected
35
+ buildTestAnchorMap([{ file: target.file, position: target.position }]),
36
+ semantic.outline,
37
+ );
38
+
39
+ const prioritySignals = summarizePrioritySignalsForFiles(
40
+ cwd,
41
+ analysis.affectedFiles.size > 0 ? [...analysis.affectedFiles] : [target.file],
42
+ lspService,
43
+ );
44
+
45
+ const maxResults = input.maxResults ?? 8;
46
+ const content = renderImpactSingle({
47
+ symbolName,
48
+ refs,
49
+ analysis,
50
+ maxResults,
51
+ prioritySignals,
52
+ target,
53
+ cwd,
54
+ });
55
+
56
+ const referenceEvidence = createEvidenceList({
57
+ key: "references.locations",
58
+ items: refs.refs,
59
+ maxResults,
60
+ }).metadata;
61
+ const detailsData = buildDetailsData(
62
+ analysis,
63
+ refs.refs.length,
64
+ computeOmittedCount(analysis.externalRefs, analysis.affectedFiles.size, input.maxResults),
65
+ buildTargetNextQueries(target, symbolName, cwd),
66
+ prioritySignals,
67
+ [referenceEvidence],
68
+ );
69
+
70
+ return {
71
+ content,
72
+ details: {
73
+ type: "impact",
74
+ data: detailsData,
75
+ },
76
+ };
77
+ }
78
+
79
+ function buildTargetNextQueries(
80
+ target: ResolvedTargetData,
81
+ symbolName: string,
82
+ cwd: string,
83
+ ): string[] {
84
+ const relPath = path.relative(cwd, target.file);
85
+ return [
86
+ `\`code_inspect\` with \`file: "${relPath}"\`, \`line: ${target.displayLine}\`, and \`character: ${target.displayCharacter}\` for point facts around ${symbolName}`,
87
+ `\`code_graph\`, \`file: "${relPath}"\`, \`line: ${target.displayLine}\`, and \`character: ${target.displayCharacter}\` for reference sites`,
88
+ ];
89
+ }