executable-stories-react 0.15.0 → 0.17.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.
package/dist/index.d.cts CHANGED
@@ -63,6 +63,12 @@ interface ReportProps {
63
63
  title?: string;
64
64
  /** Optional theme attribute scope. Use to force "light" or "dark". */
65
65
  dataTheme?: "light" | "dark";
66
+ /**
67
+ * Draw the "Architecture, as it ran" section above the features. Off by
68
+ * default — only an instrumented run has anything to draw, and the span
69
+ * picture is a specialist view. `--html-architecture` turns it on.
70
+ */
71
+ architecture?: boolean;
66
72
  }
67
73
  declare function Report(props: ReportProps): react.JSX.Element;
68
74
 
package/dist/index.d.ts CHANGED
@@ -63,6 +63,12 @@ interface ReportProps {
63
63
  title?: string;
64
64
  /** Optional theme attribute scope. Use to force "light" or "dark". */
65
65
  dataTheme?: "light" | "dark";
66
+ /**
67
+ * Draw the "Architecture, as it ran" section above the features. Off by
68
+ * default — only an instrumented run has anything to draw, and the span
69
+ * picture is a specialist view. `--html-architecture` turns it on.
70
+ */
71
+ architecture?: boolean;
66
72
  }
67
73
  declare function Report(props: ReportProps): react.JSX.Element;
68
74
 
package/dist/index.js CHANGED
@@ -522,12 +522,29 @@ function DocVideo({ entry }) {
522
522
  }
523
523
 
524
524
  // src/components/doc/DocHtml.tsx
525
+ import { useEffect, useRef, useState } from "react";
525
526
  import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
