@mrclrchtr/supi-code-intelligence 4.10.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 (203) 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/settings/settings-registry.ts +3 -0
  14. package/node_modules/@mrclrchtr/supi-lsp/README.md +80 -5
  15. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  16. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  17. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  18. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  19. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  20. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  21. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  22. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  23. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  24. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  25. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
  26. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  27. package/node_modules/@mrclrchtr/supi-lsp/package.json +7 -6
  28. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +10 -0
  29. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +206 -0
  30. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +78 -0
  31. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +114 -0
  32. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +372 -0
  33. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +14 -0
  34. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +62 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +491 -0
  36. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +9 -0
  37. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +71 -11
  38. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +206 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +365 -297
  40. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +52 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +185 -0
  42. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-file-state.ts +25 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +467 -115
  44. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +161 -33
  45. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +10 -1
  46. package/node_modules/@mrclrchtr/supi-lsp/src/config/defaults.json +1 -1
  47. package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +45 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +38 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +79 -9
  50. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +13 -4
  51. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +300 -24
  52. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +5 -2
  53. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +464 -96
  54. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-refactor-provider.ts +130 -0
  55. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +45 -329
  56. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +57 -120
  57. package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-edit-normalizer.ts +320 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +207 -0
  59. package/node_modules/@mrclrchtr/supi-lsp/src/session/readiness.ts +72 -2
  60. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +151 -26
  61. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +40 -0
  62. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +50 -0
  63. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +136 -120
  64. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +49 -0
  65. package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +102 -0
  66. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +17 -7
  67. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  68. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  69. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  70. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  71. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  72. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  73. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  74. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  75. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  76. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  77. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
  78. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  79. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/LICENSE +21 -0
  80. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/README.md +258 -0
  81. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/babel.cjs +257 -0
  82. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/jiti.cjs +1 -0
  83. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-cli.mjs +34 -0
  84. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-hooks.mjs +124 -0
  85. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-native.mjs +121 -0
  86. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.d.mts +1 -0
  87. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.mjs +4 -0
  88. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-static.mjs +23 -0
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.cjs +30 -0
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.cts +8 -0
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.mts +8 -0
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.mjs +29 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/types.d.ts +420 -0
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/package.json +146 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -3
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +0 -9
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -8
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +16 -12
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +65 -87
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +47 -95
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-timing.ts +147 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client-lifecycle.ts +39 -0
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +561 -0
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-message-size.ts +24 -0
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +452 -0
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +4 -2
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +12 -4
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +4 -2
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/imports.ts +4 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +5 -3
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +33 -12
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/blocking-test-bootstrap.mjs +34 -0
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/bootstrap.mjs +8 -0
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store-helpers.ts +23 -0
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +400 -0
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/request-control.ts +48 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-parser-helpers.ts +24 -0
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-query-helpers.ts +43 -0
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +421 -0
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +116 -0
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +201 -0
  122. package/package.json +5 -5
  123. package/src/analysis/health/diagnostics.ts +236 -24
  124. package/src/analysis/health/recovery.ts +6 -2
  125. package/src/analysis/provider.ts +58 -0
  126. package/src/analysis/readiness.ts +30 -9
  127. package/src/analysis/refactor/apply.ts +45 -1
  128. package/src/analysis/refactor/mutation-authority.ts +143 -0
  129. package/src/analysis/relations/callees.ts +9 -1
  130. package/src/analysis/relations/types.ts +5 -2
  131. package/src/analysis/search/ast-scan-timing.ts +9 -2
  132. package/src/analysis/search/ast-scan.ts +1 -1
  133. package/src/analysis/search/deadline.ts +2 -2
  134. package/src/analysis/search/pattern-analysis.ts +46 -32
  135. package/src/analysis/search/pattern.ts +12 -2
  136. package/src/analysis/target/anchored.ts +20 -11
  137. package/src/analysis/target/file.ts +18 -11
  138. package/src/analysis/target/identity.ts +19 -3
  139. package/src/analysis/target/symbol.ts +36 -15
  140. package/src/api.ts +4 -0
  141. package/src/diagnostics/evidence.ts +51 -0
  142. package/src/session/capability-adapter.ts +12 -3
  143. package/src/session/find-workflow.ts +17 -7
  144. package/src/session/graph/collect.ts +18 -2
  145. package/src/session/graph-workflow.ts +19 -12
  146. package/src/session/health-refresh.ts +148 -0
  147. package/src/session/health-types.ts +37 -15
  148. package/src/session/health-workflow.ts +37 -39
  149. package/src/session/inspect/collect.ts +20 -3
  150. package/src/session/inspect-workflow.ts +10 -5
  151. package/src/session/orientation/collect.ts +10 -1
  152. package/src/session/orientation/context-facts.ts +3 -1
  153. package/src/session/orientation/context-sections.ts +20 -7
  154. package/src/session/orientation/gather.ts +17 -11
  155. package/src/session/orientation-types.ts +2 -1
  156. package/src/session/orientation-workflow.ts +15 -8
  157. package/src/session/refactor-plans.ts +2 -0
  158. package/src/session/refactor-workflow.ts +59 -14
  159. package/src/session/session.ts +4 -1
  160. package/src/session/target-workflow.ts +54 -23
  161. package/src/session/workflow-control.ts +7 -3
  162. package/src/substrate/lsp/lifecycle.ts +26 -46
  163. package/src/substrate/lsp/maintenance.ts +199 -25
  164. package/src/substrate/lsp/state.ts +2 -2
  165. package/src/substrate/workspace-provider-host.ts +25 -3
  166. package/src/tool/find/execute.ts +7 -1
  167. package/src/tool/find/render.ts +20 -3
  168. package/src/tool/find/tui.ts +23 -21
  169. package/src/tool/graph/execute.ts +23 -3
  170. package/src/tool/graph/tui.ts +59 -46
  171. package/src/tool/health/execute.ts +7 -2
  172. package/src/tool/health/markdown.ts +56 -14
  173. package/src/tool/health/refresh-status.ts +105 -0
  174. package/src/tool/health/tui.ts +95 -98
  175. package/src/tool/infra/workflow-control.ts +8 -0
  176. package/src/tool/inspect/execute.ts +7 -1
  177. package/src/tool/inspect/tui.ts +26 -18
  178. package/src/tool/orientation/execute.ts +21 -3
  179. package/src/tool/orientation/tui.ts +51 -35
  180. package/src/tool/refactor-apply/execute.ts +3 -0
  181. package/src/tool/refactor-apply/tui.ts +43 -25
  182. package/src/tool/refactor-plan/execute.ts +4 -0
  183. package/src/tool/refactor-plan/tui.ts +33 -20
  184. package/src/tool/register.ts +127 -22
  185. package/src/tool/resolve/execute.ts +18 -1
  186. package/src/tool/resolve/tui.ts +42 -24
  187. package/src/tool/result/display.ts +107 -0
  188. package/src/tool/result/errors.ts +20 -17
  189. package/src/tool/result/find.ts +52 -8
  190. package/src/tool/result/graph.ts +44 -1
  191. package/src/tool/result/health.ts +53 -1
  192. package/src/tool/result/inspect.ts +113 -1
  193. package/src/tool/result/orientation.ts +66 -14
  194. package/src/tool/result/refactor.ts +36 -4
  195. package/src/tool/result/resolve.ts +44 -7
  196. package/src/tool/result/types.ts +20 -0
  197. package/src/types/execution.ts +18 -5
  198. package/src/types/index.ts +8 -1
  199. package/src/ui/status-command.ts +5 -3
  200. package/src/ui/status-overlay.ts +4 -0
  201. package/src/ui/tui/common.ts +108 -10
  202. package/src/ui/tui/display.ts +48 -0
  203. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime.ts +0 -351
