@mrclrchtr/supi-code-intelligence 1.16.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/README.md +373 -63
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  9. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  10. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  11. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  12. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  13. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  14. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  15. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  16. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  17. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  18. package/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  19. package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  20. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  21. package/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  22. package/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  23. package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  24. package/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  25. package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  26. package/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  27. package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  28. package/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  29. package/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  30. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  31. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  32. package/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  33. package/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  34. package/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/README.md +44 -56
  36. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  37. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  40. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  42. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  45. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  46. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  47. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  50. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  51. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  52. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  53. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  54. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  55. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  56. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  57. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  59. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  60. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  61. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  62. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  63. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  64. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  65. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  66. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  67. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  68. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  69. package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -31
  70. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +27 -0
  71. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +5 -0
  72. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +246 -1
  73. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +4 -0
  74. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +3 -0
  75. package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +4 -2
  76. package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +102 -0
  77. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +59 -0
  78. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +4 -0
  79. package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +11 -0
  80. package/node_modules/@mrclrchtr/supi-lsp/src/manager/capability-index.ts +1 -1
  81. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +2 -1
  82. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +115 -26
  83. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +177 -134
  84. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +214 -0
  85. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +320 -0
  86. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +26 -5
  87. package/node_modules/@mrclrchtr/supi-lsp/src/session/service-registry.ts +81 -4
  88. package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +2 -0
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +18 -37
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/LICENSE +21 -0
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/README.md +265 -0
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs +4661 -0
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs.map +7 -0
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js +4605 -0
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js.map +7 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +57 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +100 -0
  132. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs +4063 -0
  133. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs.map +7 -0
  134. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts +1025 -0
  135. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts.map +58 -0
  136. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1025 -0
  137. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +58 -0
  138. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js +4007 -0
  139. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js.map +7 -0
  140. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  141. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +55 -0
  142. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -12
  143. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +29 -0
  144. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +28 -0
  145. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -0
  146. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +14 -2
  147. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +157 -0
  148. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +8 -1
  149. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +86 -0
  150. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +35 -16
  151. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +1 -0
  152. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +10 -0
  153. package/package.json +14 -9
  154. package/src/{model.ts → analysis/architecture/discovery.ts} +15 -72
  155. package/src/analysis/architecture/model.ts +76 -0
  156. package/src/analysis/brief/directory.ts +324 -0
  157. package/src/analysis/brief/enrich.ts +157 -0
  158. package/src/analysis/brief/file.ts +84 -0
  159. package/src/analysis/brief/inventory.ts +177 -0
  160. package/src/analysis/brief/main.ts +176 -0
  161. package/src/analysis/brief/models.ts +75 -0
  162. package/src/{brief.ts → analysis/brief/public-brief.ts} +21 -26
  163. package/src/analysis/brief/summarize.ts +208 -0
  164. package/src/analysis/brief/types.ts +27 -0
  165. package/src/{use-case/generate-brief.ts → analysis/brief/use-case.ts} +67 -144
  166. package/src/analysis/coverage/coverage-warnings.ts +224 -0
  167. package/src/analysis/evidence.ts +91 -0
  168. package/src/{semantic-action-helpers.ts → analysis/helpers.ts} +4 -4
  169. package/src/analysis/provider.ts +186 -0
  170. package/src/analysis/read-next.ts +126 -0
  171. package/src/analysis/readiness.ts +73 -0
  172. package/src/{refactor → analysis/refactor}/safety.ts +1 -1
  173. package/src/{use-case/support/semantic-references.ts → analysis/references/semantic-refs.ts} +58 -26
  174. package/src/analysis/search/pattern.ts +345 -0
  175. package/src/analysis/search/ripgrep.ts +473 -0
  176. package/src/{git-context.ts → analysis/signals/git.ts} +20 -7
  177. package/src/{prioritization-signals.ts → analysis/signals/project.ts} +33 -19
  178. package/src/analysis/target/anchored.ts +349 -0
  179. package/src/analysis/target/bridge.ts +152 -0
  180. package/src/analysis/target/file-resolution.ts +125 -0
  181. package/src/{targeting/resolve-file.ts → analysis/target/file.ts} +40 -20
  182. package/src/{planner → analysis/target}/planner.ts +30 -20
  183. package/src/{targeting → analysis/target}/query.ts +17 -3
  184. package/src/analysis/target/resolve-common.ts +115 -0
  185. package/src/analysis/target/service.ts +229 -0
  186. package/src/analysis/target/symbol.ts +196 -0
  187. package/src/{targeting → analysis/target}/types.ts +17 -1
  188. package/src/analysis/tests/likely-tests.ts +174 -0
  189. package/src/analysis/tests/test-discovery.ts +540 -0
  190. package/src/analysis/tests/vitest.ts +87 -0
  191. package/src/api.ts +34 -41
  192. package/src/app/app.ts +125 -0
  193. package/src/app/manager.ts +65 -0
  194. package/src/extension.ts +132 -1
  195. package/src/index.ts +1 -57
  196. package/src/session/refactor-plans.ts +82 -0
  197. package/src/session/session.ts +300 -0
  198. package/src/session/target-store.ts +293 -0
  199. package/src/substrate/lsp/diagnostic-injection.ts +218 -0
  200. package/src/substrate/lsp/lifecycle.ts +66 -0
  201. package/src/substrate/lsp/overrides.ts +132 -0
  202. package/src/substrate/lsp/recovery.ts +55 -0
  203. package/src/substrate/lsp/settings.ts +286 -0
  204. package/src/substrate/lsp/state.ts +46 -0
  205. package/src/substrate/lsp/utils.ts +17 -0
  206. package/src/substrate/tree-sitter/lifecycle.ts +52 -0
  207. package/src/tool/find/execute.ts +118 -0
  208. package/src/{presentation/markdown/pattern.ts → tool/find/markdown.ts} +102 -53
  209. package/src/{use-case/generate-pattern.ts → tool/find/orchestrate.ts} +67 -33
  210. package/src/tool/find/semantic-search.ts +114 -0
  211. package/src/tool/find/tui.ts +39 -0
  212. package/src/tool/graph/callees.ts +87 -0
  213. package/src/tool/graph/calls-md.ts +54 -0
  214. package/src/tool/graph/collect-relation.ts +371 -0
  215. package/src/tool/graph/execute.ts +95 -0
  216. package/src/tool/graph/implementations-md.ts +79 -0
  217. package/src/tool/graph/implementations.ts +76 -0
  218. package/src/tool/graph/markdown-base.ts +243 -0
  219. package/src/tool/graph/orchestrate.ts +285 -0
  220. package/src/tool/graph/references-md.ts +34 -0
  221. package/src/tool/graph/references.ts +81 -0
  222. package/src/tool/graph/tui.ts +120 -0
  223. package/src/tool/graph/types.ts +97 -0
  224. package/src/tool/guidance.ts +96 -49
  225. package/src/tool/health/execute.ts +76 -0
  226. package/src/tool/health/markdown.ts +280 -0
  227. package/src/tool/health/orchestrate.ts +159 -0
  228. package/src/tool/health/sections/diagnostics.ts +182 -0
  229. package/src/tool/health/sections/recovery.ts +89 -0
  230. package/src/tool/health/sections/signals.ts +89 -0
  231. package/src/tool/health/tui.ts +137 -0
  232. package/src/tool/impact/analysis.ts +247 -0
  233. package/src/tool/impact/change-set-impact.ts +151 -0
  234. package/src/tool/impact/execute.ts +98 -0
  235. package/src/tool/impact/file-level-impact.ts +81 -0
  236. package/src/tool/impact/markdown.ts +283 -0
  237. package/src/tool/impact/orchestrate.ts +97 -0
  238. package/src/tool/impact/result.ts +21 -0
  239. package/src/tool/impact/single-impact.ts +89 -0
  240. package/src/tool/impact/tui.ts +39 -0
  241. package/src/tool/impact/types.ts +34 -0
  242. package/src/tool/infra/cross-field.ts +335 -0
  243. package/src/tool/infra/error-results.ts +199 -0
  244. package/src/tool/infra/pipeline.ts +311 -0
  245. package/src/tool/infra/progress.ts +21 -0
  246. package/src/tool/infra/readiness-message.ts +5 -0
  247. package/src/tool/infra/truncate.ts +49 -0
  248. package/src/tool/inspect/execute.ts +76 -0
  249. package/src/tool/inspect/markdown.ts +169 -0
  250. package/src/tool/inspect/orchestrate.ts +156 -0
  251. package/src/tool/inspect/tui.ts +36 -0
  252. package/src/tool/orientation/deps.ts +63 -0
  253. package/src/tool/orientation/execute.ts +50 -0
  254. package/src/tool/orientation/markdown.ts +35 -0
  255. package/src/tool/orientation/mode.ts +88 -0
  256. package/src/tool/orientation/orchestrate.ts +478 -0
  257. package/src/tool/orientation/precise-target.ts +257 -0
  258. package/src/tool/orientation/tui.ts +131 -0
  259. package/src/{refactor/apply-workspace-edit.ts → tool/refactor-apply/apply.ts} +39 -16
  260. package/src/tool/refactor-apply/execute.ts +20 -0
  261. package/src/tool/refactor-apply/markdown.ts +118 -0
  262. package/src/tool/refactor-apply/orchestrate.ts +89 -0
  263. package/src/tool/refactor-apply/tui.ts +51 -0
  264. package/src/tool/refactor-plan/execute.ts +73 -0
  265. package/src/tool/refactor-plan/markdown.ts +118 -0
  266. package/src/tool/refactor-plan/orchestrate.ts +363 -0
  267. package/src/tool/refactor-plan/tui.ts +42 -0
  268. package/src/tool/register.ts +123 -0
  269. package/src/tool/resolve/execute.ts +82 -0
  270. package/src/tool/resolve/markdown.ts +150 -0
  271. package/src/tool/resolve/orchestrate.ts +134 -0
  272. package/src/tool/resolve/tui.ts +40 -0
  273. package/src/tool/schemas.ts +337 -0
  274. package/src/tool/specs.ts +257 -0
  275. package/src/types/details.ts +188 -0
  276. package/src/types/execution.ts +60 -0
  277. package/src/types/index.ts +28 -0
  278. package/src/{intent/types.ts → types/tool-names.ts} +15 -14
  279. package/src/ui/footer.ts +52 -0
  280. package/src/ui/markdown/brief.ts +218 -0
  281. package/src/ui/markdown/gather.ts +177 -0
  282. package/src/{use-case/build-overview.ts → ui/markdown/overview-data.ts} +2 -2
  283. package/src/{presentation → ui}/markdown/overview.ts +2 -2
  284. package/src/ui/markdown/types.ts +80 -0
  285. package/{node_modules/@mrclrchtr/supi-lsp/src/ui/renderer.ts → src/ui/message-renderer.ts} +11 -10
  286. package/src/ui/status-command.ts +260 -0
  287. package/src/ui/status-overlay.ts +500 -0
  288. package/src/ui/tui/common.ts +220 -0
  289. package/src/ui/tui/index.ts +37 -0
  290. package/node_modules/@mrclrchtr/supi-lsp/src/extension.ts +0 -1
  291. package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +0 -373
  292. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/diagnostic-injection.ts +0 -182
  293. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/session-lifecycle.ts +0 -149
  294. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/status-command.ts +0 -38
  295. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/workspace-recovery.ts +0 -92
  296. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +0 -37
  297. package/node_modules/@mrclrchtr/supi-lsp/src/session/lsp-state.ts +0 -93
  298. package/node_modules/@mrclrchtr/supi-lsp/src/session/settings-registration.ts +0 -296
  299. package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +0 -75
  300. package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +0 -69
  301. package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +0 -27
  302. package/node_modules/@mrclrchtr/supi-lsp/src/tool/overrides.ts +0 -204
  303. package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +0 -69
  304. package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +0 -399
  305. package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +0 -248
  306. package/node_modules/@mrclrchtr/supi-lsp/src/ui/ui.ts +0 -360
  307. package/node_modules/@mrclrchtr/supi-lsp/src/workspace-change.ts +0 -40
  308. package/node_modules/@mrclrchtr/supi-tree-sitter/src/extension.ts +0 -1
  309. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/formatting.ts +0 -104
  310. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +0 -35
  311. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/handlers.ts +0 -196
  312. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/register-tools.ts +0 -107
  313. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/tool-specs.ts +0 -117
  314. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +0 -47
  315. package/src/brief-focused.ts +0 -563
  316. package/src/code-intelligence.ts +0 -70
  317. package/src/pattern-structured.ts +0 -194
  318. package/src/presentation/markdown/affected.ts +0 -170
  319. package/src/presentation/markdown/brief.ts +0 -174
  320. package/src/presentation/markdown/map.ts +0 -54
  321. package/src/presentation/markdown/refactor.ts +0 -27
  322. package/src/presentation/markdown/relations.ts +0 -121
  323. package/src/resolve-target.ts +0 -130
  324. package/src/search-helpers.ts +0 -303
  325. package/src/substrates/types.ts +0 -30
  326. package/src/target-resolution.ts +0 -122
  327. package/src/targeting/resolve-anchored.ts +0 -80
  328. package/src/targeting/resolve-symbol.ts +0 -110
  329. package/src/tool/execute-affected.ts +0 -71
  330. package/src/tool/execute-brief.ts +0 -59
  331. package/src/tool/execute-map.ts +0 -35
  332. package/src/tool/execute-pattern.ts +0 -29
  333. package/src/tool/execute-refactor.ts +0 -101
  334. package/src/tool/execute-relations.ts +0 -79
  335. package/src/tool/register-tools.ts +0 -32
  336. package/src/tool/tool-specs.ts +0 -190
  337. package/src/tool/validation.ts +0 -43
  338. package/src/types.ts +0 -169
  339. package/src/use-case/generate-affected.ts +0 -297
  340. package/src/use-case/generate-map.ts +0 -176
  341. package/src/use-case/generate-relations.ts +0 -438
  342. package/src/use-case/types.ts +0 -43
  343. package/src/workspace/request-context.ts +0 -139
  344. /package/src/{query-params.ts → tool/params.ts} +0 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * TUI renderer for code_refactor_apply — renderCall + renderResult.
