@aiscene/core 8.1.2 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/agent/agent.mjs +26 -11
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/task-builder.mjs +4 -2
- package/dist/es/agent/task-builder.mjs.map +1 -1
- package/dist/es/agent/tasks.mjs +21 -13
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/ui-utils.mjs +13 -1
- package/dist/es/agent/ui-utils.mjs.map +1 -1
- package/dist/es/agent/usage-intent.mjs +18 -0
- package/dist/es/agent/usage-intent.mjs.map +1 -0
- package/dist/es/agent/utils.mjs +9 -26
- package/dist/es/agent/utils.mjs.map +1 -1
- package/dist/es/ai-model/auto-glm/planning.mjs.map +1 -1
- package/dist/es/ai-model/inspect.mjs +2 -4
- package/dist/es/ai-model/inspect.mjs.map +1 -1
- package/dist/es/ai-model/llm-planning.mjs +1 -3
- package/dist/es/ai-model/llm-planning.mjs.map +1 -1
- package/dist/es/ai-model/prompt/extraction.mjs +0 -2
- package/dist/es/ai-model/prompt/extraction.mjs.map +1 -1
- package/dist/es/ai-model/prompt/llm-planning.mjs +18 -0
- package/dist/es/ai-model/prompt/llm-planning.mjs.map +1 -1
- package/dist/es/ai-model/prompt/playwright-generator.mjs +4 -4
- package/dist/es/ai-model/prompt/playwright-generator.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/codex-app-server.mjs +12 -12
- package/dist/es/ai-model/service-caller/codex-app-server.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/index.mjs +148 -118
- package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/request-timeout.mjs +49 -0
- package/dist/es/ai-model/service-caller/request-timeout.mjs.map +1 -0
- package/dist/es/ai-model/ui-tars-planning.mjs.map +1 -1
- package/dist/es/common.mjs +16 -3
- package/dist/es/common.mjs.map +1 -1
- package/dist/es/device/index.mjs +171 -30
- package/dist/es/device/index.mjs.map +1 -1
- package/dist/es/dump/screenshot-store.mjs +7 -6
- package/dist/es/dump/screenshot-store.mjs.map +1 -1
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/report-generator.mjs +25 -25
- package/dist/es/report-generator.mjs.map +1 -1
- package/dist/es/report.mjs +20 -1
- package/dist/es/report.mjs.map +1 -1
- package/dist/es/skill/index.mjs +3 -4
- package/dist/es/skill/index.mjs.map +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +2 -2
- package/dist/es/yaml/player.mjs +2 -17
- package/dist/es/yaml/player.mjs.map +1 -1
- package/dist/lib/agent/agent.js +27 -12
- 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 +5 -3
- 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 +22 -14
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/ui-utils.js +14 -2
- package/dist/lib/agent/ui-utils.js.map +1 -1
- package/dist/lib/agent/usage-intent.js +52 -0
- package/dist/lib/agent/usage-intent.js.map +1 -0
- package/dist/lib/agent/utils.js +10 -27
- 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 +3 -5
- package/dist/lib/ai-model/inspect.js.map +1 -1
- package/dist/lib/ai-model/llm-planning.js +2 -4
- 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 -3
- 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 +19 -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 +5 -5
- 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 +13 -13
- 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 +149 -119
- package/dist/lib/ai-model/service-caller/index.js.map +1 -1
- package/dist/lib/ai-model/service-caller/request-timeout.js +95 -0
- package/dist/lib/ai-model/service-caller/request-timeout.js.map +1 -0
- 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 +17 -4
- 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 +177 -30
- 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 +7 -6
- package/dist/lib/dump/screenshot-store.js.map +1 -1
- package/dist/lib/index.js +1 -1
- 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 +24 -24
- 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 +20 -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 +4 -5
- 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 +3 -3
- 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 +3 -18
- 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/agent/agent.d.ts +4 -0
- package/dist/types/agent/tasks.d.ts +8 -7
- package/dist/types/agent/usage-intent.d.ts +3 -0
- package/dist/types/ai-model/llm-planning.d.ts +2 -2
- package/dist/types/ai-model/service-caller/codex-app-server.d.ts +5 -5
- package/dist/types/ai-model/service-caller/index.d.ts +1 -4
- package/dist/types/ai-model/service-caller/request-timeout.d.ts +32 -0
- package/dist/types/device/device-options.d.ts +11 -1
- package/dist/types/device/index.d.ts +195 -24
- package/dist/types/dump/screenshot-store.d.ts +2 -2
- package/dist/types/index.d.ts +0 -1
- package/dist/types/report-generator.d.ts +7 -0
- package/dist/types/types.d.ts +15 -4
- package/package.json +2 -2
|
@@ -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};","import { existsSync, mkdirSync, readdirSync, writeFileSync } from 'node:fs';\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 { appendFileSync, 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 }) {\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: (id, base64) => {\n appendFileSync(\n this.reportPath,\n `\\n${generateImageScriptTag(id, base64)}`,\n );\n },\n alsoWriteFileCopy: this.shouldPersistExecutionDump,\n });\n this.hydrateStateFromExistingReport();\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 },\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 });\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(() => {\n if (this.destroyed) return;\n 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 doWriteExecution(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): void {\n const singleDump = this.wrapAsReportDump(execution, reportMeta);\n\n if (this.screenshotMode === 'inline') {\n this.writeInlineExecution(execution, singleDump);\n } else {\n this.writeDirectoryExecution(execution, singleDump);\n }\n\n if (this.shouldPersistExecutionDump) {\n 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 if (key === 'data-group-id') {\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 private writeInlineExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): 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 writeFileSync(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 this.screenshotStore.persist(screenshot);\n }\n\n // Append dump tag (always — frontend keeps only last per execution id)\n const serialized = singleDump.serialize();\n appendFileSync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\n }\n\n private writeDirectoryExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): 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 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 writeFileSync(\n this.reportPath,\n `${getReportTpl()}${getBaseUrlFixScript()}`,\n );\n this.initialized = true;\n }\n\n appendFileSync(\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 persistExecutionDumpToFile(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): 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 writeFileSync(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","writeFileSync","getReportTpl","screenshot","serialized","appendFileSync","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 ("u" > 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-markdown.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report-markdown.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 { basename } from 'node:path';\nimport { extractInsightParam, paramStr, typeStr } from '@/agent/ui-utils';\nimport { ScreenshotItem } from '@/screenshot-item';\nimport type {\n ExecutionDump,\n ExecutionRecorderItem,\n ExecutionTask,\n IExecutionDump,\n IReportActionDump,\n ReportActionDump,\n} from '@/types';\nimport { normalizeScreenshotRef } from './dump/screenshot-store';\n\nexport interface MarkdownAttachment {\n id: string;\n suggestedFileName: string;\n mimeType?: string;\n filePath: string;\n executionIndex: number;\n taskIndex: number;\n /** Populated when screenshot data is available in memory (e.g. browser context). */\n base64Data?: string;\n}\n\nexport interface ExecutionMarkdownOptions {\n screenshotBaseDir?: string;\n}\n\nexport interface ExecutionMarkdownResult {\n markdown: string;\n attachments: MarkdownAttachment[];\n}\n\nexport interface ReportMarkdownResult {\n markdown: string;\n attachments: MarkdownAttachment[];\n}\n\nfunction toExecutionDump(\n execution: ExecutionDump | IExecutionDump,\n): IExecutionDump {\n if (!execution || typeof execution !== 'object') {\n throw new Error('executionToMarkdown: execution is required');\n }\n\n if (!Array.isArray(execution.tasks)) {\n throw new Error('executionToMarkdown: execution.tasks must be an array');\n }\n\n if (!execution.name) {\n throw new Error('executionToMarkdown: execution.name is required');\n }\n\n return execution;\n}\n\nfunction toReportDump(\n report: ReportActionDump | IReportActionDump,\n): IReportActionDump {\n if (!report || typeof report !== 'object') {\n throw new Error('reportToMarkdown: report is required');\n }\n\n if (!Array.isArray(report.executions)) {\n throw new Error('reportToMarkdown: report.executions must be an array');\n }\n\n return report;\n}\n\nfunction formatTime(ts?: number): string {\n if (typeof ts !== 'number' || Number.isNaN(ts)) {\n return 'N/A';\n }\n return new Date(ts).toISOString();\n}\n\nfunction resolveTaskTiming(task: ExecutionTask): {\n start?: number;\n end?: number;\n cost?: number;\n} {\n const timing = task.timing;\n if (!timing) {\n return {};\n }\n\n const start = timing.start ?? timing.callAiStart ?? timing.callActionStart;\n const end =\n timing.end ??\n timing.callAiEnd ??\n timing.callActionEnd ??\n timing.captureAfterCallingSnapshotEnd;\n const cost =\n timing.cost ??\n (typeof start === 'number' && typeof end === 'number'\n ? end - start\n : undefined);\n\n return { start, end, cost };\n}\n\nfunction safeTaskParam(task: ExecutionTask): string {\n const readable = paramStr(task);\n if (readable) {\n return readable;\n }\n\n if (task.type === 'Insight') {\n return extractInsightParam((task as any).param).content;\n }\n\n return '';\n}\n\nfunction formatSize(\n size?: { width?: number; height?: number } | null,\n): string | undefined {\n if (\n !size ||\n typeof size.width !== 'number' ||\n typeof size.height !== 'number' ||\n Number.isNaN(size.width) ||\n Number.isNaN(size.height)\n ) {\n return undefined;\n }\n\n return `${size.width} x ${size.height}`;\n}\n\nfunction extractLocateCenter(\n task: ExecutionTask,\n): [number, number] | undefined {\n const outputCenter = (task.output as { element?: { center?: unknown } })\n ?.element?.center;\n if (\n Array.isArray(outputCenter) &&\n outputCenter.length >= 2 &&\n typeof outputCenter[0] === 'number' &&\n typeof outputCenter[1] === 'number'\n ) {\n return [outputCenter[0], outputCenter[1]];\n }\n\n const paramLocateCenter = (task.param as { locate?: { center?: unknown } })\n ?.locate?.center;\n if (\n Array.isArray(paramLocateCenter) &&\n paramLocateCenter.length >= 2 &&\n typeof paramLocateCenter[0] === 'number' &&\n typeof paramLocateCenter[1] === 'number'\n ) {\n return [paramLocateCenter[0], paramLocateCenter[1]];\n }\n\n const paramCenter = (task.param as { center?: unknown })?.center;\n if (\n Array.isArray(paramCenter) &&\n paramCenter.length >= 2 &&\n typeof paramCenter[0] === 'number' &&\n typeof paramCenter[1] === 'number'\n ) {\n return [paramCenter[0], paramCenter[1]];\n }\n\n return undefined;\n}\n\nfunction tryExtractBase64(screenshot: unknown): string | undefined {\n if (!screenshot || typeof screenshot !== 'object') return undefined;\n const s = screenshot as Record<string, unknown>;\n if (typeof s.base64 === 'string' && s.base64.length > 0) {\n return s.base64;\n }\n return undefined;\n}\n\nfunction screenshotAttachment(\n screenshot: unknown,\n screenshotBaseDir: string,\n executionIndex: number,\n taskIndex: number,\n): { markdown: string; attachment: MarkdownAttachment } {\n if (screenshot instanceof ScreenshotItem) {\n const ext = screenshot.extension;\n const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${screenshot.id}.${ext}`;\n const filePath = `${screenshotBaseDir}/${suggestedFileName}`;\n return {\n markdown: `\\n`,\n attachment: {\n id: screenshot.id,\n suggestedFileName,\n filePath,\n mimeType: `image/${ext === 'jpeg' ? 'jpeg' : 'png'}`,\n executionIndex,\n taskIndex,\n base64Data: tryExtractBase64(screenshot),\n },\n };\n }\n\n const ref = normalizeScreenshotRef(screenshot);\n if (ref) {\n const ext = ref.mimeType === 'image/jpeg' ? 'jpeg' : 'png';\n const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${ref.id}.${ext}`;\n const filePath = ref.path || `${screenshotBaseDir}/${suggestedFileName}`;\n return {\n markdown: `\\n`,\n attachment: {\n id: ref.id,\n suggestedFileName,\n filePath,\n mimeType: ref.mimeType,\n executionIndex,\n taskIndex,\n base64Data: tryExtractBase64(screenshot),\n },\n };\n }\n\n const base64 = tryExtractBase64(screenshot);\n if (base64) {\n const ext = base64.startsWith('data:image/jpeg') ? 'jpeg' : 'png';\n const id = `restored-${executionIndex + 1}-${taskIndex + 1}`;\n const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${id}.${ext}`;\n const filePath = `${screenshotBaseDir}/${suggestedFileName}`;\n return {\n markdown: `\\n`,\n attachment: {\n id,\n suggestedFileName,\n filePath,\n mimeType: `image/${ext}`,\n executionIndex,\n taskIndex,\n base64Data: base64,\n },\n };\n }\n\n throw new Error(\n `executionToMarkdown: missing screenshot for execution #${executionIndex + 1} task #${taskIndex + 1}`,\n );\n}\n\nfunction recorderMarkdownSection(\n recorder: ExecutionRecorderItem[] | undefined,\n screenshotBaseDir: string,\n executionIndex: number,\n taskIndex: number,\n): { lines: string[]; attachments: MarkdownAttachment[] } {\n if (!recorder?.length) {\n return { lines: [], attachments: [] };\n }\n\n const lines: string[] = ['', '### Recorder'];\n const attachments: MarkdownAttachment[] = [];\n\n recorder.forEach((item, recorderIndex) => {\n lines.push(\n `- #${recorderIndex + 1} type=${item.type}, ts=${formatTime(item.ts)}, timing=${item.timing || 'N/A'}`,\n );\n\n if (!item.screenshot) {\n return;\n }\n\n const imageResult = screenshotAttachment(\n item.screenshot,\n screenshotBaseDir,\n executionIndex,\n taskIndex,\n );\n\n lines.push(imageResult.markdown);\n attachments.push(imageResult.attachment);\n });\n\n return { lines, attachments };\n}\n\nfunction renderExecution(\n executionRaw: ExecutionDump | IExecutionDump,\n executionIndex: number,\n options?: ExecutionMarkdownOptions,\n): ExecutionMarkdownResult {\n const execution = toExecutionDump(executionRaw);\n const screenshotBaseDir = options?.screenshotBaseDir ?? './screenshots';\n\n const lines: string[] = [];\n const attachments: MarkdownAttachment[] = [];\n\n lines.push(`# ${execution.name}`);\n if (execution.description) {\n lines.push('', execution.description);\n }\n\n lines.push('', `- Execution start: ${formatTime(execution.logTime)}`);\n lines.push(`- Task count: ${execution.tasks.length}`);\n\n execution.tasks.forEach((task, taskIndex) => {\n const title = typeStr(task);\n const detail = safeTaskParam(task);\n const time = resolveTaskTiming(task);\n\n lines.push(\n '',\n `## ${taskIndex + 1}. ${title}${detail ? ` - ${detail}` : ''}`,\n );\n lines.push(`- Status: ${task.status || 'unknown'}`);\n lines.push(`- Start: ${formatTime(time.start)}`);\n lines.push(`- End: ${formatTime(time.end)}`);\n lines.push(\n `- Cost(ms): ${typeof time.cost === 'number' ? time.cost : 'N/A'}`,\n );\n lines.push(\n `- Screen size: ${formatSize(task.uiContext?.shotSize) || 'N/A'}`,\n );\n\n if (task.subType === 'Locate') {\n const locateCenter = extractLocateCenter(task);\n if (locateCenter) {\n lines.push(`- Locate center: (${locateCenter[0]}, ${locateCenter[1]})`);\n }\n }\n\n if (task.errorMessage) {\n lines.push(`- Error: ${task.errorMessage}`);\n }\n\n if (task.uiContext?.screenshot) {\n const imageResult = screenshotAttachment(\n task.uiContext.screenshot,\n screenshotBaseDir,\n executionIndex,\n taskIndex,\n );\n\n lines.push(imageResult.markdown);\n attachments.push(imageResult.attachment);\n }\n\n const recorderSection = recorderMarkdownSection(\n task.recorder,\n screenshotBaseDir,\n executionIndex,\n taskIndex,\n );\n if (recorderSection.lines.length) {\n lines.push(...recorderSection.lines);\n attachments.push(...recorderSection.attachments);\n }\n });\n\n return {\n markdown: lines.join('\\n'),\n attachments,\n };\n}\n\nfunction reportFileName(\n execution: IExecutionDump,\n executionIndex: number,\n): string {\n const safeName =\n execution.name\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/[^a-zA-Z0-9-_]/g, '') || `execution-${executionIndex + 1}`;\n return `${executionIndex + 1}-${basename(safeName)}.md`;\n}\n\nexport function executionToMarkdown(\n execution: ExecutionDump | IExecutionDump,\n options?: ExecutionMarkdownOptions,\n): ExecutionMarkdownResult {\n return renderExecution(execution, 0, options);\n}\n\nexport function reportToMarkdown(\n report: ReportActionDump | IReportActionDump,\n): ReportMarkdownResult {\n const reportDump = toReportDump(report);\n\n const executionResults = reportDump.executions.map((execution, index) => {\n const rendered = renderExecution(execution, index);\n return {\n executionIndex: index,\n executionName: execution.name,\n markdown: rendered.markdown,\n attachments: rendered.attachments,\n suggestedFileName: reportFileName(execution, index),\n };\n });\n\n const attachments = executionResults.flatMap((item) => item.attachments);\n\n const header = [\n `# ${reportDump.groupName}`,\n reportDump.groupDescription ? `\\n${reportDump.groupDescription}` : '',\n `\\n- SDK Version: ${reportDump.sdkVersion}`,\n `- Execution count: ${reportDump.executions.length}`,\n '\\n## Suggested execution markdown files',\n ...executionResults.map(\n (item) => `- ${item.suggestedFileName} (${item.executionName})`,\n ),\n ]\n .filter(Boolean)\n .join('\\n');\n\n return {\n markdown: `${header}\\n\\n${executionResults.map((item) => item.markdown).join('\\n\\n---\\n\\n')}`,\n attachments,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","toExecutionDump","execution","Error","Array","toReportDump","report","formatTime","ts","Number","Date","resolveTaskTiming","task","timing","start","end","cost","undefined","safeTaskParam","readable","paramStr","extractInsightParam","formatSize","size","extractLocateCenter","outputCenter","paramLocateCenter","paramCenter","tryExtractBase64","screenshot","s","screenshotAttachment","screenshotBaseDir","executionIndex","taskIndex","ScreenshotItem","ext","suggestedFileName","filePath","ref","normalizeScreenshotRef","base64","id","recorderMarkdownSection","recorder","lines","attachments","item","recorderIndex","imageResult","renderExecution","executionRaw","options","title","typeStr","detail","time","locateCenter","recorderSection","reportFileName","safeName","basename","executionToMarkdown","reportToMarkdown","reportDump","executionResults","index","rendered","header","Boolean"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"report-markdown.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report-markdown.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 { basename } from 'node:path';\nimport { extractInsightParam, paramStr, typeStr } from '@/agent/ui-utils';\nimport { ScreenshotItem } from '@/screenshot-item';\nimport type {\n ExecutionDump,\n ExecutionRecorderItem,\n ExecutionTask,\n IExecutionDump,\n IReportActionDump,\n ReportActionDump,\n} from '@/types';\nimport { normalizeScreenshotRef } from './dump/screenshot-store';\n\nexport interface MarkdownAttachment {\n id: string;\n suggestedFileName: string;\n mimeType?: string;\n filePath: string;\n executionIndex: number;\n taskIndex: number;\n /** Populated when screenshot data is available in memory (e.g. browser context). */\n base64Data?: string;\n}\n\nexport interface ExecutionMarkdownOptions {\n screenshotBaseDir?: string;\n}\n\nexport interface ExecutionMarkdownResult {\n markdown: string;\n attachments: MarkdownAttachment[];\n}\n\nexport interface ReportMarkdownResult {\n markdown: string;\n attachments: MarkdownAttachment[];\n}\n\nfunction toExecutionDump(\n execution: ExecutionDump | IExecutionDump,\n): IExecutionDump {\n if (!execution || typeof execution !== 'object') {\n throw new Error('executionToMarkdown: execution is required');\n }\n\n if (!Array.isArray(execution.tasks)) {\n throw new Error('executionToMarkdown: execution.tasks must be an array');\n }\n\n if (!execution.name) {\n throw new Error('executionToMarkdown: execution.name is required');\n }\n\n return execution;\n}\n\nfunction toReportDump(\n report: ReportActionDump | IReportActionDump,\n): IReportActionDump {\n if (!report || typeof report !== 'object') {\n throw new Error('reportToMarkdown: report is required');\n }\n\n if (!Array.isArray(report.executions)) {\n throw new Error('reportToMarkdown: report.executions must be an array');\n }\n\n return report;\n}\n\nfunction formatTime(ts?: number): string {\n if (typeof ts !== 'number' || Number.isNaN(ts)) {\n return 'N/A';\n }\n return new Date(ts).toISOString();\n}\n\nfunction resolveTaskTiming(task: ExecutionTask): {\n start?: number;\n end?: number;\n cost?: number;\n} {\n const timing = task.timing;\n if (!timing) {\n return {};\n }\n\n const start = timing.start ?? timing.callAiStart ?? timing.callActionStart;\n const end =\n timing.end ??\n timing.callAiEnd ??\n timing.callActionEnd ??\n timing.captureAfterCallingSnapshotEnd;\n const cost =\n timing.cost ??\n (typeof start === 'number' && typeof end === 'number'\n ? end - start\n : undefined);\n\n return { start, end, cost };\n}\n\nfunction safeTaskParam(task: ExecutionTask): string {\n const readable = paramStr(task);\n if (readable) {\n return readable;\n }\n\n if (task.type === 'Insight') {\n return extractInsightParam((task as any).param).content;\n }\n\n return '';\n}\n\nfunction formatSize(\n size?: { width?: number; height?: number } | null,\n): string | undefined {\n if (\n !size ||\n typeof size.width !== 'number' ||\n typeof size.height !== 'number' ||\n Number.isNaN(size.width) ||\n Number.isNaN(size.height)\n ) {\n return undefined;\n }\n\n return `${size.width} x ${size.height}`;\n}\n\nfunction extractLocateCenter(\n task: ExecutionTask,\n): [number, number] | undefined {\n const outputCenter = (task.output as { element?: { center?: unknown } })\n ?.element?.center;\n if (\n Array.isArray(outputCenter) &&\n outputCenter.length >= 2 &&\n typeof outputCenter[0] === 'number' &&\n typeof outputCenter[1] === 'number'\n ) {\n return [outputCenter[0], outputCenter[1]];\n }\n\n const paramLocateCenter = (task.param as { locate?: { center?: unknown } })\n ?.locate?.center;\n if (\n Array.isArray(paramLocateCenter) &&\n paramLocateCenter.length >= 2 &&\n typeof paramLocateCenter[0] === 'number' &&\n typeof paramLocateCenter[1] === 'number'\n ) {\n return [paramLocateCenter[0], paramLocateCenter[1]];\n }\n\n const paramCenter = (task.param as { center?: unknown })?.center;\n if (\n Array.isArray(paramCenter) &&\n paramCenter.length >= 2 &&\n typeof paramCenter[0] === 'number' &&\n typeof paramCenter[1] === 'number'\n ) {\n return [paramCenter[0], paramCenter[1]];\n }\n\n return undefined;\n}\n\nfunction tryExtractBase64(screenshot: unknown): string | undefined {\n if (!screenshot || typeof screenshot !== 'object') return undefined;\n const s = screenshot as Record<string, unknown>;\n if (typeof s.base64 === 'string' && s.base64.length > 0) {\n return s.base64;\n }\n return undefined;\n}\n\nfunction screenshotAttachment(\n screenshot: unknown,\n screenshotBaseDir: string,\n executionIndex: number,\n taskIndex: number,\n): { markdown: string; attachment: MarkdownAttachment } {\n if (screenshot instanceof ScreenshotItem) {\n const ext = screenshot.extension;\n const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${screenshot.id}.${ext}`;\n const filePath = `${screenshotBaseDir}/${suggestedFileName}`;\n return {\n markdown: `\\n`,\n attachment: {\n id: screenshot.id,\n suggestedFileName,\n filePath,\n mimeType: `image/${ext === 'jpeg' ? 'jpeg' : 'png'}`,\n executionIndex,\n taskIndex,\n base64Data: tryExtractBase64(screenshot),\n },\n };\n }\n\n const ref = normalizeScreenshotRef(screenshot);\n if (ref) {\n const ext = ref.mimeType === 'image/jpeg' ? 'jpeg' : 'png';\n const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${ref.id}.${ext}`;\n const filePath = ref.path || `${screenshotBaseDir}/${suggestedFileName}`;\n return {\n markdown: `\\n`,\n attachment: {\n id: ref.id,\n suggestedFileName,\n filePath,\n mimeType: ref.mimeType,\n executionIndex,\n taskIndex,\n base64Data: tryExtractBase64(screenshot),\n },\n };\n }\n\n const base64 = tryExtractBase64(screenshot);\n if (base64) {\n const ext = base64.startsWith('data:image/jpeg') ? 'jpeg' : 'png';\n const id = `restored-${executionIndex + 1}-${taskIndex + 1}`;\n const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${id}.${ext}`;\n const filePath = `${screenshotBaseDir}/${suggestedFileName}`;\n return {\n markdown: `\\n`,\n attachment: {\n id,\n suggestedFileName,\n filePath,\n mimeType: `image/${ext}`,\n executionIndex,\n taskIndex,\n base64Data: base64,\n },\n };\n }\n\n throw new Error(\n `executionToMarkdown: missing screenshot for execution #${executionIndex + 1} task #${taskIndex + 1}`,\n );\n}\n\nfunction recorderMarkdownSection(\n recorder: ExecutionRecorderItem[] | undefined,\n screenshotBaseDir: string,\n executionIndex: number,\n taskIndex: number,\n): { lines: string[]; attachments: MarkdownAttachment[] } {\n if (!recorder?.length) {\n return { lines: [], attachments: [] };\n }\n\n const lines: string[] = ['', '### Recorder'];\n const attachments: MarkdownAttachment[] = [];\n\n recorder.forEach((item, recorderIndex) => {\n lines.push(\n `- #${recorderIndex + 1} type=${item.type}, ts=${formatTime(item.ts)}, timing=${item.timing || 'N/A'}`,\n );\n\n if (!item.screenshot) {\n return;\n }\n\n const imageResult = screenshotAttachment(\n item.screenshot,\n screenshotBaseDir,\n executionIndex,\n taskIndex,\n );\n\n lines.push(imageResult.markdown);\n attachments.push(imageResult.attachment);\n });\n\n return { lines, attachments };\n}\n\nfunction renderExecution(\n executionRaw: ExecutionDump | IExecutionDump,\n executionIndex: number,\n options?: ExecutionMarkdownOptions,\n): ExecutionMarkdownResult {\n const execution = toExecutionDump(executionRaw);\n const screenshotBaseDir = options?.screenshotBaseDir ?? './screenshots';\n\n const lines: string[] = [];\n const attachments: MarkdownAttachment[] = [];\n\n lines.push(`# ${execution.name}`);\n if (execution.description) {\n lines.push('', execution.description);\n }\n\n lines.push('', `- Execution start: ${formatTime(execution.logTime)}`);\n lines.push(`- Task count: ${execution.tasks.length}`);\n\n execution.tasks.forEach((task, taskIndex) => {\n const title = typeStr(task);\n const detail = safeTaskParam(task);\n const time = resolveTaskTiming(task);\n\n lines.push(\n '',\n `## ${taskIndex + 1}. ${title}${detail ? ` - ${detail}` : ''}`,\n );\n lines.push(`- Status: ${task.status || 'unknown'}`);\n lines.push(`- Start: ${formatTime(time.start)}`);\n lines.push(`- End: ${formatTime(time.end)}`);\n lines.push(\n `- Cost(ms): ${typeof time.cost === 'number' ? time.cost : 'N/A'}`,\n );\n lines.push(\n `- Screen size: ${formatSize(task.uiContext?.shotSize) || 'N/A'}`,\n );\n\n if (task.subType === 'Locate') {\n const locateCenter = extractLocateCenter(task);\n if (locateCenter) {\n lines.push(`- Locate center: (${locateCenter[0]}, ${locateCenter[1]})`);\n }\n }\n\n if (task.errorMessage) {\n lines.push(`- Error: ${task.errorMessage}`);\n }\n\n if (task.uiContext?.screenshot) {\n const imageResult = screenshotAttachment(\n task.uiContext.screenshot,\n screenshotBaseDir,\n executionIndex,\n taskIndex,\n );\n\n lines.push(imageResult.markdown);\n attachments.push(imageResult.attachment);\n }\n\n const recorderSection = recorderMarkdownSection(\n task.recorder,\n screenshotBaseDir,\n executionIndex,\n taskIndex,\n );\n if (recorderSection.lines.length) {\n lines.push(...recorderSection.lines);\n attachments.push(...recorderSection.attachments);\n }\n });\n\n return {\n markdown: lines.join('\\n'),\n attachments,\n };\n}\n\nfunction reportFileName(\n execution: IExecutionDump,\n executionIndex: number,\n): string {\n const safeName =\n execution.name\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/[^a-zA-Z0-9-_]/g, '') || `execution-${executionIndex + 1}`;\n return `${executionIndex + 1}-${basename(safeName)}.md`;\n}\n\nexport function executionToMarkdown(\n execution: ExecutionDump | IExecutionDump,\n options?: ExecutionMarkdownOptions,\n): ExecutionMarkdownResult {\n return renderExecution(execution, 0, options);\n}\n\nexport function reportToMarkdown(\n report: ReportActionDump | IReportActionDump,\n): ReportMarkdownResult {\n const reportDump = toReportDump(report);\n\n const executionResults = reportDump.executions.map((execution, index) => {\n const rendered = renderExecution(execution, index);\n return {\n executionIndex: index,\n executionName: execution.name,\n markdown: rendered.markdown,\n attachments: rendered.attachments,\n suggestedFileName: reportFileName(execution, index),\n };\n });\n\n const attachments = executionResults.flatMap((item) => item.attachments);\n\n const header = [\n `# ${reportDump.groupName}`,\n reportDump.groupDescription ? `\\n${reportDump.groupDescription}` : '',\n `\\n- SDK Version: ${reportDump.sdkVersion}`,\n `- Execution count: ${reportDump.executions.length}`,\n '\\n## Suggested execution markdown files',\n ...executionResults.map(\n (item) => `- ${item.suggestedFileName} (${item.executionName})`,\n ),\n ]\n .filter(Boolean)\n .join('\\n');\n\n return {\n markdown: `${header}\\n\\n${executionResults.map((item) => item.markdown).join('\\n\\n---\\n\\n')}`,\n attachments,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","toExecutionDump","execution","Error","Array","toReportDump","report","formatTime","ts","Number","Date","resolveTaskTiming","task","timing","start","end","cost","undefined","safeTaskParam","readable","paramStr","extractInsightParam","formatSize","size","extractLocateCenter","outputCenter","paramLocateCenter","paramCenter","tryExtractBase64","screenshot","s","screenshotAttachment","screenshotBaseDir","executionIndex","taskIndex","ScreenshotItem","ext","suggestedFileName","filePath","ref","normalizeScreenshotRef","base64","id","recorderMarkdownSection","recorder","lines","attachments","item","recorderIndex","imageResult","renderExecution","executionRaw","options","title","typeStr","detail","time","locateCenter","recorderSection","reportFileName","safeName","basename","executionToMarkdown","reportToMarkdown","reportDump","executionResults","index","rendered","header","Boolean"],"mappings":"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"}
|
package/dist/lib/report.js
CHANGED
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -62,6 +62,17 @@ function dedupeExecutionsKeepLatest(executions) {
|
|
|
62
62
|
}
|
|
63
63
|
return Array.from(deduped.values());
|
|
64
64
|
}
|
|
65
|
+
function peekReportSdkVersion(reportFilePath) {
|
|
66
|
+
try {
|
|
67
|
+
const dump = (0, html_utils_js_namespaceObject.extractLastDumpScriptSync)(reportFilePath);
|
|
68
|
+
if (!dump) return;
|
|
69
|
+
const match = dump.match(/"sdkVersion"\s*:\s*"([^"]+)"/);
|
|
70
|
+
return match?.[1];
|
|
71
|
+
} catch {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const warnedMismatchedVersions = new Set();
|
|
65
76
|
class ReportMergingTool {
|
|
66
77
|
createEmptyDumpString(groupName, groupDescription) {
|
|
67
78
|
return new external_types_js_namespaceObject.ReportActionDump({
|
|
@@ -73,6 +84,14 @@ class ReportMergingTool {
|
|
|
73
84
|
}).serialize();
|
|
74
85
|
}
|
|
75
86
|
append(reportInfo) {
|
|
87
|
+
if (reportInfo.reportFilePath) {
|
|
88
|
+
const sourceVersion = peekReportSdkVersion(reportInfo.reportFilePath);
|
|
89
|
+
const currentVersion = (0, external_utils_js_namespaceObject.getVersion)();
|
|
90
|
+
if (sourceVersion && currentVersion && sourceVersion !== currentVersion && !warnedMismatchedVersions.has(sourceVersion)) {
|
|
91
|
+
warnedMismatchedVersions.add(sourceVersion);
|
|
92
|
+
(0, utils_namespaceObject.logMsg)(`[@aiscene/core] ReportMergingTool version mismatch: source report was written by @aiscene/core@${sourceVersion} but the merger is @aiscene/core@${currentVersion}. This commonly means @aiscene/core and the device package (e.g. @aiscene/android) resolve to different versions in node_modules. Merged output may silently drop intermediate steps. Align the versions and reinstall (rm -rf node_modules package-lock.json && npm install).`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
76
95
|
this.reportInfos.push(reportInfo);
|
|
77
96
|
}
|
|
78
97
|
clear() {
|
package/dist/lib/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report.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 appendFileSync,\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport * as path from 'node:path';\nimport { getMidsceneRunSubDir } from '@aiscene/shared/common';\nimport { antiEscapeScriptTag, logMsg } from '@aiscene/shared/utils';\nimport { getReportFileName } from './agent';\nimport {\n extractAllDumpScriptsSync,\n extractLastDumpScriptSync,\n getBaseUrlFixScript,\n streamDumpScriptsSync,\n streamImageScriptsToFile,\n} from './dump/html-utils';\nimport {\n normalizeScreenshotRef,\n resolveScreenshotSource,\n} from './dump/screenshot-store';\nimport {\n type ExecutionDump,\n type IExecutionDump,\n ReportActionDump,\n} from './types';\nimport type { ReportFileWithAttributes } from './types';\nimport { getReportTpl, reportHTMLContent } from './utils';\n\n/**\n * Check if a report is in directory mode (html-and-external-assets).\n * Directory mode reports: {name}/index.html + {name}/screenshots/\n */\nexport function isDirectoryModeReport(reportFilePath: string): boolean {\n const reportDir = path.dirname(reportFilePath);\n return (\n path.basename(reportFilePath) === 'index.html' &&\n existsSync(path.join(reportDir, 'screenshots'))\n );\n}\n\n/**\n * Deduplicate executions by stable id, keeping only the last occurrence.\n * Old-format executions without id are always preserved.\n */\nexport function dedupeExecutionsKeepLatest<T extends Pick<ExecutionDump, 'id'>>(\n executions: T[],\n): T[] {\n let noIdCounter = 0;\n const deduped = new Map<string, T>();\n for (const exec of executions) {\n const key = exec.id || `__no_id_${noIdCounter++}`;\n deduped.set(key, exec);\n }\n return Array.from(deduped.values());\n}\nexport class ReportMergingTool {\n private reportInfos: ReportFileWithAttributes[] = [];\n\n private createEmptyDumpString(groupName: string, groupDescription?: string) {\n return new ReportActionDump({\n sdkVersion: '',\n groupName,\n groupDescription,\n modelBriefs: [],\n executions: [],\n }).serialize();\n }\n\n public append(reportInfo: ReportFileWithAttributes) {\n this.reportInfos.push(reportInfo);\n }\n public clear() {\n this.reportInfos = [];\n }\n\n /**\n * Merge multiple dump script contents (from the same source report)\n * into a single serialized ReportActionDump string.\n * If there's only one dump, return it as-is. If multiple, merge\n * all executions into the first dump's group structure.\n */\n private mergeDumpScripts(contents: string[]): string {\n const unescaped = contents\n .map((c) => antiEscapeScriptTag(c))\n .filter((c) => c.length > 0);\n if (unescaped.length === 0) return '';\n if (unescaped.length === 1) return unescaped[0];\n\n // Parse all dumps and collect executions, deduplicating by id (keep last).\n // Only executions with a stable id are deduped; old-format entries without\n // id are always kept (they may be distinct despite sharing the same name).\n const base = ReportActionDump.fromSerializedString(unescaped[0]);\n const allExecutions = [...base.executions];\n for (let i = 1; i < unescaped.length; i++) {\n const other = ReportActionDump.fromSerializedString(unescaped[i]);\n allExecutions.push(...other.executions);\n }\n base.executions = dedupeExecutionsKeepLatest(allExecutions);\n return base.serialize();\n }\n\n public mergeReports(\n reportFileName: 'AUTO' | string = 'AUTO',\n opts?: {\n rmOriginalReports?: boolean;\n overwrite?: boolean;\n },\n ): string | null {\n const { rmOriginalReports = false, overwrite = false } = opts ?? {};\n\n if (this.reportInfos.length === 0) {\n logMsg('No reports to merge');\n return null;\n }\n\n const targetDir = getMidsceneRunSubDir('report');\n\n // Check if any source report is directory mode\n const hasDirectoryModeReport = this.reportInfos.some((info) => {\n const reportFilePath = info.reportFilePath;\n return Boolean(reportFilePath && isDirectoryModeReport(reportFilePath));\n });\n\n const resolvedName =\n reportFileName === 'AUTO'\n ? getReportFileName('merged-report')\n : reportFileName;\n\n // Directory mode: output as {name}/index.html to keep relative paths working\n // Inline mode: output as {name}.html (single file)\n const outputFilePath = hasDirectoryModeReport\n ? path.resolve(targetDir, resolvedName, 'index.html')\n : path.resolve(targetDir, `${resolvedName}.html`);\n\n if (reportFileName !== 'AUTO' && existsSync(outputFilePath)) {\n if (!overwrite) {\n throw new Error(\n `Report file already exists: ${outputFilePath}\\nSet overwrite to true to overwrite this file.`,\n );\n }\n if (hasDirectoryModeReport) {\n rmSync(path.dirname(outputFilePath), { recursive: true, force: true });\n } else {\n unlinkSync(outputFilePath);\n }\n }\n\n if (hasDirectoryModeReport) {\n mkdirSync(path.dirname(outputFilePath), { recursive: true });\n }\n\n logMsg(\n `Start merging ${this.reportInfos.length} reports...\\nCreating template file...`,\n );\n\n try {\n // Write template without closing </html> tag so we can append\n // dump scripts before it. The closing tag is added at the end.\n const htmlEndTag = '</html>';\n const tpl = getReportTpl();\n const htmlEndIdx = tpl.lastIndexOf(htmlEndTag);\n const tplWithoutClose =\n htmlEndIdx !== -1 ? tpl.slice(0, htmlEndIdx) : tpl;\n appendFileSync(outputFilePath, tplWithoutClose);\n\n // For directory-mode output, inject base URL fix script\n if (hasDirectoryModeReport) {\n appendFileSync(outputFilePath, getBaseUrlFixScript());\n }\n\n // Process all reports one by one\n for (let i = 0; i < this.reportInfos.length; i++) {\n const reportInfo = this.reportInfos[i];\n logMsg(`Processing report ${i + 1}/${this.reportInfos.length}`);\n\n const { reportAttributes } = reportInfo;\n let dumpString = this.createEmptyDumpString(\n reportAttributes.testTitle,\n reportAttributes.testDescription,\n );\n let mergedGroupId = `merged-group-${i}`;\n\n if (reportInfo.reportFilePath) {\n if (isDirectoryModeReport(reportInfo.reportFilePath)) {\n // Directory mode: copy external screenshot files\n const reportDir = path.dirname(reportInfo.reportFilePath);\n const screenshotsDir = path.join(reportDir, 'screenshots');\n const mergedScreenshotsDir = path.join(\n path.dirname(outputFilePath),\n 'screenshots',\n );\n mkdirSync(mergedScreenshotsDir, { recursive: true });\n for (const file of readdirSync(screenshotsDir)) {\n const src = path.join(screenshotsDir, file);\n const dest = path.join(mergedScreenshotsDir, file);\n copyFileSync(src, dest);\n }\n } else {\n // Inline mode: stream image scripts to output file\n streamImageScriptsToFile(reportInfo.reportFilePath, outputFilePath);\n }\n\n // Extract all dump scripts from the source report.\n // After the per-execution append refactor, a single source report\n // may contain multiple <script type=\"midscene_web_dump\"> tags\n // (one per execution). We merge them into a single ReportActionDump.\n // Filter by data-group-id to exclude false matches from the template's\n // bundled JS code, which also references the midscene_web_dump type string.\n const allDumps = extractAllDumpScriptsSync(\n reportInfo.reportFilePath,\n ).filter((d) => d.openTag.includes('data-group-id'));\n const groupIdMatch = allDumps[0]?.openTag.match(\n /data-group-id=\"([^\"]+)\"/,\n );\n if (groupIdMatch) {\n mergedGroupId = decodeURIComponent(groupIdMatch[1]);\n }\n const extractedDumpString =\n allDumps.length > 0\n ? this.mergeDumpScripts(allDumps.map((d) => d.content))\n : extractLastDumpScriptSync(reportInfo.reportFilePath);\n if (extractedDumpString) {\n dumpString = extractedDumpString;\n }\n }\n\n const reportHtmlStr = `${reportHTMLContent(\n {\n dumpString,\n attributes: {\n 'data-group-id': mergedGroupId,\n playwright_test_duration: reportAttributes.testDuration,\n playwright_test_status: reportAttributes.testStatus,\n playwright_test_title: reportAttributes.testTitle,\n playwright_test_id: reportAttributes.testId,\n playwright_test_description: reportAttributes.testDescription,\n is_merged: true,\n },\n },\n undefined,\n undefined,\n false,\n )}\\n`;\n\n appendFileSync(outputFilePath, reportHtmlStr);\n }\n\n // Close the HTML document\n appendFileSync(outputFilePath, `${htmlEndTag}\\n`);\n\n logMsg(`Successfully merged new report: ${outputFilePath}`);\n\n // Remove original reports if needed\n if (rmOriginalReports) {\n for (const info of this.reportInfos) {\n if (!info.reportFilePath) continue;\n try {\n if (isDirectoryModeReport(info.reportFilePath)) {\n // Directory mode: remove the entire report directory\n const reportDir = path.dirname(info.reportFilePath);\n rmSync(reportDir, { recursive: true, force: true });\n } else {\n unlinkSync(info.reportFilePath);\n }\n } catch (error) {\n logMsg(`Error deleting report ${info.reportFilePath}: ${error}`);\n }\n }\n logMsg(`Removed ${this.reportInfos.length} original reports`);\n }\n return outputFilePath;\n } catch (error) {\n logMsg(`Error in mergeReports: ${error}`);\n throw error;\n }\n }\n}\n\nexport interface SplitReportHtmlOptions {\n htmlPath: string;\n outputDir: string;\n}\n\nexport interface SplitReportHtmlResult {\n executionJsonFiles: string[];\n screenshotFiles: string[];\n}\n\nexport interface CollectedReportExecutions {\n baseDump: ReportActionDump;\n executions: IExecutionDump[];\n}\n\n/**\n * Collect executions from a report HTML, deduplicating by stable id while\n * keeping only the latest occurrence. Old-format executions without id are\n * always preserved.\n */\nexport function collectDedupedExecutions(\n htmlPath: string,\n): CollectedReportExecutions {\n let baseDump: ReportActionDump | null = null;\n let executionSerial = 0;\n const latestSerialByExecutionId = new Map<string, number>();\n\n streamDumpScriptsSync(htmlPath, (dumpScript) => {\n if (!dumpScript.openTag.includes('data-group-id')) {\n return false;\n }\n const groupedDump = ReportActionDump.fromSerializedString(\n antiEscapeScriptTag(dumpScript.content),\n );\n for (const execution of groupedDump.executions) {\n executionSerial += 1;\n if (execution.id) {\n latestSerialByExecutionId.set(execution.id, executionSerial);\n }\n }\n return false;\n });\n\n const executions: IExecutionDump[] = [];\n executionSerial = 0;\n streamDumpScriptsSync(htmlPath, (dumpScript) => {\n if (!dumpScript.openTag.includes('data-group-id')) {\n return false;\n }\n\n const groupedDump = ReportActionDump.fromSerializedString(\n antiEscapeScriptTag(dumpScript.content),\n );\n if (!baseDump) {\n baseDump = groupedDump;\n }\n\n for (const execution of groupedDump.executions) {\n executionSerial += 1;\n if (\n execution.id &&\n latestSerialByExecutionId.get(execution.id) !== executionSerial\n ) {\n continue;\n }\n executions.push(execution);\n }\n\n return false;\n });\n\n if (!baseDump) {\n throw new Error(`No report dump scripts found in ${htmlPath}`);\n }\n\n return {\n baseDump,\n executions,\n };\n}\n\nfunction extensionByMimeType(mimeType: string): 'png' | 'jpeg' {\n if (mimeType === 'image/png') return 'png';\n if (mimeType === 'image/jpeg') return 'jpeg';\n throw new Error(`Unsupported screenshot mime type: ${mimeType}`);\n}\n\nfunction externalizeScreenshotsInExecution(\n execution: IExecutionDump,\n opts: {\n htmlPath: string;\n screenshotsDir: string;\n writtenFiles: Set<string>;\n },\n): void {\n const visit = (node: unknown): void => {\n if (Array.isArray(node)) {\n for (const item of node) {\n visit(item);\n }\n return;\n }\n\n if (typeof node !== 'object' || node === null) return;\n\n const ref = normalizeScreenshotRef(node);\n if (ref) {\n const ext = extensionByMimeType(ref.mimeType);\n const fileName = `${ref.id}.${ext}`;\n const relativePath = `./screenshots/${fileName}`;\n const absolutePath = path.join(opts.screenshotsDir, fileName);\n\n if (!opts.writtenFiles.has(fileName)) {\n const resolved = resolveScreenshotSource(ref, {\n reportPath: opts.htmlPath,\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 } else {\n copyFileSync(resolved.filePath, absolutePath);\n }\n opts.writtenFiles.add(fileName);\n }\n\n ref.storage = 'file';\n ref.path = relativePath;\n return;\n }\n\n for (const value of Object.values(node)) {\n visit(value);\n }\n };\n\n visit(execution);\n}\n\n/**\n * Reverse parse a Midscene report HTML into per-execution JSON files and\n * externalized screenshots.\n */\nexport function splitReportHtmlByExecution(\n options: SplitReportHtmlOptions,\n): SplitReportHtmlResult {\n const { htmlPath, outputDir } = options;\n const screenshotsDir = path.join(outputDir, 'screenshots');\n\n mkdirSync(outputDir, { recursive: true });\n mkdirSync(screenshotsDir, { recursive: true });\n\n const executionJsonFiles: string[] = [];\n const writtenScreenshotFiles = new Set<string>();\n const { baseDump, executions } = collectDedupedExecutions(htmlPath);\n\n let fileIndex = 0;\n for (const execution of executions) {\n fileIndex += 1;\n externalizeScreenshotsInExecution(execution, {\n htmlPath,\n screenshotsDir,\n writtenFiles: writtenScreenshotFiles,\n });\n const singleExecutionDump = new ReportActionDump({\n sdkVersion: baseDump.sdkVersion,\n groupName: baseDump.groupName,\n groupDescription: baseDump.groupDescription,\n modelBriefs: baseDump.modelBriefs,\n deviceType: baseDump.deviceType,\n executions: [execution],\n });\n\n const jsonFilePath = path.join(outputDir, `${fileIndex}.execution.json`);\n writeFileSync(jsonFilePath, singleExecutionDump.serialize(2), 'utf-8');\n executionJsonFiles.push(jsonFilePath);\n }\n\n return {\n executionJsonFiles,\n screenshotFiles: Array.from(writtenScreenshotFiles)\n .sort()\n .map((fileName) => path.join(screenshotsDir, fileName)),\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","isDirectoryModeReport","reportFilePath","reportDir","path","existsSync","dedupeExecutionsKeepLatest","executions","noIdCounter","deduped","Map","exec","Array","ReportMergingTool","groupName","groupDescription","ReportActionDump","reportInfo","contents","unescaped","c","antiEscapeScriptTag","base","allExecutions","i","other","reportFileName","opts","rmOriginalReports","overwrite","logMsg","targetDir","getMidsceneRunSubDir","hasDirectoryModeReport","info","Boolean","resolvedName","getReportFileName","outputFilePath","Error","rmSync","unlinkSync","mkdirSync","htmlEndTag","tpl","getReportTpl","htmlEndIdx","tplWithoutClose","appendFileSync","getBaseUrlFixScript","reportAttributes","dumpString","mergedGroupId","screenshotsDir","mergedScreenshotsDir","file","readdirSync","src","dest","copyFileSync","streamImageScriptsToFile","allDumps","extractAllDumpScriptsSync","d","groupIdMatch","decodeURIComponent","extractedDumpString","extractLastDumpScriptSync","reportHtmlStr","reportHTMLContent","undefined","error","collectDedupedExecutions","htmlPath","baseDump","executionSerial","latestSerialByExecutionId","streamDumpScriptsSync","dumpScript","groupedDump","execution","extensionByMimeType","mimeType","externalizeScreenshotsInExecution","visit","node","item","ref","normalizeScreenshotRef","ext","fileName","relativePath","absolutePath","resolved","resolveScreenshotSource","rawBase64","writeFileSync","Buffer","value","splitReportHtmlByExecution","options","outputDir","executionJsonFiles","writtenScreenshotFiles","Set","fileIndex","singleExecutionDump","jsonFilePath"],"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC+BO,SAASI,sBAAsBC,cAAsB;IAC1D,MAAMC,YAAYC,mCAAAA,OAAY,CAACF;IAC/B,OACEE,AAAkC,iBAAlCA,mCAAAA,QAAa,CAACF,mBACdG,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWD,mCAAAA,IAAS,CAACD,WAAW;AAEpC;AAMO,SAASG,2BACdC,UAAe;IAEf,IAAIC,cAAc;IAClB,MAAMC,UAAU,IAAIC;IACpB,KAAK,MAAMC,QAAQJ,WAAY;QAC7B,MAAMX,MAAMe,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAEH,eAAe;QACjDC,QAAQ,GAAG,CAACb,KAAKe;IACnB;IACA,OAAOC,MAAM,IAAI,CAACH,QAAQ,MAAM;AAClC;AACO,MAAMI;IAGH,sBAAsBC,SAAiB,EAAEC,gBAAyB,EAAE;QAC1E,OAAO,IAAIC,kCAAAA,gBAAgBA,CAAC;YAC1B,YAAY;YACZF;YACAC;YACA,aAAa,EAAE;YACf,YAAY,EAAE;QAChB,GAAG,SAAS;IACd;IAEO,OAAOE,UAAoC,EAAE;QAClD,IAAI,CAAC,WAAW,CAAC,IAAI,CAACA;IACxB;IACO,QAAQ;QACb,IAAI,CAAC,WAAW,GAAG,EAAE;IACvB;IAQQ,iBAAiBC,QAAkB,EAAU;QACnD,MAAMC,YAAYD,SACf,GAAG,CAAC,CAACE,IAAMC,AAAAA,IAAAA,sBAAAA,mBAAAA,AAAAA,EAAoBD,IAC/B,MAAM,CAAC,CAACA,IAAMA,EAAE,MAAM,GAAG;QAC5B,IAAID,AAAqB,MAArBA,UAAU,MAAM,EAAQ,OAAO;QACnC,IAAIA,AAAqB,MAArBA,UAAU,MAAM,EAAQ,OAAOA,SAAS,CAAC,EAAE;QAK/C,MAAMG,OAAON,kCAAAA,gBAAAA,CAAAA,oBAAqC,CAACG,SAAS,CAAC,EAAE;QAC/D,MAAMI,gBAAgB;eAAID,KAAK,UAAU;SAAC;QAC1C,IAAK,IAAIE,IAAI,GAAGA,IAAIL,UAAU,MAAM,EAAEK,IAAK;YACzC,MAAMC,QAAQT,kCAAAA,gBAAAA,CAAAA,oBAAqC,CAACG,SAAS,CAACK,EAAE;YAChED,cAAc,IAAI,IAAIE,MAAM,UAAU;QACxC;QACAH,KAAK,UAAU,GAAGhB,2BAA2BiB;QAC7C,OAAOD,KAAK,SAAS;IACvB;IAEO,aACLI,iBAAkC,MAAM,EACxCC,IAGC,EACc;QACf,MAAM,EAAEC,oBAAoB,KAAK,EAAEC,YAAY,KAAK,EAAE,GAAGF,QAAQ,CAAC;QAElE,IAAI,AAA4B,MAA5B,IAAI,CAAC,WAAW,CAAC,MAAM,EAAQ;YACjCG,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO;YACP,OAAO;QACT;QAEA,MAAMC,YAAYC,AAAAA,IAAAA,uBAAAA,oBAAAA,AAAAA,EAAqB;QAGvC,MAAMC,yBAAyB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAACC;YACpD,MAAMhC,iBAAiBgC,KAAK,cAAc;YAC1C,OAAOC,QAAQjC,kBAAkBD,sBAAsBC;QACzD;QAEA,MAAMkC,eACJV,AAAmB,WAAnBA,iBACIW,AAAAA,IAAAA,yBAAAA,iBAAAA,AAAAA,EAAkB,mBAClBX;QAIN,MAAMY,iBAAiBL,yBACnB7B,mCAAAA,OAAY,CAAC2B,WAAWK,cAAc,gBACtChC,mCAAAA,OAAY,CAAC2B,WAAW,GAAGK,aAAa,KAAK,CAAC;QAElD,IAAIV,AAAmB,WAAnBA,kBAA6BrB,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWiC,iBAAiB;YAC3D,IAAI,CAACT,WACH,MAAM,IAAIU,MACR,CAAC,4BAA4B,EAAED,eAAe,+CAA+C,CAAC;YAGlG,IAAIL,wBACFO,AAAAA,IAAAA,iCAAAA,MAAAA,AAAAA,EAAOpC,mCAAAA,OAAY,CAACkC,iBAAiB;gBAAE,WAAW;gBAAM,OAAO;YAAK;iBAEpEG,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWH;QAEf;QAEA,IAAIL,wBACFS,AAAAA,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUtC,mCAAAA,OAAY,CAACkC,iBAAiB;YAAE,WAAW;QAAK;QAG5DR,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,CAAC,cAAc,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,sCAAsC,CAAC;QAGlF,IAAI;YAGF,MAAMa,aAAa;YACnB,MAAMC,MAAMC,AAAAA,IAAAA,kCAAAA,YAAAA,AAAAA;YACZ,MAAMC,aAAaF,IAAI,WAAW,CAACD;YACnC,MAAMI,kBACJD,AAAe,OAAfA,aAAoBF,IAAI,KAAK,CAAC,GAAGE,cAAcF;YACjDI,IAAAA,iCAAAA,cAAAA,AAAAA,EAAeV,gBAAgBS;YAG/B,IAAId,wBACFe,AAAAA,IAAAA,iCAAAA,cAAAA,AAAAA,EAAeV,gBAAgBW,AAAAA,IAAAA,8BAAAA,mBAAAA,AAAAA;YAIjC,IAAK,IAAIzB,IAAI,GAAGA,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAEA,IAAK;gBAChD,MAAMP,aAAa,IAAI,CAAC,WAAW,CAACO,EAAE;gBACtCM,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,kBAAkB,EAAEN,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;gBAE9D,MAAM,EAAE0B,gBAAgB,EAAE,GAAGjC;gBAC7B,IAAIkC,aAAa,IAAI,CAAC,qBAAqB,CACzCD,iBAAiB,SAAS,EAC1BA,iBAAiB,eAAe;gBAElC,IAAIE,gBAAgB,CAAC,aAAa,EAAE5B,GAAG;gBAEvC,IAAIP,WAAW,cAAc,EAAE;oBAC7B,IAAIhB,sBAAsBgB,WAAW,cAAc,GAAG;wBAEpD,MAAMd,YAAYC,mCAAAA,OAAY,CAACa,WAAW,cAAc;wBACxD,MAAMoC,iBAAiBjD,mCAAAA,IAAS,CAACD,WAAW;wBAC5C,MAAMmD,uBAAuBlD,mCAAAA,IAAS,CACpCA,mCAAAA,OAAY,CAACkC,iBACb;wBAEFI,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUY,sBAAsB;4BAAE,WAAW;wBAAK;wBAClD,KAAK,MAAMC,QAAQC,AAAAA,IAAAA,iCAAAA,WAAAA,AAAAA,EAAYH,gBAAiB;4BAC9C,MAAMI,MAAMrD,mCAAAA,IAAS,CAACiD,gBAAgBE;4BACtC,MAAMG,OAAOtD,mCAAAA,IAAS,CAACkD,sBAAsBC;4BAC7CI,IAAAA,iCAAAA,YAAAA,AAAAA,EAAaF,KAAKC;wBACpB;oBACF,OAEEE,AAAAA,IAAAA,8BAAAA,wBAAAA,AAAAA,EAAyB3C,WAAW,cAAc,EAAEqB;oBAStD,MAAMuB,WAAWC,AAAAA,IAAAA,8BAAAA,yBAAAA,AAAAA,EACf7C,WAAW,cAAc,EACzB,MAAM,CAAC,CAAC8C,IAAMA,EAAE,OAAO,CAAC,QAAQ,CAAC;oBACnC,MAAMC,eAAeH,QAAQ,CAAC,EAAE,EAAE,QAAQ,MACxC;oBAEF,IAAIG,cACFZ,gBAAgBa,mBAAmBD,YAAY,CAAC,EAAE;oBAEpD,MAAME,sBACJL,SAAS,MAAM,GAAG,IACd,IAAI,CAAC,gBAAgB,CAACA,SAAS,GAAG,CAAC,CAACE,IAAMA,EAAE,OAAO,KACnDI,AAAAA,IAAAA,8BAAAA,yBAAAA,AAAAA,EAA0BlD,WAAW,cAAc;oBACzD,IAAIiD,qBACFf,aAAae;gBAEjB;gBAEA,MAAME,gBAAgB,GAAGC,AAAAA,IAAAA,kCAAAA,iBAAAA,AAAAA,EACvB;oBACElB;oBACA,YAAY;wBACV,iBAAiBC;wBACjB,0BAA0BF,iBAAiB,YAAY;wBACvD,wBAAwBA,iBAAiB,UAAU;wBACnD,uBAAuBA,iBAAiB,SAAS;wBACjD,oBAAoBA,iBAAiB,MAAM;wBAC3C,6BAA6BA,iBAAiB,eAAe;wBAC7D,WAAW;oBACb;gBACF,GACAoB,QACAA,QACA,OACA,EAAE,CAAC;gBAELtB,IAAAA,iCAAAA,cAAAA,AAAAA,EAAeV,gBAAgB8B;YACjC;YAGApB,IAAAA,iCAAAA,cAAAA,AAAAA,EAAeV,gBAAgB,GAAGK,WAAW,EAAE,CAAC;YAEhDb,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,gCAAgC,EAAEQ,gBAAgB;YAG1D,IAAIV,mBAAmB;gBACrB,KAAK,MAAMM,QAAQ,IAAI,CAAC,WAAW,CACjC,IAAKA,KAAK,cAAc,EACxB,IAAI;oBACF,IAAIjC,sBAAsBiC,KAAK,cAAc,GAAG;wBAE9C,MAAM/B,YAAYC,mCAAAA,OAAY,CAAC8B,KAAK,cAAc;wBAClDM,IAAAA,iCAAAA,MAAAA,AAAAA,EAAOrC,WAAW;4BAAE,WAAW;4BAAM,OAAO;wBAAK;oBACnD,OACEsC,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWP,KAAK,cAAc;gBAElC,EAAE,OAAOqC,OAAO;oBACdzC,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,sBAAsB,EAAEI,KAAK,cAAc,CAAC,EAAE,EAAEqC,OAAO;gBACjE;gBAEFzC,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,CAAC;YAC9D;YACA,OAAOQ;QACT,EAAE,OAAOiC,OAAO;YACdzC,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,uBAAuB,EAAEyC,OAAO;YACxC,MAAMA;QACR;IACF;;QA3NA,uBAAQ,eAA0C,EAAE;;AA4NtD;AAsBO,SAASC,yBACdC,QAAgB;IAEhB,IAAIC,WAAoC;IACxC,IAAIC,kBAAkB;IACtB,MAAMC,4BAA4B,IAAIlE;IAEtCmE,IAAAA,8BAAAA,qBAAAA,AAAAA,EAAsBJ,UAAU,CAACK;QAC/B,IAAI,CAACA,WAAW,OAAO,CAAC,QAAQ,CAAC,kBAC/B,OAAO;QAET,MAAMC,cAAc/D,kCAAAA,gBAAAA,CAAAA,oBAAqC,CACvDK,AAAAA,IAAAA,sBAAAA,mBAAAA,AAAAA,EAAoByD,WAAW,OAAO;QAExC,KAAK,MAAME,aAAaD,YAAY,UAAU,CAAE;YAC9CJ,mBAAmB;YACnB,IAAIK,UAAU,EAAE,EACdJ,0BAA0B,GAAG,CAACI,UAAU,EAAE,EAAEL;QAEhD;QACA,OAAO;IACT;IAEA,MAAMpE,aAA+B,EAAE;IACvCoE,kBAAkB;IAClBE,IAAAA,8BAAAA,qBAAAA,AAAAA,EAAsBJ,UAAU,CAACK;QAC/B,IAAI,CAACA,WAAW,OAAO,CAAC,QAAQ,CAAC,kBAC/B,OAAO;QAGT,MAAMC,cAAc/D,kCAAAA,gBAAAA,CAAAA,oBAAqC,CACvDK,AAAAA,IAAAA,sBAAAA,mBAAAA,AAAAA,EAAoByD,WAAW,OAAO;QAExC,IAAI,CAACJ,UACHA,WAAWK;QAGb,KAAK,MAAMC,aAAaD,YAAY,UAAU,CAAE;YAC9CJ,mBAAmB;YACnB,IACEK,CAAAA,UAAU,EAAE,IACZJ,0BAA0B,GAAG,CAACI,UAAU,EAAE,MAAML,iBAIlDpE,WAAW,IAAI,CAACyE;QAClB;QAEA,OAAO;IACT;IAEA,IAAI,CAACN,UACH,MAAM,IAAInC,MAAM,CAAC,gCAAgC,EAAEkC,UAAU;IAG/D,OAAO;QACLC;QACAnE;IACF;AACF;AAEA,SAAS0E,oBAAoBC,QAAgB;IAC3C,IAAIA,AAAa,gBAAbA,UAA0B,OAAO;IACrC,IAAIA,AAAa,iBAAbA,UAA2B,OAAO;IACtC,MAAM,IAAI3C,MAAM,CAAC,kCAAkC,EAAE2C,UAAU;AACjE;AAEA,SAASC,kCACPH,SAAyB,EACzBrD,IAIC;IAED,MAAMyD,QAAQ,CAACC;QACb,IAAIzE,MAAM,OAAO,CAACyE,OAAO;YACvB,KAAK,MAAMC,QAAQD,KACjBD,MAAME;YAER;QACF;QAEA,IAAI,AAAgB,YAAhB,OAAOD,QAAqBA,AAAS,SAATA,MAAe;QAE/C,MAAME,MAAMC,AAAAA,IAAAA,oCAAAA,sBAAAA,AAAAA,EAAuBH;QACnC,IAAIE,KAAK;YACP,MAAME,MAAMR,oBAAoBM,IAAI,QAAQ;YAC5C,MAAMG,WAAW,GAAGH,IAAI,EAAE,CAAC,CAAC,EAAEE,KAAK;YACnC,MAAME,eAAe,CAAC,cAAc,EAAED,UAAU;YAChD,MAAME,eAAexF,mCAAAA,IAAS,CAACuB,KAAK,cAAc,EAAE+D;YAEpD,IAAI,CAAC/D,KAAK,YAAY,CAAC,GAAG,CAAC+D,WAAW;gBACpC,MAAMG,WAAWC,AAAAA,IAAAA,oCAAAA,uBAAAA,AAAAA,EAAwBP,KAAK;oBAC5C,YAAY5D,KAAK,QAAQ;gBAC3B;gBACA,IAAIkE,AAAkB,eAAlBA,SAAS,IAAI,EAAiB;oBAChC,MAAME,YAAYF,SAAS,OAAO,CAAC,OAAO,CACxC,mCACA;oBAEFG,IAAAA,iCAAAA,aAAAA,AAAAA,EAAcJ,cAAcK,OAAO,IAAI,CAACF,WAAW;gBACrD,OACEpC,AAAAA,IAAAA,iCAAAA,YAAAA,AAAAA,EAAakC,SAAS,QAAQ,EAAED;gBAElCjE,KAAK,YAAY,CAAC,GAAG,CAAC+D;YACxB;YAEAH,IAAI,OAAO,GAAG;YACdA,IAAI,IAAI,GAAGI;YACX;QACF;QAEA,KAAK,MAAMO,SAASrG,OAAO,MAAM,CAACwF,MAChCD,MAAMc;IAEV;IAEAd,MAAMJ;AACR;AAMO,SAASmB,2BACdC,OAA+B;IAE/B,MAAM,EAAE3B,QAAQ,EAAE4B,SAAS,EAAE,GAAGD;IAChC,MAAM/C,iBAAiBjD,mCAAAA,IAAS,CAACiG,WAAW;IAE5C3D,IAAAA,iCAAAA,SAAAA,AAAAA,EAAU2D,WAAW;QAAE,WAAW;IAAK;IACvC3D,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUW,gBAAgB;QAAE,WAAW;IAAK;IAE5C,MAAMiD,qBAA+B,EAAE;IACvC,MAAMC,yBAAyB,IAAIC;IACnC,MAAM,EAAE9B,QAAQ,EAAEnE,UAAU,EAAE,GAAGiE,yBAAyBC;IAE1D,IAAIgC,YAAY;IAChB,KAAK,MAAMzB,aAAazE,WAAY;QAClCkG,aAAa;QACbtB,kCAAkCH,WAAW;YAC3CP;YACApB;YACA,cAAckD;QAChB;QACA,MAAMG,sBAAsB,IAAI1F,kCAAAA,gBAAgBA,CAAC;YAC/C,YAAY0D,SAAS,UAAU;YAC/B,WAAWA,SAAS,SAAS;YAC7B,kBAAkBA,SAAS,gBAAgB;YAC3C,aAAaA,SAAS,WAAW;YACjC,YAAYA,SAAS,UAAU;YAC/B,YAAY;gBAACM;aAAU;QACzB;QAEA,MAAM2B,eAAevG,mCAAAA,IAAS,CAACiG,WAAW,GAAGI,UAAU,eAAe,CAAC;QACvET,IAAAA,iCAAAA,aAAAA,AAAAA,EAAcW,cAAcD,oBAAoB,SAAS,CAAC,IAAI;QAC9DJ,mBAAmB,IAAI,CAACK;IAC1B;IAEA,OAAO;QACLL;QACA,iBAAiB1F,MAAM,IAAI,CAAC2F,wBACzB,IAAI,GACJ,GAAG,CAAC,CAACb,WAAatF,mCAAAA,IAAS,CAACiD,gBAAgBqC;IACjD;AACF"}
|
|
1
|
+
{"version":3,"file":"report.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report.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 appendFileSync,\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport * as path from 'node:path';\nimport { getMidsceneRunSubDir } from '@aiscene/shared/common';\nimport { antiEscapeScriptTag, logMsg } from '@aiscene/shared/utils';\nimport { getReportFileName } from './agent';\nimport {\n extractAllDumpScriptsSync,\n extractLastDumpScriptSync,\n getBaseUrlFixScript,\n streamDumpScriptsSync,\n streamImageScriptsToFile,\n} from './dump/html-utils';\nimport {\n normalizeScreenshotRef,\n resolveScreenshotSource,\n} from './dump/screenshot-store';\nimport {\n type ExecutionDump,\n type IExecutionDump,\n ReportActionDump,\n} from './types';\nimport type { ReportFileWithAttributes } from './types';\nimport { getReportTpl, getVersion, reportHTMLContent } from './utils';\n\n/**\n * Check if a report is in directory mode (html-and-external-assets).\n * Directory mode reports: {name}/index.html + {name}/screenshots/\n */\nexport function isDirectoryModeReport(reportFilePath: string): boolean {\n const reportDir = path.dirname(reportFilePath);\n return (\n path.basename(reportFilePath) === 'index.html' &&\n existsSync(path.join(reportDir, 'screenshots'))\n );\n}\n\n/**\n * Deduplicate executions by stable id, keeping only the last occurrence.\n * Old-format executions without id are always preserved.\n */\nexport function dedupeExecutionsKeepLatest<T extends Pick<ExecutionDump, 'id'>>(\n executions: T[],\n): T[] {\n let noIdCounter = 0;\n const deduped = new Map<string, T>();\n for (const exec of executions) {\n const key = exec.id || `__no_id_${noIdCounter++}`;\n deduped.set(key, exec);\n }\n return Array.from(deduped.values());\n}\n/**\n * Peek at the first `sdkVersion` field embedded in a midscene_web_dump\n * script tag inside the given report file. Returns undefined if no\n * recognizable tag or sdkVersion is present.\n */\nfunction peekReportSdkVersion(reportFilePath: string): string | undefined {\n try {\n const dump = extractLastDumpScriptSync(reportFilePath);\n if (!dump) return undefined;\n const match = dump.match(/\"sdkVersion\"\\s*:\\s*\"([^\"]+)\"/);\n return match?.[1];\n } catch {\n return undefined;\n }\n}\n\nconst warnedMismatchedVersions = new Set<string>();\n\nexport class ReportMergingTool {\n private reportInfos: ReportFileWithAttributes[] = [];\n\n private createEmptyDumpString(groupName: string, groupDescription?: string) {\n return new ReportActionDump({\n sdkVersion: '',\n groupName,\n groupDescription,\n modelBriefs: [],\n executions: [],\n }).serialize();\n }\n\n public append(reportInfo: ReportFileWithAttributes) {\n if (reportInfo.reportFilePath) {\n const sourceVersion = peekReportSdkVersion(reportInfo.reportFilePath);\n const currentVersion = getVersion();\n if (\n sourceVersion &&\n currentVersion &&\n sourceVersion !== currentVersion &&\n !warnedMismatchedVersions.has(sourceVersion)\n ) {\n warnedMismatchedVersions.add(sourceVersion);\n logMsg(\n `[@aiscene/core] ReportMergingTool version mismatch: source report was written by @aiscene/core@${sourceVersion} but the merger is @aiscene/core@${currentVersion}. This commonly means @aiscene/core and the device package (e.g. @aiscene/android) resolve to different versions in node_modules. Merged output may silently drop intermediate steps. Align the versions and reinstall (rm -rf node_modules package-lock.json && npm install).`,\n );\n }\n }\n this.reportInfos.push(reportInfo);\n }\n public clear() {\n this.reportInfos = [];\n }\n\n /**\n * Merge multiple dump script contents (from the same source report)\n * into a single serialized ReportActionDump string.\n * If there's only one dump, return it as-is. If multiple, merge\n * all executions into the first dump's group structure.\n */\n private mergeDumpScripts(contents: string[]): string {\n const unescaped = contents\n .map((c) => antiEscapeScriptTag(c))\n .filter((c) => c.length > 0);\n if (unescaped.length === 0) return '';\n if (unescaped.length === 1) return unescaped[0];\n\n // Parse all dumps and collect executions, deduplicating by id (keep last).\n // Only executions with a stable id are deduped; old-format entries without\n // id are always kept (they may be distinct despite sharing the same name).\n const base = ReportActionDump.fromSerializedString(unescaped[0]);\n const allExecutions = [...base.executions];\n for (let i = 1; i < unescaped.length; i++) {\n const other = ReportActionDump.fromSerializedString(unescaped[i]);\n allExecutions.push(...other.executions);\n }\n base.executions = dedupeExecutionsKeepLatest(allExecutions);\n return base.serialize();\n }\n\n public mergeReports(\n reportFileName: 'AUTO' | string = 'AUTO',\n opts?: {\n rmOriginalReports?: boolean;\n overwrite?: boolean;\n },\n ): string | null {\n const { rmOriginalReports = false, overwrite = false } = opts ?? {};\n\n if (this.reportInfos.length === 0) {\n logMsg('No reports to merge');\n return null;\n }\n\n const targetDir = getMidsceneRunSubDir('report');\n\n // Check if any source report is directory mode\n const hasDirectoryModeReport = this.reportInfos.some((info) => {\n const reportFilePath = info.reportFilePath;\n return Boolean(reportFilePath && isDirectoryModeReport(reportFilePath));\n });\n\n const resolvedName =\n reportFileName === 'AUTO'\n ? getReportFileName('merged-report')\n : reportFileName;\n\n // Directory mode: output as {name}/index.html to keep relative paths working\n // Inline mode: output as {name}.html (single file)\n const outputFilePath = hasDirectoryModeReport\n ? path.resolve(targetDir, resolvedName, 'index.html')\n : path.resolve(targetDir, `${resolvedName}.html`);\n\n if (reportFileName !== 'AUTO' && existsSync(outputFilePath)) {\n if (!overwrite) {\n throw new Error(\n `Report file already exists: ${outputFilePath}\\nSet overwrite to true to overwrite this file.`,\n );\n }\n if (hasDirectoryModeReport) {\n rmSync(path.dirname(outputFilePath), { recursive: true, force: true });\n } else {\n unlinkSync(outputFilePath);\n }\n }\n\n if (hasDirectoryModeReport) {\n mkdirSync(path.dirname(outputFilePath), { recursive: true });\n }\n\n logMsg(\n `Start merging ${this.reportInfos.length} reports...\\nCreating template file...`,\n );\n\n try {\n // Write template without closing </html> tag so we can append\n // dump scripts before it. The closing tag is added at the end.\n const htmlEndTag = '</html>';\n const tpl = getReportTpl();\n const htmlEndIdx = tpl.lastIndexOf(htmlEndTag);\n const tplWithoutClose =\n htmlEndIdx !== -1 ? tpl.slice(0, htmlEndIdx) : tpl;\n appendFileSync(outputFilePath, tplWithoutClose);\n\n // For directory-mode output, inject base URL fix script\n if (hasDirectoryModeReport) {\n appendFileSync(outputFilePath, getBaseUrlFixScript());\n }\n\n // Process all reports one by one\n for (let i = 0; i < this.reportInfos.length; i++) {\n const reportInfo = this.reportInfos[i];\n logMsg(`Processing report ${i + 1}/${this.reportInfos.length}`);\n\n const { reportAttributes } = reportInfo;\n let dumpString = this.createEmptyDumpString(\n reportAttributes.testTitle,\n reportAttributes.testDescription,\n );\n let mergedGroupId = `merged-group-${i}`;\n\n if (reportInfo.reportFilePath) {\n if (isDirectoryModeReport(reportInfo.reportFilePath)) {\n // Directory mode: copy external screenshot files\n const reportDir = path.dirname(reportInfo.reportFilePath);\n const screenshotsDir = path.join(reportDir, 'screenshots');\n const mergedScreenshotsDir = path.join(\n path.dirname(outputFilePath),\n 'screenshots',\n );\n mkdirSync(mergedScreenshotsDir, { recursive: true });\n for (const file of readdirSync(screenshotsDir)) {\n const src = path.join(screenshotsDir, file);\n const dest = path.join(mergedScreenshotsDir, file);\n copyFileSync(src, dest);\n }\n } else {\n // Inline mode: stream image scripts to output file\n streamImageScriptsToFile(reportInfo.reportFilePath, outputFilePath);\n }\n\n // Extract all dump scripts from the source report.\n // After the per-execution append refactor, a single source report\n // may contain multiple <script type=\"midscene_web_dump\"> tags\n // (one per execution). We merge them into a single ReportActionDump.\n // Filter by data-group-id to exclude false matches from the template's\n // bundled JS code, which also references the midscene_web_dump type string.\n const allDumps = extractAllDumpScriptsSync(\n reportInfo.reportFilePath,\n ).filter((d) => d.openTag.includes('data-group-id'));\n const groupIdMatch = allDumps[0]?.openTag.match(\n /data-group-id=\"([^\"]+)\"/,\n );\n if (groupIdMatch) {\n mergedGroupId = decodeURIComponent(groupIdMatch[1]);\n }\n const extractedDumpString =\n allDumps.length > 0\n ? this.mergeDumpScripts(allDumps.map((d) => d.content))\n : extractLastDumpScriptSync(reportInfo.reportFilePath);\n if (extractedDumpString) {\n dumpString = extractedDumpString;\n }\n }\n\n const reportHtmlStr = `${reportHTMLContent(\n {\n dumpString,\n attributes: {\n 'data-group-id': mergedGroupId,\n playwright_test_duration: reportAttributes.testDuration,\n playwright_test_status: reportAttributes.testStatus,\n playwright_test_title: reportAttributes.testTitle,\n playwright_test_id: reportAttributes.testId,\n playwright_test_description: reportAttributes.testDescription,\n is_merged: true,\n },\n },\n undefined,\n undefined,\n false,\n )}\\n`;\n\n appendFileSync(outputFilePath, reportHtmlStr);\n }\n\n // Close the HTML document\n appendFileSync(outputFilePath, `${htmlEndTag}\\n`);\n\n logMsg(`Successfully merged new report: ${outputFilePath}`);\n\n // Remove original reports if needed\n if (rmOriginalReports) {\n for (const info of this.reportInfos) {\n if (!info.reportFilePath) continue;\n try {\n if (isDirectoryModeReport(info.reportFilePath)) {\n // Directory mode: remove the entire report directory\n const reportDir = path.dirname(info.reportFilePath);\n rmSync(reportDir, { recursive: true, force: true });\n } else {\n unlinkSync(info.reportFilePath);\n }\n } catch (error) {\n logMsg(`Error deleting report ${info.reportFilePath}: ${error}`);\n }\n }\n logMsg(`Removed ${this.reportInfos.length} original reports`);\n }\n return outputFilePath;\n } catch (error) {\n logMsg(`Error in mergeReports: ${error}`);\n throw error;\n }\n }\n}\n\nexport interface SplitReportHtmlOptions {\n htmlPath: string;\n outputDir: string;\n}\n\nexport interface SplitReportHtmlResult {\n executionJsonFiles: string[];\n screenshotFiles: string[];\n}\n\nexport interface CollectedReportExecutions {\n baseDump: ReportActionDump;\n executions: IExecutionDump[];\n}\n\n/**\n * Collect executions from a report HTML, deduplicating by stable id while\n * keeping only the latest occurrence. Old-format executions without id are\n * always preserved.\n */\nexport function collectDedupedExecutions(\n htmlPath: string,\n): CollectedReportExecutions {\n let baseDump: ReportActionDump | null = null;\n let executionSerial = 0;\n const latestSerialByExecutionId = new Map<string, number>();\n\n streamDumpScriptsSync(htmlPath, (dumpScript) => {\n if (!dumpScript.openTag.includes('data-group-id')) {\n return false;\n }\n const groupedDump = ReportActionDump.fromSerializedString(\n antiEscapeScriptTag(dumpScript.content),\n );\n for (const execution of groupedDump.executions) {\n executionSerial += 1;\n if (execution.id) {\n latestSerialByExecutionId.set(execution.id, executionSerial);\n }\n }\n return false;\n });\n\n const executions: IExecutionDump[] = [];\n executionSerial = 0;\n streamDumpScriptsSync(htmlPath, (dumpScript) => {\n if (!dumpScript.openTag.includes('data-group-id')) {\n return false;\n }\n\n const groupedDump = ReportActionDump.fromSerializedString(\n antiEscapeScriptTag(dumpScript.content),\n );\n if (!baseDump) {\n baseDump = groupedDump;\n }\n\n for (const execution of groupedDump.executions) {\n executionSerial += 1;\n if (\n execution.id &&\n latestSerialByExecutionId.get(execution.id) !== executionSerial\n ) {\n continue;\n }\n executions.push(execution);\n }\n\n return false;\n });\n\n if (!baseDump) {\n throw new Error(`No report dump scripts found in ${htmlPath}`);\n }\n\n return {\n baseDump,\n executions,\n };\n}\n\nfunction extensionByMimeType(mimeType: string): 'png' | 'jpeg' {\n if (mimeType === 'image/png') return 'png';\n if (mimeType === 'image/jpeg') return 'jpeg';\n throw new Error(`Unsupported screenshot mime type: ${mimeType}`);\n}\n\nfunction externalizeScreenshotsInExecution(\n execution: IExecutionDump,\n opts: {\n htmlPath: string;\n screenshotsDir: string;\n writtenFiles: Set<string>;\n },\n): void {\n const visit = (node: unknown): void => {\n if (Array.isArray(node)) {\n for (const item of node) {\n visit(item);\n }\n return;\n }\n\n if (typeof node !== 'object' || node === null) return;\n\n const ref = normalizeScreenshotRef(node);\n if (ref) {\n const ext = extensionByMimeType(ref.mimeType);\n const fileName = `${ref.id}.${ext}`;\n const relativePath = `./screenshots/${fileName}`;\n const absolutePath = path.join(opts.screenshotsDir, fileName);\n\n if (!opts.writtenFiles.has(fileName)) {\n const resolved = resolveScreenshotSource(ref, {\n reportPath: opts.htmlPath,\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 } else {\n copyFileSync(resolved.filePath, absolutePath);\n }\n opts.writtenFiles.add(fileName);\n }\n\n ref.storage = 'file';\n ref.path = relativePath;\n return;\n }\n\n for (const value of Object.values(node)) {\n visit(value);\n }\n };\n\n visit(execution);\n}\n\n/**\n * Reverse parse a Midscene report HTML into per-execution JSON files and\n * externalized screenshots.\n */\nexport function splitReportHtmlByExecution(\n options: SplitReportHtmlOptions,\n): SplitReportHtmlResult {\n const { htmlPath, outputDir } = options;\n const screenshotsDir = path.join(outputDir, 'screenshots');\n\n mkdirSync(outputDir, { recursive: true });\n mkdirSync(screenshotsDir, { recursive: true });\n\n const executionJsonFiles: string[] = [];\n const writtenScreenshotFiles = new Set<string>();\n const { baseDump, executions } = collectDedupedExecutions(htmlPath);\n\n let fileIndex = 0;\n for (const execution of executions) {\n fileIndex += 1;\n externalizeScreenshotsInExecution(execution, {\n htmlPath,\n screenshotsDir,\n writtenFiles: writtenScreenshotFiles,\n });\n const singleExecutionDump = new ReportActionDump({\n sdkVersion: baseDump.sdkVersion,\n groupName: baseDump.groupName,\n groupDescription: baseDump.groupDescription,\n modelBriefs: baseDump.modelBriefs,\n deviceType: baseDump.deviceType,\n executions: [execution],\n });\n\n const jsonFilePath = path.join(outputDir, `${fileIndex}.execution.json`);\n writeFileSync(jsonFilePath, singleExecutionDump.serialize(2), 'utf-8');\n executionJsonFiles.push(jsonFilePath);\n }\n\n return {\n executionJsonFiles,\n screenshotFiles: Array.from(writtenScreenshotFiles)\n .sort()\n .map((fileName) => path.join(screenshotsDir, fileName)),\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","isDirectoryModeReport","reportFilePath","reportDir","path","existsSync","dedupeExecutionsKeepLatest","executions","noIdCounter","deduped","Map","exec","Array","peekReportSdkVersion","dump","extractLastDumpScriptSync","match","warnedMismatchedVersions","Set","ReportMergingTool","groupName","groupDescription","ReportActionDump","reportInfo","sourceVersion","currentVersion","getVersion","logMsg","contents","unescaped","c","antiEscapeScriptTag","base","allExecutions","i","other","reportFileName","opts","rmOriginalReports","overwrite","targetDir","getMidsceneRunSubDir","hasDirectoryModeReport","info","Boolean","resolvedName","getReportFileName","outputFilePath","Error","rmSync","unlinkSync","mkdirSync","htmlEndTag","tpl","getReportTpl","htmlEndIdx","tplWithoutClose","appendFileSync","getBaseUrlFixScript","reportAttributes","dumpString","mergedGroupId","screenshotsDir","mergedScreenshotsDir","file","readdirSync","src","dest","copyFileSync","streamImageScriptsToFile","allDumps","extractAllDumpScriptsSync","d","groupIdMatch","decodeURIComponent","extractedDumpString","reportHtmlStr","reportHTMLContent","undefined","error","collectDedupedExecutions","htmlPath","baseDump","executionSerial","latestSerialByExecutionId","streamDumpScriptsSync","dumpScript","groupedDump","execution","extensionByMimeType","mimeType","externalizeScreenshotsInExecution","visit","node","item","ref","normalizeScreenshotRef","ext","fileName","relativePath","absolutePath","resolved","resolveScreenshotSource","rawBase64","writeFileSync","Buffer","value","splitReportHtmlByExecution","options","outputDir","executionJsonFiles","writtenScreenshotFiles","fileIndex","singleExecutionDump","jsonFilePath"],"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,MAAlB,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC+BO,SAASI,sBAAsBC,cAAsB;IAC1D,MAAMC,YAAYC,mCAAAA,OAAY,CAACF;IAC/B,OACEE,AAAkC,iBAAlCA,mCAAAA,QAAa,CAACF,mBACdG,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWD,mCAAAA,IAAS,CAACD,WAAW;AAEpC;AAMO,SAASG,2BACdC,UAAe;IAEf,IAAIC,cAAc;IAClB,MAAMC,UAAU,IAAIC;IACpB,KAAK,MAAMC,QAAQJ,WAAY;QAC7B,MAAMX,MAAMe,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAEH,eAAe;QACjDC,QAAQ,GAAG,CAACb,KAAKe;IACnB;IACA,OAAOC,MAAM,IAAI,CAACH,QAAQ,MAAM;AAClC;AAMA,SAASI,qBAAqBX,cAAsB;IAClD,IAAI;QACF,MAAMY,OAAOC,AAAAA,IAAAA,8BAAAA,yBAAAA,AAAAA,EAA0Bb;QACvC,IAAI,CAACY,MAAM;QACX,MAAME,QAAQF,KAAK,KAAK,CAAC;QACzB,OAAOE,OAAO,CAAC,EAAE;IACnB,EAAE,OAAM;QACN;IACF;AACF;AAEA,MAAMC,2BAA2B,IAAIC;AAE9B,MAAMC;IAGH,sBAAsBC,SAAiB,EAAEC,gBAAyB,EAAE;QAC1E,OAAO,IAAIC,kCAAAA,gBAAgBA,CAAC;YAC1B,YAAY;YACZF;YACAC;YACA,aAAa,EAAE;YACf,YAAY,EAAE;QAChB,GAAG,SAAS;IACd;IAEO,OAAOE,UAAoC,EAAE;QAClD,IAAIA,WAAW,cAAc,EAAE;YAC7B,MAAMC,gBAAgBX,qBAAqBU,WAAW,cAAc;YACpE,MAAME,iBAAiBC,AAAAA,IAAAA,kCAAAA,UAAAA,AAAAA;YACvB,IACEF,iBACAC,kBACAD,kBAAkBC,kBAClB,CAACR,yBAAyB,GAAG,CAACO,gBAC9B;gBACAP,yBAAyB,GAAG,CAACO;gBAC7BG,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,CAAC,+FAA+F,EAAEH,cAAc,iCAAiC,EAAEC,eAAe,8QAA8Q,CAAC;YAErb;QACF;QACA,IAAI,CAAC,WAAW,CAAC,IAAI,CAACF;IACxB;IACO,QAAQ;QACb,IAAI,CAAC,WAAW,GAAG,EAAE;IACvB;IAQQ,iBAAiBK,QAAkB,EAAU;QACnD,MAAMC,YAAYD,SACf,GAAG,CAAC,CAACE,IAAMC,AAAAA,IAAAA,sBAAAA,mBAAAA,AAAAA,EAAoBD,IAC/B,MAAM,CAAC,CAACA,IAAMA,EAAE,MAAM,GAAG;QAC5B,IAAID,AAAqB,MAArBA,UAAU,MAAM,EAAQ,OAAO;QACnC,IAAIA,AAAqB,MAArBA,UAAU,MAAM,EAAQ,OAAOA,SAAS,CAAC,EAAE;QAK/C,MAAMG,OAAOV,kCAAAA,gBAAAA,CAAAA,oBAAqC,CAACO,SAAS,CAAC,EAAE;QAC/D,MAAMI,gBAAgB;eAAID,KAAK,UAAU;SAAC;QAC1C,IAAK,IAAIE,IAAI,GAAGA,IAAIL,UAAU,MAAM,EAAEK,IAAK;YACzC,MAAMC,QAAQb,kCAAAA,gBAAAA,CAAAA,oBAAqC,CAACO,SAAS,CAACK,EAAE;YAChED,cAAc,IAAI,IAAIE,MAAM,UAAU;QACxC;QACAH,KAAK,UAAU,GAAG1B,2BAA2B2B;QAC7C,OAAOD,KAAK,SAAS;IACvB;IAEO,aACLI,iBAAkC,MAAM,EACxCC,IAGC,EACc;QACf,MAAM,EAAEC,oBAAoB,KAAK,EAAEC,YAAY,KAAK,EAAE,GAAGF,QAAQ,CAAC;QAElE,IAAI,AAA4B,MAA5B,IAAI,CAAC,WAAW,CAAC,MAAM,EAAQ;YACjCV,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO;YACP,OAAO;QACT;QAEA,MAAMa,YAAYC,AAAAA,IAAAA,uBAAAA,oBAAAA,AAAAA,EAAqB;QAGvC,MAAMC,yBAAyB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAACC;YACpD,MAAMzC,iBAAiByC,KAAK,cAAc;YAC1C,OAAOC,QAAQ1C,kBAAkBD,sBAAsBC;QACzD;QAEA,MAAM2C,eACJT,AAAmB,WAAnBA,iBACIU,AAAAA,IAAAA,yBAAAA,iBAAAA,AAAAA,EAAkB,mBAClBV;QAIN,MAAMW,iBAAiBL,yBACnBtC,mCAAAA,OAAY,CAACoC,WAAWK,cAAc,gBACtCzC,mCAAAA,OAAY,CAACoC,WAAW,GAAGK,aAAa,KAAK,CAAC;QAElD,IAAIT,AAAmB,WAAnBA,kBAA6B/B,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAW0C,iBAAiB;YAC3D,IAAI,CAACR,WACH,MAAM,IAAIS,MACR,CAAC,4BAA4B,EAAED,eAAe,+CAA+C,CAAC;YAGlG,IAAIL,wBACFO,AAAAA,IAAAA,iCAAAA,MAAAA,AAAAA,EAAO7C,mCAAAA,OAAY,CAAC2C,iBAAiB;gBAAE,WAAW;gBAAM,OAAO;YAAK;iBAEpEG,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWH;QAEf;QAEA,IAAIL,wBACFS,AAAAA,IAAAA,iCAAAA,SAAAA,AAAAA,EAAU/C,mCAAAA,OAAY,CAAC2C,iBAAiB;YAAE,WAAW;QAAK;QAG5DpB,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,CAAC,cAAc,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,sCAAsC,CAAC;QAGlF,IAAI;YAGF,MAAMyB,aAAa;YACnB,MAAMC,MAAMC,AAAAA,IAAAA,kCAAAA,YAAAA,AAAAA;YACZ,MAAMC,aAAaF,IAAI,WAAW,CAACD;YACnC,MAAMI,kBACJD,AAAe,OAAfA,aAAoBF,IAAI,KAAK,CAAC,GAAGE,cAAcF;YACjDI,IAAAA,iCAAAA,cAAAA,AAAAA,EAAeV,gBAAgBS;YAG/B,IAAId,wBACFe,AAAAA,IAAAA,iCAAAA,cAAAA,AAAAA,EAAeV,gBAAgBW,AAAAA,IAAAA,8BAAAA,mBAAAA,AAAAA;YAIjC,IAAK,IAAIxB,IAAI,GAAGA,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAEA,IAAK;gBAChD,MAAMX,aAAa,IAAI,CAAC,WAAW,CAACW,EAAE;gBACtCP,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,kBAAkB,EAAEO,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;gBAE9D,MAAM,EAAEyB,gBAAgB,EAAE,GAAGpC;gBAC7B,IAAIqC,aAAa,IAAI,CAAC,qBAAqB,CACzCD,iBAAiB,SAAS,EAC1BA,iBAAiB,eAAe;gBAElC,IAAIE,gBAAgB,CAAC,aAAa,EAAE3B,GAAG;gBAEvC,IAAIX,WAAW,cAAc,EAAE;oBAC7B,IAAItB,sBAAsBsB,WAAW,cAAc,GAAG;wBAEpD,MAAMpB,YAAYC,mCAAAA,OAAY,CAACmB,WAAW,cAAc;wBACxD,MAAMuC,iBAAiB1D,mCAAAA,IAAS,CAACD,WAAW;wBAC5C,MAAM4D,uBAAuB3D,mCAAAA,IAAS,CACpCA,mCAAAA,OAAY,CAAC2C,iBACb;wBAEFI,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUY,sBAAsB;4BAAE,WAAW;wBAAK;wBAClD,KAAK,MAAMC,QAAQC,AAAAA,IAAAA,iCAAAA,WAAAA,AAAAA,EAAYH,gBAAiB;4BAC9C,MAAMI,MAAM9D,mCAAAA,IAAS,CAAC0D,gBAAgBE;4BACtC,MAAMG,OAAO/D,mCAAAA,IAAS,CAAC2D,sBAAsBC;4BAC7CI,IAAAA,iCAAAA,YAAAA,AAAAA,EAAaF,KAAKC;wBACpB;oBACF,OAEEE,AAAAA,IAAAA,8BAAAA,wBAAAA,AAAAA,EAAyB9C,WAAW,cAAc,EAAEwB;oBAStD,MAAMuB,WAAWC,AAAAA,IAAAA,8BAAAA,yBAAAA,AAAAA,EACfhD,WAAW,cAAc,EACzB,MAAM,CAAC,CAACiD,IAAMA,EAAE,OAAO,CAAC,QAAQ,CAAC;oBACnC,MAAMC,eAAeH,QAAQ,CAAC,EAAE,EAAE,QAAQ,MACxC;oBAEF,IAAIG,cACFZ,gBAAgBa,mBAAmBD,YAAY,CAAC,EAAE;oBAEpD,MAAME,sBACJL,SAAS,MAAM,GAAG,IACd,IAAI,CAAC,gBAAgB,CAACA,SAAS,GAAG,CAAC,CAACE,IAAMA,EAAE,OAAO,KACnDzD,AAAAA,IAAAA,8BAAAA,yBAAAA,AAAAA,EAA0BQ,WAAW,cAAc;oBACzD,IAAIoD,qBACFf,aAAae;gBAEjB;gBAEA,MAAMC,gBAAgB,GAAGC,AAAAA,IAAAA,kCAAAA,iBAAAA,AAAAA,EACvB;oBACEjB;oBACA,YAAY;wBACV,iBAAiBC;wBACjB,0BAA0BF,iBAAiB,YAAY;wBACvD,wBAAwBA,iBAAiB,UAAU;wBACnD,uBAAuBA,iBAAiB,SAAS;wBACjD,oBAAoBA,iBAAiB,MAAM;wBAC3C,6BAA6BA,iBAAiB,eAAe;wBAC7D,WAAW;oBACb;gBACF,GACAmB,QACAA,QACA,OACA,EAAE,CAAC;gBAELrB,IAAAA,iCAAAA,cAAAA,AAAAA,EAAeV,gBAAgB6B;YACjC;YAGAnB,IAAAA,iCAAAA,cAAAA,AAAAA,EAAeV,gBAAgB,GAAGK,WAAW,EAAE,CAAC;YAEhDzB,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,gCAAgC,EAAEoB,gBAAgB;YAG1D,IAAIT,mBAAmB;gBACrB,KAAK,MAAMK,QAAQ,IAAI,CAAC,WAAW,CACjC,IAAKA,KAAK,cAAc,EACxB,IAAI;oBACF,IAAI1C,sBAAsB0C,KAAK,cAAc,GAAG;wBAE9C,MAAMxC,YAAYC,mCAAAA,OAAY,CAACuC,KAAK,cAAc;wBAClDM,IAAAA,iCAAAA,MAAAA,AAAAA,EAAO9C,WAAW;4BAAE,WAAW;4BAAM,OAAO;wBAAK;oBACnD,OACE+C,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWP,KAAK,cAAc;gBAElC,EAAE,OAAOoC,OAAO;oBACdpD,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,sBAAsB,EAAEgB,KAAK,cAAc,CAAC,EAAE,EAAEoC,OAAO;gBACjE;gBAEFpD,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,CAAC;YAC9D;YACA,OAAOoB;QACT,EAAE,OAAOgC,OAAO;YACdpD,IAAAA,sBAAAA,MAAAA,AAAAA,EAAO,CAAC,uBAAuB,EAAEoD,OAAO;YACxC,MAAMA;QACR;IACF;;QA1OA,uBAAQ,eAA0C,EAAE;;AA2OtD;AAsBO,SAASC,yBACdC,QAAgB;IAEhB,IAAIC,WAAoC;IACxC,IAAIC,kBAAkB;IACtB,MAAMC,4BAA4B,IAAI1E;IAEtC2E,IAAAA,8BAAAA,qBAAAA,AAAAA,EAAsBJ,UAAU,CAACK;QAC/B,IAAI,CAACA,WAAW,OAAO,CAAC,QAAQ,CAAC,kBAC/B,OAAO;QAET,MAAMC,cAAcjE,kCAAAA,gBAAAA,CAAAA,oBAAqC,CACvDS,AAAAA,IAAAA,sBAAAA,mBAAAA,AAAAA,EAAoBuD,WAAW,OAAO;QAExC,KAAK,MAAME,aAAaD,YAAY,UAAU,CAAE;YAC9CJ,mBAAmB;YACnB,IAAIK,UAAU,EAAE,EACdJ,0BAA0B,GAAG,CAACI,UAAU,EAAE,EAAEL;QAEhD;QACA,OAAO;IACT;IAEA,MAAM5E,aAA+B,EAAE;IACvC4E,kBAAkB;IAClBE,IAAAA,8BAAAA,qBAAAA,AAAAA,EAAsBJ,UAAU,CAACK;QAC/B,IAAI,CAACA,WAAW,OAAO,CAAC,QAAQ,CAAC,kBAC/B,OAAO;QAGT,MAAMC,cAAcjE,kCAAAA,gBAAAA,CAAAA,oBAAqC,CACvDS,AAAAA,IAAAA,sBAAAA,mBAAAA,AAAAA,EAAoBuD,WAAW,OAAO;QAExC,IAAI,CAACJ,UACHA,WAAWK;QAGb,KAAK,MAAMC,aAAaD,YAAY,UAAU,CAAE;YAC9CJ,mBAAmB;YACnB,IACEK,CAAAA,UAAU,EAAE,IACZJ,0BAA0B,GAAG,CAACI,UAAU,EAAE,MAAML,iBAIlD5E,WAAW,IAAI,CAACiF;QAClB;QAEA,OAAO;IACT;IAEA,IAAI,CAACN,UACH,MAAM,IAAIlC,MAAM,CAAC,gCAAgC,EAAEiC,UAAU;IAG/D,OAAO;QACLC;QACA3E;IACF;AACF;AAEA,SAASkF,oBAAoBC,QAAgB;IAC3C,IAAIA,AAAa,gBAAbA,UAA0B,OAAO;IACrC,IAAIA,AAAa,iBAAbA,UAA2B,OAAO;IACtC,MAAM,IAAI1C,MAAM,CAAC,kCAAkC,EAAE0C,UAAU;AACjE;AAEA,SAASC,kCACPH,SAAyB,EACzBnD,IAIC;IAED,MAAMuD,QAAQ,CAACC;QACb,IAAIjF,MAAM,OAAO,CAACiF,OAAO;YACvB,KAAK,MAAMC,QAAQD,KACjBD,MAAME;YAER;QACF;QAEA,IAAI,AAAgB,YAAhB,OAAOD,QAAqBA,AAAS,SAATA,MAAe;QAE/C,MAAME,MAAMC,AAAAA,IAAAA,oCAAAA,sBAAAA,AAAAA,EAAuBH;QACnC,IAAIE,KAAK;YACP,MAAME,MAAMR,oBAAoBM,IAAI,QAAQ;YAC5C,MAAMG,WAAW,GAAGH,IAAI,EAAE,CAAC,CAAC,EAAEE,KAAK;YACnC,MAAME,eAAe,CAAC,cAAc,EAAED,UAAU;YAChD,MAAME,eAAehG,mCAAAA,IAAS,CAACiC,KAAK,cAAc,EAAE6D;YAEpD,IAAI,CAAC7D,KAAK,YAAY,CAAC,GAAG,CAAC6D,WAAW;gBACpC,MAAMG,WAAWC,AAAAA,IAAAA,oCAAAA,uBAAAA,AAAAA,EAAwBP,KAAK;oBAC5C,YAAY1D,KAAK,QAAQ;gBAC3B;gBACA,IAAIgE,AAAkB,eAAlBA,SAAS,IAAI,EAAiB;oBAChC,MAAME,YAAYF,SAAS,OAAO,CAAC,OAAO,CACxC,mCACA;oBAEFG,IAAAA,iCAAAA,aAAAA,AAAAA,EAAcJ,cAAcK,OAAO,IAAI,CAACF,WAAW;gBACrD,OACEnC,AAAAA,IAAAA,iCAAAA,YAAAA,AAAAA,EAAaiC,SAAS,QAAQ,EAAED;gBAElC/D,KAAK,YAAY,CAAC,GAAG,CAAC6D;YACxB;YAEAH,IAAI,OAAO,GAAG;YACdA,IAAI,IAAI,GAAGI;YACX;QACF;QAEA,KAAK,MAAMO,SAAS7G,OAAO,MAAM,CAACgG,MAChCD,MAAMc;IAEV;IAEAd,MAAMJ;AACR;AAMO,SAASmB,2BACdC,OAA+B;IAE/B,MAAM,EAAE3B,QAAQ,EAAE4B,SAAS,EAAE,GAAGD;IAChC,MAAM9C,iBAAiB1D,mCAAAA,IAAS,CAACyG,WAAW;IAE5C1D,IAAAA,iCAAAA,SAAAA,AAAAA,EAAU0D,WAAW;QAAE,WAAW;IAAK;IACvC1D,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUW,gBAAgB;QAAE,WAAW;IAAK;IAE5C,MAAMgD,qBAA+B,EAAE;IACvC,MAAMC,yBAAyB,IAAI7F;IACnC,MAAM,EAAEgE,QAAQ,EAAE3E,UAAU,EAAE,GAAGyE,yBAAyBC;IAE1D,IAAI+B,YAAY;IAChB,KAAK,MAAMxB,aAAajF,WAAY;QAClCyG,aAAa;QACbrB,kCAAkCH,WAAW;YAC3CP;YACAnB;YACA,cAAciD;QAChB;QACA,MAAME,sBAAsB,IAAI3F,kCAAAA,gBAAgBA,CAAC;YAC/C,YAAY4D,SAAS,UAAU;YAC/B,WAAWA,SAAS,SAAS;YAC7B,kBAAkBA,SAAS,gBAAgB;YAC3C,aAAaA,SAAS,WAAW;YACjC,YAAYA,SAAS,UAAU;YAC/B,YAAY;gBAACM;aAAU;QACzB;QAEA,MAAM0B,eAAe9G,mCAAAA,IAAS,CAACyG,WAAW,GAAGG,UAAU,eAAe,CAAC;QACvER,IAAAA,iCAAAA,aAAAA,AAAAA,EAAcU,cAAcD,oBAAoB,SAAS,CAAC,IAAI;QAC9DH,mBAAmB,IAAI,CAACI;IAC1B;IAEA,OAAO;QACLJ;QACA,iBAAiBlG,MAAM,IAAI,CAACmG,wBACzB,IAAI,GACJ,GAAG,CAAC,CAACb,WAAa9F,mCAAAA,IAAS,CAAC0D,gBAAgBoC;IACjD;AACF"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ("u" > 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":"screenshot-item.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/screenshot-item.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 { readFileSync } from 'node:fs';\nimport { uuid } from '@aiscene/shared/utils';\nimport { extractImageByIdSync } from './dump/html-utils';\nimport {\n type ScreenshotRef,\n normalizeScreenshotRef,\n} from './dump/screenshot-store';\n\n/**\n * Serialization format for ScreenshotItem\n * - { $screenshot: \"id\" } - inline mode, references imageMap in HTML\n * - { base64: \"path\" } - directory mode, references external file path\n */\nexport type ScreenshotSerializeFormat = ScreenshotRef;\n\n/**\n * Detect image format from base64 data URI prefix.\n */\nfunction detectFormat(base64: string): 'png' | 'jpeg' {\n if (base64.startsWith('data:image/jpeg')) return 'jpeg';\n if (base64.startsWith('data:image/jpg')) return 'jpeg';\n return 'png';\n}\n\n/**\n * ScreenshotItem encapsulates screenshot data.\n *\n * Supports lazy loading after memory release:\n * - inline mode: reads from HTML file using streaming (extractImageByIdSync)\n * - directory mode: reads from file on disk\n *\n * After persistence, memory is released but the screenshot can be recovered\n * on-demand from disk, making it safe to release memory at any time.\n */\nexport class ScreenshotItem {\n private _id: string;\n private _base64: string | null;\n private _format: 'png' | 'jpeg';\n private _capturedAt: number;\n private _serializedRef: ScreenshotRef | null = null;\n private _persistedPath: string | null = null;\n private _persistedHtmlPath: string | null = null;\n\n private constructor(id: string, base64: string, capturedAt: number) {\n this._id = id;\n this._base64 = base64;\n this._format = detectFormat(base64);\n this._capturedAt = capturedAt;\n }\n\n /** Create a new ScreenshotItem from base64 data */\n static create(base64: string, capturedAt: number): ScreenshotItem {\n return new ScreenshotItem(uuid(), base64, capturedAt);\n }\n\n get id(): string {\n return this._id;\n }\n\n /** Get the image format (png or jpeg) */\n get format(): 'png' | 'jpeg' {\n return this._format;\n }\n\n /** Get the file extension for this screenshot */\n get extension(): string {\n return this._format === 'jpeg' ? 'jpeg' : 'png';\n }\n\n /** Get screenshot capture timestamp in milliseconds */\n get capturedAt(): number {\n return this._capturedAt;\n }\n\n get base64(): string {\n // If data is in memory, return it directly\n if (this._base64 !== null) {\n return this._base64;\n }\n\n const loadFromFile = (): string => {\n if (this._persistedPath === null) {\n throw new Error(`Screenshot ${this._id}: file recovery path missing`);\n }\n const buffer = readFileSync(this._persistedPath);\n return `data:image/${this._format};base64,${buffer.toString('base64')}`;\n };\n\n const loadFromInline = (): string => {\n if (this._persistedHtmlPath === null) {\n throw new Error(`Screenshot ${this._id}: HTML recovery path missing`);\n }\n const data = extractImageByIdSync(this._persistedHtmlPath, this._id);\n if (data) {\n return data;\n }\n throw new Error(\n `Screenshot ${this._id}: cannot recover from HTML (id not found in ${this._persistedHtmlPath})`,\n );\n };\n\n // Recover from the primary serialized mode first.\n if (this._serializedRef?.storage === 'file') {\n return loadFromFile();\n }\n\n if (this._serializedRef?.storage === 'inline') {\n return loadFromInline();\n }\n\n // Fall back to whichever recovery path is available.\n if (this._persistedPath !== null) {\n return loadFromFile();\n }\n\n if (this._persistedHtmlPath !== null) {\n return loadFromInline();\n }\n\n throw new Error(\n `Screenshot ${this._id}: base64 data released without recovery path`,\n );\n }\n\n /** Check if base64 data is still available in memory (not yet released) */\n hasBase64(): boolean {\n return this._base64 !== null;\n }\n\n /**\n * Mark as persisted to HTML (inline mode).\n * Releases base64 memory, but keeps HTML path for lazy loading recovery.\n * @param htmlPath - absolute path to the HTML file containing the image\n */\n markPersistedInline(htmlPath: string): ScreenshotRef {\n const ref = this.createRef('inline');\n this._serializedRef = ref;\n this._persistedHtmlPath = htmlPath;\n this._base64 = null;\n return ref;\n }\n\n /**\n * Register a file-backed recovery path without changing the serialized mode.\n * Used when inline persistence also needs a shared file copy next to dumps.\n */\n registerPersistedFileCopy(\n relativePath: string,\n absolutePath: string,\n ): ScreenshotRef {\n const ref = this.createRef('file', relativePath);\n this._persistedPath = absolutePath;\n this._base64 = null;\n return ref;\n }\n\n /**\n * Mark as persisted to file (directory mode).\n * Releases base64 memory, but keeps file path for lazy loading recovery.\n * @param relativePath - relative path for serialization (e.g., \"./screenshots/id.jpeg\")\n * @param absolutePath - absolute path for lazy loading recovery\n */\n markPersistedToPath(\n relativePath: string,\n absolutePath: string,\n ): ScreenshotRef {\n const ref = this.registerPersistedFileCopy(relativePath, absolutePath);\n this._serializedRef = ref;\n return ref;\n }\n\n /** Serialize for JSON - format depends on persistence state */\n toSerializable(): ScreenshotSerializeFormat {\n return (\n this._serializedRef ?? {\n type: 'midscene_screenshot_ref',\n id: this._id,\n capturedAt: this._capturedAt,\n mimeType: this._format === 'jpeg' ? 'image/jpeg' : 'image/png',\n storage: 'inline',\n }\n );\n }\n\n /** Check if a value is a serialized ScreenshotItem reference (inline or directory mode) */\n static isSerialized(value: unknown): value is ScreenshotSerializeFormat {\n return normalizeScreenshotRef(value) !== null;\n }\n\n private createRef(\n storage: 'inline' | 'file',\n relativePath?: string,\n ): ScreenshotRef {\n const baseRef: Omit<ScreenshotRef, 'path'> = {\n type: 'midscene_screenshot_ref',\n id: this._id,\n capturedAt: this._capturedAt,\n mimeType: this._format === 'jpeg' ? 'image/jpeg' : 'image/png',\n storage,\n };\n if (storage === 'file') {\n return {\n ...baseRef,\n storage,\n path: relativePath!,\n };\n }\n return baseRef;\n }\n\n /**\n * Get base64 data without the data URI prefix.\n * Useful for writing raw binary data to files.\n */\n get rawBase64(): string {\n return this.base64.replace(/^data:image\\/(png|jpeg|jpg);base64,/, '');\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","detectFormat","base64","ScreenshotItem","capturedAt","uuid","loadFromFile","Error","buffer","readFileSync","loadFromInline","data","extractImageByIdSync","htmlPath","ref","relativePath","absolutePath","value","normalizeScreenshotRef","storage","baseRef","id"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"screenshot-item.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/screenshot-item.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 { readFileSync } from 'node:fs';\nimport { uuid } from '@aiscene/shared/utils';\nimport { extractImageByIdSync } from './dump/html-utils';\nimport {\n type ScreenshotRef,\n normalizeScreenshotRef,\n} from './dump/screenshot-store';\n\n/**\n * Serialization format for ScreenshotItem\n * - { $screenshot: \"id\" } - inline mode, references imageMap in HTML\n * - { base64: \"path\" } - directory mode, references external file path\n */\nexport type ScreenshotSerializeFormat = ScreenshotRef;\n\n/**\n * Detect image format from base64 data URI prefix.\n */\nfunction detectFormat(base64: string): 'png' | 'jpeg' {\n if (base64.startsWith('data:image/jpeg')) return 'jpeg';\n if (base64.startsWith('data:image/jpg')) return 'jpeg';\n return 'png';\n}\n\n/**\n * ScreenshotItem encapsulates screenshot data.\n *\n * Supports lazy loading after memory release:\n * - inline mode: reads from HTML file using streaming (extractImageByIdSync)\n * - directory mode: reads from file on disk\n *\n * After persistence, memory is released but the screenshot can be recovered\n * on-demand from disk, making it safe to release memory at any time.\n */\nexport class ScreenshotItem {\n private _id: string;\n private _base64: string | null;\n private _format: 'png' | 'jpeg';\n private _capturedAt: number;\n private _serializedRef: ScreenshotRef | null = null;\n private _persistedPath: string | null = null;\n private _persistedHtmlPath: string | null = null;\n\n private constructor(id: string, base64: string, capturedAt: number) {\n this._id = id;\n this._base64 = base64;\n this._format = detectFormat(base64);\n this._capturedAt = capturedAt;\n }\n\n /** Create a new ScreenshotItem from base64 data */\n static create(base64: string, capturedAt: number): ScreenshotItem {\n return new ScreenshotItem(uuid(), base64, capturedAt);\n }\n\n get id(): string {\n return this._id;\n }\n\n /** Get the image format (png or jpeg) */\n get format(): 'png' | 'jpeg' {\n return this._format;\n }\n\n /** Get the file extension for this screenshot */\n get extension(): string {\n return this._format === 'jpeg' ? 'jpeg' : 'png';\n }\n\n /** Get screenshot capture timestamp in milliseconds */\n get capturedAt(): number {\n return this._capturedAt;\n }\n\n get base64(): string {\n // If data is in memory, return it directly\n if (this._base64 !== null) {\n return this._base64;\n }\n\n const loadFromFile = (): string => {\n if (this._persistedPath === null) {\n throw new Error(`Screenshot ${this._id}: file recovery path missing`);\n }\n const buffer = readFileSync(this._persistedPath);\n return `data:image/${this._format};base64,${buffer.toString('base64')}`;\n };\n\n const loadFromInline = (): string => {\n if (this._persistedHtmlPath === null) {\n throw new Error(`Screenshot ${this._id}: HTML recovery path missing`);\n }\n const data = extractImageByIdSync(this._persistedHtmlPath, this._id);\n if (data) {\n return data;\n }\n throw new Error(\n `Screenshot ${this._id}: cannot recover from HTML (id not found in ${this._persistedHtmlPath})`,\n );\n };\n\n // Recover from the primary serialized mode first.\n if (this._serializedRef?.storage === 'file') {\n return loadFromFile();\n }\n\n if (this._serializedRef?.storage === 'inline') {\n return loadFromInline();\n }\n\n // Fall back to whichever recovery path is available.\n if (this._persistedPath !== null) {\n return loadFromFile();\n }\n\n if (this._persistedHtmlPath !== null) {\n return loadFromInline();\n }\n\n throw new Error(\n `Screenshot ${this._id}: base64 data released without recovery path`,\n );\n }\n\n /** Check if base64 data is still available in memory (not yet released) */\n hasBase64(): boolean {\n return this._base64 !== null;\n }\n\n /**\n * Mark as persisted to HTML (inline mode).\n * Releases base64 memory, but keeps HTML path for lazy loading recovery.\n * @param htmlPath - absolute path to the HTML file containing the image\n */\n markPersistedInline(htmlPath: string): ScreenshotRef {\n const ref = this.createRef('inline');\n this._serializedRef = ref;\n this._persistedHtmlPath = htmlPath;\n this._base64 = null;\n return ref;\n }\n\n /**\n * Register a file-backed recovery path without changing the serialized mode.\n * Used when inline persistence also needs a shared file copy next to dumps.\n */\n registerPersistedFileCopy(\n relativePath: string,\n absolutePath: string,\n ): ScreenshotRef {\n const ref = this.createRef('file', relativePath);\n this._persistedPath = absolutePath;\n this._base64 = null;\n return ref;\n }\n\n /**\n * Mark as persisted to file (directory mode).\n * Releases base64 memory, but keeps file path for lazy loading recovery.\n * @param relativePath - relative path for serialization (e.g., \"./screenshots/id.jpeg\")\n * @param absolutePath - absolute path for lazy loading recovery\n */\n markPersistedToPath(\n relativePath: string,\n absolutePath: string,\n ): ScreenshotRef {\n const ref = this.registerPersistedFileCopy(relativePath, absolutePath);\n this._serializedRef = ref;\n return ref;\n }\n\n /** Serialize for JSON - format depends on persistence state */\n toSerializable(): ScreenshotSerializeFormat {\n return (\n this._serializedRef ?? {\n type: 'midscene_screenshot_ref',\n id: this._id,\n capturedAt: this._capturedAt,\n mimeType: this._format === 'jpeg' ? 'image/jpeg' : 'image/png',\n storage: 'inline',\n }\n );\n }\n\n /** Check if a value is a serialized ScreenshotItem reference (inline or directory mode) */\n static isSerialized(value: unknown): value is ScreenshotSerializeFormat {\n return normalizeScreenshotRef(value) !== null;\n }\n\n private createRef(\n storage: 'inline' | 'file',\n relativePath?: string,\n ): ScreenshotRef {\n const baseRef: Omit<ScreenshotRef, 'path'> = {\n type: 'midscene_screenshot_ref',\n id: this._id,\n capturedAt: this._capturedAt,\n mimeType: this._format === 'jpeg' ? 'image/jpeg' : 'image/png',\n storage,\n };\n if (storage === 'file') {\n return {\n ...baseRef,\n storage,\n path: relativePath!,\n };\n }\n return baseRef;\n }\n\n /**\n * Get base64 data without the data URI prefix.\n * Useful for writing raw binary data to files.\n */\n get rawBase64(): string {\n return this.base64.replace(/^data:image\\/(png|jpeg|jpg);base64,/, '');\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","detectFormat","base64","ScreenshotItem","capturedAt","uuid","loadFromFile","Error","buffer","readFileSync","loadFromInline","data","extractImageByIdSync","htmlPath","ref","relativePath","absolutePath","value","normalizeScreenshotRef","storage","baseRef","id"],"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 ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|