pi-lens 2.0.8 → 2.0.9

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.
@@ -354,12 +354,14 @@ message: found
354
354
  }
355
355
 
356
356
  return result_groups;
357
- } catch {
357
+ } catch (err) { void err;
358
358
  return [];
359
359
  } finally {
360
360
  try {
361
361
  require("node:fs").rmSync(ruleDir, { recursive: true, force: true });
362
- } catch (err) { void err; }
362
+ } catch (err) {
363
+ void err;
364
+ }
363
365
  }
364
366
  }
365
367
 
@@ -435,7 +437,9 @@ message: found
435
437
  } finally {
436
438
  try {
437
439
  require("node:fs").rmSync(ruleDir, { recursive: true, force: true });
438
- } catch (err) { void err; }
440
+ } catch (err) {
441
+ void err;
442
+ }
439
443
  }
440
444
 
441
445
  return exports;
@@ -484,7 +488,7 @@ message: found
484
488
  const parsed = JSON.parse(stdout);
485
489
  const matches = Array.isArray(parsed) ? parsed : [parsed];
486
490
  resolve({ matches });
487
- } catch {
491
+ } catch (err) { void err;
488
492
  resolve({ matches: [], error: "Failed to parse output" });
489
493
  }
490
494
  });
@@ -595,7 +599,7 @@ message: found
595
599
  }
596
600
  return diagnostics;
597
601
  }
598
- } catch {
602
+ } catch (err) { void err;
599
603
  // Not a JSON array, try ndjson format (legacy)
600
604
  }
601
605
 
@@ -607,7 +611,7 @@ message: found
607
611
  const item: AstGrepJsonDiagnostic = JSON.parse(line);
608
612
  const diag = this.parseDiagnostic(item, resolvedFilterFile);
609
613
  if (diag) diagnostics.push(diag);
610
- } catch {
614
+ } catch (err) { void err;
611
615
  // Skip unparseable lines
612
616
  }
613
617
  }
@@ -313,7 +313,7 @@ export class BiomeClient {
313
313
  if (content === formatted) return "";
314
314
 
315
315
  return this.computeDiff(content, formatted);
316
- } catch {
316
+ } catch (err) { void err;
317
317
  return "";
318
318
  }
319
319
  }
@@ -368,7 +368,7 @@ export class BiomeClient {
368
368
  }
369
369
 
370
370
  return diagnostics;
371
- } catch {
371
+ } catch (err) { void err;
372
372
  this.log("Failed to parse biome JSON output");
373
373
  return [];
374
374
  }
@@ -79,7 +79,9 @@ export class GoClient {
79
79
  return p;
80
80
  }
81
81
  }
82
- } catch (err) { void err; }
82
+ } catch (err) {
83
+ void err;
84
+ }
83
85
  }
84
86
 
85
87
  return null;
@@ -120,7 +120,9 @@ export class JscpdClient {
120
120
  } finally {
121
121
  try {
122
122
  fs.rmSync(outDir, { recursive: true, force: true });
123
- } catch (err) { void err; }
123
+ } catch (err) {
124
+ void err;
125
+ }
124
126
  }
125
127
  }
126
128
 
@@ -168,7 +170,7 @@ export class JscpdClient {
168
170
  }));
169
171
 
170
172
  return { success: true, clones, duplicatedLines, totalLines, percentage };
