@mrclrchtr/supi-code-intelligence 1.16.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/README.md +373 -63
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  9. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  10. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  11. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  12. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  13. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  14. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  15. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  16. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  17. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  18. package/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  19. package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  20. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  21. package/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  22. package/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  23. package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  24. package/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  25. package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  26. package/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  27. package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  28. package/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  29. package/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  30. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  31. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  32. package/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  33. package/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  34. package/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/README.md +44 -56
  36. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  37. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  40. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  42. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  45. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  46. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  47. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  50. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  51. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  52. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  53. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  54. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  55. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  56. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  57. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  59. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  60. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  61. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  62. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  63. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  64. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  65. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  66. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  67. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  68. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  69. package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -31
  70. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +27 -0
  71. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +5 -0
  72. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +246 -1
  73. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +4 -0
  74. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +3 -0
  75. package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +4 -2
  76. package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +102 -0
  77. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +59 -0
  78. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +4 -0
  79. package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +11 -0
  80. package/node_modules/@mrclrchtr/supi-lsp/src/manager/capability-index.ts +1 -1
  81. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +2 -1
  82. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +115 -26
  83. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +177 -134
  84. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +214 -0
  85. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +320 -0
  86. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +26 -5
  87. package/node_modules/@mrclrchtr/supi-lsp/src/session/service-registry.ts +81 -4
  88. package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +2 -0
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +18 -37
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/LICENSE +21 -0
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/README.md +265 -0
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs +4661 -0
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs.map +7 -0
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js +4605 -0
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js.map +7 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +57 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +100 -0
  132. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs +4063 -0
  133. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs.map +7 -0
  134. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts +1025 -0
  135. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts.map +58 -0
  136. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1025 -0
  137. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +58 -0
  138. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js +4007 -0
  139. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js.map +7 -0
  140. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  141. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +55 -0
  142. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -12
  143. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +29 -0
  144. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +28 -0
  145. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -0
  146. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +14 -2
  147. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +157 -0
  148. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +8 -1
  149. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +86 -0
  150. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +35 -16
  151. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +1 -0
  152. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +10 -0
  153. package/package.json +14 -9
  154. package/src/{model.ts → analysis/architecture/discovery.ts} +15 -72
  155. package/src/analysis/architecture/model.ts +76 -0
  156. package/src/analysis/brief/directory.ts +324 -0
  157. package/src/analysis/brief/enrich.ts +157 -0
  158. package/src/analysis/brief/file.ts +84 -0
  159. package/src/analysis/brief/inventory.ts +177 -0
  160. package/src/analysis/brief/main.ts +176 -0
  161. package/src/analysis/brief/models.ts +75 -0
  162. package/src/{brief.ts → analysis/brief/public-brief.ts} +21 -26
  163. package/src/analysis/brief/summarize.ts +208 -0
  164. package/src/analysis/brief/types.ts +27 -0
  165. package/src/{use-case/generate-brief.ts → analysis/brief/use-case.ts} +67 -144
  166. package/src/analysis/coverage/coverage-warnings.ts +224 -0
  167. package/src/analysis/evidence.ts +91 -0
  168. package/src/{semantic-action-helpers.ts → analysis/helpers.ts} +4 -4
  169. package/src/analysis/provider.ts +186 -0
  170. package/src/analysis/read-next.ts +126 -0
  171. package/src/analysis/readiness.ts +73 -0
  172. package/src/{refactor → analysis/refactor}/safety.ts +1 -1
  173. package/src/{use-case/support/semantic-references.ts → analysis/references/semantic-refs.ts} +58 -26
  174. package/src/analysis/search/pattern.ts +345 -0
  175. package/src/analysis/search/ripgrep.ts +473 -0
  176. package/src/{git-context.ts → analysis/signals/git.ts} +20 -7
  177. package/src/{prioritization-signals.ts → analysis/signals/project.ts} +33 -19
  178. package/src/analysis/target/anchored.ts +349 -0
  179. package/src/analysis/target/bridge.ts +152 -0
  180. package/src/analysis/target/file-resolution.ts +125 -0
  181. package/src/{targeting/resolve-file.ts → analysis/target/file.ts} +40 -20
  182. package/src/{planner → analysis/target}/planner.ts +30 -20
  183. package/src/{targeting → analysis/target}/query.ts +17 -3
  184. package/src/analysis/target/resolve-common.ts +115 -0
  185. package/src/analysis/target/service.ts +229 -0
  186. package/src/analysis/target/symbol.ts +196 -0
  187. package/src/{targeting → analysis/target}/types.ts +17 -1
  188. package/src/analysis/tests/likely-tests.ts +174 -0
  189. package/src/analysis/tests/test-discovery.ts +540 -0
  190. package/src/analysis/tests/vitest.ts +87 -0
  191. package/src/api.ts +34 -41
  192. package/src/app/app.ts +125 -0
  193. package/src/app/manager.ts +65 -0
  194. package/src/extension.ts +132 -1
  195. package/src/index.ts +1 -57
  196. package/src/session/refactor-plans.ts +82 -0
  197. package/src/session/session.ts +300 -0
  198. package/src/session/target-store.ts +293 -0
  199. package/src/substrate/lsp/diagnostic-injection.ts +218 -0
  200. package/src/substrate/lsp/lifecycle.ts +66 -0
  201. package/src/substrate/lsp/overrides.ts +132 -0
  202. package/src/substrate/lsp/recovery.ts +55 -0
  203. package/src/substrate/lsp/settings.ts +286 -0
  204. package/src/substrate/lsp/state.ts +46 -0
  205. package/src/substrate/lsp/utils.ts +17 -0
  206. package/src/substrate/tree-sitter/lifecycle.ts +52 -0
  207. package/src/tool/find/execute.ts +118 -0
  208. package/src/{presentation/markdown/pattern.ts → tool/find/markdown.ts} +102 -53
  209. package/src/{use-case/generate-pattern.ts → tool/find/orchestrate.ts} +67 -33
  210. package/src/tool/find/semantic-search.ts +114 -0
  211. package/src/tool/find/tui.ts +39 -0
  212. package/src/tool/graph/callees.ts +87 -0
  213. package/src/tool/graph/calls-md.ts +54 -0
  214. package/src/tool/graph/collect-relation.ts +371 -0
  215. package/src/tool/graph/execute.ts +95 -0
  216. package/src/tool/graph/implementations-md.ts +79 -0
  217. package/src/tool/graph/implementations.ts +76 -0
  218. package/src/tool/graph/markdown-base.ts +243 -0
  219. package/src/tool/graph/orchestrate.ts +285 -0
  220. package/src/tool/graph/references-md.ts +34 -0
  221. package/src/tool/graph/references.ts +81 -0
  222. package/src/tool/graph/tui.ts +120 -0
  223. package/src/tool/graph/types.ts +97 -0
  224. package/src/tool/guidance.ts +96 -49
  225. package/src/tool/health/execute.ts +76 -0
  226. package/src/tool/health/markdown.ts +280 -0
  227. package/src/tool/health/orchestrate.ts +159 -0
  228. package/src/tool/health/sections/diagnostics.ts +182 -0
  229. package/src/tool/health/sections/recovery.ts +89 -0
  230. package/src/tool/health/sections/signals.ts +89 -0
  231. package/src/tool/health/tui.ts +137 -0
  232. package/src/tool/impact/analysis.ts +247 -0
  233. package/src/tool/impact/change-set-impact.ts +151 -0
  234. package/src/tool/impact/execute.ts +98 -0
  235. package/src/tool/impact/file-level-impact.ts +81 -0
  236. package/src/tool/impact/markdown.ts +283 -0
  237. package/src/tool/impact/orchestrate.ts +97 -0
  238. package/src/tool/impact/result.ts +21 -0
  239. package/src/tool/impact/single-impact.ts +89 -0
  240. package/src/tool/impact/tui.ts +39 -0
  241. package/src/tool/impact/types.ts +34 -0
  242. package/src/tool/infra/cross-field.ts +335 -0
  243. package/src/tool/infra/error-results.ts +199 -0
  244. package/src/tool/infra/pipeline.ts +311 -0
  245. package/src/tool/infra/progress.ts +21 -0
  246. package/src/tool/infra/readiness-message.ts +5 -0
  247. package/src/tool/infra/truncate.ts +49 -0
  248. package/src/tool/inspect/execute.ts +76 -0
  249. package/src/tool/inspect/markdown.ts +169 -0
  250. package/src/tool/inspect/orchestrate.ts +156 -0
  251. package/src/tool/inspect/tui.ts +36 -0
  252. package/src/tool/orientation/deps.ts +63 -0
  253. package/src/tool/orientation/execute.ts +50 -0
  254. package/src/tool/orientation/markdown.ts +35 -0
  255. package/src/tool/orientation/mode.ts +88 -0
  256. package/src/tool/orientation/orchestrate.ts +478 -0
  257. package/src/tool/orientation/precise-target.ts +257 -0
  258. package/src/tool/orientation/tui.ts +131 -0
  259. package/src/{refactor/apply-workspace-edit.ts → tool/refactor-apply/apply.ts} +39 -16
  260. package/src/tool/refactor-apply/execute.ts +20 -0
  261. package/src/tool/refactor-apply/markdown.ts +118 -0
  262. package/src/tool/refactor-apply/orchestrate.ts +89 -0
  263. package/src/tool/refactor-apply/tui.ts +51 -0
  264. package/src/tool/refactor-plan/execute.ts +73 -0
  265. package/src/tool/refactor-plan/markdown.ts +118 -0
  266. package/src/tool/refactor-plan/orchestrate.ts +363 -0
  267. package/src/tool/refactor-plan/tui.ts +42 -0
  268. package/src/tool/register.ts +123 -0
  269. package/src/tool/resolve/execute.ts +82 -0
  270. package/src/tool/resolve/markdown.ts +150 -0
  271. package/src/tool/resolve/orchestrate.ts +134 -0
  272. package/src/tool/resolve/tui.ts +40 -0
  273. package/src/tool/schemas.ts +337 -0
  274. package/src/tool/specs.ts +257 -0
  275. package/src/types/details.ts +188 -0
  276. package/src/types/execution.ts +60 -0
  277. package/src/types/index.ts +28 -0
  278. package/src/{intent/types.ts → types/tool-names.ts} +15 -14
  279. package/src/ui/footer.ts +52 -0
  280. package/src/ui/markdown/brief.ts +218 -0
  281. package/src/ui/markdown/gather.ts +177 -0
  282. package/src/{use-case/build-overview.ts → ui/markdown/overview-data.ts} +2 -2
  283. package/src/{presentation → ui}/markdown/overview.ts +2 -2
  284. package/src/ui/markdown/types.ts +80 -0
  285. package/{node_modules/@mrclrchtr/supi-lsp/src/ui/renderer.ts → src/ui/message-renderer.ts} +11 -10
  286. package/src/ui/status-command.ts +260 -0
  287. package/src/ui/status-overlay.ts +500 -0
  288. package/src/ui/tui/common.ts +220 -0
  289. package/src/ui/tui/index.ts +37 -0
  290. package/node_modules/@mrclrchtr/supi-lsp/src/extension.ts +0 -1
  291. package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +0 -373
  292. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/diagnostic-injection.ts +0 -182
  293. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/session-lifecycle.ts +0 -149
  294. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/status-command.ts +0 -38
  295. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/workspace-recovery.ts +0 -92
  296. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +0 -37
  297. package/node_modules/@mrclrchtr/supi-lsp/src/session/lsp-state.ts +0 -93
  298. package/node_modules/@mrclrchtr/supi-lsp/src/session/settings-registration.ts +0 -296
  299. package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +0 -75
  300. package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +0 -69
  301. package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +0 -27
  302. package/node_modules/@mrclrchtr/supi-lsp/src/tool/overrides.ts +0 -204
  303. package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +0 -69
  304. package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +0 -399
  305. package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +0 -248
  306. package/node_modules/@mrclrchtr/supi-lsp/src/ui/ui.ts +0 -360
  307. package/node_modules/@mrclrchtr/supi-lsp/src/workspace-change.ts +0 -40
  308. package/node_modules/@mrclrchtr/supi-tree-sitter/src/extension.ts +0 -1
  309. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/formatting.ts +0 -104
  310. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +0 -35
  311. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/handlers.ts +0 -196
  312. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/register-tools.ts +0 -107
  313. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/tool-specs.ts +0 -117
  314. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +0 -47
  315. package/src/brief-focused.ts +0 -563
  316. package/src/code-intelligence.ts +0 -70
  317. package/src/pattern-structured.ts +0 -194
  318. package/src/presentation/markdown/affected.ts +0 -170
  319. package/src/presentation/markdown/brief.ts +0 -174
  320. package/src/presentation/markdown/map.ts +0 -54
  321. package/src/presentation/markdown/refactor.ts +0 -27
  322. package/src/presentation/markdown/relations.ts +0 -121
  323. package/src/resolve-target.ts +0 -130
  324. package/src/search-helpers.ts +0 -303
  325. package/src/substrates/types.ts +0 -30
  326. package/src/target-resolution.ts +0 -122
  327. package/src/targeting/resolve-anchored.ts +0 -80
  328. package/src/targeting/resolve-symbol.ts +0 -110
  329. package/src/tool/execute-affected.ts +0 -71
  330. package/src/tool/execute-brief.ts +0 -59
  331. package/src/tool/execute-map.ts +0 -35
  332. package/src/tool/execute-pattern.ts +0 -29
  333. package/src/tool/execute-refactor.ts +0 -101
  334. package/src/tool/execute-relations.ts +0 -79
  335. package/src/tool/register-tools.ts +0 -32
  336. package/src/tool/tool-specs.ts +0 -190
  337. package/src/tool/validation.ts +0 -43
  338. package/src/types.ts +0 -169
  339. package/src/use-case/generate-affected.ts +0 -297
  340. package/src/use-case/generate-map.ts +0 -176
  341. package/src/use-case/generate-relations.ts +0 -438
  342. package/src/use-case/types.ts +0 -43
  343. package/src/workspace/request-context.ts +0 -139
  344. /package/src/{query-params.ts → tool/params.ts} +0 -0
