@mrclrchtr/supi-code-intelligence 1.16.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/README.md +373 -63
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  9. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  10. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  11. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  12. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  13. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  14. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  15. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  16. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  17. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  18. package/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  19. package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  20. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  21. package/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  22. package/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  23. package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  24. package/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  25. package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  26. package/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  27. package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  28. package/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  29. package/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  30. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  31. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  32. package/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  33. package/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  34. package/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/README.md +44 -56
  36. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  37. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  40. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  42. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  45. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  46. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  47. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  50. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  51. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  52. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  53. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  54. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  55. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  56. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  57. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  59. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  60. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  61. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  62. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  63. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  64. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  65. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  66. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  67. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  68. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  69. package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -31
  70. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +27 -0
  71. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +5 -0
  72. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +246 -1
  73. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +4 -0
  74. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +3 -0
  75. package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +4 -2
  76. package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +102 -0
  77. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +59 -0
  78. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +4 -0
  79. package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +11 -0
  80. package/node_modules/@mrclrchtr/supi-lsp/src/manager/capability-index.ts +1 -1
  81. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +2 -1
  82. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +115 -26
  83. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +177 -134
  84. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +214 -0
  85. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +320 -0
  86. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +26 -5
  87. package/node_modules/@mrclrchtr/supi-lsp/src/session/service-registry.ts +81 -4
  88. package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +2 -0
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +18 -37
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/LICENSE +21 -0
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/README.md +265 -0
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs +4661 -0
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs.map +7 -0
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js +4605 -0
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js.map +7 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +57 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +100 -0
  132. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs +4063 -0
  133. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs.map +7 -0
  134. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts +1025 -0
  135. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts.map +58 -0
  136. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1025 -0
  137. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +58 -0
  138. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js +4007 -0
  139. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js.map +7 -0
  140. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  141. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +55 -0
  142. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -12
  143. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +29 -0
  144. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +28 -0
  145. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -0
  146. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +14 -2
  147. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +157 -0
  148. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +8 -1
  149. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +86 -0
  150. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +35 -16
  151. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +1 -0
  152. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +10 -0
  153. package/package.json +14 -9
  154. package/src/{model.ts → analysis/architecture/discovery.ts} +15 -72
  155. package/src/analysis/architecture/model.ts +76 -0
  156. package/src/analysis/brief/directory.ts +324 -0
  157. package/src/analysis/brief/enrich.ts +157 -0
  158. package/src/analysis/brief/file.ts +84 -0
  159. package/src/analysis/brief/inventory.ts +177 -0
  160. package/src/analysis/brief/main.ts +176 -0
  161. package/src/analysis/brief/models.ts +75 -0
  162. package/src/{brief.ts → analysis/brief/public-brief.ts} +21 -26
  163. package/src/analysis/brief/summarize.ts +208 -0
  164. package/src/analysis/brief/types.ts +27 -0
  165. package/src/{use-case/generate-brief.ts → analysis/brief/use-case.ts} +67 -144
  166. package/src/analysis/coverage/coverage-warnings.ts +224 -0
  167. package/src/analysis/evidence.ts +91 -0
  168. package/src/{semantic-action-helpers.ts → analysis/helpers.ts} +4 -4
  169. package/src/analysis/provider.ts +186 -0
  170. package/src/analysis/read-next.ts +126 -0
  171. package/src/analysis/readiness.ts +73 -0
  172. package/src/{refactor → analysis/refactor}/safety.ts +1 -1
  173. package/src/{use-case/support/semantic-references.ts → analysis/references/semantic-refs.ts} +58 -26
  174. package/src/analysis/search/pattern.ts +345 -0
  175. package/src/analysis/search/ripgrep.ts +473 -0
  176. package/src/{git-context.ts → analysis/signals/git.ts} +20 -7
  177. package/src/{prioritization-signals.ts → analysis/signals/project.ts} +33 -19
  178. package/src/analysis/target/anchored.ts +349 -0
  179. package/src/analysis/target/bridge.ts +152 -0
  180. package/src/analysis/target/file-resolution.ts +125 -0
  181. package/src/{targeting/resolve-file.ts → analysis/target/file.ts} +40 -20
  182. package/src/{planner → analysis/target}/planner.ts +30 -20
  183. package/src/{targeting → analysis/target}/query.ts +17 -3
  184. package/src/analysis/target/resolve-common.ts +115 -0
  185. package/src/analysis/target/service.ts +229 -0
  186. package/src/analysis/target/symbol.ts +196 -0
  187. package/src/{targeting → analysis/target}/types.ts +17 -1
  188. package/src/analysis/tests/likely-tests.ts +174 -0
  189. package/src/analysis/tests/test-discovery.ts +540 -0
  190. package/src/analysis/tests/vitest.ts +87 -0
  191. package/src/api.ts +34 -41
  192. package/src/app/app.ts +125 -0
  193. package/src/app/manager.ts +65 -0
  194. package/src/extension.ts +132 -1
  195. package/src/index.ts +1 -57
  196. package/src/session/refactor-plans.ts +82 -0
  197. package/src/session/session.ts +300 -0
  198. package/src/session/target-store.ts +293 -0
  199. package/src/substrate/lsp/diagnostic-injection.ts +218 -0
  200. package/src/substrate/lsp/lifecycle.ts +66 -0
  201. package/src/substrate/lsp/overrides.ts +132 -0
  202. package/src/substrate/lsp/recovery.ts +55 -0
  203. package/src/substrate/lsp/settings.ts +286 -0
  204. package/src/substrate/lsp/state.ts +46 -0
  205. package/src/substrate/lsp/utils.ts +17 -0
  206. package/src/substrate/tree-sitter/lifecycle.ts +52 -0
  207. package/src/tool/find/execute.ts +118 -0
  208. package/src/{presentation/markdown/pattern.ts → tool/find/markdown.ts} +102 -53
  209. package/src/{use-case/generate-pattern.ts → tool/find/orchestrate.ts} +67 -33
  210. package/src/tool/find/semantic-search.ts +114 -0
  211. package/src/tool/find/tui.ts +39 -0
  212. package/src/tool/graph/callees.ts +87 -0
  213. package/src/tool/graph/calls-md.ts +54 -0
  214. package/src/tool/graph/collect-relation.ts +371 -0
  215. package/src/tool/graph/execute.ts +95 -0
  216. package/src/tool/graph/implementations-md.ts +79 -0
  217. package/src/tool/graph/implementations.ts +76 -0
  218. package/src/tool/graph/markdown-base.ts +243 -0
  219. package/src/tool/graph/orchestrate.ts +285 -0
  220. package/src/tool/graph/references-md.ts +34 -0
  221. package/src/tool/graph/references.ts +81 -0
  222. package/src/tool/graph/tui.ts +120 -0
  223. package/src/tool/graph/types.ts +97 -0
  224. package/src/tool/guidance.ts +96 -49
  225. package/src/tool/health/execute.ts +76 -0
  226. package/src/tool/health/markdown.ts +280 -0
  227. package/src/tool/health/orchestrate.ts +159 -0
  228. package/src/tool/health/sections/diagnostics.ts +182 -0
  229. package/src/tool/health/sections/recovery.ts +89 -0
  230. package/src/tool/health/sections/signals.ts +89 -0
  231. package/src/tool/health/tui.ts +137 -0
  232. package/src/tool/impact/analysis.ts +247 -0
  233. package/src/tool/impact/change-set-impact.ts +151 -0
  234. package/src/tool/impact/execute.ts +98 -0
  235. package/src/tool/impact/file-level-impact.ts +81 -0
  236. package/src/tool/impact/markdown.ts +283 -0
  237. package/src/tool/impact/orchestrate.ts +97 -0
  238. package/src/tool/impact/result.ts +21 -0
  239. package/src/tool/impact/single-impact.ts +89 -0
  240. package/src/tool/impact/tui.ts +39 -0
  241. package/src/tool/impact/types.ts +34 -0
  242. package/src/tool/infra/cross-field.ts +335 -0
  243. package/src/tool/infra/error-results.ts +199 -0
  244. package/src/tool/infra/pipeline.ts +311 -0
  245. package/src/tool/infra/progress.ts +21 -0
  246. package/src/tool/infra/readiness-message.ts +5 -0
  247. package/src/tool/infra/truncate.ts +49 -0
  248. package/src/tool/inspect/execute.ts +76 -0
  249. package/src/tool/inspect/markdown.ts +169 -0
  250. package/src/tool/inspect/orchestrate.ts +156 -0
  251. package/src/tool/inspect/tui.ts +36 -0
  252. package/src/tool/orientation/deps.ts +63 -0
  253. package/src/tool/orientation/execute.ts +50 -0
  254. package/src/tool/orientation/markdown.ts +35 -0
  255. package/src/tool/orientation/mode.ts +88 -0
  256. package/src/tool/orientation/orchestrate.ts +478 -0
  257. package/src/tool/orientation/precise-target.ts +257 -0
  258. package/src/tool/orientation/tui.ts +131 -0
  259. package/src/{refactor/apply-workspace-edit.ts → tool/refactor-apply/apply.ts} +39 -16
  260. package/src/tool/refactor-apply/execute.ts +20 -0
  261. package/src/tool/refactor-apply/markdown.ts +118 -0
  262. package/src/tool/refactor-apply/orchestrate.ts +89 -0
  263. package/src/tool/refactor-apply/tui.ts +51 -0
  264. package/src/tool/refactor-plan/execute.ts +73 -0
  265. package/src/tool/refactor-plan/markdown.ts +118 -0
  266. package/src/tool/refactor-plan/orchestrate.ts +363 -0
  267. package/src/tool/refactor-plan/tui.ts +42 -0
  268. package/src/tool/register.ts +123 -0
  269. package/src/tool/resolve/execute.ts +82 -0
  270. package/src/tool/resolve/markdown.ts +150 -0
  271. package/src/tool/resolve/orchestrate.ts +134 -0
  272. package/src/tool/resolve/tui.ts +40 -0
  273. package/src/tool/schemas.ts +337 -0
  274. package/src/tool/specs.ts +257 -0
  275. package/src/types/details.ts +188 -0
  276. package/src/types/execution.ts +60 -0
  277. package/src/types/index.ts +28 -0
  278. package/src/{intent/types.ts → types/tool-names.ts} +15 -14
  279. package/src/ui/footer.ts +52 -0
  280. package/src/ui/markdown/brief.ts +218 -0
  281. package/src/ui/markdown/gather.ts +177 -0
  282. package/src/{use-case/build-overview.ts → ui/markdown/overview-data.ts} +2 -2
  283. package/src/{presentation → ui}/markdown/overview.ts +2 -2
  284. package/src/ui/markdown/types.ts +80 -0
  285. package/{node_modules/@mrclrchtr/supi-lsp/src/ui/renderer.ts → src/ui/message-renderer.ts} +11 -10
  286. package/src/ui/status-command.ts +260 -0
  287. package/src/ui/status-overlay.ts +500 -0
  288. package/src/ui/tui/common.ts +220 -0
  289. package/src/ui/tui/index.ts +37 -0
  290. package/node_modules/@mrclrchtr/supi-lsp/src/extension.ts +0 -1
  291. package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +0 -373
  292. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/diagnostic-injection.ts +0 -182
  293. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/session-lifecycle.ts +0 -149
  294. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/status-command.ts +0 -38
  295. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/workspace-recovery.ts +0 -92
  296. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +0 -37
  297. package/node_modules/@mrclrchtr/supi-lsp/src/session/lsp-state.ts +0 -93
  298. package/node_modules/@mrclrchtr/supi-lsp/src/session/settings-registration.ts +0 -296
  299. package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +0 -75
  300. package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +0 -69
  301. package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +0 -27
  302. package/node_modules/@mrclrchtr/supi-lsp/src/tool/overrides.ts +0 -204
  303. package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +0 -69
  304. package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +0 -399
  305. package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +0 -248
  306. package/node_modules/@mrclrchtr/supi-lsp/src/ui/ui.ts +0 -360
  307. package/node_modules/@mrclrchtr/supi-lsp/src/workspace-change.ts +0 -40
  308. package/node_modules/@mrclrchtr/supi-tree-sitter/src/extension.ts +0 -1
  309. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/formatting.ts +0 -104
  310. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +0 -35
  311. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/handlers.ts +0 -196
  312. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/register-tools.ts +0 -107
  313. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/tool-specs.ts +0 -117
  314. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +0 -47
  315. package/src/brief-focused.ts +0 -563
  316. package/src/code-intelligence.ts +0 -70
  317. package/src/pattern-structured.ts +0 -194
  318. package/src/presentation/markdown/affected.ts +0 -170
  319. package/src/presentation/markdown/brief.ts +0 -174
  320. package/src/presentation/markdown/map.ts +0 -54
  321. package/src/presentation/markdown/refactor.ts +0 -27
  322. package/src/presentation/markdown/relations.ts +0 -121
  323. package/src/resolve-target.ts +0 -130
  324. package/src/search-helpers.ts +0 -303
  325. package/src/substrates/types.ts +0 -30
  326. package/src/target-resolution.ts +0 -122
  327. package/src/targeting/resolve-anchored.ts +0 -80
  328. package/src/targeting/resolve-symbol.ts +0 -110
  329. package/src/tool/execute-affected.ts +0 -71
  330. package/src/tool/execute-brief.ts +0 -59
  331. package/src/tool/execute-map.ts +0 -35
  332. package/src/tool/execute-pattern.ts +0 -29
  333. package/src/tool/execute-refactor.ts +0 -101
  334. package/src/tool/execute-relations.ts +0 -79
  335. package/src/tool/register-tools.ts +0 -32
  336. package/src/tool/tool-specs.ts +0 -190
  337. package/src/tool/validation.ts +0 -43
  338. package/src/types.ts +0 -169
  339. package/src/use-case/generate-affected.ts +0 -297
  340. package/src/use-case/generate-map.ts +0 -176
  341. package/src/use-case/generate-relations.ts +0 -438
  342. package/src/use-case/types.ts +0 -43
  343. package/src/workspace/request-context.ts +0 -139
  344. /package/src/{query-params.ts → tool/params.ts} +0 -0
