executable-stories-react 0.14.0 → 0.15.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.
@@ -47,9 +47,9 @@ __export(interactive_exports, {
47
47
  module.exports = __toCommonJS(interactive_exports);
48
48
 
49
49
  // src/interactive/ReportInteractive.tsx
50
- var import_lucide_react6 = require("lucide-react");
51
- var import_react22 = require("webmcpable/react");
52
- var import_react23 = require("react");
50
+ var import_lucide_react7 = require("lucide-react");
51
+ var import_react23 = require("webmcpable/react");
52
+ var import_react24 = require("react");
53
53
 
54
54
  // src/components/ui/empty.tsx
55
55
  var import_class_variance_authority = require("class-variance-authority");
@@ -2526,9 +2526,139 @@ var ReportSearch = (0, import_react13.forwardRef)(
2526
2526
  }
2527
2527
  );
2528
2528
 
2529
- // src/interactive/ReportSinceLastVisit.tsx
2529
+ // src/interactive/ReportShare.tsx
2530
+ var import_lucide_react5 = require("lucide-react");
2530
2531
  var import_react14 = require("react");
2531
2532
 
2533
+ // src/components/ui/button.tsx
2534
+ var React7 = require("react");
2535
+ var import_class_variance_authority4 = require("class-variance-authority");
2536
+ var import_use_render2 = require("@base-ui/react/use-render");
2537
+ var buttonVariants = (0, import_class_variance_authority4.cva)(
2538
+ "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
2539
+ {
2540
+ variants: {
2541
+ variant: {
2542
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
2543
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
2544
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
2545
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
2546
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
2547
+ link: "text-primary underline-offset-4 hover:underline"
2548
+ },
2549
+ size: {
2550
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
2551
+ xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
2552
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
2553
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
2554
+ icon: "size-9",
2555
+ "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
2556
+ "icon-sm": "size-8",
2557
+ "icon-lg": "size-10"
2558
+ }
2559
+ },
2560
+ defaultVariants: {
2561
+ variant: "default",
2562
+ size: "default"
2563
+ }
2564
+ }
2565
+ );
2566
+ function Button({
2567
+ className,
2568
+ variant = "default",
2569
+ size = "default",
2570
+ render,
2571
+ ...props
2572
+ }) {
2573
+ return (0, import_use_render2.useRender)({
2574
+ defaultTagName: "button",
2575
+ render,
2576
+ props: {
2577
+ "data-slot": "button",
2578
+ "data-variant": variant,
2579
+ "data-size": size,
2580
+ className: cn(buttonVariants({ variant, size, className })),
2581
+ ...props
2582
+ }
2583
+ });
2584
+ }
2585
+
2586
+ // src/interactive/ReportShare.tsx
2587
+ var import_jsx_runtime47 = require("react/jsx-runtime");
2588
+ var DEFAULT_SHARE_COMMAND = "npx executable-stories share reports/";
2589
+ function ReportShare({
2590
+ command = DEFAULT_SHARE_COMMAND,
2591
+ onCopy
2592
+ }) {
2593
+ const [open, setOpen] = (0, import_react14.useState)(false);
2594
+ const dialogRef = (0, import_react14.useRef)(null);
2595
+ (0, import_react14.useEffect)(() => {
2596
+ const dialog = dialogRef.current;
2597
+ if (!dialog) return;
2598
+ if (open && !dialog.open) dialog.showModal();
2599
+ else if (!open && dialog.open) dialog.close();
2600
+ }, [open]);
2601
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
2602
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
2603
+ Button,
2604
+ {
2605
+ type: "button",
2606
+ variant: "ghost",
2607
+ size: "sm",
2608
+ "aria-label": "Share this report",
2609
+ title: "Share this report",
2610
+ onClick: () => setOpen(true),
2611
+ children: [
2612
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react5.Share2, { "aria-hidden": "true", className: "size-4" }),
2613
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "sr-only sm:not-sr-only", children: "Share" })
2614
+ ]
2615
+ }
2616
+ ),
2617
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
2618
+ "dialog",
2619
+ {
2620
+ ref: dialogRef,
2621
+ className: "es-report-share m-auto w-[min(90vw,32rem)] rounded-lg border border-border bg-card p-6 text-card-foreground shadow-lg [overscroll-behavior:contain] backdrop:bg-black/40",
2622
+ "aria-label": "Share this report",
2623
+ onClose: () => setOpen(false),
2624
+ children: [
2625
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h2", { className: "text-base font-semibold", children: "Share this report" }),
2626
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "mt-2 text-sm text-muted-foreground", children: "Publish it to Executable Stories Cloud and send a link. Screenshots and videos go with it. Run this from your project:" }),
2627
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "mt-4 flex items-center gap-2", children: [
2628
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("code", { className: "min-w-0 flex-1 truncate rounded border border-border bg-muted px-3 py-2 font-mono text-xs", children: command }),
2629
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2630
+ Button,
2631
+ {
2632
+ type: "button",
2633
+ size: "sm",
2634
+ onClick: () => onCopy(command, "Command copied"),
2635
+ children: "Copy"
2636
+ }
2637
+ )
2638
+ ] }),
2639
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "mt-3 text-xs text-muted-foreground", children: "The file you are reading cannot upload itself, so the command does it: only the CLI can read the assets this report links to." }),
2640
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "mt-6 flex items-center justify-between gap-4", children: [
2641
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2642
+ "a",
2643
+ {
2644
+ className: "text-xs underline underline-offset-2",
2645
+ href: "https://executablestories.com/guides/sharing-reports/",
2646
+ target: "_blank",
2647
+ rel: "noreferrer",
2648
+ children: "How sharing works"
2649
+ }
2650
+ ),
2651
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setOpen(false), children: "Close" })
2652
+ ] })
2653
+ ]
2654
+ }
2655
+ )
2656
+ ] });
2657
+ }
2658
+
2659
+ // src/interactive/ReportSinceLastVisit.tsx
2660
+ var import_react15 = require("react");
2661
+
2532
2662
  // src/interactive/last-visit.ts
