@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
@@ -0,0 +1,52 @@
1
+ import { createHash } from "node:crypto";
2
+ import type { Diagnostic } from "../config/types.ts";
3
+ import type { DiagnosticCacheEntry } from "./client-diagnostic-evidence.ts";
4
+
5
+ /** One file's stored diagnostics as consumed by manager-level collection. */
6
+ export interface DiagnosticEntry {
7
+ uri: string;
8
+ diagnostics: Diagnostic[];
9
+ current: boolean;
10
+ }
11
+
12
+ /** One tracked document's current diagnostic freshness. */
13
+ export interface ClientDiagnosticDocument {
14
+ uri: string;
15
+ current: boolean;
16
+ status: "confirmed" | "unconfirmed" | "failed" | "removed";
17
+ }
18
+
19
+ /** One client's diagnostic snapshot, including empty cache freshness. */
20
+ export interface ClientDiagnosticSnapshot {
21
+ entries: DiagnosticEntry[];
22
+ documents: ClientDiagnosticDocument[];
23
+ current: boolean;
24
+ }
25
+
26
+ /** One open document's current protocol and content state. */
27
+ export interface OpenDocumentState {
28
+ version: number;
29
+ synchronizationId: number;
30
+ evidenceRevision: number;
31
+ contentFingerprint: string;
32
+ }
33
+
34
+ /** Compute a path-free content identity for unchanged-document checks. */
35
+ export function fingerprintDocumentContent(content: string): string {
36
+ return createHash("sha256").update(content).digest("hex");
37
+ }
38
+
39
+ /** Test whether cached diagnostics still prove the current document state. */
40
+ export function hasCurrentDiagnosticEvidence(
41
+ document: OpenDocumentState | undefined,
42
+ entry: DiagnosticCacheEntry | undefined,
43
+ evidenceRevision: number,
44
+ ): boolean {
45
+ return Boolean(
46
+ document &&
47
+ entry &&
48
+ document.evidenceRevision === evidenceRevision &&
49
+ entry.synchronizationId === document.synchronizationId &&
50
+ entry.evidenceRevision === evidenceRevision,
51
+ );
52
+ }
@@ -0,0 +1,185 @@
1
+ import { readFileSync } from "node:fs";
2
+ import type { TextDocumentItem, VersionedTextDocumentIdentifier } from "../config/types.ts";
3
+ import type { DiagnosticSynchronization } from "./client-diagnostic-evidence.ts";
4
+ import type { DiagnosticWaitRegistry } from "./client-diagnostic-waiters.ts";
5
+ import { fingerprintDocumentContent, type OpenDocumentState } from "./client-document-state.ts";
6
+ import { getDiagnosticFileState } from "./client-file-state.ts";
7
+
8
+ type NotificationSender = (method: string, params: unknown) => void;
9
+
10
+ interface SynchronizeDocumentOptions {
11
+ uri: string;
12
+ content: string;
13
+ document: OpenDocumentState;
14
+ version: number;
15
+ synchronizationId: number;
16
+ evidenceRevision: number;
17
+ waiters: DiagnosticWaitRegistry;
18
+ sendNotification: NotificationSender;
19
+ }
20
+
21
+ /** Advance and publish one explicit document synchronization. */
22
+ export function synchronizeDocument(options: SynchronizeDocumentOptions): void {
23
+ options.waiters.releaseFile(options.uri);
24
+ options.waiters.cancelSettle();
25
+ options.document.version = options.version;
26
+ options.document.synchronizationId = options.synchronizationId;
27
+ options.document.evidenceRevision = options.evidenceRevision;
28
+ options.document.contentFingerprint = fingerprintDocumentContent(options.content);
29
+ options.sendNotification("textDocument/didChange", {
30
+ textDocument: {
31
+ uri: options.uri,
32
+ version: options.version,
33
+ } satisfies VersionedTextDocumentIdentifier,
34
+ contentChanges: [{ text: options.content }],
35
+ });
36
+ }
37
+
38
+ /** Remove one document and release all diagnostic waits for its URI. */
39
+ export function clearTrackedDocumentState(
40
+ openDocuments: Map<string, OpenDocumentState>,
41
+ diagnosticStore: Map<string, unknown>,
42
+ waiters: DiagnosticWaitRegistry,
43
+ uri: string,
44
+ ): void {
45
+ openDocuments.delete(uri);
46
+ diagnosticStore.delete(uri);
47
+ waiters.releaseFile(uri);
48
+ waiters.cancelSettle();
49
+ }
50
+
51
+ /** Close and reopen one open document while preserving cache and version history. */
52
+ export function reopenDocument(options: {
53
+ uri: string;
54
+ content: string;
55
+ document: OpenDocumentState;
56
+ languageId: string;
57
+ nextVersion(): number;
58
+ nextSynchronizationId(): number;
59
+ evidenceRevision: number;
60
+ waiters: DiagnosticWaitRegistry;
61
+ sendNotification: NotificationSender;
62
+ markUnversionedSyncMoment?(): void;
63
+ }): void {
64
+ // Mirror didClose release semantics: pending waiters for this URI observe
65
+ // the protocol close, and the settle generation is cancelled so concurrent
66
+ // settles re-arm against the reopened state.
67
+ options.waiters.releaseFile(options.uri);
68
+ options.waiters.cancelSettle();
69
+ options.markUnversionedSyncMoment?.();
70
+ options.sendNotification("textDocument/didClose", {
71
+ textDocument: { uri: options.uri },
72
+ });
73
+ const version = options.nextVersion();
74
+ options.document.version = version;
75
+ options.document.synchronizationId = options.nextSynchronizationId();
76
+ options.document.evidenceRevision = options.evidenceRevision;
77
+ options.document.contentFingerprint = fingerprintDocumentContent(options.content);
78
+ options.sendNotification("textDocument/didOpen", {
79
+ textDocument: {
80
+ uri: options.uri,
81
+ languageId: options.languageId,
82
+ version,
83
+ text: options.content,
84
+ } satisfies TextDocumentItem,
85
+ });
86
+ }
87
+
88
+ /** Synchronize one open document, or open it when the route is not tracked yet. */
89
+ export function synchronizeTrackedDocument(options: {
90
+ uri: string;
91
+ content: string;
92
+ document: OpenDocumentState | undefined;
93
+ nextVersion(): number;
94
+ nextSynchronizationId(): number;
95
+ evidenceRevision: number;
96
+ waiters: DiagnosticWaitRegistry;
97
+ sendNotification: NotificationSender;
98
+ markUnversionedSyncMoment?(): void;
99
+ clearFailedFile?(): void;
100
+ open(): void;
101
+ }): void {
102
+ if (!options.document) {
103
+ options.open();
104
+ return;
105
+ }
106
+ options.markUnversionedSyncMoment?.();
107
+ synchronizeDocument({
108
+ uri: options.uri,
109
+ content: options.content,
110
+ document: options.document,
111
+ version: options.nextVersion(),
112
+ synchronizationId: options.nextSynchronizationId(),
113
+ evidenceRevision: options.evidenceRevision,
114
+ waiters: options.waiters,
115
+ sendNotification: options.sendNotification,
116
+ });
117
+ options.clearFailedFile?.();
118
+ }
119
+
120
+ interface ResynchronizeDocumentsOptions {
121
+ openDocuments: Map<string, OpenDocumentState>;
122
+ waiters: DiagnosticWaitRegistry;
123
+ nextVersion(uri: string): number;
124
+ nextSynchronizationId(): number;
125
+ evidenceRevision: number;
126
+ sendNotification: NotificationSender;
127
+ uriToFile(uri: string): string;
128
+ clearFile(uri: string): void;
129
+ invalidateEvidence(uri: string): void;
130
+ markUnversionedSyncMoment(uri: string): void;
131
+ clearFailedFile(uri: string): void;
132
+ }
133
+
134
+ /** Document coverage produced while re-reading tracked files for refresh. */
135
+ export interface ResynchronizeDocumentsResult {
136
+ /** Documents that were synchronized and can receive fresh evidence. */
137
+ synchronizations: DiagnosticSynchronization[];
138
+ /** Existing tracked documents removed because their files no longer exist. */
139
+ removedFiles: string[];
140
+ /** Existing tracked documents that could not be read or synchronized. */
141
+ failedFiles: string[];
142
+ }
143
+
144
+ /** Re-read and synchronize every existing open document. */
145
+ export function resynchronizeOpenDocuments(
146
+ options: ResynchronizeDocumentsOptions,
147
+ ): ResynchronizeDocumentsResult {
148
+ const synchronizations: DiagnosticSynchronization[] = [];
149
+ const removedFiles: string[] = [];
150
+ const failedFiles: string[] = [];
151
+ for (const [uri, document] of options.openDocuments) {
152
+ const filePath = options.uriToFile(uri);
153
+ try {
154
+ options.markUnversionedSyncMoment(uri);
155
+ synchronizeDocument({
156
+ uri,
157
+ content: readFileSync(filePath, "utf-8"),
158
+ document,
159
+ version: options.nextVersion(uri),
160
+ synchronizationId: options.nextSynchronizationId(),
161
+ evidenceRevision: options.evidenceRevision,
162
+ waiters: options.waiters,
163
+ sendNotification: options.sendNotification,
164
+ });
165
+ options.clearFailedFile(uri);
166
+ synchronizations.push({
167
+ uri,
168
+ synchronizationId: document.synchronizationId,
169
+ evidenceRevision: document.evidenceRevision,
170
+ });
171
+ } catch {
172
+ if (getDiagnosticFileState(filePath) === "removed") {
173
+ options.clearFile(uri);
174
+ options.sendNotification("textDocument/didClose", { textDocument: { uri } });
175
+ removedFiles.push(filePath);
176
+ continue;
177
+ }
178
+ options.invalidateEvidence(uri);
179
+ options.markUnversionedSyncMoment(uri);
180
+ failedFiles.push(filePath);
181
+ // Keep the document open when a transient read fails.
182
+ }
183
+ }
184
+ return { synchronizations, removedFiles, failedFiles };
185
+ }
@@ -0,0 +1,25 @@
1
+ import { accessSync, constants, statSync } from "node:fs";
2
+
3
+ /** State used to distinguish deleted files from files that cannot be read. */
4
+ export type DiagnosticFileState = "present" | "removed" | "unreadable";
5
+
6
+ /** Read the file-system state without treating access errors as deletion. */
7
+ export function getDiagnosticFileState(filePath: string): DiagnosticFileState {
8
+ try {
9
+ if (!statSync(filePath).isFile()) return "unreadable";
10
+ accessSync(filePath, constants.R_OK);
11
+ return "present";
12
+ } catch (error) {
13
+ return isMissingFileError(error) ? "removed" : "unreadable";
14
+ }
15
+ }
16
+
17
+ /** Identify file-system errors that prove that a tracked path is missing. */
18
+ export function isMissingFileError(error: unknown): boolean {
19
+ return (
20
+ typeof error === "object" &&
21
+ error !== null &&
22
+ "code" in error &&
23
+ (error.code === "ENOENT" || error.code === "ENOTDIR")
24
+ );
25
+ }