527
+ var MEASURE_SCRIPT = "<script>(function(){if(parent===window)return;var last=0,queued=false;var measure=function(){var kids=document.body.children,h=0;for(var i=0;i<kids.length;i++)h=Math.max(h,kids[i].getBoundingClientRect().bottom);return Math.ceil(h||document.body.getBoundingClientRect().bottom)};var post=function(){queued=false;var h=measure();if(h===last)return;last=h;parent.postMessage({__esHtmlHeight:h},'*')};var schedule=function(){if(queued)return;queued=true;requestAnimationFrame(post)};var start=function(){new ResizeObserver(schedule).observe(document.body);new MutationObserver(schedule).observe(document.body,{subtree:true,childList:true,attributes:true,characterData:true});addEventListener('load',schedule);post()};if(document.body)start();else addEventListener('DOMContentLoaded',start)})();</script>";
528
+ var MAX_MEASURED_HEIGHT = 5e3;
526
529
  function DocHtml({ entry }) {
527
- const height = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
530
+ const declaredHeight = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
528
531
  const title = entry.title ?? "Embedded HTML";
529
532
  const safeHref = safeUrl(entry.url ?? entry.path);
530
- const frameProps = entry.content !== void 0 ? { srcDoc: entry.content } : { src: safeHref ?? "" };
533
+ const frameRef = useRef(null);
534
+ const [measuredHeight, setMeasuredHeight] = useState();
535
+ useEffect(() => {
536
+ if (entry.content === void 0) return;
537
+ const onMessage = (event) => {
538
+ if (event.source !== frameRef.current?.contentWindow) return;
539
+ const reported = event.data?.__esHtmlHeight;
540
+ if (typeof reported !== "number" || !Number.isFinite(reported) || reported <= 0) return;
541
+ setMeasuredHeight(Math.min(reported, MAX_MEASURED_HEIGHT));
542
+ };
543
+ window.addEventListener("message", onMessage);
544
+ return () => window.removeEventListener("message", onMessage);
545
+ }, [entry.content]);
546
+ const height = measuredHeight === void 0 ? declaredHeight : `${measuredHeight}px`;
547
+ const frameProps = entry.content !== void 0 ? { srcDoc: entry.content + MEASURE_SCRIPT } : { src: safeHref ?? "" };
531
548
  return /* @__PURE__ */ jsxs9("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
532
549
  /* @__PURE__ */ jsxs9("figcaption", { className: "flex items-center justify-between border-b border-border bg-muted/40 px-3 py-1.5 text-xs font-medium text-muted-foreground", children: [
533
550
  /* @__PURE__ */ jsx14("span", { children: entry.title ?? "HTML" }),
@@ -547,6 +564,7 @@ function DocHtml({ entry }) {
547
564
  /* @__PURE__ */ jsx14(
548
565
  "iframe",
549
566
  {
567
+ ref: frameRef,
550
568
  ...frameProps,
551
569
  sandbox: "allow-scripts",
552
570
  loading: "lazy",
@@ -1095,7 +1113,7 @@ function ScenarioRunHistory({ scenarioId }) {
1095
1113
  }
1096
1114
 
1097
1115
  // src/components/ScenarioStaleness.tsx
1098
- import { useEffect, useState } from "react";
1116
+ import { useEffect as useEffect2, useState as useState2 } from "react";
1099
1117
 
1100
1118
  // src/lib/provenance.ts
1101
1119
  function reportLastRunMs(report) {
@@ -1163,8 +1181,8 @@ import { jsxs as jsxs16 } from "react/jsx-runtime";
1163
1181
  function ScenarioStaleness({ scenario }) {
1164
1182
  const freshness = useScenarioFreshness();
1165
1183
  const fixedNow = freshness?.nowMs;
1166
- const [now, setNow] = useState(fixedNow);
1167
- useEffect(() => {
1184
+ const [now, setNow] = useState2(fixedNow);
1185
+ useEffect2(() => {
1168
1186
  if (fixedNow === void 0) setNow(Date.now());
1169
1187
  }, [fixedNow]);
1170
1188
  if (!freshness || now === void 0) return null;
@@ -1178,7 +1196,7 @@ function ScenarioStaleness({ scenario }) {
1178
1196
  }
1179
1197
 
1180
1198
  // src/interactive/collapse-context.ts
1181
- import { createContext as createContext4, useCallback, useContext as useContext5, useState as useState2 } from "react";
1199
+ import { createContext as createContext4, useCallback, useContext as useContext5, useState as useState3 } from "react";
1182
1200
  var CollapseContext = createContext4(null);
1183
1201
  var CollapseProvider = CollapseContext.Provider;
1184
1202
  function useCollapse() {
@@ -1752,25 +1770,86 @@ function ReportErrorShell({
1752
1770
  return /* @__PURE__ */ jsx36("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx36(ReportSchemaError, { error }) });
1753
1771
  }
1754
1772
 
1755
- // src/components/Report.tsx
1773
+ // src/components/ReportSpanGraph.tsx
1774
+ import { deriveSpanGraph, spanGraphNodeMark, spanGraphToMermaid } from "executable-stories-core/span-graph";
1775
+ import { useMemo as useMemo2 } from "react";
1756
1776
  import { jsx as jsx37, jsxs as jsxs25 } from "react/jsx-runtime";
1777
+ var LANE_LABEL = {
1778
+ edge: "Edge",
1779
+ service: "Service",
1780
+ queue: "Queue",
1781
+ datastore: "Data"
1782
+ };
1783
+ var MARK_LABEL = {
1784
+ failing: "Failing",
1785
+ added: "New",
1786
+ changed: "Changed"
1787
+ };
1788
+ var MARK_CLASS = {
1789
+ failing: "text-fail",
1790
+ added: "text-pass",
1791
+ changed: "text-pend"
1792
+ };
1793
+ function MarkBadge({ node }) {
1794
+ const mark = spanGraphNodeMark(node);
1795
+ if (!mark) return null;
1796
+ return /* @__PURE__ */ jsx37("span", { className: cn("ml-2 text-xs font-medium", MARK_CLASS[mark]), children: MARK_LABEL[mark] });
1797
+ }
1798
+ function ReportSpanGraph() {
1799
+ const report = useReport();
1800
+ const { code, graph, titleById } = useMemo2(() => {
1801
+ const scenarios = report.features.flatMap((feature) => feature.scenarios);
1802
+ const derived = deriveSpanGraph(scenarios);
1803
+ return {
1804
+ graph: derived,
1805
+ code: spanGraphToMermaid(derived),
1806
+ titleById: new Map(scenarios.map((scenario) => [scenario.id, scenario.title]))
1807
+ };
1808
+ }, [report]);
1809
+ if (code === "") return null;
1810
+ return /* @__PURE__ */ jsxs25("section", { className: "es-span-graph mt-6", "aria-labelledby": "es-span-graph-heading", children: [
1811
+ /* @__PURE__ */ jsx37("h2", { id: "es-span-graph-heading", className: "text-base font-semibold text-foreground", children: "Architecture, as it ran" }),
1812
+ /* @__PURE__ */ jsx37("p", { className: "mt-1 text-sm text-muted-foreground", children: "Derived from this run\u2019s traces. Every component was named by a span while a scenario ran, so nothing here is inferred from the code. Instrumented, exercised paths only: a component no scenario reaches does not appear." }),
1813
+ /* @__PURE__ */ jsx37(DocMermaid, { entry: { kind: "mermaid", phase: "static", code } }),
1814
+ /* @__PURE__ */ jsxs25("table", { className: "mt-2 w-full border-collapse text-left text-sm", children: [
1815
+ /* @__PURE__ */ jsx37("caption", { className: "sr-only", children: "Each component and the scenarios that exercised it" }),
1816
+ /* @__PURE__ */ jsx37("thead", { children: /* @__PURE__ */ jsxs25("tr", { className: "text-xs text-muted-foreground", children: [
1817
+ /* @__PURE__ */ jsx37("th", { scope: "col", className: "py-1 pr-4 font-medium", children: "Component" }),
1818
+ /* @__PURE__ */ jsx37("th", { scope: "col", className: "py-1 pr-4 font-medium", children: "Lane" }),
1819
+ /* @__PURE__ */ jsx37("th", { scope: "col", className: "py-1 font-medium", children: "Covered by" })
1820
+ ] }) }),
1821
+ /* @__PURE__ */ jsx37("tbody", { children: graph.nodes.map((node) => /* @__PURE__ */ jsxs25("tr", { className: "border-t border-border align-top", children: [
1822
+ /* @__PURE__ */ jsxs25("th", { scope: "row", className: "py-1.5 pr-4 font-mono text-xs font-normal", children: [
1823
+ node.id,
1824
+ /* @__PURE__ */ jsx37(MarkBadge, { node })
1825
+ ] }),
1826
+ /* @__PURE__ */ jsx37("td", { className: "py-1.5 pr-4 text-xs text-muted-foreground", children: LANE_LABEL[node.kind] }),
1827
+ /* @__PURE__ */ jsx37("td", { className: "py-1.5", children: /* @__PURE__ */ jsx37("ul", { className: "flex flex-col gap-0.5", children: node.scenarioIds.map((id) => /* @__PURE__ */ jsx37("li", { children: /* @__PURE__ */ jsx37("a", { href: `#${id}`, className: "text-xs text-link underline underline-offset-2 hover:text-foreground", children: titleById.get(id) ?? id }) }, id)) }) })
1828
+ ] }, node.id)) })
1829
+ ] })
1830
+ ] });
1831
+ }
1832
+
1833
+ // src/components/Report.tsx
1834
+ import { jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
1757
1835
  function Report(props) {
1758
- const { report, customRenderers, renderers, className, title, dataTheme } = props;
1836
+ const { report, customRenderers, renderers, className, title, dataTheme, architecture = false } = props;
1759
1837
  const result = unwrapReport(report);
1760
1838
  if (!result.ok) {
1761
- return /* @__PURE__ */ jsx37(ReportErrorShell, { error: result.error, className, title, dataTheme });
1839
+ return /* @__PURE__ */ jsx38(ReportErrorShell, { error: result.error, className, title, dataTheme });
1762
1840
  }
1763
1841
  const data = result.data;
1764
1842
  const hasContent = data.features.length > 0;
1765
- return /* @__PURE__ */ jsx37(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs25("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
1766
- /* @__PURE__ */ jsx37("header", { className: "es-report-header", children: /* @__PURE__ */ jsx37(ReportTitleBlock, { title }) }),
1767
- hasContent ? /* @__PURE__ */ jsx37(ReportFeatureList, {}) : /* @__PURE__ */ jsx37(ReportEmpty, {})
1843
+ return /* @__PURE__ */ jsx38(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs26("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
1844
+ /* @__PURE__ */ jsx38("header", { className: "es-report-header", children: /* @__PURE__ */ jsx38(ReportTitleBlock, { title }) }),
1845
+ architecture ? /* @__PURE__ */ jsx38(ReportSpanGraph, {}) : null,
1846
+ hasContent ? /* @__PURE__ */ jsx38(ReportFeatureList, {}) : /* @__PURE__ */ jsx38(ReportEmpty, {})
1768
1847
  ] }) });
1769
1848
  }
1770
1849
 
1771
1850
  // src/components/doc/MermaidView.tsx
1772
- import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
1773
- import { Fragment as Fragment11, jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
1851
+ import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
1852
+ import { Fragment as Fragment11, jsx as jsx39, jsxs as jsxs27 } from "react/jsx-runtime";
1774
1853
  function prefersDark(el) {
1775
1854
  const themed = el?.closest("[data-theme]");
1776
1855
  if (themed?.dataset.theme === "dark") return true;
@@ -1778,10 +1857,10 @@ function prefersDark(el) {
1778
1857
  return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
1779
1858
  }
1780
1859
  function MermaidView({ entry, load }) {
1781
- const ref = useRef(null);
1782
- const [svg, setSvg] = useState3(null);
1783
- const [error, setError] = useState3(null);
1784
- useEffect2(() => {
1860
+ const ref = useRef2(null);
1861
+ const [svg, setSvg] = useState4(null);
1862
+ const [error, setError] = useState4(null);
1863
+ useEffect3(() => {
1785
1864
  let cancelled = false;
1786
1865
  const draw = async () => {
1787
1866
  let mermaid;
@@ -1798,7 +1877,10 @@ function MermaidView({ entry, load }) {
1798
1877
  mermaid.initialize({
1799
1878
  startOnLoad: false,
1800
1879
  securityLevel: "strict",
1801
- theme: prefersDark(ref.current) ? "dark" : "default"
1880
+ // "neutral" in light: the same theme the static, no-JS render uses
1881
+ // in ssr-entry, so a diagram keeps its colours when the island takes
1882
+ // over.
1883
+ theme: prefersDark(ref.current) ? "dark" : "neutral"
1802
1884
  });
1803
1885
  await mermaid.parse(entry.code);
1804
1886
  const id = `es-mermaid-${Math.random().toString(36).slice(2)}`;
@@ -1824,9 +1906,9 @@ function MermaidView({ entry, load }) {
1824
1906
  };
1825
1907
  }, [entry.code, load]);
1826
1908
  if (svg) {
1827
- return /* @__PURE__ */ jsxs26("figure", { ref, className: "my-3", children: [
1828
- entry.title ? /* @__PURE__ */ jsx38("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
1829
- /* @__PURE__ */ jsx38(
1909
+ return /* @__PURE__ */ jsxs27("figure", { ref, className: "my-3", children: [
1910
+ entry.title ? /* @__PURE__ */ jsx39("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
1911
+ /* @__PURE__ */ jsx39(
1830
1912
  "div",
1831
1913
  {
1832
1914
  role: "img",
@@ -1837,8 +1919,8 @@ function MermaidView({ entry, load }) {
1837
1919
  )
1838
1920
  ] });
1839
1921
  }
1840
- return /* @__PURE__ */ jsxs26(Fragment11, { children: [
1841
- error ? /* @__PURE__ */ jsxs26(
1922
+ return /* @__PURE__ */ jsxs27(Fragment11, { children: [
1923
+ error ? /* @__PURE__ */ jsxs27(
1842
1924
  "p",
1843
1925
  {
1844
1926
  role: "alert",
@@ -1850,34 +1932,34 @@ function MermaidView({ entry, load }) {
1850
1932
  ]
1851
1933
  }
1852
1934
  ) : null,
1853
- /* @__PURE__ */ jsx38(MermaidSource, { entry, ref })
1935
+ /* @__PURE__ */ jsx39(MermaidSource, { entry, ref })
1854
1936
  ] });
1855
1937
  }
1856
1938
 
1857
1939
  // src/components/doc/MermaidDiagram.tsx
1858
- import { jsx as jsx39 } from "react/jsx-runtime";
1940
+ import { jsx as jsx40 } from "react/jsx-runtime";
1859
1941
  var mermaidLoader;
1860
1942
  function loadMermaid() {
1861
1943
  mermaidLoader ??= import("mermaid").then((m) => m.default);
1862
1944
  return mermaidLoader;
1863
1945
  }
1864
1946
  function MermaidDiagram({ entry, load = loadMermaid }) {
1865
- return /* @__PURE__ */ jsx39(MermaidView, { entry, load });
1947
+ return /* @__PURE__ */ jsx40(MermaidView, { entry, load });
1866
1948
  }
1867
1949
 
1868
1950
  // src/components/ScenarioExplorer.tsx
1869
- import { useState as useState4 } from "react";
1951
+ import { useState as useState5 } from "react";
1870
1952
 
1871
1953
  // src/components/ui/command.tsx
1872
1954
  import "react";
1873
1955
  import { Command as CommandPrimitive } from "cmdk";
1874
1956
  import { SearchIcon } from "lucide-react";
1875
- import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
1957
+ import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
1876
1958
  function Command({
1877
1959
  className,
1878
1960
  ...props
1879
1961
  }) {
1880
- return /* @__PURE__ */ jsx40(
1962
+ return /* @__PURE__ */ jsx41(
1881
1963
  CommandPrimitive,
1882
1964
  {
1883
1965
  "data-slot": "command",
@@ -1893,14 +1975,14 @@ function CommandInput({
1893
1975
  className,
1894
1976
  ...props
1895
1977
  }) {
1896
- return /* @__PURE__ */ jsxs27(
1978
+ return /* @__PURE__ */ jsxs28(
1897
1979
  "div",
1898
1980
  {
1899
1981
  "data-slot": "command-input-wrapper",
1900
1982
  className: "flex h-9 items-center gap-2 border-b px-3",
1901
1983
  children: [
1902
- /* @__PURE__ */ jsx40(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
1903
- /* @__PURE__ */ jsx40(
1984
+ /* @__PURE__ */ jsx41(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
1985
+ /* @__PURE__ */ jsx41(
1904
1986
  CommandPrimitive.Input,
1905
1987
  {
1906
1988
  "data-slot": "command-input",
@@ -1919,7 +2001,7 @@ function CommandList({
1919
2001
  className,
1920
2002
  ...props
1921
2003
  }) {
1922
- return /* @__PURE__ */ jsx40(
2004
+ return /* @__PURE__ */ jsx41(
1923
2005
  CommandPrimitive.List,
1924
2006
  {
1925
2007
  "data-slot": "command-list",
@@ -1934,7 +2016,7 @@ function CommandList({
1934
2016
  function CommandEmpty({
1935
2017
  ...props
1936
2018
  }) {
1937
- return /* @__PURE__ */ jsx40(
2019
+ return /* @__PURE__ */ jsx41(
1938
2020
  CommandPrimitive.Empty,
1939
2021
  {
1940
2022
  "data-slot": "command-empty",
@@ -1947,7 +2029,7 @@ function CommandGroup({
1947
2029
  className,
1948
2030
  ...props
1949
2031
  }) {
1950
- return /* @__PURE__ */ jsx40(
2032
+ return /* @__PURE__ */ jsx41(
1951
2033
  CommandPrimitive.Group,
1952
2034
  {
1953
2035
  "data-slot": "command-group",
@@ -1963,7 +2045,7 @@ function CommandItem({
1963
2045
  className,
1964
2046
  ...props
1965
2047
  }) {
1966
- return /* @__PURE__ */ jsx40(
2048
+ return /* @__PURE__ */ jsx41(
1967
2049
  CommandPrimitive.Item,
1968
2050
  {
1969
2051
  "data-slot": "command-item",
@@ -1977,7 +2059,7 @@ function CommandItem({
1977
2059
  }
1978
2060
 
1979
2061
  // src/components/ScenarioExplorer.tsx
1980
- import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
2062
+ import { jsx as jsx42, jsxs as jsxs29 } from "react/jsx-runtime";
1981
2063
  var STATUS_FILTERS = [
1982
2064
  { value: "all", label: "All" },
1983
2065
  { value: "passed", label: "Passed" },
@@ -1986,24 +2068,24 @@ var STATUS_FILTERS = [
1986
2068
  { value: "pending", label: "Pending" }
1987
2069
  ];
1988
2070
  function ScenarioExplorer({ scenarios, summary }) {
1989
- const [status, setStatus] = useState4("all");
2071
+ const [status, setStatus] = useState5("all");
1990
2072
  const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
1991
- return /* @__PURE__ */ jsxs28("div", { className: "font-sans text-foreground", children: [
1992
- summary ? /* @__PURE__ */ jsxs28("p", { className: "mb-3 text-sm text-muted-foreground", children: [
2073
+ return /* @__PURE__ */ jsxs29("div", { className: "font-sans text-foreground", children: [
2074
+ summary ? /* @__PURE__ */ jsxs29("p", { className: "mb-3 text-sm text-muted-foreground", children: [
1993
2075
  summary.total,
1994
2076
  " scenarios \xB7 ",
1995
- /* @__PURE__ */ jsxs28("span", { className: "text-pass", children: [
2077
+ /* @__PURE__ */ jsxs29("span", { className: "text-pass", children: [
1996
2078
  summary.passed,
1997
2079
  " passed"
1998
2080
  ] }),
1999
2081
  " \xB7",
2000
2082
  " ",
2001
- /* @__PURE__ */ jsxs28("span", { className: "text-fail", children: [
2083
+ /* @__PURE__ */ jsxs29("span", { className: "text-fail", children: [
2002
2084
  summary.failed,
2003
2085
  " failed"
2004
2086
  ] })
2005
2087
  ] }) : null,
2006
- /* @__PURE__ */ jsx41("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ jsx41(
2088
+ /* @__PURE__ */ jsx42("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ jsx42(
2007
2089
  "button",
2008
2090
  {
2009
2091
  type: "button",
@@ -2018,26 +2100,26 @@ function ScenarioExplorer({ scenarios, summary }) {
2018
2100
  },
2019
2101
  f.value
2020
2102
  )) }),
2021
- /* @__PURE__ */ jsxs28(
2103
+ /* @__PURE__ */ jsxs29(
2022
2104
  Command,
2023
2105
  {
2024
2106
  className: "rounded-lg border border-border bg-card",
2025
2107
  filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
2026
2108
  children: [
2027
- /* @__PURE__ */ jsx41(CommandInput, { placeholder: "Search scenarios\u2026" }),
2028
- /* @__PURE__ */ jsxs28(CommandList, { className: "max-h-none", children: [
2029
- /* @__PURE__ */ jsx41(CommandEmpty, { children: "No scenarios match your filters." }),
2030
- /* @__PURE__ */ jsx41(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ jsx41(
2109
+ /* @__PURE__ */ jsx42(CommandInput, { placeholder: "Search scenarios\u2026" }),
2110
+ /* @__PURE__ */ jsxs29(CommandList, { className: "max-h-none", children: [
2111
+ /* @__PURE__ */ jsx42(CommandEmpty, { children: "No scenarios match your filters." }),
2112
+ /* @__PURE__ */ jsx42(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ jsx42(
2031
2113
  CommandItem,
2032
2114
  {
2033
2115
  value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
2034
2116
  asChild: true,
2035
2117
  className: "cursor-pointer",
2036
- children: /* @__PURE__ */ jsxs28("a", { href: s.href, className: "flex items-center gap-3", children: [
2037
- /* @__PURE__ */ jsx41(Badge, { variant: s.status, children: s.status }),
2038
- /* @__PURE__ */ jsx41("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
2039
- s.tags.slice(0, 3).map((t) => /* @__PURE__ */ jsx41(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
2040
- /* @__PURE__ */ jsx41("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
2118
+ children: /* @__PURE__ */ jsxs29("a", { href: s.href, className: "flex items-center gap-3", children: [
2119
+ /* @__PURE__ */ jsx42(Badge, { variant: s.status, children: s.status }),
2120
+ /* @__PURE__ */ jsx42("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
2121
+ s.tags.slice(0, 3).map((t) => /* @__PURE__ */ jsx42(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
2122
+ /* @__PURE__ */ jsx42("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
2041
2123
  ] })
2042
2124
  },
2043
2125
  s.id