pi-lens 3.1.2 → 3.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 (154) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +16 -12
  3. package/clients/ast-grep-client.js +8 -1
  4. package/clients/ast-grep-client.ts +9 -1
  5. package/clients/biome-client.js +51 -38
  6. package/clients/biome-client.ts +60 -58
  7. package/clients/dependency-checker.js +30 -1
  8. package/clients/dependency-checker.ts +35 -1
  9. package/clients/dispatch/__tests__/runner-registration.test.ts +286 -282
  10. package/clients/dispatch/bus-dispatcher.js +15 -14
  11. package/clients/dispatch/bus-dispatcher.ts +32 -25
  12. package/clients/dispatch/dispatcher.js +18 -25
  13. package/clients/dispatch/dispatcher.test.ts +2 -1
  14. package/clients/dispatch/dispatcher.ts +17 -28
  15. package/clients/dispatch/plan.js +77 -32
  16. package/clients/dispatch/plan.ts +78 -32
  17. package/clients/dispatch/runners/ast-grep-napi.js +36 -376
  18. package/clients/dispatch/runners/ast-grep-napi.ts +60 -433
  19. package/clients/dispatch/runners/index.js +8 -4
  20. package/clients/dispatch/runners/index.ts +8 -4
  21. package/clients/dispatch/runners/lsp.js +65 -0
  22. package/clients/dispatch/runners/lsp.ts +125 -0
  23. package/clients/dispatch/runners/oxlint.js +2 -2
  24. package/clients/dispatch/runners/oxlint.ts +2 -2
  25. package/clients/dispatch/runners/pyright.js +24 -8
  26. package/clients/dispatch/runners/pyright.ts +28 -14
  27. package/clients/dispatch/runners/rust-clippy.js +2 -2
  28. package/clients/dispatch/runners/rust-clippy.ts +2 -4
  29. package/clients/dispatch/runners/tree-sitter.js +14 -2
  30. package/clients/dispatch/runners/tree-sitter.ts +15 -2
  31. package/clients/dispatch/runners/ts-lsp.js +3 -3
  32. package/clients/dispatch/runners/ts-lsp.ts +8 -5
  33. package/clients/dispatch/runners/yaml-rule-parser.js +292 -0
  34. package/clients/dispatch/runners/yaml-rule-parser.ts +338 -0
  35. package/clients/dispatch/types.js +3 -0
  36. package/clients/dispatch/types.ts +3 -0
  37. package/clients/formatters.js +67 -14
  38. package/clients/formatters.ts +68 -15
  39. package/clients/installer/index.js +78 -10
  40. package/clients/installer/index.ts +519 -426
  41. package/clients/jscpd-client.js +28 -0
  42. package/clients/jscpd-client.ts +41 -3
  43. package/clients/knip-client.js +30 -1
  44. package/clients/knip-client.ts +34 -2
  45. package/clients/lsp/__tests__/client.test.ts +64 -41
  46. package/clients/lsp/__tests__/config.test.ts +25 -17
  47. package/clients/lsp/__tests__/launch.test.ts +108 -43
  48. package/clients/lsp/__tests__/service.test.ts +76 -48
  49. package/clients/lsp/client.js +87 -2
  50. package/clients/lsp/client.ts +150 -6
  51. package/clients/lsp/config.js +8 -11
  52. package/clients/lsp/config.ts +24 -21
  53. package/clients/lsp/index.js +69 -0
  54. package/clients/lsp/index.ts +82 -0
  55. package/clients/lsp/interactive-install.js +19 -8
  56. package/clients/lsp/interactive-install.ts +52 -27
  57. package/clients/lsp/launch.js +182 -32
  58. package/clients/lsp/launch.ts +241 -38
  59. package/clients/lsp/path-utils.js +3 -46
  60. package/clients/lsp/path-utils.ts +11 -51
  61. package/clients/lsp/server.js +93 -71
  62. package/clients/lsp/server.ts +173 -131
  63. package/clients/path-utils.js +142 -0
  64. package/clients/path-utils.ts +153 -0
  65. package/clients/ruff-client.js +33 -4
  66. package/clients/ruff-client.ts +44 -13
  67. package/clients/safe-spawn.js +3 -1
  68. package/clients/safe-spawn.ts +3 -1
  69. package/clients/services/effect-integration.js +11 -7
  70. package/clients/services/effect-integration.ts +34 -26
  71. package/clients/sg-runner.js +51 -9
  72. package/clients/sg-runner.ts +58 -15
  73. package/clients/tree-sitter-client.js +12 -0
  74. package/clients/tree-sitter-client.ts +12 -0
  75. package/clients/typescript-client.js +6 -2
  76. package/clients/typescript-client.ts +9 -2
  77. package/commands/booboo.js +2 -4
  78. package/commands/booboo.ts +2 -4
  79. package/index.ts +377 -93
  80. package/package.json +2 -1
  81. package/rules/tree-sitter-queries/tsx/no-nested-links.yml +45 -0
  82. package/rules/tree-sitter-queries/typescript/constructor-super.yml +55 -0
  83. package/rules/tree-sitter-queries/typescript/debugger.yml +1 -1
  84. package/rules/tree-sitter-queries/typescript/no-dupe-class-members.yml +47 -0
  85. package/tsconfig.json +1 -1
  86. package/clients/__tests__/file-time.test.js +0 -216
  87. package/clients/__tests__/format-service.test.js +0 -245
  88. package/clients/__tests__/formatters.test.js +0 -271
  89. package/clients/agent-behavior-client.test.js +0 -94
  90. package/clients/ast-grep-client.test.js +0 -129
  91. package/clients/ast-grep-client.test.ts +0 -155
  92. package/clients/biome-client.test.js +0 -144
  93. package/clients/cache-manager.test.js +0 -197
  94. package/clients/complexity-client.test.js +0 -234
  95. package/clients/dependency-checker.test.js +0 -60
  96. package/clients/dispatch/__tests__/autofix-integration.test.js +0 -245
  97. package/clients/dispatch/__tests__/runner-registration.test.js +0 -236
  98. package/clients/dispatch/dispatcher.edge.test.js +0 -82
  99. package/clients/dispatch/dispatcher.format.test.js +0 -46
  100. package/clients/dispatch/dispatcher.inline.test.js +0 -74
  101. package/clients/dispatch/dispatcher.test.js +0 -115
  102. package/clients/dispatch/runners/architect.test.js +0 -138
  103. package/clients/dispatch/runners/ast-grep-napi.test.js +0 -106
  104. package/clients/dispatch/runners/oxlint.test.js +0 -230
  105. package/clients/dispatch/runners/pyright.test.js +0 -98
  106. package/clients/dispatch/runners/python-slop.test.js +0 -203
  107. package/clients/dispatch/runners/scan_codebase.test.js +0 -89
  108. package/clients/dispatch/runners/shellcheck.test.js +0 -98
  109. package/clients/dispatch/runners/spellcheck.test.js +0 -158
  110. package/clients/dispatch/runners/ts-slop.test.js +0 -180
  111. package/clients/dispatch/runners/ts-slop.test.ts +0 -230
  112. package/clients/dogfood.test.js +0 -201
  113. package/clients/file-kinds.test.js +0 -169
  114. package/clients/go-client.test.js +0 -127
  115. package/clients/jscpd-client.test.js +0 -127
  116. package/clients/knip-client.test.js +0 -112
  117. package/clients/lsp/__tests__/client.test.js +0 -325
  118. package/clients/lsp/__tests__/config.test.js +0 -166
  119. package/clients/lsp/__tests__/error-recovery.test.js +0 -213
  120. package/clients/lsp/__tests__/integration.test.js +0 -127
  121. package/clients/lsp/__tests__/launch.test.js +0 -260
  122. package/clients/lsp/__tests__/server.test.js +0 -259
  123. package/clients/lsp/__tests__/service.test.js +0 -417
  124. package/clients/metrics-client.test.js +0 -141
  125. package/clients/ruff-client.test.js +0 -132
  126. package/clients/rust-client.test.js +0 -108
  127. package/clients/sanitize.test.js +0 -177
  128. package/clients/secrets-scanner.test.js +0 -100
  129. package/clients/services/__tests__/effect-integration.test.js +0 -86
  130. package/clients/test-runner-client.test.js +0 -192
  131. package/clients/todo-scanner.test.js +0 -301
  132. package/clients/type-coverage-client.test.js +0 -105
  133. package/clients/typescript-client.codefix.test.js +0 -157
  134. package/clients/typescript-client.test.js +0 -105
  135. package/commands/clients/ast-grep-client.js +0 -250
  136. package/commands/clients/ast-grep-parser.js +0 -86
  137. package/commands/clients/ast-grep-rule-manager.js +0 -91
  138. package/commands/clients/ast-grep-types.js +0 -9
  139. package/commands/clients/biome-client.js +0 -380
  140. package/commands/clients/complexity-client.js +0 -667
  141. package/commands/clients/file-kinds.js +0 -177
  142. package/commands/clients/file-utils.js +0 -40
  143. package/commands/clients/jscpd-client.js +0 -169
  144. package/commands/clients/knip-client.js +0 -211
  145. package/commands/clients/ruff-client.js +0 -297
  146. package/commands/clients/safe-spawn.js +0 -88
  147. package/commands/clients/scan-utils.js +0 -83
  148. package/commands/clients/sg-runner.js +0 -190
  149. package/commands/clients/types.js +0 -11
  150. package/commands/clients/typescript-client.js +0 -505
  151. package/commands/rate.test.js +0 -119
  152. package/rules/ast-grep-rules/rules/no-dangerously-set-inner-html.yml +0 -13
  153. package/rules/ast-grep-rules/rules/no-debugger.yml +0 -12
  154. package/rules/ast-grep-rules/rules/no-eval.yml +0 -13
