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

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 +1544 -821
  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,77 @@ 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 || lensesRan.length === 0) {
459
+ return true;
460
+ }
461
+ return lensesRan.some((lensId) => LENS_TO_METRIC_MAP[lensId] === metricKey);
462
+ }
409
463
  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 }
464
+ {
465
+ key: "formatting",
466
+ label: "Format",
467
+ color: themeColors.metricColors.formatting,
468
+ angle: -120
469
+ },
470
+ {
471
+ key: "linting",
472
+ label: "Linting",
473
+ color: themeColors.metricColors.linting,
474
+ angle: -60
475
+ },
476
+ {
477
+ key: "types",
478
+ label: "Types",
479
+ color: themeColors.metricColors.types,
480
+ angle: 0
481
+ },
482
+ {
483
+ key: "tests",
484
+ label: "Tests",
485
+ color: themeColors.metricColors.tests,
486
+ angle: 60
487
+ },
488
+ {
489
+ key: "deadCode",
490
+ label: "Dead Code",
491
+ color: themeColors.metricColors.deadCode,
492
+ angle: 120
493
+ },
494
+ {
495
+ key: "documentation",
496
+ label: "Docs",
497
+ color: themeColors.metricColors.documentation,
498
+ angle: 180
499
+ }
416
500
  ];