@@ -0,0 +1,50 @@
1
+ import type { Diagnostic } from "../config/types.ts";
2
+ import type { DiagnosticEvidenceSummary } from "../diagnostics/evidence.ts";
3
+
4
+ export type {
5
+ DiagnosticEvidenceDocument,
6
+ DiagnosticEvidenceStatus,
7
+ DiagnosticEvidenceSummary,
8
+ } from "../diagnostics/evidence.ts";
9
+
10
+ /** Workspace diagnostic snapshot with explicit cache freshness and coverage. */
11
+ export interface WorkspaceDiagnosticSnapshot<T> {
12
+ entries: T[];
13
+ current: boolean;
14
+ evidence: DiagnosticEvidenceSummary;
15
+ }
16
+
17
+ /** Workspace diagnostic summary grouped by file. */
18
+ export interface WorkspaceDiagnosticSummaryEntry {
19
+ file: string;
20
+ errors: number;
21
+ warnings: number;
22
+ }
23
+
24
+ /** Outstanding diagnostics grouped by file, including info and hint counts. */
25
+ export interface OutstandingDiagnosticSummaryEntry {
26
+ file: string;
27
+ total: number;
28
+ errors: number;
29
+ warnings: number;
30
+ information: number;
31
+ hints: number;
32
+ }
33
+
34
+ /** Result from a workspace diagnostic recovery pass. */
35
+ export interface RecoverDiagnosticsResult {
36
+ /** Active clients targeted by the best-effort refresh, not confirmed successful refreshes. */
37
+ attemptedClients: number;
38
+ restartedClients: number;
39
+ /** Final document-level evidence from the last refresh in this recovery pass. */
40
+ diagnosticEvidence: DiagnosticEvidenceSummary;
41
+ /** Failure from the first refresh, when no later pass replaced it. */
42
+ refreshFailureReason?: string;
43
+ /** Wall-clock duration of the whole recovery pass, for telemetry. */
44
+ elapsedMs: number;
45
+ staleAssessment: {
46
+ suspected: boolean;
47
+ matchedFiles: Array<{ file: string; diagnostics: Diagnostic[] }>;
48
+ warning: string | null;
49
+ };
50
+ }
@@ -1,10 +1,15 @@
1
1
  // Shared session-scoped LSP service registry reused by peer extensions.