@@ -0,0 +1,73 @@
1
+ import { getDefaultWorkspaceRuntime } from "@mrclrchtr/supi-code-runtime/api";
2
+ import {
3
+ getSessionLspService,
4
+ type SemanticReadinessResult,
5
+ type SessionLspServiceState,
6
+ waitForSessionLspService,
7
+ } from "@mrclrchtr/supi-lsp/api";
8
+
9
+ export const DEFAULT_SEMANTIC_STARTUP_TIMEOUT_MS = 15_000;
10
+
11
+ export type SemanticStartupScope = { kind: "workspace" } | { kind: "file"; file: string };
12
+
13
+ export async function ensureSemanticReadiness(
14
+ cwd: string,
15
+ scope: SemanticStartupScope,
16
+ timeoutMs: number = DEFAULT_SEMANTIC_STARTUP_TIMEOUT_MS,
17
+ ): Promise<SemanticReadinessResult> {
18
+ const workspace = getDefaultWorkspaceRuntime().getWorkspace(cwd);
19
+ if (workspace.semantic.provider === null) {
20
+ return {
21
+ kind: "unavailable",
22
+ reason: "No semantic/LSP provider is active for this workspace.",
23
+ };
24
+ }
25
+
26
+ if (workspace.semantic.state.kind === "ready") {
27
+ return { kind: "ready" };
28
+ }
29
+
30
+ if (workspace.semantic.state.kind !== "pending") {
31
+ return {
32
+ kind: "unavailable",
33
+ reason: `Semantic provider is ${workspace.semantic.state.kind} for this workspace.`,
34
+ };
35
+ }
36
+
37
+ const deadline = Date.now() + timeoutMs;
38
+
39
+ const remainingAfterService = deadline - Date.now();
40
+ if (remainingAfterService <= 0) {
41
+ return { kind: "timeout" };
42
+ }
43
+ const lspState = await resolveSemanticServiceState(cwd, remainingAfterService);
44
+ if (lspState.kind === "pending") {
45
+ return { kind: "timeout" };
46
+ }
47
+ if (lspState.kind !== "ready") {
48
+ return {
49
+ kind: "unavailable",
50
+ reason:
51
+ lspState.kind === "unavailable"
52
+ ? lspState.reason
53
+ : `LSP service is ${lspState.kind} for this workspace.`,
54
+ };
55
+ }
56
+
57
+ const remainingAfterLsp = deadline - Date.now();
58
+ if (remainingAfterLsp <= 0) {
59
+ return { kind: "timeout" };
60
+ }
61
+ return scope.kind === "workspace"
62
+ ? lspState.service.waitUntilReadyForWorkspace({ timeoutMs: remainingAfterLsp })
63
+ : lspState.service.waitUntilReadyForFile(scope.file, { timeoutMs: remainingAfterLsp });
64
+ }
65
+
66
+ async function resolveSemanticServiceState(
67
+ cwd: string,
68
+ timeoutMs: number,
69
+ ): Promise<SessionLspServiceState> {
70
+ const initialState = getSessionLspService(cwd);
71
+ if (initialState.kind !== "pending") return initialState;
72
+ return waitForSessionLspService(cwd, timeoutMs);
73
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Edit validation safety checks for the code_refactor apply path.
2
+ * Refactor safety edit validation for workspace edits.
3
3
  *
4
4
  * Rejects empty edits, invalid ranges, and out-of-bounds changes
5
5
  * before they reach the filesystem.
@@ -2,11 +2,18 @@
2
2
  // Moved from src/actions/semantic-references.ts into the use-case support layer.
3
3
 
4
4
  import * as path from "node:path";
5
- import { filterOutDeclaration, isInProjectPath, uriToFile } from "../../search-helpers.ts";
6
- import { dedupeFileLineRefs, highestConfidence } from "../../semantic-action-helpers.ts";
7
- import type { SemanticSubstrate } from "../../substrates/types.ts";
8
- import type { ResolvedTarget } from "../../target-resolution.ts";
9
- import type { ConfidenceMode } from "../../types.ts";
5
+ import type {
6
+ ConfidenceMode,
7
+ SemanticProvider as SemanticSubstrate,
8
+ } from "@mrclrchtr/supi-code-runtime/api";
9
+ import {
10
+ createEvidenceList,
11
+ type EvidenceListMetadata,
12
+ renderEvidenceListDisclosure,
13
+ } from "../evidence.ts";
14
+ import { dedupeFileLineRefs, highestConfidence } from "../helpers.ts";
15
+ import { filterOutDeclaration, isInProjectPath, uriToFile } from "../search/ripgrep.ts";
16
+ import type { ResolvedTargetData } from "../target/types.ts";
10
17
 
11
18
  export interface FileLineRef {
12
19
  file: string;
@@ -24,7 +31,7 @@ export interface ReferenceCollection {
24
31
  * and partitioning project vs external (node_modules/out-of-tree) references.
25
32
  */
26
33
  export async function collectReferences(
27
- target: ResolvedTarget,
34
+ target: { file: string; position: { line: number; character: number } },
28
35
  cwd: string,
29
36
  semantic: SemanticSubstrate,
30
37
  ): Promise<ReferenceCollection> {
@@ -58,8 +65,8 @@ export async function collectReferences(
58
65
  * Deduplicates refs by file:line, merges confidence, and sums external counts.
59
66
  */
60
67
  export async function aggregatePerTarget<T extends ReferenceCollection>(
61
- targets: ResolvedTarget[],
62
- collectFn: (target: ResolvedTarget) => Promise<T>,
68
+ targets: ResolvedTargetData[],
69
+ collectFn: (target: ResolvedTargetData) => Promise<T>,
63
70
  ): Promise<ReferenceCollection> {
64
71
  if (targets.length === 0) {
65
72
  return { refs: [], confidence: "unavailable", externalCount: 0 };
@@ -73,42 +80,67 @@ export async function aggregatePerTarget<T extends ReferenceCollection>(
73
80
  return { refs: combinedRefs, confidence: combinedConfidence, externalCount: combinedExternal };
74
81
  }
75
82
 
83
+ /**
84
+ * Compact sorted line numbers into a concise label string.
85
+ * Consecutive runs produce ranges: [9,10] → "L9-L10".
86
+ * Non-consecutive lines stay single: [9,348] → "L9, L348".
87
+ */
88
+ export function compactLineRanges(lines: number[]): string {
89
+ const unique = [...new Set(lines)];
90
+ const sorted = unique.sort((a, b) => a - b);
91
+ const parts: string[] = [];
92
+ let i = 0;
93
+ while (i < sorted.length) {
94
+ let j = i;
95
+ while (j + 1 < sorted.length && sorted[j + 1] === sorted[j] + 1) {
96
+ j++;
97
+ }
98
+ if (j > i) {
99
+ parts.push(`L${sorted[i]}-L${sorted[j]}`);
100
+ } else {
101
+ parts.push(`L${sorted[i]}`);
102
+ }
103
+ i = j + 1;
104
+ }
105
+ return parts.join(", ");
106
+ }
107
+
76
108
  /**
77
109
  * Append a formatted reference list to a lines array.
78
- * Groups refs by file, caps per-file lines at 5, and caps total files at maxResults.
110
+ * Groups shown refs by file, compacts line numbers into concise labels, and
111
+ * caps reference-location atoms at maxResults.
79
112
  */
80
113
  export function formatReferenceList(
81
114
  lines: string[],
82
115
  refs: FileLineRef[],
83
116
  maxResults: number,
84
- _cwd: string,
85
- ): void {
86
- if (refs.length === 0) return;
117
+ ): EvidenceListMetadata | null {
118
+ if (refs.length === 0) return null;
119
+
120
+ const evidence = createEvidenceList({
121
+ key: "references.locations",
122
+ items: refs,
123
+ maxResults,
124
+ });
87
125
 
88
126
  const byFile = new Map<string, number[]>();
89
- for (const ref of refs) {
127
+ for (const ref of evidence.items) {
90
128
  const group = byFile.get(ref.file) ?? [];
91
129
  group.push(ref.line);
92
130
  byFile.set(ref.file, group);
93
131
  }
94
132
 
95
- let shown = 0;
96
133
  for (const [file, locations] of byFile) {
97
- if (shown >= maxResults) break;
98
134
  lines.push(`### ${file}`);
99
- for (const loc of locations.slice(0, 5)) {
100
- lines.push(`- L${loc}`);
101
- }
102
- if (locations.length > 5) {
103
- lines.push(`- _+${locations.length - 5} more in this file_`);
104
- }
135
+ const label = compactLineRanges(locations);
136
+ lines.push(`- ${label}`);
105
137
  lines.push("");
106
- shown++;
107
138
  }
108
139
 
109
- if (byFile.size > maxResults) {
110
- lines.push(
111
- `_+${byFile.size - maxResults} more files omitted. Narrow with \`path\` or increase \`maxResults\`._`,
112
- );
140
+ const disclosure = renderEvidenceListDisclosure(evidence);
141
+ if (disclosure) {
142
+ lines.push(disclosure);
113
143
  }
144
+
145
+ return evidence.metadata;
114
146
  }
@@ -0,0 +1,345 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import * as path from "node:path";
3
+ import type { StructuralProvider as StructuralSubstrate } from "@mrclrchtr/supi-code-runtime/api";
4
+ import { getSupportedExtensions } from "@mrclrchtr/supi-tree-sitter/api";
5
+
6
+ /** Soft file cap — warn when a workspace has more source files than this. */
7
+ const FILE_SOFT_CAP = 5000;
8
+ const STRUCTURED_PATTERN_TIMEOUT_MS = 10_000;
9
+
10
+ export type StructuredPatternKind =
11
+ | "definition"
12
+ | "export"
13
+ | "import"
14
+ | "call"
15
+ | "type"
16
+ | "interface"
17
+ | "class"
18
+ | "method"
19
+ | "enum"
20
+ | "test";
21
+
22
+ export interface StructuredPatternParams {
23
+ pattern: string;
24
+ kind: StructuredPatternKind;
25
+ regex?: boolean;
26
+ }
27
+
28
+ export interface StructuredMatch {
29
+ file: string;
30
+ name: string;
31
+ kind: string;
32
+ line: number;
33
+ }
34
+
35
+ export interface StructuredPatternResult {
36
+ matches: StructuredMatch[];
37
+ omittedCount: number;
38
+ partialReason: "file-cap" | "timeout" | null;
39
+ /** Per-file parse/analysis failures surfaced to the agent. */
40
+ failures: StructuredFailure[];
41
+ }
42
+
43
+ export interface StructuredFailure {
44
+ file: string;
45
+ reason: string;
46
+ }
47
+
48
+ export function isStructuredPatternKind(kind: string | undefined): kind is StructuredPatternKind {
49
+ return (
50
+ kind === "definition" ||
51
+ kind === "export" ||
52
+ kind === "import" ||
53
+ kind === "call" ||
54
+ kind === "type" ||
55
+ kind === "interface" ||
56
+ kind === "class" ||
57
+ kind === "method" ||
58
+ kind === "enum" ||
59
+ kind === "test"
60
+ );
61
+ }
62
+
63
+ // biome-ignore lint/complexity/useMaxParams: substrate injection keeps related inputs explicit for readability
64
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: enumeration-interrupted, cap, timeout, and error branches are each necessary
65
+ export async function getStructuredPatternMatches(
66
+ params: StructuredPatternParams,
67
+ scopePath: string,
68
+ cwd: string,
69
+ relScope: string,
70
+ structural: StructuralSubstrate,
71
+ ): Promise<StructuredPatternResult | string | null> {
72
+ const deadline = Date.now() + STRUCTURED_PATTERN_TIMEOUT_MS;
73
+
74
+ // Enumerate all supported source files via ripgrep (language-agnostic).
75
+ const enumeration = enumerateSourceFiles(scopePath, cwd);
76
+ if (enumeration === null) {
77
+ return `Ripgrep (rg) is not available. Install it for structured pattern search.`;
78
+ }
79
+
80
+ const allFiles = enumeration.files;
81
+ let omittedCount = 0;
82
+
83
+ if (enumeration.interrupted) {
84
+ // rg was killed before completing the file listing — treat as partial
85
+ omittedCount = Math.max(1, omittedCount);
86
+ }
87
+
88
+ if (allFiles.length === 0) {
89
+ return {
90
+ matches: [],
91
+ omittedCount,
92
+ partialReason: enumeration.interrupted ? "timeout" : null,
93
+ failures: [],
94
+ };
95
+ }
96
+
97
+ const capped = allFiles.slice(0, FILE_SOFT_CAP);
98
+ if (allFiles.length > FILE_SOFT_CAP) {
99
+ omittedCount = allFiles.length - FILE_SOFT_CAP;
100
+ }
101
+
102
+ const matcher = createStructuredMatcher(params.pattern, params.regex ?? false);
103
+ if (typeof matcher === "string") {
104
+ return matcher;
105
+ }
106
+
107
+ try {
108
+ const matches: StructuredMatch[] = [];
109
+ const failures: StructuredFailure[] = [];
110
+ let timedOut = false;
111
+
112
+ for (const [index, file] of capped.entries()) {
113
+ if (Date.now() > deadline) {
114
+ omittedCount += capped.length - index;
115
+ timedOut = true;
116
+ break;
117
+ }
118
+ const absFile = path.resolve(cwd, file);
119
+ const relFile = path.relative(cwd, absFile);
120
+ await collectMatchesForFile(matches, failures, structural, relFile, params.kind, matcher);
121
+ }
122
+
123
+ return {
124
+ matches,
125
+ failures,
126
+ omittedCount: timedOut ? Math.max(1, omittedCount) : omittedCount,
127
+ partialReason: timedOut ? "timeout" : omittedCount > 0 ? "file-cap" : null,
128
+ };
129
+ } catch {
130
+ return `No structured ${params.kind} search data available in \`${relScope}\`. Try omitting \`kind\` for plain text search.`;
131
+ }
132
+ }
133
+
134
+ // ── File enumeration ─────────────────────────────────────────────────
135
+
136
+ interface FileEnumeration {
137
+ files: string[];
138
+ /** True when rg was terminated before completing the listing. */
139
+ interrupted: boolean;
140
+ }
141
+
142
+ /**
143
+ * Enumerate all tree-sitter-supported source files in scopePath using rg --files.
144
+ * Returns null if ripgrep is not available.
145
+ */
146
+ function enumerateSourceFiles(scopePath: string, cwd: string): FileEnumeration | null {
147
+ const extensions = getSupportedExtensions();
148
+ // Strip leading dots — ripgrep -g expects ".ext" without the dot prefix
149
+ const globPattern = `*.{${Array.from(extensions)
150
+ .map((ext) => ext.replace(/^\./, ""))
151
+ .join(",")}}`;
152
+
153
+ try {
154
+ const output = execFileSync("rg", ["--files", "-g", globPattern, scopePath], {
155
+ encoding: "utf-8",
156
+ cwd,
157
+ timeout: 5000,
158
+ stdio: ["pipe", "pipe", "pipe"],
159
+ });
160
+ return {
161
+ files: output
162
+ .split("\n")
163
+ .map((line) => line.trim())
164
+ .filter((line) => line.length > 0)
165
+ .sort((a, b) => a.localeCompare(b)),
166
+ interrupted: false,
167
+ };
168
+ } catch (err: unknown) {
169
+ if (isCodeError(err, "ENOENT")) {
170
+ return null;
171
+ }
172
+ // Non-zero exit (e.g. no matches) is fine — return what we got
173
+ if (isExecError(err)) {
174
+ const stdout = typeof err.stdout === "string" ? err.stdout : "";
175
+ const wasKilled = (err as { killed?: boolean }).killed === true;
176
+ return {
177
+ files: stdout
178
+ .split("\n")
179
+ .map((line) => line.trim())
180
+ .filter((line) => line.length > 0)
181
+ .sort((a, b) => a.localeCompare(b)),
182
+ interrupted: wasKilled,
183
+ };
184
+ }
185
+ return { files: [], interrupted: false };
186
+ }
187
+ }
188
+
189
+ // biome-ignore lint/complexity/useMaxParams: helper takes explicit collection inputs to avoid intermediate objects in the hot path
190
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: kind-specific tree-sitter matching is clearest as one helper
191
+ async function collectMatchesForFile(
192
+ matches: StructuredMatch[],
193
+ failures: StructuredFailure[],
194
+ structural: StructuralSubstrate,
195
+ relFile: string,
196
+ kind: StructuredPatternKind,
197
+ matcher: (value: string) => boolean,
198
+ ): Promise<void> {
199
+ const recordFailure = (reason: string) => {
200
+ failures.push({ file: relFile, reason });
201
+ };
202
+
203
+ if (kind === "definition") {
204
+ const outline = await structural.outline(relFile);
205
+ if (!handleStructuralResult(outline, relFile, recordFailure)) return;
206
+ for (const item of outline.data) {
207
+ if (!matcher(item.name)) continue;
208
+ matches.push({ file: relFile, name: item.name, kind: item.kind, line: item.startLine });
209
+ }
210
+ return;
211
+ }
212
+
213
+ if (kind === "export") {
214
+ const exportsResult = await structural.exports(relFile);
215
+ if (!handleStructuralResult(exportsResult, relFile, recordFailure)) return;
216
+ for (const item of exportsResult.data) {
217
+ if (!matcher(item.name)) continue;
218
+ matches.push({ file: relFile, name: item.name, kind: item.kind, line: item.startLine });
219
+ }
220
+ return;
221
+ }
222
+
223
+ if (kind === "import") {
224
+ const importsResult = await structural.imports(relFile);
225
+ if (!handleStructuralResult(importsResult, relFile, recordFailure)) return;
226
+ for (const item of importsResult.data) {
227
+ if (!matcher(item.moduleSpecifier)) continue;
228
+ matches.push({
229
+ file: relFile,
230
+ name: item.moduleSpecifier,
231
+ kind: "import",
232
+ line: item.startLine,
233
+ });
234
+ }
235
+ return;
236
+ }
237
+
238
+ if (kind === "call") {
239
+ const callResult = await structural.callSites(relFile);
240
+ if (!handleStructuralResult(callResult, relFile, recordFailure)) return;
241
+ for (const cs of callResult.data) {
242
+ if (!matcher(cs.name)) continue;
243
+ matches.push({ file: relFile, name: cs.name, kind: "call", line: cs.startLine });
244
+ }
245
+ return;
246
+ }
247
+
248
+ // ── type / interface / class / method / enum / test — use outline with kind-specific filters ─
249
+
250
+ if (
251
+ kind === "type" ||
252
+ kind === "interface" ||
253
+ kind === "class" ||
254
+ kind === "method" ||
255
+ kind === "enum" ||
256
+ kind === "test"
257
+ ) {
258
+ const outline = await structural.outline(relFile);
259
+ if (!handleStructuralResult(outline, relFile, recordFailure)) return;
260
+ for (const item of outline.data) {
261
+ if (kind === "type" && !isTypeLikeKind(item.kind)) continue;
262
+ if (kind === "interface" && !isInterfaceKind(item.kind)) continue;
263
+ if (kind === "class" && item.kind.toLowerCase() !== "class") continue;
264
+ if (kind === "method" && item.kind.toLowerCase() !== "method") continue;
265
+ if (kind === "enum" && item.kind.toLowerCase() !== "enum") continue;
266
+ if (kind === "test") {
267
+ const isTestName =
268
+ /^(test|it|describe|spec)\b/.test(item.name) ||
269
+ /\b(test|spec|Test|Spec)\b/.test(item.name);
270
+ if (!isTestName && !matcher(item.name)) continue;
271
+ }
272
+ if (!matcher(item.name)) continue;
273
+ matches.push({ file: relFile, name: item.name, kind: item.kind, line: item.startLine });
274
+ }
275
+ }
276
+ }
277
+
278
+ // ── Result handling ──────────────────────────────────────────────────
279
+
280
+ /**
281
+ * Handle a structural CodeResult: surface non-success results as failures,
282
+ * return whether the caller should continue processing data.
283
+ */
284
+ function handleStructuralResult<T>(
285
+ result: { kind: string; message?: string; file?: string },
286
+ _relFile: string,
287
+ recordFailure: (reason: string) => void,
288
+ ): result is { kind: "success"; data: T } {
289
+ if (result.kind === "success") return true;
290
+ recordFailure(result.message ?? result.kind);
291
+ return false;
292
+ }
293
+
294
+ /** Outline kind values that represent type declarations (as normalized by the outline extractor). */
295
+ const TYPE_LIKE_KINDS = new Set(["class", "interface", "type", "enum"]);
296
+
297
+ function isTypeLikeKind(kind: string): boolean {
298
+ return TYPE_LIKE_KINDS.has(kind.toLowerCase());
299
+ }
300
+
301
+ function isInterfaceKind(kind: string): boolean {
302
+ return kind.toLowerCase() === "interface";
303
+ }
304
+
305
+ function createStructuredMatcher(
306
+ pattern: string,
307
+ regex: boolean,
308
+ ): ((value: string) => boolean) | string {
309
+ const ignoreCase = !/[A-Z]/.test(pattern);
310
+
311
+ if (regex) {
312
+ try {
313
+ const compiled = new RegExp(pattern, ignoreCase ? "i" : undefined);
314
+ return (value: string) => compiled.test(value);
315
+ } catch (error) {
316
+ const message = error instanceof Error ? error.message : "Invalid regex";
317
+ return `**Error:** Invalid regex pattern \`${pattern}\`: ${message}`;
318
+ }
319
+ }
320
+
321
+ const needle = ignoreCase ? pattern.toLowerCase() : pattern;
322
+ return (value: string) => {
323
+ const haystack = ignoreCase ? value.toLowerCase() : value;
324
+ return haystack.includes(needle);
325
+ };
326
+ }
327
+
328
+ // ── Error helpers ────────────────────────────────────────────────────
329
+
330
+ function isExecError(err: unknown): err is {
331
+ status: number;
332
+ stdout?: unknown;
333
+ stderr?: unknown;
334
+ } {
335
+ return typeof err === "object" && err !== null && "status" in err;
336
+ }
337
+
338
+ function isCodeError(err: unknown, code: string): boolean {
339
+ return (
340
+ typeof err === "object" &&
341
+ err !== null &&
342
+ "code" in err &&
343
+ (err as { code: unknown }).code === code
344
+ );
345
+ }