@principal-ade/code-quality-panels 0.1.20 → 0.1.22

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 (40) hide show
  1. package/README.md +27 -27
  2. package/dist/panels.bundle.js +1546 -820
  3. package/dist/panels.bundle.js.map +1 -1
  4. package/dist/src/components/LensDataDebugPanel.d.ts +2 -2
  5. package/dist/src/components/LensDataDebugPanel.d.ts.map +1 -1
  6. package/dist/src/components/LensDataDebugPanel.stories.d.ts +2 -2
  7. package/dist/src/components/LensDataDebugPanel.stories.d.ts.map +1 -1
  8. package/dist/src/components/QualityEmptyState.d.ts +2 -2
  9. package/dist/src/components/QualityEmptyState.d.ts.map +1 -1
  10. package/dist/src/components/QualityHexagon.d.ts +16 -10
  11. package/dist/src/components/QualityHexagon.d.ts.map +1 -1
  12. package/dist/src/components/QualityHexagon.stories.d.ts +2 -2
  13. package/dist/src/components/QualityHexagon.stories.d.ts.map +1 -1
  14. package/dist/src/components/QualityMetricsList.d.ts +4 -4
  15. package/dist/src/components/QualityMetricsList.d.ts.map +1 -1
  16. package/dist/src/components/QualityMetricsList.stories.d.ts +2 -2
  17. package/dist/src/components/QualityMetricsList.stories.d.ts.map +1 -1
  18. package/dist/src/components/RepositoryQualityGrid.d.ts +3 -3
  19. package/dist/src/components/RepositoryQualityGrid.d.ts.map +1 -1
  20. package/dist/src/components/RepositoryQualityGrid.stories.d.ts +2 -2
  21. package/dist/src/components/RepositoryQualityGrid.stories.d.ts.map +1 -1
  22. package/dist/src/components/index.d.ts +5 -5
  23. package/dist/src/index.d.ts +7 -7
  24. package/dist/src/index.d.ts.map +1 -1
  25. package/dist/src/mocks/panelContext.d.ts +2 -2
  26. package/dist/src/mocks/panelContext.d.ts.map +1 -1
  27. package/dist/src/panels/LensDataDebugPanel.d.ts +2 -2
  28. package/dist/src/panels/LensDataDebugPanel.d.ts.map +1 -1
  29. package/dist/src/panels/LensDataDebugPanel.stories.d.ts +1 -1
  30. package/dist/src/panels/LensDataDebugPanel.stories.d.ts.map +1 -1
  31. package/dist/src/panels/QualityHexagonPanel.d.ts +2 -2
  32. package/dist/src/panels/QualityHexagonPanel.d.ts.map +1 -1
  33. package/dist/src/panels/QualityHexagonPanel.stories.d.ts +1 -1
  34. package/dist/src/panels/QualityHexagonPanel.stories.d.ts.map +1 -1
  35. package/dist/src/panels/RepositoryQualityGridPanel.d.ts +2 -2
  36. package/dist/src/panels/RepositoryQualityGridPanel.d.ts.map +1 -1
  37. package/dist/src/panels/RepositoryQualityGridPanel.stories.d.ts +1 -1
  38. package/dist/src/panels/RepositoryQualityGridPanel.stories.d.ts.map +1 -1
  39. package/dist/src/types/index.d.ts +1 -1
  40. package/package.json +1 -1