2533
2663
  function snapshotOf(report, atMs) {
2534
2664
  const statuses = {};
@@ -2563,7 +2693,7 @@ function diffSinceVisit(previous, report) {
2563
2693
  }
2564
2694
 
2565
2695
  // src/interactive/ReportSinceLastVisit.tsx
2566
- var import_jsx_runtime47 = require("react/jsx-runtime");
2696
+ var import_jsx_runtime48 = require("react/jsx-runtime");
2567
2697
  var KEY = "es-last-visit";
2568
2698
  var MAX_LINKS2 = 5;
2569
2699
  function readVisit() {
@@ -2588,12 +2718,12 @@ function writeVisit(snapshot) {
2588
2718
  }
2589
2719
  }
2590
2720
  function ScenarioLinks2({ scenarios, tone }) {
2591
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
2592
- scenarios.slice(0, MAX_LINKS2).map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { children: [
2721
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
2722
+ scenarios.slice(0, MAX_LINKS2).map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { children: [
2593
2723
  i > 0 ? ", " : "",
2594
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
2724
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
2595
2725
  ] }, s.id)),
2596
- scenarios.length > MAX_LINKS2 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { children: [
2726
+ scenarios.length > MAX_LINKS2 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { children: [
2597
2727
  " and ",
2598
2728
  scenarios.length - MAX_LINKS2,
2599
2729
  " more"
@@ -2601,9 +2731,9 @@ function ScenarioLinks2({ scenarios, tone }) {
2601
2731
  ] });
2602
2732
  }
2603
2733
  function ReportSinceLastVisit({ report }) {
2604
- const [delta, setDelta] = (0, import_react14.useState)(null);
2605
- const [nowMs, setNowMs] = (0, import_react14.useState)(0);
2606
- (0, import_react14.useEffect)(() => {
2734
+ const [delta, setDelta] = (0, import_react15.useState)(null);
2735
+ const [nowMs, setNowMs] = (0, import_react15.useState)(0);
2736
+ (0, import_react15.useEffect)(() => {
2607
2737
  const now = Date.now();
2608
2738
  setDelta(diffSinceVisit(readVisit(), report));
2609
2739
  setNowMs(now);
@@ -2611,25 +2741,25 @@ function ReportSinceLastVisit({ report }) {
2611
2741
  }, [report]);
2612
2742
  if (!delta) return null;
2613
2743
  const { newlyFailing, newlyPassing, added } = delta;
2614
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("p", { className: "text-xs text-muted-foreground", "data-testid": "es-since-last-visit", children: [
2615
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "font-medium text-foreground", children: [
2744
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("p", { className: "text-xs text-muted-foreground", "data-testid": "es-since-last-visit", children: [
2745
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "font-medium text-foreground", children: [
2616
2746
  "Since your last visit (",
2617
2747
  formatRelativeAge(delta.sinceMs, nowMs),
2618
2748
  "):"
2619
2749
  ] }),
2620
- newlyFailing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ml-2 text-fail", children: [
2750
+ newlyFailing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "ml-2 text-fail", children: [
2621
2751
  newlyFailing.length,
2622
2752
  " started failing (",
2623
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ScenarioLinks2, { scenarios: newlyFailing, tone: "text-fail" }),
2753
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ScenarioLinks2, { scenarios: newlyFailing, tone: "text-fail" }),
2624
2754
  ")"
2625
2755
  ] }) : null,
2626
- newlyPassing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ml-2 text-pass", children: [
2756
+ newlyPassing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "ml-2 text-pass", children: [
2627
2757
  newlyPassing.length,
2628
2758
  " fixed (",
2629
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ScenarioLinks2, { scenarios: newlyPassing, tone: "text-pass" }),
2759
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ScenarioLinks2, { scenarios: newlyPassing, tone: "text-pass" }),
2630
2760
  ")"
2631
2761
  ] }) : null,
2632
- added.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ml-2", children: [
2762
+ added.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "ml-2", children: [
2633
2763
  added.length,
2634
2764
  " new"
2635
2765
  ] }) : null
@@ -2637,63 +2767,8 @@ function ReportSinceLastVisit({ report }) {
2637
2767
  }
2638
2768
 
2639
2769
  // src/interactive/ReportShortcutsHelp.tsx
2640
- var import_react15 = require("react");
2641
-
2642
- // src/components/ui/button.tsx
2643
- var React7 = require("react");
2644
- var import_class_variance_authority4 = require("class-variance-authority");
2645
- var import_use_render2 = require("@base-ui/react/use-render");
2646
- var buttonVariants = (0, import_class_variance_authority4.cva)(
2647
- "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
2648
- {
2649
- variants: {
2650
- variant: {
2651
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
2652
- destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
2653
- outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
2654
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
2655
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
2656
- link: "text-primary underline-offset-4 hover:underline"
2657
- },
2658
- size: {
2659
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
2660
- xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
2661
- sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
2662
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
2663
- icon: "size-9",
2664
- "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
2665
- "icon-sm": "size-8",
2666
- "icon-lg": "size-10"
2667
- }
2668
- },
2669
- defaultVariants: {
2670
- variant: "default",
2671
- size: "default"
2672
- }
2673
- }
2674
- );
2675
- function Button({
2676
- className,
2677
- variant = "default",
2678
- size = "default",
2679
- render,
2680
- ...props
2681
- }) {
2682
- return (0, import_use_render2.useRender)({
2683
- defaultTagName: "button",
2684
- render,
2685
- props: {
2686
- "data-slot": "button",
2687
- "data-variant": variant,
2688
- "data-size": size,
2689
- className: cn(buttonVariants({ variant, size, className })),
2690
- ...props
2691
- }
2692
- });
2693
- }
2694
-
2695
- // src/interactive/ReportShortcutsHelp.tsx
2696
- var import_jsx_runtime48 = require("react/jsx-runtime");
2770
+ var import_react16 = require("react");
2771
+ var import_jsx_runtime49 = require("react/jsx-runtime");
2697
2772
  var SHORTCUTS = [
2698
2773
  { keys: "/", description: "Focus search" },
2699
2774
  { keys: "f", description: "Jump to next failure" },
@@ -2705,20 +2780,20 @@ var SHORTCUTS = [
2705
2780
  ];
2706
2781
  function Keys({ keys }) {
2707
2782
  const parts = keys.split(" ");
2708
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
2709
- i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
2710
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("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 })
2783
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
2784
+ i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
2785
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("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 })
2711
2786
  ] }, k)) });
2712
2787
  }