@@ -0,0 +1,500 @@
1
+ // Code Intelligence status dialog — toggleable center overlay showing LSP + Tree-sitter
2
+ // status, expandable per-file diagnostics, and active code_* tool surface.
3
+
4
+ import { DynamicBorder } from "@earendil-works/pi-coding-agent";
5
+ import {
6
+ Container,
7
+ Key,
8
+ matchesKey,
9
+ Spacer,
10
+ Text,
11
+ truncateToWidth,
12
+ visibleWidth,
13
+ } from "@earendil-works/pi-tui";
14
+ import { BRAILLE_SPINNER_FRAMES } from "@mrclrchtr/supi-core/spinner-frames";
15
+ import type {
16
+ Diagnostic,
17
+ OutstandingDiagnosticSummaryEntry,
18
+ ProjectServerInfo,
19
+ } from "@mrclrchtr/supi-lsp/api";
20
+ import type { CoverageWarningReport } from "../analysis/coverage/coverage-warnings.ts";
21
+ import { diagnosticMessageString } from "../substrate/lsp/utils.ts";
22
+
23
+ /**
24
+ * Minimal theme contract used by the dialog. Matches the public `theme.fg()` /
25
+ * `theme.bold()` shape exposed by `@earendil-works/pi-tui` — the full Theme
26
+ * type is internal to pi-coding-agent and not re-exported.
27
+ */
28
+ export interface CiDialogTheme {
29
+ fg: (color: string, text: string) => string;
30
+ bg?: (color: string, text: string) => string;
31
+ bold: (text: string) => string;
32
+ }
33
+
34
+ export interface CiStatusData {
35
+ servers: ProjectServerInfo[];
36
+ /** Sorted: errors desc, then warnings desc, then info desc, then hints desc. */
37
+ diagnostics: OutstandingDiagnosticSummaryEntry[];
38
+ capabilities: {
39
+ semantic: { kind: string; reason?: string; providerAvailable: boolean };
40
+ structural: { kind: string; reason?: string; providerAvailable: boolean };
41
+ refactorAvailable: boolean;
42
+ };
43
+ activeTools: string[];
44
+ /** Coverage warnings for degraded semantic/structural substrate. Undefined when fully healthy. */
45
+ degradedCoverage?: CoverageWarningReport;
46
+ }
47
+
48
+ /** Fetcher for full diagnostic details when a file row is expanded. */
49
+ export type DiagFetcher = (
50
+ maxSeverity: number,
51
+ ) =>
52
+ | Array<{ file: string; diagnostics: Diagnostic[] }>
53
+ | Promise<Array<{ file: string; diagnostics: Diagnostic[] }>>;
54
+
55
+ export interface CiStatusDialogDeps {
56
+ theme: CiDialogTheme;
57
+ done: () => void;
58
+ tui: { requestRender: () => void };
59
+ /** Async fetcher for full diagnostics on expand. Optional. */
60
+ fetchDetailedDiagnostics?: DiagFetcher;
61
+ /** Refresh callback — re-fetches data when 'r' is pressed. */
62
+ onRefresh?: () => Promise<CiStatusData>;
63
+ }
64
+
65
+ const MAX_FILES_IN_LIST = 10;
66
+ const MAX_INLINE_MESSAGES = 5;
67
+ const MAX_OPEN_FILES_SHOWN = 3;
68
+ const SPINNER_INTERVAL_MS = 80;
69
+
70
+ export class CiStatusDialog {
71
+ private selectedFileIdx = 0;
72
+ private expandedFileIdx: number | null = null;
73
+ private expandedDiagnostics: Diagnostic[] | null = null;
74
+ private cachedWidth: number | undefined;
75
+ private cachedLines: string[] | undefined;
76
+ private spinnerInterval: ReturnType<typeof setInterval> | null = null;
77
+ private spinnerFrame = 0;
78
+ private loading = false;
79
+
80
+ constructor(
81
+ private data: CiStatusData,
82
+ deps: CiStatusDialogDeps,
83
+ ) {
84
+ this.theme = deps.theme;
85
+ this.done = deps.done;
86
+ this.tui = deps.tui;
87
+ this.fetchDetailedDiagnostics = deps.fetchDetailedDiagnostics;
88
+ this.onRefresh = deps.onRefresh;
89
+ }
90
+
91
+ /** Called by pi-tui when the overlay is removed. */
92
+ dispose(): void {
93
+ this.stopSpinner();
94
+ }
95
+
96
+ render(width: number): string[] {
97
+ if (this.cachedLines && this.cachedWidth === width) {
98
+ return this.cachedLines;
99
+ }
100
+ const container = new Container();
101
+ container.addChild(new DynamicBorder((s: string) => this.theme.fg("accent", s)));
102
+ container.addChild(new Text(this.renderHeader(), 1, 0));
103
+ container.addChild(new Spacer(1));
104
+ container.addChild(new Text(this.renderSummaryLine(width), 1, 0));
105
+ container.addChild(new Spacer(1));
106
+ this.addServerSection(container);
107
+ container.addChild(new Spacer(1));
108
+ this.addProblemsSection(container, width);
109
+ container.addChild(new Spacer(1));
110
+ this.addCapabilitiesSection(container);
111
+ this.addDegradedCoverageSection(container);
112
+ this.addToolsSection(container, width);
113
+ container.addChild(new Text(this.renderKeyHints(), 1, 0));
114
+ container.addChild(new DynamicBorder((s: string) => this.theme.fg("accent", s)));
115
+
116
+ const lines = container.render(width).map((line) => truncateToWidth(line, width));
117
+ this.cachedWidth = width;
118
+ this.cachedLines = lines;
119
+ return lines;
120
+ }
121
+
122
+ invalidate(): void {
123
+ this.cachedWidth = undefined;
124
+ this.cachedLines = undefined;
125
+ }
126
+
127
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: single handler dispatching keyboard shortcuts
128
+ handleInput(data: string): boolean {
129
+ // ── Global actions ───────────────────────────────────────────────
130
+ if (matchesKey(data, Key.ctrl("c")) || matchesKey(data, Key.escape)) {
131
+ this.stopSpinner();
132
+ this.done();
133
+ return true;
134
+ }
135
+
136
+ if (data === "a") {
137
+ this.expandedFileIdx = null;
138
+ this.expandedDiagnostics = null;
139
+ this.stopSpinner();
140
+ this.invalidate();
141
+ this.tui.requestRender();
142
+ return true;
143
+ }
144
+
145
+ if (data === "r" && this.onRefresh) {
146
+ void this.handleRefresh();
147
+ return true;
148
+ }
149
+
150
+ // ── Navigation ───────────────────────────────────────────────────
151
+ const fileCount = this.data.diagnostics.length;
152
+
153
+ if ((matchesKey(data, Key.up) || data === "k") && this.selectedFileIdx > 0) {
154
+ this.selectedFileIdx--;
155
+ this.invalidate();
156
+ this.tui.requestRender();
157
+ return true;
158
+ }
159
+
160
+ if ((matchesKey(data, Key.down) || data === "j") && this.selectedFileIdx < fileCount - 1) {
161
+ this.selectedFileIdx++;
162
+ this.invalidate();
163
+ this.tui.requestRender();
164
+ return true;
165
+ }
166
+
167
+ if (
168
+ (matchesKey(data, Key.enter) || matchesKey(data, Key.space) || data === " ") &&
169
+ fileCount > 0
170
+ ) {
171
+ if (this.expandedFileIdx === this.selectedFileIdx) {
172
+ this.expandedFileIdx = null;
173
+ this.expandedDiagnostics = null;
174
+ this.stopSpinner();
175
+ } else {
176
+ this.expandedFileIdx = this.selectedFileIdx;
177
+ this.expandedDiagnostics = null;
178
+ void this.loadDetailedDiagnostics();
179
+ }
180
+ this.invalidate();
181
+ this.tui.requestRender();
182
+ return true;
183
+ }
184
+
185
+ return false;
186
+ }
187
+
188
+ // ── Spinner ───────────────────────────────────────────────────────
189
+
190
+ private startSpinner(): void {
191
+ if (this.spinnerInterval) return;
192
+ this.loading = true;
193
+ this.spinnerFrame = 0;
194
+ this.spinnerInterval = setInterval(() => {
195
+ this.spinnerFrame = (this.spinnerFrame + 1) % BRAILLE_SPINNER_FRAMES.length;
196
+ this.invalidate();
197
+ this.tui.requestRender();
198
+ }, SPINNER_INTERVAL_MS);
199
+ }
200
+
201
+ private stopSpinner(): void {
202
+ if (this.spinnerInterval) {
203
+ clearInterval(this.spinnerInterval);
204
+ this.spinnerInterval = null;
205
+ }
206
+ this.loading = false;
207
+ }
208
+
209
+ // ── Async data loading ─────────────────────────────────────────────
210
+
211
+ private async handleRefresh(): Promise<void> {
212
+ if (!this.onRefresh) return;
213
+ this.startSpinner();
214
+ try {
215
+ this.data = await this.onRefresh();
216
+ } finally {
217
+ this.stopSpinner();
218
+ }
219
+ this.selectedFileIdx = Math.min(
220
+ this.selectedFileIdx,
221
+ Math.max(0, this.data.diagnostics.length - 1),
222
+ );
223
+ this.expandedFileIdx = null;
224
+ this.expandedDiagnostics = null;
225
+ this.invalidate();
226
+ this.tui.requestRender();
227
+ }
228
+
229
+ private async loadDetailedDiagnostics(): Promise<void> {
230
+ if (!this.fetchDetailedDiagnostics || this.expandedFileIdx === null) return;
231
+ const fileName = this.data.diagnostics[this.expandedFileIdx]?.file;
232
+ if (!fileName) return;
233
+ this.startSpinner();
234
+ try {
235
+ const detailed = await this.fetchDetailedDiagnostics(1);
236
+ const entry = detailed.find((d) => d.file === fileName);
237
+ this.expandedDiagnostics = entry?.diagnostics ?? [];
238
+ } catch {
239
+ this.expandedDiagnostics = [];
240
+ } finally {
241
+ this.stopSpinner();
242
+ }
243
+ this.invalidate();
244
+ this.tui.requestRender();
245
+ }
246
+
247
+ // ── Section builders ──────────────────────────────────────────────
248
+
249
+ private renderHeader(): string {
250
+ const accent = this.theme.fg("accent", this.theme.bold("◆ Code Intelligence"));
251
+ const hint = this.theme.fg("dim", " /supi-ci-status toggles · ↑↓ nav · enter expand");
252
+ return truncateToWidth(accent + hint, 1000);
253
+ }
254
+
255
+ private renderKeyHints(): string {
256
+ return this.theme.fg("dim", " r refresh · a collapse all · esc close");
257
+ }
258
+
259
+ private renderSummaryLine(width: number): string {
260
+ const t = this.theme;
261
+ const running = this.data.servers.filter((s) => s.status === "running").length;
262
+ const totalErrors = this.data.diagnostics.reduce((sum, d) => sum + d.errors, 0);
263
+ const totalWarnings = this.data.diagnostics.reduce((sum, d) => sum + d.warnings, 0);
264
+ const sep = t.fg("dim", " · ");
265
+
266
+ const parts: string[] = [];
267
+ if (running > 0) {
268
+ parts.push(t.fg("text", `${running} server${running === 1 ? "" : "s"}`));
269
+ }
270
+ if (totalErrors > 0) {
271
+ parts.push(t.fg("error", `${totalErrors} error${totalErrors === 1 ? "" : "s"}`));
272
+ }
273
+ if (totalWarnings > 0) {
274
+ parts.push(t.fg("warning", `${totalWarnings} warning${totalWarnings === 1 ? "" : "s"}`));
275
+ }
276
+ const structKind = this.data.capabilities.structural.kind;
277
+ if (structKind === "ready") parts.push(t.fg("success", "✓ ts ready"));
278
+ else if (structKind === "pending") parts.push(t.fg("dim", "ts pending…"));
279
+ else parts.push(t.fg("error", "ts unavailable"));
280
+
281
+ const joined = parts.length > 0 ? parts.join(sep) : t.fg("dim", "(no data)");
282
+ return truncateToWidth(joined, width);
283
+ }
284
+
285
+ private addServerSection(container: Container): void {
286
+ const t = this.theme;
287
+ container.addChild(new Text(t.fg("accent", t.bold(" Servers")), 1, 0));
288
+ if (this.data.servers.length === 0) {
289
+ this.addEmptyServerRow(container);
290
+ return;
291
+ }
292
+ for (const server of this.data.servers) {
293
+ this.addServerRow(container, server);
294
+ }
295
+ }
296
+
297
+ private addEmptyServerRow(container: Container): void {
298
+ const t = this.theme;
299
+ const sem = this.data.capabilities.semantic;
300
+ if (sem.kind !== "ready") {
301
+ container.addChild(new Text(t.fg("dim", " no LSP session for this workspace"), 1, 0));
302
+ } else {
303
+ container.addChild(new Text(t.fg("dim", " no configured language servers"), 1, 0));
304
+ }
305
+ }
306
+
307
+ private addServerRow(container: Container, server: ProjectServerInfo): void {
308
+ const t = this.theme;
309
+ const statusColor =
310
+ server.status === "running" ? "success" : server.status === "error" ? "error" : "warning";
311
+ const icon = server.status === "running" ? "✓" : server.status === "error" ? "✗" : "?";
312
+
313
+ container.addChild(
314
+ new Text(
315
+ t.fg("accent", " ▸ ") +
316
+ t.fg("text", server.name) +
317
+ " " +
318
+ t.fg(statusColor, icon) +
319
+ " " +
320
+ t.fg("dim", `root: ${server.root}`),
321
+ 0,
322
+ 0,
323
+ ),
324
+ );
325
+
326
+ const fileTypes = server.fileTypes.map((f) => `.${f}`).join(" ");
327
+ container.addChild(new Text(t.fg("dim", ` files: ${fileTypes || "(none)"}`), 0, 0));
328
+
329
+ if (server.openFiles.length > 0) {
330
+ const shown = server.openFiles.slice(0, MAX_OPEN_FILES_SHOWN);
331
+ const remaining = server.openFiles.length - shown.length;
332
+ const suffix = remaining > 0 ? t.fg("dim", ` +${remaining}`) : "";
333
+ container.addChild(new Text(t.fg("dim", ` open: ${shown.join(", ")}`) + suffix, 0, 0));
334
+ } else {
335
+ container.addChild(new Text(t.fg("dim", " open: (none)"), 0, 0));
336
+ }
337
+ }
338
+
339
+ private addProblemsSection(container: Container, width: number): void {
340
+ const t = this.theme;
341
+ container.addChild(new Text(t.fg("accent", t.bold(" Problems")), 1, 0));
342
+ if (this.data.diagnostics.length === 0) {
343
+ this.addEmptyProblemsRow(container);
344
+ return;
345
+ }
346
+ container.addChild(
347
+ new Text(t.fg("dim", " ↑↓ navigate · enter to expand · single-expand"), 1, 0),
348
+ );
349
+
350
+ const visible = this.data.diagnostics.slice(0, MAX_FILES_IN_LIST);
351
+ visible.forEach((entry, idx) => {
352
+ this.addProblemRow(container, entry, idx, width);
353
+ });
354
+
355
+ const remaining = this.data.diagnostics.length - visible.length;
356
+ if (remaining > 0) {
357
+ container.addChild(
358
+ new Text(t.fg("dim", ` ↳ +${remaining} more file${remaining === 1 ? "" : "s"}`), 1, 0),
359
+ );
360
+ }
361
+ }
362
+
363
+ private addEmptyProblemsRow(container: Container): void {
364
+ const t = this.theme;
365
+ const sem = this.data.capabilities.semantic;
366
+ if (sem.kind !== "ready") {
367
+ container.addChild(new Text(t.fg("dim", " (LSP not ready)"), 1, 0));
368
+ } else {
369
+ container.addChild(new Text(t.fg("success", " ✓ no issues"), 1, 0));
370
+ }
371
+ }
372
+
373
+ private addProblemRow(
374
+ container: Container,
375
+ entry: OutstandingDiagnosticSummaryEntry,
376
+ idx: number,
377
+ width: number,
378
+ ): void {
379
+ const t = this.theme;
380
+ const isSelected = idx === this.selectedFileIdx;
381
+ const isExpanded = idx === this.expandedFileIdx;
382
+
383
+ const counts: string[] = [];
384
+ if (entry.errors > 0) {
385
+ counts.push(t.fg("error", `${entry.errors} error${entry.errors === 1 ? "" : "s"}`));
386
+ }
387
+ if (entry.warnings > 0) {
388
+ counts.push(t.fg("warning", `${entry.warnings} warning${entry.warnings === 1 ? "" : "s"}`));
389
+ }
390
+ const countsText = counts.length > 0 ? ` ${counts.join(" ")}` : "";
391
+ const indicator = isExpanded ? t.fg("accent", "▼") : isSelected ? t.fg("accent", "▶") : " ";
392
+ const fileColor = isSelected ? "accent" : "muted";
393
+ const line = `${indicator} ${t.fg(fileColor, entry.file)}${countsText}`;
394
+ container.addChild(new Text(truncateToWidth(line, width), 0, 0));
395
+
396
+ if (isExpanded) {
397
+ this.addInlineDiagnostics(container, width);
398
+ }
399
+ }
400
+
401
+ private addInlineDiagnostics(container: Container, width: number): void {
402
+ const t = this.theme;
403
+ if (this.loading) {
404
+ const frame = BRAILLE_SPINNER_FRAMES[this.spinnerFrame] ?? BRAILLE_SPINNER_FRAMES[0];
405
+ container.addChild(new Text(t.fg("accent", ` └ ${frame} loading…`), 0, 0));
406
+ return;
407
+ }
408
+ if (this.expandedDiagnostics === null) {
409
+ container.addChild(new Text(t.fg("dim", " └ no diagnostics available"), 0, 0));
410
+ return;
411
+ }
412
+ const messages = this.expandedDiagnostics;
413
+ for (const diag of messages.slice(0, MAX_INLINE_MESSAGES)) {
414
+ const lineNum = diag.range.start.line + 1;
415
+ const colNum = diag.range.start.character + 1;
416
+ const sevColor = diag.severity === 1 ? "error" : "warning";
417
+ const messageText = truncateTextForInline(diagnosticMessageString(diag), width - 14);
418
+ const msg = ` ${t.fg(sevColor, "└")} ${lineNum}:${colNum} ${t.fg("dim", messageText)}`;
419
+ container.addChild(new Text(msg, 0, 0));
420
+ }
421
+ const remaining = messages.length - MAX_INLINE_MESSAGES;
422
+ if (remaining > 0) {
423
+ container.addChild(new Text(t.fg("dim", ` └ +${remaining} more`), 0, 0));
424
+ }
425
+ }
426
+
427
+ private addCapabilitiesSection(container: Container): void {
428
+ const t = this.theme;
429
+ container.addChild(new Text(t.fg("accent", t.bold(" Capabilities")), 1, 0));
430
+ this.addCapabilityRow(container, "Semantic ", this.data.capabilities.semantic);
431
+ this.addCapabilityRow(container, "Structural ", this.data.capabilities.structural);
432
+ const refLabel = this.data.capabilities.refactorAvailable ? "✓ available" : "✗ unavailable";
433
+ const refColor = this.data.capabilities.refactorAvailable ? "success" : "error";
434
+ container.addChild(
435
+ new Text(` ${t.fg("text", "Refactor ")} ${t.fg(refColor, refLabel)}`, 0, 0),
436
+ );
437
+ }
438
+
439
+ private addCapabilityRow(
440
+ container: Container,
441
+ label: string,
442
+ cap: { kind: string; reason?: string },
443
+ ): void {
444
+ const t = this.theme;
445
+ const capLabel =
446
+ cap.kind === "ready" ? "✓ ready" : cap.kind === "pending" ? "⏳ pending" : "✗ unavailable";
447
+ const capColor = cap.kind === "ready" ? "success" : cap.kind === "pending" ? "dim" : "error";
448
+ const reason = cap.reason ? t.fg("dim", ` — ${cap.reason}`) : "";
449
+ container.addChild(
450
+ new Text(` ${t.fg("text", label)} ${t.fg(capColor, capLabel)}${reason}`, 0, 0),
451
+ );
452
+ }
453
+
454
+ private addDegradedCoverageSection(container: Container): void {
455
+ const warnings = this.data.degradedCoverage;
456
+ if (!warnings?.hasWarnings) return;
457
+
458
+ const t = this.theme;
459
+ container.addChild(new Spacer(1));
460
+ container.addChild(new Text(t.fg("error", t.bold(" Degraded Coverage")), 1, 0));
461
+
462
+ for (const w of warnings.warnings) {
463
+ const lang = w.language ? `${t.fg("accent", w.language)} ` : "";
464
+ const detail = w.detail ? t.fg("dim", ` — ${w.detail}`) : "";
465
+ container.addChild(
466
+ new Text(` ${t.fg("warning", "⚠")} ${lang}${t.fg("dim", w.message)}${detail}`, 0, 0),
467
+ );
468
+ }
469
+ container.addChild(new Spacer(1));
470
+ }
471
+
472
+ private addToolsSection(container: Container, width: number): void {
473
+ const t = this.theme;
474
+ if (this.data.activeTools.length === 0) return;
475
+ container.addChild(new Spacer(1));
476
+ container.addChild(new Text(t.fg("accent", t.bold(" Tools")), 1, 0));
477
+ const label = ` ${this.data.activeTools.map((tool) => t.fg("text", tool)).join(t.fg("dim", ", "))}`;
478
+ const truncated = truncateTextForInline(label, width - 4);
479
+ container.addChild(new Text(truncated, 0, 0));
480
+ container.addChild(new Spacer(1));
481
+ }
482
+
483
+ private readonly theme: CiDialogTheme;
484
+ private readonly done: () => void;
485
+ private readonly tui: { requestRender: () => void };
486
+ private readonly fetchDetailedDiagnostics?: DiagFetcher;
487
+ private readonly onRefresh?: () => Promise<CiStatusData>;
488
+ }
489
+
490
+ function truncateTextForInline(text: string, maxWidth: number): string {
491
+ if (visibleWidth(text) <= maxWidth) return text;
492
+ return truncateToWidth(text, Math.max(8, maxWidth), "…");
493
+ }
494
+
495
+ /**
496
+ * Factory for use with `ctx.ui.custom()`.
497
+ */
498
+ export function createCiStatusDialog(data: CiStatusData, deps: CiStatusDialogDeps): CiStatusDialog {
499
+ return new CiStatusDialog(data, deps);
500
+ }