playwright-checkpoint 0.1.0-beta.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +665 -0
  3. package/dist/chunk-DGUM43GV.js +11 -0
  4. package/dist/chunk-DGUM43GV.js.map +1 -0
  5. package/dist/chunk-F5A6XGLJ.js +104 -0
  6. package/dist/chunk-F5A6XGLJ.js.map +1 -0
  7. package/dist/chunk-K5DX32TO.js +214 -0
  8. package/dist/chunk-K5DX32TO.js.map +1 -0
  9. package/dist/chunk-KG37WSYS.js +1549 -0
  10. package/dist/chunk-KG37WSYS.js.map +1 -0
  11. package/dist/chunk-X5IPL32H.js +1484 -0
  12. package/dist/chunk-X5IPL32H.js.map +1 -0
  13. package/dist/cli/bin.cjs +3972 -0
  14. package/dist/cli/bin.cjs.map +1 -0
  15. package/dist/cli/bin.d.cts +1 -0
  16. package/dist/cli/bin.d.ts +1 -0
  17. package/dist/cli/bin.js +43 -0
  18. package/dist/cli/bin.js.map +1 -0
  19. package/dist/cli/index.cjs +1672 -0
  20. package/dist/cli/index.cjs.map +1 -0
  21. package/dist/cli/index.d.cts +31 -0
  22. package/dist/cli/index.d.ts +31 -0
  23. package/dist/cli/index.js +17 -0
  24. package/dist/cli/index.js.map +1 -0
  25. package/dist/cli/mcp-args.cjs +129 -0
  26. package/dist/cli/mcp-args.cjs.map +1 -0
  27. package/dist/cli/mcp-args.d.cts +32 -0
  28. package/dist/cli/mcp-args.d.ts +32 -0
  29. package/dist/cli/mcp-args.js +10 -0
  30. package/dist/cli/mcp-args.js.map +1 -0
  31. package/dist/components.cjs +53 -0
  32. package/dist/components.cjs.map +1 -0
  33. package/dist/components.d.cts +27 -0
  34. package/dist/components.d.ts +27 -0
  35. package/dist/components.js +26 -0
  36. package/dist/components.js.map +1 -0
  37. package/dist/core-CD4jHGgI.d.cts +51 -0
  38. package/dist/core-CZvnc0rE.d.ts +51 -0
  39. package/dist/core.cjs +1576 -0
  40. package/dist/core.cjs.map +1 -0
  41. package/dist/core.d.cts +3 -0
  42. package/dist/core.d.ts +3 -0
  43. package/dist/core.js +32 -0
  44. package/dist/core.js.map +1 -0
  45. package/dist/index-BjYQX_hK.d.ts +8 -0
  46. package/dist/index-Cabk31qi.d.cts +8 -0
  47. package/dist/index.cjs +3318 -0
  48. package/dist/index.cjs.map +1 -0
  49. package/dist/index.d.cts +94 -0
  50. package/dist/index.d.ts +94 -0
  51. package/dist/index.js +285 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/mcp/index.cjs +3467 -0
  54. package/dist/mcp/index.cjs.map +1 -0
  55. package/dist/mcp/index.d.cts +26 -0
  56. package/dist/mcp/index.d.ts +26 -0
  57. package/dist/mcp/index.js +586 -0
  58. package/dist/mcp/index.js.map +1 -0
  59. package/dist/teardown.cjs +1509 -0
  60. package/dist/teardown.cjs.map +1 -0
  61. package/dist/teardown.d.cts +5 -0
  62. package/dist/teardown.d.ts +5 -0
  63. package/dist/teardown.js +52 -0
  64. package/dist/teardown.js.map +1 -0
  65. package/dist/types-G7w4n8kR.d.cts +359 -0
  66. package/dist/types-G7w4n8kR.d.ts +359 -0
  67. package/package.json +109 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/report/story-utils.ts","../src/report/html-reporter.ts","../src/report/markdown-reporter.ts","../src/report/mdx-reporter.ts","../src/report/annotate.ts","../src/report/index.ts"],"sourcesContent":["import type { RunRecord } from '../types';\n\nexport function groupByStory(runs: RunRecord[]): Map<string, RunRecord[]> {\n const stories = new Map<string, RunRecord[]>();\n\n for (const run of runs) {\n const existing = stories.get(run.title) ?? [];\n existing.push(run);\n stories.set(run.title, existing);\n }\n\n return stories;\n}\n\nexport function orderedCheckpointNames(runs: RunRecord[]): string[] {\n const names: string[] = [];\n const seen = new Set<string>();\n\n for (const run of runs) {\n for (const checkpoint of run.checkpoints) {\n if (seen.has(checkpoint.name)) {\n continue;\n }\n\n seen.add(checkpoint.name);\n names.push(checkpoint.name);\n }\n }\n\n return names;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointRecord, ReportGenerator, RunRecord, ScreenshotCollectorData } from '../types';\nimport { groupByStory, orderedCheckpointNames } from './story-utils';\n\ntype HtmlReporterConfig = {\n title?: string;\n projectOrder?: string[];\n};\n\nconst DEFAULT_PROJECT_ORDER = ['desktop-light', 'desktop-dark', 'mobile-light', 'mobile-dark'];\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;');\n}\n\nfunction slugify(value: string): string {\n return (\n value\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'story'\n );\n}\n\nfunction formatDateTime(isoDate: string): string {\n const date = new Date(isoDate);\n if (Number.isNaN(date.getTime())) {\n return isoDate;\n }\n\n return new Intl.DateTimeFormat('en-US', {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date);\n}\n\nfunction projectWeight(projectName: string, projectOrder: string[]): number {\n const index = projectOrder.indexOf(projectName);\n return index === -1 ? Number.MAX_SAFE_INTEGER : index;\n}\n\nfunction formatProjectLabel(projectName: string): string {\n const [device, mode] = projectName.split('-');\n if (!device || !mode) {\n return projectName;\n }\n\n const deviceLabel = device === 'desktop' ? 'Desktop' : device === 'mobile' ? 'Mobile' : device;\n const modeLabel = mode === 'light' ? 'Light' : mode === 'dark' ? 'Dark' : mode;\n return `${deviceLabel} / ${modeLabel}`;\n}\n\nfunction sortByProjectAndTime(a: RunRecord, b: RunRecord, projectOrder: string[]): number {\n const byProject = projectWeight(a.project, projectOrder) - projectWeight(b.project, projectOrder);\n if (byProject !== 0) {\n return byProject;\n }\n\n const byProjectName = a.project.localeCompare(b.project);\n if (byProjectName !== 0) {\n return byProjectName;\n }\n\n return new Date(a.startedAt).getTime() - new Date(b.startedAt).getTime();\n}\n\nfunction getCollectorSummaryNumber(checkpoint: CheckpointRecord, collectorName: string, key: string): number | null {\n const value = checkpoint.collectors[collectorName]?.summary[key];\n return typeof value === 'number' ? value : null;\n}\n\nfunction screenshotData(checkpoint: CheckpointRecord): Partial<ScreenshotCollectorData> | null {\n const data = checkpoint.collectors.screenshot?.data;\n return data && typeof data === 'object' ? (data as Partial<ScreenshotCollectorData>) : null;\n}\n\nfunction highlightOverlayStyle(checkpoint: CheckpointRecord): string | null {\n const data = screenshotData(checkpoint);\n const bounds = data?.highlightBounds;\n const imageSize = data?.imageSize;\n\n if (\n !bounds ||\n !imageSize ||\n typeof bounds.x !== 'number' ||\n typeof bounds.y !== 'number' ||\n typeof bounds.width !== 'number' ||\n typeof bounds.height !== 'number' ||\n typeof imageSize.width !== 'number' ||\n typeof imageSize.height !== 'number' ||\n imageSize.width <= 0 ||\n imageSize.height <= 0\n ) {\n return null;\n }\n\n const left = (bounds.x / imageSize.width) * 100;\n const top = (bounds.y / imageSize.height) * 100;\n const width = (bounds.width / imageSize.width) * 100;\n const height = (bounds.height / imageSize.height) * 100;\n\n return [\n `left:${left.toFixed(4)}%`,\n `top:${top.toFixed(4)}%`,\n `width:${width.toFixed(4)}%`,\n `height:${height.toFixed(4)}%`,\n ].join(';');\n}\n\nfunction highlightLabel(checkpoint: CheckpointRecord): string | null {\n const selector = screenshotData(checkpoint)?.highlightSelector;\n return typeof selector === 'string' && selector.trim().length > 0 ? `Focus: ${selector.trim()}` : null;\n}\n\nfunction resolveArtifactPath(run: RunRecord, artifactPath: string): string {\n return path.isAbsolute(artifactPath) ? artifactPath : path.resolve(path.dirname(run.sourceManifestPath), artifactPath);\n}\n\nfunction toEncodedHref(outputDir: string, filePath: string | null): string | null {\n if (!filePath) {\n return null;\n }\n\n const relativePath = path.relative(outputDir, filePath);\n return relativePath.split(path.sep).map(encodeURIComponent).join('/');\n}\n\nfunction getArtifactHref(\n run: RunRecord,\n checkpoint: CheckpointRecord,\n outputDir: string,\n collectorName: string,\n artifactName?: string,\n): string | null {\n const artifacts = checkpoint.collectors[collectorName]?.artifacts ?? [];\n const artifact = artifactName\n ? artifacts.find((entry) => entry.name === artifactName)\n : artifacts[0];\n\n if (!artifact?.path) {\n return null;\n }\n\n return toEncodedHref(outputDir, resolveArtifactPath(run, artifact.path));\n}\n\nfunction renderArtifactLinks(run: RunRecord, checkpoint: CheckpointRecord, outputDir: string): string {\n const links: Array<{ label: string; href: string | null }> = [\n { label: 'DOM HTML', href: getArtifactHref(run, checkpoint, outputDir, 'html', 'html') },\n { label: 'Axe', href: getArtifactHref(run, checkpoint, outputDir, 'axe', 'axe') },\n { label: 'Web Vitals', href: getArtifactHref(run, checkpoint, outputDir, 'web-vitals', 'web-vitals') },\n { label: 'Console', href: getArtifactHref(run, checkpoint, outputDir, 'console', 'console-errors') },\n { label: 'Failed Requests', href: getArtifactHref(run, checkpoint, outputDir, 'network', 'failed-requests') },\n ];\n\n return links\n .map((link) => {\n if (!link.href) {\n return `<span class=\"artifact disabled\">${escapeHtml(link.label)}</span>`;\n }\n\n return `<a class=\"artifact\" href=\"${link.href}\" target=\"_blank\" rel=\"noreferrer\">${escapeHtml(link.label)}</a>`;\n })\n .join('');\n}\n\nfunction renderCheckpointCard(run: RunRecord, checkpointName: string, outputDir: string): string {\n const checkpoint = run.checkpoints.find((entry) => entry.name === checkpointName);\n if (!checkpoint) {\n return `\n <article class=\"variant-card missing\">\n <header class=\"variant-card-header\">\n <div>\n <h5>${escapeHtml(formatProjectLabel(run.project))}</h5>\n <p>${escapeHtml(run.project)}</p>\n </div>\n <time>${escapeHtml(formatDateTime(run.startedAt))}</time>\n </header>\n <div class=\"empty-card\">No checkpoint captured for this run.</div>\n </article>\n `;\n }\n\n const screenshotHref = getArtifactHref(run, checkpoint, outputDir, 'screenshot', 'screenshot');\n const overlayStyle = highlightOverlayStyle(checkpoint);\n const focus = highlightLabel(checkpoint);\n const axeViolations = getCollectorSummaryNumber(checkpoint, 'axe', 'violations');\n const consoleErrors = getCollectorSummaryNumber(checkpoint, 'console', 'consoleErrorCount') ?? 0;\n const failedRequests = getCollectorSummaryNumber(checkpoint, 'network', 'failedRequestCount') ?? 0;\n\n return `\n <article class=\"variant-card\">\n <header class=\"variant-card-header\">\n <div>\n <h5>${escapeHtml(formatProjectLabel(run.project))}</h5>\n <p>${escapeHtml(run.project)}</p>\n </div>\n <time>${escapeHtml(formatDateTime(checkpoint.timestamp || run.startedAt))}</time>\n </header>\n <p class=\"page-meta\">\n <span>${escapeHtml(checkpoint.title || 'Untitled page')}</span>\n <span class=\"page-url\">${escapeHtml(checkpoint.url)}</span>\n </p>\n ${\n screenshotHref\n ? `<a class=\"thumbnail-link\" href=\"${screenshotHref}\" target=\"_blank\" rel=\"noreferrer\">\n <img src=\"${screenshotHref}\" alt=\"${escapeHtml(`${run.project} — ${checkpoint.name}`)}\" loading=\"lazy\" />\n ${overlayStyle ? `<span class=\"highlight-overlay\" style=\"${overlayStyle}\" aria-hidden=\"true\"></span>` : ''}\n ${focus ? `<span class=\"highlight-label\">${escapeHtml(focus)}</span>` : ''}\n </a>`\n : '<div class=\"empty-card\">Screenshot unavailable.</div>'\n }\n <div class=\"stats-grid\">\n <span><strong>${axeViolations ?? 'n/a'}</strong><small>Axe violations</small></span>\n <span><strong>${consoleErrors}</strong><small>Console errors</small></span>\n <span><strong>${failedRequests}</strong><small>Failed requests</small></span>\n </div>\n <div class=\"artifact-list\">${renderArtifactLinks(run, checkpoint, outputDir)}</div>\n </article>\n `;\n}\n\nfunction renderStorySection(title: string, runs: RunRecord[], outputDir: string): string {\n const checkpointNames = orderedCheckpointNames(runs);\n const environments = [...new Set(runs.map((run) => run.environment))].sort();\n const tags = [...new Set(runs.flatMap((run) => run.tags))].sort();\n\n const checkpointBlocks = checkpointNames\n .map(\n (checkpointName) => `\n <details class=\"accordion checkpoint-block\">\n <summary class=\"checkpoint-summary\">\n <span>${escapeHtml(checkpointName)}</span>\n <span class=\"checkpoint-meta\">${runs.length} variants</span>\n </summary>\n <div class=\"variant-grid\">\n ${runs.map((run) => renderCheckpointCard(run, checkpointName, outputDir)).join('')}\n </div>\n </details>\n `,\n )\n .join('');\n\n return `\n <details class=\"accordion story-block\" id=\"story-${slugify(title)}\" open>\n <summary class=\"story-summary\">\n <span class=\"story-title\">${escapeHtml(title)}</span>\n <span class=\"story-meta-chip\">${runs.length} run${runs.length === 1 ? '' : 's'}</span>\n </summary>\n <div class=\"story-body\">\n <div class=\"story-meta-row\">\n <span><strong>Projects</strong> ${escapeHtml(runs.map((run) => run.project).join(', '))}</span>\n <span><strong>Environments</strong> ${escapeHtml(environments.join(', ') || 'n/a')}</span>\n <span><strong>Tags</strong> ${escapeHtml(tags.join(', ') || 'none')}</span>\n </div>\n ${checkpointBlocks || '<p class=\"empty-state\">No checkpoints captured for this story.</p>'}\n </div>\n </details>\n `;\n}\n\nfunction buildHtmlReport(runs: RunRecord[], outputDir: string, config: HtmlReporterConfig): string {\n const groupedRuns = groupByStory(runs);\n const storyTitles = [...groupedRuns.keys()].sort((a, b) => a.localeCompare(b));\n const projectOrder = Array.isArray(config.projectOrder)\n ? config.projectOrder.filter((value): value is string => typeof value === 'string')\n : DEFAULT_PROJECT_ORDER;\n const generatedAt = new Date().toISOString();\n const reportTitle = typeof config.title === 'string' && config.title.trim() ? config.title.trim() : 'Playwright Checkpoint Report';\n\n for (const title of storyTitles) {\n groupedRuns.get(title)?.sort((a, b) => sortByProjectAndTime(a, b, projectOrder));\n }\n\n const navLinks = storyTitles\n .map((title) => `<a href=\"#story-${slugify(title)}\">${escapeHtml(title)}</a>`)\n .join('');\n\n const storySections = storyTitles\n .map((title) => renderStorySection(title, groupedRuns.get(title) ?? [], outputDir))\n .join('');\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${escapeHtml(reportTitle)}</title>\n <style>\n :root {\n color-scheme: dark;\n --bg: #0b1020;\n --panel: rgba(15, 23, 42, 0.88);\n --panel-2: rgba(17, 25, 40, 0.98);\n --text: #e5eefb;\n --muted: #9fb3c8;\n --accent: #60a5fa;\n --accent-2: #22d3ee;\n --border: rgba(148, 163, 184, 0.18);\n --success: #34d399;\n --warning: #fbbf24;\n --danger: #fb7185;\n --shadow: 0 24px 64px rgba(2, 6, 23, 0.45);\n }\n * { box-sizing: border-box; }\n html { scroll-behavior: smooth; }\n body {\n margin: 0;\n min-height: 100vh;\n font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n background:\n radial-gradient(circle at top, rgba(96, 165, 250, 0.14), transparent 30%),\n linear-gradient(180deg, #07101f 0%, #0b1020 100%);\n color: var(--text);\n }\n a { color: inherit; }\n .page {\n width: min(1600px, calc(100vw - 32px));\n margin: 0 auto;\n padding: 28px 0 56px;\n }\n .hero {\n background: linear-gradient(180deg, rgba(15, 23, 42, 0.96), rgba(15, 23, 42, 0.84));\n border: 1px solid var(--border);\n border-radius: 24px;\n padding: 24px;\n box-shadow: var(--shadow);\n backdrop-filter: blur(18px);\n }\n .hero h1 {\n margin: 0;\n font-size: clamp(1.9rem, 2.6vw, 3rem);\n line-height: 1.1;\n }\n .hero p {\n margin: 10px 0 0;\n color: var(--muted);\n max-width: 72ch;\n line-height: 1.6;\n }\n .summary-bar {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n margin-top: 18px;\n }\n .summary-pill {\n display: inline-flex;\n gap: 8px;\n align-items: center;\n padding: 9px 12px;\n border: 1px solid var(--border);\n border-radius: 999px;\n background: rgba(15, 23, 42, 0.72);\n color: var(--muted);\n font-size: 0.92rem;\n }\n .summary-pill strong { color: var(--text); }\n .toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n gap: 16px;\n margin-top: 18px;\n padding-top: 18px;\n border-top: 1px solid var(--border);\n }\n .story-nav {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n }\n .story-nav a,\n .toolbar button,\n .artifact {\n border: 1px solid var(--border);\n border-radius: 999px;\n background: rgba(15, 23, 42, 0.7);\n color: var(--text);\n text-decoration: none;\n padding: 8px 12px;\n font: inherit;\n font-size: 0.86rem;\n transition: transform 140ms ease, border-color 140ms ease, background 140ms ease;\n }\n .toolbar button:hover,\n .story-nav a:hover,\n .artifact:hover {\n transform: translateY(-1px);\n border-color: rgba(96, 165, 250, 0.55);\n background: rgba(30, 41, 59, 0.96);\n cursor: pointer;\n }\n .content {\n display: grid;\n gap: 18px;\n margin-top: 22px;\n }\n .accordion {\n border: 1px solid var(--border);\n border-radius: 22px;\n background: var(--panel);\n box-shadow: var(--shadow);\n overflow: hidden;\n }\n .accordion summary {\n list-style: none;\n cursor: pointer;\n }\n .accordion summary::-webkit-details-marker { display: none; }\n .story-summary,\n .checkpoint-summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n }\n .story-summary {\n padding: 20px 22px;\n background: linear-gradient(180deg, rgba(15, 23, 42, 0.92), rgba(15, 23, 42, 0.74));\n }\n .story-title {\n font-size: 1.1rem;\n font-weight: 700;\n }\n .story-meta-chip,\n .checkpoint-meta {\n color: var(--muted);\n font-size: 0.84rem;\n white-space: nowrap;\n }\n .story-body {\n padding: 0 22px 22px;\n }\n .story-meta-row {\n display: flex;\n flex-wrap: wrap;\n gap: 16px;\n color: var(--muted);\n font-size: 0.92rem;\n line-height: 1.5;\n margin: 4px 0 18px;\n }\n .story-meta-row strong { color: var(--text); margin-right: 6px; }\n .checkpoint-block {\n margin-top: 14px;\n border-radius: 18px;\n background: var(--panel-2);\n border: 1px solid rgba(148, 163, 184, 0.14);\n }\n .checkpoint-summary {\n padding: 16px 18px;\n font-weight: 600;\n background: rgba(15, 23, 42, 0.68);\n }\n .variant-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 14px;\n padding: 0 18px 18px;\n }\n .variant-card {\n display: grid;\n gap: 12px;\n border: 1px solid rgba(148, 163, 184, 0.14);\n border-radius: 18px;\n background: rgba(15, 23, 42, 0.72);\n padding: 16px;\n min-height: 100%;\n }\n .variant-card.missing {\n opacity: 0.72;\n border-style: dashed;\n }\n .variant-card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 10px;\n }\n .variant-card-header h5 {\n margin: 0;\n font-size: 1rem;\n }\n .variant-card-header p,\n .variant-card-header time {\n margin: 4px 0 0;\n color: var(--muted);\n font-size: 0.83rem;\n }\n .page-meta {\n display: grid;\n gap: 4px;\n margin: 0;\n color: var(--muted);\n font-size: 0.9rem;\n }\n .page-url {\n overflow-wrap: anywhere;\n font-size: 0.82rem;\n }\n .thumbnail-link {\n position: relative;\n display: block;\n border-radius: 14px;\n overflow: hidden;\n border: 1px solid rgba(148, 163, 184, 0.18);\n background: rgba(2, 6, 23, 0.65);\n }\n .thumbnail-link img {\n display: block;\n width: 100%;\n aspect-ratio: 16 / 10;\n object-fit: cover;\n }\n .highlight-overlay {\n position: absolute;\n border: 2px solid var(--danger);\n border-radius: 12px;\n background: rgba(251, 113, 133, 0.08);\n box-shadow: 0 0 0 999px rgba(251, 113, 133, 0.02);\n pointer-events: none;\n }\n .highlight-label {\n position: absolute;\n left: 12px;\n bottom: 12px;\n max-width: calc(100% - 24px);\n padding: 6px 9px;\n border-radius: 999px;\n background: rgba(15, 23, 42, 0.9);\n border: 1px solid rgba(251, 113, 133, 0.35);\n color: #ffe4e6;\n font-size: 0.74rem;\n line-height: 1.3;\n overflow-wrap: anywhere;\n }\n .stats-grid {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 10px;\n }\n .stats-grid span {\n display: grid;\n gap: 6px;\n padding: 10px 12px;\n border-radius: 14px;\n background: rgba(2, 6, 23, 0.42);\n border: 1px solid rgba(148, 163, 184, 0.12);\n }\n .stats-grid strong {\n font-size: 1.15rem;\n line-height: 1;\n }\n .stats-grid small {\n color: var(--muted);\n font-size: 0.76rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n .artifact-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n }\n .artifact.disabled {\n opacity: 0.45;\n pointer-events: none;\n }\n .empty-state,\n .empty-card {\n margin: 0;\n color: var(--muted);\n padding: 12px;\n border: 1px dashed rgba(148, 163, 184, 0.2);\n border-radius: 14px;\n background: rgba(2, 6, 23, 0.24);\n }\n @media (max-width: 720px) {\n .page {\n width: min(100vw - 20px, 1600px);\n padding-top: 18px;\n }\n .hero,\n .story-summary,\n .story-body,\n .checkpoint-summary,\n .variant-grid {\n padding-left: 16px;\n padding-right: 16px;\n }\n .variant-card-header,\n .story-summary,\n .checkpoint-summary,\n .toolbar {\n flex-direction: column;\n align-items: flex-start;\n }\n .stats-grid {\n grid-template-columns: 1fr;\n }\n }\n </style>\n</head>\n<body>\n <main class=\"page\">\n <section class=\"hero\">\n <h1>${escapeHtml(reportTitle)}</h1>\n <p>Explore checkpoint runs by story, inspect every project variant side-by-side, and jump directly to screenshots and generated artifacts.</p>\n <div class=\"summary-bar\">\n <span class=\"summary-pill\"><strong>Generated</strong> ${escapeHtml(formatDateTime(generatedAt))}</span>\n <span class=\"summary-pill\"><strong>Stories</strong> ${storyTitles.length}</span>\n <span class=\"summary-pill\"><strong>Runs</strong> ${runs.length}</span>\n <span class=\"summary-pill\"><strong>Output</strong> ${escapeHtml(outputDir)}</span>\n </div>\n <div class=\"toolbar\">\n <nav class=\"story-nav\">${navLinks || '<span class=\"summary-pill\">No stories found</span>'}</nav>\n <div class=\"toolbar-actions\">\n <button type=\"button\" data-action=\"expand-all\">Expand all</button>\n <button type=\"button\" data-action=\"collapse-all\">Collapse all</button>\n </div>\n </div>\n </section>\n <section class=\"content\">\n ${storySections || '<p class=\"empty-state\">No checkpoint manifests found.</p>'}\n </section>\n </main>\n <script>\n (() => {\n const details = Array.from(document.querySelectorAll('details.accordion'));\n const setAll = (open) => {\n details.forEach((entry) => {\n entry.open = open;\n });\n };\n document.querySelector('[data-action=\"expand-all\"]')?.addEventListener('click', () => setAll(true));\n document.querySelector('[data-action=\"collapse-all\"]')?.addEventListener('click', () => setAll(false));\n const revealHash = () => {\n if (!window.location.hash) {\n return;\n }\n const target = document.querySelector(window.location.hash);\n if (!(target instanceof HTMLElement)) {\n return;\n }\n const parentDetails = target.closest('details');\n if (parentDetails instanceof HTMLDetailsElement) {\n parentDetails.open = true;\n }\n target.scrollIntoView({ block: 'start', behavior: 'smooth' });\n };\n window.addEventListener('hashchange', revealHash);\n revealHash();\n })();\n </script>\n</body>\n</html>\n`;\n}\n\nexport const htmlReporter: ReportGenerator = {\n name: 'html',\n description: 'Responsive HTML report for checkpoint manifests.',\n\n validateConfig(config): boolean {\n return config != null && typeof config === 'object' && !Array.isArray(config);\n },\n\n async generate(context) {\n const outputFile = path.join(context.outputDir, 'index.html');\n const html = buildHtmlReport(context.runs, context.outputDir, context.config as HtmlReporterConfig);\n\n await fs.mkdir(context.outputDir, { recursive: true });\n await fs.writeFile(outputFile, html, 'utf8');\n\n const storyCount = new Set(context.runs.map((run) => run.title)).size;\n\n return {\n files: [outputFile],\n summary: `Generated HTML report for ${storyCount} stor${storyCount === 1 ? 'y' : 'ies'} (${context.runs.length} run${context.runs.length === 1 ? '' : 's'}).`,\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointRecord, ReportGenerator, RunRecord, ScreenshotCollectorData } from '../types';\nimport { groupByStory } from './story-utils';\n\ntype MarkdownReporterConfig = {\n storiesDir?: string;\n screenshotsDir?: string;\n includeTags?: string[];\n preferredProject?: string;\n header?: string;\n footer?: string;\n frontmatter?: boolean | Record<string, unknown>;\n imagePathPrefix?: string;\n copyScreenshots?: boolean;\n};\n\ntype MarkdownStep = {\n checkpoint: CheckpointRecord;\n order: number;\n heading: string;\n description: string;\n imagePath: string | null;\n urlLabel: string;\n breadcrumbLabel: string | null;\n focusNote: string | null;\n};\n\nfunction slugify(value: string): string {\n return (\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'story'\n );\n}\n\nfunction stripTags(value: string): string {\n const stripped = value.replace(/\\s+@[a-z0-9-]+/gi, ' ').replace(/\\s+/g, ' ').trim();\n return stripped || value.trim() || 'Untitled story';\n}\n\nfunction normalizeConfig(config: Record<string, unknown>): MarkdownReporterConfig {\n return {\n storiesDir: typeof config.storiesDir === 'string' ? config.storiesDir : '.',\n screenshotsDir: typeof config.screenshotsDir === 'string' ? config.screenshotsDir : 'screenshots',\n includeTags: Array.isArray(config.includeTags)\n ? config.includeTags.filter((value): value is string => typeof value === 'string')\n : undefined,\n preferredProject: typeof config.preferredProject === 'string' ? config.preferredProject : undefined,\n header: typeof config.header === 'string' ? config.header : undefined,\n footer: typeof config.footer === 'string' ? config.footer : undefined,\n frontmatter:\n config.frontmatter === true ||\n config.frontmatter === false ||\n (config.frontmatter != null && typeof config.frontmatter === 'object' && !Array.isArray(config.frontmatter))\n ? (config.frontmatter as MarkdownReporterConfig['frontmatter'])\n : false,\n imagePathPrefix: typeof config.imagePathPrefix === 'string' ? config.imagePathPrefix : undefined,\n copyScreenshots: typeof config.copyScreenshots === 'boolean' ? config.copyScreenshots : true,\n };\n}\n\nfunction normalizeTags(tags: string[] | undefined): string[] {\n return (tags ?? []).map((tag) => tag.trim().toLowerCase()).filter(Boolean);\n}\n\nfunction shouldIncludeRun(run: RunRecord, config: MarkdownReporterConfig): boolean {\n const includeTags = normalizeTags(config.includeTags);\n if (includeTags.length > 0) {\n const runTags = new Set(normalizeTags(run.tags));\n return includeTags.some((tag) => runTags.has(tag));\n }\n\n return run.checkpoints.some((checkpoint) => {\n const hasDescription = typeof checkpoint.description === 'string' && checkpoint.description.trim().length > 0;\n return hasDescription || typeof checkpoint.step === 'number';\n });\n}\n\nfunction choosePrimaryRun(runs: RunRecord[], preferredProject?: string): RunRecord | null {\n if (runs.length === 0) {\n return null;\n }\n\n return [...runs].sort((left, right) => {\n const leftPreferred = preferredProject && left.project === preferredProject ? 0 : 1;\n const rightPreferred = preferredProject && right.project === preferredProject ? 0 : 1;\n if (leftPreferred !== rightPreferred) {\n return leftPreferred - rightPreferred;\n }\n\n const rightTime = new Date(right.startedAt).getTime();\n const leftTime = new Date(left.startedAt).getTime();\n if (rightTime !== leftTime) {\n return rightTime - leftTime;\n }\n\n return left.project.localeCompare(right.project);\n })[0] ?? null;\n}\n\nfunction resolveArtifactPath(run: RunRecord, artifactPath: string): string {\n return path.isAbsolute(artifactPath) ? artifactPath : path.resolve(path.dirname(run.sourceManifestPath), artifactPath);\n}\n\nfunction screenshotSourcePath(run: RunRecord, checkpoint: CheckpointRecord): string | null {\n const artifacts = checkpoint.collectors.screenshot?.artifacts ?? [];\n const artifact = artifacts.find((entry) => entry.name === 'screenshot') ?? artifacts[0];\n return artifact?.path ? resolveArtifactPath(run, artifact.path) : null;\n}\n\nfunction screenshotData(checkpoint: CheckpointRecord): Partial<ScreenshotCollectorData> | null {\n const data = checkpoint.collectors.screenshot?.data;\n return data && typeof data === 'object' ? (data as Partial<ScreenshotCollectorData>) : null;\n}\n\nfunction focusNote(checkpoint: CheckpointRecord): string | null {\n const data = screenshotData(checkpoint);\n const selector = typeof data?.highlightSelector === 'string' ? data.highlightSelector.trim() : '';\n if (selector) {\n return `Focus: \\`${selector}\\``;\n }\n\n const bounds = data?.highlightBounds;\n if (\n bounds &&\n typeof bounds.x === 'number' &&\n typeof bounds.y === 'number' &&\n typeof bounds.width === 'number' &&\n typeof bounds.height === 'number'\n ) {\n return 'Focus: highlighted UI element.';\n }\n\n return null;\n}\n\nfunction urlLabel(url: string): string {\n try {\n const parsed = new URL(url);\n const value = `${parsed.pathname}${parsed.search}${parsed.hash}`;\n return value || '/';\n } catch {\n return url || '/';\n }\n}\n\nfunction breadcrumbLabel(url: string): string | null {\n const label = urlLabel(url);\n if (!label.startsWith('/')) {\n return null;\n }\n\n const [withoutQuery = label] = label.split('?');\n const [withoutHash = withoutQuery] = withoutQuery.split('#');\n\n const segments = withoutHash\n .split('/')\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => decodeURIComponent(segment).replace(/[-_]+/g, ' '));\n\n return segments.length > 0 ? segments.join(' › ') : 'home';\n}\n\nfunction autoDescription(checkpoint: CheckpointRecord): string {\n const pageTitle = checkpoint.title.trim();\n const location = urlLabel(checkpoint.url);\n\n if (pageTitle) {\n return `This step captures **${pageTitle}** at \\`${location}\\`.`;\n }\n\n return `This step captures **${checkpoint.name}** at \\`${location}\\`.`;\n}\n\nfunction markdownRelativePath(fromFile: string, toFile: string): string {\n const relativePath = path.relative(path.dirname(fromFile), toFile).split(path.sep).join('/');\n if (relativePath.startsWith('.')) {\n return relativePath;\n }\n\n return `./${relativePath}`;\n}\n\nfunction rewriteImagePath(markdownFile: string, imageFile: string, outputDir: string, prefix?: string): string {\n const relativePath = path.relative(outputDir, imageFile).split(path.sep).join('/');\n if (prefix) {\n return `${prefix.replace(/\\/+$/g, '')}/${relativePath.replace(/^\\/+/, '')}`;\n }\n\n return markdownRelativePath(markdownFile, imageFile);\n}\n\nfunction yamlScalar(value: unknown): string {\n return JSON.stringify(value);\n}\n\nfunction serializeFrontmatter(fields: Record<string, unknown>): string {\n const lines = ['---'];\n\n for (const [key, value] of Object.entries(fields)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n lines.push(`${key}:`);\n if (value.length === 0) {\n lines.push(' []');\n continue;\n }\n\n for (const item of value) {\n lines.push(` - ${yamlScalar(item)}`);\n }\n continue;\n }\n\n lines.push(`${key}: ${yamlScalar(value)}`);\n }\n\n lines.push('---', '');\n return lines.join('\\n');\n}\n\nasync function materializeScreenshot(args: {\n run: RunRecord;\n checkpoint: CheckpointRecord;\n storySlug: string;\n stepOrder: number;\n outputDir: string;\n markdownFile: string;\n config: MarkdownReporterConfig;\n writtenFiles: Set<string>;\n}): Promise<string | null> {\n const sourcePath = screenshotSourcePath(args.run, args.checkpoint);\n if (!sourcePath) {\n return null;\n }\n\n const extension = path.extname(sourcePath) || '.png';\n const targetPath = path.join(\n args.outputDir,\n args.config.screenshotsDir ?? 'screenshots',\n args.storySlug,\n `${String(args.stepOrder).padStart(2, '0')}-${slugify(args.checkpoint.name)}${extension}`,\n );\n\n try {\n if (args.config.copyScreenshots !== false) {\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\n await fs.copyFile(sourcePath, targetPath);\n args.writtenFiles.add(targetPath);\n return rewriteImagePath(args.markdownFile, targetPath, args.outputDir, args.config.imagePathPrefix);\n }\n\n return rewriteImagePath(args.markdownFile, sourcePath, args.outputDir, args.config.imagePathPrefix);\n } catch {\n return null;\n }\n}\n\nfunction orderedCheckpoints(checkpoints: CheckpointRecord[]): CheckpointRecord[] {\n return [...checkpoints].sort((left, right) => {\n const leftOrder = typeof left.step === 'number' ? left.step : Number.MAX_SAFE_INTEGER;\n const rightOrder = typeof right.step === 'number' ? right.step : Number.MAX_SAFE_INTEGER;\n if (leftOrder !== rightOrder) {\n return leftOrder - rightOrder;\n }\n\n return checkpoints.indexOf(left) - checkpoints.indexOf(right);\n });\n}\n\nasync function buildSteps(args: {\n run: RunRecord;\n storySlug: string;\n outputDir: string;\n markdownFile: string;\n config: MarkdownReporterConfig;\n writtenFiles: Set<string>;\n}): Promise<MarkdownStep[]> {\n const checkpoints = orderedCheckpoints(args.run.checkpoints);\n const steps: MarkdownStep[] = [];\n\n for (const [index, checkpoint] of checkpoints.entries()) {\n const order = typeof checkpoint.step === 'number' ? checkpoint.step : index + 1;\n steps.push({\n checkpoint,\n order,\n heading: checkpoint.name,\n description:\n typeof checkpoint.description === 'string' && checkpoint.description.trim().length > 0\n ? checkpoint.description.trim()\n : autoDescription(checkpoint),\n imagePath: await materializeScreenshot({\n run: args.run,\n checkpoint,\n storySlug: args.storySlug,\n stepOrder: order,\n outputDir: args.outputDir,\n markdownFile: args.markdownFile,\n config: args.config,\n writtenFiles: args.writtenFiles,\n }),\n urlLabel: urlLabel(checkpoint.url),\n breadcrumbLabel: breadcrumbLabel(checkpoint.url),\n focusNote: focusNote(checkpoint),\n });\n }\n\n return steps;\n}\n\nfunction renderMarkdown(args: {\n title: string;\n steps: MarkdownStep[];\n run: RunRecord;\n config: MarkdownReporterConfig;\n generatedAt: string;\n}): string {\n const frontmatterFields =\n args.config.frontmatter === true || typeof args.config.frontmatter === 'object'\n ? {\n title: args.title,\n project: args.run.project,\n testId: args.run.testId,\n tags: args.run.tags,\n startedAt: args.run.startedAt,\n generatedAt: args.generatedAt,\n ...(args.config.frontmatter && typeof args.config.frontmatter === 'object' ? args.config.frontmatter : {}),\n }\n : null;\n\n const sections = args.steps\n .map((step) => {\n const lines = [`## Step ${step.order}: ${step.heading}`, ''];\n\n if (step.imagePath) {\n lines.push(`![${step.checkpoint.title || step.heading}](${step.imagePath})`, '');\n }\n\n lines.push(`**URL:** \\`${step.urlLabel}\\``);\n if (step.breadcrumbLabel) {\n lines.push('', `**Breadcrumb:** ${step.breadcrumbLabel}`);\n }\n\n if (step.focusNote) {\n lines.push('', `> ${step.focusNote}`);\n }\n\n lines.push('', step.description);\n\n return lines.join('\\n');\n })\n .join('\\n\\n');\n\n const parts = [\n frontmatterFields ? serializeFrontmatter(frontmatterFields) : '',\n `# ${args.title}`,\n args.config.header ? args.config.header.trim() : '',\n sections,\n args.config.footer ? args.config.footer.trim() : '',\n ].filter((value) => value.trim().length > 0);\n\n return `${parts.join('\\n\\n')}\\n`;\n}\n\nexport const markdownReporter: ReportGenerator = {\n name: 'markdown',\n description: 'Generates one Markdown help article per captured story.',\n\n validateConfig(config): boolean {\n return config != null && typeof config === 'object' && !Array.isArray(config);\n },\n\n async generate(context) {\n const config = normalizeConfig(context.config);\n const stories = groupByStory(context.runs);\n const generatedAt = new Date().toISOString();\n const writtenFiles = new Set<string>();\n let articleCount = 0;\n\n for (const [storyTitle, runs] of stories) {\n const primaryRun = choosePrimaryRun(runs, config.preferredProject);\n if (!primaryRun || !shouldIncludeRun(primaryRun, config)) {\n continue;\n }\n\n const title = stripTags(storyTitle);\n const storySlug = slugify(title);\n const markdownFile = path.join(context.outputDir, config.storiesDir ?? '.', `${storySlug}.md`);\n const steps = await buildSteps({\n run: primaryRun,\n storySlug,\n outputDir: context.outputDir,\n markdownFile,\n config,\n writtenFiles,\n });\n\n await fs.mkdir(path.dirname(markdownFile), { recursive: true });\n await fs.writeFile(\n markdownFile,\n renderMarkdown({\n title,\n steps,\n run: primaryRun,\n config,\n generatedAt,\n }),\n 'utf8',\n );\n\n writtenFiles.add(markdownFile);\n articleCount += 1;\n }\n\n return {\n files: [...writtenFiles],\n summary: `Generated ${articleCount} Markdown article${articleCount === 1 ? '' : 's'}.`,\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointRecord, ReportGenerator, RunRecord, ScreenshotCollectorData } from '../types';\nimport { groupByStory } from './story-utils';\n\ntype MdxReporterConfig = {\n storiesDir?: string;\n screenshotsDir?: string;\n includeTags?: string[];\n preferredProject?: string;\n imagePathPrefix?: string;\n copyScreenshots?: boolean;\n componentImportPath?: string;\n};\n\ntype MdxVariant = {\n project: string;\n projectLabel: string;\n imagePath: string | null;\n imageAlt: string;\n};\n\ntype MdxStep = {\n checkpoint: CheckpointRecord;\n order: number;\n title: string;\n description: string;\n focusNote: string | null;\n variants: MdxVariant[];\n};\n\nconst DEFAULT_PROJECT_ORDER = ['desktop-light', 'desktop-dark', 'mobile-light', 'mobile-dark'];\n\nfunction slugify(value: string): string {\n return (\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'story'\n );\n}\n\nfunction stripTags(value: string): string {\n const stripped = value.replace(/\\s+@[a-z0-9-]+/gi, ' ').replace(/\\s+/g, ' ').trim();\n return stripped || value.trim() || 'Untitled story';\n}\n\nfunction normalizeConfig(config: Record<string, unknown>): MdxReporterConfig {\n return {\n storiesDir: typeof config.storiesDir === 'string' ? config.storiesDir : '.',\n screenshotsDir: typeof config.screenshotsDir === 'string' ? config.screenshotsDir : 'screenshots',\n includeTags: Array.isArray(config.includeTags)\n ? config.includeTags.filter((value): value is string => typeof value === 'string')\n : undefined,\n preferredProject: typeof config.preferredProject === 'string' ? config.preferredProject : undefined,\n imagePathPrefix: typeof config.imagePathPrefix === 'string' ? config.imagePathPrefix : undefined,\n copyScreenshots: typeof config.copyScreenshots === 'boolean' ? config.copyScreenshots : true,\n componentImportPath:\n typeof config.componentImportPath === 'string' ? config.componentImportPath : 'playwright-checkpoint/components',\n };\n}\n\nfunction normalizeTags(tags: string[] | undefined): string[] {\n return (tags ?? []).map((tag) => tag.trim().toLowerCase()).filter(Boolean);\n}\n\nfunction frontmatterTags(tags: string[]): string[] {\n return normalizeTags(tags).map((tag) => tag.replace(/^@+/, '')).filter(Boolean);\n}\n\nfunction shouldIncludeRun(run: RunRecord, config: MdxReporterConfig): boolean {\n const includeTags = normalizeTags(config.includeTags);\n if (includeTags.length > 0) {\n const runTags = new Set(normalizeTags(run.tags));\n return includeTags.some((tag) => runTags.has(tag));\n }\n\n return run.checkpoints.some((checkpoint) => {\n const hasDescription = typeof checkpoint.description === 'string' && checkpoint.description.trim().length > 0;\n return hasDescription || typeof checkpoint.step === 'number';\n });\n}\n\nfunction choosePrimaryRun(runs: RunRecord[], preferredProject?: string): RunRecord | null {\n if (runs.length === 0) {\n return null;\n }\n\n return [...runs].sort((left, right) => {\n const leftPreferred = preferredProject && left.project === preferredProject ? 0 : 1;\n const rightPreferred = preferredProject && right.project === preferredProject ? 0 : 1;\n if (leftPreferred !== rightPreferred) {\n return leftPreferred - rightPreferred;\n }\n\n const rightTime = new Date(right.startedAt).getTime();\n const leftTime = new Date(left.startedAt).getTime();\n if (rightTime !== leftTime) {\n return rightTime - leftTime;\n }\n\n return left.project.localeCompare(right.project);\n })[0] ?? null;\n}\n\nfunction orderedCheckpoints(checkpoints: CheckpointRecord[]): CheckpointRecord[] {\n return [...checkpoints].sort((left, right) => {\n const leftOrder = typeof left.step === 'number' ? left.step : Number.MAX_SAFE_INTEGER;\n const rightOrder = typeof right.step === 'number' ? right.step : Number.MAX_SAFE_INTEGER;\n if (leftOrder !== rightOrder) {\n return leftOrder - rightOrder;\n }\n\n return checkpoints.indexOf(left) - checkpoints.indexOf(right);\n });\n}\n\nfunction resolveArtifactPath(run: RunRecord, artifactPath: string): string {\n return path.isAbsolute(artifactPath) ? artifactPath : path.resolve(path.dirname(run.sourceManifestPath), artifactPath);\n}\n\nfunction screenshotSourcePath(run: RunRecord, checkpoint: CheckpointRecord): string | null {\n const artifacts = checkpoint.collectors.screenshot?.artifacts ?? [];\n const artifact = artifacts.find((entry) => entry.name === 'screenshot') ?? artifacts[0];\n return artifact?.path ? resolveArtifactPath(run, artifact.path) : null;\n}\n\nfunction screenshotData(checkpoint: CheckpointRecord): Partial<ScreenshotCollectorData> | null {\n const data = checkpoint.collectors.screenshot?.data;\n return data && typeof data === 'object' ? (data as Partial<ScreenshotCollectorData>) : null;\n}\n\nfunction focusNote(checkpoint: CheckpointRecord): string | null {\n const data = screenshotData(checkpoint);\n const selector = typeof data?.highlightSelector === 'string' ? data.highlightSelector.trim() : '';\n if (selector) {\n return `Focus: \\`${selector}\\``;\n }\n\n const bounds = data?.highlightBounds;\n if (\n bounds &&\n typeof bounds.x === 'number' &&\n typeof bounds.y === 'number' &&\n typeof bounds.width === 'number' &&\n typeof bounds.height === 'number'\n ) {\n return 'Focus: highlighted UI element.';\n }\n\n return null;\n}\n\nfunction urlLabel(url: string): string {\n try {\n const parsed = new URL(url);\n const value = `${parsed.pathname}${parsed.search}${parsed.hash}`;\n return value || '/';\n } catch {\n return url || '/';\n }\n}\n\nfunction autoDescription(checkpoint: CheckpointRecord): string {\n const pageTitle = checkpoint.title.trim();\n const location = urlLabel(checkpoint.url);\n\n if (pageTitle) {\n return `This step captures **${pageTitle}** at \\`${location}\\`.`;\n }\n\n return `This step captures **${checkpoint.name}** at \\`${location}\\`.`;\n}\n\nfunction markdownRelativePath(fromFile: string, toFile: string): string {\n const relativePath = path.relative(path.dirname(fromFile), toFile).split(path.sep).join('/');\n if (relativePath.startsWith('.')) {\n return relativePath;\n }\n\n return `./${relativePath}`;\n}\n\nfunction rewriteImagePath(mdxFile: string, imageFile: string, outputDir: string, prefix?: string): string {\n const relativePath = path.relative(outputDir, imageFile).split(path.sep).join('/');\n if (prefix) {\n return `${prefix.replace(/\\/+$/g, '')}/${relativePath.replace(/^\\/+/, '')}`;\n }\n\n return markdownRelativePath(mdxFile, imageFile);\n}\n\nfunction yamlScalar(value: unknown): string {\n return JSON.stringify(value);\n}\n\nfunction serializeFrontmatter(fields: Record<string, unknown>): string {\n const lines = ['---'];\n\n for (const [key, value] of Object.entries(fields)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n lines.push(`${key}:`);\n if (value.length === 0) {\n lines.push(' []');\n continue;\n }\n\n for (const item of value) {\n lines.push(` - ${yamlScalar(item)}`);\n }\n continue;\n }\n\n lines.push(`${key}: ${yamlScalar(value)}`);\n }\n\n lines.push('---', '');\n return lines.join('\\n');\n}\n\nfunction quoteJsx(value: string): string {\n return JSON.stringify(value);\n}\n\nfunction projectWeight(projectName: string): number {\n const index = DEFAULT_PROJECT_ORDER.indexOf(projectName);\n return index === -1 ? Number.MAX_SAFE_INTEGER : index;\n}\n\nfunction formatProjectLabel(projectName: string): string {\n const [device, mode] = projectName.split('-');\n if (!device || !mode) {\n return projectName;\n }\n\n const deviceLabel = device === 'desktop' ? 'Desktop' : device === 'mobile' ? 'Mobile' : device;\n const modeLabel = mode === 'light' ? 'Light' : mode === 'dark' ? 'Dark' : mode;\n return `${deviceLabel} / ${modeLabel}`;\n}\n\nfunction sortRunsForVariants(runs: RunRecord[]): RunRecord[] {\n return [...runs].sort((left, right) => {\n const byWeight = projectWeight(left.project) - projectWeight(right.project);\n if (byWeight !== 0) {\n return byWeight;\n }\n\n return left.project.localeCompare(right.project);\n });\n}\n\nfunction findMatchingCheckpoint(run: RunRecord, baseCheckpoint: CheckpointRecord, fallbackIndex: number): CheckpointRecord | null {\n const checkpoints = orderedCheckpoints(run.checkpoints);\n\n if (typeof baseCheckpoint.step === 'number') {\n const byStep = checkpoints.find((entry) => entry.step === baseCheckpoint.step);\n if (byStep) {\n return byStep;\n }\n }\n\n const byName = checkpoints.find((entry) => entry.name === baseCheckpoint.name);\n if (byName) {\n return byName;\n }\n\n return checkpoints[fallbackIndex] ?? null;\n}\n\nasync function materializeScreenshot(args: {\n run: RunRecord;\n checkpoint: CheckpointRecord;\n storySlug: string;\n stepOrder: number;\n outputDir: string;\n mdxFile: string;\n config: MdxReporterConfig;\n writtenFiles: Set<string>;\n}): Promise<string | null> {\n const sourcePath = screenshotSourcePath(args.run, args.checkpoint);\n if (!sourcePath) {\n return null;\n }\n\n const extension = path.extname(sourcePath) || '.png';\n const targetPath = path.join(\n args.outputDir,\n args.config.screenshotsDir ?? 'screenshots',\n args.storySlug,\n `${String(args.stepOrder).padStart(2, '0')}-${slugify(args.run.project)}-${slugify(args.checkpoint.name)}${extension}`,\n );\n\n try {\n if (args.config.copyScreenshots !== false) {\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\n await fs.copyFile(sourcePath, targetPath);\n args.writtenFiles.add(targetPath);\n return rewriteImagePath(args.mdxFile, targetPath, args.outputDir, args.config.imagePathPrefix);\n }\n\n return rewriteImagePath(args.mdxFile, sourcePath, args.outputDir, args.config.imagePathPrefix);\n } catch {\n return null;\n }\n}\n\nasync function buildSteps(args: {\n runs: RunRecord[];\n primaryRun: RunRecord;\n storySlug: string;\n outputDir: string;\n mdxFile: string;\n config: MdxReporterConfig;\n writtenFiles: Set<string>;\n}): Promise<MdxStep[]> {\n const baseCheckpoints = orderedCheckpoints(args.primaryRun.checkpoints);\n const sortedRuns = sortRunsForVariants(args.runs);\n const steps: MdxStep[] = [];\n\n for (const [index, checkpoint] of baseCheckpoints.entries()) {\n const order = typeof checkpoint.step === 'number' ? checkpoint.step : index + 1;\n const variants: MdxVariant[] = [];\n const matchedCheckpoints: CheckpointRecord[] = [];\n\n for (const run of sortedRuns) {\n const variantCheckpoint = findMatchingCheckpoint(run, checkpoint, index);\n if (!variantCheckpoint) {\n continue;\n }\n\n matchedCheckpoints.push(variantCheckpoint);\n variants.push({\n project: run.project,\n projectLabel: formatProjectLabel(run.project),\n imagePath: await materializeScreenshot({\n run,\n checkpoint: variantCheckpoint,\n storySlug: args.storySlug,\n stepOrder: order,\n outputDir: args.outputDir,\n mdxFile: args.mdxFile,\n config: args.config,\n writtenFiles: args.writtenFiles,\n }),\n imageAlt: variantCheckpoint.title || `${checkpoint.name} (${formatProjectLabel(run.project)})`,\n });\n }\n\n const descriptionSource = matchedCheckpoints.find(\n (entry) => typeof entry.description === 'string' && entry.description.trim().length > 0,\n ) ?? checkpoint;\n const stepFocus = matchedCheckpoints.map((entry) => focusNote(entry)).find((value): value is string => Boolean(value)) ?? null;\n\n steps.push({\n checkpoint,\n order,\n title: checkpoint.name,\n description:\n typeof descriptionSource.description === 'string' && descriptionSource.description.trim().length > 0\n ? descriptionSource.description.trim()\n : autoDescription(descriptionSource),\n focusNote: stepFocus,\n variants,\n });\n }\n\n return steps;\n}\n\nfunction renderVariantTabs(variants: MdxVariant[]): string {\n if (variants.length === 0) {\n return '';\n }\n\n if (variants.length === 1) {\n const [variant] = variants;\n if (!variant?.imagePath) {\n return '';\n }\n\n return `<Screenshot src={${quoteJsx(variant.imagePath)}} alt={${quoteJsx(variant.imageAlt)}} />`;\n }\n\n const tabs = variants\n .map((variant) => {\n const lines = [` <DeviceTab label={${quoteJsx(variant.projectLabel)}}>`];\n if (variant.imagePath) {\n lines.push(` <Screenshot src={${quoteJsx(variant.imagePath)}} alt={${quoteJsx(variant.imageAlt)}} />`);\n } else {\n lines.push(` <p>No screenshot captured for ${variant.projectLabel}.</p>`);\n }\n lines.push(' </DeviceTab>');\n return lines.join('\\n');\n })\n .join('\\n');\n\n return `<DeviceTabs>\\n${tabs}\\n</DeviceTabs>`;\n}\n\nfunction renderStep(step: MdxStep): string {\n const lines = [` <Step number={${step.order}} title={${quoteJsx(step.title)}}>`];\n const variantBlock = renderVariantTabs(step.variants);\n if (variantBlock) {\n lines.push(` ${variantBlock.replace(/\\n/g, '\\n ')}`, '');\n }\n\n if (step.focusNote) {\n lines.push(` ${step.focusNote}`, '');\n }\n\n lines.push(` ${step.description}`, ' </Step>');\n return lines.join('\\n');\n}\n\nfunction renderMdx(args: {\n title: string;\n steps: MdxStep[];\n runs: RunRecord[];\n config: MdxReporterConfig;\n generatedAt: string;\n}): string {\n const importNames = new Set(['Screenshot', 'StepList', 'Step']);\n if (args.steps.some((step) => step.variants.length > 1)) {\n importNames.add('DeviceTabs');\n importNames.add('DeviceTab');\n }\n\n const frontmatter = serializeFrontmatter({\n title: args.title,\n tags: frontmatterTags([...new Set(args.runs.flatMap((run) => run.tags))]),\n generatedAt: args.generatedAt,\n projects: [...new Set(args.runs.map((run) => run.project))],\n });\n\n const stepBlocks = args.steps.map(renderStep).join('\\n\\n');\n\n return `${frontmatter}import { ${[...importNames].join(', ')} } from '${args.config.componentImportPath}';\\n\\n<StepList>\\n${stepBlocks}\\n</StepList>\\n`;\n}\n\nexport const mdxReporter: ReportGenerator = {\n name: 'mdx',\n description: 'Generates one MDX help article per captured story.',\n\n validateConfig(config): boolean {\n return config != null && typeof config === 'object' && !Array.isArray(config);\n },\n\n async generate(context) {\n const config = normalizeConfig(context.config);\n const stories = groupByStory(context.runs);\n const generatedAt = new Date().toISOString();\n const writtenFiles = new Set<string>();\n let articleCount = 0;\n\n for (const [storyTitle, runs] of stories) {\n const primaryRun = choosePrimaryRun(runs, config.preferredProject);\n if (!primaryRun || !shouldIncludeRun(primaryRun, config)) {\n continue;\n }\n\n const title = stripTags(storyTitle);\n const storySlug = slugify(title);\n const mdxFile = path.join(context.outputDir, config.storiesDir ?? '.', `${storySlug}.mdx`);\n const steps = await buildSteps({\n runs,\n primaryRun,\n storySlug,\n outputDir: context.outputDir,\n mdxFile,\n config,\n writtenFiles,\n });\n\n await fs.mkdir(path.dirname(mdxFile), { recursive: true });\n await fs.writeFile(\n mdxFile,\n renderMdx({\n title,\n steps,\n runs,\n config,\n generatedAt,\n }),\n 'utf8',\n );\n\n writtenFiles.add(mdxFile);\n articleCount += 1;\n }\n\n return {\n files: [...writtenFiles],\n summary: `Generated ${articleCount} MDX article${articleCount === 1 ? '' : 's'}.`,\n };\n },\n};\n","import { createRequire } from 'node:module';\nimport path from 'node:path';\nimport type { BoundingBox } from '../types';\n\ntype SharpLike = {\n (input: string | Buffer): {\n metadata(): Promise<{ width?: number; height?: number }>;\n composite(items: Array<{ input: Buffer; top?: number; left?: number }>): {\n png(): {\n toFile(filePath: string): Promise<void>;\n };\n };\n };\n};\n\nconst require = (() => {\n try {\n return Function('return require')() as NodeRequire;\n } catch {\n return createRequire(path.join(process.cwd(), 'playwright-checkpoint-annotate-runtime.cjs'));\n }\n})();\n\nasync function loadSharp(): Promise<SharpLike | null> {\n try {\n const loaded = require('sharp') as SharpLike | { default?: SharpLike };\n return typeof loaded === 'function' ? loaded : loaded.default ?? null;\n } catch {\n return null;\n }\n}\n\nfunction buildOverlaySvg(width: number, height: number, bounds: BoundingBox): Buffer {\n const strokeWidth = Math.max(2, Math.round(Math.min(width, height) * 0.005));\n const radius = Math.max(6, Math.round(Math.min(bounds.width, bounds.height) * 0.08));\n\n const svg = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">\n <rect\n x=\"${bounds.x}\"\n y=\"${bounds.y}\"\n width=\"${bounds.width}\"\n height=\"${bounds.height}\"\n rx=\"${radius}\"\n ry=\"${radius}\"\n fill=\"rgba(239, 68, 68, 0.10)\"\n stroke=\"rgba(239, 68, 68, 0.95)\"\n stroke-width=\"${strokeWidth}\"\n />\n </svg>\n `.trim();\n\n return Buffer.from(svg, 'utf8');\n}\n\nexport async function annotateScreenshot(\n imagePath: string,\n bounds: BoundingBox,\n outputPath: string,\n): Promise<string | null> {\n const sharp = await loadSharp();\n if (!sharp) {\n return null;\n }\n\n const image = sharp(imagePath);\n const metadata = await image.metadata();\n if (!metadata.width || !metadata.height) {\n return null;\n }\n\n const overlay = buildOverlaySvg(metadata.width, metadata.height, bounds);\n await image.composite([{ input: overlay, top: 0, left: 0 }]).png().toFile(outputPath);\n return outputPath;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n CheckpointConfig,\n CheckpointManifest,\n ReportGenerationResults,\n ReportGenerator,\n ReporterConfig,\n RunRecord,\n} from '../types';\nimport { htmlReporter } from './html-reporter';\nimport { markdownReporter } from './markdown-reporter';\nimport { mdxReporter } from './mdx-reporter';\nexport { groupByStory, orderedCheckpointNames } from './story-utils';\n\nconst builtinReporters = new Map<string, ReportGenerator>();\nconst builtinReporterDefaults: Partial<Record<string, ReporterConfig>> = {\n html: true,\n markdown: false,\n mdx: false,\n};\n\nasync function walkFiles(directory: string): Promise<string[]> {\n const dirents = await fs.readdir(directory, { withFileTypes: true });\n const files: string[] = [];\n\n for (const dirent of dirents) {\n const absolutePath = path.join(directory, dirent.name);\n if (dirent.isDirectory()) {\n files.push(...(await walkFiles(absolutePath)));\n continue;\n }\n if (dirent.isFile()) {\n files.push(absolutePath);\n }\n }\n\n return files;\n}\n\nfunction isCheckpointManifestFile(filePath: string): boolean {\n const fileName = path.basename(filePath);\n return fileName === 'checkpoint-manifest.json' || (fileName.startsWith('checkpoint-manifest-') && fileName.endsWith('.json'));\n}\n\nfunction isCheckpointManifest(value: unknown): value is CheckpointManifest {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const manifest = value as Partial<CheckpointManifest>;\n return (\n typeof manifest.project === 'string' &&\n typeof manifest.testId === 'string' &&\n typeof manifest.title === 'string' &&\n typeof manifest.startedAt === 'string' &&\n Array.isArray(manifest.tags) &&\n Array.isArray(manifest.checkpoints)\n );\n}\n\nfunction toRunRecord(manifest: CheckpointManifest, sourceManifestPath: string): RunRecord {\n return {\n key: `${manifest.testId}|${manifest.project}|${manifest.startedAt}`,\n sourceManifestPath,\n environment: manifest.environment || 'unknown',\n project: manifest.project,\n testId: manifest.testId,\n title: manifest.title,\n tags: manifest.tags,\n startedAt: manifest.startedAt,\n checkpoints: manifest.checkpoints,\n };\n}\n\nfunction toManifest(run: RunRecord): CheckpointManifest {\n return {\n environment: run.environment,\n project: run.project,\n testId: run.testId,\n title: run.title,\n tags: run.tags,\n startedAt: run.startedAt,\n checkpoints: run.checkpoints,\n };\n}\n\nfunction normalizeReporterConfig(config: ReporterConfig | undefined): Record<string, unknown> | null {\n if (config == null || config === false) {\n return null;\n }\n\n if (config === true) {\n return {};\n }\n\n return { ...config };\n}\n\nexport function registerBuiltinReporter(reporter: ReportGenerator): void {\n builtinReporters.set(reporter.name, reporter);\n}\n\nexport function dedupeRuns(runs: RunRecord[]): RunRecord[] {\n const map = new Map<string, RunRecord>();\n\n for (const run of runs) {\n const existing = map.get(run.key);\n if (!existing) {\n map.set(run.key, run);\n continue;\n }\n\n const existingTime = new Date(existing.startedAt).getTime();\n const currentTime = new Date(run.startedAt).getTime();\n if (currentTime >= existingTime) {\n map.set(run.key, run);\n }\n }\n\n return [...map.values()];\n}\n\nexport async function loadRuns(testResultsDir: string): Promise<RunRecord[]> {\n let manifestFiles: string[];\n try {\n manifestFiles = (await walkFiles(testResultsDir)).filter(isCheckpointManifestFile);\n } catch {\n return [];\n }\n\n const runs: RunRecord[] = [];\n for (const manifestPath of manifestFiles) {\n let rawManifest: unknown;\n try {\n rawManifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));\n } catch {\n continue;\n }\n\n if (!isCheckpointManifest(rawManifest)) {\n continue;\n }\n\n runs.push(toRunRecord(rawManifest, manifestPath));\n }\n\n return dedupeRuns(runs);\n}\n\nexport async function runReporters(\n config: CheckpointConfig,\n testResultsDir: string,\n outputDir: string,\n): Promise<ReportGenerationResults> {\n const runs = await loadRuns(testResultsDir);\n const manifests = runs.map(toManifest);\n const results: ReportGenerationResults = {};\n const reporterConfigMap: Partial<Record<string, ReporterConfig>> = {\n ...builtinReporterDefaults,\n ...(config.reporters ?? {}),\n };\n\n for (const [name, value] of Object.entries(reporterConfigMap)) {\n const reporterConfig = normalizeReporterConfig(value);\n if (!reporterConfig) {\n continue;\n }\n\n const reporter = builtinReporters.get(name);\n if (!reporter) {\n throw new Error(`Reporter \"${name}\" is enabled but no implementation is registered.`);\n }\n\n if (reporter.validateConfig && !reporter.validateConfig(reporterConfig)) {\n throw new Error(`Reporter \"${name}\" received invalid configuration.`);\n }\n\n results[name] = await reporter.generate({\n runs,\n outputDir,\n config: reporterConfig,\n manifests,\n });\n }\n\n return results;\n}\n\nregisterBuiltinReporter(htmlReporter);\nregisterBuiltinReporter(markdownReporter);\nregisterBuiltinReporter(mdxReporter);\n\nexport { annotateScreenshot } from './annotate';\nexport { htmlReporter, markdownReporter, mdxReporter };\nexport type { ReportGenerator } from '../types';\n"],"mappings":"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","names":["fs","path","slugify","resolveArtifactPath","path","screenshotData","fs","fs","path","DEFAULT_PROJECT_ORDER","slugify","stripTags","normalizeConfig","normalizeTags","shouldIncludeRun","choosePrimaryRun","orderedCheckpoints","resolveArtifactPath","path","screenshotSourcePath","screenshotData","focusNote","urlLabel","autoDescription","markdownRelativePath","rewriteImagePath","yamlScalar","serializeFrontmatter","projectWeight","formatProjectLabel","materializeScreenshot","fs","buildSteps","path","require","fs","path","fs","path"]}