@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.
- package/README.md +2 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
- package/node_modules/@mrclrchtr/supi-core/src/debug-timing.ts +34 -21
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/README.md +80 -5
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-timing.ts +34 -21
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/package.json +7 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +10 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +206 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +78 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +114 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +372 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +14 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +62 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +491 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +215 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +206 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +370 -266
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +52 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +185 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-file-state.ts +25 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +467 -115
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +238 -11
- package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +10 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/defaults.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +45 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +38 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +79 -9
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +13 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +300 -24
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +5 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +464 -96
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-refactor-provider.ts +130 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +45 -329
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +57 -120
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-edit-normalizer.ts +320 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +207 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/readiness.ts +72 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +151 -26
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +40 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +50 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +136 -120
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +49 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +102 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +26 -6
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-timing.ts +34 -21
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/LICENSE +21 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/README.md +258 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/babel.cjs +257 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/jiti.cjs +1 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-cli.mjs +34 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-hooks.mjs +124 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-native.mjs +121 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.d.mts +1 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.mjs +4 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-static.mjs +23 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.cjs +30 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.cts +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.mts +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.mjs +29 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/types.d.ts +420 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/package.json +146 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +4 -4
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +4 -4
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +7 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/kotlin/tree-sitter-kotlin.wasm.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/sql/tree-sitter-sql.wasm.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +0 -9
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +16 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +65 -87
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +47 -95
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-timing.ts +147 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client-lifecycle.ts +39 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +561 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-message-size.ts +24 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +452 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +12 -4
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/imports.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +5 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +33 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/blocking-test-bootstrap.mjs +34 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/bootstrap.mjs +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store-helpers.ts +23 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +400 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/request-control.ts +48 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-parser-helpers.ts +24 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-query-helpers.ts +43 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +421 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +116 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +201 -0
- package/package.json +5 -5
- package/src/analysis/health/diagnostics.ts +236 -24
- package/src/analysis/health/recovery.ts +6 -2
- package/src/analysis/provider.ts +58 -0
- package/src/analysis/readiness.ts +30 -9
- package/src/analysis/refactor/apply.ts +59 -20
- package/src/analysis/refactor/mutation-authority.ts +143 -0
- package/src/analysis/refactor/position.ts +47 -0
- package/src/analysis/refactor/safety.ts +18 -10
- package/src/analysis/relations/callees.ts +9 -1
- package/src/analysis/relations/types.ts +5 -2
- package/src/analysis/search/ast-scan-timing.ts +9 -4
- package/src/analysis/search/ast-scan.ts +1 -1
- package/src/analysis/search/deadline.ts +2 -2
- package/src/analysis/search/pattern-analysis.ts +46 -32
- package/src/analysis/search/pattern.ts +12 -2
- package/src/analysis/target/anchored.ts +20 -11
- package/src/analysis/target/file.ts +18 -11
- package/src/analysis/target/identity.ts +19 -3
- package/src/analysis/target/symbol.ts +36 -15
- package/src/api.ts +4 -0
- package/src/diagnostics/evidence.ts +51 -0
- package/src/session/capability-adapter.ts +12 -3
- package/src/session/find-workflow.ts +17 -7
- package/src/session/graph/collect.ts +18 -2
- package/src/session/graph-workflow.ts +19 -12
- package/src/session/health-refresh.ts +148 -0
- package/src/session/health-types.ts +37 -15
- package/src/session/health-workflow.ts +37 -39
- package/src/session/inspect/collect.ts +20 -3
- package/src/session/inspect-workflow.ts +10 -5
- package/src/session/orientation/collect.ts +10 -1
- package/src/session/orientation/context-facts.ts +3 -1
- package/src/session/orientation/context-sections.ts +20 -7
- package/src/session/orientation/gather.ts +17 -11
- package/src/session/orientation-types.ts +2 -1
- package/src/session/orientation-workflow.ts +15 -8
- package/src/session/refactor-plans.ts +2 -0
- package/src/session/refactor-workflow.ts +59 -14
- package/src/session/session.ts +4 -1
- package/src/session/target-workflow.ts +54 -23
- package/src/session/workflow-control.ts +7 -3
- package/src/substrate/lsp/lifecycle.ts +26 -46
- package/src/substrate/lsp/maintenance.ts +199 -25
- package/src/substrate/lsp/state.ts +2 -2
- package/src/substrate/workspace-provider-host.ts +25 -3
- package/src/tool/find/execute.ts +7 -1
- package/src/tool/find/render.ts +20 -3
- package/src/tool/find/tui.ts +23 -21
- package/src/tool/graph/execute.ts +23 -3
- package/src/tool/graph/tui.ts +59 -46
- package/src/tool/health/execute.ts +7 -2
- package/src/tool/health/markdown.ts +56 -14
- package/src/tool/health/refresh-status.ts +105 -0
- package/src/tool/health/tui.ts +95 -98
- package/src/tool/infra/workflow-control.ts +8 -0
- package/src/tool/inspect/execute.ts +7 -1
- package/src/tool/inspect/tui.ts +26 -18
- package/src/tool/orientation/execute.ts +21 -3
- package/src/tool/orientation/tui.ts +51 -35
- package/src/tool/refactor-apply/execute.ts +3 -0
- package/src/tool/refactor-apply/tui.ts +43 -25
- package/src/tool/refactor-plan/execute.ts +4 -0
- package/src/tool/refactor-plan/tui.ts +33 -20
- package/src/tool/register.ts +127 -22
- package/src/tool/resolve/execute.ts +18 -1
- package/src/tool/resolve/tui.ts +42 -24
- package/src/tool/result/display.ts +107 -0
- package/src/tool/result/errors.ts +20 -17
- package/src/tool/result/find.ts +52 -8
- package/src/tool/result/graph.ts +44 -1
- package/src/tool/result/health.ts +53 -1
- package/src/tool/result/inspect.ts +113 -1
- package/src/tool/result/orientation.ts +66 -14
- package/src/tool/result/refactor.ts +36 -4
- package/src/tool/result/resolve.ts +44 -7
- package/src/tool/result/types.ts +20 -0
- package/src/types/execution.ts +18 -5
- package/src/types/index.ts +8 -1
- package/src/ui/status-command.ts +5 -3
- package/src/ui/status-overlay.ts +4 -0
- package/src/ui/tui/common.ts +108 -10
- package/src/ui/tui/display.ts +48 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime.ts +0 -247
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
// biome-ignore-all lint/style/noExcessiveLinesPerFile: refresh orchestration, pull collection, and the reopen fallback stay in one cohesive module.
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import {
|
|
4
|
+
type CodeRequestControl,
|
|
5
|
+
isCodeRequestInterruption,
|
|
6
|
+
throwIfCodeRequestInterrupted,
|
|
7
|
+
} from "@mrclrchtr/supi-code-runtime/api";
|
|
8
|
+
import type { TextDocumentIdentifier } from "../config/types.ts";
|
|
9
|
+
import {
|
|
10
|
+
type DiagnosticEvidenceSummary,
|
|
11
|
+
summarizeDiagnosticEvidence,
|
|
12
|
+
} from "../diagnostics/evidence.ts";
|
|
13
|
+
import { detectLanguageId, fileToUri, uriToFile } from "../utils.ts";
|
|
14
|
+
import {
|
|
15
|
+
type DiagnosticCacheEntry,
|
|
16
|
+
type DiagnosticSynchronization,
|
|
17
|
+
hasFreshEvidence,
|
|
18
|
+
hasFreshPush,
|
|
19
|
+
isCurrentSynchronization,
|
|
20
|
+
latestFreshEvidenceReceivedAt,
|
|
21
|
+
nextDocumentVersion,
|
|
22
|
+
raceDiagnosticPull,
|
|
23
|
+
} from "./client-diagnostic-evidence.ts";
|
|
24
|
+
import type { ClientDiagnosticsHost } from "./client-diagnostic-host.ts";
|
|
25
|
+
import { pullDiagnosticEvidence } from "./client-diagnostic-pull.ts";
|
|
26
|
+
import type { DiagnosticPullRequest } from "./client-diagnostic-request.ts";
|
|
27
|
+
import {
|
|
28
|
+
DiagnosticObserver,
|
|
29
|
+
DiagnosticPullError,
|
|
30
|
+
isDiagnosticTimeout,
|
|
31
|
+
} from "./client-diagnostic-timing.ts";
|
|
32
|
+
import type { DiagnosticStateWait, DiagnosticWaitRegistry } from "./client-diagnostic-waiters.ts";
|
|
33
|
+
import type { OpenDocumentState } from "./client-document-state.ts";
|
|
34
|
+
import {
|
|
35
|
+
type ResynchronizeDocumentsResult,
|
|
36
|
+
reopenDocument,
|
|
37
|
+
resynchronizeOpenDocuments,
|
|
38
|
+
} from "./client-document-sync.ts";
|
|
39
|
+
import { getDiagnosticFileState } from "./client-file-state.ts";
|
|
40
|
+
|
|
41
|
+
/** Send the protocol close notification for one removed document. */
|
|
42
|
+
export function sendDidCloseNotification(
|
|
43
|
+
host: Pick<ClientDiagnosticsHost, "sendNotification">,
|
|
44
|
+
uri: string,
|
|
45
|
+
): void {
|
|
46
|
+
host.sendNotification("textDocument/didClose", {
|
|
47
|
+
textDocument: { uri } satisfies TextDocumentIdentifier,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Build final document coverage after one client refresh attempt. */
|
|
52
|
+
export function buildDiagnosticRefreshEvidence(options: {
|
|
53
|
+
requestedFiles: readonly string[];
|
|
54
|
+
resynchronization: ResynchronizeDocumentsResult;
|
|
55
|
+
/** Synchronizations that prove evidence, after reopen-resync updates. */
|
|
56
|
+
synchronizations: readonly DiagnosticSynchronization[];
|
|
57
|
+
failedPullUris: ReadonlySet<string>;
|
|
58
|
+
failedFiles: ReadonlySet<string>;
|
|
59
|
+
failedResynchronizations: ReadonlySet<string>;
|
|
60
|
+
currentEvidenceRevision: number;
|
|
61
|
+
openDocuments: ReadonlyMap<string, unknown>;
|
|
62
|
+
diagnosticStore: ReadonlyMap<string, DiagnosticCacheEntry>;
|
|
63
|
+
}): DiagnosticEvidenceSummary {
|
|
64
|
+
const synchronizationByFile = new Map(
|
|
65
|
+
options.synchronizations.map((item) => [uriToFile(item.uri), item]),
|
|
66
|
+
);
|
|
67
|
+
const removedFiles = new Set(options.resynchronization.removedFiles);
|
|
68
|
+
const failedFiles = new Set(options.resynchronization.failedFiles);
|
|
69
|
+
const documents = options.requestedFiles.map((file) => {
|
|
70
|
+
const uri = fileToUri(file);
|
|
71
|
+
const synchronization = synchronizationByFile.get(file);
|
|
72
|
+
if (removedFiles.has(file) || getDiagnosticFileState(file) === "removed") {
|
|
73
|
+
return { file, status: "removed" as const };
|
|
74
|
+
}
|
|
75
|
+
if (
|
|
76
|
+
failedFiles.has(file) ||
|
|
77
|
+
options.failedFiles.has(file) ||
|
|
78
|
+
options.failedResynchronizations.has(file)
|
|
79
|
+
) {
|
|
80
|
+
return { file, status: "failed" as const };
|
|
81
|
+
}
|
|
82
|
+
if (!options.openDocuments.has(uri)) {
|
|
83
|
+
return { file, status: "unconfirmed" as const };
|
|
84
|
+
}
|
|
85
|
+
if (
|
|
86
|
+
synchronization &&
|
|
87
|
+
hasFreshEvidence(options.diagnosticStore, synchronization, options.currentEvidenceRevision)
|
|
88
|
+
) {
|
|
89
|
+
return { file, status: "confirmed" as const };
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
file,
|
|
93
|
+
status: options.failedPullUris.has(uri) ? ("failed" as const) : ("unconfirmed" as const),
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
return summarizeDiagnosticEvidence(documents);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Pull one document and reject evidence from a stale client generation. */
|
|
100
|
+
export function pullClientDiagnosticEvidence(
|
|
101
|
+
options: Omit<DiagnosticPullRequest, "previousResultId"> & {
|
|
102
|
+
store: Map<string, DiagnosticCacheEntry>;
|
|
103
|
+
synchronizationId?: number;
|
|
104
|
+
evidenceRevision: number;
|
|
105
|
+
currentRevision(): number;
|
|
106
|
+
isCurrentSynchronization(): boolean;
|
|
107
|
+
isRelatedUriTracked(uri: string): boolean;
|
|
108
|
+
pull(
|
|
109
|
+
request: DiagnosticPullRequest,
|
|
110
|
+
): Promise<import("../config/types.ts").DocumentDiagnosticReport | null>;
|
|
111
|
+
},
|
|
112
|
+
): Promise<boolean> {
|
|
113
|
+
return pullDiagnosticEvidence(options);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Pull one document through a client's host and preserve generation checks. */
|
|
117
|
+
export function pullClientDiagnosticEvidenceFromHost(options: {
|
|
118
|
+
host: Pick<ClientDiagnosticsHost, "pullDocumentDiagnostics">;
|
|
119
|
+
store: Map<string, DiagnosticCacheEntry>;
|
|
120
|
+
openDocuments: ReadonlyMap<string, { synchronizationId: number; evidenceRevision?: number }>;
|
|
121
|
+
currentEvidenceRevision(): number;
|
|
122
|
+
isRelatedUriTracked(uri: string): boolean;
|
|
123
|
+
request: Omit<DiagnosticPullRequest, "previousResultId"> & {
|
|
124
|
+
synchronizationId?: number;
|
|
125
|
+
evidenceRevision?: number;
|
|
126
|
+
};
|
|
127
|
+
}): Promise<boolean> {
|
|
128
|
+
return pullClientDiagnosticEvidence({
|
|
129
|
+
store: options.store,
|
|
130
|
+
...options.request,
|
|
131
|
+
evidenceRevision: options.request.evidenceRevision ?? options.currentEvidenceRevision(),
|
|
132
|
+
currentRevision: options.currentEvidenceRevision,
|
|
133
|
+
isCurrentSynchronization: () =>
|
|
134
|
+
options.request.synchronizationId === undefined ||
|
|
135
|
+
isCurrentSynchronization(options.openDocuments, {
|
|
136
|
+
uri: options.request.uri,
|
|
137
|
+
synchronizationId: options.request.synchronizationId,
|
|
138
|
+
evidenceRevision: options.request.evidenceRevision,
|
|
139
|
+
}),
|
|
140
|
+
isRelatedUriTracked: options.isRelatedUriTracked,
|
|
141
|
+
pull: (request) => options.host.pullDocumentDiagnostics(request),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Collect pull evidence for every synchronized document in one refresh. */
|
|
146
|
+
export async function pullDiagnosticsForOpenDocuments(options: {
|
|
147
|
+
requests: readonly DiagnosticSynchronization[];
|
|
148
|
+
syncStart: number;
|
|
149
|
+
maxWaitMs: number;
|
|
150
|
+
signal?: AbortSignal;
|
|
151
|
+
deadline?: number;
|
|
152
|
+
operationId?: string;
|
|
153
|
+
currentEvidenceRevision: () => number;
|
|
154
|
+
openDocuments: ReadonlyMap<string, { evidenceRevision: number; synchronizationId: number }>;
|
|
155
|
+
diagnosticStore: ReadonlyMap<string, DiagnosticCacheEntry>;
|
|
156
|
+
waitForChange: () => DiagnosticStateWait;
|
|
157
|
+
pullDiagnostics: (options: {
|
|
158
|
+
request: DiagnosticSynchronization;
|
|
159
|
+
timeoutMs: number;
|
|
160
|
+
signal: AbortSignal;
|
|
161
|
+
operationId?: string;
|
|
162
|
+
deadline?: number;
|
|
163
|
+
}) => Promise<boolean>;
|
|
164
|
+
}): Promise<void> {
|
|
165
|
+
const deadline = options.syncStart + options.maxWaitMs;
|
|
166
|
+
const results = await Promise.allSettled(
|
|
167
|
+
options.requests.map(async (request) => {
|
|
168
|
+
const remaining = deadline - Date.now();
|
|
169
|
+
if (remaining <= 0) throw new Error("pull diagnostic timeout");
|
|
170
|
+
const pullController = new AbortController();
|
|
171
|
+
// Link the caller's cancellation to this document's pull controller so
|
|
172
|
+
// an in-flight pull receives protocol cancellation and stops promptly.
|
|
173
|
+
const onAbort = () => pullController.abort(options.signal?.reason);
|
|
174
|
+
if (options.signal?.aborted) onAbort();
|
|
175
|
+
else options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
176
|
+
try {
|
|
177
|
+
const outcome = await raceDiagnosticPull({
|
|
178
|
+
pull: options.pullDiagnostics({
|
|
179
|
+
request,
|
|
180
|
+
timeoutMs: remaining,
|
|
181
|
+
signal: pullController.signal,
|
|
182
|
+
operationId: options.operationId,
|
|
183
|
+
deadline: options.deadline,
|
|
184
|
+
}),
|
|
185
|
+
waitForChange: options.waitForChange,
|
|
186
|
+
freshPush: () =>
|
|
187
|
+
hasFreshPush(options.diagnosticStore, request, options.currentEvidenceRevision()),
|
|
188
|
+
current: () => isCurrentSynchronization(options.openDocuments, request),
|
|
189
|
+
});
|
|
190
|
+
if (outcome !== "pull") pullController.abort();
|
|
191
|
+
return outcome === "pull";
|
|
192
|
+
} finally {
|
|
193
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
194
|
+
}
|
|
195
|
+
}),
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
// A cancelled refresh must not degrade into failed coverage evidence:
|
|
199
|
+
// the caller no longer awaits a result.
|
|
200
|
+
throwIfCodeRequestInterrupted({ signal: options.signal, deadline: options.deadline });
|
|
201
|
+
|
|
202
|
+
const incomplete = results.some((result) => result.status === "rejected" || !result.value);
|
|
203
|
+
if (incomplete && options.requests.length > 0) {
|
|
204
|
+
const failedUris = options.requests.flatMap((request, index) => {
|
|
205
|
+
const result = results[index];
|
|
206
|
+
return result?.status === "rejected" && !isDiagnosticTimeout(result.reason)
|
|
207
|
+
? [request.uri]
|
|
208
|
+
: [];
|
|
209
|
+
});
|
|
210
|
+
throw new DiagnosticPullError(
|
|
211
|
+
results.some((result) => result.status === "rejected" && isDiagnosticTimeout(result.reason)),
|
|
212
|
+
failedUris,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
interface ClientDiagnosticRefreshOptions {
|
|
218
|
+
readonly host: ClientDiagnosticsHost;
|
|
219
|
+
readonly openDocuments: Map<string, OpenDocumentState>;
|
|
220
|
+
readonly diagnosticStore: Map<string, DiagnosticCacheEntry>;
|
|
221
|
+
readonly waiters: DiagnosticWaitRegistry;
|
|
222
|
+
readonly versionHistory: Map<string, number>;
|
|
223
|
+
readonly requestedFiles: readonly string[];
|
|
224
|
+
readonly evidenceRevision: () => number;
|
|
225
|
+
readonly failedFiles: () => ReadonlySet<string>;
|
|
226
|
+
readonly isRelatedUriTracked: (uri: string) => boolean;
|
|
227
|
+
readonly nextSynchronizationId: () => number;
|
|
228
|
+
readonly clearFile: (uri: string) => void;
|
|
229
|
+
readonly invalidateEvidence: (uri: string) => void;
|
|
230
|
+
readonly markUnversionedSyncMoment: (uri: string) => void;
|
|
231
|
+
readonly clearFailedFile: (uri: string) => void;
|
|
232
|
+
readonly options: { maxWaitMs?: number; quietMs?: number } & CodeRequestControl;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Refresh one client and return exact document evidence for that attempt. */
|
|
236
|
+
export async function refreshClientOpenDiagnostics(
|
|
237
|
+
options: ClientDiagnosticRefreshOptions,
|
|
238
|
+
): Promise<DiagnosticEvidenceSummary> {
|
|
239
|
+
// Reject immediately when the request was already cancelled: no document
|
|
240
|
+
// resynchronization or protocol traffic may start for a pass the caller
|
|
241
|
+
// no longer awaits.
|
|
242
|
+
throwIfCodeRequestInterrupted(options.options);
|
|
243
|
+
const supportsPull = options.host.supportsPullDiagnostics();
|
|
244
|
+
const observer = new DiagnosticObserver("refresh-open", supportsPull, options.options, {
|
|
245
|
+
server: options.host.server,
|
|
246
|
+
cwd: options.host.cwd,
|
|
247
|
+
});
|
|
248
|
+
if (!options.host.isOperational()) {
|
|
249
|
+
observer.skipped(options.requestedFiles.length);
|
|
250
|
+
return summarizeDiagnosticEvidence(
|
|
251
|
+
options.requestedFiles.map((file) => ({
|
|
252
|
+
file,
|
|
253
|
+
status:
|
|
254
|
+
getDiagnosticFileState(file) === "removed" ? ("removed" as const) : ("failed" as const),
|
|
255
|
+
})),
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const maxWaitMs = options.options.maxWaitMs ?? 3_000;
|
|
260
|
+
const quietMs = options.options.quietMs ?? 200;
|
|
261
|
+
const syncStart = Date.now();
|
|
262
|
+
const resynchronization = resynchronizeOpenDocuments({
|
|
263
|
+
openDocuments: options.openDocuments,
|
|
264
|
+
waiters: options.waiters,
|
|
265
|
+
nextVersion: (uri) => nextDocumentVersion(options.versionHistory, uri),
|
|
266
|
+
nextSynchronizationId: options.nextSynchronizationId,
|
|
267
|
+
evidenceRevision: options.evidenceRevision(),
|
|
268
|
+
sendNotification: (method, params) => options.host.sendNotification(method, params),
|
|
269
|
+
uriToFile,
|
|
270
|
+
clearFile: options.clearFile,
|
|
271
|
+
invalidateEvidence: options.invalidateEvidence,
|
|
272
|
+
markUnversionedSyncMoment: options.markUnversionedSyncMoment,
|
|
273
|
+
clearFailedFile: options.clearFailedFile,
|
|
274
|
+
});
|
|
275
|
+
let synchronizations = resynchronization.synchronizations;
|
|
276
|
+
const settleEpoch = options.waiters.settleEpoch;
|
|
277
|
+
observer.synchronized();
|
|
278
|
+
const documentCount = synchronizations.length;
|
|
279
|
+
let failedPullUris: ReadonlySet<string> = new Set();
|
|
280
|
+
const buildEvidence = () =>
|
|
281
|
+
buildDiagnosticRefreshEvidence({
|
|
282
|
+
requestedFiles: options.requestedFiles,
|
|
283
|
+
resynchronization,
|
|
284
|
+
synchronizations,
|
|
285
|
+
failedPullUris,
|
|
286
|
+
failedFiles: options.failedFiles(),
|
|
287
|
+
failedResynchronizations: new Set(resynchronization.failedFiles),
|
|
288
|
+
currentEvidenceRevision: options.evidenceRevision(),
|
|
289
|
+
openDocuments: options.openDocuments,
|
|
290
|
+
diagnosticStore: options.diagnosticStore,
|
|
291
|
+
});
|
|
292
|
+
if (documentCount === 0) {
|
|
293
|
+
observer.skipped(0);
|
|
294
|
+
return buildEvidence();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (supportsPull) {
|
|
298
|
+
const pull = await collectPullEvidenceForRefresh({
|
|
299
|
+
options,
|
|
300
|
+
synchronizations,
|
|
301
|
+
syncStart,
|
|
302
|
+
maxWaitMs,
|
|
303
|
+
observer,
|
|
304
|
+
});
|
|
305
|
+
failedPullUris = new Set(pull.failedPullUris);
|
|
306
|
+
if (pull.completed) return buildEvidence();
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
let finalSettle = await options.waiters.waitForSettle(
|
|
310
|
+
{
|
|
311
|
+
syncStart,
|
|
312
|
+
maxWaitMs,
|
|
313
|
+
quietMs,
|
|
314
|
+
settleEpoch,
|
|
315
|
+
isComplete: () =>
|
|
316
|
+
synchronizations.every((item) =>
|
|
317
|
+
hasFreshEvidence(options.diagnosticStore, item, options.evidenceRevision()),
|
|
318
|
+
),
|
|
319
|
+
latestReceived: () =>
|
|
320
|
+
latestFreshEvidenceReceivedAt(
|
|
321
|
+
options.diagnosticStore,
|
|
322
|
+
synchronizations,
|
|
323
|
+
options.evidenceRevision(),
|
|
324
|
+
),
|
|
325
|
+
},
|
|
326
|
+
options.options,
|
|
327
|
+
);
|
|
328
|
+
if (!supportsPull && finalSettle.outcome === "timed-out") {
|
|
329
|
+
const reopen = await reopenUnconfirmedDocuments({
|
|
330
|
+
options,
|
|
331
|
+
synchronizations,
|
|
332
|
+
maxWaitMs,
|
|
333
|
+
quietMs,
|
|
334
|
+
observer,
|
|
335
|
+
});
|
|
336
|
+
if (reopen.performed) {
|
|
337
|
+
synchronizations = reopen.synchronizations;
|
|
338
|
+
finalSettle = await options.waiters.waitForSettle(
|
|
339
|
+
{
|
|
340
|
+
syncStart: reopen.startedAt,
|
|
341
|
+
maxWaitMs: reopen.budgetMs,
|
|
342
|
+
quietMs,
|
|
343
|
+
settleEpoch: options.waiters.settleEpoch,
|
|
344
|
+
isComplete: () =>
|
|
345
|
+
synchronizations.every((item) =>
|
|
346
|
+
hasFreshEvidence(options.diagnosticStore, item, options.evidenceRevision()),
|
|
347
|
+
),
|
|
348
|
+
latestReceived: () =>
|
|
349
|
+
latestFreshEvidenceReceivedAt(
|
|
350
|
+
options.diagnosticStore,
|
|
351
|
+
synchronizations,
|
|
352
|
+
options.evidenceRevision(),
|
|
353
|
+
),
|
|
354
|
+
},
|
|
355
|
+
options.options,
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
observer.pushSettled(documentCount, finalSettle);
|
|
360
|
+
// A cancelled settle must not publish evidence the caller no longer awaits.
|
|
361
|
+
throwIfCodeRequestInterrupted(options.options);
|
|
362
|
+
return buildEvidence();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Pull diagnostic evidence for every synchronized document, or fall through
|
|
367
|
+
* to the push settle path when any pull fails. An interruption during the
|
|
368
|
+
* pull phase stops the refresh instead of degrading into failed coverage.
|
|
369
|
+
*/
|
|
370
|
+
async function collectPullEvidenceForRefresh(options: {
|
|
371
|
+
options: ClientDiagnosticRefreshOptions;
|
|
372
|
+
synchronizations: readonly DiagnosticSynchronization[];
|
|
373
|
+
syncStart: number;
|
|
374
|
+
maxWaitMs: number;
|
|
375
|
+
observer: DiagnosticObserver;
|
|
376
|
+
}): Promise<{ completed: boolean; failedPullUris: ReadonlySet<string> }> {
|
|
377
|
+
const { options: refresh, synchronizations, syncStart, maxWaitMs, observer } = options;
|
|
378
|
+
try {
|
|
379
|
+
await pullDiagnosticsForOpenDocuments({
|
|
380
|
+
requests: synchronizations,
|
|
381
|
+
syncStart,
|
|
382
|
+
maxWaitMs,
|
|
383
|
+
signal: refresh.options.signal,
|
|
384
|
+
deadline: refresh.options.deadline,
|
|
385
|
+
operationId: refresh.options.operationId,
|
|
386
|
+
currentEvidenceRevision: refresh.evidenceRevision,
|
|
387
|
+
openDocuments: refresh.openDocuments,
|
|
388
|
+
diagnosticStore: refresh.diagnosticStore,
|
|
389
|
+
waitForChange: () => refresh.waiters.waitForChange(),
|
|
390
|
+
pullDiagnostics: (pullOptions) =>
|
|
391
|
+
pullClientDiagnosticEvidenceFromHost({
|
|
392
|
+
host: refresh.host,
|
|
393
|
+
store: refresh.diagnosticStore,
|
|
394
|
+
openDocuments: refresh.openDocuments,
|
|
395
|
+
currentEvidenceRevision: refresh.evidenceRevision,
|
|
396
|
+
isRelatedUriTracked: refresh.isRelatedUriTracked,
|
|
397
|
+
request: {
|
|
398
|
+
uri: pullOptions.request.uri,
|
|
399
|
+
timeoutMs: pullOptions.timeoutMs,
|
|
400
|
+
synchronizationId: pullOptions.request.synchronizationId,
|
|
401
|
+
evidenceRevision:
|
|
402
|
+
refresh.openDocuments.get(pullOptions.request.uri)?.evidenceRevision ??
|
|
403
|
+
refresh.evidenceRevision(),
|
|
404
|
+
signal: pullOptions.signal,
|
|
405
|
+
deadline: pullOptions.deadline,
|
|
406
|
+
operationId: pullOptions.operationId,
|
|
407
|
+
},
|
|
408
|
+
}),
|
|
409
|
+
});
|
|
410
|
+
observer.pullCompleted(synchronizations.length);
|
|
411
|
+
return { completed: true, failedPullUris: new Set() };
|
|
412
|
+
} catch (error) {
|
|
413
|
+
observer.pullFailed(error);
|
|
414
|
+
if (error instanceof DiagnosticPullError) {
|
|
415
|
+
return { completed: false, failedPullUris: new Set(error.failedUris) };
|
|
416
|
+
}
|
|
417
|
+
if (isCodeRequestInterruption(error, refresh.options)) throw error;
|
|
418
|
+
return { completed: false, failedPullUris: new Set() };
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Reopen-resync fallback (R2): on push-only routes an open document that
|
|
424
|
+
|
|
425
|
+
* stays unconfirmed after the settle window receives no further push — a
|
|
426
|
+
* clean file gets no push on didChange at all. Close and reopen each
|
|
427
|
+
* unconfirmed document so the server publishes on didOpen, then settle
|
|
428
|
+
* again within a bounded second window. The cache entry and version
|
|
429
|
+
* history survive the reopen; other documents keep their server state.
|
|
430
|
+
*/
|
|
431
|
+
async function reopenUnconfirmedDocuments(options: {
|
|
432
|
+
options: ClientDiagnosticRefreshOptions;
|
|
433
|
+
synchronizations: readonly DiagnosticSynchronization[];
|
|
434
|
+
maxWaitMs: number;
|
|
435
|
+
quietMs: number;
|
|
436
|
+
observer: DiagnosticObserver;
|
|
437
|
+
}): Promise<{
|
|
438
|
+
performed: boolean;
|
|
439
|
+
startedAt: number;
|
|
440
|
+
budgetMs: number;
|
|
441
|
+
synchronizations: DiagnosticSynchronization[];
|
|
442
|
+
}> {
|
|
443
|
+
const { options: refresh, synchronizations, maxWaitMs, quietMs, observer } = options;
|
|
444
|
+
const startedAt = Date.now();
|
|
445
|
+
const budgetMs = Math.min(maxWaitMs, quietMs * 4);
|
|
446
|
+
const unconfirmed = synchronizations.filter(
|
|
447
|
+
(item) => !hasFreshEvidence(refresh.diagnosticStore, item, refresh.evidenceRevision()),
|
|
448
|
+
);
|
|
449
|
+
const reopenedSynchronizations: DiagnosticSynchronization[] = [];
|
|
450
|
+
for (const item of unconfirmed) {
|
|
451
|
+
const document = refresh.openDocuments.get(item.uri);
|
|
452
|
+
if (!document) continue;
|
|
453
|
+
const filePath = uriToFile(item.uri);
|
|
454
|
+
let content: string;
|
|
455
|
+
try {
|
|
456
|
+
content = readFileSync(filePath, "utf-8");
|
|
457
|
+
} catch {
|
|
458
|
+
// The file disappeared mid-refresh; keep the document as-is and
|
|
459
|
+
// report its current unconfirmed coverage.
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
reopenDocument({
|
|
463
|
+
uri: item.uri,
|
|
464
|
+
content,
|
|
465
|
+
document,
|
|
466
|
+
languageId: detectLanguageId(filePath),
|
|
467
|
+
nextVersion: () => nextDocumentVersion(refresh.versionHistory, item.uri),
|
|
468
|
+
nextSynchronizationId: refresh.nextSynchronizationId,
|
|
469
|
+
evidenceRevision: refresh.evidenceRevision(),
|
|
470
|
+
waiters: refresh.waiters,
|
|
471
|
+
sendNotification: (method, params) => refresh.host.sendNotification(method, params),
|
|
472
|
+
markUnversionedSyncMoment: () => refresh.markUnversionedSyncMoment(item.uri),
|
|
473
|
+
});
|
|
474
|
+
reopenedSynchronizations.push({
|
|
475
|
+
uri: item.uri,
|
|
476
|
+
synchronizationId: document.synchronizationId,
|
|
477
|
+
evidenceRevision: document.evidenceRevision,
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
if (reopenedSynchronizations.length === 0) {
|
|
481
|
+
return { performed: false, startedAt, budgetMs, synchronizations: [...synchronizations] };
|
|
482
|
+
}
|
|
483
|
+
observer.reopened(reopenedSynchronizations.length);
|
|
484
|
+
const reopenedByUri = new Map(reopenedSynchronizations.map((item) => [item.uri, item]));
|
|
485
|
+
return {
|
|
486
|
+
performed: true,
|
|
487
|
+
startedAt,
|
|
488
|
+
budgetMs,
|
|
489
|
+
synchronizations: synchronizations.map((item) => reopenedByUri.get(item.uri) ?? item),
|
|
490
|
+
};
|
|
491
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Sanitized ownership and transport control for one explicit diagnostic pull. */
|
|
2
|
+
export interface DiagnosticPullRequest {
|
|
3
|
+
readonly uri: string;
|
|
4
|
+
readonly previousResultId: string | undefined;
|
|
5
|
+
readonly timeoutMs: number;
|
|
6
|
+
readonly signal?: AbortSignal;
|
|
7
|
+
readonly deadline?: number;
|
|
8
|
+
readonly operationId?: string;
|
|
9
|
+
}
|