@mrclrchtr/supi-code-intelligence 4.9.0 → 5.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 (215) hide show
  1. package/README.md +2 -1
  2. package/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  3. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  4. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  6. package/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  8. package/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  9. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  10. package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  11. package/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  12. package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
  13. package/node_modules/@mrclrchtr/supi-core/src/debug-timing.ts +34 -21
  14. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  15. package/node_modules/@mrclrchtr/supi-lsp/README.md +80 -5
  16. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  17. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  18. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  19. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  20. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  21. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  22. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  23. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  24. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  25. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  26. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
  27. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-timing.ts +34 -21
  28. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  29. package/node_modules/@mrclrchtr/supi-lsp/package.json +7 -6
  30. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +10 -0
  31. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +206 -0
  32. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +78 -0
  33. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +114 -0
  34. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +372 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +14 -0
  36. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +62 -0
  37. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +491 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +9 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +215 -0
  40. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +206 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +370 -266
  42. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +52 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +185 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-file-state.ts +25 -0
  45. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +467 -115
  46. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +238 -11
  47. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +10 -1
  48. package/node_modules/@mrclrchtr/supi-lsp/src/config/defaults.json +1 -1
  49. package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +45 -0
  50. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +38 -0
  51. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +79 -9
  52. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +13 -4
  53. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +300 -24
  54. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +5 -2
  55. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +464 -96
  56. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-refactor-provider.ts +130 -0
  57. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +45 -329
  58. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +57 -120
  59. package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-edit-normalizer.ts +320 -0
  60. package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +207 -0
  61. package/node_modules/@mrclrchtr/supi-lsp/src/session/readiness.ts +72 -2
  62. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +151 -26
  63. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +40 -0
  64. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +50 -0
  65. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +136 -120
  66. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +49 -0
  67. package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +102 -0
  68. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +26 -6
  69. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  70. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  71. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  72. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  73. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  74. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  75. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  76. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  77. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  78. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  79. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
  80. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-timing.ts +34 -21
  81. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  82. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/LICENSE +21 -0
  83. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/README.md +258 -0
  84. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/babel.cjs +257 -0
  85. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/jiti.cjs +1 -0
  86. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-cli.mjs +34 -0
  87. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-hooks.mjs +124 -0
  88. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-native.mjs +121 -0
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.d.mts +1 -0
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.mjs +4 -0
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-static.mjs +23 -0
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.cjs +30 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.cts +8 -0
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.mts +8 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.mjs +29 -0
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/types.d.ts +420 -0
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/package.json +146 -0
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +4 -4
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +1 -1
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +4 -4
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +7 -3
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/kotlin/tree-sitter-kotlin.wasm.json +1 -1
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/sql/tree-sitter-sql.wasm.json +1 -1
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +0 -9
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -8
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +16 -12
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +65 -87
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +47 -95
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-timing.ts +147 -0
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client-lifecycle.ts +39 -0
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +561 -0
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-message-size.ts +24 -0
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +452 -0
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +4 -2
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +12 -4
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +4 -2
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/imports.ts +4 -2
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +5 -3
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +33 -12
  122. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/blocking-test-bootstrap.mjs +34 -0
  123. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/bootstrap.mjs +8 -0
  124. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store-helpers.ts +23 -0
  125. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +400 -0
  126. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/request-control.ts +48 -0
  127. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-parser-helpers.ts +24 -0
  128. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-query-helpers.ts +43 -0
  129. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +421 -0
  130. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +116 -0
  131. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +201 -0
  132. package/package.json +5 -5
  133. package/src/analysis/health/diagnostics.ts +236 -24
  134. package/src/analysis/health/recovery.ts +6 -2
  135. package/src/analysis/provider.ts +58 -0
  136. package/src/analysis/readiness.ts +30 -9
  137. package/src/analysis/refactor/apply.ts +59 -20
  138. package/src/analysis/refactor/mutation-authority.ts +143 -0
  139. package/src/analysis/refactor/position.ts +47 -0
  140. package/src/analysis/refactor/safety.ts +18 -10
  141. package/src/analysis/relations/callees.ts +9 -1
  142. package/src/analysis/relations/types.ts +5 -2
  143. package/src/analysis/search/ast-scan-timing.ts +9 -4
  144. package/src/analysis/search/ast-scan.ts +1 -1
  145. package/src/analysis/search/deadline.ts +2 -2
  146. package/src/analysis/search/pattern-analysis.ts +46 -32
  147. package/src/analysis/search/pattern.ts +12 -2
  148. package/src/analysis/target/anchored.ts +20 -11
  149. package/src/analysis/target/file.ts +18 -11
  150. package/src/analysis/target/identity.ts +19 -3
  151. package/src/analysis/target/symbol.ts +36 -15
  152. package/src/api.ts +4 -0
  153. package/src/diagnostics/evidence.ts +51 -0
  154. package/src/session/capability-adapter.ts +12 -3
  155. package/src/session/find-workflow.ts +17 -7
  156. package/src/session/graph/collect.ts +18 -2
  157. package/src/session/graph-workflow.ts +19 -12
  158. package/src/session/health-refresh.ts +148 -0
  159. package/src/session/health-types.ts +37 -15
  160. package/src/session/health-workflow.ts +37 -39
  161. package/src/session/inspect/collect.ts +20 -3
  162. package/src/session/inspect-workflow.ts +10 -5
  163. package/src/session/orientation/collect.ts +10 -1
  164. package/src/session/orientation/context-facts.ts +3 -1
  165. package/src/session/orientation/context-sections.ts +20 -7
  166. package/src/session/orientation/gather.ts +17 -11
  167. package/src/session/orientation-types.ts +2 -1
  168. package/src/session/orientation-workflow.ts +15 -8
  169. package/src/session/refactor-plans.ts +2 -0
  170. package/src/session/refactor-workflow.ts +59 -14
  171. package/src/session/session.ts +4 -1
  172. package/src/session/target-workflow.ts +54 -23
  173. package/src/session/workflow-control.ts +7 -3
  174. package/src/substrate/lsp/lifecycle.ts +26 -46
  175. package/src/substrate/lsp/maintenance.ts +199 -25
  176. package/src/substrate/lsp/state.ts +2 -2
  177. package/src/substrate/workspace-provider-host.ts +25 -3
  178. package/src/tool/find/execute.ts +7 -1
  179. package/src/tool/find/render.ts +20 -3
  180. package/src/tool/find/tui.ts +23 -21
  181. package/src/tool/graph/execute.ts +23 -3
  182. package/src/tool/graph/tui.ts +59 -46
  183. package/src/tool/health/execute.ts +7 -2
  184. package/src/tool/health/markdown.ts +56 -14
  185. package/src/tool/health/refresh-status.ts +105 -0
  186. package/src/tool/health/tui.ts +95 -98
  187. package/src/tool/infra/workflow-control.ts +8 -0
  188. package/src/tool/inspect/execute.ts +7 -1
  189. package/src/tool/inspect/tui.ts +26 -18
  190. package/src/tool/orientation/execute.ts +21 -3
  191. package/src/tool/orientation/tui.ts +51 -35
  192. package/src/tool/refactor-apply/execute.ts +3 -0
  193. package/src/tool/refactor-apply/tui.ts +43 -25
  194. package/src/tool/refactor-plan/execute.ts +4 -0
  195. package/src/tool/refactor-plan/tui.ts +33 -20
  196. package/src/tool/register.ts +127 -22
  197. package/src/tool/resolve/execute.ts +18 -1
  198. package/src/tool/resolve/tui.ts +42 -24
  199. package/src/tool/result/display.ts +107 -0
  200. package/src/tool/result/errors.ts +20 -17
  201. package/src/tool/result/find.ts +52 -8
  202. package/src/tool/result/graph.ts +44 -1
  203. package/src/tool/result/health.ts +53 -1
  204. package/src/tool/result/inspect.ts +113 -1
  205. package/src/tool/result/orientation.ts +66 -14
  206. package/src/tool/result/refactor.ts +36 -4
  207. package/src/tool/result/resolve.ts +44 -7
  208. package/src/tool/result/types.ts +20 -0
  209. package/src/types/execution.ts +18 -5
  210. package/src/types/index.ts +8 -1
  211. package/src/ui/status-command.ts +5 -3
  212. package/src/ui/status-overlay.ts +4 -0
  213. package/src/ui/tui/common.ts +108 -10
  214. package/src/ui/tui/display.ts +48 -0
  215. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime.ts +0 -247
