@mrclrchtr/supi-code-intelligence 6.0.1 → 6.2.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 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +5 -0
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/debug-identity.ts +11 -0
- package/node_modules/@mrclrchtr/supi-core/src/debug.ts +5 -0
- package/node_modules/@mrclrchtr/supi-lsp/README.md +26 -4
- 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/capability/types.ts +5 -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/debug-identity.ts +11 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug.ts +5 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-jsonrpc/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.colorProvider.d.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.d.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.fileOperations.d.ts +9 -9
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/esm/main.d.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/esm/main.js +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/umd/main.d.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/umd/main.js +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +14 -7
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +0 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +6 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +2 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +5 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +2 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +23 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +40 -18
- package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +164 -30
- package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +9 -87
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +8 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +4 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/config/types.ts +1 -29
- package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +7 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-severity.ts +6 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-summary.ts +11 -14
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +0 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/stale-diagnostics.ts +0 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +29 -49
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +4 -8
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-helpers.ts +1 -9
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +12 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +9 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +26 -41
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +849 -117
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +6 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +59 -28
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +27 -19
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +10 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +26 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +0 -17
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +118 -27
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +7 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/session/scanner.ts +24 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +33 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +19 -40
- package/node_modules/@mrclrchtr/supi-lsp/src/utils.ts +13 -19
- package/node_modules/@mrclrchtr/supi-lsp/src/workspace-path-policy.ts +287 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +6 -18
- 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/capability/types.ts +5 -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/debug-identity.ts +11 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug.ts +5 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/kotlin/tree-sitter-kotlin.wasm.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/sql/tree-sitter-sql.wasm.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +1 -11
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/coordinates.ts +19 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -23
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/operation-support.ts +3 -21
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +5 -9
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +10 -20
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +7 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +9 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +134 -9
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-name.ts +96 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +11 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +39 -56
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +9 -7
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/js-binding-pattern.ts +26 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +2 -21
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-html-sql.ts +144 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline.ts +50 -37
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/scope.ts +138 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +0 -7
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +1 -14
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +0 -10
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +6 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +34 -10
- package/package.json +5 -5
- package/src/analysis/capability/capability-warnings.ts +4 -22
- package/src/analysis/health/recovery.ts +4 -0
- package/src/analysis/health/server-status.ts +64 -0
- package/src/analysis/health/signals.ts +1 -0
- package/src/analysis/provider.ts +2 -1
- package/src/analysis/search/ast-scan-timing.ts +4 -2
- package/src/analysis/search/ast-scan.ts +1 -1
- package/src/analysis/target/symbol.ts +28 -16
- package/src/analysis/target/types.ts +1 -0
- package/src/api.ts +1 -0
- package/src/extension.ts +4 -2
- package/src/session/find-workflow.ts +5 -12
- package/src/session/health-refresh.ts +30 -4
- package/src/session/health-types.ts +27 -2
- package/src/session/health-workflow.ts +5 -1
- package/src/session/input/health-refactor.ts +16 -14
- package/src/session/refactor-types.ts +14 -1
- package/src/session/refactor-workflow.ts +21 -16
- package/src/session/semantic-demand.ts +36 -0
- package/src/session/target-workflow.ts +9 -12
- package/src/substrate/lsp/lifecycle.ts +0 -3
- package/src/substrate/lsp/maintenance.ts +4 -5
- package/src/substrate/lsp/settings.ts +6 -9
- package/src/substrate/lsp/state.ts +0 -2
- package/src/substrate/workspace-provider-host.ts +2 -2
- package/src/tool/code_health/file-scope-markdown.ts +43 -0
- package/src/tool/code_health/guidance.ts +2 -2
- package/src/tool/code_health/markdown.ts +81 -69
- package/src/tool/code_health/refresh-outcome.ts +46 -0
- package/src/tool/code_health/refresh-status.ts +166 -23
- package/src/tool/code_health/result.ts +15 -5
- package/src/tool/code_health/spec.ts +2 -1
- package/src/tool/code_health/tui.ts +42 -8
- package/src/tool/code_refactor_apply/guidance.ts +3 -2
- package/src/tool/code_refactor_plan/guidance.ts +1 -1
- package/src/tool/register.ts +5 -2
- package/src/tool/result/errors.ts +1 -0
- package/src/tool/result/types.ts +6 -0
- package/src/tool/schemas.ts +21 -11
- package/src/ui/footer.ts +7 -5
- package/src/ui/status-command.ts +31 -0
- package/src/ui/status-overlay.ts +69 -23
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +0 -59
- package/node_modules/@mrclrchtr/supi-lsp/src/pattern-matcher.ts +0 -24
- package/node_modules/@mrclrchtr/supi-tree-sitter/scripts/generate-kotlin-wasm.mjs +0 -132
- package/node_modules/@mrclrchtr/supi-tree-sitter/scripts/generate-sql-wasm.mjs +0 -158
- package/node_modules/@mrclrchtr/supi-tree-sitter/scripts/vendor-wasm.mjs +0 -167
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -42
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-registration.ts +0 -37
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/service-registry.ts +0 -30
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +0 -8
|
@@ -92,12 +92,14 @@ export function createLspSemanticProvider(lsp: WorkspaceLspRuntime): SemanticPro
|
|
|
92
92
|
async workspaceSymbols(
|
|
93
93
|
query: string,
|
|
94
94
|
control?: CodeRequestControl,
|
|
95
|
+
scopes?: readonly string[],
|
|
95
96
|
): Promise<CodeQueryResult<CodeSymbol[]>> {
|
|
96
|
-
const result = control
|
|
97
|
-
? await lsp.workspaceSymbol(query, control)
|
|
98
|
-
: await lsp.workspaceSymbol(query);
|
|
97
|
+
const result = await lsp.workspaceSymbol(query, control, scopes);
|
|
99
98
|
return mapCodeQueryResult(result, (results) =>
|
|
100
|
-
results.
|
|
99
|
+
results.flatMap((symbol) => {
|
|
100
|
+
const mapped = toCodeSymbol(symbol as SymbolInformation);
|
|
101
|
+
return mapped ? [mapped] : [];
|
|
102
|
+
}),
|
|
101
103
|
);
|
|
102
104
|
},
|
|
103
105
|
|
|
@@ -30,20 +30,34 @@ function toCodeLocation(item: Location | LocationLink): CodeLocation | null {
|
|
|
30
30
|
const loc = item as Record<string, unknown>;
|
|
31
31
|
const uri = loc.uri ?? loc.targetUri;
|
|
32
32
|
if (typeof uri !== "string") return null;
|
|
33
|
-
const range = loc.targetSelectionRange ?? loc.targetRange ?? loc.range;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
const range = toValidRange(loc.targetSelectionRange ?? loc.targetRange ?? loc.range);
|
|
34
|
+
return range ? { uri, range } : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function toValidRange(value: unknown): SourceRange | null {
|
|
38
|
+
if (!value || typeof value !== "object") return null;
|
|
39
|
+
const range = value as { start?: unknown; end?: unknown };
|
|
40
|
+
const start = toValidPosition(range.start);
|
|
41
|
+
const end = toValidPosition(range.end);
|
|
42
|
+
return start && end && !isPositionBefore(end, start) ? { start, end } : null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function toValidPosition(value: unknown): { line: number; character: number } | null {
|
|
46
|
+
if (!value || typeof value !== "object") return null;
|
|
47
|
+
const position = value as Record<string, unknown>;
|
|
48
|
+
return Number.isInteger(position.line) &&
|
|
49
|
+
(position.line as number) >= 0 &&
|
|
50
|
+
Number.isInteger(position.character) &&
|
|
51
|
+
(position.character as number) >= 0
|
|
52
|
+
? { line: position.line as number, character: position.character as number }
|
|
53
|
+
: null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function isPositionBefore(
|
|
57
|
+
left: { line: number; character: number },
|
|
58
|
+
right: { line: number; character: number },
|
|
59
|
+
): boolean {
|
|
60
|
+
return left.line < right.line || (left.line === right.line && left.character < right.character);
|
|
47
61
|
}
|
|
48
62
|
|
|
49
63
|
const SYMBOL_KIND_NAMES: Record<number, string> = {
|
|
@@ -102,8 +116,19 @@ function flattenDocumentSymbols(
|
|
|
102
116
|
let document: DocumentSymbol | null = null;
|
|
103
117
|
if (isSymbolInformation(sym)) information = sym;
|
|
104
118
|
else document = sym;
|
|
105
|
-
const
|
|
106
|
-
if (!
|
|
119
|
+
const declarationRange = toValidRange(document?.range ?? information?.location.range);
|
|
120
|
+
if (!declarationRange) {
|
|
121
|
+
if (document?.children?.length) {
|
|
122
|
+
result.push(
|
|
123
|
+
...flattenDocumentSymbols(document.children, filePath, sym.name, {
|
|
124
|
+
sourceLines: context.sourceLines,
|
|
125
|
+
nesting: "nested",
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const declStart = declarationRange.start;
|
|
107
132
|
const nameStart = document
|
|
108
133
|
? resolveDocumentSymbolNameStart(document, context.sourceLines)
|
|
109
134
|
: null;
|
|
@@ -149,8 +174,9 @@ function resolveDocumentSymbolNameStart(
|
|
|
149
174
|
symbol: DocumentSymbol,
|
|
150
175
|
sourceLines: readonly string[] | null,
|
|
151
176
|
): { line: number; character: number } | null {
|
|
152
|
-
const
|
|
153
|
-
if (!
|
|
177
|
+
const selectionRange = toValidRange(symbol.selectionRange);
|
|
178
|
+
if (!selectionRange) return null;
|
|
179
|
+
const selectionStart = selectionRange.start;
|
|
154
180
|
if (!sourceLines) return selectionStart;
|
|
155
181
|
const sourceLine = sourceLines[selectionStart.line];
|
|
156
182
|
if (sourceLine === undefined) return null;
|
|
@@ -160,25 +186,30 @@ function resolveDocumentSymbolNameStart(
|
|
|
160
186
|
) {
|
|
161
187
|
return selectionStart;
|
|
162
188
|
}
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
const from =
|
|
166
|
-
|
|
189
|
+
const declarationRange = toValidRange(symbol.range);
|
|
190
|
+
if (!declarationRange) return null;
|
|
191
|
+
const from =
|
|
192
|
+
declarationRange.start.line === selectionStart.line ? declarationRange.start.character : 0;
|
|
193
|
+
const until =
|
|
194
|
+
declarationRange.end.line === selectionStart.line
|
|
195
|
+
? declarationRange.end.character
|
|
196
|
+
: sourceLine.length;
|
|
167
197
|
const character = sourceLine.indexOf(symbol.name, from);
|
|
168
198
|
if (character < 0 || character + symbol.name.length > until) return null;
|
|
169
199
|
return { line: selectionStart.line, character };
|
|
170
200
|
}
|
|
171
201
|
|
|
172
|
-
/** Map one workspace symbol to the shared representation. */
|
|
173
|
-
export function toCodeSymbol(sym: SymbolInformation): CodeSymbol {
|
|
174
|
-
const
|
|
202
|
+
/** Map one valid workspace symbol to the shared representation. */
|
|
203
|
+
export function toCodeSymbol(sym: SymbolInformation): CodeSymbol | null {
|
|
204
|
+
const location = toCodeLocation(sym.location);
|
|
205
|
+
if (!location) return null;
|
|
175
206
|
return {
|
|
176
207
|
name: sym.name,
|
|
177
208
|
kind: symbolKindName(sym.kind),
|
|
178
|
-
file: uriToFile(
|
|
209
|
+
file: uriToFile(location.uri),
|
|
179
210
|
declarationAnchor: {
|
|
180
|
-
line: start
|
|
181
|
-
character: start
|
|
211
|
+
line: location.range.start.line + 1,
|
|
212
|
+
character: location.range.start.character + 1,
|
|
182
213
|
},
|
|
183
214
|
container: sym.containerName ?? null,
|
|
184
215
|
};
|
|
@@ -9,14 +9,19 @@
|
|
|
9
9
|
|
|
10
10
|
// biome-ignore lint/style/noExcessiveLinesPerFile: session lifecycle, capability projection, and telemetry stay in one controller.
|
|
11
11
|
import type { WorkspaceRuntime } from "@mrclrchtr/supi-code-runtime/api";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
recordDebugEvent,
|
|
14
|
+
truncateDebugIdentity as truncateIdentity,
|
|
15
|
+
} from "@mrclrchtr/supi-core/debug";
|
|
13
16
|
import { loadConfig } from "../config/config.ts";
|
|
14
17
|
import { type LspSettings, loadLspSettings } from "../config/lsp-settings.ts";
|
|
15
18
|
import { clearTsconfigCache } from "../config/tsconfig-scope.ts";
|
|
16
19
|
import type { DetectedProjectServer, LspConfig, ProjectServerInfo } from "../config/types.ts";
|
|
17
|
-
import { truncateIdentity } from "../debug-telemetry.ts";
|
|
18
|
-
import { scanWorkspaceSentinels } from "../diagnostics/workspace-sentinels.ts";
|
|
19
20
|
import { LspManager, type ManagerLifecycleTransition } from "../manager/manager.ts";
|
|
21
|
+
import {
|
|
22
|
+
type AutomaticLspPathPolicy,
|
|
23
|
+
createAutomaticLspPathPolicy,
|
|
24
|
+
} from "../workspace-path-policy.ts";
|
|
20
25
|
import {
|
|
21
26
|
markLspCapabilitiesReady,
|
|
22
27
|
registerPendingLspCapabilities,
|
|
@@ -58,6 +63,7 @@ interface LspControllerReady {
|
|
|
58
63
|
projectServers: ProjectServerInfo[];
|
|
59
64
|
detectedServers: DetectedProjectServer[];
|
|
60
65
|
settings: LspSettings;
|
|
66
|
+
automaticPathPolicy: AutomaticLspPathPolicy;
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
interface LspControllerDisabled {
|
|
@@ -207,7 +213,6 @@ export class LspRuntimeController {
|
|
|
207
213
|
*
|
|
208
214
|
* Always attempts detected servers unless they were explicitly disabled
|
|
209
215
|
* per language via `lsp.servers.<language>.enabled: false`.
|
|
210
|
-
* The global `lsp.enabled` and `lsp.active` keys are deprecated and ignored.
|
|
211
216
|
*
|
|
212
217
|
* Returns the start result and updates the controller's state.
|
|
213
218
|
*/
|
|
@@ -220,11 +225,6 @@ export class LspRuntimeController {
|
|
|
220
225
|
if (generation !== this.#readinessGeneration) return supersededStartResult();
|
|
221
226
|
|
|
222
227
|
const lspSettings = loadLspSettings(this.#cwd);
|
|
223
|
-
// Note: lspSettings.enabled is ignored — the global switch is deprecated.
|
|
224
|
-
// Per-language `lsp.servers.<language>.enabled: false` is the supported
|
|
225
|
-
// way to opt out and is already handled by loadConfig.
|
|
226
|
-
// lspSettings.active is also ignored — the allowlist is deprecated.
|
|
227
|
-
|
|
228
228
|
const config = loadConfig(this.#cwd);
|
|
229
229
|
|
|
230
230
|
try {
|
|
@@ -287,27 +287,35 @@ export class LspRuntimeController {
|
|
|
287
287
|
if (Object.keys(config.servers).length === 0) return this.setDisabled(generation);
|
|
288
288
|
this.#state = { kind: "pending" };
|
|
289
289
|
|
|
290
|
+
const automaticPathPolicy = createAutomaticLspPathPolicy(this.#cwd, settings.exclude);
|
|
290
291
|
let manager: LspManager;
|
|
291
|
-
manager = new LspManager(
|
|
292
|
-
|
|
293
|
-
|
|
292
|
+
manager = new LspManager(
|
|
293
|
+
config,
|
|
294
|
+
this.#cwd,
|
|
295
|
+
(transition) => {
|
|
296
|
+
this.handleManagerLifecycle(manager, generation, transition);
|
|
297
|
+
},
|
|
298
|
+
automaticPathPolicy,
|
|
299
|
+
);
|
|
294
300
|
this.#activeManager = manager;
|
|
295
301
|
this.#latestManagerTransition = null;
|
|
296
302
|
this.publishLifecycle("startup", false, []);
|
|
297
|
-
manager.setExcludePatterns(settings.exclude);
|
|
298
303
|
setWorkspaceLspRuntimeState(this.#cwd, { kind: "pending" });
|
|
299
304
|
|
|
300
|
-
const detectedServers = scanProjectCapabilities(
|
|
305
|
+
const detectedServers = scanProjectCapabilities(
|
|
306
|
+
config,
|
|
307
|
+
this.#cwd,
|
|
308
|
+
undefined,
|
|
309
|
+
automaticPathPolicy,
|
|
310
|
+
);
|
|
301
311
|
manager.registerDetectedServers(detectedServers);
|
|
302
|
-
await startDetectedServers(manager, detectedServers);
|
|
312
|
+
await startDetectedServers(manager, detectedServers, automaticPathPolicy);
|
|
303
313
|
if (generation !== this.#readinessGeneration) {
|
|
304
314
|
if (this.#activeManager === manager) this.#activeManager = null;
|
|
305
315
|
await manager.shutdownAll();
|
|
306
316
|
return supersededStartResult();
|
|
307
317
|
}
|
|
308
318
|
|
|
309
|
-
scanWorkspaceSentinels(this.#cwd);
|
|
310
|
-
|
|
311
319
|
const runtimeOwner = createWorkspaceLspRuntimeOwner(manager);
|
|
312
320
|
const workspaceRuntime = runtimeOwner.runtime;
|
|
313
321
|
setWorkspaceLspRuntimeState(this.#cwd, { kind: "ready", runtime: workspaceRuntime });
|
|
@@ -333,6 +341,7 @@ export class LspRuntimeController {
|
|
|
333
341
|
projectServers,
|
|
334
342
|
detectedServers,
|
|
335
343
|
settings,
|
|
344
|
+
automaticPathPolicy,
|
|
336
345
|
};
|
|
337
346
|
|
|
338
347
|
this.projectSemanticReadiness(workspaceRuntime, semanticReady);
|
|
@@ -397,7 +406,6 @@ export class LspRuntimeController {
|
|
|
397
406
|
projectServers: projectServers.map((server) => ({
|
|
398
407
|
...server,
|
|
399
408
|
fileTypes: [...server.fileTypes],
|
|
400
|
-
supportedActions: [...server.supportedActions],
|
|
401
409
|
openFiles: [...server.openFiles],
|
|
402
410
|
})),
|
|
403
411
|
};
|
|
@@ -452,6 +460,6 @@ export class LspRuntimeController {
|
|
|
452
460
|
getMissingServers(): Array<{ name: string; command: string }> {
|
|
453
461
|
if (this.#state.kind !== "ready") return [];
|
|
454
462
|
const config = loadConfig(this.#cwd);
|
|
455
|
-
return scanMissingServers(config, this.#cwd);
|
|
463
|
+
return scanMissingServers(config, this.#cwd, undefined, this.#state.automaticPathPolicy);
|
|
456
464
|
}
|
|
457
465
|
}
|
|
@@ -8,6 +8,14 @@ import type {
|
|
|
8
8
|
WorkspaceDiagnosticSummaryEntry,
|
|
9
9
|
} from "./runtime-diagnostics.ts";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Explicit diagnostic demand that can recover previously running crashed
|
|
13
|
+
* routes. Omitted scopes include every route with retained tracked files.
|
|
14
|
+
*/
|
|
15
|
+
export interface ProcessCrashDiagnosticDemand {
|
|
16
|
+
readonly scopes?: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
/** Diagnostic and recovery operations owned by a workspace LSP runtime. */
|
|
12
20
|
export interface WorkspaceLspDiagnosticSurface {
|
|
13
21
|
fileDiagnostics(
|
|
@@ -37,6 +45,8 @@ export interface WorkspaceLspDiagnosticSurface {
|
|
|
37
45
|
quietMs?: number;
|
|
38
46
|
/** Evidence from a refresh the caller already completed; skips this pass's own refresh when no watched-file changes apply. */
|
|
39
47
|
initialEvidence?: DiagnosticEvidenceSummary;
|
|
48
|
+
/** Explicit demand to recover crashed routes with tracked files in scope. */
|
|
49
|
+
processCrashDemand?: ProcessCrashDiagnosticDemand;
|
|
40
50
|
control?: CodeRequestControl;
|
|
41
51
|
}): Promise<RecoverDiagnosticsResult>;
|
|
42
52
|
}
|
|
@@ -45,11 +45,37 @@ export interface OutstandingDiagnosticSummaryEntry {
|
|
|
45
45
|
hints: number;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Outcome of explicit process-crash recovery demand in one diagnostic pass.
|
|
50
|
+
*
|
|
51
|
+
* Routes are counted rather than client generations because process-crash
|
|
52
|
+
* recovery owns one budget per LSP route. `attemptedRoutes` is the number of
|
|
53
|
+
* crashed routes selected by the demand; a route can be failed already or
|
|
54
|
+
* have a shared replacement in progress when the demand observes it.
|
|
55
|
+
*/
|
|
56
|
+
export interface ProcessCrashRecoverySummary {
|
|
57
|
+
attemptedRoutes: number;
|
|
58
|
+
recoveredRoutes: number;
|
|
59
|
+
failedRoutes: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Create the empty outcome for a pass with no process-crash demand. */
|
|
63
|
+
export function emptyProcessCrashRecoverySummary(): ProcessCrashRecoverySummary {
|
|
64
|
+
return {
|
|
65
|
+
attemptedRoutes: 0,
|
|
66
|
+
recoveredRoutes: 0,
|
|
67
|
+
failedRoutes: 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
48
71
|
/** Result from a workspace diagnostic recovery pass. */
|
|
49
72
|
export interface RecoverDiagnosticsResult {
|
|
50
73
|
/** Active clients targeted by the best-effort refresh, not confirmed successful refreshes. */
|
|
51
74
|
attemptedClients: number;
|
|
75
|
+
/** Clients restarted by stale-diagnostic recovery, not process-crash recovery. */
|
|
52
76
|
restartedClients: number;
|
|
77
|
+
/** Separate outcome for process-crash route recovery selected by this pass. */
|
|
78
|
+
processCrashRecovery: ProcessCrashRecoverySummary;
|
|
53
79
|
/** Evidence collected by the refresh and recovery operations. */
|
|
54
80
|
diagnosticEvidence: DiagnosticEvidenceSummary;
|
|
55
81
|
/** Final diagnostic report captured after all refresh and recovery work. */
|
|
@@ -26,23 +26,6 @@ export function registerPendingLspCapabilities(
|
|
|
26
26
|
runtime.registerSemanticPending(cwd, provider);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/**
|
|
30
|
-
* Register LSP capabilities for a workspace cwd as ready.
|
|
31
|
-
*
|
|
32
|
-
* Wraps WorkspaceLspRuntime into a SemanticProvider via the existing semantic
|
|
33
|
-
* adapter and publishes it into the shared workspace runtime so that
|
|
34
|
-
* code-intelligence and other consumers can discover semantic analysis
|
|
35
|
-
* availability.
|
|
36
|
-
*/
|
|
37
|
-
export function registerLspCapabilities(
|
|
38
|
-
runtime: WorkspaceRuntime,
|
|
39
|
-
cwd: string,
|
|
40
|
-
service: WorkspaceLspRuntime,
|
|
41
|
-
): void {
|
|
42
|
-
const provider = createLspSemanticProvider(service);
|
|
43
|
-
runtime.registerSemantic(cwd, provider);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
29
|
/** Promote an already-registered pending semantic provider to ready. */
|
|
47
30
|
export function markLspCapabilitiesReady(runtime: WorkspaceRuntime, cwd: string): void {
|
|
48
31
|
runtime.markSemanticReady(cwd);
|
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
throwIfCodeRequestInterrupted,
|
|
10
10
|
unavailableCodeQuery,
|
|
11
11
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
recordDebugEvent,
|
|
14
|
+
truncateDebugIdentity as truncateIdentity,
|
|
15
|
+
} from "@mrclrchtr/supi-core/debug";
|
|
16
|
+
import { resolveToolPath as resolveSessionPath } from "@mrclrchtr/supi-core/path";
|
|
13
17
|
import { createSessionStateRegistry } from "@mrclrchtr/supi-core/session";
|
|
14
18
|
import type {
|
|
15
19
|
CodeAction,
|
|
@@ -26,11 +30,18 @@ import type {
|
|
|
26
30
|
WorkspaceEdit,
|
|
27
31
|
WorkspaceSymbol,
|
|
28
32
|
} from "../config/types.ts";
|
|
29
|
-
import { boundServerNames
|
|
33
|
+
import { boundServerNames } from "../debug-telemetry.ts";
|
|
34
|
+
import type {
|
|
35
|
+
WorkspaceSentinelScanOptions,
|
|
36
|
+
WorkspaceSentinelSyncResult,
|
|
37
|
+
} from "../diagnostics/workspace-sentinels.ts";
|
|
30
38
|
import type { LspManager } from "../manager/manager.ts";
|
|
31
|
-
import { resolveSessionPath } from "../utils.ts";
|
|
32
39
|
import { raceReadinessValue } from "./readiness.ts";
|
|
33
|
-
import type {
|
|
40
|
+
import type {
|
|
41
|
+
DiagnosticEvidenceSummary,
|
|
42
|
+
ProcessCrashRecoverySummary,
|
|
43
|
+
RecoverDiagnosticsResult,
|
|
44
|
+
} from "./runtime-diagnostics.ts";
|
|
34
45
|
import type {
|
|
35
46
|
RoutedMutationResponse,
|
|
36
47
|
SemanticReadinessResult,
|
|
@@ -38,16 +49,21 @@ import type {
|
|
|
38
49
|
WorkspaceLspRuntimeState,
|
|
39
50
|
} from "./workspace-lsp-runtime.ts";
|
|
40
51
|
|
|
41
|
-
export type { WorkspaceLspDiagnosticSurface } from "./runtime-diagnostic-surface.ts";
|
|
42
52
|
export type {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
ProcessCrashDiagnosticDemand,
|
|
54
|
+
WorkspaceLspDiagnosticSurface,
|
|
55
|
+
} from "./runtime-diagnostic-surface.ts";
|
|
56
|
+
export {
|
|
57
|
+
type DiagnosticEvidenceDocument,
|
|
58
|
+
type DiagnosticEvidenceStatus,
|
|
59
|
+
type DiagnosticEvidenceSummary,
|
|
60
|
+
emptyProcessCrashRecoverySummary,
|
|
61
|
+
type OutstandingDiagnosticSummaryEntry,
|
|
62
|
+
type ProcessCrashRecoverySummary,
|
|
63
|
+
type RecoverDiagnosticsResult,
|
|
64
|
+
type WorkspaceDiagnosticReport,
|
|
65
|
+
type WorkspaceDiagnosticSnapshot,
|
|
66
|
+
type WorkspaceDiagnosticSummaryEntry,
|
|
51
67
|
} from "./runtime-diagnostics.ts";
|
|
52
68
|
export type {
|
|
53
69
|
RoutedMutationResponse,
|
|
@@ -64,6 +80,29 @@ function unavailableFileQuery<T>(operation: string, file: string): CodeQueryResu
|
|
|
64
80
|
return unavailableCodeQuery(`No routed LSP client could complete ${operation} for ${file}.`);
|
|
65
81
|
}
|
|
66
82
|
|
|
83
|
+
function hasProcessCrashRecovery(summary: ProcessCrashRecoverySummary): boolean {
|
|
84
|
+
return summary.attemptedRoutes > 0 || summary.recoveredRoutes > 0 || summary.failedRoutes > 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Combine the eager and current state for one readiness wait.
|
|
89
|
+
* A current failure replaces the older pending view; max avoids double-counting
|
|
90
|
+
* one route when both views describe the same recovery attempt.
|
|
91
|
+
*/
|
|
92
|
+
function mergeProcessCrashRecoverySummaries(
|
|
93
|
+
eager: ProcessCrashRecoverySummary | undefined,
|
|
94
|
+
current: ProcessCrashRecoverySummary | null,
|
|
95
|
+
): ProcessCrashRecoverySummary | undefined {
|
|
96
|
+
if (!eager) return current ?? undefined;
|
|
97
|
+
if (!current) return eager;
|
|
98
|
+
if (current.failedRoutes > 0) return current;
|
|
99
|
+
return {
|
|
100
|
+
attemptedRoutes: Math.max(eager.attemptedRoutes, current.attemptedRoutes),
|
|
101
|
+
recoveredRoutes: Math.max(eager.recoveredRoutes, current.recoveredRoutes),
|
|
102
|
+
failedRoutes: Math.max(eager.failedRoutes, current.failedRoutes),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
67
106
|
/** Emit one aggregate tsconfig scope-decision event after a recovery pass. */
|
|
68
107
|
function recordScopeDecisionEvent(manager: LspManager): void {
|
|
69
108
|
try {
|
|
@@ -107,7 +146,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
107
146
|
control?: CodeRequestControl,
|
|
108
147
|
): Promise<CodeQueryResult<Hover | null>> {
|
|
109
148
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
110
|
-
const client = await this.manager.ensureFileOpen(resolvedPath
|
|
149
|
+
const client = await this.manager.ensureFileOpen(resolvedPath, {
|
|
150
|
+
recoverProcessCrash: true,
|
|
151
|
+
control,
|
|
152
|
+
});
|
|
111
153
|
if (!client) return unavailableFileQuery("hover", resolvedPath);
|
|
112
154
|
return client.hover(resolvedPath, position, control);
|
|
113
155
|
}
|
|
@@ -118,7 +160,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
118
160
|
control?: CodeRequestControl,
|
|
119
161
|
): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>> {
|
|
120
162
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
121
|
-
const client = await this.manager.ensureFileOpen(resolvedPath
|
|
163
|
+
const client = await this.manager.ensureFileOpen(resolvedPath, {
|
|
164
|
+
recoverProcessCrash: true,
|
|
165
|
+
control,
|
|
166
|
+
});
|
|
122
167
|
if (!client) return unavailableFileQuery("definition", resolvedPath);
|
|
123
168
|
return client.definition(resolvedPath, position, control);
|
|
124
169
|
}
|
|
@@ -129,7 +174,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
129
174
|
control?: CodeRequestControl,
|
|
130
175
|
): Promise<CodeQueryResult<Location[]>> {
|
|
131
176
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
132
|
-
const client = await this.manager.ensureFileOpen(resolvedPath
|
|
177
|
+
const client = await this.manager.ensureFileOpen(resolvedPath, {
|
|
178
|
+
recoverProcessCrash: true,
|
|
179
|
+
control,
|
|
180
|
+
});
|
|
133
181
|
if (!client) return unavailableFileQuery("references", resolvedPath);
|
|
134
182
|
return mapCodeQueryResult(
|
|
135
183
|
await client.references(resolvedPath, position, control),
|
|
@@ -143,7 +191,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
143
191
|
control?: CodeRequestControl,
|
|
144
192
|
): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>> {
|
|
145
193
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
146
|
-
const client = await this.manager.ensureFileOpen(resolvedPath
|
|
194
|
+
const client = await this.manager.ensureFileOpen(resolvedPath, {
|
|
195
|
+
recoverProcessCrash: true,
|
|
196
|
+
control,
|
|
197
|
+
});
|
|
147
198
|
if (!client) return unavailableFileQuery("implementation", resolvedPath);
|
|
148
199
|
return client.implementation(resolvedPath, position, control);
|
|
149
200
|
}
|
|
@@ -153,7 +204,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
153
204
|
control?: CodeRequestControl,
|
|
154
205
|
): Promise<CodeQueryResult<DocumentSymbol[] | SymbolInformation[]>> {
|
|
155
206
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
156
|
-
const client = await this.manager.ensureFileOpen(resolvedPath
|
|
207
|
+
const client = await this.manager.ensureFileOpen(resolvedPath, {
|
|
208
|
+
recoverProcessCrash: true,
|
|
209
|
+
control,
|
|
210
|
+
});
|
|
157
211
|
if (!client) return unavailableFileQuery("document symbols", resolvedPath);
|
|
158
212
|
return mapCodeQueryResult(
|
|
159
213
|
await client.documentSymbols(resolvedPath, control),
|
|
@@ -164,8 +218,9 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
164
218
|
async workspaceSymbol(
|
|
165
219
|
query: string,
|
|
166
220
|
control?: CodeRequestControl,
|
|
221
|
+
scopes?: readonly string[],
|
|
167
222
|
): Promise<CodeQueryResult<SymbolInformation[] | WorkspaceSymbol[]>> {
|
|
168
|
-
return this.manager.workspaceSymbol(query, control);
|
|
223
|
+
return this.manager.workspaceSymbol(query, control, scopes);
|
|
169
224
|
}
|
|
170
225
|
|
|
171
226
|
async rename(
|
|
@@ -175,7 +230,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
175
230
|
control?: CodeRequestControl,
|
|
176
231
|
): Promise<RoutedMutationResponse<WorkspaceEdit | null> | null> {
|
|
177
232
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
178
|
-
const client = await this.manager.ensureFileOpen(resolvedPath
|
|
233
|
+
const client = await this.manager.ensureFileOpen(resolvedPath, {
|
|
234
|
+
recoverProcessCrash: true,
|
|
235
|
+
control,
|
|
236
|
+
});
|
|
179
237
|
if (!client) return null;
|
|
180
238
|
return {
|
|
181
239
|
value: await client.rename(resolvedPath, position, newName, control),
|
|
@@ -193,7 +251,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
193
251
|
control?: CodeRequestControl,
|
|
194
252
|
): Promise<RoutedMutationResponse<CodeAction[] | null> | null> {
|
|
195
253
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
196
|
-
const client = await this.manager.ensureFileOpen(resolvedPath
|
|
254
|
+
const client = await this.manager.ensureFileOpen(resolvedPath, {
|
|
255
|
+
recoverProcessCrash: true,
|
|
256
|
+
control,
|
|
257
|
+
});
|
|
197
258
|
if (!client) return null;
|
|
198
259
|
|
|
199
260
|
const range = isRange(positionOrRange)
|
|
@@ -221,25 +282,39 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
221
282
|
): Promise<SemanticReadinessResult> {
|
|
222
283
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
223
284
|
if (!this.manager.canServeFile(resolvedPath)) {
|
|
285
|
+
const processCrashRecovery = this.manager.getProcessCrashRecoverySummaryForFile(resolvedPath);
|
|
224
286
|
return {
|
|
225
287
|
kind: "unavailable",
|
|
226
288
|
reason: "No LSP client can serve this file",
|
|
289
|
+
...(processCrashRecovery ? { processCrashRecovery } : {}),
|
|
227
290
|
};
|
|
228
291
|
}
|
|
229
292
|
|
|
293
|
+
let eagerProcessCrashRecovery: ProcessCrashRecoverySummary | undefined;
|
|
230
294
|
const readiness = await raceReadinessValue(
|
|
231
|
-
this.manager.waitUntilFileReady(resolvedPath, control)
|
|
295
|
+
this.manager.waitUntilFileReady(resolvedPath, control, (summary) => {
|
|
296
|
+
eagerProcessCrashRecovery = summary;
|
|
297
|
+
}),
|
|
232
298
|
options.timeoutMs,
|
|
233
299
|
control,
|
|
234
300
|
);
|
|
235
|
-
if (readiness.kind !== "resolved")
|
|
236
|
-
|
|
301
|
+
if (readiness.kind !== "resolved") {
|
|
302
|
+
const processCrashRecovery = mergeProcessCrashRecoverySummaries(
|
|
303
|
+
eagerProcessCrashRecovery,
|
|
304
|
+
this.manager.getProcessCrashRecoverySummaryForFile(resolvedPath),
|
|
305
|
+
);
|
|
306
|
+
return processCrashRecovery ? { ...readiness, processCrashRecovery } : readiness;
|
|
307
|
+
}
|
|
308
|
+
const { client, processCrashRecovery } = readiness.value;
|
|
309
|
+
const recovery = hasProcessCrashRecovery(processCrashRecovery) ? { processCrashRecovery } : {};
|
|
310
|
+
if (!client) {
|
|
237
311
|
return {
|
|
238
312
|
kind: "unavailable",
|
|
239
313
|
reason: "The routed LSP client could not be started for this file",
|
|
314
|
+
...recovery,
|
|
240
315
|
};
|
|
241
316
|
}
|
|
242
|
-
return { kind: "ready" };
|
|
317
|
+
return { kind: "ready", ...recovery };
|
|
243
318
|
}
|
|
244
319
|
|
|
245
320
|
/**
|
|
@@ -269,9 +344,22 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
269
344
|
return this.manager.getKnownProjectServers([]);
|
|
270
345
|
}
|
|
271
346
|
|
|
272
|
-
/** Check whether
|
|
347
|
+
/** Check whether automatic LSP work can use and serve the source file. */
|
|
273
348
|
isSupportedSourceFile(filePath: string): boolean {
|
|
274
|
-
return this.manager.
|
|
349
|
+
return this.manager.isSupportedSourceFile(this.resolveFilePath(filePath));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** Inventory automatic workspace sentinel and source paths. */
|
|
353
|
+
scanWorkspaceSentinels(options: WorkspaceSentinelScanOptions = {}): Map<string, number> {
|
|
354
|
+
return this.manager.scanWorkspaceSentinels(options);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/** Refresh the automatic workspace sentinel and source inventory. */
|
|
358
|
+
syncWorkspaceSentinelSnapshot(
|
|
359
|
+
previous: Map<string, number>,
|
|
360
|
+
options: WorkspaceSentinelScanOptions = {},
|
|
361
|
+
): WorkspaceSentinelSyncResult {
|
|
362
|
+
return this.manager.syncWorkspaceSentinelSnapshot(previous, options);
|
|
275
363
|
}
|
|
276
364
|
|
|
277
365
|
/** Track a file in its routed client without exposing that client. */
|
|
@@ -345,6 +433,8 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
345
433
|
quietMs?: number;
|
|
346
434
|
/** Evidence from a refresh the caller already completed; skips this pass's own refresh when no watched-file changes apply. */
|
|
347
435
|
initialEvidence?: DiagnosticEvidenceSummary;
|
|
436
|
+
/** Explicit demand to recover crashed routes with tracked files in scope. */
|
|
437
|
+
processCrashDemand?: import("./runtime-diagnostic-surface.ts").ProcessCrashDiagnosticDemand;
|
|
348
438
|
control?: CodeRequestControl;
|
|
349
439
|
}): Promise<RecoverDiagnosticsResult> {
|
|
350
440
|
const recoveryStartedAt = Date.now();
|
|
@@ -362,6 +452,7 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
362
452
|
elapsedMs: result.elapsedMs,
|
|
363
453
|
attemptedClients: result.attemptedClients,
|
|
364
454
|
restartedClients: result.restartedClients,
|
|
455
|
+
processCrashRecovery: result.processCrashRecovery,
|
|
365
456
|
attemptedServers: boundServerNames(result.attemptedServers ?? []),
|
|
366
457
|
restartedServers: boundServerNames(result.restartedServers ?? []),
|
|
367
458
|
...(result.restartReason ? { reason: result.restartReason } : {}),
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
recordDebugEvent,
|
|
3
|
+
truncateDebugIdentity as truncateIdentity,
|
|
4
|
+
} from "@mrclrchtr/supi-core/debug";
|
|
2
5
|
import type { ProjectServerInfo } from "../config/types.ts";
|
|
3
|
-
import { MAX_SERVERS
|
|
6
|
+
import { MAX_SERVERS } from "../debug-telemetry.ts";
|
|
4
7
|
import type { LspRuntimeTransition } from "./runtime-controller.ts";
|
|
5
8
|
|
|
6
9
|
/** One bounded server entry in a runtime-transition payload. */
|
|
@@ -8,6 +11,7 @@ export interface TransitionServerEntry {
|
|
|
8
11
|
readonly name: string;
|
|
9
12
|
readonly status: ProjectServerInfo["status"];
|
|
10
13
|
readonly ready: boolean;
|
|
14
|
+
readonly statusReason?: NonNullable<ProjectServerInfo["statusReason"]>;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
/** Bound a project-server snapshot to MAX_SERVERS name/status/ready entries. */
|
|
@@ -18,6 +22,7 @@ function boundedServerEntries(
|
|
|
18
22
|
name: truncateIdentity(server.name),
|
|
19
23
|
status: server.status,
|
|
20
24
|
ready: server.ready,
|
|
25
|
+
...(server.statusReason ? { statusReason: server.statusReason } : {}),
|
|
21
26
|
}));
|
|
22
27
|
}
|
|
23
28
|
|