171
- } catch {
173
+ } catch (err) { void err;
172
174
  return {
173
175
  success: false,
174
176
  clones: [],
@@ -241,7 +241,7 @@ export class KnipClient {
241
241
  unlistedDeps,
242
242
  summary: `Found ${issues.length} issues`,
243
243
  };
244
- } catch {
244
+ } catch (err) { void err;
245
245
  this.log("Failed to parse knip JSON output");
246
246
  return {
247
247
  success: false,
@@ -64,7 +64,7 @@ export class RuffClient {
64
64
  if (this.ruffAvailable) {
65
65
  this.log(`Ruff found: ${result.stdout.trim()}`);
66
66
  }
67
- } catch {
67
+ } catch (err) { void err;
68
68
  this.ruffAvailable = false;
69
69
  }
70
70
 
@@ -147,9 +147,7 @@ export class RuffClient {
147
147
  .split("\n")
148
148
  .filter((l) => l.startsWith("+") || l.startsWith("-")).length;
149
149
  return `[Ruff Format] ${diffLines} line(s) would change — run 'ruff format ${path.basename(filePath)}' to fix`;
150
- } catch {
151
- return "";
152
- }
150
+ } catch (err) { void err; return ""; } // Intentionally return empty string on diff failure
153
151
  }
154
152
 
155
153
  /**
@@ -318,7 +316,7 @@ export class RuffClient {
318
316
  }
319
317
 
320
318
  return diagnostics;
321
- } catch {
319
+ } catch (err) { void err;
322
320
  this.log("Failed to parse ruff JSON output");
323
321
  return [];
324
322
  }
@@ -95,7 +95,9 @@ export class RustClient {
95
95
  return p;
96
96
  }
97
97
  }
98
- } catch (err) { void err; }
98
+ } catch (err) {
99
+ void err;
100
+ }
99
101
  }
100
102
 
101
103
  return null;
@@ -265,7 +267,9 @@ export class RustClient {
265
267
  });
266
268
  }
267
269
  }
268
- } catch (err) { void err; } // Skip non-JSON lines
270
+ } catch (err) {
271
+ void err;
272
+ } // Skip non-JSON lines
269
273
  }
270
274
 
271
275
  return diags;
@@ -84,7 +84,7 @@ export abstract class SubprocessClient<T extends Diagnostic> {
84
84
  } else {
85
85
  this.log(`${this.toolName} not available`);
86
86
  }
87
- } catch {
87
+ } catch (err) { void err;
88
88
  this.available = false;
89
89
  }
90
90
 
@@ -262,7 +262,7 @@ export class TestRunnerClient {
262
262
  this.availableRunners.set(`${cwd}:pytest:config`, true);
263
263
  return { runner: "pytest", config: RUNNERS.pytest };
264
264
  }
265
- } catch {
265
+ } catch (err) { void err;
266
266
  // package.json parse error
267
267
  }
268
268
  }
@@ -291,7 +291,7 @@ export class TestRunnerClient {
291
291
  return files.some((f) =>
292
292
  new RegExp(cf.replace(/\*/g, ".*")).test(f),
293
293
  );
294
- } catch {
294
+ } catch (err) { void err;
295
295
  return false;
296
296
  }
297
297
  }
@@ -315,7 +315,9 @@ export class TestRunnerClient {
315
315
  this.log("Detected pytest globally");
316
316
  return { runner: "pytest", config: RUNNERS.pytest };
317
317
  }
318
- } catch (err) { void err; }
318
+ } catch (err) {
319
+ void err;
320
+ }
319
321
 
320
322
  return null;
321
323
  }
@@ -364,7 +366,7 @@ export class TestRunnerClient {
364
366
  this.log(`Found test file: ${testPath}`);
365
367
  return { testFile: testPath, runner: detected.runner };
366
368
  }
367
- } catch {
369
+ } catch (err) { void err;
368
370
  // Directory not readable
369
371
  }
370
372
  }
@@ -545,7 +547,7 @@ export class TestRunnerClient {
545
547
  failures,
546
548
  duration: 0, // Vitest JSON doesn't include duration in this format
547
549
  };