@@ -1,12 +1,15 @@
1
- import type {
2
- CodeResult,
3
- OutlineData,
4
- StructuralProvider as StructuralSubstrate,
1
+ import {
2
+ type CodeRequestControl,
3
+ type CodeResult,
4
+ isCodeRequestDeadlineError,
5
+ isCodeRequestInterruption,
6
+ type OutlineData,
7
+ type StructuralProvider as StructuralSubstrate,
5
8
  } from "@mrclrchtr/supi-code-runtime/api";
6
9
  import type { CodeFindAstKind } from "../../tool/find/ast-kinds.ts";
7
10
  import type { AstScanLimitation } from "./ast-scan.ts";
8
11
  import { callableExpressionForMatching } from "./call-name.ts";
9
- import { settleByDeadline } from "./deadline.ts";
12
+ import { type DeadlineOutcome, settleByDeadline } from "./deadline.ts";
10
13
  import { relativeDisplayPath } from "./paths.ts";
11
14
 
12
15
  export interface StructuredPatternParams {
@@ -52,6 +55,7 @@ interface AnalyzeStructuredFilesOptions {
52
55
  readonly deadline: number;
53
56
  readonly now: () => number;
54
57
  readonly signal?: AbortSignal;
58
+ readonly requestControl: CodeRequestControl;
55
59
  readonly initialLimitations: readonly AstScanLimitation[];
56
60
  }
57
61
 
@@ -67,34 +71,43 @@ export async function analyzeStructuredFiles(
67
71
 
68
72
  for (const [index, absoluteFile] of options.files.entries()) {
69
73
  options.signal?.throwIfAborted();
70
- if (options.now() > options.deadline) {
74
+ if (options.now() >= options.deadline) {
71
75
  addAnalysisTimeout(limitations, options.files.slice(index), options.displayBase);
72
76
  break;
73
77
  }
74
78
  const relativeFile = relativeDisplayPath(options.displayBase, absoluteFile);
75
79
  const fileMatches: StructuredMatch[] = [];
76
80
  const fileFailures: StructuredFailure[] = [];
77
- const outcome = await settleByDeadline(
78
- async () => {
79
- try {
80
- await collectMatchesForFile(
81
- fileMatches,
82
- fileFailures,
83
- options.structural,
84
- relativeFile,
85
- options.params.kind,
86
- matcher,
87
- );
88
- } catch (error) {
89
- fileFailures.push({
90
- file: relativeFile,
91
- kind: "runtime-error",
92
- reason: errorMessage(error),
93
- });
94
- }
95
- },
96
- { deadline: options.deadline, now: options.now, signal: options.signal },
97
- );
81
+ let outcome: DeadlineOutcome<void>;
82
+ try {
83
+ outcome = await settleByDeadline(
84
+ async () => {
85
+ try {
86
+ await collectMatchesForFile(
87
+ fileMatches,
88
+ fileFailures,
89
+ options.structural,
90
+ relativeFile,
91
+ options.params.kind,
92
+ matcher,
93
+ options.requestControl,
94
+ );
95
+ } catch (error) {
96
+ if (isCodeRequestInterruption(error, options.requestControl)) throw error;
97
+ fileFailures.push({
98
+ file: relativeFile,
99
+ kind: "runtime-error",
100
+ reason: errorMessage(error),
101
+ });
102
+ }
103
+ },
104
+ { deadline: options.deadline, now: options.now, signal: options.signal },
105
+ );
106
+ } catch (error) {
107
+ if (!isCodeRequestDeadlineError(error)) throw error;
108
+ addAnalysisTimeout(limitations, options.files.slice(index), options.displayBase);
109
+ break;
110
+ }
98
111
  if (outcome.kind === "timeout") {
99
112
  addAnalysisTimeout(limitations, options.files.slice(index), options.displayBase);
100
113
  break;
@@ -137,13 +150,14 @@ async function collectMatchesForFile(
137
150
  relFile: string,
138
151
  kind: CodeFindAstKind,
139
152
  matcher: (value: string) => boolean,
153
+ requestControl: CodeRequestControl,
140
154
  ): Promise<void> {
141
155
  const recordFailure = (kind: StructuredFailureKind, reason: string) => {
142
156
  failures.push({ file: relFile, kind, reason });
143
157
  };
144
158
 
145
159
  if (kind === "definition") {
146
- const outline = await structural.outline(relFile);
160
+ const outline = await structural.outline(relFile, requestControl);
147
161
  if (!handleStructuralResult(outline, recordFailure)) return;
148
162
  for (const item of flattenOutlineItems(outline.data)) {
149
163
  if (!matcher(item.name)) continue;
@@ -153,7 +167,7 @@ async function collectMatchesForFile(
153
167
  }
154
168
 
155
169
  if (kind === "export") {
156
- const exportsResult = await structural.exports(relFile);
170
+ const exportsResult = await structural.exports(relFile, requestControl);
157
171
  if (!handleStructuralResult(exportsResult, recordFailure)) return;
158
172
  for (const item of exportsResult.data) {
159
173
  if (!matcher(item.name)) continue;
@@ -163,7 +177,7 @@ async function collectMatchesForFile(
163
177
  }
164
178
 
165
179
  if (kind === "import") {
166
- const importsResult = await structural.imports(relFile);
180
+ const importsResult = await structural.imports(relFile, requestControl);
167
181
  if (!handleStructuralResult(importsResult, recordFailure)) return;
168
182
  for (const item of importsResult.data) {
169
183
  if (!matcher(item.moduleSpecifier)) continue;
@@ -178,7 +192,7 @@ async function collectMatchesForFile(
178
192
  }
179
193
 
180
194
  if (kind === "call") {
181
- const callResult = await structural.callSites(relFile);
195
+ const callResult = await structural.callSites(relFile, requestControl);
182
196
  if (!handleStructuralResult(callResult, recordFailure)) return;
183
197
  for (const call of callResult.data) {
184
198
  if (!matcher(callableExpressionForMatching(call.name))) continue;
@@ -187,7 +201,7 @@ async function collectMatchesForFile(
187
201
  return;
188
202
  }
189
203
 
190
- const outline = await structural.outline(relFile);
204
+ const outline = await structural.outline(relFile, requestControl);
191
205
  if (!handleStructuralResult(outline, recordFailure)) return;
192
206
  for (const item of flattenOutlineItems(outline.data)) {
193
207
  if (kind === "type" && !TYPE_KIND.test(item.kind.toLowerCase())) continue;
@@ -56,11 +56,14 @@ export type StructuredPatternOutcome =
56
56
 
57
57
  /** Internal controls for deterministic deadline, filesystem, and cancellation tests. */
58
58
  export interface StructuredPatternControl {
59
+ readonly operationId?: string;
59
60
  readonly signal?: AbortSignal;
60
61
  readonly now?: () => number;
61
62
  readonly operations?: AstScanOperations;
62
63
  readonly maxFiles?: number;
63
64
  readonly timeoutMs?: number;
65
+ /** Optional caller deadline; the earlier caller/policy deadline wins. */
66
+ readonly deadline?: number;
64
67
  }
65
68
 
66
69
  export interface StructuredPatternSearchOptions {
@@ -80,11 +83,12 @@ export interface StructuredPatternSearchOptions {
80
83
  export async function getStructuredPatternMatches(
81
84
  options: StructuredPatternSearchOptions,
82
85
  ): Promise<StructuredPatternOutcome> {
83
- const scanTimer = startAstScanTimer();
86
+ const scanTimer = startAstScanTimer(options.control, options.cwd);
84
87
  const now = options.control?.now ?? Date.now;
85
88
  const maxFiles = options.control?.maxFiles ?? DEFAULT_AST_SCAN_MAX_FILES;
86
89
  const timeoutMs = options.control?.timeoutMs ?? DEFAULT_AST_SCAN_TIMEOUT_MS;
87
- const deadline = now() + timeoutMs;
90
+ const policyDeadline = now() + timeoutMs;
91
+ const deadline = Math.min(options.control?.deadline ?? Number.POSITIVE_INFINITY, policyDeadline);
88
92
  const roots = Array.isArray(options.roots) ? [...options.roots] : [options.roots];
89
93
  const operation = structuralOperationForKind(options.params.kind);
90
94
  options.control?.signal?.throwIfAborted();
@@ -127,6 +131,11 @@ export async function getStructuredPatternMatches(
127
131
  }
128
132
 
129
133
  scanTimer.enumerationCompleted();
134
+ const requestControl = {
135
+ operationId: options.control?.operationId,
136
+ signal: options.control?.signal,
137
+ deadline,
138
+ };
130
139
  const analysis = await analyzeStructuredFiles({
131
140
  files: enumeration.files,
132
141
  displayBase: enumeration.displayBase,
@@ -135,6 +144,7 @@ export async function getStructuredPatternMatches(
135
144
  deadline,
136
145
  now,
137
146
  signal: options.control?.signal,
147
+ requestControl,
138
148
  initialLimitations: enumeration.limitations,
139
149
  });
140
150
  const capabilityMismatches = analysis.failures.filter(
@@ -9,12 +9,14 @@
9
9
 
10
10
  import * as fs from "node:fs";
11
11
  import * as path from "node:path";
12
- import type {
13
- CodeResult,
14
- CodeSymbol,
15
- NodeAtData,
16
- SemanticProvider,
17
- StructuralProvider,
12
+ import {
13
+ type CodeRequestControl,
14
+ type CodeResult,
15
+ type CodeSymbol,
16
+ isCodeRequestInterruption,
17
+ type NodeAtData,
18
+ type SemanticProvider,
19
+ type StructuralProvider,
18
20
  } from "@mrclrchtr/supi-code-runtime/api";
19
21
  import type { AnchorKind } from "../../session/target-store.ts";
20
22
  import type { AnchoredResolutionMetadata, AnchoredResolutionSource } from "../../types/index.ts";
@@ -217,17 +219,20 @@ async function candidatesFromSymbols(
217
219
  }
218
220
 
219
221
  /** Layer 1: match the coordinate against LSP document symbols. Returns null to fall through. */
222
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: layered anchored resolution keeps layer-1 symbol matching and identity resolution together.
220
223
  async function resolveFromSemantic(
221
224
  file: string,
222
225
  requested: Anchor,
223
226
  provider: AnchoredResolverProvider,
227
+ control?: CodeRequestControl,
224
228
  ): Promise<TargetOutcome | null> {
225
229
  if (!provider.documentSymbols) return null;
226
230
  let symbols: CodeSymbol[] = [];
227
231
  try {
228
232
  const result = await provider.documentSymbols(file);
229
233
  if (result.kind !== "unavailable") symbols = result.data;
230
- } catch {
234
+ } catch (error) {
235
+ if (isCodeRequestInterruption(error, control)) throw error;
231
236
  symbols = [];
232
237
  }
233
238
  if (symbols.length === 0) return null;
@@ -241,7 +246,7 @@ async function resolveFromSemantic(
241
246
  }
242
247
 
243
248
  const structural = provider.nodeAt ? { nodeAt: provider.nodeAt } : undefined;
244
- const resolveIdentity = createCodeSymbolIdentityResolver(file, symbols, structural);
249
+ const resolveIdentity = createCodeSymbolIdentityResolver(file, symbols, structural, control);
245
250
  if (exact.length === 1) {
246
251
  return resolvedFromSymbol(file, exact[0], {
247
252
  snapped: false,
@@ -268,12 +273,14 @@ async function resolveFromStructural(
268
273
  file: string,
269
274
  requested: Anchor,
270
275
  provider: AnchoredResolverProvider,
276
+ control?: CodeRequestControl,
271
277
  ): Promise<TargetOutcome | null> {
272
278
  if (!provider.nodeAt) return null;
273
279
  let nodeResult: CodeResult<NodeAtData> | null = null;
274
280
  try {
275
281
  nodeResult = await provider.nodeAt(file, requested.line, requested.character);
276
- } catch {
282
+ } catch (error) {
283
+ if (isCodeRequestInterruption(error, control)) throw error;
277
284
  nodeResult = null;
278
285
  }
279
286
  if (nodeResult?.kind !== "success") return null;
@@ -351,11 +358,13 @@ async function resolveFromStructural(
351
358
  * This does not perform heuristic global text search and does not silently
352
359
  * treat declaration anchors as name anchors (ADR 0003).
353
360
  */
361
+ // biome-ignore lint/complexity/useMaxParams: anchored resolution is a stable public resolver boundary with fixed positional fields.
354
362
  export async function resolveAnchoredSymbolTarget(
355
363
  file: string,
356
364
  line: number,
357
365
  character: number,
358
366
  provider: AnchoredResolverProvider | null,
367
+ control?: CodeRequestControl,
359
368
  ): Promise<TargetOutcome> {
360
369
  if (!fs.existsSync(file)) {
361
370
  return { kind: "error", message: `File not found: \`${file}\`` };
@@ -369,9 +378,9 @@ export async function resolveAnchoredSymbolTarget(
369
378
 
370
379
  const requested: Anchor = { line, character };
371
380
  if (provider) {
372
- const semantic = await resolveFromSemantic(file, requested, provider);
381
+ const semantic = await resolveFromSemantic(file, requested, provider, control);
373
382
  if (semantic) return semantic;
374
- const structural = await resolveFromStructural(file, requested, provider);
383
+ const structural = await resolveFromStructural(file, requested, provider, control);
375
384
  if (structural) return structural;
376
385
  }
377
386
 
@@ -9,12 +9,14 @@
9
9
 
10
10
  import * as fs from "node:fs";
11
11
  import * as path from "node:path";
12
- import type {
13
- DeclarationNesting,
14
- DocumentCodeSymbol,
15
- OutlineData,
16
- SemanticProvider as SemanticSubstrate,
17
- StructuralProvider as StructuralSubstrate,
12
+ import {
13
+ type CodeRequestControl,
14
+ type DeclarationNesting,
15
+ type DocumentCodeSymbol,
16
+ isCodeRequestInterruption,
17
+ type OutlineData,
18
+ type SemanticProvider as SemanticSubstrate,
19
+ type StructuralProvider as StructuralSubstrate,
18
20
  } from "@mrclrchtr/supi-code-runtime/api";
19
21
  import type { AnchorKind } from "../../session/target-store.ts";
20
22
  import { normalizePath } from "../search/paths.ts";
@@ -80,6 +82,7 @@ export async function resolveFileTargetGroup(
80
82
  semantic?: SemanticSubstrate;
81
83
  structural?: StructuralSubstrate;
82
84
  } = {},
85
+ control?: CodeRequestControl,
83
86
  ): Promise<
84
87
  | { kind: "resolved"; group: ResolvedTargetGroupData }
85
88
  | { kind: "invalid-input"; message: string }
@@ -90,8 +93,8 @@ export async function resolveFileTargetGroup(
90
93
  const resolvedFile = validation.file;
91
94
 
92
95
  const [semantic, structural] = await Promise.all([
93
- discoverSemantic(resolvedFile, deps.semantic, deps.structural),
94
- discoverStructural(resolvedFile, deps.structural),
96
+ discoverSemantic(resolvedFile, deps.semantic, deps.structural, control),
97
+ discoverStructural(resolvedFile, deps.structural, control),
95
98
  ]);
96
99
  if (!semantic.available && !structural.available) {
97
100
  const displayFile = path.relative(cwd, resolvedFile) || file;
@@ -148,6 +151,7 @@ async function discoverSemantic(
148
151
  file: string,
149
152
  semantic: SemanticSubstrate | undefined,
150
153
  structural: StructuralSubstrate | undefined,
154
+ control?: CodeRequestControl,
151
155
  ): Promise<DiscoveryResult> {
152
156
  if (!semantic) return { available: false, targets: [] };
153
157
  try {
@@ -158,12 +162,13 @@ async function discoverSemantic(
158
162
  targets: await Promise.all(
159
163
  result.data.map(async (symbol) => {
160
164
  const target = targetFromSymbol(file, symbol);
161
- const refined = await refineTypeAliasIdentity(target, structural);
165
+ const refined = await refineTypeAliasIdentity(target, structural, control);
162
166
  return { ...refined, nesting: target.nesting };
163
167
  }),
164
168
  ),
165
169
  };
166
- } catch {
170
+ } catch (error) {
171
+ if (isCodeRequestInterruption(error, control)) throw error;
167
172
  return { available: false, targets: [] };
168
173
  }
169
174
  }
@@ -196,13 +201,15 @@ function normalizeNesting(value: unknown): DeclarationNesting {
196
201
  async function discoverStructural(
197
202
  file: string,
198
203
  structural: StructuralSubstrate | undefined,
204
+ control?: CodeRequestControl,
199
205
  ): Promise<DiscoveryResult> {
200
206
  if (!structural) return { available: false, targets: [] };
201
207
  try {
202
208
  const result = await structural.outline(file);
203
209
  if (result.kind !== "success") return { available: false, targets: [] };
204
210
  return { available: true, targets: flattenOutline(file, result.data) };
205
- } catch {
211
+ } catch (error) {
212
+ if (isCodeRequestInterruption(error, control)) throw error;
206
213
  return { available: false, targets: [] };
207
214
  }
208
215
  }
@@ -1,5 +1,10 @@
1
1
  import { resolve } from "node:path";
2
- import type { CodeSymbol, StructuralProvider } from "@mrclrchtr/supi-code-runtime/api";
2
+ import {
3
+ type CodeRequestControl,
4
+ type CodeSymbol,
5
+ isCodeRequestInterruption,
6
+ type StructuralProvider,
7
+ } from "@mrclrchtr/supi-code-runtime/api";
3
8
  import type { ResolvedTargetData, TargetOutcome } from "./types.ts";
4
9
 
5
10
  /**
@@ -45,6 +50,7 @@ export interface DeclarationOccurrenceIdentity extends DeclarationIdentityResult
45
50
  export async function resolveDeclarationIdentityKind(
46
51
  observation: DeclarationIdentityObservation,
47
52
  structural: Pick<StructuralProvider, "nodeAt"> | undefined,
53
+ control?: CodeRequestControl,
48
54
  ): Promise<DeclarationIdentityResult> {
49
55
  const identityKind = canonicalDeclarationKind(observation.providerKind);
50
56
  if (
@@ -69,7 +75,8 @@ export async function resolveDeclarationIdentityKind(
69
75
  return exactNameAnchor && isTypeAlias
70
76
  ? { identityKind: "type", structuralEvidence: true }
71
77
  : { identityKind, structuralEvidence: false };
72
- } catch {
78
+ } catch (error) {
79
+ if (isCodeRequestInterruption(error, control)) throw error;
73
80
  return { identityKind, structuralEvidence: false };
74
81
  }
75
82
  }
@@ -82,6 +89,7 @@ export function createCodeSymbolIdentityResolver(
82
89
  file: string,
83
90
  allSymbols: readonly CodeSymbol[],
84
91
  structural: Pick<StructuralProvider, "nodeAt"> | undefined,
92
+ control?: CodeRequestControl,
85
93
  ): (symbol: CodeSymbol) => Promise<DeclarationOccurrenceIdentity> {
86
94
  const identities = new Map<CodeSymbol, Promise<DeclarationIdentityResult>>();
87
95
  const occurrences = new Map<CodeSymbol, Promise<DeclarationOccurrenceIdentity>>();
@@ -97,6 +105,7 @@ export function createCodeSymbolIdentityResolver(
97
105
  nameAnchor: symbol.nameAnchor ?? null,
98
106
  },
99
107
  structural,
108
+ control,
100
109
  );
101
110
  identities.set(symbol, identity);
102
111
  return identity;
@@ -147,6 +156,7 @@ function compareCodeSymbolDeclarations(left: CodeSymbol, right: CodeSymbol): num
147
156
  export async function refineTypeAliasIdentity(
148
157
  target: ResolvedTargetData,
149
158
  structural: Pick<StructuralProvider, "nodeAt"> | undefined,
159
+ control?: CodeRequestControl,
150
160
  ): Promise<ResolvedTargetData> {
151
161
  if (target.identityKind !== undefined) return target;
152
162
  const identity = await resolveDeclarationIdentityKind(
@@ -160,6 +170,7 @@ export async function refineTypeAliasIdentity(
160
170
  : null,
161
171
  },
162
172
  structural,
173
+ control,
163
174
  );
164
175
  return {
165
176
  ...target,
@@ -173,9 +184,13 @@ export async function refineTargetOutcomeIdentity(
173
184
  outcome: TargetOutcome,
174
185
  cwd: string,
175
186
  structural: Pick<StructuralProvider, "nodeAt"> | undefined,
187
+ control?: CodeRequestControl,
176
188
  ): Promise<TargetOutcome> {
177
189
  if (outcome.kind === "resolved") {
178
- return { kind: "resolved", target: await refineTypeAliasIdentity(outcome.target, structural) };
190
+ return {
191
+ kind: "resolved",
192
+ target: await refineTypeAliasIdentity(outcome.target, structural, control),
193
+ };
179
194
  }
180
195
  if (outcome.kind !== "disambiguation" && outcome.kind !== "kind-mismatch") return outcome;
181
196
 
@@ -195,6 +210,7 @@ export async function refineTargetOutcomeIdentity(
195
210
  : null,
196
211
  },
197
212
  structural,
213
+ control,
198
214
  );
199
215
  return {
200
216
  candidate: {
@@ -7,9 +7,11 @@
7
7
  */
8
8
 
9
9
  import * as path from "node:path";
10
- import type {
11
- CodeSymbol,
12
- SemanticProvider as SemanticSubstrate,
10
+ import {
11
+ type CodeRequestControl,
12
+ type CodeSymbol,
13
+ isCodeRequestInterruption,
14
+ type SemanticProvider as SemanticSubstrate,
13
15
  } from "@mrclrchtr/supi-code-runtime/api";
14
16
  import { isWithinOrEqual } from "@mrclrchtr/supi-core/project";
15
17
  import type { TargetSymbolKind } from "../../session/target-input.ts";
@@ -59,6 +61,7 @@ function anchorOf(s: CodeSymbol): CodeSymbol["declarationAnchor"] {
59
61
  async function refineResolvedSymbolAnchor(
60
62
  workspaceSymbol: CodeSymbol,
61
63
  semantic: SemanticSubstrate,
64
+ control?: CodeRequestControl,
62
65
  ): Promise<CodeSymbol> {
63
66
  try {
64
67
  const result = await semantic.documentSymbols(workspaceSymbol.file);
@@ -84,7 +87,8 @@ async function refineResolvedSymbolAnchor(
84
87
  }
85
88
 
86
89
  return refined;
87
- } catch {
90
+ } catch (error) {
91
+ if (isCodeRequestInterruption(error, control)) throw error;
88
92
  return workspaceSymbol;
89
93
  }
90
94
  }
@@ -107,6 +111,7 @@ export async function resolveSymbolTarget(
107
111
  kind?: TargetSymbolKind;
108
112
  exportedOnly?: boolean;
109
113
  maxResults?: number;
114
+ control?: CodeRequestControl;
110
115
  },
111
116
  ): Promise<TargetOutcome> {
112
117
  const result = await semantic.workspaceSymbols(symbol);
@@ -150,12 +155,25 @@ export async function resolveSymbolTarget(
150
155
  cwd,
151
156
  maxResults: options.maxResults,
152
157
  requestedKind,
158
+ control: options.control,
153
159
  });
154
160
  }
155
- return resolveCandidates(exactKind, semantic, cwd, options.maxResults);
161
+ return resolveCandidates({
162
+ candidates: exactKind,
163
+ semantic,
164
+ cwd,
165
+ maxResults: options.maxResults,
166
+ control: options.control,
167
+ });
156
168
  }
157
169
 
158
- return resolveCandidates(eligible, semantic, cwd, options?.maxResults);
170
+ return resolveCandidates({
171
+ candidates: eligible,
172
+ semantic,
173
+ cwd,
174
+ maxResults: options?.maxResults,
175
+ control: options?.control,
176
+ });
159
177
  }
160
178
 
161
179
  function providerKindMatches(reported: string, requested: TargetSymbolKind): boolean {
@@ -166,18 +184,20 @@ function normalizeProviderKind(kind: string): string {
166
184
  return kind.replace(/[\s_-]/g, "").toLowerCase();
167
185
  }
168
186
 
169
- async function resolveCandidates(
170
- candidates: readonly CodeSymbol[],
171
- semantic: SemanticSubstrate,
172
- cwd: string,
173
- maxResults?: number,
174
- ): Promise<TargetOutcome> {
187
+ async function resolveCandidates(options: {
188
+ candidates: readonly CodeSymbol[];
189
+ semantic: SemanticSubstrate;
190
+ cwd: string;
191
+ maxResults?: number;
192
+ control?: CodeRequestControl;
193
+ }): Promise<TargetOutcome> {
194
+ const { candidates, semantic, cwd, maxResults, control } = options;
175
195
  const ranged = candidates.filter(
176
196
  (candidate) =>
177
197
  candidate.declarationAnchor.line > 0 || candidate.declarationAnchor.character > 0,
178
198
  );
179
199
  if (ranged.length === 1) {
180
- return resolvedTarget(await refineResolvedSymbolAnchor(ranged[0], semantic));
200
+ return resolvedTarget(await refineResolvedSymbolAnchor(ranged[0], semantic, control));
181
201
  }
182
202
  return buildCandidateOutcome({
183
203
  kind: "disambiguation",
@@ -185,6 +205,7 @@ async function resolveCandidates(
185
205
  semantic,
186
206
  cwd,
187
207
  maxResults,
208
+ control,
188
209
  });
189
210
  }
190
211
 
@@ -220,7 +241,7 @@ type CandidateOutcomeOptions = CandidateOutcomeBase &
220
241
  (
221
242
  | { kind: "disambiguation"; requestedKind?: never }
222
243
  | { kind: "kind-mismatch"; requestedKind: TargetSymbolKind }
223
- );
244
+ ) & { control?: CodeRequestControl };
224
245
 
225
246
  /**
226
247
  * Refine only bounded visible candidates to name anchors while retaining the
@@ -234,7 +255,7 @@ async function buildCandidateOutcome(
234
255
  const refined = await Promise.all(
235
256
  options.candidates
236
257
  .slice(0, cap)
237
- .map((candidate) => refineResolvedSymbolAnchor(candidate, options.semantic)),
258
+ .map((candidate) => refineResolvedSymbolAnchor(candidate, options.semantic, options.control)),
238
259
  );
239
260
  const common = {
240
261
  candidates: toDisambiguationCandidates(refined, options.cwd),
package/src/api.ts CHANGED
@@ -57,6 +57,7 @@ export type { TargetSymbolKind } from "./session/target-input.ts";
57
57
  // Code-intelligence-specific result types.
58
58
  export type {
59
59
  CodeIntelResult,
60
+ CodeIntelResultDetails,
60
61
  ContextDetails,
61
62
  DisambiguationCandidate,
62
63
  HealthDetails,
@@ -65,4 +66,7 @@ export type {
65
66
  OrientationSectionDetails,
66
67
  ResolveDetails,
67
68
  SearchDetails,
69
+ ToolDisplaySection,
70
+ ToolOutputTruncationDetails,
71
+ ToolResultStatus,
68
72
  } from "./types/index.ts";
@@ -0,0 +1,51 @@
1
+ import * as path from "node:path";
2
+ import type {
3
+ DiagnosticEvidenceDocument,
4
+ DiagnosticEvidenceStatus,
5
+ DiagnosticEvidenceSummary,
6
+ } from "@mrclrchtr/supi-lsp/api";
7
+
8
+ /** Merge file-local diagnostic evidence without inventing coverage. */
9
+ export function mergeDiagnosticEvidence(
10
+ previous: DiagnosticEvidenceSummary,
11
+ latest: DiagnosticEvidenceSummary,
12
+ cwd?: string,
13
+ policy: "latest" | "conservative" = "latest",
14
+ ): DiagnosticEvidenceSummary {
15
+ const byFile = new Map<string, DiagnosticEvidenceDocument>();
16
+ for (const document of [...previous.documents, ...latest.documents]) {
17
+ const file = cwd ? path.relative(cwd, path.resolve(cwd, document.file)) : document.file;
18
+ const next = { file, status: document.status };
19
+ const previousDocument = byFile.get(file);
20
+ if (
21
+ !previousDocument ||
22
+ policy === "latest" ||
23
+ evidenceStatusRank(next.status) > evidenceStatusRank(previousDocument.status)
24
+ ) {
25
+ byFile.set(file, next);
26
+ }
27
+ }
28
+ const documents = Array.from(byFile.values()).sort((a, b) => a.file.localeCompare(b.file));
29
+ const counts = {
30
+ requested: documents.length,
31
+ confirmed: 0,
32
+ unconfirmed: 0,
33
+ failed: 0,
34
+ removed: 0,
35
+ };
36
+ for (const document of documents) counts[document.status]++;
37
+ return { ...counts, documents };
38
+ }
39
+
40
+ function evidenceStatusRank(status: DiagnosticEvidenceStatus): number {
41
+ switch (status) {
42
+ case "confirmed":
43
+ return 1;
44
+ case "unconfirmed":
45
+ return 2;
46
+ case "failed":
47
+ return 3;
48
+ case "removed":
49
+ return 4;
50
+ }
51
+ }
@@ -9,6 +9,7 @@
9
9
 
10
10
  import {
11
11
  type CapabilityState,
12
+ type CodeRequestControl,
12
13
  getDefaultWorkspaceRuntime,
13
14
  type SemanticProvider,
14
15
  type StructuralProvider,
@@ -67,7 +68,11 @@ export interface CapabilityAdapter {
67
68
  * the target workflow can decide whether to proceed, return a
68
69
  * timeout note, or return an unavailable result.
69
70
  */
70
- ensureSemanticReadiness(cwd: string, scope: ReadinessScope): Promise<ReadinessOutcome>;
71
+ ensureSemanticReadiness(
72
+ cwd: string,
73
+ scope: ReadinessScope,
74
+ control?: CodeRequestControl,
75
+ ): Promise<ReadinessOutcome>;
71
76
  }
72
77
 
73
78
  // ── Production adapter ────────────────────────────────────────────────
@@ -107,8 +112,12 @@ export class WorkspaceCapabilityAdapter implements CapabilityAdapter {
107
112
  return null;
108
113
  }
109
114
 
110
- async ensureSemanticReadiness(cwd: string, scope: ReadinessScope): Promise<ReadinessOutcome> {
111
- const result = await ensureSemanticReadiness(cwd, scope);
115
+ async ensureSemanticReadiness(
116
+ cwd: string,
117
+ scope: ReadinessScope,
118
+ control?: CodeRequestControl,
119
+ ): Promise<ReadinessOutcome> {
120
+ const result = await ensureSemanticReadiness(cwd, scope, undefined, control);
112
121
  return result;
113
122
  }
114
123