@mrclrchtr/supi-code-intelligence 1.16.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/README.md +373 -63
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  9. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  10. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  11. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  12. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  13. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  14. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  15. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  16. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  17. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  18. package/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  19. package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  20. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  21. package/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  22. package/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  23. package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  24. package/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  25. package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  26. package/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  27. package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  28. package/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  29. package/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  30. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  31. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  32. package/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  33. package/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  34. package/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/README.md +44 -56
  36. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  37. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  40. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  42. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  45. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  46. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  47. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  50. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  51. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  52. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  53. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  54. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  55. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  56. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  57. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  59. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  60. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  61. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  62. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  63. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  64. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  65. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  66. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  67. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  68. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  69. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.diagnostic.d.ts +21 -2
  70. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.diagnostic.js +1 -0
  71. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineValue.d.ts +2 -1
  72. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/package.json +1 -1
  73. package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -31
  74. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +27 -0
  75. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +5 -0
  76. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +246 -1
  77. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +4 -0
  78. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +3 -0
  79. package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +4 -2
  80. package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +102 -0
  81. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +59 -0
  82. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +4 -0
  83. package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +11 -0
  84. package/node_modules/@mrclrchtr/supi-lsp/src/manager/capability-index.ts +1 -1
  85. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +2 -1
  86. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +115 -26
  87. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +177 -134
  88. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +214 -0
  89. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +320 -0
  90. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +26 -5
  91. package/node_modules/@mrclrchtr/supi-lsp/src/session/service-registry.ts +81 -4
  92. package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +2 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +18 -37
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +3 -2
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +7 -0
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +56 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/evidence-badge.ts +40 -0
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +5 -0
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +76 -3
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/workspace/runtime.ts +37 -2
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +6 -1
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +31 -0
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +8 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +10 -4
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +1 -0
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +1 -1
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +6 -0
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +9 -2
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +109 -4
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +5 -1
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/LICENSE +21 -0
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/README.md +265 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs +4661 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs.map +7 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js +4605 -0
  132. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js.map +7 -0
  133. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  134. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +57 -0
  135. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +100 -0
  136. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs +4063 -0
  137. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs.map +7 -0
  138. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts +1025 -0
  139. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts.map +58 -0
  140. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1025 -0
  141. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +58 -0
  142. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js +4007 -0
  143. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js.map +7 -0
  144. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  145. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +55 -0
  146. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -12
  147. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +29 -0
  148. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +28 -0
  149. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -0
  150. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +14 -2
  151. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +157 -0
  152. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +8 -1
  153. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +86 -0
  154. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +35 -16
  155. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +1 -0
  156. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +10 -0
  157. package/package.json +14 -9
  158. package/src/{model.ts → analysis/architecture/discovery.ts} +15 -72
  159. package/src/analysis/architecture/model.ts +76 -0
  160. package/src/analysis/brief/directory.ts +324 -0
  161. package/src/analysis/brief/enrich.ts +157 -0
  162. package/src/analysis/brief/file.ts +84 -0
  163. package/src/analysis/brief/inventory.ts +177 -0
  164. package/src/analysis/brief/main.ts +176 -0
  165. package/src/analysis/brief/models.ts +75 -0
  166. package/src/{brief.ts → analysis/brief/public-brief.ts} +21 -26
  167. package/src/analysis/brief/summarize.ts +208 -0
  168. package/src/analysis/brief/types.ts +27 -0
  169. package/src/{use-case/generate-brief.ts → analysis/brief/use-case.ts} +67 -144
  170. package/src/analysis/coverage/coverage-warnings.ts +224 -0
  171. package/src/analysis/evidence.ts +91 -0
  172. package/src/{semantic-action-helpers.ts → analysis/helpers.ts} +4 -4
  173. package/src/analysis/provider.ts +186 -0
  174. package/src/analysis/read-next.ts +126 -0
  175. package/src/analysis/readiness.ts +73 -0
  176. package/src/{refactor → analysis/refactor}/safety.ts +1 -1
  177. package/src/{use-case/support/semantic-references.ts → analysis/references/semantic-refs.ts} +58 -26
  178. package/src/analysis/search/pattern.ts +345 -0
  179. package/src/analysis/search/ripgrep.ts +473 -0
  180. package/src/{git-context.ts → analysis/signals/git.ts} +20 -7
  181. package/src/{prioritization-signals.ts → analysis/signals/project.ts} +33 -19
  182. package/src/analysis/target/anchored.ts +349 -0
  183. package/src/analysis/target/bridge.ts +152 -0
  184. package/src/analysis/target/file-resolution.ts +125 -0
  185. package/src/{targeting/resolve-file.ts → analysis/target/file.ts} +40 -20
  186. package/src/{planner → analysis/target}/planner.ts +30 -20
  187. package/src/{targeting → analysis/target}/query.ts +17 -3
  188. package/src/analysis/target/resolve-common.ts +115 -0
  189. package/src/analysis/target/service.ts +229 -0
  190. package/src/analysis/target/symbol.ts +196 -0
  191. package/src/{targeting → analysis/target}/types.ts +17 -1
  192. package/src/analysis/tests/likely-tests.ts +174 -0
  193. package/src/analysis/tests/test-discovery.ts +540 -0
  194. package/src/analysis/tests/vitest.ts +87 -0
  195. package/src/api.ts +34 -41
  196. package/src/app/app.ts +125 -0
  197. package/src/app/manager.ts +65 -0
  198. package/src/extension.ts +132 -1
  199. package/src/index.ts +1 -57
  200. package/src/session/refactor-plans.ts +82 -0
  201. package/src/session/session.ts +300 -0
  202. package/src/session/target-store.ts +293 -0
  203. package/src/substrate/lsp/diagnostic-injection.ts +218 -0
  204. package/src/substrate/lsp/lifecycle.ts +66 -0
  205. package/src/substrate/lsp/overrides.ts +132 -0
  206. package/src/substrate/lsp/recovery.ts +55 -0
  207. package/src/substrate/lsp/settings.ts +286 -0
  208. package/src/substrate/lsp/state.ts +46 -0
  209. package/src/substrate/lsp/utils.ts +17 -0
  210. package/src/substrate/tree-sitter/lifecycle.ts +52 -0
  211. package/src/tool/find/execute.ts +118 -0
  212. package/src/{presentation/markdown/pattern.ts → tool/find/markdown.ts} +102 -53
  213. package/src/{use-case/generate-pattern.ts → tool/find/orchestrate.ts} +67 -33
  214. package/src/tool/find/semantic-search.ts +114 -0
  215. package/src/tool/find/tui.ts +39 -0
  216. package/src/tool/graph/callees.ts +87 -0
  217. package/src/tool/graph/calls-md.ts +54 -0
  218. package/src/tool/graph/collect-relation.ts +371 -0
  219. package/src/tool/graph/execute.ts +95 -0
  220. package/src/tool/graph/implementations-md.ts +79 -0
  221. package/src/tool/graph/implementations.ts +76 -0
  222. package/src/tool/graph/markdown-base.ts +243 -0
  223. package/src/tool/graph/orchestrate.ts +285 -0
  224. package/src/tool/graph/references-md.ts +34 -0
  225. package/src/tool/graph/references.ts +81 -0
  226. package/src/tool/graph/tui.ts +120 -0
  227. package/src/tool/graph/types.ts +97 -0
  228. package/src/tool/guidance.ts +96 -49
  229. package/src/tool/health/execute.ts +76 -0
  230. package/src/tool/health/markdown.ts +280 -0
  231. package/src/tool/health/orchestrate.ts +159 -0
  232. package/src/tool/health/sections/diagnostics.ts +182 -0
  233. package/src/tool/health/sections/recovery.ts +89 -0
  234. package/src/tool/health/sections/signals.ts +89 -0
  235. package/src/tool/health/tui.ts +137 -0
  236. package/src/tool/impact/analysis.ts +247 -0
  237. package/src/tool/impact/change-set-impact.ts +151 -0
  238. package/src/tool/impact/execute.ts +98 -0
  239. package/src/tool/impact/file-level-impact.ts +81 -0
  240. package/src/tool/impact/markdown.ts +283 -0
  241. package/src/tool/impact/orchestrate.ts +97 -0
  242. package/src/tool/impact/result.ts +21 -0
  243. package/src/tool/impact/single-impact.ts +89 -0
  244. package/src/tool/impact/tui.ts +39 -0
  245. package/src/tool/impact/types.ts +34 -0
  246. package/src/tool/infra/cross-field.ts +335 -0
  247. package/src/tool/infra/error-results.ts +199 -0
  248. package/src/tool/infra/pipeline.ts +311 -0
  249. package/src/tool/infra/progress.ts +21 -0
  250. package/src/tool/infra/readiness-message.ts +5 -0
  251. package/src/tool/infra/truncate.ts +49 -0
  252. package/src/tool/inspect/execute.ts +76 -0
  253. package/src/tool/inspect/markdown.ts +169 -0
  254. package/src/tool/inspect/orchestrate.ts +156 -0
  255. package/src/tool/inspect/tui.ts +36 -0
  256. package/src/tool/orientation/deps.ts +63 -0
  257. package/src/tool/orientation/execute.ts +50 -0
  258. package/src/tool/orientation/markdown.ts +35 -0
  259. package/src/tool/orientation/mode.ts +88 -0
  260. package/src/tool/orientation/orchestrate.ts +478 -0
  261. package/src/tool/orientation/precise-target.ts +257 -0
  262. package/src/tool/orientation/tui.ts +131 -0
  263. package/src/{refactor/apply-workspace-edit.ts → tool/refactor-apply/apply.ts} +39 -16
  264. package/src/tool/refactor-apply/execute.ts +20 -0
  265. package/src/tool/refactor-apply/markdown.ts +118 -0
  266. package/src/tool/refactor-apply/orchestrate.ts +89 -0
  267. package/src/tool/refactor-apply/tui.ts +51 -0
  268. package/src/tool/refactor-plan/execute.ts +73 -0
  269. package/src/tool/refactor-plan/markdown.ts +118 -0
  270. package/src/tool/refactor-plan/orchestrate.ts +363 -0
  271. package/src/tool/refactor-plan/tui.ts +42 -0
  272. package/src/tool/register.ts +123 -0
  273. package/src/tool/resolve/execute.ts +82 -0
  274. package/src/tool/resolve/markdown.ts +150 -0
  275. package/src/tool/resolve/orchestrate.ts +134 -0
  276. package/src/tool/resolve/tui.ts +40 -0
  277. package/src/tool/schemas.ts +337 -0
  278. package/src/tool/specs.ts +257 -0
  279. package/src/types/details.ts +188 -0
  280. package/src/types/execution.ts +60 -0
  281. package/src/types/index.ts +28 -0
  282. package/src/{intent/types.ts → types/tool-names.ts} +15 -14
  283. package/src/ui/footer.ts +52 -0
  284. package/src/ui/markdown/brief.ts +218 -0
  285. package/src/ui/markdown/gather.ts +177 -0
  286. package/src/{use-case/build-overview.ts → ui/markdown/overview-data.ts} +2 -2
  287. package/src/{presentation → ui}/markdown/overview.ts +2 -2
  288. package/src/ui/markdown/types.ts +80 -0
  289. package/{node_modules/@mrclrchtr/supi-lsp/src/ui/renderer.ts → src/ui/message-renderer.ts} +11 -10
  290. package/src/ui/status-command.ts +260 -0
  291. package/src/ui/status-overlay.ts +500 -0
  292. package/src/ui/tui/common.ts +220 -0
  293. package/src/ui/tui/index.ts +37 -0
  294. package/node_modules/@mrclrchtr/supi-lsp/src/extension.ts +0 -1
  295. package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +0 -373
  296. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/diagnostic-injection.ts +0 -182
  297. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/session-lifecycle.ts +0 -149
  298. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/status-command.ts +0 -38
  299. package/node_modules/@mrclrchtr/supi-lsp/src/handlers/workspace-recovery.ts +0 -92
  300. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +0 -37
  301. package/node_modules/@mrclrchtr/supi-lsp/src/session/lsp-state.ts +0 -93
  302. package/node_modules/@mrclrchtr/supi-lsp/src/session/settings-registration.ts +0 -296
  303. package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +0 -75
  304. package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +0 -69
  305. package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +0 -27
  306. package/node_modules/@mrclrchtr/supi-lsp/src/tool/overrides.ts +0 -204
  307. package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +0 -69
  308. package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +0 -399
  309. package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +0 -248
  310. package/node_modules/@mrclrchtr/supi-lsp/src/ui/ui.ts +0 -360
  311. package/node_modules/@mrclrchtr/supi-lsp/src/workspace-change.ts +0 -40
  312. package/node_modules/@mrclrchtr/supi-tree-sitter/src/extension.ts +0 -1
  313. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/formatting.ts +0 -104
  314. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +0 -35
  315. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/handlers.ts +0 -196
  316. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/register-tools.ts +0 -107
  317. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/tool-specs.ts +0 -117
  318. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +0 -47
  319. package/src/brief-focused.ts +0 -563
  320. package/src/code-intelligence.ts +0 -70
  321. package/src/pattern-structured.ts +0 -194
  322. package/src/presentation/markdown/affected.ts +0 -170
  323. package/src/presentation/markdown/brief.ts +0 -174
  324. package/src/presentation/markdown/map.ts +0 -54
  325. package/src/presentation/markdown/refactor.ts +0 -27
  326. package/src/presentation/markdown/relations.ts +0 -121
  327. package/src/resolve-target.ts +0 -130
  328. package/src/search-helpers.ts +0 -303
  329. package/src/substrates/types.ts +0 -30
  330. package/src/target-resolution.ts +0 -122
  331. package/src/targeting/resolve-anchored.ts +0 -80
  332. package/src/targeting/resolve-symbol.ts +0 -110
  333. package/src/tool/execute-affected.ts +0 -71
  334. package/src/tool/execute-brief.ts +0 -59
  335. package/src/tool/execute-map.ts +0 -35
  336. package/src/tool/execute-pattern.ts +0 -29
  337. package/src/tool/execute-refactor.ts +0 -101
  338. package/src/tool/execute-relations.ts +0 -79
  339. package/src/tool/register-tools.ts +0 -32
  340. package/src/tool/tool-specs.ts +0 -190
  341. package/src/tool/validation.ts +0 -43
  342. package/src/types.ts +0 -169
  343. package/src/use-case/generate-affected.ts +0 -297
  344. package/src/use-case/generate-map.ts +0 -176
  345. package/src/use-case/generate-relations.ts +0 -438
  346. package/src/use-case/types.ts +0 -43
  347. package/src/workspace/request-context.ts +0 -139
  348. /package/src/{query-params.ts → tool/params.ts} +0 -0