417
501
  function calculateHexagonPoints(center, radius, metricConfig) {
418
502
  return metricConfig.map(({ angle }) => {
@@ -437,6 +521,7 @@ function QualityHexagon({
437
521
  showLabels = false,
438
522
  showValues = false,
439
523
  className,
524
+ lensesRan,
440
525
  onVertexHover,
441
526
  onVertexLeave,
442
527
  onVertexClick
@@ -453,17 +538,26 @@ function QualityHexagon({
453
538
  const dotSize = viewBoxSize * 0.015;
454
539
  const hexagonPoints = calculateHexagonPoints(center, radius, metricConfig);
455
540
  const dataPoints = metricConfig.map(({ key, angle }) => {
541
+ const configured = isMetricConfigured(key, lensesRan);
542
+ if (!configured) {
543
+ return calculateMetricPoint(center, radius, angle, 0);
544
+ }
456
545
  let value = metrics[key];
457
546
  if (key === "deadCode") {
458
547
  value = 100 - value;
459
548
  }
460
549
  return calculateMetricPoint(center, radius, angle, value);
461
550
  }).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
551
+ const configuredMetrics = metricConfig.filter(
552
+ ({ key }) => isMetricConfigured(key, lensesRan)
466
553
  );
554
+ const metricsForAverage = configuredMetrics.map(({ key }) => {
555
+ const value = metrics[key];
556
+ return key === "deadCode" ? 100 - value : value;
557
+ });
558
+ const averageScore = metricsForAverage.length > 0 ? Math.round(
559
+ metricsForAverage.reduce((a, b) => a + b, 0) / metricsForAverage.length
560
+ ) : 0;
467
561
  const hexagon = /* @__PURE__ */ jsxs(
468
562
  "svg",
469
563
  {
@@ -474,7 +568,11 @@ function QualityHexagon({
474
568
  /* @__PURE__ */ jsx("g", { className: "opacity-20", children: [20, 40, 60, 80, 100].map((percent) => /* @__PURE__ */ jsx(
475
569
  "polygon",
476
570
  {
477
- points: calculateHexagonPoints(center, radius * percent / 100, metricConfig),
571
+ points: calculateHexagonPoints(
572
+ center,
573
+ radius * percent / 100,
574
+ metricConfig
575
+ ),
478
576
  fill: "none",
479
577
  stroke: themeColors.gridColor,
480
578
  strokeWidth: 0.5,
@@ -520,13 +618,20 @@ function QualityHexagon({
520
618
  }
521
619
  ),
522
620
  metricConfig.map(({ key, label, color, angle }) => {
621
+ const configured = isMetricConfigured(key, lensesRan);
523
622
  const rawValue = metrics[key];
524
623
  let value = rawValue;
525
624
  if (key === "deadCode") {
526
625
  value = 100 - value;
527
626
  }
627
+ const effectiveValue = configured ? value : 0;
528
628
  const point = calculateMetricPoint(center, radius, angle, 100);
529
- const dataPoint = calculateMetricPoint(center, radius, angle, value);
629
+ const dataPoint = calculateMetricPoint(
630
+ center,
631
+ radius,
632
+ angle,
633
+ effectiveValue
634
+ );
530
635
  const vertexInfo = {
531
636
  key,
532
637
  label,
@@ -538,7 +643,9 @@ function QualityHexagon({
538
643
  };
539
644
  const handleClick = (e) => {
540
645
  e.stopPropagation();
541
- onVertexClick == null ? void 0 : onVertexClick(vertexInfo);
646
+ if (configured) {
647
+ onVertexClick == null ? void 0 : onVertexClick(vertexInfo);
648
+ }
542
649
  };
543
650
  return /* @__PURE__ */ jsxs(
544
651
  "g",
@@ -546,7 +653,10 @@ function QualityHexagon({
546
653
  onMouseEnter: handleMouseEnter,
547
654
  onMouseLeave: onVertexLeave,
548
655
  onClick: handleClick,
549
- style: { cursor: onVertexHover || onVertexClick ? "pointer" : "default" },
656
+ style: {
657
+ cursor: configured && (onVertexHover || onVertexClick) ? "pointer" : "default",
658
+ opacity: configured ? 1 : 0.4
659
+ },
550
660
  children: [
551
661
  /* @__PURE__ */ jsx(
552
662
  "circle",
@@ -563,12 +673,13 @@ function QualityHexagon({
563
673
  cx: point.x,
564
674
  cy: point.y,
565
675
  r: dotSize,
566
- fill: "white",
567
- stroke: colors.stroke,
568
- strokeWidth: 1.5
676
+ fill: configured ? "white" : themeColors.gridColor,
677
+ stroke: configured ? colors.stroke : themeColors.gridColor,
678
+ strokeWidth: 1.5,
679
+ strokeDasharray: configured ? "none" : "2,2"
569
680
  }
570
681
  ),
571
- /* @__PURE__ */ jsx(
682
+ configured && /* @__PURE__ */ jsx(
572
683
  "circle",
573
684
  {
574
685
  cx: dataPoint.x,
@@ -678,117 +789,190 @@ function QualityHexagonDetailed({
678
789
  backgroundColor: colors.bg
679
790
  },
680
791
  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",
792
+ hasHeader && /* @__PURE__ */ jsxs(
793
+ "div",
794
+ {
795
+ style: {
796
+ display: "flex",
797
+ alignItems: "center",
798
+ justifyContent: "space-between",
799
+ gap: 12
800
+ },
801
+ children: [
802
+ packageName ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
803
+ packageName.startsWith("@") && packageName.includes("/") ? /* @__PURE__ */ jsxs(Fragment, { children: [
804
+ /* @__PURE__ */ jsx(
805
+ "span",
806
+ {
807
+ style: {
808
+ fontSize: 12,
809
+ color: theme.colors.textMuted
810
+ },
811
+ children: packageName.split("/")[0]
812
+ }
813
+ ),
814
+ /* @__PURE__ */ jsx(
815
+ "span",
816
+ {
817
+ style: {
818
+ fontSize: 14,
819
+ fontWeight: 500,
820
+ color: colors.stroke
821
+ },
822
+ children: packageName.split("/")[1]
823
+ }
824
+ )
825
+ ] }) : /* @__PURE__ */ jsx(
826
+ "span",
827
+ {
828
+ style: {
829
+ fontSize: 14,
830
+ fontWeight: 500,
831
+ color: colors.stroke
832
+ },
833
+ children: packageName
834
+ }
835
+ ),
836
+ packageVersion && /* @__PURE__ */ jsxs(
837
+ "span",
838
+ {
839
+ style: {
840
+ fontSize: 12,
841
+ color: theme.colors.textMuted
842
+ },
843
+ children: [
844
+ "v",
845
+ packageVersion
846
+ ]
847
+ }
848
+ )
849
+ ] }) : /* @__PURE__ */ jsx("span", {}),
850
+ onRefresh && /* @__PURE__ */ jsx(
851
+ "button",
731
852
  {
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",
853
+ onClick: onRefresh,
854
+ disabled: isRefreshing,
740
855
  style: {
741
- animation: isRefreshing ? "spin 1s linear infinite" : "none"
856
+ padding: 6,
857
+ display: "flex",
858
+ alignItems: "center",
859
+ justifyContent: "center",
860
+ border: `1px solid ${theme.colors.border}`,
861
+ borderRadius: 4,
862
+ background: theme.colors.surface,
863
+ color: theme.colors.textMuted,
864
+ cursor: isRefreshing ? "not-allowed" : "pointer",
865
+ opacity: isRefreshing ? 0.6 : 1
742
866
  },
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
- ]
867
+ title: "Refresh",
868
+ children: /* @__PURE__ */ jsxs(
869
+ "svg",
870
+ {
871
+ width: "14",
872
+ height: "14",
873
+ viewBox: "0 0 24 24",
874
+ fill: "none",
875
+ stroke: "currentColor",
876
+ strokeWidth: "2",
877
+ strokeLinecap: "round",
878
+ strokeLinejoin: "round",
879
+ style: {
880
+ animation: isRefreshing ? "spin 1s linear infinite" : "none"
881
+ },
882
+ children: [
883
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
884
+ /* @__PURE__ */ jsx("path", { d: "M3 3v5h5" }),
885
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" }),
886
+ /* @__PURE__ */ jsx("path", { d: "M16 16h5v5" })
887
+ ]
888
+ }
889
+ )
749
890
  }
750
891
  )
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
- ] })
892
+ ]
893
+ }
894
+ ),
895
+ /* @__PURE__ */ jsxs(
896
+ "div",
897
+ {
898
+ style: {
899
+ display: "flex",
900
+ flexWrap: "wrap",
901
+ alignItems: "center",
902
+ justifyContent: "center",
903
+ gap: 24
904
+ },
905
+ children: [
906
+ /* @__PURE__ */ jsx("div", { style: { flex: "1 1 200px", maxWidth: 300, aspectRatio: "1 / 1" }, children: /* @__PURE__ */ jsx(
907
+ QualityHexagon,
908
+ {
909
+ metrics,
910
+ tier,
911
+ theme,
912
+ showLabels: true,
913
+ showValues: false
914
+ }
915
+ ) }),
916
+ /* @__PURE__ */ jsx(
917
+ "div",
918
+ {
919
+ style: {
920
+ flex: "1 1 200px",
921
+ minWidth: 200,
922
+ display: "flex",
923
+ flexDirection: "column",
924
+ gap: 8,
925
+ padding: "8px 24px"
926
+ },
927
+ children: metricConfig.map(({ key, label }) => {
928
+ const value = metrics[key];
929
+ return /* @__PURE__ */ jsxs(
930
+ "div",
931
+ {
932
+ style: {
933
+ display: "flex",
934
+ alignItems: "center",
935
+ justifyContent: "space-between",
936
+ gap: 12
937
+ },
938
+ children: [
939
+ /* @__PURE__ */ jsxs(
940
+ "span",
941
+ {
942
+ style: {
943
+ fontSize: 14,
944
+ color: theme.colors.textMuted
945
+ },
946
+ children: [
947
+ label,
948
+ key === "deadCode" ? " ↓" : ""
949
+ ]
950
+ }
951
+ ),
952
+ /* @__PURE__ */ jsxs(
953
+ "span",
954
+ {
955
+ style: {
956
+ fontSize: 14,
957
+ fontWeight: 500,
958
+ color: getValueColor$2(value, key)
959
+ },
960
+ children: [
961
+ value,
962
+ "%"
963
+ ]
964
+ }
965
+ )
966
+ ]
967
+ },
968
+ key
969
+ );
970
+ })
971
+ }
972
+ )
973
+ ]
974
+ }
975
+ )
792
976
  ]
793
977
  }
794
978
  );
@@ -801,6 +985,7 @@ function QualityHexagonExpandable({
801
985
  packageName,
802
986
  packageVersion,
803
987
  packagePath,
988
+ lensesRan,
804
989
  onRefresh,
805
990
  isRefreshing = false,
806
991
  defaultExpanded = false,
@@ -831,79 +1016,109 @@ function QualityHexagonExpandable({
831
1016
  flex: "1 1 200px"
832
1017
  },
833
1018
  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",
1019
+ hasHeader && /* @__PURE__ */ jsxs(
1020
+ "div",
1021
+ {
1022
+ style: {
1023
+ display: "flex",
1024
+ alignItems: "center",
1025
+ justifyContent: "space-between",
1026
+ gap: 12
1027
+ },
1028
+ children: [
1029
+ packageName ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
1030
+ packageName.startsWith("@") && packageName.includes("/") ? /* @__PURE__ */ jsxs(Fragment, { children: [
1031
+ /* @__PURE__ */ jsx(
1032
+ "span",
1033
+ {
1034
+ style: {
1035
+ fontSize: 12,
1036
+ color: theme.colors.textMuted
1037
+ },
1038
+ children: packageName.split("/")[0]
1039
+ }
1040
+ ),
1041
+ /* @__PURE__ */ jsx(
1042
+ "span",
1043
+ {
1044
+ style: {
1045
+ fontSize: 14,
1046
+ fontWeight: 500,
1047
+ color: colors.stroke
1048
+ },
1049
+ children: packageName.split("/")[1]
1050
+ }
1051
+ )
1052
+ ] }) : /* @__PURE__ */ jsx(
1053
+ "span",
1054
+ {
1055
+ style: {
1056
+ fontSize: 14,
1057
+ fontWeight: 500,
1058
+ color: colors.stroke
1059
+ },
1060
+ children: packageName
1061
+ }
1062
+ ),
1063
+ packageVersion && /* @__PURE__ */ jsxs(
1064
+ "span",
1065
+ {
1066
+ style: {
1067
+ fontSize: 12,
1068
+ color: theme.colors.textMuted
1069
+ },
1070
+ children: [
1071
+ "v",
1072
+ packageVersion
1073
+ ]
1074
+ }
1075
+ )
1076
+ ] }) : /* @__PURE__ */ jsx("span", {}),
1077
+ onRefresh && /* @__PURE__ */ jsx(
1078
+ "button",
884
1079
  {
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",
1080
+ onClick: onRefresh,
1081
+ disabled: isRefreshing,
893
1082
  style: {
894
- animation: isRefreshing ? "spin 1s linear infinite" : "none"
1083
+ padding: 6,
1084
+ display: "flex",
1085
+ alignItems: "center",
1086
+ justifyContent: "center",
1087
+ border: `1px solid ${theme.colors.border}`,
1088
+ borderRadius: 4,
1089
+ background: theme.colors.surface,
1090
+ color: theme.colors.textMuted,
1091
+ cursor: isRefreshing ? "not-allowed" : "pointer",
1092
+ opacity: isRefreshing ? 0.6 : 1
895
1093
  },
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
- ]
1094
+ title: "Refresh",
1095
+ children: /* @__PURE__ */ jsxs(
1096
+ "svg",
1097
+ {
1098
+ width: "14",
1099
+ height: "14",
1100
+ viewBox: "0 0 24 24",
1101
+ fill: "none",
1102
+ stroke: "currentColor",
1103
+ strokeWidth: "2",
1104
+ strokeLinecap: "round",
1105
+ strokeLinejoin: "round",
1106
+ style: {
1107
+ animation: isRefreshing ? "spin 1s linear infinite" : "none"
1108
+ },
1109
+ children: [
1110
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
1111
+ /* @__PURE__ */ jsx("path", { d: "M3 3v5h5" }),
1112
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" }),
1113
+ /* @__PURE__ */ jsx("path", { d: "M16 16h5v5" })
1114
+ ]
1115
+ }
1116
+ )
902
1117
  }
903
1118
  )
904
- }
905
- )
906
- ] }),
1119
+ ]
1120
+ }
1121
+ ),
907
1122
  /* @__PURE__ */ jsx(
908
1123
  "div",
909
1124
  {
@@ -921,7 +1136,8 @@ function QualityHexagonExpandable({
921
1136
  tier,
922
1137
  theme,
923
1138
  showLabels: true,
924
- showValues: false
1139
+ showValues: false,
1140
+ lensesRan
925
1141
  }
926
1142
  ) })
927
1143
  }
@@ -934,73 +1150,93 @@ function QualityHexagonExpandable({
934
1150
  gridTemplateRows: expanded ? "1fr" : "0fr",
935
1151
  transition: "grid-template-rows 0.3s ease"
936
1152
  },
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
- ]
1153
+ children: /* @__PURE__ */ jsx("div", { style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(
1154
+ "div",
1155
+ {
1156
+ style: {
1157
+ display: "flex",
1158
+ flexDirection: "column",
1159
+ gap: 8,
1160
+ padding: "8px 24px",
1161
+ borderTop: `1px solid ${theme.colors.border}`,
1162
+ marginTop: 8
989
1163
  },
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",
1003
- padding: 4
1164
+ children: metricConfig.map(({ key, label }) => {
1165
+ const value = metrics[key];
1166
+ const configured = isMetricConfigured(key, lensesRan);
1167
+ return /* @__PURE__ */ jsxs(
1168
+ "div",
1169
+ {
1170
+ onClick: (e) => {
1171
+ e.stopPropagation();
1172
+ if (configured) {
1173
+ onMetricClick == null ? void 0 : onMetricClick(key);
1174
+ }
1175
+ },
1176
+ style: {
1177
+ display: "flex",
1178
+ alignItems: "center",
1179
+ justifyContent: "space-between",
1180
+ gap: 12,
1181
+ cursor: configured && onMetricClick ? "pointer" : "default",
1182
+ padding: "4px 8px",
1183
+ margin: "0 -8px",
1184
+ borderRadius: 4,
1185
+ transition: "background-color 0.15s ease",
1186
+ opacity: configured ? 1 : 0.5
1187
+ },
1188
+ onMouseEnter: (e) => {
1189
+ if (configured && onMetricClick) {
1190
+ e.currentTarget.style.backgroundColor = theme.colors.surface;
1191
+ }
1192
+ },
1193
+ onMouseLeave: (e) => {
1194
+ e.currentTarget.style.backgroundColor = "transparent";
1195
+ },
1196
+ children: [
1197
+ /* @__PURE__ */ jsxs(
1198
+ "span",
1199
+ {
1200
+ style: {
1201
+ fontSize: 14,
1202
+ color: theme.colors.textMuted
1203
+ },
1204
+ children: [
1205
+ label,
1206
+ key === "deadCode" ? " ↓" : ""
1207
+ ]
1208
+ }
1209
+ ),
1210
+ /* @__PURE__ */ jsx(
1211
+ "span",
1212
+ {
1213
+ style: {
1214
+ fontSize: 14,
1215
+ fontWeight: 500,
1216
+ color: configured ? getValueColor$2(value, key) : theme.colors.textMuted
1217
+ },
1218
+ title: configured ? void 0 : "Not configured",
1219
+ children: configured ? `${value}%` : "N/A"
1220
+ }
1221
+ )
1222
+ ]
1223
+ },
1224
+ key
1225
+ );
1226
+ })
1227
+ }
1228
+ ) })
1229
+ }
1230
+ ),
1231
+ /* @__PURE__ */ jsx(
1232
+ "div",
1233
+ {
1234
+ onClick: handleToggleExpand,
1235
+ style: {
1236
+ display: "flex",
1237
+ justifyContent: "center",
1238
+ cursor: "pointer",
1239
+ padding: 4
1004
1240
  },
1005
1241
  children: /* @__PURE__ */ jsx(
1006
1242
  "svg",
@@ -1026,10 +1262,26 @@ function QualityHexagonExpandable({
1026
1262
  }
1027
1263
  );
1028
1264
  }
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;
1265
+ function calculateQualityTier(metrics, lensesRan) {
1266
+ const allMetricKeys = [
1267
+ "formatting",
1268
+ "linting",
1269
+ "types",
1270
+ "tests",
1271
+ "deadCode",
1272
+ "documentation"
1273
+ ];
1274
+ const configuredKeys = allMetricKeys.filter(
1275
+ (key) => isMetricConfigured(key, lensesRan)
1276
+ );
1277
+ if (configuredKeys.length === 0) {
1278
+ return "none";
1279
+ }
1280
+ const values = configuredKeys.map((key) => {
1281
+ const value = metrics[key];
1282
+ return key === "deadCode" ? 100 - value : value;
1283
+ });
1284
+ const average = values.reduce((a, b) => a + b, 0) / values.length;
1033
1285
  if (average >= 90) return "platinum";
1034
1286
  if (average >= 75) return "gold";
1035
1287
  if (average >= 60) return "silver";
@@ -1100,12 +1352,42 @@ const CommandLine = ({ command, theme, label }) => {
1100
1352
  };
1101
1353
  const MetricsPreview = ({ theme }) => {
1102
1354
  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 }
1355
+ {
1356
+ key: "formatting",
1357
+ label: "Formatting",
1358
+ description: "Prettier code style",
1359
+ Icon: Sparkles
1360
+ },
1361
+ {
1362
+ key: "linting",
1363
+ label: "Linting",
1364
+ description: "ESLint code quality",
1365
+ Icon: FileSearch
1366
+ },
1367
+ {
1368
+ key: "types",
1369
+ label: "Types",
1370
+ description: "TypeScript type safety",
1371
+ Icon: Braces
1372
+ },
1373
+ {
1374
+ key: "tests",
1375
+ label: "Tests",
1376
+ description: "Test coverage & pass rate",
1377
+ Icon: FlaskConical
1378
+ },
1379
+ {
1380
+ key: "deadCode",
1381
+ label: "Dead Code",
1382
+ description: "Unused exports & deps",
1383
+ Icon: Trash2
1384
+ },
1385
+ {
1386
+ key: "documentation",
1387
+ label: "Docs",
1388
+ description: "Code documentation",
1389
+ Icon: BookOpen
1390
+ }
1109
1391
  ];
1110
1392
  return /* @__PURE__ */ jsx(
1111
1393
  "div",
@@ -1209,13 +1491,32 @@ const QualityEmptyState = ({
1209
1491
  color: theme.colors.textMuted
1210
1492
  },
1211
1493
  children: [
1212
- /* @__PURE__ */ jsx(Info, { size: 14, style: { flexShrink: 0, marginTop: 2 }, color: theme.colors.warning }),
1494
+ /* @__PURE__ */ jsx(
1495
+ Info,
1496
+ {
1497
+ size: 14,
1498
+ style: { flexShrink: 0, marginTop: 2 },
1499
+ color: theme.colors.warning
1500
+ }
1501
+ ),
1213
1502
  /* @__PURE__ */ jsxs("div", { children: [
1214
1503
  /* @__PURE__ */ jsx("strong", { style: { color: theme.colors.text }, children: "Using private npm packages?" }),
1215
1504
  /* @__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."
1505
+ "Add",
1506
+ " ",
1507
+ /* @__PURE__ */ jsx(
1508
+ "code",
1509
+ {
1510
+ style: {
1511
+ backgroundColor: theme.colors.background,
1512
+ padding: "1px 4px",
1513
+ borderRadius: 3
1514
+ },
1515
+ children: "NPM_TOKEN"
1516
+ }
1517
+ ),
1518
+ " ",
1519
+ "to your repository secrets and ensure the workflow has access to it."
1219
1520
  ] })
1220
1521
  ]
1221
1522
  }
@@ -1435,13 +1736,32 @@ const QualityEmptyState = ({
1435
1736
  color: theme.colors.textMuted
1436
1737
  },
1437
1738
  children: [
1438
- /* @__PURE__ */ jsx(Info, { size: 14, style: { flexShrink: 0, marginTop: 2 }, color: theme.colors.warning }),
1739
+ /* @__PURE__ */ jsx(
1740
+ Info,
1741
+ {
1742
+ size: 14,
1743
+ style: { flexShrink: 0, marginTop: 2 },
1744
+ color: theme.colors.warning
1745
+ }
1746
+ ),
1439
1747
  /* @__PURE__ */ jsxs("div", { children: [
1440
1748
  /* @__PURE__ */ jsx("strong", { style: { color: theme.colors.text }, children: "Private npm packages?" }),
1441
1749
  /* @__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."
1750
+ "If your project uses private @org packages, add",
1751
+ " ",
1752
+ /* @__PURE__ */ jsx(
1753
+ "code",
1754
+ {
1755
+ style: {
1756
+ backgroundColor: theme.colors.background,
1757
+ padding: "1px 4px",
1758
+ borderRadius: 3
1759
+ },
1760
+ children: "NPM_TOKEN"
1761
+ }
1762
+ ),
1763
+ " ",
1764
+ "to your GitHub repository secrets under Settings → Secrets → Actions, and set the workflow environment if needed."
1445
1765
  ] })
1446
1766
  ]
1447
1767
  }
@@ -1498,7 +1818,10 @@ const QualityHexagonPanelContent = ({
1498
1818
  const isLoading = (qualitySlice == null ? void 0 : qualitySlice.loading) ?? false;
1499
1819
  const fileTreeSlice = context.getSlice("fileTree");
1500
1820
  const hasWorkflow = React2__default.useMemo(() => {
1501
- return checkFileExistsInTree((fileTreeSlice == null ? void 0 : fileTreeSlice.data) ?? void 0, WORKFLOW_FILE_PATH);
1821
+ return checkFileExistsInTree(
1822
+ (fileTreeSlice == null ? void 0 : fileTreeSlice.data) ?? void 0,
1823
+ WORKFLOW_FILE_PATH
1824
+ );
1502
1825
  }, [fileTreeSlice == null ? void 0 : fileTreeSlice.data]);
1503
1826
  const packages = React2__default.useMemo(() => {
1504
1827
  var _a2;
@@ -1536,15 +1859,37 @@ const QualityHexagonPanelContent = ({
1536
1859
  gold: "#FFD700",
1537
1860
  platinum: "#E5E4E2"
1538
1861
  };
1862
+ const allLensesRan = React2__default.useMemo(() => {
1863
+ const lensSet = /* @__PURE__ */ new Set();
1864
+ for (const pkg of packages) {
1865
+ if (pkg.lensesRan) {
1866
+ for (const lens of pkg.lensesRan) {
1867
+ lensSet.add(lens);
1868
+ }
1869
+ }
1870
+ }
1871
+ return lensSet.size > 0 ? Array.from(lensSet) : void 0;
1872
+ }, [packages]);
1539
1873
  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 })
1874
+ packages.reduce(
1875
+ (acc, pkg) => ({
1876
+ tests: acc.tests + pkg.metrics.tests / packages.length,
1877
+ deadCode: acc.deadCode + pkg.metrics.deadCode / packages.length,
1878
+ linting: acc.linting + pkg.metrics.linting / packages.length,
1879
+ formatting: acc.formatting + pkg.metrics.formatting / packages.length,
1880
+ types: acc.types + pkg.metrics.types / packages.length,
1881
+ documentation: acc.documentation + pkg.metrics.documentation / packages.length
1882
+ }),
1883
+ {
1884
+ tests: 0,
1885
+ deadCode: 0,
1886
+ linting: 0,
1887
+ formatting: 0,
1888
+ types: 0,
1889
+ documentation: 0
1890
+ }
1891
+ ),
1892
+ allLensesRan
1548
1893
  ) : "none";
1549
1894
  return /* @__PURE__ */ jsxs(
1550
1895
  "div",
@@ -1562,57 +1907,69 @@ const QualityHexagonPanelContent = ({
1562
1907
  position: "relative"
1563
1908
  },
1564
1909
  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
- ] }),
1910
+ /* @__PURE__ */ jsxs(
1911
+ "div",
1912
+ {
1913
+ style: {
1914
+ display: "flex",
1915
+ alignItems: "center",
1916
+ gap: 12,
1917
+ height: 40,
1918
+ flexShrink: 0,
1919
+ padding: "0 16px",
1920
+ borderBottom: `1px solid ${theme.colors.border}`,
1921
+ boxSizing: "border-box"
1922
+ },
1923
+ children: [
1924
+ /* @__PURE__ */ jsx(Hexagon, { size: 20, color: tierColors[overallTier] }),
1925
+ /* @__PURE__ */ jsx(
1926
+ "h2",
1927
+ {
1928
+ style: {
1929
+ margin: 0,
1930
+ fontSize: 14,
1931
+ fontWeight: 600,
1932
+ color: theme.colors.text
1933
+ },
1934
+ children: "Code Quality"
1935
+ }
1936
+ ),
1937
+ /* @__PURE__ */ jsx(
1938
+ "span",
1939
+ {
1940
+ onClick: () => setShowHelpOverlay(true),
1941
+ title: "Click for help",
1942
+ style: {
1943
+ display: "inline-flex",
1944
+ alignItems: "center",
1945
+ justifyContent: "center",
1946
+ width: 16,
1947
+ height: 16,
1948
+ borderRadius: "50%",
1949
+ border: `1px solid ${theme.colors.border}`,
1950
+ fontSize: 11,
1951
+ color: theme.colors.textMuted,
1952
+ cursor: "pointer"
1953
+ },
1954
+ children: "?"
1955
+ }
1956
+ ),
1957
+ packages.length > 1 && /* @__PURE__ */ jsxs(
1958
+ "span",
1959
+ {
1960
+ style: {
1961
+ fontSize: 13,
1962
+ color: theme.colors.textMuted
1963
+ },
1964
+ children: [
1965
+ packages.length,
1966
+ " packages"
1967
+ ]
1968
+ }
1969
+ )
1970
+ ]
1971
+ }
1972
+ ),
1616
1973
  /* @__PURE__ */ jsx(
1617
1974
  "div",
1618
1975
  {
@@ -1624,54 +1981,61 @@ const QualityHexagonPanelContent = ({
1624
1981
  flex: 1,
1625
1982
  minHeight: 0
1626
1983
  },
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,
1984
+ children: /* @__PURE__ */ jsx(
1985
+ "div",
1633
1986
  {
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
- }
1987
+ style: { display: "flex", flexWrap: "wrap", gap: 16, minHeight: 0 },
1988
+ children: isLoading ? /* @__PURE__ */ jsx(
1989
+ "div",
1990
+ {
1991
+ style: {
1992
+ padding: 40,
1993
+ textAlign: "center",
1994
+ color: theme.colors.textMuted
1995
+ },
1996
+ children: "Loading quality metrics..."
1670
1997
  }
1671
- },
1672
- pkg.name
1673
- );
1674
- }) })
1998
+ ) : packages.length === 0 ? /* @__PURE__ */ jsx(QualityEmptyState, { theme, hasWorkflow }) : packages.map((pkg) => {
1999
+ const tier = calculateQualityTier(pkg.metrics, pkg.lensesRan);
2000
+ const packagePath = pkg.path ?? "";
2001
+ return /* @__PURE__ */ jsx(
2002
+ QualityHexagonExpandable,
2003
+ {
2004
+ metrics: pkg.metrics,
2005
+ tier,
2006
+ theme,
2007
+ packageName: pkg.name,
2008
+ packageVersion: pkg.version,
2009
+ packagePath,
2010
+ lensesRan: pkg.lensesRan,
2011
+ onExpandChange: (expanded, info) => {
2012
+ events.emit({
2013
+ type: "package:select",
2014
+ source: "principal-ade.quality-hexagon-panel",
2015
+ timestamp: Date.now(),
2016
+ payload: expanded ? {
2017
+ packagePath: info.packagePath ?? "",
2018
+ packageName: info.packageName
2019
+ } : null
2020
+ });
2021
+ },
2022
+ onMetricClick: (metric) => {
2023
+ const colorMode = METRIC_TO_COLOR_MODE[metric];
2024
+ if (colorMode) {
2025
+ events.emit({
2026
+ type: "quality:colorMode:select",
2027
+ source: "principal-ade.quality-hexagon-panel",
2028
+ timestamp: Date.now(),
2029
+ payload: { colorMode }
2030
+ });
2031
+ }
2032
+ }
2033
+ },
2034
+ pkg.name
2035
+ );
2036
+ })
2037
+ }
2038
+ )
1675
2039
  }
1676
2040
  ),
1677
2041
  showHelpOverlay && /* @__PURE__ */ jsx(
@@ -1703,42 +2067,66 @@ const QualityHexagonPanelContent = ({
1703
2067
  },
1704
2068
  onClick: (e) => e.stopPropagation(),
1705
2069
  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:" }),
2070
+ /* @__PURE__ */ jsxs(
2071
+ "div",
2072
+ {
2073
+ style: {
2074
+ display: "flex",
2075
+ justifyContent: "space-between",
2076
+ alignItems: "center",
2077
+ marginBottom: 16
2078
+ },
2079
+ children: [
2080
+ /* @__PURE__ */ jsx(
2081
+ "h3",
2082
+ {
2083
+ style: {
2084
+ margin: 0,
2085
+ fontSize: 16,
2086
+ fontWeight: 600,
2087
+ color: theme.colors.text
2088
+ },
2089
+ children: "Quality Lens CLI"
2090
+ }
2091
+ ),
2092
+ /* @__PURE__ */ jsx(
2093
+ "button",
2094
+ {
2095
+ onClick: () => setShowHelpOverlay(false),
2096
+ style: {
2097
+ background: "none",
2098
+ border: "none",
2099
+ cursor: "pointer",
2100
+ padding: 4,
2101
+ display: "flex",
2102
+ color: theme.colors.textMuted
2103
+ },
2104
+ children: /* @__PURE__ */ jsx(X, { size: 18 })
2105
+ }
2106
+ )
2107
+ ]
2108
+ }
2109
+ ),
2110
+ /* @__PURE__ */ jsx(
2111
+ "p",
2112
+ {
2113
+ style: {
2114
+ fontSize: 13,
2115
+ color: theme.colors.textMuted,
2116
+ margin: "0 0 12px 0"
2117
+ },
2118
+ children: "Run quality checks locally with the CLI:"
2119
+ }
2120
+ ),
1739
2121
  [
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" }
2122
+ {
2123
+ cmd: "npx @principal-ai/quality-lens-cli init",
2124
+ label: "Initialize quality lens in your project"
2125
+ },
2126
+ {
2127
+ cmd: "npx @principal-ai/quality-lens-cli list",
2128
+ label: "List available quality lenses"
2129
+ }
1742
2130
  ].map(({ cmd, label }) => /* @__PURE__ */ jsxs("div", { style: { marginBottom: 12 }, children: [
1743
2131
  /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: theme.colors.textMuted }, children: label }),
1744
2132
  /* @__PURE__ */ jsxs(
@@ -1780,22 +2168,39 @@ const QualityHexagonPanelContent = ({
1780
2168
  }
1781
2169
  )
1782
2170
  ] }, 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
- ] })
2171
+ /* @__PURE__ */ jsxs(
2172
+ "div",
2173
+ {
2174
+ style: {
2175
+ marginTop: 16,
2176
+ padding: 12,
2177
+ backgroundColor: theme.colors.background,
2178
+ borderRadius: 6,
2179
+ fontSize: 12,
2180
+ color: theme.colors.textMuted
2181
+ },
2182
+ children: [
2183
+ /* @__PURE__ */ jsx("strong", { style: { color: theme.colors.text }, children: "Tiers:" }),
2184
+ /* @__PURE__ */ jsxs(
2185
+ "div",
2186
+ {
2187
+ style: {
2188
+ marginTop: 8,
2189
+ display: "flex",
2190
+ flexDirection: "column",
2191
+ gap: 4
2192
+ },
2193
+ children: [
2194
+ /* @__PURE__ */ jsx("span", { children: "🏆 Platinum: 90%+ average" }),
2195
+ /* @__PURE__ */ jsx("span", { children: "🥇 Gold: 75%+ average" }),
2196
+ /* @__PURE__ */ jsx("span", { children: "🥈 Silver: 60%+ average" }),
2197
+ /* @__PURE__ */ jsx("span", { children: "🥉 Bronze: 40%+ average" })
2198
+ ]
2199
+ }
2200
+ )
2201
+ ]
2202
+ }
2203
+ )
1799
2204
  ]
1800
2205
  }
1801
2206
  )
@@ -1843,7 +2248,14 @@ function calculateOverallTier(items) {
1843
2248
  types: acc.types + item.metrics.types / items.length,
1844
2249
  documentation: acc.documentation + item.metrics.documentation / items.length
1845
2250
  }),
1846
- { tests: 0, deadCode: 0, linting: 0, formatting: 0, types: 0, documentation: 0 }
2251
+ {
2252
+ tests: 0,
2253
+ deadCode: 0,
2254
+ linting: 0,
2255
+ formatting: 0,
2256
+ types: 0,
2257
+ documentation: 0
2258
+ }
1847
2259
  );
1848
2260
  return calculateQualityTier(avgMetrics);
1849
2261
  }
@@ -2033,11 +2445,18 @@ function RepositoryQualityGrid({
2033
2445
  showRepositoryName = true,
2034
2446
  showSummary = true
2035
2447
  }) {
2036
- const [selectedMetric, setSelectedMetric] = React2.useState(null);
2037
- const items = React2.useMemo(() => flattenRepositories(repositories), [repositories]);
2448
+ const [selectedMetric, setSelectedMetric] = React2.useState(
2449
+ null
2450
+ );
2451
+ const items = React2.useMemo(
2452
+ () => flattenRepositories(repositories),
2453
+ [repositories]
2454
+ );
2038
2455
  const overallTier = React2.useMemo(() => calculateOverallTier(items), [items]);
2039
2456
  const sortedItems = React2.useMemo(() => {
2040
- return [...items].sort((a, b) => a.packageName.localeCompare(b.packageName));
2457
+ return [...items].sort(
2458
+ (a, b) => a.packageName.localeCompare(b.packageName)
2459
+ );
2041
2460
  }, [items]);
2042
2461
  const tierColors = {
2043
2462
  none: "#808080",
@@ -2132,7 +2551,9 @@ function RepositoryQualityGrid({
2132
2551
  "select",
2133
2552
  {
2134
2553
  value: selectedMetric ?? "",
2135
- onChange: (e) => setSelectedMetric(e.target.value ? e.target.value : null),
2554
+ onChange: (e) => setSelectedMetric(
2555
+ e.target.value ? e.target.value : null
2556
+ ),
2136
2557
  style: {
2137
2558
  padding: "4px 8px",
2138
2559
  fontSize: 13,
@@ -2224,8 +2645,12 @@ const RepositoryQualityGridPanelContent = ({
2224
2645
  }) => {
2225
2646
  var _a;
2226
2647
  const { theme } = useTheme();
2227
- const [selectedItemKey, setSelectedItemKey] = React2__default.useState(null);
2228
- const qualitySlice = context.getSlice("repositoriesQuality");
2648
+ const [selectedItemKey, setSelectedItemKey] = React2__default.useState(
2649
+ null
2650
+ );
2651
+ const qualitySlice = context.getSlice(
2652
+ "repositoriesQuality"
2653
+ );
2229
2654
  const isLoading = (qualitySlice == null ? void 0 : qualitySlice.loading) ?? false;
2230
2655
  const repositories = React2__default.useMemo(() => {
2231
2656
  var _a2;
@@ -2387,7 +2812,13 @@ function getPackageSummary(results) {
2387
2812
  failCount++;
2388
2813
  }
2389
2814
  }
2390
- return { totalErrors, totalWarnings, passCount, failCount, lensCount: results.length };
2815
+ return {
2816
+ totalErrors,
2817
+ totalWarnings,
2818
+ passCount,
2819
+ failCount,
2820
+ lensCount: results.length
2821
+ };
2391
2822
  }
2392
2823
  function LensDataDebugPanel$1({
2393
2824
  data,
@@ -2397,13 +2828,21 @@ function LensDataDebugPanel$1({
2397
2828
  onFileClick,
2398
2829
  onPackageSelect
2399
2830
  }) {
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]);
2831
+ const packageGroups = React2.useMemo(
2832
+ () => groupResultsByPackage((data == null ? void 0 : data.results) ?? []),
2833
+ [data == null ? void 0 : data.results]
2834
+ );
2835
+ const packageNames = React2.useMemo(
2836
+ () => Array.from(packageGroups.keys()),
2837
+ [packageGroups]
2838
+ );
2402
2839
  const [selectedPackage, setSelectedPackage] = React2.useState(
2403
2840
  initialSelectedPackage || (packageNames.length === 1 ? packageNames[0] : null)
2404
2841
  );
2405
2842
  const [expandedLens, setExpandedLens] = React2.useState(null);
2406
- const [expandedFiles, setExpandedFiles] = React2.useState(/* @__PURE__ */ new Set());
2843
+ const [expandedFiles, setExpandedFiles] = React2.useState(
2844
+ /* @__PURE__ */ new Set()
2845
+ );
2407
2846
  const handlePackageSelect = (pkg) => {
2408
2847
  setSelectedPackage(pkg);
2409
2848
  setExpandedLens(null);
@@ -2438,82 +2877,112 @@ function LensDataDebugPanel$1({
2438
2877
  fontSize: 13
2439
2878
  },
2440
2879
  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
- ]
2880
+ packageNames.length > 1 && /* @__PURE__ */ jsx(
2881
+ "div",
2882
+ {
2883
+ style: {
2884
+ display: "flex",
2885
+ flexWrap: "wrap",
2886
+ gap: 8,
2887
+ marginBottom: 8
2480
2888
  },
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" }),
2889
+ children: packageNames.map((pkg) => {
2890
+ const summary = getPackageSummary(packageGroups.get(pkg) || []);
2891
+ const isSelected = selectedPackage === pkg;
2892
+ return /* @__PURE__ */ jsxs(
2893
+ "button",
2894
+ {
2895
+ onClick: () => handlePackageSelect(pkg),
2896
+ style: {
2897
+ display: "flex",
2898
+ alignItems: "center",
2899
+ gap: 8,
2900
+ padding: "8px 12px",
2901
+ borderRadius: 6,
2902
+ border: `1px solid ${isSelected ? theme.colors.primary : theme.colors.border}`,
2903
+ backgroundColor: isSelected ? theme.colors.surface : "transparent",
2904
+ color: theme.colors.text,
2905
+ cursor: "pointer",
2906
+ transition: "all 0.15s ease"
2907
+ },
2908
+ children: [
2909
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: pkg }),
2910
+ /* @__PURE__ */ jsxs(
2911
+ "span",
2912
+ {
2913
+ style: {
2914
+ fontSize: 11,
2915
+ padding: "2px 6px",
2916
+ borderRadius: 4,
2917
+ backgroundColor: summary.totalErrors > 0 ? getSeverityBg("error") : summary.totalWarnings > 0 ? getSeverityBg("warning") : "rgba(34, 197, 94, 0.1)",
2918
+ color: summary.totalErrors > 0 ? getSeverityColor("error") : summary.totalWarnings > 0 ? getSeverityColor("warning") : "#22c55e"
2919
+ },
2920
+ children: [
2921
+ summary.passCount,
2922
+ "/",
2923
+ summary.lensCount,
2924
+ " pass"
2925
+ ]
2926
+ }
2927
+ )
2928
+ ]
2929
+ },
2930
+ pkg
2931
+ );
2932
+ })
2933
+ }
2934
+ ),
2935
+ packageNames.length === 1 && /* @__PURE__ */ jsxs(
2936
+ "div",
2937
+ {
2938
+ style: {
2939
+ display: "flex",
2940
+ alignItems: "center",
2941
+ gap: 12,
2942
+ padding: "8px 12px",
2943
+ backgroundColor: theme.colors.surface,
2944
+ borderRadius: 6,
2945
+ marginBottom: 8
2946
+ },
2947
+ children: [
2948
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: theme.colors.text }, children: packageNames[0] }),
2949
+ (() => {
2950
+ const summary = getPackageSummary(selectedResults);
2951
+ return /* @__PURE__ */ jsxs(
2952
+ "span",
2953
+ {
2954
+ style: {
2955
+ fontSize: 11,
2956
+ padding: "2px 6px",
2957
+ borderRadius: 4,
2958
+ backgroundColor: summary.totalErrors > 0 ? getSeverityBg("error") : summary.totalWarnings > 0 ? getSeverityBg("warning") : "rgba(34, 197, 94, 0.1)",
2959
+ color: summary.totalErrors > 0 ? getSeverityColor("error") : summary.totalWarnings > 0 ? getSeverityColor("warning") : "#22c55e"
2960
+ },
2961
+ children: [
2962
+ summary.passCount,
2963
+ "/",
2964
+ summary.lensCount,
2965
+ " pass"
2966
+ ]
2967
+ }
2968
+ );
2969
+ })()
2970
+ ]
2971
+ }
2972
+ ),
2973
+ !selectedPackage && packageNames.length > 1 && /* @__PURE__ */ jsx(
2974
+ "div",
2975
+ {
2976
+ style: {
2977
+ padding: 24,
2978
+ textAlign: "center",
2979
+ color: theme.colors.textMuted,
2980
+ backgroundColor: theme.colors.surface,
2981
+ borderRadius: 6
2982
+ },
2983
+ children: "Select a package above to view lens results"
2984
+ }
2985
+ ),
2517
2986
  selectedPackage && selectedResults.map((result, idx) => {
2518
2987
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
2519
2988
  const lensKey = `${((_a = result.lens) == null ? void 0 : _a.id) ?? "unknown"}-${idx}`;
@@ -2568,34 +3037,53 @@ function LensDataDebugPanel$1({
2568
3037
  ] })
2569
3038
  ] }),
2570
3039
  /* @__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" }),
3040
+ /* @__PURE__ */ jsx(
3041
+ "span",
3042
+ {
3043
+ style: {
3044
+ padding: "2px 6px",
3045
+ borderRadius: 4,
3046
+ fontSize: 11,
3047
+ backgroundColor: ((_e = result.execution) == null ? void 0 : _e.success) ? "rgba(34, 197, 94, 0.1)" : "rgba(239, 68, 68, 0.1)",
3048
+ color: ((_f = result.execution) == null ? void 0 : _f.success) ? "#22c55e" : "#ef4444"
3049
+ },
3050
+ children: ((_g = result.execution) == null ? void 0 : _g.success) ? "pass" : "fail"
3051
+ }
3052
+ ),
2578
3053
  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
- ] })
3054
+ (((_i = (_h = result.metrics) == null ? void 0 : _h.issuesBySeverity) == null ? void 0 : _i.error) ?? 0) > 0 && /* @__PURE__ */ jsxs(
3055
+ "span",
3056
+ {
3057
+ style: {
3058
+ padding: "2px 6px",
3059
+ borderRadius: 4,
3060
+ fontSize: 11,
3061
+ backgroundColor: getSeverityBg("error"),
3062
+ color: getSeverityColor("error")
3063
+ },
3064
+ children: [
3065
+ ((_k = (_j = result.metrics) == null ? void 0 : _j.issuesBySeverity) == null ? void 0 : _k.error) ?? 0,
3066
+ " errors"
3067
+ ]
3068
+ }
3069
+ ),
3070
+ (((_m = (_l = result.metrics) == null ? void 0 : _l.issuesBySeverity) == null ? void 0 : _m.warning) ?? 0) > 0 && /* @__PURE__ */ jsxs(
3071
+ "span",
3072
+ {
3073
+ style: {
3074
+ padding: "2px 6px",
3075
+ borderRadius: 4,
3076
+ fontSize: 11,
3077
+ backgroundColor: getSeverityBg("warning"),
3078
+ color: getSeverityColor("warning")
3079
+ },
3080
+ children: [
3081
+ ((_o = (_n = result.metrics) == null ? void 0 : _n.issuesBySeverity) == null ? void 0 : _o.warning) ?? 0,
3082
+ " ",
3083
+ "warnings"
3084
+ ]
3085
+ }
3086
+ )
2599
3087
  ] }),
