@mrclrchtr/supi-code-intelligence 6.0.0 → 6.1.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.
Files changed (71) hide show
  1. package/README.md +3 -1
  2. package/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  3. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  4. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +5 -0
  5. package/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  6. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  7. package/node_modules/@mrclrchtr/supi-lsp/README.md +7 -1
  8. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  9. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  10. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +5 -0
  11. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  12. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  13. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-jsonrpc/package.json +1 -1
  14. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.colorProvider.d.ts +1 -1
  15. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.d.ts +2 -2
  16. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.fileOperations.d.ts +9 -9
  17. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/package.json +3 -3
  18. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/esm/main.d.ts +2 -2
  19. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/esm/main.js +1 -1
  20. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/umd/main.d.ts +2 -2
  21. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/umd/main.js +1 -1
  22. package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/package.json +1 -1
  23. package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
  24. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +2 -0
  25. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +6 -0
  26. package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +8 -0
  27. package/node_modules/@mrclrchtr/supi-lsp/src/config/types.ts +1 -0
  28. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +6 -3
  29. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +582 -26
  30. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +2 -3
  31. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +10 -0
  32. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +36 -9
  33. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +2 -0
  34. package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +4 -2
  35. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +2 -0
  36. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  37. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  38. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +5 -0
  39. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  40. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  41. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
  42. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +4 -4
  43. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +1 -1
  44. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
  45. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +4 -4
  46. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
  47. package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/kotlin/tree-sitter-kotlin.wasm.json +1 -1
  48. package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/sql/tree-sitter-sql.wasm.json +1 -1
  49. package/package.json +5 -5
  50. package/src/analysis/health/recovery.ts +4 -0
  51. package/src/analysis/health/server-status.ts +64 -0
  52. package/src/analysis/health/signals.ts +1 -0
  53. package/src/analysis/provider.ts +2 -1
  54. package/src/analysis/target/symbol.ts +28 -16
  55. package/src/analysis/target/types.ts +1 -0
  56. package/src/session/find-workflow.ts +5 -12
  57. package/src/session/health-refresh.ts +6 -2
  58. package/src/session/health-types.ts +8 -2
  59. package/src/session/health-workflow.ts +5 -1
  60. package/src/session/semantic-demand.ts +36 -0
  61. package/src/session/target-workflow.ts +9 -12
  62. package/src/tool/code_health/guidance.ts +2 -2
  63. package/src/tool/code_health/markdown.ts +15 -3
  64. package/src/tool/code_health/result.ts +14 -5
  65. package/src/tool/code_health/spec.ts +2 -1
  66. package/src/tool/code_health/tui.ts +24 -3
  67. package/src/tool/result/errors.ts +1 -0
  68. package/src/tool/result/types.ts +6 -0
  69. package/src/ui/footer.ts +7 -5
  70. package/src/ui/status-command.ts +31 -0
  71. package/src/ui/status-overlay.ts +69 -23
@@ -251,5 +251,11 @@ export interface HealthDetails {
251
251
  capabilityWarnings: CapabilityWarningReport | null;
252
252
  diagnosticFileCount: number;
253
253
  serverCount: number;
254
+ /** Workspace-wide non-running LSP route counts, separate from semantic readiness. */
255
+ serverRouteStatusCounts: {
256
+ recovering: number;
257
+ error: number;
258
+ unavailable: number;
259
+ };
254
260
  evidenceLists?: EvidenceListMetadata[];
255
261
  }
package/src/ui/footer.ts CHANGED
@@ -8,6 +8,7 @@
8
8
 
9
9
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
10
10
  import { footerContributions } from "@mrclrchtr/supi-core/footer-registry";
11
+ import { countProjectServerRouteStatuses } from "../analysis/health/server-status.ts";
11
12
  import { LSP_STATE_CHANGE_EVENT, type LspAdapterState } from "../substrate/lsp/state.ts";
12
13
 
