@mrclrchtr/supi-code-intelligence 1.16.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/README.md +373 -63
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  9. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  10. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  11. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  12. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  13. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  14. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  15. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  16. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  17. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  18. package/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  19. package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  20. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  21. package/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  22. package/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  23. package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  24. package/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  25. package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  26. package/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  27. package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  28. package/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  29. package/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  30. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  31. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  32. package/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  33. package/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  34. package/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/README.md +44 -56
  36. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  37. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  40. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  42. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  45. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  46. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  47. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  50. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  51. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  52. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  53. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  54. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  55. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  56. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  57. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  59. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  60. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  61. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  62. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  63. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  64. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  65. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  66. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  67. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  68. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  69. package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -31
  70. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +27 -0
  71. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +5 -0
  72. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +246 -1
  73. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +4 -0
  74. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +3 -0
  75. package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +4 -2
  76. package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +102 -0
  77. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +59 -0
  78. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +4 -0
  79. package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +11 -0
  80. package/node_modules/@mrclrchtr/supi-lsp/src/manager/capability-index.ts +1 -1
  81. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +2 -1
  82. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +115 -26
  83. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +177 -134
  84. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +214 -0
  85. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +320 -0
  86. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +26 -5
  87. package/node_modules/@mrclrchtr/supi-lsp/src/session/service-registry.ts +81 -4
  88. package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +2 -0
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +18 -37
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/LICENSE +21 -0
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/README.md +265 -0
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs +4661 -0
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs.map +7 -0
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js +4605 -0
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js.map +7 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +57 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +100 -0
  132. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs +4063 -0
  133. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs.map +7 -0
  134. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts +1025 -0
  135. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts.map +58 -0
  136. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1025 -0
  137. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +58 -0
  138. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js +4007 -0
  139. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js.map +7 -0
  140. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  141. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +55 -0
  142. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -12
  143. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +29 -0
  144. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +28 -0
  145. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -0
  146. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +14 -2
  147. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +157 -0
  148. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +8 -1
  149. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +86 -0
  150. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +35 -16
  151. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +1 -0
  152. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +10 -0
  153. package/package.json +14 -9
  154. package/src/{model.ts → analysis/architecture/discovery.ts} +15 -72
  155. package/src/analysis/architecture/model.ts +76 -0
  156. package/src/analysis/brief/directory.ts +324 -0
  157. package/src/analysis/brief/enrich.ts +157 -0
  158. package/src/analysis/brief/file.ts +84 -0
  159. package/src/analysis/brief/inventory.ts +177 -0
  160. package/src/analysis/brief/main.ts +176 -0
  161. package/src/analysis/brief/models.ts +75 -0
  162. package/src/{brief.ts → analysis/brief/public-brief.ts} +21 -26
  163. package/src/analysis/brief/summarize.ts +208 -0
  164. package/src/analysis/brief/types.ts +27 -0
  165. package/src/{use-case/generate-brief.ts → analysis/brief/use-case.ts} +67 -144
  166. package/src/analysis/coverage/coverage-warnings.ts +224 -0
  167. package/src/analysis/evidence.ts +91 -0
  168. package/src/{semantic-action-helpers.ts → analysis/helpers.ts} +4 -4
  169. package/src/analysis/provider.ts +186 -0
  170. package/src/analysis/read-next.ts +126 -0
  171. package/src/analysis/readiness.ts +73 -0
  172. package/src/{refactor → analysis/refactor}/safety.ts +1 -1
  173. package/src/{use-case/support/semantic-references.ts → analysis/references/semantic-refs.ts} +58 -26
  174. package/src/analysis/search/pattern.ts +345 -0
  175. package/src/analysis/search/ripgrep.ts +473 -0
  176. package/src/{git-context.ts → analysis/signals/git.ts} +20 -7
  177. package/src/{prioritization-signals.ts → analysis/signals/project.ts} +33 -19
  178. package/src/analysis/target/anchored.ts +349 -0
  179. package/src/analysis/target/bridge.ts +152 -0
  180. package/src/analysis/target/file-resolution.ts +125 -0
  181. package/src/{targeting/resolve-file.ts → analysis/target/file.ts} +40 -20
  182. package/src/{planner → analysis/target}/planner.ts +30 -20
  183. package/src/{targeting → analysis/target}/query.ts +17 -3
  184. package/src/analysis/target/resolve-common.ts +115 -0
  185. package/src/analysis/target/service.ts +229 -0
  186. package/src/analysis/target/symbol.ts +196 -0
  187. package/src/{targeting → analysis/target}/types.ts +17 -1
  188. package/src/analysis/tests/likely-tests.ts +174 -0
  189. package/src/analysis/tests/test-discovery.ts +540 -0
  190. package/src/analysis/tests/vitest.ts +87 -0
  191. package/src/api.ts +34 -41
  192. package/src/app/app.ts +125 -0
  193. package/src/app/manager.ts +65 -0
  194. package/src/extension.ts +132 -1
  195. package/src/index.ts +1 -57
  196. package/src/session/refactor-plans.ts +82 -0
  197. package/src/session/session.ts +300 -0
  198. package/src/session/target-store.ts +293 -0
  199. package/src/substrate/lsp/diagnostic-injection.ts +218 -0
  200. package/src/substrate/lsp/lifecycle.ts +66 -0
  201. package/src/substrate/lsp/overrides.ts +132 -0
  202. package/src/substrate/lsp/recovery.ts +55 -0
  203. package/src/substrate/lsp/settings.ts +286 -0
  204. package/src/substrate/lsp/state.ts +46 -0
  205. package/src/substrate/lsp/utils.ts +17 -0
  206. package/src/substrate/tree-sitter/lifecycle.ts +52 -0
  207. package/src/tool/find/execute.ts +118 -0
  208. package/src/{presentation/markdown/pattern.ts → tool/find/markdown.ts} +102 -53
  209. package/src/{use-case/generate-pattern.ts → tool/find/orchestrate.ts} +67 -33
  210. package/src/tool/find/semantic-search.ts +114 -0
  211. package/src/tool/find/tui.ts +39 -0
  212. package/src/tool/graph/callees.ts +87 -0
  213. package/src/tool/graph/calls-md.ts +54 -0
  214. package/src/tool/graph/collect-relation.ts +371 -0
  215. package/src/tool/graph/execute.ts +95 -0
  216. package/src/tool/graph/implementations-md.ts +79 -0
  217. package/src/tool/graph/implementations.ts +76 -0
  218. package/src/tool/graph/markdown-base.ts +243 -0
  219. package/src/tool/graph/orchestrate.ts +285 -0
  220. package/src/tool/graph/references-md.ts +34 -0
  221. package/src/tool/graph/references.ts +81 -0
  222. package/src/tool/graph/tui.ts +120 -0
  223. package/src/tool/graph/types.ts +97 -0
  224. package/src/tool/guidance.ts +96 -49
  225. package/src/tool/health/execute.ts +76 -0
  226. package/src/tool/health/markdown.ts +280 -0
  227. package/src/tool/health/orchestrate.ts +159 -0
  228. package/src/tool/health/sections/diagnostics.ts +182 -0
  229. package/src/tool/health/sections/recovery.ts +89 -0
  230. package/src/tool/health/sections/signals.ts +89 -0
  231. package/src/tool/health/tui.ts +137 -0
  232. package/src/tool/impact/analysis.ts +247 -0
  233. package/src/tool/impact/change-set-impact.ts +151 -0
  234. package/src/tool/impact/execute.ts +98 -0
  235. package/src/tool/impact/file-level-impact.ts +81 -0
  236. package/src/tool/impact/markdown.ts +283 -0
  237. package/src/tool/impact/orchestrate.ts +97 -0
  238. package/src/tool/impact/result.ts +21 -0
  239. package/src/tool/impact/single-impact.ts +89 -0
  240. package/src/tool/impact/tui.ts +39 -0
  241. package/src/tool/impact/types.ts +34 -0
  242. package/src/tool/infra/cross-field.ts +335 -0
  243. package/src/tool/infra/error-results.ts +199 -0
  244. package/src/tool/infra/pipeline.ts +311 -0
  245. package/src/tool/infra/progress.ts +21 -0
  246. package/src/tool/infra/readiness-message.ts +5 -0
  247. package/src/tool/infra/truncate.ts +49 -0
  248. package/src/tool/inspect/execute.ts +76 -0
  249. package/src/tool/inspect/markdown.ts +169 -0
  250. package/src/tool/inspect/orchestrate.ts +156 -0
  251. package/src/tool/inspect/tui.ts +36 -0
  252. package/src/tool/orientation/deps.ts +63 -0
  253. package/src/tool/orientation/execute.ts +50 -0
  254. package/src/tool/orientation/markdown.ts +35 -0
  255. package/src/tool/orientation/mode.ts +88 -0
  256. package/src/tool/orientation/orchestrate.ts +478 -0
  257. package/src/tool/orientation/precise-target.ts +257 -0
  258. package/src/tool/orientation/tui.ts +131 -0
  259. package/src/{refactor/apply-workspace-edit.ts → tool/refactor-apply/apply.ts} +39 -16
  260. package/src/tool/refactor-apply/execute.ts +20 -0
  261. package/src/tool/refactor-apply/markdown.ts +118 -0
  262. package/src/tool/refactor-apply/orchestrate.ts +89 -0
  263. package/src/tool/refactor-apply/tui.ts +51 -0
  264. package/src/tool/refactor-plan/execute.ts +73 -0
  265. package/src/tool/refactor-plan/markdown.ts +118 -0
  266. package/src/tool/refactor-plan/orchestrate.ts +363 -0
  267. package/src/tool/refactor-plan/tui.ts +42 -0
  268. package/src/tool/register.ts +123 -0
  269. package/src/tool/resolve/execute.ts +82 -0
  270. package/src/tool/resolve/markdown.ts +150 -0
  271. package/src/tool/resolve/orchestrate.ts +134 -0
  272. package/src/tool/resolve/tui.ts +40 -0
  273. package/src/tool/schemas.ts +337 -0
  274. package/src/tool/specs.ts +257 -0
  275. package/src/types/details.ts +188 -0
  276. package/src/types/execution.ts +60 -0
  277. package/src/types/index.ts +28 -0
  278. package/src/{intent/types.ts → types/tool-names.ts} +15 -14
  279. package/src/ui/footer.ts +52 -0
  280. package/src/ui/markdown/brief.ts +218 -0
  281. package/src/ui/markdown/gather.ts +177 -0
  282. package/src/{use-case/build-overview.ts → ui/markdown/overview-data.ts} +2 -2
  283. package/src/{presentation → ui}/markdown/overview.ts +2 -2
  284. package/src/ui/markdown/types.ts +80 -0
  285. package/{node_modules/@mrclrchtr/supi-lsp/src/ui/renderer.ts → src/ui/message-renderer.ts} +11 -10
  286. package/src/ui/status-command.ts +260 -0
  287. package/src/ui/status-overlay.ts +500 -0
  288. package/src/ui/tui/common.ts +220 -0
  289. package/src/ui/tui/index.ts +37 -0
  290. package/node_modules/@mrclrchtr/supi-lsp/src/extension.ts +0 -1
  291. package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +0 -373
  292. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/diagnostic-injection.ts +0 -182
  293. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/session-lifecycle.ts +0 -149
  294. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/status-command.ts +0 -38
  295. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/workspace-recovery.ts +0 -92
  296. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +0 -37
  297. package/node_modules/@mrclrchtr/supi-lsp/src/session/lsp-state.ts +0 -93
  298. package/node_modules/@mrclrchtr/supi-lsp/src/session/settings-registration.ts +0 -296
  299. package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +0 -75
  300. package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +0 -69
  301. package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +0 -27
  302. package/node_modules/@mrclrchtr/supi-lsp/src/tool/overrides.ts +0 -204
  303. package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +0 -69
  304. package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +0 -399
  305. package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +0 -248
  306. package/node_modules/@mrclrchtr/supi-lsp/src/ui/ui.ts +0 -360
  307. package/node_modules/@mrclrchtr/supi-lsp/src/workspace-change.ts +0 -40
  308. package/node_modules/@mrclrchtr/supi-tree-sitter/src/extension.ts +0 -1
  309. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/formatting.ts +0 -104
  310. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +0 -35
  311. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/handlers.ts +0 -196
  312. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/register-tools.ts +0 -107
  313. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/tool-specs.ts +0 -117
  314. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +0 -47
  315. package/src/brief-focused.ts +0 -563
  316. package/src/code-intelligence.ts +0 -70
  317. package/src/pattern-structured.ts +0 -194
  318. package/src/presentation/markdown/affected.ts +0 -170
  319. package/src/presentation/markdown/brief.ts +0 -174
  320. package/src/presentation/markdown/map.ts +0 -54
  321. package/src/presentation/markdown/refactor.ts +0 -27
  322. package/src/presentation/markdown/relations.ts +0 -121
  323. package/src/resolve-target.ts +0 -130
  324. package/src/search-helpers.ts +0 -303
  325. package/src/substrates/types.ts +0 -30
  326. package/src/target-resolution.ts +0 -122
  327. package/src/targeting/resolve-anchored.ts +0 -80
  328. package/src/targeting/resolve-symbol.ts +0 -110
  329. package/src/tool/execute-affected.ts +0 -71
  330. package/src/tool/execute-brief.ts +0 -59
  331. package/src/tool/execute-map.ts +0 -35
  332. package/src/tool/execute-pattern.ts +0 -29
  333. package/src/tool/execute-refactor.ts +0 -101
  334. package/src/tool/execute-relations.ts +0 -79
  335. package/src/tool/register-tools.ts +0 -32
  336. package/src/tool/tool-specs.ts +0 -190
  337. package/src/tool/validation.ts +0 -43
  338. package/src/types.ts +0 -169
  339. package/src/use-case/generate-affected.ts +0 -297
  340. package/src/use-case/generate-map.ts +0 -176
  341. package/src/use-case/generate-relations.ts +0 -438
  342. package/src/use-case/types.ts +0 -43
  343. package/src/workspace/request-context.ts +0 -139
  344. /package/src/{query-params.ts → tool/params.ts} +0 -0
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Substrate context gathering for symbol briefs and point inspection (code_inspect).
3
+ *
4
+ * Extracted from generate-brief.ts to keep the file within the
5
+ * noExcessiveLinesPerFile threshold.
6
+ */
7
+
8
+ import { resolve } from "node:path";
9
+ import type { SourceRange } from "@mrclrchtr/supi-code-runtime/api";
10
+ import type { SessionLspServiceState } from "@mrclrchtr/supi-lsp/api";
11
+ import type { CodeProvider } from "../../analysis/provider.ts";
12
+ import { diagnosticMessageString } from "../../substrate/lsp/utils.ts";
13
+
14
+ export interface TreeSitterContext {
15
+ nodeInfo: {
16
+ type: string;
17
+ text: string;
18
+ startLine: number;
19
+ startCharacter: number;
20
+ ancestry: Array<{
21
+ type: string;
22
+ startLine: number;
23
+ startCharacter: number;
24
+ endLine: number;
25
+ endCharacter: number;
26
+ }>;
27
+ } | null;
28
+ outline: Array<{ name: string; kind: string; startLine: number; endLine: number }>;
29
+ imports: Array<{ moduleSpecifier: string }>;
30
+ exports: Array<{ name: string; kind: string }>;
31
+ /** Best-effort LSP hover info at the anchored position. `null` when unavailable. */
32
+ hover: { contents: string; range?: SourceRange } | null;
33
+ /** Best-effort LSP definition targets at the anchored position. `null` when unavailable. */
34
+ definition: Array<{ uri: string; range: SourceRange }> | null;
35
+ /** Best-effort code action titles at the anchored position. `null` when unavailable. */
36
+ codeActions: Array<{ title: string; kind?: string }> | null;
37
+ }
38
+
39
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: best-effort substrate gathering with independent try/catch blocks kept together for readability
40
+ export async function gatherTreeSitterContext(
41
+ provider: CodeProvider | null,
42
+ relPath: string,
43
+ line: number,
44
+ character: number,
45
+ ): Promise<TreeSitterContext> {
46
+ let nodeInfo: TreeSitterContext["nodeInfo"] = null;
47
+ let outline: TreeSitterContext["outline"] = [];
48
+ let imports: TreeSitterContext["imports"] = [];
49
+ let exports: TreeSitterContext["exports"] = [];
50
+ let hover: TreeSitterContext["hover"] = null;
51
+ let definition: TreeSitterContext["definition"] = null;
52
+ let codeActions: TreeSitterContext["codeActions"] = null;
53
+
54
+ if (!provider)
55
+ return { nodeInfo, outline, imports, exports, hover, definition: null, codeActions: null };
56
+
57
+ try {
58
+ const nodeResult = await provider.nodeAt(relPath, line, character);
59
+ if (nodeResult.kind === "success") {
60
+ nodeInfo = {
61
+ type: nodeResult.data.type,
62
+ text: nodeResult.data.text,
63
+ startLine: nodeResult.data.startLine,
64
+ startCharacter: nodeResult.data.startCharacter,
65
+ ancestry: nodeResult.data.ancestry ?? [],
66
+ };
67
+ }
68
+
69
+ const outlineResult = await provider.outline(relPath);
70
+ if (outlineResult.kind === "success") {
71
+ outline = outlineResult.data.map((item) => ({
72
+ name: item.name,
73
+ kind: item.kind,
74
+ startLine: item.startLine,
75
+ endLine: item.endLine,
76
+ }));
77
+ }
78
+
79
+ const importsResult = await provider.imports(relPath);
80
+ if (importsResult.kind === "success") {
81
+ imports = importsResult.data;
82
+ }
83
+
84
+ const exportsResult = await provider.exports(relPath);
85
+ if (exportsResult.kind === "success") {
86
+ exports = exportsResult.data.map((item) => ({
87
+ name: item.name,
88
+ kind: item.kind,
89
+ }));
90
+ }
91
+
92
+ // Best-effort hover — LSP expects 0-based coordinates
93
+ if (provider.hover) {
94
+ try {
95
+ const hoverResult = await provider.hover(relPath, {
96
+ line: line - 1,
97
+ character: character - 1,
98
+ });
99
+ if (hoverResult) hover = hoverResult;
100
+ } catch {
101
+ // hover failed — continue without it
102
+ }
103
+ }
104
+
105
+ // Best-effort definition — LSP expects 0-based coordinates
106
+ if (provider.definition) {
107
+ try {
108
+ const defResult = await provider.definition(relPath, {
109
+ line: line - 1,
110
+ character: character - 1,
111
+ });
112
+ if (defResult && defResult.length > 0) {
113
+ definition = defResult.map((loc) => ({
114
+ uri: loc.uri,
115
+ range: loc.range,
116
+ }));
117
+ }
118
+ } catch {
119
+ // definition failed — continue without it
120
+ }
121
+ }
122
+
123
+ // Best-effort code actions — LSP expects 0-based coordinates
124
+ if (provider.codeActionTitles) {
125
+ try {
126
+ const titles = await provider.codeActionTitles(relPath, {
127
+ line: line - 1,
128
+ character: character - 1,
129
+ });
130
+ if (titles && titles.length > 0) {
131
+ codeActions = titles.map((a) => ({
132
+ title: a.title,
133
+ kind: a.kind,
134
+ }));
135
+ }
136
+ } catch {
137
+ // code actions failed — continue without it
138
+ }
139
+ }
140
+ } catch {
141
+ // Provider not available
142
+ }
143
+
144
+ return { nodeInfo, outline, imports, exports, hover, definition, codeActions };
145
+ }
146
+
147
+ export interface NearbyDiagnostic {
148
+ line: number;
149
+ severity: number;
150
+ message: string;
151
+ }
152
+
153
+ // biome-ignore lint/complexity/useMaxParams: lspService is a DI seam, not a logic parameter
154
+ export async function gatherNearbyDiagnostics(
155
+ cwd: string,
156
+ file: string,
157
+ line: number,
158
+ maxResults: number,
159
+ lspService: SessionLspServiceState,
160
+ ): Promise<NearbyDiagnostic[]> {
161
+ if (lspService.kind !== "ready") return [];
162
+
163
+ try {
164
+ const diagnostics = await lspService.service.fileDiagnostics(resolve(cwd, file), 4);
165
+ if (!diagnostics || diagnostics.length === 0) return [];
166
+
167
+ const nearby = diagnostics.filter((d) => Math.abs(d.range.start.line + 1 - line) <= 2);
168
+ const chosen = nearby.length > 0 ? nearby : diagnostics;
169
+ return chosen.slice(0, maxResults).map((d) => ({
170
+ line: d.range.start.line + 1,
171
+ severity: d.severity ?? 1,
172
+ message: diagnosticMessageString(d),
173
+ }));
174
+ } catch {
175
+ return [];
176
+ }
177
+ }
@@ -1,7 +1,7 @@
1
1
  // Typed overview data builder from ArchitectureModel.
