@mrclrchtr/supi-lsp 6.1.0 → 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.
Files changed (47) hide show
  1. package/README.md +21 -3
  2. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  3. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  4. package/node_modules/@mrclrchtr/supi-core/src/debug-identity.ts +11 -0
  5. package/node_modules/@mrclrchtr/supi-core/src/debug.ts +5 -0
  6. package/package.json +4 -5
  7. package/src/api.ts +12 -7
  8. package/src/client/client-diagnostic-cache.ts +1 -1
  9. package/src/client/client-diagnostic-capabilities.ts +0 -5
  10. package/src/client/client-diagnostic-publication.ts +6 -3
  11. package/src/client/client-diagnostic-refresh.ts +2 -1
  12. package/src/client/client-diagnostic-timing.ts +5 -2
  13. package/src/client/client-diagnostics.ts +2 -1
  14. package/src/client/client.ts +17 -5
  15. package/src/client/transport.ts +40 -18
  16. package/src/config/config.ts +164 -30
  17. package/src/config/lsp-settings.ts +9 -87
  18. package/src/config/server-config.ts +0 -1
  19. package/src/config/tsconfig-scope.ts +4 -5
  20. package/src/config/types.ts +0 -29
  21. package/src/debug-telemetry.ts +7 -21
  22. package/src/diagnostics/diagnostic-severity.ts +6 -0
  23. package/src/diagnostics/diagnostic-summary.ts +11 -14
  24. package/src/diagnostics/evidence.ts +0 -5
  25. package/src/diagnostics/stale-diagnostics.ts +0 -1
  26. package/src/diagnostics/workspace-sentinels.ts +29 -49
  27. package/src/manager/manager-client-state.ts +1 -1
  28. package/src/manager/manager-diagnostics.ts +4 -8
  29. package/src/manager/manager-helpers.ts +1 -9
  30. package/src/manager/manager-project-info.ts +6 -3
  31. package/src/manager/manager-workspace-recovery.ts +9 -1
  32. package/src/manager/manager-workspace-symbol.ts +26 -41
  33. package/src/manager/manager.ts +275 -99
  34. package/src/provider/lsp-semantic-provider.ts +4 -1
  35. package/src/provider/semantic-symbol-mapper.ts +59 -28
  36. package/src/session/runtime-controller.ts +27 -19
  37. package/src/session/runtime-diagnostics.ts +26 -0
  38. package/src/session/runtime-registration.ts +0 -17
  39. package/src/session/runtime-registry.ts +83 -19
  40. package/src/session/runtime-transition-debug.ts +5 -2
  41. package/src/session/scanner.ts +24 -21
  42. package/src/session/workspace-lsp-runtime.ts +29 -3
  43. package/src/summary.ts +19 -40
  44. package/src/utils.ts +13 -19
  45. package/src/workspace-path-policy.ts +287 -0
  46. package/src/config/server-actions.ts +0 -59
  47. package/src/pattern-matcher.ts +0 -24
@@ -1,4 +1,3 @@
1
- import * as fs from "node:fs";
2
1
  import * as path from "node:path";
