{"version":3,"sources":["../../src/cli/index.ts","../../src/cli/config-loader.ts","../../src/cli/errors.ts","../../src/cli/config-detector.ts","../../src/cli/config-merger.ts","../../src/types/index.ts","../../src/cli/arg-filter.ts","../../src/cli/temp-config.ts","../../src/utils/ui.ts","../../src/utils/update-notifier.ts","../../src/utils/package-version.ts","../../src/cli/logger.ts","../../src/cli/playwright-spawner.ts","../../src/cli/rerun/client.ts","../../src/cli/rerun/prepare.ts","../../src/cli/rerun/verify.ts","../../src/utils/index.ts","../../src/metadata/ci.ts","../../src/cli/rerun/in-run.ts","../../src/cli/rerun/types.ts","../../src/cli/commands/test.ts","../../src/cli/swarm/swarm-command.ts","../../src/cli/swarm/dispatch-errors.ts","../../src/cli/swarm/machine-count.ts","../../src/cli/swarm/mint-client.ts","../../src/cli/swarm/playwright-list-runner.ts","../../src/cli/swarm/unit-builder.ts","../../src/cli/swarm/mint.ts","../../src/cli/swarm/machine-id.ts","../../src/cli/swarm/run-loop.ts","../../src/cli/swarm/ws-client.ts","../../src/cli/swarm/ws-url.ts","../../src/cli/swarm/run-command.ts","../../src/cli/swarm/mode.ts","../../src/cli/swarm/passthrough.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { TestCommand } from './commands/test.js';\nimport { Logger } from './logger.js';\nimport { TestDinoError } from './errors.js';\nimport { awaitUpdateResult, checkForUpdate, getPackageVersion } from '../utils/update-notifier.js';\nimport { isDebugEnabled } from '../utils/index.js';\nimport { startSwarm } from './swarm/swarm-command.js';\nimport { joinSwarm } from './swarm/run-command.js';\nimport { resolveSwarmMode } from './swarm/mode.js';\nimport { splitSwarmOperands } from './swarm/passthrough.js';\nimport type { SwarmMintCliOptions } from './swarm/swarm-command.js';\n\ntype SwarmCliOptions = SwarmMintCliOptions & { id?: string; machineId?: string };\n\nconst logger = new Logger(isDebugEnabled());\n\nfunction buildProgram(): Command {\n  const program = new Command()\n    .name('tdpw')\n    .description('Run Playwright tests with TestDino reporting')\n    .version(getPackageVersion(), '-v, --version', 'Output the current version')\n    .helpOption('-h, --help', 'Display help for command');\n\n  program\n    .command('test')\n    .description('Run Playwright tests with TestDino reporter')\n    .option('-t, --token <token>', 'TestDino authentication token')\n    .option('--ci-run-id <id>', 'CI run ID for grouping test runs')\n    .option('--server-url <url>', 'TestDino server URL')\n    .option('--debug', 'Enable debug logging')\n    .option('--no-artifacts', 'Disable artifact uploads (screenshots, videos, traces)')\n    .option('--tags <tags>', 'Comma-separated run-level tags (e.g. smoke,prod)')\n    .option('--split <current/total>', 'Manual split index/total (e.g. 1/5) — requires --split-id')\n    .option('--split-id <id>', 'Group ID correlating all splits of one logical run')\n    .option('--rerun <scope>', \"Re-run only the source run's failed, flaky or failed-and-flaky tests\")\n    .option('--from-run <runId>', 'The run to re-run from (required with --rerun)')\n    .option('--test-ids <ids>', 'Comma-separated test ids to re-run (overrides the --rerun scope)')\n    .option('--exclude-ids <ids>', 'Comma-separated test ids to drop from the --rerun scope')\n    .option('--rerun-tags <tags>', 'Comma-separated run tags added to the --rerun run (env: TESTDINO_RERUN_TAGS)')\n    .allowUnknownOption()\n    .allowExcessArguments()\n    .action(async (options, command) => {\n      if (options.debug) {\n        logger.setDebug(true);\n      }\n\n      // Started before the run so the network round trip overlaps test execution.\n      // Never let a version check fail the run.\n      const updatePromise = checkForUpdate(getPackageVersion()).catch(() => undefined);\n\n      const printUpdateNotice = async (): Promise<void> => {\n        try {\n          const latestVersion = await awaitUpdateResult(updatePromise);\n          if (latestVersion) {\n            logger.updateNotice(getPackageVersion(), latestVersion);\n          }\n        } catch {\n          // A version check must never fail the run.\n        }\n      };\n\n      try {\n        const args = command.args || [];\n\n        // Create and execute test command\n        const testCommand = new TestCommand(undefined, undefined, undefined, undefined, undefined, undefined, logger);\n        const result = await testCommand.execute(options, args);\n\n        await printUpdateNotice();\n\n        // Exit with Playwright's exit code\n        process.exit(result.exitCode);\n      } catch (error) {\n        if (error instanceof TestDinoError) {\n          // Custom errors have well-formatted messages\n          logger.error(error.message);\n        } else {\n          logger.error(\n            error instanceof Error ? error.message : String(error),\n            error instanceof Error ? error : undefined\n          );\n        }\n\n        await printUpdateNotice();\n        process.exit(1);\n      }\n    });\n\n  program\n    .command('swarm')\n    .description('Run a Playwright suite as a swarm: machines take the next spec as they free up')\n    .option(\n      '--machines <N>',\n      'Start a swarm across N machines (or TESTDINO_MACHINES). Workers (W) comes from the Playwright config.'\n    )\n    .option('--id <swarmId>', 'Join the swarm with this id instead of starting one')\n    .option('--machine-id <id>', 'Stable id for this machine when joining (or TESTDINO_MACHINE_ID)')\n    .option('--grep <pattern>', 'Only include tests matching the pattern (start only)')\n    .option('--project <name...>', 'Restrict the swarm to one or more Playwright projects (start only)')\n    .option('--out <file>', 'Write the started swarm as JSON, for the matrix to read (start only)')\n    .option('--token <token>', 'TestDino pipeline token (or TESTDINO_TOKEN)')\n    .option('--server-url <url>', 'TestDino server URL')\n    .option('--debug', 'Enable debug logging')\n    // Passthrough: `-- <args>` forwards verbatim to each `playwright test` invocation.\n    .allowUnknownOption()\n    .allowExcessArguments()\n    .action(async (options: SwarmCliOptions, command: Command) => {\n      if (options.debug) logger.setDebug(true);\n      const { passthrough, stray } = splitSwarmOperands(command.args ?? []);\n      if (stray.length > 0) {\n        logger.error(\n          `Unexpected argument \"${stray[0]}\". Use \\`tdpw swarm --machines <N>\\` to start a swarm or ` +\n            '`tdpw swarm --id <swarmId>` to join one; Playwright args go after `--`.'\n        );\n        process.exitCode = 1;\n        return;\n      }\n      const decision = resolveSwarmMode({\n        machines: options.machines,\n        id: options.id,\n        envMachines: process.env.TESTDINO_MACHINES,\n      });\n      if (decision.mode === 'error') {\n        logger.error(decision.message);\n        process.exitCode = 1;\n        return;\n      }\n      if (decision.mode === 'join') {\n        await joinSwarm(logger, { ...options, id: decision.id }, passthrough);\n        return;\n      }\n      await startSwarm(logger, options);\n    });\n\n  return program;\n}\n\nasync function main(): Promise<void> {\n  try {\n    logger.banner(getPackageVersion());\n\n    const program = buildProgram();\n    await program.parseAsync(process.argv);\n  } catch (error) {\n    if (error instanceof TestDinoError) {\n      logger.error(error.message);\n    } else {\n      logger.error(error instanceof Error ? error.message : String(error), error instanceof Error ? error : undefined);\n    }\n\n    process.exit(1);\n  }\n}\n\n// Run CLI\nmain().catch((error) => {\n  logger.error('Unexpected error', error instanceof Error ? error : undefined);\n  process.exit(1);\n});\n","import { existsSync, statSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { createJiti } from 'jiti';\nimport type { ConfigFileContent } from './types.js';\nimport { ConfigSyntaxError } from './errors.js';\n\nconst CONFIG_FILENAMES = ['testdino.config.ts', 'testdino.config.js'];\n\nexport interface ConfigLoadResult {\n  config: ConfigFileContent;\n  configPath?: string;\n}\n\nexport class ConfigLoader {\n  private cwd: string;\n\n  constructor(cwd: string = process.cwd()) {\n    this.cwd = cwd;\n  }\n\n  async load(): Promise<ConfigLoadResult> {\n    const configPath = this.findConfigFile();\n\n    if (!configPath) {\n      return { config: {} };\n    }\n\n    try {\n      const config = await this.loadConfigFile(configPath);\n      return { config, configPath };\n    } catch (error) {\n      throw new ConfigSyntaxError(configPath, error instanceof Error ? error : new Error(String(error)));\n    }\n  }\n\n  private findConfigFile(): string | undefined {\n    let currentDir = this.cwd;\n\n    while (true) {\n      for (const filename of CONFIG_FILENAMES) {\n        const configPath = join(currentDir, filename);\n        if (existsSync(configPath)) {\n          return configPath;\n        }\n      }\n\n      const gitDir = join(currentDir, '.git');\n      if (existsSync(gitDir) && statSync(gitDir).isDirectory()) {\n        break;\n      }\n\n      // Move to parent directory\n      const parentDir = dirname(currentDir);\n\n      // Stop if we've reached the root\n      if (parentDir === currentDir) {\n        break;\n      }\n\n      currentDir = parentDir;\n    }\n\n    return undefined;\n  }\n\n  private async loadConfigFile(configPath: string): Promise<ConfigFileContent> {\n    const jitiLoader = createJiti(dirname(configPath), {\n      interopDefault: true,\n      fsCache: false,\n      extensions: ['.ts', '.js'],\n    });\n\n    let loaded: unknown;\n    try {\n      // Use jiti's esmResolve to handle both ESM and CommonJS\n      const resolved = jitiLoader.esmResolve(configPath, { try: true });\n      if (!resolved) {\n        throw new Error(`Could not resolve config file: ${configPath}`);\n      }\n\n      const resolvedPath = typeof resolved === 'string' ? resolved : fileURLToPath(resolved);\n      loaded = await jitiLoader.import(resolvedPath);\n    } catch (error) {\n      throw new Error(`Syntax error: ${error instanceof Error ? error.message : String(error)}`, { cause: error });\n    }\n\n    let config: unknown;\n    if (loaded && typeof loaded === 'object' && '__esModule' in loaded) {\n      config = (loaded as Record<string, unknown>).default;\n    } else if (loaded && typeof loaded === 'object' && 'default' in loaded) {\n      config = (loaded as Record<string, unknown>).default;\n    } else {\n      config = loaded;\n    }\n\n    if (config === null || config === undefined) {\n      return {};\n    }\n\n    if (typeof config === 'function') {\n      try {\n        config = config();\n      } catch (error) {\n        throw new Error(`Error executing config function: ${error instanceof Error ? error.message : String(error)}`, {\n          cause: error,\n        });\n      }\n\n      // Don't support async configs\n      if (config instanceof Promise) {\n        throw new Error('Async config functions are not supported');\n      }\n\n      if (config === null || config === undefined) {\n        return {};\n      }\n    }\n\n    if (config && typeof config !== 'object') {\n      throw new Error('Config must be an object');\n    }\n\n    return config ?? {};\n  }\n}\n","export class TestDinoError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = 'TestDinoError';\n    Error.captureStackTrace(this, this.constructor);\n  }\n}\n\nexport class TokenMissingError extends TestDinoError {\n  constructor() {\n    const message = `Token is required to run tests with TestDino\n\nProvide token via:\n  • CLI flag:    npx tdpw test --token <your-token>\n  • Environment: export TESTDINO_TOKEN=<your-token>\n  • Config file: testdino.config.ts with token: process.env.TESTDINO_TOKEN\n\nGet your token at: https://testdino.com/settings`;\n\n    super(message);\n    this.name = 'TokenMissingError';\n  }\n}\n\nexport class ConfigSyntaxError extends TestDinoError {\n  constructor(configPath: string, originalError: Error) {\n    const message = `Failed to load ${configPath}\n\n${originalError.message}\n\nFix the syntax error and try again.`;\n\n    super(message);\n    this.name = 'ConfigSyntaxError';\n  }\n}\n\nexport class InvalidSplitFlagError extends TestDinoError {\n  constructor(value: string) {\n    const message = `Invalid --split value: ${value}\n\n--split must be <current>/<total> with positive integers and current <= total.\n\nExamples:\n  • --split 1/5\n  • --split 3/3`;\n\n    super(message);\n    this.name = 'InvalidSplitFlagError';\n  }\n}\n\nexport class InvalidMachineCountError extends TestDinoError {\n  constructor(value?: string) {\n    const seen = value === undefined ? '' : `: ${value}`;\n    const message = `Invalid machine count${seen}\n\nThe number of machines is required and must be a positive integer.\n\nProvide it via:\n  • CLI flag:    npx tdpw swarm --machines <N>\n  • Environment: export TESTDINO_MACHINES=<N>\n\nExample:\n  • --machines 4`;\n\n    super(message);\n    this.name = 'InvalidMachineCountError';\n  }\n}\nexport class SplitConfigMismatchError extends TestDinoError {\n  constructor() {\n    const message = `Split mode requires both a position (--split) and a group id (--split-id or TESTDINO_SPLIT_ID)\n\nProvide both:\n  • npx tdpw test --split 1/5 --split-id <group-id>\n  • or set the id from the environment:  TESTDINO_SPLIT_ID=<group-id> npx tdpw test --split 1/5\n\nThe group id must be unique per pipeline execution so separate runs do not merge.`;\n\n    super(message);\n    this.name = 'SplitConfigMismatchError';\n  }\n}\n\nexport class SwarmSplitConflictError extends TestDinoError {\n  constructor() {\n    super(\n      `Swarm and manual-split modes are mutually exclusive — a run cannot carry both a swarm id and a split id. Use one grouping mode per run.`\n    );\n    this.name = 'SwarmSplitConflictError';\n  }\n}\n\nexport class NoTestsDiscoveredError extends TestDinoError {\n  constructor(grep?: string, project?: string[]) {\n    const applied = [grep ? `--grep ${grep}` : '', project?.length ? `--project ${project.join(',')}` : '']\n      .filter(Boolean)\n      .join(' ');\n    const message = `No tests matched discovery${applied ? ` for ${applied}` : ''}\n\nCheck your filters and that Playwright can collect tests in this directory.`;\n\n    super(message);\n    this.name = 'NoTestsDiscoveredError';\n  }\n}\n\nexport class DiscoveryFailedError extends TestDinoError {\n  constructor(detail: string) {\n    const message = `Failed to list tests via Playwright\n\n${detail}\n\nEnsure @playwright/test is installed and your Playwright config compiles:\n  • npm install -D @playwright/test`;\n\n    super(message);\n    this.name = 'DiscoveryFailedError';\n  }\n}\n\nexport class RerunSplitConflictError extends TestDinoError {\n  constructor(source: string) {\n    const message = `A re-run cannot be combined with split mode (${source})\n\nA re-run is a single run of the selected tests. Drop the split flags:\n  • npx tdpw test --rerun failed --from-run <runId>`;\n\n    super(message);\n    this.name = 'RerunSplitConflictError';\n  }\n}\n\nexport class InvalidServerUrlError extends TestDinoError {\n  constructor(url: string) {\n    const message = `Invalid server URL: ${url}\n\nServer URL must be a valid HTTP or HTTPS URL.\n\nExample:\n  • https://reporter.testdino.com`;\n\n    super(message);\n    this.name = 'InvalidServerUrlError';\n  }\n}\n","import { existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { createJiti } from 'jiti';\nimport type { TestdinoConfig } from '../types/index.js';\nimport { ConfigSyntaxError } from './errors.js';\n\nconst PLAYWRIGHT_CONFIG_FILENAMES = ['playwright.config.ts', 'playwright.config.js'];\nconst TESTDINO_REPORTER_NAMES = ['@testdino/playwright', 'testdino-playwright', 'TestdinoReporter'];\n\nexport interface ConfigDetectionResult {\n  hasReporter: boolean;\n  options?: TestdinoConfig;\n  configPath?: string;\n  // Read straight from the Playwright config file; may differ from the runtime\n  // effective values if the run overrides them via --workers / PLAYWRIGHT_WORKERS.\n  workers?: number;\n  fullyParallel?: boolean;\n}\n\ninterface PlaywrightConfig {\n  reporter?: ReporterConfig;\n  [key: string]: unknown;\n}\n\ntype ReporterConfig = string | [string, Record<string, unknown>?] | Array<string | [string, Record<string, unknown>?]>;\n\nexport class ConfigDetector {\n  private cwd: string;\n\n  constructor(cwd: string = process.cwd()) {\n    this.cwd = cwd;\n  }\n\n  async detect(): Promise<ConfigDetectionResult> {\n    const configPath = this.findPlaywrightConfig();\n\n    if (!configPath) {\n      return { hasReporter: false };\n    }\n\n    try {\n      const config = await this.loadPlaywrightConfig(configPath);\n      const result = this.extractTestdinoReporter(config);\n\n      // A percentage ('50%') cannot resolve to a per-machine count at discover time\n      // (the run machines' CPU count is unknown), so it is left unset to warn+default.\n      const workersInt = typeof config.workers === 'number' && Number.isInteger(config.workers) && config.workers >= 1;\n      return {\n        ...result,\n        configPath,\n        ...(workersInt ? { workers: config.workers as number } : {}),\n        ...(typeof config.fullyParallel === 'boolean' ? { fullyParallel: config.fullyParallel } : {}),\n      };\n    } catch (error) {\n      throw new ConfigSyntaxError(configPath, error instanceof Error ? error : new Error(String(error)));\n    }\n  }\n\n  private findPlaywrightConfig(): string | undefined {\n    for (const filename of PLAYWRIGHT_CONFIG_FILENAMES) {\n      const configPath = join(this.cwd, filename);\n      if (existsSync(configPath)) {\n        return configPath;\n      }\n    }\n    return undefined;\n  }\n\n  private async loadPlaywrightConfig(configPath: string): Promise<PlaywrightConfig> {\n    const jitiLoader = createJiti(dirname(configPath), {\n      interopDefault: true,\n      fsCache: false,\n      extensions: ['.ts', '.js'],\n    });\n\n    let loaded: unknown;\n    try {\n      const resolved = jitiLoader.esmResolve(configPath, { try: true });\n      if (!resolved) {\n        throw new Error(`Could not resolve Playwright config: ${configPath}`);\n      }\n\n      const resolvedPath = typeof resolved === 'string' ? resolved : fileURLToPath(resolved);\n      loaded = await jitiLoader.import(resolvedPath);\n    } catch (error) {\n      throw new Error(`Syntax error: ${error instanceof Error ? error.message : String(error)}`, { cause: error });\n    }\n\n    let config: unknown;\n    if (loaded && typeof loaded === 'object' && '__esModule' in loaded) {\n      config = (loaded as Record<string, unknown>).default;\n    } else if (loaded && typeof loaded === 'object' && 'default' in loaded) {\n      config = (loaded as Record<string, unknown>).default;\n    } else {\n      config = loaded;\n    }\n\n    if (typeof config === 'function') {\n      try {\n        config = config();\n      } catch (error) {\n        throw new Error(`Error executing config function: ${error instanceof Error ? error.message : String(error)}`, {\n          cause: error,\n        });\n      }\n    }\n\n    if (!config || typeof config !== 'object') {\n      throw new Error('Playwright config must be an object');\n    }\n\n    return config as PlaywrightConfig;\n  }\n\n  private extractTestdinoReporter(config: PlaywrightConfig): Omit<ConfigDetectionResult, 'configPath'> {\n    const { reporter } = config;\n\n    if (!reporter) {\n      return { hasReporter: false };\n    }\n\n    if (typeof reporter === 'string') {\n      if (this.isTestdinoReporter(reporter)) {\n        return { hasReporter: true, options: {} };\n      }\n      return { hasReporter: false };\n    }\n\n    if (Array.isArray(reporter) && reporter.length > 0) {\n      if (typeof reporter[0] === 'string') {\n        const [name, options] = reporter as [string, Record<string, unknown>?];\n        if (this.isTestdinoReporter(name)) {\n          return {\n            hasReporter: true,\n            options: this.extractOptions(options),\n          };\n        }\n        // this is a single [name, options] tuple — not an array of reporters.\n        if (!Array.isArray(reporter[1])) {\n          return { hasReporter: false };\n        }\n        // reporter[1] is an array → this is an array-of-reporters, fall through to scan\n      }\n\n      for (const item of reporter) {\n        if (typeof item === 'string') {\n          if (this.isTestdinoReporter(item)) {\n            return { hasReporter: true, options: {} };\n          }\n        } else if (Array.isArray(item) && item.length > 0) {\n          const [name, options] = item as [string, Record<string, unknown>?];\n          if (this.isTestdinoReporter(name)) {\n            return {\n              hasReporter: true,\n              options: this.extractOptions(options),\n            };\n          }\n        }\n      }\n    }\n\n    return { hasReporter: false };\n  }\n\n  private isTestdinoReporter(name: string): boolean {\n    return TESTDINO_REPORTER_NAMES.some((testdinoName) => name === testdinoName || name.includes(testdinoName));\n  }\n\n  private extractOptions(options?: Record<string, unknown>): TestdinoConfig {\n    if (!options || typeof options !== 'object') {\n      return {};\n    }\n\n    const config: TestdinoConfig = {};\n\n    if ('token' in options && typeof options.token === 'string') {\n      config.token = options.token;\n    }\n\n    if ('serverUrl' in options && typeof options.serverUrl === 'string') {\n      config.serverUrl = options.serverUrl;\n    }\n\n    if ('ciRunId' in options && typeof options.ciRunId === 'string') {\n      config.ciRunId = options.ciRunId;\n    }\n\n    if ('debug' in options && typeof options.debug === 'boolean') {\n      config.debug = options.debug;\n    }\n\n    return config;\n  }\n}\n","import { randomUUID } from 'crypto';\nimport type { CliOptions, MergedConfig, ConfigFileContent } from './types.js';\nimport type { TestdinoConfig } from '../types/index.js';\nimport {\n  TokenMissingError,\n  InvalidServerUrlError,\n  InvalidSplitFlagError,\n  SplitConfigMismatchError,\n  SwarmSplitConflictError,\n} from './errors.js';\nimport { DEFAULT_SERVER_URL } from '../types/index.js';\n\n// TESTDINO_RERUN_TAGS is not a reporter option, so it rides beside the config.\nexport type EnvConfig = Partial<TestdinoConfig> & { rerunTags?: string[] };\n\nexport interface ConfigSources {\n  env?: EnvConfig;\n  playwrightConfig?: TestdinoConfig;\n  testdinoConfig?: ConfigFileContent;\n  cliOptions?: CliOptions;\n}\n\n// Parses a `--split` value (\"current/total\"). CLI-flag-only (like --shard) — no env source.\nexport function parseSplitFlag(raw: string): { current: number; total: number } {\n  const match = /^(\\d+)\\/(\\d+)$/.exec(raw.trim());\n  if (!match) {\n    throw new InvalidSplitFlagError(raw);\n  }\n  const current = Number(match[1]);\n  const total = Number(match[2]);\n  if (current < 1 || total < 1 || current > total) {\n    throw new InvalidSplitFlagError(raw);\n  }\n  return { current, total };\n}\n\nexport class ConfigMerger {\n  merge(sources: ConfigSources): MergedConfig {\n    const { env = {}, playwrightConfig = {}, testdinoConfig = {}, cliOptions = {} } = sources;\n\n    // Merge token (required field)\n    const token = this.selectValue(cliOptions.token, testdinoConfig.token, playwrightConfig.token, env.token);\n\n    // Merge serverUrl with default fallback\n    const serverUrl =\n      this.selectValue(cliOptions.serverUrl, testdinoConfig.serverUrl, playwrightConfig.serverUrl, env.serverUrl) ||\n      DEFAULT_SERVER_URL;\n\n    // Merge ciRunId (auto-generate if not provided)\n    const ciRunId =\n      this.selectValue(cliOptions.ciRunId, testdinoConfig.ciRunId, playwrightConfig.ciRunId, env.ciRunId) ||\n      this.generateCiRunId();\n\n    // Merge debug flag (default to false)\n    const debug = this.selectValue(cliOptions.debug, testdinoConfig.debug, playwrightConfig.debug, env.debug) ?? false;\n\n    // Merge artifacts flag (default to true)\n    // CLI --no-artifacts sets artifacts=false via Commander's boolean negation\n    const artifacts =\n      cliOptions.artifacts !== undefined\n        ? cliOptions.artifacts\n        : (this.selectValue(testdinoConfig.artifacts, playwrightConfig.artifacts) ?? true);\n\n    // Merge run-level tags — first source that yields a non-empty array wins\n    const baseTags =\n      this.normalizeTags(cliOptions.tags) ??\n      this.normalizeTags(testdinoConfig.tags) ??\n      this.normalizeTags(playwrightConfig.tags) ??\n      this.normalizeTags(env.tags);\n    // Re-run tags are appended, not a source: the workflow's own tags must survive.\n    const rerunTags =\n      cliOptions.rerun !== undefined\n        ? (this.normalizeTags(cliOptions.rerunTags) ?? this.normalizeTags(env.rerunTags))\n        : undefined;\n    const tags = rerunTags ? this.normalizeTags([...(baseTags ?? []), ...rerunTags]) : baseTags;\n\n    // Split position is CLI-flag-only (like --shard): dynamic per job. The group\n    // id is a correlation key like ciRunId, resolved from every source.\n    const split = cliOptions.split !== undefined ? parseSplitFlag(cliOptions.split) : undefined;\n    // Swarm ids are CLI-internal only — never resolved from config/env.\n    const swarmId = cliOptions.swarmId;\n    const runId = cliOptions.runId;\n    const machineId = cliOptions.machineId;\n    // Only an explicit --split-id conflicts with swarm; a stale ambient\n    // TESTDINO_SPLIT_ID on a CI runner must not abort every swarm run.\n    const splitId = swarmId\n      ? cliOptions.splitId\n      : this.selectValue(cliOptions.splitId, testdinoConfig.splitId, playwrightConfig.splitId, env.splitId);\n\n    const mergedConfig: MergedConfig = {\n      token,\n      serverUrl,\n      ciRunId,\n      debug,\n      artifacts,\n      ...(tags ? { tags } : {}),\n      ...(split ? { split } : {}),\n      ...(splitId ? { splitId } : {}),\n      ...(swarmId ? { swarmId } : {}),\n      ...(runId ? { runId } : {}),\n      ...(machineId ? { machineId } : {}),\n    };\n\n    this.validate(mergedConfig);\n\n    return mergedConfig;\n  }\n\n  // A blank string is treated as absent, not as a value. Otherwise a higher-priority\n  // `--server-url \"\"` masks a valid lower-priority serverUrl and silently routes the\n  // run to the built-in default instead of the server the user configured.\n  private selectValue<T>(...values: (T | undefined | null)[]): T | undefined {\n    return values.find(\n      (value): value is T =>\n        value !== undefined && value !== null && !(typeof value === 'string' && value.trim() === '')\n    );\n  }\n\n  private normalizeTags(input: string | string[] | undefined | null): string[] | undefined {\n    if (input === undefined || input === null) return undefined;\n    const raw = typeof input === 'string' ? input.split(',') : input;\n    const seen = new Set<string>();\n    const out: string[] = [];\n    for (const item of raw) {\n      if (typeof item !== 'string') continue;\n      const t = item.trim();\n      if (!t || seen.has(t)) continue;\n      seen.add(t);\n      out.push(t);\n    }\n    return out.length > 0 ? out : undefined;\n  }\n\n  private generateCiRunId(): string {\n    return `run-${randomUUID()}`;\n  }\n\n  private validate(config: MergedConfig): void {\n    // Token is required - throw specific error\n    if (!config.token || typeof config.token !== 'string' || config.token.trim().length === 0) {\n      throw new TokenMissingError();\n    }\n\n    // ServerUrl must be valid if provided - throw specific error\n    if (config.serverUrl) {\n      if (typeof config.serverUrl !== 'string' || !this.isValidUrl(config.serverUrl)) {\n        throw new InvalidServerUrlError(config.serverUrl);\n      }\n    }\n\n    // Split mode needs both the position and the group id, or neither. A blank\n    // splitId was already dropped in merge(), so presence here means a real value.\n    const hasSplit = config.split !== undefined;\n    const hasSplitId = config.splitId !== undefined;\n    if (hasSplit !== hasSplitId) {\n      throw new SplitConfigMismatchError();\n    }\n\n    // Swarm and split are mutually exclusive group keys — ingestion rejects\n    // a run:begin carrying both. Fail fast here, before a temp-config with the\n    // invalid pair is written and a Playwright child spawned.\n    if (config.swarmId !== undefined && hasSplitId) {\n      throw new SwarmSplitConflictError();\n    }\n\n    // and don't need user-facing error messages\n  }\n\n  private isValidUrl(urlString: string): boolean {\n    try {\n      const url = new URL(urlString);\n      return url.protocol === 'http:' || url.protocol === 'https:';\n    } catch {\n      return false;\n    }\n  }\n\n  static getEnvConfig(): EnvConfig {\n    const config: EnvConfig = {};\n\n    if (process.env.TESTDINO_TOKEN) {\n      config.token = process.env.TESTDINO_TOKEN;\n    }\n\n    if (process.env.TESTDINO_SERVER_URL) {\n      config.serverUrl = process.env.TESTDINO_SERVER_URL;\n    }\n\n    if (process.env.TESTDINO_CI_RUN_ID) {\n      config.ciRunId = process.env.TESTDINO_CI_RUN_ID;\n    }\n\n    // Group id only — the split position (TESTDINO_SPLIT) is deliberately CLI-only, like --shard.\n    if (process.env.TESTDINO_SPLIT_ID) {\n      config.splitId = process.env.TESTDINO_SPLIT_ID;\n    }\n\n    if (process.env.TESTDINO_DEBUG) {\n      config.debug = process.env.TESTDINO_DEBUG === 'true' || process.env.TESTDINO_DEBUG === '1';\n    }\n\n    if (process.env.TESTDINO_TAGS) {\n      // Raw CSV; normalization happens in merge()\n      config.tags = process.env.TESTDINO_TAGS.split(',');\n    }\n\n    if (process.env.TESTDINO_RERUN_TAGS) {\n      config.rerunTags = process.env.TESTDINO_RERUN_TAGS.split(',');\n    }\n\n    return config;\n  }\n}\n","export const DEFAULT_SERVER_URL = 'https://reporter.testdino.com';\n\nimport type { CompleteMetadata } from '../metadata/types.js';\n\nexport type {\n  CompleteMetadata as RunMetadata,\n  GitMetadata,\n  CIMetadata,\n  PRMetadata,\n  SystemMetadata,\n  PlaywrightMetadata,\n  ShardMetadata,\n  MetadataCollectionResult,\n  MetadataCollectionSummary,\n  MetadataCollector,\n} from '../metadata/types.js';\n\nexport type { QuotaExhaustedError, QuotaExceededError, ServerError } from '../reporter/errors.js';\nexport type { SessionCreationQuotaResponse, NackMessage } from './errors.js';\n\nexport interface TestdinoConfig {\n  token?: string;\n  ciRunId?: string;\n  // Manual-split group id — correlation key like ciRunId (CLI flag, testdino.config, reporter opts, or TESTDINO_SPLIT_ID env). The split position stays CLI-only.\n  splitId?: string;\n  // Swarm id — set only by `tdpw swarm --id` (CLI flag, threaded to the reporter via temp-config). Mutually exclusive with splitId.\n  swarmId?: string;\n  serverUrl?: string;\n  debug?: boolean;\n  artifacts?: boolean;\n  tags?: string[];\n}\n\nexport type TestEvent =\n  | TestRunBeginEvent\n  | TestBeginEvent\n  | TestStepBeginEvent\n  | TestStepEndEvent\n  | TestEndEvent\n  | TestRunEndEvent\n  | TestRunErrorEvent\n  | TestConsoleOutEvent\n  | TestConsoleErrEvent\n  | RunHeartbeatEvent;\n\nexport interface Annotation {\n  type: string;\n  description?: string;\n}\n\nexport interface BaseEvent {\n  type: string;\n  timestamp: number;\n  runId: string;\n  sequence: number;\n}\n\nexport interface TestRunBeginEvent extends BaseEvent {\n  type: 'run:begin';\n  projectId: string;\n  metadata: CompleteMetadata;\n  ciRunId?: string;\n  shard?: {\n    current: number;\n    total: number;\n  };\n  splitId?: string;\n  swarmId?: string;\n  // machineId: the reporting machine under swarm; ingestion stamps it on every case for attribution.\n  machineId?: string;\n  split?: {\n    current: number;\n    total: number;\n  };\n  tags?: string[];\n  // The run whose failed/flaky selection this run re-executes.\n  rerunOf?: string;\n}\n\nexport interface TestBeginEvent extends BaseEvent {\n  type: 'test:begin';\n  testId: string;\n  title: string;\n  titlePath: Array<string>;\n  location: {\n    file: string;\n    line: number;\n    column: number;\n  };\n  tags: Array<string>;\n  expectedStatus: 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted';\n  timeout: number;\n  retries: number;\n  annotations: Array<Annotation>;\n  retry: number;\n  workerIndex: number;\n  parallelIndex: number;\n  repeatEachIndex?: number;\n  parentSuite: {\n    title: string;\n    type: 'root' | 'project' | 'file' | 'describe';\n    location?: {\n      file: string;\n      line: number;\n      column: number;\n    };\n  };\n  startTime: number;\n}\n\nexport interface TestStepBeginEvent extends BaseEvent {\n  type: 'step:begin';\n  testId: string;\n  stepId: string;\n  title: string;\n  titlePath: Array<string>;\n  category: string;\n  location?: {\n    file: string;\n    line: number;\n    column: number;\n  };\n  parentStep?: {\n    title: string;\n    category: string;\n    location?: {\n      file: string;\n      line: number;\n      column: number;\n    };\n  };\n  startTime: number;\n  retry: number;\n  workerIndex: number;\n  parallelIndex: number;\n  annotations: Array<Annotation>;\n}\n\nexport interface TestStepEndEvent extends BaseEvent {\n  type: 'step:end';\n  testId: string;\n  stepId: string;\n  title?: string;\n  titlePath?: string[];\n  duration: number;\n  error?: {\n    message: string;\n    stack?: string;\n    snippet?: string;\n    value?: string;\n    location?: {\n      file: string;\n      line: number;\n      column: number;\n    };\n  };\n  status: 'passed' | 'failed';\n  childSteps: {\n    count: number;\n    steps: Array<{\n      title: string;\n      status: 'passed' | 'failed';\n    }>;\n  };\n  workerIndex: number;\n  parallelIndex: number;\n  // step attachments never carry path — would leak local FS.\n  attachments: Array<{\n    name: string;\n    contentType: string;\n  }>;\n  annotations?: Array<Annotation>;\n  retry: number;\n}\n\nexport interface TestEndEvent extends BaseEvent {\n  type: 'test:end';\n  testId: string;\n  status: 'passed' | 'failed' | 'skipped' | 'timedOut' | 'interrupted';\n  outcome: 'expected' | 'unexpected' | 'flaky' | 'skipped';\n  duration: number;\n  retry: number;\n  workerIndex: number;\n  parallelIndex: number;\n  annotations: Array<Annotation>;\n  errors: Array<{\n    message: string;\n    stack?: string;\n    snippet?: string;\n    value?: string;\n    location?: {\n      file: string;\n      line: number;\n      column: number;\n    };\n  }>;\n  steps: {\n    total: number;\n    passed: number;\n    failed: number;\n  };\n  // Three mutually-exclusive states: uploaded (blobKey) / failed (unavailable) / in-memory (excluded upstream).\n  // path never emitted — non-dereferenceable + PII.\n  attachments: Array<{\n    name: string;\n    contentType: string;\n    blobKey?: string;\n    unavailable?: boolean;\n  }>;\n  stdout?: string[];\n  stderr?: string[];\n}\n\nexport interface TestRunEndEvent extends BaseEvent {\n  type: 'run:end';\n  status: 'passed' | 'failed' | 'timedout' | 'interrupted';\n  duration: number;\n  startTime: number;\n  shard?: {\n    current: number;\n    total: number;\n  };\n  splitId?: string;\n  swarmId?: string;\n  // machineId: the reporting machine under swarm; ingestion stamps it on every case for attribution.\n  machineId?: string;\n  split?: {\n    current: number;\n    total: number;\n  };\n  // Test Controls: what this process did with the quarantine list. Absent from\n  // reporters that predate it; the server then stores no quarantine state.\n  quarantine?: RunQuarantineBlock;\n  // Tests this process brought to a final verdict, plus attempts still open at\n  // interruption. The server compares its recorded results against this rather\n  // than the run:begin skeleton, which cannot tell a short run from lost events.\n  executedTests?: number;\n  // Set when the run failed before its first test began (global setup or test\n  // loading failed), so its run:begin declared no tests although some were meant\n  // to run. Absent otherwise.\n  notStarted?: true;\n}\n\n/** GET /api/v1/reporter/quarantine — Playwright test ids per Test Controls rule. */\nexport interface QuarantineList {\n  quarantined: string[];\n  knownErrors: { testIds: string[]; pattern: string }[];\n  critical: string[];\n  // One per rule, however many browser variants it expands to. Absent on\n  // servers older than the count.\n  rules?: { quarantined: number; knownErrors: number; critical: number };\n  generatedAt?: string;\n}\n\nexport interface RunQuarantineBlock {\n  state: 'applied' | 'not_applied';\n  reason?: 'unreachable' | 'timeout' | 'not_found';\n  // Quarantined tests that ran here; a known-error test only if it passed or\n  // its failure matched.\n  testIds?: string[];\n  // Critical tests that passed only on retry; the reporter failed the build.\n  criticalFlakyTestIds?: string[];\n  // The build result Test Controls ended with: its override, else Playwright's.\n  // The server cannot rebuild it from counts (an error outside any test is\n  // invisible there).\n  build: 'passed' | 'failed';\n}\n\n// No sequence — not part of event ordering.\nexport interface RunHeartbeatEvent {\n  type: 'run:heartbeat';\n  runId: string;\n  timestamp: number;\n}\n\nexport interface TestRunErrorEvent extends BaseEvent {\n  type: 'run:error';\n  error: {\n    message?: string;\n    stack?: string;\n    value?: string;\n    snippet?: string;\n    location?: {\n      file: string;\n      line: number;\n      column: number;\n    };\n    // v1.49+\n    cause?: {\n      message?: string;\n      stack?: string;\n      value?: string;\n      snippet?: string;\n      location?: {\n        file: string;\n        line: number;\n        column: number;\n      };\n    };\n  };\n}\n\nexport interface TestConsoleOutEvent extends BaseEvent {\n  type: 'console:out';\n  text: string; // Chunk, UTF-8, max 10KB.\n  testId?: string;\n  retry?: number;\n  truncated?: boolean;\n}\n\nexport interface TestConsoleErrEvent extends BaseEvent {\n  type: 'console:err';\n  text: string; // Chunk, UTF-8, max 10KB.\n  testId?: string;\n  retry?: number;\n  truncated?: boolean;\n}\n","// Commander stores --no-artifacts as options.artifacts = false (not options.noArtifacts)\nconst TESTDINO_FLAGS = ['--token', '-t', '--ci-run-id', '--server-url', '--debug', '--no-artifacts'];\n\nconst FLAGS_WITH_VALUES = ['--token', '-t', '--ci-run-id', '--server-url'];\n\nexport class ArgFilter {\n  filter(args: string[]): string[] {\n    const result: string[] = [];\n    let skipNext = false;\n\n    for (let i = 0; i < args.length; i++) {\n      const arg = args[i];\n\n      if (skipNext) {\n        skipNext = false;\n        continue;\n      }\n\n      if (this.isTestdinoFlag(arg)) {\n        if (this.isFlagWithValue(arg) && !arg.includes('=')) {\n          skipNext = true;\n        }\n        continue;\n      }\n\n      // Keep this argument\n      result.push(arg);\n    }\n\n    return result;\n  }\n\n  private isTestdinoFlag(arg: string): boolean {\n    const flagName = arg.split('=')[0];\n    return TESTDINO_FLAGS.includes(flagName);\n  }\n\n  private isFlagWithValue(arg: string): boolean {\n    const flagName = arg.split('=')[0];\n    return FLAGS_WITH_VALUES.includes(flagName);\n  }\n}\n","import { writeFileSync, unlinkSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { tmpdir } from 'os';\nimport { randomUUID } from 'crypto';\nimport type { MergedConfig, TempConfigInfo } from './types.js';\nimport { Logger } from './logger.js';\n\nexport class TempConfigManager {\n  private tempFiles: Set<string> = new Set();\n  private cleanupHandlersRegistered = false;\n  private exitHandler?: () => void;\n  private sigintHandler?: () => void;\n  private sigtermHandler?: () => void;\n  private uncaughtExceptionHandler?: (error: Error) => void;\n  private unhandledRejectionHandler?: (reason: unknown) => void;\n  private logger: Logger;\n\n  constructor(logger?: Logger) {\n    this.logger = logger ?? new Logger();\n  }\n\n  create(config: MergedConfig): TempConfigInfo {\n    const tempPath = this.generateTempPath();\n\n    try {\n      const configJson = JSON.stringify(config, null, 2);\n      writeFileSync(tempPath, configJson, 'utf-8');\n\n      this.tempFiles.add(tempPath);\n\n      if (!this.cleanupHandlersRegistered) {\n        this.registerCleanupHandlers();\n        this.cleanupHandlersRegistered = true;\n      }\n\n      return {\n        path: tempPath,\n        config,\n      };\n    } catch (error) {\n      throw new Error(\n        `Failed to create temp config file: ${tempPath}\\n${error instanceof Error ? error.message : String(error)}`,\n        { cause: error }\n      );\n    }\n  }\n\n  cleanup(tempPath: string): void {\n    try {\n      if (existsSync(tempPath)) {\n        unlinkSync(tempPath);\n      }\n      this.tempFiles.delete(tempPath);\n    } catch {\n      // Log error but don't throw - cleanup should be best-effort\n      this.logger.warn(`Failed to cleanup temp file: ${tempPath}`);\n    }\n  }\n\n  cleanupAll(): void {\n    for (const tempPath of this.tempFiles) {\n      this.cleanup(tempPath);\n    }\n    this.tempFiles.clear();\n    this.removeHandlers();\n  }\n\n  removeHandlers(): void {\n    if (this.exitHandler) {\n      process.removeListener('exit', this.exitHandler);\n    }\n    if (this.sigintHandler) {\n      process.removeListener('SIGINT', this.sigintHandler);\n    }\n    if (this.sigtermHandler) {\n      process.removeListener('SIGTERM', this.sigtermHandler);\n    }\n    if (this.uncaughtExceptionHandler) {\n      process.removeListener('uncaughtException', this.uncaughtExceptionHandler);\n    }\n    if (this.unhandledRejectionHandler) {\n      process.removeListener('unhandledRejection', this.unhandledRejectionHandler);\n    }\n    this.cleanupHandlersRegistered = false;\n  }\n\n  private generateTempPath(): string {\n    const filename = `testdino-config-${randomUUID()}.json`;\n    return join(tmpdir(), filename);\n  }\n\n  private registerCleanupHandlers(): void {\n    // Remove any existing handlers first to prevent listener accumulation\n    this.removeHandlers();\n\n    // Normal exit\n    this.exitHandler = () => {\n      this.cleanupAll();\n    };\n    process.on('exit', this.exitHandler);\n\n    // SIGINT (Ctrl+C)\n    this.sigintHandler = () => {\n      // Remove handler to prevent duplicate calls on repeated Ctrl+C\n      if (this.sigintHandler) {\n        process.removeListener('SIGINT', this.sigintHandler);\n      }\n      // Don't call cleanupAll() or process.exit() here.\n      // Let the spawned Playwright process handle the signal and exit naturally.\n      // The reporter needs time to send the run:end event with status='interrupted'.\n      // Cleanup will happen in TestCommand's finally block after the child exits.\n    };\n    process.on('SIGINT', this.sigintHandler);\n\n    // SIGTERM\n    this.sigtermHandler = () => {\n      // Remove handler to prevent duplicate calls\n      if (this.sigtermHandler) {\n        process.removeListener('SIGTERM', this.sigtermHandler);\n      }\n      // Don't call cleanupAll() or process.exit() - same reasoning as SIGINT\n    };\n    process.on('SIGTERM', this.sigtermHandler);\n\n    // Uncaught exceptions\n    this.uncaughtExceptionHandler = (error: Error) => {\n      this.logger.error('Uncaught exception', error);\n      this.cleanupAll();\n      process.exit(1);\n    };\n    process.on('uncaughtException', this.uncaughtExceptionHandler);\n\n    // Unhandled promise rejections\n    this.unhandledRejectionHandler = (reason: unknown) => {\n      this.logger.error('Unhandled rejection', reason instanceof Error ? reason : undefined);\n      this.cleanupAll();\n      process.exit(1);\n    };\n    process.on('unhandledRejection', this.unhandledRejectionHandler);\n  }\n\n  getTempFiles(): string[] {\n    return Array.from(this.tempFiles);\n  }\n}\n","import chalk from 'chalk';\n\nexport function supportsColor(): boolean {\n  if (process.env.NO_COLOR) return false;\n  if (process.env.FORCE_COLOR) return true;\n  return Boolean(process.stdout.isTTY);\n}\n\nexport const colors = {\n  success: (text: string) => (supportsColor() ? chalk.green(text) : text),\n  error: (text: string) => (supportsColor() ? chalk.red(text) : text),\n  warning: (text: string) => (supportsColor() ? chalk.yellow(text) : text),\n  info: (text: string) => (supportsColor() ? chalk.cyan(text) : text),\n  bold: (text: string) => (supportsColor() ? chalk.bold(text) : text),\n  dim: (text: string) => (supportsColor() ? chalk.dim(text) : text),\n  white: (text: string) => (supportsColor() ? chalk.white(text) : text),\n  gray: (text: string) => (supportsColor() ? chalk.gray(text) : text),\n  blue: (text: string) => (supportsColor() ? chalk.blue(text) : text),\n  url: (text: string) => (supportsColor() ? chalk.blue.underline(text) : text),\n};\n\nexport const symbols = {\n  success: '\\u2713', // ✓\n  error: '\\u2716', // ✖\n  warning: '!',\n  info: 'i',\n  debug: '[debug]',\n  bullet: '\\u2022', // •\n  pointer: '\\u276F', // ❯\n  line: '\\u2500', // ─\n};\n\n// Chalk emits SGR sequences only; this is not a full ECMA-48 parser.\nconst ESC = String.fromCharCode(27);\nconst ANSI_PATTERN = `${ESC}\\\\[[0-9;]*[a-zA-Z]`;\nconst ANSI_GLOBAL = new RegExp(ANSI_PATTERN, 'g');\nconst ANSI_SEQUENCE = new RegExp(`^${ANSI_PATTERN}`);\n\nexport function stripAnsi(str: string): string {\n  return str.replace(ANSI_GLOBAL, '');\n}\n\nexport function pad(str: string, len: number): string {\n  const vLen = stripAnsi(str).length;\n  return vLen >= len ? str : str + ' '.repeat(len - vLen);\n}\n\n// Terminal display columns, not UTF-16 code units. A CJK commit subject measured\n// by .length renders at twice its measured width and pushes the box border out.\nexport function visibleWidth(str: string): number {\n  let width = 0;\n  for (const ch of stripAnsi(str)) {\n    const cp = ch.codePointAt(0)!;\n    if (isZeroWidth(cp)) continue;\n    width += isWide(cp) ? 2 : 1;\n  }\n  return width;\n}\n\nfunction isZeroWidth(cp: number): boolean {\n  // Combining marks and zero-width joiners/selectors occupy no column of their own.\n  return (\n    (cp >= 0x0300 && cp <= 0x036f) || (cp >= 0x200b && cp <= 0x200f) || cp === 0xfeff || (cp >= 0xfe00 && cp <= 0xfe0f)\n  );\n}\n\nfunction isWide(cp: number): boolean {\n  return (\n    (cp >= 0x1100 && cp <= 0x115f) ||\n    (cp >= 0x2e80 && cp <= 0xa4cf) ||\n    (cp >= 0xac00 && cp <= 0xd7a3) ||\n    (cp >= 0xf900 && cp <= 0xfaff) ||\n    (cp >= 0xfe30 && cp <= 0xfe6f) ||\n    (cp >= 0xff00 && cp <= 0xff60) ||\n    (cp >= 0xffe0 && cp <= 0xffe6) ||\n    (cp >= 0x1f300 && cp <= 0x1faff) ||\n    (cp >= 0x20000 && cp <= 0x3fffd)\n  );\n}\n\n// Pads like pad(), but also truncates when the visible content overruns `len`.\n// A fixed-width box row must never exceed its budget or the border is pushed out.\nexport function fit(str: string, len: number): string {\n  if (len <= 0) return '';\n  const vLen = visibleWidth(str);\n  if (vLen === len) return str;\n  if (vLen < len) return str + ' '.repeat(len - vLen);\n\n  // Iterate by code point so a surrogate pair is copied or dropped whole; a split\n  // pair would emit a lone surrogate and still miscount the column.\n  let out = '';\n  let width = 0;\n  let hasStyle = false;\n  let i = 0;\n  while (i < str.length) {\n    if (str[i] === ESC) {\n      const match = ANSI_SEQUENCE.exec(str.slice(i));\n      if (match) {\n        out += match[0];\n        hasStyle = true;\n        i += match[0].length;\n        continue;\n      }\n    }\n    const ch = String.fromCodePoint(str.codePointAt(i)!);\n    const cw = visibleWidth(ch);\n    if (width + cw > len - 1) {\n      out += '\\u2026';\n      break;\n    }\n    out += ch;\n    width += cw;\n    i += ch.length;\n  }\n  // Reset styling so a truncated color cannot leak into the border.\n  return hasStyle ? `${out}${ESC}[0m` : out;\n}\n\ninterface BoxOptions {\n  borderColor?: 'green' | 'red' | 'yellow' | 'cyan' | 'white';\n  title?: string;\n  padding?: number;\n}\n\nexport function box(content: string[], options: BoxOptions = {}): string {\n  if (content.length === 0 && !options.title) return '';\n\n  const { padding = 1, borderColor = 'white', title } = options;\n\n  const maxContentWidth = Math.max(\n    0,\n    ...content.map((line) => stripAnsi(line).length),\n    title ? stripAnsi(title).length : 0\n  );\n  const boxWidth = maxContentWidth + padding * 2 + 2;\n\n  const colorFn =\n    borderColor === 'green'\n      ? colors.success\n      : borderColor === 'red'\n        ? colors.error\n        : borderColor === 'yellow'\n          ? colors.warning\n          : borderColor === 'cyan'\n            ? colors.info\n            : colors.white;\n\n  const lines: string[] = [];\n\n  // Top border with optional title\n  if (title) {\n    const titleText = ` ${title} `;\n    const remainingWidth = boxWidth - 2 - titleText.length;\n    const leftPad = Math.floor(remainingWidth / 2);\n    const rightPad = remainingWidth - leftPad;\n    lines.push(\n      colorFn('\\u250C') +\n        colorFn('\\u2500'.repeat(leftPad)) +\n        colors.bold(titleText) +\n        colorFn('\\u2500'.repeat(rightPad)) +\n        colorFn('\\u2510')\n    );\n  } else {\n    lines.push(colorFn('\\u250C') + colorFn('\\u2500'.repeat(boxWidth - 2)) + colorFn('\\u2510'));\n  }\n\n  // Top padding\n  if (padding > 0) {\n    lines.push(colorFn('\\u2502') + ' '.repeat(boxWidth - 2) + colorFn('\\u2502'));\n  }\n\n  // Content lines\n  for (const line of content) {\n    const lineLength = stripAnsi(line).length;\n    const rightSpace = boxWidth - 2 - padding - lineLength - padding;\n    lines.push(\n      colorFn('\\u2502') + ' '.repeat(padding) + line + ' '.repeat(Math.max(0, rightSpace + padding)) + colorFn('\\u2502')\n    );\n  }\n\n  // Bottom padding\n  if (padding > 0) {\n    lines.push(colorFn('\\u2502') + ' '.repeat(boxWidth - 2) + colorFn('\\u2502'));\n  }\n\n  // Bottom border\n  lines.push(colorFn('\\u2514') + colorFn('\\u2500'.repeat(boxWidth - 2)) + colorFn('\\u2518'));\n\n  return lines.join('\\n');\n}\n\nexport function formatDuration(ms: number): string {\n  if (ms < 1000) return `${ms}ms`;\n  const seconds = ms / 1000;\n  if (seconds < 60) return `${seconds.toFixed(1)}s`;\n  const minutes = Math.floor(seconds / 60);\n  const remainingSeconds = (seconds % 60).toFixed(0);\n  return `${minutes}m ${remainingSeconds}s`;\n}\n\n// OSC 8 makes the text itself clickable in a terminal; CI log viewers do not\n// render it, so there the URL is printed in full, where they link it.\nexport function hyperlink(text: string, url: string): string {\n  if (process.env.CI || process.env.NO_COLOR || !process.stderr.isTTY) return `${text}: ${url}`;\n  return `\\u001b]8;;${url}\\u0007${colors.url(text)}\\u001b]8;;\\u0007`;\n}\n","import axios from 'axios';\nimport { readFileSync, writeFileSync } from 'fs';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { colors } from './ui.js';\nimport { getPackageVersion, UNRESOLVED_VERSION } from './package-version.js';\n\n// The packument root, not /latest: the abbreviated-packument Accept header below is\n// only content-negotiable here, and /latest answers it with HTTP 406.\nconst REGISTRY_URL = 'https://registry.npmjs.org/@testdino%2fplaywright';\nconst CHECK_TIMEOUT_MS = 1500;\nconst PACKAGE_NAME = '@testdino/playwright';\nconst CHANGELOG_URL = 'https://changelog.testdino.com/?type=cli';\n\n// Without this the registry is hit on every single run — once per shard, per retry,\n// per CI job — for a notice that changes at most a few times a year.\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst CACHE_FILE = join(tmpdir(), 'testdino-playwright-update-check.json');\n\ninterface UpdateCache {\n  checkedAt: number;\n  latest: string;\n}\n\nfunction readCachedLatest(): string | undefined {\n  try {\n    const parsed = JSON.parse(readFileSync(CACHE_FILE, 'utf-8')) as Partial<UpdateCache>;\n    if (typeof parsed.checkedAt !== 'number' || typeof parsed.latest !== 'string') return undefined;\n    // A clock moved backwards would otherwise pin a stale entry as fresh forever.\n    const age = Date.now() - parsed.checkedAt;\n    if (age < 0 || age >= CACHE_TTL_MS) return undefined;\n    return parsed.latest;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction writeCachedLatest(latest: string): void {\n  try {\n    const entry: UpdateCache = { checkedAt: Date.now(), latest };\n    writeFileSync(CACHE_FILE, JSON.stringify(entry), 'utf-8');\n  } catch {\n    // A cache that cannot be written just means we check again next run.\n  }\n}\n\n// Shared by the CLI and reporter renderers so the two surfaces cannot drift apart.\nexport function buildUpdateNoticeLines(currentVersion: string, latestVersion: string): string[] {\n  // Pad before coloring, since padEnd on a colored string counts invisible ANSI bytes.\n  const label = (text: string): string => colors.dim(text.padEnd('Current:'.length));\n\n  return [\n    `A new version of ${colors.info(PACKAGE_NAME)} is available`,\n    '',\n    `${label('Current:')} ${colors.error(currentVersion)}`,\n    `${label('Latest:')} ${colors.success(latestVersion)}`,\n    '',\n    'Update with:',\n    `npm install --save-dev ${PACKAGE_NAME}@latest`,\n    '',\n    `Release notes: ${colors.url(CHANGELOG_URL)}`,\n  ];\n}\n\nexport function compareVersions(a: string, b: string): number {\n  const parse = (v: string): number[] =>\n    v\n      .replace(/^v/, '')\n      .split('+')[0]\n      .split('-')[0]\n      .split('.')\n      .map((part) => Number.parseInt(part, 10));\n\n  const left = parse(a);\n  const right = parse(b);\n\n  if (left.some(Number.isNaN) || right.some(Number.isNaN)) return 0;\n\n  for (let i = 0; i < 3; i++) {\n    const diff = (left[i] ?? 0) - (right[i] ?? 0);\n    if (diff !== 0) return diff > 0 ? 1 : -1;\n  }\n  return 0;\n}\n\n// A prerelease (2.1.0-beta.1) must not be told it's behind the stable it precedes.\nfunction isPrerelease(version: string): boolean {\n  return version.includes('-');\n}\n\nexport async function fetchLatestVersion(): Promise<string | undefined> {\n  try {\n    const response = await axios.get(REGISTRY_URL, {\n      timeout: CHECK_TIMEOUT_MS,\n      headers: { Accept: 'application/vnd.npm.install-v1+json' },\n    });\n    const version = (response.data as { 'dist-tags'?: { latest?: unknown } })?.['dist-tags']?.latest;\n    return typeof version === 'string' ? version : undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nexport async function checkForUpdate(currentVersion: string): Promise<string | undefined> {\n  // UNRESOLVED_VERSION means we could not read our own package.json. Comparing it\n  // would report \"Current: 0.0.0\" as a real upgrade on every run.\n  if (currentVersion === UNRESOLVED_VERSION) return undefined;\n  if (isPrerelease(currentVersion)) return undefined;\n\n  const cached = readCachedLatest();\n  const latest = cached ?? (await fetchLatestVersion());\n  if (!latest || isPrerelease(latest)) return undefined;\n  if (!cached) writeCachedLatest(latest);\n\n  return compareVersions(latest, currentVersion) > 0 ? latest : undefined;\n}\n\n// The check runs concurrently with the test run. When the run finishes first,\n// the notice is worth at most a brief wait, never the full request timeout,\n// which would make a fast suite appear to hang after its results are printed.\nconst SETTLE_GRACE_MS = 150;\n\nexport async function awaitUpdateResult(pending: Promise<string | undefined>): Promise<string | undefined> {\n  let timer: ReturnType<typeof setTimeout> | undefined;\n  const grace = new Promise<undefined>((resolve) => {\n    timer = setTimeout(() => resolve(undefined), SETTLE_GRACE_MS);\n    timer.unref?.();\n  });\n\n  try {\n    return await Promise.race([pending.catch(() => undefined), grace]);\n  } finally {\n    clearTimeout(timer);\n  }\n}\n\nexport { getPackageVersion };\n","import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst PACKAGE_NAME = '@testdino/playwright';\nexport const UNRESOLVED_VERSION = '0.0.0';\n\n// Resolves in both the CJS and ESM bundles: import.meta.url is unavailable in one\n// and __dirname in the other, so try each.\nfunction getModuleDir(): string {\n  const metaUrl = typeof import.meta === 'object' ? import.meta?.url : undefined;\n  if (metaUrl) return dirname(fileURLToPath(metaUrl));\n  return __dirname;\n}\n\nexport function getPackageVersion(): string {\n  // dist/index.js and dist/cli/index.mjs sit at different depths under the package root.\n  const candidates = ['../package.json', '../../package.json'];\n\n  for (const candidate of candidates) {\n    try {\n      const raw = readFileSync(join(getModuleDir(), candidate), 'utf-8');\n      const parsed = JSON.parse(raw) as { name?: unknown; version?: unknown };\n      if (parsed.name === PACKAGE_NAME && typeof parsed.version === 'string') {\n        return parsed.version;\n      }\n    } catch {\n      continue;\n    }\n  }\n  return UNRESOLVED_VERSION;\n}\n","import type { Logger as LoggerInterface } from '../utils/logger.js';\nimport { colors, symbols, box } from '../utils/ui.js';\nimport { buildUpdateNoticeLines } from '../utils/update-notifier.js';\n\nexport class Logger implements LoggerInterface {\n  private debugEnabled: boolean;\n\n  constructor(debugEnabled = false) {\n    this.debugEnabled = debugEnabled;\n  }\n\n  setDebug(enabled: boolean): void {\n    this.debugEnabled = enabled;\n  }\n\n  error(message: string, error?: Error): void {\n    console.error(`  ${colors.error(symbols.error)} ${colors.error(message)}`);\n    if (error && this.debugEnabled) {\n      console.error(colors.dim(`  Stack trace:\\n${error.stack || error.message}`));\n    }\n  }\n\n  warn(message: string): void {\n    console.warn(`  ${colors.warning(symbols.warning)} ${colors.warning(message)}`);\n  }\n\n  info(message: string): void {\n    console.log(`  ${colors.info(symbols.info)} ${message}`);\n  }\n\n  success(message: string): void {\n    console.log(`  ${colors.success(symbols.success)} ${message}`);\n  }\n\n  debug(message: string): void {\n    if (this.debugEnabled) {\n      console.log(`  ${colors.dim(symbols.debug)} ${colors.dim(message)}`);\n    }\n  }\n\n  newline(): void {\n    console.log();\n  }\n\n  section(title: string): void {\n    console.log(`\\n${colors.bold(title)}`);\n  }\n\n  listItem(text: string): void {\n    console.log(`  ${colors.dim(symbols.bullet)} ${text}`);\n  }\n\n  code(text: string): void {\n    console.log(colors.gray(`  ${text}`));\n  }\n\n  banner(version: string): void {\n    console.log(\n      box([`TestDino Playwright v${version}`, colors.dim('https://testdino.com')], {\n        borderColor: 'cyan',\n      })\n    );\n    console.log();\n  }\n\n  updateNotice(currentVersion: string, latestVersion: string): void {\n    console.log(box(buildUpdateNoticeLines(currentVersion, latestVersion), { borderColor: 'white' }));\n    console.log();\n  }\n}\n","import { randomUUID } from 'crypto';\nimport { readFileSync, unlinkSync } from 'fs';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { execa, type ExecaError } from 'execa';\nimport type { MergedConfig } from './types.js';\nimport { Logger } from './logger.js';\n\nexport interface PlaywrightSpawnOptions {\n  args: string[];\n  tempConfigPath: string;\n  config: MergedConfig;\n  cwd?: string;\n}\n\nexport interface PlaywrightSpawnResult {\n  exitCode: number;\n  success: boolean;\n  // resultsProduced = the reporter wrote totalTests>0 to the sentinel file. It is\n  // the ack gate for swarm: a batch that produced no results must never be\n  // acked (the backend re-distributes it), or its tests are silently lost.\n  resultsProduced: boolean;\n  totalTests: number;\n}\n\nconst TESTDINO_REPORTER = '@testdino/playwright';\n\n// Playwright keeps only the last --reporter, so a user reporter is merged into\n// one comma-separated value rather than placed before or after ours. Appending\n// is skipped when the value already names ours, or the reporter loads twice and\n// streams two runs for one Playwright invocation.\nfunction withOurs(value: string): string {\n  return value\n    .split(',')\n    .map((reporter) => reporter.trim())\n    .includes(TESTDINO_REPORTER)\n    ? value\n    : `${value},${TESTDINO_REPORTER}`;\n}\n\nexport function withTestdinoReporter(args: string[]): string[] {\n  const merged: string[] = [];\n  let userReporter = false;\n  for (let i = 0; i < args.length; i++) {\n    const arg = args[i];\n    if (arg === '--reporter' && i + 1 < args.length) {\n      merged.push(`--reporter=${withOurs(args[++i])}`);\n      userReporter = true;\n    } else if (arg.startsWith('--reporter=')) {\n      merged.push(`--reporter=${withOurs(arg.slice('--reporter='.length))}`);\n      userReporter = true;\n    } else {\n      merged.push(arg);\n    }\n  }\n  return userReporter ? merged : ['--reporter', TESTDINO_REPORTER, ...merged];\n}\n\nexport class PlaywrightSpawner {\n  private logger: Logger;\n\n  constructor(logger?: Logger) {\n    this.logger = logger ?? new Logger();\n  }\n\n  async spawn(options: PlaywrightSpawnOptions): Promise<PlaywrightSpawnResult> {\n    const { args, tempConfigPath, config, cwd = process.cwd() } = options;\n\n    // The reporter writes { totalTests } here from onEnd; the path is unique per\n    // spawn so concurrent invocations never read each other's sentinel.\n    const resultPath = join(tmpdir(), `testdino-result-${randomUUID()}.json`);\n\n    try {\n      // Build environment variables\n      const env = {\n        ...process.env,\n        TESTDINO_CLI_CONFIG_PATH: tempConfigPath,\n        TESTDINO_TOKEN: config.token,\n        ...(config.serverUrl !== undefined && { TESTDINO_SERVER_URL: config.serverUrl }),\n        ...(config.ciRunId !== undefined && { TESTDINO_CI_RUN_ID: config.ciRunId }),\n        TESTDINO_DEBUG: config.debug ? 'true' : 'false',\n        TESTDINO_RUN_RESULT_PATH: resultPath,\n      };\n\n      const playwrightArgs = ['playwright', 'test', ...withTestdinoReporter(args)];\n\n      // Spawn Playwright with execa\n      const result = await execa('npx', playwrightArgs, {\n        stdio: 'inherit', // Forward stdout/stderr in real-time\n        cwd,\n        env,\n        reject: false, // Don't throw on non-zero exit codes\n      });\n\n      const exitCode = result.exitCode ?? 0;\n      const totalTests = this.readTotalTests(resultPath);\n\n      return {\n        exitCode,\n        success: exitCode === 0,\n        resultsProduced: totalTests > 0,\n        totalTests,\n      };\n    } catch (error) {\n      return this.handleSpawnError(error);\n    } finally {\n      try {\n        unlinkSync(resultPath);\n      } catch {\n        // The reporter may never have written it (spawn failure / globalSetup crash).\n      }\n    }\n  }\n\n  // A missing or corrupt sentinel means the reporter never reached onEnd (globalSetup\n  // crash, immediate spawn failure) — treat that as zero tests produced.\n  private readTotalTests(resultPath: string): number {\n    try {\n      const parsed = JSON.parse(readFileSync(resultPath, 'utf-8')) as { totalTests?: unknown };\n      return typeof parsed.totalTests === 'number' ? parsed.totalTests : 0;\n    } catch {\n      return 0;\n    }\n  }\n\n  private handleSpawnError(error: unknown): PlaywrightSpawnResult {\n    const execaError = error as ExecaError;\n\n    if (execaError.code === 'ENOENT') {\n      this.logger.error('Failed to spawn Playwright');\n      this.logger.newline();\n      this.logger.info('Playwright is not installed or npx is not available.');\n      this.logger.newline();\n      this.logger.section('To install Playwright:');\n      this.logger.code('npm install -D @playwright/test');\n      this.logger.code('npx playwright install');\n      return {\n        exitCode: 1,\n        success: false,\n        resultsProduced: false,\n        totalTests: 0,\n      };\n    }\n\n    if (execaError.code === 'EACCES') {\n      this.logger.error('Permission denied when trying to spawn Playwright');\n      this.logger.newline();\n      this.logger.info('Please check file permissions and try again.');\n      return {\n        exitCode: 1,\n        success: false,\n        resultsProduced: false,\n        totalTests: 0,\n      };\n    }\n\n    // Generic error\n    this.logger.error('Failed to spawn Playwright');\n    this.logger.newline();\n    this.logger.info(`Error: ${execaError.message || String(error)}`);\n    return {\n      exitCode: 1,\n      success: false,\n      resultsProduced: false,\n      totalTests: 0,\n    };\n  }\n}\n","import type { RerunScope, RerunSelection } from './types.js';\n\n// The server writes a run's outcomes asynchronously after finalization —\n// sub-second warm, ~30s on a cold pipeline — so a re-run waits rather than\n// concluding nothing failed. Bounded, so a run that never extracts fails with\n// a message instead of hanging CI.\nconst NOT_READY_BUDGET_MS = 90_000;\nconst NOT_READY_POLL_MS = 2_000;\n// Per request: the budget above only bounds retries, not a stalled socket.\nconst REQUEST_TIMEOUT_MS = 15_000;\n\nexport class RerunSelectionError extends Error {\n  constructor(\n    message: string,\n    readonly code?: string\n  ) {\n    super(message);\n    this.name = 'RerunSelectionError';\n  }\n}\n\nexport interface FetchSelectionOptions {\n  serverUrl: string;\n  token: string;\n  runId: string;\n  scope: RerunScope;\n  testIds?: string[];\n  excludeTestIds?: string[];\n  fetchImpl?: typeof fetch;\n  sleep?: (ms: number) => Promise<void>;\n  now?: () => number;\n}\n\nconst defaultSleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport function rerunSelectionPath(runId: string): string {\n  return `/api/v1/reporter/runs/${encodeURIComponent(runId)}/rerun-selection`;\n}\n\n// Retries only SELECTION_NOT_READY; every other failure is terminal, because\n// re-running the wrong set is worse than stopping.\nexport async function fetchRerunSelection(options: FetchSelectionOptions): Promise<RerunSelection> {\n  const { fetchImpl = fetch, sleep = defaultSleep, now = Date.now } = options;\n  const url = `${options.serverUrl.replace(/\\/+$/, '')}${rerunSelectionPath(options.runId)}`;\n  const body = JSON.stringify({\n    ...(options.testIds?.length ? { testIds: options.testIds } : { scope: options.scope }),\n    ...(options.excludeTestIds?.length ? { excludeTestIds: options.excludeTestIds } : {}),\n  });\n  const deadline = now() + NOT_READY_BUDGET_MS;\n\n  for (;;) {\n    const response = await fetchImpl(url, {\n      method: 'POST',\n      headers: { Authorization: `Bearer ${options.token}`, 'Content-Type': 'application/json' },\n      body,\n      signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n    }).catch((error: unknown) => {\n      throw new RerunSelectionError(\n        `Could not reach ${url}: ${error instanceof Error ? error.message : String(error)}`\n      );\n    });\n    if (response.ok) {\n      return await readSelection(response, url);\n    }\n\n    const code = await readErrorCode(response);\n    if (code === 'SELECTION_NOT_READY' && now() < deadline) {\n      await sleep(NOT_READY_POLL_MS);\n      continue;\n    }\n    throw new RerunSelectionError(describeFailure(response.status, code, options.runId, url), code);\n  }\n}\n\n// A proxy or login page can answer 200 with HTML; this client must never hand\n// Playwright a list it did not look at.\nasync function readSelection(response: Response, url: string): Promise<RerunSelection> {\n  let body: Partial<RerunSelection> | undefined;\n  try {\n    body = (await response.json()) as Partial<RerunSelection>;\n  } catch {\n    body = undefined;\n  }\n  if (!body || !Array.isArray(body.testList) || typeof body.resolution?.selected !== 'number') {\n    throw new RerunSelectionError(`Unexpected response from ${url}: not a re-run selection.`);\n  }\n  return body as RerunSelection;\n}\n\nasync function readErrorCode(response: Response): Promise<string | undefined> {\n  try {\n    const parsed = (await response.json()) as { error?: { code?: string } };\n    return parsed?.error?.code;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction describeFailure(status: number, code: string | undefined, runId: string, url: string): string {\n  // Every refusal this API makes carries an error code. A 5xx without one came\n  // from whatever sits in front of it — a proxy, a Cloudflare tunnel (530), a\n  // load balancer — so naming the URL points at the unreachable server instead\n  // of reading as a verdict about the selection.\n  if (status >= 500 && !code) {\n    return `Could not reach the TestDino API at ${url} (HTTP ${status}). The server, or something in front of it, answered with an error instead of a re-run selection — check the server URL and that the service is up.`;\n  }\n  switch (code) {\n    case 'RUN_NOT_FOUND':\n      return `Run ${runId} is unknown, belongs to another project, or is not accessible with this token.`;\n    case 'RUN_NOT_FINALIZED':\n      return `Run ${runId} has not finished yet, so its failed set is incomplete.`;\n    case 'SELECTION_NOT_READY':\n      return `Run ${runId} finished but its results were never processed within ${NOT_READY_BUDGET_MS / 1000}s. Check the run in TestDino before retrying.`;\n    case 'INVALID_PARAM':\n      return `The re-run selection request for ${runId} was rejected as invalid.`;\n    default:\n      return `Could not resolve the re-run selection for ${runId} (HTTP ${status}${code ? ` ${code}` : ''}).`;\n  }\n}\n","import { readFileSync, unlinkSync, writeFileSync } from 'fs';\nimport { tmpdir } from 'os';\nimport { dirname, join, resolve } from 'path';\nimport { randomUUID } from 'crypto';\n\n// --test-list landed in 1.56.0. Below it the only selector that takes a file\n// needs the config evaluated, and a wrong guess re-runs the WHOLE suite while\n// reporting success.\nexport const MIN_TEST_LIST_VERSION = [1, 56, 0] as const;\n\nconst RERUN_FLAGS = ['--rerun', '--from-run', '--test-ids', '--exclude-ids', '--rerun-tags'];\nconst CONFLICTING_FLAGS = ['--test-list', '--test-list-invert', '--last-failed', '--grep', '-g', '--grep-invert'];\nconst SHARD_FLAG = '--shard';\n\nfunction hasFlag(args: string[], flags: string[]): string | undefined {\n  return args.find((arg) => flags.some((flag) => arg === flag || arg.startsWith(`${flag}=`)));\n}\n\n// Commander does not parse options after `--`; a rerun flag there would reach\n// Playwright as an unknown option, or be dropped, and the whole suite would run.\nexport function misplacedRerunFlag(playwrightArgs: string[]): string | undefined {\n  return hasFlag(playwrightArgs, RERUN_FLAGS);\n}\n\n// A user selector would either be overridden by the selection or silently\n// widen it; neither is safe to guess at.\nexport function conflictingSelector(playwrightArgs: string[]): string | undefined {\n  return hasFlag(playwrightArgs, CONFLICTING_FLAGS);\n}\n\n// Sharding splits by count: a few re-run tests land on one shard and every\n// other shard finds nothing and exits 1 — a red pipeline that ran nothing.\nexport function hasShardFlag(playwrightArgs: string[]): boolean {\n  return hasFlag(playwrightArgs, [SHARD_FLAG]) !== undefined;\n}\n\nexport function parseVersion(raw: string | undefined): [number, number, number] | undefined {\n  const match = raw ? /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(raw.trim()) : null;\n  return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : undefined;\n}\n\n// An unreadable version counts as unsupported: guessing risks the whole-suite\n// failure mode above.\nexport function supportsTestList(raw: string | undefined): boolean {\n  const version = parseVersion(raw);\n  if (!version) return false;\n  for (let i = 0; i < MIN_TEST_LIST_VERSION.length; i++) {\n    if (version[i] > MIN_TEST_LIST_VERSION[i]) return true;\n    if (version[i] < MIN_TEST_LIST_VERSION[i]) return false;\n  }\n  return true;\n}\n\n// Resolved from the project the CLI was invoked in, not from this package's\n// own tree, by walking up: the CLI ships as an ESM bundle where a bare\n// require.resolve throws the same way for \"not installed\".\nexport function readInstalledPlaywrightVersion(cwd: string = process.cwd()): string | undefined {\n  let dir = resolve(cwd);\n  for (;;) {\n    try {\n      const parsed = JSON.parse(\n        readFileSync(join(dir, 'node_modules', '@playwright', 'test', 'package.json'), 'utf-8')\n      ) as {\n        version?: string;\n      };\n      if (typeof parsed.version === 'string' && parsed.version !== '') return parsed.version;\n    } catch {\n      // Not at this level — keep walking.\n    }\n    const parent = dirname(dir);\n    if (parent === dir) return undefined;\n    dir = parent;\n  }\n}\n\n// Lives in the OS temp dir: a file inside the project would be a stale\n// selection a later plain `playwright test --test-list` could pick up.\nexport class SelectionFile {\n  private path?: string;\n\n  write(lines: string[]): string {\n    this.path = join(tmpdir(), `testdino-rerun-${randomUUID()}.txt`);\n    writeFileSync(this.path, `${lines.join('\\n')}\\n`, 'utf-8');\n    return this.path;\n  }\n\n  cleanup(): void {\n    if (!this.path) return;\n    try {\n      unlinkSync(this.path);\n    } catch {\n      // Already reclaimed by the OS.\n    }\n    this.path = undefined;\n  }\n}\n","import { execa } from 'execa';\nimport { mkdtempSync, readFileSync, rmSync } from 'fs';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { TestDinoError } from '../errors.js';\n\nconst LIST_TIMEOUT_MS = 60_000;\n\nexport type ListRunner = (args: string[]) => Promise<string>;\n\n// Ours go last: Playwright keeps the final --reporter, so a user's\n// `--reporter=html` after `--` must not replace the JSON parsed here.\n// The report goes to a file because stdout is shared with anything else the\n// project prints (a dotenvx banner broke JSON.parse). _OUTPUT_FILE wins over\n// _OUTPUT_NAME, so both are set or a user's own _OUTPUT_FILE steals the report;\n// an absolute _OUTPUT_NAME works only because Playwright path.resolve()s it\n// against its output dir, which an absolute path discards.\nexport const defaultListRunner: ListRunner = async (args) => {\n  const dir = mkdtempSync(join(tmpdir(), 'testdino-list-'));\n  const reportPath = join(dir, 'list.json');\n  try {\n    const result = await execa('npx', ['playwright', 'test', ...args, '--list', '--reporter=json'], {\n      timeout: LIST_TIMEOUT_MS,\n      reject: false,\n      stdin: 'ignore',\n      env: { PLAYWRIGHT_JSON_OUTPUT_FILE: reportPath, PLAYWRIGHT_JSON_OUTPUT_NAME: reportPath },\n    });\n    let report = '';\n    try {\n      report = readFileSync(reportPath, 'utf-8');\n    } catch (error) {\n      if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n    }\n    if (report.trim() === '') {\n      const why = result.timedOut ? `timed out after ${LIST_TIMEOUT_MS / 1000}s` : `exit ${result.exitCode}`;\n      throw new Error(`playwright --list produced no report (${why})`);\n    }\n    return report;\n  } finally {\n    rmSync(dir, { recursive: true, force: true });\n  }\n};\n\ninterface ListSuite {\n  specs?: Array<{ id?: string; tests?: unknown[] }>;\n  suites?: ListSuite[];\n}\n\ninterface ListReport {\n  suites?: ListSuite[];\n  errors?: Array<{ message?: string }>;\n  config?: { shard?: { current?: number; total?: number } | null };\n}\n\n// The shard Playwright resolved for this invocation, from --shard or the config\n// file. Read from the list report because the narrowed command appends\n// --shard=1/1, which would otherwise erase the job's identity for the reporter.\nexport function listShard(listJson: string): { current: number; total: number } | undefined {\n  const shard = (JSON.parse(listJson) as ListReport).config?.shard;\n  if (!shard || typeof shard.current !== 'number' || typeof shard.total !== 'number') {\n    return undefined;\n  }\n  return { current: shard.current, total: shard.total };\n}\n\nfunction countReportTests(report: ListReport): number {\n  const walk = (suite: ListSuite): number =>\n    (suite.specs ?? []).reduce((n, spec) => n + (spec.tests ?? []).length, 0) +\n    (suite.suites ?? []).reduce((n, child) => n + walk(child), 0);\n  return (report.suites ?? []).reduce((n, suite) => n + walk(suite), 0);\n}\n\n// A --list spec is one test in one project, and its id is the test id\n// TestDino stores, so ids say WHICH tests matched, not only how many.\nfunction collectTestIds(report: ListReport): string[] {\n  const ids: string[] = [];\n  const walk = (suite: ListSuite): void => {\n    for (const spec of suite.specs ?? []) {\n      if (spec.id && (spec.tests ?? []).length > 0) ids.push(spec.id);\n    }\n    (suite.suites ?? []).forEach(walk);\n  };\n  (report.suites ?? []).forEach(walk);\n  return ids;\n}\n\n// The ids a `--list` report would run; a load error means the list is not\n// the suite, so it throws rather than returning a short list.\nexport function listTestIds(listJson: string): string[] {\n  const report = JSON.parse(listJson) as ListReport;\n  const loadError = report.errors?.[0]?.message;\n  if (loadError) {\n    throw new Error(`Playwright could not load the tests: ${loadError}`);\n  }\n  return collectTestIds(report);\n}\n\nexport interface SelectionMatch {\n  matched: number;\n  ids?: string[];\n  // False when the check could not run; callers must not read that as zero.\n  checked: boolean;\n  reason?: string;\n}\n\n// Playwright proceeds with whatever matched and exits 0 even when nothing\n// did, so the CLI has to compare the selection against this checkout itself.\nexport async function countSelectedTests(\n  selectionPath: string,\n  playwrightArgs: string[],\n  listRunner: ListRunner = defaultListRunner\n): Promise<SelectionMatch> {\n  let report: ListReport;\n  try {\n    report = JSON.parse(await listRunner([...playwrightArgs, `--test-list=${selectionPath}`])) as ListReport;\n  } catch (error) {\n    return { matched: 0, checked: false, reason: error instanceof Error ? error.message : String(error) };\n  }\n  // A spec that fails to load lists nothing and puts the error in the report,\n  // not on stderr; without this it reads as \"every selected test was renamed\".\n  const loadError = report.errors?.[0]?.message;\n  if (loadError) {\n    throw new TestDinoError(`Playwright could not load the selected tests:\\n${loadError}`);\n  }\n  return { matched: countReportTests(report), ids: collectTestIds(report), checked: true };\n}\n","import { relative } from 'path';\n\nexport function normalizePath(filePath: string, rootDir?: string): string {\n  if (rootDir) {\n    // Strip trailing slash so boundary check uses consistent form\n    const root = rootDir.endsWith('/') ? rootDir.slice(0, -1) : rootDir;\n    if (filePath === root || filePath.startsWith(`${root}/`)) {\n      return relative(root, filePath);\n    }\n  }\n  return filePath;\n}\n\nexport function sleep(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function isDebugEnabled(): boolean {\n  return process.env.TESTDINO_DEBUG === 'true' || process.env.TESTDINO_DEBUG === '1';\n}\n\n/** Settles with `fallback` after `ms`; clears its timer so it never holds the process open. */\nexport async function waitAtMost<T, F>(promise: Promise<T>, ms: number, fallback: F): Promise<T | F> {\n  let timer: ReturnType<typeof setTimeout> | undefined;\n  const late = new Promise<F>((resolve) => {\n    timer = setTimeout(() => resolve(fallback), ms);\n  });\n  try {\n    return await Promise.race([promise, late]);\n  } finally {\n    clearTimeout(timer);\n  }\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, operation: string): Promise<T> {\n  let timer: ReturnType<typeof setTimeout> | undefined;\n  const timeoutPromise = new Promise<never>((_, reject) => {\n    timer = setTimeout(() => reject(new Error(`${operation} timed out after ${timeoutMs}ms`)), timeoutMs);\n  });\n  try {\n    return await Promise.race([promise, timeoutPromise]);\n  } finally {\n    clearTimeout(timer);\n  }\n}\n","/**\n * CI metadata collector\n *\n * Collects CI/CD environment information across the major providers. Detection\n * mirrors the standalone testdino-cli precedence so a run reports the same\n * provider regardless of which CLI produced it.\n *\n * Provider env var references:\n * - GitHub Actions: https://docs.github.com/en/actions/reference/workflows-and-actions/variables\n * - GitLab CI:      https://docs.gitlab.com/ci/variables/predefined_variables/\n * - CircleCI:       https://circleci.com/docs/reference/variables/\n * - Jenkins:        https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables\n * - Azure DevOps:   https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables\n * - AWS CodeBuild:  https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html\n * - Bitbucket:      https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/\n * - Buildkite:      https://buildkite.com/docs/pipelines/configure/environment-variables\n * - Harness:        https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables/\n */\n\nimport { type as osType, release as osRelease } from 'os';\nimport { BaseMetadataCollector } from './base.js';\nimport { detectCIProvider } from './detect-ci-provider.js';\nimport type { CIMetadata, GitMetadata, PRMetadata } from './types.js';\n\n/**\n * Provider-specific pipeline + build slice. Environment info is collected once\n * and shared, so providers only resolve the fields that differ between them.\n */\ntype ProviderMetadata = Pick<CIMetadata, 'pipeline' | 'build'>;\n\n/**\n * Collects CI environment metadata\n */\nexport class CIMetadataCollector extends BaseMetadataCollector<CIMetadata> {\n  constructor() {\n    super('ci');\n  }\n\n  /**\n   * Collect CI metadata\n   */\n  protected async collectMetadata(): Promise<CIMetadata> {\n    const provider = detectCIProvider();\n\n    if (!provider) {\n      return {\n        provider: 'local',\n        environment: this.collectEnvironment(),\n      };\n    }\n\n    const { pipeline, build } = this.getProviderMetadata(provider);\n\n    return {\n      provider,\n      pipeline,\n      build,\n      environment: this.collectEnvironment(),\n    };\n  }\n\n  /**\n   * Get empty metadata\n   */\n  protected getEmptyMetadata(): CIMetadata {\n    return {};\n  }\n\n  /**\n   * Route to the provider-specific pipeline/build extractor\n   */\n  private getProviderMetadata(provider: string): ProviderMetadata {\n    switch (provider) {\n      case 'github-actions':\n        return this.getGitHubActionsMetadata();\n      case 'gitlab-ci':\n        return this.getGitLabCIMetadata();\n      case 'circleci':\n        return this.getCircleCIMetadata();\n      case 'jenkins':\n        return this.getJenkinsMetadata();\n      case 'azure-devops':\n        return this.getAzureDevOpsMetadata();\n      case 'aws-codebuild':\n        return this.getAWSCodeBuildMetadata();\n      case 'bitbucket-pipelines':\n        return this.getBitbucketPipelinesMetadata();\n      case 'buildkite':\n        return this.getBuildkiteMetadata();\n      case 'harness':\n        return this.getHarnessMetadata();\n      default:\n        return this.getGenericMetadata();\n    }\n  }\n\n  /**\n   * GitHub Actions pipeline + build\n   */\n  private getGitHubActionsMetadata(): ProviderMetadata {\n    const { env } = process;\n\n    return {\n      pipeline: {\n        id: env.GITHUB_RUN_ID,\n        name: env.GITHUB_WORKFLOW,\n        url: this.buildGitHubPipelineUrl(),\n        attempt: parseRunAttempt(env.GITHUB_RUN_ATTEMPT),\n      },\n      build: {\n        number: env.GITHUB_RUN_NUMBER,\n        trigger: env.GITHUB_EVENT_NAME,\n        // GITHUB_ACTOR stays the first attempt's initiator on a re-run.\n        actor: env.GITHUB_TRIGGERING_ACTOR || env.GITHUB_ACTOR,\n      },\n    };\n  }\n\n  /**\n   * Build the GitHub Actions pipeline URL when all parts are present\n   */\n  private buildGitHubPipelineUrl(): string | undefined {\n    const { env } = process;\n    const { GITHUB_SERVER_URL, GITHUB_REPOSITORY, GITHUB_RUN_ID } = env;\n\n    if (GITHUB_SERVER_URL && GITHUB_REPOSITORY && GITHUB_RUN_ID) {\n      return `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}`;\n    }\n\n    return undefined;\n  }\n\n  /**\n   * GitLab CI pipeline + build\n   */\n  private getGitLabCIMetadata(): ProviderMetadata {\n    const { env } = process;\n\n    return {\n      pipeline: {\n        id: env.CI_PIPELINE_ID,\n        name: this.getGitLabPipelineName(),\n        url: env.CI_PIPELINE_URL,\n      },\n      build: {\n        number: env.CI_JOB_ID || env.CI_PIPELINE_IID,\n        trigger: env.CI_PIPELINE_SOURCE,\n        actor: env.GITLAB_USER_NAME || env.GITLAB_USER_LOGIN,\n      },\n    };\n  }\n\n  /**\n   * Derive a human-readable GitLab pipeline name\n   */\n  private getGitLabPipelineName(): string | undefined {\n    const { CI_PIPELINE_SOURCE, CI_COMMIT_TITLE, CI_PIPELINE_NAME } = process.env;\n\n    if (CI_PIPELINE_SOURCE) return `${CI_PIPELINE_SOURCE} pipeline`;\n\n    return CI_COMMIT_TITLE || CI_PIPELINE_NAME || undefined;\n  }\n\n  /**\n   * CircleCI pipeline + build\n   */\n  private getCircleCIMetadata(): ProviderMetadata {\n    const { env } = process;\n\n    return {\n      pipeline: {\n        id: env.CIRCLE_PIPELINE_ID || env.CIRCLE_BUILD_NUM,\n        name: env.CIRCLE_JOB,\n        url: env.CIRCLE_BUILD_URL,\n      },\n      build: {\n        number: env.CIRCLE_BUILD_NUM,\n        trigger: this.getCircleCIBuildTrigger(),\n      },\n    };\n  }\n\n  /**\n   * Determine CircleCI build trigger from available env vars\n   */\n  private getCircleCIBuildTrigger(): string {\n    const { env } = process;\n\n    if (env.CIRCLE_TAG) return 'tag';\n    if (env.CIRCLE_PR_NUMBER || env.CIRCLE_PULL_REQUEST) return 'pr';\n\n    return 'push';\n  }\n\n  /**\n   * Jenkins pipeline + build\n   */\n  private getJenkinsMetadata(): ProviderMetadata {\n    const { env } = process;\n\n    return {\n      pipeline: {\n        id: env.BUILD_ID,\n        name: env.JOB_NAME,\n        url: env.BUILD_URL,\n      },\n      build: {\n        number: env.BUILD_NUMBER,\n        trigger: this.getJenkinsBuildTrigger(),\n      },\n    };\n  }\n\n  /**\n   * Jenkins doesn't expose a single BUILD_CAUSE env var — it exposes each cause\n   * as a separate boolean (BUILD_CAUSE_MANUALTRIGGER, BUILD_CAUSE_SCMTRIGGER,\n   * etc.) that the Groovy env-vars plugin sets. Prefer these; fall back to the\n   * legacy BUILD_CAUSE if a customer sets it manually in their pipeline.\n   */\n  private getJenkinsBuildTrigger(): string | undefined {\n    const { env } = process;\n\n    if (env.BUILD_CAUSE_MANUALTRIGGER === 'true') return 'manual';\n    if (env.BUILD_CAUSE_SCMTRIGGER === 'true') return 'push';\n    if (env.BUILD_CAUSE_TIMERTRIGGER === 'true') return 'scheduled';\n    if (env.BUILD_CAUSE_UPSTREAMTRIGGER === 'true') return 'upstream';\n    if (env.BUILD_CAUSE_REMOTECAUSE === 'true') return 'remote';\n\n    return env.BUILD_CAUSE;\n  }\n\n  /**\n   * Azure DevOps pipeline + build\n   */\n  private getAzureDevOpsMetadata(): ProviderMetadata {\n    const { env } = process;\n\n    return {\n      pipeline: {\n        id: env.BUILD_BUILDID,\n        name: env.BUILD_DEFINITIONNAME,\n        url: this.buildAzureDevOpsPipelineUrl(),\n      },\n      build: {\n        number: env.BUILD_BUILDNUMBER,\n        trigger: env.BUILD_REASON,\n        actor: env.BUILD_REQUESTEDFOR,\n      },\n    };\n  }\n\n  /**\n   * Construct the Azure DevOps build-results URL when all parts are present\n   */\n  private buildAzureDevOpsPipelineUrl(): string | undefined {\n    const { SYSTEM_TEAMFOUNDATIONSERVERURI, SYSTEM_TEAMPROJECT, BUILD_BUILDID } = process.env;\n\n    if (!SYSTEM_TEAMFOUNDATIONSERVERURI || !SYSTEM_TEAMPROJECT || !BUILD_BUILDID) {\n      return undefined;\n    }\n\n    try {\n      const baseUrl = SYSTEM_TEAMFOUNDATIONSERVERURI.replace(/\\/$/, '');\n      const encodedProject = encodeURIComponent(SYSTEM_TEAMPROJECT);\n      return `${baseUrl}/${encodedProject}/_build/results?buildId=${BUILD_BUILDID}`;\n    } catch {\n      return undefined;\n    }\n  }\n\n  /**\n   * AWS CodeBuild pipeline + build\n   */\n  private getAWSCodeBuildMetadata(): ProviderMetadata {\n    const { env } = process;\n    const buildId = env.CODEBUILD_BUILD_ID || '';\n    // Build ID format is `project-name:build-uuid`\n    const projectName = buildId.split(':')[0] || undefined;\n\n    return {\n      pipeline: {\n        id: env.CODEBUILD_BUILD_ID,\n        name: projectName,\n        url: env.CODEBUILD_BUILD_URL,\n      },\n      build: {\n        number: env.CODEBUILD_BUILD_NUMBER,\n        trigger: this.getAWSCodeBuildTrigger(),\n      },\n    };\n  }\n\n  /**\n   * Determine the AWS CodeBuild trigger from webhook/initiator env vars\n   */\n  private getAWSCodeBuildTrigger(): string | undefined {\n    const { env } = process;\n\n    if (env.CODEBUILD_WEBHOOK_EVENT) return env.CODEBUILD_WEBHOOK_EVENT;\n\n    if (env.CODEBUILD_INITIATOR) {\n      return env.CODEBUILD_INITIATOR.startsWith('codepipeline/') ? 'codepipeline' : 'manual';\n    }\n\n    return undefined;\n  }\n\n  /**\n   * Bitbucket Pipelines pipeline + build\n   */\n  private getBitbucketPipelinesMetadata(): ProviderMetadata {\n    const { env } = process;\n    const { BITBUCKET_WORKSPACE, BITBUCKET_REPO_SLUG, BITBUCKET_BUILD_NUMBER } = env;\n\n    const url =\n      BITBUCKET_WORKSPACE && BITBUCKET_REPO_SLUG && BITBUCKET_BUILD_NUMBER\n        ? `https://bitbucket.org/${BITBUCKET_WORKSPACE}/${BITBUCKET_REPO_SLUG}/pipelines/results/${BITBUCKET_BUILD_NUMBER}`\n        : undefined;\n\n    let trigger = 'push';\n    if (env.BITBUCKET_PR_ID) {\n      trigger = 'pull_request';\n    } else if (env.BITBUCKET_TAG) {\n      trigger = 'tag';\n    }\n\n    return {\n      pipeline: {\n        id: env.BITBUCKET_PIPELINE_UUID,\n        name: 'Bitbucket Pipeline',\n        url,\n      },\n      build: {\n        number: BITBUCKET_BUILD_NUMBER,\n        trigger,\n      },\n    };\n  }\n\n  /**\n   * Buildkite pipeline + build\n   */\n  private getBuildkiteMetadata(): ProviderMetadata {\n    const { env } = process;\n\n    return {\n      pipeline: {\n        id: env.BUILDKITE_PIPELINE_ID || env.BUILDKITE_PIPELINE_SLUG,\n        name: env.BUILDKITE_PIPELINE_NAME || env.BUILDKITE_PIPELINE_SLUG,\n        url: env.BUILDKITE_BUILD_URL,\n      },\n      build: {\n        number: env.BUILDKITE_BUILD_NUMBER,\n        trigger: this.getBuildkiteTrigger(),\n        actor: env.BUILDKITE_BUILD_CREATOR,\n      },\n    };\n  }\n\n  /**\n   * Determine the Buildkite trigger. BUILDKITE_PULL_REQUEST is the PR number or\n   * the literal string 'false' when the build is not for a PR.\n   *\n   * BUILDKITE_SOURCE describes what started the build (webhook, ui, api,\n   * schedule, trigger_job). It's normalized to the same push/manual/scheduled\n   * vocabulary the other providers emit — an ordinary git push arrives as\n   * 'webhook', which would otherwise leak as a trigger value. Unknown sources\n   * pass through so no signal is lost.\n   */\n  private getBuildkiteTrigger(): string {\n    const { env } = process;\n\n    if (env.BUILDKITE_TAG) return 'tag';\n    if (env.BUILDKITE_PULL_REQUEST && env.BUILDKITE_PULL_REQUEST !== 'false') return 'pull_request';\n\n    switch (env.BUILDKITE_SOURCE) {\n      case undefined:\n      case '':\n      case 'webhook':\n        return 'push';\n      case 'ui':\n        return 'manual';\n      case 'schedule':\n        return 'scheduled';\n      default:\n        return env.BUILDKITE_SOURCE;\n    }\n  }\n\n  /**\n   * Harness CI pipeline + build.\n   *\n   * Harness CI is built on Drone and mirrors the documented DRONE_* vars into\n   * the step container; those are the reliable source for build number and\n   * trigger. The HARNESS_* vars carry pipeline identity. The results URL is\n   * account/module-specific and not reliably reconstructable from env, so it is\n   * left undefined. `name` is omitted rather than duplicating the identifier —\n   * Harness exposes no distinct pipeline-name env var.\n   */\n  private getHarnessMetadata(): ProviderMetadata {\n    const { env } = process;\n\n    return {\n      pipeline: {\n        id: env.HARNESS_PIPELINE_ID,\n      },\n      build: {\n        number: env.HARNESS_BUILD_ID || env.DRONE_BUILD_NUMBER,\n        trigger: this.getHarnessTrigger(),\n      },\n    };\n  }\n\n  /**\n   * Normalize the Harness/Drone build event. Drone emits 'cron' for scheduled\n   * builds; align it with the 'scheduled' vocabulary the other providers use.\n   * Other events (push, pull_request, tag) pass through unchanged.\n   */\n  private getHarnessTrigger(): string | undefined {\n    const event = process.env.DRONE_BUILD_EVENT;\n    if (!event) return undefined;\n    return event === 'cron' ? 'scheduled' : event;\n  }\n\n  /**\n   * Fallback for a detected-but-unmapped CI provider.\n   *\n   * Kept intentionally narrow: only reads env vars that are truly widely-shared\n   * across generic CI images (CI_BUILD_NUMBER, BUILD_NUMBER). Does NOT leak\n   * GitLab-specific vars (CI_PIPELINE_ID / CI_PIPELINE_NAME / CI_PIPELINE_URL /\n   * CI_PIPELINE_SOURCE), which would falsely attribute an unknown provider's\n   * run to GitLab semantics in the dashboard.\n   */\n  private getGenericMetadata(): ProviderMetadata {\n    const { env } = process;\n\n    return {\n      pipeline: {},\n      build: {\n        number: env.CI_BUILD_NUMBER || env.BUILD_NUMBER,\n      },\n    };\n  }\n\n  /**\n   * Collect runner environment information\n   */\n  private collectEnvironment(): CIMetadata['environment'] {\n    try {\n      return {\n        name: osType(),\n        type: process.platform,\n        os: `${osType()} ${osRelease()}`,\n        node: process.version,\n      };\n    } catch {\n      return {};\n    }\n  }\n\n  /**\n   * Whether the person who started the run wrote the commit, from evidence only\n   * (an account login or matching emails); left unset when the provider cannot tell.\n   */\n  static resolveActorIsAuthor(ci: CIMetadata, git: GitMetadata): void {\n    const verifiedLogin = git.commit?.verifiedLogin;\n    if (git.commit) delete git.commit.verifiedLogin;\n\n    const actor = ci.build?.actor;\n    if (!ci.build || !actor) return;\n\n    const { env } = process;\n    const commitEmail = git.commit?.email;\n    const sameEmail = (a?: string, b?: string): boolean | undefined =>\n      a && b ? a.toLowerCase() === b.toLowerCase() : undefined;\n\n    let result: boolean | undefined;\n    switch (ci.provider) {\n      case 'github-actions':\n        result = verifiedLogin\n          ? verifiedLogin.toLowerCase() === actor.toLowerCase()\n          : CIMetadataCollector.isNoreplyEmailOf(commitEmail, actor) || undefined;\n        break;\n      case 'gitlab-ci':\n        result = sameEmail(env.GITLAB_USER_EMAIL, commitEmail);\n        break;\n      case 'azure-devops':\n        result = sameEmail(env.BUILD_REQUESTEDFOREMAIL, commitEmail);\n        break;\n      case 'buildkite':\n        result = sameEmail(env.BUILDKITE_BUILD_CREATOR_EMAIL, env.BUILDKITE_BUILD_AUTHOR_EMAIL || commitEmail);\n        break;\n    }\n    if (result !== undefined) ci.build.actorIsAuthor = result;\n  }\n\n  // GitHub's `{id}+{login}@users.noreply.github.com` (or the older `{login}@...`) belongs to that login.\n  private static isNoreplyEmailOf(email: string | undefined, login: string): boolean {\n    if (!email) return false;\n    const match = /^(?:\\d+\\+)?([^@]+)@users\\.noreply\\.github\\.com$/i.exec(email);\n    return match !== null && match[1].toLowerCase() === login.toLowerCase();\n  }\n\n  /**\n   * Reconcile CI and Git metadata after both collectors complete.\n   *\n   * Bitbucket Pipelines runs that fire on the target branch after a PR merge do\n   * not expose `BITBUCKET_PR_ID`, so env-only detection reports `push`. The\n   * auto-merge commit subject (`Merged in <branch> (pull request #N)`) is the\n   * reliable signal that the push originated from a PR — when present we surface\n   * the run as a `pull_request` trigger and backfill PR number/url/status/title.\n   *\n   * No-op for every other provider.\n   */\n  static reconcileWithGit(ci: CIMetadata, git: GitMetadata): void {\n    if (ci.provider !== 'bitbucket-pipelines') return;\n    if (ci.build?.trigger !== 'push') return;\n\n    const message = git.commit?.message || '';\n    // Anchored to Bitbucket's auto-merge subject so we don't false-positive on\n    // commits that merely quote the phrase (e.g. `Revert \"Merged in ...\"`).\n    const match = message.match(/^Merged in [^\\n]+\\(pull request #(\\d+)\\)/i);\n    const prId = match?.[1];\n    if (!prId) return;\n\n    if (ci.build) ci.build.trigger = 'pull_request';\n\n    const pr: PRMetadata = git.pr ?? {};\n\n    if (pr.number === undefined) {\n      pr.number = Number(prId);\n      if (git.repository?.url) {\n        const base = git.repository.url.replace(/\\.git$/, '').replace(/\\/$/, '');\n        pr.url = `${base}/pull-requests/${prId}`;\n      }\n      pr.status = 'merged';\n      pr.merged = true;\n    }\n\n    // The auto-merge subject is the only place the PR title lives for post-merge\n    // runs; use it when nothing better is available.\n    if (!pr.title) {\n      const subject = message.split('\\n')[0]?.trim();\n      if (subject) pr.title = subject;\n    }\n\n    git.pr = pr;\n  }\n}\n\n// The server reads only a positive integer, so anything else is omitted.\nexport function parseRunAttempt(value: string | undefined): number | undefined {\n  return value !== undefined && /^[1-9]\\d*$/.test(value) ? Number(value) : undefined;\n}\n","import { parseRunAttempt } from '../../metadata/ci.js';\nimport { supportsTestList } from './prepare.js';\nimport { defaultListRunner, listShard, listTestIds } from './verify.js';\nimport type { ListRunner } from './verify.js';\nimport type { RerunSelection } from './types.js';\n\n// Same budget as an explicit --rerun: extract lands seconds after a run ends.\nconst NOT_READY_BUDGET_MS = 90_000;\nconst NOT_READY_POLL_MS = 2_000;\nconst REQUEST_TIMEOUT_MS = 15_000;\nconst PIPELINE_ID = /^[0-9]{1,20}$/;\nconst USER_TEST_LIST_FLAGS = ['--test-list', '--test-list-invert', '--list'];\n\nexport const CI_RERUN_SELECTION_PATH = '/api/v1/reporter/ci-reruns/selection';\n\nexport interface InRunRerunOptions {\n  env: NodeJS.ProcessEnv;\n  serverUrl: string;\n  token?: string;\n  playwrightArgs: string[];\n  readPlaywrightVersion: () => string | undefined;\n  listRunner?: ListRunner;\n  fetchImpl?: typeof fetch;\n  sleep?: (ms: number) => Promise<void>;\n  now?: () => number;\n}\n\nexport type InRunRerunResult =\n  | { kind: 'skip' }\n  | { kind: 'full'; reason: string; sourceRunId?: string }\n  | {\n      kind: 'narrow';\n      attempt: number;\n      selection: RerunSelection;\n      // The job's real shard, so the retried jobs of one attempt still group\n      // into a single run even though each executes --shard=1/1.\n      shard?: { current: number; total: number };\n    };\n\nconst defaultSleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * On a GitHub Actions retry, asks TestDino which of this invocation's tests\n * failed in the earlier attempt (microservices docs/RERUN_FAILED_TESTS.md §14).\n * Never throws: every failure is `full`, so the user's command runs unchanged\n * rather than a red job turning green on a partial run.\n */\nexport async function resolveInRunRerun(options: InRunRerunOptions): Promise<InRunRerunResult> {\n  const { env } = options;\n  const attempt = parseRunAttempt(env.GITHUB_RUN_ATTEMPT);\n  const pipelineId = env.GITHUB_RUN_ID ?? '';\n  if (env.GITHUB_ACTIONS !== 'true' || attempt === undefined || attempt < 2 || !PIPELINE_ID.test(pipelineId)) {\n    return { kind: 'skip' };\n  }\n  if (!options.token) {\n    return { kind: 'skip' };\n  }\n  const playwrightVersion = options.readPlaywrightVersion();\n  if (!supportsTestList(playwrightVersion)) {\n    return { kind: 'full', reason: `Playwright ${playwrightVersion ?? '(unknown)'} has no --test-list` };\n  }\n  const ownSelector = options.playwrightArgs.find((arg) =>\n    USER_TEST_LIST_FLAGS.some((flag) => arg === flag || arg.startsWith(`${flag}=`))\n  );\n  if (ownSelector) {\n    return { kind: 'full', reason: `the command already passes ${ownSelector}` };\n  }\n\n  try {\n    const listJson = await (options.listRunner ?? defaultListRunner)(options.playwrightArgs);\n    const listed = listTestIds(listJson);\n    const answer = await fetchCISelection(options, { pipelineId, attempt, testIds: listed });\n    if (answer.narrow !== true) {\n      // The door refused, but it still names the run this retry came from\n      // (every reason but NO_INTENT), so the full run is linked to its source.\n      return { kind: 'full', reason: describeReason(answer.reason), sourceRunId: answer.sourceRunId };\n    }\n    if (!Array.isArray(answer.testList) || answer.testList.length === 0 || typeof answer.sourceRunId !== 'string') {\n      return {\n        kind: 'full',\n        reason: 'the server answered without a selection',\n        sourceRunId: answer.sourceRunId,\n      };\n    }\n    const shard = listShard(listJson);\n    return {\n      kind: 'narrow',\n      attempt,\n      selection: answer as RerunSelection,\n      ...(shard && shard.total > 1 && { shard }),\n    };\n  } catch (error) {\n    return { kind: 'full', reason: error instanceof Error ? error.message : String(error) };\n  }\n}\n\ninterface CISelectionAnswer extends Partial<RerunSelection> {\n  narrow?: boolean;\n  reason?: string;\n}\n\nasync function fetchCISelection(\n  options: InRunRerunOptions,\n  body: { pipelineId: string; attempt: number; testIds: string[] }\n): Promise<CISelectionAnswer> {\n  const { fetchImpl = fetch, sleep = defaultSleep, now = Date.now } = options;\n  const url = `${options.serverUrl.replace(/\\/+$/, '')}${CI_RERUN_SELECTION_PATH}`;\n  const payload = JSON.stringify(body);\n  const deadline = now() + NOT_READY_BUDGET_MS;\n\n  for (;;) {\n    const response = await fetchImpl(url, {\n      method: 'POST',\n      headers: { Authorization: `Bearer ${options.token}`, 'Content-Type': 'application/json' },\n      body: payload,\n      signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n    });\n    let parsed: (CISelectionAnswer & { error?: { code?: string } }) | undefined;\n    try {\n      parsed = (await response.json()) as CISelectionAnswer & { error?: { code?: string } };\n    } catch {\n      parsed = undefined;\n    }\n    if (response.ok && parsed) {\n      return parsed;\n    }\n    const code = parsed?.error?.code;\n    if (code === 'SELECTION_NOT_READY' && now() < deadline) {\n      await sleep(NOT_READY_POLL_MS);\n      continue;\n    }\n    throw new Error(`TestDino answered HTTP ${response.status}${code ? ` ${code}` : ''}`);\n  }\n}\n\nfunction describeReason(reason: string | undefined): string {\n  switch (reason) {\n    case 'NO_INTENT':\n      return 'this retry was not started from TestDino';\n    case 'NOTHING_FAILED':\n      return 'none of these tests failed in the earlier attempt';\n    case 'NOT_COVERED':\n      return 'some of these tests did not run in the earlier attempt';\n    case 'MULTIPLE_SOURCES':\n      return 'the earlier failures span more than one TestDino run';\n    case 'MULTIPLE_JOBS':\n      return 'these tests also ran in another job of the earlier attempt, so TestDino cannot tell which results are this job\\u2019s';\n    case 'TOO_MANY_TESTS':\n      return 'the suite is too large to narrow';\n    default:\n      return reason ? `TestDino answered ${reason}` : 'TestDino gave no reason';\n  }\n}\n","export const RERUN_SCOPES = ['failed', 'flaky', 'failed-and-flaky'] as const;\n\nexport type RerunScope = (typeof RERUN_SCOPES)[number];\n\nexport function isRerunScope(value: string): value is RerunScope {\n  return (RERUN_SCOPES as readonly string[]).includes(value);\n}\n\nexport interface RerunSelection {\n  sourceRunId: string;\n  // Absent from older servers; the messages then name the run by its id.\n  sourceRunCounter?: number;\n  sourceCommitSha?: string;\n  sourceRunUrl?: string;\n  testList: string[];\n  // The Playwright test id of each testList line; absent from older servers.\n  testIds?: string[];\n  // Positional args Playwright ANDs with --test-list; they narrow a shortened\n  // line to the one test it stands for.\n  locations?: string[];\n  resolution: {\n    selected: number;\n    inScope: number;\n    missingTestIds?: string[];\n    unrenderableTests?: Array<{ pwTestId: string; title: string }>;\n  };\n}\n","import { ConfigLoader } from '../config-loader.js';\nimport { ConfigDetector } from '../config-detector.js';\nimport { ConfigMerger } from '../config-merger.js';\nimport { ArgFilter } from '../arg-filter.js';\nimport { TempConfigManager } from '../temp-config.js';\nimport { PlaywrightSpawner } from '../playwright-spawner.js';\nimport { Logger } from '../logger.js';\nimport { RerunSplitConflictError, TestDinoError } from '../errors.js';\nimport { fetchRerunSelection } from '../rerun/client.js';\nimport {\n  conflictingSelector,\n  hasShardFlag,\n  misplacedRerunFlag,\n  readInstalledPlaywrightVersion,\n  SelectionFile,\n  supportsTestList,\n} from '../rerun/prepare.js';\nimport { countSelectedTests } from '../rerun/verify.js';\nimport { resolveInRunRerun } from '../rerun/in-run.js';\nimport { isRerunScope, RERUN_SCOPES } from '../rerun/types.js';\nimport type { RerunScope, RerunSelection } from '../rerun/types.js';\nimport type { CliOptions, MergedConfig } from '../types.js';\nimport { DEFAULT_SERVER_URL } from '../../types/index.js';\nimport { colors, hyperlink } from '../../utils/ui.js';\nimport type { PlaywrightSpawnResult } from '../playwright-spawner.js';\n\nconst SCOPE_LABELS: Record<RerunScope, string> = {\n  failed: 'failed',\n  flaky: 'flaky',\n  'failed-and-flaky': 'failed and flaky',\n};\n\ninterface RerunPlan {\n  scope: RerunScope;\n  fromRun: string;\n  token: string;\n  testIds?: string[];\n  excludeTestIds?: string[];\n}\n\nexport class TestCommand {\n  private configLoader: ConfigLoader;\n  private configDetector: ConfigDetector;\n  private configMerger: ConfigMerger;\n  private argFilter: ArgFilter;\n  private tempConfigManager: TempConfigManager;\n  private playwrightSpawner: PlaywrightSpawner;\n  private logger: Logger;\n  private inRunRerun: typeof resolveInRunRerun;\n\n  constructor(\n    configLoader?: ConfigLoader,\n    configDetector?: ConfigDetector,\n    configMerger?: ConfigMerger,\n    argFilter?: ArgFilter,\n    tempConfigManager?: TempConfigManager,\n    playwrightSpawner?: PlaywrightSpawner,\n    logger?: Logger,\n    inRunRerun?: typeof resolveInRunRerun\n  ) {\n    this.configLoader = configLoader || new ConfigLoader();\n    this.configDetector = configDetector || new ConfigDetector();\n    this.configMerger = configMerger || new ConfigMerger();\n    this.argFilter = argFilter || new ArgFilter();\n    this.tempConfigManager = tempConfigManager || new TempConfigManager(logger);\n    this.playwrightSpawner = playwrightSpawner || new PlaywrightSpawner(logger);\n    this.logger = logger || new Logger();\n    this.inRunRerun = inRunRerun || resolveInRunRerun;\n  }\n\n  async execute(options: CliOptions, args: string[]): Promise<PlaywrightSpawnResult> {\n    let tempConfigPath: string | undefined;\n    const selectionFile = new SelectionFile();\n\n    try {\n      // 1. Load testdino.config.[ts|js]\n      const testdinoConfigResult = await this.configLoader.load();\n\n      // 2. Detect playwright.config.[ts|js] and TestdinoReporter\n      const playwrightConfigResult = await this.configDetector.detect();\n\n      // 3. Get environment variables\n      const envConfig = ConfigMerger.getEnvConfig();\n\n      // 4. Merge all configs with proper priority\n      const mergedConfig = this.configMerger.merge({\n        env: envConfig,\n        playwrightConfig: playwrightConfigResult.options,\n        testdinoConfig: testdinoConfigResult.config,\n        cliOptions: options,\n      });\n\n      // 5. Filter TestDino-specific arguments\n      let filteredArgs = this.argFilter.filter(args);\n\n      // 6. Re-run selection: resolve the source run's failed set server-side and\n      //    hand it to Playwright as --test-list. Refusals happen before any\n      //    network call; a resolved empty set exits 0 without a run.\n      const misplaced = misplacedRerunFlag(filteredArgs);\n      if (misplaced) {\n        throw new TestDinoError(\n          `${misplaced} must come before \"--\": everything after it goes to Playwright unchanged.\\n\\nUse: npx tdpw test --rerun failed --from-run <runId> -- <playwright args>`\n        );\n      }\n      if (options.rerun === undefined && options.rerunTags !== undefined) {\n        throw new TestDinoError(\n          '--rerun-tags only applies to a re-run: pass it with --rerun <scope> --from-run <runId>, or use --tags for a normal run.'\n        );\n      }\n      if (options.rerun !== undefined) {\n        const selection = await this.resolveRerunSelection(options, mergedConfig, filteredArgs);\n        if (selection === null) {\n          return { exitCode: 0, success: true, resultsProduced: false, totalTests: 0 };\n        }\n        const selectionPath = selectionFile.write(selection.testList);\n        const locationArgs = selection.locations ?? [];\n        await this.verifyRerunSelection(selectionPath, [...filteredArgs, ...locationArgs], selection);\n        filteredArgs = [...filteredArgs, ...locationArgs, `--test-list=${selectionPath}`];\n        mergedConfig.rerunOf = selection.sourceRunId;\n      } else {\n        filteredArgs = await this.applyInRunRerun(mergedConfig, filteredArgs, selectionFile);\n      }\n\n      // 7. Create temp config file\n      const tempConfigInfo = this.tempConfigManager.create(mergedConfig);\n      tempConfigPath = tempConfigInfo.path;\n\n      // 8. Spawn Playwright with filtered args and config\n      const result = await this.playwrightSpawner.spawn({\n        args: filteredArgs,\n        tempConfigPath,\n        config: mergedConfig,\n      });\n\n      return result;\n    } finally {\n      // 9. Always cleanup temp files\n      if (tempConfigPath) {\n        this.tempConfigManager.cleanup(tempConfigPath);\n      }\n      selectionFile.cleanup();\n    }\n  }\n\n  // A GitHub retry started from TestDino runs only this job's failed tests.\n  // Anything unexpected runs the command unchanged: a narrowed run that skips a\n  // failure would turn a red job green.\n  private async applyInRunRerun(\n    mergedConfig: MergedConfig,\n    playwrightArgs: string[],\n    selectionFile: SelectionFile\n  ): Promise<string[]> {\n    const result = await this.inRunRerun({\n      env: process.env,\n      serverUrl: mergedConfig.serverUrl ?? DEFAULT_SERVER_URL,\n      token: mergedConfig.token,\n      playwrightArgs,\n      readPlaywrightVersion: () => readInstalledPlaywrightVersion(),\n    });\n    if (result.kind === 'skip') return playwrightArgs;\n    if (result.kind === 'full') {\n      // Still a re-run of that run, even though every test runs: without the link\n      // it lands as a run of its own and is counted in run-level metrics.\n      if (result.sourceRunId) mergedConfig.rerunOf = result.sourceRunId;\n      this.logger.info(`TestDino: running the full command on this GitHub retry — ${result.reason}.`);\n      return playwrightArgs;\n    }\n    const { selection, attempt } = result;\n    // A trailing --shard=1/1 wins over the job's own shard, from args or config,\n    // which would otherwise drop selected tests that belong to other shards.\n    const narrowedArgs = [...playwrightArgs, ...(selection.locations ?? []), '--shard=1/1'];\n    const selectionPath = selectionFile.write(selection.testList);\n    const mismatch = await this.inRunMismatch(selectionPath, narrowedArgs, selection);\n    if (mismatch) {\n      selectionFile.cleanup();\n      // Still the re-run of that source: the selection did not survive this\n      // checkout, but the run it came from is known, and an unlinked run would\n      // count as a fresh one in run-level metrics.\n      mergedConfig.rerunOf = selection.sourceRunId;\n      this.logger.warn(`TestDino: could not narrow this GitHub retry (${mismatch}); running the full command.`);\n      return playwrightArgs;\n    }\n    mergedConfig.rerunOf = selection.sourceRunId;\n    // Executed as --shard=1/1 so Playwright cannot re-slice the selection, but\n    // reported as the job's real shard so one attempt's jobs form one run.\n    if (result.shard) {\n      mergedConfig.shard = result.shard;\n    }\n    const source = selection.sourceRunCounter ? `#${selection.sourceRunCounter}` : selection.sourceRunId;\n    this.logger.info(\n      `TestDino: GitHub retry (attempt ${attempt}) — running the ${selection.testList.length} test(s) that failed in run ${source}, not the full suite.`\n    );\n    return [...narrowedArgs, `--test-list=${selectionPath}`];\n  }\n\n  // Narrows only when --list matches exactly the selected tests; a missing or\n  // an extra test means the checkout and the selection disagree.\n  private async inRunMismatch(\n    selectionPath: string,\n    playwrightArgs: string[],\n    selection: RerunSelection\n  ): Promise<string | undefined> {\n    let match;\n    try {\n      match = await countSelectedTests(selectionPath, playwrightArgs);\n    } catch (error) {\n      return error instanceof Error ? error.message : String(error);\n    }\n    if (!match.checked) return match.reason ?? 'the selection could not be listed';\n    if (selection.testIds?.length && match.ids) {\n      const expected = new Set(selection.testIds);\n      const listed = new Set(match.ids);\n      const same = expected.size === listed.size && [...expected].every((id) => listed.has(id));\n      return same ? undefined : `--list matched ${listed.size} of ${expected.size} selected tests`;\n    }\n    return match.matched === selection.testList.length\n      ? undefined\n      : `--list matched ${match.matched} of ${selection.testList.length} selected tests`;\n  }\n\n  private planRerun(options: CliOptions, mergedConfig: MergedConfig, playwrightArgs: string[]): RerunPlan {\n    const scope = String(options.rerun);\n    if (!isRerunScope(scope)) {\n      throw new TestDinoError(`--rerun must be one of: ${RERUN_SCOPES.join(', ')} (got \"${scope}\").`);\n    }\n    if (!options.fromRun) {\n      throw new TestDinoError('--rerun requires --from-run <runId>: the run whose failures should be re-executed.');\n    }\n    // ConfigMerger.validate already refused a missing token; this narrows the type.\n    if (!mergedConfig.token) {\n      throw new TestDinoError('--rerun needs a TestDino token (--token or TESTDINO_TOKEN).');\n    }\n    if (mergedConfig.split !== undefined || mergedConfig.splitId !== undefined) {\n      throw new RerunSplitConflictError(mergedConfig.split !== undefined ? '--split' : '--split-id');\n    }\n    const conflict = conflictingSelector(playwrightArgs);\n    if (conflict) {\n      throw new TestDinoError(\n        `--rerun cannot be combined with ${conflict}: the re-run selection already decides which tests run.`\n      );\n    }\n    if (hasShardFlag(playwrightArgs)) {\n      throw new TestDinoError(\n        '--rerun cannot be combined with --shard: a re-run is a handful of tests, so every other shard would find nothing and fail.'\n      );\n    }\n    const playwrightVersion = readInstalledPlaywrightVersion();\n    if (!supportsTestList(playwrightVersion)) {\n      throw new TestDinoError(\n        `--rerun needs Playwright 1.56 or newer for --test-list (found ${playwrightVersion ?? 'no readable version'}). On older releases the selection cannot be passed safely and the whole suite would run instead.`\n      );\n    }\n    return {\n      scope,\n      fromRun: options.fromRun,\n      token: mergedConfig.token,\n      testIds: splitIds(options.testIds),\n      excludeTestIds: splitIds(options.excludeIds),\n    };\n  }\n\n  // null means \"nothing to re-run\" — reported, not an error.\n  private async resolveRerunSelection(\n    options: CliOptions,\n    mergedConfig: MergedConfig,\n    playwrightArgs: string[]\n  ): Promise<RerunSelection | null> {\n    const plan = this.planRerun(options, mergedConfig, playwrightArgs);\n    const selection = await fetchRerunSelection({\n      serverUrl: mergedConfig.serverUrl ?? DEFAULT_SERVER_URL,\n      token: plan.token,\n      runId: plan.fromRun,\n      scope: plan.scope,\n      testIds: plan.testIds,\n      excludeTestIds: plan.excludeTestIds,\n    });\n    const { selected, inScope, missingTestIds, unrenderableTests } = selection.resolution;\n    const what = plan.testIds ? 'selected' : SCOPE_LABELS[plan.scope];\n\n    for (const test of unrenderableTests ?? []) {\n      this.logger.warn(`TestDino re-run: \"${test.title}\" cannot be selected by its title or location; run it by hand.`);\n    }\n    if (missingTestIds?.length) {\n      this.logger.warn(\n        `TestDino re-run: ${missingTestIds.length} requested test id(s) are not in run ${plan.fromRun}.`\n      );\n    }\n    if (selected === 0) {\n      this.logger.info(`TestDino re-run: nothing to re-run — run ${plan.fromRun} has no ${what} tests in scope.`);\n      return null;\n    }\n    this.logger.info(`TestDino re-run: ${selected} of ${inScope} ${what} test(s) from run ${plan.fromRun}`);\n    return selection;\n  }\n\n  // Playwright runs whatever matched and exits 0 even when nothing did, so a\n  // zero match must be refused here or a stale selection reports green.\n  private async verifyRerunSelection(\n    selectionPath: string,\n    playwrightArgs: string[],\n    selection: RerunSelection\n  ): Promise<void> {\n    const selected = selection.testList.length;\n    const match = await countSelectedTests(selectionPath, playwrightArgs);\n    if (!match.checked) {\n      this.logger.warn(\n        `TestDino re-run: could not verify the selection against this checkout (${match.reason ?? 'unknown'}); running it as-is.`\n      );\n      return;\n    }\n    if (selection.testIds?.length && match.ids) {\n      this.checkRerunIdentity(selection, match.ids);\n      return;\n    }\n    if (match.matched === selected) return;\n    if (match.matched === 0) {\n      throw new TestDinoError(noneMatchError(selected, selection, selection.testList));\n    }\n    if (match.matched > selected) {\n      throw new TestDinoError(\n        `The selection matched ${match.matched} tests but ${selected} were selected, so it is broader than intended. Run the tests by hand and report run ${selection.sourceRunId} to TestDino.`\n      );\n    }\n    this.logger.warn(skippedTestsWarning(selected - match.matched, selected, selection));\n  }\n\n  // A count can hide a swap: on a later commit a placed test's line may now hold\n  // a different test. An unexpected id refuses; a missing one only warns.\n  private checkRerunIdentity(selection: RerunSelection, listed: string[]): void {\n    const expected = new Set(selection.testIds);\n    const extra = listed.filter((id) => !expected.has(id));\n    if (extra.length > 0) {\n      throw new TestDinoError(\n        `The selection would also run ${extra.length} test(s) that were not selected from run ${selection.sourceRunId}, most likely because the code changed since that run. Nothing was run; re-run these tests by hand.`\n      );\n    }\n    const found = new Set(listed);\n    const selected = selection.testIds?.length ?? 0;\n    const missingLines = (selection.testIds ?? []).flatMap((id, i) =>\n      found.has(id) ? [] : [selection.testList[i] ?? id]\n    );\n    const missing = missingLines.length;\n    if (missing === selected) {\n      throw new TestDinoError(noneMatchError(selected, selection, missingLines));\n    }\n    if (missing > 0) {\n      this.logger.warn(skippedTestsWarning(missing, selected, selection, missingLines));\n    }\n  }\n}\n\nconst MAX_NAMED_SKIPS = 10;\n\nfunction missingTestsMessage(headline: string, source: RerunSelection, names: string[]): string {\n  const shown = names.slice(0, MAX_NAMED_SKIPS);\n  const run = source.sourceRunCounter ? `#${source.sourceRunCounter}` : source.sourceRunId;\n  const commit = source.sourceCommitSha?.slice(0, 7);\n  return [\n    headline + (shown.length ? ':' : '.'),\n    ...shown.map((name) => `  - ${colors.white(name)}`),\n    ...(names.length > shown.length ? [`  …and ${names.length - shown.length} more`] : []),\n    colors.dim(\n      `They may have been renamed, moved or deleted since run ${run}${commit ? ` (commit ${commit})` : ''}, ` +\n        `or filtered out by your Playwright arguments (--project, a file filter).`\n    ),\n    `To run them unchanged, re-run on \"This commit\" or check out ${commit ?? \"that run's commit\"}.`,\n    ...(source.sourceRunUrl ? [hyperlink(`View run ${run}`, source.sourceRunUrl)] : []),\n  ].join('\\n');\n}\n\nfunction skippedTestsWarning(skipped: number, selected: number, source: RerunSelection, names: string[] = []): string {\n  return missingTestsMessage(\n    `TestDino re-run: ${skipped} of ${selected} tests were not found and will be skipped`,\n    source,\n    names\n  );\n}\n\nfunction noneMatchError(selected: number, source: RerunSelection, names: string[]): string {\n  return missingTestsMessage(`None of the ${selected} tests were found, so nothing ran`, source, names);\n}\n\nfunction splitIds(csv: string | undefined): string[] | undefined {\n  const ids = (csv ?? '')\n    .split(',')\n    .map((id) => id.trim())\n    .filter((id) => id !== '');\n  return ids.length > 0 ? ids : undefined;\n}\n","import { writeFileSync } from 'fs';\nimport { ConfigLoader } from '../config-loader.js';\nimport { ConfigDetector } from '../config-detector.js';\nimport { ConfigMerger } from '../config-merger.js';\nimport { Logger } from '../logger.js';\nimport { TestDinoError, TokenMissingError } from '../errors.js';\nimport { DispatchError } from './dispatch-errors.js';\nimport { resolveMachineCount } from './machine-count.js';\nimport { HttpMintClient, describeMintError } from './mint-client.js';\nimport { SwarmMintCommand } from './mint.js';\n\nexport interface SwarmMintCliOptions {\n  grep?: string;\n  project?: string[];\n  out?: string;\n  debug?: boolean;\n  machines?: string;\n  token?: string;\n  serverUrl?: string;\n}\n\n/** `tdpw swarm --machines N`: mint the swarm and print its id. Runs no tests. */\nexport async function startSwarm(logger: Logger, options: SwarmMintCliOptions): Promise<void> {\n  try {\n    const machines = resolveMachineCount({\n      flag: options.machines,\n      env: process.env.TESTDINO_MACHINES,\n    });\n\n    const testdinoConfig = await new ConfigLoader().load();\n    const detection = await new ConfigDetector().detect();\n    const merged = new ConfigMerger().merge({\n      env: ConfigMerger.getEnvConfig(),\n      playwrightConfig: detection.options,\n      testdinoConfig: testdinoConfig.config,\n      cliOptions: { token: options.token, serverUrl: options.serverUrl, debug: options.debug },\n    });\n    if (!merged.token) throw new TokenMissingError();\n\n    const workers = detection.workers ?? 1;\n    if (detection.workers === undefined) {\n      logger.warn(\n        'workers not set to a positive integer in the Playwright config (a percentage cannot be resolved when the swarm starts) — defaulting to 1; set an integer for accurate distribution'\n      );\n    }\n    const fullyParallel = detection.fullyParallel ?? false;\n\n    const client = new HttpMintClient({\n      token: merged.token,\n      serverUrl: merged.serverUrl ?? '',\n      onDebug: (m) => logger.debug(m),\n    });\n\n    const result = await new SwarmMintCommand(undefined, client).execute({\n      grep: options.grep,\n      project: options.project,\n      machines,\n      workers,\n      fullyParallel,\n    });\n\n    logger.success(`Started swarm ${result.swarmId}`);\n    logger.listItem(`machines: ${result.machines}`);\n    logger.listItem(`workers: ${result.workers}`);\n    logger.listItem(`fullyParallel: ${result.fullyParallel}`);\n    logger.listItem(`specCount: ${result.specCount}`);\n\n    if (options.out) {\n      writeFileSync(options.out, `${JSON.stringify(result, null, 2)}\\n`, 'utf-8');\n      logger.listItem(`swarm written to ${options.out}`);\n    }\n  } catch (error) {\n    if (error instanceof DispatchError) {\n      logger.error(`Starting the swarm failed: ${describeMintError(error)}`);\n    } else if (error instanceof TestDinoError) {\n      logger.error(error.message);\n    } else {\n      logger.error(error instanceof Error ? error.message : String(error), error instanceof Error ? error : undefined);\n    }\n    process.exitCode = 1;\n  }\n}\n","import { isAxiosError } from 'axios';\n\nexport type DispatchErrorKind = 'client' | 'server_error' | 'network';\n\nexport class DispatchError extends Error {\n  readonly kind: DispatchErrorKind;\n  readonly httpStatus?: number;\n  readonly serverCode?: string;\n\n  constructor(message: string, kind: DispatchErrorKind, httpStatus?: number, serverCode?: string) {\n    super(message);\n    this.name = 'DispatchError';\n    this.kind = kind;\n    this.httpStatus = httpStatus;\n    this.serverCode = serverCode;\n  }\n\n  // Only network (provably pre-commit) + 408/429 (server pre-processing) retry;\n  // a 5xx could be post-commit and retrying would orphan a second swarm.\n  get transient(): boolean {\n    if (this.kind === 'network') return true;\n    return this.httpStatus === 408 || this.httpStatus === 429;\n  }\n}\n\nexport function classifyDispatchError(error: unknown): DispatchError {\n  if (error instanceof DispatchError) return error;\n  if (isAxiosError(error)) {\n    const status = error.response?.status;\n    if (status === undefined) {\n      return new DispatchError(error.message || 'network error', 'network');\n    }\n    const code = extractCode(error.response?.data);\n    const message = extractMessage(error.response?.data) ?? error.message;\n    const kind: DispatchErrorKind = status >= 500 ? 'server_error' : 'client';\n    return new DispatchError(message, kind, status, code);\n  }\n  return new DispatchError(error instanceof Error ? error.message : String(error), 'network');\n}\n\n// Envelope is {\"error\":{\"code\",\"message\"}}; also tolerate a flat {code,message}.\nfunction extractCode(data: unknown): string | undefined {\n  const d = data as Record<string, unknown> | undefined;\n  const nested = d?.error as Record<string, unknown> | undefined;\n  if (typeof nested?.code === 'string') return nested.code;\n  if (typeof d?.code === 'string') return d.code;\n  return undefined;\n}\n\nfunction extractMessage(data: unknown): string | undefined {\n  const d = data as Record<string, unknown> | undefined;\n  const nested = d?.error as Record<string, unknown> | undefined;\n  if (typeof nested?.message === 'string') return nested.message;\n  if (typeof d?.message === 'string') return d.message;\n  return undefined;\n}\n","import { InvalidMachineCountError } from '../errors.js';\n\nexport interface MachineCountSources {\n  flag?: string;\n  env?: string;\n}\n\nexport function resolveMachineCount(sources: MachineCountSources = {}): number {\n  const raw = sources.flag?.trim() || sources.env?.trim();\n  if (!raw) throw new InvalidMachineCountError();\n\n  // Decimal-only: Number() would otherwise accept hex (0x10) and scientific (1e3).\n  if (!/^\\d+$/.test(raw)) throw new InvalidMachineCountError(raw);\n  const n = Number(raw);\n  if (n < 1) throw new InvalidMachineCountError(raw);\n  return n;\n}\n","import axios, { type AxiosInstance } from 'axios';\nimport { sleep } from '../../utils/index.js';\nimport { DispatchError, classifyDispatchError } from './dispatch-errors.js';\nimport type { DiscoverSpec } from './types.js';\n\n/** Wire (CLI → data-handler): POST /api/v1/swarms body. */\nexport interface MintDiscoverRequest {\n  suiteFingerprint: string;\n  machines: number;\n  workers: number;\n  fullyParallel: boolean;\n  specs: DiscoverSpec[];\n  /** Discover --grep pattern; persisted so runners re-apply it per batch. */\n  grep?: string;\n}\n\n/** Wire (data-handler → CLI): mint response. `created` is always true (mint is not idempotent). */\nexport interface MintDiscoverResponse {\n  swarmId: string;\n  machines: number;\n  workers: number;\n  fullyParallel: boolean;\n  specCount: number;\n  created: boolean;\n}\n\nexport interface DiscoverClient {\n  mint(req: MintDiscoverRequest): Promise<MintDiscoverResponse>;\n}\n\nexport interface HttpMintClientOptions {\n  token: string;\n  serverUrl: string;\n  maxAttempts?: number;\n  retryDelay?: number;\n  timeout?: number;\n  onDebug?: (message: string) => void;\n}\n\n/** Maps a mint DispatchError to an operator-facing sentence. */\nexport function describeMintError(err: DispatchError): string {\n  switch (err.httpStatus) {\n    case 422:\n      return 'no specs, or more than 50000 specs';\n    case 404:\n      return 'project not found or access denied';\n    default:\n      return err.message;\n  }\n}\n\nexport class HttpMintClient implements DiscoverClient {\n  private readonly http: AxiosInstance;\n  private readonly maxAttempts: number;\n  private readonly retryDelay: number;\n  private readonly onDebug: (message: string) => void;\n\n  constructor(options: HttpMintClientOptions) {\n    this.maxAttempts = options.maxAttempts ?? 3;\n    this.retryDelay = options.retryDelay ?? 500;\n    this.onDebug = options.onDebug ?? (() => {});\n    this.http = axios.create({\n      baseURL: options.serverUrl,\n      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${options.token}` },\n      timeout: options.timeout ?? 15_000,\n    });\n  }\n\n  async mint(req: MintDiscoverRequest): Promise<MintDiscoverResponse> {\n    let lastError: DispatchError | null = null;\n    for (let attempt = 0; attempt < this.maxAttempts; attempt++) {\n      try {\n        const res = await this.http.post<MintDiscoverResponse>('/api/v1/swarms', req);\n        return res.data;\n      } catch (error) {\n        const classified = classifyDispatchError(error);\n        lastError = classified;\n        if (!classified.transient) throw classified;\n        if (attempt < this.maxAttempts - 1) {\n          const base = this.retryDelay * Math.pow(2, attempt);\n          // Equal jitter so concurrent callers don't retry in lockstep.\n          const delay = Math.round(base / 2 + Math.random() * (base / 2));\n          this.onDebug(`mint transient (${classified.kind}/${classified.httpStatus ?? '?'}) — retrying in ${delay}ms`);\n          await sleep(delay);\n        }\n      }\n    }\n    throw lastError ?? new DispatchError('mint failed', 'network');\n  }\n}\n","import { execa } from 'execa';\nimport type { PlaywrightListReport } from './types.js';\nimport { DiscoveryFailedError } from '../errors.js';\n\nexport interface ListRunnerOptions {\n  grep?: string;\n  projects?: string[];\n  cwd?: string;\n  env?: NodeJS.ProcessEnv;\n}\n\nexport function buildListArgs(grep?: string, projects: string[] = []): string[] {\n  return [\n    'playwright',\n    'test',\n    '--list',\n    '--reporter=json',\n    ...(grep ? ['--grep', grep] : []),\n    ...projects.flatMap((p) => ['--project', p]),\n  ];\n}\n\nexport class PlaywrightListRunner {\n  async list(options: ListRunnerOptions = {}): Promise<PlaywrightListReport> {\n    const { grep, projects = [], cwd = process.cwd(), env = process.env } = options;\n    const args = buildListArgs(grep, projects);\n\n    let result;\n    try {\n      result = await execa('npx', args, { cwd, env, reject: false, stdio: ['ignore', 'pipe', 'pipe'] });\n    } catch (error) {\n      const code = (error as { code?: string }).code;\n      if (code === 'ENOENT') {\n        throw new DiscoveryFailedError('Playwright is not installed or npx is not available.');\n      }\n      throw new DiscoveryFailedError(error instanceof Error ? error.message : String(error));\n    }\n\n    const stdout = result.stdout ?? '';\n    if (result.exitCode !== 0 && !stdout.trim()) {\n      throw new DiscoveryFailedError(result.stderr || `playwright exited with code ${result.exitCode}`);\n    }\n\n    let report: PlaywrightListReport;\n    try {\n      report = JSON.parse(stdout) as PlaywrightListReport;\n    } catch (error) {\n      throw new DiscoveryFailedError(\n        `could not parse --list JSON: ${error instanceof Error ? error.message : String(error)}`\n      );\n    }\n\n    // Playwright emits partial reports on spec load errors — fail loudly rather than\n    // mint a partial suite (silent-drop). \"No tests found\" is a benign zero-match.\n    const loadErrors = (report.errors ?? []).filter((e) => !isNoTestsFoundError(e));\n    if (loadErrors.length > 0) {\n      throw new DiscoveryFailedError(\n        `Playwright could not load the full test suite (${loadErrors.length} error(s)); refusing to mint a partial set: ${listErrorMessage(loadErrors[0])}`\n      );\n    }\n    return report;\n  }\n}\n\nfunction listErrorMessage(err: unknown): string {\n  if (err && typeof err === 'object' && typeof (err as { message?: unknown }).message === 'string') {\n    return (err as { message: string }).message;\n  }\n  return String(err);\n}\n\nfunction isNoTestsFoundError(err: unknown): boolean {\n  return /no tests found/i.test(listErrorMessage(err));\n}\n","import { createHash } from 'node:crypto';\nimport type { PlaywrightListReport, PlaywrightJSONSuite, DiscoverUnit, DiscoverSpec } from './types.js';\n\n// Fan out on spec.tests so a spec with multiple project entries stays correct.\nexport function buildUnits(report: PlaywrightListReport): DiscoverUnit[] {\n  const byKey = new Map<string, DiscoverUnit>();\n\n  const visit = (suite: PlaywrightJSONSuite, titleChain: string[]): void => {\n    const chain = [...titleChain, suite.title];\n    for (const spec of suite.specs ?? []) {\n      const tags = spec.tags ?? [];\n      for (const test of spec.tests ?? []) {\n        const key = JSON.stringify([spec.file, test.projectName]);\n        let unit = byKey.get(key);\n        if (!unit) {\n          unit = { file: spec.file, project: test.projectName, tags: [], tests: [] };\n          byKey.set(key, unit);\n        }\n        unit.tests.push({\n          title: spec.title,\n          titlePath: [test.projectName, ...chain, spec.title],\n          tags,\n          line: spec.line,\n          column: spec.column,\n        });\n        for (const tag of tags) {\n          if (!unit.tags.includes(tag)) unit.tags.push(tag);\n        }\n      }\n    }\n    for (const child of suite.suites ?? []) visit(child, chain);\n  };\n\n  for (const fileSuite of report.suites ?? []) visit(fileSuite, []);\n\n  return [...byKey.values()].sort((a, b) => a.file.localeCompare(b.file) || a.project.localeCompare(b.project));\n}\n\n// NUL-join because project names can contain '|', '\\', or spaces — any printable\n// separator can collide across file+project pairs. Grep folded in only when present.\nexport function computeSuiteFingerprint(units: DiscoverUnit[], grep?: string): string {\n  const keys = units.map((u) => `${u.file}\\x00${u.project}`).sort();\n  const base = keys.join('\\n');\n  const input = grep ? `${base}\\x00grep=${grep}` : base;\n  return createHash('sha256').update(input).digest('hex');\n}\n\nexport function buildDiscoverSpecs(units: DiscoverUnit[]): DiscoverSpec[] {\n  const byUnit = new Map<string, DiscoverSpec>();\n  for (const unit of units) {\n    // Key by file+project (not file alone) so multi-browser suites stay distinct;\n    // NUL-join because project names can contain spaces (\"Desktop Chrome\").\n    const key = `${unit.file}\\0${unit.project}`;\n    let spec = byUnit.get(key);\n    if (!spec) {\n      spec = { file: unit.file, project: unit.project, tests: [] };\n      byUnit.set(key, spec);\n    }\n    for (const test of unit.tests) {\n      spec.tests.push({ titlePath: test.titlePath });\n    }\n  }\n  return [...byUnit.values()];\n}\n","import { PlaywrightListRunner } from './playwright-list-runner.js';\nimport { buildUnits, buildDiscoverSpecs, computeSuiteFingerprint } from './unit-builder.js';\nimport { NoTestsDiscoveredError } from '../errors.js';\nimport type { DiscoverClient, MintDiscoverResponse } from './mint-client.js';\n\nexport interface DiscoverMintInput {\n  grep?: string;\n  project?: string[];\n  machines: number;\n  workers: number;\n  fullyParallel: boolean;\n}\n\nexport interface DiscoverMintResult extends MintDiscoverResponse {\n  suiteFingerprint: string;\n  totalTests: number;\n}\n\nexport class SwarmMintCommand {\n  constructor(\n    private readonly listRunner: PlaywrightListRunner = new PlaywrightListRunner(),\n    private readonly client: DiscoverClient\n  ) {}\n\n  async execute(input: DiscoverMintInput): Promise<DiscoverMintResult> {\n    const report = await this.listRunner.list({ grep: input.grep, projects: input.project });\n    const units = buildUnits(report);\n    const totalTests = units.reduce((n, u) => n + u.tests.length, 0);\n    if (totalTests === 0) throw new NoTestsDiscoveredError(input.grep, input.project);\n\n    const suiteFingerprint = computeSuiteFingerprint(units, input.grep);\n    const specs = buildDiscoverSpecs(units);\n    const response = await this.client.mint({\n      suiteFingerprint,\n      machines: input.machines,\n      workers: input.workers,\n      fullyParallel: input.fullyParallel,\n      specs,\n      ...(input.grep ? { grep: input.grep } : {}),\n    });\n\n    return { ...response, suiteFingerprint, totalTests };\n  }\n}\n","import { hostname } from 'os';\n\nexport interface MachineIdSources {\n  flag?: string;\n  env?: NodeJS.ProcessEnv;\n}\n\n// Call once per process — the id is this machine's identity on the socket; a mid-session\n// change registers as an extra machine and skews batch distribution.\nexport function resolveMachineId(sources: MachineIdSources = {}): string {\n  const flag = sources.flag?.trim();\n  if (flag) return flag;\n\n  const env = sources.env ?? process.env;\n  const explicit = env.TESTDINO_MACHINE_ID?.trim();\n  if (explicit) return explicit;\n\n  const ciIndex = env.CI_NODE_INDEX?.trim() || env.CIRCLE_NODE_INDEX?.trim();\n  if (ciIndex) return `ci-${ciIndex}`;\n\n  return `${hostname()}-${process.pid}`;\n}\n","import { randomUUID } from 'crypto';\nimport { TestCommand } from '../commands/test.js';\nimport { Logger } from '../logger.js';\nimport { SwarmWsClient, SwarmWsError } from './ws-client.js';\nimport type { SwarmWsClientOptions, SwarmWsOutcome } from './ws-client.js';\n\nexport interface SwarmRunLoopOptions {\n  serverUrl: string;\n  token: string;\n  swarmId: string;\n  machineId: string;\n  passthroughArgs: string[];\n  debug?: boolean;\n  logger: Logger;\n  testCommand?: TestCommand;\n  clientFactory?: (options: SwarmWsClientOptions) => SwarmWsClient;\n}\n\nexport class SwarmRunLoop {\n  private readonly serverUrl: string;\n  private readonly token: string;\n  private readonly swarmId: string;\n  private readonly machineId: string;\n  private readonly passthroughArgs: string[];\n  private readonly debug: boolean;\n  private readonly logger: Logger;\n  private readonly testCommand: TestCommand;\n  private readonly clientFactory: (options: SwarmWsClientOptions) => SwarmWsClient;\n\n  private client: SwarmWsClient | null = null;\n  // Re-applied to each batch so the runner executes only the discovered tests.\n  private assignGrep?: string;\n  private busy = false;\n  // Single-slot: a third queued is a protocol violation. Project rides per-batch.\n  // gen: the socket generation the batch arrived on; a batch from a dead socket was re-queued by the hub.\n  private queued: { specs: string[]; project?: string; batchId?: string; gen: number } | null = null;\n  private reconnectRequested = false;\n  private sigintRequested = false;\n  private fatalOverlap = false;\n\n  constructor(options: SwarmRunLoopOptions) {\n    this.serverUrl = options.serverUrl;\n    this.token = options.token;\n    this.swarmId = options.swarmId;\n    this.machineId = options.machineId;\n    this.passthroughArgs = options.passthroughArgs;\n    this.debug = options.debug ?? false;\n    this.logger = options.logger;\n    this.testCommand =\n      options.testCommand ??\n      new TestCommand(undefined, undefined, undefined, undefined, undefined, undefined, this.logger);\n    this.clientFactory = options.clientFactory ?? ((opts) => new SwarmWsClient(opts));\n  }\n\n  async run(): Promise<number> {\n    const onSignal = (): void => {\n      this.sigintRequested = true;\n      this.client?.close();\n    };\n    // SIGTERM matters for Kubernetes rollouts / CI cancel; targeted pre-clear survives\n    // a re-run in the same process without nuking unrelated handlers.\n    process.removeListener('SIGINT', onSignal);\n    process.removeListener('SIGTERM', onSignal);\n    process.on('SIGINT', onSignal);\n    process.on('SIGTERM', onSignal);\n\n    try {\n      for (;;) {\n        this.client = this.buildClient();\n\n        let outcome: SwarmWsOutcome;\n        try {\n          outcome = await this.client.connect();\n        } catch (error) {\n          if (error instanceof SwarmWsError) {\n            this.logger.error(`Swarm session failed: ${error.message}`);\n            return 1;\n          }\n          throw error;\n        }\n\n        if (this.fatalOverlap) return 1;\n\n        if (outcome === 'ended') return 0;\n\n        // SIGINT wins over a racing reconnect request.\n        if (this.sigintRequested) return 130;\n        if (this.reconnectRequested) {\n          this.reconnectRequested = false;\n          continue;\n        }\n        return 0;\n      }\n    } finally {\n      process.removeListener('SIGINT', onSignal);\n      process.removeListener('SIGTERM', onSignal);\n    }\n  }\n\n  private buildClient(): SwarmWsClient {\n    const options: SwarmWsClientOptions = {\n      serverUrl: this.serverUrl,\n      token: this.token,\n      swarmId: this.swarmId,\n      machineId: this.machineId,\n      onAssign: (specs, grep, project, batchId) => this.onAssign(specs, grep, project, batchId),\n      onDebug: this.debug ? (m) => this.logger.debug(m) : undefined,\n    };\n    return this.clientFactory(options);\n  }\n\n  // Sync ws callback — must not await the run or the socket read pump blocks.\n  private onAssign(specs: string[], grep?: string, project?: string, batchId?: string): void {\n    this.assignGrep = grep;\n    if (this.busy) {\n      if (this.queued !== null) {\n        this.fatalOverlap = true;\n        this.logger.error('Swarm protocol violation: a second batch was assigned while one was already queued');\n        this.client?.close();\n        return;\n      }\n      this.queued = { specs, project, batchId, gen: this.client?.currentGeneration() ?? 0 };\n      return;\n    }\n    this.busy = true;\n    // Catch defensively: a throw from processAssign's finally would crash Node ≥18.\n    void this.processAssign(specs, project, batchId).catch((err) =>\n      this.logger.error(`Swarm batch dispatch error: ${err instanceof Error ? err.message : String(err)}`)\n    );\n  }\n\n  private async processAssign(specs: string[], project?: string, batchId?: string): Promise<void> {\n    let ackDropped = false;\n    try {\n      if (specs.length === 0) {\n        this.logger.debug('Received an empty batch (no specs); requeuing via reconnect');\n        this.reconnectRequested = true;\n        this.client?.close();\n        return;\n      }\n\n      const runId = randomUUID();\n      const result = await this.testCommand.execute(\n        {\n          token: this.token,\n          serverUrl: this.serverUrl,\n          debug: this.debug,\n          swarmId: this.swarmId,\n          runId,\n          machineId: this.machineId,\n        },\n        [...this.passthroughArgs, ...this.grepArgs(), ...this.projectArgs(project), ...specs]\n      );\n\n      if (result.resultsProduced) {\n        // Acked even after a socket bounce: the batch id lets the hub answer\n        // `stale` if it already re-queued the batch, and clear it otherwise. A\n        // dropped ack is never re-sent — the hub re-queues on the disconnect.\n        const acked = (await this.client?.ack([runId], batchId ?? '')) ?? false;\n        if (!acked) ackDropped = true;\n      } else {\n        // No results → never ack; reconnect so the backend crash-requeues.\n        this.reconnectRequested = true;\n        this.client?.close();\n      }\n    } catch (error) {\n      this.reconnectRequested = true;\n      this.logger.error(`Swarm batch execution error: ${error instanceof Error ? error.message : String(error)}`);\n      this.client?.close();\n    } finally {\n      this.busy = false;\n      // A batch queued on a socket that has since died was re-queued by the hub —\n      // running it locally would double-run.\n      if (this.queued !== null) {\n        const staleSocket = this.queued.gen !== (this.client?.currentGeneration() ?? 0);\n        if (this.reconnectRequested || this.sigintRequested || this.fatalOverlap || ackDropped || staleSocket) {\n          this.queued = null;\n        } else {\n          const next = this.queued;\n          this.queued = null;\n          this.busy = true;\n          void this.processAssign(next.specs, next.project, next.batchId).catch((err) =>\n            this.logger.error(`Swarm batch dispatch error: ${err instanceof Error ? err.message : String(err)}`)\n          );\n        }\n      }\n    }\n  }\n\n  private grepArgs(): string[] {\n    if (!this.assignGrep) return [];\n    const hasOwnGrep = this.passthroughArgs.some((a) => a === '--grep' || a.startsWith('--grep=') || a === '-g');\n    return hasOwnGrep ? [] : ['--grep', this.assignGrep];\n  }\n\n  private projectArgs(project?: string): string[] {\n    if (!project) return [];\n    const hasOwnProject = this.passthroughArgs.some((a) => a === '--project' || a.startsWith('--project='));\n    // Equals form REQUIRED: --project is variadic, the space form swallows trailing spec files.\n    return hasOwnProject ? [] : [`--project=${project}`];\n  }\n}\n","import type { IncomingMessage } from 'node:http';\nimport WebSocket from 'ws';\nimport type { RawData } from 'ws';\nimport { buildSwarmWsUrl } from './ws-url.js';\n\nexport type SwarmWsErrorKind = 'auth' | 'protocol' | 'exhausted';\n\nexport class SwarmWsError extends Error {\n  readonly kind: SwarmWsErrorKind;\n\n  constructor(message: string, kind: SwarmWsErrorKind) {\n    super(message);\n    this.name = 'SwarmWsError';\n    this.kind = kind;\n  }\n}\n\nexport type SwarmWsOutcome = 'ended' | 'closed';\n\nexport interface SwarmWsClientOptions {\n  serverUrl: string;\n  token: string;\n  swarmId: string;\n  machineId: string;\n  onAssign: (specs: string[], grep?: string, project?: string, batchId?: string) => void;\n  onOpen?: () => void;\n  onEnd?: () => void;\n  onError?: (message: string) => void;\n  onDebug?: (message: string) => void;\n  maxReconnectAttempts?: number;\n  baseReconnectDelayMs?: number;\n  maxReconnectDelayMs?: number;\n  handshakeTimeoutMs?: number;\n  // Default 70s: sits above the hub's ~54s ping cadence (pongWait 60s × 9/10).\n  livenessTimeoutMs?: number;\n}\n\nexport class SwarmWsClient {\n  private readonly onAssign: (specs: string[], grep?: string, project?: string, batchId?: string) => void;\n  private readonly onOpen: () => void;\n  private readonly onEnd: () => void;\n  private readonly onError: (message: string) => void;\n  private readonly onDebug: (message: string) => void;\n  private readonly maxReconnectAttempts: number;\n  private readonly baseReconnectDelayMs: number;\n  private readonly maxReconnectDelayMs: number;\n  private readonly handshakeTimeoutMs: number;\n  private readonly livenessTimeoutMs: number;\n\n  private ws: WebSocket | null = null;\n  private connectPromise: Promise<SwarmWsOutcome> | null = null;\n  private resolveConnect: ((outcome: SwarmWsOutcome) => void) | null = null;\n  private rejectConnect: ((err: SwarmWsError) => void) | null = null;\n  private settled = false;\n  private closedByCaller = false;\n  private attempt = 0;\n  private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n  private livenessTimer: ReturnType<typeof setTimeout> | null = null;\n  // Bumped on every 'open'; a change under an inflight batch means the backend requeued.\n  private generation = 0;\n\n  constructor(private readonly options: SwarmWsClientOptions) {\n    this.onAssign = options.onAssign;\n    this.onOpen = options.onOpen ?? (() => {});\n    this.onEnd = options.onEnd ?? (() => {});\n    this.onError = options.onError ?? (() => {});\n    this.onDebug = options.onDebug ?? (() => {});\n    this.maxReconnectAttempts = options.maxReconnectAttempts ?? 10;\n    this.baseReconnectDelayMs = options.baseReconnectDelayMs ?? 1000;\n    this.maxReconnectDelayMs = options.maxReconnectDelayMs ?? 30_000;\n    this.handshakeTimeoutMs = options.handshakeTimeoutMs ?? 15_000;\n    this.livenessTimeoutMs = options.livenessTimeoutMs ?? 70_000;\n  }\n\n  // Do NOT await before acking — the promise settles at session end; acks fire from callbacks.\n  connect(): Promise<SwarmWsOutcome> {\n    if (this.connectPromise) return this.connectPromise;\n    this.connectPromise = new Promise<SwarmWsOutcome>((resolve, reject) => {\n      this.resolveConnect = resolve;\n      this.rejectConnect = reject;\n    });\n    this.openSocket();\n    return this.connectPromise;\n  }\n\n  // Awaits ws's send-completion callback: readyState can flip to CLOSING between check and flush.\n  async ack(runIds: string[], batchId: string): Promise<boolean> {\n    const socket = this.ws;\n    if (!socket || socket.readyState !== WebSocket.OPEN) {\n      this.onDebug(`ack skipped: socket not open (${runIds.length} runIds)`);\n      return false;\n    }\n    return new Promise<boolean>((resolve) => {\n      try {\n        socket.send(JSON.stringify({ action: 'ack', batchId, runIds }), (err) => {\n          if (err) {\n            this.onDebug(`ack send failed: ${err.message}`);\n            resolve(false);\n          } else {\n            resolve(true);\n          }\n        });\n      } catch (err) {\n        this.onDebug(`ack send threw: ${err instanceof Error ? err.message : String(err)}`);\n        resolve(false);\n      }\n    });\n  }\n\n  currentGeneration(): number {\n    return this.generation;\n  }\n\n  close(): void {\n    this.closedByCaller = true;\n    this.clearReconnectTimer();\n    this.clearLivenessTimer();\n    if (this.ws) this.ws.close(1000);\n    this.resolveWith('closed');\n  }\n\n  private openSocket(): void {\n    if (this.settled || this.closedByCaller) return;\n    const url = buildSwarmWsUrl(this.options.serverUrl, this.options.swarmId, this.options.machineId);\n    // handshakeTimeout: a stalled upgrade emits 'error' → scheduleReconnect, not hang.\n    const socket = new WebSocket(url, {\n      headers: { Authorization: `Bearer ${this.options.token}` },\n      handshakeTimeout: this.handshakeTimeoutMs,\n    });\n    this.ws = socket;\n\n    socket.on('open', () => {\n      if (socket !== this.ws) return;\n      this.attempt = 0;\n      this.generation++;\n      this.resetLivenessTimer();\n      this.onDebug('swarm socket open');\n      this.safeInvoke(() => this.onOpen(), 'onOpen');\n    });\n    socket.on('message', (data: RawData) => {\n      if (socket !== this.ws) return;\n      this.resetLivenessTimer();\n      this.handleMessage(data);\n    });\n    // Received ping is proof of life — server drives keepalive, ws auto-pongs.\n    socket.on('ping', () => {\n      if (socket !== this.ws) return;\n      this.resetLivenessTimer();\n    });\n    socket.on('error', (err: Error) => {\n      if (socket !== this.ws) return;\n      this.onDebug(`swarm socket error: ${err.message}`);\n      this.scheduleReconnect();\n    });\n    socket.on('close', () => {\n      if (socket !== this.ws) return;\n      // Only an end frame terminates; a bare close (any code, incl. 1000) reconnects.\n      this.scheduleReconnect();\n    });\n    socket.on('unexpected-response', (_req: unknown, res: IncomingMessage) => {\n      if (socket !== this.ws) return;\n      const status = res.statusCode ?? 0;\n      const retryable = status === 408 || status === 425 || status === 429;\n      if (status >= 400 && status < 500 && !retryable) {\n        this.rejectWith(`swarm handshake rejected with ${status}`, 'auth');\n      } else {\n        this.onDebug(`swarm handshake responded ${status} — reconnecting`);\n        this.scheduleReconnect();\n      }\n      socket.terminate();\n    });\n  }\n\n  private handleMessage(data: RawData): void {\n    // Drop late frames (error-then-end, second end) after settlement — no duplicate callbacks.\n    if (this.settled) return;\n    let msg: unknown;\n    try {\n      msg = JSON.parse(data.toString());\n    } catch {\n      this.onDebug('ignoring non-JSON frame');\n      return;\n    }\n    if (!msg || typeof msg !== 'object') {\n      this.onDebug('ignoring malformed frame');\n      return;\n    }\n    const frame = msg as {\n      event?: unknown;\n      batchId?: unknown;\n      specs?: unknown;\n      grep?: unknown;\n      project?: unknown;\n      data?: unknown;\n    };\n    switch (frame.event) {\n      case 'assign': {\n        // Non-empty specs only: empty string substring-matches every file → whole-suite run.\n        if (!Array.isArray(frame.specs) || !frame.specs.every((s) => typeof s === 'string' && s.length > 0)) {\n          this.onDebug('ignoring assign frame with malformed specs');\n          return;\n        }\n        const grep = typeof frame.grep === 'string' && frame.grep.length > 0 ? frame.grep : undefined;\n        const project = typeof frame.project === 'string' && frame.project.length > 0 ? frame.project : undefined;\n        const batchId = typeof frame.batchId === 'string' && frame.batchId.length > 0 ? frame.batchId : undefined;\n        this.safeInvoke(() => this.onAssign(frame.specs as string[], grep, project, batchId), 'onAssign');\n        return;\n      }\n      case 'end': {\n        // Settle FIRST — a throwing onEnd must not leave connect() unsettled with a live timer.\n        this.resolveWith('ended');\n        this.safeInvoke(() => this.onEnd(), 'onEnd');\n        this.ws?.close(1000);\n        return;\n      }\n      case 'error': {\n        const payload = frame.data as { message?: unknown } | undefined;\n        const message = typeof payload?.message === 'string' ? payload.message : 'swarm error';\n        this.rejectWith(message, 'protocol');\n        this.safeInvoke(() => this.onError(message), 'onError');\n        return;\n      }\n      default:\n        this.onDebug(`ignoring frame with unknown event: ${String(frame.event)}`);\n    }\n  }\n\n  private scheduleReconnect(): void {\n    this.clearLivenessTimer();\n    if (this.settled || this.closedByCaller) return;\n    // Dedup the error+close pair a single drop fires.\n    if (this.reconnectTimer) return;\n    this.attempt++;\n    if (this.attempt > this.maxReconnectAttempts) {\n      this.rejectWith(`swarm socket unreachable after ${this.maxReconnectAttempts} attempts`, 'exhausted');\n      return;\n    }\n    const delay = this.backoffDelay(this.attempt);\n    this.onDebug(`swarm reconnect attempt ${this.attempt} in ${Math.round(delay)}ms`);\n    this.reconnectTimer = setTimeout(() => {\n      this.reconnectTimer = null;\n      this.openSocket();\n    }, delay);\n  }\n\n  private backoffDelay(attempt: number): number {\n    const capped = Math.min(this.baseReconnectDelayMs * Math.pow(2, attempt - 1), this.maxReconnectDelayMs);\n    return capped * (0.8 + Math.random() * 0.4);\n  }\n\n  // terminate() on half-open socket → 'close' → scheduleReconnect.\n  private resetLivenessTimer(): void {\n    this.clearLivenessTimer();\n    if (this.settled || this.closedByCaller) return;\n    const socket = this.ws;\n    this.livenessTimer = setTimeout(() => {\n      this.livenessTimer = null;\n      if (socket !== this.ws) return;\n      this.onDebug(`swarm socket silent for ${this.livenessTimeoutMs}ms — terminating to reconnect`);\n      socket?.terminate();\n    }, this.livenessTimeoutMs);\n  }\n\n  private clearLivenessTimer(): void {\n    if (this.livenessTimer) {\n      clearTimeout(this.livenessTimer);\n      this.livenessTimer = null;\n    }\n  }\n\n  private clearReconnectTimer(): void {\n    if (this.reconnectTimer) {\n      clearTimeout(this.reconnectTimer);\n      this.reconnectTimer = null;\n    }\n  }\n\n  // Traps callback throws — an EventEmitter handler exception can crash the process.\n  private safeInvoke(fn: () => void, label: string): void {\n    try {\n      fn();\n    } catch (err) {\n      this.onDebug(`${label} callback threw: ${err instanceof Error ? err.message : String(err)}`);\n    }\n  }\n\n  private resolveWith(outcome: SwarmWsOutcome): void {\n    if (this.settled) return;\n    this.settled = true;\n    this.clearLivenessTimer();\n    this.clearReconnectTimer();\n    this.resolveConnect?.(outcome);\n  }\n\n  private rejectWith(message: string, kind: SwarmWsErrorKind): void {\n    if (this.settled) return;\n    this.settled = true;\n    this.clearLivenessTimer();\n    this.clearReconnectTimer();\n    if (this.ws) this.ws.close(1000);\n    this.rejectConnect?.(new SwarmWsError(message, kind));\n  }\n}\n","import { InvalidServerUrlError } from '../errors.js';\n\n// Strip user:pass@ — ws would send Basic alongside Bearer and leak into error logs.\nexport function buildSwarmWsUrl(serverUrl: string, swarmId: string, machineId: string): string {\n  let url: URL;\n  try {\n    url = new URL(serverUrl);\n  } catch {\n    throw new InvalidServerUrlError(serverUrl);\n  }\n  if (url.protocol === 'https:') url.protocol = 'wss:';\n  else if (url.protocol === 'http:') url.protocol = 'ws:';\n  else throw new InvalidServerUrlError(serverUrl);\n\n  url.username = '';\n  url.password = '';\n  url.pathname = '/ws/swarm/' + encodeURIComponent(swarmId);\n  url.search = '';\n  url.searchParams.set('machineId', machineId);\n  return url.toString();\n}\n","import { ConfigLoader } from '../config-loader.js';\nimport { ConfigDetector } from '../config-detector.js';\nimport { ConfigMerger } from '../config-merger.js';\nimport { Logger } from '../logger.js';\nimport { TestDinoError, TokenMissingError } from '../errors.js';\nimport { resolveMachineId } from './machine-id.js';\nimport { SwarmRunLoop } from './run-loop.js';\n\nexport interface SwarmJoinCliOptions {\n  id: string;\n  machineId?: string;\n  token?: string;\n  serverUrl?: string;\n  debug?: boolean;\n}\n\n/** `tdpw swarm --id <swarmId>`: join the swarm and run the batches it assigns. */\nexport async function joinSwarm(\n  logger: Logger,\n  options: SwarmJoinCliOptions,\n  passthroughArgs: string[]\n): Promise<void> {\n  try {\n    const machineId = resolveMachineId({ flag: options.machineId });\n\n    const testdinoConfig = await new ConfigLoader().load();\n    const detection = await new ConfigDetector().detect();\n    const merged = new ConfigMerger().merge({\n      env: ConfigMerger.getEnvConfig(),\n      playwrightConfig: detection.options,\n      testdinoConfig: testdinoConfig.config,\n      cliOptions: { token: options.token, serverUrl: options.serverUrl, debug: options.debug },\n    });\n    if (!merged.token) throw new TokenMissingError();\n\n    const loop = new SwarmRunLoop({\n      serverUrl: merged.serverUrl ?? '',\n      token: merged.token,\n      swarmId: options.id,\n      machineId,\n      passthroughArgs,\n      debug: options.debug,\n      logger,\n    });\n\n    process.exitCode = await loop.run();\n  } catch (error) {\n    if (error instanceof TestDinoError) {\n      logger.error(error.message);\n    } else {\n      logger.error(error instanceof Error ? error.message : String(error), error instanceof Error ? error : undefined);\n    }\n    process.exitCode = 1;\n  }\n}\n","export interface SwarmModeInputs {\n  machines?: string;\n  id?: string;\n  envMachines?: string;\n}\n\nexport type SwarmMode = { mode: 'start' } | { mode: 'join'; id: string } | { mode: 'error'; message: string };\n\n/**\n * One command, two modes. Decided here rather than inline so a missing `--id`\n * can never fall through to starting a second swarm that no machine joins.\n */\nexport function resolveSwarmMode(inputs: SwarmModeInputs): SwarmMode {\n  const starting = inputs.machines !== undefined || inputs.envMachines !== undefined;\n  if (starting && inputs.id !== undefined) {\n    return { mode: 'error', message: 'Pass either --machines (start a swarm) or --id (join one), not both.' };\n  }\n  if (inputs.id !== undefined) {\n    return inputs.id.trim() === ''\n      ? { mode: 'error', message: '--id needs the swarm id to join.' }\n      : { mode: 'join', id: inputs.id };\n  }\n  if (starting) return { mode: 'start' };\n  return {\n    mode: 'error',\n    message: 'Nothing to do: pass --machines <N> to start a swarm, or --id <swarmId> to join one.',\n  };\n}\n","export interface SwarmOperands {\n  passthrough: string[];\n  stray: string[];\n}\n\n/**\n * Split `tdpw swarm` operands at the `--` separator. Everything before it is a\n * mistake (a leftover sub-command, a stray spec path): Commander's\n * allowExcessArguments would otherwise swallow it, and in join mode it would\n * reach `playwright test` as a spec filter and silently narrow the batch.\n */\nexport function splitSwarmOperands(argv: string[]): SwarmOperands {\n  const sep = argv.indexOf('--');\n  if (sep === -1) return { passthrough: [], stray: argv.filter((a) => !a.startsWith('-')) };\n  return {\n    passthrough: argv.slice(sep + 1),\n    stray: argv.slice(0, sep).filter((a) => !a.startsWith('-')),\n  };\n}\n"],"mappings":"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","names":["existsSync","join","dirname","fileURLToPath","createJiti","join","existsSync","createJiti","dirname","fileURLToPath","writeFileSync","existsSync","join","tmpdir","randomUUID","readFileSync","join","dirname","join","fileURLToPath","PACKAGE_NAME","join","readFileSync","resolve","logger","writeFileSync","existsSync","randomUUID","join","tmpdir","randomUUID","readFileSync","unlinkSync","tmpdir","join","logger","join","tmpdir","randomUUID","unlinkSync","readFileSync","resolve","sleep","readFileSync","unlinkSync","writeFileSync","tmpdir","dirname","join","randomUUID","execa","readFileSync","tmpdir","join","join","tmpdir","execa","readFileSync","resolve","NOT_READY_BUDGET_MS","NOT_READY_POLL_MS","REQUEST_TIMEOUT_MS","defaultSleep","resolve","sleep","logger","writeFileSync","axios","axios","execa","execa","logger","writeFileSync","randomUUID","resolve","randomUUID","logger"]}