{"version":3,"file":"dockerChromeForTesting-BpNc3_AC.mjs","names":["chromeForTestingConfig.version","chromeForTestingConfig.dockerImage","chromeForTestingConfig.dockerPlatform","cloakBrowserConfig.dockerImage"],"sources":["../src/config/chrome-for-testing.json","../src/config/cloakbrowser.json","../src/services/ChromeForTestingService.ts","../src/utils/dockerChromeForTesting.ts"],"sourcesContent":["","","/**\n * ChromeForTestingService\n *\n * DESIGN PATTERNS:\n * - Service pattern for Chrome for Testing lifecycle management\n * - Downloads and caches Chrome for Testing binary\n * - Provides executable path for extension mode\n *\n * CODING STANDARDS:\n * - Use async/await for I/O operations\n * - Proper error handling with try-catch\n * - Clear responsibility: manage Chrome for Testing lifecycle\n *\n * AVOID:\n * - Synchronous blocking operations\n * - Mixing concerns with browser launching\n */\n\nimport 'reflect-metadata/lite';\nimport { type ChildProcess, spawn } from 'node:child_process';\nimport { constants, createWriteStream, existsSync, mkdirSync } from 'node:fs';\nimport { access, chmod, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport { arch, homedir, platform } from 'node:os';\nimport { join } from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\n\nimport { injectable } from 'inversify';\n\nimport chromeForTestingConfig from '../config/chrome-for-testing.json';\n\n/** Chrome for Testing version info from API */\ninterface CftVersionInfo {\n  version: string;\n  revision: string;\n  downloads: {\n    chrome: Array<{\n      platform: string;\n      url: string;\n    }>;\n  };\n}\n\n/** Chrome for Testing API response */\ninterface CftApiResponse {\n  timestamp: string;\n  versions: CftVersionInfo[];\n}\n\nexport const PINNED_CHROME_FOR_TESTING_VERSION = chromeForTestingConfig.version;\nexport const CHROME_FOR_TESTING_VERSION_ENV_VAR = 'BROWSE_TOOL_CHROME_FOR_TESTING_VERSION';\nexport const CHROME_FOR_TESTING_PATH_ENV_VAR = 'BROWSE_TOOL_CHROME_FOR_TESTING_PATH';\nexport const RECORDER_PAGE_CLEANUP_SAFE_MIN_VERSION = '147.0.7727.3';\n\nfunction compareChromeVersionParts(left: string, right: string): number {\n  const leftParts = left.split('.').map((part) => Number.parseInt(part, 10) || 0);\n  const rightParts = right.split('.').map((part) => Number.parseInt(part, 10) || 0);\n  const maxLength = Math.max(leftParts.length, rightParts.length);\n\n  for (let index = 0; index < maxLength; index += 1) {\n    const leftPart = leftParts[index] ?? 0;\n    const rightPart = rightParts[index] ?? 0;\n    if (leftPart !== rightPart) {\n      return leftPart > rightPart ? 1 : -1;\n    }\n  }\n\n  return 0;\n}\n\nexport function getRequestedChromeForTestingVersion(): string {\n  const override = process.env[CHROME_FOR_TESTING_VERSION_ENV_VAR]?.trim();\n  return override && override.length > 0 ? override : PINNED_CHROME_FOR_TESTING_VERSION;\n}\n\nexport function getConfiguredChromeForTestingPath(): string | undefined {\n  const override = process.env[CHROME_FOR_TESTING_PATH_ENV_VAR]?.trim();\n  return override && override.length > 0 ? override : undefined;\n}\n\nexport function isRecorderPageCleanupSafeChromeVersion(version: string): boolean {\n  return compareChromeVersionParts(version, RECORDER_PAGE_CLEANUP_SAFE_MIN_VERSION) >= 0;\n}\n\nexport function shouldCleanupRecorderPageAfterStop(): boolean {\n  return isRecorderPageCleanupSafeChromeVersion(getRequestedChromeForTestingVersion());\n}\n\nexport interface IChromeForTestingService {\n  /** Get the path to Chrome for Testing executable, downloading if necessary */\n  getExecutablePath(): Promise<string>;\n  /** Check if Chrome for Testing is installed */\n  isInstalled(): Promise<boolean>;\n  /** Get the installed version */\n  getInstalledVersion(): Promise<string | null>;\n  /** Force re-download of Chrome for Testing */\n  update(): Promise<string>;\n}\n\n@injectable()\nexport class ChromeForTestingService implements IChromeForTestingService {\n  private static readonly API_URL =\n    'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json';\n\n  /** Cache directory for Chrome for Testing */\n  private readonly cacheDir: string;\n\n  constructor() {\n    this.cacheDir = join(homedir(), '.cache', 'chrome-for-testing');\n  }\n\n  /**\n   * Get the path to Chrome for Testing executable.\n   * Refreshes to the pinned known-good build when the cache is stale.\n   */\n  async getExecutablePath(): Promise<string> {\n    const configuredPath = getConfiguredChromeForTestingPath();\n    if (configuredPath) {\n      return this.validateConfiguredExecutablePath(configuredPath);\n    }\n\n    const execPath = this.getExpectedExecutablePath();\n    const installedVersion = await this.getInstalledVersion();\n\n    try {\n      const requestedVersion = this.getRequestedVersion();\n      const pinnedVersion = await this.fetchVersionInfo(requestedVersion);\n      const isCurrentInstall = existsSync(execPath) && installedVersion === requestedVersion;\n      if (isCurrentInstall) {\n        return execPath;\n      }\n\n      return this.download(pinnedVersion);\n    } catch (error) {\n      if (existsSync(execPath)) {\n        return execPath;\n      }\n\n      throw error;\n    }\n  }\n\n  /**\n   * Check if Chrome for Testing is installed\n   */\n  async isInstalled(): Promise<boolean> {\n    return existsSync(this.getExpectedExecutablePath());\n  }\n\n  /**\n   * Get the installed version from the version file\n   */\n  async getInstalledVersion(): Promise<string | null> {\n    const versionFile = join(this.cacheDir, 'version.txt');\n    if (!existsSync(versionFile)) {\n      return null;\n    }\n    try {\n      const version = await readFile(versionFile, 'utf-8');\n      return version.trim();\n    } catch {\n      return null;\n    }\n  }\n\n  /**\n   * Force re-download of Chrome for Testing\n   */\n  async update(): Promise<string> {\n    const chromeDir = join(this.cacheDir, 'chrome');\n    if (existsSync(chromeDir)) {\n      await rm(chromeDir, { recursive: true, force: true });\n    }\n    return this.download(await this.fetchVersionInfo(this.getRequestedVersion()));\n  }\n\n  /**\n   * Download Chrome for Testing\n   */\n  private async download(versionInfo: CftVersionInfo): Promise<string> {\n    mkdirSync(this.cacheDir, { recursive: true });\n    const downloadUrl = this.getDownloadUrl(versionInfo);\n\n    if (!downloadUrl) {\n      throw new Error(`No Chrome for Testing download available for ${this.getPlatformKey()}`);\n    }\n\n    const zipPath = join(this.cacheDir, 'chrome.zip');\n    const extractDir = join(this.cacheDir, 'chrome');\n\n    await this.downloadFile(downloadUrl, zipPath);\n    await this.extractZip(zipPath, extractDir);\n    await rm(zipPath, { force: true });\n    await writeFile(join(this.cacheDir, 'version.txt'), versionInfo.version, 'utf-8');\n\n    const execPath = this.getExpectedExecutablePath();\n    if (!existsSync(execPath)) {\n      throw new Error(`Chrome for Testing executable not found at expected path: ${execPath}`);\n    }\n\n    if (platform() !== 'win32') {\n      await chmod(execPath, 0o755);\n    }\n\n    return execPath;\n  }\n\n  /**\n   * Fetch version info from Chrome for Testing API\n   */\n  private async fetchVersionInfo(requestedVersion: string): Promise<CftVersionInfo> {\n    const response = await fetch(ChromeForTestingService.API_URL);\n    if (!response.ok) {\n      throw new Error(`Failed to fetch Chrome for Testing info: ${response.statusText}`);\n    }\n    const data = (await response.json()) as CftApiResponse;\n    const versionInfo = data.versions.find((entry) => entry.version === requestedVersion);\n    if (!versionInfo) {\n      throw new Error(`Chrome for Testing version ${requestedVersion} not found in feed`);\n    }\n    return versionInfo;\n  }\n\n  private getRequestedVersion(): string {\n    return getRequestedChromeForTestingVersion();\n  }\n\n  private async validateConfiguredExecutablePath(execPath: string): Promise<string> {\n    try {\n      const stats = await stat(execPath);\n      if (!stats.isFile()) {\n        throw new Error('configured path is not a file');\n      }\n\n      if (platform() !== 'win32') {\n        await access(execPath, constants.X_OK);\n      }\n\n      return execPath;\n    } catch (error) {\n      throw new Error(\n        `Chrome for Testing executable configured by ${CHROME_FOR_TESTING_PATH_ENV_VAR} was not found or is not executable: ${execPath}`,\n        { cause: error },\n      );\n    }\n  }\n\n  /**\n   * Get the download URL for current platform\n   */\n  private getDownloadUrl(versionInfo: CftVersionInfo): string | undefined {\n    const platformKey = this.getPlatformKey();\n    const download = versionInfo.downloads.chrome.find((d) => d.platform === platformKey);\n    return download?.url;\n  }\n\n  /**\n   * Get platform key for Chrome for Testing API\n   */\n  private getPlatformKey(): string {\n    const os = platform();\n    const architecture = arch();\n\n    if (os === 'darwin') {\n      return architecture === 'arm64' ? 'mac-arm64' : 'mac-x64';\n    }\n    if (os === 'linux') {\n      return 'linux64';\n    }\n    if (os === 'win32') {\n      return architecture === 'x64' ? 'win64' : 'win32';\n    }\n    throw new Error(`Unsupported platform: ${os}`);\n  }\n\n  /**\n   * Get the expected executable path based on platform\n   */\n  private getExpectedExecutablePath(): string {\n    const os = platform();\n    const chromeDir = join(this.cacheDir, 'chrome');\n\n    if (os === 'darwin') {\n      const archSuffix = arch() === 'arm64' ? 'arm64' : 'x64';\n      return join(\n        chromeDir,\n        `chrome-mac-${archSuffix}`,\n        'Google Chrome for Testing.app',\n        'Contents',\n        'MacOS',\n        'Google Chrome for Testing',\n      );\n    }\n    if (os === 'linux') {\n      return join(chromeDir, 'chrome-linux64', 'chrome');\n    }\n    if (os === 'win32') {\n      const archSuffix = arch() === 'x64' ? '64' : '32';\n      return join(chromeDir, `chrome-win${archSuffix}`, 'chrome.exe');\n    }\n    throw new Error(`Unsupported platform: ${os}`);\n  }\n\n  /**\n   * Download a file from URL to local path\n   */\n  private async downloadFile(url: string, destPath: string): Promise<void> {\n    const response = await fetch(url);\n    if (!response.ok || !response.body) {\n      throw new Error(`Failed to download: ${response.statusText}`);\n    }\n\n    const tempPath = `${destPath}.tmp`;\n    const fileStream = createWriteStream(tempPath);\n\n    const reader = response.body.getReader();\n    const nodeStream = new Readable({\n      async read() {\n        const { done, value } = await reader.read();\n        if (done) {\n          this.push(null);\n        } else {\n          this.push(Buffer.from(value));\n        }\n      },\n    });\n\n    await pipeline(nodeStream, fileStream);\n    await rename(tempPath, destPath);\n  }\n\n  /**\n   * Extract a zip file to destination directory\n   */\n  private async extractZip(zipPath: string, destDir: string): Promise<void> {\n    const os = platform();\n\n    return new Promise((resolve, reject) => {\n      let proc: ChildProcess;\n\n      if (os === 'win32') {\n        proc = spawn('powershell', [\n          '-NoProfile',\n          '-Command',\n          `Expand-Archive -Path \"${zipPath}\" -DestinationPath \"${destDir}\" -Force`,\n        ]);\n      } else {\n        mkdirSync(destDir, { recursive: true });\n        proc = spawn('unzip', ['-o', '-q', zipPath, '-d', destDir]);\n      }\n\n      proc.on('close', (code) => {\n        if (code === 0) {\n          resolve();\n        } else {\n          reject(new Error(`Failed to extract zip (exit code: ${code})`));\n        }\n      });\n\n      proc.on('error', (err) => {\n        reject(new Error(`Failed to spawn extraction process: ${err.message}`));\n      });\n    });\n  }\n}\n","import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport chromeForTestingConfig from '../config/chrome-for-testing.json';\nimport cloakBrowserConfig from '../config/cloakbrowser.json';\nimport { getRequestedChromeForTestingVersion } from '../services/ChromeForTestingService.js';\n\nconst WORKSPACE_MARKERS = ['pnpm-workspace.yaml', 'nx.json', '.git'];\nconst DEFAULT_DOCKER_IMAGE = chromeForTestingConfig.dockerImage;\nconst DEFAULT_DOCKER_PLATFORM = chromeForTestingConfig.dockerPlatform;\nconst DEFAULT_DOCKER_REPOSITORY = DEFAULT_DOCKER_IMAGE.split(':')[0] ?? DEFAULT_DOCKER_IMAGE;\nconst CLOAKBROWSER_DOCKER_IMAGE = cloakBrowserConfig.dockerImage;\nconst CLOAKBROWSER_DOCKER_REPOSITORY = CLOAKBROWSER_DOCKER_IMAGE.split(':')[0] ?? CLOAKBROWSER_DOCKER_IMAGE;\nconst PACKAGE_NAME = '@agimon-ai/po-browse-tool';\n\nexport interface DockerChromeForTestingBuildOptions {\n  version?: string;\n  image?: string;\n  platform?: string;\n  stdio?: 'inherit' | 'pipe' | 'ignore';\n}\n\ninterface DockerCommandResult {\n  exitCode: number;\n  stderr: string;\n}\n\nfunction resolveWorkspaceRoot(startPath = process.cwd()): string {\n  let current = path.resolve(startPath);\n\n  while (true) {\n    for (const marker of WORKSPACE_MARKERS) {\n      if (pathExists(path.join(current, marker))) {\n        return current;\n      }\n    }\n\n    const parent = path.dirname(current);\n    if (parent === current) {\n      return startPath;\n    }\n    current = parent;\n  }\n}\n\nfunction pathExists(candidatePath: string): boolean {\n  return fs.existsSync(candidatePath);\n}\n\nfunction getDefaultDockerImageRepository(): string {\n  return DEFAULT_DOCKER_REPOSITORY;\n}\n\nfunction getDefaultDockerImage(version: string): string {\n  return `${getDefaultDockerImageRepository()}:${version}`;\n}\n\nfunction resolvePackageRoot(startDir: string): string {\n  let current = path.resolve(startDir);\n\n  for (let index = 0; index < 8; index += 1) {\n    const packageJsonPath = path.join(current, 'package.json');\n    if (pathExists(packageJsonPath)) {\n      try {\n        const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as { name?: string };\n        if (packageJson.name === PACKAGE_NAME) {\n          return current;\n        }\n      } catch {\n        // Keep walking.\n      }\n    }\n\n    const parent = path.dirname(current);\n    if (parent === current) {\n      break;\n    }\n    current = parent;\n  }\n\n  return path.resolve(startDir, '../..');\n}\n\nfunction resolveDockerfilePath(): string {\n  const currentDir = path.dirname(fileURLToPath(import.meta.url));\n  return path.join(resolvePackageRoot(currentDir), 'docker/chrome-for-testing.Dockerfile');\n}\n\nfunction resolveBuildContext(): string {\n  const currentDir = path.dirname(fileURLToPath(import.meta.url));\n  const packageRoot = resolvePackageRoot(currentDir);\n  return resolveWorkspaceRoot(packageRoot);\n}\n\nfunction resolveVersionFromImage(image?: string): string | undefined {\n  if (!image?.includes(':')) {\n    return undefined;\n  }\n\n  const [, tag] = image.split(':', 2);\n  const normalizedTag = tag?.trim();\n  if (!normalizedTag || !/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(normalizedTag)) {\n    return undefined;\n  }\n\n  return normalizedTag;\n}\n\nfunction normalizePlatform(platform?: string): string {\n  return (platform?.trim() || DEFAULT_DOCKER_PLATFORM).toLowerCase();\n}\n\nexport function resolveChromeForTestingArchivePlatform(platform?: string): string {\n  const normalized = normalizePlatform(platform);\n\n  if (normalized.includes('arm64') || normalized.includes('aarch64')) {\n    return 'linux-arm64';\n  }\n\n  return 'linux64';\n}\n\nexport function isManagedDockerChromeForTestingImage(image: string): boolean {\n  return image.startsWith(`${getDefaultDockerImageRepository()}:`);\n}\n\nasync function runDockerCommand(args: string[], stdio: 'inherit' | 'pipe' | 'ignore'): Promise<DockerCommandResult> {\n  return await new Promise<DockerCommandResult>((resolve, reject) => {\n    let stderr = '';\n    const child = spawn('docker', args, {\n      stdio: stdio === 'pipe' ? ['ignore', 'pipe', 'pipe'] : ['ignore', stdio, stdio],\n    });\n\n    if (stdio === 'pipe') {\n      child.stderr?.on('data', (chunk) => {\n        stderr += chunk.toString('utf8');\n      });\n    }\n\n    child.once('error', reject);\n    child.once('close', (code) => {\n      resolve({\n        exitCode: code ?? 1,\n        stderr,\n      });\n    });\n  });\n}\n\nexport async function dockerImageExistsLocally(image: string): Promise<boolean> {\n  const result = await runDockerCommand(['image', 'inspect', image], 'ignore');\n  return result.exitCode === 0;\n}\n\nexport async function buildDockerChromeForTestingImage(\n  options: DockerChromeForTestingBuildOptions = {},\n): Promise<{ image: string; version: string; platform: string }> {\n  const version =\n    options.version?.trim() || resolveVersionFromImage(options.image) || getRequestedChromeForTestingVersion();\n  const image = options.image?.trim() || getDefaultDockerImage(version);\n  const platform = normalizePlatform(options.platform);\n  const archivePlatform = resolveChromeForTestingArchivePlatform(platform);\n  const stdio = options.stdio ?? 'inherit';\n  const args = [\n    'buildx',\n    'build',\n    '--platform',\n    platform,\n    '--load',\n    '-t',\n    image,\n    '--build-arg',\n    `CFT_VERSION=${version}`,\n    '--build-arg',\n    `CFT_ARCHIVE_PLATFORM=${archivePlatform}`,\n    '-f',\n    resolveDockerfilePath(),\n    resolveBuildContext(),\n  ];\n\n  const result = await runDockerCommand(args, stdio);\n  if (result.exitCode !== 0) {\n    const stderr = result.stderr.trim();\n    throw new Error(\n      stderr ? `Failed to build Docker image ${image}: ${stderr}` : `Failed to build Docker image ${image}`,\n    );\n  }\n\n  return { image, version, platform };\n}\n\nexport async function ensureManagedDockerChromeForTestingImageAvailable(input: {\n  image: string;\n  platform?: string;\n}): Promise<boolean> {\n  if (!isManagedDockerChromeForTestingImage(input.image)) {\n    return false;\n  }\n\n  const exists = await dockerImageExistsLocally(input.image);\n  if (exists) {\n    return false;\n  }\n\n  await buildDockerChromeForTestingImage({\n    image: input.image,\n    platform: input.platform,\n    stdio: 'inherit',\n  });\n  return true;\n}\n\nexport function isManagedCloakBrowserImage(image: string): boolean {\n  return image.startsWith(`${CLOAKBROWSER_DOCKER_REPOSITORY}:`);\n}\n\nfunction resolveCloakBrowserDockerfilePath(): string {\n  const currentDir = path.dirname(fileURLToPath(import.meta.url));\n  return path.join(resolvePackageRoot(currentDir), 'docker/cloakbrowser.Dockerfile');\n}\n\nexport async function buildDockerCloakBrowserImage(\n  options: { image?: string; platform?: string; stdio?: 'inherit' | 'pipe' | 'ignore' } = {},\n): Promise<{ image: string; platform: string }> {\n  const image = options.image?.trim() || CLOAKBROWSER_DOCKER_IMAGE;\n  const platform = normalizePlatform(options.platform);\n  const stdio = options.stdio ?? 'inherit';\n\n  const args = [\n    'buildx',\n    'build',\n    '--platform',\n    platform,\n    '--load',\n    '-t',\n    image,\n    '-f',\n    resolveCloakBrowserDockerfilePath(),\n    resolveBuildContext(),\n  ];\n\n  const result = await runDockerCommand(args, stdio);\n  if (result.exitCode !== 0) {\n    const stderr = result.stderr.trim();\n    throw new Error(\n      stderr\n        ? `Failed to build CloakBrowser Docker image ${image}: ${stderr}`\n        : `Failed to build CloakBrowser Docker image ${image}`,\n    );\n  }\n\n  return { image, platform };\n}\n\nexport async function ensureCloakBrowserImageAvailable(input: { image: string; platform?: string }): Promise<boolean> {\n  if (!isManagedCloakBrowserImage(input.image)) {\n    return false;\n  }\n\n  const exists = await dockerImageExistsLocally(input.image);\n  if (exists) {\n    return false;\n  }\n\n  await buildDockerCloakBrowserImage({\n    image: input.image,\n    platform: input.platform,\n    stdio: 'inherit',\n  });\n  return true;\n}\n"],"mappings":"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"}