2713
2788
  function ReportShortcutsHelp({ open, onClose }) {
2714
- const dialogRef = (0, import_react15.useRef)(null);
2715
- (0, import_react15.useEffect)(() => {
2789
+ const dialogRef = (0, import_react16.useRef)(null);
2790
+ (0, import_react16.useEffect)(() => {
2716
2791
  const dialog = dialogRef.current;
2717
2792
  if (!dialog) return;
2718
2793
  if (open && !dialog.open) dialog.showModal();
2719
2794
  else if (!open && dialog.open) dialog.close();
2720
2795
  }, [open]);
2721
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
2796
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
2722
2797
  "dialog",
2723
2798
  {
2724
2799
  ref: dialogRef,
@@ -2726,20 +2801,20 @@ function ReportShortcutsHelp({ open, onClose }) {
2726
2801
  "aria-label": "Keyboard shortcuts",
2727
2802
  onClose,
2728
2803
  children: [
2729
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
2730
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
2731
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("dt", { className: "justify-self-start", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Keys, { keys: s.keys }) }),
2732
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("dd", { className: "text-sm text-muted-foreground", children: s.description })
2804
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
2805
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
2806
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dt", { className: "justify-self-start", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Keys, { keys: s.keys }) }),
2807
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dd", { className: "text-sm text-muted-foreground", children: s.description })
2733
2808
  ] }, s.keys)) }),
2734
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
2809
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
2735
2810
  ]
2736
2811
  }
2737
2812
  );
2738
2813
  }
2739
2814
 
2740
2815
  // src/interactive/ReportToc.tsx
2741
- var import_react16 = require("react");
2742
- var import_jsx_runtime49 = require("react/jsx-runtime");
2816
+ var import_react17 = require("react");
2817
+ var import_jsx_runtime50 = require("react/jsx-runtime");
2743
2818
  var DOT = {
2744
2819
  passed: "bg-pass",
2745
2820
  failed: "bg-fail",
@@ -2748,12 +2823,12 @@ var DOT = {
2748
2823
  };
2749
2824
  function TocContent({ onNavigate }) {
2750
2825
  const report = useReport();
2751
- const [activeId, setActiveId] = (0, import_react16.useState)(null);
2752
- const scenarioIds = (0, import_react16.useMemo)(
2826
+ const [activeId, setActiveId] = (0, import_react17.useState)(null);
2827
+ const scenarioIds = (0, import_react17.useMemo)(
2753
2828
  () => report.features.flatMap((f) => f.scenarios.map((s) => s.id)),
2754
2829
  [report]
2755
2830
  );
2756
- (0, import_react16.useEffect)(() => {
2831
+ (0, import_react17.useEffect)(() => {
2757
2832
  if (typeof IntersectionObserver === "undefined") return;
2758
2833
  const els = scenarioIds.map((id) => document.getElementById(id)).filter((el) => el !== null);
2759
2834
  if (els.length === 0) return;
@@ -2768,11 +2843,11 @@ function TocContent({ onNavigate }) {
2768
2843
  return () => observer.disconnect();
2769
2844
  }, [scenarioIds]);
2770
2845
  if (report.features.length === 0) return null;
2771
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("li", { children: [
2772
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
2773
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
2846
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("li", { children: [
2847
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
2848
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
2774
2849
  const active = activeId === scenario.id;
2775
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
2850
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
2776
2851
  "a",
2777
2852
  {
2778
2853
  href: `#${scenario.id}`,
@@ -2787,14 +2862,14 @@ function TocContent({ onNavigate }) {
2787
2862
  active ? "border-primary font-medium text-foreground" : "border-border text-muted-foreground"
2788
2863
  ),
2789
2864
  children: [
2790
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
2865
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
2791
2866
  "span",
2792
2867
  {
2793
2868
  "aria-hidden": true,
2794
2869
  className: cn("mt-1 size-1.5 shrink-0 rounded-full", DOT[scenario.status])
2795
2870
  }
2796
2871
  ),
2797
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "break-words", children: scenario.title })
2872
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "break-words", children: scenario.title })
2798
2873
  ]
2799
2874
  }
2800
2875
  ) }, scenario.id);
@@ -2804,48 +2879,48 @@ function TocContent({ onNavigate }) {
2804
2879
  function ReportToc() {
2805
2880
  const report = useReport();
2806
2881
  if (report.features.length === 0) return null;
2807
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
2882
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
2808
2883
  "nav",
2809
2884
  {
2810
2885
  "aria-label": "Table of contents",
2811
2886
  className: "sticky top-4 hidden h-fit w-64 shrink-0 self-start text-xs lg:block",
2812
2887
  children: [
2813
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
2814
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TocContent, {})
2888
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
2889
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(TocContent, {})
2815
2890
  ]
2816
2891
  }
2817
2892
  );
2818
2893
  }
2819
2894
 
2820
2895
  // src/interactive/ReportTocDrawer.tsx
2821
- var import_react17 = require("react");
2896
+ var import_react18 = require("react");
2822
2897
  var import_dialog = require("@base-ui/react/dialog");
2823
- var import_lucide_react5 = require("lucide-react");
2824
- var import_jsx_runtime50 = require("react/jsx-runtime");
2898
+ var import_lucide_react6 = require("lucide-react");
2899
+ var import_jsx_runtime51 = require("react/jsx-runtime");
2825
2900
  function ReportTocDrawer() {
2826
2901
  const report = useReport();
2827
- const [open, setOpen] = (0, import_react17.useState)(false);
2902
+ const [open, setOpen] = (0, import_react18.useState)(false);
2828
2903
  if (report.features.length === 0) return null;
2829
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_dialog.Dialog.Root, { open, onOpenChange: setOpen, children: [
2830
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_dialog.Dialog.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: [
2831
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_lucide_react5.ListIcon, { "aria-hidden": true }),
2904
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_dialog.Dialog.Root, { open, onOpenChange: setOpen, children: [
2905
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_dialog.Dialog.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: [
2906
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react6.ListIcon, { "aria-hidden": true }),
2832
2907
  " Contents"
2833
2908
  ] }),
2834
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_dialog.Dialog.Portal, { children: [
2835
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_dialog.Dialog.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
2836
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_dialog.Dialog.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: [
2837
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex items-center justify-between", children: [
2838
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_dialog.Dialog.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
2839
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
2909
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_dialog.Dialog.Portal, { children: [
2910
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_dialog.Dialog.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
2911
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_dialog.Dialog.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: [
2912
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center justify-between", children: [
2913
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_dialog.Dialog.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
2914
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
2840
2915
  import_dialog.Dialog.Close,
2841
2916
  {
2842
2917
  "aria-label": "Close contents",
2843
2918
  className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
2844
- children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_lucide_react5.XIcon, { "aria-hidden": true })
2919
+ children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react6.XIcon, { "aria-hidden": true })
2845
2920
  }
2846
2921
  )
2847
2922
  ] }),
2848
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(TocContent, { onNavigate: () => setOpen(false) })
2923
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(TocContent, { onNavigate: () => setOpen(false) })
2849
2924
  ] })
2850
2925
  ] })
