@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
|
@@ -57,7 +57,7 @@ export function formatProjectServerStatusReason(
|
|
|
57
57
|
case "process-crash-recovery-pending":
|
|
58
58
|
return "process recovery in progress";
|
|
59
59
|
case "process-crash-recovery-exhausted":
|
|
60
|
-
return "process recovery exhausted;
|
|
60
|
+
return "process recovery exhausted; try another explicit health refresh";
|
|
61
61
|
default:
|
|
62
62
|
return null;
|
|
63
63
|
}
|
|
@@ -11,6 +11,8 @@ export interface CalleesResult {
|
|
|
11
11
|
enclosingScope: CalleeScope | null;
|
|
12
12
|
callees: CalleeEntry[];
|
|
13
13
|
confidence: "structural" | "unavailable";
|
|
14
|
+
/** Original provider reason when callee evidence is unavailable. */
|
|
15
|
+
message: string | null;
|
|
14
16
|
depth: "direct" | "deep";
|
|
15
17
|
}
|
|
16
18
|
|
|
@@ -30,7 +32,7 @@ export async function collectCallees(
|
|
|
30
32
|
control?: CodeRequestControl,
|
|
31
33
|
): Promise<CalleesResult> {
|
|
32
34
|
if (!deps.provider?.calleesAt) {
|
|
33
|
-
return unavailableCallees(targetName);
|
|
35
|
+
return unavailableCallees(targetName, "No structural callee provider", depth);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
const depthOrOptions = control ? { depth, control } : depth;
|
|
@@ -40,8 +42,8 @@ export async function collectCallees(
|
|
|
40
42
|
targetCharacter,
|
|
41
43
|
depthOrOptions,
|
|
42
44
|
);
|
|
43
|
-
if (result.kind !== "success"
|
|
44
|
-
return unavailableCallees(targetName);
|
|
45
|
+
if (result.kind !== "success") {
|
|
46
|
+
return unavailableCallees(targetName, result.message, depth);
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
void maxResults;
|
|
@@ -53,9 +55,10 @@ export async function collectCallees(
|
|
|
53
55
|
);
|
|
54
56
|
const callees: CalleeEntry[] = result.data.callees.map((c) => ({
|
|
55
57
|
name: c.name,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
...(c.displayName ? { displayName: c.displayName } : {}),
|
|
59
|
+
file: targetFile,
|
|
60
|
+
line: c.startLine,
|
|
61
|
+
character: c.startCharacter,
|
|
59
62
|
}));
|
|
60
63
|
|
|
61
64
|
return {
|
|
@@ -64,18 +67,24 @@ export async function collectCallees(
|
|
|
64
67
|
enclosingScope,
|
|
65
68
|
callees,
|
|
66
69
|
confidence: "structural",
|
|
70
|
+
message: null,
|
|
67
71
|
depth: result.data.depth ?? depth,
|
|
68
72
|
};
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
function unavailableCallees(
|
|
75
|
+
function unavailableCallees(
|
|
76
|
+
targetName: string | null,
|
|
77
|
+
message: string,
|
|
78
|
+
depth: "direct" | "deep",
|
|
79
|
+
): CalleesResult {
|
|
72
80
|
return {
|
|
73
81
|
kind: "callees",
|
|
74
82
|
targetName: targetName ?? "symbol",
|
|
75
83
|
enclosingScope: null,
|
|
76
84
|
callees: [],
|
|
77
85
|
confidence: "unavailable",
|
|
78
|
-
|
|
86
|
+
message,
|
|
87
|
+
depth,
|
|
79
88
|
};
|
|
80
89
|
}
|
|
81
90
|
|
|
@@ -73,8 +73,7 @@ export async function collectImplementations(
|
|
|
73
73
|
implementations: project,
|
|
74
74
|
externalCount: normalized.external.length,
|
|
75
75
|
invalidLocationCount: normalized.invalidLocationCount,
|
|
76
|
-
partialReason:
|
|
77
|
-
normalized.partialReason ?? (result.kind === "partial" ? "provider-limited" : null),
|
|
76
|
+
partialReason: result.kind === "partial" ? "provider-limited" : normalized.partialReason,
|
|
78
77
|
confidence: "semantic",
|
|
79
78
|
};
|
|
80
79
|
}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "./provider-locations.ts";
|
|
14
14
|
import type { CallerEvidence, CallerReference, RelationsServiceDeps } from "./types.ts";
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
interface CallerEvidenceData {
|
|
17
17
|
kind: "callers";
|
|
18
18
|
targetName: string;
|
|
19
19
|
references: CallerReference[];
|
|
@@ -22,9 +22,12 @@ export interface CallersResult {
|
|
|
22
22
|
invalidLocationCount: number;
|
|
23
23
|
partialReason: RelationLocationPartialReason | null;
|
|
24
24
|
evidence: CallerEvidence;
|
|
25
|
-
confidence: "semantic" | "unavailable";
|
|
26
25
|
}
|
|
27
26
|
|
|
27
|
+
/** Reference evidence, or the provider reason that prevented collection. */
|
|
28
|
+
export type CallersResult = CallerEvidenceData &
|
|
29
|
+
({ confidence: "semantic" } | { confidence: "unavailable"; message: string });
|
|
30
|
+
|
|
28
31
|
/**
|
|
29
32
|
* Collect callers (references) for a target file/position using semantic provider.
|
|
30
33
|
*/
|
|
@@ -46,6 +49,7 @@ export async function collectCallers(
|
|
|
46
49
|
partialReason: null,
|
|
47
50
|
evidence: "semantic-references",
|
|
48
51
|
confidence: "unavailable",
|
|
52
|
+
message: "No semantic references provider",
|
|
49
53
|
};
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -60,6 +64,7 @@ export async function collectCallers(
|
|
|
60
64
|
partialReason: null,
|
|
61
65
|
evidence: "semantic-references",
|
|
62
66
|
confidence: "unavailable",
|
|
67
|
+
message: result.reason,
|
|
63
68
|
};
|
|
64
69
|
}
|
|
65
70
|
|
|
@@ -77,8 +82,7 @@ export async function collectCallers(
|
|
|
77
82
|
references: inProject,
|
|
78
83
|
externalCount: normalized.external.length,
|
|
79
84
|
invalidLocationCount: normalized.invalidLocationCount,
|
|
80
|
-
partialReason:
|
|
81
|
-
normalized.partialReason ?? (result.kind === "partial" ? "provider-limited" : null),
|
|
85
|
+
partialReason: result.kind === "partial" ? "provider-limited" : normalized.partialReason,
|
|
82
86
|
evidence: "semantic-references",
|
|
83
87
|
confidence: "semantic",
|
|
84
88
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SemanticProvider, StructuralProvider } from "@mrclrchtr/supi-code-runtime/api";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Shared types for the relations analysis modules.
|
|
@@ -32,13 +32,15 @@ export interface CalleeScope {
|
|
|
32
32
|
/** One direct structural callee entry from an enclosing-scope lookup. */
|
|
33
33
|
export interface CalleeEntry {
|
|
34
34
|
name: string;
|
|
35
|
+
/** Syntax-based preview only; the full name remains the grouping key. */
|
|
36
|
+
displayName?: string;
|
|
35
37
|
file: string;
|
|
36
38
|
line: number;
|
|
37
39
|
character: number;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
/**
|
|
41
|
-
export type CallEntry =
|
|
42
|
+
/** One structural call site with a 1-based UTF-16 coordinate. */
|
|
43
|
+
export type CallEntry = CalleeEntry;
|
|
42
44
|
|
|
43
45
|
/** One implementation entry from a semantic implementation lookup. */
|
|
44
46
|
export interface ImplementationEntry {
|
|
@@ -54,32 +56,6 @@ export interface RelationsServiceDeps {
|
|
|
54
56
|
provider: {
|
|
55
57
|
references?: SemanticProvider["references"];
|
|
56
58
|
implementation?: SemanticProvider["implementation"];
|
|
57
|
-
calleesAt?:
|
|
58
|
-
file: string,
|
|
59
|
-
line: number,
|
|
60
|
-
character: number,
|
|
61
|
-
depthOrOptions?:
|
|
62
|
-
| "direct"
|
|
63
|
-
| "deep"
|
|
64
|
-
| { depth?: "direct" | "deep"; control?: CodeRequestControl },
|
|
65
|
-
) => Promise<{
|
|
66
|
-
kind: string;
|
|
67
|
-
data?: {
|
|
68
|
-
enclosingScope?: {
|
|
69
|
-
name?: string;
|
|
70
|
-
startLine?: number;
|
|
71
|
-
endLine?: number;
|
|
72
|
-
};
|
|
73
|
-
callees: Array<{
|
|
74
|
-
name: string;
|
|
75
|
-
file?: string;
|
|
76
|
-
location?: string;
|
|
77
|
-
startLine?: number;
|
|
78
|
-
startCharacter?: number;
|
|
79
|
-
}>;
|
|
80
|
-
depth?: "direct" | "deep";
|
|
81
|
-
};
|
|
82
|
-
message?: string;
|
|
83
|
-
}>;
|
|
59
|
+
calleesAt?: StructuralProvider["calleesAt"];
|
|
84
60
|
} | null;
|
|
85
61
|
}
|
|
@@ -191,7 +191,9 @@ async function candidatesFromSymbols(
|
|
|
191
191
|
): Promise<{
|
|
192
192
|
kind: "disambiguation";
|
|
193
193
|
candidates: DisambiguationCandidateData[];
|
|
194
|
+
totalCount: number;
|
|
194
195
|
omittedCount: number;
|
|
196
|
+
partialReason: null;
|
|
195
197
|
}> {
|
|
196
198
|
const candidates = await Promise.all(
|
|
197
199
|
matched.map(async (s, idx) => {
|
|
@@ -215,7 +217,13 @@ async function candidatesFromSymbols(
|
|
|
215
217
|
} satisfies DisambiguationCandidateData;
|
|
216
218
|
}),
|
|
217
219
|
);
|
|
218
|
-
return {
|
|
220
|
+
return {
|
|
221
|
+
kind: "disambiguation",
|
|
222
|
+
candidates,
|
|
223
|
+
totalCount: candidates.length,
|
|
224
|
+
omittedCount: 0,
|
|
225
|
+
partialReason: null,
|
|
226
|
+
};
|
|
219
227
|
}
|
|
220
228
|
|
|
221
229
|
/** Layer 1: match the coordinate against LSP document symbols. Returns null to fall through. */
|
|
@@ -18,7 +18,11 @@ import { isWithinOrEqual } from "@mrclrchtr/supi-core/project";
|
|
|
18
18
|
import type { TargetSymbolKind } from "../../session/target-input.ts";
|
|
19
19
|
import type { AnchorKind } from "../../session/target-store.ts";
|
|
20
20
|
import { normalizePath } from "../search/paths.ts";
|
|
21
|
-
import type {
|
|
21
|
+
import type {
|
|
22
|
+
DisambiguationCandidateData,
|
|
23
|
+
TargetCandidateCompleteness,
|
|
24
|
+
TargetOutcome,
|
|
25
|
+
} from "./types.ts";
|
|
22
26
|
|
|
23
27
|
const MAX_CANDIDATES = 8; // default fallback when maxResults is not provided
|
|
24
28
|
const NON_EXPORTED_KINDS = new Set(["Variable", "Field", "Property"]);
|
|
@@ -146,6 +150,7 @@ export async function resolveSymbolTarget(
|
|
|
146
150
|
return buildCandidateOutcome({
|
|
147
151
|
kind: "kind-mismatch",
|
|
148
152
|
candidates: eligible,
|
|
153
|
+
...candidateCompleteness(result, eligible.length),
|
|
149
154
|
semantic,
|
|
150
155
|
cwd,
|
|
151
156
|
maxResults: options.maxResults,
|
|
@@ -155,6 +160,7 @@ export async function resolveSymbolTarget(
|
|
|
155
160
|
}
|
|
156
161
|
return resolveCandidates({
|
|
157
162
|
candidates: exactKind,
|
|
163
|
+
...candidateCompleteness(result, exactKind.length),
|
|
158
164
|
semantic,
|
|
159
165
|
cwd,
|
|
160
166
|
maxResults: options.maxResults,
|
|
@@ -164,6 +170,7 @@ export async function resolveSymbolTarget(
|
|
|
164
170
|
|
|
165
171
|
return resolveCandidates({
|
|
166
172
|
candidates: eligible,
|
|
173
|
+
...candidateCompleteness(result, eligible.length),
|
|
167
174
|
semantic,
|
|
168
175
|
cwd,
|
|
169
176
|
maxResults: options?.maxResults,
|
|
@@ -179,19 +186,15 @@ function normalizeProviderKind(kind: string): string {
|
|
|
179
186
|
return kind.replace(/[\s_-]/g, "").toLowerCase();
|
|
180
187
|
}
|
|
181
188
|
|
|
182
|
-
async function resolveCandidates(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
cwd
|
|
186
|
-
maxResults?: number;
|
|
187
|
-
control?: CodeRequestControl;
|
|
188
|
-
}): Promise<TargetOutcome> {
|
|
189
|
-
const { candidates, semantic, cwd, maxResults, control } = options;
|
|
189
|
+
async function resolveCandidates(
|
|
190
|
+
options: CandidateOutcomeBase & Pick<TargetCandidateCompleteness, "totalCount" | "partialReason">,
|
|
191
|
+
): Promise<TargetOutcome> {
|
|
192
|
+
const { candidates, semantic, cwd, maxResults, control, totalCount, partialReason } = options;
|
|
190
193
|
const ranged = candidates.filter(
|
|
191
194
|
(candidate) =>
|
|
192
195
|
candidate.declarationAnchor.line > 0 || candidate.declarationAnchor.character > 0,
|
|
193
196
|
);
|
|
194
|
-
if (ranged.length === 1) {
|
|
197
|
+
if (ranged.length === 1 && totalCount !== null) {
|
|
195
198
|
return resolvedTarget(await refineResolvedSymbolAnchor(ranged[0], semantic, control));
|
|
196
199
|
}
|
|
197
200
|
return buildCandidateOutcome({
|
|
@@ -200,6 +203,8 @@ async function resolveCandidates(options: {
|
|
|
200
203
|
semantic,
|
|
201
204
|
cwd,
|
|
202
205
|
maxResults,
|
|
206
|
+
totalCount,
|
|
207
|
+
partialReason,
|
|
203
208
|
control,
|
|
204
209
|
});
|
|
205
210
|
}
|
|
@@ -230,13 +235,24 @@ interface CandidateOutcomeBase {
|
|
|
230
235
|
semantic: SemanticSubstrate;
|
|
231
236
|
cwd: string;
|
|
232
237
|
maxResults?: number;
|
|
238
|
+
control?: CodeRequestControl;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function candidateCompleteness(
|
|
242
|
+
result: Exclude<CodeQueryResult<CodeSymbol[]>, { kind: "unavailable" }>,
|
|
243
|
+
totalCount: number,
|
|
244
|
+
): Pick<TargetCandidateCompleteness, "totalCount" | "partialReason"> {
|
|
245
|
+
return result.kind === "partial"
|
|
246
|
+
? { totalCount: null, partialReason: "provider-limited" }
|
|
247
|
+
: { totalCount, partialReason: null };
|
|
233
248
|
}
|
|
234
249
|
|
|
235
250
|
type CandidateOutcomeOptions = CandidateOutcomeBase &
|
|
251
|
+
Pick<TargetCandidateCompleteness, "totalCount" | "partialReason"> &
|
|
236
252
|
(
|
|
237
253
|
| { kind: "disambiguation"; requestedKind?: never }
|
|
238
254
|
| { kind: "kind-mismatch"; requestedKind: TargetSymbolKind }
|
|
239
|
-
)
|
|
255
|
+
);
|
|
240
256
|
|
|
241
257
|
/**
|
|
242
258
|
* Refine only bounded visible candidates to name anchors while retaining the
|
|
@@ -271,7 +287,9 @@ async function buildCandidateOutcome(
|
|
|
271
287
|
);
|
|
272
288
|
const common = {
|
|
273
289
|
candidates: toDisambiguationCandidates(refined, options.cwd),
|
|
290
|
+
totalCount: options.totalCount,
|
|
274
291
|
omittedCount: Math.max(0, options.candidates.length - cap),
|
|
292
|
+
partialReason: options.partialReason,
|
|
275
293
|
};
|
|
276
294
|
return options.kind === "kind-mismatch"
|
|
277
295
|
? {
|
|
@@ -136,6 +136,16 @@ export interface DisambiguationCandidateData {
|
|
|
136
136
|
anchorKind: AnchorKind;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/** Completeness metadata for a bounded candidate collection. */
|
|
140
|
+
export interface TargetCandidateCompleteness {
|
|
141
|
+
/** Exact candidate total, or null when the provider returned partial data. */
|
|
142
|
+
totalCount: number | null;
|
|
143
|
+
/** Candidates returned by the provider but hidden by the target cap. */
|
|
144
|
+
omittedCount: number;
|
|
145
|
+
/** Why the provider cannot establish an exact candidate total. */
|
|
146
|
+
partialReason: "provider-limited" | null;
|
|
147
|
+
}
|
|
148
|
+
|
|
139
149
|
/**
|
|
140
150
|
* Typed outcome of a resolution attempt.
|
|
141
151
|
*
|
|
@@ -145,16 +155,14 @@ export interface DisambiguationCandidateData {
|
|
|
145
155
|
export type TargetOutcome =
|
|
146
156
|
| { kind: "resolved"; target: ResolvedTargetData }
|
|
147
157
|
| { kind: "group"; group: ResolvedTargetGroupData }
|
|
148
|
-
| {
|
|
158
|
+
| ({
|
|
149
159
|
kind: "disambiguation";
|
|
150
160
|
candidates: DisambiguationCandidateData[];
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
| {
|
|
161
|
+
} & TargetCandidateCompleteness)
|
|
162
|
+
| ({
|
|
154
163
|
kind: "kind-mismatch";
|
|
155
164
|
requestedKind: TargetSymbolKind;
|
|
156
165
|
candidates: DisambiguationCandidateData[];
|
|
157
|
-
|
|
158
|
-
}
|
|
166
|
+
} & TargetCandidateCompleteness)
|
|
159
167
|
| { kind: "unavailable"; reason: string }
|
|
160
168
|
| { kind: "error"; message: string };
|
package/src/api.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
8
8
|
import type { CodeProvider } from "../../analysis/provider.ts";
|
|
9
9
|
import {
|
|
10
|
+
readNextAround,
|
|
10
11
|
readNextEnclosingScope,
|
|
11
12
|
readNextTarget,
|
|
12
13
|
readNextTopSites,
|
|
@@ -75,7 +76,7 @@ async function collectReferences(options: CollectRelationOptions): Promise<Graph
|
|
|
75
76
|
},
|
|
76
77
|
});
|
|
77
78
|
if (result.confidence === "unavailable") {
|
|
78
|
-
return { kind: "unavailable", rel: "references", message:
|
|
79
|
+
return { kind: "unavailable", rel: "references", message: result.message };
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
const targetLine = options.position.line + 1;
|
|
@@ -132,7 +133,11 @@ async function collectCalleesRelation(options: CollectRelationOptions): Promise<
|
|
|
132
133
|
options.requestControl,
|
|
133
134
|
);
|
|
134
135
|
if (result.confidence === "unavailable") {
|
|
135
|
-
return {
|
|
136
|
+
return {
|
|
137
|
+
kind: "unavailable",
|
|
138
|
+
rel: "callees",
|
|
139
|
+
message: `${result.message ?? "Callees unavailable"}\nUse code_inspect at the target position to check the scope.`,
|
|
140
|
+
};
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
const enclosingScope = result.enclosingScope ?? {
|
|
@@ -143,8 +148,10 @@ async function collectCalleesRelation(options: CollectRelationOptions): Promise<
|
|
|
143
148
|
};
|
|
144
149
|
const calls: CallEntry[] = result.callees.map((callee) => ({
|
|
145
150
|
name: callee.name,
|
|
151
|
+
...(callee.displayName ? { displayName: callee.displayName } : {}),
|
|
146
152
|
file: callee.file,
|
|
147
153
|
line: callee.line,
|
|
154
|
+
character: callee.character,
|
|
148
155
|
}));
|
|
149
156
|
return {
|
|
150
157
|
kind: "ok",
|
|
@@ -192,6 +199,14 @@ async function collectImplementationsRelation(
|
|
|
192
199
|
invalidLocationCount: result.invalidLocationCount,
|
|
193
200
|
partialReason: result.partialReason,
|
|
194
201
|
},
|
|
195
|
-
readNext:
|
|
202
|
+
readNext: result.implementations
|
|
203
|
+
.slice(0, Math.min(options.maxResults, 2))
|
|
204
|
+
.map((implementation) =>
|
|
205
|
+
readNextAround(
|
|
206
|
+
toDisplayPath(options.cwd, implementation.file),
|
|
207
|
+
implementation.line,
|
|
208
|
+
"inspect an implementation site",
|
|
209
|
+
),
|
|
210
|
+
),
|
|
196
211
|
};
|
|
197
212
|
}
|
|
@@ -4,12 +4,15 @@ import {
|
|
|
4
4
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
5
5
|
import {
|
|
6
6
|
emptyProcessCrashRecoveryReport,
|
|
7
|
+
emptyStartupRetryReport,
|
|
8
|
+
type SemanticReadinessResult,
|
|
7
9
|
type WorkspaceDiagnosticReport,
|
|
8
10
|
type WorkspaceLspRuntime,
|
|
9
11
|
} from "@mrclrchtr/supi-lsp/api";
|
|
10
12
|
import { recoverDiagnosticRuntime } from "../analysis/health/recovery.ts";
|
|
11
13
|
import { mergeDiagnosticEvidence } from "../diagnostics/evidence.ts";
|
|
12
14
|
import { refreshFileLspMaintenance, refreshLspMaintenance } from "../substrate/lsp/maintenance.ts";
|
|
15
|
+
import type { LspMaintenanceState } from "../substrate/lsp/source-tracking.ts";
|
|
13
16
|
import type {
|
|
14
17
|
HealthDiagnosticScope,
|
|
15
18
|
HealthFileReadiness,
|
|
@@ -21,13 +24,17 @@ interface HealthRefreshAttemptOptions {
|
|
|
21
24
|
readonly diagnosticsScope: HealthDiagnosticScope;
|
|
22
25
|
readonly attemptedAt: number;
|
|
23
26
|
readonly cwd: string;
|
|
24
|
-
readonly
|
|
27
|
+
readonly maintenanceState: LspMaintenanceState;
|
|
25
28
|
readonly control?: CodeRequestControl;
|
|
26
29
|
readonly reportRecoveryProgress?: () => void;
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export interface HealthRefreshCollection {
|
|
30
33
|
readonly attempt: HealthRefreshAttempt;
|
|
34
|
+
/** File readiness observed by the same explicit refresh call. */
|
|
35
|
+
readonly fileReadiness?: SemanticReadinessResult;
|
|
36
|
+
/** Next typed maintenance state, committed only after the attempt returns. */
|
|
37
|
+
readonly maintenanceState: LspMaintenanceState;
|
|
31
38
|
/** Final report from the runtime, retained only for the current workflow. */
|
|
32
39
|
readonly diagnosticReport?: WorkspaceDiagnosticReport;
|
|
33
40
|
}
|
|
@@ -49,19 +56,20 @@ async function collectFileRefreshAttempt(
|
|
|
49
56
|
const maintenance = await refreshFileLspMaintenance({
|
|
50
57
|
runtime: options.runtime,
|
|
51
58
|
cwd: options.cwd,
|
|
52
|
-
|
|
59
|
+
maintenanceState: options.maintenanceState,
|
|
53
60
|
filePath: scope.path,
|
|
54
61
|
control: options.control,
|
|
55
62
|
});
|
|
56
|
-
updateSentinelSnapshot(options.sentinelSnapshot, maintenance.snapshot);
|
|
57
63
|
const readiness = await options.runtime.waitUntilReadyForFile(
|
|
58
64
|
scope.path,
|
|
59
|
-
|
|
65
|
+
{ retryFailedRoute: true },
|
|
60
66
|
options.control,
|
|
61
67
|
);
|
|
62
68
|
const fileReadiness: HealthFileReadiness =
|
|
63
69
|
readiness.kind === "ready" ? "ready" : readiness.kind === "timeout" ? "pending" : "unavailable";
|
|
64
70
|
return {
|
|
71
|
+
fileReadiness: readiness,
|
|
72
|
+
maintenanceState: maintenance.maintenanceState,
|
|
65
73
|
attempt: {
|
|
66
74
|
kind: "completed",
|
|
67
75
|
attemptedAt: options.attemptedAt,
|
|
@@ -72,6 +80,7 @@ async function collectFileRefreshAttempt(
|
|
|
72
80
|
fileReadiness,
|
|
73
81
|
restartedClients: 0,
|
|
74
82
|
processCrashRecovery: readiness.processCrashRecovery ?? emptyProcessCrashRecoveryReport(),
|
|
83
|
+
startupRetry: readiness.startupRetry ?? emptyStartupRetryReport(),
|
|
75
84
|
staleAssessment: {
|
|
76
85
|
scope: "file",
|
|
77
86
|
suspected: null,
|
|
@@ -90,16 +99,16 @@ async function collectWorkspaceRefreshAttempt(
|
|
|
90
99
|
const maintenance = await refreshLspMaintenance(
|
|
91
100
|
options.runtime,
|
|
92
101
|
options.cwd,
|
|
93
|
-
options.
|
|
102
|
+
options.maintenanceState,
|
|
94
103
|
{
|
|
95
104
|
control: options.control,
|
|
96
105
|
scope: workspaceScope?.filter ?? null,
|
|
97
106
|
trackSources: workspaceScope !== null,
|
|
98
107
|
},
|
|
99
108
|
);
|
|
100
|
-
updateSentinelSnapshot(options.sentinelSnapshot, maintenance.snapshot);
|
|
101
109
|
if (maintenance.failureReason) {
|
|
102
110
|
return {
|
|
111
|
+
maintenanceState: maintenance.maintenanceState,
|
|
103
112
|
attempt: {
|
|
104
113
|
kind: "failed",
|
|
105
114
|
attemptedAt: options.attemptedAt,
|
|
@@ -108,6 +117,8 @@ async function collectWorkspaceRefreshAttempt(
|
|
|
108
117
|
operationScope: "workspace-runtime",
|
|
109
118
|
diagnosticEvidence: maintenance.diagnosticEvidence,
|
|
110
119
|
processCrashRecovery: emptyProcessCrashRecoveryReport(),
|
|
120
|
+
startupRetry: emptyStartupRetryReport(),
|
|
121
|
+
...(maintenance.sourceTracking ? { sourceTracking: maintenance.sourceTracking } : {}),
|
|
111
122
|
reason: maintenance.failureReason,
|
|
112
123
|
},
|
|
113
124
|
};
|
|
@@ -123,6 +134,7 @@ async function collectWorkspaceRefreshAttempt(
|
|
|
123
134
|
// runtime then performs a fresh pass that includes the replacement.
|
|
124
135
|
initialEvidence: maintenance.diagnosticEvidence,
|
|
125
136
|
processCrashDemand: {
|
|
137
|
+
explicit: true,
|
|
126
138
|
...(workspaceScope?.filter ? { scopes: [workspaceScope.filter] } : {}),
|
|
127
139
|
},
|
|
128
140
|
});
|
|
@@ -133,6 +145,7 @@ async function collectWorkspaceRefreshAttempt(
|
|
|
133
145
|
);
|
|
134
146
|
if (recovery.refreshFailureReason) {
|
|
135
147
|
return {
|
|
148
|
+
maintenanceState: maintenance.maintenanceState,
|
|
136
149
|
attempt: {
|
|
137
150
|
kind: "failed",
|
|
138
151
|
attemptedAt: options.attemptedAt,
|
|
@@ -149,12 +162,15 @@ async function collectWorkspaceRefreshAttempt(
|
|
|
149
162
|
},
|
|
150
163
|
diagnosticEvidence,
|
|
151
164
|
processCrashRecovery: recovery.processCrashRecovery,
|
|
165
|
+
startupRetry: recovery.startupRetry,
|
|
166
|
+
...(maintenance.sourceTracking ? { sourceTracking: maintenance.sourceTracking } : {}),
|
|
152
167
|
reason: recovery.refreshFailureReason,
|
|
153
168
|
},
|
|
154
169
|
diagnosticReport: recovery.diagnosticReport,
|
|
155
170
|
};
|
|
156
171
|
}
|
|
157
172
|
return {
|
|
173
|
+
maintenanceState: maintenance.maintenanceState,
|
|
158
174
|
attempt: {
|
|
159
175
|
kind: "completed",
|
|
160
176
|
attemptedAt: options.attemptedAt,
|
|
@@ -164,7 +180,9 @@ async function collectWorkspaceRefreshAttempt(
|
|
|
164
180
|
attemptedActiveClients: recovery.attemptedClients,
|
|
165
181
|
restartedClients: recovery.restartedClients,
|
|
166
182
|
processCrashRecovery: recovery.processCrashRecovery,
|
|
183
|
+
startupRetry: recovery.startupRetry,
|
|
167
184
|
diagnosticEvidence,
|
|
185
|
+
...(maintenance.sourceTracking ? { sourceTracking: maintenance.sourceTracking } : {}),
|
|
168
186
|
staleAssessment: {
|
|
169
187
|
scope: "workspace",
|
|
170
188
|
suspected: recovery.staleAssessment.suspected,
|
|
@@ -179,6 +197,7 @@ async function collectWorkspaceRefreshAttempt(
|
|
|
179
197
|
// recorded failed attempt.
|
|
180
198
|
if (isCodeRequestInterruption(error, options.control)) throw error;
|
|
181
199
|
return {
|
|
200
|
+
maintenanceState: maintenance.maintenanceState,
|
|
182
201
|
attempt: {
|
|
183
202
|
kind: "failed",
|
|
184
203
|
attemptedAt: options.attemptedAt,
|
|
@@ -187,17 +206,14 @@ async function collectWorkspaceRefreshAttempt(
|
|
|
187
206
|
operationScope: "workspace-runtime",
|
|
188
207
|
diagnosticEvidence: maintenance.diagnosticEvidence,
|
|
189
208
|
processCrashRecovery: emptyProcessCrashRecoveryReport(),
|
|
209
|
+
startupRetry: emptyStartupRetryReport(),
|
|
210
|
+
...(maintenance.sourceTracking ? { sourceTracking: maintenance.sourceTracking } : {}),
|
|
190
211
|
reason: errorMessage(error),
|
|
191
212
|
},
|
|
192
213
|
};
|
|
193
214
|
}
|
|
194
215
|
}
|
|
195
216
|
|
|
196
|
-
function updateSentinelSnapshot(target: Map<string, number>, next: Map<string, number>): void {
|
|
197
|
-
target.clear();
|
|
198
|
-
for (const [key, value] of next) target.set(key, value);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
217
|
function errorMessage(error: unknown): string {
|
|
202
218
|
return error instanceof Error && error.message ? error.message : "Diagnostic refresh failed.";
|
|
203
219
|
}
|
|
@@ -4,8 +4,10 @@ import type {
|
|
|
4
4
|
ProcessCrashRecoveryReport,
|
|
5
5
|
ProjectServerInfo,
|
|
6
6
|
ProjectServerStatusReason,
|
|
7
|
+
StartupRetryReport,
|
|
7
8
|
} from "@mrclrchtr/supi-lsp/api";
|
|
8
9
|
import type { CapabilityWarningReport } from "../analysis/capability/capability-warnings.ts";
|
|
10
|
+
import type { SourceTrackingReport } from "../substrate/lsp/source-tracking.ts";
|
|
9
11
|
|
|
10
12
|
export type HealthSection = "diagnostics" | "servers";
|
|
11
13
|
|
|
@@ -62,7 +64,7 @@ export type HealthDiagnosticObservation =
|
|
|
62
64
|
readonly scope: HealthDiagnosticScope;
|
|
63
65
|
readonly entries: readonly HealthDiagnosticEntry[];
|
|
64
66
|
readonly evidence: DiagnosticEvidenceSummary;
|
|
65
|
-
/** Tsconfig scope decision for
|
|
67
|
+
/** Tsconfig scope decision for an applicable TypeScript or JavaScript file. */
|
|
66
68
|
readonly scopeStatus?: FileScopeDecision;
|
|
67
69
|
}
|
|
68
70
|
| {
|
|
@@ -71,7 +73,7 @@ export type HealthDiagnosticObservation =
|
|
|
71
73
|
readonly entries: readonly HealthDiagnosticEntry[];
|
|
72
74
|
readonly evidence: DiagnosticEvidenceSummary;
|
|
73
75
|
readonly reason: string;
|
|
74
|
-
/** Tsconfig scope decision for
|
|
76
|
+
/** Tsconfig scope decision for an applicable TypeScript or JavaScript file. */
|
|
75
77
|
readonly scopeStatus?: FileScopeDecision;
|
|
76
78
|
}
|
|
77
79
|
| {
|
|
@@ -80,7 +82,7 @@ export type HealthDiagnosticObservation =
|
|
|
80
82
|
readonly entries: readonly HealthDiagnosticEntry[];
|
|
81
83
|
readonly evidence: DiagnosticEvidenceSummary;
|
|
82
84
|
readonly reason: string;
|
|
83
|
-
/** Tsconfig scope decision for
|
|
85
|
+
/** Tsconfig scope decision for an applicable TypeScript or JavaScript file. */
|
|
84
86
|
readonly scopeStatus?: FileScopeDecision;
|
|
85
87
|
};
|
|
86
88
|
|
|
@@ -92,6 +94,7 @@ export interface HealthStaleAssessment {
|
|
|
92
94
|
readonly warning: string | null;
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
/** Runtime scope of maintenance; it is not the diagnostic result scope. */
|
|
95
98
|
export type HealthRefreshOperationScope = "file-runtime" | "workspace-runtime";
|
|
96
99
|
|
|
97
100
|
/** Readiness result for a file-scoped maintenance attempt. */
|
|
@@ -113,10 +116,17 @@ interface CompletedHealthRefreshAttempt {
|
|
|
113
116
|
readonly restartedClients: number;
|
|
114
117
|
/** Separate outcome for process-crash route recovery. */
|
|
115
118
|
readonly processCrashRecovery: ProcessCrashRecoveryReport;
|
|
119
|
+
/** Separate outcome for initial-start retries. */
|
|
120
|
+
readonly startupRetry?: StartupRetryReport;
|
|
116
121
|
readonly staleAssessment: HealthStaleAssessment;
|
|
122
|
+
/**
|
|
123
|
+
* Source discovery and bounded tracking facts for broad refreshes. The
|
|
124
|
+
* report's skipped list describes automatic tracking policy, not capability.
|
|
125
|
+
*/
|
|
126
|
+
readonly sourceTracking?: SourceTrackingReport;
|
|
117
127
|
}
|
|
118
128
|
|
|
119
|
-
/** A diagnostic refresh attempt
|
|
129
|
+
/** A diagnostic refresh attempt with separate maintenance and result scopes. */
|
|
120
130
|
export type HealthRefreshAttempt =
|
|
121
131
|
| (CompletedHealthRefreshAttempt & {
|
|
122
132
|
readonly operationScope: "workspace-runtime";
|
|
@@ -144,6 +154,13 @@ export type HealthRefreshAttempt =
|
|
|
144
154
|
readonly diagnosticEvidence?: DiagnosticEvidenceSummary;
|
|
145
155
|
/** Process-crash outcome, when the recovery pass returned one. */
|
|
146
156
|
readonly processCrashRecovery?: ProcessCrashRecoveryReport;
|
|
157
|
+
/** Initial-start retry outcome, when the recovery pass returned one. */
|
|
158
|
+
readonly startupRetry?: StartupRetryReport;
|
|
159
|
+
/**
|
|
160
|
+
* Source discovery and bounded tracking facts for broad refreshes. The
|
|
161
|
+
* report's skipped list describes automatic tracking policy, not capability.
|
|
162
|
+
*/
|
|
163
|
+
readonly sourceTracking?: SourceTrackingReport;
|
|
147
164
|
/** File readiness outcome, when a file-scoped attempt failed. */
|
|
148
165
|
readonly fileReadiness?: HealthFileReadiness;
|
|
149
166
|
readonly reason: string;
|