@midscene/core 1.17.6 → 1.17.7

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 (72) hide show
  1. package/dist/es/agent/agent-report-manager.mjs +1 -1
  2. package/dist/es/agent/agent-report-manager.mjs.map +1 -1
  3. package/dist/es/agent/utils.mjs +1 -1
  4. package/dist/es/ai-model/model-adapter/locate-prompt-order.mjs +80 -0
  5. package/dist/es/ai-model/model-adapter/locate-prompt-order.mjs.map +1 -0
  6. package/dist/es/ai-model/model-adapter/locate.mjs +2 -1
  7. package/dist/es/ai-model/model-adapter/locate.mjs.map +1 -1
  8. package/dist/es/ai-model/workflows/grounding/locate.mjs +1 -1
  9. package/dist/es/ai-model/workflows/grounding/locate.mjs.map +1 -1
  10. package/dist/es/ai-model/workflows/grounding/section-locate.mjs +1 -1
  11. package/dist/es/ai-model/workflows/grounding/section-locate.mjs.map +1 -1
  12. package/dist/es/ai-model/workflows/grounding/utils.mjs +8 -26
  13. package/dist/es/ai-model/workflows/grounding/utils.mjs.map +1 -1
  14. package/dist/es/dump/report-image-export.mjs +58 -0
  15. package/dist/es/dump/report-image-export.mjs.map +1 -0
  16. package/dist/es/dump/screenshot-store.mjs +5 -0
  17. package/dist/es/dump/screenshot-store.mjs.map +1 -1
  18. package/dist/es/report-cli.mjs +13 -29
  19. package/dist/es/report-cli.mjs.map +1 -1
  20. package/dist/es/report-generator.mjs +22 -8
  21. package/dist/es/report-generator.mjs.map +1 -1
  22. package/dist/es/report-html-template.mjs +1 -1
  23. package/dist/es/report-markdown.mjs +50 -53
  24. package/dist/es/report-markdown.mjs.map +1 -1
  25. package/dist/es/report.mjs +8 -24
  26. package/dist/es/report.mjs.map +1 -1
  27. package/dist/es/utils.mjs +1 -1
  28. package/dist/lib/agent/agent-report-manager.js +1 -1
  29. package/dist/lib/agent/agent-report-manager.js.map +1 -1
  30. package/dist/lib/agent/utils.js +1 -1
  31. package/dist/lib/ai-model/model-adapter/locate-prompt-order.js +117 -0
  32. package/dist/lib/ai-model/model-adapter/locate-prompt-order.js.map +1 -0
  33. package/dist/lib/ai-model/model-adapter/locate.js +2 -1
  34. package/dist/lib/ai-model/model-adapter/locate.js.map +1 -1
  35. package/dist/lib/ai-model/workflows/grounding/locate.js +1 -1
  36. package/dist/lib/ai-model/workflows/grounding/locate.js.map +1 -1
  37. package/dist/lib/ai-model/workflows/grounding/section-locate.js +1 -1
  38. package/dist/lib/ai-model/workflows/grounding/section-locate.js.map +1 -1
  39. package/dist/lib/ai-model/workflows/grounding/utils.js +8 -26
  40. package/dist/lib/ai-model/workflows/grounding/utils.js.map +1 -1
  41. package/dist/lib/dump/report-image-export.js +92 -0
  42. package/dist/lib/dump/report-image-export.js.map +1 -0
  43. package/dist/lib/dump/screenshot-store.js +5 -0
  44. package/dist/lib/dump/screenshot-store.js.map +1 -1
  45. package/dist/lib/report-cli.js +12 -28
  46. package/dist/lib/report-cli.js.map +1 -1
  47. package/dist/lib/report-generator.js +22 -8
  48. package/dist/lib/report-generator.js.map +1 -1
  49. package/dist/lib/report-html-template.js +1 -1
  50. package/dist/lib/report-markdown.js +50 -53
  51. package/dist/lib/report-markdown.js.map +1 -1
  52. package/dist/lib/report.js +6 -22
  53. package/dist/lib/report.js.map +1 -1
  54. package/dist/lib/utils.js +1 -1
  55. package/dist/types/ai-model/model-adapter/locate-prompt-order.d.ts +24 -0
  56. package/dist/types/ai-model/model-adapter/locate-prompt-order.d.ts.map +1 -0
  57. package/dist/types/ai-model/model-adapter/locate.d.ts.map +1 -1
  58. package/dist/types/ai-model/model-adapter/types.d.ts +9 -3
  59. package/dist/types/ai-model/model-adapter/types.d.ts.map +1 -1
  60. package/dist/types/ai-model/workflows/grounding/utils.d.ts +4 -9
  61. package/dist/types/ai-model/workflows/grounding/utils.d.ts.map +1 -1
  62. package/dist/types/dump/report-image-export.d.ts +12 -0
  63. package/dist/types/dump/report-image-export.d.ts.map +1 -0
  64. package/dist/types/dump/screenshot-store.d.ts +2 -0
  65. package/dist/types/dump/screenshot-store.d.ts.map +1 -1
  66. package/dist/types/report-cli.d.ts.map +1 -1
  67. package/dist/types/report-generator.d.ts +4 -2
  68. package/dist/types/report-generator.d.ts.map +1 -1
  69. package/dist/types/report-markdown.d.ts +4 -2
  70. package/dist/types/report-markdown.d.ts.map +1 -1
  71. package/dist/types/report.d.ts.map +1 -1
  72. package/package.json +2 -2
@@ -33,31 +33,12 @@ const external_node_fs_namespaceObject = require("node:fs");
33
33
  const external_node_path_namespaceObject = require("node:path");
34
34
  const external_zod_namespaceObject = require("zod");
35
35
  const report_artifact_reader_js_namespaceObject = require("./dump/report-artifact-reader.js");
36
- const screenshot_store_js_namespaceObject = require("./dump/screenshot-store.js");
36
+ const report_image_export_js_namespaceObject = require("./dump/report-image-export.js");
37
37
  const task_status_js_namespaceObject = require("./dump/task-status.js");
38
38
  const external_report_js_namespaceObject = require("./report.js");
39
39
  const external_report_markdown_js_namespaceObject = require("./report-markdown.js");
40
40
  const external_report_stats_js_namespaceObject = require("./report-stats.js");
41
41
  const external_types_js_namespaceObject = require("./types.js");
