executable-stories-react 0.9.0 → 0.10.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/ssr.js CHANGED
@@ -18,63 +18,6 @@ import { useMemo } from "react";
18
18
  import { createContext } from "react";
19
19
  var ReportContext = createContext(null);
20
20
 
21
- // src/context/ReportRoot.tsx
22
- import { jsx } from "react/jsx-runtime";
23
- var EMPTY_CUSTOM = {};
24
- var EMPTY_RENDERERS = {};
25
- function ReportRoot({
26
- report,
27
- customRenderers,
28
- renderers,
29
- children
30
- }) {
31
- const value = useMemo(
32
- () => ({
33
- report,
34
- customRenderers: customRenderers ?? EMPTY_CUSTOM,
35
- renderers: renderers ?? EMPTY_RENDERERS
36
- }),
37
- [report, customRenderers, renderers]
38
- );
39
- return /* @__PURE__ */ jsx(ReportContext.Provider, { value, children });
40
- }
41
-
42
- // src/hooks/useReport.ts
43
- import { useContext } from "react";
44
- function useReport() {
45
- const ctx = useContext(ReportContext);
46
- if (!ctx) {
47
- throw new Error(
48
- "useReport must be used inside <ReportRoot> or <Report>. Wrap your tree with one of those."
49
- );
50
- }
51
- return ctx.report;
52
- }
53
-
54
- // ../executable-stories-core/dist/utils/duration.js
55
- function formatDuration(ms) {
56
- if (ms < 1e3) {
57
- return `${Math.round(ms)} ms`;
58
- }
59
- if (ms < 6e4) {
60
- return `${(ms / 1e3).toFixed(2)} s`;
61
- }
62
- const minutes = Math.floor(ms / 6e4);
63
- const seconds = Math.floor(ms % 6e4 / 1e3);
64
- if (minutes < 60) {
65
- return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
66
- }
67
- const hours = Math.floor(minutes / 60);
68
- const remainingMinutes = minutes % 60;
69
- return `${hours}h ${remainingMinutes}m`;
70
- }
71
-
72
- // src/components/doc/DocNote.tsx
73
- import { jsx as jsx2 } from "react/jsx-runtime";
74
- function DocNote({ entry }) {
75
- return /* @__PURE__ */ jsx2("p", { className: "my-2 text-sm text-muted-foreground", children: entry.text });
76
- }
77
-
78
21
  // src/components/ui/badge.tsx
79
22
  import "react";
80
23
  import { cva } from "class-variance-authority";
@@ -133,14 +76,249 @@ function Badge({
133
76
  });
134
77
  }
135
78
 
136
- // src/components/doc/DocTag.tsx
79
+ // src/components/doc/NarrativeBlocks.tsx
80
+ import { jsx, jsxs } from "react/jsx-runtime";
81
+ var FILE_TREE_TYPE = "file-tree";
82
+ var DATA_MODEL_TYPE = "data-model";
83
+ function isChangeKind(value) {
84
+ return value === "added" || value === "modified" || value === "removed" || value === "renamed";
85
+ }
86
+ function isRecord(value) {
87
+ return typeof value === "object" && value !== null && !Array.isArray(value);
88
+ }
89
+ function str(value) {
90
+ return typeof value === "string" && value !== "" ? value : void 0;
91
+ }
92
+ function AuthoredMarker({ authored }) {
93
+ if (authored !== "agent") return null;
94
+ return /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "border-border text-[10px] text-muted-foreground", children: "AI-authored, not verified by a run" });
95
+ }
96
+ function BlockFrame({
97
+ title,
98
+ authored,
99
+ children
100
+ }) {
101
+ return /* @__PURE__ */ jsxs("figure", { className: "my-3", children: [
102
+ title || authored === "agent" ? /* @__PURE__ */ jsxs("figcaption", { className: "mb-1.5 flex flex-wrap items-center gap-2", children: [
103
+ title ? /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: title }) : null,
104
+ /* @__PURE__ */ jsx(AuthoredMarker, { authored })
105
+ ] }) : null,
106
+ children
107
+ ] });
108
+ }
109
+ function ChangeBadge({ change }) {
110
+ return /* @__PURE__ */ jsx(Badge, { variant: "tag", className: "text-[10px]", children: change });
111
+ }
112
+ function parseFileTree(data) {
113
+ if (!isRecord(data) || !Array.isArray(data.files)) return void 0;
114
+ const files = [];
115
+ for (const raw of data.files) {
116
+ if (typeof raw === "string") {
117
+ if (raw) files.push({ path: raw });
118
+ continue;
119
+ }
120
+ if (!isRecord(raw)) continue;
121
+ const path = str(raw.path);
122
+ if (!path) continue;
123
+ files.push({
124
+ path,
125
+ change: isChangeKind(raw.change) ? raw.change : void 0,
126
+ note: str(raw.note)
127
+ });
128
+ }
129
+ if (files.length === 0) return void 0;
130
+ return { title: str(data.title), authored: str(data.authored), files };
131
+ }
132
+ function buildTree(files) {
133
+ const root = { name: "", children: /* @__PURE__ */ new Map() };
134
+ for (const file of files) {
135
+ const segments = file.path.split("/").filter(Boolean);
136
+ let node = root;
137
+ segments.forEach((segment, index) => {
138
+ let child = node.children.get(segment);
139
+ if (!child) {
140
+ child = { name: segment, children: /* @__PURE__ */ new Map() };
141
+ node.children.set(segment, child);
142
+ }
143
+ if (index === segments.length - 1) child.file = file;
144
+ node = child;
145
+ });
146
+ }
147
+ return root;
148
+ }
149
+ function sortedChildren(node) {
150
+ return [...node.children.values()].sort((a, b) => {
151
+ const aDir = a.children.size > 0;
152
+ const bDir = b.children.size > 0;
153
+ if (aDir !== bDir) return aDir ? -1 : 1;
154
+ return a.name.localeCompare(b.name);
155
+ });
156
+ }
157
+ function TreeBranch({ node, depth }) {
158
+ const children = sortedChildren(node);
159
+ return /* @__PURE__ */ jsx("ul", { className: cn("space-y-0.5", depth > 0 && "ml-3 border-l border-border/60 pl-3"), children: children.map((child) => {
160
+ const isDir = child.children.size > 0;
161
+ return /* @__PURE__ */ jsxs("li", { children: [
162
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-2", children: [
163
+ /* @__PURE__ */ jsx(
164
+ "span",
165
+ {
166
+ className: cn(
167
+ "font-mono text-xs",
168
+ isDir ? "text-muted-foreground" : "text-foreground"
169
+ ),
170
+ children: isDir ? `${child.name}/` : child.name
171
+ }
172
+ ),
173
+ child.file?.change ? /* @__PURE__ */ jsx(ChangeBadge, { change: child.file.change }) : null,
174
+ child.file?.note ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: child.file.note }) : null
175
+ ] }),
176
+ isDir ? /* @__PURE__ */ jsx(TreeBranch, { node: child, depth: depth + 1 }) : null
177
+ ] }, child.name);
178
+ }) });
179
+ }
180
+ function FileTreeBlock({ entry }) {
181
+ const data = parseFileTree(entry.data);
182
+ if (!data) return /* @__PURE__ */ jsx(UnreadableBlock, { entry });
183
+ return /* @__PURE__ */ jsx(BlockFrame, { title: data.title ?? "Files changed", authored: data.authored, children: /* @__PURE__ */ jsx("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border bg-card p-3", children: /* @__PURE__ */ jsx(TreeBranch, { node: buildTree(data.files), depth: 0 }) }) });
184
+ }
185
+ function parseDataModel(data) {
186
+ if (!isRecord(data) || !Array.isArray(data.fields)) return void 0;
187
+ const fields = [];
188
+ for (const raw of data.fields) {
189
+ if (!isRecord(raw)) continue;
190
+ const name = str(raw.name);
191
+ if (!name) continue;
192
+ fields.push({
193
+ name,
194
+ type: str(raw.type),
195
+ note: str(raw.note),
196
+ change: isChangeKind(raw.change) ? raw.change : void 0
197
+ });
198
+ }
199
+ if (fields.length === 0) return void 0;
200
+ return {
201
+ title: str(data.title),
202
+ authored: str(data.authored),
203
+ name: str(data.name),
204
+ fields
205
+ };
206
+ }
207
+ function DataModelBlock({ entry }) {
208
+ const data = parseDataModel(entry.data);
209
+ if (!data) return /* @__PURE__ */ jsx(UnreadableBlock, { entry });
210
+ const hasNotes = data.fields.some((f) => f.note);
211
+ return /* @__PURE__ */ jsx(BlockFrame, { title: data.title ?? data.name ?? "Data model", authored: data.authored, children: /* @__PURE__ */ jsx("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-sm", children: [
212
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "bg-muted/50", children: [
213
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: "Field" }),
214
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: "Type" }),
215
+ hasNotes ? /* @__PURE__ */ jsx("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: "Note" }) : null
216
+ ] }) }),
217
+ /* @__PURE__ */ jsx("tbody", { children: data.fields.map((field) => /* @__PURE__ */ jsxs("tr", { children: [
218
+ /* @__PURE__ */ jsx("td", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-center gap-2", children: [
219
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-foreground", children: field.name }),
220
+ field.change ? /* @__PURE__ */ jsx(ChangeBadge, { change: field.change }) : null
221
+ ] }) }),
222
+ /* @__PURE__ */ jsx("td", { className: "border-b border-border px-3 py-2 font-mono text-xs text-muted-foreground", children: field.type ?? "" }),
223
+ hasNotes ? /* @__PURE__ */ jsx("td", { className: "border-b border-border px-3 py-2 text-foreground", children: field.note ?? "" }) : null
224
+ ] }, field.name)) })
225
+ ] }) }) });
226
+ }
227
+ function UnreadableBlock({ entry }) {
228
+ return /* @__PURE__ */ jsxs("div", { className: "my-2", "data-type": entry.type, children: [
229
+ /* @__PURE__ */ jsxs("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: [
230
+ entry.type,
231
+ " (unrecognised shape)"
232
+ ] }),
233
+ /* @__PURE__ */ jsx(
234
+ "pre",
235
+ {
236
+ tabIndex: 0,
237
+ className: "overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs text-foreground",
238
+ children: safeStringify(entry.data)
239
+ }
240
+ )
241
+ ] });
242
+ }
243
+ function safeStringify(value) {
244
+ try {
245
+ return JSON.stringify(value, null, 2);
246
+ } catch {
247
+ return String(value);
248
+ }
249
+ }
250
+ var narrativeBlockRenderers = {
251
+ [FILE_TREE_TYPE]: (entry) => /* @__PURE__ */ jsx(FileTreeBlock, { entry }),
252
+ [DATA_MODEL_TYPE]: (entry) => /* @__PURE__ */ jsx(DataModelBlock, { entry })
253
+ };
254
+
255
+ // src/context/ReportRoot.tsx
256
+ import { jsx as jsx2 } from "react/jsx-runtime";
257
+ var EMPTY_RENDERERS = {};
258
+ function ReportRoot({
259
+ report,
260
+ customRenderers,
261
+ renderers,
262
+ children
263
+ }) {
264
+ const value = useMemo(
265
+ () => ({
266
+ report,
267
+ // Narrative blocks render everywhere the report does (static SSR, the
268
+ // island, Astro) without every host wiring them up. A host renderer for
269
+ // the same type still wins.
270
+ customRenderers: { ...narrativeBlockRenderers, ...customRenderers },
271
+ renderers: renderers ?? EMPTY_RENDERERS
272
+ }),
273
+ [report, customRenderers, renderers]
274
+ );
275
+ return /* @__PURE__ */ jsx2(ReportContext.Provider, { value, children });
276
+ }
277
+
278
+ // src/hooks/useReport.ts
279
+ import { useContext } from "react";
280
+ function useReport() {
281
+ const ctx = useContext(ReportContext);
282
+ if (!ctx) {
283
+ throw new Error(
284
+ "useReport must be used inside <ReportRoot> or <Report>. Wrap your tree with one of those."
285
+ );
286
+ }
287
+ return ctx.report;
288
+ }
289
+
290
+ // ../executable-stories-core/dist/utils/duration.js
291
+ function formatDuration(ms) {
292
+ if (ms < 1e3) {
293
+ return `${Math.round(ms)} ms`;
294
+ }
295
+ if (ms < 6e4) {
296
+ return `${(ms / 1e3).toFixed(2)} s`;
297
+ }
298
+ const minutes = Math.floor(ms / 6e4);
299
+ const seconds = Math.floor(ms % 6e4 / 1e3);
300
+ if (minutes < 60) {
301
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
302
+ }
303
+ const hours = Math.floor(minutes / 60);
304
+ const remainingMinutes = minutes % 60;
305
+ return `${hours}h ${remainingMinutes}m`;
306
+ }
307
+
308
+ // src/components/doc/DocNote.tsx
137
309
  import { jsx as jsx3 } from "react/jsx-runtime";