@@ -7,6 +7,7 @@
7
7
  * - Platform-specific handling
8
8
  */
9
9
 
10
+ import { stat } from "node:fs/promises";
10
11
  import path from "node:path";
11
12
  import { ensureTool, getToolEnvironment } from "../installer/index.js";
12
13
  import {
@@ -58,10 +59,10 @@ async function spawnWithInteractiveInstall(
58
59
  _command: string,
59
60
  _args: string[],
60
61
  options: { cwd: string },
61
- spawnFn: () => LSPProcess,
62
+ spawnFn: () => LSPProcess | Promise<LSPProcess>,
62
63
  ): Promise<LSPProcess | undefined> {
63
64
  try {
64
- return spawnFn();
65
+ return await spawnFn();
65
66
  } catch (error) {
66
67
  // Check if this is a "command not found" error
67
68
  const errorMsg = String(error);
@@ -74,7 +75,7 @@ async function spawnWithInteractiveInstall(
74
75
  const shouldInstall = await promptForInstall(language, options.cwd);
75
76
  if (shouldInstall) {
76
77
  // Try again after install
77
- return spawnFn();
78
+ return await spawnFn();
78
79
  }
79
80
  // User declined, return undefined to skip this LSP
80
81
  return undefined;
@@ -86,40 +87,59 @@ async function spawnWithInteractiveInstall(
86
87
  }
87
88
 
88
89
  /**
89
- * Walk up the tree looking for project root markers
90
+ * Walk up the directory tree looking for project root markers.
91
+ *
92
+ * NearestRoot(includePatterns, excludePatterns?) → RootFunction
93
+ *
94
+ * - includePatterns: file/dir names that signal the project root (e.g. ["package.json"])
95
+ * - excludePatterns: if any of these exist in a directory, skip it (e.g. ["node_modules"])
96
+ * - stopDir: walk stops here (defaults to filesystem root; set to project cwd for safety)
97
+ *
98
+ * Equivalent to createRootDetector; exported under both names for clarity.
90
99
  */
91
- export function createRootDetector(
100
+ export function NearestRoot(
92
101
  includePatterns: string[],
93
102
  excludePatterns?: string[],
103
+ stopDir?: string,
94
104
  ): RootFunction {
95
105
  return async (file: string): Promise<string | undefined> => {
96
106
  let currentDir = path.dirname(file);
97
- const root = path.parse(currentDir).root;
107
+ const fsRoot = path.parse(currentDir).root;
108
+ const stop = stopDir ?? fsRoot;
109
+
110
+ while (currentDir !== fsRoot) {
111
+ // Bail out if we've reached the stop boundary
112
+ if (
113
+ currentDir === stop ||
114
+ (currentDir.startsWith(stop + path.sep) === false &&
115
+ currentDir === stop)
116
+ ) {
117
+ break;
118
+ }
98
119
 
99
- while (currentDir !== root) {
100
- // Check exclude patterns first
120
+ // Check exclude patterns — skip this dir (but keep walking up)
101
121
  if (excludePatterns) {
122
+ let excluded = false;
102
123
  for (const pattern of excludePatterns) {
103
- const checkPath = path.join(currentDir, pattern);
104
124
  try {
105
- const stat = await import("node:fs/promises").then((fs) =>
106
- fs.stat(checkPath),
107
- );
108
- if (stat) return undefined; // Excluded
125
+ await stat(path.join(currentDir, pattern));
126
+ excluded = true;
127
+ break;
109
128
  } catch {
110
129
  /* not found */
111
130
  }
112
131
  }
132
+ if (excluded) {
133
+ currentDir = path.dirname(currentDir);
134
+ continue;
135
+ }
113
136
  }
114
137
 
115
138
  // Check include patterns
116
139
  for (const pattern of includePatterns) {
117
- const checkPath = path.join(currentDir, pattern);
118
140
  try {
119
- const stat = await import("node:fs/promises").then((fs) =>
120
- fs.stat(checkPath),
121
- );
122
- if (stat) return currentDir;
141
+ await stat(path.join(currentDir, pattern));
142
+ return currentDir;
123
143
  } catch {
124
144
  /* not found */
125
145
  }
@@ -132,23 +152,23 @@ export function createRootDetector(
132
152
  };
133
153
  }
134
154
 
155
+ /** Alias kept for backward compatibility */
156
+ export const createRootDetector = NearestRoot;
157
+
135
158
  // --- Server Definitions ---
136
159
 
137
160
  export const TypeScriptServer: LSPServerInfo = {
138
161
  id: "typescript",
139
162
  name: "TypeScript Language Server",
140
163
  extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
141
- root: createRootDetector(
142
- [
143
- "package-lock.json",
144
- "bun.lockb",
145
- "bun.lock",
146
- "pnpm-lock.yaml",
147
- "yarn.lock",
148
- "package.json",
149
- ],
150
- [".pi-lens"],
151
- ),
164
+ root: createRootDetector([
165
+ "package-lock.json",
166
+ "bun.lockb",
167
+ "bun.lock",
168
+ "pnpm-lock.yaml",
169
+ "yarn.lock",
170
+ "package.json",
171
+ ]),
152
172
  async spawn(root) {
153
173
  const path = await import("node:path");
154
174
  const fs = await import("node:fs/promises");
@@ -224,7 +244,7 @@ export const TypeScriptServer: LSPServerInfo = {
224
244
 
225
245
  // Use absolute path and proper environment
226
246
  const env = await getToolEnvironment();
227
- const proc = launchLSP(lspPath, ["--stdio"], {
247
+ const proc = await launchLSP(lspPath, ["--stdio"], {
228
248
  cwd: root,
229
249
  env: {
230
250
  ...env,
@@ -245,23 +265,24 @@ export const PythonServer: LSPServerInfo = {
245
265
  id: "python",
246
266
  name: "Pyright Language Server",
247
267
  extensions: [".py", ".pyi"],
248
- root: createRootDetector(
249
- [
250
- "pyproject.toml",
251
- "setup.py",
252
- "setup.cfg",
253
- "requirements.txt",
254
- "Pipfile",
255
- "poetry.lock",
256
- ],
257
- [".pi-lens"],
258
- ),
268
+ root: createRootDetector([
269
+ "pyproject.toml",
270
+ "setup.py",
271
+ "setup.cfg",
272
+ "requirements.txt",
273
+ "Pipfile",
274
+ "poetry.lock",
275
+ ]),
259
276
  async spawn(root) {
260
277
  const env = await getToolEnvironment();
261
- const proc = launchViaPackageManager("pyright-langserver", ["--stdio"], {
262
- cwd: root,
263
- env,
264
- });
278
+ const proc = await launchViaPackageManager(
279
+ "pyright-langserver",
280
+ ["--stdio"],
281
+ {
282
+ cwd: root,
283
+ env,
284
+ },
285
+ );
265
286
 
266
287
  // Detect virtual environment
267
288
  const initialization: Record<string, unknown> = {};
@@ -296,16 +317,28 @@ export const GoServer: LSPServerInfo = {
296
317
  id: "go",
297
318
  name: "gopls",
298
319
  extensions: [".go"],
299
- root: createRootDetector(["go.mod", "go.sum"], [".pi-lens"]),
320
+ root: createRootDetector(["go.mod", "go.sum"]),
300
321
  async spawn(root) {
301
322
  const proc = await spawnWithInteractiveInstall(
302
323
  "go",
303
324
  "gopls",
304
325
  [],
305
326
  { cwd: root },
306
- () => launchLSP("gopls", [], { cwd: root }),
327
+ async () => await launchLSP("gopls", [], { cwd: root }),
307
328
  );
308
- return proc ? { process: proc } : undefined;
329
+ // gopls works best with minimal initialization options
330
+ // The client capabilities fix (workspaceFolders: true) is the key fix
331
+ return proc
332
+ ? {
333
+ process: proc,
334
+ initialization: {
335
+ // Disable experimental features that may cause issues
336
+ ui: {
337
+ semanticTokens: true,
338
+ },
339
+ },
340
+ }
341
+ : undefined;
309
342
  },
310
343
  };
311
344
 
@@ -313,16 +346,29 @@ export const RustServer: LSPServerInfo = {
313
346
  id: "rust",
314
347
  name: "rust-analyzer",
315
348
  extensions: [".rs"],
316
- root: createRootDetector(["Cargo.toml", "Cargo.lock"], [".pi-lens"]),
349
+ root: createRootDetector(["Cargo.toml", "Cargo.lock"]),
317
350
  async spawn(root) {
318
351
  const proc = await spawnWithInteractiveInstall(
319
352
  "rust",
320
353
  "rust-analyzer",
321
354
  [],
322
355
  { cwd: root },
323
- () => launchLSP("rust-analyzer", [], { cwd: root }),
356
+ async () => await launchLSP("rust-analyzer", [], { cwd: root }),
324
357
  );
325
- return proc ? { process: proc } : undefined;
358
+ // rust-analyzer needs minimal initialization to avoid capability mismatches
359
+ return proc
360
+ ? {
361
+ process: proc,
362
+ initialization: {
363
+ // Disable features that may conflict with our client capabilities
364
+ cargo: {
365
+ buildScripts: { enable: true },
366
+ },
367
+ procMacro: { enable: true },
368
+ diagnostics: { enable: true },
369
+ },
370
+ }
371
+ : undefined;
326
372
  },
327
373
  };
328
374
 
@@ -330,14 +376,14 @@ export const RubyServer: LSPServerInfo = {
330
376
  id: "ruby",
331
377
  name: "Ruby LSP",
332
378
  extensions: [".rb", ".rake", ".gemspec", ".ru"],
333
- root: createRootDetector(["Gemfile", ".ruby-version"], [".pi-lens"]),
379
+ root: createRootDetector(["Gemfile", ".ruby-version"]),
334
380
  async spawn(root) {
335
381
  // Try ruby-lsp first, fall back to solargraph
336
382
  try {
337
- const proc = launchLSP("ruby-lsp", [], { cwd: root });
383
+ const proc = await launchLSP("ruby-lsp", [], { cwd: root });
338
384
  return { process: proc };
339
385
  } catch {
340
- const proc = launchViaPackageManager("solargraph", ["stdio"], {
386
+ const proc = await launchViaPackageManager("solargraph", ["stdio"], {
341
387
  cwd: root,
342
388
  });
343
389
  return { process: proc };
@@ -349,9 +395,9 @@ export const PHPServer: LSPServerInfo = {
349
395
  id: "php",
350
396
  name: "Intelephense",
351
397
  extensions: [".php"],
352
- root: createRootDetector(["composer.json", "composer.lock"], [".pi-lens"]),
398
+ root: createRootDetector(["composer.json", "composer.lock"]),
353
399
  async spawn(root) {
354
- const proc = launchViaPackageManager("intelephense", ["--stdio"], {
400
+ const proc = await launchViaPackageManager("intelephense", ["--stdio"], {
355
401
  cwd: root,
356
402
  });
357
403
  return {
@@ -365,9 +411,9 @@ export const CSharpServer: LSPServerInfo = {
365
411
  id: "csharp",
366
412
  name: "csharp-ls",
367
413
  extensions: [".cs"],
368
- root: createRootDetector([".sln", ".csproj", ".slnx"], [".pi-lens"]),
414
+ root: createRootDetector([".sln", ".csproj", ".slnx"]),
369
415
  async spawn(root) {
370
- const proc = launchLSP("csharp-ls", [], { cwd: root });
416
+ const proc = await launchLSP("csharp-ls", [], { cwd: root });
371
417
  return { process: proc };
372
418
  },
373
419
  };
@@ -376,9 +422,9 @@ export const FSharpServer: LSPServerInfo = {
376
422
  id: "fsharp",
377
423
  name: "FSAutocomplete",
378
424
  extensions: [".fs", ".fsi", ".fsx"],
379
- root: createRootDetector([".sln", ".fsproj"], [".pi-lens"]),
425
+ root: createRootDetector([".sln", ".fsproj"]),
380
426
  async spawn(root) {
381
- const proc = launchLSP("fsautocomplete", [], { cwd: root });
427
+ const proc = await launchLSP("fsautocomplete", [], { cwd: root });
382
428
  return { process: proc };
383
429
  },
384
430
  };
@@ -387,14 +433,11 @@ export const JavaServer: LSPServerInfo = {
387
433
  id: "java",
388
434
  name: "JDT Language Server",
389
435
  extensions: [".java"],
390
- root: createRootDetector(
391
- ["pom.xml", "build.gradle", ".classpath"],
392
- [".pi-lens"],
393
- ),
436
+ root: createRootDetector(["pom.xml", "build.gradle", ".classpath"]),
394
437
  async spawn(root) {
395
438
  // JDTLS requires special handling - paths to launcher jar
396
439
  const jdtlsPath = process.env.JDTLS_PATH || "jdtls";
397
- const proc = launchLSP(jdtlsPath, [], { cwd: root });
440
+ const proc = await launchLSP(jdtlsPath, [], { cwd: root });
398
441
  return { process: proc };
399
442
  },
400
443
  };
@@ -403,12 +446,9 @@ export const KotlinServer: LSPServerInfo = {
403
446
  id: "kotlin",
404
447
  name: "Kotlin Language Server",
405
448
  extensions: [".kt", ".kts"],
406
- root: createRootDetector(
407
- ["build.gradle.kts", "build.gradle", "pom.xml"],
408
- [".pi-lens"],
409
- ),
449
+ root: createRootDetector(["build.gradle.kts", "build.gradle", "pom.xml"]),
410
450
  async spawn(root) {
411
- const proc = launchLSP("kotlin-language-server", [], { cwd: root });
451
+ const proc = await launchLSP("kotlin-language-server", [], { cwd: root });
412
452
  return { process: proc };
413
453
  },
414
454
  };
@@ -417,9 +457,9 @@ export const SwiftServer: LSPServerInfo = {
417
457
  id: "swift",
418
458
  name: "SourceKit-LSP",
419
459
  extensions: [".swift"],
420
- root: createRootDetector(["Package.swift"], [".pi-lens"]),
460
+ root: createRootDetector(["Package.swift"]),
421
461
  async spawn(root) {
422
- const proc = launchLSP("sourcekit-lsp", [], { cwd: root });
462
+ const proc = await launchLSP("sourcekit-lsp", [], { cwd: root });
423
463
  return { process: proc };
424
464
  },
425
465
  };
@@ -428,11 +468,15 @@ export const DartServer: LSPServerInfo = {
428
468
  id: "dart",
429
469
  name: "Dart Analysis Server",
430
470
  extensions: [".dart"],
431
- root: createRootDetector(["pubspec.yaml"], [".pi-lens"]),
471
+ root: createRootDetector(["pubspec.yaml"]),
432
472
  async spawn(root) {
433
- const proc = launchLSP("dart", ["language-server", "--protocol=lsp"], {
434
- cwd: root,
435
- });
473
+ const proc = await launchLSP(
474
+ "dart",
475
+ ["language-server", "--protocol=lsp"],
476
+ {
477
+ cwd: root,
478
+ },
479
+ );
436
480
  return { process: proc };
437
481
  },
438
482
  };
@@ -441,9 +485,9 @@ export const LuaServer: LSPServerInfo = {
441
485
  id: "lua",
442
486
  name: "Lua Language Server",
443
487
  extensions: [".lua"],
444
- root: createRootDetector([".luarc.json", ".luacheckrc"], [".pi-lens"]),
488
+ root: createRootDetector([".luarc.json", ".luacheckrc"]),
445
489
  async spawn(root) {
446
- const proc = launchLSP("lua-language-server", [], { cwd: root });
490
+ const proc = await launchLSP("lua-language-server", [], { cwd: root });
447
491
  return { process: proc };
448
492
  },
449
493
  };
@@ -459,7 +503,9 @@ export const CppServer: LSPServerInfo = {
459
503
  "Makefile",
460
504
  ]),
461
505
  async spawn(root) {
462
- const proc = launchLSP("clangd", ["--background-index"], { cwd: root });
506
+ const proc = await launchLSP("clangd", ["--background-index"], {
507
+ cwd: root,
508
+ });
463
509
  return { process: proc };
464
510
  },
465
511
  };
@@ -468,9 +514,9 @@ export const ZigServer: LSPServerInfo = {
468
514
  id: "zig",
469
515
  name: "ZLS",
470
516
  extensions: [".zig", ".zon"],
471
- root: createRootDetector(["build.zig"], [".pi-lens"]),
517
+ root: createRootDetector(["build.zig"]),
472
518
  async spawn(root) {
473
- const proc = launchLSP("zls", [], { cwd: root });
519
+ const proc = await launchLSP("zls", [], { cwd: root });
474
520
  return { process: proc };
475
521
  },
476
522
  };
@@ -479,12 +525,9 @@ export const HaskellServer: LSPServerInfo = {
479
525
  id: "haskell",
480
526
  name: "Haskell Language Server",
481
527
  extensions: [".hs", ".lhs"],
482
- root: createRootDetector(
483
- ["stack.yaml", "cabal.project", "*.cabal"],
484
- [".pi-lens"],
485
- ),
528
+ root: createRootDetector(["stack.yaml", "cabal.project", "*.cabal"]),
486
529
  async spawn(root) {
487
- const proc = launchLSP("haskell-language-server-wrapper", ["--lsp"], {
530
+ const proc = await launchLSP("haskell-language-server-wrapper", ["--lsp"], {
488
531
  cwd: root,
489
532
  });
490
533
  return { process: proc };
@@ -495,9 +538,9 @@ export const ElixirServer: LSPServerInfo = {
495
538
  id: "elixir",
496
539
  name: "ElixirLS",
497
540
  extensions: [".ex", ".exs"],
498
- root: createRootDetector(["mix.exs"], [".pi-lens"]),
541
+ root: createRootDetector(["mix.exs"]),
499
542
  async spawn(root) {
500
- const proc = launchLSP("elixir-ls", [], { cwd: root });
543
+ const proc = await launchLSP("elixir-ls", [], { cwd: root });
501
544
  return { process: proc };
502
545
  },
503
546
  };
@@ -506,9 +549,9 @@ export const GleamServer: LSPServerInfo = {
506
549
  id: "gleam",
507
550
  name: "Gleam LSP",
508
551
  extensions: [".gleam"],
509
- root: createRootDetector(["gleam.toml"], [".pi-lens"]),
552
+ root: createRootDetector(["gleam.toml"]),
510
553
  async spawn(root) {
511
- const proc = launchLSP("gleam", ["lsp"], { cwd: root });
554
+ const proc = await launchLSP("gleam", ["lsp"], { cwd: root });
512
555
  return { process: proc };
513
556
  },
514
557
  };
@@ -517,9 +560,9 @@ export const OCamlServer: LSPServerInfo = {
517
560
  id: "ocaml",
518
561
  name: "ocamllsp",
519
562
  extensions: [".ml", ".mli"],
520
- root: createRootDetector(["dune-project", "opam"], [".pi-lens"]),
563
+ root: createRootDetector(["dune-project", "opam"]),
521
564
  async spawn(root) {
522
- const proc = launchLSP("ocamllsp", [], { cwd: root });
565
+ const proc = await launchLSP("ocamllsp", [], { cwd: root });
523
566
  return { process: proc };
524
567
  },
525
568
  };
@@ -528,9 +571,9 @@ export const ClojureServer: LSPServerInfo = {
528
571
  id: "clojure",
529
572
  name: "Clojure LSP",
530
573
  extensions: [".clj", ".cljs", ".cljc", ".edn"],
531
- root: createRootDetector(["deps.edn", "project.clj"], [".pi-lens"]),
574
+ root: createRootDetector(["deps.edn", "project.clj"]),
532
575
  async spawn(root) {
533
- const proc = launchLSP("clojure-lsp", [], { cwd: root });
576
+ const proc = await launchLSP("clojure-lsp", [], { cwd: root });
534
577
  return { process: proc };
535
578
  },
536
579
  };
@@ -539,9 +582,9 @@ export const TerraformServer: LSPServerInfo = {
539
582
  id: "terraform",
540
583
  name: "Terraform LSP",
541
584
  extensions: [".tf", ".tfvars"],
542
- root: createRootDetector([".terraform.lock.hcl"], [".pi-lens"]),
585
+ root: createRootDetector([".terraform.lock.hcl"]),
543
586
  async spawn(root) {
544
- const proc = launchLSP("terraform-ls", ["serve"], { cwd: root });
587
+ const proc = await launchLSP("terraform-ls", ["serve"], { cwd: root });
545
588
  return { process: proc };
546
589
  },
547
590
  };
@@ -550,9 +593,9 @@ export const NixServer: LSPServerInfo = {
550
593
  id: "nix",
551
594
  name: "nixd",
552
595
  extensions: [".nix"],
553
- root: createRootDetector(["flake.nix"], [".pi-lens"]),
596
+ root: createRootDetector(["flake.nix"]),
554
597
  async spawn(root) {
555
- const proc = launchLSP("nixd", [], { cwd: root });
598
+ const proc = await launchLSP("nixd", [], { cwd: root });
556
599
  return { process: proc };
557
600
  },
558
601
  };
@@ -569,7 +612,7 @@ export const BashServer: LSPServerInfo = {
569
612
  "bash-language-server",
570
613
  ["start"],
571
614
  { cwd },
572
- () => launchLSP("bash-language-server", ["start"], {}),
615
+ async () => await launchLSP("bash-language-server", ["start"], {}),
573
616
  );
574
617
  return proc ? { process: proc } : undefined;
575
618
  },
@@ -582,7 +625,7 @@ export const DockerServer: LSPServerInfo = {
582
625
  root: async () => process.cwd(),
583
626
  async spawn() {
584
627
  // Use npx since it's not auto-installed
585
- const proc = launchViaPackageManager(
628
+ const proc = await launchViaPackageManager(
586
629
  "dockerfile-language-server-nodejs",
587
630
  ["--stdio"],
588
631
  {},
@@ -603,7 +646,7 @@ export const YamlServer: LSPServerInfo = {
603
646
  "yaml-language-server",
604
647
  ["--stdio"],
605
648
  { cwd },
606
- () => launchLSP("yaml-language-server", ["--stdio"], {}),
649
+ async () => await launchLSP("yaml-language-server", ["--stdio"], {}),
607
650
  );
608
651
  return proc ? { process: proc } : undefined;
609
652
  },
@@ -618,10 +661,11 @@ export const JsonServer: LSPServerInfo = {
618
661
  const cwd = process.cwd();
619
662
  const proc = await spawnWithInteractiveInstall(
620
663
  "json",
621
- "vscode-json-languageserver",
664
+ "vscode-json-language-server",
622
665
  ["--stdio"],
623
666
  { cwd },
624
- () => launchLSP("vscode-json-languageserver", ["--stdio"], {}),
667
+ async () =>
668
+ await launchLSP("vscode-json-language-server", ["--stdio"], {}),
625
669
  );
626
670
  return proc ? { process: proc } : undefined;
627
671
  },
@@ -631,10 +675,10 @@ export const PrismaServer: LSPServerInfo = {
631
675
  id: "prisma",
632
676
  name: "Prisma Language Server",
633
677
  extensions: [".prisma"],
634
- root: createRootDetector(["prisma/schema.prisma"], [".pi-lens"]),
678
+ root: createRootDetector(["prisma/schema.prisma"]),
635
679
  async spawn(root) {
636
680
  // Use npx since it's not auto-installed
637
- const proc = launchViaPackageManager(
681
+ const proc = await launchViaPackageManager(
638
682
  "@prisma/language-server",
639
683
  ["--stdio"],
640
684
  { cwd: root },
@@ -649,21 +693,22 @@ export const VueServer: LSPServerInfo = {
649
693
  id: "vue",
650
694
  name: "Vue Language Server",
651
695
  extensions: [".vue"],
652
- root: createRootDetector(
653
- [
654
- "package-lock.json",
655
- "bun.lockb",
656
- "bun.lock",
657
- "pnpm-lock.yaml",
658
- "yarn.lock",
659
- ],
660
- [".pi-lens"],
661
- ),
696
+ root: createRootDetector([
697
+ "package-lock.json",
698
+ "bun.lockb",
699
+ "bun.lock",
700
+ "pnpm-lock.yaml",
701
+ "yarn.lock",
702
+ ]),
662
703
  async spawn(root) {
663
704
  // Use npx since it's not auto-installed
664
- const proc = launchViaPackageManager("@vue/language-server", ["--stdio"], {
665
- cwd: root,
666
- });
705
+ const proc = await launchViaPackageManager(
706
+ "@vue/language-server",
707
+ ["--stdio"],
708
+ {
709
+ cwd: root,
710
+ },
711
+ );
667
712
  return { process: proc };
668
713
  },
669
714
  };
@@ -672,19 +717,16 @@ export const SvelteServer: LSPServerInfo = {
672
717
  id: "svelte",
673
718
  name: "Svelte Language Server",
674
719
  extensions: [".svelte"],
675
- root: createRootDetector(
676
- [
677
- "package-lock.json",
678
- "bun.lockb",
679
- "bun.lock",
680
- "pnpm-lock.yaml",
681
- "yarn.lock",
682
- ],
683
- [".pi-lens"],
684
- ),
720
+ root: createRootDetector([
721
+ "package-lock.json",
722
+ "bun.lockb",
723
+ "bun.lock",
724
+ "pnpm-lock.yaml",
725
+ "yarn.lock",
726
+ ]),
685
727
  async spawn(root) {
686
728
  // Use npx since it's not auto-installed
687
- const proc = launchViaPackageManager(
729
+ const proc = await launchViaPackageManager(
688
730
  "svelte-language-server",
689
731
  ["--stdio"],
690
732
  { cwd: root },
@@ -708,7 +750,7 @@ export const ESLintServer: LSPServerInfo = {
708
750
  async spawn(root) {
709
751
  // Try via package manager (npx) since it's not auto-installed
710
752
  try {
711
- const proc = launchViaPackageManager(
753
+ const proc = await launchViaPackageManager(
712
754
  "vscode-eslint-language-server",
713
755
  ["--stdio"],
714
756
  { cwd: root },
@@ -731,7 +773,7 @@ export const CssServer: LSPServerInfo = {
731
773
  root: async () => process.cwd(),
732
774
  async spawn() {
733
775
  // Use npx since it's not auto-installed
734
- const proc = launchViaPackageManager(
776
+ const proc = await launchViaPackageManager(
735
777
  "vscode-css-languageserver",
736
778
  ["--stdio"],
737
779
  {},