@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,89 @@
1
+ // Coverage, unused, and server collection for code_health.
2
+ // Extracted from orchestrate.ts.
3
+
4
+ import { existsSync } from "node:fs";
5
+ import { resolve } from "node:path";
6
+ import { isWithinOrEqual } from "@mrclrchtr/supi-core/api";
7
+ import type { SessionLspService } from "@mrclrchtr/supi-lsp/api";
8
+ import { gatherGitContext } from "../../../analysis/signals/git.ts";
9
+ import type { LoadedSignals } from "../../../analysis/signals/project.ts";
10
+ import type {
11
+ HealthCoverageData,
12
+ HealthData,
13
+ HealthSection,
14
+ HealthUnusedData,
15
+ } from "../markdown.ts";
16
+
17
+ // ── Servers ───────────────────────────────────────────────────────────
18
+
19
+ export function collectServers(
20
+ service: SessionLspService | null,
21
+ included: string[],
22
+ ): HealthData["servers"] {
23
+ if (!included.includes("servers") || !service) return [];
24
+
25
+ return service.getProjectServers().map((s) => ({
26
+ name: s.name,
27
+ root: s.root,
28
+ fileTypes: s.fileTypes,
29
+ status: s.status,
30
+ }));
31
+ }
32
+
33
+ // ── Coverage ──────────────────────────────────────────────────────────
34
+
35
+ export function needsPrioritizationSignals(included: HealthSection[]): boolean {
36
+ return included.includes("coverage") || included.includes("unused");
37
+ }
38
+
39
+ export function collectCoverageSection(
40
+ loaded: LoadedSignals | null,
41
+ cwd: string,
42
+ scopeFilter: string | null,
43
+ coveragePath?: string,
44
+ ): HealthCoverageData {
45
+ const reportPath = resolve(cwd, coveragePath ?? "coverage/coverage-summary.json");
46
+ if (!existsSync(reportPath) || !loaded) {
47
+ return { available: false, entries: [] };
48
+ }
49
+
50
+ const entries = [...loaded.coverageByFile.entries()]
51
+ .filter(([file, pct]) => pct < 50 && isWithinOptionalScope(scopeFilter, file))
52
+ .sort((left, right) => left[1] - right[1] || left[0].localeCompare(right[0]))
53
+ .map(([file, pct]) => ({ file, pct }));
54
+
55
+ return { available: true, entries };
56
+ }
57
+
58
+ export function collectUnusedSection(
59
+ loaded: LoadedSignals | null,
60
+ cwd: string,
61
+ scopeFilter: string | null,
62
+ unusedPath?: string,
63
+ ): HealthUnusedData {
64
+ const reportPath = resolve(cwd, unusedPath ?? "knip.json");
65
+ if (!existsSync(reportPath) || !loaded) {
66
+ return { available: false, files: [], exports: [] };
67
+ }
68
+
69
+ const files = [...loaded.unusedFiles]
70
+ .filter((file) => isWithinOptionalScope(scopeFilter, file))
71
+ .sort((left, right) => left.localeCompare(right));
72
+ const exports = loaded.unusedExports
73
+ .filter((entry) => isWithinOptionalScope(scopeFilter, entry.file))
74
+ .sort((left, right) => left.name.localeCompare(right.name));
75
+
76
+ return { available: true, files, exports };
77
+ }
78
+
79
+ // ── Git context ───────────────────────────────────────────────────────
80
+
81
+ export function collectGitContext(included: string[], cwd: string) {
82
+ return included.includes("dirty") ? gatherGitContext(cwd) : null;
83
+ }
84
+
85
+ // ── Helpers ───────────────────────────────────────────────────────────
86
+
87
+ function isWithinOptionalScope(scopeFilter: string | null, file: string): boolean {
88
+ return !scopeFilter || isWithinOrEqual(scopeFilter, file);
89
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * TUI renderer for code_health — renderCall + renderResult.
3
+ */
4
+
5
+ import type { Theme } from "@earendil-works/pi-coding-agent";
6
+ import { Container, Spacer, Text } from "@earendil-works/pi-tui";
7
+ import { formatEvidenceBadge } from "@mrclrchtr/supi-code-runtime/api";
8
+ import {
9
+ type EvidenceEntry,
10
+ type ResultOptios,
11
+ renderEvidenceLines,
12
+ renderMarkdownDetail,
13
+ renderPartial,
14
+ type ToolResult,
15
+ } from "../../ui/tui/common.ts";
16
+ import type { CodeHealthToolParams } from "./execute.ts";
17
+
18
+ /** ── renderCall ────────────────────────────────────────────────── */
19
+
20
+ export function renderHealthCall(args: unknown, theme: Theme, _context: unknown): Text {
21
+ const params = (args ?? {}) as CodeHealthToolParams;
22
+ const sections = params.include?.length ? params.include.join(", ") : "diag, servers";
23
+
24
+ let content = theme.fg("toolTitle", "code_health");
25
+ content += ` ${theme.fg("accent", sections)}`;
26
+
27
+ if (params.scope) {
28
+ content += ` ${theme.fg("dim", params.scope)}`;
29
+ }
30
+
31
+ return new Text(content, 0, 0);
32
+ }
33
+
34
+ /** ── renderResult ──────────────────────────────────────────────── */
35
+
36
+ export function renderHealthResult(
37
+ result: ToolResult,
38
+ options: ResultOptios,
39
+ theme: Theme,
40
+ _context: unknown,
41
+ ): Container | Text {
42
+ if (options.isPartial) {
43
+ return renderPartial("Gathering workspace health…", theme);
44
+ }
45
+
46
+ const container = new Container();
47
+ const data =
48
+ result.details?.type === "health" ? (result.details.data as Record<string, unknown>) : null;
49
+
50
+ if (result.isError) {
51
+ container.addChild(new Text(theme.fg("error", "code_health failed"), 0, 0));
52
+ return container;
53
+ }
54
+
55
+ if (!options.expanded) {
56
+ container.addChild(buildCompactSummary(data, theme));
57
+ return container;
58
+ }
59
+
60
+ // Expanded view
61
+ container.addChild(buildStatusBar(data, theme));
62
+ container.addChild(new Spacer(1));
63
+ container.addChild(buildDiagnosticSummary(data, theme));
64
+
65
+ const lists = data?.evidenceLists as EvidenceEntry[] | undefined;
66
+ if (lists && lists.length > 0) {
67
+ container.addChild(new Spacer(1));
68
+ renderEvidenceLines(container, lists, theme);
69
+ }
70
+
71
+ renderMarkdownDetail(container, result, theme);
72
+
73
+ return container;
74
+ }
75
+
76
+ /** ── Helpers ───────────────────────────────────────────────────── */
77
+
78
+ function buildCompactSummary(data: Record<string, unknown> | null, theme: Theme): Text {
79
+ if (!data) {
80
+ return new Text(theme.fg("dim", "No health data"), 0, 0);
81
+ }
82
+
83
+ const diagCount = (data.diagnosticFileCount as number) ?? 0;
84
+ const serverCount = (data.serverCount as number) ?? 0;
85
+ const lspStatus = (data.lspStatus as string) ?? "unknown";
86
+
87
+ const statusColor = lspStatus === "ready" ? "success" : "warning";
88
+ const dot = theme.fg("dim", "·");
89
+
90
+ const segments = [
91
+ `${theme.fg("dim", "diag")} ${theme.fg("success", theme.bold(`${diagCount}`))}${theme.fg("muted", " with issues")}`,
92
+ `${theme.fg("dim", "servers")} ${theme.fg("muted", `${serverCount}`)}`,
93
+ `${theme.fg("dim", "lsp")} ${theme.fg(statusColor, lspStatus)}`,
94
+ ];
95
+
96
+ return new Text(segments.join(` ${dot} `), 0, 0);
97
+ }
98
+
99
+ function buildStatusBar(data: Record<string, unknown> | null, theme: Theme): Text {
100
+ if (!data) return new Text("", 0, 0);
101
+
102
+ const lspStatus = (data.lspStatus as string) ?? "unknown";
103
+ const structuralStatus = (data.structuralStatus as string) ?? "unknown";
104
+ const recovered = data.recovered;
105
+
106
+ const lspColor = lspStatus.startsWith("ready") ? "success" : "warning";
107
+ const structuralColor = structuralStatus === "ready" ? "success" : "muted";
108
+
109
+ const lspLabel =
110
+ lspStatus.includes("(recovered)") || !recovered ? lspStatus : `${lspStatus} (recovered)`;
111
+
112
+ const lines: string[] = [
113
+ `LSP: ${theme.fg(lspColor, lspLabel)}`,
114
+ `Tree-sitter: ${theme.fg(structuralColor, structuralStatus)}`,
115
+ ];
116
+
117
+ return new Text(lines.join(" "), 0, 0);
118
+ }
119
+
120
+ function buildDiagnosticSummary(data: Record<string, unknown> | null, theme: Theme): Text {
121
+ if (!data) return new Text("", 0, 0);
122
+
123
+ const diagCount = (data.diagnosticFileCount as number) ?? 0;
124
+ if (diagCount === 0) {
125
+ return new Text(theme.fg("success", "No diagnostics found"), 0, 0);
126
+ }
127
+
128
+ const badge = formatEvidenceBadge({
129
+ shownCount: diagCount,
130
+ totalCount: diagCount,
131
+ omittedCount: 0,
132
+ partialReason: null,
133
+ label: "files with issues",
134
+ });
135
+
136
+ return new Text(theme.fg("warning", theme.bold(badge)), 0, 0);
137
+ }
@@ -0,0 +1,247 @@
1
+ // Impact analysis — shared analysis functions for impact orchestration.
2
+ // Extracted from orchestrate.ts to keep per-mode files focused.
3
+
4
+ import * as path from "node:path";
5
+ import type { buildArchitectureModel } from "../../analysis/architecture/discovery.ts";
6
+ import { findModuleForPath, getDependents } from "../../analysis/architecture/model.ts";
7
+ import type { EvidenceListMetadata } from "../../analysis/evidence.ts";
8
+ import type { CodeProvider } from "../../analysis/provider.ts";
9
+ import type { ReferenceCollection } from "../../analysis/references/semantic-refs.ts";
10
+ import type { ResolvedTargetData } from "../../analysis/target/types.ts";
11
+ import {
12
+ buildLikelyTestCommands,
13
+ buildTestAnchorMap,
14
+ type ChangeSetFileEntry,
15
+ collectLikelyTests,
16
+ type TestAnchorMap,
17
+ } from "../../analysis/tests/likely-tests.ts";
18
+ import { buildTestSurfaceDetails } from "../../analysis/tests/test-discovery.ts";
19
+ import type { AffectedDetails, ImpactDetails } from "../../types/index.ts";
20
+ import type { ImpactAnalysis } from "./types.ts";
21
+
22
+ // ── Shared analysis ────────────────────────────────────────────────────
23
+
24
+ /** Seed files parameter is explicit for testability. */
25
+ // biome-ignore lint/complexity/useMaxParams: explicit params for testability
26
+ export async function analyzeReferenceImpact(
27
+ result: ReferenceCollection,
28
+ model: Awaited<ReturnType<typeof buildArchitectureModel>>,
29
+ cwd: string,
30
+ includeTests: boolean,
31
+ references: CodeProvider["references"] | undefined,
32
+ seedFiles?: string[],
33
+ testAnchors?: TestAnchorMap,
34
+ outline?: CodeProvider["outline"],
35
+ ): Promise<ImpactAnalysis> {
36
+ const affectedFiles = new Set(result.refs.map((r) => path.resolve(cwd, r.file)));
37
+
38
+ // Seed the target file(s) so zero-reference targets still have affected evidence
39
+ if (seedFiles) {
40
+ for (const f of seedFiles) {
41
+ affectedFiles.add(path.resolve(cwd, f));
42
+ }
43
+ }
44
+
45
+ const { affectedModules, checkNext, downstreamCount } = analyzeModelImpact(
46
+ affectedFiles,
47
+ model,
48
+ cwd,
49
+ );
50
+
51
+ const likelyTestsResult = includeTests
52
+ ? await collectLikelyTests(affectedFiles, cwd, references, testAnchors, undefined, outline)
53
+ : null;
54
+ const likelyTests = likelyTestsResult?.paths ?? [];
55
+ const likelyTestCommands = buildLikelyTestCommands(cwd, likelyTests);
56
+ const tests =
57
+ likelyTestsResult === null
58
+ ? undefined
59
+ : buildTestSurfaceDetails(
60
+ {
61
+ status: likelyTestsResult.files.length > 0 ? "found" : "empty",
62
+ provenance: likelyTestsResult.provenance,
63
+ files: likelyTestsResult.files,
64
+ },
65
+ cwd,
66
+ );
67
+
68
+ return {
69
+ confidence: result.confidence,
70
+ affectedFiles,
71
+ affectedModules,
72
+ downstreamCount,
73
+ checkNext,
74
+ likelyTests,
75
+ likelyTestCommands,
76
+ tests,
77
+ riskLevel: assessRisk(
78
+ result.refs.length + result.externalCount,
79
+ affectedModules.size,
80
+ downstreamCount,
81
+ ),
82
+ externalRefs: result.externalCount,
83
+ };
84
+ }
85
+
86
+ export interface AnalyzeChangeSetOptions {
87
+ changeSetFiles: ChangeSetFileEntry[];
88
+ model: Awaited<ReturnType<typeof buildArchitectureModel>>;
89
+ cwd: string;
90
+ includeTests: boolean;
91
+ semanticImpact: ChangeSetSemanticImpact | null;
92
+ }
93
+
94
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: change-set impact merges structural, semantic, test, and risk evidence in one staged result.
95
+ export async function analyzeChangeSet(options: AnalyzeChangeSetOptions): Promise<ImpactAnalysis> {
96
+ const { changeSetFiles, model, cwd, includeTests, semanticImpact } = options;
97
+ const affectedFiles = new Set(changeSetFiles.map((entry) => entry.absPath));
98
+ if (semanticImpact) {
99
+ for (const ref of semanticImpact.refs.refs) {
100
+ affectedFiles.add(path.resolve(cwd, ref.file));
101
+ }
102
+ }
103
+
104
+ const { affectedModules, checkNext, downstreamCount } = analyzeModelImpact(
105
+ affectedFiles,
106
+ model,
107
+ cwd,
108
+ );
109
+
110
+ const likelyTestsResult = includeTests
111
+ ? await collectLikelyTests(
112
+ affectedFiles,
113
+ cwd,
114
+ semanticImpact?.references,
115
+ semanticImpact ? buildTestAnchorMap(semanticImpact.targets) : undefined,
116
+ semanticImpact ? undefined : "conventions-only",
117
+ semanticImpact?.outline,
118
+ )
119
+ : null;
120
+ const likelyTests = likelyTestsResult?.paths ?? [];
121
+ const likelyTestCommands = buildLikelyTestCommands(cwd, likelyTests);
122
+ const tests =
123
+ likelyTestsResult === null
124
+ ? undefined
125
+ : buildTestSurfaceDetails(
126
+ {
127
+ status: likelyTestsResult.files.length > 0 ? "found" : "empty",
128
+ provenance: likelyTestsResult.provenance,
129
+ files: likelyTestsResult.files,
130
+ },
131
+ cwd,
132
+ );
133
+
134
+ const semanticRefCount = semanticImpact ? semanticImpact.refs.refs.length : 0;
135
+ const externalRefs = semanticImpact ? semanticImpact.refs.externalCount : 0;
136
+ const semanticRefFiles = semanticImpact ? collectUniqueRefFiles(semanticImpact.refs) : undefined;
137
+
138
+ return {
139
+ confidence: semanticImpact ? "semantic" : "structural",
140
+ affectedFiles,
141
+ affectedModules,
142
+ downstreamCount,
143
+ checkNext,
144
+ likelyTests,
145
+ likelyTestCommands,
146
+ tests,
147
+ riskLevel: assessRisk(
148
+ changeSetFiles.length + semanticRefCount,
149
+ affectedModules.size,
150
+ downstreamCount,
151
+ ),
152
+ externalRefs,
153
+ semanticRefFiles,
154
+ };
155
+ }
156
+
157
+ export interface ChangeSetSemanticImpact {
158
+ targets: ResolvedTargetData[];
159
+ refs: ReferenceCollection;
160
+ references: CodeProvider["references"];
161
+ outline?: CodeProvider["outline"];
162
+ }
163
+
164
+ export function collectUniqueRefFiles(refs: ReferenceCollection): string[] {
165
+ return [...new Set(refs.refs.map((ref) => ref.file))].sort((a, b) => a.localeCompare(b));
166
+ }
167
+
168
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: module-impact traversal keeps affected/downstream/check-next logic together
169
+ export function analyzeModelImpact(
170
+ affectedFiles: Set<string>,
171
+ model: Awaited<ReturnType<typeof buildArchitectureModel>>,
172
+ cwd: string,
173
+ ): Pick<ImpactAnalysis, "affectedModules" | "checkNext" | "downstreamCount"> {
174
+ const affectedModules = new Set<string>();
175
+ const checkNext: string[] = [];
176
+ let downstreamCount = 0;
177
+
178
+ if (model) {
179
+ for (const file of affectedFiles) {
180
+ const mod = findModuleForPath(model, path.resolve(cwd, file));
181
+ if (mod) affectedModules.add(mod.name);
182
+ }
183
+
184
+ const downstreamModules = new Set<string>();
185
+ const queue = [...affectedModules];
186
+ while (queue.length > 0) {
187
+ const modName = queue.shift() as string;
188
+ for (const dep of getDependents(model, modName)) {
189
+ if (!affectedModules.has(dep.name) && !downstreamModules.has(dep.name)) {
190
+ downstreamModules.add(dep.name);
191
+ queue.push(dep.name);
192
+ }
193
+ }
194
+ }
195
+ downstreamCount = downstreamModules.size;
196
+
197
+ for (const modName of [...affectedModules, ...downstreamModules].slice(0, 3)) {
198
+ const mod = model.modules.find((m) => m.name === modName);
199
+ if (mod) checkNext.push(`${mod.name.replace(/^@[^/]+\//, "")} (\`${mod.relativePath}\`)`);
200
+ }
201
+ }
202
+
203
+ return { affectedModules, checkNext, downstreamCount };
204
+ }
205
+
206
+ export function assessRisk(
207
+ totalRefs: number,
208
+ moduleCount: number,
209
+ downstreamCount: number,
210
+ ): "low" | "medium" | "high" {
211
+ if (totalRefs > 10 || moduleCount > 3 || downstreamCount > 1) return "high";
212
+ if (totalRefs > 3 || moduleCount > 1 || downstreamCount >= 1) return "medium";
213
+ return "low";
214
+ }
215
+
216
+ export function computeOmittedCount(
217
+ externalRefs: number,
218
+ affectedFileCount: number,
219
+ maxResults?: number,
220
+ ): number {
221
+ return externalRefs + Math.max(0, affectedFileCount - (maxResults ?? 8));
222
+ }
223
+
224
+ // biome-ignore lint/complexity/useMaxParams: detail assembly keeps shared counts, queries, and signals explicit for both surfaces
225
+ export function buildDetailsData(
226
+ analysis: ImpactAnalysis,
227
+ directCount: number,
228
+ omittedCount: number,
229
+ nextQueries: string[],
230
+ prioritySignals: AffectedDetails["prioritySignals"],
231
+ evidenceLists: EvidenceListMetadata[] = [],
232
+ ): AffectedDetails | ImpactDetails {
233
+ return {
234
+ confidence: analysis.confidence,
235
+ directCount,
236
+ downstreamCount: analysis.downstreamCount,
237
+ riskLevel: analysis.riskLevel,
238
+ checkNext: analysis.checkNext,
239
+ likelyTests: analysis.likelyTests,
240
+ likelyTestCommands: analysis.likelyTestCommands,
241
+ omittedCount,
242
+ evidenceLists,
243
+ nextQueries,
244
+ prioritySignals,
245
+ tests: analysis.tests,
246
+ };
247
+ }
@@ -0,0 +1,151 @@
1
+ // Change-set impact execution.
2
+ // Extracted from orchestrate.ts.
3
+
4
+ import { buildArchitectureModel } from "../../analysis/architecture/discovery.ts";
5
+ import type { CodeProvider } from "../../analysis/provider.ts";
6
+ import { aggregatePerTarget, collectReferences } from "../../analysis/references/semantic-refs.ts";
7
+ import { summarizePrioritySignalsForFiles } from "../../analysis/signals/project.ts";
8
+ import { resolveFileTargetGroup } from "../../analysis/target/file.ts";
9
+ import type { ResolvedTargetData } from "../../analysis/target/types.ts";
10
+ import type { ChangeSetFileEntry } from "../../analysis/tests/likely-tests.ts";
11
+ import { normalizeChangeSet } from "../../analysis/tests/likely-tests.ts";
12
+ import type { CodeIntelResult } from "../../types/index.ts";
13
+ import { analyzeChangeSet, buildDetailsData, type ChangeSetSemanticImpact } from "./analysis.ts";
14
+ import { renderChangeSetImpact } from "./markdown.ts";
15
+ import { unavailableImpactResult } from "./result.ts";
16
+ import type { ImpactAnalysis, ImpactInput } from "./types.ts";
17
+
18
+ export async function executeChangeSetImpact(
19
+ input: ImpactInput,
20
+ cwd: string,
21
+ provider: CodeProvider | null,
22
+ lspService: import("@mrclrchtr/supi-lsp/api").SessionLspServiceState,
23
+ ): Promise<CodeIntelResult> {
24
+ const changeSetFiles = normalizeChangeSet(input.changeSetFiles ?? [], cwd);
25
+ if (changeSetFiles.length === 0) {
26
+ return unavailableImpactResult(
27
+ "**Unavailable:** No readable change-set files were provided for impact analysis.",
28
+ [
29
+ "Provide `changeSetFiles` with workspace-relative file paths",
30
+ "Use `code_resolve` when you want symbol-level impact instead",
31
+ ],
32
+ );
33
+ }
34
+
35
+ const model = await buildArchitectureModel(cwd);
36
+ const semanticImpact = await collectChangeSetSemanticImpact(changeSetFiles, cwd, provider);
37
+ const analysis = await analyzeChangeSet({
38
+ changeSetFiles,
39
+ model,
40
+ cwd,
41
+ includeTests: input.includeTests === true,
42
+ semanticImpact,
43
+ });
44
+ const prioritySignals = summarizePrioritySignalsForFiles(
45
+ cwd,
46
+ changeSetFiles.map((entry) => entry.absPath),
47
+ lspService,
48
+ );
49
+ const nextQueries = buildChangeSetNextQueries(changeSetFiles, analysis, semanticImpact);
50
+ const upgradeSuggestion = buildSemanticUpgradeSuggestion(changeSetFiles, semanticImpact);
51
+ const evidenceNote =
52
+ analysis.confidence === "semantic"
53
+ ? "\n**Evidence: semantic+structural** — semantic references for symbols defined in change-set files were merged with file-level module analysis and bounded test discovery.\n"
54
+ : `\n**Evidence: structural** — impact limited to file-level module analysis and path-based test discovery.\n${upgradeSuggestion}\n`;
55
+ const content =
56
+ renderChangeSetImpact({
57
+ changeSetFiles: changeSetFiles.map((entry) => entry.relPath),
58
+ analysis,
59
+ prioritySignals,
60
+ }) + evidenceNote;
61
+
62
+ const detailsData = buildDetailsData(
63
+ analysis,
64
+ changeSetFiles.length,
65
+ 0,
66
+ nextQueries,
67
+ prioritySignals,
68
+ );
69
+
70
+ return {
71
+ content,
72
+ details: {
73
+ type: "impact",
74
+ data: detailsData,
75
+ },
76
+ };
77
+ }
78
+
79
+ async function collectChangeSetSemanticImpact(
80
+ changeSetFiles: ChangeSetFileEntry[],
81
+ cwd: string,
82
+ provider: CodeProvider | null,
83
+ ): Promise<ChangeSetSemanticImpact | null> {
84
+ if (!provider?.references) return null;
85
+
86
+ const targets: ResolvedTargetData[] = [];
87
+ for (const entry of changeSetFiles) {
88
+ try {
89
+ const outcome = await resolveFileTargetGroup(entry.relPath, cwd, {
90
+ semantic: provider,
91
+ structural: provider,
92
+ });
93
+ if (outcome.kind === "resolved") {
94
+ targets.push(...outcome.group.targets);
95
+ }
96
+ } catch {
97
+ // Keep change-set analysis best-effort: structural impact still applies.
98
+ }
99
+ }
100
+
101
+ const cappedTargets = targets.slice(0, 25);
102
+ if (cappedTargets.length === 0) return null;
103
+
104
+ const refs = await aggregatePerTarget(cappedTargets, (target) =>
105
+ collectReferences(target, cwd, provider),
106
+ );
107
+ if (refs.confidence !== "semantic" || (refs.refs.length === 0 && refs.externalCount === 0)) {
108
+ return null;
109
+ }
110
+
111
+ return {
112
+ targets: cappedTargets,
113
+ refs,
114
+ references: provider.references,
115
+ outline: provider.outline,
116
+ };
117
+ }
118
+
119
+ function buildChangeSetNextQueries(
120
+ changeSetFiles: ChangeSetFileEntry[],
121
+ analysis: ImpactAnalysis,
122
+ semanticImpact: ChangeSetSemanticImpact | null,
123
+ ): string[] {
124
+ const firstFile = changeSetFiles[0]?.relPath;
125
+ const next: string[] = [];
126
+ if (firstFile) {
127
+ next.push(
128
+ `\`code_orientation\` with \`focus: "${firstFile}"\` for focused orientation on the change-set file`,
129
+ );
130
+ }
131
+ if (analysis.checkNext.length > 0) {
132
+ next.push("`code_orientation` on the most-affected module for broader orientation");
133
+ }
134
+ if (analysis.confidence !== "semantic" && firstFile) {
135
+ const symbolHint = semanticImpact?.targets[0]?.name ?? "<primary exported symbol>";
136
+ next.push(
137
+ `For semantic impact, run \`code_resolve(query="${symbolHint}", scope="${firstFile}")\` then \`code_impact(targetId="<result>", change="<your change>")\``,
138
+ );
139
+ }
140
+ return next;
141
+ }
142
+
143
+ function buildSemanticUpgradeSuggestion(
144
+ changeSetFiles: ChangeSetFileEntry[],
145
+ semanticImpact: ChangeSetSemanticImpact | null,
146
+ ): string {
147
+ const firstFile = changeSetFiles[0]?.relPath;
148
+ if (!firstFile) return "";
149
+ const symbolHint = semanticImpact?.targets[0]?.name ?? "<primary exported symbol>";
150
+ return `For semantic impact, run \`code_resolve(query="${symbolHint}", scope="${firstFile}")\` then \`code_impact(targetId="<result>", change="<your change>")\`.`;
151
+ }