2
2
 
3
- import { formatGitContext, gatherGitContext } from "../git-context.ts";
4
- import type { ArchitectureModel } from "../model.ts";
3
+ import type { ArchitectureModel } from "../../analysis/architecture/model.ts";
4
+ import { formatGitContext, gatherGitContext } from "../../analysis/signals/git.ts";
5
5
  import type { OverviewData, OverviewModule } from "./types.ts";
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  // Hidden overview markdown renderer for the first-turn session injection.
2
2
  // Consumes OverviewData produced by the overview use-case.
3
3
 
4
- import type { OverviewData } from "../../use-case/types.ts";
4
+ import type { OverviewData } from "./types.ts";
5
5
 
6
6
  /**
7
7
  * Render the compact architecture overview for first-turn session injection.
@@ -53,7 +53,7 @@ export function renderOverview(data: OverviewData): string {
53
53
  lines.push(data.gitContextOverview);
54
54
  }
55
55
 
56
- lines.push("_Use `code_brief` for deeper context on any module or file._");
56
+ lines.push('_For deeper orientation, use `code_orientation({ focus: "..." })`._');
57
57
 
58
58
  return lines.join("\n");
59
59
  }
@@ -0,0 +1,80 @@
1
+ // Shared typed data interfaces between use-case and presentation layers.
2
+
3
+ import type { SessionLspServiceState } from "@mrclrchtr/supi-lsp/api";
4
+ import type { ArchitectureModel } from "../../analysis/architecture/model.ts";
5
+ import type { CodeProvider } from "../../analysis/provider.ts";
6
+ import type { AnchorKind } from "../../session/target-store.ts";
7
+ import type { ContextDetails, InspectDetails } from "../../types/details.ts";
8
+
9
+ // ── Overview use-case ────────────────────────────────────────────────
10
+
11
+ export interface OverviewModule {
12
+ name: string;
13
+ shortName: string;
14
+ description: string | null;
15
+ isLeaf: boolean;
16
+ internalDeps: string[];
17
+ }
18
+
19
+ export interface OverviewData {
20
+ projectName: string | null;
21
+ projectDescription: string | null;
22
+ modules: OverviewModule[];
23
+ omittedModuleCount: number;
24
+ gitContextOverview: string | null;
25
+ }
26
+
27
+ // ── Inspect use-case ─────────────────────────────────────────────────
28
+
29
+ export interface InspectInput {
30
+ file: string;
31
+ line: number;
32
+ character: number;
33
+ maxResults?: number;
34
+ }
35
+
36
+ export interface InspectDeps {
37
+ provider: CodeProvider | null;
38
+ cwd: string;
39
+ lspService: SessionLspServiceState;
40
+ }
41
+
42
+ export interface InspectUseCaseResult {
43
+ content: string;
44
+ details: InspectDetails;
45
+ }
46
+
47
+ // ── Orientation use-case ─────────────────────────────────────────────────
48
+
49
+ export type OrientationSection = "defs" | "docs" | "diagnostics";
50
+
51
+ export interface OrientationTarget {
52
+ file: string;
53
+ line: number;
54
+ character: number;
55
+ name: string | null;
56
+ kind: string | null;
57
+ /** Which anchor this target carries; strict consumers refuse declaration anchors. */
58
+ anchorKind: AnchorKind;
59
+ }
60
+
61
+ export interface OrientationInput {
62
+ target?: OrientationTarget | null;
63
+ /** Resolved orientation focus path for project/module/directory/file orientation. */
64
+ focus?: string;
65
+ maxResults?: number;
66
+ /** Show git context in orientation output. Defaults to true. */
67
+ showGitContext?: boolean;
68
+ }
69
+
70
+ export interface OrientationDeps {
71
+ model: ArchitectureModel | null;
72
+ provider: CodeProvider | null;
73
+ cwd: string;
74
+ lspService: SessionLspServiceState;
75
+ }
76
+
77
+ export interface OrientationUseCaseResult {
78
+ content: string;
79
+ details: ContextDetails;
80
+ }
@@ -1,3 +1,8 @@
1
+ // LSP context diagnostic message renderer — TUI renderer for lsp-context messages.
2
+ //
3
+ // Ported from supi-lsp's renderer. Inline diagnostic rendering for the
4
+ // diagnostic messages injected by before_agent_start.
5
+
1
6
  import type { ThemeColor } from "@earendil-works/pi-coding-agent";
