@mrclrchtr/supi-code-intelligence 1.16.0 → 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 (348) 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/node_modules/vscode-languageserver-protocol/lib/common/protocol.diagnostic.d.ts +21 -2
  70. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.diagnostic.js +1 -0
  71. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineValue.d.ts +2 -1
  72. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/package.json +1 -1
  73. package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -31
  74. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +27 -0
  75. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +5 -0
  76. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +246 -1
  77. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +4 -0
  78. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +3 -0
  79. package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +4 -2
  80. package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +102 -0
  81. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +59 -0
  82. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +4 -0
  83. package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +11 -0
  84. package/node_modules/@mrclrchtr/supi-lsp/src/manager/capability-index.ts +1 -1
  85. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +2 -1
  86. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +115 -26
  87. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +177 -134
  88. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +214 -0
  89. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +320 -0
  90. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +26 -5
  91. package/node_modules/@mrclrchtr/supi-lsp/src/session/service-registry.ts +81 -4
  92. package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +2 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +18 -37
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  97. 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
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  102. 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
  103. 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
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/LICENSE +21 -0
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/README.md +265 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs +4661 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs.map +7 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js +4605 -0
  132. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js.map +7 -0
  133. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  134. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +57 -0
  135. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +100 -0
  136. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs +4063 -0
  137. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs.map +7 -0
  138. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts +1025 -0
  139. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts.map +58 -0
  140. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1025 -0
  141. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +58 -0
  142. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js +4007 -0
  143. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js.map +7 -0
  144. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  145. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +55 -0
  146. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -12
  147. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +29 -0
  148. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +28 -0
  149. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -0
  150. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +14 -2
  151. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +157 -0
  152. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +8 -1
  153. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +86 -0
  154. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +35 -16
  155. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +1 -0
  156. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +10 -0
  157. package/package.json +14 -9
  158. package/src/{model.ts → analysis/architecture/discovery.ts} +15 -72
  159. package/src/analysis/architecture/model.ts +76 -0
  160. package/src/analysis/brief/directory.ts +324 -0
  161. package/src/analysis/brief/enrich.ts +157 -0
  162. package/src/analysis/brief/file.ts +84 -0
  163. package/src/analysis/brief/inventory.ts +177 -0
  164. package/src/analysis/brief/main.ts +176 -0
  165. package/src/analysis/brief/models.ts +75 -0
  166. package/src/{brief.ts → analysis/brief/public-brief.ts} +21 -26
  167. package/src/analysis/brief/summarize.ts +208 -0
  168. package/src/analysis/brief/types.ts +27 -0
  169. package/src/{use-case/generate-brief.ts → analysis/brief/use-case.ts} +67 -144
  170. package/src/analysis/coverage/coverage-warnings.ts +224 -0
  171. package/src/analysis/evidence.ts +91 -0
  172. package/src/{semantic-action-helpers.ts → analysis/helpers.ts} +4 -4
  173. package/src/analysis/provider.ts +186 -0
  174. package/src/analysis/read-next.ts +126 -0
  175. package/src/analysis/readiness.ts +73 -0
  176. package/src/{refactor → analysis/refactor}/safety.ts +1 -1
  177. package/src/{use-case/support/semantic-references.ts → analysis/references/semantic-refs.ts} +58 -26
  178. package/src/analysis/search/pattern.ts +345 -0
  179. package/src/analysis/search/ripgrep.ts +473 -0
  180. package/src/{git-context.ts → analysis/signals/git.ts} +20 -7
  181. package/src/{prioritization-signals.ts → analysis/signals/project.ts} +33 -19
  182. package/src/analysis/target/anchored.ts +349 -0
  183. package/src/analysis/target/bridge.ts +152 -0
  184. package/src/analysis/target/file-resolution.ts +125 -0
  185. package/src/{targeting/resolve-file.ts → analysis/target/file.ts} +40 -20
  186. package/src/{planner → analysis/target}/planner.ts +30 -20
  187. package/src/{targeting → analysis/target}/query.ts +17 -3
  188. package/src/analysis/target/resolve-common.ts +115 -0
  189. package/src/analysis/target/service.ts +229 -0
  190. package/src/analysis/target/symbol.ts +196 -0
  191. package/src/{targeting → analysis/target}/types.ts +17 -1
  192. package/src/analysis/tests/likely-tests.ts +174 -0
  193. package/src/analysis/tests/test-discovery.ts +540 -0
  194. package/src/analysis/tests/vitest.ts +87 -0
  195. package/src/api.ts +34 -41
  196. package/src/app/app.ts +125 -0
  197. package/src/app/manager.ts +65 -0
  198. package/src/extension.ts +132 -1
  199. package/src/index.ts +1 -57
  200. package/src/session/refactor-plans.ts +82 -0
  201. package/src/session/session.ts +300 -0
  202. package/src/session/target-store.ts +293 -0
  203. package/src/substrate/lsp/diagnostic-injection.ts +218 -0
  204. package/src/substrate/lsp/lifecycle.ts +66 -0
  205. package/src/substrate/lsp/overrides.ts +132 -0
  206. package/src/substrate/lsp/recovery.ts +55 -0
  207. package/src/substrate/lsp/settings.ts +286 -0
  208. package/src/substrate/lsp/state.ts +46 -0
  209. package/src/substrate/lsp/utils.ts +17 -0
  210. package/src/substrate/tree-sitter/lifecycle.ts +52 -0
  211. package/src/tool/find/execute.ts +118 -0
  212. package/src/{presentation/markdown/pattern.ts → tool/find/markdown.ts} +102 -53
  213. package/src/{use-case/generate-pattern.ts → tool/find/orchestrate.ts} +67 -33
  214. package/src/tool/find/semantic-search.ts +114 -0
  215. package/src/tool/find/tui.ts +39 -0
  216. package/src/tool/graph/callees.ts +87 -0
  217. package/src/tool/graph/calls-md.ts +54 -0
  218. package/src/tool/graph/collect-relation.ts +371 -0
  219. package/src/tool/graph/execute.ts +95 -0
  220. package/src/tool/graph/implementations-md.ts +79 -0
  221. package/src/tool/graph/implementations.ts +76 -0
  222. package/src/tool/graph/markdown-base.ts +243 -0
  223. package/src/tool/graph/orchestrate.ts +285 -0
  224. package/src/tool/graph/references-md.ts +34 -0
  225. package/src/tool/graph/references.ts +81 -0
  226. package/src/tool/graph/tui.ts +120 -0
  227. package/src/tool/graph/types.ts +97 -0
  228. package/src/tool/guidance.ts +96 -49
  229. package/src/tool/health/execute.ts +76 -0
  230. package/src/tool/health/markdown.ts +280 -0
  231. package/src/tool/health/orchestrate.ts +159 -0
  232. package/src/tool/health/sections/diagnostics.ts +182 -0
  233. package/src/tool/health/sections/recovery.ts +89 -0
  234. package/src/tool/health/sections/signals.ts +89 -0
  235. package/src/tool/health/tui.ts +137 -0
  236. package/src/tool/impact/analysis.ts +247 -0
  237. package/src/tool/impact/change-set-impact.ts +151 -0
  238. package/src/tool/impact/execute.ts +98 -0
  239. package/src/tool/impact/file-level-impact.ts +81 -0
  240. package/src/tool/impact/markdown.ts +283 -0
  241. package/src/tool/impact/orchestrate.ts +97 -0
  242. package/src/tool/impact/result.ts +21 -0
  243. package/src/tool/impact/single-impact.ts +89 -0
  244. package/src/tool/impact/tui.ts +39 -0
  245. package/src/tool/impact/types.ts +34 -0
  246. package/src/tool/infra/cross-field.ts +335 -0
  247. package/src/tool/infra/error-results.ts +199 -0
  248. package/src/tool/infra/pipeline.ts +311 -0
  249. package/src/tool/infra/progress.ts +21 -0
  250. package/src/tool/infra/readiness-message.ts +5 -0
  251. package/src/tool/infra/truncate.ts +49 -0
  252. package/src/tool/inspect/execute.ts +76 -0
  253. package/src/tool/inspect/markdown.ts +169 -0
  254. package/src/tool/inspect/orchestrate.ts +156 -0
  255. package/src/tool/inspect/tui.ts +36 -0
  256. package/src/tool/orientation/deps.ts +63 -0
  257. package/src/tool/orientation/execute.ts +50 -0
  258. package/src/tool/orientation/markdown.ts +35 -0
  259. package/src/tool/orientation/mode.ts +88 -0
  260. package/src/tool/orientation/orchestrate.ts +478 -0
  261. package/src/tool/orientation/precise-target.ts +257 -0
  262. package/src/tool/orientation/tui.ts +131 -0
  263. package/src/{refactor/apply-workspace-edit.ts → tool/refactor-apply/apply.ts} +39 -16
  264. package/src/tool/refactor-apply/execute.ts +20 -0
  265. package/src/tool/refactor-apply/markdown.ts +118 -0
  266. package/src/tool/refactor-apply/orchestrate.ts +89 -0
  267. package/src/tool/refactor-apply/tui.ts +51 -0
  268. package/src/tool/refactor-plan/execute.ts +73 -0
  269. package/src/tool/refactor-plan/markdown.ts +118 -0
  270. package/src/tool/refactor-plan/orchestrate.ts +363 -0
  271. package/src/tool/refactor-plan/tui.ts +42 -0
  272. package/src/tool/register.ts +123 -0
  273. package/src/tool/resolve/execute.ts +82 -0
  274. package/src/tool/resolve/markdown.ts +150 -0
  275. package/src/tool/resolve/orchestrate.ts +134 -0
  276. package/src/tool/resolve/tui.ts +40 -0
  277. package/src/tool/schemas.ts +337 -0
  278. package/src/tool/specs.ts +257 -0
  279. package/src/types/details.ts +188 -0
  280. package/src/types/execution.ts +60 -0
  281. package/src/types/index.ts +28 -0
  282. package/src/{intent/types.ts → types/tool-names.ts} +15 -14
  283. package/src/ui/footer.ts +52 -0
  284. package/src/ui/markdown/brief.ts +218 -0
  285. package/src/ui/markdown/gather.ts +177 -0
  286. package/src/{use-case/build-overview.ts → ui/markdown/overview-data.ts} +2 -2
  287. package/src/{presentation → ui}/markdown/overview.ts +2 -2
  288. package/src/ui/markdown/types.ts +80 -0
  289. package/{node_modules/@mrclrchtr/supi-lsp/src/ui/renderer.ts → src/ui/message-renderer.ts} +11 -10
  290. package/src/ui/status-command.ts +260 -0
  291. package/src/ui/status-overlay.ts +500 -0
  292. package/src/ui/tui/common.ts +220 -0
  293. package/src/ui/tui/index.ts +37 -0
  294. package/node_modules/@mrclrchtr/supi-lsp/src/extension.ts +0 -1
  295. package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +0 -373
  296. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/diagnostic-injection.ts +0 -182
  297. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/session-lifecycle.ts +0 -149
  298. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/status-command.ts +0 -38
  299. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/workspace-recovery.ts +0 -92
  300. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +0 -37
  301. package/node_modules/@mrclrchtr/supi-lsp/src/session/lsp-state.ts +0 -93
  302. package/node_modules/@mrclrchtr/supi-lsp/src/session/settings-registration.ts +0 -296
  303. package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +0 -75
  304. package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +0 -69
  305. package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +0 -27
  306. package/node_modules/@mrclrchtr/supi-lsp/src/tool/overrides.ts +0 -204
  307. package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +0 -69
  308. package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +0 -399
  309. package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +0 -248
  310. package/node_modules/@mrclrchtr/supi-lsp/src/ui/ui.ts +0 -360
  311. package/node_modules/@mrclrchtr/supi-lsp/src/workspace-change.ts +0 -40
  312. package/node_modules/@mrclrchtr/supi-tree-sitter/src/extension.ts +0 -1
  313. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/formatting.ts +0 -104
  314. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +0 -35
  315. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/handlers.ts +0 -196
  316. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/register-tools.ts +0 -107
  317. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/tool-specs.ts +0 -117
  318. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +0 -47
  319. package/src/brief-focused.ts +0 -563
  320. package/src/code-intelligence.ts +0 -70
  321. package/src/pattern-structured.ts +0 -194
  322. package/src/presentation/markdown/affected.ts +0 -170
  323. package/src/presentation/markdown/brief.ts +0 -174
  324. package/src/presentation/markdown/map.ts +0 -54
  325. package/src/presentation/markdown/refactor.ts +0 -27
  326. package/src/presentation/markdown/relations.ts +0 -121
  327. package/src/resolve-target.ts +0 -130
  328. package/src/search-helpers.ts +0 -303
  329. package/src/substrates/types.ts +0 -30
  330. package/src/target-resolution.ts +0 -122
  331. package/src/targeting/resolve-anchored.ts +0 -80
  332. package/src/targeting/resolve-symbol.ts +0 -110
  333. package/src/tool/execute-affected.ts +0 -71
  334. package/src/tool/execute-brief.ts +0 -59
  335. package/src/tool/execute-map.ts +0 -35
  336. package/src/tool/execute-pattern.ts +0 -29
  337. package/src/tool/execute-refactor.ts +0 -101
  338. package/src/tool/execute-relations.ts +0 -79
  339. package/src/tool/register-tools.ts +0 -32
  340. package/src/tool/tool-specs.ts +0 -190
  341. package/src/tool/validation.ts +0 -43
  342. package/src/types.ts +0 -169
  343. package/src/use-case/generate-affected.ts +0 -297
  344. package/src/use-case/generate-map.ts +0 -176
  345. package/src/use-case/generate-relations.ts +0 -438
  346. package/src/use-case/types.ts +0 -43
  347. package/src/workspace/request-context.ts +0 -139
  348. /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
+ }