@mrclrchtr/supi-code-intelligence 6.3.0 → 7.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 +164 -82
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +8 -1
- package/node_modules/@mrclrchtr/supi-core/README.md +8 -0
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +10 -3
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +2 -0
- package/node_modules/@mrclrchtr/supi-core/src/llm.ts +141 -16
- package/node_modules/@mrclrchtr/supi-lsp/README.md +35 -13
- 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/types.ts +8 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +8 -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/footer-registry.ts +10 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/llm.ts +141 -16
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/ignore/index.js +3 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/ignore/legacy.js +3 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/ignore/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +16 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +43 -35
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +83 -17
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +108 -92
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +44 -82
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +3 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +9 -68
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +45 -58
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +230 -331
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +201 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +129 -70
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-typescript.ts +395 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +8 -12
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +685 -183
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +60 -60
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-request-enrollment.ts +75 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-semantic-input-barrier.ts +443 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-semantic-input-errors.ts +30 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-semantic-input-file.ts +15 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +290 -37
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +72 -16
- package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +1 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +30 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +4 -32
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sources.ts +108 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +10 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-process-crash-report.ts +50 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +11 -7
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +770 -56
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +3 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +37 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +48 -12
- package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +50 -4
- 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/types.ts +8 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +8 -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/footer-registry.ts +10 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/llm.ts +141 -16
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callee-display-name.ts +165 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +67 -9
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +2 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +19 -18
- package/node_modules/yaml/browser/dist/nodes/Alias.js +25 -23
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.js +19 -18
- package/node_modules/yaml/dist/nodes/Alias.js +25 -23
- package/node_modules/yaml/package.json +1 -1
- package/package.json +5 -5
- package/src/analysis/health/diagnostics.ts +1 -2
- package/src/analysis/health/file-scope.ts +4 -1
- package/src/analysis/health/server-status.ts +1 -1
- package/src/analysis/relations/callees.ts +17 -8
- package/src/analysis/relations/implementations.ts +1 -2
- package/src/analysis/relations/references.ts +8 -4
- package/src/analysis/relations/types.ts +6 -30
- package/src/analysis/target/anchored.ts +9 -1
- package/src/analysis/target/symbol.ts +29 -11
- package/src/analysis/target/types.ts +14 -6
- package/src/api.ts +2 -0
- package/src/session/graph/collect.ts +18 -3
- package/src/session/health-refresh.ts +27 -11
- package/src/session/health-types.ts +21 -4
- package/src/session/health-workflow.ts +28 -22
- package/src/session/orientation-types.ts +5 -6
- package/src/session/orientation-workflow.ts +10 -2
- package/src/session/session.ts +12 -5
- package/src/session/target-workflow.ts +9 -6
- package/src/substrate/lsp/maintenance.ts +53 -47
- package/src/substrate/lsp/source-tracking.ts +252 -0
- package/src/tool/code_find/guidance.ts +3 -3
- package/src/tool/code_find/spec.ts +5 -4
- package/src/tool/code_find/tui.ts +7 -1
- package/src/tool/code_graph/details.ts +32 -0
- package/src/tool/code_graph/display.ts +54 -0
- package/src/tool/code_graph/format.ts +60 -0
- package/src/tool/code_graph/guidance.ts +2 -2
- package/src/tool/code_graph/markdown.ts +76 -198
- package/src/tool/code_graph/read-next.ts +65 -0
- package/src/tool/code_graph/result.ts +118 -83
- package/src/tool/code_graph/tui.ts +216 -54
- package/src/tool/code_health/guidance.ts +3 -5
- package/src/tool/code_health/markdown.ts +90 -57
- package/src/tool/code_health/refresh-outcome.ts +51 -0
- package/src/tool/code_health/refresh-status.ts +130 -43
- package/src/tool/code_health/scope.ts +78 -0
- package/src/tool/code_health/spec.ts +1 -1
- package/src/tool/code_health/tui.ts +29 -38
- package/src/tool/code_inspect/guidance.ts +5 -3
- package/src/tool/code_inspect/tui.ts +7 -1
- package/src/tool/code_orientation/guidance.ts +3 -4
- package/src/tool/code_orientation/result.ts +31 -8
- package/src/tool/code_orientation/tui.ts +26 -5
- package/src/tool/code_refactor_apply/guidance.ts +1 -1
- package/src/tool/code_refactor_apply/tui.ts +7 -3
- package/src/tool/code_refactor_plan/guidance.ts +3 -5
- package/src/tool/code_refactor_plan/tui.ts +7 -1
- package/src/tool/code_resolve/guidance.ts +3 -5
- package/src/tool/code_resolve/result.ts +13 -10
- package/src/tool/code_resolve/tui.ts +18 -1
- package/src/tool/guidance.ts +11 -9
- package/src/tool/infra/truncate.ts +39 -13
- package/src/tool/result/candidate-row.ts +27 -0
- package/src/tool/result/errors.ts +21 -6
- package/src/tool/result/types.ts +7 -3
- package/src/tool/schemas.ts +5 -0
- package/src/types/execution.ts +2 -0
- package/src/types/index.ts +2 -0
- package/src/ui/tui/candidate-legacy-body.ts +69 -0
- package/src/ui/tui/candidate-selection.ts +366 -0
- package/src/ui/tui/common.ts +26 -31
- package/src/ui/tui/execution-error.ts +92 -0
|
@@ -4,6 +4,7 @@ import type { CapabilityState } from "@mrclrchtr/supi-code-runtime/api";
|
|
|
4
4
|
import { isCodeRequestInterruption } from "@mrclrchtr/supi-code-runtime/api";
|
|
5
5
|
import type {
|
|
6
6
|
LspRuntimeController,
|
|
7
|
+
SemanticReadinessResult,
|
|
7
8
|
WorkspaceDiagnosticReport,
|
|
8
9
|
WorkspaceLspRuntime,
|
|
9
10
|
WorkspaceLspRuntimeState,
|
|
@@ -21,6 +22,7 @@ import { describeStructuralState } from "../analysis/health/recovery.ts";
|
|
|
21
22
|
import { collectServers } from "../analysis/health/signals.ts";
|
|
22
23
|
import { SEMANTIC_READINESS_TIMEOUT_REASON } from "../analysis/readiness.ts";
|
|
23
24
|
import { resolveScope } from "../analysis/search/paths.ts";
|
|
25
|
+
import type { LspMaintenanceState } from "../substrate/lsp/source-tracking.ts";
|
|
24
26
|
import type { CapabilityAdapter } from "./capability-adapter.ts";
|
|
25
27
|
import { collectHealthRefreshAttempt } from "./health-refresh.ts";
|
|
26
28
|
import type {
|
|
@@ -45,8 +47,10 @@ export interface HealthWorkflowDeps {
|
|
|
45
47
|
readonly lspController: LspRuntimeController | null;
|
|
46
48
|
readonly lastRefreshAttempt: HealthRefreshAttempt | null;
|
|
47
49
|
readonly trackRefreshAttempt: (attempt: HealthRefreshAttempt) => void;
|
|
48
|
-
/**
|
|
49
|
-
readonly
|
|
50
|
+
/** Typed sentinel, source-baseline, and created-source queue state. */
|
|
51
|
+
readonly maintenanceState: LspMaintenanceState;
|
|
52
|
+
/** Commit maintenance state only after a health attempt completes. */
|
|
53
|
+
readonly updateMaintenanceState: (state: LspMaintenanceState) => void;
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
/** Collect health facts without rendering a public result. */
|
|
@@ -77,7 +81,6 @@ export async function runHealthWorkflow(
|
|
|
77
81
|
const diagnosticsScope = diagnosticScope(scopeFilter);
|
|
78
82
|
const refreshCollection = await collectRefreshState({
|
|
79
83
|
refreshRequested: request.refresh === true,
|
|
80
|
-
diagnosticsRequested: included.includes("diagnostics"),
|
|
81
84
|
runtime,
|
|
82
85
|
lspState,
|
|
83
86
|
diagnosticsScope,
|
|
@@ -91,6 +94,7 @@ export async function runHealthWorkflow(
|
|
|
91
94
|
scopeFilter,
|
|
92
95
|
lspState,
|
|
93
96
|
capabilityState: capabilityStates.semantic,
|
|
97
|
+
refreshReadiness: refreshCollection.fileReadiness,
|
|
94
98
|
control,
|
|
95
99
|
});
|
|
96
100
|
const semanticReady = semanticState?.kind === "ready";
|
|
@@ -143,6 +147,8 @@ interface SemanticHealthStateOptions {
|
|
|
143
147
|
requested: boolean;
|
|
144
148
|
/** Whether this call requests file-routed evidence rather than passive inventory. */
|
|
145
149
|
fileReadinessRequested: boolean;
|
|
150
|
+
/** Readiness observed by the explicit refresh phase, when one ran. */
|
|
151
|
+
refreshReadiness?: SemanticReadinessResult;
|
|
146
152
|
runtime: WorkspaceLspRuntime | null;
|
|
147
153
|
scopeFilter: string | null;
|
|
148
154
|
lspState: WorkspaceLspRuntimeState;
|
|
@@ -154,12 +160,17 @@ async function establishSemanticHealthState(
|
|
|
154
160
|
options: SemanticHealthStateOptions,
|
|
155
161
|
): Promise<SemanticHealthState | null> {
|
|
156
162
|
if (!options.requested) return null;
|
|
157
|
-
if (options.fileReadinessRequested &&
|
|
158
|
-
const readiness =
|
|
159
|
-
options.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
+
if (options.fileReadinessRequested && isScopedFile(options.scopeFilter)) {
|
|
164
|
+
const readiness =
|
|
165
|
+
options.refreshReadiness ??
|
|
166
|
+
(options.runtime
|
|
167
|
+
? await options.runtime.waitUntilReadyForFile(
|
|
168
|
+
options.scopeFilter,
|
|
169
|
+
undefined,
|
|
170
|
+
options.control,
|
|
171
|
+
)
|
|
172
|
+
: null);
|
|
173
|
+
if (!readiness) return deriveNonReadySemanticState(options.lspState, options.capabilityState);
|
|
163
174
|
if (readiness.kind === "ready") return { kind: "ready" };
|
|
164
175
|
if (readiness.kind === "timeout") {
|
|
165
176
|
return { kind: "pending", reason: SEMANTIC_READINESS_TIMEOUT_REASON };
|
|
@@ -223,12 +234,12 @@ function collectCapabilityWarnings(
|
|
|
223
234
|
|
|
224
235
|
interface HealthRefreshStateCollection {
|
|
225
236
|
readonly attempt: HealthRefreshState;
|
|
237
|
+
readonly fileReadiness?: SemanticReadinessResult;
|
|
226
238
|
readonly diagnosticReport?: WorkspaceDiagnosticReport;
|
|
227
239
|
}
|
|
228
240
|
|
|
229
241
|
interface RefreshStateOptions {
|
|
230
242
|
readonly refreshRequested: boolean;
|
|
231
|
-
readonly diagnosticsRequested: boolean;
|
|
232
243
|
readonly runtime: WorkspaceLspRuntime | null;
|
|
233
244
|
readonly lspState: WorkspaceLspRuntimeState;
|
|
234
245
|
readonly diagnosticsScope: HealthDiagnosticScope;
|
|
@@ -240,16 +251,7 @@ interface RefreshStateOptions {
|
|
|
240
251
|
async function collectRefreshState(
|
|
241
252
|
options: RefreshStateOptions,
|
|
242
253
|
): Promise<HealthRefreshStateCollection> {
|
|
243
|
-
const { deps,
|
|
244
|
-
if (!diagnosticsRequested) {
|
|
245
|
-
return {
|
|
246
|
-
attempt: {
|
|
247
|
-
kind: "not-requested",
|
|
248
|
-
reason: "Diagnostics were not requested.",
|
|
249
|
-
lastAttempt: deps.lastRefreshAttempt,
|
|
250
|
-
},
|
|
251
|
-
};
|
|
252
|
-
}
|
|
254
|
+
const { deps, diagnosticsScope, lspState, runtime } = options;
|
|
253
255
|
if (!options.refreshRequested) {
|
|
254
256
|
return {
|
|
255
257
|
attempt: {
|
|
@@ -282,7 +284,7 @@ async function collectRefreshState(
|
|
|
282
284
|
diagnosticsScope,
|
|
283
285
|
attemptedAt,
|
|
284
286
|
cwd: options.deps.cwd,
|
|
285
|
-
|
|
287
|
+
maintenanceState: options.deps.maintenanceState,
|
|
286
288
|
control: options.control,
|
|
287
289
|
reportRecoveryProgress: () =>
|
|
288
290
|
reportProgress(options.control, {
|
|
@@ -291,8 +293,12 @@ async function collectRefreshState(
|
|
|
291
293
|
message: "Refreshing diagnostics and recovery state",
|
|
292
294
|
}),
|
|
293
295
|
});
|
|
296
|
+
deps.updateMaintenanceState(attempt.maintenanceState);
|
|
294
297
|
deps.trackRefreshAttempt(attempt.attempt);
|
|
295
|
-
return
|
|
298
|
+
return {
|
|
299
|
+
...attempt,
|
|
300
|
+
...(attempt.fileReadiness ? { fileReadiness: attempt.fileReadiness } : {}),
|
|
301
|
+
};
|
|
296
302
|
} catch (error) {
|
|
297
303
|
// Cancellation must propagate; a cancelled caller no longer awaits a
|
|
298
304
|
// recorded failed attempt or the refresh data it would carry.
|
|
@@ -5,6 +5,7 @@ import type { EvidenceListMetadata } from "../analysis/evidence.ts";
|
|
|
5
5
|
import type { InstructionFilesMetadata } from "../analysis/instruction-files.ts";
|
|
6
6
|
import type { CodeProvider } from "../analysis/provider.ts";
|
|
7
7
|
import type { ReadNextItem } from "../analysis/read-next.ts";
|
|
8
|
+
import type { TargetCandidateCompleteness } from "../analysis/target/types.ts";
|
|
8
9
|
import type { OrientationTargetInput, TargetSymbolKind } from "./target-input.ts";
|
|
9
10
|
import type { AnchorKind, TargetStoreEntry } from "./target-store.ts";
|
|
10
11
|
|
|
@@ -118,16 +119,14 @@ export interface OrientationResultData {
|
|
|
118
119
|
|
|
119
120
|
export type OrientationWorkflowOutcome =
|
|
120
121
|
| { readonly kind: "completed"; readonly data: OrientationResultData }
|
|
121
|
-
| {
|
|
122
|
+
| ({
|
|
122
123
|
readonly kind: "disambiguation";
|
|
123
124
|
readonly candidates: readonly OrientationCandidate[];
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
| {
|
|
125
|
+
} & TargetCandidateCompleteness)
|
|
126
|
+
| ({
|
|
127
127
|
readonly kind: "kind-mismatch";
|
|
128
128
|
readonly requestedKind: TargetSymbolKind;
|
|
129
129
|
readonly candidates: readonly OrientationCandidate[];
|
|
130
|
-
|
|
131
|
-
}
|
|
130
|
+
} & TargetCandidateCompleteness)
|
|
132
131
|
| { readonly kind: "invalid-input"; readonly message: string }
|
|
133
132
|
| { readonly kind: "unavailable"; readonly reason: string };
|
|
@@ -131,10 +131,18 @@ async function orientTarget(options: {
|
|
|
131
131
|
? {
|
|
132
132
|
kind: "kind-mismatch",
|
|
133
133
|
requestedKind: target.requestedKind,
|
|
134
|
-
omittedCount: target.omittedCount,
|
|
135
134
|
candidates,
|
|
135
|
+
totalCount: target.totalCount,
|
|
136
|
+
omittedCount: target.omittedCount,
|
|
137
|
+
partialReason: target.partialReason,
|
|
136
138
|
}
|
|
137
|
-
: {
|
|
139
|
+
: {
|
|
140
|
+
kind: "disambiguation",
|
|
141
|
+
candidates,
|
|
142
|
+
totalCount: target.totalCount,
|
|
143
|
+
omittedCount: target.omittedCount,
|
|
144
|
+
partialReason: target.partialReason,
|
|
145
|
+
};
|
|
138
146
|
}
|
|
139
147
|
if (target.kind !== "resolved") return target;
|
|
140
148
|
throwIfAborted(control);
|
package/src/session/session.ts
CHANGED
|
@@ -20,6 +20,10 @@ import { realpathSync } from "node:fs";
|
|
|
20
20
|
import * as path from "node:path";
|
|
21
21
|
import type { SessionEntry } from "@earendil-works/pi-coding-agent";
|
|
22
22
|
import type { LspRuntimeController } from "@mrclrchtr/supi-lsp/api";
|
|
23
|
+
import {
|
|
24
|
+
createLspMaintenanceState,
|
|
25
|
+
type LspMaintenanceState,
|
|
26
|
+
} from "../substrate/lsp/source-tracking.ts";
|
|
23
27
|
import { type CapabilityAdapter, WorkspaceCapabilityAdapter } from "./capability-adapter.ts";
|
|
24
28
|
import type { FindWorkflowInput, FindWorkflowOutcome } from "./find-types.ts";
|
|
25
29
|
import { runFindWorkflow } from "./find-workflow.ts";
|
|
@@ -162,8 +166,8 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
162
166
|
*/
|
|
163
167
|
#lspController: LspRuntimeController | null = null;
|
|
164
168
|
|
|
165
|
-
/**
|
|
166
|
-
#
|
|
169
|
+
/** Typed sentinel, source-baseline, and created-source queue state. */
|
|
170
|
+
#maintenanceState: LspMaintenanceState = createLspMaintenanceState();
|
|
167
171
|
|
|
168
172
|
/** Whether the project owning this session is trusted for config loading. */
|
|
169
173
|
#projectTrusted = false;
|
|
@@ -196,7 +200,7 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
196
200
|
* Called by the extension entry point after LSP initialization.
|
|
197
201
|
*/
|
|
198
202
|
seedSentinelSnapshot(snapshot: Map<string, number>): void {
|
|
199
|
-
this.#
|
|
203
|
+
this.#maintenanceState = createLspMaintenanceState(snapshot);
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
/** Restore overview state from the active session branch. */
|
|
@@ -283,7 +287,10 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
283
287
|
trackRefreshAttempt: (attempt) => {
|
|
284
288
|
this.#lastHealthRefreshAttempt = attempt;
|
|
285
289
|
},
|
|
286
|
-
|
|
290
|
+
maintenanceState: this.#maintenanceState,
|
|
291
|
+
updateMaintenanceState: (state) => {
|
|
292
|
+
this.#maintenanceState = state;
|
|
293
|
+
},
|
|
287
294
|
},
|
|
288
295
|
control,
|
|
289
296
|
);
|
|
@@ -429,7 +436,7 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
429
436
|
this.#workflowTargets.clear();
|
|
430
437
|
this.#surfacedInstructionDirs.clear();
|
|
431
438
|
this.#nativeInstructionPaths.clear();
|
|
432
|
-
this.#
|
|
439
|
+
this.#maintenanceState = createLspMaintenanceState();
|
|
433
440
|
this.#lspController = null;
|
|
434
441
|
this.#projectTrusted = false;
|
|
435
442
|
}
|
|
@@ -19,6 +19,7 @@ import { resolveSymbolTarget } from "../analysis/target/symbol.ts";
|
|
|
19
19
|
import type {
|
|
20
20
|
ResolvedTargetData,
|
|
21
21
|
ResolvedTargetGroupData,
|
|
22
|
+
TargetCandidateCompleteness,
|
|
22
23
|
TargetOutcome,
|
|
23
24
|
} from "../analysis/target/types.ts";
|
|
24
25
|
import type { CapabilityAdapter } from "./capability-adapter.ts";
|
|
@@ -59,17 +60,15 @@ export type TargetWorkflowOutcome =
|
|
|
59
60
|
omittedCount: number;
|
|
60
61
|
unknownNestingCount: number;
|
|
61
62
|
}
|
|
62
|
-
| {
|
|
63
|
+
| ({
|
|
63
64
|
kind: "disambiguation";
|
|
64
65
|
candidates: ReadonlyArray<TargetWorkflowCandidate>;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
| {
|
|
66
|
+
} & TargetCandidateCompleteness)
|
|
67
|
+
| ({
|
|
68
68
|
kind: "kind-mismatch";
|
|
69
69
|
requestedKind: TargetSymbolKind;
|
|
70
70
|
candidates: ReadonlyArray<TargetWorkflowCandidate>;
|
|
71
|
-
|
|
72
|
-
}
|
|
71
|
+
} & TargetCandidateCompleteness)
|
|
73
72
|
| { kind: "invalid-input"; message: string }
|
|
74
73
|
| { kind: "unavailable"; reason: string };
|
|
75
74
|
|
|
@@ -318,12 +317,16 @@ function toWorkflowOutcome(
|
|
|
318
317
|
kind: "kind-mismatch",
|
|
319
318
|
requestedKind: outcome.requestedKind,
|
|
320
319
|
candidates,
|
|
320
|
+
totalCount: outcome.totalCount,
|
|
321
321
|
omittedCount: outcome.omittedCount,
|
|
322
|
+
partialReason: outcome.partialReason,
|
|
322
323
|
}
|
|
323
324
|
: {
|
|
324
325
|
kind: "disambiguation",
|
|
325
326
|
candidates,
|
|
327
|
+
totalCount: outcome.totalCount,
|
|
326
328
|
omittedCount: outcome.omittedCount,
|
|
329
|
+
partialReason: outcome.partialReason,
|
|
327
330
|
};
|
|
328
331
|
}
|
|
329
332
|
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
isCodeRequestInterruption,
|
|
14
14
|
throwIfCodeRequestInterrupted,
|
|
15
15
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
16
|
-
import { isWithinOrEqual } from "@mrclrchtr/supi-core/api";
|
|
17
16
|
import { uriToFile } from "@mrclrchtr/supi-core/path";
|
|
18
17
|
import type { DiagnosticEvidenceSummary } from "@mrclrchtr/supi-lsp/api";
|
|
19
18
|
import {
|
|
@@ -27,6 +26,12 @@ import {
|
|
|
27
26
|
type WorkspaceLspRuntime,
|
|
28
27
|
} from "@mrclrchtr/supi-lsp/api";
|
|
29
28
|
import { mergeDiagnosticEvidence } from "../../diagnostics/evidence.ts";
|
|
29
|
+
import {
|
|
30
|
+
type LspMaintenanceState,
|
|
31
|
+
type SourceTrackingReport,
|
|
32
|
+
trackCreatedSources,
|
|
33
|
+
withSentinelSnapshot,
|
|
34
|
+
} from "./source-tracking.ts";
|
|
30
35
|
|
|
31
36
|
/** Options shared by the workspace and file-scoped maintenance passes. */
|
|
32
37
|
export interface LspMaintenanceOptions {
|
|
@@ -36,11 +41,7 @@ export interface LspMaintenanceOptions {
|
|
|
36
41
|
* tracks created files inside this prefix; null disables the scope bound.
|
|
37
42
|
*/
|
|
38
43
|
scope?: string | null;
|
|
39
|
-
/**
|
|
40
|
-
* Track files created since the last refresh so the following refresh pull
|
|
41
|
-
* includes them. Only the workspace-runtime path sets this; the snapshot is
|
|
42
|
-
* still widened on file-scoped passes so later diffs stay correct.
|
|
43
|
-
*/
|
|
44
|
+
/** Track source additions only for a broad tracked-file refresh. */
|
|
44
45
|
trackSources?: boolean;
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -52,10 +53,11 @@ export interface LspMaintenanceOptions {
|
|
|
52
53
|
export async function refreshLspMaintenance(
|
|
53
54
|
runtime: WorkspaceLspRuntime,
|
|
54
55
|
cwd: string,
|
|
55
|
-
|
|
56
|
+
maintenanceState: LspMaintenanceState,
|
|
56
57
|
options: LspMaintenanceOptions = {},
|
|
57
58
|
): Promise<WorkspaceLspMaintenanceResult> {
|
|
58
|
-
const
|
|
59
|
+
const synchronized = await synchronizeSentinels(runtime, cwd, maintenanceState, options);
|
|
60
|
+
const { snapshot, nextState, sourceTracking } = synchronized;
|
|
59
61
|
let diagnosticEvidence = emptyEvidence();
|
|
60
62
|
let failureReason: string | undefined;
|
|
61
63
|
|
|
@@ -80,15 +82,21 @@ export async function refreshLspMaintenance(
|
|
|
80
82
|
|
|
81
83
|
return {
|
|
82
84
|
snapshot,
|
|
85
|
+
maintenanceState: nextState,
|
|
83
86
|
diagnosticEvidence,
|
|
87
|
+
...(sourceTracking ? { sourceTracking } : {}),
|
|
84
88
|
...(failureReason ? { failureReason } : {}),
|
|
85
89
|
};
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
/** Sentinel state and diagnostic evidence retained from one workspace pass. */
|
|
89
93
|
export interface WorkspaceLspMaintenanceResult {
|
|
94
|
+
/** The next typed maintenance state for the session. */
|
|
95
|
+
maintenanceState: LspMaintenanceState;
|
|
90
96
|
/** The next sentinel snapshot for the session-owned maintenance state. */
|
|
91
97
|
snapshot: Map<string, number>;
|
|
98
|
+
/** Source discovery and bounded tracking facts for broad refreshes. */
|
|
99
|
+
sourceTracking?: SourceTrackingReport;
|
|
92
100
|
/** Evidence from every diagnostic refresh performed by this pass. */
|
|
93
101
|
diagnosticEvidence: DiagnosticEvidenceSummary;
|
|
94
102
|
/** Failure from the first workspace refresh, when no fresh pass completed. */
|
|
@@ -97,6 +105,8 @@ export interface WorkspaceLspMaintenanceResult {
|
|
|
97
105
|
|
|
98
106
|
/** Sentinel state and stale-file facts from one file-scoped pass. */
|
|
99
107
|
export interface FileLspMaintenanceResult {
|
|
108
|
+
/** The next typed maintenance state for the session. */
|
|
109
|
+
maintenanceState: LspMaintenanceState;
|
|
100
110
|
/** The next sentinel snapshot for the session-owned maintenance state. */
|
|
101
111
|
snapshot: Map<string, number>;
|
|
102
112
|
/** Number of stale files that matched the requested file. */
|
|
@@ -107,14 +117,14 @@ export interface FileLspMaintenanceResult {
|
|
|
107
117
|
export async function refreshFileLspMaintenance(options: {
|
|
108
118
|
runtime: WorkspaceLspRuntime;
|
|
109
119
|
cwd: string;
|
|
110
|
-
|
|
120
|
+
maintenanceState: LspMaintenanceState;
|
|
111
121
|
filePath: string;
|
|
112
122
|
control?: CodeRequestControl;
|
|
113
123
|
}): Promise<FileLspMaintenanceResult> {
|
|
114
|
-
const { runtime, cwd,
|
|
124
|
+
const { runtime, cwd, maintenanceState, filePath, control } = options;
|
|
115
125
|
// A cancelled caller stops before any maintenance work starts.
|
|
116
126
|
throwIfCodeRequestInterrupted(control);
|
|
117
|
-
const { snapshot } = await synchronizeSentinels(runtime,
|
|
127
|
+
const { snapshot, nextState } = await synchronizeSentinels(runtime, cwd, maintenanceState);
|
|
118
128
|
const target = nodePath.resolve(filePath);
|
|
119
129
|
const stale = confirmedOutstandingDiagnostics(runtime, cwd).some(
|
|
120
130
|
(entry) =>
|
|
@@ -132,38 +142,51 @@ export async function refreshFileLspMaintenance(options: {
|
|
|
132
142
|
runtime.pruneMissingFiles();
|
|
133
143
|
throwIfCodeRequestInterrupted(control);
|
|
134
144
|
|
|
135
|
-
return {
|
|
145
|
+
return {
|
|
146
|
+
snapshot,
|
|
147
|
+
maintenanceState: nextState,
|
|
148
|
+
matchedStaleFileCount: stale ? 1 : 0,
|
|
149
|
+
};
|
|
136
150
|
}
|
|
137
151
|
|
|
138
152
|
/**
|
|
139
|
-
* Sync
|
|
140
|
-
* source files newly created since the last pass.
|
|
153
|
+
* Sync sentinel state and, only for broad refreshes, process source additions.
|
|
141
154
|
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* on the workspace-runtime path and only once the snapshot was primed by an
|
|
146
|
-
* earlier pass — the first pass establishes the baseline and cannot tell a
|
|
147
|
-
* just-created file from a long-existing one.
|
|
155
|
+
* Sentinel state and source state use separate baselines. A complete source
|
|
156
|
+
* inventory establishes the first baseline without treating existing files as
|
|
157
|
+
* created. Limited inventories leave the previous source state unchanged.
|
|
148
158
|
*/
|
|
149
159
|
async function synchronizeSentinels(
|
|
150
160
|
runtime: WorkspaceLspRuntime,
|
|
151
|
-
|
|
161
|
+
cwd: string,
|
|
162
|
+
maintenanceState: LspMaintenanceState,
|
|
152
163
|
options: LspMaintenanceOptions = {},
|
|
153
|
-
) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
164
|
+
): Promise<{
|
|
165
|
+
snapshot: Map<string, number>;
|
|
166
|
+
nextState: LspMaintenanceState;
|
|
167
|
+
sourceTracking?: SourceTrackingReport;
|
|
168
|
+
}> {
|
|
169
|
+
const state = runtime.syncWorkspaceSentinelSnapshot(maintenanceState.sentinelSnapshot);
|
|
159
170
|
invalidateChangedProjectConfigs(state.changes);
|
|
160
171
|
if (state.changes.length > 0) runtime.noteWorkspaceChanges(state.changes);
|
|
161
172
|
|
|
162
|
-
|
|
163
|
-
|
|
173
|
+
const nextSentinelState = withSentinelSnapshot(maintenanceState, state.snapshot);
|
|
174
|
+
if (!options.trackSources) {
|
|
175
|
+
return { snapshot: state.snapshot, nextState: nextSentinelState };
|
|
164
176
|
}
|
|
165
177
|
|
|
166
|
-
|
|
178
|
+
const sourceResult = await trackCreatedSources({
|
|
179
|
+
runtime,
|
|
180
|
+
cwd,
|
|
181
|
+
state: nextSentinelState,
|
|
182
|
+
scope: options.scope,
|
|
183
|
+
control: options.control,
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
snapshot: state.snapshot,
|
|
187
|
+
nextState: sourceResult.state,
|
|
188
|
+
sourceTracking: sourceResult.report,
|
|
189
|
+
};
|
|
167
190
|
}
|
|
168
191
|
|
|
169
192
|
/** Invalidate cached tsconfig scope parses only for config files that changed. */
|
|
@@ -181,23 +204,6 @@ function invalidateChangedProjectConfigs(changes: readonly FileEvent[]): void {
|
|
|
181
204
|
}
|
|
182
205
|
}
|
|
183
206
|
|
|
184
|
-
/** Track source files newly created since the last pass, within the scope bound. */
|
|
185
|
-
async function trackCreatedSourceFiles(
|
|
186
|
-
runtime: WorkspaceLspRuntime,
|
|
187
|
-
sourceChanges: readonly FileEvent[],
|
|
188
|
-
scope: string | null | undefined,
|
|
189
|
-
): Promise<void> {
|
|
190
|
-
for (const change of sourceChanges) {
|
|
191
|
-
if (change.type !== FileChangeType.Created) continue;
|
|
192
|
-
const filePath = uriToFile(change.uri);
|
|
193
|
-
if (scope && !isWithinOrEqual(scope, filePath)) continue;
|
|
194
|
-
if (!runtime.isSupportedSourceFile(filePath)) continue;
|
|
195
|
-
// Best-effort: a file no client can serve stays untracked and is
|
|
196
|
-
// simply absent from evidence until a later explicit request.
|
|
197
|
-
await runtime.trackFile(filePath);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
207
|
/** Return only diagnostics whose document evidence is confirmed. */
|
|
202
208
|
function confirmedOutstandingDiagnostics(runtime: WorkspaceLspRuntime, cwd: string) {
|
|
203
209
|
const outstanding = runtime.getOutstandingDiagnostics(1);
|