pi-lens 2.2.0 → 2.2.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 CHANGED
@@ -298,6 +298,11 @@ All notable changes to pi-lens will be documented in this file.
298
298
  ### Changed
299
299
  - **Improved ast-grep tool descriptions**: Better pattern guidance to prevent overly broad searches.
300
300
 
301
+ ## [2.2.1] - 2026-03-29
302
+
303
+ ### Fixed
304
+ - **No auto-install**: Runners (biome, pyright) now use direct CLI commands instead of `npx`. If not installed, gracefully skip instead of attempting to download.
305
+
301
306
  ## [2.2.0] - 2026-03-29
302
307
 
303
308
  ### Added
package/README.md CHANGED
@@ -395,7 +395,7 @@ Each rule includes a `message` and `note` that are shown in diagnostics, so the
395
395
  | `type-coverage` | `npm i -D type-coverage` | TypeScript `any` coverage percentage |
396
396
  | `madge` | `npm i -D madge` | Circular dependency detection |
397
397
  | `ruff` | `pip install ruff` | Python lint + format + autofix |
398
- | `pyright` | `npx pyright` (auto-installed) | Python type-checking |
398
+ | `pyright` | `pip install pyright` or `npm i -g pyright` | Python type-checking (optional, graceful skip if not installed) |
399
399
 
400
400
  ---
401
401
 
@@ -1,27 +1,38 @@
1
1
  /**
2
2
  * Biome runner for dispatch system
3
+ *
4
+ * Requires: @biomejs/biome (npm install -D @biomejs/biome)
3
5
  */
4
6
  import { spawnSync } from "node:child_process";
