@mrclrchtr/supi-code-intelligence 5.0.0 → 6.0.1
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 +4 -2
- 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-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/README.md +36 -3
- 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-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +12 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +67 -28
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +63 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +46 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +1 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +214 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +278 -79
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +29 -8
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +101 -19
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +19 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +49 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +73 -15
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +5 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-extends.ts +68 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-path.ts +8 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +176 -24
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +4 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +46 -10
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +4 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +65 -17
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +143 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +43 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +31 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +2 -0
- 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-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- 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 +3 -3
- package/package.json +5 -5
- package/src/analysis/health/diagnostics.ts +58 -126
- package/src/analysis/health/file-scope.ts +184 -0
- package/src/analysis/health/recovery.ts +8 -1
- package/src/analysis/readiness.ts +4 -0
- package/src/analysis/search/ast-scan.ts +4 -1
- package/src/analysis/search/pattern-analysis.ts +10 -3
- package/src/analysis/search/pattern.ts +6 -1
- package/src/config.ts +35 -1
- package/src/extension.ts +57 -14
- package/src/overview/overview-data.ts +9 -2
- package/src/overview/overview.ts +49 -30
- package/src/overview/types.ts +2 -0
- package/src/session/find-types.ts +2 -2
- package/src/session/find-workflow.ts +3 -2
- package/src/session/health-refresh.ts +76 -49
- package/src/session/health-types.ts +7 -1
- package/src/session/health-workflow.ts +35 -18
- package/src/session/input/workflows.ts +2 -2
- package/src/session/inspect-workflow.ts +2 -1
- package/src/session/orientation/collect.ts +2 -2
- package/src/session/orientation-types.ts +2 -0
- package/src/session/orientation-workflow.ts +8 -2
- package/src/session/refactor-workflow.ts +2 -1
- package/src/session/session.ts +25 -1
- package/src/substrate/lsp/maintenance.ts +105 -23
- package/src/substrate/lsp/recovery.ts +11 -5
- package/src/tool/code_find/execute.ts +23 -0
- package/src/tool/code_find/guidance.ts +8 -0
- package/src/tool/{find → code_find}/render.ts +1 -1
- package/src/tool/{result/find.ts → code_find/result.ts} +36 -11
- package/src/tool/code_find/spec.ts +37 -0
- package/src/tool/code_graph/execute.ts +24 -0
- package/src/tool/code_graph/guidance.ts +6 -0
- package/src/tool/{graph → code_graph}/markdown.ts +1 -1
- package/src/tool/{result/graph.ts → code_graph/result.ts} +69 -4
- package/src/tool/code_graph/spec.ts +39 -0
- package/src/tool/{health → code_health}/execute.ts +2 -18
- package/src/tool/code_health/guidance.ts +8 -0
- package/src/tool/{health → code_health}/markdown.ts +68 -18
- package/src/tool/{result/health.ts → code_health/result.ts} +29 -4
- package/src/tool/code_health/spec.ts +41 -0
- package/src/tool/code_inspect/execute.ts +20 -0
- package/src/tool/code_inspect/guidance.ts +6 -0
- package/src/tool/{inspect → code_inspect}/markdown.ts +1 -1
- package/src/tool/{result/inspect.ts → code_inspect/result.ts} +32 -3
- package/src/tool/code_inspect/spec.ts +25 -0
- package/src/tool/code_orientation/execute.ts +25 -0
- package/src/tool/code_orientation/guidance.ts +9 -0
- package/src/tool/{orientation → code_orientation}/markdown.ts +1 -1
- package/src/tool/{result/orientation.ts → code_orientation/result.ts} +67 -3
- package/src/tool/code_orientation/spec.ts +25 -0
- package/src/tool/code_refactor_apply/execute.ts +17 -0
- package/src/tool/code_refactor_apply/guidance.ts +5 -0
- package/src/tool/{refactor-apply/execute.ts → code_refactor_apply/result.ts} +5 -11
- package/src/tool/code_refactor_apply/spec.ts +26 -0
- package/src/tool/code_refactor_plan/execute.ts +27 -0
- package/src/tool/code_refactor_plan/guidance.ts +8 -0
- package/src/tool/{refactor-plan/execute.ts → code_refactor_plan/result.ts} +9 -22
- package/src/tool/code_refactor_plan/spec.ts +25 -0
- package/src/tool/code_resolve/execute.ts +19 -0
- package/src/tool/code_resolve/guidance.ts +8 -0
- package/src/tool/{resolve → code_resolve}/markdown.ts +1 -1
- package/src/tool/{result/resolve.ts → code_resolve/result.ts} +37 -24
- package/src/tool/code_resolve/spec.ts +25 -0
- package/src/tool/guidance.ts +71 -52
- package/src/tool/infra/truncate.ts +40 -0
- package/src/tool/{refactor-plan/markdown.ts → refactor-markdown.ts} +4 -7
- package/src/tool/register.ts +9 -97
- package/src/tool/result/refactor.ts +1 -4
- package/src/tool/schemas.ts +26 -157
- package/src/tool/specs.ts +40 -126
- package/src/tool/find/execute.ts +0 -43
- package/src/tool/graph/execute.ts +0 -82
- package/src/tool/inspect/execute.ts +0 -40
- package/src/tool/orientation/execute.ts +0 -80
- package/src/tool/resolve/execute.ts +0 -53
- /package/src/tool/{find → code_find}/ast-kinds.ts +0 -0
- /package/src/tool/{find → code_find}/markdown.ts +0 -0
- /package/src/tool/{find → code_find}/modes.ts +0 -0
- /package/src/tool/{find → code_find}/tui.ts +0 -0
- /package/src/tool/{graph → code_graph}/tui.ts +0 -0
- /package/src/tool/{health → code_health}/refresh-status.ts +0 -0
- /package/src/tool/{health → code_health}/semantic-state.ts +0 -0
- /package/src/tool/{health → code_health}/tui.ts +0 -0
- /package/src/tool/{inspect → code_inspect}/tui.ts +0 -0
- /package/src/tool/{orientation → code_orientation}/tui.ts +0 -0
- /package/src/tool/{refactor-apply → code_refactor_apply}/tui.ts +0 -0
- /package/src/tool/{refactor-plan → code_refactor_plan}/tui.ts +0 -0
- /package/src/tool/{resolve → code_resolve}/tui.ts +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-tree-sitter",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "Structural AST analysis for SuPi code intelligence",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"jiti": "^2.7.0",
|
|
38
38
|
"web-tree-sitter": "^0.26.8",
|
|
39
|
-
"@mrclrchtr/supi-code-runtime": "
|
|
40
|
-
"@mrclrchtr/supi-core": "
|
|
39
|
+
"@mrclrchtr/supi-code-runtime": "6.0.1",
|
|
40
|
+
"@mrclrchtr/supi-core": "6.0.1"
|
|
41
41
|
},
|
|
42
42
|
"bundledDependencies": [
|
|
43
43
|
"@mrclrchtr/supi-code-runtime",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-code-intelligence",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "LSP and AST navigation, search, diagnostics, and refactoring",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"yaml": "^2.9.0",
|
|
38
|
-
"@mrclrchtr/supi-
|
|
39
|
-
"@mrclrchtr/supi-
|
|
40
|
-
"@mrclrchtr/supi-
|
|
41
|
-
"@mrclrchtr/supi-
|
|
38
|
+
"@mrclrchtr/supi-code-runtime": "6.0.1",
|
|
39
|
+
"@mrclrchtr/supi-tree-sitter": "6.0.1",
|
|
40
|
+
"@mrclrchtr/supi-lsp": "6.0.1",
|
|
41
|
+
"@mrclrchtr/supi-core": "6.0.1"
|
|
42
42
|
},
|
|
43
43
|
"bundledDependencies": [
|
|
44
44
|
"@mrclrchtr/supi-code-runtime",
|
|
@@ -3,25 +3,28 @@
|
|
|
3
3
|
|
|
4
4
|
import { existsSync, statSync } from "node:fs";
|
|
5
5
|
import { relative, resolve } from "node:path";
|
|
6
|
-
import {
|
|
7
|
-
type CodeRequestControl,
|
|
8
|
-
isCodeRequestInterruption,
|
|
9
|
-
} from "@mrclrchtr/supi-code-runtime/api";
|
|
6
|
+
import type { CodeRequestControl } from "@mrclrchtr/supi-code-runtime/api";
|
|
10
7
|
import { isWithinOrEqual } from "@mrclrchtr/supi-core/api";
|
|
11
8
|
import type {
|
|
12
|
-
Diagnostic,
|
|
13
9
|
DiagnosticEvidenceDocument,
|
|
14
10
|
DiagnosticEvidenceSummary,
|
|
11
|
+
WorkspaceDiagnosticReport,
|
|
15
12
|
WorkspaceLspRuntime,
|
|
16
13
|
} from "@mrclrchtr/supi-lsp/api";
|
|
17
14
|
import { mergeDiagnosticEvidence } from "../../diagnostics/evidence.ts";
|
|
18
15
|
import type {
|
|
19
16
|
HealthDiagnosticEntry,
|
|
20
|
-
HealthDiagnosticMessage,
|
|
21
17
|
HealthDiagnosticObservation,
|
|
22
18
|
HealthDiagnosticScope,
|
|
23
19
|
HealthSection,
|
|
24
20
|
} from "../../session/health-types.ts";
|
|
21
|
+
import {
|
|
22
|
+
collectScopedFileDiagnostics,
|
|
23
|
+
fileScopeStatus,
|
|
24
|
+
toFileDiagnosticEntries,
|
|
25
|
+
unavailableDiagnostics,
|
|
26
|
+
unavailableFileEvidence,
|
|
27
|
+
} from "./file-scope.ts";
|
|
25
28
|
|
|
26
29
|
// ── Diagnostics ───────────────────────────────────────────────────────
|
|
27
30
|
|
|
@@ -47,8 +50,10 @@ interface CollectDiagnosticsOptions {
|
|
|
47
50
|
/** Collect individual messages per file (detailed level). */
|
|
48
51
|
readonly detailed?: boolean;
|
|
49
52
|
readonly requestControl?: CodeRequestControl;
|
|
50
|
-
/**
|
|
53
|
+
/** Evidence from an explicit workspace refresh, when one ran. */
|
|
51
54
|
readonly refreshEvidence?: DiagnosticEvidenceSummary;
|
|
55
|
+
/** Coherent final report from an explicit workspace refresh, when one ran. */
|
|
56
|
+
readonly refreshReport?: WorkspaceDiagnosticReport;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
/** Collect diagnostics without widening the requested evidence scope. */
|
|
@@ -61,75 +66,49 @@ export async function collectDiagnostics(
|
|
|
61
66
|
return unavailableDiagnostics(
|
|
62
67
|
scope,
|
|
63
68
|
unavailableReason,
|
|
64
|
-
unavailableScopeEvidence(
|
|
69
|
+
unavailableScopeEvidence({
|
|
70
|
+
scope,
|
|
71
|
+
refreshEvidence: options.refreshEvidence,
|
|
72
|
+
refreshReport: options.refreshReport,
|
|
73
|
+
evidenceService: options.evidenceService,
|
|
74
|
+
cwd,
|
|
75
|
+
}),
|
|
76
|
+
scope.kind === "file" ? fileScopeStatus(scope.path, cwd) : undefined,
|
|
65
77
|
);
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
return scope.kind === "file"
|
|
69
|
-
? collectScopedFileDiagnostics(service, scope, detailed, requestControl)
|
|
81
|
+
? collectScopedFileDiagnostics({ service, scope, cwd, detailed, requestControl })
|
|
70
82
|
: collectTrackedFileDiagnostics({
|
|
71
83
|
service,
|
|
72
84
|
scope,
|
|
73
85
|
cwd,
|
|
74
86
|
detailed,
|
|
75
87
|
refreshEvidence: options.refreshEvidence,
|
|
88
|
+
refreshReport: options.refreshReport,
|
|
76
89
|
});
|
|
77
90
|
}
|
|
78
91
|
|
|
79
|
-
async function collectScopedFileDiagnostics(
|
|
80
|
-
service: WorkspaceLspRuntime,
|
|
81
|
-
scope: Extract<HealthDiagnosticScope, { kind: "file" }>,
|
|
82
|
-
detailed?: boolean,
|
|
83
|
-
requestControl?: CodeRequestControl,
|
|
84
|
-
): Promise<HealthDiagnosticObservation> {
|
|
85
|
-
try {
|
|
86
|
-
const result = await service.fileDiagnostics(scope.path, 4, requestControl);
|
|
87
|
-
if (result.kind === "unavailable") {
|
|
88
|
-
return unavailableDiagnostics(scope, result.reason, unavailableFileEvidence(scope.path));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const entries = toFileDiagnosticEntries(scope.path, result.data, detailed);
|
|
92
|
-
return result.kind === "partial"
|
|
93
|
-
? {
|
|
94
|
-
kind: "partial",
|
|
95
|
-
scope,
|
|
96
|
-
entries,
|
|
97
|
-
evidence: singleFileEvidence(scope.path, "unconfirmed"),
|
|
98
|
-
reason: result.reason,
|
|
99
|
-
}
|
|
100
|
-
: {
|
|
101
|
-
kind: "completed",
|
|
102
|
-
scope,
|
|
103
|
-
entries,
|
|
104
|
-
evidence: singleFileEvidence(scope.path, "confirmed"),
|
|
105
|
-
};
|
|
106
|
-
} catch (error) {
|
|
107
|
-
if (isCodeRequestInterruption(error, requestControl)) throw error;
|
|
108
|
-
return unavailableDiagnostics(
|
|
109
|
-
scope,
|
|
110
|
-
errorMessage(error, "File diagnostic request failed."),
|
|
111
|
-
unavailableFileEvidence(scope.path),
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
92
|
interface TrackedFileDiagnosticOptions {
|
|
117
93
|
readonly service: WorkspaceLspRuntime;
|
|
118
94
|
readonly scope: Extract<HealthDiagnosticScope, { kind: "tracked-files" }>;
|
|
119
95
|
readonly cwd: string;
|
|
120
96
|
readonly detailed?: boolean;
|
|
121
97
|
readonly refreshEvidence?: DiagnosticEvidenceSummary;
|
|
98
|
+
readonly refreshReport?: WorkspaceDiagnosticReport;
|
|
122
99
|
}
|
|
123
100
|
|
|
124
101
|
function collectTrackedFileDiagnostics(
|
|
125
102
|
options: TrackedFileDiagnosticOptions,
|
|
126
103
|
): HealthDiagnosticObservation {
|
|
127
|
-
const { service, scope, cwd, detailed, refreshEvidence } = options;
|
|
104
|
+
const { service, scope, cwd, detailed, refreshEvidence, refreshReport } = options;
|
|
128
105
|
try {
|
|
129
106
|
const snapshot = detailed
|
|
130
|
-
? collectWorkspaceDiagnosticsDetailed(service, scope.filter, cwd)
|
|
131
|
-
: collectWorkspaceDiagnostics(service, scope.filter, cwd);
|
|
132
|
-
const sourceEvidence =
|
|
107
|
+
? collectWorkspaceDiagnosticsDetailed(service, scope.filter, cwd, refreshReport)
|
|
108
|
+
: collectWorkspaceDiagnostics(service, scope.filter, cwd, refreshReport);
|
|
109
|
+
const sourceEvidence = refreshReport
|
|
110
|
+
? snapshot.evidence
|
|
111
|
+
: mergeEvidence(refreshEvidence, snapshot.evidence, cwd);
|
|
133
112
|
const scopedEvidence = selectTrackedFileEvidence(sourceEvidence, scope.filter, cwd);
|
|
134
113
|
const evidence = ensureEvidenceCoversEntries(scopedEvidence, snapshot.entries, cwd);
|
|
135
114
|
return evidenceIsComplete(evidence, snapshot.entries.length > 0, snapshot.current)
|
|
@@ -142,8 +121,9 @@ function collectTrackedFileDiagnostics(
|
|
|
142
121
|
reason: diagnosticEvidenceReason(evidence),
|
|
143
122
|
};
|
|
144
123
|
} catch (error) {
|
|
145
|
-
const
|
|
146
|
-
|
|
124
|
+
const evidenceSource = options.refreshReport?.summary.evidence ?? options.refreshEvidence;
|
|
125
|
+
const evidence = evidenceSource
|
|
126
|
+
? selectTrackedFileEvidence(evidenceSource, scope.filter, cwd)
|
|
147
127
|
: emptyEvidence();
|
|
148
128
|
return unavailableDiagnostics(
|
|
149
129
|
scope,
|
|
@@ -153,31 +133,17 @@ function collectTrackedFileDiagnostics(
|
|
|
153
133
|
}
|
|
154
134
|
}
|
|
155
135
|
|
|
156
|
-
function toFileDiagnosticEntries(
|
|
157
|
-
file: string,
|
|
158
|
-
diagnostics: ReadonlyArray<Pick<Diagnostic, "severity" | "message" | "source" | "range">>,
|
|
159
|
-
detailed?: boolean,
|
|
160
|
-
): HealthDiagnosticEntry[] {
|
|
161
|
-
const errors = diagnostics.filter((diagnostic) => (diagnostic.severity ?? 1) === 1).length;
|
|
162
|
-
const warnings = diagnostics.filter((diagnostic) => (diagnostic.severity ?? 1) === 2).length;
|
|
163
|
-
if (!hasIssueCounts(errors, warnings)) return [];
|
|
164
|
-
const entry: HealthDiagnosticEntry = { file, errors, warnings };
|
|
165
|
-
if (detailed) {
|
|
166
|
-
return [{ ...entry, messages: extractMessages(diagnostics) }];
|
|
167
|
-
}
|
|
168
|
-
return [entry];
|
|
169
|
-
}
|
|
170
|
-
|
|
171
136
|
function collectWorkspaceDiagnostics(
|
|
172
137
|
service: WorkspaceLspRuntime,
|
|
173
138
|
scopeFilter: string | null,
|
|
174
139
|
cwd: string,
|
|
140
|
+
report?: WorkspaceDiagnosticReport,
|
|
175
141
|
): {
|
|
176
142
|
entries: HealthDiagnosticEntry[];
|
|
177
143
|
current: boolean;
|
|
178
144
|
evidence: DiagnosticEvidenceSummary;
|
|
179
145
|
} {
|
|
180
|
-
const summary = service.getWorkspaceDiagnosticSummary();
|
|
146
|
+
const summary = report?.summary ?? service.getWorkspaceDiagnosticSummary();
|
|
181
147
|
const result: HealthDiagnosticEntry[] = [];
|
|
182
148
|
|
|
183
149
|
for (const entry of summary.entries) {
|
|
@@ -195,12 +161,13 @@ function collectWorkspaceDiagnosticsDetailed(
|
|
|
195
161
|
service: WorkspaceLspRuntime,
|
|
196
162
|
scopeFilter: string | null,
|
|
197
163
|
cwd: string,
|
|
164
|
+
report?: WorkspaceDiagnosticReport,
|
|
198
165
|
): {
|
|
199
166
|
entries: HealthDiagnosticEntry[];
|
|
200
167
|
current: boolean;
|
|
201
168
|
evidence: DiagnosticEvidenceSummary;
|
|
202
169
|
} {
|
|
203
|
-
const outstanding = service.getOutstandingDiagnostics(2);
|
|
170
|
+
const outstanding = report?.outstanding ?? service.getOutstandingDiagnostics(2);
|
|
204
171
|
const result: HealthDiagnosticEntry[] = [];
|
|
205
172
|
|
|
206
173
|
for (const { file, diagnostics } of outstanding.entries) {
|
|
@@ -213,37 +180,24 @@ function collectWorkspaceDiagnosticsDetailed(
|
|
|
213
180
|
return { entries: result, current: outstanding.current, evidence: outstanding.evidence };
|
|
214
181
|
}
|
|
215
182
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
): HealthDiagnosticMessage[] {
|
|
223
|
-
const errorsAndWarnings = diagnostics
|
|
224
|
-
.filter((d) => (d.severity ?? 1) <= 2)
|
|
225
|
-
.sort(
|
|
226
|
-
(a, b) => (a.severity ?? 1) - (b.severity ?? 1) || a.range.start.line - b.range.start.line,
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
return errorsAndWarnings.slice(0, MAX_MESSAGES_PER_FILE).map((d) => ({
|
|
230
|
-
line: d.range.start.line + 1,
|
|
231
|
-
severity: (d.severity ?? 1) === 1 ? ("error" as const) : ("warning" as const),
|
|
232
|
-
message: typeof d.message === "string" ? d.message : d.message.value,
|
|
233
|
-
...(d.source ? { source: d.source } : {}),
|
|
234
|
-
}));
|
|
183
|
+
interface UnavailableScopeEvidenceOptions {
|
|
184
|
+
readonly scope: HealthDiagnosticScope;
|
|
185
|
+
readonly refreshEvidence?: DiagnosticEvidenceSummary;
|
|
186
|
+
readonly refreshReport?: WorkspaceDiagnosticReport;
|
|
187
|
+
readonly evidenceService?: WorkspaceLspRuntime | null;
|
|
188
|
+
readonly cwd: string;
|
|
235
189
|
}
|
|
236
190
|
|
|
237
191
|
function unavailableScopeEvidence(
|
|
238
|
-
|
|
239
|
-
refreshEvidence: DiagnosticEvidenceSummary | undefined,
|
|
240
|
-
evidenceService: WorkspaceLspRuntime | null | undefined,
|
|
241
|
-
cwd: string,
|
|
192
|
+
options: UnavailableScopeEvidenceOptions,
|
|
242
193
|
): DiagnosticEvidenceSummary {
|
|
243
|
-
const
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
194
|
+
const { scope, refreshEvidence, refreshReport, evidenceService, cwd } = options;
|
|
195
|
+
const runtimeEvidence = refreshReport?.summary.evidence ?? readRuntimeEvidence(evidenceService);
|
|
196
|
+
const knownEvidence = refreshReport
|
|
197
|
+
? runtimeEvidence
|
|
198
|
+
: refreshEvidence
|
|
199
|
+
? mergeDiagnosticEvidence(refreshEvidence, runtimeEvidence, cwd, "conservative")
|
|
200
|
+
: runtimeEvidence;
|
|
247
201
|
if (knownEvidence.requested === 0 && knownEvidence.documents.length === 0) {
|
|
248
202
|
return scope.kind === "file" ? unavailableFileEvidence(scope.path) : emptyEvidence();
|
|
249
203
|
}
|
|
@@ -256,10 +210,6 @@ function unavailableScopeEvidence(
|
|
|
256
210
|
return scope.kind === "file" ? unavailableFileEvidence(scope.path) : scoped;
|
|
257
211
|
}
|
|
258
212
|
|
|
259
|
-
function unavailableFileEvidence(file: string): DiagnosticEvidenceSummary {
|
|
260
|
-
return singleFileEvidence(file, existsSync(file) ? "failed" : "removed");
|
|
261
|
-
}
|
|
262
|
-
|
|
263
213
|
function readRuntimeEvidence(
|
|
264
214
|
service: WorkspaceLspRuntime | null | undefined,
|
|
265
215
|
): DiagnosticEvidenceSummary {
|
|
@@ -271,14 +221,6 @@ function readRuntimeEvidence(
|
|
|
271
221
|
}
|
|
272
222
|
}
|
|
273
223
|
|
|
274
|
-
function unavailableDiagnostics(
|
|
275
|
-
scope: HealthDiagnosticScope,
|
|
276
|
-
reason: string,
|
|
277
|
-
evidence: DiagnosticEvidenceSummary = emptyEvidence(),
|
|
278
|
-
): HealthDiagnosticObservation {
|
|
279
|
-
return { kind: "unavailable", scope, entries: [], evidence, reason };
|
|
280
|
-
}
|
|
281
|
-
|
|
282
224
|
function errorMessage(error: unknown, fallback: string): string {
|
|
283
225
|
return error instanceof Error && error.message ? error.message : fallback;
|
|
284
226
|
}
|
|
@@ -298,20 +240,6 @@ function emptyEvidence(): DiagnosticEvidenceSummary {
|
|
|
298
240
|
};
|
|
299
241
|
}
|
|
300
242
|
|
|
301
|
-
function singleFileEvidence(
|
|
302
|
-
file: string,
|
|
303
|
-
status: DiagnosticEvidenceDocument["status"],
|
|
304
|
-
): DiagnosticEvidenceSummary {
|
|
305
|
-
return {
|
|
306
|
-
requested: 1,
|
|
307
|
-
confirmed: status === "confirmed" ? 1 : 0,
|
|
308
|
-
unconfirmed: status === "unconfirmed" ? 1 : 0,
|
|
309
|
-
failed: status === "failed" ? 1 : 0,
|
|
310
|
-
removed: status === "removed" ? 1 : 0,
|
|
311
|
-
documents: [{ file, status }],
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
|
|
315
243
|
function mergeEvidence(
|
|
316
244
|
refreshEvidence: DiagnosticEvidenceSummary | undefined,
|
|
317
245
|
snapshotEvidence: DiagnosticEvidenceSummary,
|
|
@@ -375,15 +303,19 @@ function evidenceIsComplete(
|
|
|
375
303
|
if (!snapshotCurrent && evidence.requested === 0) return false;
|
|
376
304
|
if (evidence.requested === 0) return !hasDiagnosticEntries;
|
|
377
305
|
return (
|
|
378
|
-
evidence.confirmed === evidence.requested &&
|
|
306
|
+
evidence.confirmed + evidence.removed === evidence.requested &&
|
|
379
307
|
evidence.unconfirmed === 0 &&
|
|
380
|
-
evidence.failed === 0
|
|
381
|
-
evidence.removed === 0
|
|
308
|
+
evidence.failed === 0
|
|
382
309
|
);
|
|
383
310
|
}
|
|
384
311
|
|
|
385
312
|
function diagnosticEvidenceReason(evidence: DiagnosticEvidenceSummary): string {
|
|
386
|
-
|
|
313
|
+
let reason = `Diagnostic evidence is partial: ${evidence.requested} requested, ${evidence.confirmed} confirmed, ${evidence.unconfirmed} unconfirmed, ${evidence.failed} failed, ${evidence.removed} removed.`;
|
|
314
|
+
if (evidence.unconfirmed > 0) {
|
|
315
|
+
reason +=
|
|
316
|
+
" Unconfirmed documents await a later diagnostic republish before their evidence can be confirmed (ADR 0021).";
|
|
317
|
+
}
|
|
318
|
+
return reason;
|
|
387
319
|
}
|
|
388
320
|
|
|
389
321
|
export function isDirectory(filePath: string): boolean {
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// Single-file diagnostics collection for code_health.
|
|
2
|
+
//
|
|
3
|
+
// Owns the file-scope health request: the live pull, the tsconfig scope
|
|
4
|
+
// decision for the requested file, and the evidence factories shared by the
|
|
5
|
+
// file-scope outcomes. Kept separate from the workspace-tracked collection
|
|
6
|
+
// (diagnostics.ts) so the scope-decision surface stays in one place.
|
|
7
|
+
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import {
|
|
10
|
+
type CodeRequestControl,
|
|
11
|
+
isCodeRequestInterruption,
|
|
12
|
+
} from "@mrclrchtr/supi-code-runtime/api";
|
|
13
|
+
import {
|
|
14
|
+
type Diagnostic,
|
|
15
|
+
type DiagnosticEvidenceDocument,
|
|
16
|
+
type DiagnosticEvidenceSummary,
|
|
17
|
+
type FileScopeDecision,
|
|
18
|
+
getFileScopeDecision,
|
|
19
|
+
TENTATIVE_PUSH_UNAVAILABLE_REASON,
|
|
20
|
+
type WorkspaceLspRuntime,
|
|
21
|
+
} from "@mrclrchtr/supi-lsp/api";
|
|
22
|
+
import type {
|
|
23
|
+
HealthDiagnosticEntry,
|
|
24
|
+
HealthDiagnosticMessage,
|
|
25
|
+
HealthDiagnosticObservation,
|
|
26
|
+
HealthDiagnosticScope,
|
|
27
|
+
} from "../../session/health-types.ts";
|
|
28
|
+
|
|
29
|
+
/** Collect a live per-file diagnostic pull with its tsconfig scope decision. */
|
|
30
|
+
export async function collectScopedFileDiagnostics(options: {
|
|
31
|
+
service: WorkspaceLspRuntime;
|
|
32
|
+
scope: Extract<HealthDiagnosticScope, { kind: "file" }>;
|
|
33
|
+
cwd: string;
|
|
34
|
+
detailed?: boolean;
|
|
35
|
+
requestControl?: CodeRequestControl;
|
|
36
|
+
}): Promise<HealthDiagnosticObservation> {
|
|
37
|
+
const { service, scope, cwd, detailed, requestControl } = options;
|
|
38
|
+
try {
|
|
39
|
+
const result = await service.fileDiagnostics(scope.path, 4, requestControl);
|
|
40
|
+
if (result.kind === "unavailable") {
|
|
41
|
+
const evidence =
|
|
42
|
+
result.reason === TENTATIVE_PUSH_UNAVAILABLE_REASON
|
|
43
|
+
? singleFileEvidence(scope.path, "unconfirmed")
|
|
44
|
+
: unavailableFileEvidence(scope.path);
|
|
45
|
+
return unavailableDiagnostics(
|
|
46
|
+
scope,
|
|
47
|
+
result.reason,
|
|
48
|
+
evidence,
|
|
49
|
+
fileScopeStatus(scope.path, cwd),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const entries = toFileDiagnosticEntries(scope.path, result.data, detailed);
|
|
54
|
+
const status = fileScopeStatus(scope.path, cwd);
|
|
55
|
+
return result.kind === "partial"
|
|
56
|
+
? {
|
|
57
|
+
kind: "partial",
|
|
58
|
+
scope,
|
|
59
|
+
entries,
|
|
60
|
+
evidence: singleFileEvidence(scope.path, "unconfirmed"),
|
|
61
|
+
reason: result.reason,
|
|
62
|
+
...(status ? { scopeStatus: status } : {}),
|
|
63
|
+
}
|
|
64
|
+
: {
|
|
65
|
+
kind: "completed",
|
|
66
|
+
scope,
|
|
67
|
+
entries,
|
|
68
|
+
evidence: singleFileEvidence(scope.path, "confirmed"),
|
|
69
|
+
...(status ? { scopeStatus: status } : {}),
|
|
70
|
+
};
|
|
71
|
+
} catch (error) {
|
|
72
|
+
if (isCodeRequestInterruption(error, requestControl)) throw error;
|
|
73
|
+
return unavailableDiagnostics(
|
|
74
|
+
scope,
|
|
75
|
+
errorMessage(error, "File diagnostic request failed."),
|
|
76
|
+
unavailableFileEvidence(scope.path),
|
|
77
|
+
fileScopeStatus(scope.path, cwd),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Tsconfig scope decision for the requested file, when it can be computed.
|
|
84
|
+
*
|
|
85
|
+
* Uses the same decision model the diagnostic filter delegates to, so the
|
|
86
|
+
* rendered status line cannot drift from filter behavior. Telemetry-only:
|
|
87
|
+
* a failure to compute never fails the diagnostic request.
|
|
88
|
+
*/
|
|
89
|
+
export function fileScopeStatus(filePath: string, cwd: string): FileScopeDecision | null {
|
|
90
|
+
try {
|
|
91
|
+
return getFileScopeDecision(filePath, cwd);
|
|
92
|
+
} catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function toFileDiagnosticEntries(
|
|
98
|
+
file: string,
|
|
99
|
+
diagnostics: ReadonlyArray<Pick<Diagnostic, "severity" | "message" | "source" | "range">>,
|
|
100
|
+
detailed?: boolean,
|
|
101
|
+
): HealthDiagnosticEntry[] {
|
|
102
|
+
const errors = diagnostics.filter((diagnostic) => (diagnostic.severity ?? 1) === 1).length;
|
|
103
|
+
const warnings = diagnostics.filter((diagnostic) => (diagnostic.severity ?? 1) === 2).length;
|
|
104
|
+
if (!hasIssueCounts(errors, warnings)) return [];
|
|
105
|
+
const entry: HealthDiagnosticEntry = { file, errors, warnings };
|
|
106
|
+
if (detailed) {
|
|
107
|
+
return [{ ...entry, messages: extractMessages(diagnostics) }];
|
|
108
|
+
}
|
|
109
|
+
return [entry];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ── Message extraction ────────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
const MAX_MESSAGES_PER_FILE = 3;
|
|
115
|
+
|
|
116
|
+
function extractMessages(
|
|
117
|
+
diagnostics: ReadonlyArray<Pick<Diagnostic, "severity" | "message" | "source" | "range">>,
|
|
118
|
+
): HealthDiagnosticMessage[] {
|
|
119
|
+
const errorsAndWarnings = diagnostics
|
|
120
|
+
.filter((d) => (d.severity ?? 1) <= 2)
|
|
121
|
+
.sort(
|
|
122
|
+
(a, b) => (a.severity ?? 1) - (b.severity ?? 1) || a.range.start.line - b.range.start.line,
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return errorsAndWarnings.slice(0, MAX_MESSAGES_PER_FILE).map((d) => ({
|
|
126
|
+
line: d.range.start.line + 1,
|
|
127
|
+
severity: (d.severity ?? 1) === 1 ? ("error" as const) : ("warning" as const),
|
|
128
|
+
message: typeof d.message === "string" ? d.message : d.message.value,
|
|
129
|
+
...(d.source ? { source: d.source } : {}),
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function unavailableDiagnostics(
|
|
134
|
+
scope: HealthDiagnosticScope,
|
|
135
|
+
reason: string,
|
|
136
|
+
evidence: DiagnosticEvidenceSummary = emptyEvidence(),
|
|
137
|
+
scopeStatus?: FileScopeDecision | null,
|
|
138
|
+
): HealthDiagnosticObservation {
|
|
139
|
+
return {
|
|
140
|
+
kind: "unavailable",
|
|
141
|
+
scope,
|
|
142
|
+
entries: [],
|
|
143
|
+
evidence,
|
|
144
|
+
reason,
|
|
145
|
+
...(scopeStatus ? { scopeStatus } : {}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function unavailableFileEvidence(file: string): DiagnosticEvidenceSummary {
|
|
150
|
+
return singleFileEvidence(file, existsSync(file) ? "failed" : "removed");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function singleFileEvidence(
|
|
154
|
+
file: string,
|
|
155
|
+
status: DiagnosticEvidenceDocument["status"],
|
|
156
|
+
): DiagnosticEvidenceSummary {
|
|
157
|
+
return {
|
|
158
|
+
requested: 1,
|
|
159
|
+
confirmed: status === "confirmed" ? 1 : 0,
|
|
160
|
+
unconfirmed: status === "unconfirmed" ? 1 : 0,
|
|
161
|
+
failed: status === "failed" ? 1 : 0,
|
|
162
|
+
removed: status === "removed" ? 1 : 0,
|
|
163
|
+
documents: [{ file, status }],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function emptyEvidence(): DiagnosticEvidenceSummary {
|
|
168
|
+
return {
|
|
169
|
+
requested: 0,
|
|
170
|
+
confirmed: 0,
|
|
171
|
+
unconfirmed: 0,
|
|
172
|
+
failed: 0,
|
|
173
|
+
removed: 0,
|
|
174
|
+
documents: [],
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function hasIssueCounts(errors: number, warnings: number): boolean {
|
|
179
|
+
return errors > 0 || warnings > 0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function errorMessage(error: unknown, fallback: string): string {
|
|
183
|
+
return error instanceof Error && error.message ? error.message : fallback;
|
|
184
|
+
}
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
// Extracted from orchestrate.ts.
|
|
3
3
|
|
|
4
4
|
import type { CapabilityState, CodeRequestControl } from "@mrclrchtr/supi-code-runtime/api";
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
DiagnosticEvidenceSummary,
|
|
7
|
+
RecoverDiagnosticsResult,
|
|
8
|
+
WorkspaceLspRuntime,
|
|
9
|
+
} from "@mrclrchtr/supi-lsp/api";
|
|
6
10
|
|
|
7
11
|
// ── Recovery ──────────────────────────────────────────────────────────
|
|
8
12
|
|
|
@@ -10,6 +14,8 @@ interface RecoverOptions {
|
|
|
10
14
|
service: WorkspaceLspRuntime;
|
|
11
15
|
progress?: () => void;
|
|
12
16
|
control?: CodeRequestControl;
|
|
17
|
+
/** Evidence from the maintenance refresh, so the recovery pass skips its own refresh. */
|
|
18
|
+
initialEvidence?: DiagnosticEvidenceSummary;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
/** Run the runtime's best-effort recovery and preserve its established outcome. */
|
|
@@ -19,6 +25,7 @@ export async function recoverDiagnosticRuntime(
|
|
|
19
25
|
opts.progress?.();
|
|
20
26
|
return opts.service.recoverDiagnostics({
|
|
21
27
|
restartIfStillStale: true,
|
|
28
|
+
...(opts.initialEvidence !== undefined ? { initialEvidence: opts.initialEvidence } : {}),
|
|
22
29
|
control: opts.control,
|
|
23
30
|
});
|
|
24
31
|
}
|
|
@@ -12,6 +12,10 @@ import {
|
|
|
12
12
|
|
|
13
13
|
export const DEFAULT_SEMANTIC_STARTUP_TIMEOUT_MS = 15_000;
|
|
14
14
|
|
|
15
|
+
/** Neutral reason for a typed semantic readiness timeout. */
|
|
16
|
+
export const SEMANTIC_READINESS_TIMEOUT_REASON =
|
|
17
|
+
"Semantic provider did not become ready within the wait window; retry shortly.";
|
|
18
|
+
|
|
15
19
|
export type SemanticStartupScope = { kind: "workspace" } | { kind: "file"; file: string };
|
|
16
20
|
|
|
17
21
|
export async function ensureSemanticReadiness(
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getSupportedExtensions,
|
|
6
6
|
type StructuralSearchOperation,
|
|
7
7
|
} from "@mrclrchtr/supi-tree-sitter/api";
|
|
8
|
-
import { type DeadlineOutcome, settleByDeadline } from "./deadline.ts";
|
|
8
|
+
import { type DeadlineOutcome, type ScheduleDeadline, settleByDeadline } from "./deadline.ts";
|
|
9
9
|
import { relativeDisplayPath } from "./paths.ts";
|
|
10
10
|
|
|
11
11
|
/** Directory names excluded below an AST Scan root. */
|
|
@@ -83,6 +83,8 @@ export interface EnumerateAstFilesOptions {
|
|
|
83
83
|
readonly timeoutMs?: number;
|
|
84
84
|
readonly signal?: AbortSignal;
|
|
85
85
|
readonly now?: () => number;
|
|
86
|
+
/** Timer seam for deterministic deadline tests; defaults to wall-clock timers. */
|
|
87
|
+
readonly schedule?: ScheduleDeadline;
|
|
86
88
|
readonly operations?: AstScanOperations;
|
|
87
89
|
}
|
|
88
90
|
|
|
@@ -302,6 +304,7 @@ class AstFileEnumerator {
|
|
|
302
304
|
deadline: this.options.deadline,
|
|
303
305
|
now: this.#now,
|
|
304
306
|
signal: this.options.signal,
|
|
307
|
+
schedule: this.options.schedule,
|
|
305
308
|
});
|
|
306
309
|
if (outcome.kind === "timeout") this.#markTimeout();
|
|
307
310
|
return outcome;
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
type OutlineData,
|
|
7
7
|
type StructuralProvider as StructuralSubstrate,
|
|
8
8
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
9
|
-
import type { CodeFindAstKind } from "../../tool/
|
|
9
|
+
import type { CodeFindAstKind } from "../../tool/code_find/ast-kinds.ts";
|
|
10
10
|
import type { AstScanLimitation } from "./ast-scan.ts";
|
|
11
11
|
import { callableExpressionForMatching } from "./call-name.ts";
|
|
12
|
-
import { type DeadlineOutcome, settleByDeadline } from "./deadline.ts";
|
|
12
|
+
import { type DeadlineOutcome, type ScheduleDeadline, settleByDeadline } from "./deadline.ts";
|
|
13
13
|
import { relativeDisplayPath } from "./paths.ts";
|
|
14
14
|
|
|
15
15
|
export interface StructuredPatternParams {
|
|
@@ -55,6 +55,8 @@ interface AnalyzeStructuredFilesOptions {
|
|
|
55
55
|
readonly deadline: number;
|
|
56
56
|
readonly now: () => number;
|
|
57
57
|
readonly signal?: AbortSignal;
|
|
58
|
+
/** Timer seam for deterministic deadline tests; defaults to wall-clock timers. */
|
|
59
|
+
readonly schedule?: ScheduleDeadline;
|
|
58
60
|
readonly requestControl: CodeRequestControl;
|
|
59
61
|
readonly initialLimitations: readonly AstScanLimitation[];
|
|
60
62
|
}
|
|
@@ -101,7 +103,12 @@ export async function analyzeStructuredFiles(
|
|
|
101
103
|
});
|
|
102
104
|
}
|
|
103
105
|
},
|
|
104
|
-
{
|
|
106
|
+
{
|
|
107
|
+
deadline: options.deadline,
|
|
108
|
+
now: options.now,
|
|
109
|
+
signal: options.signal,
|
|
110
|
+
schedule: options.schedule,
|
|
111
|
+
},
|
|
105
112
|
);
|
|
106
113
|
} catch (error) {
|
|
107
114
|
if (!isCodeRequestDeadlineError(error)) throw error;
|