2
7
  import { Box, Text } from "@earendil-works/pi-tui";
3
8
 
@@ -41,7 +46,7 @@ function hasDiagnosticCounts(totals: DiagnosticCounts): boolean {
41
46
  return totals.errors > 0 || totals.warnings > 0 || totals.information > 0 || totals.hints > 0;
42
47
  }
43
48
 
44
- function buildLspContextCollapsed(
49
+ function buildCollapsed(
45
50
  diagnostics: LspContextDetails["diagnostics"],
46
51
  totals: DiagnosticCounts | undefined,
47
52
  staleWarning: string | null | undefined,
@@ -61,11 +66,11 @@ function buildLspContextCollapsed(
61
66
  return `${summary}\n${theme.fg("warning", staleWarning)}`;
62
67
  }
63
68
 
64
- function formatFileDiagnosticEntry(d: DiagnosticCounts): string {
69
+ function formatFileEntry(d: DiagnosticCounts): string {
65
70
  return formatDiagnosticCounts(d, { fg: (_color, text) => text });
66
71
  }
67
72
 
68
- function formatExpandedDetails(
73
+ function buildExpanded(
69
74
  diagnostics: LspContextDetails["diagnostics"],
70
75
  token: string | undefined,
71
76
  staleWarning: string | null | undefined,
@@ -77,7 +82,7 @@ function formatExpandedDetails(
77
82
  }
78
83
  if (diagnostics && diagnostics.length > 0) {
79
84
  for (const d of diagnostics) {
80
- lines.push(theme.fg("dim", ` ${d.file}: ${formatFileDiagnosticEntry(d)}`));
85
+ lines.push(theme.fg("dim", ` ${d.file}: ${formatFileEntry(d)}`));
81
86
  }
82
87
  }
83
88
  if (token) {
@@ -86,8 +91,6 @@ function formatExpandedDetails(
86
91
  return lines.join("\n");
87
92
  }
88
93
 
89
- export type { LspContextDetails };
90
-
91
94
  export function registerLspMessageRenderer(
92
95
  pi: import("@earendil-works/pi-coding-agent").ExtensionAPI,
93
96
  ): void {
@@ -107,10 +110,8 @@ export function registerLspMessageRenderer(
107
110
  );
108
111
 
109
112
  const staleWarning = details?.staleWarning;
110
- const collapsed = buildLspContextCollapsed(diagnostics, totals, staleWarning, theme);
111
- const expandedDetails = expanded
112
- ? formatExpandedDetails(diagnostics, token, staleWarning, theme)
113
- : "";
113
+ const collapsed = buildCollapsed(diagnostics, totals, staleWarning, theme);
114
+ const expandedDetails = expanded ? buildExpanded(diagnostics, token, staleWarning, theme) : "";
114
115
  const fullText = expandedDetails ? `${collapsed}\n${expandedDetails}` : collapsed;
115
116
 
116
117
  const box = new Box(1, 1, (t) => theme.bg("customMessageBg", t));
@@ -0,0 +1,260 @@
1
+ // Code Intelligence status command — toggleable center dialog with persistent
2
+ // status bar, custom footer, and below-editor widget for LSP + structural awareness.
3
+
4
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
5
+ import { truncateToWidth } from "@earendil-works/pi-tui";
6
+ import { getDefaultWorkspaceRuntime } from "@mrclrchtr/supi-code-runtime/api";
7
+ import type { SessionLspServiceState } from "@mrclrchtr/supi-lsp/api";
8
+ import {
9
+ evaluateCoverageWarnings,
10
+ gatherCoverageEvalInput,
11
+ } from "../analysis/coverage/coverage-warnings.ts";
12
+ import { getCodeProvider } from "../analysis/provider.ts";
13
+ import { type CiStatusData, createCiStatusDialog } from "./status-overlay.ts";
14
+
15
+ const STATUS_KEY = "code-intelligence";
16
+ const WIDGET_KEY = "code-intelligence";
17
+
18
+ interface InspectorState {
19
+ handle: unknown;
20
+ close: (() => void) | null;
21
+ }
22
+
23
+ const inspector: InspectorState = { handle: null, close: null };
24
+
25
+ /** Register the interactive /supi-ci-status overlay command. */
26
+ export function registerCiStatusCommand(pi: ExtensionAPI): void {
27
+ pi.registerCommand("supi-ci-status", {
28
+ description: "Toggle code intelligence status — LSP and structural analysis state",
29
+ handler: async (_args: string, ctx: ExtensionContext) => {
30
+ if (inspector.close) {
31
+ inspector.close();
32
+ return;
33
+ }
34
+
35
+ const dataRef = { current: await gatherCiStatusData(ctx.cwd, pi) };
36
+ updateStatusAndWidget(ctx, dataRef.current);
37
+
38
+ // Custom footer while overlay is open — reads latest data via ref
39
+ ctx.ui.setFooter((_tui, _theme) => ({
40
+ render(width: number): string[] {
41
+ return [truncateFooterLine(renderFooterLine(ctx, dataRef.current), width)];
42
+ },
43
+ invalidate(): void {},
44
+ }));
45
+
46
+ void ctx.ui
47
+ .custom<void>(
48
+ (tui, theme, _kb, done) => {
49
+ inspector.close = () => done(undefined);
50
+ return createCiStatusDialog(dataRef.current, {
51
+ theme: theme as unknown as import("./status-overlay.ts").CiDialogTheme,
52
+ done: () => done(undefined),
53
+ tui,
54
+ fetchDetailedDiagnostics: async (maxSeverity) => {
55
+ const ps = getCodeProvider(ctx.cwd);
56
+ const lspState = ps.kind === "ready" ? ps.lspService : null;
57
+ if (lspState?.kind !== "ready") return [];
58
+ return lspState.service.getOutstandingDiagnostics(maxSeverity);
59
+ },
60
+ onRefresh: async () => {
61
+ const fresh = await gatherCiStatusData(ctx.cwd, pi);
62
+ dataRef.current = fresh;
63
+ updateStatusAndWidget(ctx, fresh);
64
+ return fresh;
65
+ },
66
+ });
67
+ },
68
+ {
69
+ overlay: true,
70
+ overlayOptions: {
71
+ anchor: "center",
72
+ width: "66%",
73
+ minWidth: 60,
74
+ maxHeight: "85%",
75
+ visible: (termWidth: number) => termWidth >= 60,
76
+ },
77
+ onHandle: (handle) => {
78
+ inspector.handle = handle;
79
+ },
80
+ },
81
+ )
82
+ .finally(() => {
83
+ inspector.handle = null;
84
+ inspector.close = null;
85
+ clearStatusAndWidget(ctx);
86
+ ctx.ui.setFooter(undefined);
87
+ });
88
+ },
89
+ });
90
+ }
91
+
92
+ /** Gather a snapshot of LSP and structural state for the dialog. */
93
+ async function gatherCiStatusData(cwd: string, pi: ExtensionAPI): Promise<CiStatusData> {
94
+ const workspace = getDefaultWorkspaceRuntime().getWorkspace(cwd);
95
+ const providerState = getCodeProvider(cwd);
96
+ const lspState = providerState.kind === "ready" ? providerState.lspService : null;
97
+
98
+ const servers = lspState && lspState.kind === "ready" ? lspState.service.getProjectServers() : [];
99
+ const diagnostics =
100
+ lspState && lspState.kind === "ready"
101
+ ? lspState.service.getOutstandingDiagnosticSummary(1)
102
+ : [];
103
+ const semanticState = deriveSemanticCapabilityState(workspace, lspState);
104
+
105
+ // Sort: errors desc, warnings desc, info desc, hints desc
106
+ diagnostics.sort((a, b) => {
107
+ if (b.errors !== a.errors) return b.errors - a.errors;
108
+ if (b.warnings !== a.warnings) return b.warnings - a.warnings;
109
+ if (b.information !== a.information) return b.information - a.information;
110
+ return b.hints - a.hints;
111
+ });
112
+
113
+ const structState = workspace.structural.state;
114
+ const structKind = structState.kind;
115
+ const structReason = structState.kind === "unavailable" ? structState.reason : undefined;
116
+
117
+ const activeTools = pi.getActiveTools().filter((t) => t.startsWith("code_"));
118
+
119
+ // Evaluate degraded coverage from available data
120
+ const degradedCoverage = evaluateCoverageWarnings(gatherCoverageEvalInput(cwd, null));
121
+
122
+ return {
123
+ servers,
124
+ diagnostics,
125
+ capabilities: {
126
+ semantic: semanticState,
127
+ structural: {
128
+ kind: structKind,
129
+ reason: structReason,
130
+ providerAvailable: structState.kind === "ready",
131
+ },
132
+ refactorAvailable: workspace.semantic.refactorAvailable,
133
+ },
134
+ activeTools,
135
+ degradedCoverage: degradedCoverage.hasWarnings ? degradedCoverage : undefined,
136
+ };
137
+ }
138
+
139
+ function deriveSemanticCapabilityState(
140
+ workspace: {
141
+ semantic: {
142
+ state: { kind: string };
143
+ provider: unknown | null;
144
+ };
145
+ },
146
+ lspState: SessionLspServiceState | null,
147
+ ): CiStatusData["capabilities"]["semantic"] {
148
+ if (lspState?.kind === "ready") {
149
+ return {
150
+ kind: workspace.semantic.state.kind === "pending" ? "pending" : "ready",
151
+ providerAvailable: workspace.semantic.provider !== null,
152
+ };
153
+ }
154
+ if (workspace.semantic.state.kind === "pending" || lspState?.kind === "pending") {
155
+ return {
156
+ kind: "pending",
157
+ providerAvailable: workspace.semantic.provider !== null,
158
+ };
159
+ }
160
+ if (lspState?.kind === "inactive") {
161
+ return { kind: "inactive", providerAvailable: workspace.semantic.provider !== null };
162
+ }
163
+ if (lspState?.kind === "disabled") {
164
+ return {
165
+ kind: "disabled",
166
+ reason: "LSP is disabled in settings",
167
+ providerAvailable: workspace.semantic.provider !== null,
168
+ };
169
+ }
170
+ return {
171
+ kind: workspace.semantic.state.kind,
172
+ reason: lspState && "reason" in lspState ? lspState.reason : "No LSP service",
173
+ providerAvailable: workspace.semantic.provider !== null,
174
+ };
175
+ }
176
+
177
+ /** Render the custom footer line. */
178
+ function renderFooterLine(ctx: ExtensionContext, data: CiStatusData): string {
179
+ const t = ctx.ui.theme;
180
+ const parts: string[] = [];
181
+ const running = data.servers.filter((s) => s.status === "running").length;
182
+ if (running > 0) {
183
+ parts.push(
184
+ t.fg("accent", "λ ci") + t.fg("dim", ` ${running} server${running === 1 ? "" : "s"}`),
185
+ );
186
+ }
187
+ const totalErrors = data.diagnostics.reduce((sum, d) => sum + d.errors, 0);
188
+ if (totalErrors > 0) {
189
+ parts.push(t.fg("error", `${totalErrors} error${totalErrors === 1 ? "" : "s"}`));
190
+ }
191
+ const totalWarnings = data.diagnostics.reduce((sum, d) => sum + d.warnings, 0);
192
+ if (totalWarnings > 0) {
193
+ parts.push(t.fg("warning", `${totalWarnings} warning${totalWarnings === 1 ? "" : "s"}`));
194
+ }
195
+ const structKind = data.capabilities.structural.kind;
196
+ if (structKind === "ready") parts.push(t.fg("success", "✓ ts"));
197
+ if (parts.length === 0) return t.fg("dim", "CI — no data available");
198
+ return parts.join(t.fg("dim", " "));
199
+ }
200
+
201
+ function truncateFooterLine(line: string, width: number): string {
202
+ return truncateToWidth(line, width, "…");
203
+ }
204
+
205
+ /** Update the persistent status bar and below-editor widget. */
206
+ function updateStatusAndWidget(ctx: ExtensionContext, data: CiStatusData): void {
207
+ const t = ctx.ui.theme;
208
+
209
+ // Status bar: concise one-liner
210
+ const parts: string[] = [t.fg("accent", "λ ci")];
211
+ const runningServers = data.servers.filter((s) => s.status === "running").length;
212
+ if (runningServers > 0) {
213
+ parts.push(t.fg("dim", `${runningServers} server${runningServers === 1 ? "" : "s"}`));
214
+ }
215
+ const totalErrors = data.diagnostics.reduce((sum, d) => sum + d.errors, 0);
216
+ if (totalErrors > 0) {
217
+ parts.push(t.fg("error", `${totalErrors} error${totalErrors === 1 ? "" : "s"}`));
218
+ }
219
+ const totalWarnings = data.diagnostics.reduce((sum, d) => sum + d.warnings, 0);
220
+ if (totalWarnings > 0) {
221
+ parts.push(t.fg("warning", `${totalWarnings} warning${totalWarnings === 1 ? "" : "s"}`));
222
+ }
223
+ const structKind = data.capabilities.structural.kind;
224
+ if (structKind === "ready") parts.push(t.fg("success", "✓ ts"));
225
+
226
+ const statusText = parts.length > 1 ? parts.join(t.fg("dim", " · ")) : undefined;
227
+ ctx.ui.setStatus(STATUS_KEY, statusText);
228
+
229
+ // Widget (below editor) — top problem files
230
+ if (data.diagnostics.length > 0) {
231
+ const top = data.diagnostics.slice(0, 2);
232
+ const fileLines = top.map((d) => {
233
+ const counts: string[] = [];
234
+ if (d.errors > 0) {
235
+ counts.push(t.fg("error", `${d.errors} error${d.errors === 1 ? "" : "s"}`));
236
+ }
237
+ if (d.warnings > 0) {
238
+ counts.push(t.fg("warning", `${d.warnings} warning${d.warnings === 1 ? "" : "s"}`));
239
+ }
240
+ return ` ${d.file} (${counts.join(", ")})`;
241
+ });
242
+ const more = data.diagnostics.length - top.length;
243
+ const moreSuffix = more > 0 ? t.fg("dim", ` +${more} more`) : "";
244
+ ctx.ui.setWidget(
245
+ WIDGET_KEY,
246
+ [
247
+ t.fg("accent", `λ CI — ${data.diagnostics.length} files with issues`) + moreSuffix,
248
+ ...fileLines,
249
+ ],
250
+ { placement: "belowEditor" },
251
+ );
252
+ } else {
253
+ ctx.ui.setWidget(WIDGET_KEY, undefined);
254
+ }
255
+ }
256
+
257
+ function clearStatusAndWidget(ctx: ExtensionContext): void {
258
+ ctx.ui.setStatus(STATUS_KEY, undefined);
259
+ ctx.ui.setWidget(WIDGET_KEY, undefined);
260
+ }