7
+ // Cache biome availability check
8
+ let biomeAvailable = null;
9
+ function isBiomeAvailable() {
10
+ if (biomeAvailable !== null)
11
+ return biomeAvailable;
12
+ // Check if biome CLI is available (do NOT auto-install via npx)
13
+ const check = spawnSync("biome", ["--version"], {
14
+ encoding: "utf-8",
15
+ timeout: 5000,
16
+ shell: true,
17
+ });
18
+ biomeAvailable = !check.error && check.status === 0;
19
+ return biomeAvailable;
20
+ }
5
21
  const biomeRunner = {
6
22
  id: "biome-lint",
7
23
  appliesTo: ["jsts", "json"],
8
24
  priority: 10,
9
25
  enabledByDefault: true,
10
26
  async run(ctx) {
11
- // Check if biome is available
12
- const check = spawnSync("npx", ["@biomejs/biome", "--version"], {
13
- encoding: "utf-8",
14
- timeout: 5000,
15
- shell: true,
16
- });
17
- if (check.error || check.status !== 0) {
27
+ // Skip if biome is not installed
28
+ if (!isBiomeAvailable()) {
18
29
  return { status: "skipped", diagnostics: [], semantic: "none" };
19
30
  }
20
- // Run biome check
31
+ // Run biome check (use direct command, not npx)
21
32
  const args = ctx.autofix
22
33
  ? ["check", "--write", ctx.filePath]
23
34
  : ["check", ctx.filePath];
24
- const result = spawnSync("npx", ["@biomejs/biome", ...args], {
35
+ const result = spawnSync("biome", args, {
25
36
  encoding: "utf-8",
26
37
  timeout: 30000,
27
38
  shell: true,
@@ -1,5 +1,7 @@
1
1
  /**
2
2
  * Biome runner for dispatch system
3
+ *
4
+ * Requires: @biomejs/biome (npm install -D @biomejs/biome)
3
5
  */
4
6
 
5
7
  import { spawnSync } from "node:child_process";
@@ -10,6 +12,22 @@ import type {
10
12
  RunnerResult,
11
13
  } from "../types.js";
12
14
 
15
+ // Cache biome availability check
16
+ let biomeAvailable: boolean | null = null;
17
+
18
+ function isBiomeAvailable(): boolean {
19
+ if (biomeAvailable !== null) return biomeAvailable;
20
+
21
+ // Check if biome CLI is available (do NOT auto-install via npx)
22
+ const check = spawnSync("biome", ["--version"], {
23
+ encoding: "utf-8",
24
+ timeout: 5000,
25
+ shell: true,
26
+ });
27
+ biomeAvailable = !check.error && check.status === 0;
28
+ return biomeAvailable;
29
+ }
30
+
13
31
  const biomeRunner: RunnerDefinition = {
14
32
  id: "biome-lint",
15
33
  appliesTo: ["jsts", "json"],
@@ -17,23 +35,17 @@ const biomeRunner: RunnerDefinition = {
17
35
  enabledByDefault: true,
18
36
 
19
37
  async run(ctx: DispatchContext): Promise<RunnerResult> {
20
- // Check if biome is available
21
- const check = spawnSync("npx", ["@biomejs/biome", "--version"], {
22
- encoding: "utf-8",
23
- timeout: 5000,
24
- shell: true,
25
- });
26
-
27
- if (check.error || check.status !== 0) {
38
+ // Skip if biome is not installed
39
+ if (!isBiomeAvailable()) {
28
40
  return { status: "skipped", diagnostics: [], semantic: "none" };
29
41
  }
30
42
 
31
- // Run biome check
43
+ // Run biome check (use direct command, not npx)
32
44
  const args = ctx.autofix
33
45
  ? ["check", "--write", ctx.filePath]
34
46
  : ["check", ctx.filePath];
35
47
 
36
- const result = spawnSync("npx", ["@biomejs/biome", ...args], {
48
+ const result = spawnSync("biome", args, {
37
49
  encoding: "utf-8",
38
50
  timeout: 30000,
39
51
  shell: true,
@@ -3,18 +3,38 @@
3
3
  *
4
4
  * Provides real Python type-checking (not just linting).
5
5
  * Catches type errors like: result: str = add(1, 2) # Type "int" not assignable to "str"
6
+ *
7
+ * Requires: pyright (pip install pyright or npm install -g pyright)
6
8
  */
7
9
  import { spawnSync } from "node:child_process";
10
+ // Cache pyright availability check
11
+ let pyrightAvailable = null;
12
+ function isPyrightAvailable() {
13
+ if (pyrightAvailable !== null)
14
+ return pyrightAvailable;
15
+ // Check if pyright CLI is available (do NOT auto-install via npx)
16
+ const check = spawnSync("pyright", ["--version"], {
17
+ encoding: "utf-8",
18
+ timeout: 5000,
19
+ shell: true,
20
+ });
21
+ pyrightAvailable = !check.error && check.status === 0;
22
+ return pyrightAvailable;
23
+ }
8
24
  const pyrightRunner = {
9
25
  id: "pyright",
10
26
  appliesTo: ["python"],
11
27
  priority: 5, // Higher priority than ruff (10) - type errors are more important
12
28
  enabledByDefault: true,
13
29
  async run(ctx) {
14
- // Run pyright with JSON output
15
- const result = spawnSync("npx", ["pyright", "--outputjson", ctx.filePath], {
30
+ // Skip if pyright is not installed
31
+ if (!isPyrightAvailable()) {
32
+ return { status: "skipped", diagnostics: [], semantic: "none" };
33
+ }
34
+ // Run pyright with JSON output (use direct command, not npx)
35
+ const result = spawnSync("pyright", ["--outputjson", ctx.filePath], {
16
36
  encoding: "utf-8",
17
- timeout: 60000, // Pyright can be slower on first run
37
+ timeout: 60000,
18
38
  shell: true,
19
39
  });
20
40
  // Pyright returns non-zero when errors found, that's OK
@@ -3,6 +3,8 @@
3
3
  *
4
4
  * Provides real Python type-checking (not just linting).
5
5
  * Catches type errors like: result: str = add(1, 2) # Type "int" not assignable to "str"
6
+ *
7
+ * Requires: pyright (pip install pyright or npm install -g pyright)
6
8
  */
7
9
 
8
10
  import { spawnSync } from "node:child_process";
@@ -13,6 +15,22 @@ import type {
13
15
  RunnerResult,
14
16
  } from "../types.js";
15
17
 
18
+ // Cache pyright availability check
19
+ let pyrightAvailable: boolean | null = null;
20
+
21
+ function isPyrightAvailable(): boolean {
22
+ if (pyrightAvailable !== null) return pyrightAvailable;
23
+
24
+ // Check if pyright CLI is available (do NOT auto-install via npx)
25
+ const check = spawnSync("pyright", ["--version"], {
26
+ encoding: "utf-8",
27
+ timeout: 5000,
28
+ shell: true,
29
+ });
30
+ pyrightAvailable = !check.error && check.status === 0;
31
+ return pyrightAvailable;
32
+ }
33
+
16
34
  const pyrightRunner: RunnerDefinition = {
17
35
  id: "pyright",
18
36
  appliesTo: ["python"],
@@ -20,10 +38,15 @@ const pyrightRunner: RunnerDefinition = {
20
38
  enabledByDefault: true,
21
39
 
22
40
  async run(ctx: DispatchContext): Promise<RunnerResult> {
23
- // Run pyright with JSON output
24
- const result = spawnSync("npx", ["pyright", "--outputjson", ctx.filePath], {
41
+ // Skip if pyright is not installed
42
+ if (!isPyrightAvailable()) {
43
+ return { status: "skipped", diagnostics: [], semantic: "none" };
44
+ }
45
+
46
+ // Run pyright with JSON output (use direct command, not npx)
47
+ const result = spawnSync("pyright", ["--outputjson", ctx.filePath], {
25
48
  encoding: "utf-8",
26
- timeout: 60000, // Pyright can be slower on first run
49
+ timeout: 60000,
27
50
  shell: true,
28
51
  });
29
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-lens",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "type": "module",
5
5
  "description": "Real-time code quality feedback for pi — TypeScript LSP, Biome, ast-grep, Ruff, complexity metrics, duplicate detection. Includes automated fix loop (/lens-booboo-fix) and interactive architectural refactoring (/lens-booboo-refactor) with browser-based interviews.",
6
6
  "repository": {