@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,311 @@
1
+ /**
2
+ * Lightweight tool-execution pipeline.
3
+ *
4
+ * Executors compose stages that gate before the tool-specific logic:
5
+ * targetId expansion, scope resolution, param validation, semantic
6
+ * readiness, and capability checks. Each stage returns a
7
+ * {@link PipeOutcome}: `{ kind: "continue" }` to proceed to the next
8
+ * stage, or `{ kind: "error", result }` to short-circuit the pipeline.
9
+ *
10
+ * Usage in an executor:
11
+ *
12
+ * ```ts
13
+ * return runPipe(params, ctx, [
14
+ * expandTargetId((msg) => ({ content: msg, details: ... })),
15
+ * resolveScopeParam((reason) => ({ content: reason, details: ... })),
16
+ * validateParams(myValidator, (msg) => ({ content: msg, details: ... })),
17
+ * gateSemanticReadiness("code_graph"),
18
+ * ], async (p, c) => {
19
+ * // tool-specific execution
20
+ * });
21
+ * ```
22
+ */
23
+
24
+ import { match } from "ts-pattern";
25
+ import { ensureSemanticReadiness } from "../../analysis/readiness.ts";
26
+ import { resolveScope } from "../../analysis/search/ripgrep.ts";
27
+ import { routeFor } from "../../analysis/target/planner.ts";
28
+ import type {
29
+ CodeIntelligenceToolName,
30
+ CodeIntelResult,
31
+ CodeIntelToolExecCtx,
32
+ } from "../../types/index.ts";
33
+ import { searchErrorResult } from "./error-results.ts";
34
+ import { renderSemanticReadinessTimeout } from "./readiness-message.ts";
35
+
36
+ // Re-export for stage consumers
37
+ export type { CodeIntelligenceToolName };
38
+
39
+ // ── Param accessors ──────────────────────────────────────────────────
40
+
41
+ /**
42
+ * Read a param value for runtime inspection in generic pipeline stages
43
+ * and cross-field validation rules.
44
+ *
45
+ * Centralizes the {@link Record}<string, unknown> cast needed when
46
+ * generic code accesses params by dynamic/computed keys. Callers get
47
+ * `unknown` back and must narrow to the expected type.
48
+ */
49
+ export function inspectParam<P>(params: P, key: keyof P & string): unknown {
50
+ return (params as Record<string, unknown>)[key];
51
+ }
52
+
53
+ /**
54
+ * Set a param value in generic pipeline code.
55
+ *
56
+ * Companion to {@link inspectParam} for mutation stages like
57
+ * {@link expandTargetId} and {@link resolveScopeParam}.
58
+ */
59
+ export function setParam<P>(params: P, key: keyof P & string, value: unknown): void {
60
+ (params as Record<string, unknown>)[key] = value;
61
+ }
62
+
63
+ // ── Types ─────────────────────────────────────────────────────────────
64
+
65
+ /**
66
+ * Outcome of a single pipeline stage.
67
+ *
68
+ * `continue` — proceed to the next stage (or the execute function).
69
+ * `error` — short-circuit the pipeline with the given result.
70
+ */
71
+ export type PipeOutcome = { kind: "continue" } | { kind: "error"; result: CodeIntelResult };
72
+
73
+ /**
74
+ * A pipeline stage: receives (possibly mutated) params and the execution
75
+ * context. Returns {@link PipeOutcome} — `{ kind: "continue" }` to
76
+ * advance to the next stage, or `{ kind: "error", result }` to
77
+ * short-circuit immediately.
78
+ */
79
+ export type PipeStage<P> = (
80
+ params: P,
81
+ ctx: CodeIntelToolExecCtx,
82
+ ) => Promise<PipeOutcome> | PipeOutcome;
83
+
84
+ // ── Orchestrator ──────────────────────────────────────────────────────
85
+
86
+ /**
87
+ * Run a sequence of gating stages then the tool-specific execute function.
88
+ *
89
+ * Stages are executed in order. The first stage that returns
90
+ * `{ kind: "error" }` short-circuits the pipeline and its result is
91
+ * returned to the caller. If every stage returns `{ kind: "continue" }`,
92
+ * `execute(params, ctx)` runs.
93
+ */
94
+ export async function runPipe<P>(
95
+ params: P,
96
+ ctx: CodeIntelToolExecCtx,
97
+ stages: PipeStage<P>[],
98
+ execute: (params: P, ctx: CodeIntelToolExecCtx) => Promise<CodeIntelResult>,
99
+ ): Promise<CodeIntelResult> {
100
+ for (const stage of stages) {
101
+ const outcome = await stage(params, ctx);
102
+ if (outcome.kind === "error") return outcome.result;
103
+ }
104
+ return execute(params, ctx);
105
+ }
106
+
107
+ // ── Stage factories ───────────────────────────────────────────────────
108
+
109
+ /** Minimum parameter shape needed by `expandTargetId`. */
110
+ export interface HasTargetParams {
111
+ targetId?: string;
112
+ file?: string;
113
+ line?: number;
114
+ character?: number;
115
+ /** Set by expandTargetId stage — resolved name from the stored target entry. */
116
+ _expandedName?: string | null;
117
+ /** Set by expandTargetId stage — anchor kind from the stored target entry. */
118
+ _expandedAnchorKind?: string | null;
119
+ }
120
+
121
+ /**
122
+ * Expand an optional `targetId` into file/line/character params.
123
+ *
124
+ * On success the stage mutates `params.file`, `params.line`, and
125
+ * `params.character` from the stored entry. On error it calls
126
+ * `onError(message)` to build a tool-appropriate error result.
127
+ *
128
+ * A missing/null targetId is not an error — the stage passes through
129
+ * (no expansion, params unchanged).
130
+ */
131
+ export function expandTargetId<P extends HasTargetParams>(
132
+ onError: (message: string) => CodeIntelResult,
133
+ ): PipeStage<P> {
134
+ return (params, ctx) => {
135
+ const expansion = ctx.session.expandTargetId(params);
136
+ if (expansion.kind === "error") return { kind: "error", result: onError(expansion.message) };
137
+ if (expansion.kind === "ok") {
138
+ params.file = expansion.file;
139
+ params.line = expansion.line;
140
+ params.character = expansion.character;
141
+ params._expandedName = expansion.targetName;
142
+ params._expandedAnchorKind = expansion.entry.anchorKind;
143
+ }
144
+ return { kind: "continue" };
145
+ };
146
+ }
147
+
148
+ /** Minimum parameter shape needed by `resolveScope`. */
149
+ export interface HasScopeParam {
150
+ scope?: string;
151
+ }
152
+
153
+ /**
154
+ * Resolve the `scope` parameter to an absolute path.
155
+ *
156
+ * Mutates `params.scope` to the resolved absolute path. An undefined
157
+ * scope passes through unchanged. On resolution error calls
158
+ * `onError(reason)`.
159
+ *
160
+ * @param paramName — defaults to `"scope"`.
161
+ */
162
+ export function resolveScopeParam<P extends HasScopeParam>(
163
+ onError: (reason: string) => CodeIntelResult,
164
+ paramName: keyof P & string = "scope" as keyof P & string,
165
+ ): PipeStage<P> {
166
+ return (params, ctx) => {
167
+ const raw = inspectParam(params, paramName) as string | undefined;
168
+ if (raw === undefined) return { kind: "continue" };
169
+
170
+ const result = resolveScope(raw, ctx.cwd);
171
+ if (result.kind === "error") return { kind: "error", result: onError(result.reason) };
172
+
173
+ setParam(params, paramName, result.path);
174
+ return { kind: "continue" };
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Apply cross-field validation rules after TypeBox schema validation.
180
+ *
181
+ * pi already validates structural types, required fields, and enum
182
+ * values against the TypeBox schema in {@link ./schemas.ts} before
183
+ * calling executors. This stage handles only cross-field constraints
184
+ * that TypeBox cannot express (pairing, mutual exclusion, filesystem
185
+ * checks, semantic consistency).
186
+ *
187
+ * The validator receives `(params, cwd)` and returns `null` when
188
+ * valid, or an error message string. The stage calls `onError(message)`
189
+ * to build a tool-appropriate error result.
190
+ */
191
+ export function validateParams<P>(
192
+ validator: (params: P, cwd: string) => string | null,
193
+ onError: (message: string) => CodeIntelResult,
194
+ ): PipeStage<P> {
195
+ return (params, ctx) => {
196
+ const message = validator(params, ctx.cwd);
197
+ if (message) return { kind: "error", result: onError(message) };
198
+ return { kind: "continue" };
199
+ };
200
+ }
201
+
202
+ /** Options for {@link gateSemanticReadiness}. */
203
+ export interface SemanticGateOptions {
204
+ /**
205
+ * Optional param key for the file path used for file-scoped readiness.
206
+ * When provided, readiness waits for the specific file. Defaults to
207
+ * workspace-scoped readiness.
208
+ */
209
+ fileParam?: string;
210
+
211
+ /** Build a result when readiness times out. */
212
+ onTimeout?: (toolName: string, timeoutMs: number) => CodeIntelResult;
213
+
214
+ /** When true, throw (whole-tool unavailable) instead of returning an error result. */
215
+ throwOnUnavailable?: boolean;
216
+
217
+ /**
218
+ * When true, let "unavailable" pass through to the execute function
219
+ * instead of returning an error. Use when the use-case layer handles
220
+ * missing providers with explicit unavailable-section notes.
221
+ * `throwOnUnavailable` takes precedence when both are true.
222
+ */
223
+ passThroughOnUnavailable?: boolean;
224
+
225
+ /** Build a result when readiness is permanently unavailable. */
226
+ onUnavailable?: (reason: string) => CodeIntelResult;
227
+ }
228
+
229
+ /**
230
+ * Gate execution behind semantic (LSP) readiness.
231
+ *
232
+ * Waits up to the default timeout for the LSP to be ready for the
233
+ * workspace (or a specific file). On timeout, calls `onTimeout` if
234
+ * provided, otherwise builds a default timeout result. When
235
+ * `throwOnUnavailable` is true and the provider is permanently
236
+ * unavailable, the stage throws so pi marks the call as an error.
237
+ */
238
+ export function gateSemanticReadiness<P>(
239
+ toolName: CodeIntelligenceToolName,
240
+ opts: SemanticGateOptions = {},
241
+ ): PipeStage<P> {
242
+ return async (params, ctx) => {
243
+ // opts.fileParam is a runtime string from an options bag, not a
244
+ // compile-time keyof P — keep the cast local instead of routing
245
+ // through inspectParam which requires keyof P & string.
246
+ const file = opts.fileParam
247
+ ? ((params as Record<string, unknown>)[opts.fileParam] as string | undefined)
248
+ : undefined;
249
+
250
+ const scope = file ? { kind: "file" as const, file } : { kind: "workspace" as const };
251
+ const readiness = await ensureSemanticReadiness(ctx.cwd, scope);
252
+
253
+ if (readiness.kind === "ready") return { kind: "continue" };
254
+
255
+ return handleNonReadyReadiness(readiness, toolName, opts);
256
+ };
257
+ }
258
+
259
+ /** Handle timeout or unavailable readiness, applying tool-specific callbacks. */
260
+ function handleNonReadyReadiness(
261
+ readiness: { kind: "timeout" } | { kind: "unavailable"; reason: string },
262
+ toolName: CodeIntelligenceToolName,
263
+ opts: SemanticGateOptions,
264
+ ): PipeOutcome {
265
+ return match(readiness)
266
+ .with({ kind: "timeout" }, () => {
267
+ if (opts.onTimeout)
268
+ return { kind: "error" as const, result: opts.onTimeout(toolName, 15_000) };
269
+ return defaultTimeoutOutcome(toolName);
270
+ })
271
+ .with({ kind: "unavailable" }, ({ reason }) => {
272
+ if (opts.throwOnUnavailable) throw new Error(reason);
273
+ if (opts.passThroughOnUnavailable) return { kind: "continue" as const };
274
+ if (opts.onUnavailable) return { kind: "error" as const, result: opts.onUnavailable(reason) };
275
+ return defaultUnavailableOutcome(reason);
276
+ })
277
+ .exhaustive() as PipeOutcome;
278
+ }
279
+
280
+ function defaultTimeoutOutcome(toolName: string): PipeOutcome {
281
+ return {
282
+ kind: "error",
283
+ result: searchErrorResult(renderSemanticReadinessTimeout(toolName, 15_000)),
284
+ };
285
+ }
286
+
287
+ function defaultUnavailableOutcome(reason: string): PipeOutcome {
288
+ return { kind: "error", result: searchErrorResult(`**Error:** ${reason}`) };
289
+ }
290
+
291
+ /**
292
+ * Gate execution behind capability availability.
293
+ *
294
+ * Calls `routeFor(cwd, toolName)`. When `preferred === "unavailable"`
295
+ * the stage throws (whole-tool capability-unavailable) so pi marks the
296
+ * call as an error. Partial per-relation unavailability is NOT gated
297
+ * here — executors surface that through best-effort notes.
298
+ *
299
+ * This is a sync stage — no async work.
300
+ */
301
+ export function gateCapability<P>(toolName: CodeIntelligenceToolName): PipeStage<P> {
302
+ return (_params, ctx) => {
303
+ const route = routeFor(ctx.cwd, toolName);
304
+ if (route.preferred === "unavailable") {
305
+ throw new Error(
306
+ `No analysis provider is available for this workspace. Check \`code_health\` for LSP and tree-sitter status.`,
307
+ );
308
+ }
309
+ return { kind: "continue" };
310
+ };
311
+ }
@@ -0,0 +1,21 @@
1
+ import type { AgentToolUpdateCallback } from "@earendil-works/pi-coding-agent";
2
+
3
+ /**
4
+ * Emit a coarse progress beat to the agent runtime via `onUpdate`.
5
+ *
6
+ * Long-running code-intelligence executors (code_find ripgrep, code_impact
7
+ * sweeps, code_graph `relations:["all"]`, code_health `refresh`, and
8
+ * code_refactor_plan LSP requests) call this at a few natural checkpoints —
9
+ * a start beat plus a couple of progress beats — so the UI can show the tool
10
+ * is working. Beats must stay coarse: not chatty.
11
+ *
12
+ * Safe no-op when `onUpdate` is absent (the common case for direct executor
13
+ * calls and tests). The `details.progress` marker mirrors the beat text for
14
+ * UI rendering; the final tool result carries the real structured `details`.
15
+ */
16
+ export function emitToolProgress(
17
+ onUpdate: AgentToolUpdateCallback | undefined,
18
+ text: string,
19
+ ): void {
20
+ onUpdate?.({ content: [{ type: "text", text }], details: { progress: text } });
21
+ }
@@ -0,0 +1,5 @@
1
+ /** Render user-facing semantic readiness messages for tool executors. */
2
+ export function renderSemanticReadinessTimeout(toolName: string, timeoutMs: number): string {
3
+ const seconds = Math.max(1, Math.round(timeoutMs / 1000));
4
+ return `**Error:** Semantic analysis for \`${toolName}\` is still warming for this workspace (LSP indexing/startup not finished after ${seconds}s). Try again shortly or check \`code_health\`.`;
5
+ }
@@ -0,0 +1,49 @@
1
+ import {
2
+ DEFAULT_MAX_BYTES,
3
+ DEFAULT_MAX_LINES,
4
+ formatSize,
5
+ truncateHead,
6
+ } from "@earendil-works/pi-coding-agent";
7
+
8
+ /** Options for {@link truncateToolContent}. */
9
+ export interface TruncateToolContentOptions {
10
+ /** Max lines (defaults to pi's {@link DEFAULT_MAX_LINES}). */
11
+ maxLines?: number;
12
+ /** Max bytes (defaults to pi's {@link DEFAULT_MAX_BYTES}). */
13
+ maxBytes?: number;
14
+ }
15
+
16
+ /** Result of truncating a tool's model-facing content. */
17
+ export interface TruncatedToolContent {
18
+ /** Content, with a `[truncated: ...]` notice appended when truncation occurred. */
19
+ text: string;
20
+ /** Whether truncation occurred. */
21
+ truncated: boolean;
22
+ }
23
+
24
+ /**
25
+ * Head-truncate model-facing tool content to pi defaults and append a
26
+ * `[truncated: kept N of M lines (X of Y)]` notice when truncation occurs.
27
+ *
28
+ * Used by the code-intelligence tool adapter so every tool emits uniformly
29
+ * bounded output regardless of which executor produced it. Short content is
30
+ * returned unchanged (`truncated: false`, no notice). `details` are never
31
+ * truncated — only the markdown `content` string passes through here.
32
+ *
33
+ * Head truncation (not tail) is correct for code-intelligence output: results
34
+ * are ranked/structured and the most relevant entries come first.
35
+ */
36
+ export function truncateToolContent(
37
+ content: string,
38
+ options: TruncateToolContentOptions = {},
39
+ ): TruncatedToolContent {
40
+ const result = truncateHead(content, {
41
+ maxLines: options.maxLines ?? DEFAULT_MAX_LINES,
42
+ maxBytes: options.maxBytes ?? DEFAULT_MAX_BYTES,
43
+ });
44
+ if (!result.truncated) {
45
+ return { text: content, truncated: false };
46
+ }
47
+ const notice = `\n[truncated: kept ${result.outputLines} of ${result.totalLines} lines (${formatSize(result.outputBytes)} of ${formatSize(result.totalBytes)})]\n`;
48
+ return { text: `${result.content}${notice}`, truncated: true };
49
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Tool executor for code_inspect — factual point inspection.
3
+ */
4
+
5
+ import type { CodeIntelResult, CodeIntelToolExecCtx } from "../../types/index.ts";
6
+ import { focusedToolRules } from "../infra/cross-field.ts";
7
+ import { unavailableInspectDetails } from "../infra/error-results.ts";
8
+ import { gateSemanticReadiness, runPipe, validateParams } from "../infra/pipeline.ts";
9
+ import { renderSemanticReadinessTimeout } from "../infra/readiness-message.ts";
10
+ import { executeInspect } from "./orchestrate.ts";
11
+
12
+ export interface CodeInspectToolParams {
13
+ file: string;
14
+ line: number;
15
+ character: number;
16
+ maxResults?: number;
17
+ }
18
+
19
+ export async function executeInspectTool(
20
+ params: Partial<CodeInspectToolParams>,
21
+ ctx: CodeIntelToolExecCtx,
22
+ ): Promise<CodeIntelResult> {
23
+ return runPipe(
24
+ params,
25
+ ctx,
26
+ [
27
+ validateParams(focusedToolRules(), (msg) => ({
28
+ content: msg,
29
+ details: unavailableInspectDetails("validation error", [
30
+ "Provide `file`, `line`, and `character` for point inspection",
31
+ ]),
32
+ })),
33
+ gateSemanticReadiness("code_inspect", {
34
+ fileParam: "file",
35
+ onTimeout: () => ({
36
+ content: renderSemanticReadinessTimeout("code_inspect", 15_000),
37
+ details: unavailableInspectDetails("timeout", ["Retry shortly or check `code_health`"]),
38
+ }),
39
+ // Unavailable LSP passes through — the use-case layer renders
40
+ // explicit unavailable-section notes.
41
+ passThroughOnUnavailable: true,
42
+ }),
43
+ ],
44
+ async (p, c) => {
45
+ if (!p.file || p.line == null || p.character == null) {
46
+ return {
47
+ content: "**Error:** `code_inspect` requires `file`, `line`, and `character`.",
48
+ details: unavailableInspectDetails("missing coordinates", [
49
+ "Provide `file`, `line`, and `character` for point inspection",
50
+ ]),
51
+ };
52
+ }
53
+
54
+ const providerState = c.session.getProviders();
55
+ const provider = providerState.kind === "ready" ? providerState.provider : null;
56
+ const lspService =
57
+ providerState.kind === "ready"
58
+ ? providerState.lspService
59
+ : { kind: "unavailable" as const, reason: "No provider" };
60
+
61
+ // Let unavailable pass through — the use-case layer handles missing
62
+ // providers with explicit unavailable-section notes.
63
+ const result = await executeInspect(
64
+ {
65
+ file: p.file,
66
+ line: p.line,
67
+ character: p.character,
68
+ maxResults: p.maxResults,
69
+ },
70
+ { provider, cwd: c.cwd, lspService },
71
+ );
72
+
73
+ return { content: result.content, details: { type: "inspect", data: result.details } };
74
+ },
75
+ );
76
+ }
@@ -0,0 +1,169 @@
1
+ import type { ConfidenceMode } from "@mrclrchtr/supi-code-runtime/api";
2
+ import {
3
+ type EvidenceListMetadata,
4
+ renderEvidenceListMetadataDisclosure,
5
+ } from "../../analysis/evidence.ts";
6
+
7
+ export interface InspectRenderInput {
8
+ relPath: string;
9
+ line: number;
10
+ character: number;
11
+ confidence: ConfidenceMode;
12
+ node: {
13
+ type: string;
14
+ text: string;
15
+ startLine: number;
16
+ startCharacter: number;
17
+ ancestry?: Array<
18
+ | string
19
+ | {
20
+ type: string;
21
+ startLine: number;
22
+ startCharacter: number;
23
+ endLine?: number;
24
+ endCharacter?: number;
25
+ }
26
+ >;
27
+ } | null;
28
+ enclosingSymbol: {
29
+ name: string;
30
+ kind: string;
31
+ startLine: number;
32
+ endLine: number;
33
+ } | null;
34
+ hover: string | null;
35
+ definitions: Array<{ file: string; line: number; character: number }>;
36
+ diagnostics: Array<{ line: number; severity: number | string; message: string }>;
37
+ codeActions: Array<{ title: string; kind?: string }>;
38
+ codeActionEvidence?: EvidenceListMetadata;
39
+ unavailableSections: string[];
40
+ }
41
+
42
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: inspect rendering keeps section ordering and unavailable-state handling explicit
43
+ export function renderInspectResult(input: InspectRenderInput): string {
44
+ const lines: string[] = [];
45
+ lines.push(`# Inspect: ${input.relPath}:${input.line}:${input.character}`);
46
+ lines.push("");
47
+ lines.push(`**Confidence:** \`${input.confidence}\``);
48
+ lines.push("");
49
+
50
+ if (input.node) {
51
+ lines.push("## Node");
52
+ lines.push(
53
+ `- Type: \`${input.node.type}\` at ${input.relPath}:${input.node.startLine}:${input.node.startCharacter}`,
54
+ );
55
+ if (input.node.text) {
56
+ lines.push("```ts");
57
+ lines.push(input.node.text);
58
+ lines.push("```");
59
+ }
60
+ const ancestry = normalizeAncestry(input.node.ancestry ?? []);
61
+ if (ancestry.length > 0) {
62
+ lines.push("");
63
+ lines.push("### Ancestry");
64
+ for (const ancestor of ancestry) {
65
+ lines.push(`- \`${ancestor}\``);
66
+ }
67
+ }
68
+ lines.push("");
69
+ }
70
+
71
+ if (input.enclosingSymbol) {
72
+ lines.push("## Enclosing symbol");
73
+ lines.push(
74
+ `- \`${input.enclosingSymbol.name}\` (${input.enclosingSymbol.kind}) L${input.enclosingSymbol.startLine}–${input.enclosingSymbol.endLine}`,
75
+ );
76
+ lines.push("");
77
+ }
78
+
79
+ if (input.hover) {
80
+ lines.push("## Hover");
81
+ lines.push(input.hover);
82
+ lines.push("");
83
+ }
84
+
85
+ if (input.definitions.length > 0) {
86
+ lines.push("## Definition");
87
+ for (const def of input.definitions) {
88
+ lines.push(`- \`${def.file}:${def.line}:${def.character}\``);
89
+ }
90
+ lines.push("");
91
+ }
92
+
93
+ if (input.diagnostics.length > 0) {
94
+ lines.push("## Diagnostics");
95
+ for (const diagnostic of input.diagnostics) {
96
+ lines.push(
97
+ `- L${diagnostic.line}: ${formatSeverity(diagnostic.severity)}: ${diagnostic.message}`,
98
+ );
99
+ }
100
+ lines.push("");
101
+ }
102
+
103
+ if (input.codeActions.length > 0) {
104
+ lines.push("## Code Actions");
105
+ for (const action of input.codeActions) {
106
+ const kind = action.kind ? ` (${action.kind})` : "";
107
+ lines.push(`- "${action.title}"${kind}`);
108
+ }
109
+ if (input.codeActionEvidence) {
110
+ const disclosure = renderEvidenceListMetadataDisclosure(input.codeActionEvidence);
111
+ if (disclosure) {
112
+ lines.push(disclosure);
113
+ }
114
+ }
115
+ lines.push("");
116
+ }
117
+
118
+ if (input.unavailableSections.length > 0) {
119
+ lines.push("## Unavailable");
120
+ for (const section of input.unavailableSections) {
121
+ lines.push(`- ${section}`);
122
+ }
123
+ lines.push("");
124
+ }
125
+
126
+ return lines.join("\n");
127
+ }
128
+
129
+ function normalizeAncestry(
130
+ ancestry: Array<
131
+ | string
132
+ | {
133
+ type: string;
134
+ startLine: number;
135
+ startCharacter: number;
136
+ endLine?: number;
137
+ endCharacter?: number;
138
+ }
139
+ >,
140
+ ): string[] {
141
+ return ancestry.map((entry) => {
142
+ if (typeof entry === "string") return entry;
143
+ const start = `L${entry.startLine}:${entry.startCharacter}`;
144
+ const end =
145
+ entry.endLine != null && entry.endCharacter != null
146
+ ? `–L${entry.endLine}:${entry.endCharacter}`
147
+ : "";
148
+ return `${entry.type} ${start}${end}`;
149
+ });
150
+ }
151
+
152
+ function formatSeverity(severity: number | string): string {
153
+ if (typeof severity === "string") {
154
+ return severity.charAt(0).toUpperCase() + severity.slice(1);
155
+ }
156
+
157
+ switch (severity) {
158
+ case 1:
159
+ return "Error";
160
+ case 2:
161
+ return "Warning";
162
+ case 3:
163
+ return "Info";
164
+ case 4:
165
+ return "Hint";
166
+ default:
167
+ return "Diagnostic";
168
+ }
169
+ }