@mrclrchtr/supi-code-intelligence 5.0.0 → 6.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 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/README.md +34 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +12 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +67 -28
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +63 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +46 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +1 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +214 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +278 -79
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +29 -8
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +101 -19
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +19 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +49 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +73 -15
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +5 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-extends.ts +68 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-path.ts +8 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +176 -24
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +4 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +46 -10
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +4 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +65 -17
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +143 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +43 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +31 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
- package/package.json +5 -5
- package/src/analysis/health/diagnostics.ts +58 -126
- package/src/analysis/health/file-scope.ts +184 -0
- package/src/analysis/health/recovery.ts +8 -1
- package/src/analysis/readiness.ts +4 -0
- package/src/analysis/search/ast-scan.ts +4 -1
- package/src/analysis/search/pattern-analysis.ts +10 -3
- package/src/analysis/search/pattern.ts +6 -1
- package/src/config.ts +35 -1
- package/src/extension.ts +57 -14
- package/src/overview/overview-data.ts +9 -2
- package/src/overview/overview.ts +49 -30
- package/src/overview/types.ts +2 -0
- package/src/session/find-types.ts +2 -2
- package/src/session/find-workflow.ts +3 -2
- package/src/session/health-refresh.ts +76 -49
- package/src/session/health-types.ts +7 -1
- package/src/session/health-workflow.ts +35 -18
- package/src/session/input/workflows.ts +2 -2
- package/src/session/inspect-workflow.ts +2 -1
- package/src/session/orientation/collect.ts +2 -2
- package/src/session/orientation-types.ts +2 -0
- package/src/session/orientation-workflow.ts +8 -2
- package/src/session/refactor-workflow.ts +2 -1
- package/src/session/session.ts +25 -1
- package/src/substrate/lsp/maintenance.ts +105 -23
- package/src/substrate/lsp/recovery.ts +11 -5
- package/src/tool/code_find/execute.ts +23 -0
- package/src/tool/code_find/guidance.ts +8 -0
- package/src/tool/{find → code_find}/render.ts +1 -1
- package/src/tool/{result/find.ts → code_find/result.ts} +36 -11
- package/src/tool/code_find/spec.ts +37 -0
- package/src/tool/code_graph/execute.ts +24 -0
- package/src/tool/code_graph/guidance.ts +6 -0
- package/src/tool/{graph → code_graph}/markdown.ts +1 -1
- package/src/tool/{result/graph.ts → code_graph/result.ts} +69 -4
- package/src/tool/code_graph/spec.ts +39 -0
- package/src/tool/{health → code_health}/execute.ts +2 -18
- package/src/tool/code_health/guidance.ts +8 -0
- package/src/tool/{health → code_health}/markdown.ts +68 -18
- package/src/tool/{result/health.ts → code_health/result.ts} +29 -4
- package/src/tool/code_health/spec.ts +41 -0
- package/src/tool/code_inspect/execute.ts +20 -0
- package/src/tool/code_inspect/guidance.ts +6 -0
- package/src/tool/{inspect → code_inspect}/markdown.ts +1 -1
- package/src/tool/{result/inspect.ts → code_inspect/result.ts} +32 -3
- package/src/tool/code_inspect/spec.ts +25 -0
- package/src/tool/code_orientation/execute.ts +25 -0
- package/src/tool/code_orientation/guidance.ts +9 -0
- package/src/tool/{orientation → code_orientation}/markdown.ts +1 -1
- package/src/tool/{result/orientation.ts → code_orientation/result.ts} +67 -3
- package/src/tool/code_orientation/spec.ts +25 -0
- package/src/tool/code_refactor_apply/execute.ts +17 -0
- package/src/tool/code_refactor_apply/guidance.ts +5 -0
- package/src/tool/{refactor-apply/execute.ts → code_refactor_apply/result.ts} +5 -11
- package/src/tool/code_refactor_apply/spec.ts +26 -0
- package/src/tool/code_refactor_plan/execute.ts +27 -0
- package/src/tool/code_refactor_plan/guidance.ts +8 -0
- package/src/tool/{refactor-plan/execute.ts → code_refactor_plan/result.ts} +9 -22
- package/src/tool/code_refactor_plan/spec.ts +25 -0
- package/src/tool/code_resolve/execute.ts +19 -0
- package/src/tool/code_resolve/guidance.ts +8 -0
- package/src/tool/{resolve → code_resolve}/markdown.ts +1 -1
- package/src/tool/{result/resolve.ts → code_resolve/result.ts} +37 -24
- package/src/tool/code_resolve/spec.ts +25 -0
- package/src/tool/guidance.ts +71 -52
- package/src/tool/infra/truncate.ts +40 -0
- package/src/tool/{refactor-plan/markdown.ts → refactor-markdown.ts} +4 -7
- package/src/tool/register.ts +9 -97
- package/src/tool/result/refactor.ts +1 -4
- package/src/tool/schemas.ts +26 -157
- package/src/tool/specs.ts +40 -126
- package/src/tool/find/execute.ts +0 -43
- package/src/tool/graph/execute.ts +0 -82
- package/src/tool/inspect/execute.ts +0 -40
- package/src/tool/orientation/execute.ts +0 -80
- package/src/tool/resolve/execute.ts +0 -53
- /package/src/tool/{find → code_find}/ast-kinds.ts +0 -0
- /package/src/tool/{find → code_find}/markdown.ts +0 -0
- /package/src/tool/{find → code_find}/modes.ts +0 -0
- /package/src/tool/{find → code_find}/tui.ts +0 -0
- /package/src/tool/{graph → code_graph}/tui.ts +0 -0
- /package/src/tool/{health → code_health}/refresh-status.ts +0 -0
- /package/src/tool/{health → code_health}/semantic-state.ts +0 -0
- /package/src/tool/{health → code_health}/tui.ts +0 -0
- /package/src/tool/{inspect → code_inspect}/tui.ts +0 -0
- /package/src/tool/{orientation → code_orientation}/tui.ts +0 -0
- /package/src/tool/{refactor-apply → code_refactor_apply}/tui.ts +0 -0
- /package/src/tool/{refactor-plan → code_refactor_plan}/tui.ts +0 -0
- /package/src/tool/{resolve → code_resolve}/tui.ts +0 -0
|
@@ -6,8 +6,20 @@ type DiagnosticCollection = "cache" | "fallback" | "none" | "pull" | "push";
|
|
|
6
6
|
type DiagnosticFreshness = "not-observed" | "observed";
|
|
7
7
|
type DiagnosticOutcome = "completed" | "incomplete" | "skipped" | "timed-out";
|
|
8
8
|
type DiagnosticPullOutcome = "completed" | "failed" | "not-supported" | "not-used" | "timed-out";
|
|
9
|
-
type DiagnosticPushOutcome =
|
|
10
|
-
|
|
9
|
+
type DiagnosticPushOutcome =
|
|
10
|
+
| "not-used"
|
|
11
|
+
| "published"
|
|
12
|
+
| "tentative"
|
|
13
|
+
| "released"
|
|
14
|
+
| "settled"
|
|
15
|
+
| "timed-out";
|
|
16
|
+
type DiagnosticSettleOutcome =
|
|
17
|
+
| "not-used"
|
|
18
|
+
| "published"
|
|
19
|
+
| "tentative"
|
|
20
|
+
| "quiet"
|
|
21
|
+
| "released"
|
|
22
|
+
| "timed-out";
|
|
11
23
|
type DiagnosticTimingOperation = "refresh-open" | "sync-file";
|
|
12
24
|
|
|
13
25
|
/** Result of waiting for a quiet push-diagnostic window. */
|
|
@@ -17,7 +29,7 @@ export interface DiagnosticSettleResult {
|
|
|
17
29
|
}
|
|
18
30
|
|
|
19
31
|
/** Result of waiting for one file's push diagnostics. */
|
|
20
|
-
export type DiagnosticPushWaitOutcome = "published" | "released" | "timed-out";
|
|
32
|
+
export type DiagnosticPushWaitOutcome = "published" | "tentative" | "released" | "timed-out";
|
|
21
33
|
|
|
22
34
|
interface DiagnosticTimingData {
|
|
23
35
|
readonly collection: DiagnosticCollection;
|
|
@@ -134,10 +146,15 @@ export class DiagnosticObserver {
|
|
|
134
146
|
this.#timer.mark("pull");
|
|
135
147
|
}
|
|
136
148
|
|
|
137
|
-
/**
|
|
149
|
+
/**
|
|
150
|
+
* Record that the reopen-resync fallback re-opened unconfirmed documents.
|
|
151
|
+
*
|
|
152
|
+
* The mark fires when the second settle window starts, so the measured
|
|
153
|
+
* phase is the preceding first settle window, not the reopen work.
|
|
154
|
+
*/
|
|
138
155
|
reopened(count: number): void {
|
|
139
156
|
this.#reopened += count;
|
|
140
|
-
this.#timer.mark("
|
|
157
|
+
this.#timer.mark("first-settle");
|
|
141
158
|
}
|
|
142
159
|
|
|
143
160
|
pushSettled(documentCount: number, settle: DiagnosticSettleResult): void {
|
|
@@ -161,14 +178,18 @@ export class DiagnosticObserver {
|
|
|
161
178
|
}
|
|
162
179
|
|
|
163
180
|
pushWaitCompleted(documentCount: number, push: DiagnosticPushWaitOutcome): void {
|
|
164
|
-
const
|
|
181
|
+
const confirmed = push === "published";
|
|
182
|
+
// A tentative result used the full wait budget without a confirming
|
|
183
|
+
// republish. Keep its distinct push value and report the budget expiry.
|
|
184
|
+
const timedOut = push === "tentative" || push === "timed-out";
|
|
185
|
+
const observed = push === "published" || push === "tentative";
|
|
165
186
|
this.#finish(
|
|
166
187
|
{
|
|
167
188
|
collection: this.supportsPull ? "fallback" : "push",
|
|
168
189
|
documentCount,
|
|
169
190
|
fallback: this.supportsPull,
|
|
170
|
-
freshness:
|
|
171
|
-
outcome:
|
|
191
|
+
freshness: observed ? "observed" : "not-observed",
|
|
192
|
+
outcome: confirmed ? "completed" : timedOut ? "timed-out" : "incomplete",
|
|
172
193
|
pull: this.#pull,
|
|
173
194
|
push,
|
|
174
195
|
reopen: this.#reopened,
|
|
@@ -15,12 +15,17 @@ import { collectSynchronizedFileDiagnostics } from "./client-diagnostic-collecti
|
|
|
15
15
|
import {
|
|
16
16
|
type DiagnosticCacheEntry,
|
|
17
17
|
type DiagnosticSynchronization,
|
|
18
|
+
hasCurrentEvidence,
|
|
18
19
|
hasFreshPush,
|
|
19
20
|
isCurrentSynchronization,
|
|
20
21
|
isValidPublishDiagnosticsParams,
|
|
21
22
|
nextDocumentVersion,
|
|
22
23
|
} from "./client-diagnostic-evidence.ts";
|
|
23
24
|
import type { ClientDiagnosticsHost } from "./client-diagnostic-host.ts";
|
|
25
|
+
import {
|
|
26
|
+
DiagnosticPublicationTracker,
|
|
27
|
+
trackerFileIdentityFor,
|
|
28
|
+
} from "./client-diagnostic-publication.ts";
|
|
24
29
|
import {
|
|
25
30
|
pullClientDiagnosticEvidenceFromHost,
|
|
26
31
|
refreshClientOpenDiagnostics,
|
|
@@ -32,7 +37,7 @@ import {
|
|
|
32
37
|
type ClientDiagnosticSnapshot,
|
|
33
38
|
type DiagnosticEntry,
|
|
34
39
|
fingerprintDocumentContent,
|
|
35
|
-
|
|
40
|
+
hasConfirmedDiagnosticEvidence,
|
|
36
41
|
type OpenDocumentState,
|
|
37
42
|
} from "./client-document-state.ts";
|
|
38
43
|
import {
|
|
@@ -52,6 +57,8 @@ export class ClientDiagnostics {
|
|
|
52
57
|
readonly #waiters = new DiagnosticWaitRegistry();
|
|
53
58
|
readonly #versionHistory = new Map<string, number>();
|
|
54
59
|
readonly #failedUris = new Set<string>();
|
|
60
|
+
/** Bounded push-publication telemetry for one client's diagnostic state. */
|
|
61
|
+
readonly #publications: DiagnosticPublicationTracker;
|
|
55
62
|
/** Client-side sync moment per URI: unversioned pushes before it stay rejected. */
|
|
56
63
|
readonly #unversionedPushSyncMoments = new Map<string, number>();
|
|
57
64
|
/** URIs closed by a lifecycle operation: versioned pushes stay fail-closed. */
|
|
@@ -59,7 +66,12 @@ export class ClientDiagnostics {
|
|
|
59
66
|
#evidenceRevision = 0;
|
|
60
67
|
#nextSynchronizationId = 0;
|
|
61
68
|
|
|
62
|
-
constructor(private readonly host: ClientDiagnosticsHost) {
|
|
69
|
+
constructor(private readonly host: ClientDiagnosticsHost) {
|
|
70
|
+
this.#publications = new DiagnosticPublicationTracker(
|
|
71
|
+
{ server: host.server, cwd: host.cwd },
|
|
72
|
+
trackerFileIdentityFor(host.cwd),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
63
75
|
|
|
64
76
|
get openFiles(): string[] {
|
|
65
77
|
return Array.from(this.#openDocs.keys()).map(uriToFile);
|
|
@@ -105,6 +117,7 @@ export class ClientDiagnostics {
|
|
|
105
117
|
version,
|
|
106
118
|
synchronizationId: ++this.#nextSynchronizationId,
|
|
107
119
|
evidenceRevision: this.#evidenceRevision,
|
|
120
|
+
content,
|
|
108
121
|
contentFingerprint: fingerprintDocumentContent(content),
|
|
109
122
|
});
|
|
110
123
|
this.host.sendNotification("textDocument/didOpen", {
|
|
@@ -135,6 +148,7 @@ export class ClientDiagnostics {
|
|
|
135
148
|
nextVersion: () => nextDocumentVersion(this.#versionHistory, uri),
|
|
136
149
|
nextSynchronizationId: () => ++this.#nextSynchronizationId,
|
|
137
150
|
evidenceRevision: this.#evidenceRevision,
|
|
151
|
+
incrementalSync: this.host.usesIncrementalDocumentSync(),
|
|
138
152
|
waiters: this.#waiters,
|
|
139
153
|
sendNotification: (method, params) => this.host.sendNotification(method, params),
|
|
140
154
|
markUnversionedSyncMoment: () => this.#unversionedPushSyncMoments.set(uri, Date.now()),
|
|
@@ -157,7 +171,11 @@ export class ClientDiagnostics {
|
|
|
157
171
|
}
|
|
158
172
|
|
|
159
173
|
pruneMissingFiles(): string[] {
|
|
160
|
-
const uris = new Set([
|
|
174
|
+
const uris = new Set([
|
|
175
|
+
...this.#openDocs.keys(),
|
|
176
|
+
...this.#diagnosticStore.keys(),
|
|
177
|
+
...this.#failedUris,
|
|
178
|
+
]);
|
|
161
179
|
const removedFiles: string[] = [];
|
|
162
180
|
|
|
163
181
|
for (const uri of uris) {
|
|
@@ -165,7 +183,7 @@ export class ClientDiagnostics {
|
|
|
165
183
|
if (getDiagnosticFileState(filePath) !== "removed") continue;
|
|
166
184
|
|
|
167
185
|
const wasOpen = this.#openDocs.has(uri);
|
|
168
|
-
this.#failedUris.
|
|
186
|
+
this.#failedUris.delete(uri);
|
|
169
187
|
this.#unversionedPushSyncMoments.delete(uri);
|
|
170
188
|
this.#closedVersionedBarrier.add(uri);
|
|
171
189
|
clearTrackedDocumentState(this.#openDocs, this.#diagnosticStore, this.#waiters, uri);
|
|
@@ -224,23 +242,49 @@ export class ClientDiagnostics {
|
|
|
224
242
|
|
|
225
243
|
handlePublishDiagnostics(params: unknown): void {
|
|
226
244
|
if (!isValidPublishDiagnosticsParams(params)) return;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
)
|
|
237
|
-
|
|
245
|
+
const result = applyPushDiagnostics({
|
|
246
|
+
store: this.#diagnosticStore,
|
|
247
|
+
openDocuments: this.#openDocs,
|
|
248
|
+
params,
|
|
249
|
+
evidenceRevision: this.#evidenceRevision,
|
|
250
|
+
unversionedSyncMoment: this.#unversionedPushSyncMoments.get(params.uri),
|
|
251
|
+
closedVersionedBarrier: this.#closedVersionedBarrier.has(params.uri),
|
|
252
|
+
});
|
|
253
|
+
if (!result.accepted) return;
|
|
254
|
+
const entry = this.#diagnosticStore.get(params.uri);
|
|
255
|
+
if (entry?.synchronizationId !== undefined && entry.evidenceRevision !== undefined) {
|
|
256
|
+
this.#publications.record(
|
|
257
|
+
params.uri,
|
|
258
|
+
entry.synchronizationId,
|
|
259
|
+
entry.evidenceRevision,
|
|
260
|
+
entry.receivedAt,
|
|
261
|
+
);
|
|
262
|
+
if (result.promoted) {
|
|
263
|
+
this.#publications.promoted(
|
|
264
|
+
params.uri,
|
|
265
|
+
entry.synchronizationId,
|
|
266
|
+
entry.evidenceRevision,
|
|
267
|
+
entry.receivedAt,
|
|
268
|
+
);
|
|
269
|
+
}
|
|
238
270
|
}
|
|
239
271
|
this.#waiters.releaseFile(params.uri, "published");
|
|
240
272
|
this.#waiters.notifySettle();
|
|
241
273
|
}
|
|
242
274
|
async refreshOpenDiagnostics(
|
|
243
275
|
options: { maxWaitMs?: number; quietMs?: number } & CodeRequestControl = {},
|
|
276
|
+
): Promise<DiagnosticEvidenceSummary> {
|
|
277
|
+
return this.#refreshOpenDiagnostics(options, false);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Force a full document resynchronization for a server refresh request. */
|
|
281
|
+
async refreshForServerRequest(): Promise<DiagnosticEvidenceSummary> {
|
|
282
|
+
return this.#refreshOpenDiagnostics({}, true);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async #refreshOpenDiagnostics(
|
|
286
|
+
options: { maxWaitMs?: number; quietMs?: number } & CodeRequestControl,
|
|
287
|
+
forceResynchronize: boolean,
|
|
244
288
|
): Promise<DiagnosticEvidenceSummary> {
|
|
245
289
|
const requestedFiles = Array.from(
|
|
246
290
|
new Set([...this.#openDocs.keys(), ...this.#diagnosticStore.keys(), ...this.#failedUris]),
|
|
@@ -262,14 +306,26 @@ export class ClientDiagnostics {
|
|
|
262
306
|
if (document) document.evidenceRevision = -1;
|
|
263
307
|
},
|
|
264
308
|
clearFile: (uri) => {
|
|
265
|
-
this.#failedUris.
|
|
309
|
+
this.#failedUris.delete(uri);
|
|
266
310
|
this.#unversionedPushSyncMoments.delete(uri);
|
|
267
311
|
this.#closedVersionedBarrier.add(uri);
|
|
268
312
|
clearTrackedDocumentState(this.#openDocs, this.#diagnosticStore, this.#waiters, uri);
|
|
269
313
|
},
|
|
270
314
|
markUnversionedSyncMoment: (uri) => this.#unversionedPushSyncMoments.set(uri, Date.now()),
|
|
271
315
|
clearFailedFile: (uri) => this.#failedUris.delete(uri),
|
|
316
|
+
forceResynchronize,
|
|
272
317
|
options,
|
|
318
|
+
publications: {
|
|
319
|
+
emitSummary: (summaryOptions) =>
|
|
320
|
+
this.#publications.emitSummary({
|
|
321
|
+
...summaryOptions,
|
|
322
|
+
identity: {
|
|
323
|
+
server: this.host.server,
|
|
324
|
+
cwd: this.host.cwd,
|
|
325
|
+
...summaryOptions.identity,
|
|
326
|
+
},
|
|
327
|
+
}),
|
|
328
|
+
},
|
|
273
329
|
});
|
|
274
330
|
}
|
|
275
331
|
|
|
@@ -296,8 +352,9 @@ export class ClientDiagnostics {
|
|
|
296
352
|
const contentUnchanged =
|
|
297
353
|
openDocument?.contentFingerprint === fingerprintDocumentContent(content);
|
|
298
354
|
const synchronizationCurrent = openDocument?.evidenceRevision === this.#evidenceRevision;
|
|
299
|
-
|
|
300
|
-
|
|
355
|
+
// Equivalent content joins the current synchronization. Cached evidence
|
|
356
|
+
// cannot force a no-op didChange that cancels an in-flight push or pull.
|
|
357
|
+
if (!contentUnchanged || !synchronizationCurrent) {
|
|
301
358
|
synchronizeTrackedDocument({
|
|
302
359
|
uri,
|
|
303
360
|
content,
|
|
@@ -305,6 +362,7 @@ export class ClientDiagnostics {
|
|
|
305
362
|
nextVersion: () => nextDocumentVersion(this.#versionHistory, uri),
|
|
306
363
|
nextSynchronizationId: () => ++this.#nextSynchronizationId,
|
|
307
364
|
evidenceRevision: this.#evidenceRevision,
|
|
365
|
+
incrementalSync: this.host.usesIncrementalDocumentSync(),
|
|
308
366
|
waiters: this.#waiters,
|
|
309
367
|
sendNotification: (method, params) => this.host.sendNotification(method, params),
|
|
310
368
|
markUnversionedSyncMoment: () => this.#unversionedPushSyncMoments.set(uri, Date.now()),
|
|
@@ -319,7 +377,7 @@ export class ClientDiagnostics {
|
|
|
319
377
|
}
|
|
320
378
|
if (
|
|
321
379
|
contentUnchanged &&
|
|
322
|
-
|
|
380
|
+
hasConfirmedDiagnosticEvidence(synchronization, cached, this.#evidenceRevision)
|
|
323
381
|
) {
|
|
324
382
|
observer.cacheReused(1);
|
|
325
383
|
return completedCodeQuery(cachedDiagnostics ?? []);
|
|
@@ -390,6 +448,13 @@ export class ClientDiagnostics {
|
|
|
390
448
|
current: () => isCurrentSynchronization(this.#openDocs, attemptRequest),
|
|
391
449
|
freshPush: () =>
|
|
392
450
|
hasFreshPush(this.#diagnosticStore, attemptRequest, this.#evidenceRevision),
|
|
451
|
+
currentPushReceivedAt: () => {
|
|
452
|
+
const entry = this.#diagnosticStore.get(attemptRequest.uri);
|
|
453
|
+
return entry?.source === "push" &&
|
|
454
|
+
hasCurrentEvidence(this.#diagnosticStore, attemptRequest, this.#evidenceRevision)
|
|
455
|
+
? entry.receivedAt
|
|
456
|
+
: undefined;
|
|
457
|
+
},
|
|
393
458
|
diagnostics: () => this.getDiagnostics(filePath),
|
|
394
459
|
pullDiagnostics: (timeoutMs, signal) =>
|
|
395
460
|
pullClientDiagnosticEvidenceFromHost({
|
|
@@ -454,6 +519,23 @@ export class ClientDiagnostics {
|
|
|
454
519
|
attemptMaxWaitMs = REOPEN_EVIDENCE_WAIT_MS;
|
|
455
520
|
}
|
|
456
521
|
observer.pushWaitCompleted(1, pushOutcome ?? "timed-out");
|
|
522
|
+
this.#publications.emitSummary({
|
|
523
|
+
operation: "sync-file",
|
|
524
|
+
identity: {
|
|
525
|
+
server: this.host.server,
|
|
526
|
+
cwd: this.host.cwd,
|
|
527
|
+
file: relativeDiagnosticFile(this.host.cwd, filePath),
|
|
528
|
+
},
|
|
529
|
+
synchronizations: [
|
|
530
|
+
{
|
|
531
|
+
uri,
|
|
532
|
+
synchronizationId: attemptRequest.synchronizationId,
|
|
533
|
+
evidenceRevision: attemptRequest.evidenceRevision ?? this.#evidenceRevision,
|
|
534
|
+
confirmed: result.kind === "completed",
|
|
535
|
+
},
|
|
536
|
+
],
|
|
537
|
+
operationId: control?.operationId,
|
|
538
|
+
});
|
|
457
539
|
return result;
|
|
458
540
|
}
|
|
459
541
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import type { Diagnostic } from "../config/types.ts";
|
|
3
|
-
import type
|
|
3
|
+
import { type DiagnosticCacheEntry, isTentativePushEntry } from "./client-diagnostic-evidence.ts";
|
|
4
4
|
|
|
5
5
|
/** One file's stored diagnostics as consumed by manager-level collection. */
|
|
6
6
|
export interface DiagnosticEntry {
|
|
@@ -28,6 +28,8 @@ export interface OpenDocumentState {
|
|
|
28
28
|
version: number;
|
|
29
29
|
synchronizationId: number;
|
|
30
30
|
evidenceRevision: number;
|
|
31
|
+
/** Last text sent to the server. Used to form incremental changes. */
|
|
32
|
+
content: string;
|
|
31
33
|
contentFingerprint: string;
|
|
32
34
|
}
|
|
33
35
|
|
|
@@ -50,3 +52,19 @@ export function hasCurrentDiagnosticEvidence(
|
|
|
50
52
|
entry.evidenceRevision === evidenceRevision,
|
|
51
53
|
);
|
|
52
54
|
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Test whether cached diagnostics confirm the current document state.
|
|
58
|
+
*
|
|
59
|
+
* A current tentative push matches the document state but cannot support a
|
|
60
|
+
* clean-result or cache-reuse claim until a republish confirms it (ADR 0021).
|
|
61
|
+
*/
|
|
62
|
+
export function hasConfirmedDiagnosticEvidence(
|
|
63
|
+
document: OpenDocumentState | undefined,
|
|
64
|
+
entry: DiagnosticCacheEntry | undefined,
|
|
65
|
+
evidenceRevision: number,
|
|
66
|
+
): boolean {
|
|
67
|
+
return (
|
|
68
|
+
hasCurrentDiagnosticEvidence(document, entry, evidenceRevision) && !isTentativePushEntry(entry)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -14,10 +14,39 @@ interface SynchronizeDocumentOptions {
|
|
|
14
14
|
version: number;
|
|
15
15
|
synchronizationId: number;
|
|
16
16
|
evidenceRevision: number;
|
|
17
|
+
incrementalSync: boolean;
|
|
17
18
|
waiters: DiagnosticWaitRegistry;
|
|
18
19
|
sendNotification: NotificationSender;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
function endPosition(content: string): { line: number; character: number } {
|
|
23
|
+
const lines = content.split(/\r\n|\r|\n/);
|
|
24
|
+
return { line: lines.length - 1, character: lines.at(-1)?.length ?? 0 };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* For incremental sync, replace the old full range with the new text.
|
|
29
|
+
* This is a valid incremental edit and avoids a second text-diff engine.
|
|
30
|
+
*/
|
|
31
|
+
function contentChanges(
|
|
32
|
+
previousContent: string,
|
|
33
|
+
content: string,
|
|
34
|
+
incrementalSync: boolean,
|
|
35
|
+
): unknown[] {
|
|
36
|
+
if (incrementalSync) {
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
range: {
|
|
40
|
+
start: { line: 0, character: 0 },
|
|
41
|
+
end: endPosition(previousContent),
|
|
42
|
+
},
|
|
43
|
+
text: content,
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
return [{ text: content }];
|
|
48
|
+
}
|
|
49
|
+
|
|
21
50
|
/** Advance and publish one explicit document synchronization. */
|
|
22
51
|
export function synchronizeDocument(options: SynchronizeDocumentOptions): void {
|
|
23
52
|
options.waiters.releaseFile(options.uri);
|
|
@@ -25,13 +54,19 @@ export function synchronizeDocument(options: SynchronizeDocumentOptions): void {
|
|
|
25
54
|
options.document.version = options.version;
|
|
26
55
|
options.document.synchronizationId = options.synchronizationId;
|
|
27
56
|
options.document.evidenceRevision = options.evidenceRevision;
|
|
57
|
+
const changes = contentChanges(
|
|
58
|
+
options.document.content,
|
|
59
|
+
options.content,
|
|
60
|
+
options.incrementalSync,
|
|
61
|
+
);
|
|
62
|
+
options.document.content = options.content;
|
|
28
63
|
options.document.contentFingerprint = fingerprintDocumentContent(options.content);
|
|
29
64
|
options.sendNotification("textDocument/didChange", {
|
|
30
65
|
textDocument: {
|
|
31
66
|
uri: options.uri,
|
|
32
67
|
version: options.version,
|
|
33
68
|
} satisfies VersionedTextDocumentIdentifier,
|
|
34
|
-
contentChanges:
|
|
69
|
+
contentChanges: changes,
|
|
35
70
|
});
|
|
36
71
|
}
|
|
37
72
|
|
|
@@ -74,6 +109,7 @@ export function reopenDocument(options: {
|
|
|
74
109
|
options.document.version = version;
|
|
75
110
|
options.document.synchronizationId = options.nextSynchronizationId();
|
|
76
111
|
options.document.evidenceRevision = options.evidenceRevision;
|
|
112
|
+
options.document.content = options.content;
|
|
77
113
|
options.document.contentFingerprint = fingerprintDocumentContent(options.content);
|
|
78
114
|
options.sendNotification("textDocument/didOpen", {
|
|
79
115
|
textDocument: {
|
|
@@ -93,6 +129,7 @@ export function synchronizeTrackedDocument(options: {
|
|
|
93
129
|
nextVersion(): number;
|
|
94
130
|
nextSynchronizationId(): number;
|
|
95
131
|
evidenceRevision: number;
|
|
132
|
+
incrementalSync: boolean;
|
|
96
133
|
waiters: DiagnosticWaitRegistry;
|
|
97
134
|
sendNotification: NotificationSender;
|
|
98
135
|
markUnversionedSyncMoment?(): void;
|
|
@@ -111,6 +148,7 @@ export function synchronizeTrackedDocument(options: {
|
|
|
111
148
|
version: options.nextVersion(),
|
|
112
149
|
synchronizationId: options.nextSynchronizationId(),
|
|
113
150
|
evidenceRevision: options.evidenceRevision,
|
|
151
|
+
incrementalSync: options.incrementalSync,
|
|
114
152
|
waiters: options.waiters,
|
|
115
153
|
sendNotification: options.sendNotification,
|
|
116
154
|
});
|
|
@@ -123,8 +161,11 @@ interface ResynchronizeDocumentsOptions {
|
|
|
123
161
|
nextVersion(uri: string): number;
|
|
124
162
|
nextSynchronizationId(): number;
|
|
125
163
|
evidenceRevision: number;
|
|
164
|
+
incrementalSync: boolean;
|
|
126
165
|
sendNotification: NotificationSender;
|
|
127
166
|
uriToFile(uri: string): string;
|
|
167
|
+
/** Disk content already read by classification; avoids a second read. */
|
|
168
|
+
preloadedContent?: ReadonlyMap<string, string>;
|
|
128
169
|
clearFile(uri: string): void;
|
|
129
170
|
invalidateEvidence(uri: string): void;
|
|
130
171
|
markUnversionedSyncMoment(uri: string): void;
|
|
@@ -135,6 +176,8 @@ interface ResynchronizeDocumentsOptions {
|
|
|
135
176
|
export interface ResynchronizeDocumentsResult {
|
|
136
177
|
/** Documents that were synchronized and can receive fresh evidence. */
|
|
137
178
|
synchronizations: DiagnosticSynchronization[];
|
|
179
|
+
/** URIs that received a new didChange synchronization in this pass. */
|
|
180
|
+
resynchronizedUris: ReadonlySet<string>;
|
|
138
181
|
/** Existing tracked documents removed because their files no longer exist. */
|
|
139
182
|
removedFiles: string[];
|
|
140
183
|
/** Existing tracked documents that could not be read or synchronized. */
|
|
@@ -146,6 +189,7 @@ export function resynchronizeOpenDocuments(
|
|
|
146
189
|
options: ResynchronizeDocumentsOptions,
|
|
147
190
|
): ResynchronizeDocumentsResult {
|
|
148
191
|
const synchronizations: DiagnosticSynchronization[] = [];
|
|
192
|
+
const resynchronizedUris = new Set<string>();
|
|
149
193
|
const removedFiles: string[] = [];
|
|
150
194
|
const failedFiles: string[] = [];
|
|
151
195
|
for (const [uri, document] of options.openDocuments) {
|
|
@@ -154,15 +198,17 @@ export function resynchronizeOpenDocuments(
|
|
|
154
198
|
options.markUnversionedSyncMoment(uri);
|
|
155
199
|
synchronizeDocument({
|
|
156
200
|
uri,
|
|
157
|
-
content: readFileSync(filePath, "utf-8"),
|
|
201
|
+
content: options.preloadedContent?.get(uri) ?? readFileSync(filePath, "utf-8"),
|
|
158
202
|
document,
|
|
159
203
|
version: options.nextVersion(uri),
|
|
160
204
|
synchronizationId: options.nextSynchronizationId(),
|
|
161
205
|
evidenceRevision: options.evidenceRevision,
|
|
206
|
+
incrementalSync: options.incrementalSync,
|
|
162
207
|
waiters: options.waiters,
|
|
163
208
|
sendNotification: options.sendNotification,
|
|
164
209
|
});
|
|
165
210
|
options.clearFailedFile(uri);
|
|
211
|
+
resynchronizedUris.add(uri);
|
|
166
212
|
synchronizations.push({
|
|
167
213
|
uri,
|
|
168
214
|
synchronizationId: document.synchronizationId,
|
|
@@ -181,5 +227,5 @@ export function resynchronizeOpenDocuments(
|
|
|
181
227
|
// Keep the document open when a transient read fails.
|
|
182
228
|
}
|
|
183
229
|
}
|
|
184
|
-
return { synchronizations, removedFiles, failedFiles };
|
|
230
|
+
return { synchronizations, resynchronizedUris, removedFiles, failedFiles };
|
|
185
231
|
}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
unavailableCodeQuery,
|
|
14
14
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
15
15
|
import { recordDebugEvent } from "@mrclrchtr/supi-core/debug";
|
|
16
|
-
import type
|
|
16
|
+
import { type ProgressToken, TextDocumentSyncKind } from "vscode-languageserver-protocol";
|
|
17
17
|
import { CLIENT_CAPABILITIES } from "../config/capabilities.ts";
|
|
18
18
|
import type {
|
|
19
19
|
CodeAction,
|
|
@@ -198,6 +198,7 @@ export class LspClient {
|
|
|
198
198
|
cwd: cwd,
|
|
199
199
|
isOperational: () => this.rpc !== null && this._status === "running",
|
|
200
200
|
supportsPullDiagnostics: () => this.hasDiagnosticProvider,
|
|
201
|
+
usesIncrementalDocumentSync: () => this.usesIncrementalDocumentSync,
|
|
201
202
|
sendNotification: (method, params) => {
|
|
202
203
|
if (this.rpc) void this.rpc.sendNotification(method, params);
|
|
203
204
|
},
|
|
@@ -237,6 +238,13 @@ export class LspClient {
|
|
|
237
238
|
return this.capabilities;
|
|
238
239
|
}
|
|
239
240
|
|
|
241
|
+
/** Whether the server requires range-based document changes. */
|
|
242
|
+
get usesIncrementalDocumentSync(): boolean {
|
|
243
|
+
const sync = this.capabilities?.textDocumentSync;
|
|
244
|
+
const change = typeof sync === "number" ? sync : sync?.change;
|
|
245
|
+
return change === TextDocumentSyncKind.Incremental;
|
|
246
|
+
}
|
|
247
|
+
|
|
240
248
|
/** Whether the server is currently not indexing and ready to serve queries. */
|
|
241
249
|
get ready(): boolean {
|
|
242
250
|
return this._isReady;
|
|
@@ -262,7 +270,7 @@ export class LspClient {
|
|
|
262
270
|
this.process = spawn(cmd, args, {
|
|
263
271
|
cwd: this.root,
|
|
264
272
|
stdio: ["pipe", "pipe", "pipe"],
|
|
265
|
-
env: { ...process.env },
|
|
273
|
+
env: { ...process.env, ...this.config.env },
|
|
266
274
|
// Run the server in its own process group so we can atomically
|
|
267
275
|
// kill the entire tree (server + subprocesses like tsserver)
|
|
268
276
|
// with `process.kill(-pid, signal)` on Unix or `taskkill /T` on Windows.
|
|
@@ -313,6 +321,12 @@ export class LspClient {
|
|
|
313
321
|
const result = (await this.rpc.sendRequest("initialize", {
|
|
314
322
|
processId: process.pid,
|
|
315
323
|
rootUri: fileToUri(this.root),
|
|
324
|
+
workspaceFolders: [
|
|
325
|
+
{
|
|
326
|
+
uri: fileToUri(this.root),
|
|
327
|
+
name: path.basename(this.root) || this.root,
|
|
328
|
+
},
|
|
329
|
+
],
|
|
316
330
|
capabilities: CLIENT_CAPABILITIES,
|
|
317
331
|
initializationOptions: this.config.initializationOptions,
|
|
318
332
|
})) as InitializeResult;
|
|
@@ -322,7 +336,7 @@ export class LspClient {
|
|
|
322
336
|
throw new Error(`Server selected unsupported position encoding "${positionEncoding}".`);
|
|
323
337
|
}
|
|
324
338
|
this.capabilities = result.capabilities;
|
|
325
|
-
|
|
339
|
+
await this.rpc.sendNotification("initialized", {});
|
|
326
340
|
this._status = "running";
|
|
327
341
|
this.publishLifecycle("startup");
|
|
328
342
|
|
|
@@ -708,11 +722,10 @@ export class LspClient {
|
|
|
708
722
|
case "client/unregisterCapability":
|
|
709
723
|
return this.handleUnregisterCapability(params);
|
|
710
724
|
case "workspace/diagnostic/refresh":
|
|
711
|
-
//
|
|
712
|
-
//
|
|
713
|
-
//
|
|
714
|
-
|
|
715
|
-
return null;
|
|
725
|
+
// Refresh the tracked diagnostic set without blocking the server's
|
|
726
|
+
// request. The LSP response is always null; the pass records its
|
|
727
|
+
// terminal result asynchronously for local protocol diagnosis.
|
|
728
|
+
return this.handleServerDiagnosticRefreshRequest();
|
|
716
729
|
case "window/workDoneProgress/create": {
|
|
717
730
|
// A create reserves a token; it does not prove active work. The
|
|
718
731
|
// token stays pending and readiness is untouched until a begin
|
|
@@ -727,6 +740,51 @@ export class LspClient {
|
|
|
727
740
|
}
|
|
728
741
|
}
|
|
729
742
|
|
|
743
|
+
/** Run a server-requested refresh through the forced diagnostic path. */
|
|
744
|
+
private refreshForServerRequest(): Promise<DiagnosticEvidenceSummary> {
|
|
745
|
+
return this.diagnostics.refreshForServerRequest();
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
private handleServerDiagnosticRefreshRequest(): null {
|
|
749
|
+
// Defer the pass before invoking it. Its setup rereads and resynchronizes
|
|
750
|
+
// tracked documents, so even an async method can otherwise delay the null
|
|
751
|
+
// response on the JSON-RPC request stack.
|
|
752
|
+
void Promise.resolve()
|
|
753
|
+
.then(() => this.refreshForServerRequest())
|
|
754
|
+
.then(
|
|
755
|
+
(evidence) => this.recordDiagnosticRefreshRequest("completed", evidence),
|
|
756
|
+
() => this.recordDiagnosticRefreshRequest("failed"),
|
|
757
|
+
)
|
|
758
|
+
// Consume failures from the telemetry callback as well as the pass.
|
|
759
|
+
.catch(() => {});
|
|
760
|
+
return null;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
private recordDiagnosticRefreshRequest(
|
|
764
|
+
outcome: "completed" | "failed",
|
|
765
|
+
evidence?: DiagnosticEvidenceSummary,
|
|
766
|
+
): void {
|
|
767
|
+
recordDebugEvent({
|
|
768
|
+
source: "lsp",
|
|
769
|
+
level: "debug",
|
|
770
|
+
category: "diagnostics.refresh-request",
|
|
771
|
+
message: `LSP diagnostic refresh request ${outcome}`,
|
|
772
|
+
cwd: boundCwd(this.cwd),
|
|
773
|
+
data:
|
|
774
|
+
outcome === "completed" && evidence
|
|
775
|
+
? {
|
|
776
|
+
outcome,
|
|
777
|
+
server: truncateIdentity(this.name),
|
|
778
|
+
requested: evidence.requested,
|
|
779
|
+
confirmed: evidence.confirmed,
|
|
780
|
+
unconfirmed: evidence.unconfirmed,
|
|
781
|
+
failed: evidence.failed,
|
|
782
|
+
removed: evidence.removed,
|
|
783
|
+
}
|
|
784
|
+
: { outcome, server: truncateIdentity(this.name) },
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
|
|
730
788
|
private buildWorkspaceConfigurationResult(params: unknown): unknown[] {
|
|
731
789
|
if (!params || typeof params !== "object") return [];
|
|
732
790
|
const items = (params as { items?: unknown }).items;
|
|
@@ -836,7 +894,7 @@ export class LspClient {
|
|
|
836
894
|
category: "readiness.progress-begin",
|
|
837
895
|
message: `Readiness progress begin for ${this.name}`,
|
|
838
896
|
cwd: boundCwd(this.cwd),
|
|
839
|
-
data: { server: this.name, root: truncateIdentity(this.root) },
|
|
897
|
+
data: { server: truncateIdentity(this.name), root: truncateIdentity(this.root) },
|
|
840
898
|
});
|
|
841
899
|
// begin is the only transition that proves active work: it cancels
|
|
842
900
|
// the no-progress grace timer, blocks readiness, and arms the
|
|
@@ -866,7 +924,7 @@ export class LspClient {
|
|
|
866
924
|
category: "readiness.progress-end",
|
|
867
925
|
message: `Readiness progress end for ${this.name}`,
|
|
868
926
|
cwd: boundCwd(this.cwd),
|
|
869
|
-
data: { server: this.name, root: truncateIdentity(this.root) },
|
|
927
|
+
data: { server: truncateIdentity(this.name), root: truncateIdentity(this.root) },
|
|
870
928
|
});
|
|
871
929
|
const state = this.trackedTokens.get(token);
|
|
872
930
|
if (state === undefined) return; // Unknown token: ignore fail-closed.
|
|
@@ -919,7 +977,7 @@ export class LspClient {
|
|
|
919
977
|
category: "readiness.resolved",
|
|
920
978
|
message: `LSP client ${this.name} is ready`,
|
|
921
979
|
cwd: boundCwd(this.cwd),
|
|
922
|
-
data: { server: this.name, root: truncateIdentity(this.root) },
|
|
980
|
+
data: { server: truncateIdentity(this.name), root: truncateIdentity(this.root) },
|
|
923
981
|
});
|
|
924
982
|
}
|
|
925
983
|
|
|
@@ -958,7 +1016,7 @@ export class LspClient {
|
|
|
958
1016
|
message: `LSP client ${this.name} readiness rejected: ${reason.message}`,
|
|
959
1017
|
cwd: boundCwd(this.cwd),
|
|
960
1018
|
data: {
|
|
961
|
-
server: this.name,
|
|
1019
|
+
server: truncateIdentity(this.name),
|
|
962
1020
|
root: truncateIdentity(this.root),
|
|
963
1021
|
status: this._status,
|
|
964
1022
|
},
|
|
@@ -983,7 +1041,7 @@ export class LspClient {
|
|
|
983
1041
|
category: "readiness.token-timeout",
|
|
984
1042
|
message: `Readiness per-token timeout fired for ${this.name} after ${timeoutMs}ms`,
|
|
985
1043
|
cwd: boundCwd(this.cwd),
|
|
986
|
-
data: { server: this.name, root: truncateIdentity(this.root), timeoutMs },
|
|
1044
|
+
data: { server: truncateIdentity(this.name), root: truncateIdentity(this.root), timeoutMs },
|
|
987
1045
|
});
|
|
988
1046
|
this.checkAllTokensEnded();
|
|
989
1047
|
}, timeoutMs);
|
|
@@ -1010,7 +1068,7 @@ export class LspClient {
|
|
|
1010
1068
|
category: "readiness.no-progress-cancelled",
|
|
1011
1069
|
message: `No-progress grace timer cancelled for ${this.name}`,
|
|
1012
1070
|
cwd: boundCwd(this.cwd),
|
|
1013
|
-
data: { server: this.name, root: truncateIdentity(this.root) },
|
|
1071
|
+
data: { server: truncateIdentity(this.name), root: truncateIdentity(this.root) },
|
|
1014
1072
|
});
|
|
1015
1073
|
}
|
|
1016
1074
|
}
|
|
@@ -1033,7 +1091,7 @@ export class LspClient {
|
|
|
1033
1091
|
category: "readiness.no-progress-resolved",
|
|
1034
1092
|
message: `No-progress grace timer resolved for ${this.name}`,
|
|
1035
1093
|
cwd: boundCwd(this.cwd),
|
|
1036
|
-
data: { server: this.name, root: truncateIdentity(this.root) },
|
|
1094
|
+
data: { server: truncateIdentity(this.name), root: truncateIdentity(this.root) },
|
|
1037
1095
|
});
|
|
1038
1096
|
this.resolveReady();
|
|
1039
1097
|
}
|