2600
3088
  /* @__PURE__ */ jsxs("span", { style: { fontSize: 12, color: theme.colors.textMuted }, children: [
2601
3089
  ((_p = result.metrics) == null ? void 0 : _p.filesAnalyzed) ?? 0,
@@ -2605,235 +3093,412 @@ function LensDataDebugPanel$1({
2605
3093
  ]
2606
3094
  }
2607
3095
  ),
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(
3096
+ isExpanded && /* @__PURE__ */ jsxs(
3097
+ "div",
3098
+ {
3099
+ style: {
3100
+ padding: 12,
3101
+ backgroundColor: theme.colors.backgroundLight,
3102
+ borderTop: `1px solid ${theme.colors.border}`
3103
+ },
3104
+ children: [
3105
+ /* @__PURE__ */ jsxs(
2659
3106
  "div",
2660
3107
  {
2661
3108
  style: {
2662
- border: `1px solid ${theme.colors.border}`,
2663
- borderRadius: 4,
2664
- overflow: "hidden"
3109
+ display: "grid",
3110
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
3111
+ gap: 8,
3112
+ marginBottom: 16,
3113
+ padding: 12,
3114
+ backgroundColor: theme.colors.surface,
3115
+ borderRadius: 4
2665
3116
  },
2666
3117
  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: {
3118
+ /* @__PURE__ */ jsxs("div", { children: [
3119
+ /* @__PURE__ */ jsx(
3120
+ "div",
3121
+ {
3122
+ style: { fontSize: 11, color: theme.colors.textMuted },
3123
+ children: "Files Analyzed"
3124
+ }
3125
+ ),
3126
+ /* @__PURE__ */ jsx(
3127
+ "div",
3128
+ {
3129
+ style: {
3130
+ fontSize: 16,
3131
+ fontWeight: 600,
3132
+ color: theme.colors.text
3133
+ },
3134
+ children: ((_q = result.metrics) == null ? void 0 : _q.filesAnalyzed) ?? 0
3135
+ }
3136
+ )
3137
+ ] }),
3138
+ /* @__PURE__ */ jsxs("div", { children: [
3139
+ /* @__PURE__ */ jsx(
3140
+ "div",
3141
+ {
3142
+ style: { fontSize: 11, color: theme.colors.textMuted },
3143
+ children: "Total Issues"
3144
+ }
3145
+ ),
3146
+ /* @__PURE__ */ jsx(
3147
+ "div",
3148
+ {
3149
+ style: {
3150
+ fontSize: 16,
3151
+ fontWeight: 600,
3152
+ color: theme.colors.text
3153
+ },
3154
+ children: ((_r = result.metrics) == null ? void 0 : _r.totalIssues) ?? 0
3155
+ }
3156
+ )
3157
+ ] }),
3158
+ /* @__PURE__ */ jsxs("div", { children: [
3159
+ /* @__PURE__ */ jsx(
3160
+ "div",
3161
+ {
3162
+ style: { fontSize: 11, color: theme.colors.textMuted },
3163
+ children: "Duration"
3164
+ }
3165
+ ),
3166
+ /* @__PURE__ */ jsxs(
3167
+ "div",
3168
+ {
3169
+ style: {
3170
+ fontSize: 16,
3171
+ fontWeight: 600,
3172
+ color: theme.colors.text
3173
+ },
3174
+ children: [
3175
+ ((_s = result.execution) == null ? void 0 : _s.duration) ?? 0,
3176
+ "ms"
3177
+ ]
3178
+ }
3179
+ )
3180
+ ] }),
3181
+ result.coverage && /* @__PURE__ */ jsxs("div", { children: [
3182
+ /* @__PURE__ */ jsx(
3183
+ "div",
3184
+ {
3185
+ style: {
2715
3186
  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
- ]
3187
+ color: theme.colors.textMuted
3188
+ },
3189
+ children: "Coverage"
3190
+ }
3191
+ ),
3192
+ /* @__PURE__ */ jsxs(
3193
+ "div",
3194
+ {
3195
+ style: {
3196
+ fontSize: 16,
3197
+ fontWeight: 600,
3198
+ color: theme.colors.text
3199
+ },
3200
+ children: [
3201
+ result.coverage.line,
3202
+ "%"
3203
+ ]
3204
+ }
3205
+ )
3206
+ ] })
3207
+ ]
3208
+ }
3209
+ ),
3210
+ filesWithIssues.size > 0 ? /* @__PURE__ */ jsxs("div", { children: [
3211
+ /* @__PURE__ */ jsxs(
3212
+ "div",
3213
+ {
3214
+ style: {
3215
+ fontSize: 12,
3216
+ fontWeight: 600,
3217
+ color: theme.colors.textMuted,
3218
+ marginBottom: 8
3219
+ },
3220
+ children: [
3221
+ "Files with Issues (",
3222
+ filesWithIssues.size,
3223
+ ")"
3224
+ ]
3225
+ }
3226
+ ),
3227
+ /* @__PURE__ */ jsx(
3228
+ "div",
3229
+ {
3230
+ style: {
3231
+ display: "flex",
3232
+ flexDirection: "column",
3233
+ gap: 4
3234
+ },
3235
+ children: Array.from(filesWithIssues.entries()).map(
3236
+ ([file, issues]) => {
3237
+ const isFileExpanded = expandedFiles.has(file);
3238
+ return /* @__PURE__ */ jsxs(
3239
+ "div",
3240
+ {
3241
+ style: {
3242
+ border: `1px solid ${theme.colors.border}`,
3243
+ borderRadius: 4,
3244
+ overflow: "hidden"
3245
+ },
3246
+ children: [
3247
+ /* @__PURE__ */ jsxs(
3248
+ "div",
3249
+ {
3250
+ onClick: () => toggleFile(file),
3251
+ style: {
3252
+ display: "flex",
3253
+ alignItems: "center",
3254
+ justifyContent: "space-between",
3255
+ padding: "8px 10px",
3256
+ backgroundColor: theme.colors.surface,
3257
+ cursor: "pointer"
3258
+ },
3259
+ children: [
3260
+ /* @__PURE__ */ jsxs(
3261
+ "div",
3262
+ {
3263
+ style: {
3264
+ display: "flex",
3265
+ alignItems: "center",
3266
+ gap: 6
3267
+ },
3268
+ children: [
3269
+ /* @__PURE__ */ jsx(
3270
+ "svg",
3271
+ {
3272
+ width: "12",
3273
+ height: "12",
3274
+ viewBox: "0 0 24 24",
3275
+ fill: "none",
3276
+ stroke: theme.colors.textMuted,
3277
+ strokeWidth: "2",
3278
+ style: {
3279
+ transform: isFileExpanded ? "rotate(90deg)" : "rotate(0deg)",
3280
+ transition: "transform 0.15s ease"
3281
+ },
3282
+ children: /* @__PURE__ */ jsx("polyline", { points: "9,18 15,12 9,6" })
3283
+ }
3284
+ ),
3285
+ /* @__PURE__ */ jsx(
3286
+ "span",
3287
+ {
3288
+ style: {
3289
+ color: theme.colors.text,
3290
+ cursor: onFileClick ? "pointer" : "default"
3291
+ },
3292
+ onClick: (e) => {
3293
+ if (onFileClick) {
3294
+ e.stopPropagation();
3295
+ onFileClick(file);
3296
+ }
3297
+ },
3298
+ children: file
3299
+ }
3300
+ )
3301
+ ]
3302
+ }
3303
+ ),
3304
+ /* @__PURE__ */ jsxs(
3305
+ "span",
3306
+ {
3307
+ style: {
3308
+ fontSize: 11,
3309
+ padding: "2px 6px",
3310
+ borderRadius: 4,
3311
+ backgroundColor: getSeverityBg("error"),
3312
+ color: getSeverityColor("error")
3313
+ },
3314
+ children: [
3315
+ issues.length,
3316
+ " issues"
3317
+ ]
3318
+ }
3319
+ )
3320
+ ]
3321
+ }
3322
+ ),
3323
+ isFileExpanded && /* @__PURE__ */ jsx(
3324
+ "div",
3325
+ {
3326
+ style: {
3327
+ padding: 8,
3328
+ backgroundColor: theme.colors.background,
3329
+ borderTop: `1px solid ${theme.colors.border}`,
3330
+ maxHeight: 300,
3331
+ overflow: "auto"
3332
+ },
3333
+ children: issues.map((issue, issueIdx) => /* @__PURE__ */ jsxs(
3334
+ "div",
3335
+ {
3336
+ onClick: () => onFileClick == null ? void 0 : onFileClick(file, issue.line),
3337
+ style: {
3338
+ display: "flex",
3339
+ gap: 8,
3340
+ padding: "6px 8px",
3341
+ borderRadius: 4,
3342
+ cursor: onFileClick ? "pointer" : "default",
3343
+ transition: "background-color 0.1s ease"
3344
+ },
3345
+ onMouseEnter: (e) => {
3346
+ e.currentTarget.style.backgroundColor = theme.colors.surface;
3347
+ },
3348
+ onMouseLeave: (e) => {
3349
+ e.currentTarget.style.backgroundColor = "transparent";
3350
+ },
3351
+ children: [
3352
+ /* @__PURE__ */ jsxs(
3353
+ "span",
3354
+ {
3355
+ style: {
3356
+ fontSize: 11,
3357
+ color: theme.colors.textMuted,
3358
+ minWidth: 45
3359
+ },
3360
+ children: [
3361
+ "L",
3362
+ issue.line
3363
+ ]
3364
+ }
3365
+ ),
3366
+ /* @__PURE__ */ jsx(
3367
+ "span",
3368
+ {
3369
+ style: {
3370
+ fontSize: 10,
3371
+ padding: "1px 4px",
3372
+ borderRadius: 3,
3373
+ backgroundColor: getSeverityBg(
3374
+ issue.severity
3375
+ ),
3376
+ color: getSeverityColor(
3377
+ issue.severity
3378
+ ),
3379
+ textTransform: "uppercase"
3380
+ },
3381
+ children: issue.severity.charAt(0)
3382
+ }
3383
+ ),
3384
+ /* @__PURE__ */ jsx(
3385
+ "span",
3386
+ {
3387
+ style: {
3388
+ flex: 1,
3389
+ fontSize: 12,
3390
+ color: theme.colors.text
3391
+ },
3392
+ children: issue.message
3393
+ }
3394
+ ),
3395
+ issue.rule && /* @__PURE__ */ jsx(
3396
+ "span",
3397
+ {
3398
+ style: {
3399
+ fontSize: 10,
3400
+ color: theme.colors.textMuted,
3401
+ opacity: 0.7
3402
+ },
3403
+ children: issue.rule
3404
+ }
3405
+ )
3406
+ ]
3407
+ },
3408
+ issueIdx
3409
+ ))
3410
+ }
3411
+ )
3412
+ ]
3413
+ },
3414
+ file
3415
+ );
2725
3416
  }
2726
- ),
2727
- isFileExpanded && /* @__PURE__ */ jsx("div", { style: {
3417
+ )
3418
+ }
3419
+ )
3420
+ ] }) : /* @__PURE__ */ jsx(
3421
+ "div",
3422
+ {
3423
+ style: {
3424
+ padding: 16,
3425
+ textAlign: "center",
3426
+ color: theme.colors.textMuted,
3427
+ backgroundColor: theme.colors.surface,
3428
+ borderRadius: 4
3429
+ },
3430
+ children: "No issues found"
3431
+ }
3432
+ ),
3433
+ result.fileMetrics && result.fileMetrics.length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginTop: 16 }, children: [
3434
+ /* @__PURE__ */ jsxs(
3435
+ "div",
3436
+ {
3437
+ style: {
3438
+ fontSize: 12,
3439
+ fontWeight: 600,
3440
+ color: theme.colors.textMuted,
3441
+ marginBottom: 8
3442
+ },
3443
+ children: [
3444
+ "File Metrics (",
3445
+ result.fileMetrics.length,
3446
+ ")"
3447
+ ]
3448
+ }
3449
+ ),
3450
+ /* @__PURE__ */ jsx(
3451
+ "div",
3452
+ {
3453
+ style: {
3454
+ display: "flex",
3455
+ flexDirection: "column",
3456
+ gap: 2,
2728
3457
  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(
3458
+ backgroundColor: theme.colors.surface,
3459
+ borderRadius: 4
3460
+ },
3461
+ children: result.fileMetrics.map((fm, idx2) => /* @__PURE__ */ jsxs(
2734
3462
  "div",
2735
3463
  {
2736
- onClick: () => onFileClick == null ? void 0 : onFileClick(file, issue.line),
2737
3464
  style: {
2738
3465
  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";
3466
+ alignItems: "center",
3467
+ justifyContent: "space-between",
3468
+ padding: "4px 8px"
2750
3469
  },
2751
3470
  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 })
3471
+ /* @__PURE__ */ jsx(
3472
+ "span",
3473
+ {
3474
+ style: { color: theme.colors.text, fontSize: 12 },
3475
+ children: fm.file
3476
+ }
3477
+ ),
3478
+ /* @__PURE__ */ jsxs(
3479
+ "span",
3480
+ {
3481
+ style: {
3482
+ fontSize: 12,
3483
+ fontWeight: 500,
3484
+ color: fm.score >= 80 ? "#22c55e" : fm.score >= 60 ? "#f59e0b" : "#ef4444"
3485
+ },
3486
+ children: [
3487
+ fm.score,
3488
+ "%"
3489
+ ]
3490
+ }
3491
+ )
2778
3492
  ]
2779
3493
  },
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
- ] })
3494
+ idx2
3495
+ ))
3496
+ }
3497
+ )
3498
+ ] })
3499
+ ]
3500
+ }
3501
+ )
2837
3502
  ]
