pi-lens 3.3.0 → 3.3.1
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/CHANGELOG.md +8 -0
- package/clients/lsp/launch.js +11 -6
- package/clients/lsp/launch.ts +11 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to pi-lens will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [3.3.1] - 2026-04-02
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **LSP spawn `EINVAL` on Windows** — `.cmd` files (e.g. `vscode-json-language-server.cmd`) found via npm global lookup were spawned without `shell: true`, causing `EINVAL` from `CreateProcess`. The `needsShell` recomputation for npm global paths incorrectly treated `.cmd` the same as `.exe`. Fixed in both primary and fallback spawn paths.
|
|
9
|
+
- **Unhandled `EINVAL` rejection** — LSP error handlers only caught `ENOENT` (binary not found). `EINVAL` (binary found but can't execute directly) now caught alongside `ENOENT` in both `launchLSP` and `launchViaPackageManager`.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
5
13
|
## [3.3.0] - 2026-04-02
|
|
6
14
|
|
|
7
15
|
### Removed
|
package/clients/lsp/launch.js
CHANGED
|
@@ -149,8 +149,11 @@ export async function launchLSP(command, args = [], options = {}) {
|
|
|
149
149
|
if (npmGlobalPath) {
|
|
150
150
|
spawnCommand = npmGlobalPath;
|
|
151
151
|
// Recompute needsShell for npm global path
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
needsShell =
|
|
153
|
+
isWindows &&
|
|
154
|
+
(spawnCommand.includes(" ") ||
|
|
155
|
+
/\.(cmd|bat)$/i.test(spawnCommand) ||
|
|
156
|
+
!/\.(exe|cmd|bat)$/i.test(spawnCommand));
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
159
|
let proc;
|
|
@@ -166,8 +169,10 @@ export async function launchLSP(command, args = [], options = {}) {
|
|
|
166
169
|
if (npmGlobalPath && npmGlobalPath !== spawnCommand) {
|
|
167
170
|
console.error(`[lsp] Trying npm global: ${npmGlobalPath}`);
|
|
168
171
|
// Recompute needsShell for npm global path
|
|
169
|
-
const
|
|
170
|
-
|
|
172
|
+
const needsShellGlobal = isWindows &&
|
|
173
|
+
(npmGlobalPath.includes(" ") ||
|
|
174
|
+
/\.(cmd|bat)$/i.test(npmGlobalPath) ||
|
|
175
|
+
!/\.(exe|cmd|bat)$/i.test(npmGlobalPath));
|
|
171
176
|
proc = trySpawn(npmGlobalPath, args, cwd, env, needsShellGlobal);
|
|
172
177
|
}
|
|
173
178
|
else {
|
|
@@ -192,7 +197,7 @@ export async function launchLSP(command, args = [], options = {}) {
|
|
|
192
197
|
let settled = false;
|
|
193
198
|
// Attach error handler that can reject for immediate errors
|
|
194
199
|
proc.on("error", (err) => {
|
|
195
|
-
if (!settled && err.code === "ENOENT") {
|
|
200
|
+
if (!settled && (err.code === "ENOENT" || err.code === "EINVAL")) {
|
|
196
201
|
settled = true;
|
|
197
202
|
reject(new Error(`LSP server binary not found: ${command}. ` +
|
|
198
203
|
`Install it or check your PATH.`));
|
|
@@ -254,7 +259,7 @@ export async function launchViaPackageManager(packageName, args = [], options =
|
|
|
254
259
|
await new Promise((resolve, reject) => {
|
|
255
260
|
let settled = false;
|
|
256
261
|
proc.on("error", (err) => {
|
|
257
|
-
if (!settled && err.code === "ENOENT") {
|
|
262
|
+
if (!settled && (err.code === "ENOENT" || err.code === "EINVAL")) {
|
|
258
263
|
settled = true;
|
|
259
264
|
reject(new Error(`Package manager not found for: ${packageName}. ` +
|
|
260
265
|
`Install Node.js or check your PATH.`));
|
package/clients/lsp/launch.ts
CHANGED
|
@@ -205,8 +205,11 @@ export async function launchLSP(
|
|
|
205
205
|
if (npmGlobalPath) {
|
|
206
206
|
spawnCommand = npmGlobalPath;
|
|
207
207
|
// Recompute needsShell for npm global path
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
needsShell =
|
|
209
|
+
isWindows &&
|
|
210
|
+
(spawnCommand.includes(" ") ||
|
|
211
|
+
/\.(cmd|bat)$/i.test(spawnCommand) ||
|
|
212
|
+
!/\.(exe|cmd|bat)$/i.test(spawnCommand));
|
|
210
213
|
}
|
|
211
214
|
}
|
|
212
215
|
|
|
@@ -225,9 +228,11 @@ export async function launchLSP(
|
|
|
225
228
|
if (npmGlobalPath && npmGlobalPath !== spawnCommand) {
|
|
226
229
|
console.error(`[lsp] Trying npm global: ${npmGlobalPath}`);
|
|
227
230
|
// Recompute needsShell for npm global path
|
|
228
|
-
const globalHasExt = /\.(exe|cmd|bat)$/i.test(npmGlobalPath);
|
|
229
231
|
const needsShellGlobal =
|
|
230
|
-
isWindows &&
|
|
232
|
+
isWindows &&
|
|
233
|
+
(npmGlobalPath.includes(" ") ||
|
|
234
|
+
/\.(cmd|bat)$/i.test(npmGlobalPath) ||
|
|
235
|
+
!/\.(exe|cmd|bat)$/i.test(npmGlobalPath));
|
|
231
236
|
proc = trySpawn(npmGlobalPath, args, cwd, env, needsShellGlobal);
|
|
232
237
|
} else {
|
|
233
238
|
throw err;
|
|
@@ -256,7 +261,7 @@ export async function launchLSP(
|
|
|
256
261
|
|
|
257
262
|
// Attach error handler that can reject for immediate errors
|
|
258
263
|
proc.on("error", (err: Error & { code?: string }) => {
|
|
259
|
-
if (!settled && err.code === "ENOENT") {
|
|
264
|
+
if (!settled && (err.code === "ENOENT" || err.code === "EINVAL")) {
|
|
260
265
|
settled = true;
|
|
261
266
|
reject(
|
|
262
267
|
new Error(
|
|
@@ -346,7 +351,7 @@ export async function launchViaPackageManager(
|
|
|
346
351
|
let settled = false;
|
|
347
352
|
|
|
348
353
|
proc.on("error", (err: Error & { code?: string }) => {
|
|
349
|
-
if (!settled && err.code === "ENOENT") {
|
|
354
|
+
if (!settled && (err.code === "ENOENT" || err.code === "EINVAL")) {
|
|
350
355
|
settled = true;
|
|
351
356
|
reject(
|
|
352
357
|
new Error(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-lens",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "pi extension for real-time code quality — 31 LSP servers, tree-sitter structural analysis, AST pattern matching, auto-install for TypeScript/Python tooling, duplicate detection, complexity metrics, and inline blockers with comprehensive /lens-booboo reports",
|
|
6
6
|
"repository": {
|