@@ -379,11 +379,31 @@ function getThemeColors(theme) {
379
379
  textColor: theme.colors.text,
380
380
  scoreColor: theme.colors.text,
381
381
  tierColors: {
382
- none: { fill: "#808080", stroke: "#808080", bg: theme.colors.backgroundLight },
383
- bronze: { fill: "#CD7F32", stroke: "#CD7F32", bg: theme.colors.backgroundLight },
384
- silver: { fill: "#C0C0C0", stroke: "#C0C0C0", bg: theme.colors.backgroundLight },
385
- gold: { fill: "#FFD700", stroke: "#FFD700", bg: theme.colors.backgroundLight },
386
- platinum: { fill: "#E5E4E2", stroke: "#E5E4E2", bg: theme.colors.backgroundLight }
382
+ none: {
383
+ fill: "#808080",
384
+ stroke: "#808080",
385
+ bg: theme.colors.backgroundLight
386
+ },
387
+ bronze: {
388
+ fill: "#CD7F32",
389
+ stroke: "#CD7F32",
390
+ bg: theme.colors.backgroundLight
391
+ },
392
+ silver: {
393
+ fill: "#C0C0C0",
394
+ stroke: "#C0C0C0",
395
+ bg: theme.colors.backgroundLight
396
+ },
397
+ gold: {
398
+ fill: "#FFD700",
399
+ stroke: "#FFD700",
400
+ bg: theme.colors.backgroundLight
401
+ },
402
+ platinum: {
403
+ fill: "#E5E4E2",
404
+ stroke: "#E5E4E2",
405
+ bg: theme.colors.backgroundLight
406
+ }
387
407
  },
388
408
  metricColors: {
389
409
  types: theme.colors.warning,
@@ -406,13 +426,80 @@ function getValueColor$2(value, key) {
406
426
  if (effectiveValue >= 60) return "#E6A700";
407
427
  return "#C62828";
408
428
  }
429
+ const LENS_TO_METRIC_MAP = {
430
+ // Linting tools
431
+ eslint: "linting",
432
+ biome: "linting",
433
+ "biome-lint": "linting",
434
+ oxlint: "linting",
435
+ // Type checking tools
436
+ typescript: "types",
437
+ flow: "types",
438
+ // Testing tools
439
+ test: "tests",
440
+ jest: "tests",
441
+ vitest: "tests",
442
+ "bun-test": "tests",
443
+ mocha: "tests",
444
+ playwright: "tests",
445
+ cypress: "tests",
446
+ // Formatting tools
447
+ prettier: "formatting",
448
+ "biome-format": "formatting",
449
+ // Dead code detection
450
+ knip: "deadCode",
451
+ depcheck: "deadCode",
452
+ // Documentation
453
+ typedoc: "documentation",
454
+ jsdoc: "documentation",
455
+ alexandria: "documentation"
456
+ };
457
+ function isMetricConfigured(metricKey, lensesRan) {
458
+ if (lensesRan === void 0) {
459
+ return true;
460
+ }
461
+ if (lensesRan.length === 0) {
462
+ return false;
463
+ }
464
+ return lensesRan.some((lensId) => LENS_TO_METRIC_MAP[lensId] === metricKey);
465
+ }
409
466
  const getMetricConfig = (themeColors) => [
410
- { key: "formatting", label: "Format", color: themeColors.metricColors.formatting, angle: -120 },
411
- { key: "linting", label: "Linting", color: themeColors.metricColors.linting, angle: -60 },
412
- { key: "types", label: "Types", color: themeColors.metricColors.types, angle: 0 },
413
- { key: "tests", label: "Tests", color: themeColors.metricColors.tests, angle: 60 },
414
- { key: "deadCode", label: "Dead Code", color: themeColors.metricColors.deadCode, angle: 120 },
415
- { key: "documentation", label: "Docs", color: themeColors.metricColors.documentation, angle: 180 }
467
+ {
468
+ key: "formatting",
469
+ label: "Format",
470
+ color: themeColors.metricColors.formatting,
471
+ angle: -120
472
+ },
473
+ {
474
+ key: "linting",
475
+ label: "Linting",
476
+ color: themeColors.metricColors.linting,
477
+ angle: -60
478
+ },
479
+ {
480
+ key: "types",
481
+ label: "Types",
482
+ color: themeColors.metricColors.types,
483
+ angle: 0
484
+ },
485
+ {
486
+ key: "tests",
487
+ label: "Tests",
488
+ color: themeColors.metricColors.tests,
489
+ angle: 60
490
+ },
491
+ {
492
+ key: "deadCode",
493
+ label: "Dead Code",
494
+ color: themeColors.metricColors.deadCode,
495
+ angle: 120
496
+ },
497
+ {
498
+ key: "documentation",
499
+ label: "Docs",
500
+ color: themeColors.metricColors.documentation,
501
+ angle: 180
502
+ }
416
503
  ];
417
504
  function calculateHexagonPoints(center, radius, metricConfig) {
418
505
  return metricConfig.map(({ angle }) => {
@@ -437,6 +524,7 @@ function QualityHexagon({
437
524
  showLabels = false,
438
525
  showValues = false,
439
526
  className,
527
+ lensesRan,
440
528
  onVertexHover,
441
529
  onVertexLeave,
442
530
  onVertexClick
@@ -453,17 +541,26 @@ function QualityHexagon({
453
541
  const dotSize = viewBoxSize * 0.015;
454
542
  const hexagonPoints = calculateHexagonPoints(center, radius, metricConfig);
455
543
  const dataPoints = metricConfig.map(({ key, angle }) => {
544
+ const configured = isMetricConfigured(key, lensesRan);
545
+ if (!configured) {
546
+ return calculateMetricPoint(center, radius, angle, 0);
547
+ }
456
548
  let value = metrics[key];
457
549
  if (key === "deadCode") {
458
550
  value = 100 - value;
459
551
  }
460
552
  return calculateMetricPoint(center, radius, angle, value);
461
553
  }).map((p) => `${p.x},${p.y}`).join(" ");
462
- const metricsForAverage = { ...metrics };
463
- metricsForAverage.deadCode = 100 - metricsForAverage.deadCode;
464
- const averageScore = Math.round(
465
- Object.values(metricsForAverage).reduce((a, b) => a + b, 0) / 6
554
+ const configuredMetrics = metricConfig.filter(
555
+ ({ key }) => isMetricConfigured(key, lensesRan)
466
556
  );
557
+ const metricsForAverage = configuredMetrics.map(({ key }) => {
558
+ const value = metrics[key];
559
+ return key === "deadCode" ? 100 - value : value;
560
+ });
561
+ const averageScore = metricsForAverage.length > 0 ? Math.round(
562
+ metricsForAverage.reduce((a, b) => a + b, 0) / metricsForAverage.length
563
+ ) : 0;
467
564
  const hexagon = /* @__PURE__ */ jsxs(
468
565
  "svg",
469
566
  {
@@ -474,7 +571,11 @@ function QualityHexagon({
474
571
  /* @__PURE__ */ jsx("g", { className: "opacity-20", children: [20, 40, 60, 80, 100].map((percent) => /* @__PURE__ */ jsx(
475
572
  "polygon",
476
573
  {
477
- points: calculateHexagonPoints(center, radius * percent / 100, metricConfig),
574
+ points: calculateHexagonPoints(
575
+ center,
576
+ radius * percent / 100,
577
+ metricConfig
578
+ ),
478
579
  fill: "none",
479
580
  stroke: themeColors.gridColor,
480
581
  strokeWidth: 0.5,
@@ -520,13 +621,20 @@ function QualityHexagon({
520
621
  }
521
622
  ),
522
623
  metricConfig.map(({ key, label, color, angle }) => {
624
+ const configured = isMetricConfigured(key, lensesRan);
523
625
  const rawValue = metrics[key];
524
626
  let value = rawValue;
525
627
  if (key === "deadCode") {
526
628
  value = 100 - value;
527
629
  }
630
+ const effectiveValue = configured ? value : 0;
528
631
  const point = calculateMetricPoint(center, radius, angle, 100);
529
- const dataPoint = calculateMetricPoint(center, radius, angle, value);
632
+ const dataPoint = calculateMetricPoint(
633
+ center,
634
+ radius,
635
+ angle,
636
+ effectiveValue
637
+ );
530
638
  const vertexInfo = {
531
639
  key,
532
640
  label,
@@ -538,7 +646,9 @@ function QualityHexagon({
538
646
  };
539
647
  const handleClick = (e) => {
540
648
  e.stopPropagation();
541
- onVertexClick == null ? void 0 : onVertexClick(vertexInfo);
649
+ if (configured) {
650
+ onVertexClick == null ? void 0 : onVertexClick(vertexInfo);
651
+ }
542
652
  };
543
653
  return /* @__PURE__ */ jsxs(
544
654
  "g",
@@ -546,7 +656,10 @@ function QualityHexagon({
546
656
  onMouseEnter: handleMouseEnter,
547
657
  onMouseLeave: onVertexLeave,
548
658
  onClick: handleClick,
549
- style: { cursor: onVertexHover || onVertexClick ? "pointer" : "default" },
659
+ style: {
660
+ cursor: configured && (onVertexHover || onVertexClick) ? "pointer" : "default",
661
+ opacity: configured ? 1 : 0.4
662
+ },
550
663
  children: [
551
664
  /* @__PURE__ */ jsx(
552
665
  "circle",
@@ -563,12 +676,13 @@ function QualityHexagon({
563
676
  cx: point.x,
564
677
  cy: point.y,
565
678
  r: dotSize,
566
- fill: "white",
567
- stroke: colors.stroke,
568
- strokeWidth: 1.5
679
+ fill: configured ? "white" : themeColors.gridColor,
680
+ stroke: configured ? colors.stroke : themeColors.gridColor,
681
+ strokeWidth: 1.5,
682
+ strokeDasharray: configured ? "none" : "2,2"
569
683
  }
570
684
  ),
571
- /* @__PURE__ */ jsx(
685
+ configured && /* @__PURE__ */ jsx(
572
686
  "circle",
573
687
  {
574
688
  cx: dataPoint.x,
@@ -678,117 +792,190 @@ function QualityHexagonDetailed({
678
792
  backgroundColor: colors.bg
679
793
  },
680
794
  children: [
681
- hasHeader && /* @__PURE__ */ jsxs("div", { style: {
682
- display: "flex",
683
- alignItems: "center",
684
- justifyContent: "space-between",
685
- gap: 12
686
- }, children: [
687
- packageName ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
688
- packageName.startsWith("@") && packageName.includes("/") ? /* @__PURE__ */ jsxs(Fragment, { children: [
689
- /* @__PURE__ */ jsx("span", { style: {
690
- fontSize: 12,
691
- color: theme.colors.textMuted
692
- }, children: packageName.split("/")[0] }),
693
- /* @__PURE__ */ jsx("span", { style: {
694
- fontSize: 14,
695
- fontWeight: 500,
696
- color: colors.stroke
697
- }, children: packageName.split("/")[1] })
698
- ] }) : /* @__PURE__ */ jsx("span", { style: {
699
- fontSize: 14,
700
- fontWeight: 500,
701
- color: colors.stroke
702
- }, children: packageName }),
703
- packageVersion && /* @__PURE__ */ jsxs("span", { style: {
704
- fontSize: 12,
705
- color: theme.colors.textMuted
706
- }, children: [
707
- "v",
708
- packageVersion
709
- ] })
710
- ] }) : /* @__PURE__ */ jsx("span", {}),
711
- onRefresh && /* @__PURE__ */ jsx(
712
- "button",
713
- {
714
- onClick: onRefresh,
715
- disabled: isRefreshing,
716
- style: {
717
- padding: 6,
718
- display: "flex",
719
- alignItems: "center",
720
- justifyContent: "center",
721
- border: `1px solid ${theme.colors.border}`,
722
- borderRadius: 4,
723
- background: theme.colors.surface,
724
- color: theme.colors.textMuted,
725
- cursor: isRefreshing ? "not-allowed" : "pointer",
726
- opacity: isRefreshing ? 0.6 : 1
727
- },
728
- title: "Refresh",
729
- children: /* @__PURE__ */ jsxs(
730
- "svg",
795
+ hasHeader && /* @__PURE__ */ jsxs(
796
+ "div",
797
+ {
798
+ style: {
799
+ display: "flex",
800
+ alignItems: "center",
801
+ justifyContent: "space-between",
802
+ gap: 12
803
+ },
804
+ children: [
805
+ packageName ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
806
+ packageName.startsWith("@") && packageName.includes("/") ? /* @__PURE__ */ jsxs(Fragment, { children: [
807
+ /* @__PURE__ */ jsx(
808
+ "span",
809
+ {
810
+ style: {
811
+ fontSize: 12,
812
+ color: theme.colors.textMuted
813
+ },
814
+ children: packageName.split("/")[0]
815
+ }
816
+ ),
817
+ /* @__PURE__ */ jsx(
818
+ "span",
819
+ {
820
+ style: {
821
+ fontSize: 14,
822
+ fontWeight: 500,
823
+ color: colors.stroke
824
+ },
825
+ children: packageName.split("/")[1]
826
+ }
827
+ )
828
+ ] }) : /* @__PURE__ */ jsx(
829
+ "span",
830
+ {
831
+ style: {
832
+ fontSize: 14,
833
+ fontWeight: 500,
834
+ color: colors.stroke
835
+ },
836
+ children: packageName
837
+ }
838
+ ),
839
+ packageVersion && /* @__PURE__ */ jsxs(
840
+ "span",
841
+ {
842
+ style: {
843
+ fontSize: 12,
844
+ color: theme.colors.textMuted
845
+ },
846
+ children: [
847
+ "v",
848
+ packageVersion
849
+ ]
850
+ }
851
+ )
852
+ ] }) : /* @__PURE__ */ jsx("span", {}),
853
+ onRefresh && /* @__PURE__ */ jsx(
854
+ "button",
731
855
  {
732
- width: "14",
733
- height: "14",
734
- viewBox: "0 0 24 24",
735
- fill: "none",
736
- stroke: "currentColor",
737
- strokeWidth: "2",
738
- strokeLinecap: "round",
739
- strokeLinejoin: "round",
856
+ onClick: onRefresh,
857
+ disabled: isRefreshing,
740
858
  style: {
741
- animation: isRefreshing ? "spin 1s linear infinite" : "none"
859
+ padding: 6,
860
+ display: "flex",
861
+ alignItems: "center",
862
+ justifyContent: "center",
863
+ border: `1px solid ${theme.colors.border}`,
864
+ borderRadius: 4,
865
+ background: theme.colors.surface,
866
+ color: theme.colors.textMuted,
867
+ cursor: isRefreshing ? "not-allowed" : "pointer",
868
+ opacity: isRefreshing ? 0.6 : 1
742
869
  },
743
- children: [
744
- /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
745
- /* @__PURE__ */ jsx("path", { d: "M3 3v5h5" }),
746
- /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" }),
747
- /* @__PURE__ */ jsx("path", { d: "M16 16h5v5" })
748
- ]
870
+ title: "Refresh",
871
+ children: /* @__PURE__ */ jsxs(
872
+ "svg",
873
+ {
874
+ width: "14",
875
+ height: "14",
876
+ viewBox: "0 0 24 24",
877
+ fill: "none",
878
+ stroke: "currentColor",
879
+ strokeWidth: "2",
880
+ strokeLinecap: "round",
881
+ strokeLinejoin: "round",
882
+ style: {
883
+ animation: isRefreshing ? "spin 1s linear infinite" : "none"
884
+ },
885
+ children: [
886
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
887
+ /* @__PURE__ */ jsx("path", { d: "M3 3v5h5" }),
888
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" }),
889
+ /* @__PURE__ */ jsx("path", { d: "M16 16h5v5" })
890
+ ]
891
+ }
892
+ )
749
893
  }
750
894
  )
751
- }
752
- )
753
- ] }),
754
- /* @__PURE__ */ jsxs("div", { style: {
755
- display: "flex",
756
- flexWrap: "wrap",
757
- alignItems: "center",
758
- justifyContent: "center",
759
- gap: 24
760
- }, children: [
761
- /* @__PURE__ */ jsx("div", { style: { flex: "1 1 200px", maxWidth: 300, aspectRatio: "1 / 1" }, children: /* @__PURE__ */ jsx(
762
- QualityHexagon,
763
- {
764
- metrics,
765
- tier,
766
- theme,
767
- showLabels: true,
768
- showValues: false
769
- }
770
- ) }),
771
- /* @__PURE__ */ jsx("div", { style: { flex: "1 1 200px", minWidth: 200, display: "flex", flexDirection: "column", gap: 8, padding: "8px 24px" }, children: metricConfig.map(({ key, label }) => {
772
- const value = metrics[key];
773
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }, children: [
774
- /* @__PURE__ */ jsxs("span", { style: {
775
- fontSize: 14,
776
- color: theme.colors.textMuted
777
- }, children: [
778
- label,
779
- key === "deadCode" ? " ↓" : ""
780
- ] }),
781
- /* @__PURE__ */ jsxs("span", { style: {
782
- fontSize: 14,
783
- fontWeight: 500,
784
- color: getValueColor$2(value, key)
785
- }, children: [
786
- value,
787
- "%"
788
- ] })
789
- ] }, key);
790
- }) })
791
- ] })
895
+ ]
896
+ }
897
+ ),
898
+ /* @__PURE__ */ jsxs(
899
+ "div",
900
+ {
901
+ style: {
902
+ display: "flex",
903
+ flexWrap: "wrap",
904
+ alignItems: "center",
905
+ justifyContent: "center",
906
+ gap: 24
907
+ },
908
+ children: [
909
+ /* @__PURE__ */ jsx("div", { style: { flex: "1 1 200px", maxWidth: 300, aspectRatio: "1 / 1" }, children: /* @__PURE__ */ jsx(
910
+ QualityHexagon,
911
+ {
912
+ metrics,
913
+ tier,
914
+ theme,
915
+ showLabels: true,
916
+ showValues: false
917
+ }
918
+ ) }),
919
+ /* @__PURE__ */ jsx(
920
+ "div",
921
+ {
922
+ style: {
923
+ flex: "1 1 200px",
924
+ minWidth: 200,
925
+ display: "flex",
926
+ flexDirection: "column",
927
+ gap: 8,
928
+ padding: "8px 24px"
929
+ },
930
+ children: metricConfig.map(({ key, label }) => {
931
+ const value = metrics[key];
932
+ return /* @__PURE__ */ jsxs(
933
+ "div",
934
+ {
935
+ style: {
936
+ display: "flex",
937
+ alignItems: "center",
938
+ justifyContent: "space-between",
939
+ gap: 12
940
+ },
941
+ children: [
942
+ /* @__PURE__ */ jsxs(
943
+ "span",
944
+ {
945
+ style: {
946
+ fontSize: 14,
947
+ color: theme.colors.textMuted
948
+ },
949
+ children: [
950
+ label,
951
+ key === "deadCode" ? " ↓" : ""
952
+ ]
953
+ }
954
+ ),
955
+ /* @__PURE__ */ jsxs(
956
+ "span",
957
+ {
958
+ style: {
959
+ fontSize: 14,
960
+ fontWeight: 500,
961
+ color: getValueColor$2(value, key)
962
+ },
963
+ children: [
964
+ value,
965
+ "%"
966
+ ]
967
+ }
968
+ )
969
+ ]
970
+ },
971
+ key
972
+ );
973
+ })
974
+ }
975
+ )
976
+ ]
977
+ }
978
+ )
792
979
  ]
793
980
  }
794
981
  );
@@ -801,6 +988,7 @@ function QualityHexagonExpandable({
801
988
  packageName,
802
989
  packageVersion,
803
990
  packagePath,
991
+ lensesRan,
804
992
  onRefresh,
805
993
  isRefreshing = false,
806
994
  defaultExpanded = false,
@@ -831,79 +1019,109 @@ function QualityHexagonExpandable({
831
1019
  flex: "1 1 200px"
832
1020
  },
833
1021
  children: [
834
- hasHeader && /* @__PURE__ */ jsxs("div", { style: {
835
- display: "flex",
836
- alignItems: "center",
837
- justifyContent: "space-between",
838
- gap: 12
839
- }, children: [
840
- packageName ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
841
- packageName.startsWith("@") && packageName.includes("/") ? /* @__PURE__ */ jsxs(Fragment, { children: [
842
- /* @__PURE__ */ jsx("span", { style: {
843
- fontSize: 12,
844
- color: theme.colors.textMuted
845
- }, children: packageName.split("/")[0] }),
846
- /* @__PURE__ */ jsx("span", { style: {
847
- fontSize: 14,
848
- fontWeight: 500,
849
- color: colors.stroke
850
- }, children: packageName.split("/")[1] })
851
- ] }) : /* @__PURE__ */ jsx("span", { style: {
852
- fontSize: 14,
853
- fontWeight: 500,
854
- color: colors.stroke
855
- }, children: packageName }),
856
- packageVersion && /* @__PURE__ */ jsxs("span", { style: {
857
- fontSize: 12,
858
- color: theme.colors.textMuted
859
- }, children: [
860
- "v",
861
- packageVersion
862
- ] })
863
- ] }) : /* @__PURE__ */ jsx("span", {}),
864
- onRefresh && /* @__PURE__ */ jsx(
865
- "button",
866
- {
867
- onClick: onRefresh,
868
- disabled: isRefreshing,
869
- style: {
870
- padding: 6,
871
- display: "flex",
872
- alignItems: "center",
873
- justifyContent: "center",
874
- border: `1px solid ${theme.colors.border}`,
875
- borderRadius: 4,
876
- background: theme.colors.surface,
877
- color: theme.colors.textMuted,
878
- cursor: isRefreshing ? "not-allowed" : "pointer",
879
- opacity: isRefreshing ? 0.6 : 1
880
- },
881
- title: "Refresh",
882
- children: /* @__PURE__ */ jsxs(
883
- "svg",
1022
+ hasHeader && /* @__PURE__ */ jsxs(
1023
+ "div",
1024
+ {
1025
+ style: {
1026
+ display: "flex",
1027
+ alignItems: "center",
1028
+ justifyContent: "space-between",
1029
+ gap: 12
1030
+ },
1031
+ children: [
1032
+ packageName ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
1033
+ packageName.startsWith("@") && packageName.includes("/") ? /* @__PURE__ */ jsxs(Fragment, { children: [
1034
+ /* @__PURE__ */ jsx(
1035
+ "span",
1036
+ {
1037
+ style: {
1038
+ fontSize: 12,
1039
+ color: theme.colors.textMuted
1040
+ },
1041
+ children: packageName.split("/")[0]
1042
+ }
1043
+ ),
1044
+ /* @__PURE__ */ jsx(
1045
+ "span",
1046
+ {
1047
+ style: {
1048
+ fontSize: 14,
1049
+ fontWeight: 500,
1050
+ color: colors.stroke
1051
+ },
1052
+ children: packageName.split("/")[1]
1053
+ }
1054
+ )
1055
+ ] }) : /* @__PURE__ */ jsx(
1056
+ "span",
1057
+ {
1058
+ style: {
1059
+ fontSize: 14,
1060
+ fontWeight: 500,
1061
+ color: colors.stroke
1062
+ },
1063
+ children: packageName
1064
+ }
1065
+ ),
1066
+ packageVersion && /* @__PURE__ */ jsxs(
1067
+ "span",
1068
+ {
1069
+ style: {
1070
+ fontSize: 12,
1071
+ color: theme.colors.textMuted
1072
+ },
1073
+ children: [
1074
+ "v",
1075
+ packageVersion
1076
+ ]
1077
+ }
1078
+ )
1079
+ ] }) : /* @__PURE__ */ jsx("span", {}),
1080
+ onRefresh && /* @__PURE__ */ jsx(
1081
+ "button",
884
1082
  {
885
- width: "14",
886
- height: "14",
887
- viewBox: "0 0 24 24",
888
- fill: "none",
889
- stroke: "currentColor",
890
- strokeWidth: "2",
891
- strokeLinecap: "round",
892
- strokeLinejoin: "round",
1083
+ onClick: onRefresh,
1084
+ disabled: isRefreshing,
893
1085
  style: {
894
- animation: isRefreshing ? "spin 1s linear infinite" : "none"
1086
+ padding: 6,
1087
+ display: "flex",
1088
+ alignItems: "center",
1089
+ justifyContent: "center",
1090
+ border: `1px solid ${theme.colors.border}`,
1091
+ borderRadius: 4,
1092
+ background: theme.colors.surface,
1093
+ color: theme.colors.textMuted,
1094
+ cursor: isRefreshing ? "not-allowed" : "pointer",
1095
+ opacity: isRefreshing ? 0.6 : 1
895
1096
  },
896
- children: [
897
- /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
898
- /* @__PURE__ */ jsx("path", { d: "M3 3v5h5" }),
899
- /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" }),
900
- /* @__PURE__ */ jsx("path", { d: "M16 16h5v5" })
901
- ]
1097
+ title: "Refresh",
1098
+ children: /* @__PURE__ */ jsxs(
1099
+ "svg",
1100
+ {
1101
+ width: "14",
1102
+ height: "14",
1103
+ viewBox: "0 0 24 24",
1104
+ fill: "none",
1105
+ stroke: "currentColor",
1106
+ strokeWidth: "2",
1107
+ strokeLinecap: "round",
1108
+ strokeLinejoin: "round",
1109
+ style: {
1110
+ animation: isRefreshing ? "spin 1s linear infinite" : "none"
1111
+ },
1112
+ children: [
1113
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
1114
+ /* @__PURE__ */ jsx("path", { d: "M3 3v5h5" }),
1115
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" }),
1116
+ /* @__PURE__ */ jsx("path", { d: "M16 16h5v5" })
1117
+ ]
1118
+ }
1119
+ )
902
1120
  }
903
1121
  )
904
- }
905
- )
906
- ] }),
1122
+ ]
1123
+ }
1124
+ ),
907
1125
  /* @__PURE__ */ jsx(
908
1126
  "div",
909
1127
  {
@@ -921,7 +1139,8 @@ function QualityHexagonExpandable({
921
1139
  tier,
922
1140
  theme,
923
1141
  showLabels: true,
924
- showValues: false
1142
+ showValues: false,
1143
+ lensesRan
925
1144
  }
926
1145
  ) })
927
1146
  }
@@ -934,72 +1153,92 @@ function QualityHexagonExpandable({
934
1153
  gridTemplateRows: expanded ? "1fr" : "0fr",
935
1154
  transition: "grid-template-rows 0.3s ease"
936
1155
  },
937
- children: /* @__PURE__ */ jsx("div", { style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx("div", { style: {
938
- display: "flex",
939
- flexDirection: "column",
940
- gap: 8,
941
- padding: "8px 24px",
942
- borderTop: `1px solid ${theme.colors.border}`,
943
- marginTop: 8
944
- }, children: metricConfig.map(({ key, label }) => {
945
- const value = metrics[key];
946
- return /* @__PURE__ */ jsxs(
947
- "div",
948
- {
949
- onClick: (e) => {
950
- e.stopPropagation();
951
- onMetricClick == null ? void 0 : onMetricClick(key);
952
- },
953
- style: {
954
- display: "flex",
955
- alignItems: "center",
956
- justifyContent: "space-between",
957
- gap: 12,
958
- cursor: onMetricClick ? "pointer" : "default",
959
- padding: "4px 8px",
960
- margin: "0 -8px",
961
- borderRadius: 4,
962
- transition: "background-color 0.15s ease"
963
- },
964
- onMouseEnter: (e) => {
965
- if (onMetricClick) {
966
- e.currentTarget.style.backgroundColor = theme.colors.surface;
967
- }
968
- },
969
- onMouseLeave: (e) => {
970
- e.currentTarget.style.backgroundColor = "transparent";
971
- },
972
- children: [
973
- /* @__PURE__ */ jsxs("span", { style: {
974
- fontSize: 14,
975
- color: theme.colors.textMuted
976
- }, children: [
977
- label,
978
- key === "deadCode" ? " ↓" : ""
979
- ] }),
980
- /* @__PURE__ */ jsxs("span", { style: {
981
- fontSize: 14,
982
- fontWeight: 500,
983
- color: getValueColor$2(value, key)
984
- }, children: [
985
- value,
986
- "%"
987
- ] })
988
- ]
1156
+ children: /* @__PURE__ */ jsx("div", { style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(
1157
+ "div",
1158
+ {
1159
+ style: {
1160
+ display: "flex",
1161
+ flexDirection: "column",
1162
+ gap: 8,
1163
+ padding: "8px 24px",
1164
+ borderTop: `1px solid ${theme.colors.border}`,
1165
+ marginTop: 8
989
1166
  },
990
- key
991
- );
992
- }) }) })
993
- }
994
- ),
995
- /* @__PURE__ */ jsx(
996
- "div",
997
- {
998
- onClick: handleToggleExpand,
999
- style: {
1000
- display: "flex",
1001
- justifyContent: "center",
1002
- cursor: "pointer",
1167
+ children: metricConfig.map(({ key, label }) => {
1168
+ const value = metrics[key];
1169
+ const configured = isMetricConfigured(key, lensesRan);
1170
+ return /* @__PURE__ */ jsxs(
1171
+ "div",
1172
+ {
1173
+ onClick: (e) => {
1174
+ e.stopPropagation();
1175
+ if (configured) {
1176
+ onMetricClick == null ? void 0 : onMetricClick(key);
1177
+ }
1178
+ },
1179
+ style: {
1180
+ display: "flex",
1181
+ alignItems: "center",
1182
+ justifyContent: "space-between",
1183
+ gap: 12,
1184
+ cursor: configured && onMetricClick ? "pointer" : "default",
1185
+ padding: "4px 8px",
1186
+ margin: "0 -8px",
1187
+ borderRadius: 4,
1188
+ transition: "background-color 0.15s ease",
1189
+ opacity: configured ? 1 : 0.5
1190
+ },
1191
+ onMouseEnter: (e) => {
1192
+ if (configured && onMetricClick) {
1193
+ e.currentTarget.style.backgroundColor = theme.colors.surface;
1194
+ }
1195
+ },
1196
+ onMouseLeave: (e) => {
1197
+ e.currentTarget.style.backgroundColor = "transparent";
1198
+ },
1199
+ children: [
1200
+ /* @__PURE__ */ jsxs(
1201
+ "span",
1202
+ {
1203
+ style: {
1204
+ fontSize: 14,
1205
+ color: theme.colors.textMuted
1206
+ },
1207
+ children: [
1208
+ label,
1209
+ key === "deadCode" ? " ↓" : ""
1210
+ ]
1211
+ }
1212
+ ),
1213
+ /* @__PURE__ */ jsx(
1214
+ "span",
1215
+ {
1216
+ style: {
1217
+ fontSize: 14,
1218
+ fontWeight: 500,
1219
+ color: configured ? getValueColor$2(value, key) : theme.colors.textMuted
1220
+ },
1221
+ title: configured ? void 0 : "Not configured",
1222
+ children: configured ? `${value}%` : "N/A"
1223
+ }
1224
+ )
1225
+ ]
1226
+ },
1227
+ key
1228
+ );
1229
+ })
1230
+ }
1231
+ ) })
1232
+ }
1233
+ ),
1234
+ /* @__PURE__ */ jsx(
1235
+ "div",
1236
+ {
1237
+ onClick: handleToggleExpand,
1238
+ style: {
1239
+ display: "flex",
1240
+ justifyContent: "center",
1241
+ cursor: "pointer",
1003
1242
  padding: 4
1004
1243
  },
1005
1244
  children: /* @__PURE__ */ jsx(
@@ -1026,10 +1265,26 @@ function QualityHexagonExpandable({
1026
1265
  }
1027
1266
  );
1028
1267
  }
1029
- function calculateQualityTier(metrics) {
1030
- const metricsForAverage = { ...metrics };
1031
- metricsForAverage.deadCode = 100 - metricsForAverage.deadCode;
1032
- const average = Object.values(metricsForAverage).reduce((a, b) => a + b, 0) / 6;
1268
+ function calculateQualityTier(metrics, lensesRan) {
1269
+ const allMetricKeys = [
1270
+ "formatting",
1271
+ "linting",
1272
+ "types",
1273
+ "tests",
1274
+ "deadCode",
1275
+ "documentation"
1276
+ ];
1277
+ const configuredKeys = allMetricKeys.filter(
1278
+ (key) => isMetricConfigured(key, lensesRan)
1279
+ );
1280
+ if (configuredKeys.length === 0) {
1281
+ return "none";
1282
+ }
1283
+ const values = configuredKeys.map((key) => {
1284
+ const value = metrics[key];
1285
+ return key === "deadCode" ? 100 - value : value;
1286
+ });
1287
+ const average = values.reduce((a, b) => a + b, 0) / values.length;
1033
1288
  if (average >= 90) return "platinum";
1034
1289
  if (average >= 75) return "gold";
1035
1290
  if (average >= 60) return "silver";
@@ -1100,12 +1355,42 @@ const CommandLine = ({ command, theme, label }) => {
1100
1355
  };
1101
1356
  const MetricsPreview = ({ theme }) => {
1102
1357
  const metrics = [
1103
- { key: "formatting", label: "Formatting", description: "Prettier code style", Icon: Sparkles },
1104
- { key: "linting", label: "Linting", description: "ESLint code quality", Icon: FileSearch },
1105
- { key: "types", label: "Types", description: "TypeScript type safety", Icon: Braces },
1106
- { key: "tests", label: "Tests", description: "Test coverage & pass rate", Icon: FlaskConical },
1107
- { key: "deadCode", label: "Dead Code", description: "Unused exports & deps", Icon: Trash2 },
1108
- { key: "documentation", label: "Docs", description: "Code documentation", Icon: BookOpen }
1358
+ {
1359
+ key: "formatting",
1360
+ label: "Formatting",
1361
+ description: "Prettier code style",
1362
+ Icon: Sparkles
1363
+ },
1364
+ {
1365
+ key: "linting",
1366
+ label: "Linting",
1367
+ description: "ESLint code quality",
1368
+ Icon: FileSearch
1369
+ },
1370
+ {
1371
+ key: "types",
1372
+ label: "Types",
1373
+ description: "TypeScript type safety",
1374
+ Icon: Braces
1375
+ },
1376
+ {
1377
+ key: "tests",
1378
+ label: "Tests",
1379
+ description: "Test coverage & pass rate",
1380
+ Icon: FlaskConical
1381
+ },
1382
+ {
1383
+ key: "deadCode",
1384
+ label: "Dead Code",
1385
+ description: "Unused exports & deps",
1386
+ Icon: Trash2
1387
+ },
1388
+ {
1389
+ key: "documentation",
1390
+ label: "Docs",
1391
+ description: "Code documentation",
1392
+ Icon: BookOpen
1393
+ }
1109
1394
  ];
1110
1395
  return /* @__PURE__ */ jsx(
1111
1396
  "div",
@@ -1209,13 +1494,32 @@ const QualityEmptyState = ({
1209
1494
  color: theme.colors.textMuted
1210
1495
  },
1211
1496
  children: [
1212
- /* @__PURE__ */ jsx(Info, { size: 14, style: { flexShrink: 0, marginTop: 2 }, color: theme.colors.warning }),
1497
+ /* @__PURE__ */ jsx(
1498
+ Info,
1499
+ {
1500
+ size: 14,
1501
+ style: { flexShrink: 0, marginTop: 2 },
1502
+ color: theme.colors.warning
1503
+ }
1504
+ ),
1213
1505
  /* @__PURE__ */ jsxs("div", { children: [
1214
1506
  /* @__PURE__ */ jsx("strong", { style: { color: theme.colors.text }, children: "Using private npm packages?" }),
1215
1507
  /* @__PURE__ */ jsx("br", {}),
1216
- "Add ",
1217
- /* @__PURE__ */ jsx("code", { style: { backgroundColor: theme.colors.background, padding: "1px 4px", borderRadius: 3 }, children: "NPM_TOKEN" }),
1218
- " to your repository secrets and ensure the workflow has access to it."
1508
+ "Add",
1509
+ " ",
1510
+ /* @__PURE__ */ jsx(
1511
+ "code",
1512
+ {
1513
+ style: {
1514
+ backgroundColor: theme.colors.background,
1515
+ padding: "1px 4px",
1516
+ borderRadius: 3
1517
+ },
1518
+ children: "NPM_TOKEN"
1519
+ }
1520
+ ),
1521
+ " ",
1522
+ "to your repository secrets and ensure the workflow has access to it."
1219
1523
  ] })
1220
1524
  ]
1221
1525
  }
@@ -1435,13 +1739,32 @@ const QualityEmptyState = ({
1435
1739
  color: theme.colors.textMuted
1436
1740
  },
1437
1741
  children: [
1438
- /* @__PURE__ */ jsx(Info, { size: 14, style: { flexShrink: 0, marginTop: 2 }, color: theme.colors.warning }),
1742
+ /* @__PURE__ */ jsx(
1743
+ Info,
1744
+ {
1745
+ size: 14,
1746
+ style: { flexShrink: 0, marginTop: 2 },
1747
+ color: theme.colors.warning
1748
+ }
1749
+ ),
1439
1750
  /* @__PURE__ */ jsxs("div", { children: [
1440
1751
  /* @__PURE__ */ jsx("strong", { style: { color: theme.colors.text }, children: "Private npm packages?" }),
1441
1752
  /* @__PURE__ */ jsx("br", {}),
1442
- "If your project uses private @org packages, add ",
1443
- /* @__PURE__ */ jsx("code", { style: { backgroundColor: theme.colors.background, padding: "1px 4px", borderRadius: 3 }, children: "NPM_TOKEN" }),
1444
- " to your GitHub repository secrets under Settings → Secrets → Actions, and set the workflow environment if needed."
1753
+ "If your project uses private @org packages, add",
1754
+ " ",
1755
+ /* @__PURE__ */ jsx(
1756
+ "code",
1757
+ {
1758
+ style: {
1759
+ backgroundColor: theme.colors.background,
1760
+ padding: "1px 4px",
1761
+ borderRadius: 3
1762
+ },
1763
+ children: "NPM_TOKEN"
1764
+ }
1765
+ ),
1766
+ " ",
1767
+ "to your GitHub repository secrets under Settings → Secrets → Actions, and set the workflow environment if needed."
1445
1768
  ] })
1446
1769
  ]
1447
1770
  }
@@ -1498,7 +1821,10 @@ const QualityHexagonPanelContent = ({
1498
1821
  const isLoading = (qualitySlice == null ? void 0 : qualitySlice.loading) ?? false;
1499
1822
  const fileTreeSlice = context.getSlice("fileTree");
1500
1823
  const hasWorkflow = React2__default.useMemo(() => {
1501
- return checkFileExistsInTree((fileTreeSlice == null ? void 0 : fileTreeSlice.data) ?? void 0, WORKFLOW_FILE_PATH);
1824
+ return checkFileExistsInTree(
1825
+ (fileTreeSlice == null ? void 0 : fileTreeSlice.data) ?? void 0,
1826
+ WORKFLOW_FILE_PATH
1827
+ );
1502
1828
  }, [fileTreeSlice == null ? void 0 : fileTreeSlice.data]);
1503
1829
  const packages = React2__default.useMemo(() => {
1504
1830
  var _a2;
@@ -1536,15 +1862,37 @@ const QualityHexagonPanelContent = ({
1536
1862
  gold: "#FFD700",
1537
1863
  platinum: "#E5E4E2"
1538
1864
  };
1865
+ const allLensesRan = React2__default.useMemo(() => {
1866
+ const lensSet = /* @__PURE__ */ new Set();
1867
+ for (const pkg of packages) {
1868
+ if (pkg.lensesRan) {
1869
+ for (const lens of pkg.lensesRan) {
1870
+ lensSet.add(lens);
1871
+ }
1872
+ }
1873
+ }
1874
+ return lensSet.size > 0 ? Array.from(lensSet) : void 0;
1875
+ }, [packages]);
1539
1876
  const overallTier = packages.length > 0 ? calculateQualityTier(
1540
- packages.reduce((acc, pkg) => ({
1541
- tests: acc.tests + pkg.metrics.tests / packages.length,
1542
- deadCode: acc.deadCode + pkg.metrics.deadCode / packages.length,
1543
- linting: acc.linting + pkg.metrics.linting / packages.length,
1544
- formatting: acc.formatting + pkg.metrics.formatting / packages.length,
1545
- types: acc.types + pkg.metrics.types / packages.length,
1546
- documentation: acc.documentation + pkg.metrics.documentation / packages.length
1547
- }), { tests: 0, deadCode: 0, linting: 0, formatting: 0, types: 0, documentation: 0 })
1877
+ packages.reduce(
1878
+ (acc, pkg) => ({
1879
+ tests: acc.tests + pkg.metrics.tests / packages.length,
1880
+ deadCode: acc.deadCode + pkg.metrics.deadCode / packages.length,
1881
+ linting: acc.linting + pkg.metrics.linting / packages.length,
1882
+ formatting: acc.formatting + pkg.metrics.formatting / packages.length,
1883
+ types: acc.types + pkg.metrics.types / packages.length,
1884
+ documentation: acc.documentation + pkg.metrics.documentation / packages.length
1885
+ }),
1886
+ {
1887
+ tests: 0,
1888
+ deadCode: 0,
1889
+ linting: 0,
1890
+ formatting: 0,
1891
+ types: 0,
1892
+ documentation: 0
1893
+ }
1894
+ ),
1895
+ allLensesRan
1548
1896
  ) : "none";
1549
1897
  return /* @__PURE__ */ jsxs(
1550
1898
  "div",
@@ -1562,57 +1910,69 @@ const QualityHexagonPanelContent = ({
1562
1910
  position: "relative"
1563
1911
  },
1564
1912
  children: [
1565
- /* @__PURE__ */ jsxs("div", { style: {
1566
- display: "flex",
1567
- alignItems: "center",
1568
- gap: 12,
1569
- height: 40,
1570
- flexShrink: 0,
1571
- padding: "0 16px",
1572
- borderBottom: `1px solid ${theme.colors.border}`,
1573
- boxSizing: "border-box"
1574
- }, children: [
1575
- /* @__PURE__ */ jsx(Hexagon, { size: 20, color: tierColors[overallTier] }),
1576
- /* @__PURE__ */ jsx(
1577
- "h2",
1578
- {
1579
- style: {
1580
- margin: 0,
1581
- fontSize: 14,
1582
- fontWeight: 600,
1583
- color: theme.colors.text
1584
- },
1585
- children: "Code Quality"
1586
- }
1587
- ),
1588
- /* @__PURE__ */ jsx(
1589
- "span",
1590
- {
1591
- onClick: () => setShowHelpOverlay(true),
1592
- title: "Click for help",
1593
- style: {
1594
- display: "inline-flex",
1595
- alignItems: "center",
1596
- justifyContent: "center",
1597
- width: 16,
1598
- height: 16,
1599
- borderRadius: "50%",
1600
- border: `1px solid ${theme.colors.border}`,
1601
- fontSize: 11,
1602
- color: theme.colors.textMuted,
1603
- cursor: "pointer"
1604
- },
1605
- children: "?"
1606
- }
1607
- ),
1608
- packages.length > 1 && /* @__PURE__ */ jsxs("span", { style: {
1609
- fontSize: 13,
1610
- color: theme.colors.textMuted
1611
- }, children: [
1612
- packages.length,
1613
- " packages"
1614
- ] })
1615
- ] }),
1913
+ /* @__PURE__ */ jsxs(
1914
+ "div",
1915
+ {
1916
+ style: {
1917
+ display: "flex",
1918
+ alignItems: "center",
1919
+ gap: 12,
1920
+ height: 40,
1921
+ flexShrink: 0,
1922
+ padding: "0 16px",
1923
+ borderBottom: `1px solid ${theme.colors.border}`,
1924
+ boxSizing: "border-box"
1925
+ },
1926
+ children: [
1927
+ /* @__PURE__ */ jsx(Hexagon, { size: 20, color: tierColors[overallTier] }),
1928
+ /* @__PURE__ */ jsx(
1929
+ "h2",
1930
+ {
1931
+ style: {
1932
+ margin: 0,
1933
+ fontSize: 14,
1934
+ fontWeight: 600,
1935
+ color: theme.colors.text
1936
+ },
1937
+ children: "Code Quality"
1938
+ }
1939
+ ),
1940
+ /* @__PURE__ */ jsx(
1941
+ "span",
1942
+ {
1943
+ onClick: () => setShowHelpOverlay(true),
1944
+ title: "Click for help",
1945
+ style: {
1946
+ display: "inline-flex",
1947
+ alignItems: "center",
1948
+ justifyContent: "center",
1949
+ width: 16,
1950
+ height: 16,
1951
+ borderRadius: "50%",
1952
+ border: `1px solid ${theme.colors.border}`,
1953
+ fontSize: 11,
1954
+ color: theme.colors.textMuted,
1955
+ cursor: "pointer"
1956
+ },
1957
+ children: "?"
1958
+ }
1959
+ ),
1960
+ packages.length > 1 && /* @__PURE__ */ jsxs(
1961
+ "span",
1962
+ {
1963
+ style: {
1964
+ fontSize: 13,
1965
+ color: theme.colors.textMuted
1966
+ },
1967
+ children: [
1968
+ packages.length,
1969
+ " packages"
1970
+ ]
1971
+ }
1972
+ )
1973
+ ]
1974
+ }
1975
+ ),
1616
1976
  /* @__PURE__ */ jsx(
1617
1977
  "div",
1618
1978
  {
@@ -1624,54 +1984,61 @@ const QualityHexagonPanelContent = ({
1624
1984
  flex: 1,
1625
1985
  minHeight: 0
1626
1986
  },
1627
- children: /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 16, minHeight: 0 }, children: isLoading ? /* @__PURE__ */ jsx("div", { style: {
1628
- padding: 40,
1629
- textAlign: "center",
1630
- color: theme.colors.textMuted
1631
- }, children: "Loading quality metrics..." }) : packages.length === 0 ? /* @__PURE__ */ jsx(
1632
- QualityEmptyState,
1987
+ children: /* @__PURE__ */ jsx(
1988
+ "div",
1633
1989
  {
1634
- theme,
1635
- hasWorkflow
1636
- }
1637
- ) : packages.map((pkg) => {
1638
- const tier = calculateQualityTier(pkg.metrics);
1639
- const packagePath = pkg.path ?? "";
1640
- return /* @__PURE__ */ jsx(
1641
- QualityHexagonExpandable,
1642
- {
1643
- metrics: pkg.metrics,
1644
- tier,
1645
- theme,
1646
- packageName: pkg.name,
1647
- packageVersion: pkg.version,
1648
- packagePath,
1649
- onExpandChange: (expanded, info) => {
1650
- events.emit({
1651
- type: "package:select",
1652
- source: "principal-ade.quality-hexagon-panel",
1653
- timestamp: Date.now(),
1654
- payload: expanded ? {
1655
- packagePath: info.packagePath ?? "",
1656
- packageName: info.packageName
1657
- } : null
1658
- });
1659
- },
1660
- onMetricClick: (metric) => {
1661
- const colorMode = METRIC_TO_COLOR_MODE[metric];
1662
- if (colorMode) {
1663
- events.emit({
1664
- type: "quality:colorMode:select",
1665
- source: "principal-ade.quality-hexagon-panel",
1666
- timestamp: Date.now(),
1667
- payload: { colorMode }
1668
- });
1669
- }
1990
+ style: { display: "flex", flexWrap: "wrap", gap: 16, minHeight: 0 },
1991
+ children: isLoading ? /* @__PURE__ */ jsx(
1992
+ "div",
1993
+ {
1994
+ style: {
1995
+ padding: 40,
1996
+ textAlign: "center",
1997
+ color: theme.colors.textMuted
1998
+ },
1999
+ children: "Loading quality metrics..."
1670
2000
  }
1671
- },
1672
- pkg.name
1673
- );
1674
- }) })
2001
+ ) : packages.length === 0 ? /* @__PURE__ */ jsx(QualityEmptyState, { theme, hasWorkflow }) : packages.map((pkg) => {
2002
+ const tier = calculateQualityTier(pkg.metrics, pkg.lensesRan);
2003
+ const packagePath = pkg.path ?? "";
2004
+ return /* @__PURE__ */ jsx(
2005
+ QualityHexagonExpandable,
2006
+ {
2007
+ metrics: pkg.metrics,
2008
+ tier,
2009
+ theme,
2010
+ packageName: pkg.name,
2011
+ packageVersion: pkg.version,
2012
+ packagePath,
2013
+ lensesRan: pkg.lensesRan,
2014
+ onExpandChange: (expanded, info) => {
2015
+ events.emit({
2016
+ type: "package:select",
2017
+ source: "principal-ade.quality-hexagon-panel",
2018
+ timestamp: Date.now(),
2019
+ payload: expanded ? {
2020
+ packagePath: info.packagePath ?? "",
2021
+ packageName: info.packageName
2022
+ } : null
2023
+ });
2024
+ },
2025
+ onMetricClick: (metric) => {
2026
+ const colorMode = METRIC_TO_COLOR_MODE[metric];
2027
+ if (colorMode) {
2028
+ events.emit({
2029
+ type: "quality:colorMode:select",
2030
+ source: "principal-ade.quality-hexagon-panel",
2031
+ timestamp: Date.now(),
2032
+ payload: { colorMode }
2033
+ });
2034
+ }
2035
+ }
2036
+ },
2037
+ pkg.name
2038
+ );
2039
+ })
2040
+ }
2041
+ )
1675
2042
  }
1676
2043
  ),
1677
2044
  showHelpOverlay && /* @__PURE__ */ jsx(
@@ -1703,42 +2070,66 @@ const QualityHexagonPanelContent = ({
1703
2070
  },
1704
2071
  onClick: (e) => e.stopPropagation(),
1705
2072
  children: [
1706
- /* @__PURE__ */ jsxs("div", { style: {
1707
- display: "flex",
1708
- justifyContent: "space-between",
1709
- alignItems: "center",
1710
- marginBottom: 16
1711
- }, children: [
1712
- /* @__PURE__ */ jsx("h3", { style: {
1713
- margin: 0,
1714
- fontSize: 16,
1715
- fontWeight: 600,
1716
- color: theme.colors.text
1717
- }, children: "Quality Lens CLI" }),
1718
- /* @__PURE__ */ jsx(
1719
- "button",
1720
- {
1721
- onClick: () => setShowHelpOverlay(false),
1722
- style: {
1723
- background: "none",
1724
- border: "none",
1725
- cursor: "pointer",
1726
- padding: 4,
1727
- display: "flex",
1728
- color: theme.colors.textMuted
1729
- },
1730
- children: /* @__PURE__ */ jsx(X, { size: 18 })
1731
- }
1732
- )
1733
- ] }),
1734
- /* @__PURE__ */ jsx("p", { style: {
1735
- fontSize: 13,
1736
- color: theme.colors.textMuted,
1737
- margin: "0 0 12px 0"
1738
- }, children: "Run quality checks locally with the CLI:" }),
2073
+ /* @__PURE__ */ jsxs(
2074
+ "div",
2075
+ {
2076
+ style: {
2077
+ display: "flex",
2078
+ justifyContent: "space-between",
2079
+ alignItems: "center",
2080
+ marginBottom: 16
2081
+ },
2082
+ children: [
2083
+ /* @__PURE__ */ jsx(
2084
+ "h3",
2085
+ {
2086
+ style: {
2087
+ margin: 0,
2088
+ fontSize: 16,
2089
+ fontWeight: 600,
2090
+ color: theme.colors.text
2091
+ },
2092
+ children: "Quality Lens CLI"
2093
+ }
2094
+ ),
2095
+ /* @__PURE__ */ jsx(
2096
+ "button",
2097
+ {
2098
+ onClick: () => setShowHelpOverlay(false),
2099
+ style: {
2100
+ background: "none",
2101
+ border: "none",
2102
+ cursor: "pointer",
2103
+ padding: 4,
2104
+ display: "flex",
2105
+ color: theme.colors.textMuted
2106
+ },
2107
+ children: /* @__PURE__ */ jsx(X, { size: 18 })
2108
+ }
2109
+ )
2110
+ ]
2111
+ }
2112
+ ),
2113
+ /* @__PURE__ */ jsx(
2114
+ "p",
2115
+ {
2116
+ style: {
2117
+ fontSize: 13,
2118
+ color: theme.colors.textMuted,
2119
+ margin: "0 0 12px 0"
2120
+ },
2121
+ children: "Run quality checks locally with the CLI:"
2122
+ }
2123
+ ),
1739
2124
  [
1740
- { cmd: "npx @principal-ai/quality-lens-cli init", label: "Initialize quality lens in your project" },
1741
- { cmd: "npx @principal-ai/quality-lens-cli list", label: "List available quality lenses" }
2125
+ {
2126
+ cmd: "npx @principal-ai/quality-lens-cli init",
2127
+ label: "Initialize quality lens in your project"
2128
+ },
2129
+ {
2130
+ cmd: "npx @principal-ai/quality-lens-cli list",
2131
+ label: "List available quality lenses"
2132
+ }
1742
2133
  ].map(({ cmd, label }) => /* @__PURE__ */ jsxs("div", { style: { marginBottom: 12 }, children: [
1743
2134
  /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: theme.colors.textMuted }, children: label }),
1744
2135
  /* @__PURE__ */ jsxs(
@@ -1780,22 +2171,39 @@ const QualityHexagonPanelContent = ({
1780
2171
  }
1781
2172
  )
1782
2173
  ] }, cmd)),
1783
- /* @__PURE__ */ jsxs("div", { style: {
1784
- marginTop: 16,
1785
- padding: 12,
1786
- backgroundColor: theme.colors.background,
1787
- borderRadius: 6,
1788
- fontSize: 12,
1789
- color: theme.colors.textMuted
1790
- }, children: [
1791
- /* @__PURE__ */ jsx("strong", { style: { color: theme.colors.text }, children: "Tiers:" }),
1792
- /* @__PURE__ */ jsxs("div", { style: { marginTop: 8, display: "flex", flexDirection: "column", gap: 4 }, children: [
1793
- /* @__PURE__ */ jsx("span", { children: "🏆 Platinum: 90%+ average" }),
1794
- /* @__PURE__ */ jsx("span", { children: "🥇 Gold: 75%+ average" }),
1795
- /* @__PURE__ */ jsx("span", { children: "🥈 Silver: 60%+ average" }),
1796
- /* @__PURE__ */ jsx("span", { children: "🥉 Bronze: 40%+ average" })
1797
- ] })
1798
- ] })
2174
+ /* @__PURE__ */ jsxs(
2175
+ "div",
2176
+ {
2177
+ style: {
2178
+ marginTop: 16,
2179
+ padding: 12,
2180
+ backgroundColor: theme.colors.background,
2181
+ borderRadius: 6,
2182
+ fontSize: 12,
2183
+ color: theme.colors.textMuted
2184
+ },
2185
+ children: [
2186
+ /* @__PURE__ */ jsx("strong", { style: { color: theme.colors.text }, children: "Tiers:" }),
2187
+ /* @__PURE__ */ jsxs(
2188
+ "div",
2189
+ {
2190
+ style: {
2191
+ marginTop: 8,
2192
+ display: "flex",
2193
+ flexDirection: "column",
2194
+ gap: 4
2195
+ },
2196
+ children: [
2197
+ /* @__PURE__ */ jsx("span", { children: "🏆 Platinum: 90%+ average" }),
2198
+ /* @__PURE__ */ jsx("span", { children: "🥇 Gold: 75%+ average" }),
2199
+ /* @__PURE__ */ jsx("span", { children: "🥈 Silver: 60%+ average" }),
2200
+ /* @__PURE__ */ jsx("span", { children: "🥉 Bronze: 40%+ average" })
2201
+ ]
2202
+ }
2203
+ )
2204
+ ]
2205
+ }
2206
+ )
1799
2207
  ]
1800
2208
  }
1801
2209
  )
@@ -1843,7 +2251,14 @@ function calculateOverallTier(items) {
1843
2251
  types: acc.types + item.metrics.types / items.length,
1844
2252
  documentation: acc.documentation + item.metrics.documentation / items.length
1845
2253
  }),
1846
- { tests: 0, deadCode: 0, linting: 0, formatting: 0, types: 0, documentation: 0 }
2254
+ {
2255
+ tests: 0,
2256
+ deadCode: 0,
2257
+ linting: 0,
2258
+ formatting: 0,
2259
+ types: 0,
2260
+ documentation: 0
2261
+ }
1847
2262
  );
1848
2263
  return calculateQualityTier(avgMetrics);
1849
2264
  }
@@ -2033,11 +2448,18 @@ function RepositoryQualityGrid({
2033
2448
  showRepositoryName = true,
2034
2449
  showSummary = true
2035
2450
  }) {
2036
- const [selectedMetric, setSelectedMetric] = React2.useState(null);
2037
- const items = React2.useMemo(() => flattenRepositories(repositories), [repositories]);
2451
+ const [selectedMetric, setSelectedMetric] = React2.useState(
2452
+ null
2453
+ );
2454
+ const items = React2.useMemo(
2455
+ () => flattenRepositories(repositories),
2456
+ [repositories]
2457
+ );
2038
2458
  const overallTier = React2.useMemo(() => calculateOverallTier(items), [items]);
2039
2459
  const sortedItems = React2.useMemo(() => {
2040
- return [...items].sort((a, b) => a.packageName.localeCompare(b.packageName));
2460
+ return [...items].sort(
2461
+ (a, b) => a.packageName.localeCompare(b.packageName)
2462
+ );
2041
2463
  }, [items]);
2042
2464
  const tierColors = {
2043
2465
  none: "#808080",
@@ -2132,7 +2554,9 @@ function RepositoryQualityGrid({
2132
2554
  "select",
2133
2555
  {
2134
2556
  value: selectedMetric ?? "",
2135
- onChange: (e) => setSelectedMetric(e.target.value ? e.target.value : null),
2557
+ onChange: (e) => setSelectedMetric(
2558
+ e.target.value ? e.target.value : null
2559
+ ),
2136
2560
  style: {
2137
2561
  padding: "4px 8px",
2138
2562
  fontSize: 13,
@@ -2224,8 +2648,12 @@ const RepositoryQualityGridPanelContent = ({
2224
2648
  }) => {
2225
2649
  var _a;
2226
2650
  const { theme } = useTheme();
2227
- const [selectedItemKey, setSelectedItemKey] = React2__default.useState(null);
2228
- const qualitySlice = context.getSlice("repositoriesQuality");
2651
+ const [selectedItemKey, setSelectedItemKey] = React2__default.useState(
2652
+ null
2653
+ );
2654
+ const qualitySlice = context.getSlice(
2655
+ "repositoriesQuality"
2656
+ );
2229
2657
  const isLoading = (qualitySlice == null ? void 0 : qualitySlice.loading) ?? false;
2230
2658
  const repositories = React2__default.useMemo(() => {
2231
2659
  var _a2;
@@ -2387,7 +2815,13 @@ function getPackageSummary(results) {
2387
2815
  failCount++;
2388
2816
  }
2389
2817
  }
2390
- return { totalErrors, totalWarnings, passCount, failCount, lensCount: results.length };
2818
+ return {
2819
+ totalErrors,
2820
+ totalWarnings,
2821
+ passCount,
2822
+ failCount,
2823
+ lensCount: results.length
2824
+ };
2391
2825
  }
2392
2826
  function LensDataDebugPanel$1({
2393
2827
  data,
@@ -2397,13 +2831,21 @@ function LensDataDebugPanel$1({
2397
2831
  onFileClick,
2398
2832
  onPackageSelect
2399
2833
  }) {
2400
- const packageGroups = React2.useMemo(() => groupResultsByPackage((data == null ? void 0 : data.results) ?? []), [data == null ? void 0 : data.results]);
2401
- const packageNames = React2.useMemo(() => Array.from(packageGroups.keys()), [packageGroups]);
2834
+ const packageGroups = React2.useMemo(
2835
+ () => groupResultsByPackage((data == null ? void 0 : data.results) ?? []),
2836
+ [data == null ? void 0 : data.results]
2837
+ );
2838
+ const packageNames = React2.useMemo(
2839
+ () => Array.from(packageGroups.keys()),
2840
+ [packageGroups]
2841
+ );
2402
2842
  const [selectedPackage, setSelectedPackage] = React2.useState(
2403
2843
  initialSelectedPackage || (packageNames.length === 1 ? packageNames[0] : null)
2404
2844
  );
2405
2845
  const [expandedLens, setExpandedLens] = React2.useState(null);
2406
- const [expandedFiles, setExpandedFiles] = React2.useState(/* @__PURE__ */ new Set());
2846
+ const [expandedFiles, setExpandedFiles] = React2.useState(
2847
+ /* @__PURE__ */ new Set()
2848
+ );
2407
2849
  const handlePackageSelect = (pkg) => {
2408
2850
  setSelectedPackage(pkg);
2409
2851
  setExpandedLens(null);
@@ -2438,82 +2880,112 @@ function LensDataDebugPanel$1({
2438
2880
  fontSize: 13
2439
2881
  },
2440
2882
  children: [
2441
- packageNames.length > 1 && /* @__PURE__ */ jsx("div", { style: {
2442
- display: "flex",
2443
- flexWrap: "wrap",
2444
- gap: 8,
2445
- marginBottom: 8
2446
- }, children: packageNames.map((pkg) => {
2447
- const summary = getPackageSummary(packageGroups.get(pkg) || []);
2448
- const isSelected = selectedPackage === pkg;
2449
- return /* @__PURE__ */ jsxs(
2450
- "button",
2451
- {
2452
- onClick: () => handlePackageSelect(pkg),
2453
- style: {
2454
- display: "flex",
2455
- alignItems: "center",
2456
- gap: 8,
2457
- padding: "8px 12px",
2458
- borderRadius: 6,
2459
- border: `1px solid ${isSelected ? theme.colors.primary : theme.colors.border}`,
2460
- backgroundColor: isSelected ? theme.colors.surface : "transparent",
2461
- color: theme.colors.text,
2462
- cursor: "pointer",
2463
- transition: "all 0.15s ease"
2464
- },
2465
- children: [
2466
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: pkg }),
2467
- /* @__PURE__ */ jsxs("span", { style: {
2468
- fontSize: 11,
2469
- padding: "2px 6px",
2470
- borderRadius: 4,
2471
- backgroundColor: summary.totalErrors > 0 ? getSeverityBg("error") : summary.totalWarnings > 0 ? getSeverityBg("warning") : "rgba(34, 197, 94, 0.1)",
2472
- color: summary.totalErrors > 0 ? getSeverityColor("error") : summary.totalWarnings > 0 ? getSeverityColor("warning") : "#22c55e"
2473
- }, children: [
2474
- summary.passCount,
2475
- "/",
2476
- summary.lensCount,
2477
- " pass"
2478
- ] })
2479
- ]
2883
+ packageNames.length > 1 && /* @__PURE__ */ jsx(
2884
+ "div",
2885
+ {
2886
+ style: {
2887
+ display: "flex",
2888
+ flexWrap: "wrap",
2889
+ gap: 8,
2890
+ marginBottom: 8
2480
2891
  },
2481
- pkg
2482
- );
2483
- }) }),
2484
- packageNames.length === 1 && /* @__PURE__ */ jsxs("div", { style: {
2485
- display: "flex",
2486
- alignItems: "center",
2487
- gap: 12,
2488
- padding: "8px 12px",
2489
- backgroundColor: theme.colors.surface,
2490
- borderRadius: 6,
2491
- marginBottom: 8
2492
- }, children: [
2493
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: theme.colors.text }, children: packageNames[0] }),
2494
- (() => {
2495
- const summary = getPackageSummary(selectedResults);
2496
- return /* @__PURE__ */ jsxs("span", { style: {
2497
- fontSize: 11,
2498
- padding: "2px 6px",
2499
- borderRadius: 4,
2500
- backgroundColor: summary.totalErrors > 0 ? getSeverityBg("error") : summary.totalWarnings > 0 ? getSeverityBg("warning") : "rgba(34, 197, 94, 0.1)",
2501
- color: summary.totalErrors > 0 ? getSeverityColor("error") : summary.totalWarnings > 0 ? getSeverityColor("warning") : "#22c55e"
2502
- }, children: [
2503
- summary.passCount,
2504
- "/",
2505
- summary.lensCount,
2506
- " pass"
2507
- ] });
2508
- })()
2509
- ] }),
2510
- !selectedPackage && packageNames.length > 1 && /* @__PURE__ */ jsx("div", { style: {
2511
- padding: 24,
2512
- textAlign: "center",
2513
- color: theme.colors.textMuted,
2514
- backgroundColor: theme.colors.surface,
2515
- borderRadius: 6
2516
- }, children: "Select a package above to view lens results" }),
2892
+ children: packageNames.map((pkg) => {
2893
+ const summary = getPackageSummary(packageGroups.get(pkg) || []);
2894
+ const isSelected = selectedPackage === pkg;
2895
+ return /* @__PURE__ */ jsxs(
2896
+ "button",
2897
+ {
2898
+ onClick: () => handlePackageSelect(pkg),
2899
+ style: {
2900
+ display: "flex",
2901
+ alignItems: "center",
2902
+ gap: 8,
2903
+ padding: "8px 12px",
2904
+ borderRadius: 6,
2905
+ border: `1px solid ${isSelected ? theme.colors.primary : theme.colors.border}`,
2906
+ backgroundColor: isSelected ? theme.colors.surface : "transparent",
2907
+ color: theme.colors.text,
2908
+ cursor: "pointer",
2909
+ transition: "all 0.15s ease"
2910
+ },
2911
+ children: [
2912
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: pkg }),
2913
+ /* @__PURE__ */ jsxs(
2914
+ "span",
2915
+ {
2916
+ style: {
2917
+ fontSize: 11,
2918
+ padding: "2px 6px",
2919
+ borderRadius: 4,
2920
+ backgroundColor: summary.totalErrors > 0 ? getSeverityBg("error") : summary.totalWarnings > 0 ? getSeverityBg("warning") : "rgba(34, 197, 94, 0.1)",
2921
+ color: summary.totalErrors > 0 ? getSeverityColor("error") : summary.totalWarnings > 0 ? getSeverityColor("warning") : "#22c55e"
2922
+ },
2923
+ children: [
2924
+ summary.passCount,
2925
+ "/",
2926
+ summary.lensCount,
2927
+ " pass"
2928
+ ]
2929
+ }
2930
+ )
2931
+ ]
2932
+ },
2933
+ pkg
2934
+ );
2935
+ })
2936
+ }
2937
+ ),
2938
+ packageNames.length === 1 && /* @__PURE__ */ jsxs(
2939
+ "div",
2940
+ {
2941
+ style: {
2942
+ display: "flex",
2943
+ alignItems: "center",
2944
+ gap: 12,
2945
+ padding: "8px 12px",
2946
+ backgroundColor: theme.colors.surface,
2947
+ borderRadius: 6,
2948
+ marginBottom: 8
2949
+ },
2950
+ children: [
2951
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: theme.colors.text }, children: packageNames[0] }),
2952
+ (() => {
2953
+ const summary = getPackageSummary(selectedResults);
2954
+ return /* @__PURE__ */ jsxs(
2955
+ "span",
2956
+ {
2957
+ style: {
2958
+ fontSize: 11,
2959
+ padding: "2px 6px",
2960
+ borderRadius: 4,
2961
+ backgroundColor: summary.totalErrors > 0 ? getSeverityBg("error") : summary.totalWarnings > 0 ? getSeverityBg("warning") : "rgba(34, 197, 94, 0.1)",
2962
+ color: summary.totalErrors > 0 ? getSeverityColor("error") : summary.totalWarnings > 0 ? getSeverityColor("warning") : "#22c55e"
2963
+ },
2964
+ children: [
2965
+ summary.passCount,
2966
+ "/",
2967
+ summary.lensCount,
2968
+ " pass"
2969
+ ]
2970
+ }
2971
+ );
2972
+ })()
2973
+ ]
2974
+ }
2975
+ ),
2976
+ !selectedPackage && packageNames.length > 1 && /* @__PURE__ */ jsx(
2977
+ "div",
2978
+ {
2979
+ style: {
2980
+ padding: 24,
2981
+ textAlign: "center",
2982
+ color: theme.colors.textMuted,
2983
+ backgroundColor: theme.colors.surface,
2984
+ borderRadius: 6
2985
+ },
2986
+ children: "Select a package above to view lens results"
2987
+ }
2988
+ ),
2517
2989
  selectedPackage && selectedResults.map((result, idx) => {
2518
2990
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
2519
2991
  const lensKey = `${((_a = result.lens) == null ? void 0 : _a.id) ?? "unknown"}-${idx}`;
@@ -2568,34 +3040,53 @@ function LensDataDebugPanel$1({
2568
3040
  ] })
2569
3041
  ] }),
2570
3042
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
2571
- /* @__PURE__ */ jsx("span", { style: {
2572
- padding: "2px 6px",
2573
- borderRadius: 4,
2574
- fontSize: 11,
2575
- backgroundColor: ((_e = result.execution) == null ? void 0 : _e.success) ? "rgba(34, 197, 94, 0.1)" : "rgba(239, 68, 68, 0.1)",
2576
- color: ((_f = result.execution) == null ? void 0 : _f.success) ? "#22c55e" : "#ef4444"
2577
- }, children: ((_g = result.execution) == null ? void 0 : _g.success) ? "pass" : "fail" }),
3043
+ /* @__PURE__ */ jsx(
3044
+ "span",
3045
+ {
3046
+ style: {
3047
+ padding: "2px 6px",
3048
+ borderRadius: 4,
3049
+ fontSize: 11,
3050
+ backgroundColor: ((_e = result.execution) == null ? void 0 : _e.success) ? "rgba(34, 197, 94, 0.1)" : "rgba(239, 68, 68, 0.1)",
3051
+ color: ((_f = result.execution) == null ? void 0 : _f.success) ? "#22c55e" : "#ef4444"
3052
+ },
3053
+ children: ((_g = result.execution) == null ? void 0 : _g.success) ? "pass" : "fail"
3054
+ }
3055
+ ),
2578
3056
  hasIssues && /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6 }, children: [
2579
- (((_i = (_h = result.metrics) == null ? void 0 : _h.issuesBySeverity) == null ? void 0 : _i.error) ?? 0) > 0 && /* @__PURE__ */ jsxs("span", { style: {
2580
- padding: "2px 6px",
2581
- borderRadius: 4,
2582
- fontSize: 11,
2583
- backgroundColor: getSeverityBg("error"),
2584
- color: getSeverityColor("error")
2585
- }, children: [
2586
- ((_k = (_j = result.metrics) == null ? void 0 : _j.issuesBySeverity) == null ? void 0 : _k.error) ?? 0,
2587
- " errors"
2588
- ] }),
2589
- (((_m = (_l = result.metrics) == null ? void 0 : _l.issuesBySeverity) == null ? void 0 : _m.warning) ?? 0) > 0 && /* @__PURE__ */ jsxs("span", { style: {
2590
- padding: "2px 6px",
2591
- borderRadius: 4,
2592
- fontSize: 11,
2593
- backgroundColor: getSeverityBg("warning"),
2594
- color: getSeverityColor("warning")
2595
- }, children: [
2596
- ((_o = (_n = result.metrics) == null ? void 0 : _n.issuesBySeverity) == null ? void 0 : _o.warning) ?? 0,
2597
- " warnings"
2598
- ] })
3057
+ (((_i = (_h = result.metrics) == null ? void 0 : _h.issuesBySeverity) == null ? void 0 : _i.error) ?? 0) > 0 && /* @__PURE__ */ jsxs(
3058
+ "span",
3059
+ {
3060
+ style: {
3061
+ padding: "2px 6px",
3062
+ borderRadius: 4,
3063
+ fontSize: 11,
3064
+ backgroundColor: getSeverityBg("error"),
3065
+ color: getSeverityColor("error")
3066
+ },
3067
+ children: [
3068
+ ((_k = (_j = result.metrics) == null ? void 0 : _j.issuesBySeverity) == null ? void 0 : _k.error) ?? 0,
3069
+ " errors"
3070
+ ]
3071
+ }
3072
+ ),
3073
+ (((_m = (_l = result.metrics) == null ? void 0 : _l.issuesBySeverity) == null ? void 0 : _m.warning) ?? 0) > 0 && /* @__PURE__ */ jsxs(
3074
+ "span",
3075
+ {
3076
+ style: {
3077
+ padding: "2px 6px",
3078
+ borderRadius: 4,
3079
+ fontSize: 11,
3080
+ backgroundColor: getSeverityBg("warning"),
3081
+ color: getSeverityColor("warning")
3082
+ },
3083
+ children: [
3084
+ ((_o = (_n = result.metrics) == null ? void 0 : _n.issuesBySeverity) == null ? void 0 : _o.warning) ?? 0,
3085
+ " ",
3086
+ "warnings"
3087
+ ]
3088
+ }
3089
+ )
2599
3090
  ] }),
2600
3091
  /* @__PURE__ */ jsxs("span", { style: { fontSize: 12, color: theme.colors.textMuted }, children: [
2601
3092
  ((_p = result.metrics) == null ? void 0 : _p.filesAnalyzed) ?? 0,
@@ -2605,235 +3096,412 @@ function LensDataDebugPanel$1({
2605
3096
  ]
2606
3097
  }
2607
3098
  ),
2608
- isExpanded && /* @__PURE__ */ jsxs("div", { style: {
2609
- padding: 12,
2610
- backgroundColor: theme.colors.backgroundLight,
2611
- borderTop: `1px solid ${theme.colors.border}`
2612
- }, children: [
2613
- /* @__PURE__ */ jsxs("div", { style: {
2614
- display: "grid",
2615
- gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
2616
- gap: 8,
2617
- marginBottom: 16,
2618
- padding: 12,
2619
- backgroundColor: theme.colors.surface,
2620
- borderRadius: 4
2621
- }, children: [
2622
- /* @__PURE__ */ jsxs("div", { children: [
2623
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: theme.colors.textMuted }, children: "Files Analyzed" }),
2624
- /* @__PURE__ */ jsx("div", { style: { fontSize: 16, fontWeight: 600, color: theme.colors.text }, children: ((_q = result.metrics) == null ? void 0 : _q.filesAnalyzed) ?? 0 })
2625
- ] }),
2626
- /* @__PURE__ */ jsxs("div", { children: [
2627
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: theme.colors.textMuted }, children: "Total Issues" }),
2628
- /* @__PURE__ */ jsx("div", { style: { fontSize: 16, fontWeight: 600, color: theme.colors.text }, children: ((_r = result.metrics) == null ? void 0 : _r.totalIssues) ?? 0 })
2629
- ] }),
2630
- /* @__PURE__ */ jsxs("div", { children: [
2631
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: theme.colors.textMuted }, children: "Duration" }),
2632
- /* @__PURE__ */ jsxs("div", { style: { fontSize: 16, fontWeight: 600, color: theme.colors.text }, children: [
2633
- ((_s = result.execution) == null ? void 0 : _s.duration) ?? 0,
2634
- "ms"
2635
- ] })
2636
- ] }),
2637
- result.coverage && /* @__PURE__ */ jsxs("div", { children: [
2638
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: theme.colors.textMuted }, children: "Coverage" }),
2639
- /* @__PURE__ */ jsxs("div", { style: { fontSize: 16, fontWeight: 600, color: theme.colors.text }, children: [
2640
- result.coverage.line,
2641
- "%"
2642
- ] })
2643
- ] })
2644
- ] }),
2645
- filesWithIssues.size > 0 ? /* @__PURE__ */ jsxs("div", { children: [
2646
- /* @__PURE__ */ jsxs("div", { style: {
2647
- fontSize: 12,
2648
- fontWeight: 600,
2649
- color: theme.colors.textMuted,
2650
- marginBottom: 8
2651
- }, children: [
2652
- "Files with Issues (",
2653
- filesWithIssues.size,
2654
- ")"
2655
- ] }),
2656
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: Array.from(filesWithIssues.entries()).map(([file, issues]) => {
2657
- const isFileExpanded = expandedFiles.has(file);
2658
- return /* @__PURE__ */ jsxs(
3099
+ isExpanded && /* @__PURE__ */ jsxs(
3100
+ "div",
3101
+ {
3102
+ style: {
3103
+ padding: 12,
3104
+ backgroundColor: theme.colors.backgroundLight,
3105
+ borderTop: `1px solid ${theme.colors.border}`
3106
+ },
3107
+ children: [
3108
+ /* @__PURE__ */ jsxs(
2659
3109
  "div",
2660
3110
  {
2661
3111
  style: {
2662
- border: `1px solid ${theme.colors.border}`,
2663
- borderRadius: 4,
2664
- overflow: "hidden"
3112
+ display: "grid",
3113
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
3114
+ gap: 8,
3115
+ marginBottom: 16,
3116
+ padding: 12,
3117
+ backgroundColor: theme.colors.surface,
3118
+ borderRadius: 4
2665
3119
  },
2666
3120
  children: [
2667
- /* @__PURE__ */ jsxs(
2668
- "div",
2669
- {
2670
- onClick: () => toggleFile(file),
2671
- style: {
2672
- display: "flex",
2673
- alignItems: "center",
2674
- justifyContent: "space-between",
2675
- padding: "8px 10px",
2676
- backgroundColor: theme.colors.surface,
2677
- cursor: "pointer"
2678
- },
2679
- children: [
2680
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
2681
- /* @__PURE__ */ jsx(
2682
- "svg",
2683
- {
2684
- width: "12",
2685
- height: "12",
2686
- viewBox: "0 0 24 24",
2687
- fill: "none",
2688
- stroke: theme.colors.textMuted,
2689
- strokeWidth: "2",
2690
- style: {
2691
- transform: isFileExpanded ? "rotate(90deg)" : "rotate(0deg)",
2692
- transition: "transform 0.15s ease"
2693
- },
2694
- children: /* @__PURE__ */ jsx("polyline", { points: "9,18 15,12 9,6" })
2695
- }
2696
- ),
2697
- /* @__PURE__ */ jsx(
2698
- "span",
2699
- {
2700
- style: {
2701
- color: theme.colors.text,
2702
- cursor: onFileClick ? "pointer" : "default"
2703
- },
2704
- onClick: (e) => {
2705
- if (onFileClick) {
2706
- e.stopPropagation();
2707
- onFileClick(file);
2708
- }
2709
- },
2710
- children: file
2711
- }
2712
- )
2713
- ] }),
2714
- /* @__PURE__ */ jsxs("span", { style: {
3121
+ /* @__PURE__ */ jsxs("div", { children: [
3122
+ /* @__PURE__ */ jsx(
3123
+ "div",
3124
+ {
3125
+ style: { fontSize: 11, color: theme.colors.textMuted },
3126
+ children: "Files Analyzed"
3127
+ }
3128
+ ),
3129
+ /* @__PURE__ */ jsx(
3130
+ "div",
3131
+ {
3132
+ style: {
3133
+ fontSize: 16,
3134
+ fontWeight: 600,
3135
+ color: theme.colors.text
3136
+ },
3137
+ children: ((_q = result.metrics) == null ? void 0 : _q.filesAnalyzed) ?? 0
3138
+ }
3139
+ )
3140
+ ] }),
3141
+ /* @__PURE__ */ jsxs("div", { children: [
3142
+ /* @__PURE__ */ jsx(
3143
+ "div",
3144
+ {
3145
+ style: { fontSize: 11, color: theme.colors.textMuted },
3146
+ children: "Total Issues"
3147
+ }
3148
+ ),
3149
+ /* @__PURE__ */ jsx(
3150
+ "div",
3151
+ {
3152
+ style: {
3153
+ fontSize: 16,
3154
+ fontWeight: 600,
3155
+ color: theme.colors.text
3156
+ },
3157
+ children: ((_r = result.metrics) == null ? void 0 : _r.totalIssues) ?? 0
3158
+ }
3159
+ )
3160
+ ] }),
3161
+ /* @__PURE__ */ jsxs("div", { children: [
3162
+ /* @__PURE__ */ jsx(
3163
+ "div",
3164
+ {
3165
+ style: { fontSize: 11, color: theme.colors.textMuted },
3166
+ children: "Duration"
3167
+ }
3168
+ ),
3169
+ /* @__PURE__ */ jsxs(
3170
+ "div",
3171
+ {
3172
+ style: {
3173
+ fontSize: 16,
3174
+ fontWeight: 600,
3175
+ color: theme.colors.text
3176
+ },
3177
+ children: [
3178
+ ((_s = result.execution) == null ? void 0 : _s.duration) ?? 0,
3179
+ "ms"
3180
+ ]
3181
+ }
3182
+ )
3183
+ ] }),
3184
+ result.coverage && /* @__PURE__ */ jsxs("div", { children: [
3185
+ /* @__PURE__ */ jsx(
3186
+ "div",
3187
+ {
3188
+ style: {
2715
3189
  fontSize: 11,
2716
- padding: "2px 6px",
2717
- borderRadius: 4,
2718
- backgroundColor: getSeverityBg("error"),
2719
- color: getSeverityColor("error")
2720
- }, children: [
2721
- issues.length,
2722
- " issues"
2723
- ] })
2724
- ]
3190
+ color: theme.colors.textMuted
3191
+ },
3192
+ children: "Coverage"
3193
+ }
3194
+ ),
3195
+ /* @__PURE__ */ jsxs(
3196
+ "div",
3197
+ {
3198
+ style: {
3199
+ fontSize: 16,
3200
+ fontWeight: 600,
3201
+ color: theme.colors.text
3202
+ },
3203
+ children: [
3204
+ result.coverage.line,
3205
+ "%"
3206
+ ]
3207
+ }
3208
+ )
3209
+ ] })
3210
+ ]
3211
+ }
3212
+ ),
3213
+ filesWithIssues.size > 0 ? /* @__PURE__ */ jsxs("div", { children: [
3214
+ /* @__PURE__ */ jsxs(
3215
+ "div",
3216
+ {
3217
+ style: {
3218
+ fontSize: 12,
3219
+ fontWeight: 600,
3220
+ color: theme.colors.textMuted,
3221
+ marginBottom: 8
3222
+ },
3223
+ children: [
3224
+ "Files with Issues (",
3225
+ filesWithIssues.size,
3226
+ ")"
3227
+ ]
3228
+ }
3229
+ ),
3230
+ /* @__PURE__ */ jsx(
3231
+ "div",
3232
+ {
3233
+ style: {
3234
+ display: "flex",
3235
+ flexDirection: "column",
3236
+ gap: 4
3237
+ },
3238
+ children: Array.from(filesWithIssues.entries()).map(
3239
+ ([file, issues]) => {
3240
+ const isFileExpanded = expandedFiles.has(file);
3241
+ return /* @__PURE__ */ jsxs(
3242
+ "div",
3243
+ {
3244
+ style: {
3245
+ border: `1px solid ${theme.colors.border}`,
3246
+ borderRadius: 4,
3247
+ overflow: "hidden"
3248
+ },
3249
+ children: [
3250
+ /* @__PURE__ */ jsxs(
3251
+ "div",
3252
+ {
3253
+ onClick: () => toggleFile(file),
3254
+ style: {
3255
+ display: "flex",
3256
+ alignItems: "center",
3257
+ justifyContent: "space-between",
3258
+ padding: "8px 10px",
3259
+ backgroundColor: theme.colors.surface,
3260
+ cursor: "pointer"
3261
+ },
3262
+ children: [
3263
+ /* @__PURE__ */ jsxs(
3264
+ "div",
3265
+ {
3266
+ style: {
3267
+ display: "flex",
3268
+ alignItems: "center",
3269
+ gap: 6
3270
+ },
3271
+ children: [
3272
+ /* @__PURE__ */ jsx(
3273
+ "svg",
3274
+ {
3275
+ width: "12",
3276
+ height: "12",
3277
+ viewBox: "0 0 24 24",
3278
+ fill: "none",
3279
+ stroke: theme.colors.textMuted,
3280
+ strokeWidth: "2",
3281
+ style: {
3282
+ transform: isFileExpanded ? "rotate(90deg)" : "rotate(0deg)",
3283
+ transition: "transform 0.15s ease"
3284
+ },
3285
+ children: /* @__PURE__ */ jsx("polyline", { points: "9,18 15,12 9,6" })
3286
+ }
3287
+ ),
3288
+ /* @__PURE__ */ jsx(
3289
+ "span",
3290
+ {
3291
+ style: {
3292
+ color: theme.colors.text,
3293
+ cursor: onFileClick ? "pointer" : "default"
3294
+ },
3295
+ onClick: (e) => {
3296
+ if (onFileClick) {
3297
+ e.stopPropagation();
3298
+ onFileClick(file);
3299
+ }
3300
+ },
3301
+ children: file
3302
+ }
3303
+ )
3304
+ ]
3305
+ }
3306
+ ),
3307
+ /* @__PURE__ */ jsxs(
3308
+ "span",
3309
+ {
3310
+ style: {
3311
+ fontSize: 11,
3312
+ padding: "2px 6px",
3313
+ borderRadius: 4,
3314
+ backgroundColor: getSeverityBg("error"),
3315
+ color: getSeverityColor("error")
3316
+ },
3317
+ children: [
3318
+ issues.length,
3319
+ " issues"
3320
+ ]
3321
+ }
3322
+ )
3323
+ ]
3324
+ }
3325
+ ),
3326
+ isFileExpanded && /* @__PURE__ */ jsx(
3327
+ "div",
3328
+ {
3329
+ style: {
3330
+ padding: 8,
3331
+ backgroundColor: theme.colors.background,
3332
+ borderTop: `1px solid ${theme.colors.border}`,
3333
+ maxHeight: 300,
3334
+ overflow: "auto"
3335
+ },
3336
+ children: issues.map((issue, issueIdx) => /* @__PURE__ */ jsxs(
3337
+ "div",
3338
+ {
3339
+ onClick: () => onFileClick == null ? void 0 : onFileClick(file, issue.line),
3340
+ style: {
3341
+ display: "flex",
3342
+ gap: 8,
3343
+ padding: "6px 8px",
3344
+ borderRadius: 4,
3345
+ cursor: onFileClick ? "pointer" : "default",
3346
+ transition: "background-color 0.1s ease"
3347
+ },
3348
+ onMouseEnter: (e) => {
3349
+ e.currentTarget.style.backgroundColor = theme.colors.surface;
3350
+ },
3351
+ onMouseLeave: (e) => {
3352
+ e.currentTarget.style.backgroundColor = "transparent";
3353
+ },
3354
+ children: [
3355
+ /* @__PURE__ */ jsxs(
3356
+ "span",
3357
+ {
3358
+ style: {
3359
+ fontSize: 11,
3360
+ color: theme.colors.textMuted,
3361
+ minWidth: 45
3362
+ },
3363
+ children: [
3364
+ "L",
3365
+ issue.line
3366
+ ]
3367
+ }
3368
+ ),
3369
+ /* @__PURE__ */ jsx(
3370
+ "span",
3371
+ {
3372
+ style: {
3373
+ fontSize: 10,
3374
+ padding: "1px 4px",
3375
+ borderRadius: 3,
3376
+ backgroundColor: getSeverityBg(
3377
+ issue.severity
3378
+ ),
3379
+ color: getSeverityColor(
3380
+ issue.severity
3381
+ ),
3382
+ textTransform: "uppercase"
3383
+ },
3384
+ children: issue.severity.charAt(0)
3385
+ }
3386
+ ),
3387
+ /* @__PURE__ */ jsx(
3388
+ "span",
3389
+ {
3390
+ style: {
3391
+ flex: 1,
3392
+ fontSize: 12,
3393
+ color: theme.colors.text
3394
+ },
3395
+ children: issue.message
3396
+ }
3397
+ ),
3398
+ issue.rule && /* @__PURE__ */ jsx(
3399
+ "span",
3400
+ {
3401
+ style: {
3402
+ fontSize: 10,
3403
+ color: theme.colors.textMuted,
3404
+ opacity: 0.7
3405
+ },
3406
+ children: issue.rule
3407
+ }
3408
+ )
3409
+ ]
3410
+ },
3411
+ issueIdx
3412
+ ))
3413
+ }
3414
+ )
3415
+ ]
3416
+ },
3417
+ file
3418
+ );
2725
3419
  }
2726
- ),
2727
- isFileExpanded && /* @__PURE__ */ jsx("div", { style: {
3420
+ )
3421
+ }
3422
+ )
3423
+ ] }) : /* @__PURE__ */ jsx(
3424
+ "div",
3425
+ {
3426
+ style: {
3427
+ padding: 16,
3428
+ textAlign: "center",
3429
+ color: theme.colors.textMuted,
3430
+ backgroundColor: theme.colors.surface,
3431
+ borderRadius: 4
3432
+ },
3433
+ children: "No issues found"
3434
+ }
3435
+ ),
3436
+ result.fileMetrics && result.fileMetrics.length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginTop: 16 }, children: [
3437
+ /* @__PURE__ */ jsxs(
3438
+ "div",
3439
+ {
3440
+ style: {
3441
+ fontSize: 12,
3442
+ fontWeight: 600,
3443
+ color: theme.colors.textMuted,
3444
+ marginBottom: 8
3445
+ },
3446
+ children: [
3447
+ "File Metrics (",
3448
+ result.fileMetrics.length,
3449
+ ")"
3450
+ ]
3451
+ }
3452
+ ),
3453
+ /* @__PURE__ */ jsx(
3454
+ "div",
3455
+ {
3456
+ style: {
3457
+ display: "flex",
3458
+ flexDirection: "column",
3459
+ gap: 2,
2728
3460
  padding: 8,
2729
- backgroundColor: theme.colors.background,
2730
- borderTop: `1px solid ${theme.colors.border}`,
2731
- maxHeight: 300,
2732
- overflow: "auto"
2733
- }, children: issues.map((issue, issueIdx) => /* @__PURE__ */ jsxs(
3461
+ backgroundColor: theme.colors.surface,
3462
+ borderRadius: 4
3463
+ },
3464
+ children: result.fileMetrics.map((fm, idx2) => /* @__PURE__ */ jsxs(
2734
3465
  "div",
2735
3466
  {
2736
- onClick: () => onFileClick == null ? void 0 : onFileClick(file, issue.line),
2737
3467
  style: {
2738
3468
  display: "flex",
2739
- gap: 8,
2740
- padding: "6px 8px",
2741
- borderRadius: 4,
2742
- cursor: onFileClick ? "pointer" : "default",
2743
- transition: "background-color 0.1s ease"
2744
- },
2745
- onMouseEnter: (e) => {
2746
- e.currentTarget.style.backgroundColor = theme.colors.surface;
2747
- },
2748
- onMouseLeave: (e) => {
2749
- e.currentTarget.style.backgroundColor = "transparent";
3469
+ alignItems: "center",
3470
+ justifyContent: "space-between",
3471
+ padding: "4px 8px"
2750
3472
  },
2751
3473
  children: [
2752
- /* @__PURE__ */ jsxs("span", { style: {
2753
- fontSize: 11,
2754
- color: theme.colors.textMuted,
2755
- minWidth: 45
2756
- }, children: [
2757
- "L",
2758
- issue.line
2759
- ] }),
2760
- /* @__PURE__ */ jsx("span", { style: {
2761
- fontSize: 10,
2762
- padding: "1px 4px",
2763
- borderRadius: 3,
2764
- backgroundColor: getSeverityBg(issue.severity),
2765
- color: getSeverityColor(issue.severity),
2766
- textTransform: "uppercase"
2767
- }, children: issue.severity.charAt(0) }),
2768
- /* @__PURE__ */ jsx("span", { style: {
2769
- flex: 1,
2770
- fontSize: 12,
2771
- color: theme.colors.text
2772
- }, children: issue.message }),
2773
- issue.rule && /* @__PURE__ */ jsx("span", { style: {
2774
- fontSize: 10,
2775
- color: theme.colors.textMuted,
2776
- opacity: 0.7
2777
- }, children: issue.rule })
3474
+ /* @__PURE__ */ jsx(
3475
+ "span",
3476
+ {
3477
+ style: { color: theme.colors.text, fontSize: 12 },
3478
+ children: fm.file
3479
+ }
3480
+ ),
3481
+ /* @__PURE__ */ jsxs(
3482
+ "span",
3483
+ {
3484
+ style: {
3485
+ fontSize: 12,
3486
+ fontWeight: 500,
3487
+ color: fm.score >= 80 ? "#22c55e" : fm.score >= 60 ? "#f59e0b" : "#ef4444"
3488
+ },
3489
+ children: [
3490
+ fm.score,
3491
+ "%"
3492
+ ]
3493
+ }
3494
+ )
2778
3495
  ]
2779
3496
  },
2780
- issueIdx
2781
- )) })
2782
- ]
2783
- },
2784
- file
2785
- );
2786
- }) })
2787
- ] }) : /* @__PURE__ */ jsx("div", { style: {
2788
- padding: 16,
2789
- textAlign: "center",
2790
- color: theme.colors.textMuted,
2791
- backgroundColor: theme.colors.surface,
2792
- borderRadius: 4
2793
- }, children: "No issues found" }),
2794
- result.fileMetrics && result.fileMetrics.length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginTop: 16 }, children: [
2795
- /* @__PURE__ */ jsxs("div", { style: {
2796
- fontSize: 12,
2797
- fontWeight: 600,
2798
- color: theme.colors.textMuted,
2799
- marginBottom: 8
2800
- }, children: [
2801
- "File Metrics (",
2802
- result.fileMetrics.length,
2803
- ")"
2804
- ] }),
2805
- /* @__PURE__ */ jsx("div", { style: {
2806
- display: "flex",
2807
- flexDirection: "column",
2808
- gap: 2,
2809
- padding: 8,
2810
- backgroundColor: theme.colors.surface,
2811
- borderRadius: 4
2812
- }, children: result.fileMetrics.map((fm, idx2) => /* @__PURE__ */ jsxs(
2813
- "div",
2814
- {
2815
- style: {
2816
- display: "flex",
2817
- alignItems: "center",
2818
- justifyContent: "space-between",
2819
- padding: "4px 8px"
2820
- },
2821
- children: [
2822
- /* @__PURE__ */ jsx("span", { style: { color: theme.colors.text, fontSize: 12 }, children: fm.file }),
2823
- /* @__PURE__ */ jsxs("span", { style: {
2824
- fontSize: 12,
2825
- fontWeight: 500,
2826
- color: fm.score >= 80 ? "#22c55e" : fm.score >= 60 ? "#f59e0b" : "#ef4444"
2827
- }, children: [
2828
- fm.score,
2829
- "%"
2830
- ] })
2831
- ]
2832
- },
2833
- idx2
2834
- )) })
2835
- ] })
2836
- ] })
3497
+ idx2
3498
+ ))
3499
+ }
3500
+ )
3501
+ ] })
3502
+ ]
3503
+ }
3504
+ )
2837
3505
  ]
2838
3506
  },
2839
3507
  lensKey
@@ -2876,45 +3544,68 @@ const LensDataDebugPanelContent = ({
2876
3544
  flexDirection: "column"
2877
3545
  },
2878
3546
  children: [
2879
- /* @__PURE__ */ jsxs("div", { style: {
2880
- display: "flex",
2881
- alignItems: "center",
2882
- justifyContent: "space-between",
2883
- height: 40,
2884
- flexShrink: 0,
2885
- padding: "0 16px",
2886
- borderBottom: `1px solid ${theme.colors.border}`,
2887
- boxSizing: "border-box"
2888
- }, children: [
2889
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
2890
- /* @__PURE__ */ jsx(Bug, { size: 18, color: theme.colors.primary }),
2891
- /* @__PURE__ */ jsx(
2892
- "h2",
2893
- {
2894
- style: {
2895
- margin: 0,
2896
- fontSize: 14,
2897
- fontWeight: 600,
2898
- color: theme.colors.text
2899
- },
2900
- children: "Lens Data Debug"
2901
- }
2902
- )
2903
- ] }),
2904
- (lensResultsSlice == null ? void 0 : lensResultsSlice.data) && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12, fontSize: 11, color: theme.colors.textMuted }, children: [
2905
- /* @__PURE__ */ jsxs("span", { children: [
2906
- new Set(lensResultsSlice.data.results.map((r2) => {
2907
- var _a;
2908
- return ((_a = r2.package) == null ? void 0 : _a.name) ?? "unknown";
2909
- })).size,
2910
- " packages"
2911
- ] }),
2912
- /* @__PURE__ */ jsxs("span", { children: [
2913
- lensResultsSlice.data.results.length,
2914
- " results"
2915
- ] })
2916
- ] })
2917
- ] }),
3547
+ /* @__PURE__ */ jsxs(
3548
+ "div",
3549
+ {
3550
+ style: {
3551
+ display: "flex",
3552
+ alignItems: "center",
3553
+ justifyContent: "space-between",
3554
+ height: 40,
3555
+ flexShrink: 0,
3556
+ padding: "0 16px",
3557
+ borderBottom: `1px solid ${theme.colors.border}`,
3558
+ boxSizing: "border-box"
3559
+ },
3560
+ children: [
3561
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
3562
+ /* @__PURE__ */ jsx(Bug, { size: 18, color: theme.colors.primary }),
3563
+ /* @__PURE__ */ jsx(
3564
+ "h2",
3565
+ {
3566
+ style: {
3567
+ margin: 0,
3568
+ fontSize: 14,
3569
+ fontWeight: 600,
3570
+ color: theme.colors.text
3571
+ },
3572
+ children: "Lens Data Debug"
3573
+ }
3574
+ )
3575
+ ] }),
3576
+ (lensResultsSlice == null ? void 0 : lensResultsSlice.data) && /* @__PURE__ */ jsxs(
3577
+ "div",
3578
+ {
3579
+ style: {
3580
+ display: "flex",
3581
+ alignItems: "center",
3582
+ gap: 12,
3583
+ fontSize: 11,
3584
+ color: theme.colors.textMuted
3585
+ },
3586
+ children: [
3587
+ /* @__PURE__ */ jsxs("span", { children: [
3588
+ new Set(
3589
+ lensResultsSlice.data.results.map(
3590
+ (r2) => {
3591
+ var _a;
3592
+ return ((_a = r2.package) == null ? void 0 : _a.name) ?? "unknown";
3593
+ }
3594
+ )
3595
+ ).size,
3596
+ " ",
3597
+ "packages"
3598
+ ] }),
3599
+ /* @__PURE__ */ jsxs("span", { children: [
3600
+ lensResultsSlice.data.results.length,
3601
+ " results"
3602
+ ] })
3603
+ ]
3604
+ }
3605
+ )
3606
+ ]
3607
+ }
3608
+ ),
2918
3609
  /* @__PURE__ */ jsx(
2919
3610
  "div",
2920
3611
  {
@@ -2923,19 +3614,38 @@ const LensDataDebugPanelContent = ({
2923
3614
  minHeight: 0,
2924
3615
  overflow: "auto"
2925
3616
  },
2926
- children: isLoading ? /* @__PURE__ */ jsx("div", { style: {
2927
- padding: 40,
2928
- textAlign: "center",
2929
- color: theme.colors.textMuted
2930
- }, children: "Loading lens results..." }) : !hasSlice || !(lensResultsSlice == null ? void 0 : lensResultsSlice.data) ? /* @__PURE__ */ jsxs("div", { style: {
2931
- padding: 40,
2932
- textAlign: "center",
2933
- color: theme.colors.textMuted
2934
- }, children: [
2935
- /* @__PURE__ */ jsx(Bug, { size: 48, color: theme.colors.border, style: { marginBottom: 16 } }),
2936
- /* @__PURE__ */ jsx("div", { style: { fontSize: 14, marginBottom: 8 }, children: "No lens data available" }),
2937
- /* @__PURE__ */ jsx("div", { style: { fontSize: 12 }, children: "Run quality-lens-cli or check that the lensResults slice is configured." })
2938
- ] }) : /* @__PURE__ */ jsx(
3617
+ children: isLoading ? /* @__PURE__ */ jsx(
3618
+ "div",
3619
+ {
3620
+ style: {
3621
+ padding: 40,
3622
+ textAlign: "center",
3623
+ color: theme.colors.textMuted
3624
+ },
3625
+ children: "Loading lens results..."
3626
+ }
3627
+ ) : !hasSlice || !(lensResultsSlice == null ? void 0 : lensResultsSlice.data) ? /* @__PURE__ */ jsxs(
3628
+ "div",
3629
+ {
3630
+ style: {
3631
+ padding: 40,
3632
+ textAlign: "center",
3633
+ color: theme.colors.textMuted
3634
+ },
3635
+ children: [
3636
+ /* @__PURE__ */ jsx(
3637
+ Bug,
3638
+ {
3639
+ size: 48,
3640
+ color: theme.colors.border,
3641
+ style: { marginBottom: 16 }
3642
+ }
3643
+ ),
3644
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 14, marginBottom: 8 }, children: "No lens data available" }),
3645
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 12 }, children: "Run quality-lens-cli or check that the lensResults slice is configured." })
3646
+ ]
3647
+ }
3648
+ ) : /* @__PURE__ */ jsx(
2939
3649
  LensDataDebugPanel$1,
2940
3650
  {
2941
3651
  data: lensResultsSlice.data,
@@ -3019,10 +3729,26 @@ function getMetricIcon(key) {
3019
3729
  }
3020
3730
  const METRIC_CONFIG = [
3021
3731
  { key: "types", label: "Types", description: "Type safety score" },
3022
- { key: "documentation", label: "Documentation", description: "Documentation coverage" },
3023
- { key: "tests", label: "Tests", description: "Test coverage and passing rate" },
3024
- { key: "deadCode", label: "Dead Code", description: "Unused code detected" },
3025
- { key: "formatting", label: "Formatting", description: "Code formatting consistency" },
3732
+ {
3733
+ key: "documentation",
3734
+ label: "Documentation",
3735
+ description: "Documentation coverage"
3736
+ },
3737
+ {
3738
+ key: "tests",
3739
+ label: "Tests",
3740
+ description: "Test coverage and passing rate"
3741
+ },
3742
+ {
3743
+ key: "deadCode",
3744
+ label: "Dead Code",
3745
+ description: "Unused code detected"
3746
+ },
3747
+ {
3748
+ key: "formatting",
3749
+ label: "Formatting",
3750
+ description: "Code formatting consistency"
3751
+ },
3026
3752
  { key: "linting", label: "Linting", description: "Linting compliance" }
3027
3753
  ];
3028
3754
  function QualityMetricsList({