548
- } catch {
550
+ } catch (err) { void err;
549
551
  // If JSON parsing fails, check for basic pass/fail indicators
550
552
  const failed = stdout.includes("FAIL") || stderr.includes("FAIL");
551
553
  return this.emptyResult(
@@ -617,7 +619,7 @@ export class TestRunnerClient {
617
619
  failures,
618
620
  duration: 0,
619
621
  };
620
- } catch {
622
+ } catch (err) { void err;
621
623
  const failed = stdout.includes("FAIL") || stderr.includes("FAIL");
622
624
  return this.emptyResult(
623
625
  testFile,
@@ -9,7 +9,9 @@ describe("TypeCoverageClient", () => {
9
9
 
10
10
  beforeEach(() => {
11
11
  client = new TypeCoverageClient();
12
- ({ tmpDir: _tmpDir, cleanup } = setupTestEnvironment("pi-lens-typecoverage-test-"));
12
+ ({ tmpDir: _tmpDir, cleanup } = setupTestEnvironment(
13
+ "pi-lens-typecoverage-test-",
14
+ ));
13
15
  });
14
16
 
15
17
  afterEach(() => {
@@ -81,7 +81,7 @@ function loadCompilerOptions(tsconfigPath: string): ts.CompilerOptions {
81
81
  if (parsed.errors.length) return DEFAULT_COMPILER_OPTIONS;
82
82
  // Always set skipLibCheck to avoid noise from node_modules
83
83
  return { ...parsed.options, skipLibCheck: true };
84
- } catch {
84
+ } catch (err) { void err;
85
85
  return DEFAULT_COMPILER_OPTIONS;
86
86
  }
87
87
  }
package/index.ts CHANGED
@@ -281,14 +281,14 @@ export default function (pi: ExtensionAPI) {
281
281
  if (trimmed.startsWith("[")) {
282
282
  try {
283
283
  return JSON.parse(trimmed);
284
- } catch {
284
+ } catch (err) { void err;
285
285
  return [];
286
286
  }
287
287
  }
288
288
  return raw.split("\n").flatMap((l: string) => {
289
289
  try {
290
290
  return [JSON.parse(l)];
291
- } catch {
291
+ } catch (err) { void err;
292
292
  return [];
293
293
  }
294
294
  });
@@ -661,10 +661,6 @@ export default function (pi: ExtensionAPI) {
661
661
  type: "agent",
662
662
  note: "Add this.log('Error: ' + err.message) to the catch block",
663
663
  },
664
- "silent-failure": {
665
- type: "agent",
666
- note: "Add this.log('Error: ' + err.message) or rethrow",
667
- },
668
664
  "no-console-log": {
669
665
  type: "agent",
670
666
  note: "Remove or replace with class logger method",
@@ -833,7 +829,7 @@ export default function (pi: ExtensionAPI) {
833
829
  : raw.split("\n").flatMap((l: string) => {
834
830
  try {
835
831
  return [JSON.parse(l)];
836
- } catch {
832
+ } catch (err) { void err;
837
833
  return [];
838
834
  }
839
835
  });
@@ -1241,8 +1237,18 @@ export default function (pi: ExtensionAPI) {
1241
1237
  report += `|-------|-------|------------|\n`;
1242
1238
  for (const [grade, count] of Object.entries(gradeCount)) {
1243
1239
  const pct = ((count / results.length) * 100).toFixed(1);
1244
- const gradeIcons: Record<string, string> = { A: "🟢", B: "🟡", C: "🟠", D: "🔴" };
1245
- const gradeThresholds: Record<string, number> = { A: 80, B: 60, C: 40, D: 20 };
1240
+ const gradeIcons: Record<string, string> = {
1241
+ A: "🟢",
1242
+ B: "🟡",
1243
+ C: "🟠",
1244
+ D: "🔴",
1245
+ };
1246
+ const gradeThresholds: Record<string, number> = {
1247
+ A: 80,
1248
+ B: 60,
1249
+ C: 40,
1250
+ D: 20,
1251
+ };
1246
1252
  const icon = gradeIcons[grade] ?? "⚫";
1247
1253
  const threshold = gradeThresholds[grade] ?? 0;
1248
1254
  report += `| ${icon} ${grade} (MI ≥ ${threshold}) | ${count} | ${pct}% |\n`;
@@ -1683,9 +1689,10 @@ export default function (pi: ExtensionAPI) {
1683
1689
  const preWriteHints = new Map<string, string>();
1684
1690
 
1685
1691
  pi.on("tool_call", async (event, _ctx) => {
1686
- const filePath = (isToolCallEventType("write", event) || isToolCallEventType("edit", event))
1687
- ? (event.input as { path: string }).path
1688
- : undefined;
1692
+ const filePath =
1693
+ isToolCallEventType("write", event) || isToolCallEventType("edit", event)
1694
+ ? (event.input as { path: string }).path
1695
+ : undefined;
1689
1696
 
1690
1697
  if (!filePath) return;
1691
1698
 
@@ -2113,7 +2120,7 @@ export default function (pi: ExtensionAPI) {
2113
2120
  for (const [name, file] of newExports) {
2114
2121
  cachedExports.set(name, file);
2115
2122
  }
2116
- } catch {
2123
+ } catch (err) { void err;
2117
2124
  // ast-grep not available, skip
2118
2125
  }
2119
2126
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-lens",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "description": "Real-time code feedback for pi — TypeScript LSP, Biome, ast-grep, Ruff, TODO scanner, dead code, duplicate detection, type coverage",
5
5
  "repository": {
6
6
  "type": "git",
@@ -4,13 +4,16 @@ message: "Empty catch block — handle or log the error"
4
4
  severity: warning
5
5
  note: |
6
6
  Silently swallowing errors makes debugging impossible.
7
- At minimum, log the error. Ideally, handle it properly.
7
+ Catches with return statements, assignments, or error propagation are acceptable.
8
8
  rule:
9
- all:
10
- - kind: catch_clause
11
- - has:
12
- kind: statement_block
13
- not:
14
- has:
15
- kind: expression_statement
16
- stopBy: end
9
+ kind: catch_clause
10
+ has:
11
+ kind: statement_block
12
+ not:
13
+ has:
14
+ any:
15
+ - kind: expression_statement # this.log(...), void err, etc.
16
+ - kind: return_statement # return defaultValue
17
+ - kind: throw_statement # rethrow
18
+ - kind: variable_declaration # const x = ...
19
+ - kind: assignment_expression # x = ...
@@ -1,14 +0,0 @@
1
- id: silent-failure
2
- language: TypeScript
3
- message: "Silent failure detected — log or rethrow the error"
4
- severity: warning
5
- note: |
6
- Empty catch blocks swallow errors silently.
7
- Always log the error or rethrow it to aid debugging.
8
- rule:
9
- kind: catch_clause
10
- has:
11
- kind: statement_block
12
- not:
13
- has:
14
- kind: throw_statement