@mrclrchtr/supi-code-intelligence 1.16.0 → 2.0.0

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