3
2
  import {
4
3
  type CodeQueryResult,
@@ -7,7 +6,6 @@ import {
7
6
  partialCodeQuery,
8
7
  unavailableCodeQuery,
9
8
  } from "@mrclrchtr/supi-code-runtime/api";
10
- import { walkProject } from "@mrclrchtr/supi-core/project";
11
9
  import type { LspClient } from "../client/client.ts";
12
10
  import type {
13
11
  DocumentSymbol,
@@ -15,10 +13,14 @@ import type {
15
13
  SymbolInformation,
16
14
  WorkspaceSymbol,
17
15
  } from "../config/types.ts";
16
+ import {
17
+ type AutomaticLspPathPolicy,
18
+ createDefaultAutomaticLspPathPolicy,
19
+ walkAutomaticLspTree,
20
+ } from "../workspace-path-policy.ts";
18
21
 
19
22
  type WorkspaceSymbolLike = SymbolInformation | WorkspaceSymbol;
20
23
 
21
- const SKIP_DIRS = new Set(["node_modules", ".git", ".pnpm", "dist", "build", "coverage"]);
22
24
  const DEFAULT_WARM_FILE_DEPTH = 4;
23
25
  const DEFAULT_MARKER_SCAN_DEPTH = 6;
24
26
 
@@ -30,6 +32,8 @@ export interface WorkspaceSymbolWarmTarget {
30
32
  export interface WorkspaceSymbolWarmOptions {
31
33
  maxFileDepth?: number;
32
34
  maxMarkerDepth?: number;
35
+ /** Runtime-owned automatic path policy. */
36
+ policy?: AutomaticLspPathPolicy;
33
37
  }
34
38
 
35
39
  export function getWorkspaceSymbolWarmPosition(
@@ -98,14 +102,6 @@ export function workspaceSymbolCollectionResult(
98
102
  return completedCodeQuery(collection.results);
99
103
  }
100
104
 
101
- export async function managerWorkspaceSymbol(
102
- clients: Iterable<LspClient>,
103
- query: string,
104
- control?: CodeRequestControl,
105
- ): Promise<CodeQueryResult<WorkspaceSymbolLike[]>> {
106
- return workspaceSymbolCollectionResult(await collectWorkspaceSymbols(clients, query, control));
107
- }
108
-
109
105
  export function findWorkspaceSymbolWarmTargets(
110
106
  root: string,
111
107
  rootMarkers: string[],
@@ -116,12 +112,13 @@ export function findWorkspaceSymbolWarmTargets(
116
112
  const allowed = new Set(fileTypes.map((fileType) => fileType.toLowerCase()));
117
113
  const maxFileDepth = options.maxFileDepth ?? DEFAULT_WARM_FILE_DEPTH;
118
114
  const maxMarkerDepth = options.maxMarkerDepth ?? DEFAULT_MARKER_SCAN_DEPTH;
115
+ const policy = options.policy ?? createDefaultAutomaticLspPathPolicy(resolvedRoot);
119
116
  if (allowed.size === 0) return [];
120
117
 
121
- const markerRoots = collectMarkerRoots(resolvedRoot, rootMarkers, maxMarkerDepth);
118
+ const markerRoots = collectMarkerRoots(resolvedRoot, rootMarkers, maxMarkerDepth, policy);
122
119
  const targets = markerRoots
123
120
  .map((entry) => {
124
- const file = findWarmFileRecursive(entry.root, allowed, maxFileDepth);
121
+ const file = findWarmFileRecursive(entry.root, allowed, maxFileDepth, policy);
125
122
  return file ? { projectRoot: entry.root, file, priority: entry.priority } : null;
126
123
  })
127
124
  .filter((entry): entry is { projectRoot: string; file: string; priority: number } =>
@@ -137,7 +134,7 @@ export function findWorkspaceSymbolWarmTargets(
137
134
 
138
135
  if (targets.length > 0) return targets;
139
136
 
140
- const fallback = findWarmFileRecursive(resolvedRoot, allowed, maxFileDepth);
137
+ const fallback = findWarmFileRecursive(resolvedRoot, allowed, maxFileDepth, policy);
141
138
  return fallback ? [{ projectRoot: resolvedRoot, file: fallback }] : [];
142
139
  }
143
140
 
@@ -150,13 +147,15 @@ function collectMarkerRoots(
150
147
  root: string,
151
148
  rootMarkers: string[],
152
149
  maxDepth: number,
150
+ policy: AutomaticLspPathPolicy,
153
151
  ): MarkerRootEntry[] {
154
152
  if (rootMarkers.length === 0) return [];
155
153
 
156
154
  const markerIndex = new Map(rootMarkers.map((marker, index) => [marker, index]));
157
155
  const matches = new Map<string, number>();
158
156
 
159
- walkProject(root, maxDepth, (directory, entryNames) => {
157
+ walkAutomaticLspTree(policy, root, maxDepth, (directory, entries) => {
158
+ const entryNames = new Set(entries.map((entry) => entry.name));
160
159
  const matchedPriority = rootMarkers.reduce<number | null>((best, marker) => {
161
160
  if (!entryNames.has(marker)) return best;
162
161
  const next = markerIndex.get(marker) ?? Number.MAX_SAFE_INTEGER;
@@ -181,31 +180,17 @@ function findWarmFileRecursive(
181
180
  directory: string,
182
181
  allowed: Set<string>,
183
182
  depth: number,
183
+ policy: AutomaticLspPathPolicy,
184
184
  ): string | null {
185
- let entries: fs.Dirent[];
186
- try {
187
- entries = fs.readdirSync(directory, { withFileTypes: true });
188
- } catch {
189
- return null;
190
- }
191
-
192
- const sortedEntries = [...entries].sort((a, b) => a.name.localeCompare(b.name));
193
-
194
- for (const entry of sortedEntries) {
195
- if (!entry.isFile()) continue;
196
- const ext = path.extname(entry.name).slice(1).toLowerCase();
197
- if (!allowed.has(ext)) continue;
198
- return path.join(directory, entry.name);
199
- }
200
-
201
- if (depth <= 0) return null;
202
-
203
- for (const entry of sortedEntries) {
204
- if (!entry.isDirectory()) continue;
205
- if (SKIP_DIRS.has(entry.name)) continue;
206
- const nested = findWarmFileRecursive(path.join(directory, entry.name), allowed, depth - 1);
207
- if (nested) return nested;
208
- }
209
-
210
- return null;
185
+ let warmFile: string | null = null;
186
+ walkAutomaticLspTree(policy, directory, depth, (currentDirectory, entries) => {
187
+ for (const entry of entries) {
188
+ if (!entry.isFile() && !entry.isSymbolicLink()) continue;
189
+ if (!allowed.has(path.extname(entry.name).slice(1).toLowerCase())) continue;
190
+ warmFile = path.join(currentDirectory, entry.name);
191
+ return true;
192
+ }
193
+ return false;
194
+ });
195
+ return warmFile;
211
196
  }