13
14
  /** Build the LSP status text: "λ lsp • 3 ✓ • 1 ⟳ • 1 ✗ • 2 open files" */
@@ -22,17 +23,18 @@ export function buildLspStatusText(lspState: LspAdapterState): string | undefine
22
23
  // Aggregate server states
23
24
  const ready = servers.filter((s) => s.status === "running" && s.ready).length;
24
25
  const starting = servers.filter((s) => s.status === "running" && !s.ready).length;
25
- const error = servers.filter((s) => s.status === "error").length;
26
- const unavailable = servers.filter((s) => s.status === "unavailable").length;
26
+ const routeCounts = countProjectServerRouteStatuses(servers);
27
27
 
28
- const hasServers = ready + starting + error + unavailable > 0;
28
+ const hasServers =
29
+ ready + starting + routeCounts.recovering + routeCounts.error + routeCounts.unavailable > 0;
29
30
  if (!hasServers && openFiles === 0) return undefined;
30
31
 
31
32
  const parts = ["λ lsp"];
32
33
  if (ready > 0) parts.push(`${ready} ✓`);
33
34
  if (starting > 0) parts.push(`${starting} ⟳`);
34
- if (error > 0) parts.push(`${error} ✗`);
35
- if (unavailable > 0) parts.push(`${unavailable} ⊘`);
35
+ if (routeCounts.recovering > 0) parts.push(`${routeCounts.recovering} ↻`);
36
+ if (routeCounts.error > 0) parts.push(`${routeCounts.error} ✗`);
37
+ if (routeCounts.unavailable > 0) parts.push(`${routeCounts.unavailable} ⊘`);
36
38
  if (openFiles > 0) parts.push(`${openFiles} ${openFiles === 1 ? "open file" : "open files"}`);
37
39
  return parts.join(" • ");
38
40
  }
@@ -9,6 +9,7 @@ import {
9
9
  evaluateCapabilityWarnings,
10
10
  gatherCapabilityWarningInput,
11
11
  } from "../analysis/capability/capability-warnings.ts";
12
+ import { countProjectServerRouteStatuses } from "../analysis/health/server-status.ts";
12
13
  import { type CiStatusData, createCiStatusDialog } from "./status-overlay.ts";
13
14
 
14
15
  const STATUS_KEY = "code-intelligence";
@@ -120,6 +121,7 @@ async function gatherCiStatusData(cwd: string, pi: ExtensionAPI): Promise<CiStat
120
121
  const capabilityWarnings = evaluateCapabilityWarnings(gatherCapabilityWarningInput(cwd, null));
121
122
 