2851
2926
  ] });
@@ -2879,10 +2954,10 @@ function failuresFirst(report) {
2879
2954
  }
2880
2955
 
2881
2956
  // src/interactive/use-deep-link-scroll.ts
2882
- var import_react18 = require("react");
2957
+ var import_react19 = require("react");
2883
2958
  function useDeepLinkScroll() {
2884
- const lastAnchor = (0, import_react18.useRef)(null);
2885
- (0, import_react18.useEffect)(() => {
2959
+ const lastAnchor = (0, import_react19.useRef)(null);
2960
+ (0, import_react19.useEffect)(() => {
2886
2961
  function scrollToHash() {
2887
2962
  const { anchor } = splitHash(window.location.hash);
2888
2963
  if (!anchor || anchor === lastAnchor.current) return;
@@ -2898,7 +2973,7 @@ function useDeepLinkScroll() {
2898
2973
  }
2899
2974
 
2900
2975
  // src/interactive/use-keyboard-shortcuts.ts
2901
- var import_react19 = require("react");
2976
+ var import_react20 = require("react");
2902
2977
  function isEditableTarget(target) {
2903
2978
  if (!(target instanceof HTMLElement)) return false;
2904
2979
  const tag = target.tagName;
@@ -2907,9 +2982,9 @@ function isEditableTarget(target) {
2907
2982
  return false;
2908
2983
  }
2909
2984
  function useKeyboardShortcuts(handlers) {
2910
- const ref = (0, import_react19.useRef)(handlers);
2985
+ const ref = (0, import_react20.useRef)(handlers);
2911
2986
  ref.current = handlers;
2912
- (0, import_react19.useEffect)(() => {
2987
+ (0, import_react20.useEffect)(() => {
2913
2988
  function onKeyDown(e) {
2914
2989
  const h = ref.current;
2915
2990
  if (e.key === "Escape") {
@@ -2953,7 +3028,7 @@ function useKeyboardShortcuts(handlers) {
2953
3028
  }
2954
3029
 
2955
3030
  // src/interactive/use-theme.ts
2956
- var import_react20 = require("react");
3031
+ var import_react21 = require("react");
2957
3032
  var KEY2 = "es-theme";
2958
3033
  function systemDark() {
2959
3034
  return typeof matchMedia !== "undefined" && matchMedia("(prefers-color-scheme: dark)").matches;
@@ -2974,13 +3049,13 @@ function initialPref() {
2974
3049
  return "system";
2975
3050
  }
2976
3051
  function useTheme() {
2977
- const [pref, setPrefState] = (0, import_react20.useState)("system");
2978
- (0, import_react20.useEffect)(() => {
3052
+ const [pref, setPrefState] = (0, import_react21.useState)("system");
3053
+ (0, import_react21.useEffect)(() => {
2979
3054
  const p = initialPref();
2980
3055
  setPrefState(p);
2981
3056
  applyTheme(p);
2982
3057
  }, []);
2983
- (0, import_react20.useEffect)(() => {
3058
+ (0, import_react21.useEffect)(() => {
2984
3059
  if (typeof matchMedia === "undefined") return;
2985
3060
  const mq = matchMedia("(prefers-color-scheme: dark)");
2986
3061
  const onChange = () => {
@@ -2989,7 +3064,7 @@ function useTheme() {
2989
3064
  mq.addEventListener("change", onChange);
2990
3065
  return () => mq.removeEventListener("change", onChange);
2991
3066
  }, [pref]);
2992
- const setPref = (0, import_react20.useCallback)((p) => {
3067
+ const setPref = (0, import_react21.useCallback)((p) => {
2993
3068
  setPrefState(p);
2994
3069
  applyTheme(p);
2995
3070
  try {
@@ -3001,19 +3076,19 @@ function useTheme() {
3001
3076
  }
3002
3077
 
3003
3078
  // src/interactive/use-url-state.ts
3004
- var import_react21 = require("react");
3079
+ var import_react22 = require("react");
3005
3080
  var WRITE_DELAY_MS = 250;
3006
3081
  function useUrlState() {
3007
- const [state, setState] = (0, import_react21.useState)(DEFAULT_URL_STATE);
3008
- const ready = (0, import_react21.useRef)(false);
3009
- (0, import_react21.useEffect)(() => {
3082
+ const [state, setState] = (0, import_react22.useState)(DEFAULT_URL_STATE);
3083
+ const ready = (0, import_react22.useRef)(false);
3084
+ (0, import_react22.useEffect)(() => {
3010
3085
  const read = () => setState(decodeUrlState(splitHash(window.location.hash).params));
3011
3086
  read();
3012
3087
  ready.current = true;
3013
3088
  window.addEventListener("hashchange", read);
3014
3089
  return () => window.removeEventListener("hashchange", read);
3015
3090
  }, []);
3016
- (0, import_react21.useEffect)(() => {
3091
+ (0, import_react22.useEffect)(() => {
3017
3092
  if (!ready.current) return;
3018
3093
  const timer = setTimeout(
3019
3094
  () => writeHash(splitHash(window.location.hash).anchor, encodeUrlState(state)),
@@ -3021,7 +3096,7 @@ function useUrlState() {
3021
3096
  );
3022
3097
  return () => clearTimeout(timer);
3023
3098
  }, [state]);
3024
- const update = (0, import_react21.useCallback)(
3099
+ const update = (0, import_react22.useCallback)(
3025
3100
  (patch) => setState((prev) => ({ ...prev, ...patch })),
3026
3101
  []
3027
3102
  );
@@ -3243,12 +3318,12 @@ function reportTools(deps) {
3243
3318
  }
3244
3319
 
3245
3320
  // src/interactive/ReportInteractive.tsx
3246
- var import_jsx_runtime51 = require("react/jsx-runtime");
3321
+ var import_jsx_runtime52 = require("react/jsx-runtime");
3247
3322
  function ReportInteractive(props) {
3248
3323
  const { report, className, title, dataTheme } = props;
3249
3324
  const result = unwrapReport(report);
3250
3325
  if (!result.ok) {
3251
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3326
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3252
3327
  ReportErrorShell,
3253
3328
  {
3254
3329
  error: result.error,
@@ -3258,18 +3333,18 @@ function ReportInteractive(props) {
3258
3333
  }
3259
3334
  );
3260
3335
  }
3261
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportInteractiveView, { ...props, report: result.data });
3336
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportInteractiveView, { ...props, report: result.data });
3262
3337
  }
3263
3338
  var THEME_OPTIONS = [
3264
- { value: "light", label: "Light", Icon: import_lucide_react6.Sun },
3265
- { value: "system", label: "System", Icon: import_lucide_react6.Monitor },
3266
- { value: "dark", label: "Dark", Icon: import_lucide_react6.Moon }
3339
+ { value: "light", label: "Light", Icon: import_lucide_react7.Sun },
3340
+ { value: "system", label: "System", Icon: import_lucide_react7.Monitor },
3341
+ { value: "dark", label: "Dark", Icon: import_lucide_react7.Moon }
3267
3342
  ];
3268
3343
  function ThemeSegment({
3269
3344
  pref,
3270
3345
  onPref
3271
3346
  }) {
3272
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3347
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3273
3348
  ToggleGroup,
3274
3349
  {
3275
3350
  size: "sm",
@@ -3279,14 +3354,14 @@ function ThemeSegment({
3279
3354
  if (next) onPref(next);
3280
3355
  },
3281
3356
  "aria-label": "Color theme",
3282
- children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3357
+ children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3283
3358
  ToggleGroupItem,
3284
3359
  {
3285
3360
  value,
3286
3361
  "aria-label": label,
3287
3362
  title: label,
3288
3363
  className: "px-2",
3289
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Icon, {})
3364
+ children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon, {})
3290
3365
  },
3291
3366
  value
3292
3367
  ))
@@ -3303,30 +3378,32 @@ function ReportInteractiveView({
3303
3378
  hideHeader = false,
3304
3379
  hideToc = false,
3305
3380
  staleAfterDays = 7,
3306
- scenarioHistory
3381
+ scenarioHistory,
3382
+ share = false,
3383
+ shareCommand
3307
3384
  }) {
3308
3385
  const [urlState, setUrlState] = useUrlState();
3309
3386
  const { query, status: statusFilter, tags: activeTags, detail } = urlState;
3310
- const setQuery = (0, import_react23.useCallback)(
3387
+ const setQuery = (0, import_react24.useCallback)(
3311
3388
  (next) => setUrlState({ query: next }),
3312
3389
  [setUrlState]
3313
3390
  );
3314
- const setStatusFilter = (0, import_react23.useCallback)(
3391
+ const setStatusFilter = (0, import_react24.useCallback)(
3315
3392
  (next) => setUrlState({ status: next }),
3316
3393
  [setUrlState]
3317
3394
  );
3318
- const setDetail = (0, import_react23.useCallback)(
3395
+ const setDetail = (0, import_react24.useCallback)(
3319
3396
  (next) => setUrlState({ detail: next }),
3320
3397
  [setUrlState]
3321
3398
  );
3322
- const [helpOpen, setHelpOpen] = (0, import_react23.useState)(false);
3399
+ const [helpOpen, setHelpOpen] = (0, import_react24.useState)(false);
3323
3400
  const { pref: themePref, setPref: setThemePref } = useTheme();
3324
- const searchRef = (0, import_react23.useRef)(null);
3325
- const expandId = (0, import_react23.useId)();
3326
- const docsId = (0, import_react23.useId)();
3327
- const deferredQuery = (0, import_react23.useDeferredValue)(query);
3328
- const failures = (0, import_react23.useMemo)(() => listFailures(report), [report]);
3329
- const filtered = (0, import_react23.useMemo)(
3401
+ const searchRef = (0, import_react24.useRef)(null);
3402
+ const expandId = (0, import_react24.useId)();
3403
+ const docsId = (0, import_react24.useId)();
3404
+ const deferredQuery = (0, import_react24.useDeferredValue)(query);
3405
+ const failures = (0, import_react24.useMemo)(() => listFailures(report), [report]);
3406
+ const filtered = (0, import_react24.useMemo)(
3330
3407
  // Features carrying failures float to the top so the first thing on screen
3331
3408
  // is the thing that needs attention; an all-green run keeps source order.
3332
3409
  () => failuresFirst(
@@ -3339,7 +3416,7 @@ function ReportInteractiveView({
3339
3416
  [report, deferredQuery, statusFilter, activeTags]
3340
3417
  );
3341
3418
  const isFiltering = query !== deferredQuery;
3342
- const statusOptions = (0, import_react23.useMemo)(() => {
3419
+ const statusOptions = (0, import_react24.useMemo)(() => {
3343
3420
  const s = report.summary;
3344
3421
  const opts = [
3345
3422
  { key: "all", label: "All", count: s.total }
@@ -3354,21 +3431,21 @@ function ReportInteractiveView({
3354
3431
  opts.push({ key: "pending", label: "Pending", count: s.pending });
3355
3432
  return opts;
3356
3433
  }, [report]);
3357
- const tagOptions = (0, import_react23.useMemo)(() => allTags(report), [report]);
3358
- const toggleTag = (0, import_react23.useCallback)(
3434
+ const tagOptions = (0, import_react24.useMemo)(() => allTags(report), [report]);
3435
+ const toggleTag = (0, import_react24.useCallback)(
3359
3436
  (tag) => setUrlState({
3360
3437
  tags: activeTags.includes(tag) ? activeTags.filter((t) => t !== tag) : [...activeTags, tag]
3361
3438
  }),
3362
3439
  [activeTags, setUrlState]
3363
3440
  );
3364
- const [toast, setToast] = (0, import_react23.useState)(null);
3365
- const toastTimer = (0, import_react23.useRef)(null);
3366
- const showToast = (0, import_react23.useCallback)((msg) => {
3441
+ const [toast, setToast] = (0, import_react24.useState)(null);
3442
+ const toastTimer = (0, import_react24.useRef)(null);
3443
+ const showToast = (0, import_react24.useCallback)((msg) => {
3367
3444
  setToast(msg);
3368
3445
  if (toastTimer.current) clearTimeout(toastTimer.current);
3369
3446
  toastTimer.current = setTimeout(() => setToast(null), 1800);
3370
3447
  }, []);
3371
- const copy = (0, import_react23.useCallback)(
3448
+ const copy = (0, import_react24.useCallback)(
3372
3449
  (text, msg) => {
3373
3450
  if (typeof navigator !== "undefined" && navigator.clipboard) {
3374
3451
  navigator.clipboard.writeText(text).then(
@@ -3379,7 +3456,7 @@ function ReportInteractiveView({
3379
3456
  },
3380
3457
  [showToast]
3381
3458
  );
3382
- const scenarioActions = (0, import_react23.useMemo)(
3459
+ const scenarioActions = (0, import_react24.useMemo)(
3383
3460
  () => ({
3384
3461
  copyLink: (s) => copy(scenarioPermalink(s), "Link copied"),
3385
3462
  copyMarkdown: (s) => copy(scenarioToMarkdown(s), "Markdown copied"),
@@ -3387,31 +3464,31 @@ function ReportInteractiveView({
3387
3464
  }),
3388
3465
  [copy]
3389
3466
  );
3390
- const copyAllFailures = (0, import_react23.useCallback)(
3467
+ const copyAllFailures = (0, import_react24.useCallback)(
3391
3468
  () => copy(failuresToPrompt(failedScenarios(filtered)), "Failures copied"),
3392
3469
  [copy, filtered]
3393
3470
  );
3394
- const failureIndexRef = (0, import_react23.useRef)(0);
3395
- const allCollapsibleIds = (0, import_react23.useMemo)(
3471
+ const failureIndexRef = (0, import_react24.useRef)(0);
3472
+ const allCollapsibleIds = (0, import_react24.useMemo)(
3396
3473
  () => report.features.flatMap((f) => [f.id, ...f.scenarios.map((s) => s.id)]),
3397
3474
  [report]
3398
3475
  );
3399
3476
  const collapse = useCollapseState(
3400
- (0, import_react23.useCallback)(() => defaultCollapsedIds(report), [report])
3477
+ (0, import_react24.useCallback)(() => defaultCollapsedIds(report), [report])
3401
3478
  );
3402
3479
  const revealFilteredResults = deferredQuery.trim() !== "" || statusFilter !== "all" || activeTags.length > 0;
3403
- const visibleCollapse = (0, import_react23.useMemo)(
3480
+ const visibleCollapse = (0, import_react24.useMemo)(
3404
3481
  () => revealFilteredResults ? { ...collapse.api, isCollapsed: () => false } : collapse.api,
3405
3482
  [collapse.api, revealFilteredResults]
3406
3483
  );
3407
- const collapseAll = (0, import_react23.useCallback)(
3484
+ const collapseAll = (0, import_react24.useCallback)(
3408
3485
  () => collapse.collapseAll(allCollapsibleIds),
3409
3486
  [collapse, allCollapsibleIds]
3410
3487
  );
3411
- const [expandedAll, setExpandedAll] = (0, import_react23.useState)(
3488
+ const [expandedAll, setExpandedAll] = (0, import_react24.useState)(
3412
3489
  () => report.summary.failed === 0
3413
3490
  );
3414
- const setExpanded = (0, import_react23.useCallback)(
3491
+ const setExpanded = (0, import_react24.useCallback)(
3415
3492
  (expanded) => {
3416
3493
  if (expanded) collapse.expandAll();
3417
3494
  else collapseAll();
@@ -3419,8 +3496,8 @@ function ReportInteractiveView({
3419
3496
  },
3420
3497
  [collapse, collapseAll]
3421
3498
  );
3422
- const [agentFilter, setAgentFilter] = (0, import_react23.useState)(null);
3423
- (0, import_react22.useTools)(
3499
+ const [agentFilter, setAgentFilter] = (0, import_react24.useState)(null);
3500
+ (0, import_react23.useTools)(
3424
3501
  reportTools({
3425
3502
  report,
3426
3503
  view: urlState,
@@ -3429,14 +3506,14 @@ function ReportInteractiveView({
3429
3506
  })
3430
3507
  );
3431
3508
  const showAgentFilter = agentFilter !== null && agentFilter.search === query && agentFilter.status === statusFilter && agentFilter.tags.length === activeTags.length && agentFilter.tags.every((tag) => activeTags.includes(tag));
3432
- const clearFilters = (0, import_react23.useCallback)(
3509
+ const clearFilters = (0, import_react24.useCallback)(
3433
3510
  () => setUrlState({ query: "", status: "all", tags: [] }),
3434
3511
  [setUrlState]
3435
3512
  );
3436
- const focusSearch = (0, import_react23.useCallback)(() => {
3513
+ const focusSearch = (0, import_react24.useCallback)(() => {
3437
3514
  searchRef.current?.focus();
3438
3515
  }, []);
3439
- const stepFailure = (0, import_react23.useCallback)(
3516
+ const stepFailure = (0, import_react24.useCallback)(
3440
3517
  (direction) => {
3441
3518
  if (failures.length === 0) return;
3442
3519
  failureIndexRef.current = (failureIndexRef.current + direction + failures.length) % failures.length;
@@ -3445,10 +3522,10 @@ function ReportInteractiveView({
3445
3522
  },
3446
3523
  [failures]
3447
3524
  );
3448
- const toggleHelp = (0, import_react23.useCallback)(() => {
3525
+ const toggleHelp = (0, import_react24.useCallback)(() => {
3449
3526
  setHelpOpen((v) => !v);
3450
3527
  }, []);
3451
- const escape = (0, import_react23.useCallback)(() => {
3528
+ const escape = (0, import_react24.useCallback)(() => {
3452
3529
  if (helpOpen) setHelpOpen(false);
3453
3530
  else if (query !== "") setQuery("");
3454
3531
  }, [helpOpen, query, setQuery]);
@@ -3466,13 +3543,13 @@ function ReportInteractiveView({
3466
3543
  const totalScenarios = report.summary.total;
3467
3544
  const matchedScenarios = filtered.summary.total;
3468
3545
  const showToc = !hideToc && totalScenarios > 3;
3469
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(CollapseProvider, { value: visibleCollapse, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ScenarioFreshnessProvider, { value: { staleAfterDays, report }, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3546
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(CollapseProvider, { value: visibleCollapse, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ScenarioFreshnessProvider, { value: { staleAfterDays, report }, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3470
3547
  ReportRoot,
3471
3548
  {
3472
3549
  report: filtered,
3473
3550
  customRenderers,
3474
3551
  renderers,
3475
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
3552
+ children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
3476
3553
  "main",
3477
3554
  {
3478
3555
  className: cn("es-report", "es-report-interactive", className),
@@ -3481,8 +3558,8 @@ function ReportInteractiveView({
3481
3558
  "data-theme": dataTheme,
3482
3559
  "data-detail-level": detail,
3483
3560
  children: [
3484
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("header", { className: "es-report-header", children: [
3485
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
3561
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("header", { className: "es-report-header", children: [
3562
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
3486
3563
  "div",
3487
3564
  {
3488
3565
  "data-es-navbar": true,
@@ -3491,9 +3568,9 @@ function ReportInteractiveView({
3491
3568
  hideHeader ? "justify-end" : "justify-between"
3492
3569
  ),
3493
3570
  children: [
3494
- hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("h1", { className: "min-w-0", children: title ?? "Story Report" }),
3495
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
3496
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3571
+ hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("h1", { className: "min-w-0", children: title ?? "Story Report" }),
3572
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex items-center gap-2", children: [
3573
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3497
3574
  ReportSearch,
3498
3575
  {
3499
3576
  ref: searchRef,
@@ -3503,16 +3580,17 @@ function ReportInteractiveView({
3503
3580
  totalCount: totalScenarios
3504
3581
  }
3505
3582
  ),
3506
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemeSegment, { pref: themePref, onPref: setThemePref })
3583
+ share ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportShare, { command: shareCommand, onCopy: copy }) : null,
3584
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemeSegment, { pref: themePref, onPref: setThemePref })
3507
3585
  ] })
3508
3586
  ]
3509
3587
  }
3510
3588
  ),
3511
- hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
3512
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportSummary, {}),
3513
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportMeta, {})
3589
+ hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
3590
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportSummary, {}),
3591
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportMeta, {})
3514
3592
  ] }),
3515
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3593
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3516
3594
  ReportFreshness,
3517
3595
  {
3518
3596
  lastRunMs: reportLastRunMs(report),
@@ -3520,15 +3598,15 @@ function ReportInteractiveView({
3520
3598
  staleAfterDays
3521
3599
  }
3522
3600
  ),
3523
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3601
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3524
3602
  ReportLastRunDelta,
3525
3603
  {
3526
3604
  history: scenarioHistory,
3527
3605
  report
3528
3606
  }
3529
3607
  ),
3530
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportSinceLastVisit, { report }),
3531
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3608
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportSinceLastVisit, { report }),
3609
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3532
3610
  ReportFilters,
3533
3611
  {
3534
3612
  statuses: statusOptions,
@@ -3539,10 +3617,10 @@ function ReportInteractiveView({
3539
3617
  onToggleTag: toggleTag
3540
3618
  }
3541
3619
  ),
3542
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
3543
- showToc ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportTocDrawer, {}) : null,
3544
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
3545
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3620
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
3621
+ showToc ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportTocDrawer, {}) : null,
3622
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex items-center gap-2", children: [
3623
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3546
3624
  Switch,
3547
3625
  {
3548
3626
  id: expandId,
@@ -3550,7 +3628,7 @@ function ReportInteractiveView({
3550
3628
  onCheckedChange: setExpanded
3551
3629
  }
3552
3630
  ),
3553
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3631
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3554
3632
  "label",
3555
3633
  {
3556
3634
  htmlFor: expandId,
@@ -3559,8 +3637,8 @@ function ReportInteractiveView({
3559
3637
  }
3560
3638
  )
3561
3639
  ] }),
3562
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
3563
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3640
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex items-center gap-2", children: [
3641
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3564
3642
  Switch,
3565
3643
  {
3566
3644
  id: docsId,
@@ -3568,7 +3646,7 @@ function ReportInteractiveView({
3568
3646
  onCheckedChange: (checked) => setDetail(checked ? "full" : "minimal")
3569
3647
  }
3570
3648
  ),
3571
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3649
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3572
3650
  "label",
3573
3651
  {
3574
3652
  htmlFor: docsId,
@@ -3579,7 +3657,7 @@ function ReportInteractiveView({
3579
3657
  ] })
3580
3658
  ] })
3581
3659
  ] }),
3582
- showAgentFilter ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3660
+ showAgentFilter ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3583
3661
  ReportAgentFilterNotice,
3584
3662
  {
3585
3663
  applied: agentFilter,
@@ -3587,17 +3665,17 @@ function ReportInteractiveView({
3587
3665
  onDismiss: () => setAgentFilter(null)
3588
3666
  }
3589
3667
  ) : null,
3590
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportFailureBanner, { failures, onCopyAll: copyAllFailures }),
3591
- hasContent ? showToc ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex gap-6", children: [
3592
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportToc, {}),
3593
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportFeatureList, {}) })
3594
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReportFeatureList, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3668
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportFailureBanner, { failures, onCopyAll: copyAllFailures }),
3669
+ hasContent ? showToc ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex gap-6", children: [
3670
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportToc, {}),
3671
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportFeatureList, {}) })
3672
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ReportFeatureList, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3595
3673
  ReportEmpty,
3596
3674
  {
3597
3675
  message: query ? "No scenarios match the search." : void 0
3598
3676
  }
3599
3677
  ),
3600
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3678
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3601
3679
  "button",
3602
3680
  {
3603
3681
  type: "button",
@@ -3608,14 +3686,14 @@ function ReportInteractiveView({
3608
3686
  children: "?"
3609
3687
  }
3610
3688
  ),
3611
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3689
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3612
3690
  ReportShortcutsHelp,
3613
3691
  {
3614
3692
  open: helpOpen,
3615
3693
  onClose: () => setHelpOpen(false)
3616
3694
  }
3617
3695
  ),
3618
- toast ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3696
+ toast ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3619
3697
  "div",
3620
3698
  {
3621
3699
  role: "status",
@@ -3632,14 +3710,14 @@ function ReportInteractiveView({
3632
3710
  }
3633
3711
 
3634
3712
  // src/interactive/ReportInteractiveIsland.tsx
3635
- var import_react26 = require("react");
3713
+ var import_react27 = require("react");
3636
3714
 
3637
3715
  // src/interactive/island-renderers.tsx
3638
- var import_react25 = require("react");
3716
+ var import_react26 = require("react");
3639
3717
 
3640
3718
  // src/components/doc/MermaidView.tsx
3641
- var import_react24 = require("react");
3642
- var import_jsx_runtime52 = require("react/jsx-runtime");
3719
+ var import_react25 = require("react");
3720
+ var import_jsx_runtime53 = require("react/jsx-runtime");
3643
3721
  function prefersDark(el) {
3644
3722
  const themed = el?.closest("[data-theme]");
3645
3723
  if (themed?.dataset.theme === "dark") return true;
@@ -3647,10 +3725,10 @@ function prefersDark(el) {
3647
3725
  return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
3648
3726
  }
3649
3727
  function MermaidView({ entry, load }) {
3650
- const ref = (0, import_react24.useRef)(null);
3651
- const [svg, setSvg] = (0, import_react24.useState)(null);
3652
- const [error, setError] = (0, import_react24.useState)(null);
3653
- (0, import_react24.useEffect)(() => {
3728
+ const ref = (0, import_react25.useRef)(null);
3729
+ const [svg, setSvg] = (0, import_react25.useState)(null);
3730
+ const [error, setError] = (0, import_react25.useState)(null);
3731
+ (0, import_react25.useEffect)(() => {
3654
3732
  let cancelled = false;
3655
3733
  const draw = async () => {
3656
3734
  let mermaid;
@@ -3693,9 +3771,9 @@ function MermaidView({ entry, load }) {
3693
3771
  };
3694
3772
  }, [entry.code, load]);
3695
3773
  if (svg) {
3696
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("figure", { ref, className: "my-3", children: [
3697
- entry.title ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
3698
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3774
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("figure", { ref, className: "my-3", children: [
3775
+ entry.title ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
3776
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
3699
3777
  "div",
3700
3778
  {
3701
3779
  role: "img",
@@ -3706,8 +3784,8 @@ function MermaidView({ entry, load }) {
3706
3784
  )
3707
3785
  ] });
3708
3786
  }
3709
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
3710
- error ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
3787
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
3788
+ error ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
3711
3789
  "p",
3712
3790
  {
3713
3791
  role: "alert",
@@ -3719,12 +3797,12 @@ function MermaidView({ entry, load }) {
3719
3797
  ]
3720
3798
  }
3721
3799
  ) : null,
3722
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(MermaidSource, { entry, ref })
3800
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(MermaidSource, { entry, ref })
3723
3801
  ] });
3724
3802
  }
3725
3803
 
3726
3804
  // src/interactive/island-renderers.tsx
3727
- var import_jsx_runtime53 = require("react/jsx-runtime");
3805
+ var import_jsx_runtime54 = require("react/jsx-runtime");
3728
3806
  var HLJS_ESM = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/es/highlight.min.js";
3729
3807
  var MERMAID_ESM = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";
3730
3808
  function cachedCdnModule(url) {
@@ -3741,8 +3819,8 @@ function cachedCdnModule(url) {
3741
3819
  var loadMermaidFromCdn = cachedCdnModule(MERMAID_ESM);
3742
3820
  var loadHljs = cachedCdnModule(HLJS_ESM);
3743
3821
  function CdnHighlightedCode({ entry }) {
3744
- const [html, setHtml] = (0, import_react25.useState)(null);
3745
- (0, import_react25.useEffect)(() => {
3822
+ const [html, setHtml] = (0, import_react26.useState)(null);
3823
+ (0, import_react26.useEffect)(() => {
3746
3824
  let cancelled = false;
3747
3825
  void (async () => {
3748
3826
  try {
@@ -3758,27 +3836,27 @@ function CdnHighlightedCode({ entry }) {
3758
3836
  cancelled = true;
3759
3837
  };
3760
3838
  }, [entry.content, entry.lang]);
3761
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
3839
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
3762
3840
  "code",
3763
3841
  {
3764
3842
  className: cn("hljs font-mono text-xs", entry.lang && `language-${entry.lang}`),
3765
3843
  dangerouslySetInnerHTML: { __html: html }
3766
3844
  }
3767
- ) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
3845
+ ) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
3768
3846
  }
3769
3847
  function buildIslandRenderers(opts) {
3770
3848
  const renderers = {};
3771
3849
  if (opts.mermaid) {
3772
- renderers.mermaid = (entry) => (0, import_react25.createElement)(MermaidView, { entry, load: loadMermaidFromCdn });
3850
+ renderers.mermaid = (entry) => (0, import_react26.createElement)(MermaidView, { entry, load: loadMermaidFromCdn });
3773
3851
  }
3774
3852
  if (opts.syntaxHighlighting) {
3775
- renderers.code = (entry) => (0, import_react25.createElement)(CdnHighlightedCode, { entry });
3853
+ renderers.code = (entry) => (0, import_react26.createElement)(CdnHighlightedCode, { entry });
3776
3854
  }
3777
3855
  return renderers;
3778
3856
  }
3779
3857
 
3780
3858
  // src/interactive/ReportInteractiveIsland.tsx
3781
- var import_jsx_runtime54 = require("react/jsx-runtime");
3859
+ var import_jsx_runtime55 = require("react/jsx-runtime");
3782
3860
  function ReportInteractiveIsland({
3783
3861
  report,
3784
3862
  title,
@@ -3788,11 +3866,11 @@ function ReportInteractiveIsland({
3788
3866
  syntaxHighlighting = true,
3789
3867
  mermaid = true
3790
3868
  }) {
3791
- const renderers = (0, import_react26.useMemo)(
3869
+ const renderers = (0, import_react27.useMemo)(
3792
3870
  () => buildIslandRenderers({ syntaxHighlighting, mermaid }),
3793
3871
  [syntaxHighlighting, mermaid]
3794
3872
  );
3795
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
3873
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3796
3874
  ReportInteractive,
3797
3875
  {
3798
3876
  report,