310
+ function DocNote({ entry }) {
311
+ return /* @__PURE__ */ jsx3("p", { className: "my-2 text-sm text-muted-foreground", children: entry.text });
312
+ }
313
+
314
+ // src/components/doc/DocTag.tsx
315
+ import { jsx as jsx4 } from "react/jsx-runtime";
138
316
  function DocTag({ entry }) {
139
- return /* @__PURE__ */ jsx3("ul", { className: "my-2 flex flex-wrap gap-1.5", "aria-label": "Tags", children: entry.names.map((n) => /* @__PURE__ */ jsx3("li", { children: /* @__PURE__ */ jsx3(Badge, { variant: "tag", children: n }) }, n)) });
317
+ return /* @__PURE__ */ jsx4("ul", { className: "my-2 flex flex-wrap gap-1.5", "aria-label": "Tags", children: entry.names.map((n) => /* @__PURE__ */ jsx4("li", { children: /* @__PURE__ */ jsx4(Badge, { variant: "tag", children: n }) }, n)) });
140
318
  }
141
319
 
142
320
  // src/components/doc/DocKv.tsx
143
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
321
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
144
322
  function formatValue(value) {
145
323
  if (value === null) return "null";
146
324
  if (typeof value === "string") return value;
@@ -152,19 +330,19 @@ function formatValue(value) {
152
330
  }
153
331
  }
