executable-stories-react 0.5.0 → 0.7.0

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.
@@ -202,7 +202,7 @@ function DocTable({ entry }) {
202
202
  entry.label ? /* @__PURE__ */ jsx6("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
203
203
  /* @__PURE__ */ jsx6("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ jsxs3("table", { className: "w-full border-collapse text-sm", children: [
204
204
  /* @__PURE__ */ jsx6("thead", { children: /* @__PURE__ */ jsx6("tr", { className: "bg-muted/50", children: entry.columns.map((c) => /* @__PURE__ */ jsx6("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: c }, c)) }) }),
205
- /* @__PURE__ */ jsx6("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ jsx6("tr", { children: row.map((cell, j) => /* @__PURE__ */ jsx6("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell }, j)) }, i)) })
205
+ /* @__PURE__ */ jsx6("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ jsx6("tr", { children: row.map((cell2, j) => /* @__PURE__ */ jsx6("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell2 }, j)) }, i)) })
206
206
  ] }) })
207
207
  ] });
208
208
  }
@@ -225,7 +225,7 @@ function DocLink({ entry }) {
225
225
  // src/components/doc/DocSection.tsx
226
226
  import { marked } from "marked";
227
227
 
228
- // src/lib/url.ts
228
+ // ../executable-stories-core/dist/utils/url.js
229
229
  function safeUrl(value) {
230
230
  if (!value) return void 0;
231
231
  const trimmed = value.trim();
@@ -520,18 +520,101 @@ function ReportStepItem({ step }) {
520
520
  );
521
521
  }
522
522
 
523
+ // ../executable-stories-core/dist/storyboard.js
524
+ function findScreenshot(entries) {
525
+ for (const entry of entries) {
526
+ if (entry.kind === "screenshot") return entry;
527
+ if (entry.children) {
528
+ const nested = findScreenshot(entry.children);
529
+ if (nested) return nested;
530
+ }
531
+ }
532
+ return void 0;
533
+ }
534
+ function extractStoryboardFrames(scenario) {
535
+ const frames = [];
536
+ for (const step of scenario.steps) {
537
+ const shot = findScreenshot(step.docEntries);
538
+ if (!shot) continue;
539
+ frames.push({
540
+ stepId: step.id,
541
+ stepIndex: step.index,
542
+ keyword: step.keyword,
543
+ text: step.text,
544
+ status: step.status,
545
+ path: shot.path,
546
+ ...shot.alt !== void 0 && { alt: shot.alt }
547
+ });
548
+ }
549
+ return frames;
550
+ }
551
+
552
+ // src/components/ReportStoryboard.tsx
553
+ import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
554
+ var FRAME_GLYPH = {
555
+ passed: "\u2713",
556
+ failed: "\u2717",
557
+ skipped: "\u25CB",
558
+ pending: "\u25CB"
559
+ };
560
+ var FRAME_GLYPH_COLOR = {
561
+ passed: "text-pass",
562
+ failed: "text-fail",
563
+ skipped: "text-skip",
564
+ pending: "text-pend"
565
+ };
566
+ function ReportStoryboard({ scenario }) {
567
+ const frames = extractStoryboardFrames(scenario);
568
+ if (frames.length < 2) return null;
569
+ return /* @__PURE__ */ jsxs11("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
570
+ /* @__PURE__ */ jsx18("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
571
+ /* @__PURE__ */ jsx18("ol", { className: "flex gap-3 overflow-x-auto pb-2", children: frames.map((frame) => /* @__PURE__ */ jsx18(StoryboardFrameItem, { frame }, frame.stepId)) })
572
+ ] });
573
+ }
574
+ function StoryboardFrameItem({ frame }) {
575
+ const src = isLocalFsPath(frame.path) ? void 0 : safeImageUrl(frame.path);
576
+ const label = `${frame.keyword} ${frame.text}`;
577
+ return /* @__PURE__ */ jsxs11("li", { className: "w-40 shrink-0", children: [
578
+ /* @__PURE__ */ jsx18(
579
+ "a",
580
+ {
581
+ href: `#${frame.stepId}`,
582
+ "aria-label": `Jump to step: ${label}`,
583
+ className: "block overflow-hidden rounded-md border border-border transition-colors hover:border-ring",
584
+ children: src ? /* @__PURE__ */ jsx18(
585
+ "img",
586
+ {
587
+ src,
588
+ alt: frame.alt ?? label,
589
+ loading: "lazy",
590
+ className: "h-24 w-full bg-muted object-cover object-top"
591
+ }
592
+ ) : /* @__PURE__ */ jsx18("span", { className: "flex h-24 w-full items-center justify-center border-b border-dashed border-border bg-muted px-2 text-center text-[0.6875rem] text-muted-foreground", children: "Screenshot unavailable" })
593
+ }
594
+ ),
595
+ /* @__PURE__ */ jsxs11("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
596
+ /* @__PURE__ */ jsx18("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
597
+ /* @__PURE__ */ jsxs11("span", { className: "min-w-0", children: [
598
+ /* @__PURE__ */ jsx18("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
599
+ " ",
600
+ /* @__PURE__ */ jsx18("span", { className: "text-muted-foreground", children: frame.alt ?? frame.text })
601
+ ] })
602
+ ] })
603
+ ] });
604
+ }
605
+
523
606
  // src/components/ReportAttachments.tsx