42
- function writeAttachmentFromReport(attachment, opts) {
43
- const { suggestedFileName, id, mimeType } = attachment;
44
- if (opts.writtenFiles.has(suggestedFileName)) return;
45
- const absolutePath = external_node_path_namespaceObject.join(opts.screenshotsDir, suggestedFileName);
46
- const resolved = (0, screenshot_store_js_namespaceObject.resolveScreenshotSource)(attachment.sourceRef ?? null, {
47
- reportPath: opts.htmlPath,
48
- fallbackId: id,
49
- fallbackMimeType: mimeType || 'image/png'
50
- });
51
- if ('data-uri' === resolved.type) {
52
- const rawBase64 = resolved.dataUri.replace(/^data:image\/[a-zA-Z+]+;base64,/, '');
53
- (0, external_node_fs_namespaceObject.writeFileSync)(absolutePath, Buffer.from(rawBase64, 'base64'));
54
- opts.writtenFiles.add(suggestedFileName);
55
- return;
56
- }
57
- if (!(0, external_node_fs_namespaceObject.existsSync)(resolved.filePath)) throw new Error(`Cannot resolve screenshot "${id}" for markdown attachment from ${opts.htmlPath}`);
58
- (0, external_node_fs_namespaceObject.copyFileSync)(resolved.filePath, absolutePath);
59
- opts.writtenFiles.add(suggestedFileName);
60
- }
61
42
  async function markdownFromReport(htmlPath, outputDir) {
62
43
  const screenshotsDir = external_node_path_namespaceObject.join(outputDir, 'screenshots');
63
44
  (0, external_node_fs_namespaceObject.mkdirSync)(outputDir, {
@@ -75,20 +56,23 @@ async function markdownFromReport(htmlPath, outputDir) {
75
56
  deviceType: baseDump.deviceType,
76
57
  executions
77
58
  });
78
- const result = (0, external_report_markdown_js_namespaceObject.reportToMarkdown)(mergedReport);
59
+ const images = new report_image_export_js_namespaceObject.ReportImageExporter(htmlPath, screenshotsDir);
60
+ const result = (0, external_report_markdown_js_namespaceObject.reportToMarkdown)(mergedReport, {
61
+ resolveScreenshotFileName: (attachment)=>images.write(attachment.sourceRef ?? {
62
+ type: 'midscene_screenshot_ref',
63
+ id: attachment.id,
64
+ capturedAt: 0,
65
+ mimeType: attachment.mimeType ?? 'image/png',
66
+ storage: 'inline'
67
+ }, attachment.base64Data)
68
+ });
79
69
  const markdownFiles = [];
80
- const writtenScreenshots = new Set();
81
70
  const mdPath = external_node_path_namespaceObject.join(outputDir, 'report.md');
82
71
  (0, external_node_fs_namespaceObject.writeFileSync)(mdPath, result.markdown, 'utf-8');
83
72
  markdownFiles.push(mdPath);
84
- for (const attachment of result.attachments)writeAttachmentFromReport(attachment, {
85
- htmlPath,
86
- screenshotsDir,
87
- writtenFiles: writtenScreenshots
88
- });
89
73
  return {
90
74
  markdownFiles,
91
- screenshotFiles: Array.from(writtenScreenshots).sort().map((f)=>external_node_path_namespaceObject.join(screenshotsDir, f))
75
+ screenshotFiles: images.files
92
76
  };
93
77
  }
94
78
  function resolveReportHtmlPath(htmlPath) {
@@ -1 +1 @@
1
- {"version":3,"file":"report-cli.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report-cli.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import {\n copyFileSync,\n existsSync,\n mkdirSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport * as path from 'node:path';\nimport { z } from 'zod';\nimport {\n readReportRunnerDump,\n streamReportDumpScripts,\n} from './dump/report-artifact-reader';\nimport { resolveScreenshotSource } from './dump/screenshot-store';\nimport { deriveCaseStatus } from './dump/task-status';\nimport {\n ReportMergingTool,\n collectDedupedExecutions,\n exportReportArtifact,\n splitReportHtmlByExecution,\n} from './report';\nimport { reportToMarkdown } from './report-markdown';\nimport type { MarkdownAttachment } from './report-markdown';\nimport { collectReportSummary } from './report-stats';\nimport type { ReportFileAttributes, TestStatus } from './types';\nimport { ReportActionDump } from './types';\n\ntype ReportCliToolResult = {\n isError: boolean;\n content: Array<{\n type: 'text';\n text: string;\n }>;\n};\n\ntype ReportCliSchema = Record<string, z.ZodTypeAny>;\n\nexport interface ReportCliCommandDefinition {\n name: string;\n description: string;\n schema: ReportCliSchema;\n handler: (args: Record<string, unknown>) => Promise<ReportCliToolResult>;\n}\n\nexport interface ReportCliCommandEntry {\n name: string;\n def: ReportCliCommandDefinition;\n}\n\nexport type ConsumeReportFileAction =\n | 'split'\n | 'to-markdown'\n | 'merge-html'\n | 'export';\n\nexport interface ConsumeReportFileOptions {\n htmlPath: string;\n outputDir: string;\n}\n\nexport type SplitReportFileOptions = ConsumeReportFileOptions;\nexport type ReportFileToMarkdownOptions = ConsumeReportFileOptions;\n\nexport interface MergeReportFilesOptions {\n htmlPaths: string[];\n outputDir?: string;\n outputName?: string;\n outputFormat?: 'single-html' | 'html-and-external-assets';\n overwrite?: boolean;\n}\n\nexport interface MergeReportFilesResult {\n mergedReportPath: string;\n}\n\nfunction writeAttachmentFromReport(\n attachment: MarkdownAttachment,\n opts: {\n htmlPath: string;\n screenshotsDir: string;\n writtenFiles: Set<string>;\n },\n): void {\n const { suggestedFileName, id, mimeType } = attachment;\n if (opts.writtenFiles.has(suggestedFileName)) return;\n\n const absolutePath = path.join(opts.screenshotsDir, suggestedFileName);\n\n const resolved = resolveScreenshotSource(attachment.sourceRef ?? null, {\n reportPath: opts.htmlPath,\n fallbackId: id,\n fallbackMimeType: (mimeType || 'image/png') as 'image/png' | 'image/jpeg',\n });\n\n if (resolved.type === 'data-uri') {\n const rawBase64 = resolved.dataUri.replace(\n /^data:image\\/[a-zA-Z+]+;base64,/,\n '',\n );\n writeFileSync(absolutePath, Buffer.from(rawBase64, 'base64'));\n opts.writtenFiles.add(suggestedFileName);\n return;\n }\n\n if (!existsSync(resolved.filePath)) {\n throw new Error(\n `Cannot resolve screenshot \"${id}\" for markdown attachment from ${opts.htmlPath}`,\n );\n }\n\n copyFileSync(resolved.filePath, absolutePath);\n opts.writtenFiles.add(suggestedFileName);\n}\n\nasync function markdownFromReport(\n htmlPath: string,\n outputDir: string,\n): Promise<{ markdownFiles: string[]; screenshotFiles: string[] }> {\n const screenshotsDir = path.join(outputDir, 'screenshots');\n\n mkdirSync(outputDir, { recursive: true });\n mkdirSync(screenshotsDir, { recursive: true });\n\n const { baseDump, executions } = collectDedupedExecutions(htmlPath);\n\n const mergedReport = new ReportActionDump({\n sdkVersion: baseDump.sdkVersion,\n groupName: baseDump.groupName,\n groupDescription: baseDump.groupDescription,\n modelBriefs: baseDump.modelBriefs,\n deviceType: baseDump.deviceType,\n executions,\n });\n\n const result = reportToMarkdown(mergedReport);\n\n const markdownFiles: string[] = [];\n const writtenScreenshots = new Set<string>();\n\n const mdPath = path.join(outputDir, 'report.md');\n writeFileSync(mdPath, result.markdown, 'utf-8');\n markdownFiles.push(mdPath);\n\n for (const attachment of result.attachments) {\n writeAttachmentFromReport(attachment, {\n htmlPath,\n screenshotsDir,\n writtenFiles: writtenScreenshots,\n });\n }\n\n return {\n markdownFiles,\n screenshotFiles: Array.from(writtenScreenshots)\n .sort()\n .map((f) => path.join(screenshotsDir, f)),\n };\n}\n\nfunction resolveReportHtmlPath(htmlPath: string): string {\n const normalizedPath = path.resolve(htmlPath);\n\n if (!existsSync(normalizedPath)) {\n throw new Error(`report-tool: --htmlPath does not exist: ${htmlPath}`);\n }\n\n const stats = statSync(normalizedPath);\n if (!stats.isDirectory()) {\n return normalizedPath;\n }\n\n const indexHtmlPath = path.join(normalizedPath, 'index.html');\n if (!existsSync(indexHtmlPath)) {\n throw new Error(\n `report-tool: \"${htmlPath}\" is not an HTML report file, and no index.html was found under this directory.`,\n );\n }\n\n return indexHtmlPath;\n}\n\nexport function splitReportFile(options: SplitReportFileOptions): {\n executionJsonFiles: string[];\n screenshotFiles: string[];\n} {\n const { htmlPath, outputDir } = options;\n if (!htmlPath) {\n throw new Error('splitReportFile: htmlPath is required');\n }\n\n if (!outputDir) {\n throw new Error('splitReportFile: outputDir is required');\n }\n\n const resolvedHtmlPath = resolveReportHtmlPath(htmlPath);\n return splitReportHtmlByExecution({\n htmlPath: resolvedHtmlPath,\n outputDir,\n });\n}\n\nexport async function reportFileToMarkdown(\n options: ReportFileToMarkdownOptions,\n): Promise<{ markdownFiles: string[]; screenshotFiles: string[] }> {\n const { htmlPath, outputDir } = options;\n if (!htmlPath) {\n throw new Error('reportFileToMarkdown: htmlPath is required');\n }\n\n if (!outputDir) {\n throw new Error('reportFileToMarkdown: outputDir is required');\n }\n\n const resolvedHtmlPath = resolveReportHtmlPath(htmlPath);\n return markdownFromReport(resolvedHtmlPath, outputDir);\n}\n\nconst TEST_STATUS_VALUES: ReadonlySet<TestStatus> = new Set<TestStatus>([\n 'passed',\n 'failed',\n 'timedOut',\n 'skipped',\n 'interrupted',\n]);\n\nconst FAILING_TEST_STATUSES: ReadonlySet<TestStatus> = new Set<TestStatus>([\n 'failed',\n 'timedOut',\n 'interrupted',\n]);\n\n/**\n * Reuse a `playwright_test_status` already recorded on the source report's dump\n * scripts (e.g. a Playwright-generated report carries the precise\n * timedOut/skipped/interrupted status). Returns undefined when the source has\n * no such attribute, so the caller can fall back to deriving from the dump.\n *\n * A single source report may bundle several executions (e.g. an already-merged\n * report), so surface a failing status if any execution failed — mirroring\n * `deriveCaseStatus`'s any-failure-wins semantics rather than taking the first\n * script's status and masking later failures.\n */\nfunction readSourceTestStatus(htmlPath: string): TestStatus | undefined {\n const recorded: TestStatus[] = [];\n streamReportDumpScripts(htmlPath, ({ openTag }) => {\n const match = openTag.match(/playwright_test_status=\"([^\"]*)\"/);\n if (!match) return false;\n const status = decodeURIComponent(match[1]) as TestStatus;\n if (TEST_STATUS_VALUES.has(status)) {\n recorded.push(status);\n }\n return false;\n });\n if (recorded.length === 0) return undefined;\n return recorded.find((s) => FAILING_TEST_STATUSES.has(s)) ?? recorded[0];\n}\n\nfunction deriveReportAttributesFromHtml(\n htmlPath: string,\n index: number,\n): ReportFileAttributes {\n const fallbackId = `${path.basename(path.dirname(htmlPath)) || path.basename(htmlPath, path.extname(htmlPath))}-${index + 1}`;\n const runnerDump = readReportRunnerDump(htmlPath);\n const recordedStatus = readSourceTestStatus(htmlPath);\n try {\n const { baseDump, executions } = collectDedupedExecutions(htmlPath);\n // Prefer a status the source report already recorded (keeps Playwright's\n // precise timedOut/skipped/interrupted); otherwise infer it from the dump\n // so a failing case is not silently merged in as passed.\n const testStatus =\n recordedStatus && FAILING_TEST_STATUSES.has(recordedStatus)\n ? recordedStatus\n : runnerDump?.status === 'failed'\n ? 'failed'\n : (recordedStatus ??\n (runnerDump ? 'passed' : deriveCaseStatus(executions)));\n return {\n testId: fallbackId,\n testTitle: baseDump.groupName || fallbackId,\n testDescription: baseDump.groupDescription ?? '',\n testDuration:\n runnerDump?.durationMs ??\n collectReportSummary({ executions }).timing.wallTimeMs ??\n 0,\n testStatus,\n };\n } catch {\n return {\n testId: fallbackId,\n testTitle: fallbackId,\n testDescription: '',\n testDuration: 0,\n testStatus:\n recordedStatus && FAILING_TEST_STATUSES.has(recordedStatus)\n ? recordedStatus\n : runnerDump?.status === 'failed'\n ? 'failed'\n : (recordedStatus ?? 'passed'),\n };\n }\n}\n\nexport function mergeReportFiles(\n options: MergeReportFilesOptions,\n): MergeReportFilesResult {\n const {\n htmlPaths,\n outputDir,\n outputName,\n outputFormat,\n overwrite = false,\n } = options;\n if (!htmlPaths || htmlPaths.length === 0) {\n throw new Error('mergeReportFiles: htmlPaths is required');\n }\n\n const resolvedPaths = htmlPaths.map((p) => resolveReportHtmlPath(p));\n\n const tool = new ReportMergingTool();\n resolvedPaths.forEach((htmlPath, index) => {\n tool.append({\n reportFilePath: htmlPath,\n reportAttributes: deriveReportAttributesFromHtml(htmlPath, index),\n });\n });\n\n const mergedReportPath = tool.mergeReports(outputName ?? 'AUTO', {\n overwrite,\n outputDir,\n outputFormat,\n });\n\n if (!mergedReportPath) {\n throw new Error('mergeReportFiles: failed to produce a merged report');\n }\n\n return { mergedReportPath };\n}\n\nfunction normalizeHtmlReportArg(raw: unknown): string[] | undefined {\n if (raw === undefined || raw === null) return undefined;\n if (Array.isArray(raw)) {\n return raw.filter(\n (p): p is string => typeof p === 'string' && p.length > 0,\n );\n }\n if (typeof raw === 'string') {\n const trimmed = raw.trim();\n return trimmed ? [trimmed] : [];\n }\n return undefined;\n}\n\nconst reportCommandDefinition: ReportCliCommandDefinition = {\n name: 'report-tool',\n description:\n 'Transform Midscene report artifacts, including splitting executions, converting to markdown, merging multiple reports, and exporting portable reports in either storage format.',\n schema: {\n action: z\n .enum(['split', 'to-markdown', 'merge-html', 'export'])\n .optional()\n .describe(\n 'Report action to run. Supports: split, to-markdown, merge-html, export. Defaults to split.',\n ),\n htmlPath: z\n .string()\n .optional()\n .describe(\n 'Input report HTML path (e.g. ./report/index.html). Used by split, to-markdown, and export.',\n ),\n htmlReport: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe(\n 'Input report HTML path for the merge action. Repeat the flag to merge multiple reports (e.g. --htmlReport ./a/index.html --htmlReport ./b.html).',\n ),\n outputDir: z\n .string()\n .optional()\n .describe(\n 'Output directory for generated report artifacts. For merge, defaults to the Midscene report directory.',\n ),\n outputName: z\n .string()\n .optional()\n .describe(\n 'Output report file/directory name (without .html). Merge generates a name; export uses the input name by default.',\n ),\n overwrite: z\n .union([z.boolean(), z.string()])\n .optional()\n .describe('Overwrite an existing output report for merge or export.'),\n outputFormat: z\n .enum(['single-html', 'html-and-external-assets'])\n .optional()\n .describe(\n 'Final delivery format for merge and export. Defaults to single-html.',\n ),\n },\n handler: async (args) => {\n const {\n action = 'split',\n htmlPath,\n htmlReport,\n outputDir,\n outputName,\n overwrite,\n outputFormat,\n } = args as {\n action?: string;\n htmlPath?: string;\n htmlReport?: unknown;\n outputDir?: string;\n outputName?: string;\n overwrite?: unknown;\n outputFormat?: 'single-html' | 'html-and-external-assets';\n };\n if (\n action !== 'split' &&\n action !== 'to-markdown' &&\n action !== 'merge-html' &&\n action !== 'export'\n ) {\n throw new Error(\n `report-tool: unsupported --action value \"${action}\". Currently supported: split, to-markdown, merge-html, export`,\n );\n }\n\n if (action === 'merge-html') {\n const paths = normalizeHtmlReportArg(htmlReport);\n if (!paths || paths.length === 0) {\n throw new Error(\n 'report-tool: --htmlReport is required for action \"merge-html\". Repeat --htmlReport for each report (e.g. --htmlReport ./a/index.html --htmlReport ./b.html).',\n );\n }\n\n const overwriteFlag =\n overwrite === true || overwrite === 'true' || overwrite === '1';\n\n const result = mergeReportFiles({\n htmlPaths: paths,\n outputDir,\n outputName,\n outputFormat,\n overwrite: overwriteFlag,\n });\n\n return {\n isError: false,\n content: [\n {\n type: 'text',\n text: `Merged ${paths.length} report(s) into ${result.mergedReportPath}`,\n },\n ],\n };\n }\n\n if (!htmlPath) {\n throw new Error('report-tool: --htmlPath is required');\n }\n\n if (!outputDir) {\n throw new Error('report-tool: --outputDir is required');\n }\n\n if (action === 'export') {\n const input = resolveReportHtmlPath(htmlPath);\n const name =\n outputName ??\n (path.basename(input) === 'index.html'\n ? path.basename(path.dirname(input))\n : path.basename(input, '.html'));\n const reportPath = await exportReportArtifact({\n reportPath: input,\n outputDir,\n reportFileName: name,\n outputFormat,\n overwrite:\n overwrite === true || overwrite === 'true' || overwrite === '1',\n });\n return {\n isError: false,\n content: [{ type: 'text', text: `Report exported to ${reportPath}` }],\n };\n }\n\n if (action === 'to-markdown') {\n const result = await reportFileToMarkdown({\n htmlPath,\n outputDir,\n });\n return {\n isError: false,\n content: [\n {\n type: 'text',\n text: `Markdown export completed. Generated ${result.markdownFiles.length} markdown file(s) and ${result.screenshotFiles.length} screenshot(s). Output path: ${outputDir}`,\n },\n ],\n };\n }\n\n const result = splitReportFile({\n htmlPath,\n outputDir,\n });\n\n return {\n isError: false,\n content: [\n {\n type: 'text',\n text: `Report split completed. Generated ${result.executionJsonFiles.length} execution JSON files and ${result.screenshotFiles.length} screenshots. Output path: ${outputDir}`,\n },\n ],\n };\n },\n};\n\nexport function createReportCliCommands(): ReportCliCommandEntry[] {\n return [\n {\n name: 'report-tool',\n def: reportCommandDefinition,\n },\n ];\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","writeAttachmentFromReport","attachment","opts","suggestedFileName","id","mimeType","absolutePath","path","resolved","resolveScreenshotSource","rawBase64","writeFileSync","Buffer","existsSync","Error","copyFileSync","markdownFromReport","htmlPath","outputDir","screenshotsDir","mkdirSync","baseDump","executions","collectDedupedExecutions","mergedReport","ReportActionDump","result","reportToMarkdown","markdownFiles","writtenScreenshots","Set","mdPath","Array","f","resolveReportHtmlPath","normalizedPath","stats","statSync","indexHtmlPath","splitReportFile","options","resolvedHtmlPath","splitReportHtmlByExecution","reportFileToMarkdown","TEST_STATUS_VALUES","FAILING_TEST_STATUSES","readSourceTestStatus","recorded","streamReportDumpScripts","openTag","match","status","decodeURIComponent","s","deriveReportAttributesFromHtml","index","fallbackId","runnerDump","readReportRunnerDump","recordedStatus","testStatus","deriveCaseStatus","collectReportSummary","mergeReportFiles","htmlPaths","outputName","outputFormat","overwrite","resolvedPaths","p","tool","ReportMergingTool","mergedReportPath","normalizeHtmlReportArg","raw","trimmed","reportCommandDefinition","z","args","action","htmlReport","paths","overwriteFlag","input","name","reportPath","exportReportArtifact","createReportCliCommands"],"mappings":"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"}
1
+ {"version":3,"file":"report-cli.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report-cli.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { existsSync, mkdirSync, statSync, writeFileSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { z } from 'zod';\nimport {\n readReportRunnerDump,\n streamReportDumpScripts,\n} from './dump/report-artifact-reader';\nimport { ReportImageExporter } from './dump/report-image-export';\nimport { deriveCaseStatus } from './dump/task-status';\nimport {\n ReportMergingTool,\n collectDedupedExecutions,\n exportReportArtifact,\n splitReportHtmlByExecution,\n} from './report';\nimport { reportToMarkdown } from './report-markdown';\nimport { collectReportSummary } from './report-stats';\nimport type { ReportFileAttributes, TestStatus } from './types';\nimport { ReportActionDump } from './types';\n\ntype ReportCliToolResult = {\n isError: boolean;\n content: Array<{\n type: 'text';\n text: string;\n }>;\n};\n\ntype ReportCliSchema = Record<string, z.ZodTypeAny>;\n\nexport interface ReportCliCommandDefinition {\n name: string;\n description: string;\n schema: ReportCliSchema;\n handler: (args: Record<string, unknown>) => Promise<ReportCliToolResult>;\n}\n\nexport interface ReportCliCommandEntry {\n name: string;\n def: ReportCliCommandDefinition;\n}\n\nexport type ConsumeReportFileAction =\n | 'split'\n | 'to-markdown'\n | 'merge-html'\n | 'export';\n\nexport interface ConsumeReportFileOptions {\n htmlPath: string;\n outputDir: string;\n}\n\nexport type SplitReportFileOptions = ConsumeReportFileOptions;\nexport type ReportFileToMarkdownOptions = ConsumeReportFileOptions;\n\nexport interface MergeReportFilesOptions {\n htmlPaths: string[];\n outputDir?: string;\n outputName?: string;\n outputFormat?: 'single-html' | 'html-and-external-assets';\n overwrite?: boolean;\n}\n\nexport interface MergeReportFilesResult {\n mergedReportPath: string;\n}\n\nasync function markdownFromReport(\n htmlPath: string,\n outputDir: string,\n): Promise<{ markdownFiles: string[]; screenshotFiles: string[] }> {\n const screenshotsDir = path.join(outputDir, 'screenshots');\n\n mkdirSync(outputDir, { recursive: true });\n mkdirSync(screenshotsDir, { recursive: true });\n\n const { baseDump, executions } = collectDedupedExecutions(htmlPath);\n\n const mergedReport = new ReportActionDump({\n sdkVersion: baseDump.sdkVersion,\n groupName: baseDump.groupName,\n groupDescription: baseDump.groupDescription,\n modelBriefs: baseDump.modelBriefs,\n deviceType: baseDump.deviceType,\n executions,\n });\n\n const images = new ReportImageExporter(htmlPath, screenshotsDir);\n const result = reportToMarkdown(mergedReport, {\n resolveScreenshotFileName: (attachment) =>\n images.write(\n attachment.sourceRef ?? {\n type: 'midscene_screenshot_ref',\n id: attachment.id,\n capturedAt: 0,\n mimeType: (attachment.mimeType ?? 'image/png') as\n | 'image/png'\n | 'image/jpeg',\n storage: 'inline',\n },\n attachment.base64Data,\n ),\n });\n\n const markdownFiles: string[] = [];\n\n const mdPath = path.join(outputDir, 'report.md');\n writeFileSync(mdPath, result.markdown, 'utf-8');\n markdownFiles.push(mdPath);\n\n return {\n markdownFiles,\n screenshotFiles: images.files,\n };\n}\n\nfunction resolveReportHtmlPath(htmlPath: string): string {\n const normalizedPath = path.resolve(htmlPath);\n\n if (!existsSync(normalizedPath)) {\n throw new Error(`report-tool: --htmlPath does not exist: ${htmlPath}`);\n }\n\n const stats = statSync(normalizedPath);\n if (!stats.isDirectory()) {\n return normalizedPath;\n }\n\n const indexHtmlPath = path.join(normalizedPath, 'index.html');\n if (!existsSync(indexHtmlPath)) {\n throw new Error(\n `report-tool: \"${htmlPath}\" is not an HTML report file, and no index.html was found under this directory.`,\n );\n }\n\n return indexHtmlPath;\n}\n\nexport function splitReportFile(options: SplitReportFileOptions): {\n executionJsonFiles: string[];\n screenshotFiles: string[];\n} {\n const { htmlPath, outputDir } = options;\n if (!htmlPath) {\n throw new Error('splitReportFile: htmlPath is required');\n }\n\n if (!outputDir) {\n throw new Error('splitReportFile: outputDir is required');\n }\n\n const resolvedHtmlPath = resolveReportHtmlPath(htmlPath);\n return splitReportHtmlByExecution({\n htmlPath: resolvedHtmlPath,\n outputDir,\n });\n}\n\nexport async function reportFileToMarkdown(\n options: ReportFileToMarkdownOptions,\n): Promise<{ markdownFiles: string[]; screenshotFiles: string[] }> {\n const { htmlPath, outputDir } = options;\n if (!htmlPath) {\n throw new Error('reportFileToMarkdown: htmlPath is required');\n }\n\n if (!outputDir) {\n throw new Error('reportFileToMarkdown: outputDir is required');\n }\n\n const resolvedHtmlPath = resolveReportHtmlPath(htmlPath);\n return markdownFromReport(resolvedHtmlPath, outputDir);\n}\n\nconst TEST_STATUS_VALUES: ReadonlySet<TestStatus> = new Set<TestStatus>([\n 'passed',\n 'failed',\n 'timedOut',\n 'skipped',\n 'interrupted',\n]);\n\nconst FAILING_TEST_STATUSES: ReadonlySet<TestStatus> = new Set<TestStatus>([\n 'failed',\n 'timedOut',\n 'interrupted',\n]);\n\n/**\n * Reuse a `playwright_test_status` already recorded on the source report's dump\n * scripts (e.g. a Playwright-generated report carries the precise\n * timedOut/skipped/interrupted status). Returns undefined when the source has\n * no such attribute, so the caller can fall back to deriving from the dump.\n *\n * A single source report may bundle several executions (e.g. an already-merged\n * report), so surface a failing status if any execution failed — mirroring\n * `deriveCaseStatus`'s any-failure-wins semantics rather than taking the first\n * script's status and masking later failures.\n */\nfunction readSourceTestStatus(htmlPath: string): TestStatus | undefined {\n const recorded: TestStatus[] = [];\n streamReportDumpScripts(htmlPath, ({ openTag }) => {\n const match = openTag.match(/playwright_test_status=\"([^\"]*)\"/);\n if (!match) return false;\n const status = decodeURIComponent(match[1]) as TestStatus;\n if (TEST_STATUS_VALUES.has(status)) {\n recorded.push(status);\n }\n return false;\n });\n if (recorded.length === 0) return undefined;\n return recorded.find((s) => FAILING_TEST_STATUSES.has(s)) ?? recorded[0];\n}\n\nfunction deriveReportAttributesFromHtml(\n htmlPath: string,\n index: number,\n): ReportFileAttributes {\n const fallbackId = `${path.basename(path.dirname(htmlPath)) || path.basename(htmlPath, path.extname(htmlPath))}-${index + 1}`;\n const runnerDump = readReportRunnerDump(htmlPath);\n const recordedStatus = readSourceTestStatus(htmlPath);\n try {\n const { baseDump, executions } = collectDedupedExecutions(htmlPath);\n // Prefer a status the source report already recorded (keeps Playwright's\n // precise timedOut/skipped/interrupted); otherwise infer it from the dump\n // so a failing case is not silently merged in as passed.\n const testStatus =\n recordedStatus && FAILING_TEST_STATUSES.has(recordedStatus)\n ? recordedStatus\n : runnerDump?.status === 'failed'\n ? 'failed'\n : (recordedStatus ??\n (runnerDump ? 'passed' : deriveCaseStatus(executions)));\n return {\n testId: fallbackId,\n testTitle: baseDump.groupName || fallbackId,\n testDescription: baseDump.groupDescription ?? '',\n testDuration:\n runnerDump?.durationMs ??\n collectReportSummary({ executions }).timing.wallTimeMs ??\n 0,\n testStatus,\n };\n } catch {\n return {\n testId: fallbackId,\n testTitle: fallbackId,\n testDescription: '',\n testDuration: 0,\n testStatus:\n recordedStatus && FAILING_TEST_STATUSES.has(recordedStatus)\n ? recordedStatus\n : runnerDump?.status === 'failed'\n ? 'failed'\n : (recordedStatus ?? 'passed'),\n };\n }\n}\n\nexport function mergeReportFiles(\n options: MergeReportFilesOptions,\n): MergeReportFilesResult {\n const {\n htmlPaths,\n outputDir,\n outputName,\n outputFormat,\n overwrite = false,\n } = options;\n if (!htmlPaths || htmlPaths.length === 0) {\n throw new Error('mergeReportFiles: htmlPaths is required');\n }\n\n const resolvedPaths = htmlPaths.map((p) => resolveReportHtmlPath(p));\n\n const tool = new ReportMergingTool();\n resolvedPaths.forEach((htmlPath, index) => {\n tool.append({\n reportFilePath: htmlPath,\n reportAttributes: deriveReportAttributesFromHtml(htmlPath, index),\n });\n });\n\n const mergedReportPath = tool.mergeReports(outputName ?? 'AUTO', {\n overwrite,\n outputDir,\n outputFormat,\n });\n\n if (!mergedReportPath) {\n throw new Error('mergeReportFiles: failed to produce a merged report');\n }\n\n return { mergedReportPath };\n}\n\nfunction normalizeHtmlReportArg(raw: unknown): string[] | undefined {\n if (raw === undefined || raw === null) return undefined;\n if (Array.isArray(raw)) {\n return raw.filter(\n (p): p is string => typeof p === 'string' && p.length > 0,\n );\n }\n if (typeof raw === 'string') {\n const trimmed = raw.trim();\n return trimmed ? [trimmed] : [];\n }\n return undefined;\n}\n\nconst reportCommandDefinition: ReportCliCommandDefinition = {\n name: 'report-tool',\n description:\n 'Transform Midscene report artifacts, including splitting executions, converting to markdown, merging multiple reports, and exporting portable reports in either storage format.',\n schema: {\n action: z\n .enum(['split', 'to-markdown', 'merge-html', 'export'])\n .optional()\n .describe(\n 'Report action to run. Supports: split, to-markdown, merge-html, export. Defaults to split.',\n ),\n htmlPath: z\n .string()\n .optional()\n .describe(\n 'Input report HTML path (e.g. ./report/index.html). Used by split, to-markdown, and export.',\n ),\n htmlReport: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe(\n 'Input report HTML path for the merge action. Repeat the flag to merge multiple reports (e.g. --htmlReport ./a/index.html --htmlReport ./b.html).',\n ),\n outputDir: z\n .string()\n .optional()\n .describe(\n 'Output directory for generated report artifacts. For merge, defaults to the Midscene report directory.',\n ),\n outputName: z\n .string()\n .optional()\n .describe(\n 'Output report file/directory name (without .html). Merge generates a name; export uses the input name by default.',\n ),\n overwrite: z\n .union([z.boolean(), z.string()])\n .optional()\n .describe('Overwrite an existing output report for merge or export.'),\n outputFormat: z\n .enum(['single-html', 'html-and-external-assets'])\n .optional()\n .describe(\n 'Final delivery format for merge and export. Defaults to single-html.',\n ),\n },\n handler: async (args) => {\n const {\n action = 'split',\n htmlPath,\n htmlReport,\n outputDir,\n outputName,\n overwrite,\n outputFormat,\n } = args as {\n action?: string;\n htmlPath?: string;\n htmlReport?: unknown;\n outputDir?: string;\n outputName?: string;\n overwrite?: unknown;\n outputFormat?: 'single-html' | 'html-and-external-assets';\n };\n if (\n action !== 'split' &&\n action !== 'to-markdown' &&\n action !== 'merge-html' &&\n action !== 'export'\n ) {\n throw new Error(\n `report-tool: unsupported --action value \"${action}\". Currently supported: split, to-markdown, merge-html, export`,\n );\n }\n\n if (action === 'merge-html') {\n const paths = normalizeHtmlReportArg(htmlReport);\n if (!paths || paths.length === 0) {\n throw new Error(\n 'report-tool: --htmlReport is required for action \"merge-html\". Repeat --htmlReport for each report (e.g. --htmlReport ./a/index.html --htmlReport ./b.html).',\n );\n }\n\n const overwriteFlag =\n overwrite === true || overwrite === 'true' || overwrite === '1';\n\n const result = mergeReportFiles({\n htmlPaths: paths,\n outputDir,\n outputName,\n outputFormat,\n overwrite: overwriteFlag,\n });\n\n return {\n isError: false,\n content: [\n {\n type: 'text',\n text: `Merged ${paths.length} report(s) into ${result.mergedReportPath}`,\n },\n ],\n };\n }\n\n if (!htmlPath) {\n throw new Error('report-tool: --htmlPath is required');\n }\n\n if (!outputDir) {\n throw new Error('report-tool: --outputDir is required');\n }\n\n if (action === 'export') {\n const input = resolveReportHtmlPath(htmlPath);\n const name =\n outputName ??\n (path.basename(input) === 'index.html'\n ? path.basename(path.dirname(input))\n : path.basename(input, '.html'));\n const reportPath = await exportReportArtifact({\n reportPath: input,\n outputDir,\n reportFileName: name,\n outputFormat,\n overwrite:\n overwrite === true || overwrite === 'true' || overwrite === '1',\n });\n return {\n isError: false,\n content: [{ type: 'text', text: `Report exported to ${reportPath}` }],\n };\n }\n\n if (action === 'to-markdown') {\n const result = await reportFileToMarkdown({\n htmlPath,\n outputDir,\n });\n return {\n isError: false,\n content: [\n {\n type: 'text',\n text: `Markdown export completed. Generated ${result.markdownFiles.length} markdown file(s) and ${result.screenshotFiles.length} screenshot(s). Output path: ${outputDir}`,\n },\n ],\n };\n }\n\n const result = splitReportFile({\n htmlPath,\n outputDir,\n });\n\n return {\n isError: false,\n content: [\n {\n type: 'text',\n text: `Report split completed. Generated ${result.executionJsonFiles.length} execution JSON files and ${result.screenshotFiles.length} screenshots. Output path: ${outputDir}`,\n },\n ],\n };\n },\n};\n\nexport function createReportCliCommands(): ReportCliCommandEntry[] {\n return [\n {\n name: 'report-tool',\n def: reportCommandDefinition,\n },\n ];\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","markdownFromReport","htmlPath","outputDir","screenshotsDir","path","mkdirSync","baseDump","executions","collectDedupedExecutions","mergedReport","ReportActionDump","images","ReportImageExporter","result","reportToMarkdown","attachment","markdownFiles","mdPath","writeFileSync","resolveReportHtmlPath","normalizedPath","existsSync","Error","stats","statSync","indexHtmlPath","splitReportFile","options","resolvedHtmlPath","splitReportHtmlByExecution","reportFileToMarkdown","TEST_STATUS_VALUES","Set","FAILING_TEST_STATUSES","readSourceTestStatus","recorded","streamReportDumpScripts","openTag","match","status","decodeURIComponent","s","deriveReportAttributesFromHtml","index","fallbackId","runnerDump","readReportRunnerDump","recordedStatus","testStatus","deriveCaseStatus","collectReportSummary","mergeReportFiles","htmlPaths","outputName","outputFormat","overwrite","resolvedPaths","p","tool","ReportMergingTool","mergedReportPath","normalizeHtmlReportArg","raw","Array","trimmed","reportCommandDefinition","z","args","action","htmlReport","paths","overwriteFlag","input","name","reportPath","exportReportArtifact","createReportCliCommands"],"mappings":"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"}
@@ -149,10 +149,11 @@ class ReportGenerator {
149
149
  sourcePath: this.reportPath
150
150
  });