@@ -0,0 +1,218 @@
1
+ // Diagnostic injection handlers — before_agent_start and context for lsp-context messages.
2
+ //
3
+ // Ported from supi-lsp's diagnostic-injection.ts.
4
+
5
+ import * as nodePath from "node:path";
6
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
7
+ import {
8
+ clearTsconfigCache,
9
+ isLikelyStaleDiagnostic,
10
+ syncWorkspaceSentinelSnapshot,
11
+ } from "@mrclrchtr/supi-lsp/api";
12
+ import type { LspAdapterState } from "./state.ts";
13
+ import { diagnosticMessageString } from "./utils.ts";
14
+
15
+ // LSP_TOOL_NAMES removed — lsp_* tools are no longer registered (TNDM-A9AQF4)
16
+ const LSP_TOOL_NAMES: readonly string[] = [];
17
+
18
+ export function registerDiagnosticInjectionHandlers(
19
+ pi: ExtensionAPI,
20
+ state: LspAdapterState,
21
+ ): void {
22
+ pi.on("before_agent_start", async (_event, _ctx: ExtensionContext) => {
23
+ const manager = state.controller?.manager;
24
+ if (!manager || !state.lspActive) {
25
+ const activeTools = pi.getActiveTools();
26
+ const nextTools = activeTools.filter(
27
+ (t: string) => !LSP_TOOL_NAMES.includes(t as (typeof LSP_TOOL_NAMES)[number]),
28
+ );
29
+ if (nextTools.length !== activeTools.length) {
30
+ pi.setActiveTools(nextTools);
31
+ }
32
+ return;
33
+ }
34
+
35
+ const missing = LSP_TOOL_NAMES.filter((name) => !pi.getActiveTools().includes(name));
36
+ if (missing.length > 0) {
37
+ pi.setActiveTools([...pi.getActiveTools(), ...missing]);
38
+ }
39
+
40
+ // Sentinel refresh: detect lockfile/tsconfig/d.ts changes from outside write/edit
41
+ applySentinelChanges(state, manager);
42
+
43
+ // Stale-module resync: force-reopen files with "Cannot find module" errors
44
+ await resyncStaleModuleFiles(state);
45
+
46
+ // Two-pass prune/refresh for diagnostics
47
+ manager.pruneMissingFiles();
48
+ try {
49
+ await manager.refreshOpenDiagnostics();
50
+ } catch {
51
+ /* best-effort */
52
+ }
53
+ manager.pruneMissingFiles();
54
+
55
+ const diagnostics = manager.getOutstandingDiagnosticSummary(state.inlineSeverity);
56
+ if (!diagnostics || diagnostics.length === 0) {
57
+ state.lastDiagnosticsFingerprint = null;
58
+ state.currentContextToken = null;
59
+ return;
60
+ }
61
+
62
+ state.currentContextToken = `lsp-context-${++state.contextCounter}`;
63
+
64
+ const detailedDiagnostics = manager
65
+ .getOutstandingDiagnostics(state.inlineSeverity)
66
+ .map((entry) => ({
67
+ file: entry.file,
68
+ diagnostics: entry.diagnostics.map((d) => ({
69
+ range: d.range,
70
+ message: diagnosticMessageString(d),
71
+ })),
72
+ }));
73
+
74
+ return {
75
+ message: {
76
+ customType: "lsp-context",
77
+ content: buildInjectionContent(diagnostics, detailedDiagnostics),
78
+ display: true,
79
+ details: {
80
+ contextToken: state.currentContextToken,
81
+ promptContent: buildInjectionContent(diagnostics),
82
+ inlineSeverity: state.inlineSeverity,
83
+ diagnostics: diagnostics.map(
84
+ (d: {
85
+ file: string;
86
+ errors: number;
87
+ warnings: number;
88
+ information: number;
89
+ hints: number;
90
+ }) => ({
91
+ file: d.file,
92
+ errors: d.errors,
93
+ warnings: d.warnings,
94
+ information: d.information,
95
+ hints: d.hints,
96
+ }),
97
+ ),
98
+ },
99
+ },
100
+ };
101
+ });
102
+
103
+ pi.on("context", (event, _ctx) => {
104
+ const messages = event.messages as unknown as Array<Record<string, unknown>>;
105
+ const token = state.currentContextToken;
106
+
107
+ const pruned = messages.filter((m) => {
108
+ if (m.customType !== "lsp-context") return true;
109
+ if (!token) return false;
110
+ const details = m.details as { contextToken?: string } | undefined;
111
+ return details?.contextToken === token;
112
+ });
113
+
114
+ if (pruned.length === event.messages.length) return;
115
+ return { messages: pruned as unknown as typeof event.messages };
116
+ });
117
+ }
118
+
119
+ /** Diff sentinel snapshot and notify manager of changes. */
120
+ // biome-ignore lint/suspicious/noExplicitAny: callback accepts FileEvent[] which satisfies the structural type
121
+ function applySentinelChanges(state: LspAdapterState, manager: any): void {
122
+ const controller = state.controller;
123
+ if (!controller) return;
124
+
125
+ const { snapshot, changes } = syncWorkspaceSentinelSnapshot(
126
+ controller.cwd,
127
+ state.sentinelSnapshot,
128
+ );
129
+ state.sentinelSnapshot = snapshot;
130
+
131
+ if (changes.length === 0) return;
132
+
133
+ clearTsconfigCache();
134
+ manager.clearAllPullResultIds();
135
+ manager.notifyWorkspaceFileChanges(changes);
136
+
137
+ state.staleSuspected = true;
138
+ state.lastDiagnosticsFingerprint = null;
139
+ state.currentContextToken = null;
140
+ state.lastWorkspaceChangeAt = Date.now();
141
+ }
142
+
143
+ /** Re-open files with stale module-resolution errors. */
144
+ async function resyncStaleModuleFiles(state: LspAdapterState): Promise<void> {
145
+ const manager = state.controller?.manager;
146
+ if (!manager) return;
147
+
148
+ const outstanding = manager.getOutstandingDiagnostics(1);
149
+ const staleFiles: string[] = [];
150
+
151
+ for (const entry of outstanding) {
152
+ // biome-ignore lint/suspicious/noExplicitAny: isLikelyStaleDiagnostic accepts Diagnostic, which the manager provides
153
+ if (entry.diagnostics.some((d) => isLikelyStaleDiagnostic(d as any))) {
154
+ staleFiles.push(entry.file);
155
+ }
156
+ }
157
+
158
+ if (staleFiles.length === 0) return;
159
+
160
+ const cwd = state.controller?.cwd ?? "";
161
+ for (const file of staleFiles) {
162
+ const filePath = nodePath.resolve(cwd, file);
163
+ manager.closeFile(filePath);
164
+ await manager.ensureFileOpen(filePath);
165
+ }
166
+
167
+ try {
168
+ await manager.refreshOpenDiagnostics({ quietMs: 300, maxWaitMs: 2000 });
169
+ } catch {
170
+ /* best-effort */
171
+ }
172
+ }
173
+
174
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: diagnostic formatting logic
175
+ function buildInjectionContent(
176
+ diagnostics: Array<{ file: string; errors: number; warnings: number }>,
177
+ detailed?: Array<{
178
+ file: string;
179
+ diagnostics: Array<{ message: string; range: { start: { line: number } } }>;
180
+ }>,
181
+ ): string {
182
+ if (!diagnostics || diagnostics.length === 0) return "";
183
+
184
+ const parts: string[] = [
185
+ '<extension-context source="supi-code-intelligence">',
186
+ "Outstanding LSP diagnostics:",
187
+ ];
188
+
189
+ for (const diag of diagnostics.slice(0, 15)) {
190
+ const pieces: string[] = [];
191
+ if (diag.errors > 0) pieces.push(`${diag.errors} error${diag.errors > 1 ? "s" : ""}`);
192
+ if (diag.warnings > 0) pieces.push(`${diag.warnings} warning${diag.warnings > 1 ? "s" : ""}`);
193
+ parts.push(`- ${diag.file}: ${pieces.join(", ")}`);
194
+ }
195
+
196
+ if (diagnostics.length > 15) {
197
+ parts.push(`... and ${diagnostics.length - 15} more files`);
198
+ }
199
+
200
+ if (detailed) {
201
+ for (const entry of detailed.slice(0, 5)) {
202
+ for (const d of entry.diagnostics.slice(0, 5)) {
203
+ parts.push(` ${d.range.start.line + 1}: ${d.message}`);
204
+ }
205
+ }
206
+ }
207
+
208
+ parts.push("</extension-context>");
209
+
210
+ const totalErrors = diagnostics.reduce((s: number, d: { errors: number }) => s + d.errors, 0);
211
+ if (totalErrors > 0) {
212
+ parts.push("");
213
+ parts.push(`Found ${totalErrors} errors across the workspace.`);
214
+ parts.push("Use code_health to inspect issues.");
215
+ }
216
+
217
+ return parts.join("\n");
218
+ }
@@ -0,0 +1,66 @@
1
+ // LSP session lifecycle — uses LspRuntimeController from @mrclrchtr/supi-lsp/api.
2
+ //
3
+ // Registers session_start and session_shutdown handlers that manage
4
+ // the LspRuntimeController lifecycle.
5
+
6
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
7
+ import { getDefaultWorkspaceRuntime } from "@mrclrchtr/supi-code-runtime/api";
8
+ import {
9
+ LspRuntimeController,
10
+ loadLspSettings,
11
+ scanWorkspaceSentinels,
12
+ } from "@mrclrchtr/supi-lsp/api";
13
+ import { unregisterLspFooterContribution } from "../../ui/footer.ts";
14
+ import type { LspAdapterState } from "./state.ts";
15
+
16
+ export function registerLspSessionLifecycle(pi: ExtensionAPI, state: LspAdapterState): void {
17
+ pi.on("session_start", async (_event, ctx: ExtensionContext) => {
18
+ const cwd = ctx.cwd;
19
+ const runtime = getDefaultWorkspaceRuntime();
20
+
21
+ if (state.controller) {
22
+ await state.controller.shutdown();
23
+ state.controller = null;
24
+ }
25
+ resetDiagnosticContext(state);
26
+ state.lspActive = false;
27
+
28
+ const lspSettings = loadLspSettings(cwd);
29
+ // Always-on policy: `lsp.enabled` is deprecated and ignored. Keep reading
30
+ // settings for severity/exclude data, but let LspRuntimeController decide
31
+ // startup and per-language disables.
32
+ state.inlineSeverity = lspSettings.severity;
33
+
34
+ const controller = new LspRuntimeController(cwd, runtime);
35
+ const result = await controller.start();
36
+
37
+ if (result.kind === "ready") {
38
+ state.controller = controller;
39
+ state.lspActive = true;
40
+ state.sentinelSnapshot = scanWorkspaceSentinels(cwd);
41
+ } else {
42
+ state.controller = null;
43
+ resetDiagnosticContext(state);
44
+ state.lspActive = false;
45
+ }
46
+ });
47
+
48
+ pi.on("session_shutdown", async (_event, _ctx: ExtensionContext) => {
49
+ if (state.controller) {
50
+ await state.controller.shutdown();
51
+ state.controller = null;
52
+ }
53
+ resetDiagnosticContext(state);
54
+ state.lspActive = false;
55
+ unregisterLspFooterContribution();
56
+ });
57
+ }
58
+
59
+ /** Clear diagnostic context fields that could leak across sessions. */
60
+ function resetDiagnosticContext(state: LspAdapterState): void {
61
+ state.currentContextToken = null;
62
+ state.lastDiagnosticsFingerprint = null;
63
+ state.staleSuspected = false;
64
+ state.lastWorkspaceChangeAt = 0;
65
+ state.contextCounter = 0;
66
+ }
@@ -0,0 +1,132 @@
1
+ // LSP-aware tool overrides — ports read/write/edit overrides from supi-lsp.
2
+ //
3
+ // Opens files on read, appends inline diagnostics after write/edit.
4
+ // biome-ignore-all lint/complexity/useMaxParams: pi ToolDefinition.execute signature requires 5 params.
5
+
6
+ import * as nodePath from "node:path";
7
+ import type {
8
+ AgentToolUpdateCallback,
9
+ EditToolInput,
10
+ ExtensionAPI,
11
+ ExtensionContext,
12
+ ReadToolInput,
13
+ WriteToolInput,
14
+ } from "@earendil-works/pi-coding-agent";
15
+ import { createEditTool, createReadTool, createWriteTool } from "@earendil-works/pi-coding-agent";
16
+ import type { LspAdapterState } from "./state.ts";
17
+ import { diagnosticMessageString } from "./utils.ts";
18
+
19
+ export function registerLspAwareToolOverrides(pi: ExtensionAPI, state: LspAdapterState): void {
20
+ const readMeta = createReadTool(process.cwd());
21
+ const writeMeta = createWriteTool(process.cwd());
22
+ const editMeta = createEditTool(process.cwd());
23
+
24
+ pi.registerTool({
25
+ ...readMeta,
26
+ execute: makeReadExecutor(state),
27
+ });
28
+
29
+ pi.registerTool({
30
+ ...writeMeta,
31
+ execute: makeWriteExecutor(state),
32
+ });
33
+
34
+ pi.registerTool({
35
+ ...editMeta,
36
+ execute: makeEditExecutor(state),
37
+ });
38
+ }
39
+
40
+ function makeReadExecutor(state: LspAdapterState) {
41
+ return async (
42
+ toolCallId: string,
43
+ params: ReadToolInput,
44
+ signal: AbortSignal | undefined,
45
+ onUpdate: AgentToolUpdateCallback | undefined,
46
+ ctx: ExtensionContext,
47
+ ) => {
48
+ const originalRead = createReadTool(ctx.cwd);
49
+ const result = await originalRead.execute(toolCallId, params, signal, onUpdate);
50
+ if (!state.lspActive || !state.controller?.manager) return result;
51
+ try {
52
+ await state.controller.manager.ensureFileOpen(resolveSessionPath(ctx.cwd, params.path));
53
+ } catch {
54
+ /* never block the agent */
55
+ }
56
+ return result;
57
+ };
58
+ }
59
+
60
+ function makeWriteExecutor(state: LspAdapterState) {
61
+ return async (
62
+ toolCallId: string,
63
+ params: WriteToolInput,
64
+ signal: AbortSignal | undefined,
65
+ onUpdate: AgentToolUpdateCallback | undefined,
66
+ ctx: ExtensionContext,
67
+ ) => {
68
+ const originalWrite = createWriteTool(ctx.cwd);
69
+ const result = await originalWrite.execute(toolCallId, params, signal, onUpdate);
70
+ if (!state.lspActive) return result;
71
+ return appendInlineDiagnostics(state, ctx.cwd, params.path, result);
72
+ };
73
+ }
74
+
75
+ function makeEditExecutor(state: LspAdapterState) {
76
+ return async (
77
+ toolCallId: string,
78
+ params: EditToolInput,
79
+ signal: AbortSignal | undefined,
80
+ onUpdate: AgentToolUpdateCallback | undefined,
81
+ ctx: ExtensionContext,
82
+ ) => {
83
+ const originalEdit = createEditTool(ctx.cwd);
84
+ const result = await originalEdit.execute(toolCallId, params, signal, onUpdate);
85
+ if (!state.lspActive) return result;
86
+ return appendInlineDiagnostics(state, ctx.cwd, params.path, result);
87
+ };
88
+ }
89
+
90
+ async function appendInlineDiagnostics<T extends { content: unknown[]; details: unknown }>(
91
+ state: LspAdapterState,
92
+ cwd: string,
93
+ filePath: string,
94
+ result: T,
95
+ ): Promise<T> {
96
+ const manager = state.controller?.manager;
97
+ if (!manager) return result;
98
+
99
+ try {
100
+ const resolved = resolveSessionPath(cwd, filePath);
101
+ const effectiveSeverity = Math.max(state.inlineSeverity, 2);
102
+ const entries = await manager.syncFileAndGetCascadingDiagnostics(resolved, effectiveSeverity);
103
+ if (entries.length === 0) return result;
104
+
105
+ // biome-ignore format: manual formatting for readability
106
+ const lines = [
107
+ "\n\n⚠️ LSP Diagnostics — review before continuing:",
108
+ ...entries.flatMap((entry) =>
109
+ entry.diagnostics.map(
110
+ (d) =>
111
+ ` ${entry.file}:${d.range.start.line + 1}: ${diagnosticMessageString(d)}`,
112
+ ),
113
+ ),
114
+ "If these errors are unexpected or appear across multiple files, fix the root cause before editing more.",
115
+ ];
116
+
117
+ const diagnosticContent = {
118
+ type: "text" as const,
119
+ text: lines.join("\n"),
120
+ } as T["content"][number];
121
+
122
+ return { ...result, content: [...result.content, diagnosticContent] } as T;
123
+ } catch {
124
+ return result;
125
+ }
126
+ }
127
+
128
+ function resolveSessionPath(cwd: string, filePath: string): string {
129
+ if (nodePath.isAbsolute(filePath)) return filePath;
130
+ if (filePath.startsWith("@")) return nodePath.resolve(cwd, filePath.slice(1));
131
+ return nodePath.resolve(cwd, filePath);
132
+ }
@@ -0,0 +1,55 @@
1
+ // Workspace recovery handler — tool_result event that recovers LSP state after write/edit.
2
+ //
3
+ // Notifies the LSP manager about file changes so diagnostics stay fresh.
4
+
5
+ import * as nodePath from "node:path";
6
+ import type {
7
+ ExtensionAPI,
8
+ ExtensionContext,
9
+ ToolResultEvent,
10
+ } from "@earendil-works/pi-coding-agent";
11
+ import { clearTsconfigCache } from "@mrclrchtr/supi-lsp/api";
12
+ import type { LspAdapterState } from "./state.ts";
13
+
14
+ export function registerWorkspaceRecoveryHandler(pi: ExtensionAPI, state: LspAdapterState): void {
15
+ pi.on("tool_result", async (event: ToolResultEvent, _ctx: ExtensionContext) => {
16
+ const manager = state.controller?.manager;
17
+ if (!manager || event.isError) return;
18
+
19
+ const filePath = getFilePathFromToolResult(event);
20
+ if (!filePath) return;
21
+
22
+ // Normalize @-prefixed paths (pi's built-in file tool convention)
23
+ const normalized = filePath.startsWith("@") ? filePath.slice(1) : filePath;
24
+ const resolved = nodePath.resolve(state.controller?.cwd ?? "", normalized);
25
+
26
+ // Invalidate tsconfig cache when config files change
27
+ const ext = nodePath.extname(resolved).toLowerCase();
28
+ if (ext === ".json" || ext === ".jsonc") {
29
+ clearTsconfigCache();
30
+ }
31
+
32
+ manager.clearAllPullResultIds();
33
+ manager.notifyWorkspaceFileChanges([{ uri: filePathToUri(resolved), type: 2 }]);
34
+
35
+ state.staleSuspected = true;
36
+ state.lastDiagnosticsFingerprint = null;
37
+ state.currentContextToken = null;
38
+ state.lastWorkspaceChangeAt = Date.now();
39
+ });
40
+ }
41
+
42
+ function getFilePathFromToolResult(event: ToolResultEvent): string | null {
43
+ if (event.isError) return null;
44
+ if (event.toolName !== "write" && event.toolName !== "edit") return null;
45
+ const input = (event as { input?: Record<string, unknown> }).input;
46
+ if (!input || typeof input !== "object") return null;
47
+ const pathValue = input.path;
48
+ if (typeof pathValue !== "string" || !pathValue) return null;
49
+ return pathValue;
50
+ }
51
+
52
+ function filePathToUri(filePath: string): string {
53
+ const normalized = filePath.replace(/\\/g, "/");
54
+ return `file://${normalized.startsWith("/") ? "" : "/"}${normalized}`;
55
+ }