524
- import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
607
+ import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
525
608
  function ReportAttachments({ attachments }) {
526
609
  if (attachments.length === 0) return null;
527
610
  return (
528
611
  // role="group" (not a labelled <section>) so multiple scenarios' attachment
529
612
  // blocks don't create duplicate "Attachments" region landmarks.
530
- /* @__PURE__ */ jsx18("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
613
+ /* @__PURE__ */ jsx19("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
531
614
  const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
532
615
  const isImage = att.mediaType.startsWith("image/");
533
- return /* @__PURE__ */ jsx18("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs11(Fragment6, { children: [
534
- /* @__PURE__ */ jsx18(
616
+ return /* @__PURE__ */ jsx19("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs12(Fragment6, { children: [
617
+ /* @__PURE__ */ jsx19(
535
618
  "img",
536
619
  {
537
620
  src: dataUri,
@@ -540,8 +623,8 @@ function ReportAttachments({ attachments }) {
540
623
  className: "max-w-full rounded-md border border-border"
541
624
  }
542
625
  ),
543
- /* @__PURE__ */ jsx18("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
544
- ] }) : /* @__PURE__ */ jsxs11(
626
+ /* @__PURE__ */ jsx19("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
627
+ ] }) : /* @__PURE__ */ jsxs12(
545
628
  "a",
546
629
  {
547
630
  href: dataUri,
@@ -550,7 +633,7 @@ function ReportAttachments({ attachments }) {
550
633
  children: [
551
634
  att.name,
552
635
  " ",
553
- /* @__PURE__ */ jsxs11("span", { className: "text-muted-foreground", children: [
636
+ /* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
554
637
  "(",
555
638
  att.mediaType,
556
639
  ")"
@@ -638,7 +721,7 @@ function traceWindow(rows) {
638
721
  }
639
722
 
640
723
  // src/components/ReportTrace.tsx
641
- import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
724
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
642
725
  var BAR_COLOR = {
643
726
  ok: "bg-pass",
644
727
  error: "bg-fail",
@@ -649,8 +732,8 @@ function ReportTrace({ spans }) {
649
732
  const rows = toTraceRows(spans);
650
733
  if (rows.length === 0) return null;
651
734
  const { minStartMs, totalMs } = traceWindow(rows);
652
- return /* @__PURE__ */ jsxs12("details", { className: "mt-3 rounded-md border border-border bg-muted/30", children: [
653
- /* @__PURE__ */ jsxs12("summary", { className: "cursor-pointer px-3 py-2 text-xs font-medium text-muted-foreground", children: [
735
+ return /* @__PURE__ */ jsxs13("details", { className: "mt-3 rounded-md border border-border bg-muted/30", children: [
736
+ /* @__PURE__ */ jsxs13("summary", { className: "cursor-pointer px-3 py-2 text-xs font-medium text-muted-foreground", children: [
654
737
  "Trace (",
655
738
  rows.length,
656
739
  " span",
@@ -659,11 +742,11 @@ function ReportTrace({ spans }) {
659
742
  formatDuration(totalMs),
660
743
  ")"
661
744
  ] }),
662
- /* @__PURE__ */ jsx19("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
745
+ /* @__PURE__ */ jsx20("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
663
746
  const leftPct = (row.startTimeMs - minStartMs) / totalMs * 100;
664
747
  const widthPct = Math.max(row.durationMs / totalMs * 100, 0.5);
665
- return /* @__PURE__ */ jsxs12("li", { className: "flex items-center gap-2", children: [
666
- /* @__PURE__ */ jsx19(
748
+ return /* @__PURE__ */ jsxs13("li", { className: "flex items-center gap-2", children: [
749
+ /* @__PURE__ */ jsx20(
667
750
  "span",
668
751
  {
669
752
  className: "min-w-0 flex-1 truncate text-foreground",
@@ -672,14 +755,14 @@ function ReportTrace({ spans }) {
672
755
  children: row.name
673
756
  }
674
757
  ),
675
- /* @__PURE__ */ jsx19("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ jsx19(
758
+ /* @__PURE__ */ jsx20("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ jsx20(
676
759
  "span",
677
760
  {
678
761
  className: cn("absolute top-0 h-full rounded-sm", BAR_COLOR[row.status]),
679
762
  style: { left: `${leftPct}%`, width: `${widthPct}%` }
680
763
  }
681
764
  ) }),
682
- /* @__PURE__ */ jsx19("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
765
+ /* @__PURE__ */ jsx20("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
683
766
  ] }, `${row.spanId}-${i}`);
684
767
  }) })
685
768
  ] });
@@ -748,7 +831,7 @@ function diffSinceLastRun(history2, scenarios) {
748
831
  }
749
832
 
750
833
  // src/components/ScenarioRunHistory.tsx
751
- import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
834
+ import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
752
835
  var MAX_DOTS = 10;
753
836
  var DOT_COLOR = {
754
837
  passed: "bg-pass",
@@ -768,16 +851,16 @@ function ScenarioRunHistory({ scenarioId }) {
768
851
  const recent = entries.slice(-MAX_DOTS);
769
852
  const flaky = flakinessOf(recent) === "flaky";
770
853
  const summary = flaky ? `${describeRunHistory(recent)} \xB7 Flaky` : describeRunHistory(recent);
771
- return /* @__PURE__ */ jsxs13(Fragment7, { children: [
772
- flaky ? /* @__PURE__ */ jsx20(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
773
- /* @__PURE__ */ jsx20(
854
+ return /* @__PURE__ */ jsxs14(Fragment7, { children: [
855
+ flaky ? /* @__PURE__ */ jsx21(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
856
+ /* @__PURE__ */ jsx21(
774
857
  "span",
775
858
  {
776
859
  role: "img",
777
860
  "aria-label": `Run history: ${summary}`,
778
861
  title: summary,
779
862
  className: "flex shrink-0 items-center gap-[3px]",
780
- children: recent.map((e, i) => /* @__PURE__ */ jsx20(
863
+ children: recent.map((e, i) => /* @__PURE__ */ jsx21(
781
864
  "span",
782
865
  {
783
866
  "aria-hidden": true,
@@ -855,20 +938,118 @@ function useCollapseState(computeDefault) {
855
938
 
856
939
  // src/interactive/scenario-actions.tsx
857
940
  import { createContext as createContext4, useContext as useContext5 } from "react";
941
+
942
+ // ../executable-stories-core/dist/utils/scenario-markdown.js
943
+ function cell(value) {
944
+ return value.replaceAll("|", "\\|").replaceAll("\n", " ");
945
+ }
946
+ function stringify(value) {
947
+ if (typeof value === "string") return value;
948
+ try {
949
+ return JSON.stringify(value, null, 2) ?? String(value);
950
+ } catch {
951
+ return String(value);
952
+ }
953
+ }
954
+ function docEntryToMarkdown(entry) {
955
+ const lines = [];
956
+ switch (entry.kind) {
957
+ case "note":
958
+ lines.push(entry.text);
959
+ break;
960
+ case "tag":
961
+ lines.push(entry.names.map((n) => `\`@${n}\``).join(" "));
962
+ break;
963
+ case "kv":
964
+ lines.push(`**${entry.label}:** ${stringify(entry.value)}`);
965
+ break;
966
+ case "code":
967
+ lines.push(`**${entry.label}**`, "", "```" + (entry.lang ?? ""), entry.content, "```");
968
+ break;
969
+ case "table": {
970
+ lines.push(`**${entry.label}**`, "");
971
+ lines.push(`| ${entry.columns.map(cell).join(" | ")} |`);
972
+ lines.push(`| ${entry.columns.map(() => "---").join(" | ")} |`);
973
+ for (const row of entry.rows) lines.push(`| ${row.map(cell).join(" | ")} |`);
974
+ break;
975
+ }
976
+ case "link":
977
+ lines.push(`[${entry.label}](${entry.url})`);
978
+ break;
979
+ case "section":
980
+ lines.push(`### ${entry.title}`, "", entry.markdown);
981
+ break;
982
+ case "mermaid":
983
+ if (entry.title) lines.push(`**${entry.title}**`, "");
984
+ lines.push("```mermaid", entry.code, "```");
985
+ break;
986
+ case "screenshot":
987
+ lines.push(`![${entry.alt ?? "screenshot"}](${entry.path})`);
988
+ break;
989
+ case "video":
990
+ lines.push(`Video: ${entry.path}${entry.caption ? ` \u2014 ${entry.caption}` : ""}`);
991
+ break;
992
+ case "html": {
993
+ const htmlTitle = entry.title ?? "Embedded HTML";
994
+ if (entry.content) {
995
+ lines.push(`**${htmlTitle}**`, "", "```html", entry.content, "```");
996
+ } else if (entry.url) {
997
+ lines.push(`[${htmlTitle}](${entry.url})`);
998
+ } else {
999
+ lines.push(`Embedded HTML: ${entry.path ?? "(inline)"}`);
1000
+ }
1001
+ break;
1002
+ }
1003
+ case "custom":
1004
+ lines.push(`**${entry.type}**`, "", "```json", stringify(entry.data), "```");
1005
+ break;
1006
+ }
1007
+ for (const child of entry.children ?? []) {
1008
+ lines.push("", ...docEntryToMarkdown(child));
1009
+ }
1010
+ return lines;
1011
+ }
1012
+ function stepLines(step, ordinal, full) {
1013
+ const status = step.status === "passed" ? "" : ` \u2014 **${step.status}**`;
1014
+ const lines = [`${ordinal}. **${step.keyword}** ${step.text}${status}`];
1015
+ if (!full) return lines;
1016
+ if (step.errorMessage) {
1017
+ lines.push(...step.errorMessage.split("\n").map((l) => ` > ${l}`));
1018
+ }
1019
+ for (const entry of step.docEntries) {
1020
+ lines.push("", ...docEntryToMarkdown(entry).map((l) => l === "" ? l : ` ${l}`));
1021
+ }
1022
+ return lines;
1023
+ }
1024
+ function scenarioToMarkdown(scenario, options = {}) {
1025
+ const { variant = "full", meta = [] } = options;
1026
+ const full = variant === "full";
1027
+ const lines = full ? [`# ${scenario.title}`, ""] : [`## ${scenario.title} _(${scenario.status})_`, ""];
1028
+ if (full && meta.length > 0) lines.push(...meta);
1029
+ if (scenario.steps.length > 0) {
1030
+ if (full) lines.push("", "## Steps", "");
1031
+ scenario.steps.forEach((step, i) => lines.push(...stepLines(step, i + 1, full)));
1032
+ }
1033
+ if (scenario.errorMessage) {
1034
+ if (full) lines.push("", "## Failure", "");
1035
+ else lines.push("");
1036
+ lines.push("```", scenario.errorMessage.trim(), "```");
1037
+ }
1038
+ if (full && scenario.docEntries.length > 0) {
1039
+ lines.push("", "## Docs", "");
1040
+ for (const entry of scenario.docEntries) lines.push(...docEntryToMarkdown(entry), "");
1041
+ }
1042
+ return lines.join("\n").replaceAll(/\n{3,}/g, "\n\n").trimEnd() + (full ? "\n" : "");
1043
+ }
1044
+
1045
+ // src/interactive/scenario-actions.tsx
858
1046
  var ScenarioActionsContext = createContext4(null);
859
1047
  var ScenarioActionsProvider = ScenarioActionsContext.Provider;
860
1048
  function useScenarioActions() {
861
1049
  return useContext5(ScenarioActionsContext);
862
1050
  }
863
- function scenarioToMarkdown(scenario) {
864
- const lines = [`## ${scenario.title} _(${scenario.status})_`, ""];
865
- for (const step of scenario.steps) {
866
- lines.push(`- **${step.keyword}** ${step.text}`);
867
- }
868
- if (scenario.errorMessage) {
869
- lines.push("", "```", scenario.errorMessage.trim(), "```");
870
- }
871
- return lines.join("\n");
1051
+ function scenarioToMarkdown2(scenario) {
1052
+ return scenarioToMarkdown(scenario, { variant: "compact" });
872
1053
  }
873
1054
  function scenarioToPrompt(scenario) {
874
1055
  const lines = [
@@ -896,9 +1077,9 @@ function scenarioPermalink(scenario) {
896
1077
 
897
1078
  // src/components/ui/card.tsx
898
1079
  import "react";
899
- import { jsx as jsx21 } from "react/jsx-runtime";
1080
+ import { jsx as jsx22 } from "react/jsx-runtime";
900
1081
  function Card({ className, ...props }) {
901
- return /* @__PURE__ */ jsx21(
1082
+ return /* @__PURE__ */ jsx22(
902
1083
  "div",
903
1084
  {
904
1085
  "data-slot": "card",
@@ -911,7 +1092,7 @@ function Card({ className, ...props }) {
911
1092
  );
912
1093
  }
913
1094
  function CardHeader({ className, ...props }) {
914
- return /* @__PURE__ */ jsx21(
1095
+ return /* @__PURE__ */ jsx22(
915
1096
  "div",
916
1097
  {
917
1098
  "data-slot": "card-header",
@@ -924,7 +1105,7 @@ function CardHeader({ className, ...props }) {
924
1105
  );
925
1106
  }
926
1107
  function CardContent({ className, ...props }) {
927
- return /* @__PURE__ */ jsx21(
1108
+ return /* @__PURE__ */ jsx22(
928
1109
  "div",
929
1110
  {
930
1111
  "data-slot": "card-content",
@@ -938,13 +1119,13 @@ function CardContent({ className, ...props }) {
938
1119
  import "react";
939
1120
  import { Menu as MenuPrimitive } from "@base-ui/react/menu";
940
1121
  import { CheckIcon } from "lucide-react";
941
- import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
1122
+ import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
942
1123
  var itemClasses = "relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg:not([class*='text-'])]:text-muted-foreground";
943
1124
  function DropdownMenu(props) {
944
- return /* @__PURE__ */ jsx22(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
1125
+ return /* @__PURE__ */ jsx23(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
945
1126
  }
946
1127
  function DropdownMenuTrigger(props) {
947
- return /* @__PURE__ */ jsx22(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
1128
+ return /* @__PURE__ */ jsx23(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
948
1129
  }
949
1130
  function DropdownMenuContent({
950
1131
  className,
@@ -952,14 +1133,14 @@ function DropdownMenuContent({
952
1133
  sideOffset = 4,
953
1134
  ...props
954
1135
  }) {
955
- return /* @__PURE__ */ jsx22(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx22(
1136
+ return /* @__PURE__ */ jsx23(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx23(
956
1137
  MenuPrimitive.Positioner,
957
1138
  {
958
1139
  "data-slot": "dropdown-menu-positioner",
959
1140
  className: "z-50",
960
1141
  align,
961
1142
  sideOffset,
962
- children: /* @__PURE__ */ jsx22(
1143
+ children: /* @__PURE__ */ jsx23(
963
1144
  MenuPrimitive.Popup,
964
1145
  {
965
1146
  "data-slot": "dropdown-menu-content",
@@ -977,7 +1158,7 @@ function DropdownMenuItem({
977
1158
  className,
978
1159
  ...props
979
1160
  }) {
980
- return /* @__PURE__ */ jsx22(
1161
+ return /* @__PURE__ */ jsx23(
981
1162
  MenuPrimitive.Item,
982
1163
  {
983
1164
  "data-slot": "dropdown-menu-item",
@@ -989,7 +1170,7 @@ function DropdownMenuItem({
989
1170
 
990
1171
  // src/components/ReportScenario.tsx
991
1172
  import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
992
- import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
1173
+ import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
993
1174
  var STATUS_META = {
994
1175
  passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
995
1176
  failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
@@ -1005,7 +1186,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
1005
1186
  const collapsible = collapse !== null && !hideTitle;
1006
1187
  const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
1007
1188
  const actions = useScenarioActions();
1008
- return /* @__PURE__ */ jsxs15(
1189
+ return /* @__PURE__ */ jsxs16(
1009
1190
  Card,
1010
1191
  {
1011
1192
  id: scenario.id,
@@ -1013,10 +1194,10 @@ function ReportScenario({ scenario, hideTitle = false }) {
1013
1194
  ...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
1014
1195
  className: "gap-0 py-0",
1015
1196
  children: [
1016
- /* @__PURE__ */ jsxs15(CardHeader, { className: "px-4 py-3", children: [
1017
- /* @__PURE__ */ jsxs15("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
1018
- hideTitle ? null : /* @__PURE__ */ jsxs15("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
1019
- collapsible ? /* @__PURE__ */ jsx23(
1197
+ /* @__PURE__ */ jsxs16(CardHeader, { className: "px-4 py-3", children: [
1198
+ /* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
1199
+ hideTitle ? null : /* @__PURE__ */ jsxs16("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
1200
+ collapsible ? /* @__PURE__ */ jsx24(
1020
1201
  "button",
1021
1202
  {
1022
1203
  type: "button",
@@ -1025,49 +1206,49 @@ function ReportScenario({ scenario, hideTitle = false }) {
1025
1206
  "aria-controls": bodyId,
1026
1207
  "aria-label": `Toggle ${scenario.title}`,
1027
1208
  className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
1028
- children: /* @__PURE__ */ jsx23("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
1209
+ children: /* @__PURE__ */ jsx24("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
1029
1210
  }
1030
1211
  ) : null,
1031
- /* @__PURE__ */ jsx23("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
1032
- /* @__PURE__ */ jsx23("span", { children: scenario.title })
1212
+ /* @__PURE__ */ jsx24("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
1213
+ /* @__PURE__ */ jsx24("span", { children: scenario.title })
1033
1214
  ] }),
1034
- /* @__PURE__ */ jsxs15("div", { className: "flex shrink-0 items-center gap-2", children: [
1035
- /* @__PURE__ */ jsx23(ScenarioRunHistory, { scenarioId: scenario.id }),
1036
- scenario.durationMs > 0 ? /* @__PURE__ */ jsx23("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
1037
- meta.showPill ? /* @__PURE__ */ jsx23(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx23("span", { className: "sr-only", children: `Status: ${label}` }),
1038
- actions ? /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
1039
- /* @__PURE__ */ jsx23(
1215
+ /* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
1216
+ /* @__PURE__ */ jsx24(ScenarioRunHistory, { scenarioId: scenario.id }),
1217
+ scenario.durationMs > 0 ? /* @__PURE__ */ jsx24("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
1218
+ meta.showPill ? /* @__PURE__ */ jsx24(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx24("span", { className: "sr-only", children: `Status: ${label}` }),
1219
+ actions ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
1220
+ /* @__PURE__ */ jsx24(
1040
1221
  DropdownMenuTrigger,
1041
1222
  {
1042
1223
  "aria-label": `Actions for ${scenario.title}`,
1043
1224
  className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
1044
- children: /* @__PURE__ */ jsx23(MoreHorizontalIcon, { "aria-hidden": true })
1225
+ children: /* @__PURE__ */ jsx24(MoreHorizontalIcon, { "aria-hidden": true })
1045
1226
  }
1046
1227
  ),
1047
- /* @__PURE__ */ jsxs15(DropdownMenuContent, { align: "end", children: [
1048
- /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
1049
- /* @__PURE__ */ jsx23(LinkIcon, {}),
1228
+ /* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", children: [
1229
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
1230
+ /* @__PURE__ */ jsx24(LinkIcon, {}),
1050
1231
  " Copy link"
1051
1232
  ] }),
1052
- /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
1053
- /* @__PURE__ */ jsx23(FileTextIcon, {}),
1233
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
1234
+ /* @__PURE__ */ jsx24(FileTextIcon, {}),
1054
1235
  " Copy as Markdown"
1055
1236
  ] }),
1056
- /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
1057
- /* @__PURE__ */ jsx23(SparklesIcon, {}),
1237
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
1238
+ /* @__PURE__ */ jsx24(SparklesIcon, {}),
1058
1239
  " Explain with AI"
1059
1240
  ] })
1060
1241
  ] })
1061
1242
  ] }) : null
1062
1243
  ] })
1063
1244
  ] }),
1064
- scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs15("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
1065
- scenario.tags.map((t) => /* @__PURE__ */ jsx23("li", { children: /* @__PURE__ */ jsx23(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
1066
- (scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ jsx23("li", { children: ticket.url ? /* @__PURE__ */ jsx23("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ jsx23(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ jsx23(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
1245
+ scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs16("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
1246
+ scenario.tags.map((t) => /* @__PURE__ */ jsx24("li", { children: /* @__PURE__ */ jsx24(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
1247
+ (scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ jsx24("li", { children: ticket.url ? /* @__PURE__ */ jsx24("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ jsx24(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ jsx24(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
1067
1248
  ] }) : null
1068
1249
  ] }),
1069
- /* @__PURE__ */ jsxs15(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
1070
- scenario.errorMessage ? /* @__PURE__ */ jsx23(
1250
+ /* @__PURE__ */ jsxs16(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
1251
+ scenario.errorMessage ? /* @__PURE__ */ jsx24(
1071
1252
  "pre",
1072
1253
  {
1073
1254
  role: "alert",
@@ -1075,10 +1256,11 @@ function ReportScenario({ scenario, hideTitle = false }) {
1075
1256
  children: scenario.errorMessage
1076
1257
  }
1077
1258
  ) : null,
1078
- /* @__PURE__ */ jsx23(ReportSteps, { scenario }),
1079
- scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx23("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx23(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
1080
- /* @__PURE__ */ jsx23(ReportAttachments, { attachments: scenario.attachments }),
1081
- /* @__PURE__ */ jsx23(ReportTrace, { spans: scenario.otelSpans })
1259
+ /* @__PURE__ */ jsx24(ReportStoryboard, { scenario }),
1260
+ /* @__PURE__ */ jsx24(ReportSteps, { scenario }),
1261
+ scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx24("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx24(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
1262
+ /* @__PURE__ */ jsx24(ReportAttachments, { attachments: scenario.attachments }),
1263
+ /* @__PURE__ */ jsx24(ReportTrace, { spans: scenario.otelSpans })
1082
1264
  ] })
1083
1265
  ]
1084
1266
  }
@@ -1086,13 +1268,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
1086
1268
  }
1087
1269
 
1088
1270
  // src/components/ReportScenarioList.tsx
1089
- import { Fragment as Fragment8, jsx as jsx24 } from "react/jsx-runtime";
1271
+ import { Fragment as Fragment8, jsx as jsx25 } from "react/jsx-runtime";
1090
1272
  function ReportScenarioList({ feature }) {
1091
- return /* @__PURE__ */ jsx24(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx24(ReportScenario, { scenario }, scenario.id)) });
1273
+ return /* @__PURE__ */ jsx25(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx25(ReportScenario, { scenario }, scenario.id)) });
1092
1274
  }
1093
1275
 
1094
1276
  // src/components/ReportFeature.tsx
1095
- import { Fragment as Fragment9, jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
1277
+ import { Fragment as Fragment9, jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
1096
1278
  function ReportFeature({ feature }) {
1097
1279
  const titleId = `${feature.id}-title`;
1098
1280
  const bodyId = `${feature.id}-body`;
@@ -1103,7 +1285,7 @@ function ReportFeature({ feature }) {
1103
1285
  return (
1104
1286
  // Suite = a section heading + a divider, NOT another bordered card. Drops a
1105
1287
  // layer of nesting so the scenario cards below read as the primary unit.
1106
- /* @__PURE__ */ jsxs16(
1288
+ /* @__PURE__ */ jsxs17(
1107
1289
  "section",
1108
1290
  {
1109
1291
  id: feature.id,
@@ -1111,9 +1293,9 @@ function ReportFeature({ feature }) {
1111
1293
  "aria-labelledby": titleId,
1112
1294
  className: "flex flex-col gap-3",
1113
1295
  children: [
1114
- /* @__PURE__ */ jsxs16("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
1115
- /* @__PURE__ */ jsxs16("div", { className: "min-w-0", children: [
1116
- /* @__PURE__ */ jsx25("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs16(
1296
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
1297
+ /* @__PURE__ */ jsxs17("div", { className: "min-w-0", children: [
1298
+ /* @__PURE__ */ jsx26("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs17(
1117
1299
  "button",
1118
1300
  {
1119
1301
  type: "button",
@@ -1122,31 +1304,31 @@ function ReportFeature({ feature }) {
1122
1304
  "aria-controls": bodyId,
1123
1305
  className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
1124
1306
  children: [
1125
- /* @__PURE__ */ jsx25("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
1126
- /* @__PURE__ */ jsx25("span", { className: "truncate", children: feature.title })
1307
+ /* @__PURE__ */ jsx26("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
1308
+ /* @__PURE__ */ jsx26("span", { className: "truncate", children: feature.title })
1127
1309
  ]
1128
1310
  }
1129
1311
  ) : feature.title }),
1130
- /* @__PURE__ */ jsx25("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
1312
+ /* @__PURE__ */ jsx26("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
1131
1313
  ] }),
1132
- /* @__PURE__ */ jsxs16(
1314
+ /* @__PURE__ */ jsxs17(
1133
1315
  "p",
1134
1316
  {
1135
1317
  className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
1136
1318
  "aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
1137
1319
  children: [
1138
- /* @__PURE__ */ jsxs16("span", { children: [
1320
+ /* @__PURE__ */ jsxs17("span", { children: [
1139
1321
  s.passed,
1140
1322
  " passed"
1141
1323
  ] }),
1142
- /* @__PURE__ */ jsx25("span", { "aria-hidden": true, children: "\xB7" }),
1143
- /* @__PURE__ */ jsxs16("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
1324
+ /* @__PURE__ */ jsx26("span", { "aria-hidden": true, children: "\xB7" }),
1325
+ /* @__PURE__ */ jsxs17("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
1144
1326
  s.failed,
1145
1327
  " failed"
1146
1328
  ] }),
1147
- skipped > 0 ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
1148
- /* @__PURE__ */ jsx25("span", { "aria-hidden": true, children: "\xB7" }),
1149
- /* @__PURE__ */ jsxs16("span", { children: [
1329
+ skipped > 0 ? /* @__PURE__ */ jsxs17(Fragment9, { children: [
1330
+ /* @__PURE__ */ jsx26("span", { "aria-hidden": true, children: "\xB7" }),
1331
+ /* @__PURE__ */ jsxs17("span", { children: [
1150
1332
  skipped,
1151
1333
  " skipped"
1152
1334
  ] })
@@ -1155,7 +1337,7 @@ function ReportFeature({ feature }) {
1155
1337
  }
1156
1338
  )
1157
1339
  ] }),
1158
- /* @__PURE__ */ jsx25("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx25(ReportScenarioList, { feature }) })
1340
+ /* @__PURE__ */ jsx26("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx26(ReportScenarioList, { feature }) })
1159
1341
  ]
1160
1342
  }
1161
1343
  )
@@ -1163,17 +1345,17 @@ function ReportFeature({ feature }) {
1163
1345
  }
1164
1346
 
1165
1347
  // src/components/ReportFeatureList.tsx
1166
- import { jsx as jsx26 } from "react/jsx-runtime";
1348
+ import { jsx as jsx27 } from "react/jsx-runtime";
1167
1349
  function ReportFeatureList() {
1168
1350
  const report = useReport();
1169
- return /* @__PURE__ */ jsx26("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx26(ReportFeature, { feature }, feature.id)) });
1351
+ return /* @__PURE__ */ jsx27("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx27(ReportFeature, { feature }, feature.id)) });
1170
1352
  }
1171
1353
 
1172
1354
  // src/components/ui/empty.tsx
1173
1355
  import { cva as cva2 } from "class-variance-authority";
1174
- import { jsx as jsx27 } from "react/jsx-runtime";
1356
+ import { jsx as jsx28 } from "react/jsx-runtime";
1175
1357
  function Empty({ className, ...props }) {
1176
- return /* @__PURE__ */ jsx27(
1358
+ return /* @__PURE__ */ jsx28(
1177
1359
  "div",
1178
1360
  {
1179
1361
  "data-slot": "empty",
@@ -1186,7 +1368,7 @@ function Empty({ className, ...props }) {
1186
1368
  );
1187
1369
  }
1188
1370
  function EmptyHeader({ className, ...props }) {
1189
- return /* @__PURE__ */ jsx27(
1371
+ return /* @__PURE__ */ jsx28(
1190
1372
  "div",
1191
1373
  {
1192
1374
  "data-slot": "empty-header",
@@ -1213,7 +1395,7 @@ var emptyMediaVariants = cva2(
1213
1395
  }
1214
1396
  );
1215
1397
  function EmptyTitle({ className, ...props }) {
1216
- return /* @__PURE__ */ jsx27(
1398
+ return /* @__PURE__ */ jsx28(
1217
1399
  "div",
1218
1400
  {
1219
1401
  "data-slot": "empty-title",
@@ -1224,16 +1406,16 @@ function EmptyTitle({ className, ...props }) {
1224
1406
  }
1225
1407
 
1226
1408
  // src/components/ReportEmpty.tsx
1227
- import { jsx as jsx28 } from "react/jsx-runtime";
1409
+ import { jsx as jsx29 } from "react/jsx-runtime";
1228
1410
  function ReportEmpty({ message }) {
1229
- return /* @__PURE__ */ jsx28(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx28(EmptyHeader, { children: /* @__PURE__ */ jsx28(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
1411
+ return /* @__PURE__ */ jsx29(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx29(EmptyHeader, { children: /* @__PURE__ */ jsx29(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
1230
1412
  }
1231
1413
 
1232
1414
  // src/components/ReportSummary.tsx
1233
- import { jsx as jsx29, jsxs as jsxs17 } from "react/jsx-runtime";
1415
+ import { jsx as jsx30, jsxs as jsxs18 } from "react/jsx-runtime";
1234
1416
  function ReportSummary({ className }) {
1235
1417
  const report = useReport();
1236
- return /* @__PURE__ */ jsx29(
1418
+ return /* @__PURE__ */ jsx30(
1237
1419
  ReportSummaryView,
1238
1420
  {
1239
1421
  summary: report.summary,
@@ -1259,7 +1441,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
1259
1441
  if (summary.pending > 0) {
1260
1442
  cards.push({ status: "pending", label: "Pending", value: summary.pending });
1261
1443
  }
1262
- return /* @__PURE__ */ jsx29(
1444
+ return /* @__PURE__ */ jsx30(
1263
1445
  "dl",
1264
1446
  {
1265
1447
  className: cn(
@@ -1272,17 +1454,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
1272
1454
  "aria-label": ariaLabel,
1273
1455
  children: cards.map((c) => {
1274
1456
  const tone = TONE[c.status];
1275
- return /* @__PURE__ */ jsxs17(
1457
+ return /* @__PURE__ */ jsxs18(
1276
1458
  "div",
1277
1459
  {
1278
1460
  "data-status": c.status,
1279
1461
  className: "rounded-lg border bg-card px-4 py-3",
1280
1462
  children: [
1281
- /* @__PURE__ */ jsxs17("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
1282
- /* @__PURE__ */ jsx29("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
1463
+ /* @__PURE__ */ jsxs18("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
1464
+ /* @__PURE__ */ jsx30("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
1283
1465
  c.label
1284
1466
  ] }),
1285
- /* @__PURE__ */ jsx29("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
1467
+ /* @__PURE__ */ jsx30("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
1286
1468
  ]
1287
1469
  },
1288
1470
  c.status
@@ -1342,7 +1524,7 @@ function prUrl(ci) {
1342
1524
  }
1343
1525
 
1344
1526
  // src/components/ReportMeta.tsx
1345
- import { jsx as jsx30, jsxs as jsxs18 } from "react/jsx-runtime";
1527
+ import { jsx as jsx31, jsxs as jsxs19 } from "react/jsx-runtime";
1346
1528
  function ReportMeta() {
1347
1529
  const report = useReport();
1348
1530
  const items = [];
@@ -1365,13 +1547,13 @@ function ReportMeta() {
1365
1547
  const short = sha.slice(0, 8);
1366
1548
  items.push({
1367
1549
  label: "Commit",
1368
- value: url ? /* @__PURE__ */ jsx30("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
1550
+ value: url ? /* @__PURE__ */ jsx31("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
1369
1551
  });
1370
1552
  }
1371
1553
  if (report.ci) {
1372
1554
  items.push({
1373
1555
  label: "CI",
1374
- value: report.ci.url ? /* @__PURE__ */ jsxs18("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
1556
+ value: report.ci.url ? /* @__PURE__ */ jsxs19("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
1375
1557
  ciDisplayName(report.ci.name),
1376
1558
  report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
1377
1559
  ] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
@@ -1382,7 +1564,7 @@ function ReportMeta() {
1382
1564
  const label = `#${report.ci.prNumber}`;
1383
1565
  items.push({
1384
1566
  label: "PR",
1385
- value: url ? /* @__PURE__ */ jsx30("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
1567
+ value: url ? /* @__PURE__ */ jsx31("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
1386
1568
  });
1387
1569
  }
1388
1570
  if (items.length === 0) return null;
@@ -1390,50 +1572,50 @@ function ReportMeta() {
1390
1572
  // Run metadata is useful but secondary to "what failed" — tuck it into a
1391
1573
  // collapsed disclosure so it doesn't push the result down. Native <details>
1392
1574
  // so it works with no JS (the SSR/no-hydration report still toggles).
1393
- /* @__PURE__ */ jsxs18("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
1394
- /* @__PURE__ */ jsxs18("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
1395
- /* @__PURE__ */ jsx30("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
1575
+ /* @__PURE__ */ jsxs19("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
1576
+ /* @__PURE__ */ jsxs19("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
1577
+ /* @__PURE__ */ jsx31("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
1396
1578
  "Run details"
1397
1579
  ] }),
1398
- /* @__PURE__ */ jsx30("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ jsxs18("div", { className: "flex items-baseline gap-1.5", children: [
1399
- /* @__PURE__ */ jsx30("dt", { className: "font-medium", children: item.label }),
1400
- /* @__PURE__ */ jsx30("dd", { className: "font-mono text-foreground", children: item.value })
1580
+ /* @__PURE__ */ jsx31("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ jsxs19("div", { className: "flex items-baseline gap-1.5", children: [
1581
+ /* @__PURE__ */ jsx31("dt", { className: "font-medium", children: item.label }),
1582
+ /* @__PURE__ */ jsx31("dd", { className: "font-mono text-foreground", children: item.value })
1401
1583
  ] }, item.label)) })
1402
1584
  ] })
1403
1585
  );
1404
1586
  }
1405
1587
 
1406
1588
  // src/components/ReportSchemaError.tsx
1407
- import { jsx as jsx31, jsxs as jsxs19 } from "react/jsx-runtime";
1589
+ import { jsx as jsx32, jsxs as jsxs20 } from "react/jsx-runtime";
1408
1590
  function ReportSchemaError({ error }) {
1409
- return /* @__PURE__ */ jsxs19("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
1410
- /* @__PURE__ */ jsx31("p", { children: /* @__PURE__ */ jsx31("strong", { children: "Report could not be displayed." }) }),
1411
- /* @__PURE__ */ jsx31("p", { children: error.message }),
1412
- error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs19("p", { children: [
1591
+ return /* @__PURE__ */ jsxs20("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
1592
+ /* @__PURE__ */ jsx32("p", { children: /* @__PURE__ */ jsx32("strong", { children: "Report could not be displayed." }) }),
1593
+ /* @__PURE__ */ jsx32("p", { children: error.message }),
1594
+ error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs20("p", { children: [
1413
1595
  "The report bundle is newer than this version of ",
1414
- /* @__PURE__ */ jsx31("code", { children: "executable-stories-react" }),
1596
+ /* @__PURE__ */ jsx32("code", { children: "executable-stories-react" }),
1415
1597
  ". Upgrade the package, or regenerate the report with an older formatters CLI."
1416
1598
  ] }) : null,
1417
- error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs19("details", { children: [
1418
- /* @__PURE__ */ jsxs19("summary", { children: [
1599
+ error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs20("details", { children: [
1600
+ /* @__PURE__ */ jsxs20("summary", { children: [
1419
1601
  error.issues.length,
1420
1602
  " validation issue",
1421
1603
  error.issues.length === 1 ? "" : "s"
1422
1604
  ] }),
1423
- /* @__PURE__ */ jsx31("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
1605
+ /* @__PURE__ */ jsx32("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
1424
1606
  ] }) : null
1425
1607
  ] });
1426
1608
  }
1427
1609
 
1428
1610
  // src/components/ReportShell.tsx
1429
- import { Fragment as Fragment10, jsx as jsx32, jsxs as jsxs20 } from "react/jsx-runtime";
1611
+ import { Fragment as Fragment10, jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
1430
1612
  function ReportErrorShell({
1431
1613
  error,
1432
1614
  className,
1433
1615
  title,
1434
1616
  dataTheme
1435
1617
  }) {
1436
- return /* @__PURE__ */ jsx32("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx32(ReportSchemaError, { error }) });
1618
+ return /* @__PURE__ */ jsx33("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx33(ReportSchemaError, { error }) });
1437
1619
  }
1438
1620
 
1439
1621
  // src/interactive/ReportInteractive.tsx
@@ -1442,12 +1624,12 @@ import { Monitor, Moon, Sun } from "lucide-react";
1442
1624
  // src/components/ui/switch.tsx
1443
1625
  import "react";
1444
1626
  import { Switch as SwitchPrimitive } from "@base-ui/react/switch";
1445
- import { jsx as jsx33 } from "react/jsx-runtime";
1627
+ import { jsx as jsx34 } from "react/jsx-runtime";
1446
1628
  function Switch({
1447
1629
  className,
1448
1630
  ...props
1449
1631
  }) {
1450
- return /* @__PURE__ */ jsx33(
1632
+ return /* @__PURE__ */ jsx34(
1451
1633
  SwitchPrimitive.Root,
1452
1634
  {
1453
1635
  "data-slot": "switch",
@@ -1456,7 +1638,7 @@ function Switch({
1456
1638
  className
1457
1639
  ),
1458
1640
  ...props,
1459
- children: /* @__PURE__ */ jsx33(
1641
+ children: /* @__PURE__ */ jsx34(
1460
1642
  SwitchPrimitive.Thumb,
1461
1643
  {
1462
1644
  "data-slot": "switch-thumb",
@@ -1472,7 +1654,7 @@ import * as React5 from "react";
1472
1654
  import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group";
1473
1655
  import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
1474
1656
  import { cva as cva3 } from "class-variance-authority";
1475
- import { jsx as jsx34 } from "react/jsx-runtime";
1657
+ import { jsx as jsx35 } from "react/jsx-runtime";
1476
1658
  var toggleItemVariants = cva3(
1477
1659
  "inline-flex items-center justify-center gap-1.5 rounded-md font-medium whitespace-nowrap text-muted-foreground transition-[color,background-color,box-shadow] outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-background data-[pressed]:text-foreground data-[pressed]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1478
1660
  {
@@ -1494,13 +1676,13 @@ function ToggleGroup({
1494
1676
  children,
1495
1677
  ...props
1496
1678
  }) {
1497
- return /* @__PURE__ */ jsx34(
1679
+ return /* @__PURE__ */ jsx35(
1498
1680
  ToggleGroupPrimitive,
1499
1681
  {
1500
1682
  "data-slot": "toggle-group",
1501
1683
  className: cn("flex w-fit items-center gap-0.5 rounded-lg bg-muted p-0.5", className),
1502
1684
  ...props,
1503
- children: /* @__PURE__ */ jsx34(ToggleGroupContext.Provider, { value: { size }, children })
1685
+ children: /* @__PURE__ */ jsx35(ToggleGroupContext.Provider, { value: { size }, children })
1504
1686
  }
1505
1687
  );
1506
1688
  }
@@ -1511,7 +1693,7 @@ function ToggleGroupItem({
1511
1693
  ...props
1512
1694
  }) {
1513
1695
  const context = React5.useContext(ToggleGroupContext);
1514
- return /* @__PURE__ */ jsx34(
1696
+ return /* @__PURE__ */ jsx35(
1515
1697
  TogglePrimitive,
1516
1698
  {
1517
1699
  "data-slot": "toggle-group-item",
@@ -1531,9 +1713,9 @@ import { Search } from "lucide-react";
1531
1713
 
1532
1714
  // src/components/ui/input.tsx
1533
1715
  import "react";
1534
- import { jsx as jsx35 } from "react/jsx-runtime";
1716
+ import { jsx as jsx36 } from "react/jsx-runtime";
1535
1717
  function Input({ className, type, ...props }) {
1536
- return /* @__PURE__ */ jsx35(
1718
+ return /* @__PURE__ */ jsx36(
1537
1719
  "input",
1538
1720
  {
1539
1721
  type,
@@ -1550,7 +1732,7 @@ function Input({ className, type, ...props }) {
1550
1732
  }
1551
1733
 
1552
1734
  // src/interactive/ReportSearch.tsx
1553
- import { jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
1735
+ import { jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
1554
1736
  var ReportSearch = forwardRef(
1555
1737
  function ReportSearch2(props, ref) {
1556
1738
  const {
@@ -1572,17 +1754,17 @@ var ReportSearch = forwardRef(
1572
1754
  e.preventDefault();
1573
1755
  }
1574
1756
  }
1575
- return /* @__PURE__ */ jsxs21("div", { className: cn("es-search flex flex-col gap-1", className), children: [
1576
- /* @__PURE__ */ jsx36("label", { htmlFor: inputId, className: "sr-only", children: "Search" }),
1577
- /* @__PURE__ */ jsxs21("div", { className: "relative w-full sm:w-72", children: [
1578
- /* @__PURE__ */ jsx36(
1757
+ return /* @__PURE__ */ jsxs22("div", { className: cn("es-search flex flex-col gap-1", className), children: [
1758
+ /* @__PURE__ */ jsx37("label", { htmlFor: inputId, className: "sr-only", children: "Search" }),
1759
+ /* @__PURE__ */ jsxs22("div", { className: "relative w-full sm:w-72", children: [
1760
+ /* @__PURE__ */ jsx37(
1579
1761
  Search,
1580
1762
  {
1581
1763
  "aria-hidden": true,
1582
1764
  className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"
1583
1765
  }
1584
1766
  ),
1585
- /* @__PURE__ */ jsx36(
1767
+ /* @__PURE__ */ jsx37(
1586
1768
  Input,
1587
1769
  {
1588
1770
  ref,
@@ -1599,7 +1781,7 @@ var ReportSearch = forwardRef(
1599
1781
  }
1600
1782
  )
1601
1783
  ] }),
1602
- showCounts ? /* @__PURE__ */ jsxs21(
1784
+ showCounts ? /* @__PURE__ */ jsxs22(
1603
1785
  "span",
1604
1786
  {
1605
1787
  className: "text-xs tabular-nums text-muted-foreground",
@@ -1640,7 +1822,7 @@ function scrollToScenarioId(scenarioId, options = {}) {
1640
1822
  }
1641
1823
 
1642
1824
  // src/interactive/ReportFailureBanner.tsx
1643
- import { jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
1825
+ import { jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
1644
1826
  function ReportFailureBanner({ failures }) {
1645
1827
  const first = failures[0];
1646
1828
  const jumpToFirst = useCallback2(() => {
@@ -1648,7 +1830,7 @@ function ReportFailureBanner({ failures }) {
1648
1830
  scrollToScenarioId(first.scenarioId);
1649
1831
  }, [first]);
1650
1832
  if (failures.length === 0) return null;
1651
- return /* @__PURE__ */ jsxs22(
1833
+ return /* @__PURE__ */ jsxs23(
1652
1834
  "div",
1653
1835
  {
1654
1836
  className: "es-failure-banner",
@@ -1656,13 +1838,13 @@ function ReportFailureBanner({ failures }) {
1656
1838
  "aria-live": "polite",
1657
1839
  "aria-label": "Failure summary",
1658
1840
  children: [
1659
- /* @__PURE__ */ jsxs22("span", { className: "es-failure-banner-text", children: [
1660
- /* @__PURE__ */ jsx37("strong", { children: failures.length }),
1841
+ /* @__PURE__ */ jsxs23("span", { className: "es-failure-banner-text", children: [
1842
+ /* @__PURE__ */ jsx38("strong", { children: failures.length }),
1661
1843
  " ",
1662
1844
  "failure",
1663
1845
  failures.length === 1 ? "" : "s"
1664
1846
  ] }),
1665
- /* @__PURE__ */ jsx37(
1847
+ /* @__PURE__ */ jsx38(
1666
1848
  "button",
1667
1849
  {
1668
1850
  type: "button",
@@ -1679,7 +1861,7 @@ function ReportFailureBanner({ failures }) {
1679
1861
 
1680
1862
  // src/interactive/ReportFreshness.tsx
1681
1863
  import { useEffect, useState as useState2 } from "react";
1682
- import { Fragment as Fragment11, jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
1864
+ import { Fragment as Fragment11, jsx as jsx39, jsxs as jsxs24 } from "react/jsx-runtime";
1683
1865
  function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
1684
1866
  const [now, setNow] = useState2(nowMs);
1685
1867
  useEffect(() => {
@@ -1687,7 +1869,7 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
1687
1869
  }, [nowMs]);
1688
1870
  if (lastRunMs === void 0 || now === void 0) return null;
1689
1871
  const age = formatRelativeAge(lastRunMs, now);
1690
- const runLink = ciUrl ? /* @__PURE__ */ jsx38(
1872
+ const runLink = ciUrl ? /* @__PURE__ */ jsx39(
1691
1873
  "a",
1692
1874
  {
1693
1875
  href: ciUrl,
@@ -1698,9 +1880,9 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
1698
1880
  }
1699
1881
  ) : null;
1700
1882
  if (isReportStale(lastRunMs, staleAfterDays, now)) {
1701
- return /* @__PURE__ */ jsxs23("div", { className: "es-stale-banner", role: "status", "aria-label": "Report freshness", children: [
1702
- /* @__PURE__ */ jsxs23("span", { children: [
1703
- /* @__PURE__ */ jsxs23("strong", { children: [
1883
+ return /* @__PURE__ */ jsxs24("div", { className: "es-stale-banner", role: "status", "aria-label": "Report freshness", children: [
1884
+ /* @__PURE__ */ jsxs24("span", { children: [
1885
+ /* @__PURE__ */ jsxs24("strong", { children: [
1704
1886
  "Last verified ",
1705
1887
  age,
1706
1888
  "."
@@ -1710,10 +1892,10 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
1710
1892
  runLink
1711
1893
  ] });
1712
1894
  }
1713
- return /* @__PURE__ */ jsxs23("p", { className: "es-freshness", "aria-label": "Report freshness", children: [
1895
+ return /* @__PURE__ */ jsxs24("p", { className: "es-freshness", "aria-label": "Report freshness", children: [
1714
1896
  "Verified ",
1715
1897
  age,
1716
- runLink ? /* @__PURE__ */ jsxs23(Fragment11, { children: [
1898
+ runLink ? /* @__PURE__ */ jsxs24(Fragment11, { children: [
1717
1899
  " \xB7 ",
1718
1900
  runLink
1719
1901
  ] }) : null
@@ -1721,15 +1903,15 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
1721
1903
  }
1722
1904
 
1723
1905
  // src/interactive/ReportLastRunDelta.tsx
1724
- import { Fragment as Fragment12, jsx as jsx39, jsxs as jsxs24 } from "react/jsx-runtime";
1906
+ import { Fragment as Fragment12, jsx as jsx40, jsxs as jsxs25 } from "react/jsx-runtime";
1725
1907
  var MAX_LINKS = 5;
1726
1908
  function ScenarioLinks({ scenarios, tone }) {
1727
- return /* @__PURE__ */ jsxs24(Fragment12, { children: [
1728
- scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */ jsxs24("span", { children: [
1909
+ return /* @__PURE__ */ jsxs25(Fragment12, { children: [
1910
+ scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */ jsxs25("span", { children: [
1729
1911
  i > 0 ? ", " : "",
1730
- /* @__PURE__ */ jsx39("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
1912
+ /* @__PURE__ */ jsx40("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
1731
1913
  ] }, s.id)),
1732
- scenarios.length > MAX_LINKS ? /* @__PURE__ */ jsxs24("span", { children: [
1914
+ scenarios.length > MAX_LINKS ? /* @__PURE__ */ jsxs25("span", { children: [
1733
1915
  " and ",
1734
1916
  scenarios.length - MAX_LINKS,
1735
1917
  " more"
@@ -1746,23 +1928,23 @@ function ReportLastRunDelta({
1746
1928
  if (!delta) return null;
1747
1929
  const { newlyFailing, newlyPassing, added } = delta;
1748
1930
  if (newlyFailing.length === 0 && newlyPassing.length === 0 && added.length === 0) {
1749
- return /* @__PURE__ */ jsx39("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: "Since last run: no behavior changes." });
1931
+ return /* @__PURE__ */ jsx40("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: "Since last run: no behavior changes." });
1750
1932
  }
1751
- return /* @__PURE__ */ jsxs24("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: [
1752
- /* @__PURE__ */ jsx39("span", { className: "font-medium text-foreground", children: "Since last run:" }),
1753
- newlyFailing.length > 0 ? /* @__PURE__ */ jsxs24("span", { className: "ml-2 text-fail", children: [
1933
+ return /* @__PURE__ */ jsxs25("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: [
1934
+ /* @__PURE__ */ jsx40("span", { className: "font-medium text-foreground", children: "Since last run:" }),
1935
+ newlyFailing.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2 text-fail", children: [
1754
1936
  newlyFailing.length,
1755
1937
  " newly failing (",
1756
- /* @__PURE__ */ jsx39(ScenarioLinks, { scenarios: newlyFailing, tone: "text-fail" }),
1938
+ /* @__PURE__ */ jsx40(ScenarioLinks, { scenarios: newlyFailing, tone: "text-fail" }),
1757
1939
  ")"
1758
1940
  ] }) : null,
1759
- newlyPassing.length > 0 ? /* @__PURE__ */ jsxs24("span", { className: "ml-2 text-pass", children: [
1941
+ newlyPassing.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2 text-pass", children: [
1760
1942
  newlyPassing.length,
1761
1943
  " fixed (",
1762
- /* @__PURE__ */ jsx39(ScenarioLinks, { scenarios: newlyPassing, tone: "text-pass" }),
1944
+ /* @__PURE__ */ jsx40(ScenarioLinks, { scenarios: newlyPassing, tone: "text-pass" }),
1763
1945
  ")"
1764
1946
  ] }) : null,
1765
- added.length > 0 ? /* @__PURE__ */ jsxs24("span", { className: "ml-2", children: [
1947
+ added.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2", children: [
1766
1948
  added.length,
1767
1949
  " new"
1768
1950
  ] }) : null
@@ -1826,7 +2008,7 @@ function Button({
1826
2008
  }
1827
2009
 
1828
2010
  // src/interactive/ReportShortcutsHelp.tsx
1829
- import { jsx as jsx40, jsxs as jsxs25 } from "react/jsx-runtime";
2011
+ import { jsx as jsx41, jsxs as jsxs26 } from "react/jsx-runtime";
1830
2012
  var SHORTCUTS = [
1831
2013
  { keys: "/", description: "Focus search" },
1832
2014
  { keys: "f", description: "Jump to next failure" },
@@ -1838,9 +2020,9 @@ var SHORTCUTS = [
1838
2020
  ];
1839
2021
  function Keys({ keys }) {
1840
2022
  const parts = keys.split(" ");
1841
- return /* @__PURE__ */ jsx40("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ jsxs25("span", { className: "inline-flex items-center gap-1", children: [
1842
- i > 0 ? /* @__PURE__ */ jsx40("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
1843
- /* @__PURE__ */ jsx40("kbd", { className: "inline-flex h-6 min-w-6 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs font-medium text-muted-foreground", children: k })
2023
+ return /* @__PURE__ */ jsx41("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1", children: [
2024
+ i > 0 ? /* @__PURE__ */ jsx41("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
2025
+ /* @__PURE__ */ jsx41("kbd", { className: "inline-flex h-6 min-w-6 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs font-medium text-muted-foreground", children: k })
1844
2026
  ] }, k)) });
1845
2027
  }
1846
2028
  function ReportShortcutsHelp({ open, onClose }) {
@@ -1851,7 +2033,7 @@ function ReportShortcutsHelp({ open, onClose }) {
1851
2033
  if (open && !dialog.open) dialog.showModal();
1852
2034
  else if (!open && dialog.open) dialog.close();
1853
2035
  }, [open]);
1854
- return /* @__PURE__ */ jsxs25(
2036
+ return /* @__PURE__ */ jsxs26(
1855
2037
  "dialog",
1856
2038
  {
1857
2039
  ref: dialogRef,
@@ -1859,12 +2041,12 @@ function ReportShortcutsHelp({ open, onClose }) {
1859
2041
  "aria-label": "Keyboard shortcuts",
1860
2042
  onClose,
1861
2043
  children: [
1862
- /* @__PURE__ */ jsx40("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
1863
- /* @__PURE__ */ jsx40("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ jsxs25("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
1864
- /* @__PURE__ */ jsx40("dt", { className: "justify-self-start", children: /* @__PURE__ */ jsx40(Keys, { keys: s.keys }) }),
1865
- /* @__PURE__ */ jsx40("dd", { className: "text-sm text-muted-foreground", children: s.description })
2044
+ /* @__PURE__ */ jsx41("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
2045
+ /* @__PURE__ */ jsx41("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ jsxs26("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
2046
+ /* @__PURE__ */ jsx41("dt", { className: "justify-self-start", children: /* @__PURE__ */ jsx41(Keys, { keys: s.keys }) }),
2047
+ /* @__PURE__ */ jsx41("dd", { className: "text-sm text-muted-foreground", children: s.description })
1866
2048
  ] }, s.keys)) }),
1867
- /* @__PURE__ */ jsx40("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ jsx40(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
2049
+ /* @__PURE__ */ jsx41("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ jsx41(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
1868
2050
  ]
1869
2051
  }
1870
2052
  );
@@ -2036,9 +2218,36 @@ function listFailures(report) {
2036
2218
  return out;
2037
2219
  }
2038
2220
 
2221
+ // src/interactive/triage-default.ts
2222
+ function needsAttention(status) {
2223
+ return status === "failed";
2224
+ }
2225
+ function defaultCollapsedIds(report) {
2226
+ const collapsed = /* @__PURE__ */ new Set();
2227
+ if (report.summary.failed === 0) return collapsed;
2228
+ for (const feature of report.features) {
2229
+ const featureHasFailure = feature.scenarios.some((s) => needsAttention(s.status));
2230
+ if (!featureHasFailure) collapsed.add(feature.id);
2231
+ for (const scenario of feature.scenarios) {
2232
+ if (!needsAttention(scenario.status)) collapsed.add(scenario.id);
2233
+ }
2234
+ }
2235
+ return collapsed;
2236
+ }
2237
+ function failuresFirst(report) {
2238
+ if (report.summary.failed === 0) return report;
2239
+ const withFailures = [];
2240
+ const rest = [];
2241
+ for (const feature of report.features) {
2242
+ (feature.scenarios.some((s) => needsAttention(s.status)) ? withFailures : rest).push(feature);
2243
+ }
2244
+ if (withFailures.length === 0) return report;
2245
+ return { ...report, features: [...withFailures, ...rest] };
2246
+ }
2247
+
2039
2248
  // src/interactive/ReportFilters.tsx
2040
2249
  import { useState as useState3 } from "react";
2041
- import { jsx as jsx41, jsxs as jsxs26 } from "react/jsx-runtime";
2250
+ import { jsx as jsx42, jsxs as jsxs27 } from "react/jsx-runtime";
2042
2251
  var TAG_LIMIT = 12;
2043
2252
  function ReportFilters({
2044
2253
  statuses,
@@ -2052,10 +2261,10 @@ function ReportFilters({
2052
2261
  if (statuses.length === 0 && tags.length === 0) return null;
2053
2262
  const tagsCollapsed = tags.length > TAG_LIMIT && !showAllTags;
2054
2263
  const visibleTags = tagsCollapsed ? tags.slice(0, TAG_LIMIT) : tags;
2055
- return /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-2", children: [
2056
- statuses.length > 0 ? /* @__PURE__ */ jsx41("div", { role: "group", "aria-label": "Filter by status", className: "flex flex-wrap gap-1", children: statuses.map((opt) => {
2264
+ return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-2", children: [
2265
+ statuses.length > 0 ? /* @__PURE__ */ jsx42("div", { role: "group", "aria-label": "Filter by status", className: "flex flex-wrap gap-1", children: statuses.map((opt) => {
2057
2266
  const active = status === opt.key;
2058
- return /* @__PURE__ */ jsxs26(
2267
+ return /* @__PURE__ */ jsxs27(
2059
2268
  "button",
2060
2269
  {
2061
2270
  type: "button",
@@ -2067,23 +2276,23 @@ function ReportFilters({
2067
2276
  ),
2068
2277
  children: [
2069
2278
  opt.label,
2070
- /* @__PURE__ */ jsx41("span", { className: "ml-1 font-mono opacity-70", children: opt.count })
2279
+ /* @__PURE__ */ jsx42("span", { className: "ml-1 font-mono opacity-70", children: opt.count })
2071
2280
  ]
2072
2281
  },
2073
2282
  opt.key
2074
2283
  );
2075
2284
  }) }) : null,
2076
- tags.length > 0 ? /* @__PURE__ */ jsxs26("ul", { "aria-label": "Filter by tag", className: "flex flex-wrap items-center gap-1.5", children: [
2285
+ tags.length > 0 ? /* @__PURE__ */ jsxs27("ul", { "aria-label": "Filter by tag", className: "flex flex-wrap items-center gap-1.5", children: [
2077
2286
  visibleTags.map((tag) => {
2078
2287
  const active = activeTags.includes(tag);
2079
- return /* @__PURE__ */ jsx41("li", { children: /* @__PURE__ */ jsx41(
2288
+ return /* @__PURE__ */ jsx42("li", { children: /* @__PURE__ */ jsx42(
2080
2289
  "button",
2081
2290
  {
2082
2291
  type: "button",
2083
2292
  "aria-pressed": active,
2084
2293
  onClick: () => onToggleTag(tag),
2085
2294
  className: "cursor-pointer",
2086
- children: /* @__PURE__ */ jsx41(
2295
+ children: /* @__PURE__ */ jsx42(
2087
2296
  Badge,
2088
2297
  {
2089
2298
  variant: "tag",
@@ -2096,7 +2305,7 @@ function ReportFilters({
2096
2305
  }
2097
2306
  ) }, tag);
2098
2307
  }),
2099
- tags.length > TAG_LIMIT ? /* @__PURE__ */ jsx41("li", { children: /* @__PURE__ */ jsx41(
2308
+ tags.length > TAG_LIMIT ? /* @__PURE__ */ jsx42("li", { children: /* @__PURE__ */ jsx42(
2100
2309
  "button",
2101
2310
  {
2102
2311
  type: "button",
@@ -2112,7 +2321,7 @@ function ReportFilters({
2112
2321
 
2113
2322
  // src/interactive/ReportToc.tsx
2114
2323
  import { useEffect as useEffect5, useMemo as useMemo2, useState as useState4 } from "react";
2115
- import { jsx as jsx42, jsxs as jsxs27 } from "react/jsx-runtime";
2324
+ import { jsx as jsx43, jsxs as jsxs28 } from "react/jsx-runtime";
2116
2325
  var DOT = {
2117
2326
  passed: "bg-pass",
2118
2327
  failed: "bg-fail",
@@ -2141,11 +2350,11 @@ function TocContent({ onNavigate }) {
2141
2350
  return () => observer.disconnect();
2142
2351
  }, [scenarioIds]);
2143
2352
  if (report.features.length === 0) return null;
2144
- return /* @__PURE__ */ jsx42("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ jsxs27("li", { children: [
2145
- /* @__PURE__ */ jsx42("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
2146
- /* @__PURE__ */ jsx42("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
2353
+ return /* @__PURE__ */ jsx43("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ jsxs28("li", { children: [
2354
+ /* @__PURE__ */ jsx43("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
2355
+ /* @__PURE__ */ jsx43("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
2147
2356
  const active = activeId === scenario.id;
2148
- return /* @__PURE__ */ jsx42("li", { children: /* @__PURE__ */ jsxs27(
2357
+ return /* @__PURE__ */ jsx43("li", { children: /* @__PURE__ */ jsxs28(
2149
2358
  "a",
2150
2359
  {
2151
2360
  href: `#${scenario.id}`,
@@ -2160,14 +2369,14 @@ function TocContent({ onNavigate }) {
2160
2369
  active ? "border-primary font-medium text-foreground" : "border-border text-muted-foreground"
2161
2370
  ),
2162
2371
  children: [
2163
- /* @__PURE__ */ jsx42(
2372
+ /* @__PURE__ */ jsx43(
2164
2373
  "span",
2165
2374
  {
2166
2375
  "aria-hidden": true,
2167
2376
  className: cn("mt-1 size-1.5 shrink-0 rounded-full", DOT[scenario.status])
2168
2377
  }
2169
2378
  ),
2170
- /* @__PURE__ */ jsx42("span", { className: "break-words", children: scenario.title })
2379
+ /* @__PURE__ */ jsx43("span", { className: "break-words", children: scenario.title })
2171
2380
  ]
2172
2381
  }
2173
2382
  ) }, scenario.id);
@@ -2177,14 +2386,14 @@ function TocContent({ onNavigate }) {
2177
2386
  function ReportToc() {
2178
2387
  const report = useReport();
2179
2388
  if (report.features.length === 0) return null;
2180
- return /* @__PURE__ */ jsxs27(
2389
+ return /* @__PURE__ */ jsxs28(
2181
2390
  "nav",
2182
2391
  {
2183
2392
  "aria-label": "Table of contents",
2184
2393
  className: "sticky top-4 hidden h-fit w-64 shrink-0 self-start text-xs lg:block",
2185
2394
  children: [
2186
- /* @__PURE__ */ jsx42("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
2187
- /* @__PURE__ */ jsx42(TocContent, {})
2395
+ /* @__PURE__ */ jsx43("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
2396
+ /* @__PURE__ */ jsx43(TocContent, {})
2188
2397
  ]
2189
2398
  }
2190
2399
  );
@@ -2194,31 +2403,31 @@ function ReportToc() {
2194
2403
  import { useState as useState5 } from "react";
2195
2404
  import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
2196
2405
  import { ListIcon, XIcon } from "lucide-react";
2197
- import { jsx as jsx43, jsxs as jsxs28 } from "react/jsx-runtime";
2406
+ import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
2198
2407
  function ReportTocDrawer() {
2199
2408
  const report = useReport();
2200
2409
  const [open, setOpen] = useState5(false);
2201
2410
  if (report.features.length === 0) return null;
2202
- return /* @__PURE__ */ jsxs28(DialogPrimitive.Root, { open, onOpenChange: setOpen, children: [
2203
- /* @__PURE__ */ jsxs28(DialogPrimitive.Trigger, { className: "flex cursor-pointer items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground lg:hidden [&_svg]:size-3.5", children: [
2204
- /* @__PURE__ */ jsx43(ListIcon, { "aria-hidden": true }),
2411
+ return /* @__PURE__ */ jsxs29(DialogPrimitive.Root, { open, onOpenChange: setOpen, children: [
2412
+ /* @__PURE__ */ jsxs29(DialogPrimitive.Trigger, { className: "flex cursor-pointer items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground lg:hidden [&_svg]:size-3.5", children: [
2413
+ /* @__PURE__ */ jsx44(ListIcon, { "aria-hidden": true }),
2205
2414
  " Contents"
2206
2415
  ] }),
2207
- /* @__PURE__ */ jsxs28(DialogPrimitive.Portal, { children: [
2208
- /* @__PURE__ */ jsx43(DialogPrimitive.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
2209
- /* @__PURE__ */ jsxs28(DialogPrimitive.Popup, { className: "fixed inset-y-0 left-0 z-50 flex w-72 max-w-[80vw] flex-col gap-3 overflow-y-auto border-r border-border bg-background p-4 font-sans text-xs shadow-lg outline-none transition-transform duration-200 data-[ending-style]:-translate-x-full data-[starting-style]:-translate-x-full", children: [
2210
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center justify-between", children: [
2211
- /* @__PURE__ */ jsx43(DialogPrimitive.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
2212
- /* @__PURE__ */ jsx43(
2416
+ /* @__PURE__ */ jsxs29(DialogPrimitive.Portal, { children: [
2417
+ /* @__PURE__ */ jsx44(DialogPrimitive.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
2418
+ /* @__PURE__ */ jsxs29(DialogPrimitive.Popup, { className: "fixed inset-y-0 left-0 z-50 flex w-72 max-w-[80vw] flex-col gap-3 overflow-y-auto border-r border-border bg-background p-4 font-sans text-xs shadow-lg outline-none transition-transform duration-200 data-[ending-style]:-translate-x-full data-[starting-style]:-translate-x-full", children: [
2419
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-between", children: [
2420
+ /* @__PURE__ */ jsx44(DialogPrimitive.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
2421
+ /* @__PURE__ */ jsx44(
2213
2422
  DialogPrimitive.Close,
2214
2423
  {
2215
2424
  "aria-label": "Close contents",
2216
2425
  className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
2217
- children: /* @__PURE__ */ jsx43(XIcon, { "aria-hidden": true })
2426
+ children: /* @__PURE__ */ jsx44(XIcon, { "aria-hidden": true })
2218
2427
  }
2219
2428
  )
2220
2429
  ] }),
2221
- /* @__PURE__ */ jsx43(TocContent, { onNavigate: () => setOpen(false) })
2430
+ /* @__PURE__ */ jsx44(TocContent, { onNavigate: () => setOpen(false) })
2222
2431
  ] })
2223
2432
  ] })
2224
2433
  ] });
@@ -2273,14 +2482,14 @@ function useTheme() {
2273
2482
  }
2274
2483
 
2275
2484
  // src/interactive/ReportInteractive.tsx
2276
- import { Fragment as Fragment13, jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
2485
+ import { Fragment as Fragment13, jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
2277
2486
  function ReportInteractive(props) {
2278
2487
  const { report, className, title, dataTheme } = props;
2279
2488
  const result = unwrapReport(report);
2280
2489
  if (!result.ok) {
2281
- return /* @__PURE__ */ jsx44(ReportErrorShell, { error: result.error, className, title, dataTheme });
2490
+ return /* @__PURE__ */ jsx45(ReportErrorShell, { error: result.error, className, title, dataTheme });
2282
2491
  }
2283
- return /* @__PURE__ */ jsx44(ReportInteractiveView, { ...props, report: result.data });
2492
+ return /* @__PURE__ */ jsx45(ReportInteractiveView, { ...props, report: result.data });
2284
2493
  }
2285
2494
  var THEME_OPTIONS = [
2286
2495
  { value: "light", label: "Light", Icon: Sun },
@@ -2288,7 +2497,7 @@ var THEME_OPTIONS = [
2288
2497
  { value: "dark", label: "Dark", Icon: Moon }
2289
2498
  ];
2290
2499
  function ThemeSegment({ pref, onPref }) {
2291
- return /* @__PURE__ */ jsx44(
2500
+ return /* @__PURE__ */ jsx45(
2292
2501
  ToggleGroup,
2293
2502
  {
2294
2503
  size: "sm",
@@ -2298,7 +2507,7 @@ function ThemeSegment({ pref, onPref }) {
2298
2507
  if (next) onPref(next);
2299
2508
  },
2300
2509
  "aria-label": "Color theme",
2301
- children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ jsx44(ToggleGroupItem, { value, "aria-label": label, title: label, className: "px-2", children: /* @__PURE__ */ jsx44(Icon, {}) }, value))
2510
+ children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ jsx45(ToggleGroupItem, { value, "aria-label": label, title: label, className: "px-2", children: /* @__PURE__ */ jsx45(Icon, {}) }, value))
2302
2511
  }
2303
2512
  );
2304
2513
  }
@@ -2326,7 +2535,9 @@ function ReportInteractiveView({
2326
2535
  const deferredQuery = useDeferredValue(query);
2327
2536
  const failures = useMemo3(() => listFailures(report), [report]);
2328
2537
  const filtered = useMemo3(
2329
- () => filterReport(report, { query: deferredQuery, status: statusFilter, tags: activeTags }),
2538
+ // Features carrying failures float to the top so the first thing on screen
2539
+ // is the thing that needs attention; an all-green run keeps source order.
2540
+ () => failuresFirst(filterReport(report, { query: deferredQuery, status: statusFilter, tags: activeTags })),
2330
2541
  [report, deferredQuery, statusFilter, activeTags]
2331
2542
  );
2332
2543
  const isFiltering = query !== deferredQuery;
@@ -2364,7 +2575,7 @@ function ReportInteractiveView({
2364
2575
  const scenarioActions = useMemo3(
2365
2576
  () => ({
2366
2577
  copyLink: (s) => copy(scenarioPermalink(s), "Link copied"),
2367
- copyMarkdown: (s) => copy(scenarioToMarkdown(s), "Markdown copied"),
2578
+ copyMarkdown: (s) => copy(scenarioToMarkdown2(s), "Markdown copied"),
2368
2579
  copyPrompt: (s) => copy(scenarioToPrompt(s), "Prompt copied")
2369
2580
  }),
2370
2581
  [copy]
@@ -2374,9 +2585,9 @@ function ReportInteractiveView({
2374
2585
  () => report.features.flatMap((f) => [f.id, ...f.scenarios.map((s) => s.id)]),
2375
2586
  [report]
2376
2587
  );
2377
- const collapse = useCollapseState();
2588
+ const collapse = useCollapseState(useCallback4(() => defaultCollapsedIds(report), [report]));
2378
2589
  const collapseAll = useCallback4(() => collapse.collapseAll(allCollapsibleIds), [collapse, allCollapsibleIds]);
2379
- const [expandedAll, setExpandedAll] = useState7(true);
2590
+ const [expandedAll, setExpandedAll] = useState7(() => report.summary.failed === 0);
2380
2591
  const setExpanded = useCallback4(
2381
2592
  (expanded) => {
2382
2593
  if (expanded) collapse.expandAll();
@@ -2418,13 +2629,13 @@ function ReportInteractiveView({
2418
2629
  const totalScenarios = report.summary.total;
2419
2630
  const matchedScenarios = filtered.summary.total;
2420
2631
  const showToc = !hideToc && totalScenarios > 3;
2421
- return /* @__PURE__ */ jsx44(CollapseProvider, { value: collapse.api, children: /* @__PURE__ */ jsx44(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ jsx44(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ jsx44(
2632
+ return /* @__PURE__ */ jsx45(CollapseProvider, { value: collapse.api, children: /* @__PURE__ */ jsx45(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ jsx45(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ jsx45(
2422
2633
  ReportRoot,
2423
2634
  {
2424
2635
  report: filtered,
2425
2636
  customRenderers,
2426
2637
  renderers,
2427
- children: /* @__PURE__ */ jsxs29(
2638
+ children: /* @__PURE__ */ jsxs30(
2428
2639
  "main",
2429
2640
  {
2430
2641
  className: cn("es-report", "es-report-interactive", className),
@@ -2433,8 +2644,8 @@ function ReportInteractiveView({
2433
2644
  "data-theme": dataTheme,
2434
2645
  "data-detail-level": detail,
2435
2646
  children: [
2436
- /* @__PURE__ */ jsxs29("header", { className: "es-report-header", children: [
2437
- /* @__PURE__ */ jsxs29(
2647
+ /* @__PURE__ */ jsxs30("header", { className: "es-report-header", children: [
2648
+ /* @__PURE__ */ jsxs30(
2438
2649
  "div",
2439
2650
  {
2440
2651
  "data-es-navbar": true,
@@ -2443,9 +2654,9 @@ function ReportInteractiveView({
2443
2654
  hideHeader ? "justify-end" : "justify-between"
2444
2655
  ),
2445
2656
  children: [
2446
- hideHeader ? null : /* @__PURE__ */ jsx44("h1", { className: "min-w-0", children: title ?? "Story Report" }),
2447
- /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-2", children: [
2448
- /* @__PURE__ */ jsx44(
2657
+ hideHeader ? null : /* @__PURE__ */ jsx45("h1", { className: "min-w-0", children: title ?? "Story Report" }),
2658
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
2659
+ /* @__PURE__ */ jsx45(
2449
2660
  ReportSearch,
2450
2661
  {
2451
2662
  ref: searchRef,
@@ -2455,16 +2666,16 @@ function ReportInteractiveView({
2455
2666
  totalCount: totalScenarios
2456
2667
  }
2457
2668
  ),
2458
- /* @__PURE__ */ jsx44(ThemeSegment, { pref: themePref, onPref: setThemePref })
2669
+ /* @__PURE__ */ jsx45(ThemeSegment, { pref: themePref, onPref: setThemePref })
2459
2670
  ] })
2460
2671
  ]
2461
2672
  }
2462
2673
  ),
2463
- hideHeader ? null : /* @__PURE__ */ jsxs29(Fragment13, { children: [
2464
- /* @__PURE__ */ jsx44(ReportSummary, {}),
2465
- /* @__PURE__ */ jsx44(ReportMeta, {})
2674
+ hideHeader ? null : /* @__PURE__ */ jsxs30(Fragment13, { children: [
2675
+ /* @__PURE__ */ jsx45(ReportSummary, {}),
2676
+ /* @__PURE__ */ jsx45(ReportMeta, {})
2466
2677
  ] }),
2467
- /* @__PURE__ */ jsx44(
2678
+ /* @__PURE__ */ jsx45(
2468
2679
  ReportFreshness,
2469
2680
  {
2470
2681
  lastRunMs: reportLastRunMs(report),
@@ -2472,8 +2683,8 @@ function ReportInteractiveView({
2472
2683
  staleAfterDays
2473
2684
  }
2474
2685
  ),
2475
- /* @__PURE__ */ jsx44(ReportLastRunDelta, { history: scenarioHistory, report }),
2476
- /* @__PURE__ */ jsx44(
2686
+ /* @__PURE__ */ jsx45(ReportLastRunDelta, { history: scenarioHistory, report }),
2687
+ /* @__PURE__ */ jsx45(
2477
2688
  ReportFilters,
2478
2689
  {
2479
2690
  statuses: statusOptions,
@@ -2484,14 +2695,14 @@ function ReportInteractiveView({
2484
2695
  onToggleTag: toggleTag
2485
2696
  }
2486
2697
  ),
2487
- /* @__PURE__ */ jsxs29("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
2488
- showToc ? /* @__PURE__ */ jsx44(ReportTocDrawer, {}) : null,
2489
- /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-2", children: [
2490
- /* @__PURE__ */ jsx44(Switch, { id: expandId, checked: expandedAll, onCheckedChange: setExpanded }),
2491
- /* @__PURE__ */ jsx44("label", { htmlFor: expandId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Expand all" })
2698
+ /* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
2699
+ showToc ? /* @__PURE__ */ jsx45(ReportTocDrawer, {}) : null,
2700
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
2701
+ /* @__PURE__ */ jsx45(Switch, { id: expandId, checked: expandedAll, onCheckedChange: setExpanded }),
2702
+ /* @__PURE__ */ jsx45("label", { htmlFor: expandId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Expand all" })
2492
2703
  ] }),
2493
- /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-2", children: [
2494
- /* @__PURE__ */ jsx44(
2704
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
2705
+ /* @__PURE__ */ jsx45(
2495
2706
  Switch,
2496
2707
  {
2497
2708
  id: docsId,
@@ -2499,16 +2710,16 @@ function ReportInteractiveView({
2499
2710
  onCheckedChange: (checked) => setDetail(checked ? "full" : "minimal")
2500
2711
  }
2501
2712
  ),
2502
- /* @__PURE__ */ jsx44("label", { htmlFor: docsId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Show documentation" })
2713
+ /* @__PURE__ */ jsx45("label", { htmlFor: docsId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Show documentation" })
2503
2714
  ] })
2504
2715
  ] })
2505
2716
  ] }),
2506
- /* @__PURE__ */ jsx44(ReportFailureBanner, { failures }),
2507
- hasContent ? showToc ? /* @__PURE__ */ jsxs29("div", { className: "flex gap-6", children: [
2508
- /* @__PURE__ */ jsx44(ReportToc, {}),
2509
- /* @__PURE__ */ jsx44("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ jsx44(ReportFeatureList, {}) })
2510
- ] }) : /* @__PURE__ */ jsx44("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsx44(ReportFeatureList, {}) }) : /* @__PURE__ */ jsx44(ReportEmpty, { message: query ? "No scenarios match the search." : void 0 }),
2511
- /* @__PURE__ */ jsx44(
2717
+ /* @__PURE__ */ jsx45(ReportFailureBanner, { failures }),
2718
+ hasContent ? showToc ? /* @__PURE__ */ jsxs30("div", { className: "flex gap-6", children: [
2719
+ /* @__PURE__ */ jsx45(ReportToc, {}),
2720
+ /* @__PURE__ */ jsx45("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ jsx45(ReportFeatureList, {}) })
2721
+ ] }) : /* @__PURE__ */ jsx45("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsx45(ReportFeatureList, {}) }) : /* @__PURE__ */ jsx45(ReportEmpty, { message: query ? "No scenarios match the search." : void 0 }),
2722
+ /* @__PURE__ */ jsx45(
2512
2723
  "button",
2513
2724
  {
2514
2725
  type: "button",
@@ -2519,8 +2730,8 @@ function ReportInteractiveView({
2519
2730
  children: "?"
2520
2731
  }
2521
2732
  ),
2522
- /* @__PURE__ */ jsx44(ReportShortcutsHelp, { open: helpOpen, onClose: () => setHelpOpen(false) }),
2523
- toast ? /* @__PURE__ */ jsx44(
2733
+ /* @__PURE__ */ jsx45(ReportShortcutsHelp, { open: helpOpen, onClose: () => setHelpOpen(false) }),
2734
+ toast ? /* @__PURE__ */ jsx45(
2524
2735
  "div",
2525
2736
  {
2526
2737
  role: "status",
@@ -2544,7 +2755,7 @@ import { createElement, useEffect as useEffect8, useState as useState9 } from "r
2544
2755
 
2545
2756
  // src/components/doc/MermaidView.tsx
2546
2757
  import { useEffect as useEffect7, useRef as useRef4, useState as useState8 } from "react";
2547
- import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
2758
+ import { jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
2548
2759
  function prefersDark(el) {
2549
2760
  const themed = el?.closest("[data-theme]");
2550
2761
  if (themed?.dataset.theme === "dark") return true;
@@ -2581,9 +2792,9 @@ function MermaidView({ entry, load }) {
2581
2792
  };
2582
2793
  }, [entry.code, load]);
2583
2794
  if (svg) {
2584
- return /* @__PURE__ */ jsxs30("figure", { ref, className: "my-3", children: [
2585
- entry.title ? /* @__PURE__ */ jsx45("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
2586
- /* @__PURE__ */ jsx45(
2795
+ return /* @__PURE__ */ jsxs31("figure", { ref, className: "my-3", children: [
2796
+ entry.title ? /* @__PURE__ */ jsx46("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
2797
+ /* @__PURE__ */ jsx46(
2587
2798
  "div",
2588
2799
  {
2589
2800
  role: "img",
@@ -2594,11 +2805,11 @@ function MermaidView({ entry, load }) {
2594
2805
  )
2595
2806
  ] });
2596
2807
  }
2597
- return /* @__PURE__ */ jsx45(MermaidSource, { entry, ref });
2808
+ return /* @__PURE__ */ jsx46(MermaidSource, { entry, ref });
2598
2809
  }
2599
2810
 
2600
2811
  // src/interactive/island-renderers.tsx
2601
- import { jsx as jsx46 } from "react/jsx-runtime";
2812
+ import { jsx as jsx47 } from "react/jsx-runtime";
2602
2813
  var HLJS_ESM = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/es/highlight.min.js";
2603
2814
  var MERMAID_ESM = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";
2604
2815
  function cachedCdnModule(url) {
@@ -2632,13 +2843,13 @@ function CdnHighlightedCode({ entry }) {
2632
2843
  cancelled = true;
2633
2844
  };
2634
2845
  }, [entry.content, entry.lang]);
2635
- return /* @__PURE__ */ jsx46(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ jsx46(
2846
+ return /* @__PURE__ */ jsx47(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ jsx47(
2636
2847
  "code",
2637
2848
  {
2638
2849
  className: cn("hljs font-mono text-xs", entry.lang && `language-${entry.lang}`),
2639
2850
  dangerouslySetInnerHTML: { __html: html }
2640
2851
  }
2641
- ) : /* @__PURE__ */ jsx46("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
2852
+ ) : /* @__PURE__ */ jsx47("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
2642
2853
  }
2643
2854
  function buildIslandRenderers(opts) {
2644
2855
  const renderers = {};
@@ -2652,7 +2863,7 @@ function buildIslandRenderers(opts) {
2652
2863
  }
2653
2864
 
2654
2865
  // src/interactive/ReportInteractiveIsland.tsx
2655
- import { jsx as jsx47 } from "react/jsx-runtime";
2866
+ import { jsx as jsx48 } from "react/jsx-runtime";
2656
2867
  function ReportInteractiveIsland({
2657
2868
  report,
2658
2869
  title,
@@ -2666,7 +2877,7 @@ function ReportInteractiveIsland({
2666
2877
  () => buildIslandRenderers({ syntaxHighlighting, mermaid }),
2667
2878
  [syntaxHighlighting, mermaid]
2668
2879
  );
2669
- return /* @__PURE__ */ jsx47(
2880
+ return /* @__PURE__ */ jsx48(
2670
2881
  ReportInteractive,
2671
2882
  {
2672
2883
  report,