151
151
  for (const diagnostic of dump.diagnostics ?? [])warnReport(diagnostic.message);
152
+ this.enableSourceSnapshots(scopeId);
152
153
  const sourceDump = await this.serializeSourceDump();
153
154
  const images = [];
154
155
  if ('inline' === this.screenshotMode) for (const ref of sourceDump.images.values()){
155
- const bytes = await (0, promises_namespaceObject.readFile)((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.reportPath), ref.path));
156
+ const bytes = await (0, promises_namespaceObject.readFile)((0, external_node_path_namespaceObject.join)(this.sourceDirectory, ref.path));
156
157
  images.push((0, html_utils_js_namespaceObject.generateImageScriptTag)(ref.id, `data:${ref.mimeType};base64,${bytes.toString('base64')}`));
157
158
  }
158
159
  if (this.artifactStore) {
@@ -206,19 +207,27 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
206
207
  await this.flush();
207
208
  return this.reportPath;
208
209
  }
209
- enableSourceSnapshots() {
210
- this.screenshotStore.enableFileCopies();
210
+ enableSourceSnapshots(scopeId = this.reportStreamId) {
211
+ if (!scopeId || '.' === scopeId || '..' === scopeId || /[/\\]/.test(scopeId)) throw new Error('Invalid report scope ID');
212
+ if (this.sourceStore) return;
213
+ this.sourceDirectory = (0, external_node_path_namespaceObject.join)((0, common_namespaceObject.getMidsceneRunSubDir)('test-results'), scopeId, 'records');
214
+ this.sourceStore = new screenshot_store_js_namespaceObject.ReportImageStore({
215
+ mode: 'directory',
216
+ reportPath: (0, external_node_path_namespaceObject.join)(this.sourceDirectory, 'source.json'),
217
+ screenshotsDir: (0, external_node_path_namespaceObject.join)(this.sourceDirectory, 'screenshots')
218
+ });
211
219
  }
212
220
  async serializeSourceDump(snapshot) {
213
221
  this.enableSourceSnapshots();
222
+ const store = this.sourceStore;
214
223
  const captured = snapshot ?? this.recorder.capture(void 0, this.lastReportMeta ?? {
215
224
  sdkVersion: '',
216
225
  groupName: 'YAML execution',
217
226
  modelBriefs: []
218
227
  });
219
- for (const screenshot of captured.screenshots)await this.screenshotStore.persist(screenshot);
228
+ for (const screenshot of captured.screenshots)await store.persistFileCopy(screenshot);
220
229
  const references = new Map();
221
- for (const url of captured.referenceImageUrls)references.set(url, await this.screenshotStore.persistReferenceImage(url));
230
+ for (const url of captured.referenceImageUrls)references.set(url, await store.persistReferenceImage(url));
222
231
  const images = new Map();
223
232
  const serialized = JSON.stringify(JSON.parse(captured.dump.serializeWithReferenceImages(references)), (_key, value)=>{
224
233
  const ref = (0, image_reference_js_namespaceObject.normalizeStoredImageRef)(value);
@@ -226,7 +235,7 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
226
235
  const stored = {
227
236
  ...ref,
228
237
  storage: 'file',
229
- path: 'file' === ref.storage ? ref.path : this.screenshotStore.getFilePath(ref.id)
238
+ path: store.getFilePath(ref.id)
230
239
  };
231
240
  images.set(ref.id, stored);
232
241
  return stored;
@@ -246,7 +255,7 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
246
255
  });
247
256
  const publication = (async ()=>{
248
257
  const { serialized } = await this.serializeSourceDump(snapshot);
249
- const dumpPath = `${this.reportPath}.${scopeId}.${(0, utils_namespaceObject.uuid)()}.json`;
258
+ const dumpPath = (0, external_node_path_namespaceObject.join)(this.sourceDirectory, `${this.reportStreamId}.${scopeId}.${(0, utils_namespaceObject.uuid)()}.json`);
250
259
  (0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.dirname)(dumpPath), {
251
260
  recursive: true
252
261
  });
@@ -328,7 +337,10 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
328
337
  await (0, promises_namespaceObject.writeFile)(this.reportPath, `${(0, external_utils_js_namespaceObject.getReportTpl)()}${baseUrlFix}${marker}`);
329
338
  this.initialized = true;
330
339
  }
331
- for (const screenshot of execution.collectScreenshots())await this.screenshotStore.persist(screenshot);
340
+ for (const screenshot of execution.collectScreenshots()){
341
+ await this.sourceStore?.persistFileCopy(screenshot);
342
+ await this.screenshotStore.persist(screenshot);
343
+ }
332
344
  const referenceImageRefs = await this.persistReferenceImages(execution);
333
345
  const serialized = singleDump.serializeWithReferenceImages(referenceImageRefs);
334
346
  if (this.artifactStore) await this.artifactStore.writeExecution(this.getExecutionCommentKey(execution), serialized, this.getDumpScriptAttributes());
@@ -406,6 +418,8 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
406
418
  _define_property(this, "executionLogFileIndexByExecutionKey", new Map());
407
419
  _define_property(this, "reportStreamId", void 0);
408
420
  _define_property(this, "screenshotStore", void 0);
421
+ _define_property(this, "sourceStore", void 0);
422
+ _define_property(this, "sourceDirectory", void 0);
409
423
  _define_property(this, "initialized", false);
410
424
  _define_property(this, "lastExecution", void 0);
411
425
  _define_property(this, "lastReportMeta", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"report-generator.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report-generator.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/*\n * PERF INVARIANT — DO NOT reintroduce sync fs APIs (writeFileSync /\n * appendFileSync) in this file's write paths. `ReportGenerator` runs on\n * the Electron main event loop during agent execution, and a single\n * progress tick appends a multi-MB ExecutionDump payload. Sync I/O here\n * blocked the loop for 20+ seconds per run, freezing IPC, scrcpy and\n * every renderer round-trip. Always use `fs/promises`. See commit\n * 6a25e05c and `report-generator-async-contract.test.ts`.\n */\nimport { existsSync, mkdirSync, readdirSync } from 'node:fs';\nimport {\n appendFile as appendFileAsync,\n readFile as readFileAsync,\n rename as renameAsync,\n unlink as unlinkAsync,\n writeFile as writeFileAsync,\n} from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport {\n MIDSCENE_REPORT_QUIET,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug, logReport } from '@midscene/shared/logger';\nimport { ifInBrowser, uuid } from '@midscene/shared/utils';\nimport {\n type ExecutionRecordSnapshot,\n ExecutionRecorder,\n} from './dump/execution-recorder';\nimport {\n DATA_SCREENSHOT_MODE_ATTR,\n generateAgentReportComment,\n generateDumpScriptTag,\n generateImageScriptTag,\n generateReportArtifactScriptTag,\n generateTestRunReportScriptTag,\n getBaseUrlFixScript,\n} from './dump/html-utils';\nimport { normalizeStoredImageRef } from './dump/image-reference';\nimport { readReportArtifactManifest } from './dump/report-artifact-reader';\nimport { ReportArtifactStore } from './dump/report-artifact-store';\nimport { compactReportDumps } from './dump/report-dump-compactor';\nimport { type ImageUrlRef, ReportImageStore } from './dump/screenshot-store';\nimport type { WorkflowReportSource } from './test-runner/engine/types';\nimport { buildAgentTestRunReportDump } from './test-runner/reporting/agent-report';\nimport type { RunReportInput } from './test-runner/reporting/types';\nimport {\n type ExecutionDump,\n ReportActionDump,\n type ReportAttributes,\n type ReportMeta,\n type ScreenshotMode,\n} from './types';\nimport { getReportTpl } from './utils';\n\nconst warnReport = getDebug('report-generator', { console: true });\nconst maxReportFilenameBytes = 255;\n\nexport interface IReportGenerator {\n /**\n * Write or update a single execution.\n * Inline reports append dump tags; directory reports replace the execution's\n * data file. Both retain the latest state for each stable execution ID.\n *\n * @param execution Current execution's full data\n * @param reportMeta Report-level metadata (groupName, sdkVersion, etc.)\n */\n onExecutionUpdate(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n attributes?: ReportAttributes,\n ): void;\n\n /**\n * @deprecated Use onExecutionUpdate instead. Kept for backward compatibility.\n */\n onDumpUpdate?(dump: ReportActionDump): void;\n\n /**\n * Wait for all queued write operations to complete.\n */\n flush(): Promise<void>;\n enableSourceSnapshots?(): void;\n createSourceSnapshot?(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource | undefined>;\n\n /**\n * Finalize the report. Calls flush() internally.\n */\n finalize(): Promise<string | undefined>;\n\n getReportPath(): string | undefined;\n /** Publish a single root Runner snapshot into this Agent's existing report. */\n writeRunnerReport?(\n input: RunReportInput,\n scopeId: string,\n meta: ReportMeta,\n ): Promise<string | undefined>;\n}\n\nexport const nullReportGenerator: IReportGenerator = {\n onExecutionUpdate: () => {},\n flush: async () => {},\n finalize: async () => undefined,\n getReportPath: () => undefined,\n writeRunnerReport: async () => undefined,\n};\n\nexport function assertReportGenerationOptions(opts: {\n generateReport?: boolean;\n persistExecutionDump?: boolean;\n}): void {\n if (opts.generateReport === false && opts.persistExecutionDump === true) {\n throw new Error(\n 'persistExecutionDump cannot be true when generateReport is false',\n );\n }\n}\n\nexport class ReportGenerator implements IReportGenerator {\n private reportPath: string;\n private screenshotMode: ScreenshotMode;\n private shouldPersistExecutionDump: boolean;\n private autoPrint: boolean;\n private firstWriteDone = false;\n private executionLogIndex = 0;\n private executionLogFileIndexByExecutionKey = new Map<string, number>();\n\n // Unique identifier for this report stream — used as data-group-id\n private readonly reportStreamId: string;\n\n // Tracks screenshots already written to disk (by id) to avoid duplicates\n private screenshotStore: ReportImageStore;\n private initialized = false;\n\n // Tracks the last execution + groupMeta for re-writing on finalize\n private lastExecution?: ExecutionDump;\n private lastReportMeta?: ReportMeta;\n private readonly recorder = new ExecutionRecorder();\n private readonly artifactStore?: ReportArtifactStore;\n private executionCommentKeyByObject = new WeakMap<ExecutionDump, string>();\n private executionCommentKeyIndex = 0;\n private reportAttributes: Record<string, string> = {};\n private agentCommentWritten = false;\n\n // write queue for serial execution\n private writeQueue: Promise<void> = Promise.resolve();\n private finalization?: Promise<string | undefined>;\n private sourcePublications = new Set<Promise<unknown>>();\n\n constructor(options: {\n reportPath: string;\n screenshotMode: ScreenshotMode;\n persistExecutionDump?: boolean;\n autoPrint?: boolean;\n reuseExistingReport?: boolean;\n }) {\n this.reportPath = options.reportPath;\n this.screenshotMode = options.screenshotMode;\n this.shouldPersistExecutionDump = options.persistExecutionDump ?? false;\n this.autoPrint = options.autoPrint ?? true;\n this.reportStreamId = uuid();\n if (this.screenshotMode === 'directory') {\n this.artifactStore = new ReportArtifactStore(\n dirname(this.reportPath),\n this.reportStreamId,\n 'agent',\n options.reuseExistingReport,\n basename(this.reportPath),\n );\n }\n this.screenshotStore = new ReportImageStore({\n mode: this.screenshotMode === 'inline' ? 'inline' : 'directory',\n reportPath: this.reportPath,\n screenshotsDir: join(dirname(this.reportPath), 'screenshots'),\n writeInlineImage: async (id, base64) => {\n await appendFileAsync(\n this.reportPath,\n `\\n${generateImageScriptTag(id, base64)}`,\n );\n },\n alsoWriteFileCopy: this.shouldPersistExecutionDump,\n reuseExistingReport: options.reuseExistingReport,\n });\n if (options.reuseExistingReport) {\n this.hydrateStateFromExistingReport();\n }\n }\n\n static create(\n reportFileName: string,\n opts: {\n generateReport?: boolean;\n persistExecutionDump?: boolean;\n outputFormat?: 'single-html' | 'html-and-external-assets';\n autoPrintReportMsg?: boolean;\n reuseExistingReport?: boolean;\n },\n ): IReportGenerator {\n assertReportGenerationOptions(opts);\n validateReportFileName(reportFileName, opts.outputFormat);\n if (opts.generateReport === false) return nullReportGenerator;\n\n // In browser environment, file system is not available\n if (ifInBrowser) return nullReportGenerator;\n\n const reportRootDir = getMidsceneRunSubDir('report');\n const outputDir = join(reportRootDir, reportFileName);\n const reportPath =\n opts.outputFormat === 'html-and-external-assets'\n ? join(outputDir, 'index.html')\n : join(reportRootDir, ensureHtmlFileName(reportFileName));\n return new ReportGenerator({\n reportPath,\n screenshotMode:\n opts.outputFormat === 'html-and-external-assets'\n ? 'directory'\n : 'inline',\n persistExecutionDump: opts.persistExecutionDump,\n autoPrint: opts.autoPrintReportMsg,\n reuseExistingReport: opts.reuseExistingReport,\n });\n }\n\n onExecutionUpdate(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n attributes?: ReportAttributes,\n ): void {\n this.assertOpen();\n this.lastExecution = execution;\n this.lastReportMeta = reportMeta;\n this.recorder.record(execution, reportMeta);\n this.mergeReportAttributes(attributes);\n this.writeQueue = this.writeQueue.then(async () => {\n await this.doWriteExecution(execution, reportMeta);\n });\n }\n\n async flush(): Promise<void> {\n await this.writeQueue;\n }\n\n async finalize(): Promise<string | undefined> {\n if (!this.finalization) {\n // Enqueue the final state before sealing the generator to new writes.\n if (this.lastExecution && this.lastReportMeta) {\n this.onExecutionUpdate(this.lastExecution, this.lastReportMeta);\n }\n this.finalization = this.finishPublication();\n }\n return this.finalization;\n }\n\n private async finishPublication(): Promise<string | undefined> {\n // Snapshots freeze independently of the HTML queue, but both must be on\n // disk before their backing executions and diagnostic data are released.\n await Promise.all([this.flush(), ...this.sourcePublications]);\n if (this.initialized) {\n if (this.artifactStore) {\n await this.artifactStore.finalize();\n } else {\n await this.appendAgentReportComment();\n try {\n await compactReportDumps(this.reportPath);\n } catch (error) {\n warnReport(\n `Failed to compact report ${this.reportPath}; keeping the uncompressed report: ${String(error)}`,\n );\n }\n }\n }\n this.recorder.clear();\n this.lastExecution = undefined;\n this.lastReportMeta = undefined;\n this.executionCommentKeyByObject = new WeakMap();\n this.executionLogFileIndexByExecutionKey.clear();\n return this.initialized ? this.reportPath : undefined;\n }\n\n private assertOpen(): void {\n if (this.finalization) throw new Error('The report has been finalized.');\n }\n\n getReportPath(): string | undefined {\n return this.reportPath;\n }\n\n async writeRunnerReport(\n input: RunReportInput,\n scopeId: string,\n meta: ReportMeta,\n ): Promise<string> {\n this.assertOpen();\n this.writeQueue = this.writeQueue.then(async () => {\n // This runs at YAML invocation completion, never on progress ticks. Keep\n // all file I/O asynchronous and publish atomically for an open viewer.\n const reportMeta = this.lastReportMeta ?? meta;\n const executions = this.recorder.executions;\n const agentDump = new ReportActionDump({ ...reportMeta, executions });\n const reportId =\n this.reportAttributes['data-report-id'] ??\n this.reportAttributes['data-group-id'] ??\n this.reportStreamId;\n const dump = buildAgentTestRunReportDump(input, agentDump, {\n reportId,\n scopeId,\n sourcePath: this.reportPath,\n });\n for (const diagnostic of dump.diagnostics ?? [])\n warnReport(diagnostic.message);\n const sourceDump = await this.serializeSourceDump();\n const images: string[] = [];\n if (this.screenshotMode === 'inline') {\n for (const ref of sourceDump.images.values()) {\n const bytes = await readFileAsync(\n join(dirname(this.reportPath), ref.path!),\n );\n images.push(\n generateImageScriptTag(\n ref.id,\n `data:${ref.mimeType};base64,${bytes.toString('base64')}`,\n ),\n );\n }\n }\n if (this.artifactStore) {\n for (const execution of executions) {\n await this.writeExecution(\n execution,\n this.wrapAsReportDump(execution, reportMeta),\n );\n }\n if (!executions.length) {\n // An empty execution group still carries setup/collection diagnostics.\n await this.artifactStore.writeExecution(\n 'empty',\n sourceDump.serialized,\n this.getDumpScriptAttributes(),\n );\n if (!this.initialized) {\n const marker = generateReportArtifactScriptTag('report.json');\n await writeFileAsync(\n this.reportPath,\n `${getReportTpl()}${getBaseUrlFixScript()}\\n${marker}`,\n );\n this.initialized = true;\n }\n }\n await this.artifactStore.writeRunner(JSON.stringify(dump));\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n return;\n }\n // Rebuild from the owned dump and image index, never parse this HTML back.\n const renderedDump =\n this.screenshotMode === 'inline'\n ? JSON.stringify(JSON.parse(sourceDump.serialized), (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n return ref\n ? { ...ref, storage: 'inline', path: undefined }\n : value;\n })\n : sourceDump.serialized;\n const contents = `${getReportTpl()}${this.screenshotMode === 'directory' ? getBaseUrlFixScript() : ''}\n${generateDumpScriptTag(renderedDump, this.getDumpScriptAttributes())}\n${images.join('\\n')}\n${generateTestRunReportScriptTag(dump)}\n${generateAgentReportComment(agentDump)}`;\n mkdirSync(dirname(this.reportPath), { recursive: true });\n const temporaryPath = `${this.reportPath}.runner-${uuid()}.tmp`;\n try {\n await writeFileAsync(temporaryPath, contents);\n await renameAsync(temporaryPath, this.reportPath);\n } finally {\n await unlinkAsync(temporaryPath).catch((error) => {\n if (error.code !== 'ENOENT') throw error;\n });\n }\n this.initialized = true;\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n });\n await this.flush();\n return this.reportPath;\n }\n\n enableSourceSnapshots(): void {\n this.screenshotStore.enableFileCopies();\n }\n\n private async serializeSourceDump(snapshot?: ExecutionRecordSnapshot) {\n this.enableSourceSnapshots();\n const captured =\n snapshot ??\n this.recorder.capture(\n undefined,\n this.lastReportMeta ?? {\n sdkVersion: '',\n groupName: 'YAML execution',\n modelBriefs: [],\n },\n );\n for (const screenshot of captured.screenshots)\n await this.screenshotStore.persist(screenshot);\n const references = new Map<string, ImageUrlRef>();\n for (const url of captured.referenceImageUrls) {\n references.set(\n url,\n await this.screenshotStore.persistReferenceImage(url),\n );\n }\n const images = new Map<\n string,\n ReturnType<typeof normalizeStoredImageRef> & {}\n >();\n const serialized = JSON.stringify(\n JSON.parse(captured.dump.serializeWithReferenceImages(references)),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n if (!ref) return value;\n const stored = {\n ...ref,\n storage: 'file' as const,\n path:\n ref.storage === 'file'\n ? ref.path\n : this.screenshotStore.getFilePath(ref.id),\n };\n images.set(ref.id, stored);\n return stored;\n },\n );\n return { serialized, images };\n }\n\n async createSourceSnapshot(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource & { dumpPath: string }> {\n this.assertOpen();\n if (!scopeId || basename(scopeId) !== scopeId)\n throw new Error('Invalid report scope ID');\n const snapshot = this.recorder.capture(\n executionIds,\n this.lastReportMeta ?? {\n sdkVersion: '',\n groupName: 'YAML execution',\n modelBriefs: [],\n },\n );\n const publication = (async () => {\n const { serialized } = await this.serializeSourceDump(snapshot);\n const dumpPath = `${this.reportPath}.${scopeId}.${uuid()}.json`;\n mkdirSync(dirname(dumpPath), { recursive: true });\n await writeFileAsync(dumpPath, serialized, { flag: 'wx' });\n return {\n sourcePath: this.reportPath,\n dumpPath,\n collection: {\n status: 'complete' as const,\n capturedAt: snapshot.capturedAt,\n },\n };\n })();\n this.sourcePublications.add(publication);\n try {\n return await publication;\n } finally {\n this.sourcePublications.delete(publication);\n }\n }\n\n private printReportPath(): void {\n if (!this.autoPrint || !this.reportPath) return;\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET))\n return;\n\n if (this.screenshotMode === 'directory') {\n logReport(\n `Midscene - report file updated: npx serve ${dirname(this.reportPath)}`,\n );\n } else {\n logReport(`Midscene - report file updated: ${this.reportPath}`);\n }\n }\n\n private async doWriteExecution(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): Promise<void> {\n const singleDump = this.wrapAsReportDump(execution, reportMeta);\n\n const referenceImageRefs = await this.writeExecution(execution, singleDump);\n\n if (this.shouldPersistExecutionDump && !this.artifactStore) {\n await this.persistExecutionDumpToFile(\n execution,\n singleDump,\n referenceImageRefs,\n );\n }\n\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n }\n\n private mergeReportAttributes(attributes?: ReportAttributes): void {\n if (!attributes) {\n return;\n }\n\n for (const [key, value] of Object.entries(attributes)) {\n if (value === undefined || value === null) {\n continue;\n }\n this.reportAttributes[key] = String(value);\n }\n }\n\n private hydrateStateFromExistingReport(): void {\n if (!existsSync(this.reportPath)) {\n return;\n }\n\n if (this.artifactStore && !readReportArtifactManifest(this.reportPath)) {\n throw new Error(\n 'Cannot reuse an incompatible directory report. Choose a new reportFileName or regenerate the report.',\n );\n }\n\n // Reuse existing report file and append new updates instead of rewriting.\n this.initialized = true;\n\n if (!this.shouldPersistExecutionDump) {\n return;\n }\n\n if (!existsSync(this.executionDumpDir)) return;\n const existingExecutionIndices = readdirSync(this.executionDumpDir)\n .map((name) => /^(\\d+)\\.execution\\.json$/.exec(name)?.[1])\n .filter((index): index is string => Boolean(index))\n .map((index) => Number.parseInt(index, 10))\n .filter((index) => Number.isFinite(index));\n\n if (existingExecutionIndices.length > 0) {\n this.executionLogIndex = Math.max(...existingExecutionIndices);\n }\n }\n\n private getDumpScriptAttributes(): Record<string, string> {\n return {\n 'data-group-id': this.reportStreamId,\n // Self-describe how this report file stores screenshots so consumers\n // (merge/delete) never have to guess the mode from the filesystem.\n [DATA_SCREENSHOT_MODE_ATTR]: this.screenshotMode,\n ...this.reportAttributes,\n 'data-report-kind': 'agent',\n };\n }\n\n /**\n * Wrap an ExecutionDump + ReportMeta into a single-execution ReportActionDump.\n */\n private wrapAsReportDump(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): ReportActionDump {\n return new ReportActionDump({\n sdkVersion: reportMeta.sdkVersion,\n groupName: reportMeta.groupName,\n groupDescription: reportMeta.groupDescription,\n modelBriefs: reportMeta.modelBriefs,\n deviceType: reportMeta.deviceType,\n executions: [execution],\n });\n }\n\n /**\n * Append assets and a dump tag without duplicating mode-specific workflows.\n * The frontend deduplicates executions with the same id/name (keeps last).\n * Duplicate dump JSON is acceptable; only screenshots are deduplicated.\n *\n * All writes go through `fs/promises` so they run on libuv's thread pool\n * rather than blocking the Node event loop. A long agent run previously\n * appended multi-MB dumps (screenshots + serialized tasks) per progress\n * tick on the main thread, starving IPC and UI for >10s per stall.\n */\n private async writeExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<Map<string, ImageUrlRef>> {\n const dir = dirname(this.reportPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Initialize: write HTML template once\n if (!this.initialized) {\n const baseUrlFix =\n this.screenshotMode === 'directory' ? getBaseUrlFixScript() : '';\n const marker = this.artifactStore\n ? `\\n${generateReportArtifactScriptTag('report.json')}`\n : '';\n await writeFileAsync(\n this.reportPath,\n `${getReportTpl()}${baseUrlFix}${marker}`,\n );\n this.initialized = true;\n }\n\n // Append new screenshots (skip already-written ones)\n for (const screenshot of execution.collectScreenshots()) {\n await this.screenshotStore.persist(screenshot);\n }\n const referenceImageRefs = await this.persistReferenceImages(execution);\n\n // Publish the latest facts using the selected storage format.\n const serialized =\n singleDump.serializeWithReferenceImages(referenceImageRefs);\n if (this.artifactStore) {\n await this.artifactStore.writeExecution(\n this.getExecutionCommentKey(execution),\n serialized,\n this.getDumpScriptAttributes(),\n );\n } else {\n await appendFileAsync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\n }\n return referenceImageRefs;\n }\n\n private async persistReferenceImages(\n execution: ExecutionDump,\n ): Promise<Map<string, ImageUrlRef>> {\n const refs = new Map<string, ImageUrlRef>();\n for (const imageUrl of execution.getReferenceImageUrls()) {\n const ref = await this.screenshotStore.persistReferenceImage(imageUrl);\n refs.set(imageUrl, ref);\n }\n return refs;\n }\n\n private async appendAgentReportComment(): Promise<void> {\n if (\n this.agentCommentWritten ||\n !this.lastReportMeta ||\n this.recorder.executions.length === 0\n ) {\n return;\n }\n\n const reportDump = new ReportActionDump({\n sdkVersion: this.lastReportMeta.sdkVersion,\n groupName: this.lastReportMeta.groupName,\n groupDescription: this.lastReportMeta.groupDescription,\n modelBriefs: this.lastReportMeta.modelBriefs,\n deviceType: this.lastReportMeta.deviceType,\n executions: this.recorder.executions,\n });\n await appendFileAsync(\n this.reportPath,\n `\\n${generateAgentReportComment(reportDump)}`,\n );\n this.agentCommentWritten = true;\n }\n\n private getExecutionLogKey(execution: ExecutionDump): string {\n if (!execution.id) {\n throw new Error(\n 'ReportGenerator: execution.id is required for persisting execution dumps',\n );\n }\n return `id:${execution.id}`;\n }\n\n private getExecutionCommentKey(execution: ExecutionDump): string {\n if (execution.id) {\n return `id:${execution.id}`;\n }\n\n const existingKey = this.executionCommentKeyByObject.get(execution);\n if (existingKey) {\n return existingKey;\n }\n\n const key = `no-id:${this.executionCommentKeyIndex++}`;\n this.executionCommentKeyByObject.set(execution, key);\n return key;\n }\n\n private get executionDumpDir(): string {\n // Inline HTML files share their parent directory. Each needs its own\n // numbered JSON namespace; external-asset reports already have one.\n return this.screenshotMode === 'inline'\n ? join(\n dirname(this.reportPath),\n '.execution-dumps',\n basename(this.reportPath),\n )\n : dirname(this.reportPath);\n }\n\n private async persistExecutionDumpToFile(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n referenceImageRefs: ReadonlyMap<string, ImageUrlRef>,\n ): Promise<void> {\n const dir = this.executionDumpDir;\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n const executionLogKey = this.getExecutionLogKey(execution);\n let fileIndex =\n this.executionLogFileIndexByExecutionKey.get(executionLogKey);\n if (!fileIndex) {\n this.executionLogIndex += 1;\n fileIndex = this.executionLogIndex;\n this.executionLogFileIndexByExecutionKey.set(executionLogKey, fileIndex);\n }\n\n const fileName = `${fileIndex}.execution.json`;\n const filePath = join(dir, fileName);\n let serialized = singleDump.serializeWithReferenceImages(\n referenceImageRefs,\n 2,\n );\n if (this.screenshotMode === 'inline') {\n // JSON is two directories below the HTML. Point to the existing file\n // copies so it can be consumed without resolving inline HTML assets.\n serialized = JSON.stringify(\n JSON.parse(serialized),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n return ref\n ? {\n ...ref,\n storage: 'file',\n path: `../../${this.screenshotStore.getFilePath(ref.id).replace(/^\\.\\//, '')}`,\n }\n : value;\n },\n 2,\n );\n }\n await writeFileAsync(filePath, serialized, 'utf-8');\n }\n}\n\nfunction ensureHtmlFileName(reportFileName: string): string {\n return reportFileName.endsWith('.html')\n ? reportFileName\n : `${reportFileName}.html`;\n}\n\nfunction validateReportFileName(\n reportFileName: string,\n outputFormat?: 'single-html' | 'html-and-external-assets',\n): void {\n if (!reportFileName?.trim()) {\n throw new Error('reportFileName must be a non-empty string');\n }\n\n if (/[\\\\/]/.test(reportFileName)) {\n throw new Error(\n 'reportFileName must not contain path separators (`/` or `\\\\\\\\`)',\n );\n }\n\n if (/[:*?\"<>|]/.test(reportFileName)) {\n throw new Error(\n 'reportFileName contains illegal filename characters: : * ? \" < > |',\n );\n }\n\n const filenameComponent =\n outputFormat === 'html-and-external-assets'\n ? reportFileName\n : ensureHtmlFileName(reportFileName);\n const filenameBytes = new TextEncoder().encode(filenameComponent).byteLength;\n if (filenameBytes > maxReportFilenameBytes) {\n throw new Error(\n `reportFileName produces a filename component of ${filenameBytes} UTF-8 bytes; maximum is ${maxReportFilenameBytes}`,\n );\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","warnReport","getDebug","maxReportFilenameBytes","nullReportGenerator","undefined","assertReportGenerationOptions","opts","Error","ReportGenerator","reportFileName","validateReportFileName","ifInBrowser","reportRootDir","getMidsceneRunSubDir","outputDir","join","reportPath","ensureHtmlFileName","execution","reportMeta","attributes","Promise","compactReportDumps","error","String","WeakMap","input","scopeId","meta","executions","agentDump","ReportActionDump","reportId","dump","buildAgentTestRunReportDump","diagnostic","sourceDump","images","ref","bytes","readFileAsync","dirname","generateImageScriptTag","marker","generateReportArtifactScriptTag","writeFileAsync","getReportTpl","getBaseUrlFixScript","JSON","renderedDump","_key","value","normalizeStoredImageRef","contents","generateDumpScriptTag","generateTestRunReportScriptTag","generateAgentReportComment","mkdirSync","temporaryPath","uuid","renameAsync","unlinkAsync","snapshot","captured","screenshot","references","Map","url","serialized","stored","executionIds","basename","publication","dumpPath","globalConfigManager","MIDSCENE_REPORT_QUIET","logReport","singleDump","referenceImageRefs","existsSync","readReportArtifactManifest","existingExecutionIndices","readdirSync","name","index","Boolean","Number","Math","DATA_SCREENSHOT_MODE_ATTR","dir","baseUrlFix","appendFileAsync","refs","imageUrl","reportDump","existingKey","executionLogKey","fileIndex","fileName","filePath","options","ExecutionRecorder","Set","ReportArtifactStore","ReportImageStore","id","base64","outputFormat","filenameComponent","filenameBytes","TextEncoder"],"mappings":"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"}
1
+ {"version":3,"file":"report-generator.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report-generator.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/*\n * PERF INVARIANT — DO NOT reintroduce sync fs APIs (writeFileSync /\n * appendFileSync) in this file's write paths. `ReportGenerator` runs on\n * the Electron main event loop during agent execution, and a single\n * progress tick appends a multi-MB ExecutionDump payload. Sync I/O here\n * blocked the loop for 20+ seconds per run, freezing IPC, scrcpy and\n * every renderer round-trip. Always use `fs/promises`. See commit\n * 6a25e05c and `report-generator-async-contract.test.ts`.\n */\nimport { existsSync, mkdirSync, readdirSync } from 'node:fs';\nimport {\n appendFile as appendFileAsync,\n readFile as readFileAsync,\n rename as renameAsync,\n unlink as unlinkAsync,\n writeFile as writeFileAsync,\n} from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport {\n MIDSCENE_REPORT_QUIET,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug, logReport } from '@midscene/shared/logger';\nimport { ifInBrowser, uuid } from '@midscene/shared/utils';\nimport {\n type ExecutionRecordSnapshot,\n ExecutionRecorder,\n} from './dump/execution-recorder';\nimport {\n DATA_SCREENSHOT_MODE_ATTR,\n generateAgentReportComment,\n generateDumpScriptTag,\n generateImageScriptTag,\n generateReportArtifactScriptTag,\n generateTestRunReportScriptTag,\n getBaseUrlFixScript,\n} from './dump/html-utils';\nimport { normalizeStoredImageRef } from './dump/image-reference';\nimport { readReportArtifactManifest } from './dump/report-artifact-reader';\nimport { ReportArtifactStore } from './dump/report-artifact-store';\nimport { compactReportDumps } from './dump/report-dump-compactor';\nimport { type ImageUrlRef, ReportImageStore } from './dump/screenshot-store';\nimport type { WorkflowReportSource } from './test-runner/engine/types';\nimport { buildAgentTestRunReportDump } from './test-runner/reporting/agent-report';\nimport type { RunReportInput } from './test-runner/reporting/types';\nimport {\n type ExecutionDump,\n ReportActionDump,\n type ReportAttributes,\n type ReportMeta,\n type ScreenshotMode,\n} from './types';\nimport { getReportTpl } from './utils';\n\nconst warnReport = getDebug('report-generator', { console: true });\nconst maxReportFilenameBytes = 255;\n\nexport interface IReportGenerator {\n /**\n * Write or update a single execution.\n * Inline reports append dump tags; directory reports replace the execution's\n * data file. Both retain the latest state for each stable execution ID.\n *\n * @param execution Current execution's full data\n * @param reportMeta Report-level metadata (groupName, sdkVersion, etc.)\n */\n onExecutionUpdate(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n attributes?: ReportAttributes,\n ): void;\n\n /**\n * @deprecated Use onExecutionUpdate instead. Kept for backward compatibility.\n */\n onDumpUpdate?(dump: ReportActionDump): void;\n\n /**\n * Wait for all queued write operations to complete.\n */\n flush(): Promise<void>;\n enableSourceSnapshots?(scopeId?: string): void;\n createSourceSnapshot?(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource | undefined>;\n\n /**\n * Finalize the report. Calls flush() internally.\n */\n finalize(): Promise<string | undefined>;\n\n getReportPath(): string | undefined;\n /** Publish a single root Runner snapshot into this Agent's existing report. */\n writeRunnerReport?(\n input: RunReportInput,\n scopeId: string,\n meta: ReportMeta,\n ): Promise<string | undefined>;\n}\n\nexport const nullReportGenerator: IReportGenerator = {\n onExecutionUpdate: () => {},\n flush: async () => {},\n finalize: async () => undefined,\n getReportPath: () => undefined,\n writeRunnerReport: async () => undefined,\n};\n\nexport function assertReportGenerationOptions(opts: {\n generateReport?: boolean;\n persistExecutionDump?: boolean;\n}): void {\n if (opts.generateReport === false && opts.persistExecutionDump === true) {\n throw new Error(\n 'persistExecutionDump cannot be true when generateReport is false',\n );\n }\n}\n\nexport class ReportGenerator implements IReportGenerator {\n private reportPath: string;\n private screenshotMode: ScreenshotMode;\n private shouldPersistExecutionDump: boolean;\n private autoPrint: boolean;\n private firstWriteDone = false;\n private executionLogIndex = 0;\n private executionLogFileIndexByExecutionKey = new Map<string, number>();\n\n // Unique identifier for this report stream — used as data-group-id\n private readonly reportStreamId: string;\n\n // Tracks screenshots already written to disk (by id) to avoid duplicates\n private screenshotStore: ReportImageStore;\n private sourceStore?: ReportImageStore;\n private sourceDirectory?: string;\n private initialized = false;\n\n // Tracks the last execution + groupMeta for re-writing on finalize\n private lastExecution?: ExecutionDump;\n private lastReportMeta?: ReportMeta;\n private readonly recorder = new ExecutionRecorder();\n private readonly artifactStore?: ReportArtifactStore;\n private executionCommentKeyByObject = new WeakMap<ExecutionDump, string>();\n private executionCommentKeyIndex = 0;\n private reportAttributes: Record<string, string> = {};\n private agentCommentWritten = false;\n\n // write queue for serial execution\n private writeQueue: Promise<void> = Promise.resolve();\n private finalization?: Promise<string | undefined>;\n private sourcePublications = new Set<Promise<unknown>>();\n\n constructor(options: {\n reportPath: string;\n screenshotMode: ScreenshotMode;\n persistExecutionDump?: boolean;\n autoPrint?: boolean;\n reuseExistingReport?: boolean;\n }) {\n this.reportPath = options.reportPath;\n this.screenshotMode = options.screenshotMode;\n this.shouldPersistExecutionDump = options.persistExecutionDump ?? false;\n this.autoPrint = options.autoPrint ?? true;\n this.reportStreamId = uuid();\n if (this.screenshotMode === 'directory') {\n this.artifactStore = new ReportArtifactStore(\n dirname(this.reportPath),\n this.reportStreamId,\n 'agent',\n options.reuseExistingReport,\n basename(this.reportPath),\n );\n }\n this.screenshotStore = new ReportImageStore({\n mode: this.screenshotMode === 'inline' ? 'inline' : 'directory',\n reportPath: this.reportPath,\n screenshotsDir: join(dirname(this.reportPath), 'screenshots'),\n writeInlineImage: async (id, base64) => {\n await appendFileAsync(\n this.reportPath,\n `\\n${generateImageScriptTag(id, base64)}`,\n );\n },\n alsoWriteFileCopy: this.shouldPersistExecutionDump,\n reuseExistingReport: options.reuseExistingReport,\n });\n if (options.reuseExistingReport) {\n this.hydrateStateFromExistingReport();\n }\n }\n\n static create(\n reportFileName: string,\n opts: {\n generateReport?: boolean;\n persistExecutionDump?: boolean;\n outputFormat?: 'single-html' | 'html-and-external-assets';\n autoPrintReportMsg?: boolean;\n reuseExistingReport?: boolean;\n },\n ): IReportGenerator {\n assertReportGenerationOptions(opts);\n validateReportFileName(reportFileName, opts.outputFormat);\n if (opts.generateReport === false) return nullReportGenerator;\n\n // In browser environment, file system is not available\n if (ifInBrowser) return nullReportGenerator;\n\n const reportRootDir = getMidsceneRunSubDir('report');\n const outputDir = join(reportRootDir, reportFileName);\n const reportPath =\n opts.outputFormat === 'html-and-external-assets'\n ? join(outputDir, 'index.html')\n : join(reportRootDir, ensureHtmlFileName(reportFileName));\n return new ReportGenerator({\n reportPath,\n screenshotMode:\n opts.outputFormat === 'html-and-external-assets'\n ? 'directory'\n : 'inline',\n persistExecutionDump: opts.persistExecutionDump,\n autoPrint: opts.autoPrintReportMsg,\n reuseExistingReport: opts.reuseExistingReport,\n });\n }\n\n onExecutionUpdate(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n attributes?: ReportAttributes,\n ): void {\n this.assertOpen();\n this.lastExecution = execution;\n this.lastReportMeta = reportMeta;\n this.recorder.record(execution, reportMeta);\n this.mergeReportAttributes(attributes);\n this.writeQueue = this.writeQueue.then(async () => {\n await this.doWriteExecution(execution, reportMeta);\n });\n }\n\n async flush(): Promise<void> {\n await this.writeQueue;\n }\n\n async finalize(): Promise<string | undefined> {\n if (!this.finalization) {\n // Enqueue the final state before sealing the generator to new writes.\n if (this.lastExecution && this.lastReportMeta) {\n this.onExecutionUpdate(this.lastExecution, this.lastReportMeta);\n }\n this.finalization = this.finishPublication();\n }\n return this.finalization;\n }\n\n private async finishPublication(): Promise<string | undefined> {\n // Snapshots freeze independently of the HTML queue, but both must be on\n // disk before their backing executions and diagnostic data are released.\n await Promise.all([this.flush(), ...this.sourcePublications]);\n if (this.initialized) {\n if (this.artifactStore) {\n await this.artifactStore.finalize();\n } else {\n await this.appendAgentReportComment();\n try {\n await compactReportDumps(this.reportPath);\n } catch (error) {\n warnReport(\n `Failed to compact report ${this.reportPath}; keeping the uncompressed report: ${String(error)}`,\n );\n }\n }\n }\n this.recorder.clear();\n this.lastExecution = undefined;\n this.lastReportMeta = undefined;\n this.executionCommentKeyByObject = new WeakMap();\n this.executionLogFileIndexByExecutionKey.clear();\n return this.initialized ? this.reportPath : undefined;\n }\n\n private assertOpen(): void {\n if (this.finalization) throw new Error('The report has been finalized.');\n }\n\n getReportPath(): string | undefined {\n return this.reportPath;\n }\n\n async writeRunnerReport(\n input: RunReportInput,\n scopeId: string,\n meta: ReportMeta,\n ): Promise<string> {\n this.assertOpen();\n this.writeQueue = this.writeQueue.then(async () => {\n // This runs at YAML invocation completion, never on progress ticks. Keep\n // all file I/O asynchronous and publish atomically for an open viewer.\n const reportMeta = this.lastReportMeta ?? meta;\n const executions = this.recorder.executions;\n const agentDump = new ReportActionDump({ ...reportMeta, executions });\n const reportId =\n this.reportAttributes['data-report-id'] ??\n this.reportAttributes['data-group-id'] ??\n this.reportStreamId;\n const dump = buildAgentTestRunReportDump(input, agentDump, {\n reportId,\n scopeId,\n sourcePath: this.reportPath,\n });\n for (const diagnostic of dump.diagnostics ?? [])\n warnReport(diagnostic.message);\n this.enableSourceSnapshots(scopeId);\n const sourceDump = await this.serializeSourceDump();\n const images: string[] = [];\n if (this.screenshotMode === 'inline') {\n for (const ref of sourceDump.images.values()) {\n const bytes = await readFileAsync(\n join(this.sourceDirectory!, ref.path!),\n );\n images.push(\n generateImageScriptTag(\n ref.id,\n `data:${ref.mimeType};base64,${bytes.toString('base64')}`,\n ),\n );\n }\n }\n if (this.artifactStore) {\n for (const execution of executions) {\n await this.writeExecution(\n execution,\n this.wrapAsReportDump(execution, reportMeta),\n );\n }\n if (!executions.length) {\n // An empty execution group still carries setup/collection diagnostics.\n await this.artifactStore.writeExecution(\n 'empty',\n sourceDump.serialized,\n this.getDumpScriptAttributes(),\n );\n if (!this.initialized) {\n const marker = generateReportArtifactScriptTag('report.json');\n await writeFileAsync(\n this.reportPath,\n `${getReportTpl()}${getBaseUrlFixScript()}\\n${marker}`,\n );\n this.initialized = true;\n }\n }\n await this.artifactStore.writeRunner(JSON.stringify(dump));\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n return;\n }\n // Rebuild from the owned dump and image index, never parse this HTML back.\n const renderedDump =\n this.screenshotMode === 'inline'\n ? JSON.stringify(JSON.parse(sourceDump.serialized), (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n return ref\n ? { ...ref, storage: 'inline', path: undefined }\n : value;\n })\n : sourceDump.serialized;\n const contents = `${getReportTpl()}${this.screenshotMode === 'directory' ? getBaseUrlFixScript() : ''}\n${generateDumpScriptTag(renderedDump, this.getDumpScriptAttributes())}\n${images.join('\\n')}\n${generateTestRunReportScriptTag(dump)}\n${generateAgentReportComment(agentDump)}`;\n mkdirSync(dirname(this.reportPath), { recursive: true });\n const temporaryPath = `${this.reportPath}.runner-${uuid()}.tmp`;\n try {\n await writeFileAsync(temporaryPath, contents);\n await renameAsync(temporaryPath, this.reportPath);\n } finally {\n await unlinkAsync(temporaryPath).catch((error) => {\n if (error.code !== 'ENOENT') throw error;\n });\n }\n this.initialized = true;\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n });\n await this.flush();\n return this.reportPath;\n }\n\n enableSourceSnapshots(scopeId = this.reportStreamId): void {\n if (\n !scopeId ||\n scopeId === '.' ||\n scopeId === '..' ||\n /[/\\\\]/.test(scopeId)\n )\n throw new Error('Invalid report scope ID');\n if (this.sourceStore) return;\n this.sourceDirectory = join(\n getMidsceneRunSubDir('test-results'),\n scopeId,\n 'records',\n );\n this.sourceStore = new ReportImageStore({\n mode: 'directory',\n reportPath: join(this.sourceDirectory, 'source.json'),\n screenshotsDir: join(this.sourceDirectory, 'screenshots'),\n });\n }\n\n private async serializeSourceDump(snapshot?: ExecutionRecordSnapshot) {\n this.enableSourceSnapshots();\n const store = this.sourceStore!;\n const captured =\n snapshot ??\n this.recorder.capture(\n undefined,\n this.lastReportMeta ?? {\n sdkVersion: '',\n groupName: 'YAML execution',\n modelBriefs: [],\n },\n );\n for (const screenshot of captured.screenshots)\n await store.persistFileCopy(screenshot);\n const references = new Map<string, ImageUrlRef>();\n for (const url of captured.referenceImageUrls) {\n references.set(url, await store.persistReferenceImage(url));\n }\n const images = new Map<\n string,\n ReturnType<typeof normalizeStoredImageRef> & {}\n >();\n const serialized = JSON.stringify(\n JSON.parse(captured.dump.serializeWithReferenceImages(references)),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n if (!ref) return value;\n const stored = {\n ...ref,\n storage: 'file' as const,\n path: store.getFilePath(ref.id),\n };\n images.set(ref.id, stored);\n return stored;\n },\n );\n return { serialized, images };\n }\n\n async createSourceSnapshot(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource & { dumpPath: string }> {\n this.assertOpen();\n if (!scopeId || basename(scopeId) !== scopeId)\n throw new Error('Invalid report scope ID');\n const snapshot = this.recorder.capture(\n executionIds,\n this.lastReportMeta ?? {\n sdkVersion: '',\n groupName: 'YAML execution',\n modelBriefs: [],\n },\n );\n const publication = (async () => {\n const { serialized } = await this.serializeSourceDump(snapshot);\n const dumpPath = join(\n this.sourceDirectory!,\n `${this.reportStreamId}.${scopeId}.${uuid()}.json`,\n );\n mkdirSync(dirname(dumpPath), { recursive: true });\n await writeFileAsync(dumpPath, serialized, { flag: 'wx' });\n return {\n sourcePath: this.reportPath,\n dumpPath,\n collection: {\n status: 'complete' as const,\n capturedAt: snapshot.capturedAt,\n },\n };\n })();\n this.sourcePublications.add(publication);\n try {\n return await publication;\n } finally {\n this.sourcePublications.delete(publication);\n }\n }\n\n private printReportPath(): void {\n if (!this.autoPrint || !this.reportPath) return;\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET))\n return;\n\n if (this.screenshotMode === 'directory') {\n logReport(\n `Midscene - report file updated: npx serve ${dirname(this.reportPath)}`,\n );\n } else {\n logReport(`Midscene - report file updated: ${this.reportPath}`);\n }\n }\n\n private async doWriteExecution(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): Promise<void> {\n const singleDump = this.wrapAsReportDump(execution, reportMeta);\n\n const referenceImageRefs = await this.writeExecution(execution, singleDump);\n\n if (this.shouldPersistExecutionDump && !this.artifactStore) {\n await this.persistExecutionDumpToFile(\n execution,\n singleDump,\n referenceImageRefs,\n );\n }\n\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n }\n\n private mergeReportAttributes(attributes?: ReportAttributes): void {\n if (!attributes) {\n return;\n }\n\n for (const [key, value] of Object.entries(attributes)) {\n if (value === undefined || value === null) {\n continue;\n }\n this.reportAttributes[key] = String(value);\n }\n }\n\n private hydrateStateFromExistingReport(): void {\n if (!existsSync(this.reportPath)) {\n return;\n }\n\n if (this.artifactStore && !readReportArtifactManifest(this.reportPath)) {\n throw new Error(\n 'Cannot reuse an incompatible directory report. Choose a new reportFileName or regenerate the report.',\n );\n }\n\n // Reuse existing report file and append new updates instead of rewriting.\n this.initialized = true;\n\n if (!this.shouldPersistExecutionDump) {\n return;\n }\n\n if (!existsSync(this.executionDumpDir)) return;\n const existingExecutionIndices = readdirSync(this.executionDumpDir)\n .map((name) => /^(\\d+)\\.execution\\.json$/.exec(name)?.[1])\n .filter((index): index is string => Boolean(index))\n .map((index) => Number.parseInt(index, 10))\n .filter((index) => Number.isFinite(index));\n\n if (existingExecutionIndices.length > 0) {\n this.executionLogIndex = Math.max(...existingExecutionIndices);\n }\n }\n\n private getDumpScriptAttributes(): Record<string, string> {\n return {\n 'data-group-id': this.reportStreamId,\n // Self-describe how this report file stores screenshots so consumers\n // (merge/delete) never have to guess the mode from the filesystem.\n [DATA_SCREENSHOT_MODE_ATTR]: this.screenshotMode,\n ...this.reportAttributes,\n 'data-report-kind': 'agent',\n };\n }\n\n /**\n * Wrap an ExecutionDump + ReportMeta into a single-execution ReportActionDump.\n */\n private wrapAsReportDump(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): ReportActionDump {\n return new ReportActionDump({\n sdkVersion: reportMeta.sdkVersion,\n groupName: reportMeta.groupName,\n groupDescription: reportMeta.groupDescription,\n modelBriefs: reportMeta.modelBriefs,\n deviceType: reportMeta.deviceType,\n executions: [execution],\n });\n }\n\n /**\n * Append assets and a dump tag without duplicating mode-specific workflows.\n * The frontend deduplicates executions with the same id/name (keeps last).\n * Duplicate dump JSON is acceptable; only screenshots are deduplicated.\n *\n * All writes go through `fs/promises` so they run on libuv's thread pool\n * rather than blocking the Node event loop. A long agent run previously\n * appended multi-MB dumps (screenshots + serialized tasks) per progress\n * tick on the main thread, starving IPC and UI for >10s per stall.\n */\n private async writeExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<Map<string, ImageUrlRef>> {\n const dir = dirname(this.reportPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Initialize: write HTML template once\n if (!this.initialized) {\n const baseUrlFix =\n this.screenshotMode === 'directory' ? getBaseUrlFixScript() : '';\n const marker = this.artifactStore\n ? `\\n${generateReportArtifactScriptTag('report.json')}`\n : '';\n await writeFileAsync(\n this.reportPath,\n `${getReportTpl()}${baseUrlFix}${marker}`,\n );\n this.initialized = true;\n }\n\n // Append new screenshots (skip already-written ones)\n for (const screenshot of execution.collectScreenshots()) {\n await this.sourceStore?.persistFileCopy(screenshot);\n await this.screenshotStore.persist(screenshot);\n }\n const referenceImageRefs = await this.persistReferenceImages(execution);\n\n // Publish the latest facts using the selected storage format.\n const serialized =\n singleDump.serializeWithReferenceImages(referenceImageRefs);\n if (this.artifactStore) {\n await this.artifactStore.writeExecution(\n this.getExecutionCommentKey(execution),\n serialized,\n this.getDumpScriptAttributes(),\n );\n } else {\n await appendFileAsync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\n }\n return referenceImageRefs;\n }\n\n private async persistReferenceImages(\n execution: ExecutionDump,\n ): Promise<Map<string, ImageUrlRef>> {\n const refs = new Map<string, ImageUrlRef>();\n for (const imageUrl of execution.getReferenceImageUrls()) {\n const ref = await this.screenshotStore.persistReferenceImage(imageUrl);\n refs.set(imageUrl, ref);\n }\n return refs;\n }\n\n private async appendAgentReportComment(): Promise<void> {\n if (\n this.agentCommentWritten ||\n !this.lastReportMeta ||\n this.recorder.executions.length === 0\n ) {\n return;\n }\n\n const reportDump = new ReportActionDump({\n sdkVersion: this.lastReportMeta.sdkVersion,\n groupName: this.lastReportMeta.groupName,\n groupDescription: this.lastReportMeta.groupDescription,\n modelBriefs: this.lastReportMeta.modelBriefs,\n deviceType: this.lastReportMeta.deviceType,\n executions: this.recorder.executions,\n });\n await appendFileAsync(\n this.reportPath,\n `\\n${generateAgentReportComment(reportDump)}`,\n );\n this.agentCommentWritten = true;\n }\n\n private getExecutionLogKey(execution: ExecutionDump): string {\n if (!execution.id) {\n throw new Error(\n 'ReportGenerator: execution.id is required for persisting execution dumps',\n );\n }\n return `id:${execution.id}`;\n }\n\n private getExecutionCommentKey(execution: ExecutionDump): string {\n if (execution.id) {\n return `id:${execution.id}`;\n }\n\n const existingKey = this.executionCommentKeyByObject.get(execution);\n if (existingKey) {\n return existingKey;\n }\n\n const key = `no-id:${this.executionCommentKeyIndex++}`;\n this.executionCommentKeyByObject.set(execution, key);\n return key;\n }\n\n private get executionDumpDir(): string {\n // Inline HTML files share their parent directory. Each needs its own\n // numbered JSON namespace; external-asset reports already have one.\n return this.screenshotMode === 'inline'\n ? join(\n dirname(this.reportPath),\n '.execution-dumps',\n basename(this.reportPath),\n )\n : dirname(this.reportPath);\n }\n\n private async persistExecutionDumpToFile(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n referenceImageRefs: ReadonlyMap<string, ImageUrlRef>,\n ): Promise<void> {\n const dir = this.executionDumpDir;\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n const executionLogKey = this.getExecutionLogKey(execution);\n let fileIndex =\n this.executionLogFileIndexByExecutionKey.get(executionLogKey);\n if (!fileIndex) {\n this.executionLogIndex += 1;\n fileIndex = this.executionLogIndex;\n this.executionLogFileIndexByExecutionKey.set(executionLogKey, fileIndex);\n }\n\n const fileName = `${fileIndex}.execution.json`;\n const filePath = join(dir, fileName);\n let serialized = singleDump.serializeWithReferenceImages(\n referenceImageRefs,\n 2,\n );\n if (this.screenshotMode === 'inline') {\n // JSON is two directories below the HTML. Point to the existing file\n // copies so it can be consumed without resolving inline HTML assets.\n serialized = JSON.stringify(\n JSON.parse(serialized),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n return ref\n ? {\n ...ref,\n storage: 'file',\n path: `../../${this.screenshotStore.getFilePath(ref.id).replace(/^\\.\\//, '')}`,\n }\n : value;\n },\n 2,\n );\n }\n await writeFileAsync(filePath, serialized, 'utf-8');\n }\n}\n\nfunction ensureHtmlFileName(reportFileName: string): string {\n return reportFileName.endsWith('.html')\n ? reportFileName\n : `${reportFileName}.html`;\n}\n\nfunction validateReportFileName(\n reportFileName: string,\n outputFormat?: 'single-html' | 'html-and-external-assets',\n): void {\n if (!reportFileName?.trim()) {\n throw new Error('reportFileName must be a non-empty string');\n }\n\n if (/[\\\\/]/.test(reportFileName)) {\n throw new Error(\n 'reportFileName must not contain path separators (`/` or `\\\\\\\\`)',\n );\n }\n\n if (/[:*?\"<>|]/.test(reportFileName)) {\n throw new Error(\n 'reportFileName contains illegal filename characters: : * ? \" < > |',\n );\n }\n\n const filenameComponent =\n outputFormat === 'html-and-external-assets'\n ? reportFileName\n : ensureHtmlFileName(reportFileName);\n const filenameBytes = new TextEncoder().encode(filenameComponent).byteLength;\n if (filenameBytes > maxReportFilenameBytes) {\n throw new Error(\n `reportFileName produces a filename component of ${filenameBytes} UTF-8 bytes; maximum is ${maxReportFilenameBytes}`,\n );\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","warnReport","getDebug","maxReportFilenameBytes","nullReportGenerator","undefined","assertReportGenerationOptions","opts","Error","ReportGenerator","reportFileName","validateReportFileName","ifInBrowser","reportRootDir","getMidsceneRunSubDir","outputDir","join","reportPath","ensureHtmlFileName","execution","reportMeta","attributes","Promise","compactReportDumps","error","String","WeakMap","input","scopeId","meta","executions","agentDump","ReportActionDump","reportId","dump","buildAgentTestRunReportDump","diagnostic","sourceDump","images","ref","bytes","readFileAsync","generateImageScriptTag","marker","generateReportArtifactScriptTag","writeFileAsync","getReportTpl","getBaseUrlFixScript","JSON","renderedDump","_key","value","normalizeStoredImageRef","contents","generateDumpScriptTag","generateTestRunReportScriptTag","generateAgentReportComment","mkdirSync","dirname","temporaryPath","uuid","renameAsync","unlinkAsync","ReportImageStore","snapshot","store","captured","screenshot","references","Map","url","serialized","stored","executionIds","basename","publication","dumpPath","globalConfigManager","MIDSCENE_REPORT_QUIET","logReport","singleDump","referenceImageRefs","existsSync","readReportArtifactManifest","existingExecutionIndices","readdirSync","name","index","Boolean","Number","Math","DATA_SCREENSHOT_MODE_ATTR","dir","baseUrlFix","appendFileAsync","refs","imageUrl","reportDump","existingKey","executionLogKey","fileIndex","fileName","filePath","options","ExecutionRecorder","Set","ReportArtifactStore","id","base64","outputFormat","filenameComponent","filenameBytes","TextEncoder"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;;;;;;;;;;;;;;;ACEC;;;;;;;;;;AA+CD,MAAMI,aAAaC,AAAAA,IAAAA,uBAAAA,QAAAA,AAAAA,EAAS,oBAAoB;IAAE,SAAS;AAAK;AAChE,MAAMC,yBAAyB;AA8CxB,MAAMC,sBAAwC;IACnD,mBAAmB,KAAO;IAC1B,OAAO,WAAa;IACpB,UAAU,UAAYC;IACtB,eAAe,IAAMA;IACrB,mBAAmB,UAAYA;AACjC;AAEO,SAASC,8BAA8BC,IAG7C;IACC,IAAIA,AAAwB,UAAxBA,KAAK,cAAc,IAAcA,AAA8B,SAA9BA,KAAK,oBAAoB,EAC5D,MAAM,IAAIC,MACR;AAGN;AAEO,MAAMC;IAwEX,OAAO,OACLC,cAAsB,EACtBH,IAMC,EACiB;QAClBD,8BAA8BC;QAC9BI,uBAAuBD,gBAAgBH,KAAK,YAAY;QACxD,IAAIA,AAAwB,UAAxBA,KAAK,cAAc,EAAY,OAAOH;QAG1C,IAAIQ,sBAAAA,WAAWA,EAAE,OAAOR;QAExB,MAAMS,gBAAgBC,AAAAA,IAAAA,uBAAAA,oBAAAA,AAAAA,EAAqB;QAC3C,MAAMC,YAAYC,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAKH,eAAeH;QACtC,MAAMO,aACJV,AAAsB,+BAAtBA,KAAK,YAAY,GACbS,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAKD,WAAW,gBAChBC,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAKH,eAAeK,mBAAmBR;QAC7C,OAAO,IAAID,gBAAgB;YACzBQ;YACA,gBACEV,AAAsB,+BAAtBA,KAAK,YAAY,GACb,cACA;YACN,sBAAsBA,KAAK,oBAAoB;YAC/C,WAAWA,KAAK,kBAAkB;YAClC,qBAAqBA,KAAK,mBAAmB;QAC/C;IACF;IAEA,kBACEY,SAAwB,EACxBC,UAAsB,EACtBC,UAA6B,EACvB;QACN,IAAI,CAAC,UAAU;QACf,IAAI,CAAC,aAAa,GAAGF;QACrB,IAAI,CAAC,cAAc,GAAGC;QACtB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAACD,WAAWC;QAChC,IAAI,CAAC,qBAAqB,CAACC;QAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACrC,MAAM,IAAI,CAAC,gBAAgB,CAACF,WAAWC;QACzC;IACF;IAEA,MAAM,QAAuB;QAC3B,MAAM,IAAI,CAAC,UAAU;IACvB;IAEA,MAAM,WAAwC;QAC5C,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YAEtB,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,cAAc,EAC3C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,cAAc;YAEhE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,iBAAiB;QAC5C;QACA,OAAO,IAAI,CAAC,YAAY;IAC1B;IAEA,MAAc,oBAAiD;QAG7D,MAAME,QAAQ,GAAG,CAAC;YAAC,IAAI,CAAC,KAAK;eAAO,IAAI,CAAC,kBAAkB;SAAC;QAC5D,IAAI,IAAI,CAAC,WAAW,EAClB,IAAI,IAAI,CAAC,aAAa,EACpB,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ;aAC5B;YACL,MAAM,IAAI,CAAC,wBAAwB;YACnC,IAAI;gBACF,MAAMC,AAAAA,IAAAA,yCAAAA,kBAAAA,AAAAA,EAAmB,IAAI,CAAC,UAAU;YAC1C,EAAE,OAAOC,OAAO;gBACdvB,WACE,CAAC,yBAAyB,EAAE,IAAI,CAAC,UAAU,CAAC,mCAAmC,EAAEwB,OAAOD,QAAQ;YAEpG;QACF;QAEF,IAAI,CAAC,QAAQ,CAAC,KAAK;QACnB,IAAI,CAAC,aAAa,GAAGnB;QACrB,IAAI,CAAC,cAAc,GAAGA;QACtB,IAAI,CAAC,2BAA2B,GAAG,IAAIqB;QACvC,IAAI,CAAC,mCAAmC,CAAC,KAAK;QAC9C,OAAO,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,GAAGrB;IAC9C;IAEQ,aAAmB;QACzB,IAAI,IAAI,CAAC,YAAY,EAAE,MAAM,IAAIG,MAAM;IACzC;IAEA,gBAAoC;QAClC,OAAO,IAAI,CAAC,UAAU;IACxB;IAEA,MAAM,kBACJmB,KAAqB,EACrBC,OAAe,EACfC,IAAgB,EACC;QACjB,IAAI,CAAC,UAAU;QACf,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAGrC,MAAMT,aAAa,IAAI,CAAC,cAAc,IAAIS;YAC1C,MAAMC,aAAa,IAAI,CAAC,QAAQ,CAAC,UAAU;YAC3C,MAAMC,YAAY,IAAIC,kCAAAA,gBAAgBA,CAAC;gBAAE,GAAGZ,UAAU;gBAAEU;YAAW;YACnE,MAAMG,WACJ,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,IACvC,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,IACtC,IAAI,CAAC,cAAc;YACrB,MAAMC,OAAOC,AAAAA,IAAAA,gCAAAA,2BAAAA,AAAAA,EAA4BR,OAAOI,WAAW;gBACzDE;gBACAL;gBACA,YAAY,IAAI,CAAC,UAAU;YAC7B;YACA,KAAK,MAAMQ,cAAcF,KAAK,WAAW,IAAI,EAAE,CAC7CjC,WAAWmC,WAAW,OAAO;YAC/B,IAAI,CAAC,qBAAqB,CAACR;YAC3B,MAAMS,aAAa,MAAM,IAAI,CAAC,mBAAmB;YACjD,MAAMC,SAAmB,EAAE;YAC3B,IAAI,AAAwB,aAAxB,IAAI,CAAC,cAAc,EACrB,KAAK,MAAMC,OAAOF,WAAW,MAAM,CAAC,MAAM,GAAI;gBAC5C,MAAMG,QAAQ,MAAMC,AAAAA,IAAAA,yBAAAA,QAAAA,AAAAA,EAClBzB,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAK,IAAI,CAAC,eAAe,EAAGuB,IAAI,IAAI;gBAEtCD,OAAO,IAAI,CACTI,AAAAA,IAAAA,8BAAAA,sBAAAA,AAAAA,EACEH,IAAI,EAAE,EACN,CAAC,KAAK,EAAEA,IAAI,QAAQ,CAAC,QAAQ,EAAEC,MAAM,QAAQ,CAAC,WAAW;YAG/D;YAEF,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,KAAK,MAAMrB,aAAaW,WACtB,MAAM,IAAI,CAAC,cAAc,CACvBX,WACA,IAAI,CAAC,gBAAgB,CAACA,WAAWC;gBAGrC,IAAI,CAACU,WAAW,MAAM,EAAE;oBAEtB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CACrC,SACAO,WAAW,UAAU,EACrB,IAAI,CAAC,uBAAuB;oBAE9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;wBACrB,MAAMM,SAASC,AAAAA,IAAAA,8BAAAA,+BAAAA,AAAAA,EAAgC;wBAC/C,MAAMC,AAAAA,IAAAA,yBAAAA,SAAAA,AAAAA,EACJ,IAAI,CAAC,UAAU,EACf,GAAGC,AAAAA,IAAAA,kCAAAA,YAAAA,AAAAA,MAAiBC,AAAAA,IAAAA,8BAAAA,mBAAAA,AAAAA,IAAsB,EAAE,EAAEJ,QAAQ;wBAExD,IAAI,CAAC,WAAW,GAAG;oBACrB;gBACF;gBACA,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAACK,KAAK,SAAS,CAACd;gBACpD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;oBACxB,IAAI,CAAC,cAAc,GAAG;oBACtB,IAAI,CAAC,eAAe;gBACtB;gBACA;YACF;YAEA,MAAMe,eACJ,AAAwB,aAAxB,IAAI,CAAC,cAAc,GACfD,KAAK,SAAS,CAACA,KAAK,KAAK,CAACX,WAAW,UAAU,GAAG,CAACa,MAAMC;gBACvD,MAAMZ,MAAMa,AAAAA,IAAAA,mCAAAA,uBAAAA,AAAAA,EAAwBD;gBACpC,OAAOZ,MACH;oBAAE,GAAGA,GAAG;oBAAE,SAAS;oBAAU,MAAMlC;gBAAU,IAC7C8C;YACN,KACAd,WAAW,UAAU;YAC3B,MAAMgB,WAAW,GAAGP,AAAAA,IAAAA,kCAAAA,YAAAA,AAAAA,MAAiB,AAAwB,gBAAxB,IAAI,CAAC,cAAc,GAAmBC,AAAAA,IAAAA,8BAAAA,mBAAAA,AAAAA,MAAwB,GAAG;AAC5G,EAAEO,AAAAA,IAAAA,8BAAAA,qBAAAA,AAAAA,EAAsBL,cAAc,IAAI,CAAC,uBAAuB,IAAI;AACtE,EAAEX,OAAO,IAAI,CAAC,MAAM;AACpB,EAAEiB,AAAAA,IAAAA,8BAAAA,8BAAAA,AAAAA,EAA+BrB,MAAM;AACvC,EAAEsB,AAAAA,IAAAA,8BAAAA,0BAAAA,AAAAA,EAA2BzB,YAAY;YACnC0B,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUC,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ,IAAI,CAAC,UAAU,GAAG;gBAAE,WAAW;YAAK;YACtD,MAAMC,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAEC,AAAAA,IAAAA,sBAAAA,IAAAA,AAAAA,IAAO,IAAI,CAAC;YAC/D,IAAI;gBACF,MAAMf,AAAAA,IAAAA,yBAAAA,SAAAA,AAAAA,EAAec,eAAeN;gBACpC,MAAMQ,AAAAA,IAAAA,yBAAAA,MAAAA,AAAAA,EAAYF,eAAe,IAAI,CAAC,UAAU;YAClD,SAAU;gBACR,MAAMG,AAAAA,IAAAA,yBAAAA,MAAAA,AAAAA,EAAYH,eAAe,KAAK,CAAC,CAACnC;oBACtC,IAAIA,AAAe,aAAfA,MAAM,IAAI,EAAe,MAAMA;gBACrC;YACF;YACA,IAAI,CAAC,WAAW,GAAG;YACnB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBACxB,IAAI,CAAC,cAAc,GAAG;gBACtB,IAAI,CAAC,eAAe;YACtB;QACF;QACA,MAAM,IAAI,CAAC,KAAK;QAChB,OAAO,IAAI,CAAC,UAAU;IACxB;IAEA,sBAAsBI,UAAU,IAAI,CAAC,cAAc,EAAQ;QACzD,IACE,CAACA,WACDA,AAAY,QAAZA,WACAA,AAAY,SAAZA,WACA,QAAQ,IAAI,CAACA,UAEb,MAAM,IAAIpB,MAAM;QAClB,IAAI,IAAI,CAAC,WAAW,EAAE;QACtB,IAAI,CAAC,eAAe,GAAGQ,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EACrBF,AAAAA,IAAAA,uBAAAA,oBAAAA,AAAAA,EAAqB,iBACrBc,SACA;QAEF,IAAI,CAAC,WAAW,GAAG,IAAImC,oCAAAA,gBAAgBA,CAAC;YACtC,MAAM;YACN,YAAY/C,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAK,IAAI,CAAC,eAAe,EAAE;YACvC,gBAAgBA,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAK,IAAI,CAAC,eAAe,EAAE;QAC7C;IACF;IAEA,MAAc,oBAAoBgD,QAAkC,EAAE;QACpE,IAAI,CAAC,qBAAqB;QAC1B,MAAMC,QAAQ,IAAI,CAAC,WAAW;QAC9B,MAAMC,WACJF,YACA,IAAI,CAAC,QAAQ,CAAC,OAAO,CACnB3D,QACA,IAAI,CAAC,cAAc,IAAI;YACrB,YAAY;YACZ,WAAW;YACX,aAAa,EAAE;QACjB;QAEJ,KAAK,MAAM8D,cAAcD,SAAS,WAAW,CAC3C,MAAMD,MAAM,eAAe,CAACE;QAC9B,MAAMC,aAAa,IAAIC;QACvB,KAAK,MAAMC,OAAOJ,SAAS,kBAAkB,CAC3CE,WAAW,GAAG,CAACE,KAAK,MAAML,MAAM,qBAAqB,CAACK;QAExD,MAAMhC,SAAS,IAAI+B;QAInB,MAAME,aAAavB,KAAK,SAAS,CAC/BA,KAAK,KAAK,CAACkB,SAAS,IAAI,CAAC,4BAA4B,CAACE,cACtD,CAAClB,MAAMC;YACL,MAAMZ,MAAMa,AAAAA,IAAAA,mCAAAA,uBAAAA,AAAAA,EAAwBD;YACpC,IAAI,CAACZ,KAAK,OAAOY;YACjB,MAAMqB,SAAS;gBACb,GAAGjC,GAAG;gBACN,SAAS;gBACT,MAAM0B,MAAM,WAAW,CAAC1B,IAAI,EAAE;YAChC;YACAD,OAAO,GAAG,CAACC,IAAI,EAAE,EAAEiC;YACnB,OAAOA;QACT;QAEF,OAAO;YAAED;YAAYjC;QAAO;IAC9B;IAEA,MAAM,qBACJV,OAAe,EACf6C,YAAgC,EACsB;QACtD,IAAI,CAAC,UAAU;QACf,IAAI,CAAC7C,WAAW8C,AAAAA,IAAAA,mCAAAA,QAAAA,AAAAA,EAAS9C,aAAaA,SACpC,MAAM,IAAIpB,MAAM;QAClB,MAAMwD,WAAW,IAAI,CAAC,QAAQ,CAAC,OAAO,CACpCS,cACA,IAAI,CAAC,cAAc,IAAI;YACrB,YAAY;YACZ,WAAW;YACX,aAAa,EAAE;QACjB;QAEF,MAAME,cAAe;YACnB,MAAM,EAAEJ,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAACP;YACtD,MAAMY,WAAW5D,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EACf,IAAI,CAAC,eAAe,EACpB,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,EAAEY,QAAQ,CAAC,EAAEgC,AAAAA,IAAAA,sBAAAA,IAAAA,AAAAA,IAAO,KAAK,CAAC;YAEpDH,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUC,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQkB,WAAW;gBAAE,WAAW;YAAK;YAC/C,MAAM/B,AAAAA,IAAAA,yBAAAA,SAAAA,AAAAA,EAAe+B,UAAUL,YAAY;gBAAE,MAAM;YAAK;YACxD,OAAO;gBACL,YAAY,IAAI,CAAC,UAAU;gBAC3BK;gBACA,YAAY;oBACV,QAAQ;oBACR,YAAYZ,SAAS,UAAU;gBACjC;YACF;QACF;QACA,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAACW;QAC5B,IAAI;YACF,OAAO,MAAMA;QACf,SAAU;YACR,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAACA;QACjC;IACF;IAEQ,kBAAwB;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;QACzC,IAAIE,oBAAAA,mBAAAA,CAAAA,qBAAyC,CAACC,oBAAAA,qBAAqBA,GACjE;QAEF,IAAI,AAAwB,gBAAxB,IAAI,CAAC,cAAc,EACrBC,AAAAA,IAAAA,uBAAAA,SAAAA,AAAAA,EACE,CAAC,0CAA0C,EAAErB,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ,IAAI,CAAC,UAAU,GAAG;aAGzEqB,AAAAA,IAAAA,uBAAAA,SAAAA,AAAAA,EAAU,CAAC,gCAAgC,EAAE,IAAI,CAAC,UAAU,EAAE;IAElE;IAEA,MAAc,iBACZ5D,SAAwB,EACxBC,UAAsB,EACP;QACf,MAAM4D,aAAa,IAAI,CAAC,gBAAgB,CAAC7D,WAAWC;QAEpD,MAAM6D,qBAAqB,MAAM,IAAI,CAAC,cAAc,CAAC9D,WAAW6D;QAEhE,IAAI,IAAI,CAAC,0BAA0B,IAAI,CAAC,IAAI,CAAC,aAAa,EACxD,MAAM,IAAI,CAAC,0BAA0B,CACnC7D,WACA6D,YACAC;QAIJ,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACxB,IAAI,CAAC,cAAc,GAAG;YACtB,IAAI,CAAC,eAAe;QACtB;IACF;IAEQ,sBAAsB5D,UAA6B,EAAQ;QACjE,IAAI,CAACA,YACH;QAGF,KAAK,MAAM,CAACzB,KAAKuD,MAAM,IAAItD,OAAO,OAAO,CAACwB,YACxC,IAAI8B,QAAAA,OAGJ,IAAI,CAAC,gBAAgB,CAACvD,IAAI,GAAG6B,OAAO0B;IAExC;IAEQ,iCAAuC;QAC7C,IAAI,CAAC+B,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAW,IAAI,CAAC,UAAU,GAC7B;QAGF,IAAI,IAAI,CAAC,aAAa,IAAI,CAACC,AAAAA,IAAAA,0CAAAA,0BAAAA,AAAAA,EAA2B,IAAI,CAAC,UAAU,GACnE,MAAM,IAAI3E,MACR;QAKJ,IAAI,CAAC,WAAW,GAAG;QAEnB,IAAI,CAAC,IAAI,CAAC,0BAA0B,EAClC;QAGF,IAAI,CAAC0E,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAW,IAAI,CAAC,gBAAgB,GAAG;QACxC,MAAME,2BAA2BC,AAAAA,IAAAA,iCAAAA,WAAAA,AAAAA,EAAY,IAAI,CAAC,gBAAgB,EAC/D,GAAG,CAAC,CAACC,OAAS,2BAA2B,IAAI,CAACA,OAAO,CAAC,EAAE,EACxD,MAAM,CAAC,CAACC,QAA2BC,QAAQD,QAC3C,GAAG,CAAC,CAACA,QAAUE,OAAO,QAAQ,CAACF,OAAO,KACtC,MAAM,CAAC,CAACA,QAAUE,OAAO,QAAQ,CAACF;QAErC,IAAIH,yBAAyB,MAAM,GAAG,GACpC,IAAI,CAAC,iBAAiB,GAAGM,KAAK,GAAG,IAAIN;IAEzC;IAEQ,0BAAkD;QACxD,OAAO;YACL,iBAAiB,IAAI,CAAC,cAAc;YAGpC,CAACO,8BAAAA,yBAAyBA,CAAC,EAAE,IAAI,CAAC,cAAc;YAChD,GAAG,IAAI,CAAC,gBAAgB;YACxB,oBAAoB;QACtB;IACF;IAKQ,iBACNxE,SAAwB,EACxBC,UAAsB,EACJ;QAClB,OAAO,IAAIY,kCAAAA,gBAAgBA,CAAC;YAC1B,YAAYZ,WAAW,UAAU;YACjC,WAAWA,WAAW,SAAS;YAC/B,kBAAkBA,WAAW,gBAAgB;YAC7C,aAAaA,WAAW,WAAW;YACnC,YAAYA,WAAW,UAAU;YACjC,YAAY;gBAACD;aAAU;QACzB;IACF;IAYA,MAAc,eACZA,SAAwB,EACxB6D,UAA4B,EACO;QACnC,MAAMY,MAAMlC,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ,IAAI,CAAC,UAAU;QACnC,IAAI,CAACwB,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWU,MACdnC,AAAAA,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUmC,KAAK;YAAE,WAAW;QAAK;QAInC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YACrB,MAAMC,aACJ,AAAwB,gBAAxB,IAAI,CAAC,cAAc,GAAmB9C,AAAAA,IAAAA,8BAAAA,mBAAAA,AAAAA,MAAwB;YAChE,MAAMJ,SAAS,IAAI,CAAC,aAAa,GAC7B,CAAC,EAAE,EAAEC,AAAAA,IAAAA,8BAAAA,+BAAAA,AAAAA,EAAgC,gBAAgB,GACrD;YACJ,MAAMC,AAAAA,IAAAA,yBAAAA,SAAAA,AAAAA,EACJ,IAAI,CAAC,UAAU,EACf,GAAGC,AAAAA,IAAAA,kCAAAA,YAAAA,AAAAA,MAAiB+C,aAAalD,QAAQ;YAE3C,IAAI,CAAC,WAAW,GAAG;QACrB;QAGA,KAAK,MAAMwB,cAAchD,UAAU,kBAAkB,GAAI;YACvD,MAAM,IAAI,CAAC,WAAW,EAAE,gBAAgBgD;YACxC,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAACA;QACrC;QACA,MAAMc,qBAAqB,MAAM,IAAI,CAAC,sBAAsB,CAAC9D;QAG7D,MAAMoD,aACJS,WAAW,4BAA4B,CAACC;QAC1C,IAAI,IAAI,CAAC,aAAa,EACpB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CACrC,IAAI,CAAC,sBAAsB,CAAC9D,YAC5BoD,YACA,IAAI,CAAC,uBAAuB;aAG9B,MAAMuB,AAAAA,IAAAA,yBAAAA,UAAAA,AAAAA,EACJ,IAAI,CAAC,UAAU,EACf,CAAC,EAAE,EAAExC,AAAAA,IAAAA,8BAAAA,qBAAAA,AAAAA,EAAsBiB,YAAY,IAAI,CAAC,uBAAuB,KAAK;QAG5E,OAAOU;IACT;IAEA,MAAc,uBACZ9D,SAAwB,EACW;QACnC,MAAM4E,OAAO,IAAI1B;QACjB,KAAK,MAAM2B,YAAY7E,UAAU,qBAAqB,GAAI;YACxD,MAAMoB,MAAM,MAAM,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAACyD;YAC7DD,KAAK,GAAG,CAACC,UAAUzD;QACrB;QACA,OAAOwD;IACT;IAEA,MAAc,2BAA0C;QACtD,IACE,IAAI,CAAC,mBAAmB,IACxB,CAAC,IAAI,CAAC,cAAc,IACpB,AAAoC,MAApC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAE/B;QAGF,MAAME,aAAa,IAAIjE,kCAAAA,gBAAgBA,CAAC;YACtC,YAAY,IAAI,CAAC,cAAc,CAAC,UAAU;YAC1C,WAAW,IAAI,CAAC,cAAc,CAAC,SAAS;YACxC,kBAAkB,IAAI,CAAC,cAAc,CAAC,gBAAgB;YACtD,aAAa,IAAI,CAAC,cAAc,CAAC,WAAW;YAC5C,YAAY,IAAI,CAAC,cAAc,CAAC,UAAU;YAC1C,YAAY,IAAI,CAAC,QAAQ,CAAC,UAAU;QACtC;QACA,MAAM8D,AAAAA,IAAAA,yBAAAA,UAAAA,AAAAA,EACJ,IAAI,CAAC,UAAU,EACf,CAAC,EAAE,EAAEtC,AAAAA,IAAAA,8BAAAA,0BAAAA,AAAAA,EAA2ByC,aAAa;QAE/C,IAAI,CAAC,mBAAmB,GAAG;IAC7B;IAEQ,mBAAmB9E,SAAwB,EAAU;QAC3D,IAAI,CAACA,UAAU,EAAE,EACf,MAAM,IAAIX,MACR;QAGJ,OAAO,CAAC,GAAG,EAAEW,UAAU,EAAE,EAAE;IAC7B;IAEQ,uBAAuBA,SAAwB,EAAU;QAC/D,IAAIA,UAAU,EAAE,EACd,OAAO,CAAC,GAAG,EAAEA,UAAU,EAAE,EAAE;QAG7B,MAAM+E,cAAc,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC/E;QACzD,IAAI+E,aACF,OAAOA;QAGT,MAAMtG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,wBAAwB,IAAI;QACtD,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAACuB,WAAWvB;QAChD,OAAOA;IACT;IAEA,IAAY,mBAA2B;QAGrC,OAAO,AAAwB,aAAxB,IAAI,CAAC,cAAc,GACtBoB,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EACE0C,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ,IAAI,CAAC,UAAU,GACvB,oBACAgB,AAAAA,IAAAA,mCAAAA,QAAAA,AAAAA,EAAS,IAAI,CAAC,UAAU,KAE1BhB,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ,IAAI,CAAC,UAAU;IAC7B;IAEA,MAAc,2BACZvC,SAAwB,EACxB6D,UAA4B,EAC5BC,kBAAoD,EACrC;QACf,MAAMW,MAAM,IAAI,CAAC,gBAAgB;QACjC,IAAI,CAACV,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWU,MACdnC,AAAAA,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUmC,KAAK;YAAE,WAAW;QAAK;QAGnC,MAAMO,kBAAkB,IAAI,CAAC,kBAAkB,CAAChF;QAChD,IAAIiF,YACF,IAAI,CAAC,mCAAmC,CAAC,GAAG,CAACD;QAC/C,IAAI,CAACC,WAAW;YACd,IAAI,CAAC,iBAAiB,IAAI;YAC1BA,YAAY,IAAI,CAAC,iBAAiB;YAClC,IAAI,CAAC,mCAAmC,CAAC,GAAG,CAACD,iBAAiBC;QAChE;QAEA,MAAMC,WAAW,GAAGD,UAAU,eAAe,CAAC;QAC9C,MAAME,WAAWtF,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAK4E,KAAKS;QAC3B,IAAI9B,aAAaS,WAAW,4BAA4B,CACtDC,oBACA;QAEF,IAAI,AAAwB,aAAxB,IAAI,CAAC,cAAc,EAGrBV,aAAavB,KAAK,SAAS,CACzBA,KAAK,KAAK,CAACuB,aACX,CAACrB,MAAMC;YACL,MAAMZ,MAAMa,AAAAA,IAAAA,mCAAAA,uBAAAA,AAAAA,EAAwBD;YACpC,OAAOZ,MACH;gBACE,GAAGA,GAAG;gBACN,SAAS;gBACT,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,WAAW,CAACA,IAAI,EAAE,EAAE,OAAO,CAAC,SAAS,KAAK;YAChF,IACAY;QACN,GACA;QAGJ,MAAMN,AAAAA,IAAAA,yBAAAA,SAAAA,AAAAA,EAAeyD,UAAU/B,YAAY;IAC7C;IA/mBA,YAAYgC,OAMX,CAAE;QAtCH,uBAAQ,cAAR;QACA,uBAAQ,kBAAR;QACA,uBAAQ,8BAAR;QACA,uBAAQ,aAAR;QACA,uBAAQ,kBAAiB;QACzB,uBAAQ,qBAAoB;QAC5B,uBAAQ,uCAAsC,IAAIlC;QAGlD,uBAAiB,kBAAjB;QAGA,uBAAQ,mBAAR;QACA,uBAAQ,eAAR;QACA,uBAAQ,mBAAR;QACA,uBAAQ,eAAc;QAGtB,uBAAQ,iBAAR;QACA,uBAAQ,kBAAR;QACA,uBAAiB,YAAW,IAAImC,sCAAAA,iBAAiBA;QACjD,uBAAiB,iBAAjB;QACA,uBAAQ,+BAA8B,IAAI9E;QAC1C,uBAAQ,4BAA2B;QACnC,uBAAQ,oBAA2C,CAAC;QACpD,uBAAQ,uBAAsB;QAG9B,uBAAQ,cAA4BJ,QAAQ,OAAO;QACnD,uBAAQ,gBAAR;QACA,uBAAQ,sBAAqB,IAAImF;QAS/B,IAAI,CAAC,UAAU,GAAGF,QAAQ,UAAU;QACpC,IAAI,CAAC,cAAc,GAAGA,QAAQ,cAAc;QAC5C,IAAI,CAAC,0BAA0B,GAAGA,QAAQ,oBAAoB,IAAI;QAClE,IAAI,CAAC,SAAS,GAAGA,QAAQ,SAAS,IAAI;QACtC,IAAI,CAAC,cAAc,GAAG3C,AAAAA,IAAAA,sBAAAA,IAAAA,AAAAA;QACtB,IAAI,AAAwB,gBAAxB,IAAI,CAAC,cAAc,EACrB,IAAI,CAAC,aAAa,GAAG,IAAI8C,yCAAAA,mBAAmBA,CAC1ChD,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ,IAAI,CAAC,UAAU,GACvB,IAAI,CAAC,cAAc,EACnB,SACA6C,QAAQ,mBAAmB,EAC3B7B,AAAAA,IAAAA,mCAAAA,QAAAA,AAAAA,EAAS,IAAI,CAAC,UAAU;QAG5B,IAAI,CAAC,eAAe,GAAG,IAAIX,oCAAAA,gBAAgBA,CAAC;YAC1C,MAAM,AAAwB,aAAxB,IAAI,CAAC,cAAc,GAAgB,WAAW;YACpD,YAAY,IAAI,CAAC,UAAU;YAC3B,gBAAgB/C,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAK0C,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ,IAAI,CAAC,UAAU,GAAG;YAC/C,kBAAkB,OAAOiD,IAAIC;gBAC3B,MAAMd,AAAAA,IAAAA,yBAAAA,UAAAA,AAAAA,EACJ,IAAI,CAAC,UAAU,EACf,CAAC,EAAE,EAAEpD,AAAAA,IAAAA,8BAAAA,sBAAAA,AAAAA,EAAuBiE,IAAIC,SAAS;YAE7C;YACA,mBAAmB,IAAI,CAAC,0BAA0B;YAClD,qBAAqBL,QAAQ,mBAAmB;QAClD;QACA,IAAIA,QAAQ,mBAAmB,EAC7B,IAAI,CAAC,8BAA8B;IAEvC;AA2kBF;AAEA,SAASrF,mBAAmBR,cAAsB;IAChD,OAAOA,eAAe,QAAQ,CAAC,WAC3BA,iBACA,GAAGA,eAAe,KAAK,CAAC;AAC9B;AAEA,SAASC,uBACPD,cAAsB,EACtBmG,YAAyD;IAEzD,IAAI,CAACnG,gBAAgB,QACnB,MAAM,IAAIF,MAAM;IAGlB,IAAI,QAAQ,IAAI,CAACE,iBACf,MAAM,IAAIF,MACR;IAIJ,IAAI,YAAY,IAAI,CAACE,iBACnB,MAAM,IAAIF,MACR;IAIJ,MAAMsG,oBACJD,AAAiB,+BAAjBA,eACInG,iBACAQ,mBAAmBR;IACzB,MAAMqG,gBAAgB,IAAIC,cAAc,MAAM,CAACF,mBAAmB,UAAU;IAC5E,IAAIC,gBAAgB5G,wBAClB,MAAM,IAAIK,MACR,CAAC,gDAAgD,EAAEuG,cAAc,yBAAyB,EAAE5G,wBAAwB;AAG1H"}