@mrclrchtr/supi-lsp 3.2.0 → 4.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.
Files changed (52) hide show
  1. package/README.md +72 -62
  2. package/node_modules/@mrclrchtr/supi-code-runtime/README.md +8 -0
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -4
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +0 -4
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +3 -2
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +0 -4
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/llm.ts +0 -10
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +19 -15
  9. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  10. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +10 -1
  11. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +19 -29
  12. package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +7 -1
  13. package/node_modules/@mrclrchtr/supi-code-runtime/src/query-result.ts +42 -0
  14. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +15 -10
  15. package/node_modules/@mrclrchtr/supi-core/package.json +2 -4
  16. package/node_modules/@mrclrchtr/supi-core/src/api.ts +0 -4
  17. package/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +3 -2
  18. package/node_modules/@mrclrchtr/supi-core/src/index.ts +0 -4
  19. package/node_modules/@mrclrchtr/supi-core/src/llm.ts +0 -10
  20. package/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +19 -15
  21. package/package.json +4 -5
  22. package/src/api.ts +9 -9
  23. package/src/client/client.ts +70 -41
  24. package/src/client/transport.ts +16 -13
  25. package/src/config/config.ts +2 -2
  26. package/src/config/lsp-settings.ts +0 -2
  27. package/src/index.ts +6 -6
  28. package/src/manager/manager-diagnostics.ts +5 -95
  29. package/src/manager/manager-workspace-recovery.ts +4 -3
  30. package/src/manager/manager-workspace-symbol.ts +44 -6
  31. package/src/manager/manager.ts +47 -65
  32. package/src/provider/lsp-semantic-provider.ts +132 -79
  33. package/src/provider/refactor-planning.ts +6 -14
  34. package/src/session/readiness.ts +38 -0
  35. package/src/session/runtime-controller.ts +87 -75
  36. package/src/session/runtime-registration.ts +5 -5
  37. package/src/session/{service-registry.ts → runtime-registry.ts} +163 -71
  38. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +0 -31
  39. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/substrate-types.ts +0 -11
  40. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/types.ts +0 -2
  41. package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +0 -31
  42. package/node_modules/@mrclrchtr/supi-core/src/substrate-types.ts +0 -11
  43. package/node_modules/@mrclrchtr/supi-core/src/types.ts +0 -2
  44. package/src/diagnostics/diagnostic-augmentation.ts +0 -82
  45. package/src/diagnostics/diagnostic-context.ts +0 -116
  46. package/src/diagnostics/diagnostic-display.ts +0 -69
  47. package/src/manager/capability-index.ts +0 -24
  48. package/src/manager/client-pool.ts +0 -33
  49. package/src/manager/diagnostic-store.ts +0 -51
  50. package/src/manager/manager-stale-resync.ts +0 -47
  51. package/src/manager/recovery-coordinator.ts +0 -37
  52. package/src/manager/workspace-router.ts +0 -44
