{"version":3,"file":"report-cli.mjs","sources":["../../src/report-cli.ts"],"sourcesContent":["import {\n  copyFileSync,\n  existsSync,\n  mkdirSync,\n  statSync,\n  writeFileSync,\n} from 'node:fs';\nimport * as path from 'node:path';\nimport { z } from 'zod';\nimport { resolveScreenshotSource } from './dump/screenshot-store';\nimport {\n  ReportMergingTool,\n  collectDedupedExecutions,\n  splitReportHtmlByExecution,\n} from './report';\nimport { reportToMarkdown } from './report-markdown';\nimport type { MarkdownAttachment } from './report-markdown';\nimport type { ReportFileAttributes, TestStatus } from './types';\nimport { ReportActionDump } from './types';\n\ntype ReportCliToolResult = {\n  isError: boolean;\n  content: Array<{\n    type: 'text';\n    text: string;\n  }>;\n};\n\ntype ReportCliSchema = Record<string, z.ZodTypeAny>;\n\nexport interface ReportCliCommandDefinition {\n  name: string;\n  description: string;\n  schema: ReportCliSchema;\n  handler: (args: Record<string, unknown>) => Promise<ReportCliToolResult>;\n}\n\nexport interface ReportCliCommandEntry {\n  name: string;\n  def: ReportCliCommandDefinition;\n}\n\nexport type ConsumeReportFileAction = 'split' | 'to-markdown' | 'merge-html';\n\nexport interface ConsumeReportFileOptions {\n  htmlPath: string;\n  outputDir: string;\n}\n\nexport type SplitReportFileOptions = ConsumeReportFileOptions;\nexport type ReportFileToMarkdownOptions = ConsumeReportFileOptions;\n\nexport interface MergeReportFilesOptions {\n  htmlPaths: string[];\n  outputDir?: string;\n  outputName?: string;\n  overwrite?: boolean;\n}\n\nexport interface MergeReportFilesResult {\n  mergedReportPath: string;\n}\n\nfunction writeAttachmentFromReport(\n  attachment: MarkdownAttachment,\n  opts: {\n    htmlPath: string;\n    screenshotsDir: string;\n    writtenFiles: Set<string>;\n  },\n): void {\n  const { suggestedFileName, id, mimeType } = attachment;\n  if (opts.writtenFiles.has(suggestedFileName)) return;\n\n  const absolutePath = path.join(opts.screenshotsDir, suggestedFileName);\n\n  const resolved = resolveScreenshotSource(attachment.sourceRef ?? null, {\n    reportPath: opts.htmlPath,\n    fallbackId: id,\n    fallbackMimeType: (mimeType || 'image/png') as 'image/png' | 'image/jpeg',\n  });\n\n  if (resolved.type === 'data-uri') {\n    const rawBase64 = resolved.dataUri.replace(\n      /^data:image\\/[a-zA-Z+]+;base64,/,\n      '',\n    );\n    writeFileSync(absolutePath, Buffer.from(rawBase64, 'base64'));\n    opts.writtenFiles.add(suggestedFileName);\n    return;\n  }\n\n  if (!existsSync(resolved.filePath)) {\n    throw new Error(\n      `Cannot resolve screenshot \"${id}\" for markdown attachment from ${opts.htmlPath}`,\n    );\n  }\n\n  copyFileSync(resolved.filePath, absolutePath);\n  opts.writtenFiles.add(suggestedFileName);\n}\n\nasync function markdownFromReport(\n  htmlPath: string,\n  outputDir: string,\n): Promise<{ markdownFiles: string[]; screenshotFiles: string[] }> {\n  const screenshotsDir = path.join(outputDir, 'screenshots');\n\n  mkdirSync(outputDir, { recursive: true });\n  mkdirSync(screenshotsDir, { recursive: true });\n\n  const { baseDump, executions } = collectDedupedExecutions(htmlPath);\n\n  const mergedReport = new ReportActionDump({\n    sdkVersion: baseDump.sdkVersion,\n    groupName: baseDump.groupName,\n    groupDescription: baseDump.groupDescription,\n    modelBriefs: baseDump.modelBriefs,\n    deviceType: baseDump.deviceType,\n    executions,\n  });\n\n  const result = reportToMarkdown(mergedReport);\n\n  const markdownFiles: string[] = [];\n  const writtenScreenshots = new Set<string>();\n\n  const mdPath = path.join(outputDir, 'report.md');\n  writeFileSync(mdPath, result.markdown, 'utf-8');\n  markdownFiles.push(mdPath);\n\n  for (const attachment of result.attachments) {\n    writeAttachmentFromReport(attachment, {\n      htmlPath,\n      screenshotsDir,\n      writtenFiles: writtenScreenshots,\n    });\n  }\n\n  return {\n    markdownFiles,\n    screenshotFiles: Array.from(writtenScreenshots)\n      .sort()\n      .map((f) => path.join(screenshotsDir, f)),\n  };\n}\n\nfunction resolveReportHtmlPath(htmlPath: string): string {\n  const normalizedPath = path.resolve(htmlPath);\n\n  if (!existsSync(normalizedPath)) {\n    throw new Error(`report-tool: --htmlPath does not exist: ${htmlPath}`);\n  }\n\n  const stats = statSync(normalizedPath);\n  if (!stats.isDirectory()) {\n    return normalizedPath;\n  }\n\n  const indexHtmlPath = path.join(normalizedPath, 'index.html');\n  if (!existsSync(indexHtmlPath)) {\n    throw new Error(\n      `report-tool: \"${htmlPath}\" is not an HTML report file, and no index.html was found under this directory.`,\n    );\n  }\n\n  return indexHtmlPath;\n}\n\nexport function splitReportFile(options: SplitReportFileOptions): {\n  executionJsonFiles: string[];\n  screenshotFiles: string[];\n} {\n  const { htmlPath, outputDir } = options;\n  if (!htmlPath) {\n    throw new Error('splitReportFile: htmlPath is required');\n  }\n\n  if (!outputDir) {\n    throw new Error('splitReportFile: outputDir is required');\n  }\n\n  const resolvedHtmlPath = resolveReportHtmlPath(htmlPath);\n  return splitReportHtmlByExecution({\n    htmlPath: resolvedHtmlPath,\n    outputDir,\n  });\n}\n\nexport async function reportFileToMarkdown(\n  options: ReportFileToMarkdownOptions,\n): Promise<{ markdownFiles: string[]; screenshotFiles: string[] }> {\n  const { htmlPath, outputDir } = options;\n  if (!htmlPath) {\n    throw new Error('reportFileToMarkdown: htmlPath is required');\n  }\n\n  if (!outputDir) {\n    throw new Error('reportFileToMarkdown: outputDir is required');\n  }\n\n  const resolvedHtmlPath = resolveReportHtmlPath(htmlPath);\n  return markdownFromReport(resolvedHtmlPath, outputDir);\n}\n\nfunction deriveReportAttributesFromHtml(\n  htmlPath: string,\n  index: number,\n): ReportFileAttributes {\n  const fallbackId = `${path.basename(path.dirname(htmlPath)) || path.basename(htmlPath, path.extname(htmlPath))}-${index + 1}`;\n  try {\n    const { baseDump } = collectDedupedExecutions(htmlPath);\n    return {\n      testId: fallbackId,\n      testTitle: baseDump.groupName || fallbackId,\n      testDescription: baseDump.groupDescription ?? '',\n      testDuration: 0,\n      testStatus: 'passed' as TestStatus,\n    };\n  } catch {\n    return {\n      testId: fallbackId,\n      testTitle: fallbackId,\n      testDescription: '',\n      testDuration: 0,\n      testStatus: 'passed' as TestStatus,\n    };\n  }\n}\n\nexport function mergeReportFiles(\n  options: MergeReportFilesOptions,\n): MergeReportFilesResult {\n  const { htmlPaths, outputDir, outputName, overwrite = false } = options;\n  if (!htmlPaths || htmlPaths.length === 0) {\n    throw new Error('mergeReportFiles: htmlPaths is required');\n  }\n\n  const resolvedPaths = htmlPaths.map((p) => resolveReportHtmlPath(p));\n\n  const tool = new ReportMergingTool();\n  resolvedPaths.forEach((htmlPath, index) => {\n    tool.append({\n      reportFilePath: htmlPath,\n      reportAttributes: deriveReportAttributesFromHtml(htmlPath, index),\n    });\n  });\n\n  const mergedReportPath = tool.mergeReports(outputName ?? 'AUTO', {\n    overwrite,\n    outputDir,\n  });\n\n  if (!mergedReportPath) {\n    throw new Error('mergeReportFiles: failed to produce a merged report');\n  }\n\n  return { mergedReportPath };\n}\n\nfunction normalizeHtmlReportArg(raw: unknown): string[] | undefined {\n  if (raw === undefined || raw === null) return undefined;\n  if (Array.isArray(raw)) {\n    return raw.filter(\n      (p): p is string => typeof p === 'string' && p.length > 0,\n    );\n  }\n  if (typeof raw === 'string') {\n    const trimmed = raw.trim();\n    return trimmed ? [trimmed] : [];\n  }\n  return undefined;\n}\n\nconst reportCommandDefinition: ReportCliCommandDefinition = {\n  name: 'report-tool',\n  description:\n    'Transform Midscene report artifacts, including splitting executions, converting to markdown, and merging multiple reports.',\n  schema: {\n    action: z\n      .enum(['split', 'to-markdown', 'merge-html'])\n      .optional()\n      .describe(\n        'Report action to run. Supports: split, to-markdown, merge-html. Defaults to split.',\n      ),\n    htmlPath: z\n      .string()\n      .optional()\n      .describe(\n        'Input report HTML path (e.g. ./report/index.html). Used by split and to-markdown.',\n      ),\n    htmlReport: z\n      .union([z.string(), z.array(z.string())])\n      .optional()\n      .describe(\n        'Input report HTML path for the merge action. Repeat the flag to merge multiple reports (e.g. --htmlReport ./a/index.html --htmlReport ./b.html).',\n      ),\n    outputDir: z\n      .string()\n      .optional()\n      .describe(\n        'Output directory for generated report artifacts. For merge, defaults to the Midscene report directory.',\n      ),\n    outputName: z\n      .string()\n      .optional()\n      .describe(\n        'Output report file/directory name (without .html) for the merge action. Defaults to an auto-generated name.',\n      ),\n    overwrite: z\n      .union([z.boolean(), z.string()])\n      .optional()\n      .describe(\n        'Overwrite the existing merged report file if present (merge action only).',\n      ),\n  },\n  handler: async (args) => {\n    const {\n      action = 'split',\n      htmlPath,\n      htmlReport,\n      outputDir,\n      outputName,\n      overwrite,\n    } = args as {\n      action?: string;\n      htmlPath?: string;\n      htmlReport?: unknown;\n      outputDir?: string;\n      outputName?: string;\n      overwrite?: unknown;\n    };\n    if (\n      action !== 'split' &&\n      action !== 'to-markdown' &&\n      action !== 'merge-html'\n    ) {\n      throw new Error(\n        `report-tool: unsupported --action value \"${action}\". Currently supported: split, to-markdown, merge-html`,\n      );\n    }\n\n    if (action === 'merge-html') {\n      const paths = normalizeHtmlReportArg(htmlReport);\n      if (!paths || paths.length === 0) {\n        throw new Error(\n          'report-tool: --htmlReport is required for action \"merge-html\". Repeat --htmlReport for each report (e.g. --htmlReport ./a/index.html --htmlReport ./b.html).',\n        );\n      }\n\n      const overwriteFlag =\n        overwrite === true || overwrite === 'true' || overwrite === '1';\n\n      const result = mergeReportFiles({\n        htmlPaths: paths,\n        outputDir,\n        outputName,\n        overwrite: overwriteFlag,\n      });\n\n      return {\n        isError: false,\n        content: [\n          {\n            type: 'text',\n            text: `Merged ${paths.length} report(s) into ${result.mergedReportPath}`,\n          },\n        ],\n      };\n    }\n\n    if (!htmlPath) {\n      throw new Error('report-tool: --htmlPath is required');\n    }\n\n    if (!outputDir) {\n      throw new Error('report-tool: --outputDir is required');\n    }\n\n    if (action === 'to-markdown') {\n      const result = await reportFileToMarkdown({\n        htmlPath,\n        outputDir,\n      });\n      return {\n        isError: false,\n        content: [\n          {\n            type: 'text',\n            text: `Markdown export completed. Generated ${result.markdownFiles.length} markdown file(s) and ${result.screenshotFiles.length} screenshot(s). Output path: ${outputDir}`,\n          },\n        ],\n      };\n    }\n\n    const result = splitReportFile({\n      htmlPath,\n      outputDir,\n    });\n\n    return {\n      isError: false,\n      content: [\n        {\n          type: 'text',\n          text: `Report split completed. Generated ${result.executionJsonFiles.length} execution JSON files and ${result.screenshotFiles.length} screenshots. Output path: ${outputDir}`,\n        },\n      ],\n    };\n  },\n};\n\nexport function createReportCliCommands(): ReportCliCommandEntry[] {\n  return [\n    {\n      name: 'report-tool',\n      def: reportCommandDefinition,\n    },\n  ];\n}\n"],"names":["writeAttachmentFromReport","attachment","opts","suggestedFileName","id","mimeType","absolutePath","path","resolved","resolveScreenshotSource","rawBase64","writeFileSync","Buffer","existsSync","Error","copyFileSync","markdownFromReport","htmlPath","outputDir","screenshotsDir","mkdirSync","baseDump","executions","collectDedupedExecutions","mergedReport","ReportActionDump","result","reportToMarkdown","markdownFiles","writtenScreenshots","Set","mdPath","Array","f","resolveReportHtmlPath","normalizedPath","stats","statSync","indexHtmlPath","splitReportFile","options","resolvedHtmlPath","splitReportHtmlByExecution","reportFileToMarkdown","deriveReportAttributesFromHtml","index","fallbackId","mergeReportFiles","htmlPaths","outputName","overwrite","resolvedPaths","p","tool","ReportMergingTool","mergedReportPath","normalizeHtmlReportArg","raw","trimmed","reportCommandDefinition","z","args","action","htmlReport","paths","overwriteFlag","createReportCliCommands"],"mappings":"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"}