@principal-ade/code-quality-panels 0.1.25 → 0.1.26

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.
@@ -370,7 +370,16 @@ var LENS_REGISTRY = [
370
370
  outputsAggregate: true,
371
371
  colorScheme: "issues",
372
372
  description: "Pluggable linting utility for JavaScript and TypeScript",
373
- command: "eslint"
373
+ command: "eslint",
374
+ fileMetricsRequirements: {
375
+ completeCommand: "npx eslint . --format json",
376
+ requiredFlags: ["--format json"],
377
+ formatFlag: "--format json",
378
+ withoutConfig: "Only files with issues are reported in the output",
379
+ fallbackStrategy: "source-file-count",
380
+ nativelyComplete: false,
381
+ notes: "ESLint JSON output only includes files that have issues. Clean files are not listed."
382
+ }
374
383
  },
375
384
  {
376
385
  id: "biome-lint",
@@ -382,7 +391,16 @@ var LENS_REGISTRY = [
382
391
  outputsAggregate: true,
383
392
  colorScheme: "issues",
384
393
  description: "Fast linter for JavaScript and TypeScript",
385
- command: "biome lint"
394
+ command: "biome lint",
395
+ fileMetricsRequirements: {
396
+ completeCommand: "npx @biomejs/biome lint . --reporter=json",
397
+ requiredFlags: ["--reporter=json"],
398
+ formatFlag: "--reporter=json",
399
+ withoutConfig: "Output cannot be parsed for file metrics",
400
+ fallbackStrategy: "source-file-count",
401
+ nativelyComplete: true,
402
+ notes: "Biome JSON output includes all analyzed files."
403
+ }
386
404
  },
387
405
  {
388
406
  id: "oxlint",
@@ -394,7 +412,15 @@ var LENS_REGISTRY = [
394
412
  outputsAggregate: true,
395
413
  colorScheme: "issues",
396
414
  description: "Blazing fast JavaScript/TypeScript linter",
397
- command: "oxlint"
415
+ command: "oxlint",
416
+ fileMetricsRequirements: {
417
+ completeCommand: "npx oxlint --format json",
418
+ requiredFlags: ["--format json"],
419
+ formatFlag: "--format json",
420
+ withoutConfig: "Output cannot be parsed for file metrics",
421
+ fallbackStrategy: "source-file-count",
422
+ nativelyComplete: false
423
+ }
398
424
  },
399
425
  // Python linting
400
426
  {
@@ -407,7 +433,16 @@ var LENS_REGISTRY = [
407
433
  outputsAggregate: true,
408
434
  colorScheme: "issues",
409
435
  description: "Extremely fast Python linter",
410
- command: "ruff check"
436
+ command: "ruff check",
437
+ fileMetricsRequirements: {
438
+ completeCommand: "ruff check . --output-format=json",
439
+ requiredFlags: ["--output-format=json"],
440
+ formatFlag: "--output-format=json",
441
+ withoutConfig: "Output cannot be parsed for file metrics",
442
+ fallbackStrategy: "source-file-count",
443
+ nativelyComplete: false,
444
+ notes: "Ruff JSON output only includes files with issues."
445
+ }
411
446
  },
412
447
  {
413
448
  id: "pylint",
@@ -418,7 +453,15 @@ var LENS_REGISTRY = [
418
453
  outputsAggregate: true,
419
454
  colorScheme: "issues",
420
455
  description: "Python static code analyzer",
421
- command: "pylint"
456
+ command: "pylint",
457
+ fileMetricsRequirements: {
458
+ completeCommand: "pylint --output-format=json .",
459
+ requiredFlags: ["--output-format=json"],
460
+ formatFlag: "--output-format=json",
461
+ withoutConfig: "Output cannot be parsed for file metrics",
462
+ fallbackStrategy: "source-file-count",
463
+ nativelyComplete: false
464
+ }
422
465
  },
423
466
  // Go linting
424
467
  {
@@ -457,7 +500,15 @@ var LENS_REGISTRY = [
457
500
  outputsAggregate: true,
458
501
  colorScheme: "binary",
459
502
  description: "Opinionated code formatter",
460
- command: "prettier --check"
503
+ command: "prettier --check",
504
+ fileMetricsRequirements: {
505
+ completeCommand: "npx prettier --check . --no-error-on-unmatched-pattern --log-level debug",
506
+ requiredFlags: ["--check", "--log-level debug"],
507
+ withoutConfig: "Without --log-level debug, file list is not available",
508
+ fallbackStrategy: "source-file-count",
509
+ nativelyComplete: true,
510
+ notes: "Prettier with --log-level debug lists all checked files. This is the reference implementation for complete file metrics."
511
+ }
461
512
  },
462
513
  {
463
514
  id: "biome-format",
@@ -469,7 +520,15 @@ var LENS_REGISTRY = [
469
520
  outputsAggregate: true,
470
521
  colorScheme: "binary",
471
522
  description: "Fast code formatter for JavaScript and TypeScript",
472
- command: "biome format"
523
+ command: "biome format",
524
+ fileMetricsRequirements: {
525
+ completeCommand: "npx @biomejs/biome format . --reporter=json",
526
+ requiredFlags: ["--reporter=json"],
527
+ formatFlag: "--reporter=json",
528
+ withoutConfig: "Output cannot be parsed for file metrics",
529
+ fallbackStrategy: "source-file-count",
530
+ nativelyComplete: true
531
+ }
473
532
  },
474
533
  // Python formatting
475
534
  {
@@ -532,7 +591,15 @@ var LENS_REGISTRY = [
532
591
  outputsAggregate: true,
533
592
  colorScheme: "issues",
534
593
  description: "TypeScript type checker",
535
- command: "tsc --noEmit"
594
+ command: "tsc --noEmit",
595
+ fileMetricsRequirements: {
596
+ completeCommand: "npx tsc --noEmit --listFiles",
597
+ requiredFlags: ["--listFiles"],
598
+ withoutConfig: "Only files with type errors are reported. Cannot determine total files analyzed.",
599
+ fallbackStrategy: "source-file-count",
600
+ nativelyComplete: false,
601
+ notes: "The --listFiles flag is REQUIRED to get the complete list of files TypeScript analyzed. Without it, only files with errors appear in output."
602
+ }
536
603
  },
537
604
  // Python type checking
538
605
  {
@@ -583,7 +650,16 @@ var LENS_REGISTRY = [
583
650
  outputsAggregate: true,
584
651
  colorScheme: "coverage",
585
652
  description: "JavaScript testing framework",
586
- command: "jest --coverage"
653
+ command: "jest --coverage",
654
+ fileMetricsRequirements: {
655
+ completeCommand: "npx jest --coverage --json --outputFile=jest-results.json",
656
+ requiredFlags: ["--coverage", "--json"],
657
+ formatFlag: "--json",
658
+ withoutConfig: "Without --coverage, no per-file coverage data is available. Without --json, output cannot be parsed.",
659
+ fallbackStrategy: "coverage-only",
660
+ nativelyComplete: false,
661
+ notes: "Jest coverage data provides per-file metrics for source files. Test file results are separate from source coverage."
662
+ }
587
663
  },
588
664
  {
589
665
  id: "vitest",
@@ -595,7 +671,16 @@ var LENS_REGISTRY = [
595
671
  outputsAggregate: true,
596
672
  colorScheme: "coverage",
597
673
  description: "Vite-native testing framework",
598
- command: "vitest run --coverage"
674
+ command: "vitest run --coverage",
675
+ fileMetricsRequirements: {
676
+ completeCommand: "npx vitest run --coverage --reporter=json",
677
+ requiredFlags: ["--coverage", "--reporter=json"],
678
+ formatFlag: "--reporter=json",
679
+ withoutConfig: "Without --coverage, no per-file coverage data is available",
680
+ fallbackStrategy: "coverage-only",
681
+ nativelyComplete: false,
682
+ notes: "Vitest coverage provides per-file metrics. Requires @vitest/coverage-v8 or @vitest/coverage-istanbul."
683
+ }
599
684
  },
600
685
  {
601
686
  id: "bun-test",
@@ -607,7 +692,15 @@ var LENS_REGISTRY = [
607
692
  outputsAggregate: true,
608
693
  colorScheme: "coverage",
609
694
  description: "Bun native test runner",
610
- command: "bun test"
695
+ command: "bun test",
696
+ fileMetricsRequirements: {
697
+ completeCommand: "bun test --coverage",
698
+ requiredFlags: ["--coverage"],
699
+ withoutConfig: "Without --coverage, no per-file coverage data is available",
700
+ fallbackStrategy: "coverage-only",
701
+ nativelyComplete: false,
702
+ notes: "Bun test coverage is built-in but requires --coverage flag."
703
+ }
611
704
  },
612
705
  // Python testing
613
706
  {
@@ -658,7 +751,16 @@ var LENS_REGISTRY = [
658
751
  outputsAggregate: true,
659
752
  colorScheme: "issues",
660
753
  description: "Find unused files, dependencies and exports",
661
- command: "knip"
754
+ command: "knip",
755
+ fileMetricsRequirements: {
756
+ completeCommand: "npx knip --reporter json",
757
+ requiredFlags: ["--reporter json"],
758
+ formatFlag: "--reporter json",
759
+ withoutConfig: "Output cannot be parsed for file metrics",
760
+ fallbackStrategy: "source-file-count",
761
+ nativelyComplete: false,
762
+ notes: "Knip reports unused files and exports. It does not list all analyzed files, only those with issues."
763
+ }
662
764
  },
663
765
  // Python
664
766
  {
@@ -684,7 +786,16 @@ var LENS_REGISTRY = [
684
786
  outputsAggregate: true,
685
787
  colorScheme: "binary",
686
788
  description: "Documentation coverage checker",
687
- command: "alexandria lint"
789
+ command: "alexandria lint",
790
+ fileMetricsRequirements: {
791
+ completeCommand: "npx @principal-ai/alexandria-cli coverage --json",
792
+ requiredFlags: ["--json"],
793
+ formatFlag: "--json",
794
+ withoutConfig: "Output cannot be parsed for file metrics",
795
+ fallbackStrategy: "source-file-count",
796
+ nativelyComplete: true,
797
+ notes: "Alexandria reports documentation coverage for all analyzed files."
798
+ }
688
799
  },
689
800
  {
690
801
  id: "typedoc",
@@ -1544,7 +1655,10 @@ function QualityHexagonExpandable({
1544
1655
  },
1545
1656
  children: metricConfig.map(({ key, label }) => {
1546
1657
  const value = metrics[key];
1547
- const configured = isMetricConfigured(key, lensesRan);
1658
+ const configured = isMetricConfigured(
1659
+ key,
1660
+ lensesRan
1661
+ );
1548
1662
  return /* @__PURE__ */ jsxs(
1549
1663
  "div",
1550
1664
  {
@@ -2179,7 +2293,10 @@ const LEGACY_FALLBACKS = {
2179
2293
  function getColorModeForMetric(metric, lensesRan) {
2180
2294
  if (!isValidHexagonMetric(metric)) return null;
2181
2295
  const hexagonMetric = metric;
2182
- const colorMode = getColorModeForHexagonMetric(hexagonMetric, lensesRan ?? []);
2296
+ const colorMode = getColorModeForHexagonMetric(
2297
+ hexagonMetric,
2298
+ lensesRan ?? []
2299
+ );
2183
2300
  if (!colorMode && lensesRan === void 0) {
2184
2301
  return LEGACY_FALLBACKS[hexagonMetric] ?? null;
2185
2302
  }
@@ -2413,7 +2530,10 @@ const QualityHexagonPanelContent = ({
2413
2530
  });
2414
2531
  },
2415
2532
  onMetricClick: (metric) => {
2416
- const colorMode = getColorModeForMetric(metric, pkg.lensesRan);
2533
+ const colorMode = getColorModeForMetric(
2534
+ metric,
2535
+ pkg.lensesRan
2536
+ );
2417
2537
  if (colorMode) {
2418
2538
  events.emit({
2419
2539
  type: "quality:colorMode:select",
@@ -3236,10 +3356,25 @@ function LensDataDebugPanel$1({
3236
3356
  const [expandedFiles, setExpandedFiles] = React2.useState(
3237
3357
  /* @__PURE__ */ new Set()
3238
3358
  );
3359
+ const [expandedAnalyzedFiles, setExpandedAnalyzedFiles] = React2.useState(/* @__PURE__ */ new Set());
3360
+ React2.useEffect(() => {
3361
+ if (initialSelectedPackage) {
3362
+ setSelectedPackage((current) => {
3363
+ if (current !== initialSelectedPackage) {
3364
+ setExpandedLens(null);
3365
+ setExpandedFiles(/* @__PURE__ */ new Set());
3366
+ setExpandedAnalyzedFiles(/* @__PURE__ */ new Set());
3367
+ return initialSelectedPackage;
3368
+ }
3369
+ return current;
3370
+ });
3371
+ }
3372
+ }, [initialSelectedPackage]);
3239
3373
  const handlePackageSelect = (pkg) => {
3240
3374
  setSelectedPackage(pkg);
3241
3375
  setExpandedLens(null);
3242
3376
  setExpandedFiles(/* @__PURE__ */ new Set());
3377
+ setExpandedAnalyzedFiles(/* @__PURE__ */ new Set());
3243
3378
  onPackageSelect == null ? void 0 : onPackageSelect(pkg);
3244
3379
  };
3245
3380
  const toggleLens = (lensId) => {
@@ -3255,6 +3390,15 @@ function LensDataDebugPanel$1({
3255
3390
  }
3256
3391
  setExpandedFiles(newSet);
3257
3392
  };
3393
+ const toggleAnalyzedFiles = (lensKey) => {
3394
+ const newSet = new Set(expandedAnalyzedFiles);
3395
+ if (newSet.has(lensKey)) {
3396
+ newSet.delete(lensKey);
3397
+ } else {
3398
+ newSet.add(lensKey);
3399
+ }
3400
+ setExpandedAnalyzedFiles(newSet);
3401
+ };
3258
3402
  const selectedResults = selectedPackage ? packageGroups.get(selectedPackage) || [] : [];
3259
3403
  return /* @__PURE__ */ jsxs(
3260
3404
  "div",
@@ -3270,62 +3414,7 @@ function LensDataDebugPanel$1({
3270
3414
  fontSize: 13
3271
3415
  },
3272
3416
  children: [
3273
- packageNames.length > 1 && /* @__PURE__ */ jsx(
3274
- "div",
3275
- {
3276
- style: {
3277
- display: "flex",
3278
- flexWrap: "wrap",
3279
- gap: 8,
3280
- marginBottom: 8
3281
- },
3282
- children: packageNames.map((pkg) => {
3283
- const summary = getPackageSummary(packageGroups.get(pkg) || []);
3284
- const isSelected = selectedPackage === pkg;
3285
- return /* @__PURE__ */ jsxs(
3286
- "button",
3287
- {
3288
- onClick: () => handlePackageSelect(pkg),
3289
- style: {
3290
- display: "flex",
3291
- alignItems: "center",
3292
- gap: 8,
3293
- padding: "8px 12px",
3294
- borderRadius: 6,
3295
- border: `1px solid ${isSelected ? theme.colors.primary : theme.colors.border}`,
3296
- backgroundColor: isSelected ? theme.colors.surface : "transparent",
3297
- color: theme.colors.text,
3298
- cursor: "pointer",
3299
- transition: "all 0.15s ease"
3300
- },
3301
- children: [
3302
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: pkg }),
3303
- /* @__PURE__ */ jsxs(
3304
- "span",
3305
- {
3306
- style: {
3307
- fontSize: 11,
3308
- padding: "2px 6px",
3309
- borderRadius: 4,
3310
- backgroundColor: summary.totalErrors > 0 ? getSeverityBg("error") : summary.totalWarnings > 0 ? getSeverityBg("warning") : "rgba(34, 197, 94, 0.1)",
3311
- color: summary.totalErrors > 0 ? getSeverityColor("error") : summary.totalWarnings > 0 ? getSeverityColor("warning") : "#22c55e"
3312
- },
3313
- children: [
3314
- summary.passCount,
3315
- "/",
3316
- summary.lensCount,
3317
- " pass"
3318
- ]
3319
- }
3320
- )
3321
- ]
3322
- },
3323
- pkg
3324
- );
3325
- })
3326
- }
3327
- ),
3328
- packageNames.length === 1 && /* @__PURE__ */ jsxs(
3417
+ selectedPackage && !onPackageSelect && /* @__PURE__ */ jsxs(
3329
3418
  "div",
3330
3419
  {
3331
3420
  style: {
@@ -3338,7 +3427,26 @@ function LensDataDebugPanel$1({
3338
3427
  marginBottom: 8
3339
3428
  },
3340
3429
  children: [
3341
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: theme.colors.text }, children: packageNames[0] }),
3430
+ packageNames.length > 1 ? /* @__PURE__ */ jsx(
3431
+ "select",
3432
+ {
3433
+ value: selectedPackage,
3434
+ onChange: (e) => handlePackageSelect(e.target.value),
3435
+ style: {
3436
+ padding: "4px 8px",
3437
+ borderRadius: 4,
3438
+ border: `1px solid ${theme.colors.border}`,
3439
+ backgroundColor: theme.colors.background,
3440
+ color: theme.colors.text,
3441
+ fontFamily: "monospace",
3442
+ fontSize: 13,
3443
+ fontWeight: 600,
3444
+ cursor: "pointer",
3445
+ outline: "none"
3446
+ },
3447
+ children: packageNames.map((pkg) => /* @__PURE__ */ jsx("option", { value: pkg, children: pkg }, pkg))
3448
+ }
3449
+ ) : /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: theme.colors.text }, children: selectedPackage }),
3342
3450
  (() => {
3343
3451
  const summary = getPackageSummary(selectedResults);
3344
3452
  return /* @__PURE__ */ jsxs(
@@ -3363,21 +3471,8 @@ function LensDataDebugPanel$1({
3363
3471
  ]
3364
3472
  }
3365
3473
  ),
3366
- !selectedPackage && packageNames.length > 1 && /* @__PURE__ */ jsx(
3367
- "div",
3368
- {
3369
- style: {
3370
- padding: 24,
3371
- textAlign: "center",
3372
- color: theme.colors.textMuted,
3373
- backgroundColor: theme.colors.surface,
3374
- borderRadius: 6
3375
- },
3376
- children: "Select a package above to view lens results"
3377
- }
3378
- ),
3379
3474
  selectedPackage && selectedResults.map((result, idx) => {
3380
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
3475
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
3381
3476
  const lensKey = `${((_a = result.lens) == null ? void 0 : _a.id) ?? "unknown"}-${idx}`;
3382
3477
  const isExpanded = expandedLens === lensKey;
3383
3478
  const filesWithIssues = getFilesWithIssues(result.issues ?? []);
@@ -3600,6 +3695,149 @@ function LensDataDebugPanel$1({
3600
3695
  ]
3601
3696
  }
3602
3697
  ),
3698
+ result.coverage && /* @__PURE__ */ jsxs("div", { style: { marginTop: 16 }, children: [
3699
+ /* @__PURE__ */ jsx(
3700
+ "div",
3701
+ {
3702
+ style: {
3703
+ fontSize: 12,
3704
+ fontWeight: 600,
3705
+ color: theme.colors.textMuted,
3706
+ marginBottom: 8
3707
+ },
3708
+ children: "Coverage Data"
3709
+ }
3710
+ ),
3711
+ /* @__PURE__ */ jsxs(
3712
+ "div",
3713
+ {
3714
+ style: {
3715
+ padding: 12,
3716
+ backgroundColor: theme.colors.surface,
3717
+ borderRadius: 4
3718
+ },
3719
+ children: [
3720
+ /* @__PURE__ */ jsxs(
3721
+ "div",
3722
+ {
3723
+ style: {
3724
+ display: "grid",
3725
+ gridTemplateColumns: "repeat(auto-fit, minmax(100px, 1fr))",
3726
+ gap: 12,
3727
+ marginBottom: 12
3728
+ },
3729
+ children: [
3730
+ /* @__PURE__ */ jsxs("div", { children: [
3731
+ /* @__PURE__ */ jsx(
3732
+ "div",
3733
+ {
3734
+ style: {
3735
+ fontSize: 11,
3736
+ color: theme.colors.textMuted
3737
+ },
3738
+ children: "Line"
3739
+ }
3740
+ ),
3741
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 14, fontWeight: 600 }, children: [
3742
+ result.coverage.line,
3743
+ "%"
3744
+ ] })
3745
+ ] }),
3746
+ result.coverage.branch !== void 0 && /* @__PURE__ */ jsxs("div", { children: [
3747
+ /* @__PURE__ */ jsx(
3748
+ "div",
3749
+ {
3750
+ style: {
3751
+ fontSize: 11,
3752
+ color: theme.colors.textMuted
3753
+ },
3754
+ children: "Branch"
3755
+ }
3756
+ ),
3757
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 14, fontWeight: 600 }, children: [
3758
+ result.coverage.branch,
3759
+ "%"
3760
+ ] })
3761
+ ] }),
3762
+ result.coverage.function !== void 0 && /* @__PURE__ */ jsxs("div", { children: [
3763
+ /* @__PURE__ */ jsx(
3764
+ "div",
3765
+ {
3766
+ style: {
3767
+ fontSize: 11,
3768
+ color: theme.colors.textMuted
3769
+ },
3770
+ children: "Function"
3771
+ }
3772
+ ),
3773
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 14, fontWeight: 600 }, children: [
3774
+ result.coverage.function,
3775
+ "%"
3776
+ ] })
3777
+ ] }),
3778
+ result.coverage.statement !== void 0 && /* @__PURE__ */ jsxs("div", { children: [
3779
+ /* @__PURE__ */ jsx(
3780
+ "div",
3781
+ {
3782
+ style: {
3783
+ fontSize: 11,
3784
+ color: theme.colors.textMuted
3785
+ },
3786
+ children: "Statement"
3787
+ }
3788
+ ),
3789
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 14, fontWeight: 600 }, children: [
3790
+ result.coverage.statement,
3791
+ "%"
3792
+ ] })
3793
+ ] })
3794
+ ]
3795
+ }
3796
+ ),
3797
+ /* @__PURE__ */ jsxs(
3798
+ "div",
3799
+ {
3800
+ style: {
3801
+ padding: 8,
3802
+ borderRadius: 4,
3803
+ backgroundColor: ((_t = result.coverage.files) == null ? void 0 : _t.length) ? "rgba(34, 197, 94, 0.1)" : "rgba(239, 68, 68, 0.1)",
3804
+ border: `1px solid ${((_u = result.coverage.files) == null ? void 0 : _u.length) ? "#22c55e" : "#ef4444"}`
3805
+ },
3806
+ children: [
3807
+ /* @__PURE__ */ jsxs(
3808
+ "div",
3809
+ {
3810
+ style: {
3811
+ fontSize: 12,
3812
+ fontWeight: 500,
3813
+ color: ((_v = result.coverage.files) == null ? void 0 : _v.length) ? "#22c55e" : "#ef4444"
3814
+ },
3815
+ children: [
3816
+ "coverage.files: ",
3817
+ ((_w = result.coverage.files) == null ? void 0 : _w.length) ?? 0,
3818
+ " ",
3819
+ "entries"
3820
+ ]
3821
+ }
3822
+ ),
3823
+ !((_x = result.coverage.files) == null ? void 0 : _x.length) && /* @__PURE__ */ jsx(
3824
+ "div",
3825
+ {
3826
+ style: {
3827
+ fontSize: 11,
3828
+ color: "#ef4444",
3829
+ marginTop: 4
3830
+ },
3831
+ children: "Warning: Coverage won't appear on map visualization!"
3832
+ }
3833
+ )
3834
+ ]
3835
+ }
3836
+ )
3837
+ ]
3838
+ }
3839
+ )
3840
+ ] }),
3603
3841
  filesWithIssues.size > 0 ? /* @__PURE__ */ jsxs("div", { children: [
3604
3842
  /* @__PURE__ */ jsxs(
3605
3843
  "div",
@@ -3888,6 +4126,98 @@ function LensDataDebugPanel$1({
3888
4126
  ))
3889
4127
  }
3890
4128
  )
4129
+ ] }),
4130
+ result.analyzedFiles && result.analyzedFiles.length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginTop: 16 }, children: [
4131
+ /* @__PURE__ */ jsxs(
4132
+ "div",
4133
+ {
4134
+ onClick: () => toggleAnalyzedFiles(lensKey),
4135
+ style: {
4136
+ fontSize: 12,
4137
+ fontWeight: 600,
4138
+ color: theme.colors.textMuted,
4139
+ marginBottom: 8,
4140
+ cursor: "pointer",
4141
+ display: "flex",
4142
+ alignItems: "center",
4143
+ gap: 6
4144
+ },
4145
+ children: [
4146
+ /* @__PURE__ */ jsx(
4147
+ "svg",
4148
+ {
4149
+ width: "12",
4150
+ height: "12",
4151
+ viewBox: "0 0 24 24",
4152
+ fill: "none",
4153
+ stroke: "currentColor",
4154
+ strokeWidth: "2",
4155
+ style: {
4156
+ transform: expandedAnalyzedFiles.has(lensKey) ? "rotate(90deg)" : "rotate(0deg)",
4157
+ transition: "transform 0.15s ease"
4158
+ },
4159
+ children: /* @__PURE__ */ jsx("polyline", { points: "9,18 15,12 9,6" })
4160
+ }
4161
+ ),
4162
+ "Analyzed Files (",
4163
+ result.analyzedFiles.length,
4164
+ ")"
4165
+ ]
4166
+ }
4167
+ ),
4168
+ expandedAnalyzedFiles.has(lensKey) && /* @__PURE__ */ jsx(
4169
+ "div",
4170
+ {
4171
+ style: {
4172
+ maxHeight: 300,
4173
+ overflow: "auto",
4174
+ padding: 8,
4175
+ backgroundColor: theme.colors.surface,
4176
+ borderRadius: 4
4177
+ },
4178
+ children: result.analyzedFiles.map((file, idx2) => /* @__PURE__ */ jsxs(
4179
+ "div",
4180
+ {
4181
+ style: {
4182
+ display: "flex",
4183
+ alignItems: "center",
4184
+ justifyContent: "space-between",
4185
+ padding: "4px 8px",
4186
+ fontSize: 12,
4187
+ borderRadius: 2,
4188
+ backgroundColor: file.hasIssues ? "rgba(239, 68, 68, 0.05)" : "transparent"
4189
+ },
4190
+ children: [
4191
+ /* @__PURE__ */ jsx(
4192
+ "span",
4193
+ {
4194
+ style: {
4195
+ color: theme.colors.text,
4196
+ cursor: onFileClick ? "pointer" : "default"
4197
+ },
4198
+ onClick: () => onFileClick == null ? void 0 : onFileClick(file.path),
4199
+ children: file.path
4200
+ }
4201
+ ),
4202
+ file.hasIssues && /* @__PURE__ */ jsx(
4203
+ "span",
4204
+ {
4205
+ style: {
4206
+ fontSize: 10,
4207
+ color: "#ef4444",
4208
+ padding: "1px 4px",
4209
+ borderRadius: 2,
4210
+ backgroundColor: "rgba(239, 68, 68, 0.1)"
4211
+ },
4212
+ children: "issues"
4213
+ }
4214
+ )
4215
+ ]
4216
+ },
4217
+ idx2
4218
+ ))
4219
+ }
4220
+ )
3891
4221
  ] })
3892
4222
  ]
3893
4223
  }
@@ -3903,15 +4233,54 @@ function LensDataDebugPanel$1({
3903
4233
  }
3904
4234
  const LensDataDebugPanelContent = ({
3905
4235
  context,
3906
- actions
4236
+ actions,
4237
+ events
3907
4238
  }) => {
4239
+ var _a;
3908
4240
  const { theme } = useTheme();
4241
+ const [selectedPackage, setSelectedPackage] = React2__default.useState(
4242
+ null
4243
+ );
3909
4244
  const lensResultsSlice = context.getSlice("lensResults");
3910
4245
  const hasSlice = context.hasSlice("lensResults");
3911
4246
  const isLoading = (lensResultsSlice == null ? void 0 : lensResultsSlice.loading) ?? false;
4247
+ const { packageNames, packagePathMap } = React2__default.useMemo(() => {
4248
+ var _a2;
4249
+ if (!((_a2 = lensResultsSlice == null ? void 0 : lensResultsSlice.data) == null ? void 0 : _a2.results))
4250
+ return { packageNames: [], packagePathMap: /* @__PURE__ */ new Map() };
4251
+ const names = /* @__PURE__ */ new Set();
4252
+ const pathMap = /* @__PURE__ */ new Map();
4253
+ lensResultsSlice.data.results.forEach((r2) => {
4254
+ var _a3, _b;
4255
+ const name = ((_a3 = r2.package) == null ? void 0 : _a3.name) ?? "unknown";
4256
+ const path = ((_b = r2.package) == null ? void 0 : _b.path) ?? "";
4257
+ names.add(name);
4258
+ if (path) pathMap.set(path, name);
4259
+ pathMap.set(name, name);
4260
+ });
4261
+ return { packageNames: Array.from(names), packagePathMap: pathMap };
4262
+ }, [(_a = lensResultsSlice == null ? void 0 : lensResultsSlice.data) == null ? void 0 : _a.results]);
4263
+ React2__default.useEffect(() => {
4264
+ if (packageNames.length > 0 && !selectedPackage) {
4265
+ setSelectedPackage(packageNames[0]);
4266
+ }
4267
+ }, [packageNames, selectedPackage]);
4268
+ React2__default.useEffect(() => {
4269
+ if (!events) return;
4270
+ const cleanup = events.on("package:select", (event) => {
4271
+ const payload = event.payload;
4272
+ if (!payload) return;
4273
+ const matchedPackage = packagePathMap.get(payload.packagePath) ?? packagePathMap.get(payload.packageName) ?? // Also try matching the last segment of the path
4274
+ packagePathMap.get(payload.packagePath.split("/").pop() ?? "");
4275
+ if (matchedPackage) {
4276
+ setSelectedPackage(matchedPackage);
4277
+ }
4278
+ });
4279
+ return cleanup;
4280
+ }, [events, packagePathMap]);
3912
4281
  const handleFileClick = (file, line) => {
3913
- var _a, _b, _c;
3914
- const repoPath = (_a = context.currentScope.repository) == null ? void 0 : _a.path;
4282
+ var _a2, _b, _c;
4283
+ const repoPath = (_a2 = context.currentScope.repository) == null ? void 0 : _a2.path;
3915
4284
  const fullPath = repoPath ? `${repoPath}/${file}` : file;
3916
4285
  if (line) {
3917
4286
  (_b = actions.openFile) == null ? void 0 : _b.call(actions, `${fullPath}:${line}`);
@@ -3963,34 +4332,34 @@ const LensDataDebugPanelContent = ({
3963
4332
  }
3964
4333
  )
3965
4334
  ] }),
3966
- (lensResultsSlice == null ? void 0 : lensResultsSlice.data) && /* @__PURE__ */ jsxs(
4335
+ (lensResultsSlice == null ? void 0 : lensResultsSlice.data) && packageNames.length > 0 && /* @__PURE__ */ jsx(
3967
4336
  "div",
3968
4337
  {
3969
4338
  style: {
3970
4339
  display: "flex",
3971
4340
  alignItems: "center",
3972
4341
  gap: 12,
3973
- fontSize: 11,
3974
- color: theme.colors.textMuted
4342
+ fontSize: 12
3975
4343
  },
3976
- children: [
3977
- /* @__PURE__ */ jsxs("span", { children: [
3978
- new Set(
3979
- lensResultsSlice.data.results.map(
3980
- (r2) => {
3981
- var _a;
3982
- return ((_a = r2.package) == null ? void 0 : _a.name) ?? "unknown";
3983
- }
3984
- )
3985
- ).size,
3986
- " ",
3987
- "packages"
3988
- ] }),
3989
- /* @__PURE__ */ jsxs("span", { children: [
3990
- lensResultsSlice.data.results.length,
3991
- " results"
3992
- ] })
3993
- ]
4344
+ children: packageNames.length > 1 ? /* @__PURE__ */ jsx(
4345
+ "select",
4346
+ {
4347
+ value: selectedPackage ?? "",
4348
+ onChange: (e) => setSelectedPackage(e.target.value),
4349
+ style: {
4350
+ padding: "4px 8px",
4351
+ borderRadius: 4,
4352
+ border: `1px solid ${theme.colors.border}`,
4353
+ backgroundColor: theme.colors.surface,
4354
+ color: theme.colors.text,
4355
+ fontFamily: theme.fonts.body,
4356
+ fontSize: 12,
4357
+ cursor: "pointer",
4358
+ outline: "none"
4359
+ },
4360
+ children: packageNames.map((pkg) => /* @__PURE__ */ jsx("option", { value: pkg, children: pkg }, pkg))
4361
+ }
4362
+ ) : /* @__PURE__ */ jsx("span", { style: { color: theme.colors.textMuted }, children: packageNames[0] })
3994
4363
  }
3995
4364
  )
3996
4365
  ]
@@ -4040,7 +4409,9 @@ const LensDataDebugPanelContent = ({
4040
4409
  {
4041
4410
  data: lensResultsSlice.data,
4042
4411
  theme,
4043
- onFileClick: handleFileClick
4412
+ onFileClick: handleFileClick,
4413
+ selectedPackage: selectedPackage ?? void 0,
4414
+ onPackageSelect: setSelectedPackage
4044
4415
  }
4045
4416
  )
4046
4417
  }