3
+ *
4
+ * Has a custom result renderer (not using renderSimpleResult) because
5
+ * its compact view shows success/error status rather than a count badge.
6
+ */
7
+ import type { Theme } from "@earendil-works/pi-coding-agent";
8
+ import { Container, Text } from "@earendil-works/pi-tui";
9
+ import {
10
+ type ResultOptios,
11
+ renderMarkdownDetail,
12
+ renderPartial,
13
+ type ToolResult,
14
+ } from "../../ui/tui/common.ts";
15
+
16
+ /** ── renderCall ────────────────────────────────────────────────── */
17
+
18
+ export function renderRefactorApplyCall(_args: unknown, theme: Theme, _context: unknown): Text {
19
+ return new Text(
20
+ `${theme.fg("toolTitle", "code_refactor_apply")} ${theme.fg("accent", "apply plan")}`,
21
+ 0,
22
+ 0,
23
+ );
24
+ }
25
+
26
+ /** ── renderResult ──────────────────────────────────────────────── */
27
+
28
+ export function renderRefactorApplyResult(
29
+ result: ToolResult,
30
+ options: ResultOptios,
31
+ theme: Theme,
32
+ _context: unknown,
33
+ ): Container | Text {
34
+ if (options.isPartial) {
35
+ return renderPartial("Applying…", theme);
36
+ }
37
+
38
+ if (!options.expanded) {
39
+ return new Text(
40
+ result.isError
41
+ ? theme.fg("error", "Refactor apply failed")
42
+ : theme.fg("success", theme.bold("Plan applied")),
43
+ 0,
44
+ 0,
45
+ );
46
+ }
47
+
48
+ const container = new Container();
49
+ renderMarkdownDetail(container, result, theme);
50
+ return container;
51
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Tool executor for the preview-only refactor planning path.
3
+ *
4
+ * Thin executor: validates semantic readiness via pipeline, then delegates
5
+ * to the refactor plan use-case for operation normalization, target resolution,
6
+ * provider interaction, and plan storage. Returns a planId for code_refactor_apply.
7
+ */
8
+
9
+ import type { CodeIntelResult, CodeIntelToolExecCtx } from "../../types/index.ts";
10
+ import { gateSemanticReadiness, runPipe } from "../infra/pipeline.ts";
11
+ import { renderSemanticReadinessTimeout } from "../infra/readiness-message.ts";
12
+ import { executeRefactorPlan } from "./orchestrate.ts";
13
+
14
+ export interface CodeRefactorPlanToolParams {
15
+ targetId?: string;
16
+ operation: string;
17
+ file?: string;
18
+ line?: number;
19
+ character?: number;
20
+ range?: {
21
+ start: { line: number; character: number };
22
+ end: { line: number; character: number };
23
+ };
24
+ newName?: string;
25
+ }
26
+
27
+ export async function executeRefactorPlanTool(
28
+ params: CodeRefactorPlanToolParams,
29
+ ctx: CodeIntelToolExecCtx,
30
+ invokedAs: "code_refactor_plan" = "code_refactor_plan",
31
+ ): Promise<CodeIntelResult> {
32
+ return runPipe(
33
+ params,
34
+ ctx,
35
+ [
36
+ gateSemanticReadiness("code_refactor_plan", {
37
+ fileParam: "file",
38
+ onTimeout: () => ({
39
+ content: renderSemanticReadinessTimeout(invokedAs, 15_000),
40
+ details: {
41
+ type: "search" as const,
42
+ data: {
43
+ confidence: "unavailable" as const,
44
+ scope: null,
45
+ candidateCount: 0,
46
+ omittedCount: 0,
47
+ nextQueries: ["Retry shortly or check `code_health`"],
48
+ },
49
+ },
50
+ }),
51
+ throwOnUnavailable: true,
52
+ }),
53
+ ],
54
+ async (_p, c) => {
55
+ return executeRefactorPlan(
56
+ {
57
+ targetId: params.targetId,
58
+ operation: params.operation,
59
+ file: params.file,
60
+ line: params.line,
61
+ character: params.character,
62
+ range: params.range,
63
+ newName: params.newName,
64
+ },
65
+ {
66
+ cwd: c.cwd,
67
+ session: c.session,
68
+ provider: c.session.getSemanticProvider(),
69
+ },
70
+ );
71
+ },
72
+ );
73
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Markdown renderer for refactor results.
3
+ */
4
+
5
+ import { createEvidenceList, renderEvidenceListDisclosure } from "../../analysis/evidence.ts";
6
+ import { toDisplayPath } from "../../analysis/search/ripgrep.ts";
7
+ import type { RefactorPlan } from "../../session/refactor-plans.ts";
8
+ import type { ApplyResult } from "../refactor-apply/apply.ts";
9
+
10
+ export interface RefactorRenderInput {
11
+ result: ApplyResult;
12
+ operation: string;
13
+ targetDescription: string;
14
+ }
15
+
16
+ /**
17
+ * Render a refactor result as human-readable markdown.
18
+ */
19
+ export function renderRefactorResult(input: RefactorRenderInput): string {
20
+ const { result, operation, targetDescription } = input;
21
+
22
+ if (result.kind === "error") {
23
+ return `**Refactor failed:** ${result.reason}`;
24
+ }
25
+
26
+ return [
27
+ `**Refactor applied:** ${operation} on ${targetDescription}`,
28
+ `- Files changed: ${result.filesChanged}`,
29
+ `- Total edits: ${result.totalEdits}`,
30
+ ].join("\n");
31
+ }
32
+
33
+ /**
34
+ * Render a refactor plan preview.
35
+ */
36
+ export function renderRefactorPlanResult(plan: RefactorPlan, cwd: string): string {
37
+ const lines: string[] = [];
38
+ const changedFiles = collectChangedFiles(plan);
39
+ const fileCount = changedFiles.length;
40
+
41
+ lines.push(`# Refactor Plan: ${plan.operation}`);
42
+ lines.push("");
43
+ lines.push(`**Plan ID:** \`${plan.id}\``);
44
+ lines.push(`**Operation:** \`${plan.operation}\``);
45
+ lines.push(
46
+ `**Target:** \`${toDisplayPath(cwd, plan.targetFile)}\`:${plan.targetLine}:${plan.targetCharacter}`,
47
+ );
48
+ if (plan.newName) {
49
+ lines.push(`**New name:** \`${plan.newName}\``);
50
+ }
51
+ if (plan.destination) {
52
+ lines.push(`**Destination:** \`${plan.destination}\``);
53
+ }
54
+ lines.push(`**Files to change:** ${fileCount} file${fileCount !== 1 ? "s" : ""}`);
55
+ lines.push(`**Total edits:** ${plan.edits.edits.length}`);
56
+ lines.push("");
57
+
58
+ lines.push("## Files");
59
+ for (const [file, count] of changedFiles) {
60
+ lines.push(`- \`${toDisplayPath(cwd, file)}\` — ${count} edit${count !== 1 ? "s" : ""}`);
61
+ }
62
+ lines.push("");
63
+ lines.push("## Preview");
64
+ lines.push("");
65
+ const editEvidence = createEvidenceList({
66
+ key: "refactor.edits",
67
+ items: plan.edits.edits,
68
+ maxResults: 5,
69
+ });
70
+ for (const edit of editEvidence.items) {
71
+ const range = edit.range;
72
+ lines.push(
73
+ `- \`${toDisplayPath(cwd, edit.file)}\` L${range.start.line + 1}:${range.start.character} → L${range.end.line + 1}:${range.end.character}`,
74
+ );
75
+ lines.push(" ```");
76
+ lines.push(` ${edit.newText.slice(0, 80).split("\n").join("\n ")}`);
77
+ lines.push(" ```");
78
+ }
79
+ const disclosure = renderEvidenceListDisclosure(editEvidence);
80
+ if (disclosure) {
81
+ lines.push(disclosure);
82
+ }
83
+ lines.push("");
84
+ lines.push("**This is a preview. No files were changed.**");
85
+ lines.push(`Use code_refactor_apply with planId: "${plan.id}" to apply this refactor.`);
86
+ return lines.join("\n");
87
+ }
88
+
89
+ /**
90
+ * Render a refactor apply result.
91
+ */
92
+ export function renderRefactorApplyResult(applyResult: ApplyResult, plan: RefactorPlan): string {
93
+ if (applyResult.kind === "error") {
94
+ return `**Refactor apply failed:** ${applyResult.reason}`;
95
+ }
96
+ const lines = [
97
+ `**Refactor applied successfully.** Plan: \`${plan.id}\``,
98
+ `- Operation: \`${plan.operation}\``,
99
+ `- Files changed: ${applyResult.filesChanged}`,
100
+ `- Total edits: ${applyResult.totalEdits}`,
101
+ ];
102
+ if (plan.newName) {
103
+ lines.push(`- New name: \`${plan.newName}\``);
104
+ }
105
+ if (plan.destination) {
106
+ lines.push(`- Destination: \`${plan.destination}\``);
107
+ }
108
+ lines.push("", "Verify the changes before continuing with other work.");
109
+ return lines.join("\n");
110
+ }
111
+
112
+ function collectChangedFiles(plan: RefactorPlan): Array<[file: string, count: number]> {
113
+ const counts = new Map<string, number>();
114
+ for (const edit of plan.edits.edits) {
115
+ counts.set(edit.file, (counts.get(edit.file) ?? 0) + 1);
116
+ }
117
+ return [...counts.entries()];
118
+ }
@@ -0,0 +1,363 @@
1
+ /**
2
+ * Refactor plan orchestration use-case.
3
+ *
4
+ * Handles operation normalization, target resolution, provider-based
5
+ * refactor planning, plan storage, and safety validation. Returns a
6
+ * rendered CodeIntelResult with a stored planId for later application.
7
+ *
8
+ * Extracted from execute-refactor-plan.ts as part of the thin-executor
9
+ * normalization.
10
+ */
11
+
12
+ import {
13
+ normalizeRefactorOperation,
14
+ type RefactorOperation,
15
+ type RefactorResult,
16
+ type SemanticProvider,
17
+ type SourceRange,
18
+ } from "@mrclrchtr/supi-code-runtime/api";
19
+ import { toLspPosition } from "@mrclrchtr/supi-lsp/api";
20
+ import { createEvidenceList } from "../../analysis/evidence.ts";
21
+ import { validateEdit } from "../../analysis/refactor/safety.ts";
22
+ import { normalizePath } from "../../analysis/search/ripgrep.ts";
23
+ import {
24
+ computeFileFingerprint,
25
+ generatePlanId,
26
+ type RefactorPlan,
27
+ } from "../../session/refactor-plans.ts";
28
+ import type { WorkspaceCodeIntelligenceSession } from "../../session/session.ts";
29
+ import type { CodeIntelResult } from "../../types/index.ts";
30
+ import { unavailableSearchDetails } from "../infra/error-results.ts";
31
+ import { renderRefactorPlanResult } from "./markdown.ts";
32
+
33
+ type CanonicalRefactorOperation = Exclude<RefactorOperation, "rename">;
34
+
35
+ export interface RefactorPlanInput {
36
+ targetId?: string;
37
+ operation: string;
38
+ file?: string;
39
+ line?: number;
40
+ character?: number;
41
+ range?: {
42
+ start: { line: number; character: number };
43
+ end: { line: number; character: number };
44
+ };
45
+ newName?: string;
46
+ }
47
+
48
+ export interface RefactorPlanDeps {
49
+ cwd: string;
50
+ session: WorkspaceCodeIntelligenceSession;
51
+ /** Semantic provider for refactor planning. */
52
+ provider: SemanticProvider | null;
53
+ }
54
+
55
+ /**
56
+ * Execute the refactor plan use-case.
57
+ *
58
+ * Returns a CodeIntelResult with a stored planId on success, or an
59
+ * error result on invalid input or unavailable provider.
60
+ */
61
+ export async function executeRefactorPlan(
62
+ input: RefactorPlanInput,
63
+ deps: RefactorPlanDeps,
64
+ ): Promise<CodeIntelResult> {
65
+ const normalizedOperation = normalizeRequestedOperation(input.operation);
66
+ if (normalizedOperation.kind === "error") {
67
+ return {
68
+ content: normalizedOperation.message,
69
+ details: unavailableSearchDetails(null, [
70
+ 'Use one of: "rename", "rename_symbol", "extract_function", "extract_variable"',
71
+ ]),
72
+ };
73
+ }
74
+ const operation = normalizedOperation.operation;
75
+
76
+ const target = resolveRefactorTarget(input, operation, deps.session);
77
+ if ("content" in target) return target;
78
+
79
+ const resolvedFile = normalizePath(target.file, deps.cwd);
80
+ const position = toLspPosition(target.line, target.character);
81
+
82
+ const refactorResult = await planRefactorWithProvider(deps.provider, {
83
+ operation,
84
+ file: resolvedFile,
85
+ position,
86
+ range: input.range ? toLspRange(input.range) : undefined,
87
+ newName: input.newName,
88
+ });
89
+
90
+ if (refactorResult.kind === "unavailable") {
91
+ throw new Error(`Refactor unavailable: ${refactorResult.reason}`);
92
+ }
93
+
94
+ if (refactorResult.kind === "ambiguous") {
95
+ return renderAmbiguousRefactorResult(refactorResult);
96
+ }
97
+
98
+ const validation = validateEdit(refactorResult.edits);
99
+ if (!validation.safe) {
100
+ return {
101
+ content: `**Refactor safety check failed:** ${validation.reason}`,
102
+ details: unavailableSearchDetails(null, ["Adjust the target or range and retry"]),
103
+ };
104
+ }
105
+
106
+ const fileFingerprints = collectFileFingerprints(refactorResult.edits.edits);
107
+ const planId = generatePlanId(
108
+ operation,
109
+ resolvedFile,
110
+ target.line,
111
+ target.character,
112
+ input.newName ?? "",
113
+ );
114
+
115
+ const plan: RefactorPlan = {
116
+ id: planId,
117
+ operation,
118
+ newName: input.newName,
119
+ targetFile: resolvedFile,
120
+ targetLine: target.line,
121
+ targetCharacter: target.character,
122
+ edits: refactorResult.edits,
123
+ fileFingerprints,
124
+ createdAt: Date.now(),
125
+ };
126
+ deps.session.storePlan(plan);
127
+
128
+ const editEvidence = createEvidenceList({
129
+ key: "refactor.edits",
130
+ items: refactorResult.edits.edits,
131
+ maxResults: 5,
132
+ }).metadata;
133
+ const content = renderRefactorPlanResult(plan, deps.cwd);
134
+
135
+ return {
136
+ content,
137
+ details: {
138
+ type: "search" as const,
139
+ data: {
140
+ confidence: "semantic" as const,
141
+ scope: null,
142
+ candidateCount: refactorResult.edits.edits.length,
143
+ omittedCount: editEvidence.omittedCount ?? 0,
144
+ evidenceLists: [editEvidence],
145
+ nextQueries: [`Use code_refactor_apply with planId: "${planId}" to apply this refactor`],
146
+ },
147
+ },
148
+ };
149
+ }
150
+
151
+ // ── Validation ────────────────────────────────────────────────────────
152
+
153
+ function normalizeRequestedOperation(
154
+ operation: string,
155
+ ): { kind: "ok"; operation: CanonicalRefactorOperation } | { kind: "error"; message: string } {
156
+ if (
157
+ operation === "rename" ||
158
+ operation === "rename_symbol" ||
159
+ operation === "extract_function" ||
160
+ operation === "extract_variable"
161
+ ) {
162
+ return {
163
+ kind: "ok",
164
+ operation: normalizeRefactorOperation(operation as RefactorOperation),
165
+ };
166
+ }
167
+
168
+ return {
169
+ kind: "error",
170
+ message:
171
+ `**Error:** Unsupported refactor operation: "${operation}". The public \`code_refactor_plan\` tool currently supports: ` +
172
+ '"rename", "rename_symbol", "extract_function", "extract_variable".',
173
+ };
174
+ }
175
+
176
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: target expansion and operation-specific validation are kept together for clear user-facing errors.
177
+ function resolveRefactorTarget(
178
+ input: RefactorPlanInput,
179
+ operation: CanonicalRefactorOperation,
180
+ session: WorkspaceCodeIntelligenceSession,
181
+ ): CodeIntelResult | { file: string; line: number; character: number } {
182
+ const expansion = session.expandTargetId(input);
183
+ if (expansion.kind === "error") {
184
+ return {
185
+ content: expansion.message,
186
+ details: unavailableSearchDetails(null, [
187
+ "Verify the `targetId` is valid and from this session",
188
+ ]),
189
+ };
190
+ }
191
+ if (expansion.kind === "ok") {
192
+ input.file = expansion.file;
193
+ input.line = expansion.line;
194
+ input.character = expansion.character;
195
+
196
+ // Per ADR 0003: rename_symbol is position-strict — LSP rename requires
197
+ // the identifier (name anchor), and a declaration anchor silently yields
198
+ // empty or wrong edits. Refuse before planning.
199
+ if (operation === "rename_symbol" && expansion.entry.anchorKind === "declaration") {
200
+ return {
201
+ content:
202
+ `**Cannot plan rename:** The resolved target fell back to a declaration anchor (the \`export\` keyword or similar), not an identifier (name anchor). LSP \`rename\` requires the identifier. ` +
203
+ `Re-resolve via \`code_resolve\` after the language server has indexed the file, ` +
204
+ `or pass \`file\` + \`line\` + \`character\` anchored directly on the identifier.`,
205
+ details: unavailableSearchDetails(null, [
206
+ "Re-resolve via `code_resolve` when the LSP has indexed the file",
207
+ "Or use `file` + `line` + `character` anchored on the identifier directly",
208
+ ]),
209
+ };
210
+ }
211
+ }
212
+
213
+ if (!input.file) {
214
+ return {
215
+ content:
216
+ "**Error:** Refactor preview requires a `file`. Provide `targetId` (from `code_resolve`) or `file` + `line` + `character`.",
217
+ details: unavailableSearchDetails(null, [
218
+ "Provide `targetId` from `code_resolve` or `file` + `line` + `character`",
219
+ ]),
220
+ };
221
+ }
222
+
223
+ if (isExtractOperation(operation) && input.range) {
224
+ const rangeError = validatePublicRange(input.range);
225
+ if (rangeError) {
226
+ return {
227
+ content: rangeError,
228
+ details: unavailableSearchDetails(null, ["Ensure `range.end` is after `range.start`"]),
229
+ };
230
+ }
231
+ if (input.line == null || input.character == null) {
232
+ input.line = input.range.start.line;
233
+ input.character = input.range.start.character;
234
+ }
235
+ }
236
+
237
+ if (input.line == null || input.character == null) {
238
+ return {
239
+ content:
240
+ "**Error:** Refactor preview requires `line` and `character`. Provide `targetId` (from `code_resolve`) or `file` + `line` + `character`.",
241
+ details: unavailableSearchDetails(null, [
242
+ "Provide `targetId` from `code_resolve` or `file` + `line` + `character`",
243
+ ]),
244
+ };
245
+ }
246
+
247
+ if ((operation === "rename_symbol" || isExtractOperation(operation)) && !input.newName) {
248
+ return {
249
+ content: `**Error:** Refactor preview requires \`newName\` for \`${operation}\`.`,
250
+ details: unavailableSearchDetails(null, [`Provide \`newName\` for \`${operation}\``]),
251
+ };
252
+ }
253
+
254
+ if (isExtractOperation(operation) && !input.range) {
255
+ return {
256
+ content: `**Error:** Refactor preview requires \`range\` for \`${operation}\`.`,
257
+ details: unavailableSearchDetails(null, [`Provide a 1-based \`range\` for \`${operation}\``]),
258
+ };
259
+ }
260
+
261
+ return {
262
+ file: input.file,
263
+ line: input.line,
264
+ character: input.character,
265
+ };
266
+ }
267
+
268
+ // ── Provider interaction ──────────────────────────────────────────────
269
+
270
+ async function planRefactorWithProvider(
271
+ provider: SemanticProvider | null,
272
+ request: {
273
+ operation: CanonicalRefactorOperation;
274
+ file: string;
275
+ position: { line: number; character: number };
276
+ range?: SourceRange;
277
+ newName?: string;
278
+ },
279
+ ): Promise<RefactorResult> {
280
+ if (!provider) {
281
+ return {
282
+ kind: "unavailable",
283
+ reason: "No semantic provider is available.",
284
+ };
285
+ }
286
+
287
+ if (provider.refactor) {
288
+ return provider.refactor(request);
289
+ }
290
+
291
+ if (request.operation === "rename_symbol" && provider.rename && request.newName) {
292
+ return provider.rename(request.file, request.position, request.newName);
293
+ }
294
+
295
+ return {
296
+ kind: "unavailable",
297
+ reason: `The active semantic provider does not support refactor planning for operation "${request.operation}".`,
298
+ };
299
+ }
300
+
301
+ // ── Helpers ───────────────────────────────────────────────────────────
302
+
303
+ function isExtractOperation(operation: CanonicalRefactorOperation): boolean {
304
+ return operation === "extract_function" || operation === "extract_variable";
305
+ }
306
+
307
+ function validatePublicRange(range: {
308
+ start: { line: number; character: number };
309
+ end: { line: number; character: number };
310
+ }): string | null {
311
+ if (
312
+ range.end.line < range.start.line ||
313
+ (range.end.line === range.start.line && range.end.character <= range.start.character)
314
+ ) {
315
+ return "**Error:** Refactor preview requires `range.end` to be after `range.start`.";
316
+ }
317
+ return null;
318
+ }
319
+
320
+ function toLspRange(range: {
321
+ start: { line: number; character: number };
322
+ end: { line: number; character: number };
323
+ }): SourceRange {
324
+ return {
325
+ start: toLspPosition(range.start.line, range.start.character),
326
+ end: toLspPosition(range.end.line, range.end.character),
327
+ };
328
+ }
329
+
330
+ function collectFileFingerprints(
331
+ edits: Array<{ file: string }>,
332
+ ): Array<{ file: string; fingerprint: string }> {
333
+ const seen = new Set<string>();
334
+ const fingerprints: Array<{ file: string; fingerprint: string }> = [];
335
+
336
+ for (const edit of edits) {
337
+ if (seen.has(edit.file)) continue;
338
+ seen.add(edit.file);
339
+ fingerprints.push({
340
+ file: edit.file,
341
+ fingerprint: computeFileFingerprint(edit.file),
342
+ });
343
+ }
344
+
345
+ return fingerprints;
346
+ }
347
+
348
+ function renderAmbiguousRefactorResult(
349
+ refactorResult: Extract<RefactorResult, { kind: "ambiguous" }>,
350
+ ): CodeIntelResult {
351
+ const candidates = refactorResult.candidates
352
+ .map(
353
+ (candidate, index) =>
354
+ `${index + 1}. ${candidate.description} (${candidate.file}:${candidate.line})`,
355
+ )
356
+ .join("\n");
357
+ return {
358
+ content: `**Refactor ambiguous:** Multiple matching targets found. Please disambiguate:\n${candidates}`,
359
+ details: unavailableSearchDetails(null, [
360
+ "Use `targetId` from `code_resolve` or provide precise anchored coordinates",
361
+ ]),
362
+ };
363
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * TUI renderer for code_refactor_plan — renderCall + renderResult.
3
+ */
4
+ import type { Theme } from "@earendil-works/pi-coding-agent";
5
+ import { Text } from "@earendil-works/pi-tui";
6
+ import { type ResultOptios, renderSimpleResult, type ToolResult } from "../../ui/tui/common.ts";
7
+
8
+ /** ── renderCall ────────────────────────────────────────────────── */
9
+
10
+ export function renderRefactorPlanCall(args: unknown, theme: Theme, _context: unknown): Text {
11
+ const params = (args ?? {}) as {
12
+ operation?: string;
13
+ newName?: string;
14
+ file?: string;
15
+ };
16
+
17
+ let content = theme.fg("toolTitle", "code_refactor_plan");
18
+
19
+ if (params.operation) {
20
+ content += ` ${theme.fg("accent", params.operation)}`;
21
+ }
22
+
23
+ if (params.newName) {
24
+ content += ` ${theme.fg("muted", params.newName)}`;
25
+ } else if (params.file) {
26
+ const file = params.file.split("/").pop() ?? params.file;
27
+ content += ` ${theme.fg("muted", file)}`;
28
+ }
29
+
30
+ return new Text(content, 0, 0);
31
+ }
32
+
33
+ /** ── renderResult ──────────────────────────────────────────────── */
34
+
35
+ export function renderRefactorPlanResult(
36
+ result: ToolResult,
37
+ options: ResultOptios,
38
+ theme: Theme,
39
+ _context: unknown,
40
+ ): ReturnType<typeof renderSimpleResult> {
41
+ return renderSimpleResult(result, options, theme, "Planning…");
42
+ }