2838
3503
  },
2839
3504
  lensKey
@@ -2876,45 +3541,68 @@ const LensDataDebugPanelContent = ({
2876
3541
  flexDirection: "column"
2877
3542
  },
2878
3543
  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
- ] }),
3544
+ /* @__PURE__ */ jsxs(
3545
+ "div",
3546
+ {
3547
+ style: {
3548
+ display: "flex",
3549
+ alignItems: "center",
3550
+ justifyContent: "space-between",
3551
+ height: 40,
3552
+ flexShrink: 0,
3553
+ padding: "0 16px",
3554
+ borderBottom: `1px solid ${theme.colors.border}`,
3555
+ boxSizing: "border-box"
3556
+ },
3557
+ children: [
3558
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
3559
+ /* @__PURE__ */ jsx(Bug, { size: 18, color: theme.colors.primary }),
3560
+ /* @__PURE__ */ jsx(
3561
+ "h2",
3562
+ {
3563
+ style: {
3564
+ margin: 0,
3565
+ fontSize: 14,
3566
+ fontWeight: 600,
3567
+ color: theme.colors.text
3568
+ },
3569
+ children: "Lens Data Debug"
3570
+ }
3571
+ )
3572
+ ] }),
3573
+ (lensResultsSlice == null ? void 0 : lensResultsSlice.data) && /* @__PURE__ */ jsxs(
3574
+ "div",
3575
+ {
3576
+ style: {
3577
+ display: "flex",
3578
+ alignItems: "center",
3579
+ gap: 12,
3580
+ fontSize: 11,
3581
+ color: theme.colors.textMuted
3582
+ },
3583
+ children: [
3584
+ /* @__PURE__ */ jsxs("span", { children: [
3585
+ new Set(
3586
+ lensResultsSlice.data.results.map(
3587
+ (r2) => {
3588
+ var _a;
3589
+ return ((_a = r2.package) == null ? void 0 : _a.name) ?? "unknown";
3590
+ }
3591
+ )
3592
+ ).size,
3593
+ " ",
3594
+ "packages"
3595
+ ] }),
3596
+ /* @__PURE__ */ jsxs("span", { children: [
3597
+ lensResultsSlice.data.results.length,
3598
+ " results"
3599
+ ] })
3600
+ ]
3601
+ }
3602
+ )
3603
+ ]
3604
+ }
3605
+ ),
2918
3606
  /* @__PURE__ */ jsx(
2919
3607
  "div",
2920
3608
  {
@@ -2923,19 +3611,38 @@ const LensDataDebugPanelContent = ({
2923
3611
  minHeight: 0,
2924
3612
  overflow: "auto"
2925
3613
  },
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(
3614
+ children: isLoading ? /* @__PURE__ */ jsx(
3615
+ "div",
3616
+ {
3617
+ style: {
3618
+ padding: 40,
3619
+ textAlign: "center",
3620
+ color: theme.colors.textMuted
3621
+ },
3622
+ children: "Loading lens results..."
3623
+ }
3624
+ ) : !hasSlice || !(lensResultsSlice == null ? void 0 : lensResultsSlice.data) ? /* @__PURE__ */ jsxs(
3625
+ "div",
3626
+ {
3627
+ style: {
3628
+ padding: 40,
3629
+ textAlign: "center",
3630
+ color: theme.colors.textMuted
3631
+ },
3632
+ children: [
3633
+ /* @__PURE__ */ jsx(
3634
+ Bug,
3635
+ {
3636
+ size: 48,
3637
+ color: theme.colors.border,
3638
+ style: { marginBottom: 16 }
3639
+ }
3640
+ ),
3641
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 14, marginBottom: 8 }, children: "No lens data available" }),
3642
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 12 }, children: "Run quality-lens-cli or check that the lensResults slice is configured." })
3643
+ ]
3644
+ }
3645
+ ) : /* @__PURE__ */ jsx(
2939
3646
  LensDataDebugPanel$1,
2940
3647
  {
2941
3648
  data: lensResultsSlice.data,
@@ -3019,10 +3726,26 @@ function getMetricIcon(key) {
3019
3726
  }
3020
3727
  const METRIC_CONFIG = [
3021
3728
  { 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" },
3729
+ {
3730
+ key: "documentation",
3731
+ label: "Documentation",
3732
+ description: "Documentation coverage"
3733
+ },
3734
+ {
3735
+ key: "tests",
3736
+ label: "Tests",
3737
+ description: "Test coverage and passing rate"
3738
+ },
3739
+ {
3740
+ key: "deadCode",
3741
+ label: "Dead Code",
3742
+ description: "Unused code detected"
3743
+ },
3744
+ {
3745
+ key: "formatting",
3746
+ label: "Formatting",
3747
+ description: "Code formatting consistency"
3748
+ },
3026
3749
  { key: "linting", label: "Linting", description: "Linting compliance" }
3027
3750
  ];
3028
3751
  function QualityMetricsList({