122
123
  return {
124
+ workspaceRoot: cwd,
123
125
  servers,
124
126
  diagnostics,
125
127
  serverInventoryAvailable,
@@ -202,12 +204,40 @@ function renderFooterLine(ctx: ExtensionContext, data: CiStatusData): string {
202
204
  if (totalWarnings > 0) {
203
205
  parts.push(t.fg("warning", `${totalWarnings} warning${totalWarnings === 1 ? "" : "s"}`));
204
206
  }
207
+ addProjectServerRouteCounts(parts, data, t);
205
208
  const structKind = data.capabilities.structural.kind;
206
209
  if (structKind === "ready") parts.push(t.fg("success", "✓ ts"));
207
210
  if (parts.length === 0) return t.fg("dim", "CI — no data available");
208
211
  return parts.join(t.fg("dim", " "));
209
212
  }
210
213
 
214
+ function addProjectServerRouteCounts(
215
+ parts: string[],
216
+ data: CiStatusData,
217
+ theme: ExtensionContext["ui"]["theme"],
218
+ ): void {
219
+ const counts = countProjectServerRouteStatuses(data.servers);
220
+ if (counts.recovering > 0) {
221
+ parts.push(
222
+ theme.fg(
223
+ "warning",
224
+ `${counts.recovering} route${counts.recovering === 1 ? "" : "s"} recovering`,
225
+ ),
226
+ );
227
+ }
228
+ if (counts.error > 0) {
229
+ parts.push(theme.fg("error", `${counts.error} route error${counts.error === 1 ? "" : "s"}`));
230
+ }
231
+ if (counts.unavailable > 0) {
232
+ parts.push(
233
+ theme.fg(
234
+ "warning",
235
+ `${counts.unavailable} route${counts.unavailable === 1 ? "" : "s"} unavailable`,
236
+ ),
237
+ );
238
+ }
239
+ }
240
+
211
241
  function truncateFooterLine(line: string, width: number): string {
212
242
  return truncateToWidth(line, width, "…");
213
243
  }
@@ -230,6 +260,7 @@ function updateStatusAndWidget(ctx: ExtensionContext, data: CiStatusData): void
230
260
  if (totalWarnings > 0) {
231
261
  parts.push(t.fg("warning", `${totalWarnings} warning${totalWarnings === 1 ? "" : "s"}`));
232
262
  }
263
+ addProjectServerRouteCounts(parts, data, t);
233
264
  const structKind = data.capabilities.structural.kind;
234
265
  if (structKind === "ready") parts.push(t.fg("success", "✓ ts"));
235
266
 
@@ -18,6 +18,11 @@ import type {
18
18
  ProjectServerInfo,
19
19
  } from "@mrclrchtr/supi-lsp/api";
20
20
  import type { CapabilityWarningReport } from "../analysis/capability/capability-warnings.ts";
21
+ import {
22
+ countProjectServerRouteStatuses,
23
+ formatProjectServerRoot,
24
+ formatProjectServerStatusReason,
25
+ } from "../analysis/health/server-status.ts";
21
26
  import { diagnosticMessageString } from "../substrate/lsp/utils.ts";
22
27
 
23
28
  /**
@@ -32,6 +37,8 @@ export interface CiDialogTheme {
32
37
  }
33
38
 
34
39
  export interface CiStatusData {
40
+ /** Canonical workspace root used to display LSP route roots. */
41
+ workspaceRoot: string;
35
42
  servers: ProjectServerInfo[];
36
43
  /** Whether the server list is complete status evidence. */
37
44
  serverInventoryAvailable: boolean;
@@ -263,31 +270,65 @@ export class CiStatusDialog {
263
270
  }
264
271
 
265
272
  private renderSummaryLine(width: number): string {
266
- const t = this.theme;
267
- const running = this.data.servers.filter((s) => s.status === "running").length;
268
- const totalErrors = this.data.diagnostics.reduce((sum, d) => sum + d.errors, 0);
269
- const totalWarnings = this.data.diagnostics.reduce((sum, d) => sum + d.warnings, 0);
270
- const sep = t.fg("dim", " · ");
271
-
272
- const parts: string[] = [];
273
- if (running > 0) {
274
- parts.push(t.fg("text", `${running} server${running === 1 ? "" : "s"}`));
275
- }
276
- if (totalErrors > 0) {
277
- parts.push(t.fg("error", `${totalErrors} error${totalErrors === 1 ? "" : "s"}`));
278
- }
279
- if (totalWarnings > 0) {
280
- parts.push(t.fg("warning", `${totalWarnings} warning${totalWarnings === 1 ? "" : "s"}`));
281
- }
282
- const structKind = this.data.capabilities.structural.kind;
283
- if (structKind === "ready") parts.push(t.fg("success", "✓ ts ready"));
284
- else if (structKind === "pending") parts.push(t.fg("dim", "ts pending…"));
285
- else parts.push(t.fg("error", "ts unavailable"));
286
-
287
- const joined = parts.length > 0 ? parts.join(sep) : t.fg("dim", "(no data)");
273
+ const parts = [
274
+ ...this.serverSummaryParts(),
275
+ ...this.diagnosticSummaryParts(),
276
+ ...this.routeSummaryParts(),
277
+ this.structuralSummaryPart(),
278
+ ];
279
+ const joined =
280
+ parts.length > 0
281
+ ? parts.join(this.theme.fg("dim", " · "))
282
+ : this.theme.fg("dim", "(no data)");
288
283
  return truncateToWidth(joined, width);
289
284
  }
290
285
 
286
+ private serverSummaryParts(): string[] {
287
+ const running = this.data.servers.filter((server) => server.status === "running").length;
288
+ return running > 0
289
+ ? [this.theme.fg("text", `${running} server${running === 1 ? "" : "s"}`)]
290
+ : [];
291
+ }
292
+
293
+ private diagnosticSummaryParts(): string[] {
294
+ const errors = this.data.diagnostics.reduce((sum, entry) => sum + entry.errors, 0);
295
+ const warnings = this.data.diagnostics.reduce((sum, entry) => sum + entry.warnings, 0);
296
+ return [
297
+ errors > 0 ? this.theme.fg("error", `${errors} error${errors === 1 ? "" : "s"}`) : null,
298
+ warnings > 0
299
+ ? this.theme.fg("warning", `${warnings} warning${warnings === 1 ? "" : "s"}`)
300
+ : null,
301
+ ].filter((part): part is string => part !== null);
302
+ }
303
+
304
+ private routeSummaryParts(): string[] {
305
+ const counts = countProjectServerRouteStatuses(this.data.servers);
306
+ return [
307
+ counts.recovering > 0
308
+ ? this.theme.fg(
309
+ "warning",
310
+ `${counts.recovering} route${counts.recovering === 1 ? "" : "s"} recovering`,
311
+ )
312
+ : null,
313
+ counts.error > 0
314
+ ? this.theme.fg("error", `${counts.error} route error${counts.error === 1 ? "" : "s"}`)
315
+ : null,
316
+ counts.unavailable > 0
317
+ ? this.theme.fg(
318
+ "warning",
319
+ `${counts.unavailable} route${counts.unavailable === 1 ? "" : "s"} unavailable`,
320
+ )
321
+ : null,
322
+ ].filter((part): part is string => part !== null);
323
+ }
324
+
325
+ private structuralSummaryPart(): string {
326
+ const kind = this.data.capabilities.structural.kind;
327
+ if (kind === "ready") return this.theme.fg("success", "✓ ts ready");
328
+ if (kind === "pending") return this.theme.fg("dim", "ts pending…");
329
+ return this.theme.fg("error", "ts unavailable");
330
+ }
331
+
291
332
  private addServerSection(container: Container): void {
292
333
  const t = this.theme;
293
334
  container.addChild(new Text(t.fg("accent", t.bold(" Servers")), 1, 0));
@@ -328,7 +369,7 @@ export class CiStatusDialog {
328
369
  " " +
329
370
  t.fg(statusColor, icon) +
330
371
  " " +
331
- t.fg("dim", `root: ${server.root}`),
372
+ t.fg("dim", `root: ${formatProjectServerRoot(this.data.workspaceRoot, server.root)}`),
332
373
  0,
333
374
  0,
334
375
  ),
@@ -337,6 +378,11 @@ export class CiStatusDialog {
337
378
  const fileTypes = server.fileTypes.map((f) => `.${f}`).join(" ");
338
379
  container.addChild(new Text(t.fg("dim", ` files: ${fileTypes || "(none)"}`), 0, 0));
339
380
 
381
+ const statusReason = formatProjectServerStatusReason(server.statusReason);
382
+ if (statusReason) {
383
+ container.addChild(new Text(t.fg("warning", ` ${statusReason}`), 0, 0));
384
+ }
385
+
340
386
  if (server.openFiles.length > 0) {
341
387
  const shown = server.openFiles.slice(0, MAX_OPEN_FILES_SHOWN);
342
388
  const remaining = server.openFiles.length - shown.length;