@aiscene/core 9.0.0 → 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/agent/tasks.mjs +5 -1
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/index.mjs +2 -2
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/report-generator.mjs.map +1 -1
- package/dist/es/types.mjs +20 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +2 -2
- package/dist/lib/agent/agent.js +1 -1
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/execution-session.js +1 -1
- package/dist/lib/agent/execution-session.js.map +1 -1
- package/dist/lib/agent/index.js +1 -1
- package/dist/lib/agent/index.js.map +1 -1
- package/dist/lib/agent/task-builder.js +1 -1
- package/dist/lib/agent/task-builder.js.map +1 -1
- package/dist/lib/agent/task-cache.js +1 -1
- package/dist/lib/agent/task-cache.js.map +1 -1
- package/dist/lib/agent/tasks.js +5 -1
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/ui-utils.js +1 -1
- package/dist/lib/agent/ui-utils.js.map +1 -1
- package/dist/lib/agent/usage-intent.js +1 -1
- package/dist/lib/agent/usage-intent.js.map +1 -1
- package/dist/lib/agent/utils.js +2 -2
- package/dist/lib/agent/utils.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/actions.js +1 -1
- package/dist/lib/ai-model/auto-glm/actions.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/index.js +1 -1
- package/dist/lib/ai-model/auto-glm/index.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/parser.js +1 -1
- package/dist/lib/ai-model/auto-glm/parser.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/planning.js +1 -1
- package/dist/lib/ai-model/auto-glm/planning.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/prompt.js +1 -1
- package/dist/lib/ai-model/auto-glm/prompt.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/util.js +1 -1
- package/dist/lib/ai-model/auto-glm/util.js.map +1 -1
- package/dist/lib/ai-model/connectivity.js +1 -1
- package/dist/lib/ai-model/connectivity.js.map +1 -1
- package/dist/lib/ai-model/conversation-history.js +1 -1
- package/dist/lib/ai-model/conversation-history.js.map +1 -1
- package/dist/lib/ai-model/index.js +1 -1
- package/dist/lib/ai-model/index.js.map +1 -1
- package/dist/lib/ai-model/inspect.js +1 -1
- package/dist/lib/ai-model/inspect.js.map +1 -1
- package/dist/lib/ai-model/llm-planning.js +1 -1
- package/dist/lib/ai-model/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/prompt/common.js +1 -1
- package/dist/lib/ai-model/prompt/common.js.map +1 -1
- package/dist/lib/ai-model/prompt/describe.js +1 -1
- package/dist/lib/ai-model/prompt/describe.js.map +1 -1
- package/dist/lib/ai-model/prompt/extraction.js +1 -1
- package/dist/lib/ai-model/prompt/extraction.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-locator.js +1 -1
- package/dist/lib/ai-model/prompt/llm-locator.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-planning.js +1 -1
- package/dist/lib/ai-model/prompt/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-section-locator.js +1 -1
- package/dist/lib/ai-model/prompt/llm-section-locator.js.map +1 -1
- package/dist/lib/ai-model/prompt/order-sensitive-judge.js +1 -1
- package/dist/lib/ai-model/prompt/order-sensitive-judge.js.map +1 -1
- package/dist/lib/ai-model/prompt/playwright-generator.js +1 -1
- package/dist/lib/ai-model/prompt/playwright-generator.js.map +1 -1
- package/dist/lib/ai-model/prompt/ui-tars-planning.js +1 -1
- package/dist/lib/ai-model/prompt/ui-tars-planning.js.map +1 -1
- package/dist/lib/ai-model/prompt/util.js +1 -1
- package/dist/lib/ai-model/prompt/util.js.map +1 -1
- package/dist/lib/ai-model/prompt/yaml-generator.js +1 -1
- package/dist/lib/ai-model/prompt/yaml-generator.js.map +1 -1
- package/dist/lib/ai-model/service-caller/codex-app-server.js +1 -1
- package/dist/lib/ai-model/service-caller/codex-app-server.js.map +1 -1
- package/dist/lib/ai-model/service-caller/image-detail.js +1 -1
- package/dist/lib/ai-model/service-caller/image-detail.js.map +1 -1
- package/dist/lib/ai-model/service-caller/index.js +1 -1
- package/dist/lib/ai-model/service-caller/index.js.map +1 -1
- package/dist/lib/ai-model/service-caller/request-timeout.js +1 -1
- package/dist/lib/ai-model/service-caller/request-timeout.js.map +1 -1
- package/dist/lib/ai-model/ui-tars-planning.js +1 -1
- package/dist/lib/ai-model/ui-tars-planning.js.map +1 -1
- package/dist/lib/common.js +1 -1
- package/dist/lib/common.js.map +1 -1
- package/dist/lib/device/device-options.js +1 -1
- package/dist/lib/device/device-options.js.map +1 -1
- package/dist/lib/device/index.js +1 -1
- package/dist/lib/device/index.js.map +1 -1
- package/dist/lib/dump/html-utils.js +1 -1
- package/dist/lib/dump/html-utils.js.map +1 -1
- package/dist/lib/dump/index.js +1 -1
- package/dist/lib/dump/index.js.map +1 -1
- package/dist/lib/dump/screenshot-restoration.js +1 -1
- package/dist/lib/dump/screenshot-restoration.js.map +1 -1
- package/dist/lib/dump/screenshot-store.js +1 -1
- package/dist/lib/dump/screenshot-store.js.map +1 -1
- package/dist/lib/index.js +8 -2
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/report-cli.js +1 -1
- package/dist/lib/report-cli.js.map +1 -1
- package/dist/lib/report-generator.js +1 -1
- package/dist/lib/report-generator.js.map +1 -1
- package/dist/lib/report-markdown.js +1 -1
- package/dist/lib/report-markdown.js.map +1 -1
- package/dist/lib/report.js +1 -1
- package/dist/lib/report.js.map +1 -1
- package/dist/lib/screenshot-item.js +1 -1
- package/dist/lib/screenshot-item.js.map +1 -1
- package/dist/lib/service/index.js +1 -1
- package/dist/lib/service/index.js.map +1 -1
- package/dist/lib/service/utils.js +1 -1
- package/dist/lib/service/utils.js.map +1 -1
- package/dist/lib/skill/index.js +1 -1
- package/dist/lib/skill/index.js.map +1 -1
- package/dist/lib/task-runner.js +1 -1
- package/dist/lib/task-runner.js.map +1 -1
- package/dist/lib/task-timing.js +1 -1
- package/dist/lib/task-timing.js.map +1 -1
- package/dist/lib/tree.js +1 -1
- package/dist/lib/tree.js.map +1 -1
- package/dist/lib/types.js +36 -9
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +3 -3
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/yaml/builder.js +1 -1
- package/dist/lib/yaml/builder.js.map +1 -1
- package/dist/lib/yaml/index.js +1 -1
- package/dist/lib/yaml/index.js.map +1 -1
- package/dist/lib/yaml/player.js +1 -1
- package/dist/lib/yaml/player.js.map +1 -1
- package/dist/lib/yaml/utils.js +1 -1
- package/dist/lib/yaml/utils.js.map +1 -1
- package/dist/lib/yaml.js +1 -1
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/types.d.ts +35 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dump/html-utils.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/html-utils.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 { closeSync, openSync, readSync, statSync } from 'node:fs';\nimport { antiEscapeScriptTag, escapeScriptTag } from '@aiscene/shared/utils';\n\nexport const escapeContent = escapeScriptTag;\nexport const unescapeContent = antiEscapeScriptTag;\n\n/** Chunk size for streaming file operations (64KB) */\nexport const STREAMING_CHUNK_SIZE = 64 * 1024;\n\n/**\n * Callback for processing matched tags during streaming.\n * @param content - The content between open and close tags\n * @returns true to stop scanning, false to continue\n */\ntype TagMatchCallback = (content: string) => boolean;\n\n/**\n * Stream through a file and find tags matching the pattern.\n * Memory usage: O(chunk_size + tag_size), not O(file_size).\n *\n * @param filePath - Absolute path to the file\n * @param openTag - Opening tag to search for\n * @param closeTag - Closing tag\n * @param onMatch - Callback for each matched tag content\n */\nexport function streamScanTags(\n filePath: string,\n openTag: string,\n closeTag: string,\n onMatch: TagMatchCallback,\n): void {\n const fd = openSync(filePath, 'r');\n const fileSize = statSync(filePath).size;\n const buffer = Buffer.alloc(STREAMING_CHUNK_SIZE);\n\n let position = 0;\n let leftover = '';\n let capturing = false;\n let currentContent = '';\n\n try {\n while (position < fileSize) {\n const bytesRead = readSync(fd, buffer, 0, STREAMING_CHUNK_SIZE, position);\n const chunk = leftover + buffer.toString('utf-8', 0, bytesRead);\n position += bytesRead;\n\n let searchStart = 0;\n\n while (searchStart < chunk.length) {\n if (!capturing) {\n const startIdx = chunk.indexOf(openTag, searchStart);\n if (startIdx !== -1) {\n capturing = true;\n currentContent = chunk.slice(startIdx + openTag.length);\n const endIdx = currentContent.indexOf(closeTag);\n if (endIdx !== -1) {\n const shouldStop = onMatch(currentContent.slice(0, endIdx));\n if (shouldStop) return;\n capturing = false;\n currentContent = '';\n searchStart =\n startIdx + openTag.length + endIdx + closeTag.length;\n } else {\n leftover = currentContent.slice(-closeTag.length);\n currentContent = currentContent.slice(0, -closeTag.length);\n break;\n }\n } else {\n leftover = chunk.slice(-openTag.length);\n break;\n }\n } else {\n const endIdx = chunk.indexOf(closeTag, searchStart);\n if (endIdx !== -1) {\n currentContent += chunk.slice(searchStart, endIdx);\n const shouldStop = onMatch(currentContent);\n if (shouldStop) return;\n capturing = false;\n currentContent = '';\n searchStart = endIdx + closeTag.length;\n } else {\n currentContent += chunk.slice(searchStart, -closeTag.length);\n leftover = chunk.slice(-closeTag.length);\n break;\n }\n }\n }\n }\n } finally {\n closeSync(fd);\n }\n}\n\n/**\n * Synchronously extract a specific image's base64 data from an HTML file by its id.\n * Uses streaming to avoid loading the entire file into memory.\n *\n * @param htmlPath - Absolute path to the HTML file\n * @param imageId - The id of the image to extract\n * @returns The base64 data string, or null if not found\n */\nexport function extractImageByIdSync(\n htmlPath: string,\n imageId: string,\n): string | null {\n const targetTag = `<script type=\"midscene-image\" data-id=\"${imageId}\">`;\n const closeTag = '</script>';\n\n let result: string | null = null;\n\n streamScanTags(htmlPath, targetTag, closeTag, (content) => {\n result = unescapeContent(content);\n return true; // Stop after first match\n });\n\n return result;\n}\n\n/**\n * Stream image script tags from source file directly to output file.\n * Memory usage: O(single_image_size), not O(all_images_size).\n *\n * @param srcFilePath - Source HTML file path\n * @param destFilePath - Destination file path to append to\n */\nexport function streamImageScriptsToFile(\n srcFilePath: string,\n destFilePath: string,\n): void {\n const { appendFileSync } = require('node:fs');\n const openTag = '<script type=\"midscene-image\"';\n const closeTag = '</script>';\n\n streamScanTags(srcFilePath, openTag, closeTag, (content) => {\n // Write complete tag immediately to destination, don't accumulate\n appendFileSync(destFilePath, `${openTag}${content}${closeTag}\\n`);\n return false; // Continue scanning for more tags\n });\n}\n\n/**\n * Extract the LAST dump script content from HTML file using streaming.\n * Memory usage: O(dump_size), not O(file_size).\n *\n * @param filePath - Absolute path to the HTML file\n * @returns The dump script content (trimmed), or empty string if not found\n */\nexport function extractLastDumpScriptSync(filePath: string): string {\n const openTagPrefix = '<script type=\"midscene_web_dump\"';\n const closeTag = '</script>';\n\n let lastContent = '';\n\n // Custom streaming to handle the special case where open tag has variable attributes\n const fd = openSync(filePath, 'r');\n const fileSize = statSync(filePath).size;\n const buffer = Buffer.alloc(STREAMING_CHUNK_SIZE);\n\n let position = 0;\n let leftover = '';\n let capturing = false;\n let currentContent = '';\n\n try {\n while (position < fileSize) {\n const bytesRead = readSync(fd, buffer, 0, STREAMING_CHUNK_SIZE, position);\n const chunk = leftover + buffer.toString('utf-8', 0, bytesRead);\n position += bytesRead;\n\n let searchStart = 0;\n\n while (searchStart < chunk.length) {\n if (!capturing) {\n const startIdx = chunk.indexOf(openTagPrefix, searchStart);\n if (startIdx !== -1) {\n // Find the end of the opening tag (the '>' character)\n const tagEndIdx = chunk.indexOf('>', startIdx);\n if (tagEndIdx !== -1) {\n capturing = true;\n currentContent = chunk.slice(tagEndIdx + 1);\n const endIdx = currentContent.indexOf(closeTag);\n if (endIdx !== -1) {\n lastContent = currentContent.slice(0, endIdx).trim();\n capturing = false;\n currentContent = '';\n searchStart = tagEndIdx + 1 + endIdx + closeTag.length;\n } else {\n leftover = currentContent.slice(-closeTag.length);\n currentContent = currentContent.slice(0, -closeTag.length);\n break;\n }\n } else {\n leftover = chunk.slice(startIdx);\n break;\n }\n } else {\n leftover = chunk.slice(-openTagPrefix.length);\n break;\n }\n } else {\n const endIdx = chunk.indexOf(closeTag, searchStart);\n if (endIdx !== -1) {\n currentContent += chunk.slice(searchStart, endIdx);\n lastContent = currentContent.trim();\n capturing = false;\n currentContent = '';\n searchStart = endIdx + closeTag.length;\n } else {\n currentContent += chunk.slice(searchStart, -closeTag.length);\n leftover = chunk.slice(-closeTag.length);\n break;\n }\n }\n }\n }\n } finally {\n closeSync(fd);\n }\n\n return lastContent;\n}\n\n/**\n * Extract ALL dump script contents from an HTML file using streaming.\n * Each entry includes the full opening tag (for attribute extraction) and the content.\n *\n * @param filePath - Absolute path to the HTML file\n * @returns Array of { openTag, content } for each dump script found\n */\nexport function extractAllDumpScriptsSync(\n filePath: string,\n): { openTag: string; content: string }[] {\n const results: { openTag: string; content: string }[] = [];\n streamDumpScriptsSync(filePath, (dumpScript) => {\n results.push(dumpScript);\n return false;\n });\n return results;\n}\n\n/**\n * Stream ALL dump scripts from an HTML file.\n * Calls onMatch for each dump script and keeps memory bounded to a single\n * dump script payload instead of accumulating every dump in memory.\n *\n * @param filePath - Absolute path to the HTML file\n * @param onMatch - Callback for each dump script; return true to stop early\n */\nexport function streamDumpScriptsSync(\n filePath: string,\n onMatch: (dumpScript: { openTag: string; content: string }) => boolean,\n): void {\n const openTagPrefix = '<script type=\"midscene_web_dump\"';\n const closeTag = '</script>';\n\n const fd = openSync(filePath, 'r');\n const fileSize = statSync(filePath).size;\n const buffer = Buffer.alloc(STREAMING_CHUNK_SIZE);\n\n let position = 0;\n let leftover = '';\n let capturing = false;\n let currentContent = '';\n let currentOpenTag = '';\n\n try {\n while (position < fileSize) {\n const bytesRead = readSync(fd, buffer, 0, STREAMING_CHUNK_SIZE, position);\n const chunk = leftover + buffer.toString('utf-8', 0, bytesRead);\n position += bytesRead;\n\n let searchStart = 0;\n\n while (searchStart < chunk.length) {\n if (!capturing) {\n const startIdx = chunk.indexOf(openTagPrefix, searchStart);\n if (startIdx !== -1) {\n const tagEndIdx = chunk.indexOf('>', startIdx);\n if (tagEndIdx !== -1) {\n capturing = true;\n currentOpenTag = chunk.slice(startIdx, tagEndIdx + 1);\n currentContent = chunk.slice(tagEndIdx + 1);\n const endIdx = currentContent.indexOf(closeTag);\n if (endIdx !== -1) {\n const shouldStop = onMatch({\n openTag: currentOpenTag,\n content: currentContent.slice(0, endIdx).trim(),\n });\n if (shouldStop) return;\n capturing = false;\n currentContent = '';\n currentOpenTag = '';\n searchStart = tagEndIdx + 1 + endIdx + closeTag.length;\n } else {\n leftover = currentContent.slice(-closeTag.length);\n currentContent = currentContent.slice(0, -closeTag.length);\n break;\n }\n } else {\n leftover = chunk.slice(startIdx);\n break;\n }\n } else {\n leftover = chunk.slice(-openTagPrefix.length);\n break;\n }\n } else {\n const endIdx = chunk.indexOf(closeTag, searchStart);\n if (endIdx !== -1) {\n currentContent += chunk.slice(searchStart, endIdx);\n const shouldStop = onMatch({\n openTag: currentOpenTag,\n content: currentContent.trim(),\n });\n if (shouldStop) return;\n capturing = false;\n currentContent = '';\n currentOpenTag = '';\n searchStart = endIdx + closeTag.length;\n } else {\n currentContent += chunk.slice(searchStart, -closeTag.length);\n leftover = chunk.slice(-closeTag.length);\n break;\n }\n }\n }\n }\n } finally {\n closeSync(fd);\n }\n}\n\nexport function parseImageScripts(html: string): Record<string, string> {\n const imageMap: Record<string, string> = {};\n const regex =\n /<script type=\"midscene-image\" data-id=\"([^\"]+)\">([\\s\\S]*?)<\\/script>/g;\n\n for (const match of html.matchAll(regex)) {\n const [, id, content] = match;\n imageMap[id] = unescapeContent(content);\n }\n\n return imageMap;\n}\n\nexport function parseDumpScript(html: string): string {\n // Use string search instead of regex to avoid ReDoS vulnerability\n // Find the LAST dump script tag (template may contain similar patterns in bundled JS)\n const scriptOpenTag = '<script type=\"midscene_web_dump\"';\n const scriptCloseTag = '</script>';\n\n // Find the last occurrence of the opening tag\n const lastOpenIndex = html.lastIndexOf(scriptOpenTag);\n if (lastOpenIndex === -1) {\n throw new Error('No dump script found in HTML');\n }\n\n // Find the end of the opening tag (the '>' character)\n const tagEndIndex = html.indexOf('>', lastOpenIndex);\n if (tagEndIndex === -1) {\n throw new Error('No dump script found in HTML');\n }\n\n // Find the closing tag after the opening tag\n const closeIndex = html.indexOf(scriptCloseTag, tagEndIndex);\n if (closeIndex === -1) {\n throw new Error('No dump script found in HTML');\n }\n\n // Extract content between opening and closing tags\n const content = html.substring(tagEndIndex + 1, closeIndex);\n return unescapeContent(content);\n}\n\nexport function parseDumpScriptAttributes(\n html: string,\n): Record<string, string> {\n const regex = /<script type=\"midscene_web_dump\"([^>]*)>/;\n const match = regex.exec(html);\n\n if (!match) {\n return {};\n }\n\n const attrString = match[1];\n const attributes: Record<string, string> = {};\n const attrRegex = /(\\w+)=\"([^\"]*)\"/g;\n\n for (const attrMatch of attrString.matchAll(attrRegex)) {\n const [, key, value] = attrMatch;\n if (key !== 'type') {\n attributes[key] = decodeURIComponent(value);\n }\n }\n\n return attributes;\n}\n\nexport function generateImageScriptTag(id: string, data: string): string {\n // Do not use template string here, will cause bundle error with <script\n return (\n // biome-ignore lint/style/useTemplate: <explanation>\n '<script type=\"midscene-image\" data-id=\"' +\n id +\n '\">' +\n escapeContent(data) +\n '</script>'\n );\n}\n\n/**\n * Inline script that fixes relative URL resolution for directory-mode reports.\n *\n * Problem: when a static server (e.g. `npx serve`) serves `name/index.html`\n * at URL `/name` (without trailing slash), relative paths like\n * `./screenshots/xxx.png` resolve to `/screenshots/xxx.png` instead of\n * `/name/screenshots/xxx.png`.\n *\n * Fix: dynamically insert a <base> tag so relative URLs resolve correctly.\n */\n// Do not use template string here, will cause bundle error with <script\n//\n// The closing </script> tag is built at runtime via scriptClose() so that no\n// bundler (rslib, webpack, rsbuild) can ever see or inline a literal\n// '</script>' into JS source. A literal '</script>' inside a <script> block\n// causes the HTML parser to prematurely close the block — which breaks the\n// report viewer when this module is bundled into the report HTML template.\n//\n// Do NOT replace this with a string constant, hex escape (\\x3c), or simple\n// concatenation — bundlers will optimise / inline them and re-introduce the\n// literal '</script>'.\nlet _baseUrlFixScript: string;\nexport function getBaseUrlFixScript(): string {\n if (!_baseUrlFixScript) {\n // Closing </script> MUST be split so that no bundler (rslib / webpack /\n // terser) can ever produce a literal '</script>' in bundle output.\n // A literal '</script>' inside a <script> block causes the HTML parser\n // to prematurely close the block, which breaks the report viewer when\n // this module is bundled into the report template.\n const close = '</' + 'script>';\n _baseUrlFixScript =\n // biome-ignore lint/style/useTemplate: see above\n '\\n<script>(function(){' +\n 'var p=window.location.pathname;' +\n 'if(p.endsWith(\"/\")||/\\\\.\\\\w+$/.test(p))return;' +\n 'var b=document.createElement(\"base\");' +\n 'b.href=p+\"/\";' +\n 'document.head.insertBefore(b,document.head.firstChild)' +\n '})()' +\n close +\n '\\n';\n }\n return _baseUrlFixScript;\n}\n\nexport function generateDumpScriptTag(\n json: string,\n attributes?: Record<string, string | number | boolean>,\n): string {\n let attrString = '';\n if (attributes && Object.keys(attributes).length > 0) {\n // Do not use template string here, will cause bundle error with <script\n attrString =\n // biome-ignore lint/style/useTemplate: <explanation>\n ' ' +\n Object.entries(attributes)\n // biome-ignore lint/style/useTemplate: <explanation>\n .map(([k, v]) => k + '=\"' + encodeURIComponent(v) + '\"')\n .join(' ');\n }\n\n // Do not use template string here, will cause bundle error with <script\n return (\n // biome-ignore lint/style/useTemplate: <explanation>\n '<script type=\"midscene_web_dump\"' +\n attrString +\n '>' +\n escapeContent(json) +\n '</script>'\n );\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","escapeContent","escapeScriptTag","unescapeContent","antiEscapeScriptTag","STREAMING_CHUNK_SIZE","streamScanTags","filePath","openTag","closeTag","onMatch","fd","openSync","fileSize","statSync","buffer","Buffer","position","leftover","capturing","currentContent","bytesRead","readSync","chunk","searchStart","endIdx","shouldStop","startIdx","closeSync","extractImageByIdSync","htmlPath","imageId","targetTag","result","content","streamImageScriptsToFile","srcFilePath","destFilePath","appendFileSync","require","extractLastDumpScriptSync","openTagPrefix","lastContent","tagEndIdx","extractAllDumpScriptsSync","results","streamDumpScriptsSync","dumpScript","currentOpenTag","parseImageScripts","html","imageMap","regex","match","id","parseDumpScript","scriptOpenTag","scriptCloseTag","lastOpenIndex","Error","tagEndIndex","closeIndex","parseDumpScriptAttributes","attrString","attributes","attrRegex","attrMatch","value","decodeURIComponent","generateImageScriptTag","data","_baseUrlFixScript","getBaseUrlFixScript","close","generateDumpScriptTag","json","k","v","encodeURIComponent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dump/html-utils.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/html-utils.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 { closeSync, openSync, readSync, statSync } from 'node:fs';\nimport { antiEscapeScriptTag, escapeScriptTag } from '@aiscene/shared/utils';\n\nexport const escapeContent = escapeScriptTag;\nexport const unescapeContent = antiEscapeScriptTag;\n\n/** Chunk size for streaming file operations (64KB) */\nexport const STREAMING_CHUNK_SIZE = 64 * 1024;\n\n/**\n * Callback for processing matched tags during streaming.\n * @param content - The content between open and close tags\n * @returns true to stop scanning, false to continue\n */\ntype TagMatchCallback = (content: string) => boolean;\n\n/**\n * Stream through a file and find tags matching the pattern.\n * Memory usage: O(chunk_size + tag_size), not O(file_size).\n *\n * @param filePath - Absolute path to the file\n * @param openTag - Opening tag to search for\n * @param closeTag - Closing tag\n * @param onMatch - Callback for each matched tag content\n */\nexport function streamScanTags(\n filePath: string,\n openTag: string,\n closeTag: string,\n onMatch: TagMatchCallback,\n): void {\n const fd = openSync(filePath, 'r');\n const fileSize = statSync(filePath).size;\n const buffer = Buffer.alloc(STREAMING_CHUNK_SIZE);\n\n let position = 0;\n let leftover = '';\n let capturing = false;\n let currentContent = '';\n\n try {\n while (position < fileSize) {\n const bytesRead = readSync(fd, buffer, 0, STREAMING_CHUNK_SIZE, position);\n const chunk = leftover + buffer.toString('utf-8', 0, bytesRead);\n position += bytesRead;\n\n let searchStart = 0;\n\n while (searchStart < chunk.length) {\n if (!capturing) {\n const startIdx = chunk.indexOf(openTag, searchStart);\n if (startIdx !== -1) {\n capturing = true;\n currentContent = chunk.slice(startIdx + openTag.length);\n const endIdx = currentContent.indexOf(closeTag);\n if (endIdx !== -1) {\n const shouldStop = onMatch(currentContent.slice(0, endIdx));\n if (shouldStop) return;\n capturing = false;\n currentContent = '';\n searchStart =\n startIdx + openTag.length + endIdx + closeTag.length;\n } else {\n leftover = currentContent.slice(-closeTag.length);\n currentContent = currentContent.slice(0, -closeTag.length);\n break;\n }\n } else {\n leftover = chunk.slice(-openTag.length);\n break;\n }\n } else {\n const endIdx = chunk.indexOf(closeTag, searchStart);\n if (endIdx !== -1) {\n currentContent += chunk.slice(searchStart, endIdx);\n const shouldStop = onMatch(currentContent);\n if (shouldStop) return;\n capturing = false;\n currentContent = '';\n searchStart = endIdx + closeTag.length;\n } else {\n currentContent += chunk.slice(searchStart, -closeTag.length);\n leftover = chunk.slice(-closeTag.length);\n break;\n }\n }\n }\n }\n } finally {\n closeSync(fd);\n }\n}\n\n/**\n * Synchronously extract a specific image's base64 data from an HTML file by its id.\n * Uses streaming to avoid loading the entire file into memory.\n *\n * @param htmlPath - Absolute path to the HTML file\n * @param imageId - The id of the image to extract\n * @returns The base64 data string, or null if not found\n */\nexport function extractImageByIdSync(\n htmlPath: string,\n imageId: string,\n): string | null {\n const targetTag = `<script type=\"midscene-image\" data-id=\"${imageId}\">`;\n const closeTag = '</script>';\n\n let result: string | null = null;\n\n streamScanTags(htmlPath, targetTag, closeTag, (content) => {\n result = unescapeContent(content);\n return true; // Stop after first match\n });\n\n return result;\n}\n\n/**\n * Stream image script tags from source file directly to output file.\n * Memory usage: O(single_image_size), not O(all_images_size).\n *\n * @param srcFilePath - Source HTML file path\n * @param destFilePath - Destination file path to append to\n */\nexport function streamImageScriptsToFile(\n srcFilePath: string,\n destFilePath: string,\n): void {\n const { appendFileSync } = require('node:fs');\n const openTag = '<script type=\"midscene-image\"';\n const closeTag = '</script>';\n\n streamScanTags(srcFilePath, openTag, closeTag, (content) => {\n // Write complete tag immediately to destination, don't accumulate\n appendFileSync(destFilePath, `${openTag}${content}${closeTag}\\n`);\n return false; // Continue scanning for more tags\n });\n}\n\n/**\n * Extract the LAST dump script content from HTML file using streaming.\n * Memory usage: O(dump_size), not O(file_size).\n *\n * @param filePath - Absolute path to the HTML file\n * @returns The dump script content (trimmed), or empty string if not found\n */\nexport function extractLastDumpScriptSync(filePath: string): string {\n const openTagPrefix = '<script type=\"midscene_web_dump\"';\n const closeTag = '</script>';\n\n let lastContent = '';\n\n // Custom streaming to handle the special case where open tag has variable attributes\n const fd = openSync(filePath, 'r');\n const fileSize = statSync(filePath).size;\n const buffer = Buffer.alloc(STREAMING_CHUNK_SIZE);\n\n let position = 0;\n let leftover = '';\n let capturing = false;\n let currentContent = '';\n\n try {\n while (position < fileSize) {\n const bytesRead = readSync(fd, buffer, 0, STREAMING_CHUNK_SIZE, position);\n const chunk = leftover + buffer.toString('utf-8', 0, bytesRead);\n position += bytesRead;\n\n let searchStart = 0;\n\n while (searchStart < chunk.length) {\n if (!capturing) {\n const startIdx = chunk.indexOf(openTagPrefix, searchStart);\n if (startIdx !== -1) {\n // Find the end of the opening tag (the '>' character)\n const tagEndIdx = chunk.indexOf('>', startIdx);\n if (tagEndIdx !== -1) {\n capturing = true;\n currentContent = chunk.slice(tagEndIdx + 1);\n const endIdx = currentContent.indexOf(closeTag);\n if (endIdx !== -1) {\n lastContent = currentContent.slice(0, endIdx).trim();\n capturing = false;\n currentContent = '';\n searchStart = tagEndIdx + 1 + endIdx + closeTag.length;\n } else {\n leftover = currentContent.slice(-closeTag.length);\n currentContent = currentContent.slice(0, -closeTag.length);\n break;\n }\n } else {\n leftover = chunk.slice(startIdx);\n break;\n }\n } else {\n leftover = chunk.slice(-openTagPrefix.length);\n break;\n }\n } else {\n const endIdx = chunk.indexOf(closeTag, searchStart);\n if (endIdx !== -1) {\n currentContent += chunk.slice(searchStart, endIdx);\n lastContent = currentContent.trim();\n capturing = false;\n currentContent = '';\n searchStart = endIdx + closeTag.length;\n } else {\n currentContent += chunk.slice(searchStart, -closeTag.length);\n leftover = chunk.slice(-closeTag.length);\n break;\n }\n }\n }\n }\n } finally {\n closeSync(fd);\n }\n\n return lastContent;\n}\n\n/**\n * Extract ALL dump script contents from an HTML file using streaming.\n * Each entry includes the full opening tag (for attribute extraction) and the content.\n *\n * @param filePath - Absolute path to the HTML file\n * @returns Array of { openTag, content } for each dump script found\n */\nexport function extractAllDumpScriptsSync(\n filePath: string,\n): { openTag: string; content: string }[] {\n const results: { openTag: string; content: string }[] = [];\n streamDumpScriptsSync(filePath, (dumpScript) => {\n results.push(dumpScript);\n return false;\n });\n return results;\n}\n\n/**\n * Stream ALL dump scripts from an HTML file.\n * Calls onMatch for each dump script and keeps memory bounded to a single\n * dump script payload instead of accumulating every dump in memory.\n *\n * @param filePath - Absolute path to the HTML file\n * @param onMatch - Callback for each dump script; return true to stop early\n */\nexport function streamDumpScriptsSync(\n filePath: string,\n onMatch: (dumpScript: { openTag: string; content: string }) => boolean,\n): void {\n const openTagPrefix = '<script type=\"midscene_web_dump\"';\n const closeTag = '</script>';\n\n const fd = openSync(filePath, 'r');\n const fileSize = statSync(filePath).size;\n const buffer = Buffer.alloc(STREAMING_CHUNK_SIZE);\n\n let position = 0;\n let leftover = '';\n let capturing = false;\n let currentContent = '';\n let currentOpenTag = '';\n\n try {\n while (position < fileSize) {\n const bytesRead = readSync(fd, buffer, 0, STREAMING_CHUNK_SIZE, position);\n const chunk = leftover + buffer.toString('utf-8', 0, bytesRead);\n position += bytesRead;\n\n let searchStart = 0;\n\n while (searchStart < chunk.length) {\n if (!capturing) {\n const startIdx = chunk.indexOf(openTagPrefix, searchStart);\n if (startIdx !== -1) {\n const tagEndIdx = chunk.indexOf('>', startIdx);\n if (tagEndIdx !== -1) {\n capturing = true;\n currentOpenTag = chunk.slice(startIdx, tagEndIdx + 1);\n currentContent = chunk.slice(tagEndIdx + 1);\n const endIdx = currentContent.indexOf(closeTag);\n if (endIdx !== -1) {\n const shouldStop = onMatch({\n openTag: currentOpenTag,\n content: currentContent.slice(0, endIdx).trim(),\n });\n if (shouldStop) return;\n capturing = false;\n currentContent = '';\n currentOpenTag = '';\n searchStart = tagEndIdx + 1 + endIdx + closeTag.length;\n } else {\n leftover = currentContent.slice(-closeTag.length);\n currentContent = currentContent.slice(0, -closeTag.length);\n break;\n }\n } else {\n leftover = chunk.slice(startIdx);\n break;\n }\n } else {\n leftover = chunk.slice(-openTagPrefix.length);\n break;\n }\n } else {\n const endIdx = chunk.indexOf(closeTag, searchStart);\n if (endIdx !== -1) {\n currentContent += chunk.slice(searchStart, endIdx);\n const shouldStop = onMatch({\n openTag: currentOpenTag,\n content: currentContent.trim(),\n });\n if (shouldStop) return;\n capturing = false;\n currentContent = '';\n currentOpenTag = '';\n searchStart = endIdx + closeTag.length;\n } else {\n currentContent += chunk.slice(searchStart, -closeTag.length);\n leftover = chunk.slice(-closeTag.length);\n break;\n }\n }\n }\n }\n } finally {\n closeSync(fd);\n }\n}\n\nexport function parseImageScripts(html: string): Record<string, string> {\n const imageMap: Record<string, string> = {};\n const regex =\n /<script type=\"midscene-image\" data-id=\"([^\"]+)\">([\\s\\S]*?)<\\/script>/g;\n\n for (const match of html.matchAll(regex)) {\n const [, id, content] = match;\n imageMap[id] = unescapeContent(content);\n }\n\n return imageMap;\n}\n\nexport function parseDumpScript(html: string): string {\n // Use string search instead of regex to avoid ReDoS vulnerability\n // Find the LAST dump script tag (template may contain similar patterns in bundled JS)\n const scriptOpenTag = '<script type=\"midscene_web_dump\"';\n const scriptCloseTag = '</script>';\n\n // Find the last occurrence of the opening tag\n const lastOpenIndex = html.lastIndexOf(scriptOpenTag);\n if (lastOpenIndex === -1) {\n throw new Error('No dump script found in HTML');\n }\n\n // Find the end of the opening tag (the '>' character)\n const tagEndIndex = html.indexOf('>', lastOpenIndex);\n if (tagEndIndex === -1) {\n throw new Error('No dump script found in HTML');\n }\n\n // Find the closing tag after the opening tag\n const closeIndex = html.indexOf(scriptCloseTag, tagEndIndex);\n if (closeIndex === -1) {\n throw new Error('No dump script found in HTML');\n }\n\n // Extract content between opening and closing tags\n const content = html.substring(tagEndIndex + 1, closeIndex);\n return unescapeContent(content);\n}\n\nexport function parseDumpScriptAttributes(\n html: string,\n): Record<string, string> {\n const regex = /<script type=\"midscene_web_dump\"([^>]*)>/;\n const match = regex.exec(html);\n\n if (!match) {\n return {};\n }\n\n const attrString = match[1];\n const attributes: Record<string, string> = {};\n const attrRegex = /(\\w+)=\"([^\"]*)\"/g;\n\n for (const attrMatch of attrString.matchAll(attrRegex)) {\n const [, key, value] = attrMatch;\n if (key !== 'type') {\n attributes[key] = decodeURIComponent(value);\n }\n }\n\n return attributes;\n}\n\nexport function generateImageScriptTag(id: string, data: string): string {\n // Do not use template string here, will cause bundle error with <script\n return (\n // biome-ignore lint/style/useTemplate: <explanation>\n '<script type=\"midscene-image\" data-id=\"' +\n id +\n '\">' +\n escapeContent(data) +\n '</script>'\n );\n}\n\n/**\n * Inline script that fixes relative URL resolution for directory-mode reports.\n *\n * Problem: when a static server (e.g. `npx serve`) serves `name/index.html`\n * at URL `/name` (without trailing slash), relative paths like\n * `./screenshots/xxx.png` resolve to `/screenshots/xxx.png` instead of\n * `/name/screenshots/xxx.png`.\n *\n * Fix: dynamically insert a <base> tag so relative URLs resolve correctly.\n */\n// Do not use template string here, will cause bundle error with <script\n//\n// The closing </script> tag is built at runtime via scriptClose() so that no\n// bundler (rslib, webpack, rsbuild) can ever see or inline a literal\n// '</script>' into JS source. A literal '</script>' inside a <script> block\n// causes the HTML parser to prematurely close the block — which breaks the\n// report viewer when this module is bundled into the report HTML template.\n//\n// Do NOT replace this with a string constant, hex escape (\\x3c), or simple\n// concatenation — bundlers will optimise / inline them and re-introduce the\n// literal '</script>'.\nlet _baseUrlFixScript: string;\nexport function getBaseUrlFixScript(): string {\n if (!_baseUrlFixScript) {\n // Closing </script> MUST be split so that no bundler (rslib / webpack /\n // terser) can ever produce a literal '</script>' in bundle output.\n // A literal '</script>' inside a <script> block causes the HTML parser\n // to prematurely close the block, which breaks the report viewer when\n // this module is bundled into the report template.\n const close = '</' + 'script>';\n _baseUrlFixScript =\n // biome-ignore lint/style/useTemplate: see above\n '\\n<script>(function(){' +\n 'var p=window.location.pathname;' +\n 'if(p.endsWith(\"/\")||/\\\\.\\\\w+$/.test(p))return;' +\n 'var b=document.createElement(\"base\");' +\n 'b.href=p+\"/\";' +\n 'document.head.insertBefore(b,document.head.firstChild)' +\n '})()' +\n close +\n '\\n';\n }\n return _baseUrlFixScript;\n}\n\nexport function generateDumpScriptTag(\n json: string,\n attributes?: Record<string, string | number | boolean>,\n): string {\n let attrString = '';\n if (attributes && Object.keys(attributes).length > 0) {\n // Do not use template string here, will cause bundle error with <script\n attrString =\n // biome-ignore lint/style/useTemplate: <explanation>\n ' ' +\n Object.entries(attributes)\n // biome-ignore lint/style/useTemplate: <explanation>\n .map(([k, v]) => k + '=\"' + encodeURIComponent(v) + '\"')\n .join(' ');\n }\n\n // Do not use template string here, will cause bundle error with <script\n return (\n // biome-ignore lint/style/useTemplate: <explanation>\n '<script type=\"midscene_web_dump\"' +\n attrString +\n '>' +\n escapeContent(json) +\n '</script>'\n );\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","escapeContent","escapeScriptTag","unescapeContent","antiEscapeScriptTag","STREAMING_CHUNK_SIZE","streamScanTags","filePath","openTag","closeTag","onMatch","fd","openSync","fileSize","statSync","buffer","Buffer","position","leftover","capturing","currentContent","bytesRead","readSync","chunk","searchStart","endIdx","shouldStop","startIdx","closeSync","extractImageByIdSync","htmlPath","imageId","targetTag","result","content","streamImageScriptsToFile","srcFilePath","destFilePath","appendFileSync","require","extractLastDumpScriptSync","openTagPrefix","lastContent","tagEndIdx","extractAllDumpScriptsSync","results","streamDumpScriptsSync","dumpScript","currentOpenTag","parseImageScripts","html","imageMap","regex","match","id","parseDumpScript","scriptOpenTag","scriptCloseTag","lastOpenIndex","Error","tagEndIndex","closeIndex","parseDumpScriptAttributes","attrString","attributes","attrRegex","attrMatch","value","decodeURIComponent","generateImageScriptTag","data","_baseUrlFixScript","getBaseUrlFixScript","close","generateDumpScriptTag","json","k","v","encodeURIComponent"],"mappings":"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"}
|
package/dist/lib/dump/index.js
CHANGED
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dump/index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object"],"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};"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol"],"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,
|
|
1
|
+
{"version":3,"file":"dump/index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object"],"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};"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol"],"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"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dump/screenshot-restoration.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/screenshot-restoration.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 { type ScreenshotRef, normalizeScreenshotRef } from './screenshot-store';\n\n/**\n * Recursively restore image references in parsed data.\n * Replaces ScreenshotRef with lazy\n * { get base64() {...}, capturedAt } objects.\n * The resolver is only called when .base64 is first accessed.\n */\nexport function restoreImageReferences<T>(\n data: T,\n resolveImage: (ref: ScreenshotRef) => string,\n): T {\n if (typeof data === 'string') {\n return data;\n }\n\n if (Array.isArray(data)) {\n return data.map((item) => restoreImageReferences(item, resolveImage)) as T;\n }\n\n if (typeof data === 'object' && data !== null) {\n const refLike = normalizeScreenshotRef(data);\n if (refLike) {\n let resolved: string | null = null;\n const lazy: { base64: string; capturedAt?: number } =\n Object.defineProperties({} as { base64: string; capturedAt?: number }, {\n base64: {\n get() {\n if (resolved === null) {\n resolved = resolveImage(refLike);\n }\n return resolved;\n },\n enumerable: true,\n },\n capturedAt: { value: refLike.capturedAt, enumerable: true },\n });\n return lazy as T;\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n result[key] = restoreImageReferences(value, resolveImage);\n }\n return result as T;\n }\n\n return data;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","restoreImageReferences","data","resolveImage","Array","item","refLike","normalizeScreenshotRef","resolved","lazy","result","value"],"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,
|
|
1
|
+
{"version":3,"file":"dump/screenshot-restoration.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/screenshot-restoration.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 { type ScreenshotRef, normalizeScreenshotRef } from './screenshot-store';\n\n/**\n * Recursively restore image references in parsed data.\n * Replaces ScreenshotRef with lazy\n * { get base64() {...}, capturedAt } objects.\n * The resolver is only called when .base64 is first accessed.\n */\nexport function restoreImageReferences<T>(\n data: T,\n resolveImage: (ref: ScreenshotRef) => string,\n): T {\n if (typeof data === 'string') {\n return data;\n }\n\n if (Array.isArray(data)) {\n return data.map((item) => restoreImageReferences(item, resolveImage)) as T;\n }\n\n if (typeof data === 'object' && data !== null) {\n const refLike = normalizeScreenshotRef(data);\n if (refLike) {\n let resolved: string | null = null;\n const lazy: { base64: string; capturedAt?: number } =\n Object.defineProperties({} as { base64: string; capturedAt?: number }, {\n base64: {\n get() {\n if (resolved === null) {\n resolved = resolveImage(refLike);\n }\n return resolved;\n },\n enumerable: true,\n },\n capturedAt: { value: refLike.capturedAt, enumerable: true },\n });\n return lazy as T;\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n result[key] = restoreImageReferences(value, resolveImage);\n }\n return result as T;\n }\n\n return data;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","restoreImageReferences","data","resolveImage","Array","item","refLike","normalizeScreenshotRef","resolved","lazy","result","value"],"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;;;;;;;;ACEO,SAASI,uBACdC,IAAO,EACPC,YAA4C;IAE5C,IAAI,AAAgB,YAAhB,OAAOD,MACT,OAAOA;IAGT,IAAIE,MAAM,OAAO,CAACF,OAChB,OAAOA,KAAK,GAAG,CAAC,CAACG,OAASJ,uBAAuBI,MAAMF;IAGzD,IAAI,AAAgB,YAAhB,OAAOD,QAAqBA,AAAS,SAATA,MAAe;QAC7C,MAAMI,UAAUC,AAAAA,IAAAA,6CAAAA,sBAAAA,AAAAA,EAAuBL;QACvC,IAAII,SAAS;YACX,IAAIE,WAA0B;YAC9B,MAAMC,OACJZ,OAAO,gBAAgB,CAAC,CAAC,GAA8C;gBACrE,QAAQ;oBACN;wBACE,IAAIW,AAAa,SAAbA,UACFA,WAAWL,aAAaG;wBAE1B,OAAOE;oBACT;oBACA,YAAY;gBACd;gBACA,YAAY;oBAAE,OAAOF,QAAQ,UAAU;oBAAE,YAAY;gBAAK;YAC5D;YACF,OAAOG;QACT;QAEA,MAAMC,SAAkC,CAAC;QACzC,KAAK,MAAM,CAACd,KAAKe,MAAM,IAAId,OAAO,OAAO,CAACK,MACxCQ,MAAM,CAACd,IAAI,GAAGK,uBAAuBU,OAAOR;QAE9C,OAAOO;IACT;IAEA,OAAOR;AACT"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dump/screenshot-store.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/screenshot-store.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, readFileSync, rmSync } from 'node:fs';\nimport { writeFile as writeFileAsync } from 'node:fs/promises';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport type { ScreenshotItem } from '../screenshot-item';\nimport { extractImageByIdSync } from './html-utils';\n\nexport interface ScreenshotRef {\n type: 'midscene_screenshot_ref';\n id: string;\n capturedAt: number;\n mimeType: 'image/png' | 'image/jpeg';\n storage: 'inline' | 'file';\n path?: string;\n}\n\nexport function normalizeScreenshotRef(value: unknown): ScreenshotRef | null {\n if (typeof value !== 'object' || value === null) return null;\n const record = value as Record<string, unknown>;\n\n if (\n record.type === 'midscene_screenshot_ref' &&\n typeof record.id === 'string' &&\n typeof record.capturedAt === 'number' &&\n (record.storage === 'inline' || record.storage === 'file') &&\n (record.mimeType === 'image/png' || record.mimeType === 'image/jpeg')\n ) {\n if (record.storage === 'file' && typeof record.path !== 'string') {\n return null;\n }\n return record as unknown as ScreenshotRef;\n }\n\n return null;\n}\n\ntype ResolvedScreenshotSource =\n | {\n type: 'data-uri';\n id: string;\n mimeType: ScreenshotRef['mimeType'];\n dataUri: string;\n }\n | {\n type: 'file';\n id: string;\n mimeType: ScreenshotRef['mimeType'];\n filePath: string;\n };\n\nfunction extensionByMimeType(mimeType: ScreenshotRef['mimeType']): string {\n return mimeType === 'image/jpeg' ? 'jpeg' : 'png';\n}\n\nexport function resolveScreenshotSource(\n refInput: unknown,\n options: {\n reportPath: string;\n fallbackId?: string;\n fallbackMimeType?: ScreenshotRef['mimeType'];\n },\n): ResolvedScreenshotSource {\n const ref = normalizeScreenshotRef(refInput);\n const id = ref?.id ?? options.fallbackId;\n const mimeType = ref?.mimeType ?? options.fallbackMimeType;\n\n if (!id || !mimeType) {\n throw new Error(\n 'ScreenshotStore: screenshot id and mimeType are required to resolve screenshot',\n );\n }\n\n const resolveReportRelativePath = (filePath: string): string =>\n isAbsolute(filePath)\n ? filePath\n : join(dirname(options.reportPath), filePath);\n\n if (ref?.storage === 'file') {\n if (!ref.path) {\n throw new Error(\n `ScreenshotStore: screenshot ref \"${ref.id}\" missing file path`,\n );\n }\n\n const explicitFilePath = resolveReportRelativePath(ref.path);\n if (existsSync(explicitFilePath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: explicitFilePath,\n };\n }\n }\n\n const inlineDataUri = extractImageByIdSync(options.reportPath, id);\n if (inlineDataUri) {\n return {\n type: 'data-uri',\n id,\n mimeType,\n dataUri: inlineDataUri,\n };\n }\n\n const siblingScreenshotPath = join(\n dirname(options.reportPath),\n 'screenshots',\n `${id}.${extensionByMimeType(mimeType)}`,\n );\n if (existsSync(siblingScreenshotPath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: siblingScreenshotPath,\n };\n }\n\n throw new Error(\n `ScreenshotStore: cannot resolve screenshot \"${id}\" from ${options.reportPath}`,\n );\n}\n\nexport class ScreenshotStore {\n private readonly mode: 'inline' | 'directory';\n private readonly reportPath: string;\n private readonly screenshotsDir?: string;\n private readonly writeInlineImage?: (\n id: string,\n base64: string,\n ) => void | Promise<void>;\n private readonly alsoWriteFileCopy: boolean;\n private readonly writtenInlineIds = new Set<string>();\n private readonly writtenFileIds = new Set<string>();\n\n constructor(options: {\n mode: 'inline' | 'directory';\n reportPath: string;\n screenshotsDir?: string;\n writeInlineImage?: (id: string, base64: string) => void | Promise<void>;\n alsoWriteFileCopy?: boolean;\n /** @deprecated Use alsoWriteFileCopy instead. */\n ensureFileCopy?: boolean;\n }) {\n this.mode = options.mode;\n this.reportPath = options.reportPath;\n this.screenshotsDir = options.screenshotsDir;\n this.writeInlineImage = options.writeInlineImage;\n this.alsoWriteFileCopy =\n options.alsoWriteFileCopy ?? options.ensureFileCopy ?? false;\n }\n\n async persist(screenshot: ScreenshotItem): Promise<ScreenshotRef> {\n const shouldWriteFileCopy =\n this.mode === 'directory' || this.alsoWriteFileCopy;\n const fileRef = shouldWriteFileCopy\n ? await this.persistToSharedFileIfNeeded(screenshot, {\n markAsPersisted: this.mode === 'directory',\n })\n : null;\n\n if (this.mode === 'inline') {\n if (!this.writeInlineImage) {\n throw new Error(\n 'ScreenshotStore: writeInlineImage is required in inline mode',\n );\n }\n if (!this.writtenInlineIds.has(screenshot.id)) {\n await this.writeInlineImage(screenshot.id, screenshot.base64);\n this.writtenInlineIds.add(screenshot.id);\n }\n return screenshot.markPersistedInline(this.reportPath);\n }\n\n if (!fileRef) {\n throw new Error(\n 'ScreenshotStore: file persistence is required in directory mode',\n );\n }\n return fileRef;\n }\n\n private async persistToSharedFileIfNeeded(\n screenshot: ScreenshotItem,\n options: {\n markAsPersisted: boolean;\n },\n ): Promise<ScreenshotRef> {\n const screenshotsDir = this.screenshotsDir;\n if (!screenshotsDir) {\n throw new Error(\n 'ScreenshotStore: screenshotsDir is required when file persistence is enabled',\n );\n }\n if (!existsSync(screenshotsDir)) {\n mkdirSync(screenshotsDir, { recursive: true });\n }\n\n const relativePath = `./screenshots/${screenshot.id}.${screenshot.extension}`;\n const absolutePath = join(\n screenshotsDir,\n `${screenshot.id}.${screenshot.extension}`,\n );\n\n if (!this.writtenFileIds.has(screenshot.id)) {\n const buffer = Buffer.from(screenshot.rawBase64, 'base64');\n await writeFileAsync(absolutePath, buffer);\n this.writtenFileIds.add(screenshot.id);\n }\n\n if (options.markAsPersisted) {\n return screenshot.markPersistedToPath(relativePath, absolutePath);\n }\n\n return screenshot.registerPersistedFileCopy(relativePath, absolutePath);\n }\n\n loadBase64(refInput: unknown): string {\n const ref = normalizeScreenshotRef(refInput);\n if (!ref) {\n throw new Error('ScreenshotStore: invalid screenshot reference');\n }\n\n const resolved = resolveScreenshotSource(ref, {\n reportPath: this.reportPath,\n });\n\n if (resolved.type === 'data-uri') {\n return resolved.dataUri;\n }\n\n const data = readFileSync(resolved.filePath);\n return `data:${resolved.mimeType};base64,${data.toString('base64')}`;\n }\n\n cleanup(): void {\n if (\n this.mode === 'directory' &&\n this.screenshotsDir &&\n existsSync(this.screenshotsDir)\n ) {\n rmSync(this.screenshotsDir, { recursive: true, force: true });\n }\n this.writtenInlineIds.clear();\n this.writtenFileIds.clear();\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","normalizeScreenshotRef","value","record","extensionByMimeType","mimeType","resolveScreenshotSource","refInput","options","ref","id","Error","resolveReportRelativePath","filePath","isAbsolute","join","dirname","explicitFilePath","existsSync","inlineDataUri","extractImageByIdSync","siblingScreenshotPath","ScreenshotStore","screenshot","shouldWriteFileCopy","fileRef","screenshotsDir","mkdirSync","relativePath","absolutePath","buffer","Buffer","writeFileAsync","resolved","data","readFileSync","rmSync","Set"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dump/screenshot-store.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/screenshot-store.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, readFileSync, rmSync } from 'node:fs';\nimport { writeFile as writeFileAsync } from 'node:fs/promises';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport type { ScreenshotItem } from '../screenshot-item';\nimport { extractImageByIdSync } from './html-utils';\n\nexport interface ScreenshotRef {\n type: 'midscene_screenshot_ref';\n id: string;\n capturedAt: number;\n mimeType: 'image/png' | 'image/jpeg';\n storage: 'inline' | 'file';\n path?: string;\n}\n\nexport function normalizeScreenshotRef(value: unknown): ScreenshotRef | null {\n if (typeof value !== 'object' || value === null) return null;\n const record = value as Record<string, unknown>;\n\n if (\n record.type === 'midscene_screenshot_ref' &&\n typeof record.id === 'string' &&\n typeof record.capturedAt === 'number' &&\n (record.storage === 'inline' || record.storage === 'file') &&\n (record.mimeType === 'image/png' || record.mimeType === 'image/jpeg')\n ) {\n if (record.storage === 'file' && typeof record.path !== 'string') {\n return null;\n }\n return record as unknown as ScreenshotRef;\n }\n\n return null;\n}\n\ntype ResolvedScreenshotSource =\n | {\n type: 'data-uri';\n id: string;\n mimeType: ScreenshotRef['mimeType'];\n dataUri: string;\n }\n | {\n type: 'file';\n id: string;\n mimeType: ScreenshotRef['mimeType'];\n filePath: string;\n };\n\nfunction extensionByMimeType(mimeType: ScreenshotRef['mimeType']): string {\n return mimeType === 'image/jpeg' ? 'jpeg' : 'png';\n}\n\nexport function resolveScreenshotSource(\n refInput: unknown,\n options: {\n reportPath: string;\n fallbackId?: string;\n fallbackMimeType?: ScreenshotRef['mimeType'];\n },\n): ResolvedScreenshotSource {\n const ref = normalizeScreenshotRef(refInput);\n const id = ref?.id ?? options.fallbackId;\n const mimeType = ref?.mimeType ?? options.fallbackMimeType;\n\n if (!id || !mimeType) {\n throw new Error(\n 'ScreenshotStore: screenshot id and mimeType are required to resolve screenshot',\n );\n }\n\n const resolveReportRelativePath = (filePath: string): string =>\n isAbsolute(filePath)\n ? filePath\n : join(dirname(options.reportPath), filePath);\n\n if (ref?.storage === 'file') {\n if (!ref.path) {\n throw new Error(\n `ScreenshotStore: screenshot ref \"${ref.id}\" missing file path`,\n );\n }\n\n const explicitFilePath = resolveReportRelativePath(ref.path);\n if (existsSync(explicitFilePath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: explicitFilePath,\n };\n }\n }\n\n const inlineDataUri = extractImageByIdSync(options.reportPath, id);\n if (inlineDataUri) {\n return {\n type: 'data-uri',\n id,\n mimeType,\n dataUri: inlineDataUri,\n };\n }\n\n const siblingScreenshotPath = join(\n dirname(options.reportPath),\n 'screenshots',\n `${id}.${extensionByMimeType(mimeType)}`,\n );\n if (existsSync(siblingScreenshotPath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: siblingScreenshotPath,\n };\n }\n\n throw new Error(\n `ScreenshotStore: cannot resolve screenshot \"${id}\" from ${options.reportPath}`,\n );\n}\n\nexport class ScreenshotStore {\n private readonly mode: 'inline' | 'directory';\n private readonly reportPath: string;\n private readonly screenshotsDir?: string;\n private readonly writeInlineImage?: (\n id: string,\n base64: string,\n ) => void | Promise<void>;\n private readonly alsoWriteFileCopy: boolean;\n private readonly writtenInlineIds = new Set<string>();\n private readonly writtenFileIds = new Set<string>();\n\n constructor(options: {\n mode: 'inline' | 'directory';\n reportPath: string;\n screenshotsDir?: string;\n writeInlineImage?: (id: string, base64: string) => void | Promise<void>;\n alsoWriteFileCopy?: boolean;\n /** @deprecated Use alsoWriteFileCopy instead. */\n ensureFileCopy?: boolean;\n }) {\n this.mode = options.mode;\n this.reportPath = options.reportPath;\n this.screenshotsDir = options.screenshotsDir;\n this.writeInlineImage = options.writeInlineImage;\n this.alsoWriteFileCopy =\n options.alsoWriteFileCopy ?? options.ensureFileCopy ?? false;\n }\n\n async persist(screenshot: ScreenshotItem): Promise<ScreenshotRef> {\n const shouldWriteFileCopy =\n this.mode === 'directory' || this.alsoWriteFileCopy;\n const fileRef = shouldWriteFileCopy\n ? await this.persistToSharedFileIfNeeded(screenshot, {\n markAsPersisted: this.mode === 'directory',\n })\n : null;\n\n if (this.mode === 'inline') {\n if (!this.writeInlineImage) {\n throw new Error(\n 'ScreenshotStore: writeInlineImage is required in inline mode',\n );\n }\n if (!this.writtenInlineIds.has(screenshot.id)) {\n await this.writeInlineImage(screenshot.id, screenshot.base64);\n this.writtenInlineIds.add(screenshot.id);\n }\n return screenshot.markPersistedInline(this.reportPath);\n }\n\n if (!fileRef) {\n throw new Error(\n 'ScreenshotStore: file persistence is required in directory mode',\n );\n }\n return fileRef;\n }\n\n private async persistToSharedFileIfNeeded(\n screenshot: ScreenshotItem,\n options: {\n markAsPersisted: boolean;\n },\n ): Promise<ScreenshotRef> {\n const screenshotsDir = this.screenshotsDir;\n if (!screenshotsDir) {\n throw new Error(\n 'ScreenshotStore: screenshotsDir is required when file persistence is enabled',\n );\n }\n if (!existsSync(screenshotsDir)) {\n mkdirSync(screenshotsDir, { recursive: true });\n }\n\n const relativePath = `./screenshots/${screenshot.id}.${screenshot.extension}`;\n const absolutePath = join(\n screenshotsDir,\n `${screenshot.id}.${screenshot.extension}`,\n );\n\n if (!this.writtenFileIds.has(screenshot.id)) {\n const buffer = Buffer.from(screenshot.rawBase64, 'base64');\n await writeFileAsync(absolutePath, buffer);\n this.writtenFileIds.add(screenshot.id);\n }\n\n if (options.markAsPersisted) {\n return screenshot.markPersistedToPath(relativePath, absolutePath);\n }\n\n return screenshot.registerPersistedFileCopy(relativePath, absolutePath);\n }\n\n loadBase64(refInput: unknown): string {\n const ref = normalizeScreenshotRef(refInput);\n if (!ref) {\n throw new Error('ScreenshotStore: invalid screenshot reference');\n }\n\n const resolved = resolveScreenshotSource(ref, {\n reportPath: this.reportPath,\n });\n\n if (resolved.type === 'data-uri') {\n return resolved.dataUri;\n }\n\n const data = readFileSync(resolved.filePath);\n return `data:${resolved.mimeType};base64,${data.toString('base64')}`;\n }\n\n cleanup(): void {\n if (\n this.mode === 'directory' &&\n this.screenshotsDir &&\n existsSync(this.screenshotsDir)\n ) {\n rmSync(this.screenshotsDir, { recursive: true, force: true });\n }\n this.writtenInlineIds.clear();\n this.writtenFileIds.clear();\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","normalizeScreenshotRef","value","record","extensionByMimeType","mimeType","resolveScreenshotSource","refInput","options","ref","id","Error","resolveReportRelativePath","filePath","isAbsolute","join","dirname","explicitFilePath","existsSync","inlineDataUri","extractImageByIdSync","siblingScreenshotPath","ScreenshotStore","screenshot","shouldWriteFileCopy","fileRef","screenshotsDir","mkdirSync","relativePath","absolutePath","buffer","Buffer","writeFileAsync","resolved","data","readFileSync","rmSync","Set"],"mappings":"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"}
|
package/dist/lib/index.js
CHANGED
|
@@ -22,7 +22,7 @@ var __webpack_require__ = {};
|
|
|
22
22
|
})();
|
|
23
23
|
(()=>{
|
|
24
24
|
__webpack_require__.r = (exports1)=>{
|
|
25
|
-
if (
|
|
25
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
26
26
|
value: 'Module'
|
|
27
27
|
});
|
|
28
28
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -53,12 +53,14 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
53
53
|
ServiceError: ()=>external_types_js_namespaceObject.ServiceError,
|
|
54
54
|
parseImageScripts: ()=>external_dump_index_js_namespaceObject.parseImageScripts,
|
|
55
55
|
PointSchema: ()=>external_ai_model_index_js_namespaceObject.PointSchema,
|
|
56
|
-
RectSchema: ()=>external_ai_model_index_js_namespaceObject.RectSchema,
|
|
57
56
|
Agent: ()=>external_agent_index_js_namespaceObject.Agent,
|
|
57
|
+
RectSchema: ()=>external_ai_model_index_js_namespaceObject.RectSchema,
|
|
58
58
|
nullReportGenerator: ()=>external_report_generator_js_namespaceObject.nullReportGenerator,
|
|
59
|
+
ActionAssertionError: ()=>external_types_js_namespaceObject.ActionAssertionError,
|
|
59
60
|
ScreenshotStore: ()=>screenshot_store_js_namespaceObject.ScreenshotStore,
|
|
60
61
|
ReportMergingTool: ()=>external_report_js_namespaceObject.ReportMergingTool,
|
|
61
62
|
Service: ()=>index_js_default(),
|
|
63
|
+
isActionAssertionError: ()=>external_types_js_namespaceObject.isActionAssertionError,
|
|
62
64
|
AiLocateElement: ()=>external_ai_model_index_js_namespaceObject.AiLocateElement,
|
|
63
65
|
createReportCliCommands: ()=>external_report_cli_js_namespaceObject.createReportCliCommands,
|
|
64
66
|
ScreenshotItem: ()=>external_screenshot_item_js_namespaceObject.ScreenshotItem,
|
|
@@ -93,6 +95,7 @@ const external_screenshot_item_js_namespaceObject = require("./screenshot-item.j
|
|
|
93
95
|
const screenshot_store_js_namespaceObject = require("./dump/screenshot-store.js");
|
|
94
96
|
const external_report_markdown_js_namespaceObject = require("./report-markdown.js");
|
|
95
97
|
const src = index_js_default();
|
|
98
|
+
exports.ActionAssertionError = __webpack_exports__.ActionAssertionError;
|
|
96
99
|
exports.Agent = __webpack_exports__.Agent;
|
|
97
100
|
exports.AiLocateElement = __webpack_exports__.AiLocateElement;
|
|
98
101
|
exports.ExecutionDump = __webpack_exports__.ExecutionDump;
|
|
@@ -122,6 +125,7 @@ exports.generateDumpScriptTag = __webpack_exports__.generateDumpScriptTag;
|
|
|
122
125
|
exports.generateImageScriptTag = __webpack_exports__.generateImageScriptTag;
|
|
123
126
|
exports.getMidsceneLocationSchema = __webpack_exports__.getMidsceneLocationSchema;
|
|
124
127
|
exports.getVersion = __webpack_exports__.getVersion;
|
|
128
|
+
exports.isActionAssertionError = __webpack_exports__.isActionAssertionError;
|
|
125
129
|
exports.nullReportGenerator = __webpack_exports__.nullReportGenerator;
|
|
126
130
|
exports.parseDumpScript = __webpack_exports__.parseDumpScript;
|
|
127
131
|
exports.parseDumpScriptAttributes = __webpack_exports__.parseDumpScriptAttributes;
|
|
@@ -136,6 +140,7 @@ exports.splitReportHtmlByExecution = __webpack_exports__.splitReportHtmlByExecut
|
|
|
136
140
|
exports.unescapeContent = __webpack_exports__.unescapeContent;
|
|
137
141
|
exports.z = __webpack_exports__.z;
|
|
138
142
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
143
|
+
"ActionAssertionError",
|
|
139
144
|
"Agent",
|
|
140
145
|
"AiLocateElement",
|
|
141
146
|
"ExecutionDump",
|
|
@@ -165,6 +170,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
|
165
170
|
"generateImageScriptTag",
|
|
166
171
|
"getMidsceneLocationSchema",
|
|
167
172
|
"getVersion",
|
|
173
|
+
"isActionAssertionError",
|
|
168
174
|
"nullReportGenerator",
|
|
169
175
|
"parseDumpScript",
|
|
170
176
|
"parseDumpScriptAttributes",
|
package/dist/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/index.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__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 { z } from 'zod';\nimport Service from './service/index';\nimport { TaskRunner } from './task-runner';\nimport { getVersion } from './utils';\n\nexport {\n plan,\n AiLocateElement,\n runConnectivityTest,\n getMidsceneLocationSchema,\n PointSchema,\n SizeSchema,\n RectSchema,\n TMultimodalPromptSchema,\n TUserPromptSchema,\n type TMultimodalPrompt,\n type TUserPrompt,\n type ConnectivityCheckResultItem,\n type ConnectivityTestConfig,\n type ConnectivityTestResult,\n} from './ai-model/index';\n\nexport {\n MIDSCENE_MODEL_NAME,\n type CreateOpenAIClientFn,\n} from '@aiscene/shared/env';\n\nexport type * from './types';\nexport {\n ServiceError,\n ExecutionDump,\n ReportActionDump,\n GroupedActionDump,\n type IExecutionDump,\n type IReportActionDump,\n type IGroupedActionDump,\n type ReportMeta,\n type GroupMeta,\n} from './types';\n\nexport { z };\n\nexport default Service;\nexport { TaskRunner, Service, getVersion };\n\nexport type {\n MidsceneYamlScript,\n MidsceneYamlTask,\n MidsceneYamlFlowItem,\n MidsceneYamlConfigResult,\n MidsceneYamlConfig,\n MidsceneYamlScriptWebEnv,\n MidsceneYamlScriptAndroidEnv,\n MidsceneYamlScriptIOSEnv,\n MidsceneYamlScriptEnv,\n LocateOption,\n DetailedLocateParam,\n} from './yaml';\n\nexport { Agent, type AgentOpt, type AiActOptions, createAgent } from './agent';\n\n// Dump utilities\nexport {\n restoreImageReferences,\n escapeContent,\n unescapeContent,\n parseImageScripts,\n parseDumpScript,\n parseDumpScriptAttributes,\n generateImageScriptTag,\n generateDumpScriptTag,\n} from './dump';\n\n// Report generator\nexport type { IReportGenerator } from './report-generator';\nexport { ReportGenerator, nullReportGenerator } from './report-generator';\nexport {\n collectDedupedExecutions,\n ReportMergingTool,\n dedupeExecutionsKeepLatest,\n splitReportHtmlByExecution,\n} from './report';\nexport {\n createReportCliCommands,\n reportFileToMarkdown,\n splitReportFile,\n type ConsumeReportFileAction,\n type ReportFileToMarkdownOptions,\n type ReportCliCommandDefinition,\n type ReportCliCommandEntry,\n type SplitReportFileOptions,\n} from './report-cli';\n\n// ScreenshotItem\nexport { ScreenshotItem } from './screenshot-item';\nexport { ScreenshotStore, type ScreenshotRef } from './dump/screenshot-store';\n\nexport {\n executionToMarkdown,\n reportToMarkdown,\n type ExecutionMarkdownOptions,\n type ExecutionMarkdownResult,\n type ReportMarkdownResult,\n type MarkdownAttachment,\n} from './report-markdown';\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","Service"],"mappings":";;;IACAA,oBAAoB,CAAC,GAAG,CAACC;QACxB,IAAIC,SAASD,UAAUA,OAAO,UAAU,GACvC,IAAOA,MAAM,CAAC,UAAU,GACxB,IAAOA;QACRD,oBAAoB,CAAC,CAACE,QAAQ;YAAE,GAAGA;QAAO;QAC1C,OAAOA;IACR;;;ICPAF,oBAAoB,CAAC,GAAG,CAAC,UAASG;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGH,oBAAoB,CAAC,CAACG,YAAYC,QAAQ,CAACJ,oBAAoB,CAAC,CAAC,UAASI,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAJ,oBAAoB,CAAC,GAAG,CAACM,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFP,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,
|
|
1
|
+
{"version":3,"file":"index.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/index.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__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 { z } from 'zod';\nimport Service from './service/index';\nimport { TaskRunner } from './task-runner';\nimport { getVersion } from './utils';\n\nexport {\n plan,\n AiLocateElement,\n runConnectivityTest,\n getMidsceneLocationSchema,\n PointSchema,\n SizeSchema,\n RectSchema,\n TMultimodalPromptSchema,\n TUserPromptSchema,\n type TMultimodalPrompt,\n type TUserPrompt,\n type ConnectivityCheckResultItem,\n type ConnectivityTestConfig,\n type ConnectivityTestResult,\n} from './ai-model/index';\n\nexport {\n MIDSCENE_MODEL_NAME,\n type CreateOpenAIClientFn,\n} from '@aiscene/shared/env';\n\nexport type * from './types';\nexport {\n ServiceError,\n ActionAssertionError,\n isActionAssertionError,\n ExecutionDump,\n ReportActionDump,\n GroupedActionDump,\n type IExecutionDump,\n type IReportActionDump,\n type IGroupedActionDump,\n type ReportMeta,\n type GroupMeta,\n} from './types';\n\nexport { z };\n\nexport default Service;\nexport { TaskRunner, Service, getVersion };\n\nexport type {\n MidsceneYamlScript,\n MidsceneYamlTask,\n MidsceneYamlFlowItem,\n MidsceneYamlConfigResult,\n MidsceneYamlConfig,\n MidsceneYamlScriptWebEnv,\n MidsceneYamlScriptAndroidEnv,\n MidsceneYamlScriptIOSEnv,\n MidsceneYamlScriptEnv,\n LocateOption,\n DetailedLocateParam,\n} from './yaml';\n\nexport { Agent, type AgentOpt, type AiActOptions, createAgent } from './agent';\n\n// Dump utilities\nexport {\n restoreImageReferences,\n escapeContent,\n unescapeContent,\n parseImageScripts,\n parseDumpScript,\n parseDumpScriptAttributes,\n generateImageScriptTag,\n generateDumpScriptTag,\n} from './dump';\n\n// Report generator\nexport type { IReportGenerator } from './report-generator';\nexport { ReportGenerator, nullReportGenerator } from './report-generator';\nexport {\n collectDedupedExecutions,\n ReportMergingTool,\n dedupeExecutionsKeepLatest,\n splitReportHtmlByExecution,\n} from './report';\nexport {\n createReportCliCommands,\n reportFileToMarkdown,\n splitReportFile,\n type ConsumeReportFileAction,\n type ReportFileToMarkdownOptions,\n type ReportCliCommandDefinition,\n type ReportCliCommandEntry,\n type SplitReportFileOptions,\n} from './report-cli';\n\n// ScreenshotItem\nexport { ScreenshotItem } from './screenshot-item';\nexport { ScreenshotStore, type ScreenshotRef } from './dump/screenshot-store';\n\nexport {\n executionToMarkdown,\n reportToMarkdown,\n type ExecutionMarkdownOptions,\n type ExecutionMarkdownResult,\n type ReportMarkdownResult,\n type MarkdownAttachment,\n} from './report-markdown';\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","Service"],"mappings":";;;IACAA,oBAAoB,CAAC,GAAG,CAACC;QACxB,IAAIC,SAASD,UAAUA,OAAO,UAAU,GACvC,IAAOA,MAAM,CAAC,UAAU,GACxB,IAAOA;QACRD,oBAAoB,CAAC,CAACE,QAAQ;YAAE,GAAGA;QAAO;QAC1C,OAAOA;IACR;;;ICPAF,oBAAoB,CAAC,GAAG,CAAC,UAASG;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGH,oBAAoB,CAAC,CAACG,YAAYC,QAAQ,CAACJ,oBAAoB,CAAC,CAAC,UAASI,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAJ,oBAAoB,CAAC,GAAG,CAACM,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFP,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOQ,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACsCA,YAAeI"}
|
package/dist/lib/report-cli.js
CHANGED
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -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 { resolveScreenshotSource } from './dump/screenshot-store';\nimport { collectDedupedExecutions, splitReportHtmlByExecution } from './report';\nimport { reportToMarkdown } from './report-markdown';\nimport type { MarkdownAttachment } from './report-markdown';\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 = 'split' | 'to-markdown';\n\nexport interface ConsumeReportFileOptions {\n htmlPath: string;\n outputDir: string;\n}\n\nexport type SplitReportFileOptions = ConsumeReportFileOptions;\nexport type ReportFileToMarkdownOptions = ConsumeReportFileOptions;\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 outputRelativePath = `./screenshots/${suggestedFileName}`;\n const sourceRef =\n attachment.filePath !== outputRelativePath\n ? {\n type: 'midscene_screenshot_ref' as const,\n id,\n capturedAt: 0,\n mimeType: (mimeType || 'image/png') as 'image/png' | 'image/jpeg',\n storage: 'file' as const,\n path: attachment.filePath,\n }\n : null;\n\n const resolved = resolveScreenshotSource(sourceRef, {\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 reportCommandDefinition: ReportCliCommandDefinition = {\n name: 'report-tool',\n description:\n 'Transform Midscene report artifacts, including splitting executions and converting to markdown.',\n schema: {\n action: z\n .enum(['split', 'to-markdown'])\n .optional()\n .describe(\n 'Report action to run. Supports: split, to-markdown. Defaults to split.',\n ),\n htmlPath: z\n .string()\n .optional()\n .describe('Input report HTML path (e.g. ./report/index.html)'),\n outputDir: z\n .string()\n .optional()\n .describe('Output directory for generated report artifacts'),\n },\n handler: async (args) => {\n const {\n action = 'split',\n htmlPath,\n outputDir,\n } = args as {\n action?: string;\n htmlPath?: string;\n outputDir?: string;\n };\n if (action !== 'split' && action !== 'to-markdown') {\n throw new Error(\n `report-tool: unsupported --action value \"${action}\". Currently supported: split, to-markdown`,\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 === '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","outputRelativePath","sourceRef","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","reportCommandDefinition","z","args","action","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 {\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 { resolveScreenshotSource } from './dump/screenshot-store';\nimport { collectDedupedExecutions, splitReportHtmlByExecution } from './report';\nimport { reportToMarkdown } from './report-markdown';\nimport type { MarkdownAttachment } from './report-markdown';\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 = 'split' | 'to-markdown';\n\nexport interface ConsumeReportFileOptions {\n htmlPath: string;\n outputDir: string;\n}\n\nexport type SplitReportFileOptions = ConsumeReportFileOptions;\nexport type ReportFileToMarkdownOptions = ConsumeReportFileOptions;\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 outputRelativePath = `./screenshots/${suggestedFileName}`;\n const sourceRef =\n attachment.filePath !== outputRelativePath\n ? {\n type: 'midscene_screenshot_ref' as const,\n id,\n capturedAt: 0,\n mimeType: (mimeType || 'image/png') as 'image/png' | 'image/jpeg',\n storage: 'file' as const,\n path: attachment.filePath,\n }\n : null;\n\n const resolved = resolveScreenshotSource(sourceRef, {\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 reportCommandDefinition: ReportCliCommandDefinition = {\n name: 'report-tool',\n description:\n 'Transform Midscene report artifacts, including splitting executions and converting to markdown.',\n schema: {\n action: z\n .enum(['split', 'to-markdown'])\n .optional()\n .describe(\n 'Report action to run. Supports: split, to-markdown. Defaults to split.',\n ),\n htmlPath: z\n .string()\n .optional()\n .describe('Input report HTML path (e.g. ./report/index.html)'),\n outputDir: z\n .string()\n .optional()\n .describe('Output directory for generated report artifacts'),\n },\n handler: async (args) => {\n const {\n action = 'split',\n htmlPath,\n outputDir,\n } = args as {\n action?: string;\n htmlPath?: string;\n outputDir?: string;\n };\n if (action !== 'split' && action !== 'to-markdown') {\n throw new Error(\n `report-tool: unsupported --action value \"${action}\". Currently supported: split, to-markdown`,\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 === '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","outputRelativePath","sourceRef","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","reportCommandDefinition","z","args","action","createReportCliCommands"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -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 writeFile as writeFileAsync,\n} from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { getMidsceneRunSubDir } from '@aiscene/shared/common';\nimport {\n MIDSCENE_REPORT_QUIET,\n globalConfigManager,\n} from '@aiscene/shared/env';\nimport { ifInBrowser, logMsg, uuid } from '@aiscene/shared/utils';\nimport {\n generateDumpScriptTag,\n generateImageScriptTag,\n getBaseUrlFixScript,\n} from './dump/html-utils';\nimport { ScreenshotStore } from './dump/screenshot-store';\nimport {\n type ExecutionDump,\n ReportActionDump,\n type ReportAttributes,\n type ReportMeta,\n} from './types';\nimport { getReportTpl } from './utils';\n\nexport interface IReportGenerator {\n /**\n * Write or update a single execution.\n * Each call appends a new dump script tag. The frontend deduplicates\n * executions with the same id/name, keeping only the last one.\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\n /**\n * Finalize the report. Calls flush() internally.\n */\n finalize(): Promise<string | undefined>;\n\n getReportPath(): string | undefined;\n}\n\nexport const nullReportGenerator: IReportGenerator = {\n onExecutionUpdate: () => {},\n flush: async () => {},\n finalize: async () => undefined,\n getReportPath: () => 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: 'inline' | 'directory';\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: ScreenshotStore;\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 reportAttributes: Record<string, string> = {};\n\n // write queue for serial execution\n private writeQueue: Promise<void> = Promise.resolve();\n private destroyed = false;\n\n constructor(options: {\n reportPath: string;\n screenshotMode: 'inline' | 'directory';\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 this.screenshotStore = new ScreenshotStore({\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 });\n if (options.reuseExistingReport) {\n this.hydrateStateFromExistingReport();\n }\n this.printReportPath('will be generated at');\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 if (opts.generateReport === false) return nullReportGenerator;\n\n // In browser environment, file system is not available\n if (ifInBrowser) return nullReportGenerator;\n validateReportFileName(reportFileName);\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.lastExecution = execution;\n this.lastReportMeta = reportMeta;\n this.mergeReportAttributes(attributes);\n this.writeQueue = this.writeQueue.then(async () => {\n if (this.destroyed) return;\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 // Re-write the last execution to capture any final state changes\n if (this.lastExecution && this.lastReportMeta) {\n this.onExecutionUpdate(this.lastExecution, this.lastReportMeta);\n }\n await this.flush();\n this.destroyed = true;\n\n if (!this.initialized) {\n // No executions were ever written — no file exists\n return undefined;\n }\n\n this.printReportPath('finalized');\n return this.reportPath;\n }\n\n getReportPath(): string | undefined {\n return this.reportPath;\n }\n\n private printReportPath(verb: string): void {\n if (!this.autoPrint || !this.reportPath) return;\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET))\n return;\n\n if (this.screenshotMode === 'directory') {\n logMsg(\n `Midscene - report ${verb}: npx serve ${dirname(this.reportPath)}`,\n );\n } else {\n logMsg(`Midscene - report ${verb}: ${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 if (this.screenshotMode === 'inline') {\n await this.writeInlineExecution(execution, singleDump);\n } else {\n await this.writeDirectoryExecution(execution, singleDump);\n }\n\n if (this.shouldPersistExecutionDump) {\n await this.persistExecutionDumpToFile(execution, singleDump);\n }\n\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath('generated');\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 // 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 const reportDir = dirname(this.reportPath);\n const existingExecutionIndices = readdirSync(reportDir)\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 ...this.reportAttributes,\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-only inline mode: write new screenshots and a dump tag on every call.\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 writeInlineExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<void> {\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 await writeFileAsync(this.reportPath, getReportTpl());\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\n // Append dump tag (always — frontend keeps only last per execution id)\n const serialized = singleDump.serialize();\n await appendFileAsync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\n }\n\n private async writeDirectoryExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<void> {\n const dir = dirname(this.reportPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n for (const screenshot of execution.collectScreenshots()) {\n await this.screenshotStore.persist(screenshot);\n }\n\n // 2. Append dump tag (always — frontend keeps only last per execution id)\n const serialized = singleDump.serialize();\n\n if (!this.initialized) {\n await writeFileAsync(\n this.reportPath,\n `${getReportTpl()}${getBaseUrlFixScript()}`,\n );\n this.initialized = true;\n }\n\n await appendFileAsync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\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 async persistExecutionDumpToFile(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<void> {\n const dir = dirname(this.reportPath);\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(dirname(this.reportPath), fileName);\n await writeFileAsync(filePath, singleDump.serialize(2), 'utf-8');\n }\n}\n\nfunction ensureHtmlFileName(reportFileName: string): string {\n return reportFileName.endsWith('.html')\n ? reportFileName\n : `${reportFileName}.html`;\n}\n\nfunction validateReportFileName(reportFileName: string): 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"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","nullReportGenerator","undefined","assertReportGenerationOptions","opts","Error","ReportGenerator","reportFileName","ifInBrowser","validateReportFileName","reportRootDir","getMidsceneRunSubDir","outputDir","join","reportPath","ensureHtmlFileName","execution","reportMeta","attributes","verb","globalConfigManager","MIDSCENE_REPORT_QUIET","logMsg","dirname","singleDump","value","String","existsSync","reportDir","existingExecutionIndices","readdirSync","name","index","Boolean","Number","Math","ReportActionDump","dir","mkdirSync","writeFileAsync","getReportTpl","screenshot","serialized","appendFileAsync","generateDumpScriptTag","getBaseUrlFixScript","executionLogKey","fileIndex","fileName","filePath","options","Map","Promise","uuid","ScreenshotStore","id","base64","generateImageScriptTag"],"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 writeFile as writeFileAsync,\n} from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { getMidsceneRunSubDir } from '@aiscene/shared/common';\nimport {\n MIDSCENE_REPORT_QUIET,\n globalConfigManager,\n} from '@aiscene/shared/env';\nimport { ifInBrowser, logMsg, uuid } from '@aiscene/shared/utils';\nimport {\n generateDumpScriptTag,\n generateImageScriptTag,\n getBaseUrlFixScript,\n} from './dump/html-utils';\nimport { ScreenshotStore } from './dump/screenshot-store';\nimport {\n type ExecutionDump,\n ReportActionDump,\n type ReportAttributes,\n type ReportMeta,\n} from './types';\nimport { getReportTpl } from './utils';\n\nexport interface IReportGenerator {\n /**\n * Write or update a single execution.\n * Each call appends a new dump script tag. The frontend deduplicates\n * executions with the same id/name, keeping only the last one.\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\n /**\n * Finalize the report. Calls flush() internally.\n */\n finalize(): Promise<string | undefined>;\n\n getReportPath(): string | undefined;\n}\n\nexport const nullReportGenerator: IReportGenerator = {\n onExecutionUpdate: () => {},\n flush: async () => {},\n finalize: async () => undefined,\n getReportPath: () => 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: 'inline' | 'directory';\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: ScreenshotStore;\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 reportAttributes: Record<string, string> = {};\n\n // write queue for serial execution\n private writeQueue: Promise<void> = Promise.resolve();\n private destroyed = false;\n\n constructor(options: {\n reportPath: string;\n screenshotMode: 'inline' | 'directory';\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 this.screenshotStore = new ScreenshotStore({\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 });\n if (options.reuseExistingReport) {\n this.hydrateStateFromExistingReport();\n }\n this.printReportPath('will be generated at');\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 if (opts.generateReport === false) return nullReportGenerator;\n\n // In browser environment, file system is not available\n if (ifInBrowser) return nullReportGenerator;\n validateReportFileName(reportFileName);\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.lastExecution = execution;\n this.lastReportMeta = reportMeta;\n this.mergeReportAttributes(attributes);\n this.writeQueue = this.writeQueue.then(async () => {\n if (this.destroyed) return;\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 // Re-write the last execution to capture any final state changes\n if (this.lastExecution && this.lastReportMeta) {\n this.onExecutionUpdate(this.lastExecution, this.lastReportMeta);\n }\n await this.flush();\n this.destroyed = true;\n\n if (!this.initialized) {\n // No executions were ever written — no file exists\n return undefined;\n }\n\n this.printReportPath('finalized');\n return this.reportPath;\n }\n\n getReportPath(): string | undefined {\n return this.reportPath;\n }\n\n private printReportPath(verb: string): void {\n if (!this.autoPrint || !this.reportPath) return;\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET))\n return;\n\n if (this.screenshotMode === 'directory') {\n logMsg(\n `Midscene - report ${verb}: npx serve ${dirname(this.reportPath)}`,\n );\n } else {\n logMsg(`Midscene - report ${verb}: ${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 if (this.screenshotMode === 'inline') {\n await this.writeInlineExecution(execution, singleDump);\n } else {\n await this.writeDirectoryExecution(execution, singleDump);\n }\n\n if (this.shouldPersistExecutionDump) {\n await this.persistExecutionDumpToFile(execution, singleDump);\n }\n\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath('generated');\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 // 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 const reportDir = dirname(this.reportPath);\n const existingExecutionIndices = readdirSync(reportDir)\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 ...this.reportAttributes,\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-only inline mode: write new screenshots and a dump tag on every call.\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 writeInlineExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<void> {\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 await writeFileAsync(this.reportPath, getReportTpl());\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\n // Append dump tag (always — frontend keeps only last per execution id)\n const serialized = singleDump.serialize();\n await appendFileAsync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\n }\n\n private async writeDirectoryExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<void> {\n const dir = dirname(this.reportPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n for (const screenshot of execution.collectScreenshots()) {\n await this.screenshotStore.persist(screenshot);\n }\n\n // 2. Append dump tag (always — frontend keeps only last per execution id)\n const serialized = singleDump.serialize();\n\n if (!this.initialized) {\n await writeFileAsync(\n this.reportPath,\n `${getReportTpl()}${getBaseUrlFixScript()}`,\n );\n this.initialized = true;\n }\n\n await appendFileAsync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\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 async persistExecutionDumpToFile(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<void> {\n const dir = dirname(this.reportPath);\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(dirname(this.reportPath), fileName);\n await writeFileAsync(filePath, singleDump.serialize(2), 'utf-8');\n }\n}\n\nfunction ensureHtmlFileName(reportFileName: string): string {\n return reportFileName.endsWith('.html')\n ? reportFileName\n : `${reportFileName}.html`;\n}\n\nfunction validateReportFileName(reportFileName: string): 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"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","nullReportGenerator","undefined","assertReportGenerationOptions","opts","Error","ReportGenerator","reportFileName","ifInBrowser","validateReportFileName","reportRootDir","getMidsceneRunSubDir","outputDir","join","reportPath","ensureHtmlFileName","execution","reportMeta","attributes","verb","globalConfigManager","MIDSCENE_REPORT_QUIET","logMsg","dirname","singleDump","value","String","existsSync","reportDir","existingExecutionIndices","readdirSync","name","index","Boolean","Number","Math","ReportActionDump","dir","mkdirSync","writeFileAsync","getReportTpl","screenshot","serialized","appendFileAsync","generateDumpScriptTag","getBaseUrlFixScript","executionLogKey","fileIndex","fileName","filePath","options","Map","Promise","uuid","ScreenshotStore","id","base64","generateImageScriptTag"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|