154
332
  function DocKv({ entry }) {
155
- return /* @__PURE__ */ jsxs("dl", { className: "my-2 flex flex-wrap items-baseline gap-x-2 text-sm", children: [
156
- /* @__PURE__ */ jsx4("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
157
- /* @__PURE__ */ jsx4("dd", { className: "font-mono text-foreground", children: formatValue(entry.value) })
333
+ return /* @__PURE__ */ jsxs2("dl", { className: "my-2 flex flex-wrap items-baseline gap-x-2 text-sm", children: [
334
+ /* @__PURE__ */ jsx5("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
335
+ /* @__PURE__ */ jsx5("dd", { className: "font-mono text-foreground", children: formatValue(entry.value) })
158
336
  ] });
159
337
  }
160
338
 
161
339
  // src/hooks/useRenderers.ts
162
340
  import { useContext as useContext2 } from "react";
163
- var EMPTY_CUSTOM2 = {};
341
+ var EMPTY_CUSTOM = {};
164
342
  var EMPTY_RENDERERS2 = {};
165
343
  function useCustomRenderers() {
166
344
  const ctx = useContext2(ReportContext);
167
- return ctx?.customRenderers ?? EMPTY_CUSTOM2;
345
+ return ctx?.customRenderers ?? EMPTY_CUSTOM;
168
346
  }
169
347
  function useBuiltinRenderers() {
170
348
  const ctx = useContext2(ReportContext);
@@ -172,37 +350,37 @@ function useBuiltinRenderers() {
172
350
  }
173
351
 
174
352
  // src/components/doc/DocCode.tsx
175
- import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
353
+ import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
176
354
  function CodeFigure({ label, children }) {
177
- return /* @__PURE__ */ jsxs2("figure", { className: "my-3", children: [
178
- label ? /* @__PURE__ */ jsx5("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: label }) : null,
179
- /* @__PURE__ */ jsx5("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3", children })
355
+ return /* @__PURE__ */ jsxs3("figure", { className: "my-3", children: [
356
+ label ? /* @__PURE__ */ jsx6("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: label }) : null,
357
+ /* @__PURE__ */ jsx6("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3", children })
180
358
  ] });
181
359
  }
182
360
  function DocCode({ entry }) {
183
361
  const renderers = useBuiltinRenderers();
184
362
  if (renderers.code) {
185
- return /* @__PURE__ */ jsx5(Fragment, { children: renderers.code(entry) });
363
+ return /* @__PURE__ */ jsx6(Fragment, { children: renderers.code(entry) });
186
364
  }
187
- return /* @__PURE__ */ jsx5(CodeFigure, { label: entry.label, children: /* @__PURE__ */ jsx5("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
365
+ return /* @__PURE__ */ jsx6(CodeFigure, { label: entry.label, children: /* @__PURE__ */ jsx6("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
188
366
  }
189
367
 
190
368
  // src/components/doc/DocTable.tsx
191
- import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
369
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
192
370
  function DocTable({ entry }) {
193
- return /* @__PURE__ */ jsxs3("figure", { className: "my-3", children: [
194
- entry.label ? /* @__PURE__ */ jsx6("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
195
- /* @__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: [
196
- /* @__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)) }) }),
197
- /* @__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)) })
371
+ return /* @__PURE__ */ jsxs4("figure", { className: "my-3", children: [
372
+ entry.label ? /* @__PURE__ */ jsx7("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
373
+ /* @__PURE__ */ jsx7("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ jsxs4("table", { className: "w-full border-collapse text-sm", children: [
374
+ /* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsx7("tr", { className: "bg-muted/50", children: entry.columns.map((c) => /* @__PURE__ */ jsx7("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: c }, c)) }) }),
375
+ /* @__PURE__ */ jsx7("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ jsx7("tr", { children: row.map((cell, j) => /* @__PURE__ */ jsx7("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell }, j)) }, i)) })
198
376
  ] }) })
199
377
  ] });
200
378
  }
201
379
 
202
380
  // src/components/doc/DocLink.tsx
203
- import { jsx as jsx7 } from "react/jsx-runtime";
381
+ import { jsx as jsx8 } from "react/jsx-runtime";
204
382
  function DocLink({ entry }) {
205
- return /* @__PURE__ */ jsx7(
383
+ return /* @__PURE__ */ jsx8(
206
384
  "a",
207
385
  {
208
386
  className: "text-sm font-medium text-primary underline underline-offset-2 hover:no-underline",
@@ -236,7 +414,7 @@ function isLocalFsPath(value) {
236
414
  }
237
415
 
238
416
  // src/components/doc/DocSection.tsx
239
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
417
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
240
418
  function neutralizeUrl(value) {
241
419
  return safeUrl(value) ?? "#";
242
420
  }
@@ -247,12 +425,12 @@ function safeMarkdownHtml(markdown) {
247
425
  function DocSection({ entry }) {
248
426
  const renderers = useBuiltinRenderers();
249
427
  if (renderers.section) {
250
- return /* @__PURE__ */ jsx8(Fragment2, { children: renderers.section(entry) });
428
+ return /* @__PURE__ */ jsx9(Fragment2, { children: renderers.section(entry) });
251
429
  }
252
430
  const html = safeMarkdownHtml(entry.markdown);
253
- return /* @__PURE__ */ jsxs4("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
254
- entry.title ? /* @__PURE__ */ jsx8("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
255
- /* @__PURE__ */ jsx8(
431
+ return /* @__PURE__ */ jsxs5("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
432
+ entry.title ? /* @__PURE__ */ jsx9("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
433
+ /* @__PURE__ */ jsx9(
256
434
  "div",
257
435
  {
258
436
  className: "es-doc-prose prose prose-sm max-w-none",
@@ -263,11 +441,11 @@ function DocSection({ entry }) {
263
441
  }
264
442
 
265
443
  // src/components/doc/DocMermaid.tsx
266
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
444
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
267
445
  function MermaidSource({ entry, ref }) {
268
- return /* @__PURE__ */ jsxs5("figure", { ref, className: "my-3", "aria-label": entry.title ?? "Diagram", children: [
269
- entry.title ? /* @__PURE__ */ jsx9("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
270
- /* @__PURE__ */ jsx9(
446
+ return /* @__PURE__ */ jsxs6("figure", { ref, className: "my-3", "aria-label": entry.title ?? "Diagram", children: [
447
+ entry.title ? /* @__PURE__ */ jsx10("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
448
+ /* @__PURE__ */ jsx10(
271
449
  "pre",
272
450
  {
273
451
  "data-mermaid": true,
@@ -281,24 +459,24 @@ function MermaidSource({ entry, ref }) {
281
459
  function DocMermaid({ entry }) {
282
460
  const renderers = useBuiltinRenderers();
283
461
  if (renderers.mermaid) {
284
- return /* @__PURE__ */ jsx9(Fragment3, { children: renderers.mermaid(entry) });
462
+ return /* @__PURE__ */ jsx10(Fragment3, { children: renderers.mermaid(entry) });
285
463
  }
286
- return /* @__PURE__ */ jsx9(MermaidSource, { entry });
464
+ return /* @__PURE__ */ jsx10(MermaidSource, { entry });
287
465
  }
288
466
 
289
467
  // src/components/doc/DocScreenshot.tsx
290
- import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
468
+ import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
291
469
  function DocScreenshot({ entry }) {
292
470
  const src = isLocalFsPath(entry.path) ? void 0 : safeImageUrl(entry.path);
293
471
  if (!src) {
294
- return /* @__PURE__ */ jsxs6("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
295
- /* @__PURE__ */ jsx10("div", { className: "font-medium", children: "Screenshot unavailable" }),
296
- /* @__PURE__ */ jsx10("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
297
- entry.alt ? /* @__PURE__ */ jsx10("figcaption", { className: "mt-1.5 text-xs", children: entry.alt }) : null
472
+ return /* @__PURE__ */ jsxs7("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
473
+ /* @__PURE__ */ jsx11("div", { className: "font-medium", children: "Screenshot unavailable" }),
474
+ /* @__PURE__ */ jsx11("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
475
+ entry.alt ? /* @__PURE__ */ jsx11("figcaption", { className: "mt-1.5 text-xs", children: entry.alt }) : null
298
476
  ] });
299
477
  }
300
- return /* @__PURE__ */ jsxs6("figure", { className: "my-3", children: [
301
- /* @__PURE__ */ jsx10(
478
+ return /* @__PURE__ */ jsxs7("figure", { className: "my-3", children: [
479
+ /* @__PURE__ */ jsx11(
302
480
  "img",
303
481
  {
304
482
  src,
@@ -307,24 +485,24 @@ function DocScreenshot({ entry }) {
307
485
  className: "max-w-full rounded-md border border-border"
308
486
  }
309
487
  ),
310
- entry.alt ? /* @__PURE__ */ jsx10("figcaption", { className: "mt-1.5 text-xs text-muted-foreground", children: entry.alt }) : null
488
+ entry.alt ? /* @__PURE__ */ jsx11("figcaption", { className: "mt-1.5 text-xs text-muted-foreground", children: entry.alt }) : null
311
489
  ] });
312
490
  }
313
491
 
314
492
  // src/components/doc/DocVideo.tsx
315
- import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
493
+ import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
316
494
  function DocVideo({ entry }) {
317
495
  if (isLocalFsPath(entry.path)) {
318
- return /* @__PURE__ */ jsxs7("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
319
- /* @__PURE__ */ jsx11("div", { className: "font-medium", children: "Video unavailable" }),
320
- /* @__PURE__ */ jsx11("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
321
- entry.caption ? /* @__PURE__ */ jsx11("figcaption", { className: "mt-1.5 text-xs", children: entry.caption }) : null
496
+ return /* @__PURE__ */ jsxs8("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
497
+ /* @__PURE__ */ jsx12("div", { className: "font-medium", children: "Video unavailable" }),
498
+ /* @__PURE__ */ jsx12("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
499
+ entry.caption ? /* @__PURE__ */ jsx12("figcaption", { className: "mt-1.5 text-xs", children: entry.caption }) : null
322
500
  ] });
323
501
  }
324
502
  const src = safeUrl(entry.path);
325
503
  const poster = safeUrl(entry.poster);
326
- return /* @__PURE__ */ jsxs7("figure", { className: "my-3", children: [
327
- /* @__PURE__ */ jsx11(
504
+ return /* @__PURE__ */ jsxs8("figure", { className: "my-3", children: [
505
+ /* @__PURE__ */ jsx12(
328
506
  "video",
329
507
  {
330
508
  controls: true,
@@ -334,21 +512,21 @@ function DocVideo({ entry }) {
334
512
  className: "max-w-full rounded-md border border-border"
335
513
  }
336
514
  ),
337
- entry.caption ? /* @__PURE__ */ jsx11("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: entry.caption }) : null
515
+ entry.caption ? /* @__PURE__ */ jsx12("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: entry.caption }) : null
338
516
  ] });
339
517
  }
340
518
 
341
519
  // src/components/doc/DocHtml.tsx
342
- import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
520
+ import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
343
521
  function DocHtml({ entry }) {
344
522
  const height = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
345
523
  const title = entry.title ?? "Embedded HTML";
346
524
  const safeHref = safeUrl(entry.url ?? entry.path);
347
525
  const frameProps = entry.content !== void 0 ? { srcDoc: entry.content } : { src: safeHref ?? "" };
348
- return /* @__PURE__ */ jsxs8("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
349
- /* @__PURE__ */ jsxs8("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: [
350
- /* @__PURE__ */ jsx12("span", { children: entry.title ?? "HTML" }),
351
- safeHref ? /* @__PURE__ */ jsx12(
526
+ return /* @__PURE__ */ jsxs9("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
527
+ /* @__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: [
528
+ /* @__PURE__ */ jsx13("span", { children: entry.title ?? "HTML" }),
529
+ safeHref ? /* @__PURE__ */ jsx13(
352
530
  "a",
353
531
  {
354
532
  href: safeHref,
@@ -361,7 +539,7 @@ function DocHtml({ entry }) {
361
539
  }
362
540
  ) : null
363
541
  ] }),
364
- /* @__PURE__ */ jsx12(
542
+ /* @__PURE__ */ jsx13(
365
543
  "iframe",
366
544
  {
367
545
  ...frameProps,
@@ -376,7 +554,7 @@ function DocHtml({ entry }) {
376
554
  }
377
555
 
378
556
  // src/components/doc/DocState.tsx
379
- import { jsx as jsx13 } from "react/jsx-runtime";
557
+ import { jsx as jsx14 } from "react/jsx-runtime";
380
558
  function DocState({ entry }) {
381
559
  let json;
382
560
  try {
@@ -384,23 +562,23 @@ function DocState({ entry }) {
384
562
  } catch {
385
563
  json = String(entry.value);
386
564
  }
387
- return /* @__PURE__ */ jsx13(CodeFigure, { label: entry.label ?? "State", children: /* @__PURE__ */ jsx13("code", { className: "font-mono text-xs language-json", children: json }) });
565
+ return /* @__PURE__ */ jsx14(CodeFigure, { label: entry.label ?? "State", children: /* @__PURE__ */ jsx14("code", { className: "font-mono text-xs language-json", children: json }) });
388
566
  }
389
567
 
390
568
  // src/components/doc/DocCustom.tsx
391
- import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
569
+ import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
392
570
  function DocCustom({ entry }) {
393
571
  const renderers = useCustomRenderers();
394
572
  const renderer = renderers[entry.type];
395
573
  if (renderer) {
396
- return /* @__PURE__ */ jsx14(Fragment4, { children: renderer(entry) });
574
+ return /* @__PURE__ */ jsx15(Fragment4, { children: renderer(entry) });
397
575
  }
398
- return /* @__PURE__ */ jsxs9("div", { className: "my-2", "data-type": entry.type, children: [
399
- /* @__PURE__ */ jsx14("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: entry.type }),
400
- /* @__PURE__ */ jsx14("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs text-foreground", children: safeStringify(entry.data) })
576
+ return /* @__PURE__ */ jsxs10("div", { className: "my-2", "data-type": entry.type, children: [
577
+ /* @__PURE__ */ jsx15("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: entry.type }),
578
+ /* @__PURE__ */ jsx15("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs text-foreground", children: safeStringify2(entry.data) })
401
579
  ] });
402
580
  }
403
- function safeStringify(value) {
581
+ function safeStringify2(value) {
404
582
  try {
405
583
  return JSON.stringify(value, null, 2);
406
584
  } catch {
@@ -409,47 +587,47 @@ function safeStringify(value) {
409
587
  }
410
588
 
411
589
  // src/components/doc/DocEntry.tsx
412
- import { jsx as jsx15 } from "react/jsx-runtime";
590
+ import { jsx as jsx16 } from "react/jsx-runtime";
413
591
  function DocEntry({ entry }) {
414
592
  switch (entry.kind) {
415
593
  case "note":
416
- return /* @__PURE__ */ jsx15(DocNote, { entry });
594
+ return /* @__PURE__ */ jsx16(DocNote, { entry });
417
595
  case "tag":
418
- return /* @__PURE__ */ jsx15(DocTag, { entry });
596
+ return /* @__PURE__ */ jsx16(DocTag, { entry });
419
597
  case "kv":
420
- return /* @__PURE__ */ jsx15(DocKv, { entry });
598
+ return /* @__PURE__ */ jsx16(DocKv, { entry });
421
599
  case "code":
422
- return /* @__PURE__ */ jsx15(DocCode, { entry });
600
+ return /* @__PURE__ */ jsx16(DocCode, { entry });
423
601
  case "table":
424
- return /* @__PURE__ */ jsx15(DocTable, { entry });
602
+ return /* @__PURE__ */ jsx16(DocTable, { entry });
425
603
  case "link":
426
- return /* @__PURE__ */ jsx15(DocLink, { entry });
604
+ return /* @__PURE__ */ jsx16(DocLink, { entry });
427
605
  case "section":
428
- return /* @__PURE__ */ jsx15(DocSection, { entry });
606
+ return /* @__PURE__ */ jsx16(DocSection, { entry });
429
607
  case "mermaid":
430
- return /* @__PURE__ */ jsx15(DocMermaid, { entry });
608
+ return /* @__PURE__ */ jsx16(DocMermaid, { entry });
431
609
  case "screenshot":
432
- return /* @__PURE__ */ jsx15(DocScreenshot, { entry });
610
+ return /* @__PURE__ */ jsx16(DocScreenshot, { entry });
433
611
  case "video":
434
- return /* @__PURE__ */ jsx15(DocVideo, { entry });
612
+ return /* @__PURE__ */ jsx16(DocVideo, { entry });
435
613
  case "html":
436
- return /* @__PURE__ */ jsx15(DocHtml, { entry });
614
+ return /* @__PURE__ */ jsx16(DocHtml, { entry });
437
615
  case "state":
438
- return /* @__PURE__ */ jsx15(DocState, { entry });
616
+ return /* @__PURE__ */ jsx16(DocState, { entry });
439
617
  case "custom":
440
- return /* @__PURE__ */ jsx15(DocCustom, { entry });
618
+ return /* @__PURE__ */ jsx16(DocCustom, { entry });
441
619
  }
442
620
  }
443
621
 
444
622
  // src/components/ReportDocEntries.tsx
445
- import { Fragment as Fragment5, jsx as jsx16 } from "react/jsx-runtime";
623
+ import { Fragment as Fragment5, jsx as jsx17 } from "react/jsx-runtime";
446
624
  function ReportDocEntries({ entries }) {
447
625
  if (entries.length === 0) return null;
448
- return /* @__PURE__ */ jsx16(Fragment5, { children: entries.map((entry, i) => /* @__PURE__ */ jsx16(DocEntry, { entry }, i)) });
626
+ return /* @__PURE__ */ jsx17(Fragment5, { children: entries.map((entry, i) => /* @__PURE__ */ jsx17(DocEntry, { entry }, i)) });
449
627
  }
450
628
 
451
629
  // src/lib/step-params.tsx
452
- import { jsx as jsx17 } from "react/jsx-runtime";
630
+ import { jsx as jsx18 } from "react/jsx-runtime";
453
631
  var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
454
632
  function highlightStepParams(text) {
455
633
  const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
@@ -461,7 +639,7 @@ function highlightStepParams(text) {
461
639
  const end = start + match[0].length;
462
640
  if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
463
641
  nodes.push(
464
- /* @__PURE__ */ jsx17("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
642
+ /* @__PURE__ */ jsx18("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
465
643
  );
466
644
  lastIndex = end;
467
645
  });
@@ -470,7 +648,7 @@ function highlightStepParams(text) {
470
648
  }
471
649
 
472
650
  // src/components/ReportSteps.tsx
473
- import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
651
+ import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
474
652
  var STEP_GLYPH = {
475
653
  passed: "\u2713",
476
654
  failed: "\u2717",
@@ -485,21 +663,21 @@ var STEP_GLYPH_COLOR = {
485
663
  };
486
664
  function ReportSteps({ scenario }) {
487
665
  if (scenario.steps.length === 0) return null;
488
- return /* @__PURE__ */ jsx18("ol", { "data-slot": "steps", className: "flex flex-col", children: scenario.steps.map((step) => /* @__PURE__ */ jsx18(ReportStepItem, { step }, step.id)) });
666
+ return /* @__PURE__ */ jsx19("ol", { "data-slot": "steps", className: "flex flex-col", children: scenario.steps.map((step) => /* @__PURE__ */ jsx19(ReportStepItem, { step }, step.id)) });
489
667
  }
490
668
  function ReportStepItem({ step }) {
491
669
  const kw = step.keyword.toLowerCase();
492
670
  const continuation = kw === "and" || kw === "but";
493
- return /* @__PURE__ */ jsxs10(
671
+ return /* @__PURE__ */ jsxs11(
494
672
  "li",
495
673
  {
496
674
  id: step.id,
497
675
  "data-status": step.status,
498
676
  className: cn("py-1.5 text-[0.8125rem] leading-normal", continuation && "pl-5"),
499
677
  children: [
500
- /* @__PURE__ */ jsxs10("div", { className: "flex items-baseline gap-2", children: [
501
- /* @__PURE__ */ jsx18("span", { "aria-hidden": true, className: cn("w-4 shrink-0 text-center text-xs", STEP_GLYPH_COLOR[step.status]), children: STEP_GLYPH[step.status] ?? "\u25CB" }),
502
- /* @__PURE__ */ jsx18(
678
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-baseline gap-2", children: [
679
+ /* @__PURE__ */ jsx19("span", { "aria-hidden": true, className: cn("w-4 shrink-0 text-center text-xs", STEP_GLYPH_COLOR[step.status]), children: STEP_GLYPH[step.status] ?? "\u25CB" }),
680
+ /* @__PURE__ */ jsx19(
503
681
  "span",
504
682
  {
505
683
  className: cn(
@@ -509,10 +687,10 @@ function ReportStepItem({ step }) {
509
687
  children: step.keyword
510
688
  }
511
689
  ),
512
- /* @__PURE__ */ jsx18("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
513
- step.durationMs > 0 ? /* @__PURE__ */ jsx18("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(step.durationMs) }) : null
690
+ /* @__PURE__ */ jsx19("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
691
+ step.durationMs > 0 ? /* @__PURE__ */ jsx19("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(step.durationMs) }) : null
514
692
  ] }),
515
- step.errorMessage ? /* @__PURE__ */ jsx18(
693
+ step.errorMessage ? /* @__PURE__ */ jsx19(
516
694
  "pre",
517
695
  {
518
696
  role: "alert",
@@ -520,7 +698,7 @@ function ReportStepItem({ step }) {
520
698
  children: step.errorMessage
521
699
  }
522
700
  ) : null,
523
- step.docEntries.length > 0 ? /* @__PURE__ */ jsx18("div", { "data-es-docs": true, className: "mt-2 ml-6", children: /* @__PURE__ */ jsx18(ReportDocEntries, { entries: step.docEntries }) }) : null
701
+ step.docEntries.length > 0 ? /* @__PURE__ */ jsx19("div", { "data-es-docs": true, className: "mt-2 ml-6", children: /* @__PURE__ */ jsx19(ReportDocEntries, { entries: step.docEntries }) }) : null
524
702
  ]
525
703
  }
526
704
  );
@@ -645,7 +823,7 @@ function extractStoryboardFrames(scenario) {
645
823
  }
646
824
 
647
825
  // src/components/ReportStoryboard.tsx
648
- import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
826
+ import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
649
827
  var FRAME_GLYPH = {
650
828
  passed: "\u2713",
651
829
  failed: "\u2717",
@@ -661,32 +839,32 @@ var FRAME_GLYPH_COLOR = {
661
839
  function ReportStoryboard({ scenario }) {
662
840
  const frames = extractStoryboardFrames(scenario);
663
841
  if (frames.length < 2) return null;
664
- return /* @__PURE__ */ jsxs11("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
665
- /* @__PURE__ */ jsx19("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
666
- /* @__PURE__ */ jsx19("ol", { className: "flex items-start gap-3 overflow-x-auto pb-2", children: frames.map((frame) => /* @__PURE__ */ jsx19(StoryboardFrameItem, { frame }, frame.stepId)) })
842
+ return /* @__PURE__ */ jsxs12("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
843
+ /* @__PURE__ */ jsx20("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
844
+ /* @__PURE__ */ jsx20("ol", { className: "flex items-start gap-3 overflow-x-auto pb-2", children: frames.map((frame) => /* @__PURE__ */ jsx20(StoryboardFrameItem, { frame }, frame.stepId)) })
667
845
  ] });
668
846
  }
669
847
  function StoryboardFrameItem({ frame }) {
670
848
  const label = `${frame.keyword} ${frame.text}`;
671
849
  const hasStates = frame.states.length > 0;
672
- const caption = /* @__PURE__ */ jsxs11("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
673
- /* @__PURE__ */ jsx19("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
674
- /* @__PURE__ */ jsxs11("span", { className: "min-w-0", children: [
675
- /* @__PURE__ */ jsx19("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
850
+ const caption = /* @__PURE__ */ jsxs12("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
851
+ /* @__PURE__ */ jsx20("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
852
+ /* @__PURE__ */ jsxs12("span", { className: "min-w-0", children: [
853
+ /* @__PURE__ */ jsx20("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
676
854
  " ",
677
- /* @__PURE__ */ jsx19("span", { className: "text-muted-foreground", children: frame.screenshot?.alt ?? frame.text })
855
+ /* @__PURE__ */ jsx20("span", { className: "text-muted-foreground", children: frame.screenshot?.alt ?? frame.text })
678
856
  ] })
679
857
  ] });
680
858
  return (
681
859
  // State cards need room for diff rows; screenshot-only frames keep the
682
860
  // original narrow film-cell width (and DOM) unchanged.
683
- /* @__PURE__ */ jsxs11("li", { className: cn("shrink-0", hasStates ? "w-64" : "w-40"), children: [
684
- frame.screenshot ? /* @__PURE__ */ jsx19(FrameScreenshot, { frame, label }) : null,
685
- hasStates ? /* @__PURE__ */ jsx19("div", { className: cn("flex flex-col gap-1.5", frame.screenshot && "mt-1.5"), children: frame.states.map((card, i) => /* @__PURE__ */ jsx19(StateCardView, { card }, card.label ?? i)) }) : null,
861
+ /* @__PURE__ */ jsxs12("li", { className: cn("shrink-0", hasStates ? "w-64" : "w-40"), children: [
862
+ frame.screenshot ? /* @__PURE__ */ jsx20(FrameScreenshot, { frame, label }) : null,
863
+ hasStates ? /* @__PURE__ */ jsx20("div", { className: cn("flex flex-col gap-1.5", frame.screenshot && "mt-1.5"), children: frame.states.map((card, i) => /* @__PURE__ */ jsx20(StateCardView, { card }, card.label ?? i)) }) : null,
686
864
  frame.screenshot ? caption : (
687
865
  // No screenshot means no image anchor, so the caption carries the
688
866
  // jump-to-step link instead.
689
- /* @__PURE__ */ jsx19("a", { href: `#${frame.stepId}`, "aria-label": `Jump to step: ${label}`, className: "block hover:underline", children: caption })
867
+ /* @__PURE__ */ jsx20("a", { href: `#${frame.stepId}`, "aria-label": `Jump to step: ${label}`, className: "block hover:underline", children: caption })
690
868
  )
691
869
  ] })
692
870
  );
@@ -694,13 +872,13 @@ function StoryboardFrameItem({ frame }) {
694
872
  function FrameScreenshot({ frame, label }) {
695
873
  const path = frame.screenshot?.path ?? "";
696
874
  const src = isLocalFsPath(path) ? void 0 : safeImageUrl(path);
697
- return /* @__PURE__ */ jsx19(
875
+ return /* @__PURE__ */ jsx20(
698
876
  "a",
699
877
  {
700
878
  href: `#${frame.stepId}`,
701
879
  "aria-label": `Jump to step: ${label}`,
702
880
  className: "block overflow-hidden rounded-md border border-border transition-colors hover:border-ring",
703
- children: src ? /* @__PURE__ */ jsx19(
881
+ children: src ? /* @__PURE__ */ jsx20(
704
882
  "img",
705
883
  {
706
884
  src,
@@ -708,7 +886,7 @@ function FrameScreenshot({ frame, label }) {
708
886
  loading: "lazy",
709
887
  className: "h-24 w-full bg-muted object-cover object-top"
710
888
  }
711
- ) : /* @__PURE__ */ jsx19("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" })
889
+ ) : /* @__PURE__ */ jsx20("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" })
712
890
  }
713
891
  );
714
892
  }
@@ -727,12 +905,12 @@ function prettyJson(value) {
727
905
  function StateCardView({ card }) {
728
906
  const json = prettyJson(card.value);
729
907
  const firstCapture = card.changes === void 0;
730
- return /* @__PURE__ */ jsxs11("div", { "data-slot": "state-card", className: "rounded-md border border-border bg-card p-2", children: [
731
- /* @__PURE__ */ jsxs11("p", { className: "flex flex-wrap items-baseline gap-1.5", children: [
732
- /* @__PURE__ */ jsx19("span", { className: "inline-flex rounded-full border border-border px-1.5 font-mono text-[0.625rem] font-medium text-muted-foreground", children: card.label ?? "State" }),
733
- firstCapture ? /* @__PURE__ */ jsx19("span", { className: "text-[0.625rem] text-muted-foreground italic", children: "first capture" }) : null
908
+ return /* @__PURE__ */ jsxs12("div", { "data-slot": "state-card", className: "rounded-md border border-border bg-card p-2", children: [
909
+ /* @__PURE__ */ jsxs12("p", { className: "flex flex-wrap items-baseline gap-1.5", children: [
910
+ /* @__PURE__ */ jsx20("span", { className: "inline-flex rounded-full border border-border px-1.5 font-mono text-[0.625rem] font-medium text-muted-foreground", children: card.label ?? "State" }),
911
+ firstCapture ? /* @__PURE__ */ jsx20("span", { className: "text-[0.625rem] text-muted-foreground italic", children: "first capture" }) : null
734
912
  ] }),
735
- !firstCapture && (card.changes && card.changes.length > 0 ? /* @__PURE__ */ jsx19("ul", { className: "mt-1.5 flex flex-col gap-0.5", children: card.changes.map((change, i) => /* @__PURE__ */ jsx19(
913
+ !firstCapture && (card.changes && card.changes.length > 0 ? /* @__PURE__ */ jsx20("ul", { className: "mt-1.5 flex flex-col gap-0.5", children: card.changes.map((change, i) => /* @__PURE__ */ jsx20(
736
914
  "li",
737
915
  {
738
916
  className: cn(
@@ -742,15 +920,15 @@ function StateCardView({ card }) {
742
920
  children: summarizeStateChanges([change])[0]
743
921
  },
744
922
  i
745
- )) }) : /* @__PURE__ */ jsx19("p", { className: "mt-1.5 text-[0.625rem] text-muted-foreground", children: "No changes" })),
746
- /* @__PURE__ */ jsxs11(
923
+ )) }) : /* @__PURE__ */ jsx20("p", { className: "mt-1.5 text-[0.625rem] text-muted-foreground", children: "No changes" })),
924
+ /* @__PURE__ */ jsxs12(
747
925
  "details",
748
926
  {
749
927
  open: firstCapture && json.length <= 240,
750
928
  className: cn(firstCapture ? "mt-1.5" : "mt-1"),
751
929
  children: [
752
- /* @__PURE__ */ jsx19("summary", { className: "cursor-pointer text-[0.625rem] text-muted-foreground hover:text-foreground", children: "Snapshot" }),
753
- /* @__PURE__ */ jsx19("pre", { tabIndex: 0, className: "mt-1 max-h-48 overflow-auto rounded-sm bg-muted p-1.5 font-mono text-[0.625rem] leading-snug", children: json })
930
+ /* @__PURE__ */ jsx20("summary", { className: "cursor-pointer text-[0.625rem] text-muted-foreground hover:text-foreground", children: "Snapshot" }),
931
+ /* @__PURE__ */ jsx20("pre", { tabIndex: 0, className: "mt-1 max-h-48 overflow-auto rounded-sm bg-muted p-1.5 font-mono text-[0.625rem] leading-snug", children: json })
754
932
  ]
755
933
  }
756
934
  )
@@ -758,17 +936,17 @@ function StateCardView({ card }) {
758
936
  }
759
937
 
760
938
  // src/components/ReportAttachments.tsx
761
- import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
939
+ import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
762
940
  function ReportAttachments({ attachments }) {
763
941
  if (attachments.length === 0) return null;
764
942
  return (
765
943
  // role="group" (not a labelled <section>) so multiple scenarios' attachment
766
944
  // blocks don't create duplicate "Attachments" region landmarks.
767
- /* @__PURE__ */ jsx20("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
945
+ /* @__PURE__ */ jsx21("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
768
946
  const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
769
947
  const isImage = att.mediaType.startsWith("image/");
770
- return /* @__PURE__ */ jsx20("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs12(Fragment6, { children: [
771
- /* @__PURE__ */ jsx20(
948
+ return /* @__PURE__ */ jsx21("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs13(Fragment6, { children: [
949
+ /* @__PURE__ */ jsx21(
772
950
  "img",
773
951
  {
774
952
  src: dataUri,
@@ -777,8 +955,8 @@ function ReportAttachments({ attachments }) {
777
955
  className: "max-w-full rounded-md border border-border"
778
956
  }
779
957
  ),
780
- /* @__PURE__ */ jsx20("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
781
- ] }) : /* @__PURE__ */ jsxs12(
958
+ /* @__PURE__ */ jsx21("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
959
+ ] }) : /* @__PURE__ */ jsxs13(
782
960
  "a",
783
961
  {
784
962
  href: dataUri,
@@ -787,7 +965,7 @@ function ReportAttachments({ attachments }) {
787
965
  children: [
788
966
  att.name,
789
967
  " ",
790
- /* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
968
+ /* @__PURE__ */ jsxs13("span", { className: "text-muted-foreground", children: [
791
969
  "(",
792
970
  att.mediaType,
793
971
  ")"
@@ -875,7 +1053,7 @@ function traceWindow(rows) {
875
1053
  }
876
1054
 
877
1055
  // src/components/ReportTrace.tsx
878
- import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
1056
+ import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
879
1057
  var BAR_COLOR = {
880
1058
  ok: "bg-pass",
881
1059
  error: "bg-fail",
@@ -886,8 +1064,8 @@ function ReportTrace({ spans }) {
886
1064
  const rows = toTraceRows(spans);
887
1065
  if (rows.length === 0) return null;
888
1066
  const { minStartMs, totalMs } = traceWindow(rows);
889
- return /* @__PURE__ */ jsxs13("details", { className: "mt-3 rounded-md border border-border bg-muted/30", children: [
890
- /* @__PURE__ */ jsxs13("summary", { className: "cursor-pointer px-3 py-2 text-xs font-medium text-muted-foreground", children: [
1067
+ return /* @__PURE__ */ jsxs14("details", { className: "mt-3 rounded-md border border-border bg-muted/30", children: [
1068
+ /* @__PURE__ */ jsxs14("summary", { className: "cursor-pointer px-3 py-2 text-xs font-medium text-muted-foreground", children: [
891
1069
  "Trace (",
892
1070
  rows.length,
893
1071
  " span",
@@ -896,11 +1074,11 @@ function ReportTrace({ spans }) {
896
1074
  formatDuration(totalMs),
897
1075
  ")"
898
1076
  ] }),
899
- /* @__PURE__ */ jsx21("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
1077
+ /* @__PURE__ */ jsx22("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
900
1078
  const leftPct = (row.startTimeMs - minStartMs) / totalMs * 100;
901
1079
  const widthPct = Math.max(row.durationMs / totalMs * 100, 0.5);
902
- return /* @__PURE__ */ jsxs13("li", { className: "flex items-center gap-2", children: [
903
- /* @__PURE__ */ jsx21(
1080
+ return /* @__PURE__ */ jsxs14("li", { className: "flex items-center gap-2", children: [
1081
+ /* @__PURE__ */ jsx22(
904
1082
  "span",
905
1083
  {
906
1084
  className: "min-w-0 flex-1 truncate text-foreground",
@@ -909,14 +1087,14 @@ function ReportTrace({ spans }) {
909
1087
  children: row.name
910
1088
  }
911
1089
  ),
912
- /* @__PURE__ */ jsx21("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ jsx21(
1090
+ /* @__PURE__ */ jsx22("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ jsx22(
913
1091
  "span",
914
1092
  {
915
1093
  className: cn("absolute top-0 h-full rounded-sm", BAR_COLOR[row.status]),
916
1094
  style: { left: `${leftPct}%`, width: `${widthPct}%` }
917
1095
  }
918
1096
  ) }),
919
- /* @__PURE__ */ jsx21("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
1097
+ /* @__PURE__ */ jsx22("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
920
1098
  ] }, `${row.spanId}-${i}`);
921
1099
  }) })
922
1100
  ] });
@@ -967,7 +1145,7 @@ function flakinessOf(entries) {
967
1145
  }
968
1146
 
969
1147
  // src/components/ScenarioRunHistory.tsx
970
- import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
1148
+ import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
971
1149
  var MAX_DOTS = 10;
972
1150
  var DOT_COLOR = {
973
1151
  passed: "bg-pass",
@@ -987,16 +1165,16 @@ function ScenarioRunHistory({ scenarioId }) {
987
1165
  const recent = entries.slice(-MAX_DOTS);
988
1166
  const flaky = flakinessOf(recent) === "flaky";
989
1167
  const summary = flaky ? `${describeRunHistory(recent)} \xB7 Flaky` : describeRunHistory(recent);
990
- return /* @__PURE__ */ jsxs14(Fragment7, { children: [
991
- flaky ? /* @__PURE__ */ jsx22(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
992
- /* @__PURE__ */ jsx22(
1168
+ return /* @__PURE__ */ jsxs15(Fragment7, { children: [
1169
+ flaky ? /* @__PURE__ */ jsx23(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
1170
+ /* @__PURE__ */ jsx23(
993
1171
  "span",
994
1172
  {
995
1173
  role: "img",
996
1174
  "aria-label": `Run history: ${summary}`,
997
1175
  title: summary,
998
1176
  className: "flex shrink-0 items-center gap-[3px]",
999
- children: recent.map((e, i) => /* @__PURE__ */ jsx22(
1177
+ children: recent.map((e, i) => /* @__PURE__ */ jsx23(
1000
1178
  "span",
1001
1179
  {
1002
1180
  "aria-hidden": true,
@@ -1035,9 +1213,9 @@ function useScenarioActions() {
1035
1213
 
1036
1214
  // src/components/ui/card.tsx
1037
1215
  import "react";
1038
- import { jsx as jsx23 } from "react/jsx-runtime";
1216
+ import { jsx as jsx24 } from "react/jsx-runtime";
1039
1217
  function Card({ className, ...props }) {
1040
- return /* @__PURE__ */ jsx23(
1218
+ return /* @__PURE__ */ jsx24(
1041
1219
  "div",
1042
1220
  {
1043
1221
  "data-slot": "card",
@@ -1050,7 +1228,7 @@ function Card({ className, ...props }) {
1050
1228
  );
1051
1229
  }
1052
1230
  function CardHeader({ className, ...props }) {
1053
- return /* @__PURE__ */ jsx23(
1231
+ return /* @__PURE__ */ jsx24(
1054
1232
  "div",
1055
1233
  {
1056
1234
  "data-slot": "card-header",
@@ -1063,7 +1241,7 @@ function CardHeader({ className, ...props }) {
1063
1241
  );
1064
1242
  }
1065
1243
  function CardContent({ className, ...props }) {
1066
- return /* @__PURE__ */ jsx23(
1244
+ return /* @__PURE__ */ jsx24(
1067
1245
  "div",
1068
1246
  {
1069
1247
  "data-slot": "card-content",
@@ -1077,13 +1255,13 @@ function CardContent({ className, ...props }) {
1077
1255
  import "react";
1078
1256
  import { Menu as MenuPrimitive } from "@base-ui/react/menu";
1079
1257
  import { CheckIcon } from "lucide-react";
1080
- import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
1258
+ import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
1081
1259
  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";
1082
1260
  function DropdownMenu(props) {
1083
- return /* @__PURE__ */ jsx24(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
1261
+ return /* @__PURE__ */ jsx25(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
1084
1262
  }
1085
1263
  function DropdownMenuTrigger(props) {
1086
- return /* @__PURE__ */ jsx24(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
1264
+ return /* @__PURE__ */ jsx25(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
1087
1265
  }
1088
1266
  function DropdownMenuContent({
1089
1267
  className,
@@ -1091,14 +1269,14 @@ function DropdownMenuContent({
1091
1269
  sideOffset = 4,
1092
1270
  ...props
1093
1271
  }) {
1094
- return /* @__PURE__ */ jsx24(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx24(
1272
+ return /* @__PURE__ */ jsx25(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx25(
1095
1273
  MenuPrimitive.Positioner,
1096
1274
  {
1097
1275
  "data-slot": "dropdown-menu-positioner",
1098
1276
  className: "z-50",
1099
1277
  align,
1100
1278
  sideOffset,
1101
- children: /* @__PURE__ */ jsx24(
1279
+ children: /* @__PURE__ */ jsx25(
1102
1280
  MenuPrimitive.Popup,
1103
1281
  {
1104
1282
  "data-slot": "dropdown-menu-content",
@@ -1116,7 +1294,7 @@ function DropdownMenuItem({
1116
1294
  className,
1117
1295
  ...props
1118
1296
  }) {
1119
- return /* @__PURE__ */ jsx24(
1297
+ return /* @__PURE__ */ jsx25(
1120
1298
  MenuPrimitive.Item,
1121
1299
  {
1122
1300
  "data-slot": "dropdown-menu-item",
@@ -1128,7 +1306,7 @@ function DropdownMenuItem({
1128
1306
 
1129
1307
  // src/components/ReportScenario.tsx
1130
1308
  import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
1131
- import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
1309
+ import { jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
1132
1310
  var STATUS_META = {
1133
1311
  passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
1134
1312
  failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
@@ -1144,7 +1322,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
1144
1322
  const collapsible = collapse !== null && !hideTitle;
1145
1323
  const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
1146
1324
  const actions = useScenarioActions();
1147
- return /* @__PURE__ */ jsxs16(
1325
+ return /* @__PURE__ */ jsxs17(
1148
1326
  Card,
1149
1327
  {
1150
1328
  id: scenario.id,
@@ -1152,10 +1330,10 @@ function ReportScenario({ scenario, hideTitle = false }) {
1152
1330
  ...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
1153
1331
  className: "gap-0 py-0",
1154
1332
  children: [
1155
- /* @__PURE__ */ jsxs16(CardHeader, { className: "px-4 py-3", children: [
1156
- /* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
1157
- hideTitle ? null : /* @__PURE__ */ jsxs16("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
1158
- collapsible ? /* @__PURE__ */ jsx25(
1333
+ /* @__PURE__ */ jsxs17(CardHeader, { className: "px-4 py-3", children: [
1334
+ /* @__PURE__ */ jsxs17("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
1335
+ hideTitle ? null : /* @__PURE__ */ jsxs17("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
1336
+ collapsible ? /* @__PURE__ */ jsx26(
1159
1337
  "button",
1160
1338
  {
1161
1339
  type: "button",
@@ -1164,49 +1342,49 @@ function ReportScenario({ scenario, hideTitle = false }) {
1164
1342
  "aria-controls": bodyId,
1165
1343
  "aria-label": `Toggle ${scenario.title}`,
1166
1344
  className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
1167
- children: /* @__PURE__ */ jsx25("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
1345
+ children: /* @__PURE__ */ jsx26("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
1168
1346
  }
1169
1347
  ) : null,
1170
- /* @__PURE__ */ jsx25("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
1171
- /* @__PURE__ */ jsx25("span", { children: scenario.title })
1348
+ /* @__PURE__ */ jsx26("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
1349
+ /* @__PURE__ */ jsx26("span", { children: scenario.title })
1172
1350
  ] }),
1173
- /* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
1174
- /* @__PURE__ */ jsx25(ScenarioRunHistory, { scenarioId: scenario.id }),
1175
- scenario.durationMs > 0 ? /* @__PURE__ */ jsx25("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
1176
- meta.showPill ? /* @__PURE__ */ jsx25(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx25("span", { className: "sr-only", children: `Status: ${label}` }),
1177
- actions ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
1178
- /* @__PURE__ */ jsx25(
1351
+ /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-2", children: [
1352
+ /* @__PURE__ */ jsx26(ScenarioRunHistory, { scenarioId: scenario.id }),
1353
+ scenario.durationMs > 0 ? /* @__PURE__ */ jsx26("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
1354
+ meta.showPill ? /* @__PURE__ */ jsx26(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx26("span", { className: "sr-only", children: `Status: ${label}` }),
1355
+ actions ? /* @__PURE__ */ jsxs17(DropdownMenu, { children: [
1356
+ /* @__PURE__ */ jsx26(
1179
1357
  DropdownMenuTrigger,
1180
1358
  {
1181
1359
  "aria-label": `Actions for ${scenario.title}`,
1182
1360
  className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
1183
- children: /* @__PURE__ */ jsx25(MoreHorizontalIcon, { "aria-hidden": true })
1361
+ children: /* @__PURE__ */ jsx26(MoreHorizontalIcon, { "aria-hidden": true })
1184
1362
  }
1185
1363
  ),
1186
- /* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", children: [
1187
- /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
1188
- /* @__PURE__ */ jsx25(LinkIcon, {}),
1364
+ /* @__PURE__ */ jsxs17(DropdownMenuContent, { align: "end", children: [
1365
+ /* @__PURE__ */ jsxs17(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
1366
+ /* @__PURE__ */ jsx26(LinkIcon, {}),
1189
1367
  " Copy link"
1190
1368
  ] }),
1191
- /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
1192
- /* @__PURE__ */ jsx25(FileTextIcon, {}),
1369
+ /* @__PURE__ */ jsxs17(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
1370
+ /* @__PURE__ */ jsx26(FileTextIcon, {}),
1193
1371
  " Copy as Markdown"
1194
1372
  ] }),
1195
- /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
1196
- /* @__PURE__ */ jsx25(SparklesIcon, {}),
1373
+ /* @__PURE__ */ jsxs17(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
1374
+ /* @__PURE__ */ jsx26(SparklesIcon, {}),
1197
1375
  " Explain with AI"
1198
1376
  ] })
1199
1377
  ] })
1200
1378
  ] }) : null
1201
1379
  ] })
1202
1380
  ] }),
1203
- 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: [
1204
- scenario.tags.map((t) => /* @__PURE__ */ jsx25("li", { children: /* @__PURE__ */ jsx25(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
1205
- (scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ jsx25("li", { children: ticket.url ? /* @__PURE__ */ jsx25("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ jsx25(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ jsx25(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
1381
+ scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs17("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
1382
+ scenario.tags.map((t) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
1383
+ (scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ jsx26("li", { children: ticket.url ? /* @__PURE__ */ jsx26("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ jsx26(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ jsx26(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
1206
1384
  ] }) : null
1207
1385
  ] }),
1208
- /* @__PURE__ */ jsxs16(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
1209
- scenario.errorMessage ? /* @__PURE__ */ jsx25(
1386
+ /* @__PURE__ */ jsxs17(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
1387
+ scenario.errorMessage ? /* @__PURE__ */ jsx26(
1210
1388
  "pre",
1211
1389
  {
1212
1390
  role: "alert",
@@ -1214,11 +1392,11 @@ function ReportScenario({ scenario, hideTitle = false }) {
1214
1392
  children: scenario.errorMessage
1215
1393
  }
1216
1394
  ) : null,
1217
- /* @__PURE__ */ jsx25(ReportStoryboard, { scenario }),
1218
- /* @__PURE__ */ jsx25(ReportSteps, { scenario }),
1219
- scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx25("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx25(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
1220
- /* @__PURE__ */ jsx25(ReportAttachments, { attachments: scenario.attachments }),
1221
- /* @__PURE__ */ jsx25(ReportTrace, { spans: scenario.otelSpans })
1395
+ /* @__PURE__ */ jsx26(ReportStoryboard, { scenario }),
1396
+ /* @__PURE__ */ jsx26(ReportSteps, { scenario }),
1397
+ scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx26("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx26(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
1398
+ /* @__PURE__ */ jsx26(ReportAttachments, { attachments: scenario.attachments }),
1399
+ /* @__PURE__ */ jsx26(ReportTrace, { spans: scenario.otelSpans })
1222
1400
  ] })
1223
1401
  ]
1224
1402
  }
@@ -1226,13 +1404,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
1226
1404
  }
1227
1405
 
1228
1406
  // src/components/ReportScenarioList.tsx
1229
- import { Fragment as Fragment8, jsx as jsx26 } from "react/jsx-runtime";
1407
+ import { Fragment as Fragment8, jsx as jsx27 } from "react/jsx-runtime";
1230
1408
  function ReportScenarioList({ feature }) {
1231
- return /* @__PURE__ */ jsx26(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx26(ReportScenario, { scenario }, scenario.id)) });
1409
+ return /* @__PURE__ */ jsx27(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx27(ReportScenario, { scenario }, scenario.id)) });
1232
1410
  }
1233
1411
 
1234
1412
  // src/components/ReportFeature.tsx
1235
- import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
1413
+ import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
1236
1414
  function ReportFeature({ feature }) {
1237
1415
  const titleId = `${feature.id}-title`;
1238
1416
  const bodyId = `${feature.id}-body`;
@@ -1243,7 +1421,7 @@ function ReportFeature({ feature }) {
1243
1421
  return (
1244
1422
  // Suite = a section heading + a divider, NOT another bordered card. Drops a
1245
1423
  // layer of nesting so the scenario cards below read as the primary unit.
1246
- /* @__PURE__ */ jsxs17(
1424
+ /* @__PURE__ */ jsxs18(
1247
1425
  "section",
1248
1426
  {
1249
1427
  id: feature.id,
@@ -1251,9 +1429,9 @@ function ReportFeature({ feature }) {
1251
1429
  "aria-labelledby": titleId,
1252
1430
  className: "flex flex-col gap-3",
1253
1431
  children: [
1254
- /* @__PURE__ */ jsxs17("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
1255
- /* @__PURE__ */ jsxs17("div", { className: "min-w-0", children: [
1256
- /* @__PURE__ */ jsx27("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs17(
1432
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
1433
+ /* @__PURE__ */ jsxs18("div", { className: "min-w-0", children: [
1434
+ /* @__PURE__ */ jsx28("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs18(
1257
1435
  "button",
1258
1436
  {
1259
1437
  type: "button",
@@ -1262,31 +1440,31 @@ function ReportFeature({ feature }) {
1262
1440
  "aria-controls": bodyId,
1263
1441
  className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
1264
1442
  children: [
1265
- /* @__PURE__ */ jsx27("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
1266
- /* @__PURE__ */ jsx27("span", { className: "truncate", children: feature.title })
1443
+ /* @__PURE__ */ jsx28("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
1444
+ /* @__PURE__ */ jsx28("span", { className: "truncate", children: feature.title })
1267
1445
  ]
1268
1446
  }
1269
1447
  ) : feature.title }),
1270
- /* @__PURE__ */ jsx27("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
1448
+ /* @__PURE__ */ jsx28("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
1271
1449
  ] }),
1272
- /* @__PURE__ */ jsxs17(
1450
+ /* @__PURE__ */ jsxs18(
1273
1451
  "p",
1274
1452
  {
1275
1453
  className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
1276
1454
  "aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
1277
1455
  children: [
1278
- /* @__PURE__ */ jsxs17("span", { children: [
1456
+ /* @__PURE__ */ jsxs18("span", { children: [
1279
1457
  s.passed,
1280
1458
  " passed"
1281
1459
  ] }),
1282
- /* @__PURE__ */ jsx27("span", { "aria-hidden": true, children: "\xB7" }),
1283
- /* @__PURE__ */ jsxs17("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
1460
+ /* @__PURE__ */ jsx28("span", { "aria-hidden": true, children: "\xB7" }),
1461
+ /* @__PURE__ */ jsxs18("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
1284
1462
  s.failed,
1285
1463
  " failed"
1286
1464
  ] }),
1287
- skipped > 0 ? /* @__PURE__ */ jsxs17(Fragment9, { children: [
1288
- /* @__PURE__ */ jsx27("span", { "aria-hidden": true, children: "\xB7" }),
1289
- /* @__PURE__ */ jsxs17("span", { children: [
1465
+ skipped > 0 ? /* @__PURE__ */ jsxs18(Fragment9, { children: [
1466
+ /* @__PURE__ */ jsx28("span", { "aria-hidden": true, children: "\xB7" }),
1467
+ /* @__PURE__ */ jsxs18("span", { children: [
1290
1468
  skipped,
1291
1469
  " skipped"
1292
1470
  ] })
@@ -1295,7 +1473,7 @@ function ReportFeature({ feature }) {
1295
1473
  }
1296
1474
  )
1297
1475
  ] }),
1298
- /* @__PURE__ */ jsx27("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx27(ReportScenarioList, { feature }) })
1476
+ /* @__PURE__ */ jsx28("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx28(ReportScenarioList, { feature }) })
1299
1477
  ]
1300
1478
  }
1301
1479
  )
@@ -1303,17 +1481,17 @@ function ReportFeature({ feature }) {
1303
1481
  }
1304
1482
 
1305
1483
  // src/components/ReportFeatureList.tsx
1306
- import { jsx as jsx28 } from "react/jsx-runtime";
1484
+ import { jsx as jsx29 } from "react/jsx-runtime";
1307
1485
  function ReportFeatureList() {
1308
1486
  const report = useReport();
1309
- return /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx28(ReportFeature, { feature }, feature.id)) });
1487
+ return /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx29(ReportFeature, { feature }, feature.id)) });
1310
1488
  }
1311
1489
 
1312
1490
  // src/components/ui/empty.tsx
1313
1491
  import { cva as cva2 } from "class-variance-authority";
1314
- import { jsx as jsx29 } from "react/jsx-runtime";
1492
+ import { jsx as jsx30 } from "react/jsx-runtime";
1315
1493
  function Empty({ className, ...props }) {
1316
- return /* @__PURE__ */ jsx29(
1494
+ return /* @__PURE__ */ jsx30(
1317
1495
  "div",
1318
1496
  {
1319
1497
  "data-slot": "empty",
@@ -1326,7 +1504,7 @@ function Empty({ className, ...props }) {
1326
1504
  );
1327
1505
  }
1328
1506
  function EmptyHeader({ className, ...props }) {
1329
- return /* @__PURE__ */ jsx29(
1507
+ return /* @__PURE__ */ jsx30(
1330
1508
  "div",
1331
1509
  {
1332
1510
  "data-slot": "empty-header",
@@ -1353,7 +1531,7 @@ var emptyMediaVariants = cva2(
1353
1531
  }
1354
1532
  );
1355
1533
  function EmptyTitle({ className, ...props }) {
1356
- return /* @__PURE__ */ jsx29(
1534
+ return /* @__PURE__ */ jsx30(
1357
1535
  "div",
1358
1536
  {
1359
1537
  "data-slot": "empty-title",
@@ -1364,16 +1542,16 @@ function EmptyTitle({ className, ...props }) {
1364
1542
  }
1365
1543
 
1366
1544
  // src/components/ReportEmpty.tsx
1367
- import { jsx as jsx30 } from "react/jsx-runtime";
1545
+ import { jsx as jsx31 } from "react/jsx-runtime";
1368
1546
  function ReportEmpty({ message }) {
1369
- return /* @__PURE__ */ jsx30(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx30(EmptyHeader, { children: /* @__PURE__ */ jsx30(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
1547
+ return /* @__PURE__ */ jsx31(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx31(EmptyHeader, { children: /* @__PURE__ */ jsx31(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
1370
1548
  }
1371
1549
 
1372
1550
  // src/components/ReportSummary.tsx
1373
- import { jsx as jsx31, jsxs as jsxs18 } from "react/jsx-runtime";
1551
+ import { jsx as jsx32, jsxs as jsxs19 } from "react/jsx-runtime";
1374
1552
  function ReportSummary({ className }) {
1375
1553
  const report = useReport();
1376
- return /* @__PURE__ */ jsx31(
1554
+ return /* @__PURE__ */ jsx32(
1377
1555
  ReportSummaryView,
1378
1556
  {
1379
1557
  summary: report.summary,
@@ -1399,7 +1577,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
1399
1577
  if (summary.pending > 0) {
1400
1578
  cards.push({ status: "pending", label: "Pending", value: summary.pending });
1401
1579
  }
1402
- return /* @__PURE__ */ jsx31(
1580
+ return /* @__PURE__ */ jsx32(
1403
1581
  "dl",
1404
1582
  {
1405
1583
  className: cn(
@@ -1412,17 +1590,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
1412
1590
  "aria-label": ariaLabel,
1413
1591
  children: cards.map((c) => {
1414
1592
  const tone = TONE[c.status];
1415
- return /* @__PURE__ */ jsxs18(
1593
+ return /* @__PURE__ */ jsxs19(
1416
1594
  "div",
1417
1595
  {
1418
1596
  "data-status": c.status,
1419
1597
  className: "rounded-lg border bg-card px-4 py-3",
1420
1598
  children: [
1421
- /* @__PURE__ */ jsxs18("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
1422
- /* @__PURE__ */ jsx31("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
1599
+ /* @__PURE__ */ jsxs19("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
1600
+ /* @__PURE__ */ jsx32("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
1423
1601
  c.label
1424
1602
  ] }),
1425
- /* @__PURE__ */ jsx31("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
1603
+ /* @__PURE__ */ jsx32("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
1426
1604
  ]
1427
1605
  },
1428
1606
  c.status
@@ -1463,7 +1641,7 @@ function prUrl(ci) {
1463
1641
  }
1464
1642
 
1465
1643
  // src/components/ReportMeta.tsx
1466
- import { jsx as jsx32, jsxs as jsxs19 } from "react/jsx-runtime";
1644
+ import { jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
1467
1645
  function ReportMeta() {
1468
1646
  const report = useReport();
1469
1647
  const items = [];
@@ -1486,13 +1664,13 @@ function ReportMeta() {
1486
1664
  const short = sha.slice(0, 8);
1487
1665
  items.push({
1488
1666
  label: "Commit",
1489
- value: url ? /* @__PURE__ */ jsx32("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
1667
+ value: url ? /* @__PURE__ */ jsx33("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
1490
1668
  });
1491
1669
  }
1492
1670
  if (report.ci) {
1493
1671
  items.push({
1494
1672
  label: "CI",
1495
- value: report.ci.url ? /* @__PURE__ */ jsxs19("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
1673
+ value: report.ci.url ? /* @__PURE__ */ jsxs20("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
1496
1674
  ciDisplayName(report.ci.name),
1497
1675
  report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
1498
1676
  ] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
@@ -1503,7 +1681,7 @@ function ReportMeta() {
1503
1681
  const label = `#${report.ci.prNumber}`;
1504
1682
  items.push({
1505
1683
  label: "PR",
1506
- value: url ? /* @__PURE__ */ jsx32("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
1684
+ value: url ? /* @__PURE__ */ jsx33("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
1507
1685
  });
1508
1686
  }
1509
1687
  if (items.length === 0) return null;
@@ -1511,48 +1689,48 @@ function ReportMeta() {
1511
1689
  // Run metadata is useful but secondary to "what failed" — tuck it into a
1512
1690
  // collapsed disclosure so it doesn't push the result down. Native <details>
1513
1691
  // so it works with no JS (the SSR/no-hydration report still toggles).
1514
- /* @__PURE__ */ jsxs19("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
1515
- /* @__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: [
1516
- /* @__PURE__ */ jsx32("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
1692
+ /* @__PURE__ */ jsxs20("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
1693
+ /* @__PURE__ */ jsxs20("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: [
1694
+ /* @__PURE__ */ jsx33("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
1517
1695
  "Run details"
1518
1696
  ] }),
1519
- /* @__PURE__ */ jsx32("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: [
1520
- /* @__PURE__ */ jsx32("dt", { className: "font-medium", children: item.label }),
1521
- /* @__PURE__ */ jsx32("dd", { className: "font-mono text-foreground", children: item.value })
1697
+ /* @__PURE__ */ jsx33("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__ */ jsxs20("div", { className: "flex items-baseline gap-1.5", children: [
1698
+ /* @__PURE__ */ jsx33("dt", { className: "font-medium", children: item.label }),
1699
+ /* @__PURE__ */ jsx33("dd", { className: "font-mono text-foreground", children: item.value })
1522
1700
  ] }, item.label)) })
1523
1701
  ] })
1524
1702
  );
1525
1703
  }
1526
1704
 
1527
1705
  // src/components/ReportSchemaError.tsx
1528
- import { jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
1706
+ import { jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
1529
1707
  function ReportSchemaError({ error }) {
1530
- return /* @__PURE__ */ jsxs20("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
1531
- /* @__PURE__ */ jsx33("p", { children: /* @__PURE__ */ jsx33("strong", { children: "Report could not be displayed." }) }),
1532
- /* @__PURE__ */ jsx33("p", { children: error.message }),
1533
- error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs20("p", { children: [
1708
+ return /* @__PURE__ */ jsxs21("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
1709
+ /* @__PURE__ */ jsx34("p", { children: /* @__PURE__ */ jsx34("strong", { children: "Report could not be displayed." }) }),
1710
+ /* @__PURE__ */ jsx34("p", { children: error.message }),
1711
+ error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs21("p", { children: [
1534
1712
  "The report bundle is newer than this version of ",
1535
- /* @__PURE__ */ jsx33("code", { children: "executable-stories-react" }),
1713
+ /* @__PURE__ */ jsx34("code", { children: "executable-stories-react" }),
1536
1714
  ". Upgrade the package, or regenerate the report with an older formatters CLI."
1537
1715
  ] }) : null,
1538
- error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs20("details", { children: [
1539
- /* @__PURE__ */ jsxs20("summary", { children: [
1716
+ error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs21("details", { children: [
1717
+ /* @__PURE__ */ jsxs21("summary", { children: [
1540
1718
  error.issues.length,
1541
1719
  " validation issue",
1542
1720
  error.issues.length === 1 ? "" : "s"
1543
1721
  ] }),
1544
- /* @__PURE__ */ jsx33("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
1722
+ /* @__PURE__ */ jsx34("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
1545
1723
  ] }) : null
1546
1724
  ] });
1547
1725
  }
1548
1726
 
1549
1727
  // src/components/ReportShell.tsx
1550
- import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
1728
+ import { Fragment as Fragment10, jsx as jsx35, jsxs as jsxs22 } from "react/jsx-runtime";
1551
1729
  function ReportTitleBlock({ title }) {
1552
- return /* @__PURE__ */ jsxs21(Fragment10, { children: [
1553
- /* @__PURE__ */ jsx34("h1", { children: title ?? "Story Report" }),
1554
- /* @__PURE__ */ jsx34(ReportSummary, {}),
1555
- /* @__PURE__ */ jsx34(ReportMeta, {})
1730
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1731
+ /* @__PURE__ */ jsx35("h1", { children: title ?? "Story Report" }),
1732
+ /* @__PURE__ */ jsx35(ReportSummary, {}),
1733
+ /* @__PURE__ */ jsx35(ReportMeta, {})
1556
1734
  ] });
1557
1735
  }
1558
1736
  function ReportErrorShell({
@@ -1561,22 +1739,22 @@ function ReportErrorShell({
1561
1739
  title,
1562
1740
  dataTheme
1563
1741
  }) {
1564
- return /* @__PURE__ */ jsx34("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx34(ReportSchemaError, { error }) });
1742
+ return /* @__PURE__ */ jsx35("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx35(ReportSchemaError, { error }) });
1565
1743
  }
1566
1744
 
1567
1745
  // src/components/Report.tsx
1568
- import { jsx as jsx35, jsxs as jsxs22 } from "react/jsx-runtime";
1746
+ import { jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
1569
1747
  function Report(props) {
1570
1748
  const { report, customRenderers, renderers, className, title, dataTheme } = props;
1571
1749
  const result = unwrapReport(report);
1572
1750
  if (!result.ok) {
1573
- return /* @__PURE__ */ jsx35(ReportErrorShell, { error: result.error, className, title, dataTheme });
1751
+ return /* @__PURE__ */ jsx36(ReportErrorShell, { error: result.error, className, title, dataTheme });
1574
1752
  }
1575
1753
  const data = result.data;
1576
1754
  const hasContent = data.features.length > 0;
1577
- return /* @__PURE__ */ jsx35(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs22("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
1578
- /* @__PURE__ */ jsx35("header", { className: "es-report-header", children: /* @__PURE__ */ jsx35(ReportTitleBlock, { title }) }),
1579
- hasContent ? /* @__PURE__ */ jsx35(ReportFeatureList, {}) : /* @__PURE__ */ jsx35(ReportEmpty, {})
1755
+ return /* @__PURE__ */ jsx36(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs23("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
1756
+ /* @__PURE__ */ jsx36("header", { className: "es-report-header", children: /* @__PURE__ */ jsx36(ReportTitleBlock, { title }) }),
1757
+ hasContent ? /* @__PURE__ */ jsx36(ReportFeatureList, {}) : /* @__PURE__ */ jsx36(ReportEmpty, {})
1580
1758
  ] }) });
1581
1759
  }
1582
1760