2
2
 
3
+ // biome-ignore lint/style/noExcessiveLinesPerFile: session registry, runtime recovery, and telemetry stay in one file; splitting would hide the recovery contract.
3
4
  import {
4
5
  type CodeQueryResult,
6
+ type CodeRequestControl,
7
+ isCodeRequestInterruption,
5
8
  mapCodeQueryResult,
9
+ throwIfCodeRequestInterrupted,
6
10
  unavailableCodeQuery,
7
11
  } from "@mrclrchtr/supi-code-runtime/api";
12
+ import { recordDebugEvent } from "@mrclrchtr/supi-core/debug";
8
13
  import { createSessionStateRegistry } from "@mrclrchtr/supi-core/session";
9
14
  import type {
10
15
  CodeAction,
@@ -21,9 +26,34 @@ import type {
21
26
  WorkspaceEdit,
22
27
  WorkspaceSymbol,
23
28
  } from "../config/types.ts";
29
+ import { boundServerNames, truncateIdentity } from "../debug-telemetry.ts";
24
30
  import type { LspManager } from "../manager/manager.ts";
25
31
  import { resolveSessionPath } from "../utils.ts";
26
32
  import { raceReadinessValue } from "./readiness.ts";
33
+ import type { DiagnosticEvidenceSummary, RecoverDiagnosticsResult } from "./runtime-diagnostics.ts";
34
+ import type {
35
+ RoutedMutationResponse,
36
+ SemanticReadinessResult,
37
+ WorkspaceLspRuntime,
38
+ WorkspaceLspRuntimeState,
39
+ } from "./workspace-lsp-runtime.ts";
40
+
41
+ export type { WorkspaceLspDiagnosticSurface } from "./runtime-diagnostic-surface.ts";
42
+ export type {
43
+ DiagnosticEvidenceDocument,
44
+ DiagnosticEvidenceStatus,
45
+ DiagnosticEvidenceSummary,
46
+ OutstandingDiagnosticSummaryEntry,
47
+ RecoverDiagnosticsResult,
48
+ WorkspaceDiagnosticSnapshot,
49
+ WorkspaceDiagnosticSummaryEntry,
50
+ } from "./runtime-diagnostics.ts";
51
+ export type {
52
+ RoutedMutationResponse,
53
+ SemanticReadinessResult,
54
+ WorkspaceLspRuntime,
55
+ WorkspaceLspRuntimeState,
56
+ } from "./workspace-lsp-runtime.ts";
27
57
 
28
58
  function isRange(value: Position | Range): value is Range {
29
59
  return "start" in value && "end" in value;
@@ -33,99 +63,6 @@ function unavailableFileQuery<T>(operation: string, file: string): CodeQueryResu
33
63
  return unavailableCodeQuery(`No routed LSP client could complete ${operation} for ${file}.`);
34
64
  }
35
65
 
36
- /** Workspace diagnostic summary grouped by file. */
37
- export interface WorkspaceDiagnosticSummaryEntry {
38
- file: string;
39
- errors: number;
40
- warnings: number;
41
- }
42
-
43
- /** Outstanding diagnostics grouped by file, including info and hint counts. */
44
- export interface OutstandingDiagnosticSummaryEntry {
45
- file: string;
46
- total: number;
47
- errors: number;
48
- warnings: number;
49
- information: number;
50
- hints: number;
51
- }
52
-
53
- /** Result from a workspace diagnostic recovery pass. */
54
- export interface RecoverDiagnosticsResult {
55
- /** Active clients targeted by the best-effort refresh, not confirmed successful refreshes. */
56
- attemptedClients: number;
57
- restartedClients: number;
58
- staleAssessment: {
59
- suspected: boolean;
60
- matchedFiles: Array<{ file: string; diagnostics: Diagnostic[] }>;
61
- warning: string | null;
62
- };
63
- }
64
-
65
- export type WorkspaceLspRuntimeState =
66
- | { kind: "ready"; runtime: WorkspaceLspRuntime }
67
- | { kind: "inactive"; runtime: WorkspaceLspRuntime }
68
- | { kind: "pending" }
69
- | { kind: "disabled" }
70
- | { kind: "unavailable"; reason: string };
71
-
72
- export type SemanticReadinessResult =
73
- | { kind: "ready" }
74
- | { kind: "timeout" }
75
- | { kind: "unavailable"; reason: string };
76
-
77
- /**
78
- * Workspace-scoped LSP interface that owns routing, readiness, semantic operations,
79
- * diagnostics, and recovery without exposing clients or the mutable manager.
80
- * File path inputs may be absolute or session-cwd-relative; a leading `@` is stripped
81
- * to match pi's built-in path-tool convention. Position arguments use raw 0-based LSP
82
- * coordinates; use `toLspPosition()` from `@mrclrchtr/supi-lsp/api` when starting from
83
- * user-facing 1-based line and character values.
84
- */
85
- export interface WorkspaceLspRuntime {
86
- hover(filePath: string, position: Position): Promise<CodeQueryResult<Hover | null>>;
87
- definition(
88
- filePath: string,
89
- position: Position,
90
- ): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>>;
91
- references(filePath: string, position: Position): Promise<CodeQueryResult<Location[]>>;
92
- implementation(
93
- filePath: string,
94
- position: Position,
95
- ): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>>;
96
- documentSymbols(
97
- filePath: string,
98
- ): Promise<CodeQueryResult<DocumentSymbol[] | SymbolInformation[]>>;
99
- workspaceSymbol(query: string): Promise<CodeQueryResult<SymbolInformation[] | WorkspaceSymbol[]>>;
100
- rename(filePath: string, position: Position, newName: string): Promise<WorkspaceEdit | null>;
101
- codeActions(filePath: string, positionOrRange: Position | Range): Promise<CodeAction[] | null>;
102
- /** Succeeds only when the concrete routed client exists and is query-ready. */
103
- waitUntilReadyForFile(
104
- filePath: string,
105
- options?: { timeoutMs?: number },
106
- ): Promise<SemanticReadinessResult>;
107
- /** Succeeds only when at least one concrete workspace client is active and query-ready. */
108
- waitUntilReadyForWorkspace(options?: { timeoutMs?: number }): Promise<SemanticReadinessResult>;
109
- getProjectServers(): ProjectServerInfo[];
110
- isSupportedSourceFile(filePath: string): boolean;
111
- trackFile(filePath: string): Promise<boolean>;
112
- closeFile(filePath: string): void;
113
- pruneMissingFiles(): readonly string[];
114
- noteWorkspaceChanges(changes: FileEvent[]): void;
115
- fileDiagnostics(filePath: string, maxSeverity?: number): Promise<CodeQueryResult<Diagnostic[]>>;
116
- refreshOpenDiagnostics(options?: { maxWaitMs?: number; quietMs?: number }): Promise<void>;
117
- getWorkspaceDiagnosticSummary(): WorkspaceDiagnosticSummaryEntry[];
118
- getOutstandingDiagnostics(
119
- maxSeverity?: number,
120
- ): Array<{ file: string; diagnostics: Diagnostic[] }>;
121
- getOutstandingDiagnosticSummary(maxSeverity?: number): OutstandingDiagnosticSummaryEntry[];
122
- recoverDiagnostics(options?: {
123
- restartIfStillStale?: boolean;
124
- maxWaitMs?: number;
125
- quietMs?: number;
126
- }): Promise<RecoverDiagnosticsResult>;
127
- }
128
-
129
66
  class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
130
67
  constructor(private readonly manager: LspManager) {}
131
68
 
@@ -136,29 +73,38 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
136
73
 
137
74
  // ── Semantic lookups ────────────────────────────────────────────────
138
75
 
139
- async hover(filePath: string, position: Position): Promise<CodeQueryResult<Hover | null>> {
76
+ async hover(
77
+ filePath: string,
78
+ position: Position,
79
+ control?: CodeRequestControl,
80
+ ): Promise<CodeQueryResult<Hover | null>> {
140
81
  const resolvedPath = this.resolveFilePath(filePath);
141
82
  const client = await this.manager.ensureFileOpen(resolvedPath);
142
83
  if (!client) return unavailableFileQuery("hover", resolvedPath);
143
- return client.hover(resolvedPath, position);
84
+ return client.hover(resolvedPath, position, control);
144
85
  }
145
86
 
146
87
  async definition(
147
88
  filePath: string,
148
89
  position: Position,
90
+ control?: CodeRequestControl,
149
91
  ): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>> {
150
92
  const resolvedPath = this.resolveFilePath(filePath);
151
93
  const client = await this.manager.ensureFileOpen(resolvedPath);
152
94
  if (!client) return unavailableFileQuery("definition", resolvedPath);
153
- return client.definition(resolvedPath, position);
95
+ return client.definition(resolvedPath, position, control);
154
96
  }
155
97
 
156
- async references(filePath: string, position: Position): Promise<CodeQueryResult<Location[]>> {
98
+ async references(
99
+ filePath: string,
100
+ position: Position,
101
+ control?: CodeRequestControl,
102
+ ): Promise<CodeQueryResult<Location[]>> {
157
103
  const resolvedPath = this.resolveFilePath(filePath);
158
104
  const client = await this.manager.ensureFileOpen(resolvedPath);
159
105
  if (!client) return unavailableFileQuery("references", resolvedPath);
160
106
  return mapCodeQueryResult(
161
- await client.references(resolvedPath, position),
107
+ await client.references(resolvedPath, position, control),
162
108
  (data) => data ?? [],
163
109
  );
164
110
  }
@@ -166,43 +112,58 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
166
112
  async implementation(
167
113
  filePath: string,
168
114
  position: Position,
115
+ control?: CodeRequestControl,
169
116
  ): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>> {
170
117
  const resolvedPath = this.resolveFilePath(filePath);
171
118
  const client = await this.manager.ensureFileOpen(resolvedPath);
172
119
  if (!client) return unavailableFileQuery("implementation", resolvedPath);
173
- return client.implementation(resolvedPath, position);
120
+ return client.implementation(resolvedPath, position, control);
174
121
  }
175
122
 
176
123
  async documentSymbols(
177
124
  filePath: string,
125
+ control?: CodeRequestControl,
178
126
  ): Promise<CodeQueryResult<DocumentSymbol[] | SymbolInformation[]>> {
179
127
  const resolvedPath = this.resolveFilePath(filePath);
180
128
  const client = await this.manager.ensureFileOpen(resolvedPath);
181
129
  if (!client) return unavailableFileQuery("document symbols", resolvedPath);
182
- return mapCodeQueryResult(await client.documentSymbols(resolvedPath), (data) => data ?? []);
130
+ return mapCodeQueryResult(
131
+ await client.documentSymbols(resolvedPath, control),
132
+ (data) => data ?? [],
133
+ );
183
134
  }
184
135
 
185
136
  async workspaceSymbol(
186
137
  query: string,
138
+ control?: CodeRequestControl,
187
139
  ): Promise<CodeQueryResult<SymbolInformation[] | WorkspaceSymbol[]>> {
188
- return this.manager.workspaceSymbol(query);
140
+ return this.manager.workspaceSymbol(query, control);
189
141
  }
190
142
 
191
143
  async rename(
192
144
  filePath: string,
193
145
  position: Position,
194
146
  newName: string,
195
- ): Promise<WorkspaceEdit | null> {
147
+ control?: CodeRequestControl,
148
+ ): Promise<RoutedMutationResponse<WorkspaceEdit | null> | null> {
196
149
  const resolvedPath = this.resolveFilePath(filePath);
197
150
  const client = await this.manager.ensureFileOpen(resolvedPath);
198
151
  if (!client) return null;
199
- return client.rename(resolvedPath, position, newName);
152
+ return {
153
+ value: await client.rename(resolvedPath, position, newName, control),
154
+ authorizedMutationRoots: [client.root],
155
+ };
156
+ }
157
+
158
+ getOpenDocumentVersion(filePath: string): number | null {
159
+ return this.manager.getOpenDocumentVersion(this.resolveFilePath(filePath));
200
160
  }
201
161
 
202
162
  async codeActions(
203
163
  filePath: string,
204
164
  positionOrRange: Position | Range,
205
- ): Promise<CodeAction[] | null> {
165
+ control?: CodeRequestControl,
166
+ ): Promise<RoutedMutationResponse<CodeAction[] | null> | null> {
206
167
  const resolvedPath = this.resolveFilePath(filePath);
207
168
  const client = await this.manager.ensureFileOpen(resolvedPath);
208
169
  if (!client) return null;
@@ -215,7 +176,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
215
176
  .filter((diagnostic) => diagnostic.range.end.line >= range.start.line)
216
177
  .filter((diagnostic) => diagnostic.range.start.line <= range.end.line);
217
178
 
218
- return client.codeActions(resolvedPath, range, { diagnostics });
179
+ return {
180
+ value: await client.codeActions(resolvedPath, range, { diagnostics }, control),
181
+ authorizedMutationRoots: [client.root],
182
+ };
219
183
  }
220
184
 
221
185
  /**
@@ -225,6 +189,7 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
225
189
  async waitUntilReadyForFile(
226
190
  filePath: string,
227
191
  options: { timeoutMs?: number } = {},
192
+ control?: CodeRequestControl,
228
193
  ): Promise<SemanticReadinessResult> {
229
194
  const resolvedPath = this.resolveFilePath(filePath);
230
195
  if (!this.manager.canServeFile(resolvedPath)) {
@@ -235,8 +200,9 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
235
200
  }
236
201
 
237
202
  const readiness = await raceReadinessValue(
238
- this.manager.waitUntilFileReady(resolvedPath),
203
+ this.manager.waitUntilFileReady(resolvedPath, control),
239
204
  options.timeoutMs,
205
+ control,
240
206
  );
241
207
  if (readiness.kind !== "resolved") return readiness;
242
208
  if (readiness.value === null) {
@@ -254,10 +220,12 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
254
220
  */
255
221
  async waitUntilReadyForWorkspace(
256
222
  options: { timeoutMs?: number } = {},
223
+ control?: CodeRequestControl,
257
224
  ): Promise<SemanticReadinessResult> {
258
225
  const readiness = await raceReadinessValue(
259
- this.manager.waitUntilWorkspaceReady(),
226
+ this.manager.waitUntilWorkspaceReady(control),
260
227
  options.timeoutMs,
228
+ control,
261
229
  );
262
230
  if (readiness.kind !== "resolved") return readiness;
263
231
  if (readiness.value === 0) {
@@ -297,7 +265,7 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
297
265
  /** Notify routed clients of workspace file changes and reset pull state. */
298
266
  noteWorkspaceChanges(changes: FileEvent[]): void {
299
267
  this.manager.clearAllPullResultIds();
300
- this.manager.notifyWorkspaceFileChanges(changes);
268
+ this.manager.noteWorkspaceChanges(changes);
301
269
  }
302
270
 
303
271
  async #shutdown(): Promise<void> {
@@ -310,34 +278,36 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
310
278
  async fileDiagnostics(
311
279
  filePath: string,
312
280
  maxSeverity: number = 4,
281
+ control?: CodeRequestControl,
313
282
  ): Promise<CodeQueryResult<Diagnostic[]>> {
314
283
  const resolvedPath = this.resolveFilePath(filePath);
315
284
  if (!this.manager.canServeFile(resolvedPath)) {
316
285
  return unavailableFileQuery("diagnostics", resolvedPath);
317
286
  }
318
- return this.manager.syncFileAndGetDiagnostics(resolvedPath, maxSeverity);
287
+ return this.manager.syncFileAndGetDiagnostics(resolvedPath, maxSeverity, control);
319
288
  }
320
289
 
321
290
  /** Re-sync every open document and wait for diagnostics to settle. */
322
- async refreshOpenDiagnostics(options?: { maxWaitMs?: number; quietMs?: number }): Promise<void> {
323
- await this.manager.refreshOpenDiagnostics(options);
291
+ async refreshOpenDiagnostics(
292
+ options?: { maxWaitMs?: number; quietMs?: number },
293
+ control?: CodeRequestControl,
294
+ ): Promise<DiagnosticEvidenceSummary> {
295
+ return this.manager.refreshOpenDiagnostics({ ...options, ...control });
324
296
  }
325
297
 
326
298
  /** Get a lightweight workspace diagnostic summary for all tracked files. */
327
- getWorkspaceDiagnosticSummary(): WorkspaceDiagnosticSummaryEntry[] {
328
- return this.manager.getDiagnosticSummary();
299
+ getWorkspaceDiagnosticSummary() {
300
+ return this.manager.getDiagnosticSnapshot();
329
301
  }
330
302
 
331
303
  /** Get outstanding diagnostics grouped by file at or above the supplied severity threshold. */
332
- getOutstandingDiagnostics(
333
- maxSeverity: number = 1,
334
- ): Array<{ file: string; diagnostics: Diagnostic[] }> {
335
- return this.manager.getOutstandingDiagnostics(maxSeverity);
304
+ getOutstandingDiagnostics(maxSeverity: number = 1) {
305
+ return this.manager.getOutstandingDiagnosticsSnapshot(maxSeverity);
336
306
  }
337
307
 
338
308
  /** Get outstanding diagnostic counts grouped by file. */
339
- getOutstandingDiagnosticSummary(maxSeverity: number = 1): OutstandingDiagnosticSummaryEntry[] {
340
- return this.manager.getOutstandingDiagnosticSummary(maxSeverity);
309
+ getOutstandingDiagnosticSummary(maxSeverity: number = 1) {
310
+ return this.manager.getOutstandingDiagnosticSummarySnapshot(maxSeverity);
341
311
  }
342
312
 
343
313
  /** Trigger a workspace-wide diagnostics refresh and stale-state recovery pass. */
@@ -345,8 +315,50 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
345
315
  restartIfStillStale?: boolean;
346
316
  maxWaitMs?: number;
347
317
  quietMs?: number;
318
+ control?: CodeRequestControl;
348
319
  }): Promise<RecoverDiagnosticsResult> {
349
- return this.manager.recoverWorkspaceDiagnostics(options);
320
+ const recoveryStartedAt = Date.now();
321
+ try {
322
+ const result = await this.manager.recoverWorkspaceDiagnostics(options);
323
+ const outcome = result.refreshFailureReason ? "failed" : "completed";
324
+ recordDebugEvent({
325
+ source: "lsp",
326
+ level: "debug",
327
+ category: "runtime.recovery",
328
+ message: `LSP diagnostic recovery ${outcome}`,
329
+ cwd: truncateIdentity(this.manager.getCwd()),
330
+ data: {
331
+ outcome,
332
+ elapsedMs: result.elapsedMs,
333
+ attemptedClients: result.attemptedClients,
334
+ restartedClients: result.restartedClients,
335
+ attemptedServers: boundServerNames(result.attemptedServers ?? []),
336
+ restartedServers: boundServerNames(result.restartedServers ?? []),
337
+ ...(result.restartReason ? { reason: result.restartReason } : {}),
338
+ },
339
+ });
340
+ return result;
341
+ } catch (error) {
342
+ // A cancelled pass has no result object, so telemetry records the
343
+ // cancelled outcome, the elapsed time, and the server names that are
344
+ // still running at cancellation. Restart identity is unavailable
345
+ // because the pass produced no result.
346
+ if (isCodeRequestInterruption(error, options?.control)) {
347
+ recordDebugEvent({
348
+ source: "lsp",
349
+ level: "debug",
350
+ category: "runtime.recovery",
351
+ message: "LSP diagnostic recovery cancelled",
352
+ cwd: truncateIdentity(this.manager.getCwd()),
353
+ data: {
354
+ outcome: "cancelled",
355
+ elapsedMs: Date.now() - recoveryStartedAt,
356
+ attemptedServers: boundServerNames(this.manager.getRunningClientNames()),
357
+ },
358
+ });
359
+ }
360
+ throw error;
361
+ }
350
362
  }
351
363
 
352
364
  private resolveFilePath(filePath: string): string {
@@ -380,15 +392,19 @@ export function getWorkspaceLspRuntime(cwd: string): WorkspaceLspRuntimeState {
380
392
  export async function waitForWorkspaceLspRuntime(
381
393
  cwd: string,
382
394
  timeoutMs: number = 250,
395
+ control?: CodeRequestControl,
383
396
  ): Promise<WorkspaceLspRuntimeState> {
384
397
  const deadline = Date.now() + Math.max(0, timeoutMs);
385
398
  let state = getWorkspaceLspRuntime(cwd);
386
399
 
387
400
  while (state.kind === "pending" && Date.now() < deadline) {
401
+ throwIfCodeRequestInterrupted(control);
388
402
  await new Promise((resolve) => setTimeout(resolve, WAIT_INTERVAL_MS));
389
403
  state = getWorkspaceLspRuntime(cwd);
390
404
  }
391
405
 
406
+ // A cancelled poll must not hand a runtime to a caller that no longer awaits.
407
+ throwIfCodeRequestInterrupted(control);
392
408
  return state;
393
409
  }
394
410
 
@@ -0,0 +1,49 @@
1
+ import { recordDebugEvent } from "@mrclrchtr/supi-core/debug";
2
+ import type { ProjectServerInfo } from "../config/types.ts";
3
+ import { MAX_SERVERS, truncateIdentity } from "../debug-telemetry.ts";
4
+ import type { LspRuntimeTransition } from "./runtime-controller.ts";
5
+
6
+ /** One bounded server entry in a runtime-transition payload. */
7
+ export interface TransitionServerEntry {
8
+ readonly name: string;
9
+ readonly status: ProjectServerInfo["status"];
10
+ readonly ready: boolean;
11
+ }
12
+
13
+ /** Bound a project-server snapshot to MAX_SERVERS name/status/ready entries. */
14
+ function boundedServerEntries(
15
+ projectServers: readonly ProjectServerInfo[],
16
+ ): TransitionServerEntry[] {
17
+ return projectServers.slice(0, MAX_SERVERS).map((server) => ({
18
+ name: truncateIdentity(server.name),
19
+ status: server.status,
20
+ ready: server.ready,
21
+ }));
22
+ }
23
+
24
+ /** Record bounded aggregate telemetry for one runtime transition. */
25
+ export function recordLspRuntimeTransition(cwd: string, transition: LspRuntimeTransition): void {
26
+ const readyClients = transition.projectServers.filter(
27
+ (server) => server.status === "running" && server.ready,
28
+ ).length;
29
+ const trackedFiles = transition.projectServers.reduce(
30
+ (count, server) => count + server.openFiles.length,
31
+ 0,
32
+ );
33
+ recordDebugEvent({
34
+ source: "lsp",
35
+ level: transition.kind === "crash" ? "warning" : "debug",
36
+ category: "runtime.transition",
37
+ message: `LSP runtime transition: ${transition.kind}`,
38
+ cwd: truncateIdentity(cwd),
39
+ data: {
40
+ generation: transition.generation,
41
+ kind: transition.kind,
42
+ semanticReady: transition.semanticReady,
43
+ readyClients,
44
+ totalClients: transition.projectServers.length,
45
+ trackedFiles,
46
+ servers: boundedServerEntries(transition.projectServers),
47
+ },
48
+ });
49
+ }
@@ -0,0 +1,102 @@
1
+ import type { CodeQueryResult, CodeRequestControl } from "@mrclrchtr/supi-code-runtime/api";
2
+ import type {
3
+ CodeAction,
4
+ DocumentSymbol,
5
+ FileEvent,
6
+ Hover,
7
+ Location,
8
+ LocationLink,
9
+ Position,
10
+ ProjectServerInfo,
11
+ Range,
12
+ SymbolInformation,
13
+ WorkspaceEdit,
14
+ WorkspaceSymbol,
15
+ } from "../config/types.ts";
16
+ import type { WorkspaceLspDiagnosticSurface } from "./runtime-diagnostic-surface.ts";
17
+
18
+ export type WorkspaceLspRuntimeState =
19
+ | { kind: "ready"; runtime: WorkspaceLspRuntime }
20
+ | { kind: "inactive"; runtime: WorkspaceLspRuntime }
21
+ | { kind: "pending" }
22
+ | { kind: "disabled" }
23
+ | { kind: "unavailable"; reason: string };
24
+
25
+ export type SemanticReadinessResult =
26
+ | { kind: "ready" }
27
+ | { kind: "timeout" }
28
+ | { kind: "unavailable"; reason: string };
29
+
30
+ /** One mutation response and the exact provider roots from its semantic route. */
31
+ export interface RoutedMutationResponse<T> {
32
+ /** Provider response from the routed client. */
33
+ readonly value: T;
34
+ /** Roots that the routed client owns for this mutation response. */
35
+ readonly authorizedMutationRoots: readonly string[];
36
+ }
37
+
38
+ /**
39
+ * Workspace-scoped LSP interface that owns routing, readiness, semantic operations,
40
+ * diagnostics, and recovery without exposing clients or the mutable manager.
41
+ * File paths can be absolute or session-cwd-relative. A leading `@` is removed to
42
+ * match Pi's built-in path-tool convention. Positions use raw 0-based LSP coordinates.
43
+ * Provider request control is accepted
44
+ * as metadata only in this expansion and is not interpreted by the runtime.
45
+ */
46
+ export interface WorkspaceLspRuntime extends WorkspaceLspDiagnosticSurface {
47
+ hover(
48
+ filePath: string,
49
+ position: Position,
50
+ control?: CodeRequestControl,
51
+ ): Promise<CodeQueryResult<Hover | null>>;
52
+ definition(
53
+ filePath: string,
54
+ position: Position,
55
+ control?: CodeRequestControl,
56
+ ): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>>;
57
+ references(
58
+ filePath: string,
59
+ position: Position,
60
+ control?: CodeRequestControl,
61
+ ): Promise<CodeQueryResult<Location[]>>;
62
+ implementation(
63
+ filePath: string,
64
+ position: Position,
65
+ control?: CodeRequestControl,
66
+ ): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>>;
67
+ documentSymbols(
68
+ filePath: string,
69
+ control?: CodeRequestControl,
70
+ ): Promise<CodeQueryResult<DocumentSymbol[] | SymbolInformation[]>>;
71
+ workspaceSymbol(
72
+ query: string,
73
+ control?: CodeRequestControl,
74
+ ): Promise<CodeQueryResult<SymbolInformation[] | WorkspaceSymbol[]>>;
75
+ rename(
76
+ filePath: string,
77
+ position: Position,
78
+ newName: string,
79
+ control?: CodeRequestControl,
80
+ ): Promise<RoutedMutationResponse<WorkspaceEdit | null> | null>;
81
+ codeActions(
82
+ filePath: string,
83
+ positionOrRange: Position | Range,
84
+ control?: CodeRequestControl,
85
+ ): Promise<RoutedMutationResponse<CodeAction[] | null> | null>;
86
+ getOpenDocumentVersion(filePath: string): number | null;
87
+ waitUntilReadyForFile(
88
+ filePath: string,
89
+ options?: { timeoutMs?: number },
90
+ control?: CodeRequestControl,
91
+ ): Promise<SemanticReadinessResult>;
92
+ waitUntilReadyForWorkspace(
93
+ options?: { timeoutMs?: number },
94
+ control?: CodeRequestControl,
95
+ ): Promise<SemanticReadinessResult>;
96
+ getProjectServers(): ProjectServerInfo[];
97
+ isSupportedSourceFile(filePath: string): boolean;
98
+ trackFile(filePath: string): Promise<boolean>;
99
+ closeFile(filePath: string): void;
100
+ pruneMissingFiles(): readonly string[];
101
+ noteWorkspaceChanges(changes: FileEvent[]): void;
102
+ }