@@ -1,69 +0,0 @@
1
- import type { Diagnostic } from "../config/types.ts";
2
- import type { OutstandingDiagnosticSummaryEntry } from "../manager/manager-types.ts";
3
-
4
- export function formatDiagnosticsDisplayContent(
5
- diagnostics: OutstandingDiagnosticSummaryEntry[],
6
- detailed?: Array<{ file: string; diagnostics: Diagnostic[] }>,
7
- ): string {
8
- const totals = collectDisplayTotals(diagnostics);
9
- const summary = buildDisplaySummary(totals);
10
-
11
- if (!detailed || detailed.length === 0) return summary;
12
-
13
- const detailLines = buildDisplayDetailLines(detailed);
14
- return detailLines.length > 0 ? `${summary}\n${detailLines.join("\n")}` : summary;
15
- }
16
-
17
- function collectDisplayTotals(
18
- diagnostics: Array<{ errors: number; warnings: number; information: number; hints: number }>,
19
- ) {
20
- return diagnostics.reduce(
21
- (acc, d) => ({
22
- errors: acc.errors + d.errors,
23
- warnings: acc.warnings + d.warnings,
24
- information: acc.information + d.information,
25
- hints: acc.hints + d.hints,
26
- }),
27
- { errors: 0, warnings: 0, information: 0, hints: 0 },
28
- );
29
- }
30
-
31
- function buildDisplaySummary(totals: {
32
- errors: number;
33
- warnings: number;
34
- information: number;
35
- hints: number;
36
- }): string {
37
- const parts: string[] = [];
38
- if (totals.errors > 0) parts.push(`${totals.errors} error${totals.errors === 1 ? "" : "s"}`);
39
- if (totals.warnings > 0)
40
- parts.push(`${totals.warnings} warning${totals.warnings === 1 ? "" : "s"}`);
41
- if (totals.information > 0)
42
- parts.push(`${totals.information} info${totals.information === 1 ? "" : "s"}`);
43
- if (totals.hints > 0) parts.push(`${totals.hints} hint${totals.hints === 1 ? "" : "s"}`);
44
-
45
- return parts.length > 0
46
- ? `LSP diagnostics injected (${parts.join(", ")})`
47
- : "LSP diagnostics injected";
48
- }
49
-
50
- function buildDisplayDetailLines(
51
- detailed: Array<{
52
- file: string;
53
- diagnostics: Diagnostic[];
54
- }>,
55
- ): string[] {
56
- const lines: string[] = [];
57
- for (const entry of detailed) {
58
- for (const d of entry.diagnostics.slice(0, 3)) {
59
- const line = d.range.start.line + 1;
60
- const source = d.source ? ` ${d.source}` : "";
61
- const msg = typeof d.message === "string" ? d.message : d.message.value;
62
- lines.push(` ${entry.file} L${line}${source}: ${msg}`);
63
- }
64
- if (entry.diagnostics.length > 3) {
65
- lines.push(` +${entry.diagnostics.length - 3} more`);
66
- }
67
- }
68
- return lines;
69
- }
@@ -1,24 +0,0 @@
1
- // Capability index — indexes and queries server capabilities.
2
-
3
- import { getSupportedLspServerActions } from "../config/server-actions.ts";
4
- import type { ServerCapabilities } from "../config/types.ts";
5
- import type { LspManager } from "./manager.ts";
6
-
7
- /**
8
- * Indexes and queries what each server supports.
9
- */
10
- export interface CapabilityIndex {
11
- /** Get the list of supported LSP actions for a server's capabilities. */
12
- getSupportedActions(capabilities: ServerCapabilities | null | undefined): string[];
13
- }
14
-
15
- /**
16
- * Create a CapabilityIndex for a workspace.
17
- */
18
- export function createCapabilityIndex(_manager: LspManager): CapabilityIndex {
19
- return {
20
- getSupportedActions(capabilities) {
21
- return getSupportedLspServerActions(capabilities);
22
- },
23
- };
24
- }
@@ -1,33 +0,0 @@
1
- // Client pool — manages LSP client lifecycle (start, stop, reconnect).
2
-
3
- import type { LspManager } from "./manager.ts";
4
-
5
- /**
6
- * Manages the lifecycle of LSP client instances for a workspace.
7
- * Currently delegates to LspManager; the extraction will grow
8
- * as responsibilities are migrated from manager.ts.
9
- */
10
- export interface ClientPool {
11
- /**
12
- * Ensure a file has an active client and return it.
13
- * Returns null if no server can serve the file.
14
- */
15
- ensureFileOpen(filePath: string): ReturnType<LspManager["ensureFileOpen"]>;
16
-
17
- /** Shut down all active clients. */
18
- shutdownAll(): Promise<void>;
19
- }
20
-
21
- /**
22
- * Create a ClientPool backed by LspManager.
23
- */
24
- export function createClientPool(manager: LspManager): ClientPool {
25
- return {
26
- async ensureFileOpen(filePath: string) {
27
- return manager.ensureFileOpen(filePath);
28
- },
29
- async shutdownAll() {
30
- return manager.shutdownAll();
31
- },
32
- };
33
- }
@@ -1,51 +0,0 @@
1
- // Diagnostic store — stores, aggregates, and queries diagnostics.
2
-
3
- import type { Diagnostic } from "../config/types.ts";
4
- import type { LspManager } from "./manager.ts";
5
-
6
- /**
7
- * Stores and queries diagnostics per file.
8
- * Currently delegates to LspManager methods.
9
- */
10
- export interface DiagnosticStore {
11
- /** Get workspace diagnostic summary grouped by file. */
12
- getDiagnosticSummary(): Array<{ file: string; errors: number; warnings: number }>;
13
-
14
- /** Get outstanding diagnostics at or above severity. */
15
- getOutstandingDiagnostics(
16
- maxSeverity?: number,
17
- ): Array<{ file: string; diagnostics: Diagnostic[] }>;
18
-
19
- /** Get outstanding diagnostic summary grouped by file. */
20
- getOutstandingDiagnosticSummary(maxSeverity?: number): Array<{
21
- file: string;
22
- total: number;
23
- errors: number;
24
- warnings: number;
25
- information: number;
26
- hints: number;
27
- }>;
28
-
29
- /** Sync a file and return its diagnostics. */
30
- syncAndGetDiagnostics(filePath: string, maxSeverity?: number): Promise<Diagnostic[] | null>;
31
- }
32
-
33
- /**
34
- * Create a DiagnosticStore backed by LspManager.
35
- */
36
- export function createDiagnosticStore(manager: LspManager): DiagnosticStore {
37
- return {
38
- getDiagnosticSummary() {
39
- return manager.getDiagnosticSummary();
40
- },
41
- getOutstandingDiagnostics(maxSeverity = 1) {
42
- return manager.getOutstandingDiagnostics(maxSeverity);
43
- },
44
- getOutstandingDiagnosticSummary(maxSeverity = 1) {
45
- return manager.getOutstandingDiagnosticSummary(maxSeverity);
46
- },
47
- async syncAndGetDiagnostics(filePath: string, maxSeverity = 4) {
48
- return manager.syncFileAndGetDiagnostics(filePath, maxSeverity);
49
- },
50
- };
51
- }
@@ -1,47 +0,0 @@
1
- import * as path from "node:path";
2
- import { isLikelyStaleDiagnostic } from "../diagnostics/stale-diagnostics.ts";
3
- import type { LspManager } from "./manager.ts";
4
-
5
- /**
6
- * Force re-open files with module-resolution errors (e.g., "Cannot find module")
7
- * to trigger fresh analysis by the language server.
8
- *
9
- * The TypeScript server caches diagnostics by file content hash. When a new
10
- * file is created that resolves an existing file's import, the stale diagnostic
11
- * persists because the importing file's content hasn't changed. Re-opening the
12
- * file (didClose + didOpen) forces the server to re-resolve all imports.
13
- *
14
- * Returns true if any files were re-synced.
15
- */
16
- export async function forceResyncStaleModuleFiles(
17
- manager: LspManager,
18
- cwd: string,
19
- ): Promise<boolean> {
20
- const outstanding = manager.getOutstandingDiagnostics(1);
21
- const staleFiles: string[] = [];
22
-
23
- for (const entry of outstanding) {
24
- if (entry.diagnostics.some((d) => isLikelyStaleDiagnostic(d))) {
25
- staleFiles.push(entry.file);
26
- }
27
- }
28
-
29
- if (staleFiles.length === 0) return false;
30
-
31
- for (const file of staleFiles) {
32
- const filePath = path.resolve(cwd, file);
33
- // Close the file to clear cached diagnostics and remove from openDocs
34
- manager.closeFile(filePath);
35
- // Re-open to force the server to re-resolve imports
36
- await manager.ensureFileOpen(filePath);
37
- }
38
-
39
- // Re-sync and wait for fresh diagnostics after the re-opens
40
- try {
41
- await manager.refreshOpenDiagnostics({ quietMs: 300, maxWaitMs: 2000 });
42
- } catch {
43
- // Best-effort: don't fail the agent turn if refresh has issues
44
- }
45
-
46
- return true;
47
- }
@@ -1,37 +0,0 @@
1
- // Recovery coordinator — orchestrates stale diagnostic recovery.
2
-
3
- import type { LspManager } from "./manager.ts";
4
-
5
- /**
6
- * Orchestrates stale diagnostic detection and recovery.
7
- */
8
- export interface RecoveryCoordinator {
9
- /**
10
- * Trigger a workspace-wide diagnostics refresh.
11
- * Returns info about refreshed/restarted clients and stale assessment.
12
- */
13
- recover(options?: {
14
- restartIfStillStale?: boolean;
15
- maxWaitMs?: number;
16
- quietMs?: number;
17
- }): Promise<{
18
- refreshedClients: number;
19
- restartedClients: number;
20
- staleAssessment: {
21
- suspected: boolean;
22
- matchedFiles: Array<{ file: string; diagnostics: unknown[] }>;
23
- warning: string | null;
24
- };
25
- }>;
26
- }
27
-
28
- /**
29
- * Create a RecoveryCoordinator backed by LspManager.
30
- */
31
- export function createRecoveryCoordinator(manager: LspManager): RecoveryCoordinator {
32
- return {
33
- async recover(options) {
34
- return manager.recoverWorkspaceDiagnostics(options);
35
- },
36
- };
37
- }
@@ -1,44 +0,0 @@
1
- // Workspace router — routes files to the correct LSP client based on project root.
2
-
3
- import type { ProjectServerInfo } from "../config/server-config.ts";
4
- import type { LspManager } from "./manager.ts";
5
-
6
- /**
7
- * Routes file paths to the correct LSP client and tracks
8
- * which project roots are known.
9
- */
10
- export interface WorkspaceRouter {
11
- /** Check whether a file can be served by any active server. */
12
- canServeFile(filePath: string): boolean;
13
-
14
- /** Check whether a source file type is supported. */
15
- isSupportedSourceFile(filePath: string): boolean;
16
-
17
- /** Get known project server info. */
18
- getProjectServers(): ProjectServerInfo[];
19
-
20
- /** Register detected servers from the workspace scan. */
21
- registerDetectedServers(servers: Array<{ language: string; root: string }>): void;
22
- }
23
-
24
- /**
25
- * Create a WorkspaceRouter backed by LspManager.
26
- */
27
- export function createWorkspaceRouter(manager: LspManager): WorkspaceRouter {
28
- return {
29
- canServeFile(filePath: string) {
30
- return manager.canServeFile(filePath);
31
- },
32
- isSupportedSourceFile(filePath: string) {
33
- return manager.isSupportedSourceFile(filePath);
34
- },
35
- getProjectServers(): ProjectServerInfo[] {
36
- return manager.getKnownProjectServers([]);
37
- },
38
- registerDetectedServers(servers: Array<{ language: string; root: string }>) {
39
- manager.registerDetectedServers(
40
- servers as unknown as Parameters<typeof manager.registerDetectedServers>[0],
41
- );
42
- },
43
- };
44
- }