@mrclrchtr/supi-code-intelligence 4.10.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/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/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 +71 -11
- 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 +365 -297
- 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 +161 -33
- 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 +17 -7
- 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/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/package.json +6 -3
- 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 +45 -1
- package/src/analysis/refactor/mutation-authority.ts +143 -0
- 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 -2
- 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 -351
|
@@ -9,12 +9,14 @@
|
|
|
9
9
|
|
|
10
10
|
import * as fs from "node:fs";
|
|
11
11
|
import * as path from "node:path";
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
import {
|
|
13
|
+
type CodeRequestControl,
|
|
14
|
+
type CodeResult,
|
|
15
|
+
type CodeSymbol,
|
|
16
|
+
isCodeRequestInterruption,
|
|
17
|
+
type NodeAtData,
|
|
18
|
+
type SemanticProvider,
|
|
19
|
+
type StructuralProvider,
|
|
18
20
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
19
21
|
import type { AnchorKind } from "../../session/target-store.ts";
|
|
20
22
|
import type { AnchoredResolutionMetadata, AnchoredResolutionSource } from "../../types/index.ts";
|
|
@@ -217,17 +219,20 @@ async function candidatesFromSymbols(
|
|
|
217
219
|
}
|
|
218
220
|
|
|
219
221
|
/** Layer 1: match the coordinate against LSP document symbols. Returns null to fall through. */
|
|
222
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: layered anchored resolution keeps layer-1 symbol matching and identity resolution together.
|
|
220
223
|
async function resolveFromSemantic(
|
|
221
224
|
file: string,
|
|
222
225
|
requested: Anchor,
|
|
223
226
|
provider: AnchoredResolverProvider,
|
|
227
|
+
control?: CodeRequestControl,
|
|
224
228
|
): Promise<TargetOutcome | null> {
|
|
225
229
|
if (!provider.documentSymbols) return null;
|
|
226
230
|
let symbols: CodeSymbol[] = [];
|
|
227
231
|
try {
|
|
228
232
|
const result = await provider.documentSymbols(file);
|
|
229
233
|
if (result.kind !== "unavailable") symbols = result.data;
|
|
230
|
-
} catch {
|
|
234
|
+
} catch (error) {
|
|
235
|
+
if (isCodeRequestInterruption(error, control)) throw error;
|
|
231
236
|
symbols = [];
|
|
232
237
|
}
|
|
233
238
|
if (symbols.length === 0) return null;
|
|
@@ -241,7 +246,7 @@ async function resolveFromSemantic(
|
|
|
241
246
|
}
|
|
242
247
|
|
|
243
248
|
const structural = provider.nodeAt ? { nodeAt: provider.nodeAt } : undefined;
|
|
244
|
-
const resolveIdentity = createCodeSymbolIdentityResolver(file, symbols, structural);
|
|
249
|
+
const resolveIdentity = createCodeSymbolIdentityResolver(file, symbols, structural, control);
|
|
245
250
|
if (exact.length === 1) {
|
|
246
251
|
return resolvedFromSymbol(file, exact[0], {
|
|
247
252
|
snapped: false,
|
|
@@ -268,12 +273,14 @@ async function resolveFromStructural(
|
|
|
268
273
|
file: string,
|
|
269
274
|
requested: Anchor,
|
|
270
275
|
provider: AnchoredResolverProvider,
|
|
276
|
+
control?: CodeRequestControl,
|
|
271
277
|
): Promise<TargetOutcome | null> {
|
|
272
278
|
if (!provider.nodeAt) return null;
|
|
273
279
|
let nodeResult: CodeResult<NodeAtData> | null = null;
|
|
274
280
|
try {
|
|
275
281
|
nodeResult = await provider.nodeAt(file, requested.line, requested.character);
|
|
276
|
-
} catch {
|
|
282
|
+
} catch (error) {
|
|
283
|
+
if (isCodeRequestInterruption(error, control)) throw error;
|
|
277
284
|
nodeResult = null;
|
|
278
285
|
}
|
|
279
286
|
if (nodeResult?.kind !== "success") return null;
|
|
@@ -351,11 +358,13 @@ async function resolveFromStructural(
|
|
|
351
358
|
* This does not perform heuristic global text search and does not silently
|
|
352
359
|
* treat declaration anchors as name anchors (ADR 0003).
|
|
353
360
|
*/
|
|
361
|
+
// biome-ignore lint/complexity/useMaxParams: anchored resolution is a stable public resolver boundary with fixed positional fields.
|
|
354
362
|
export async function resolveAnchoredSymbolTarget(
|
|
355
363
|
file: string,
|
|
356
364
|
line: number,
|
|
357
365
|
character: number,
|
|
358
366
|
provider: AnchoredResolverProvider | null,
|
|
367
|
+
control?: CodeRequestControl,
|
|
359
368
|
): Promise<TargetOutcome> {
|
|
360
369
|
if (!fs.existsSync(file)) {
|
|
361
370
|
return { kind: "error", message: `File not found: \`${file}\`` };
|
|
@@ -369,9 +378,9 @@ export async function resolveAnchoredSymbolTarget(
|
|
|
369
378
|
|
|
370
379
|
const requested: Anchor = { line, character };
|
|
371
380
|
if (provider) {
|
|
372
|
-
const semantic = await resolveFromSemantic(file, requested, provider);
|
|
381
|
+
const semantic = await resolveFromSemantic(file, requested, provider, control);
|
|
373
382
|
if (semantic) return semantic;
|
|
374
|
-
const structural = await resolveFromStructural(file, requested, provider);
|
|
383
|
+
const structural = await resolveFromStructural(file, requested, provider, control);
|
|
375
384
|
if (structural) return structural;
|
|
376
385
|
}
|
|
377
386
|
|
|
@@ -9,12 +9,14 @@
|
|
|
9
9
|
|
|
10
10
|
import * as fs from "node:fs";
|
|
11
11
|
import * as path from "node:path";
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
import {
|
|
13
|
+
type CodeRequestControl,
|
|
14
|
+
type DeclarationNesting,
|
|
15
|
+
type DocumentCodeSymbol,
|
|
16
|
+
isCodeRequestInterruption,
|
|
17
|
+
type OutlineData,
|
|
18
|
+
type SemanticProvider as SemanticSubstrate,
|
|
19
|
+
type StructuralProvider as StructuralSubstrate,
|
|
18
20
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
19
21
|
import type { AnchorKind } from "../../session/target-store.ts";
|
|
20
22
|
import { normalizePath } from "../search/paths.ts";
|
|
@@ -80,6 +82,7 @@ export async function resolveFileTargetGroup(
|
|
|
80
82
|
semantic?: SemanticSubstrate;
|
|
81
83
|
structural?: StructuralSubstrate;
|
|
82
84
|
} = {},
|
|
85
|
+
control?: CodeRequestControl,
|
|
83
86
|
): Promise<
|
|
84
87
|
| { kind: "resolved"; group: ResolvedTargetGroupData }
|
|
85
88
|
| { kind: "invalid-input"; message: string }
|
|
@@ -90,8 +93,8 @@ export async function resolveFileTargetGroup(
|
|
|
90
93
|
const resolvedFile = validation.file;
|
|
91
94
|
|
|
92
95
|
const [semantic, structural] = await Promise.all([
|
|
93
|
-
discoverSemantic(resolvedFile, deps.semantic, deps.structural),
|
|
94
|
-
discoverStructural(resolvedFile, deps.structural),
|
|
96
|
+
discoverSemantic(resolvedFile, deps.semantic, deps.structural, control),
|
|
97
|
+
discoverStructural(resolvedFile, deps.structural, control),
|
|
95
98
|
]);
|
|
96
99
|
if (!semantic.available && !structural.available) {
|
|
97
100
|
const displayFile = path.relative(cwd, resolvedFile) || file;
|
|
@@ -148,6 +151,7 @@ async function discoverSemantic(
|
|
|
148
151
|
file: string,
|
|
149
152
|
semantic: SemanticSubstrate | undefined,
|
|
150
153
|
structural: StructuralSubstrate | undefined,
|
|
154
|
+
control?: CodeRequestControl,
|
|
151
155
|
): Promise<DiscoveryResult> {
|
|
152
156
|
if (!semantic) return { available: false, targets: [] };
|
|
153
157
|
try {
|
|
@@ -158,12 +162,13 @@ async function discoverSemantic(
|
|
|
158
162
|
targets: await Promise.all(
|
|
159
163
|
result.data.map(async (symbol) => {
|
|
160
164
|
const target = targetFromSymbol(file, symbol);
|
|
161
|
-
const refined = await refineTypeAliasIdentity(target, structural);
|
|
165
|
+
const refined = await refineTypeAliasIdentity(target, structural, control);
|
|
162
166
|
return { ...refined, nesting: target.nesting };
|
|
163
167
|
}),
|
|
164
168
|
),
|
|
165
169
|
};
|
|
166
|
-
} catch {
|
|
170
|
+
} catch (error) {
|
|
171
|
+
if (isCodeRequestInterruption(error, control)) throw error;
|
|
167
172
|
return { available: false, targets: [] };
|
|
168
173
|
}
|
|
169
174
|
}
|
|
@@ -196,13 +201,15 @@ function normalizeNesting(value: unknown): DeclarationNesting {
|
|
|
196
201
|
async function discoverStructural(
|
|
197
202
|
file: string,
|
|
198
203
|
structural: StructuralSubstrate | undefined,
|
|
204
|
+
control?: CodeRequestControl,
|
|
199
205
|
): Promise<DiscoveryResult> {
|
|
200
206
|
if (!structural) return { available: false, targets: [] };
|
|
201
207
|
try {
|
|
202
208
|
const result = await structural.outline(file);
|
|
203
209
|
if (result.kind !== "success") return { available: false, targets: [] };
|
|
204
210
|
return { available: true, targets: flattenOutline(file, result.data) };
|
|
205
|
-
} catch {
|
|
211
|
+
} catch (error) {
|
|
212
|
+
if (isCodeRequestInterruption(error, control)) throw error;
|
|
206
213
|
return { available: false, targets: [] };
|
|
207
214
|
}
|
|
208
215
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
|
-
import
|
|
2
|
+
import {
|
|
3
|
+
type CodeRequestControl,
|
|
4
|
+
type CodeSymbol,
|
|
5
|
+
isCodeRequestInterruption,
|
|
6
|
+
type StructuralProvider,
|
|
7
|
+
} from "@mrclrchtr/supi-code-runtime/api";
|
|
3
8
|
import type { ResolvedTargetData, TargetOutcome } from "./types.ts";
|
|
4
9
|
|
|
5
10
|
/**
|
|
@@ -45,6 +50,7 @@ export interface DeclarationOccurrenceIdentity extends DeclarationIdentityResult
|
|
|
45
50
|
export async function resolveDeclarationIdentityKind(
|
|
46
51
|
observation: DeclarationIdentityObservation,
|
|
47
52
|
structural: Pick<StructuralProvider, "nodeAt"> | undefined,
|
|
53
|
+
control?: CodeRequestControl,
|
|
48
54
|
): Promise<DeclarationIdentityResult> {
|
|
49
55
|
const identityKind = canonicalDeclarationKind(observation.providerKind);
|
|
50
56
|
if (
|
|
@@ -69,7 +75,8 @@ export async function resolveDeclarationIdentityKind(
|
|
|
69
75
|
return exactNameAnchor && isTypeAlias
|
|
70
76
|
? { identityKind: "type", structuralEvidence: true }
|
|
71
77
|
: { identityKind, structuralEvidence: false };
|
|
72
|
-
} catch {
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (isCodeRequestInterruption(error, control)) throw error;
|
|
73
80
|
return { identityKind, structuralEvidence: false };
|
|
74
81
|
}
|
|
75
82
|
}
|
|
@@ -82,6 +89,7 @@ export function createCodeSymbolIdentityResolver(
|
|
|
82
89
|
file: string,
|
|
83
90
|
allSymbols: readonly CodeSymbol[],
|
|
84
91
|
structural: Pick<StructuralProvider, "nodeAt"> | undefined,
|
|
92
|
+
control?: CodeRequestControl,
|
|
85
93
|
): (symbol: CodeSymbol) => Promise<DeclarationOccurrenceIdentity> {
|
|
86
94
|
const identities = new Map<CodeSymbol, Promise<DeclarationIdentityResult>>();
|
|
87
95
|
const occurrences = new Map<CodeSymbol, Promise<DeclarationOccurrenceIdentity>>();
|
|
@@ -97,6 +105,7 @@ export function createCodeSymbolIdentityResolver(
|
|
|
97
105
|
nameAnchor: symbol.nameAnchor ?? null,
|
|
98
106
|
},
|
|
99
107
|
structural,
|
|
108
|
+
control,
|
|
100
109
|
);
|
|
101
110
|
identities.set(symbol, identity);
|
|
102
111
|
return identity;
|
|
@@ -147,6 +156,7 @@ function compareCodeSymbolDeclarations(left: CodeSymbol, right: CodeSymbol): num
|
|
|
147
156
|
export async function refineTypeAliasIdentity(
|
|
148
157
|
target: ResolvedTargetData,
|
|
149
158
|
structural: Pick<StructuralProvider, "nodeAt"> | undefined,
|
|
159
|
+
control?: CodeRequestControl,
|
|
150
160
|
): Promise<ResolvedTargetData> {
|
|
151
161
|
if (target.identityKind !== undefined) return target;
|
|
152
162
|
const identity = await resolveDeclarationIdentityKind(
|
|
@@ -160,6 +170,7 @@ export async function refineTypeAliasIdentity(
|
|
|
160
170
|
: null,
|
|
161
171
|
},
|
|
162
172
|
structural,
|
|
173
|
+
control,
|
|
163
174
|
);
|
|
164
175
|
return {
|
|
165
176
|
...target,
|
|
@@ -173,9 +184,13 @@ export async function refineTargetOutcomeIdentity(
|
|
|
173
184
|
outcome: TargetOutcome,
|
|
174
185
|
cwd: string,
|
|
175
186
|
structural: Pick<StructuralProvider, "nodeAt"> | undefined,
|
|
187
|
+
control?: CodeRequestControl,
|
|
176
188
|
): Promise<TargetOutcome> {
|
|
177
189
|
if (outcome.kind === "resolved") {
|
|
178
|
-
return {
|
|
190
|
+
return {
|
|
191
|
+
kind: "resolved",
|
|
192
|
+
target: await refineTypeAliasIdentity(outcome.target, structural, control),
|
|
193
|
+
};
|
|
179
194
|
}
|
|
180
195
|
if (outcome.kind !== "disambiguation" && outcome.kind !== "kind-mismatch") return outcome;
|
|
181
196
|
|
|
@@ -195,6 +210,7 @@ export async function refineTargetOutcomeIdentity(
|
|
|
195
210
|
: null,
|
|
196
211
|
},
|
|
197
212
|
structural,
|
|
213
|
+
control,
|
|
198
214
|
);
|
|
199
215
|
return {
|
|
200
216
|
candidate: {
|
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import * as path from "node:path";
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import {
|
|
11
|
+
type CodeRequestControl,
|
|
12
|
+
type CodeSymbol,
|
|
13
|
+
isCodeRequestInterruption,
|
|
14
|
+
type SemanticProvider as SemanticSubstrate,
|
|
13
15
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
14
16
|
import { isWithinOrEqual } from "@mrclrchtr/supi-core/project";
|
|
15
17
|
import type { TargetSymbolKind } from "../../session/target-input.ts";
|
|
@@ -59,6 +61,7 @@ function anchorOf(s: CodeSymbol): CodeSymbol["declarationAnchor"] {
|
|
|
59
61
|
async function refineResolvedSymbolAnchor(
|
|
60
62
|
workspaceSymbol: CodeSymbol,
|
|
61
63
|
semantic: SemanticSubstrate,
|
|
64
|
+
control?: CodeRequestControl,
|
|
62
65
|
): Promise<CodeSymbol> {
|
|
63
66
|
try {
|
|
64
67
|
const result = await semantic.documentSymbols(workspaceSymbol.file);
|
|
@@ -84,7 +87,8 @@ async function refineResolvedSymbolAnchor(
|
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
return refined;
|
|
87
|
-
} catch {
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (isCodeRequestInterruption(error, control)) throw error;
|
|
88
92
|
return workspaceSymbol;
|
|
89
93
|
}
|
|
90
94
|
}
|
|
@@ -107,6 +111,7 @@ export async function resolveSymbolTarget(
|
|
|
107
111
|
kind?: TargetSymbolKind;
|
|
108
112
|
exportedOnly?: boolean;
|
|
109
113
|
maxResults?: number;
|
|
114
|
+
control?: CodeRequestControl;
|
|
110
115
|
},
|
|
111
116
|
): Promise<TargetOutcome> {
|
|
112
117
|
const result = await semantic.workspaceSymbols(symbol);
|
|
@@ -150,12 +155,25 @@ export async function resolveSymbolTarget(
|
|
|
150
155
|
cwd,
|
|
151
156
|
maxResults: options.maxResults,
|
|
152
157
|
requestedKind,
|
|
158
|
+
control: options.control,
|
|
153
159
|
});
|
|
154
160
|
}
|
|
155
|
-
return resolveCandidates(
|
|
161
|
+
return resolveCandidates({
|
|
162
|
+
candidates: exactKind,
|
|
163
|
+
semantic,
|
|
164
|
+
cwd,
|
|
165
|
+
maxResults: options.maxResults,
|
|
166
|
+
control: options.control,
|
|
167
|
+
});
|
|
156
168
|
}
|
|
157
169
|
|
|
158
|
-
return resolveCandidates(
|
|
170
|
+
return resolveCandidates({
|
|
171
|
+
candidates: eligible,
|
|
172
|
+
semantic,
|
|
173
|
+
cwd,
|
|
174
|
+
maxResults: options?.maxResults,
|
|
175
|
+
control: options?.control,
|
|
176
|
+
});
|
|
159
177
|
}
|
|
160
178
|
|
|
161
179
|
function providerKindMatches(reported: string, requested: TargetSymbolKind): boolean {
|
|
@@ -166,18 +184,20 @@ function normalizeProviderKind(kind: string): string {
|
|
|
166
184
|
return kind.replace(/[\s_-]/g, "").toLowerCase();
|
|
167
185
|
}
|
|
168
186
|
|
|
169
|
-
async function resolveCandidates(
|
|
170
|
-
candidates: readonly CodeSymbol[]
|
|
171
|
-
semantic: SemanticSubstrate
|
|
172
|
-
cwd: string
|
|
173
|
-
maxResults?: number
|
|
174
|
-
|
|
187
|
+
async function resolveCandidates(options: {
|
|
188
|
+
candidates: readonly CodeSymbol[];
|
|
189
|
+
semantic: SemanticSubstrate;
|
|
190
|
+
cwd: string;
|
|
191
|
+
maxResults?: number;
|
|
192
|
+
control?: CodeRequestControl;
|
|
193
|
+
}): Promise<TargetOutcome> {
|
|
194
|
+
const { candidates, semantic, cwd, maxResults, control } = options;
|
|
175
195
|
const ranged = candidates.filter(
|
|
176
196
|
(candidate) =>
|
|
177
197
|
candidate.declarationAnchor.line > 0 || candidate.declarationAnchor.character > 0,
|
|
178
198
|
);
|
|
179
199
|
if (ranged.length === 1) {
|
|
180
|
-
return resolvedTarget(await refineResolvedSymbolAnchor(ranged[0], semantic));
|
|
200
|
+
return resolvedTarget(await refineResolvedSymbolAnchor(ranged[0], semantic, control));
|
|
181
201
|
}
|
|
182
202
|
return buildCandidateOutcome({
|
|
183
203
|
kind: "disambiguation",
|
|
@@ -185,6 +205,7 @@ async function resolveCandidates(
|
|
|
185
205
|
semantic,
|
|
186
206
|
cwd,
|
|
187
207
|
maxResults,
|
|
208
|
+
control,
|
|
188
209
|
});
|
|
189
210
|
}
|
|
190
211
|
|
|
@@ -220,7 +241,7 @@ type CandidateOutcomeOptions = CandidateOutcomeBase &
|
|
|
220
241
|
(
|
|
221
242
|
| { kind: "disambiguation"; requestedKind?: never }
|
|
222
243
|
| { kind: "kind-mismatch"; requestedKind: TargetSymbolKind }
|
|
223
|
-
);
|
|
244
|
+
) & { control?: CodeRequestControl };
|
|
224
245
|
|
|
225
246
|
/**
|
|
226
247
|
* Refine only bounded visible candidates to name anchors while retaining the
|
|
@@ -234,7 +255,7 @@ async function buildCandidateOutcome(
|
|
|
234
255
|
const refined = await Promise.all(
|
|
235
256
|
options.candidates
|
|
236
257
|
.slice(0, cap)
|
|
237
|
-
.map((candidate) => refineResolvedSymbolAnchor(candidate, options.semantic)),
|
|
258
|
+
.map((candidate) => refineResolvedSymbolAnchor(candidate, options.semantic, options.control)),
|
|
238
259
|
);
|
|
239
260
|
const common = {
|
|
240
261
|
candidates: toDisambiguationCandidates(refined, options.cwd),
|
package/src/api.ts
CHANGED
|
@@ -57,6 +57,7 @@ export type { TargetSymbolKind } from "./session/target-input.ts";
|
|
|
57
57
|
// Code-intelligence-specific result types.
|
|
58
58
|
export type {
|
|
59
59
|
CodeIntelResult,
|
|
60
|
+
CodeIntelResultDetails,
|
|
60
61
|
ContextDetails,
|
|
61
62
|
DisambiguationCandidate,
|
|
62
63
|
HealthDetails,
|
|
@@ -65,4 +66,7 @@ export type {
|
|
|
65
66
|
OrientationSectionDetails,
|
|
66
67
|
ResolveDetails,
|
|
67
68
|
SearchDetails,
|
|
69
|
+
ToolDisplaySection,
|
|
70
|
+
ToolOutputTruncationDetails,
|
|
71
|
+
ToolResultStatus,
|
|
68
72
|
} from "./types/index.ts";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import type {
|
|
3
|
+
DiagnosticEvidenceDocument,
|
|
4
|
+
DiagnosticEvidenceStatus,
|
|
5
|
+
DiagnosticEvidenceSummary,
|
|
6
|
+
} from "@mrclrchtr/supi-lsp/api";
|
|
7
|
+
|
|
8
|
+
/** Merge file-local diagnostic evidence without inventing coverage. */
|
|
9
|
+
export function mergeDiagnosticEvidence(
|
|
10
|
+
previous: DiagnosticEvidenceSummary,
|
|
11
|
+
latest: DiagnosticEvidenceSummary,
|
|
12
|
+
cwd?: string,
|
|
13
|
+
policy: "latest" | "conservative" = "latest",
|
|
14
|
+
): DiagnosticEvidenceSummary {
|
|
15
|
+
const byFile = new Map<string, DiagnosticEvidenceDocument>();
|
|
16
|
+
for (const document of [...previous.documents, ...latest.documents]) {
|
|
17
|
+
const file = cwd ? path.relative(cwd, path.resolve(cwd, document.file)) : document.file;
|
|
18
|
+
const next = { file, status: document.status };
|
|
19
|
+
const previousDocument = byFile.get(file);
|
|
20
|
+
if (
|
|
21
|
+
!previousDocument ||
|
|
22
|
+
policy === "latest" ||
|
|
23
|
+
evidenceStatusRank(next.status) > evidenceStatusRank(previousDocument.status)
|
|
24
|
+
) {
|
|
25
|
+
byFile.set(file, next);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const documents = Array.from(byFile.values()).sort((a, b) => a.file.localeCompare(b.file));
|
|
29
|
+
const counts = {
|
|
30
|
+
requested: documents.length,
|
|
31
|
+
confirmed: 0,
|
|
32
|
+
unconfirmed: 0,
|
|
33
|
+
failed: 0,
|
|
34
|
+
removed: 0,
|
|
35
|
+
};
|
|
36
|
+
for (const document of documents) counts[document.status]++;
|
|
37
|
+
return { ...counts, documents };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function evidenceStatusRank(status: DiagnosticEvidenceStatus): number {
|
|
41
|
+
switch (status) {
|
|
42
|
+
case "confirmed":
|
|
43
|
+
return 1;
|
|
44
|
+
case "unconfirmed":
|
|
45
|
+
return 2;
|
|
46
|
+
case "failed":
|
|
47
|
+
return 3;
|
|
48
|
+
case "removed":
|
|
49
|
+
return 4;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
type CapabilityState,
|
|
12
|
+
type CodeRequestControl,
|
|
12
13
|
getDefaultWorkspaceRuntime,
|
|
13
14
|
type SemanticProvider,
|
|
14
15
|
type StructuralProvider,
|
|
@@ -67,7 +68,11 @@ export interface CapabilityAdapter {
|
|
|
67
68
|
* the target workflow can decide whether to proceed, return a
|
|
68
69
|
* timeout note, or return an unavailable result.
|
|
69
70
|
*/
|
|
70
|
-
ensureSemanticReadiness(
|
|
71
|
+
ensureSemanticReadiness(
|
|
72
|
+
cwd: string,
|
|
73
|
+
scope: ReadinessScope,
|
|
74
|
+
control?: CodeRequestControl,
|
|
75
|
+
): Promise<ReadinessOutcome>;
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
// ── Production adapter ────────────────────────────────────────────────
|
|
@@ -107,8 +112,12 @@ export class WorkspaceCapabilityAdapter implements CapabilityAdapter {
|
|
|
107
112
|
return null;
|
|
108
113
|
}
|
|
109
114
|
|
|
110
|
-
async ensureSemanticReadiness(
|
|
111
|
-
|
|
115
|
+
async ensureSemanticReadiness(
|
|
116
|
+
cwd: string,
|
|
117
|
+
scope: ReadinessScope,
|
|
118
|
+
control?: CodeRequestControl,
|
|
119
|
+
): Promise<ReadinessOutcome> {
|
|
120
|
+
const result = await ensureSemanticReadiness(cwd, scope, undefined, control);
|
|
112
121
|
return result;
|
|
113
122
|
}
|
|
114
123
|
|
|
@@ -30,7 +30,8 @@ export async function runFindWorkflow(
|
|
|
30
30
|
const scope = resolveScopeSet(request.scope ? [...request.scope] : undefined, deps.cwd);
|
|
31
31
|
if (scope.kind === "error") return { kind: "invalid-input", message: scope.reason };
|
|
32
32
|
|
|
33
|
-
throwIfAborted(
|
|
33
|
+
if (mode === "ast") control?.signal?.throwIfAborted();
|
|
34
|
+
else throwIfAborted(control);
|
|
34
35
|
reportProgress(control, {
|
|
35
36
|
intent: "find",
|
|
36
37
|
phase: mode,
|
|
@@ -69,9 +70,11 @@ async function runSemanticSearch(options: {
|
|
|
69
70
|
control?: WorkflowControl;
|
|
70
71
|
}): Promise<FindWorkflowOutcome> {
|
|
71
72
|
const { query, scopePaths, scopeLabel, maxResults, deps, control } = options;
|
|
72
|
-
const readiness = await deps.capability.ensureSemanticReadiness(
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
const readiness = await deps.capability.ensureSemanticReadiness(
|
|
74
|
+
deps.cwd,
|
|
75
|
+
{ kind: "workspace" },
|
|
76
|
+
control,
|
|
77
|
+
);
|
|
75
78
|
if (readiness.kind === "timeout") {
|
|
76
79
|
return { kind: "unavailable", reason: "Semantic readiness timed out." };
|
|
77
80
|
}
|
|
@@ -82,7 +85,10 @@ async function runSemanticSearch(options: {
|
|
|
82
85
|
if (!provider?.workspaceSymbols) {
|
|
83
86
|
return { kind: "unavailable", reason: "No semantic workspace-symbol provider is active." };
|
|
84
87
|
}
|
|
85
|
-
const result = await provider.workspaceSymbols(query);
|
|
88
|
+
const result = await provider.workspaceSymbols(query, control);
|
|
89
|
+
// A cancellation that landed during the request must not publish symbols
|
|
90
|
+
// the caller no longer awaits.
|
|
91
|
+
throwIfAborted(control);
|
|
86
92
|
if (result.kind === "unavailable") {
|
|
87
93
|
return { kind: "unavailable", reason: result.reason };
|
|
88
94
|
}
|
|
@@ -120,13 +126,17 @@ async function runAstSearch(options: {
|
|
|
120
126
|
if (!provider) {
|
|
121
127
|
return { kind: "unavailable", reason: "No structural provider is active." };
|
|
122
128
|
}
|
|
123
|
-
throwIfAborted(
|
|
129
|
+
control?.signal?.throwIfAborted();
|
|
124
130
|
const outcome = await getStructuredPatternMatches({
|
|
125
131
|
params: { pattern: query, kind: input.kind },
|
|
126
132
|
roots: scopePaths,
|
|
127
133
|
cwd: deps.cwd,
|
|
128
134
|
structural: provider,
|
|
129
|
-
control: {
|
|
135
|
+
control: {
|
|
136
|
+
operationId: control?.operationId,
|
|
137
|
+
signal: control?.signal,
|
|
138
|
+
deadline: control?.deadline,
|
|
139
|
+
},
|
|
130
140
|
});
|
|
131
141
|
if (outcome.kind === "invalid-input") return outcome;
|
|
132
142
|
if (outcome.kind === "unavailable") return outcome;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/** Presentation-neutral relation collection used by the session-owned graph workflow. */
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
type CodeRequestControl,
|
|
5
|
+
isCodeRequestInterruption,
|
|
6
|
+
unavailableCodeQuery,
|
|
7
|
+
} from "@mrclrchtr/supi-code-runtime/api";
|
|
3
8
|
import type { CodeProvider } from "../../analysis/provider.ts";
|
|
4
9
|
import {
|
|
5
10
|
readNextEnclosingScope,
|
|
@@ -25,6 +30,7 @@ export interface CollectRelationOptions {
|
|
|
25
30
|
semanticReadinessError: string | null;
|
|
26
31
|
anchorKind: AnchorKind;
|
|
27
32
|
calleeDepth?: "direct" | "deep";
|
|
33
|
+
requestControl?: CodeRequestControl;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
/** Collect one evidence-backed graph relation without rendering it. */
|
|
@@ -46,6 +52,7 @@ export async function collectRelation(
|
|
|
46
52
|
return collectImplementationsRelation(options);
|
|
47
53
|
}
|
|
48
54
|
} catch (error) {
|
|
55
|
+
if (isCodeRequestInterruption(error, options.requestControl)) throw error;
|
|
49
56
|
return {
|
|
50
57
|
kind: "unavailable",
|
|
51
58
|
rel: relation,
|
|
@@ -61,7 +68,11 @@ async function collectReferences(options: CollectRelationOptions): Promise<Graph
|
|
|
61
68
|
|
|
62
69
|
const result = await collectCallers(options.file, options.position, options.displayName, {
|
|
63
70
|
cwd: options.cwd,
|
|
64
|
-
provider: {
|
|
71
|
+
provider: {
|
|
72
|
+
references: async (file, position) =>
|
|
73
|
+
options.provider?.references(file, position, options.requestControl) ??
|
|
74
|
+
unavailableCodeQuery("References unavailable"),
|
|
75
|
+
},
|
|
65
76
|
});
|
|
66
77
|
if (result.confidence === "unavailable") {
|
|
67
78
|
return { kind: "unavailable", rel: "references", message: "References unavailable" };
|
|
@@ -118,6 +129,7 @@ async function collectCalleesRelation(options: CollectRelationOptions): Promise<
|
|
|
118
129
|
{ cwd: options.cwd, provider: { calleesAt: options.provider.calleesAt } },
|
|
119
130
|
undefined,
|
|
120
131
|
options.calleeDepth ?? "direct",
|
|
132
|
+
options.requestControl,
|
|
121
133
|
);
|
|
122
134
|
if (result.confidence === "unavailable") {
|
|
123
135
|
return { kind: "unavailable", rel: "callees", message: "Callees unavailable" };
|
|
@@ -161,7 +173,11 @@ async function collectImplementationsRelation(
|
|
|
161
173
|
|
|
162
174
|
const result = await collectImplementations(options.file, options.position, options.displayName, {
|
|
163
175
|
cwd: options.cwd,
|
|
164
|
-
provider: {
|
|
176
|
+
provider: {
|
|
177
|
+
implementation: async (file, position) =>
|
|
178
|
+
options.provider?.implementation(file, position, options.requestControl) ??
|
|
179
|
+
unavailableCodeQuery("Implementations unavailable"),
|
|
180
|
+
},
|
|
165
181
|
});
|
|
166
182
|
if (result.confidence === "unavailable") {
|
|
167
183
|
return { kind: "unavailable", rel: "implements", message: "Implementations unavailable" };
|
|
@@ -54,7 +54,9 @@ export async function runGraphWorkflow(
|
|
|
54
54
|
maxResults: request.maxResults,
|
|
55
55
|
},
|
|
56
56
|
deps,
|
|
57
|
+
control,
|
|
57
58
|
);
|
|
59
|
+
throwIfAborted(control);
|
|
58
60
|
if (targetOutcome.kind === "target-group") {
|
|
59
61
|
return {
|
|
60
62
|
kind: "invalid-input",
|
|
@@ -64,12 +66,13 @@ export async function runGraphWorkflow(
|
|
|
64
66
|
if (targetOutcome.kind !== "resolved") return targetOutcome;
|
|
65
67
|
|
|
66
68
|
const entry = targetOutcome.entry;
|
|
67
|
-
const semanticReadinessError = await getSemanticReadinessError(
|
|
69
|
+
const semanticReadinessError = await getSemanticReadinessError({
|
|
68
70
|
relations,
|
|
69
|
-
entry.file,
|
|
70
|
-
deps.capability,
|
|
71
|
-
deps.cwd,
|
|
72
|
-
|
|
71
|
+
file: entry.file,
|
|
72
|
+
capability: deps.capability,
|
|
73
|
+
cwd: deps.cwd,
|
|
74
|
+
control,
|
|
75
|
+
});
|
|
73
76
|
const provider = deps.capability.getProvider(deps.cwd);
|
|
74
77
|
const maxResults = request.maxResults ?? 8;
|
|
75
78
|
const displayName =
|
|
@@ -94,9 +97,11 @@ export async function runGraphWorkflow(
|
|
|
94
97
|
semanticReadinessError,
|
|
95
98
|
anchorKind: entry.anchorKind,
|
|
96
99
|
calleeDepth: request.calleeDepth,
|
|
100
|
+
requestControl: control,
|
|
97
101
|
}),
|
|
98
102
|
);
|
|
99
103
|
}
|
|
104
|
+
throwIfAborted(control);
|
|
100
105
|
|
|
101
106
|
if (sections.length > 0 && sections.every((section) => section.kind === "unavailable")) {
|
|
102
107
|
return {
|
|
@@ -127,16 +132,18 @@ function normalizeRelations(
|
|
|
127
132
|
return requested as readonly GraphRelationKind[];
|
|
128
133
|
}
|
|
129
134
|
|
|
130
|
-
async function getSemanticReadinessError(
|
|
131
|
-
relations: readonly GraphRelationKind[]
|
|
132
|
-
file: string
|
|
133
|
-
capability: CapabilityAdapter
|
|
134
|
-
cwd: string
|
|
135
|
-
|
|
135
|
+
async function getSemanticReadinessError(options: {
|
|
136
|
+
relations: readonly GraphRelationKind[];
|
|
137
|
+
file: string;
|
|
138
|
+
capability: CapabilityAdapter;
|
|
139
|
+
cwd: string;
|
|
140
|
+
control?: WorkflowControl;
|
|
141
|
+
}): Promise<string | null> {
|
|
142
|
+
const { relations, file, capability, cwd, control } = options;
|
|
136
143
|
if (!relations.some((relation) => relation === "references" || relation === "implements")) {
|
|
137
144
|
return null;
|
|
138
145
|
}
|
|
139
|
-
const readiness = await capability.ensureSemanticReadiness(cwd, { kind: "file", file });
|
|
146
|
+
const readiness = await capability.ensureSemanticReadiness(cwd, { kind: "file", file }, control);
|
|
140
147
|
if (readiness.kind === "ready") return null;
|
|
141
148
|
if (readiness.kind === "timeout") {
|
|
142
149
|
return "Semantic readiness timed out. Retry shortly or inspect code_health.";
|