@open-mercato/cli 0.6.3-develop.3562.1.71049275ff → 0.6.3-develop.3574.1.f3c5dcf345

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -809,6 +809,8 @@ async function writeEphemeralEnvironmentState(input2) {
809
809
  status: "running",
810
810
  baseUrl: input2.baseUrl,
811
811
  port: input2.port,
812
+ databaseUrl: input2.databaseUrl,
813
+ queueBaseDir: input2.queueBaseDir,
812
814
  source: input2.logPrefix,
813
815
  captureScreenshots: input2.captureScreenshots,
814
816
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -849,6 +851,12 @@ async function readEphemeralEnvironmentState() {
849
851
  if (typeof record.port !== "number" || !Number.isFinite(record.port) || record.port < 1) {
850
852
  return null;
851
853
  }
854
+ if (typeof record.databaseUrl !== "string" || record.databaseUrl.length === 0) {
855
+ return null;
856
+ }
857
+ if (typeof record.queueBaseDir !== "string" || record.queueBaseDir.length === 0) {
858
+ return null;
859
+ }
852
860
  if (typeof record.source !== "string" || record.source.length === 0) {
853
861
  return null;
854
862
  }
@@ -862,6 +870,8 @@ async function readEphemeralEnvironmentState() {
862
870
  status: "running",
863
871
  baseUrl: record.baseUrl,
864
872
  port: record.port,
873
+ databaseUrl: record.databaseUrl,
874
+ queueBaseDir: record.queueBaseDir,
865
875
  source: record.source,
866
876
  captureScreenshots: record.captureScreenshots,
867
877
  startedAt: record.startedAt
@@ -1183,9 +1193,10 @@ async function acquireEphemeralRuntimeLock(logPrefix, options = {}) {
1183
1193
  }
1184
1194
  };
1185
1195
  }
1186
- function buildReusableEnvironment(baseUrl, captureScreenshots) {
1196
+ function buildReusableEnvironment(baseUrl, databaseUrl, queueBaseDir, captureScreenshots) {
1187
1197
  const enterpriseModulesFlag = process.env.OM_ENABLE_ENTERPRISE_MODULES ?? "false";
1188
1198
  return buildEnvironment({
1199
+ DATABASE_URL: databaseUrl,
1189
1200
  BASE_URL: baseUrl,
1190
1201
  APP_URL: baseUrl,
1191
1202
  NEXT_PUBLIC_APP_URL: baseUrl,
@@ -1208,6 +1219,7 @@ function buildReusableEnvironment(baseUrl, captureScreenshots) {
1208
1219
  TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? "om-ephemeral-integration-fallback-key",
1209
1220
  OM_CLI_QUIET: "1",
1210
1221
  MERCATO_QUIET: "1",
1222
+ QUEUE_BASE_DIR: queueBaseDir,
1211
1223
  NODE_NO_WARNINGS: "1",
1212
1224
  PW_CAPTURE_SCREENSHOTS: captureScreenshots ? "1" : "0"
1213
1225
  });
@@ -1258,8 +1270,13 @@ async function tryReuseExistingEnvironment(options) {
1258
1270
  return {
1259
1271
  baseUrl: state.baseUrl,
1260
1272
  port: state.port,
1261
- databaseUrl: "",
1262
- commandEnvironment: buildReusableEnvironment(state.baseUrl, state.captureScreenshots),
1273
+ databaseUrl: state.databaseUrl,
1274
+ commandEnvironment: buildReusableEnvironment(
1275
+ state.baseUrl,
1276
+ state.databaseUrl,
1277
+ state.queueBaseDir,
1278
+ state.captureScreenshots
1279
+ ),
1263
1280
  ownedByCurrentProcess: false,
1264
1281
  stop: async () => {
1265
1282
  }
@@ -2423,6 +2440,8 @@ async function startEphemeralEnvironment(options) {
2423
2440
  await writeEphemeralEnvironmentState({
2424
2441
  baseUrl: applicationBaseUrl,
2425
2442
  port: applicationPort,
2443
+ databaseUrl,
2444
+ queueBaseDir: EPHEMERAL_QUEUE_BASE_DIR,
2426
2445
  logPrefix: options.logPrefix,
2427
2446
  captureScreenshots: options.captureScreenshots
2428
2447
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/testing/integration.ts"],
4
- "sourcesContent": ["import { GenericContainer } from 'testcontainers'\nimport type { ChildProcess, StdioOptions } from 'node:child_process'\nimport { createServer } from 'node:net'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { mkdir, readdir, readFile, rm, stat, writeFile } from 'node:fs/promises'\nimport { createHash } from 'node:crypto'\nimport path from 'node:path'\nimport { createInterface, type Interface } from 'node:readline/promises'\nimport { stdin as input, stdout as output } from 'node:process'\nimport spawn from 'cross-spawn'\nimport { resolveEnvironment } from '../resolver'\nimport { resolveSpawnCommand } from '../spawn'\nimport { discoverIntegrationSpecFiles as discoverIntegrationSpecFilesShared } from './integration-discovery'\nimport { resolveDockerHostFromContext, runCommandAndCapture } from './runtime-utils'\n\ntype EphemeralRuntimeOptions = {\n verbose: boolean\n captureScreenshots: boolean\n logPrefix: string\n forceRebuild?: boolean\n reuseExisting?: boolean\n requiredExistingSource?: string\n environmentOverrides?: NodeJS.ProcessEnv\n}\n\nexport type EphemeralEnvironmentHandle = {\n baseUrl: string\n port: number\n databaseUrl: string\n commandEnvironment: NodeJS.ProcessEnv\n ownedByCurrentProcess: boolean\n stop: () => Promise<void>\n}\n\ntype IntegrationOptions = {\n keep: boolean\n filter: string | null\n captureScreenshots: boolean\n verbose: boolean\n forceRebuild: boolean\n reuseExisting: boolean\n}\n\ntype EphemeralAppOptions = {\n verbose: boolean\n captureScreenshots: boolean\n forceRebuild: boolean\n reuseExisting: boolean\n}\n\ntype InteractiveIntegrationOptions = {\n verbose: boolean\n captureScreenshots: boolean\n workers: number | null\n retries: number | null\n forceRebuild: boolean\n reuseExisting: boolean\n}\n\ntype IntegrationSpecTarget = {\n path: string\n description: string\n}\n\ntype DiscoveredIntegrationSpecFile = {\n path: string\n moduleName: string | null\n isOverlay: boolean\n requiredModules: string[]\n}\n\ntype IntegrationCoverageOptions = {\n filter: string | null\n captureScreenshots: boolean\n verbose: boolean\n workers: number | null\n retries: number | null\n shard: string | null\n json: boolean\n keepRawV8: boolean\n forceRebuild: boolean\n reuseExisting: boolean\n}\n\ntype IntegrationSpecCoverageOptions = {\n json: boolean\n strict: boolean\n}\n\ntype IntegrationCoverageReport = {\n generatedAt: string\n testRun: IntegrationTestRunSummary | null\n scenarios: {\n total: number\n covered: number\n uncovered: number\n coveragePercent: number\n }\n tests: {\n total: number\n withScenario: number\n withoutScenario: number\n }\n categories: Array<{\n code: string\n scenarioCount: number\n coveredScenarioCount: number\n testCount: number\n coveragePercent: number | null\n }>\n requiredTestFolders: {\n present: string[]\n missing: string[]\n }\n uncoveredScenarioIds: string[]\n testsWithoutScenarioIds: string[]\n}\n\ntype IntegrationTestRunSummary = {\n status: 'passed' | 'failed'\n total: number\n passed: number\n failed: number\n flaky: number\n skipped: number\n durationMs: number | null\n startTime: string | null\n}\n\nexport function shouldUseIsolatedPortForFreshEnvironment(options: {\n reuseExisting: boolean | undefined\n existingStateBeforeReuseAttempt: EphemeralEnvironmentState | null\n}): boolean {\n return options.reuseExisting === false || options.existingStateBeforeReuseAttempt !== null\n}\n\ntype EphemeralEnvironmentState = {\n status: 'running'\n baseUrl: string\n port: number\n source: string\n captureScreenshots: boolean\n startedAt: string\n}\n\ntype PlaywrightRunOptions = Pick<InteractiveIntegrationOptions, 'verbose' | 'captureScreenshots' | 'workers' | 'retries'> & {\n shard?: string | null\n}\n\nconst DEFAULT_APP_READY_TIMEOUT_MS = 90_000\nconst APP_READY_INTERVAL_MS = 1_000\nconst DEFAULT_EPHEMERAL_APP_PORT = 5001\nconst EPHEMERAL_ENV_LOCK_TIMEOUT_MS = 5 * 60_000\nconst EPHEMERAL_ENV_LOCK_POLL_MS = 500\nconst DEFAULT_BUILD_CACHE_TTL_SECONDS = 600\nconst APP_READY_TIMEOUT_ENV_VAR = 'OM_INTEGRATION_APP_READY_TIMEOUT_SECONDS'\nconst BUILD_CACHE_TTL_ENV_VAR = 'OM_INTEGRATION_BUILD_CACHE_TTL_SECONDS'\nconst PLAYWRIGHT_ENV_UNAVAILABLE_PATTERNS: RegExp[] = [\n /net::ERR_CONNECTION_REFUSED/i,\n /Failed to connect to .* (localhost|127\\.0\\.0\\.1)/i,\n /Error: connect ECONNREFUSED/i,\n /Error: read ECONNRESET/i,\n /socket hang up/i,\n /ERR_CONNECTION_RESET/i,\n /ERR_ADDRESS_UNREACHABLE/i,\n]\nconst PLAYWRIGHT_QUICK_FAILURE_THRESHOLD = 6\nconst PLAYWRIGHT_QUICK_FAILURE_MAX_DURATION_MS = 1_500\nconst PLAYWRIGHT_HEALTH_PROBE_INTERVAL_MS = 3_000\nconst ANSI_ESCAPE_REGEX = /\\x1b\\[[0-?]*[ -/]*[@-~]/g // NOSONAR \u2014 ANSI escape sequence pattern\nconst env = resolveEnvironment()\nconst projectRootDirectory = env.rootDir\nconst appDirectory = env.appDir\nconst corePackageRootDirectory = env.packageRoot('@open-mercato/core')\nconst uiPackageRootDirectory = env.packageRoot('@open-mercato/ui')\nconst EPHEMERAL_RUNTIME_LOCK_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-runtime.lock')\n\nfunction resolveFirstExistingPath(...candidates: string[]): string | null {\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n return null\n}\n\nfunction collectExistingPaths(candidates: Array<string | null | undefined>): string[] {\n const collected = new Set<string>()\n for (const candidate of candidates) {\n if (candidate && existsSync(candidate)) {\n collected.add(candidate)\n }\n }\n return Array.from(collected)\n}\n\nfunction readPackageScripts(packageRoot: string): Record<string, string> {\n try {\n const raw = JSON.parse(readFileSync(path.join(packageRoot, 'package.json'), 'utf8')) as {\n scripts?: Record<string, string>\n }\n return raw.scripts ?? {}\n } catch {\n return {}\n }\n}\n\nconst projectScripts = readPackageScripts(projectRootDirectory)\nconst appNextConfigPath = resolveFirstExistingPath(\n path.join(appDirectory, 'next.config.ts'),\n path.join(appDirectory, 'next.config.js'),\n path.join(appDirectory, 'next.config.mjs'),\n)\nconst APP_MODULES_CHECKSUM_PATH = path.join(appDirectory, '.mercato', 'generated', 'modules.generated.checksum')\nconst PROJECT_SUPPORTS_PACKAGE_BUILDS = typeof projectScripts['build:packages'] === 'string'\nconst EPHEMERAL_ENV_FILE_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.json')\nconst EPHEMERAL_ENV_LOCK_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.lock')\nconst LEGACY_EPHEMERAL_ENV_FILE_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.md')\nconst EPHEMERAL_BUILD_CACHE_STATE_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-build-cache.json')\nconst EPHEMERAL_CACHE_DB_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-cache.sqlite')\nconst EPHEMERAL_QUEUE_BASE_DIR = path.join(appDirectory, '.mercato', 'queue')\nconst PLAYWRIGHT_INTEGRATION_CONFIG_PATH = '.ai/qa/tests/playwright.config.ts'\nconst PLAYWRIGHT_RESULTS_JSON_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'test-results', 'results.json')\nconst LEGACY_INTEGRATION_TEST_ROOT = path.join(projectRootDirectory, '.ai', 'qa', 'tests')\nconst NEXT_BUILD_OUTPUT_DIRECTORIES = [\n path.join(appDirectory, '.mercato', 'next'),\n path.join(appDirectory, '.next'),\n]\nconst APP_BUILD_ARTIFACTS = collectExistingPaths([\n path.join(appDirectory, '.mercato', 'next', 'BUILD_ID'),\n path.join(appDirectory, '.next', 'BUILD_ID'),\n path.join(appDirectory, '.mercato', 'generated', 'modules.generated.ts'),\n path.join(corePackageRootDirectory, 'dist', 'index.js'),\n path.join(uiPackageRootDirectory, 'dist', 'index.js'),\n])\nconst APP_BUILD_INPUT_PATHS = collectExistingPaths([\n path.join(appDirectory, 'src'),\n path.join(appDirectory, 'package.json'),\n appNextConfigPath,\n path.join(appDirectory, 'tsconfig.json'),\n resolveFirstExistingPath(path.join(corePackageRootDirectory, 'src'), path.join(corePackageRootDirectory, 'dist')),\n path.join(corePackageRootDirectory, 'package.json'),\n path.join(corePackageRootDirectory, 'tsconfig.json'),\n resolveFirstExistingPath(path.join(uiPackageRootDirectory, 'src'), path.join(uiPackageRootDirectory, 'dist')),\n path.join(uiPackageRootDirectory, 'package.json'),\n path.join(uiPackageRootDirectory, 'tsconfig.json'),\n path.join(projectRootDirectory, 'package.json'),\n path.join(projectRootDirectory, 'tsconfig.base.json'),\n path.join(projectRootDirectory, 'yarn.lock'),\n])\nconst EXPECTED_TEST_FOLDERS = ['auth', 'catalog', 'crm', 'sales', 'admin', 'api', 'integration'] as const\nconst FOLDER_TO_CATEGORY_CODE: Record<string, string> = {\n admin: 'ADMIN',\n auth: 'AUTH',\n catalog: 'CAT',\n crm: 'CRM',\n sales: 'SALES',\n api: 'API',\n integration: 'INT',\n}\nconst BUILD_CACHE_STATE_VERSION = 2\nconst BUILD_CACHE_ENV_KEYS = [\n 'NODE_ENV',\n 'OM_ENABLE_ENTERPRISE_MODULES',\n 'OM_ENABLE_ENTERPRISE_MODULES_SSO',\n 'OM_ENABLE_ENTERPRISE_MODULES_SECURITY',\n] as const\nconst IGNORED_EPHEMERAL_BUILD_CACHE_DIRS = new Set([\n 'node_modules',\n '.next',\n 'dist',\n '.turbo',\n '.yarn',\n '.cache',\n 'tmp',\n 'temp',\n 'coverage',\n '.git',\n '.ai',\n])\n\ntype BuildCacheState = {\n version: number\n builtAt: number\n sourceFingerprint: string\n environmentFingerprint: string\n artifactPaths: string[]\n projectRoot: string\n}\n\ntype BuildCacheOptions = {\n artifactPaths?: string[]\n inputPaths?: string[]\n cacheStatePath?: string\n projectRoot?: string\n precomputedSourceFingerprint?: string\n environmentFingerprint?: string\n}\n\ntype CommandOutputMonitoringResult = {\n exitCode: number | null\n output: string\n environmentUnavailableFromOutput: boolean\n}\n\ntype IntegrationCommandError = Error & {\n environmentUnavailableFromOutput?: boolean\n commandOutput?: string\n}\n\ntype CommandMonitoringOptions = {\n detectEnvironmentUnavailable?: boolean\n abortOnEnvironmentUnavailable?: boolean\n playwrightFailureHealthCheck?: PlaywrightFailureHealthCheckOptions\n}\n\ntype LoginPageProbeResult = {\n status: number | null\n healthy: boolean\n detail: string\n}\n\ntype BackendLoginProbeResult = {\n status: number | null\n healthy: boolean\n detail: string\n}\n\ntype AuthenticatedApiProbeResult = {\n loginStatus: number | null\n apiStatus: number | null\n healthy: boolean\n detail: string\n}\n\ntype ApplicationReadinessProbeResult = {\n ready: boolean\n frontend: LoginPageProbeResult\n backend: BackendLoginProbeResult\n authenticated: AuthenticatedApiProbeResult\n}\n\ntype PlaywrightFailureHealthCheckOptions = {\n baseUrl: string\n consecutiveFailureThreshold?: number\n quickFailureMaxDurationMs?: number\n minProbeIntervalMs?: number\n}\n\ntype TimedStepOptions = {\n expectedSeconds: number\n updateIntervalSeconds?: number\n}\n\nfunction resolveYarnBinary(): string {\n return process.platform === 'win32' ? 'yarn.cmd' : 'yarn'\n}\n\nfunction buildEnvironment(overrides: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n return {\n ...process.env,\n ...overrides,\n }\n}\n\nfunction buildEnvironmentFingerprint(environment: NodeJS.ProcessEnv): string {\n const publicKeys = Object.keys(environment)\n .filter((key) => key.startsWith('NEXT_PUBLIC_'))\n .sort((left, right) => left.localeCompare(right))\n const keys = Array.from(new Set([...BUILD_CACHE_ENV_KEYS, ...publicKeys]))\n const fingerprintParts = keys.map((key) => `${key}=${environment[key] ?? ''}`)\n return createHash('sha256').update(fingerprintParts.join('\\n'), 'utf8').digest('hex')\n}\n\nasync function resetNextBuildOutputDirectories(logPrefix: string): Promise<void> {\n for (const outputDirectory of NEXT_BUILD_OUTPUT_DIRECTORIES) {\n if (!existsSync(outputDirectory)) {\n continue\n }\n await rm(outputDirectory, { recursive: true, force: true })\n console.log(`[${logPrefix}] Reset Next build output directory at ${outputDirectory}.`)\n }\n}\n\nfunction runYarnCommand(\n args: string[],\n environment: NodeJS.ProcessEnv,\n opts: { silent?: boolean } = {},\n cwd: string = projectRootDirectory,\n): Promise<void> {\n return runYarnRawCommand(['run', ...args], environment, opts, cwd)\n}\n\nasync function runTimedStep<T>(\n logPrefix: string,\n label: string,\n options: TimedStepOptions,\n task: () => Promise<T>,\n): Promise<T> {\n const startedAt = Date.now()\n const intervalMs = Math.max(1, options.updateIntervalSeconds ?? 2) * 1000\n const timer = setInterval(() => {\n const elapsedSeconds = Math.max(1, Math.floor((Date.now() - startedAt) / 1000))\n const remainingSeconds = Math.max(0, options.expectedSeconds - elapsedSeconds)\n console.log(`[${logPrefix}] ${label}... ${elapsedSeconds}s elapsed, ~${remainingSeconds}s left`)\n }, intervalMs)\n\n try {\n const result = await task()\n const durationSeconds = Math.max(1, Math.floor((Date.now() - startedAt) / 1000))\n console.log(`[${logPrefix}] ${label} completed in ${durationSeconds}s.`)\n return result\n } finally {\n clearInterval(timer)\n }\n}\n\nfunction isPlaywrightEnvironmentUnavailableChunk(chunk: string): boolean {\n return PLAYWRIGHT_ENV_UNAVAILABLE_PATTERNS.some((pattern) => pattern.test(chunk))\n}\n\nfunction stripAnsiSequences(value: string): string {\n return value.replace(ANSI_ESCAPE_REGEX, '')\n}\n\nfunction parsePlaywrightResultLine(line: string): { kind: 'pass' | 'fail'; durationMs: number } | null {\n const normalized = line.trim()\n if (!normalized) {\n return null\n }\n\n const symbolMatch = normalized.match(/^\\s*([\u2713\u2714\u2718xX])\\s+\\d+\\s+/u)\n if (!symbolMatch) {\n return null\n }\n\n const durationMatches = Array.from(normalized.matchAll(/\\(([\\d.]+)(ms|s)\\)/g))\n const lastDurationMatch = durationMatches.at(-1)\n if (!lastDurationMatch) {\n return null\n }\n\n const symbol = symbolMatch[1]\n const rawDuration = Number.parseFloat(lastDurationMatch[1] ?? '')\n const unit = lastDurationMatch[2]\n if (!Number.isFinite(rawDuration) || rawDuration < 0) {\n return null\n }\n\n const durationMs = unit === 's' ? Math.round(rawDuration * 1000) : Math.round(rawDuration)\n return {\n kind: symbol === '\u2718' || symbol.toLowerCase() === 'x' ? 'fail' : 'pass',\n durationMs,\n }\n}\n\nasync function runCommandWithOutputMonitoring(\n command: string,\n commandArgs: string[],\n environment: NodeJS.ProcessEnv,\n opts: CommandMonitoringOptions = {},\n): Promise<CommandOutputMonitoringResult> {\n return new Promise((resolve, reject) => {\n const resolvedSpawn = resolveSpawnCommand(command, commandArgs)\n const commandHandle = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd: projectRootDirectory,\n env: environment,\n stdio: ['ignore', 'pipe', 'pipe'],\n ...resolvedSpawn.spawnOptions,\n })\n\n let output = ''\n let environmentUnavailableFromOutput = false\n let terminatedByOutput = false\n let trailingOutputLine = ''\n let consecutiveQuickFailures = 0\n let lastHealthProbeAt = 0\n let healthProbeQueue: Promise<void> = Promise.resolve()\n\n const failureHealthCheck = opts.playwrightFailureHealthCheck\n const quickFailureThreshold = failureHealthCheck?.consecutiveFailureThreshold ?? PLAYWRIGHT_QUICK_FAILURE_THRESHOLD\n const quickFailureMaxDurationMs = failureHealthCheck?.quickFailureMaxDurationMs ?? PLAYWRIGHT_QUICK_FAILURE_MAX_DURATION_MS\n const minProbeIntervalMs = failureHealthCheck?.minProbeIntervalMs ?? PLAYWRIGHT_HEALTH_PROBE_INTERVAL_MS\n\n const maybeProbeEnvironmentHealth = () => {\n if (!failureHealthCheck || terminatedByOutput || environmentUnavailableFromOutput) {\n return\n }\n if (consecutiveQuickFailures < quickFailureThreshold) {\n return\n }\n const now = Date.now()\n if (now - lastHealthProbeAt < minProbeIntervalMs) {\n return\n }\n lastHealthProbeAt = now\n healthProbeQueue = healthProbeQueue\n .then(async () => {\n const unavailable = await isEnvironmentUnavailable(failureHealthCheck.baseUrl)\n if (unavailable && !terminatedByOutput) {\n environmentUnavailableFromOutput = true\n terminatedByOutput = true\n commandHandle.kill('SIGTERM')\n }\n })\n .catch(() => undefined)\n }\n\n const processOutputLine = (line: string) => {\n const parsed = parsePlaywrightResultLine(line)\n if (!parsed) {\n return\n }\n if (parsed.kind === 'pass') {\n consecutiveQuickFailures = 0\n return\n }\n\n if (parsed.durationMs <= quickFailureMaxDurationMs) {\n consecutiveQuickFailures += 1\n maybeProbeEnvironmentHealth()\n return\n }\n\n consecutiveQuickFailures = 0\n }\n\n const handleChunk = (chunk: Buffer | string, stream: 'stdout' | 'stderr') => {\n const text = chunk.toString()\n const normalizedText = stripAnsiSequences(text)\n if (stream === 'stdout') {\n process.stdout.write(text)\n } else {\n process.stderr.write(text)\n }\n\n output += text\n if (output.length > 120_000) {\n output = output.slice(-80_000)\n }\n\n if (\n !environmentUnavailableFromOutput &&\n opts.detectEnvironmentUnavailable &&\n isPlaywrightEnvironmentUnavailableChunk(normalizedText)\n ) {\n environmentUnavailableFromOutput = true\n if (opts.abortOnEnvironmentUnavailable) {\n terminatedByOutput = true\n commandHandle.kill('SIGTERM')\n }\n }\n\n trailingOutputLine += normalizedText\n let newlineIndex = trailingOutputLine.indexOf('\\n')\n while (newlineIndex >= 0) {\n const currentLine = trailingOutputLine.slice(0, newlineIndex).replace(/\\r$/, '')\n processOutputLine(currentLine)\n trailingOutputLine = trailingOutputLine.slice(newlineIndex + 1)\n newlineIndex = trailingOutputLine.indexOf('\\n')\n }\n }\n\n commandHandle.stdout?.on('data', (chunk) => {\n handleChunk(chunk, 'stdout')\n })\n commandHandle.stderr?.on('data', (chunk) => {\n handleChunk(chunk, 'stderr')\n })\n commandHandle.on('error', reject)\n commandHandle.on('exit', (code: number | null) => {\n if (trailingOutputLine.trim().length > 0) {\n processOutputLine(trailingOutputLine.trimEnd())\n }\n healthProbeQueue.finally(() => {\n resolve({\n exitCode: code,\n output: output.trim(),\n environmentUnavailableFromOutput: environmentUnavailableFromOutput || terminatedByOutput,\n })\n })\n })\n })\n}\n\nfunction createMonitoredCommandError(\n commandLabel: string,\n args: string[],\n result: CommandOutputMonitoringResult,\n): IntegrationCommandError {\n const error = new Error(\n `Command failed: ${commandLabel} ${args.join(' ')} (exit ${result.exitCode ?? 'unknown'}).`,\n ) as IntegrationCommandError\n error.environmentUnavailableFromOutput = result.environmentUnavailableFromOutput\n error.commandOutput = result.output\n return error\n}\n\nasync function runYarnCommandWithOutputMonitoring(\n args: string[],\n environment: NodeJS.ProcessEnv,\n opts: CommandMonitoringOptions = {},\n): Promise<void> {\n const result = await runCommandWithOutputMonitoring(resolveYarnBinary(), ['run', ...args], environment, {\n detectEnvironmentUnavailable: opts.detectEnvironmentUnavailable,\n abortOnEnvironmentUnavailable: opts.abortOnEnvironmentUnavailable,\n playwrightFailureHealthCheck: opts.playwrightFailureHealthCheck,\n })\n\n if (result.exitCode === 0) {\n return\n }\n\n throw createMonitoredCommandError('yarn', ['run', ...args], result)\n}\n\nasync function runNpxCommandWithOutputMonitoring(\n args: string[],\n environment: NodeJS.ProcessEnv,\n opts: CommandMonitoringOptions = {},\n): Promise<void> {\n const binary = process.platform === 'win32' ? 'npx.cmd' : 'npx'\n const result = await runCommandWithOutputMonitoring(binary, args, environment, {\n detectEnvironmentUnavailable: opts.detectEnvironmentUnavailable,\n abortOnEnvironmentUnavailable: opts.abortOnEnvironmentUnavailable,\n playwrightFailureHealthCheck: opts.playwrightFailureHealthCheck,\n })\n\n if (result.exitCode === 0) {\n return\n }\n\n throw createMonitoredCommandError('npx', args, result)\n}\n\nfunction runYarnRawCommand(\n commandArgs: string[],\n environment: NodeJS.ProcessEnv,\n opts: { silent?: boolean } = {},\n cwd: string = projectRootDirectory,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const outputMode: StdioOptions = opts.silent ? ['ignore', 'pipe', 'pipe'] : 'inherit'\n const resolvedSpawn = resolveSpawnCommand(resolveYarnBinary(), commandArgs)\n const command: ChildProcess = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd,\n env: environment,\n stdio: outputMode,\n ...resolvedSpawn.spawnOptions,\n })\n let bufferedOutput = ''\n if (opts.silent) {\n command.stdout?.on('data', (chunk: Buffer | string) => {\n bufferedOutput += chunk.toString()\n })\n command.stderr?.on('data', (chunk: Buffer | string) => {\n bufferedOutput += chunk.toString()\n })\n }\n command.on('error', reject)\n command.on('exit', (code: number | null) => {\n if (code === 0) {\n resolve()\n return\n }\n const extra = opts.silent && bufferedOutput.trim().length > 0\n ? `\\nLast output:\\n${bufferedOutput.trim().split('\\n').slice(-20).join('\\n')}`\n : ''\n reject(new Error(`Command failed: yarn ${commandArgs.join(' ')} (exit ${code ?? 'unknown'})${extra}`))\n })\n })\n}\n\nfunction runNpxCommand(args: string[], environment: NodeJS.ProcessEnv): Promise<void> {\n const binary = process.platform === 'win32' ? 'npx.cmd' : 'npx'\n return new Promise((resolve, reject) => {\n const resolvedSpawn = resolveSpawnCommand(binary, args)\n const command = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd: projectRootDirectory,\n env: environment,\n stdio: 'inherit',\n ...resolvedSpawn.spawnOptions,\n })\n command.on('error', reject)\n command.on('exit', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n reject(new Error(`Command failed: npx ${args.join(' ')} (exit ${code ?? 'unknown'})`))\n })\n })\n}\n\nfunction startYarnRawCommand(\n commandArgs: string[],\n environment: NodeJS.ProcessEnv,\n opts: { silent?: boolean } = {},\n cwd: string = projectRootDirectory,\n): ChildProcess {\n const outputMode: StdioOptions = opts.silent ? ['ignore', 'pipe', 'pipe'] : 'inherit'\n const resolvedSpawn = resolveSpawnCommand(resolveYarnBinary(), commandArgs)\n const processHandle: ChildProcess = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd,\n env: environment,\n stdio: outputMode,\n ...resolvedSpawn.spawnOptions,\n })\n if (opts.silent) {\n processHandle.stdout?.on('data', () => {})\n processHandle.stderr?.on('data', () => {})\n }\n return processHandle\n}\n\nfunction startYarnCommand(\n args: string[],\n environment: NodeJS.ProcessEnv,\n opts: { silent?: boolean } = {},\n cwd: string = projectRootDirectory,\n): ChildProcess {\n return startYarnRawCommand(['run', ...args], environment, opts, cwd)\n}\n\nasync function assertContainerRuntimeAvailable(): Promise<void> {\n const dockerInfoResult = await runCommandAndCapture('docker', ['info'])\n if (dockerInfoResult.code === 0) {\n return\n }\n\n const normalizedError = dockerInfoResult.stderr.trim()\n let guidance = 'Container runtime is unavailable. Start Docker Desktop (or another Docker-compatible runtime) and retry.'\n if (dockerInfoResult.code === -1) {\n guidance = 'Docker CLI is not available in PATH. Install Docker Desktop (or Docker CLI + runtime), then retry.'\n } else if (normalizedError.includes('Cannot connect to the Docker daemon')) {\n guidance = 'Docker CLI is installed but daemon is not running. Start Docker Desktop, wait until it is healthy, then run `docker info` and retry.'\n }\n\n throw new Error(\n [\n 'Unable to start ephemeral integration environment.',\n `Cause: ${normalizedError || 'docker info failed'}`,\n `What to do: ${guidance}`,\n ].join(' '),\n )\n}\n\nfunction assertNode24Runtime(): void {\n const major = Number.parseInt(process.versions.node.split('.')[0] ?? '0', 10)\n if (major >= 24) {\n return\n }\n throw new Error(\n [\n 'Unsupported Node.js runtime for ephemeral integration tests.',\n `Cause: Detected Node ${process.versions.node}, but this repository requires Node 24.x.`,\n 'What to do: switch your shell to Node 24 (for example `nvm use 24`), reinstall dependencies (`yarn install`), then retry `yarn test:integration:ephemeral`.',\n ].join(' '),\n )\n}\n\nfunction getProcessExitPromise(command: ChildProcess): Promise<number | null> {\n return new Promise((resolve, reject) => {\n command.on('error', reject)\n command.on('exit', (code) => resolve(code))\n })\n}\n\nfunction delay(milliseconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, milliseconds)\n })\n}\n\nexport function resolveBuildCacheTtlSeconds(logPrefix: string): number {\n const rawValue = process.env[BUILD_CACHE_TTL_ENV_VAR]\n if (!rawValue) {\n return DEFAULT_BUILD_CACHE_TTL_SECONDS\n }\n const parsed = Number.parseInt(rawValue, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n console.warn(\n `[${logPrefix}] Invalid ${BUILD_CACHE_TTL_ENV_VAR} value \"${rawValue}\". Using default ${DEFAULT_BUILD_CACHE_TTL_SECONDS}s.`,\n )\n return DEFAULT_BUILD_CACHE_TTL_SECONDS\n }\n return parsed\n}\n\nexport function resolveAppReadyTimeoutMs(logPrefix: string): number {\n const rawValue = process.env[APP_READY_TIMEOUT_ENV_VAR]\n if (!rawValue) {\n return DEFAULT_APP_READY_TIMEOUT_MS\n }\n const parsedSeconds = Number.parseInt(rawValue, 10)\n if (!Number.isFinite(parsedSeconds) || parsedSeconds < 1) {\n console.warn(\n `[${logPrefix}] Invalid ${APP_READY_TIMEOUT_ENV_VAR} value \"${rawValue}\". Using default ${DEFAULT_APP_READY_TIMEOUT_MS / 1000}s.`,\n )\n return DEFAULT_APP_READY_TIMEOUT_MS\n }\n return parsedSeconds * 1000\n}\n\nfunction buildCacheDefaults(overrides: BuildCacheOptions = {}): {\n artifactPaths: string[]\n inputPaths: string[]\n cacheStatePath: string\n projectRoot: string\n} {\n return {\n artifactPaths: overrides.artifactPaths ?? APP_BUILD_ARTIFACTS,\n inputPaths: overrides.inputPaths ?? APP_BUILD_INPUT_PATHS,\n cacheStatePath: overrides.cacheStatePath ?? EPHEMERAL_BUILD_CACHE_STATE_PATH,\n projectRoot: overrides.projectRoot ?? projectRootDirectory,\n }\n}\n\nfunction isIgnoredBuildCacheDirectory(entryName: string): boolean {\n return IGNORED_EPHEMERAL_BUILD_CACHE_DIRS.has(entryName) || entryName.startsWith('.')\n}\n\nasync function getAllBuildInputFiles(inputPath: string, projectRoot: string): Promise<string[]> {\n const normalized = path.normalize(inputPath)\n const pathStats = await stat(normalized)\n if (pathStats.isFile()) {\n return [path.relative(projectRoot, normalized)]\n }\n if (!pathStats.isDirectory()) {\n return []\n }\n\n const entries = await readdir(normalized, { withFileTypes: true })\n const files: string[] = []\n for (const entry of entries) {\n if (entry.isDirectory() && isIgnoredBuildCacheDirectory(entry.name)) {\n continue\n }\n if (entry.isDirectory()) {\n const nested = await getAllBuildInputFiles(path.join(normalized, entry.name), projectRoot)\n files.push(...nested)\n continue\n }\n if (!entry.isFile()) {\n continue\n }\n files.push(path.join(normalized, entry.name))\n }\n return files\n}\n\nasync function buildSourceFingerprint(options: BuildCacheOptions = {}): Promise<string | null> {\n const { inputPaths, projectRoot } = buildCacheDefaults(options)\n const seenPaths = new Set<string>()\n const absoluteFiles: string[] = []\n\n for (const inputPath of inputPaths) {\n let collected: string[]\n try {\n collected = await getAllBuildInputFiles(inputPath, projectRoot)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n\n for (const filePath of collected) {\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(projectRoot, filePath)\n if (!seenPaths.has(resolvedPath)) {\n seenPaths.add(resolvedPath)\n absoluteFiles.push(resolvedPath)\n }\n }\n }\n\n if (absoluteFiles.length === 0) {\n return null\n }\n\n const fingerprintParts: string[] = []\n for (const filePath of absoluteFiles.sort((a, b) => a.localeCompare(b))) {\n const fileStat = await stat(filePath)\n if (!fileStat.isFile()) {\n continue\n }\n const relativePath = path.relative(projectRoot, filePath).split(path.sep).join('/')\n fingerprintParts.push(`${relativePath}:${fileStat.size}:${Math.floor(fileStat.mtimeMs)}`)\n }\n\n if (fingerprintParts.length === 0) {\n return null\n }\n\n return createHash('sha256').update(fingerprintParts.join('\\n'), 'utf8').digest('hex')\n}\n\nasync function hasBuildInputChangesSince(\n timestampMs: number,\n options: BuildCacheOptions = {},\n): Promise<boolean> {\n const { inputPaths, projectRoot } = buildCacheDefaults(options)\n const seenPaths = new Set<string>()\n\n for (const inputPath of inputPaths) {\n let collected: string[]\n try {\n collected = await getAllBuildInputFiles(inputPath, projectRoot)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n continue\n }\n throw error\n }\n\n for (const filePath of collected) {\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(projectRoot, filePath)\n if (seenPaths.has(resolvedPath)) {\n continue\n }\n seenPaths.add(resolvedPath)\n\n let fileStat: Awaited<ReturnType<typeof stat>>\n try {\n fileStat = await stat(resolvedPath)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return true\n }\n throw error\n }\n if (fileStat.isFile() && fileStat.mtimeMs > timestampMs) {\n return true\n }\n }\n }\n\n return false\n}\n\nasync function readBuildCacheState(cacheStatePath: string): Promise<BuildCacheState | null> {\n let rawText: string\n try {\n rawText = await readFile(cacheStatePath, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n\n let parsed: unknown = null\n try {\n parsed = JSON.parse(rawText)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object') {\n return null\n }\n const maybeState = parsed as Partial<BuildCacheState>\n if (maybeState.version !== BUILD_CACHE_STATE_VERSION) {\n return null\n }\n if (typeof maybeState.builtAt !== 'number' || !Number.isFinite(maybeState.builtAt)) {\n return null\n }\n if (typeof maybeState.sourceFingerprint !== 'string' || maybeState.sourceFingerprint.length === 0) {\n return null\n }\n if (typeof maybeState.environmentFingerprint !== 'string' || maybeState.environmentFingerprint.length === 0) {\n return null\n }\n if (!Array.isArray(maybeState.artifactPaths) || maybeState.artifactPaths.length === 0) {\n return null\n }\n if (typeof maybeState.projectRoot !== 'string' || maybeState.projectRoot.length === 0) {\n return null\n }\n\n return {\n version: BUILD_CACHE_STATE_VERSION,\n builtAt: maybeState.builtAt,\n sourceFingerprint: maybeState.sourceFingerprint,\n environmentFingerprint: maybeState.environmentFingerprint,\n artifactPaths: maybeState.artifactPaths.filter((entry): entry is string => typeof entry === 'string'),\n projectRoot: maybeState.projectRoot,\n }\n}\n\nasync function writeBuildCacheState(\n sourceFingerprint: string,\n options: BuildCacheOptions = {},\n): Promise<void> {\n const defaults = buildCacheDefaults(options)\n const environmentFingerprint = options.environmentFingerprint ?? ''\n if (!environmentFingerprint) {\n throw new Error('Build cache state requires an environment fingerprint.')\n }\n await mkdir(path.dirname(defaults.cacheStatePath), { recursive: true })\n await writeFile(\n defaults.cacheStatePath,\n `${JSON.stringify(\n {\n version: BUILD_CACHE_STATE_VERSION,\n builtAt: Date.now(),\n sourceFingerprint,\n environmentFingerprint,\n artifactPaths: defaults.artifactPaths,\n projectRoot: defaults.projectRoot,\n },\n null,\n 2,\n )}\\n`,\n 'utf8',\n )\n}\n\nasync function isBuildArtifactMissing(filePath: string): Promise<boolean> {\n try {\n const artifactStats = await stat(filePath)\n return !artifactStats.isFile() || artifactStats.size <= 0\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return true\n }\n throw error\n }\n}\n\nexport async function shouldReuseBuildArtifacts(\n ttlSeconds: number,\n logPrefix: string,\n options: BuildCacheOptions = {},\n): Promise<boolean> {\n if (ttlSeconds <= 0) {\n console.log(`[${logPrefix}] Build cache disabled: ${BUILD_CACHE_TTL_ENV_VAR} is set to ${ttlSeconds}.`)\n return false\n }\n\n const defaults = buildCacheDefaults(options)\n const currentSourceFingerprint = options.precomputedSourceFingerprint ?? (await buildSourceFingerprint(defaults))\n const currentEnvironmentFingerprint = options.environmentFingerprint ?? ''\n if (!currentSourceFingerprint) {\n console.log(\n `[${logPrefix}] Build cache disabled: unable to collect source fingerprints from tracked sources.`,\n )\n return false\n }\n if (!currentEnvironmentFingerprint) {\n console.log(`[${logPrefix}] Build cache disabled: missing environment fingerprint for cache validation.`)\n return false\n }\n\n const state = await readBuildCacheState(defaults.cacheStatePath)\n if (!state) {\n console.log(`[${logPrefix}] Build cache disabled: missing or invalid cache metadata (${defaults.cacheStatePath}).`)\n return false\n }\n\n if (state.projectRoot !== defaults.projectRoot) {\n console.log(`[${logPrefix}] Build cache disabled: project root changed since cache creation.`)\n return false\n }\n\n const buildAgeSeconds = Math.floor((Date.now() - state.builtAt) / 1000)\n if (buildAgeSeconds > ttlSeconds) {\n console.log(\n `[${logPrefix}] Build cache disabled: last build age ${buildAgeSeconds}s exceeds ${BUILD_CACHE_TTL_ENV_VAR}=${ttlSeconds}s.`,\n )\n return false\n }\n\n if (state.sourceFingerprint !== currentSourceFingerprint) {\n console.log(`[${logPrefix}] Build cache disabled: source files changed since last build.`)\n return false\n }\n if (state.environmentFingerprint !== currentEnvironmentFingerprint) {\n console.log(`[${logPrefix}] Build cache disabled: build-shaping environment changed since last build.`)\n return false\n }\n\n for (const artifactPath of defaults.artifactPaths) {\n if (await isBuildArtifactMissing(artifactPath)) {\n console.log(`[${logPrefix}] Build cache disabled: missing build artifact ${artifactPath}.`)\n return false\n }\n }\n\n console.log(\n `[${logPrefix}] Reusing existing build artifacts (last build age ${buildAgeSeconds}s, TTL ${ttlSeconds}s).`,\n )\n return true\n}\n\nexport async function shouldRebuildBuildArtifacts(\n ttlSeconds: number,\n logPrefix: string,\n options: BuildCacheOptions = {},\n): Promise<boolean> {\n return !(await shouldReuseBuildArtifacts(ttlSeconds, logPrefix, options))\n}\n\nasync function getFreePort(): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = createServer()\n server.on('error', reject)\n server.listen(0, '127.0.0.1', () => {\n const address = server.address()\n if (!address || typeof address === 'string') {\n server.close()\n reject(new Error('Unable to allocate free port'))\n return\n }\n const port = address.port\n server.close((closeError) => {\n if (closeError) {\n reject(closeError)\n return\n }\n resolve(port)\n })\n })\n })\n}\n\nasync function isPortAvailable(port: number): Promise<boolean> {\n const canBind = (host: string): Promise<boolean | null> => new Promise((resolve) => {\n const server = createServer()\n server.once('error', (error) => {\n const errorCode = (error as NodeJS.ErrnoException).code\n if (errorCode === 'EAFNOSUPPORT') {\n resolve(null)\n return\n }\n resolve(false)\n })\n server.listen(port, host, () => {\n server.close(() => {\n resolve(true)\n })\n })\n })\n\n const ipv4Availability = await canBind('127.0.0.1')\n if (ipv4Availability === false) {\n return false\n }\n\n const ipv6Availability = await canBind('::1')\n if (ipv6Availability === false) {\n return false\n }\n\n return ipv4Availability === true || ipv6Availability === true\n}\n\nasync function getPreferredPort(preferredPort: number): Promise<number> {\n if (await isPortAvailable(preferredPort)) {\n return preferredPort\n }\n const fallbackPort = await getFreePort()\n console.log(`[ephemeral] Port ${preferredPort} is busy, using fallback port ${fallbackPort}.`)\n return fallbackPort\n}\n\nexport async function writeEphemeralEnvironmentState(input: {\n baseUrl: string\n port: number\n logPrefix: string\n captureScreenshots: boolean\n}): Promise<void> {\n const content: EphemeralEnvironmentState = {\n status: 'running',\n baseUrl: input.baseUrl,\n port: input.port,\n source: input.logPrefix,\n captureScreenshots: input.captureScreenshots,\n startedAt: new Date().toISOString(),\n }\n await writeFile(EPHEMERAL_ENV_FILE_PATH, `${JSON.stringify(content, null, 2)}\\n`, 'utf8')\n}\n\nexport async function clearEphemeralEnvironmentState(): Promise<void> {\n await rm(EPHEMERAL_ENV_FILE_PATH, { force: true })\n await rm(LEGACY_EPHEMERAL_ENV_FILE_PATH, { force: true })\n}\n\nexport async function readEphemeralEnvironmentState(): Promise<EphemeralEnvironmentState | null> {\n let sourceText = ''\n try {\n sourceText = await readFile(EPHEMERAL_ENV_FILE_PATH, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n\n let parsed: unknown = null\n try {\n parsed = JSON.parse(sourceText)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object') {\n return null\n }\n\n const record = parsed as Partial<EphemeralEnvironmentState>\n if (record.status !== 'running') {\n return null\n }\n if (typeof record.baseUrl !== 'string' || record.baseUrl.length === 0) {\n return null\n }\n if (typeof record.port !== 'number' || !Number.isFinite(record.port) || record.port < 1) {\n return null\n }\n if (typeof record.source !== 'string' || record.source.length === 0) {\n return null\n }\n if (typeof record.captureScreenshots !== 'boolean') {\n return null\n }\n if (typeof record.startedAt !== 'string' || record.startedAt.length === 0) {\n return null\n }\n\n return {\n status: 'running',\n baseUrl: record.baseUrl,\n port: record.port,\n source: record.source,\n captureScreenshots: record.captureScreenshots,\n startedAt: record.startedAt,\n }\n}\n\nfunction isLoginHtmlHealthy(html: string): boolean {\n return !/Application error: a client-side exception has occurred/i.test(html)\n}\n\nfunction isSuccessfulBrowserNavigationStatus(status: number): boolean {\n return status === 200 || (status >= 300 && status < 400)\n}\n\nasync function probeLoginPage(baseUrl: string): Promise<LoginPageProbeResult> {\n try {\n const response = await fetch(`${baseUrl}/login`, {\n method: 'GET',\n redirect: 'manual',\n })\n if (!isSuccessfulBrowserNavigationStatus(response.status)) {\n return {\n status: response.status,\n healthy: false,\n detail: `GET /login returned ${response.status}`,\n }\n }\n if (response.status !== 200) {\n return {\n status: response.status,\n healthy: true,\n detail: `GET /login returned redirect ${response.status}`,\n }\n }\n const html = await response.text().catch(() => '')\n if (!isLoginHtmlHealthy(html)) {\n return {\n status: response.status,\n healthy: false,\n detail: 'GET /login returned client-side exception HTML',\n }\n }\n return {\n status: response.status,\n healthy: true,\n detail: 'GET /login returned healthy HTML',\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n status: null,\n healthy: false,\n detail: `GET /login failed: ${message}`,\n }\n }\n}\n\nasync function probeBackendLoginEndpoint(baseUrl: string): Promise<BackendLoginProbeResult> {\n try {\n const form = new URLSearchParams()\n form.set('email', 'integration-healthcheck@example.invalid')\n form.set('password', 'invalid-password')\n const response = await fetch(`${baseUrl}/api/auth/login`, {\n method: 'POST',\n redirect: 'manual',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: form.toString(),\n })\n\n const healthy = response.status === 200 || response.status === 400 || response.status === 401 || response.status === 403\n return {\n status: response.status,\n healthy,\n detail: healthy\n ? `POST /api/auth/login returned ${response.status}`\n : `POST /api/auth/login returned unexpected ${response.status}`,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n status: null,\n healthy: false,\n detail: `POST /api/auth/login failed: ${message}`,\n }\n }\n}\n\nasync function probeAuthenticatedApi(baseUrl: string): Promise<AuthenticatedApiProbeResult> {\n try {\n const form = new URLSearchParams()\n form.set('email', 'admin@acme.com')\n form.set('password', 'secret')\n const loginResponse = await fetch(`${baseUrl}/api/auth/login`, {\n method: 'POST',\n redirect: 'manual',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: form.toString(),\n })\n\n const rawBody = await loginResponse.text().catch(() => '')\n let token: string | null = null\n if (rawBody) {\n try {\n const parsed = JSON.parse(rawBody) as { token?: unknown }\n token = typeof parsed.token === 'string' && parsed.token.length > 0 ? parsed.token : null\n } catch {\n token = null\n }\n }\n\n if (!loginResponse.ok || !token) {\n return {\n loginStatus: loginResponse.status,\n apiStatus: null,\n healthy: false,\n detail: loginResponse.ok\n ? 'POST /api/auth/login did not return an auth token'\n : `POST /api/auth/login returned ${loginResponse.status}`,\n }\n }\n\n const apiResponse = await fetch(`${baseUrl}/api/customers/people?pageSize=1`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n })\n\n const healthy = apiResponse.status === 200\n return {\n loginStatus: loginResponse.status,\n apiStatus: apiResponse.status,\n healthy,\n detail: healthy\n ? 'Authenticated GET /api/customers/people returned 200'\n : `Authenticated GET /api/customers/people returned ${apiResponse.status}`,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n loginStatus: null,\n apiStatus: null,\n healthy: false,\n detail: `Authenticated readiness probe failed: ${message}`,\n }\n }\n}\n\nasync function probeApplicationReadiness(baseUrl: string): Promise<ApplicationReadinessProbeResult> {\n const [frontend, backend, authenticated] = await Promise.all([\n probeLoginPage(baseUrl),\n probeBackendLoginEndpoint(baseUrl),\n probeAuthenticatedApi(baseUrl),\n ])\n\n return {\n ready: frontend.healthy && backend.healthy && authenticated.healthy,\n frontend,\n backend,\n authenticated,\n }\n}\n\nasync function acquireEphemeralEnvironmentLock(logPrefix: string): Promise<{ release: () => Promise<void> }> {\n await mkdir(path.dirname(EPHEMERAL_ENV_LOCK_PATH), { recursive: true })\n const deadlineTimestamp = Date.now() + EPHEMERAL_ENV_LOCK_TIMEOUT_MS\n let waitingLogged = false\n\n while (true) {\n try {\n await mkdir(EPHEMERAL_ENV_LOCK_PATH)\n const lockOwnerPath = path.join(EPHEMERAL_ENV_LOCK_PATH, 'owner.json')\n await writeFile(\n lockOwnerPath,\n `${JSON.stringify({ pid: process.pid, source: logPrefix, acquiredAt: new Date().toISOString() }, null, 2)}\\n`,\n 'utf8',\n )\n return {\n release: async () => {\n await rm(EPHEMERAL_ENV_LOCK_PATH, { recursive: true, force: true })\n },\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error\n }\n if (await clearStaleEphemeralEnvironmentLock(logPrefix)) {\n continue\n }\n }\n\n const remainingMilliseconds = deadlineTimestamp - Date.now()\n if (remainingMilliseconds <= 0) {\n throw new Error(\n `Timed out after ${EPHEMERAL_ENV_LOCK_TIMEOUT_MS / 1000}s waiting for ephemeral environment setup lock at ${EPHEMERAL_ENV_LOCK_PATH}.`,\n )\n }\n\n if (!waitingLogged) {\n console.log(`[${logPrefix}] Waiting for another process to finish preparing the ephemeral environment...`)\n waitingLogged = true\n }\n await delay(Math.min(EPHEMERAL_ENV_LOCK_POLL_MS, remainingMilliseconds))\n }\n}\n\nfunction isProcessRunning(processId: number): boolean {\n try {\n process.kill(processId, 0)\n return true\n } catch (error) {\n return (error as NodeJS.ErrnoException).code !== 'ESRCH'\n }\n}\n\nasync function getPathAgeMilliseconds(targetPath: string): Promise<number | null> {\n try {\n const stats = await stat(targetPath)\n return Date.now() - stats.mtimeMs\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n}\n\nasync function clearStaleEphemeralEnvironmentLock(logPrefix: string): Promise<boolean> {\n const lockOwnerPath = path.join(EPHEMERAL_ENV_LOCK_PATH, 'owner.json')\n let ownerPid: number | null = null\n\n let ownerReadFailed = false\n try {\n const ownerSource = await readFile(lockOwnerPath, 'utf8')\n const parsed = JSON.parse(ownerSource) as { pid?: unknown }\n if (typeof parsed.pid === 'number' && Number.isInteger(parsed.pid) && parsed.pid > 0) {\n ownerPid = parsed.pid\n }\n } catch {\n ownerReadFailed = true\n }\n\n if (ownerPid === null) {\n const lockAge = await getPathAgeMilliseconds(EPHEMERAL_ENV_LOCK_PATH)\n if (lockAge === null) {\n return false\n }\n if (ownerReadFailed && lockAge > EPHEMERAL_ENV_LOCK_TIMEOUT_MS) {\n await rm(EPHEMERAL_ENV_LOCK_PATH, { recursive: true, force: true })\n console.log(`[${logPrefix}] Removed stale ephemeral environment lock with invalid owner metadata.`)\n return true\n }\n return false\n }\n\n if (isProcessRunning(ownerPid)) {\n return false\n }\n\n await rm(EPHEMERAL_ENV_LOCK_PATH, { recursive: true, force: true })\n console.log(`[${logPrefix}] Removed stale ephemeral environment lock from exited process ${ownerPid}.`)\n return true\n}\n\ntype EphemeralRuntimeLockOptions = {\n lockPath?: string\n isProcessRunning?: (processId: number) => boolean\n}\n\ntype EphemeralRuntimeLockOwner = {\n pid: number\n source?: string\n acquiredAt?: string\n}\n\nasync function readEphemeralRuntimeLockOwner(lockPath: string): Promise<EphemeralRuntimeLockOwner | null> {\n const ownerPath = path.join(lockPath, 'owner.json')\n let ownerSource = ''\n try {\n ownerSource = await readFile(ownerPath, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n\n let parsed: unknown = null\n try {\n parsed = JSON.parse(ownerSource)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object') {\n return null\n }\n\n const record = parsed as Partial<EphemeralRuntimeLockOwner>\n if (typeof record.pid !== 'number' || !Number.isInteger(record.pid) || record.pid < 1) {\n return null\n }\n\n return {\n pid: record.pid,\n source: typeof record.source === 'string' ? record.source : undefined,\n acquiredAt: typeof record.acquiredAt === 'string' ? record.acquiredAt : undefined,\n }\n}\n\nasync function clearStaleEphemeralRuntimeLock(\n logPrefix: string,\n options: Required<EphemeralRuntimeLockOptions>,\n): Promise<boolean> {\n const owner = await readEphemeralRuntimeLockOwner(options.lockPath)\n const lockAge = await getPathAgeMilliseconds(options.lockPath)\n if (!owner) {\n if (lockAge !== null && lockAge > EPHEMERAL_ENV_LOCK_TIMEOUT_MS) {\n await rm(options.lockPath, { recursive: true, force: true })\n console.log(`[${logPrefix}] Removed stale ephemeral runtime lock with invalid owner metadata.`)\n return true\n }\n return false\n }\n\n if (options.isProcessRunning(owner.pid)) {\n return false\n }\n\n await rm(options.lockPath, { recursive: true, force: true })\n console.log(`[${logPrefix}] Removed stale ephemeral runtime lock from exited process ${owner.pid}.`)\n return true\n}\n\nexport async function acquireEphemeralRuntimeLock(\n logPrefix: string,\n options: EphemeralRuntimeLockOptions = {},\n): Promise<{ release: () => Promise<void> }> {\n const resolvedOptions: Required<EphemeralRuntimeLockOptions> = {\n lockPath: options.lockPath ?? EPHEMERAL_RUNTIME_LOCK_PATH,\n isProcessRunning: options.isProcessRunning ?? isProcessRunning,\n }\n\n await mkdir(path.dirname(resolvedOptions.lockPath), { recursive: true })\n\n try {\n await mkdir(resolvedOptions.lockPath)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error\n }\n\n if (await clearStaleEphemeralRuntimeLock(logPrefix, resolvedOptions)) {\n return acquireEphemeralRuntimeLock(logPrefix, resolvedOptions)\n }\n\n const owner = await readEphemeralRuntimeLockOwner(resolvedOptions.lockPath)\n const ownerSource = owner?.source ? ` started by \"${owner.source}\"` : ''\n const ownerPid = owner?.pid ? ` (pid ${owner.pid})` : ''\n throw new Error(\n `[${logPrefix}] Another ephemeral environment is already active${ownerSource}${ownerPid}. Reuse the running environment or stop it before starting a fresh ephemeral run, because a second build/generate pipeline would overwrite shared workspace artifacts.`,\n )\n }\n\n const ownerPath = path.join(resolvedOptions.lockPath, 'owner.json')\n await writeFile(\n ownerPath,\n `${JSON.stringify({ pid: process.pid, source: logPrefix, acquiredAt: new Date().toISOString() }, null, 2)}\\n`,\n 'utf8',\n )\n\n return {\n release: async () => {\n await rm(resolvedOptions.lockPath, { recursive: true, force: true })\n },\n }\n}\n\nfunction buildReusableEnvironment(baseUrl: string, captureScreenshots: boolean): NodeJS.ProcessEnv {\n const enterpriseModulesFlag = process.env.OM_ENABLE_ENTERPRISE_MODULES ?? 'false'\n return buildEnvironment({\n BASE_URL: baseUrl,\n APP_URL: baseUrl,\n NEXT_PUBLIC_APP_URL: baseUrl,\n NODE_ENV: 'production',\n JWT_SECRET: process.env.JWT_SECRET ?? 'om-ephemeral-integration-jwt-secret',\n OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? 'om-ephemeral-integration-mfa-setup-secret',\n OM_INTEGRATION_TEST: 'true',\n OM_ENABLE_ENTERPRISE_MODULES: enterpriseModulesFlag,\n OM_ENABLE_ENTERPRISE_MODULES_SSO: process.env.OM_ENABLE_ENTERPRISE_MODULES_SSO ?? enterpriseModulesFlag,\n OM_ENABLE_ENTERPRISE_MODULES_SECURITY: process.env.OM_ENABLE_ENTERPRISE_MODULES_SECURITY ?? enterpriseModulesFlag,\n OM_TEST_MODE: '1',\n OM_TEST_AUTH_RATE_LIMIT_MODE: 'opt-in',\n OM_WEBHOOKS_ALLOW_PRIVATE_URLS: process.env.OM_WEBHOOKS_ALLOW_PRIVATE_URLS ?? '1',\n ENABLE_CRUD_API_CACHE: 'true',\n MOCK_GATEWAY_WEBHOOK_SECRET: 'open-mercato-mock-dev-webhook-secret',\n MOCK_CARRIER_WEBHOOK_SECRET: 'open-mercato-mock-dev-carrier-webhook-secret',\n NEXT_PUBLIC_OM_EXAMPLE_INJECTION_WIDGETS_ENABLED: 'true',\n NEXT_PUBLIC_UMES_DEVTOOLS: 'true',\n CI: 'true',\n TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? 'om-ephemeral-integration-fallback-key',\n OM_CLI_QUIET: '1',\n MERCATO_QUIET: '1',\n NODE_NO_WARNINGS: '1',\n PW_CAPTURE_SCREENSHOTS: captureScreenshots ? '1' : '0',\n })\n}\n\nexport async function tryReuseExistingEnvironment(options: EphemeralRuntimeOptions): Promise<EphemeralEnvironmentHandle | null> {\n const state = await readEphemeralEnvironmentState()\n if (!state) {\n return null\n }\n\n if (options.requiredExistingSource && state.source !== options.requiredExistingSource) {\n console.log(\n `[${options.logPrefix}] Existing ephemeral environment source \"${state.source}\" does not match required \"${options.requiredExistingSource}\".`,\n )\n return null\n }\n\n const unavailable = await isEnvironmentUnavailable(state.baseUrl)\n if (unavailable) {\n console.log(`[${options.logPrefix}] Found stale ephemeral state. Clearing ${EPHEMERAL_ENV_FILE_PATH}.`)\n await clearEphemeralEnvironmentState()\n return null\n }\n\n const cacheTtlSeconds = resolveBuildCacheTtlSeconds(options.logPrefix)\n const startedAtMs = Date.parse(state.startedAt)\n if (Number.isFinite(startedAtMs)) {\n const environmentAgeSeconds = Math.floor((Date.now() - startedAtMs) / 1000)\n if (environmentAgeSeconds > cacheTtlSeconds) {\n console.log(\n `[${options.logPrefix}] Existing ephemeral environment is ${environmentAgeSeconds}s old, exceeding ${BUILD_CACHE_TTL_ENV_VAR}=${cacheTtlSeconds}s. Rebuilding.`,\n )\n await clearEphemeralEnvironmentState()\n return null\n }\n\n const sourceChangedSinceStart = await hasBuildInputChangesSince(startedAtMs)\n if (sourceChangedSinceStart) {\n console.log(\n `[${options.logPrefix}] Source files changed since the current ephemeral environment started. Rebuilding.`,\n )\n await clearEphemeralEnvironmentState()\n return null\n }\n }\n\n if (options.captureScreenshots !== state.captureScreenshots) {\n console.log(\n `[${options.logPrefix}] Reusing screenshot capture setting from ${EPHEMERAL_ENV_FILE_PATH}: ${state.captureScreenshots ? 'enabled' : 'disabled'}.`,\n )\n }\n console.log(`[${options.logPrefix}] Reusing existing ephemeral environment at ${state.baseUrl}.`)\n return {\n baseUrl: state.baseUrl,\n port: state.port,\n databaseUrl: '',\n commandEnvironment: buildReusableEnvironment(state.baseUrl, state.captureScreenshots),\n ownedByCurrentProcess: false,\n stop: async () => {},\n }\n}\n\nasync function waitForApplicationReadiness(\n baseUrl: string,\n appProcess: ChildProcess,\n options: { timeoutMs: number },\n): Promise<void> {\n const startTimestamp = Date.now()\n const exitPromise = getProcessExitPromise(appProcess)\n const readinessStabilizationMs = 600\n let lastProbe: ApplicationReadinessProbeResult | null = null\n\n while (Date.now() - startTimestamp < options.timeoutMs) {\n const result = await Promise.race([\n probeApplicationReadiness(baseUrl).then((probe) => ({ kind: 'probe' as const, probe })),\n exitPromise.then((code) => ({ kind: 'exit' as const, code })),\n delay(APP_READY_INTERVAL_MS).then(() => ({ kind: 'timeout' as const })),\n ])\n\n if (result.kind === 'probe') {\n lastProbe = result.probe\n if (!result.probe.ready) {\n continue\n }\n const processExited = await Promise.race([\n exitPromise.then(() => true),\n delay(readinessStabilizationMs).then(() => false),\n ])\n if (processExited) {\n throw new Error('Application process exited immediately after readiness probe.')\n }\n return\n }\n if (result.kind === 'exit') {\n throw new Error(`Application process exited before readiness check (exit ${result.code ?? 'unknown'})`)\n }\n }\n\n const lastFrontendDetail = lastProbe?.frontend.detail ?? 'GET /login was never observed'\n const lastBackendDetail = lastProbe?.backend.detail ?? 'POST /api/auth/login was never observed'\n const lastAuthenticatedDetail = lastProbe?.authenticated.detail ?? 'Authenticated API probe was never observed'\n throw new Error(\n `Application did not become ready within ${options.timeoutMs / 1000} seconds. ` +\n `Last probe: ${lastFrontendDetail}; ${lastBackendDetail}; ${lastAuthenticatedDetail}`,\n )\n}\n\nexport function parseOptions(rawArgs: string[]): IntegrationOptions {\n let keep = false\n let filter: string | null = null\n let captureScreenshots: boolean | null = null\n let verbose = false\n let forceRebuild = false\n let reuseExisting = true\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const argument = rawArgs[index]\n if (argument === '--keep') {\n keep = true\n continue\n }\n if (argument === '--screenshots') {\n captureScreenshots = true\n continue\n }\n if (argument === '--no-screenshots') {\n captureScreenshots = false\n continue\n }\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n if (argument === '--force-rebuild') {\n forceRebuild = true\n continue\n }\n if (argument === '--no-reuse-env') {\n reuseExisting = false\n continue\n }\n if (argument === '--filter') {\n const nextValue = rawArgs[index + 1]\n if (!nextValue || nextValue.startsWith('--')) {\n throw new Error('Missing value for --filter')\n }\n filter = nextValue\n index += 1\n continue\n }\n if (argument.startsWith('--filter=')) {\n const filterValue = argument.slice('--filter='.length).trim()\n if (!filterValue) {\n throw new Error('Missing value for --filter')\n }\n filter = filterValue\n continue\n }\n if (!argument.startsWith('--') && !filter) {\n filter = argument\n continue\n }\n if (argument.startsWith('--')) {\n throw new Error(`Unknown option: ${argument}`)\n }\n }\n\n const defaultCaptureScreenshots = process.env.CI !== 'true'\n return {\n keep,\n filter,\n captureScreenshots: captureScreenshots ?? defaultCaptureScreenshots,\n verbose,\n forceRebuild,\n reuseExisting,\n }\n}\n\nexport function parseEphemeralAppOptions(rawArgs: string[]): EphemeralAppOptions {\n let verbose = false\n let captureScreenshots: boolean | null = null\n let forceRebuild = false\n let reuseExisting = true\n\n for (const argument of rawArgs) {\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n if (argument === '--screenshots') {\n captureScreenshots = true\n continue\n }\n if (argument === '--no-screenshots') {\n captureScreenshots = false\n continue\n }\n if (argument === '--force-rebuild') {\n forceRebuild = true\n continue\n }\n if (argument === '--no-reuse-env') {\n reuseExisting = false\n continue\n }\n throw new Error(`Unknown option: ${argument}`)\n }\n\n const defaultCaptureScreenshots = process.env.CI !== 'true'\n return {\n verbose,\n captureScreenshots: captureScreenshots ?? defaultCaptureScreenshots,\n forceRebuild,\n reuseExisting,\n }\n}\n\nexport function parseInteractiveIntegrationOptions(rawArgs: string[]): InteractiveIntegrationOptions {\n let verbose = false\n let captureScreenshots: boolean | null = null\n let workers: number | null = null\n let retries: number | null = null\n let forceRebuild = false\n let reuseExisting = true\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const argument = rawArgs[index]\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n if (argument === '--screenshots') {\n captureScreenshots = true\n continue\n }\n if (argument === '--no-screenshots') {\n captureScreenshots = false\n continue\n }\n if (argument === '--force-rebuild') {\n forceRebuild = true\n continue\n }\n if (argument === '--no-reuse-env') {\n reuseExisting = false\n continue\n }\n if (argument === '--workers') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --workers')\n }\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new Error(`Invalid --workers value: ${value}`)\n }\n workers = parsed\n index += 1\n continue\n }\n if (argument.startsWith('--workers=')) {\n const value = argument.slice('--workers='.length)\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new Error(`Invalid --workers value: ${value}`)\n }\n workers = parsed\n continue\n }\n if (argument === '--retries') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --retries')\n }\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new Error(`Invalid --retries value: ${value}`)\n }\n retries = parsed\n index += 1\n continue\n }\n if (argument.startsWith('--retries=')) {\n const value = argument.slice('--retries='.length)\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new Error(`Invalid --retries value: ${value}`)\n }\n retries = parsed\n continue\n }\n throw new Error(`Unknown option: ${argument}`)\n }\n\n const defaultCaptureScreenshots = process.env.CI !== 'true'\n return {\n verbose,\n captureScreenshots: captureScreenshots ?? defaultCaptureScreenshots,\n workers,\n retries,\n forceRebuild,\n reuseExisting,\n }\n}\n\nexport function parseIntegrationCoverageOptions(rawArgs: string[]): IntegrationCoverageOptions {\n let filter: string | null = null\n let captureScreenshots: boolean | null = null\n let verbose = false\n let workers: number | null = null\n let retries: number | null = null\n let shard: string | null = null\n let json = false\n let keepRawV8 = false\n let forceRebuild = false\n let reuseExisting = true\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const argument = rawArgs[index]\n if (argument === '--filter') {\n const nextValue = rawArgs[index + 1]\n if (!nextValue || nextValue.startsWith('--')) {\n throw new Error('Missing value for --filter')\n }\n filter = nextValue\n index += 1\n continue\n }\n if (argument.startsWith('--filter=')) {\n const filterValue = argument.slice('--filter='.length).trim()\n if (!filterValue) {\n throw new Error('Missing value for --filter')\n }\n filter = filterValue\n continue\n }\n if (!argument.startsWith('--') && !filter) {\n filter = argument\n continue\n }\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n if (argument === '--screenshots') {\n captureScreenshots = true\n continue\n }\n if (argument === '--no-screenshots') {\n captureScreenshots = false\n continue\n }\n if (argument === '--workers') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --workers')\n }\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new Error(`Invalid --workers value: ${value}`)\n }\n workers = parsed\n index += 1\n continue\n }\n if (argument.startsWith('--workers=')) {\n const value = argument.slice('--workers='.length)\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new Error(`Invalid --workers value: ${value}`)\n }\n workers = parsed\n continue\n }\n if (argument === '--retries') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --retries')\n }\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new Error(`Invalid --retries value: ${value}`)\n }\n retries = parsed\n index += 1\n continue\n }\n if (argument.startsWith('--retries=')) {\n const value = argument.slice('--retries='.length)\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new Error(`Invalid --retries value: ${value}`)\n }\n retries = parsed\n continue\n }\n if (argument === '--shard') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --shard')\n }\n if (!/^\\d+\\/\\d+$/.test(value)) {\n throw new Error(`Invalid --shard value: ${value}. Expected format: N/M`)\n }\n shard = value\n index += 1\n continue\n }\n if (argument.startsWith('--shard=')) {\n const value = argument.slice('--shard='.length)\n if (!/^\\d+\\/\\d+$/.test(value)) {\n throw new Error(`Invalid --shard value: ${value}. Expected format: N/M`)\n }\n shard = value\n continue\n }\n if (argument === '--json') {\n json = true\n continue\n }\n if (argument === '--keep-raw-v8') {\n keepRawV8 = true\n continue\n }\n if (argument === '--force-rebuild') {\n forceRebuild = true\n continue\n }\n if (argument === '--no-reuse-env') {\n reuseExisting = false\n continue\n }\n throw new Error(`Unknown option: ${argument}`)\n }\n\n const defaultCaptureScreenshots = process.env.CI !== 'true'\n return {\n filter,\n captureScreenshots: captureScreenshots ?? defaultCaptureScreenshots,\n verbose,\n workers,\n retries,\n shard,\n json,\n keepRawV8,\n forceRebuild,\n reuseExisting,\n }\n}\n\nfunction parseIntegrationSpecCoverageOptions(rawArgs: string[]): IntegrationSpecCoverageOptions {\n let json = false\n let strict = false\n for (const argument of rawArgs) {\n if (argument === '--json') {\n json = true\n continue\n }\n if (argument === '--strict') {\n strict = true\n continue\n }\n throw new Error(`Unknown option: ${argument}`)\n }\n return { json, strict }\n}\n\nfunction normalizePath(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\nasync function discoverIntegrationSpecFiles(): Promise<DiscoveredIntegrationSpecFile[]> {\n return discoverIntegrationSpecFilesShared(projectRootDirectory, LEGACY_INTEGRATION_TEST_ROOT)\n}\n\nasync function extractSpecDescription(relativePath: string): Promise<string> {\n const absolutePath = path.join(projectRootDirectory, relativePath)\n try {\n const source = await readFile(absolutePath, 'utf8')\n const describeTitleMatch = source.match(/test\\.describe\\(\\s*['\"`]([^'\"`]+)['\"`]/)\n if (describeTitleMatch?.[1]) {\n return describeTitleMatch[1].trim()\n }\n const testCaseTitleMatch = source.match(/TC-[A-Z]+-\\d+\\s*:\\s*([^\\n*]+)/)\n if (testCaseTitleMatch?.[1]) {\n return testCaseTitleMatch[1].trim()\n }\n } catch {\n return path.basename(relativePath, '.spec.ts')\n }\n return path.basename(relativePath, '.spec.ts')\n}\n\nasync function listIntegrationSpecFiles(): Promise<IntegrationSpecTarget[]> {\n const discoveredSpecs = await discoverIntegrationSpecFiles()\n const sortedFiles = discoveredSpecs.map((entry) => entry.path)\n const targets = await Promise.all(\n sortedFiles.map(async (filePath) => ({\n path: filePath,\n description: await extractSpecDescription(filePath),\n })),\n )\n return targets\n}\n\nasync function collectFilesByExtension(\n directoryPath: string,\n extension: string,\n rootPath: string,\n): Promise<string[]> {\n let entries\n try {\n entries = await readdir(directoryPath, { withFileTypes: true })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return []\n }\n throw error\n }\n const collected: string[] = []\n for (const entry of entries) {\n const absolutePath = path.join(directoryPath, entry.name)\n if (entry.isDirectory()) {\n const nestedFiles = await collectFilesByExtension(absolutePath, extension, rootPath)\n collected.push(...nestedFiles)\n continue\n }\n if (!entry.isFile() || !entry.name.endsWith(extension)) {\n continue\n }\n const relativePath = path.relative(rootPath, absolutePath)\n collected.push(normalizePath(relativePath))\n }\n return collected\n}\n\nfunction extractTestCaseId(value: string): string | null {\n const match = value.match(/TC-([A-Z]+)-(\\d{3})/i)\n if (!match) {\n return null\n }\n const category = match[1]?.toUpperCase()\n const sequence = match[2]\n if (!category || !sequence) {\n return null\n }\n return `TC-${category}-${sequence}`\n}\n\nfunction findFolderSegmentFromPath(relativePath: string): string {\n const normalized = normalizePath(relativePath)\n const marker = `${normalizePath(path.relative(projectRootDirectory, LEGACY_INTEGRATION_TEST_ROOT))}/`\n const markerIndex = normalized.indexOf(marker)\n if (markerIndex === -1) {\n return ''\n }\n const trailing = normalized.slice(markerIndex + marker.length)\n return trailing.split('/')[0] ?? ''\n}\n\nfunction extractCategoryCodeFromCaseId(caseId: string): string | null {\n const match = caseId.match(/^TC-([A-Z]+)-\\d{3}$/)\n return match?.[1] ?? null\n}\n\nfunction computePercent(numerator: number, denominator: number): number {\n if (denominator <= 0) {\n return 100\n }\n return Math.round((numerator / denominator) * 10000) / 100\n}\n\nfunction formatPercent(value: number | null): string {\n if (value === null) {\n return 'n/a'\n }\n return `${value.toFixed(2)}%`\n}\n\nexport async function runIntegrationSpecCoverageReport(rawArgs: string[]): Promise<void> {\n const options = parseIntegrationSpecCoverageOptions(rawArgs)\n const scenarioRoot = path.join(projectRootDirectory, '.ai', 'qa', 'scenarios')\n const testFiles = (await discoverIntegrationSpecFiles()).map((entry) => entry.path)\n const scenarioFiles = await collectFilesByExtension(scenarioRoot, '.md', projectRootDirectory)\n const testRunSummary = await readIntegrationTestRunSummary()\n\n const testCaseIds = new Set<string>()\n const scenarioCaseIds = new Set<string>()\n const testsByFolder = new Map<string, number>()\n\n for (const testFile of testFiles) {\n const caseId = extractTestCaseId(path.basename(testFile))\n const categoryCode = caseId ? extractCategoryCodeFromCaseId(caseId) : null\n if (caseId) {\n testCaseIds.add(caseId)\n }\n const folder = categoryCode\n ? Object.entries(FOLDER_TO_CATEGORY_CODE).find(([, mappedCategoryCode]) => mappedCategoryCode === categoryCode)?.[0]\n : findFolderSegmentFromPath(testFile)\n if (folder) {\n testsByFolder.set(folder, (testsByFolder.get(folder) ?? 0) + 1)\n }\n }\n\n for (const scenarioFile of scenarioFiles) {\n const caseId = extractTestCaseId(path.basename(scenarioFile))\n if (caseId) {\n scenarioCaseIds.add(caseId)\n }\n }\n\n const coveredScenarioIds = Array.from(scenarioCaseIds).filter((id) => testCaseIds.has(id))\n const uncoveredScenarioIds = Array.from(scenarioCaseIds)\n .filter((id) => !testCaseIds.has(id))\n .sort((left, right) => left.localeCompare(right))\n const testsWithoutScenarioIds = Array.from(testCaseIds)\n .filter((id) => !scenarioCaseIds.has(id))\n .sort((left, right) => left.localeCompare(right))\n\n const categories = new Set<string>()\n for (const scenarioId of scenarioCaseIds) {\n const category = extractCategoryCodeFromCaseId(scenarioId)\n if (category) {\n categories.add(category)\n }\n }\n for (const testId of testCaseIds) {\n const category = extractCategoryCodeFromCaseId(testId)\n if (category) {\n categories.add(category)\n }\n }\n\n const categoryRows = Array.from(categories)\n .sort((left, right) => left.localeCompare(right))\n .map((categoryCode) => {\n const scenarioCount = Array.from(scenarioCaseIds).filter((id) => id.startsWith(`TC-${categoryCode}-`)).length\n const coveredScenarioCount = coveredScenarioIds.filter((id) => id.startsWith(`TC-${categoryCode}-`)).length\n const testCount = Array.from(testCaseIds).filter((id) => id.startsWith(`TC-${categoryCode}-`)).length\n const coveragePercent = scenarioCount > 0 ? computePercent(coveredScenarioCount, scenarioCount) : null\n return {\n code: categoryCode,\n scenarioCount,\n coveredScenarioCount,\n testCount,\n coveragePercent,\n }\n })\n\n const presentRequiredFolders = EXPECTED_TEST_FOLDERS.filter((folder) => (testsByFolder.get(folder) ?? 0) > 0)\n const missingRequiredFolders = EXPECTED_TEST_FOLDERS.filter((folder) => (testsByFolder.get(folder) ?? 0) === 0)\n const coveragePercent = computePercent(coveredScenarioIds.length, scenarioCaseIds.size)\n\n const report: IntegrationCoverageReport = {\n generatedAt: new Date().toISOString(),\n testRun: testRunSummary,\n scenarios: {\n total: scenarioCaseIds.size,\n covered: coveredScenarioIds.length,\n uncovered: uncoveredScenarioIds.length,\n coveragePercent,\n },\n tests: {\n total: testCaseIds.size,\n withScenario: testCaseIds.size - testsWithoutScenarioIds.length,\n withoutScenario: testsWithoutScenarioIds.length,\n },\n categories: categoryRows,\n requiredTestFolders: {\n present: presentRequiredFolders,\n missing: missingRequiredFolders,\n },\n uncoveredScenarioIds,\n testsWithoutScenarioIds,\n }\n\n if (options.json) {\n console.log(JSON.stringify(report, null, 2))\n } else {\n console.log('[coverage] Integration test coverage report')\n console.log(`[coverage] Generated at: ${report.generatedAt}`)\n logIntegrationTestRunSummary(report.testRun)\n console.log(\n `[coverage] Scenario coverage: ${report.scenarios.covered}/${report.scenarios.total} (${formatPercent(report.scenarios.coveragePercent)})`,\n )\n console.log(`[coverage] Tests discovered: ${report.tests.total}`)\n console.log(`[coverage] Tests linked to scenarios: ${report.tests.withScenario}`)\n console.log(`[coverage] Tests without scenarios: ${report.tests.withoutScenario}`)\n console.log(\n `[coverage] Required folders with tests: ${report.requiredTestFolders.present.length}/${EXPECTED_TEST_FOLDERS.length} (${report.requiredTestFolders.present.join(', ') || '-'})`,\n )\n if (report.requiredTestFolders.missing.length > 0) {\n console.log(`[coverage] Missing required folders: ${report.requiredTestFolders.missing.join(', ')}`)\n }\n console.log('[coverage] Category breakdown:')\n for (const category of report.categories) {\n const folder = Object.entries(FOLDER_TO_CATEGORY_CODE).find(([, code]) => code === category.code)?.[0]\n const folderLabel = folder ? ` (${folder})` : ''\n console.log(\n ` - ${category.code}${folderLabel}: scenarios ${category.coveredScenarioCount}/${category.scenarioCount}, tests ${category.testCount}, coverage ${formatPercent(category.coveragePercent)}`,\n )\n }\n if (report.uncoveredScenarioIds.length > 0) {\n console.log('[coverage] Missing test implementations for scenarios:')\n for (const scenarioId of report.uncoveredScenarioIds) {\n console.log(` - ${scenarioId}`)\n }\n }\n if (report.testsWithoutScenarioIds.length > 0) {\n console.log('[coverage] Tests without matching scenario files:')\n for (const testId of report.testsWithoutScenarioIds) {\n console.log(` - ${testId}`)\n }\n }\n logIntegrationTestRunOneLineSummary(report.testRun)\n }\n\n if (options.strict && (report.uncoveredScenarioIds.length > 0 || report.requiredTestFolders.missing.length > 0)) {\n throw new Error(\n `Coverage check failed in strict mode: uncovered scenarios=${report.uncoveredScenarioIds.length}, missing required folders=${report.requiredTestFolders.missing.length}`,\n )\n }\n}\n\nasync function resetDirectory(directoryPath: string): Promise<void> {\n await rm(directoryPath, { recursive: true, force: true })\n await mkdir(directoryPath, { recursive: true })\n}\n\nfunction getCoveragePaths(): { rawDirectory: string; reportDirectory: string } {\n const rawDirectory = path.join(projectRootDirectory, '.ai', 'qa', 'test-results', 'coverage', 'raw-v8')\n const reportDirectory = path.join(projectRootDirectory, '.ai', 'qa', 'test-results', 'coverage', 'code')\n return { rawDirectory, reportDirectory }\n}\n\nasync function generateC8CoverageReport(environment: NodeJS.ProcessEnv, rawDirectory: string, reportDirectory: string): Promise<void> {\n const c8Args = [\n 'c8',\n 'report',\n '--temp-directory',\n rawDirectory,\n '--report-dir',\n reportDirectory,\n '--reporter',\n 'text-summary',\n '--reporter',\n 'json-summary',\n '--reporter',\n 'lcov',\n '--reporter',\n 'html',\n '--exclude-after-remap',\n '--exclude',\n '**/node_modules/**',\n '--exclude',\n '**/*.spec.ts',\n '--exclude',\n '.ai/**',\n '--exclude',\n 'apps/docs/**',\n '--exclude',\n 'packages/cli/**',\n '--exclude',\n 'coverage/**',\n ]\n await runNpxCommand(c8Args, environment)\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction readOptionalNumber(record: Record<string, unknown>, key: string): number | null {\n const value = record[key]\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return null\n }\n return value\n}\n\nfunction readOptionalString(record: Record<string, unknown>, key: string): string | null {\n const value = record[key]\n return typeof value === 'string' ? value : null\n}\n\nasync function readIntegrationTestRunSummary(): Promise<IntegrationTestRunSummary | null> {\n let resultsRaw: string\n try {\n resultsRaw = await readFile(PLAYWRIGHT_RESULTS_JSON_PATH, 'utf8')\n } catch {\n return null\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(resultsRaw)\n } catch {\n return null\n }\n\n if (!isObjectRecord(parsed)) {\n return null\n }\n const statsValue = parsed.stats\n if (!isObjectRecord(statsValue)) {\n return null\n }\n\n const passed = readOptionalNumber(statsValue, 'expected') ?? 0\n const failed = readOptionalNumber(statsValue, 'unexpected') ?? 0\n const flaky = readOptionalNumber(statsValue, 'flaky') ?? 0\n const skipped = readOptionalNumber(statsValue, 'skipped') ?? 0\n\n return {\n status: failed > 0 ? 'failed' : 'passed',\n total: passed + failed + flaky + skipped,\n passed,\n failed,\n flaky,\n skipped,\n durationMs: readOptionalNumber(statsValue, 'duration'),\n startTime: readOptionalString(statsValue, 'startTime'),\n }\n}\n\nfunction logIntegrationTestRunSummary(summary: IntegrationTestRunSummary | null): void {\n if (!summary) {\n console.log('[coverage] Integration test results: unavailable (.ai/qa/test-results/results.json missing or invalid)')\n return\n }\n console.log('[coverage] Integration test results:')\n console.log(` status: ${summary.status}`)\n console.log(` passed: ${summary.passed}`)\n console.log(` failed: ${summary.failed}`)\n console.log(` flaky: ${summary.flaky}`)\n console.log(` skipped: ${summary.skipped}`)\n console.log(` total: ${summary.total}`)\n}\n\nfunction logIntegrationTestRunOneLineSummary(summary: IntegrationTestRunSummary | null): void {\n if (!summary) {\n return\n }\n console.log(\n `[coverage] Test run summary: passed=${summary.passed}, failed=${summary.failed}, flaky=${summary.flaky}, skipped=${summary.skipped}, total=${summary.total}`,\n )\n}\n\nexport async function runIntegrationCoverageReport(rawArgs: string[]): Promise<void> {\n const options = parseIntegrationCoverageOptions(rawArgs)\n const coveragePaths = getCoveragePaths()\n await resetDirectory(coveragePaths.rawDirectory)\n await resetDirectory(coveragePaths.reportDirectory)\n\n const startOptions: EphemeralRuntimeOptions = {\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n forceRebuild: options.forceRebuild,\n reuseExisting: options.reuseExisting,\n logPrefix: 'coverage',\n environmentOverrides: {\n NODE_V8_COVERAGE: coveragePaths.rawDirectory,\n },\n }\n\n let testRunError: Error | null = null\n const runCoverageAttempt = async (environment: EphemeralEnvironmentHandle): Promise<Error | null> => {\n console.log('[coverage] Running Playwright integration suite with V8 coverage enabled...')\n console.log('[coverage] Ensuring Playwright Chromium is installed...')\n await runNpxCommand(['playwright', 'install', 'chromium'], environment.commandEnvironment)\n try {\n await runPlaywrightSelection(\n environment,\n options.filter,\n {\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n workers: options.workers,\n retries: options.retries,\n shard: options.shard,\n },\n )\n return null\n } catch (error) {\n const coverageRunError = error instanceof Error ? error : new Error(String(error))\n if (isEnvironmentUnavailableError(coverageRunError)) {\n console.error('[coverage] Playwright output indicates connection loss to the ephemeral app during coverage run.')\n }\n console.error(`[coverage] Playwright run failed: ${coverageRunError.message}`)\n console.error('[coverage] Continuing to generate coverage report from collected V8 data...')\n return coverageRunError\n }\n }\n\n let environment = await startEphemeralEnvironment(startOptions)\n try {\n testRunError = await runCoverageAttempt(environment)\n if (testRunError && isEnvironmentUnavailableError(testRunError)) {\n console.log('[coverage] Rebuilding ephemeral environment and retrying coverage run once...')\n await environment.stop()\n environment = await startEphemeralEnvironment(startOptions)\n testRunError = await runCoverageAttempt(environment)\n }\n } finally {\n await environment.stop()\n }\n\n console.log('[coverage] Generating code coverage report...')\n let coverageReportError: Error | null = null\n try {\n await generateC8CoverageReport(environment.commandEnvironment, coveragePaths.rawDirectory, coveragePaths.reportDirectory)\n } catch (error) {\n coverageReportError = error instanceof Error ? error : new Error(String(error))\n }\n\n if (coverageReportError) {\n if (!options.keepRawV8) {\n await rm(coveragePaths.rawDirectory, { recursive: true, force: true })\n }\n throw coverageReportError\n }\n\n const summaryPath = path.join(coveragePaths.reportDirectory, 'coverage-summary.json')\n const summaryRaw = await readFile(summaryPath, 'utf8')\n const summary = JSON.parse(summaryRaw) as {\n total?: {\n lines?: { total?: number; covered?: number; pct?: number }\n statements?: { total?: number; covered?: number; pct?: number }\n functions?: { total?: number; covered?: number; pct?: number }\n branches?: { total?: number; covered?: number; pct?: number }\n }\n }\n const totals = summary.total ?? {}\n const testRunSummary = await readIntegrationTestRunSummary()\n const output = {\n generatedAt: new Date().toISOString(),\n reportDirectory: normalizePath(path.relative(projectRootDirectory, coveragePaths.reportDirectory)),\n rawCoverageDirectory: normalizePath(path.relative(projectRootDirectory, coveragePaths.rawDirectory)),\n testRun: testRunSummary,\n totals: {\n lines: totals.lines ?? null,\n statements: totals.statements ?? null,\n functions: totals.functions ?? null,\n branches: totals.branches ?? null,\n },\n }\n\n const linePct = output.totals.lines?.pct ?? 0\n const statementPct = output.totals.statements?.pct ?? 0\n const functionPct = output.totals.functions?.pct ?? 0\n const branchPct = output.totals.branches?.pct ?? 0\n const lineCovered = output.totals.lines?.covered ?? 0\n const lineTotal = output.totals.lines?.total ?? 0\n const statementCovered = output.totals.statements?.covered ?? 0\n const statementTotal = output.totals.statements?.total ?? 0\n const functionCovered = output.totals.functions?.covered ?? 0\n const functionTotal = output.totals.functions?.total ?? 0\n const branchCovered = output.totals.branches?.covered ?? 0\n const branchTotal = output.totals.branches?.total ?? 0\n\n if (!options.keepRawV8) {\n await rm(coveragePaths.rawDirectory, { recursive: true, force: true })\n }\n\n console.log('[coverage] Coverage totals:')\n console.log(` lines: ${lineCovered}/${lineTotal} (${linePct}%)`)\n console.log(` statements: ${statementCovered}/${statementTotal} (${statementPct}%)`)\n console.log(` functions: ${functionCovered}/${functionTotal} (${functionPct}%)`)\n console.log(` branches: ${branchCovered}/${branchTotal} (${branchPct}%)`)\n logIntegrationTestRunSummary(output.testRun)\n console.log(`[coverage] HTML report: ${output.reportDirectory}/index.html`)\n\n if (options.json) {\n console.log(JSON.stringify(output, null, 2))\n if (testRunError) {\n throw testRunError\n }\n return\n }\n\n console.log(`[coverage] Code coverage summary: lines=${linePct}%, statements=${statementPct}%, functions=${functionPct}%, branches=${branchPct}%`)\n logIntegrationTestRunOneLineSummary(output.testRun)\n console.log('[coverage] Use --json for machine-readable output or --keep-raw-v8 to keep raw process coverage files.')\n\n if (testRunError) {\n throw testRunError\n }\n}\n\nasync function runPlaywrightSelection(\n environment: EphemeralEnvironmentHandle,\n selection: string | string[] | null,\n options: PlaywrightRunOptions,\n): Promise<void> {\n const args = ['playwright', 'test', '--config', PLAYWRIGHT_INTEGRATION_CONFIG_PATH]\n if (options.workers !== null) {\n args.push('--workers', String(options.workers))\n }\n if (options.retries !== null) {\n args.push('--retries', String(options.retries))\n }\n if (options.shard) {\n args.push('--shard', options.shard)\n }\n if (Array.isArray(selection) && selection.length > 0) {\n args.push(...selection)\n } else if (typeof selection === 'string' && selection.length > 0) {\n args.push(selection)\n }\n await runNpxCommandWithOutputMonitoring(args, environment.commandEnvironment, {\n detectEnvironmentUnavailable: true,\n abortOnEnvironmentUnavailable: true,\n playwrightFailureHealthCheck: {\n baseUrl: environment.baseUrl,\n },\n })\n}\n\ntype IntegrationTestRunResult = {\n retried: boolean\n error: Error | null\n}\n\nasync function runIntegrationTestSuiteOnce(\n environment: EphemeralEnvironmentHandle,\n options: IntegrationOptions,\n): Promise<void> {\n const testArgs = ['test:integration']\n if (options.filter) {\n testArgs.push(options.filter)\n }\n await runYarnCommandWithOutputMonitoring(testArgs, environment.commandEnvironment, {\n detectEnvironmentUnavailable: true,\n abortOnEnvironmentUnavailable: true,\n playwrightFailureHealthCheck: {\n baseUrl: environment.baseUrl,\n },\n })\n}\n\nasync function isEnvironmentUnavailable(baseUrl: string): Promise<boolean> {\n const readiness = await probeApplicationReadiness(baseUrl)\n return !readiness.ready\n}\n\nfunction isEnvironmentUnavailableError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false\n }\n return (error as IntegrationCommandError).environmentUnavailableFromOutput === true\n}\n\nfunction normalizeError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error))\n}\n\nasync function runIntegrationTestAttempt(\n environment: EphemeralEnvironmentHandle,\n integrationOptions: IntegrationOptions,\n prepareTestEnvironment: (environment: EphemeralEnvironmentHandle) => Promise<void>,\n): Promise<Error | null> {\n try {\n await prepareTestEnvironment(environment)\n await runIntegrationTestSuiteOnce(environment, integrationOptions)\n return null\n } catch (error) {\n return normalizeError(error)\n }\n}\n\nasync function detectEnvironmentFailure(\n error: Error,\n baseUrl: string,\n): Promise<{ unavailable: boolean; fromOutput: boolean }> {\n const fromOutput = isEnvironmentUnavailableError(error)\n if (fromOutput) {\n return { unavailable: true, fromOutput: true }\n }\n return {\n unavailable: await isEnvironmentUnavailable(baseUrl),\n fromOutput: false,\n }\n}\n\nasync function runIntegrationTestSuiteWithRecovery(\n startOptions: Pick<EphemeralRuntimeOptions, 'verbose' | 'captureScreenshots' | 'forceRebuild' | 'reuseExisting'>,\n integrationOptions: IntegrationOptions,\n prepareTestEnvironment: (environment: EphemeralEnvironmentHandle) => Promise<void>,\n): Promise<{\n environment: EphemeralEnvironmentHandle\n testRunResult: IntegrationTestRunResult\n}> {\n let environment = await startEphemeralEnvironment({\n ...startOptions,\n logPrefix: 'integration',\n })\n\n const firstAttemptError = await runIntegrationTestAttempt(environment, integrationOptions, prepareTestEnvironment)\n if (!firstAttemptError) {\n return { environment, testRunResult: { retried: false, error: null } }\n }\n\n const failure = await detectEnvironmentFailure(firstAttemptError, environment.baseUrl)\n if (!failure.unavailable) {\n return { environment, testRunResult: { retried: false, error: firstAttemptError } }\n }\n\n if (failure.fromOutput) {\n console.error('[integration] Playwright output indicates connection loss to the app. Restarting environment.')\n }\n console.error('[integration] The ephemeral integration environment became unreachable while tests were running.')\n console.error('[integration] Rebuilding ephemeral environment and rerunning tests.')\n\n try {\n await environment.stop()\n } catch (stopError) {\n console.error(`[integration] Failed to stop old ephemeral environment before restart: ${normalizeError(stopError).message}`)\n }\n\n environment = await startEphemeralEnvironment({\n ...startOptions,\n logPrefix: 'integration',\n })\n const retryError = await runIntegrationTestAttempt(environment, integrationOptions, prepareTestEnvironment)\n return {\n environment,\n testRunResult: {\n retried: true,\n error: retryError,\n },\n }\n}\n\nasync function openIntegrationHtmlReport(environment: EphemeralEnvironmentHandle): Promise<void> {\n await runNpxCommand(['playwright', 'show-report', '.ai/qa/test-results/html'], environment.commandEnvironment)\n}\n\nasync function promptAfterRun(\n rl: Interface,\n environment: EphemeralEnvironmentHandle,\n): Promise<'menu' | 'quit'> {\n const followUpChoice = (\n await rl.question(\n '\\n[interactive] \uD83D\uDD01 Press any key then Enter to return to menu, \uD83D\uDCCA \"h\" for HTML report, or \uD83D\uDEAA \"q\" to quit: ',\n )\n )\n .trim()\n .toLowerCase()\n\n if (followUpChoice === 'h') {\n console.log('[interactive] \uD83D\uDCCA Opening HTML report...')\n try {\n await openIntegrationHtmlReport(environment)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Failed to open report: ${message}`)\n }\n return 'menu'\n }\n\n if (followUpChoice === 'q') {\n return 'quit'\n }\n\n return 'menu'\n}\n\nexport async function startEphemeralEnvironment(options: EphemeralRuntimeOptions): Promise<EphemeralEnvironmentHandle> {\n assertNode24Runtime()\n\n // Auto-detect Docker socket from active context for non-standard setups (e.g., Colima)\n const dockerConfig = await resolveDockerHostFromContext(options.logPrefix)\n if (dockerConfig) {\n process.env.DOCKER_HOST = dockerConfig.dockerHost\n process.env.TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE = dockerConfig.socketOverride\n }\n\n await assertContainerRuntimeAvailable()\n\n const setupLock = await acquireEphemeralEnvironmentLock(options.logPrefix)\n try {\n const existingStateBeforeReuseAttempt = await readEphemeralEnvironmentState()\n if (options.reuseExisting === false) {\n console.log(\n `[${options.logPrefix}] --no-reuse-env enabled. Skipping reuse checks and starting a new ephemeral environment.`,\n )\n }\n if (options.reuseExisting !== false) {\n const existingEnvironment = await tryReuseExistingEnvironment(options)\n if (existingEnvironment) {\n return existingEnvironment\n }\n }\n\n const shouldUseIsolatedPort = shouldUseIsolatedPortForFreshEnvironment({\n reuseExisting: options.reuseExisting,\n existingStateBeforeReuseAttempt,\n })\n const applicationPort = shouldUseIsolatedPort\n ? await getFreePort()\n : await getPreferredPort(DEFAULT_EPHEMERAL_APP_PORT)\n if (options.reuseExisting === false) {\n console.log(\n `[${options.logPrefix}] Starting a fresh ephemeral instance on isolated port ${applicationPort} because --no-reuse-env is enabled.`,\n )\n } else if (shouldUseIsolatedPort) {\n console.log(\n `[${options.logPrefix}] Existing ephemeral environment could not be reused. Starting a fresh instance on isolated port ${applicationPort}.`,\n )\n }\n const applicationBaseUrl = `http://127.0.0.1:${applicationPort}`\n const databaseName = 'mercato_test'\n const databaseUser = 'mercato'\n const databasePassword = 'secret'\n\n const databaseContainer = await new GenericContainer('postgres:16')\n .withEnvironment({\n POSTGRES_DB: databaseName,\n POSTGRES_USER: databaseUser,\n POSTGRES_PASSWORD: databasePassword,\n })\n .withExposedPorts(5432)\n .start()\n\n const databaseHost = databaseContainer.getHost()\n const databasePort = databaseContainer.getMappedPort(5432)\n const databaseUrl = `postgres://${databaseUser}:${databasePassword}@${databaseHost}:${databasePort}/${databaseName}`\n await rm(EPHEMERAL_CACHE_DB_PATH, { force: true }).catch(() => undefined)\n await rm(EPHEMERAL_QUEUE_BASE_DIR, { recursive: true, force: true }).catch(() => undefined)\n const enterpriseModulesFlag = process.env.OM_ENABLE_ENTERPRISE_MODULES ?? 'false'\n const commandEnvironment = buildEnvironment({\n DATABASE_URL: databaseUrl,\n CACHE_STRATEGY: 'sqlite',\n CACHE_SQLITE_PATH: EPHEMERAL_CACHE_DB_PATH,\n BASE_URL: applicationBaseUrl,\n APP_URL: applicationBaseUrl,\n NEXT_PUBLIC_APP_URL: applicationBaseUrl,\n JWT_SECRET: process.env.JWT_SECRET ?? 'om-ephemeral-integration-jwt-secret',\n OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? 'om-ephemeral-integration-mfa-setup-secret',\n NODE_ENV: 'production',\n DB_POOL_MIN: '0',\n DB_POOL_MAX: '5',\n DB_POOL_IDLE_TIMEOUT: '1000',\n DB_POOL_ACQUIRE_TIMEOUT: '10000',\n DB_IDLE_SESSION_TIMEOUT_MS: '30000',\n DB_IDLE_IN_TRANSACTION_TIMEOUT_MS: '30000',\n OM_INTEGRATION_TEST: 'true',\n OM_ENABLE_ENTERPRISE_MODULES: enterpriseModulesFlag,\n OM_ENABLE_ENTERPRISE_MODULES_SSO: process.env.OM_ENABLE_ENTERPRISE_MODULES_SSO ?? enterpriseModulesFlag,\n OM_ENABLE_ENTERPRISE_MODULES_SECURITY: process.env.OM_ENABLE_ENTERPRISE_MODULES_SECURITY ?? enterpriseModulesFlag,\n OM_TEST_MODE: '1',\n OM_TEST_AUTH_RATE_LIMIT_MODE: 'opt-in',\n OM_DISABLE_EMAIL_DELIVERY: '1',\n OM_WEBHOOKS_ALLOW_PRIVATE_URLS: process.env.OM_WEBHOOKS_ALLOW_PRIVATE_URLS ?? '1',\n ENABLE_CRUD_API_CACHE: 'true',\n MOCK_GATEWAY_WEBHOOK_SECRET: 'open-mercato-mock-dev-webhook-secret',\n MOCK_CARRIER_WEBHOOK_SECRET: 'open-mercato-mock-dev-carrier-webhook-secret',\n NEXT_PUBLIC_OM_EXAMPLE_INJECTION_WIDGETS_ENABLED: 'true',\n NEXT_PUBLIC_UMES_DEVTOOLS: 'true',\n CI: 'true',\n TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? 'om-ephemeral-integration-fallback-key',\n AUTO_SPAWN_WORKERS: 'false',\n AUTO_SPAWN_SCHEDULER: 'false',\n OM_CLI_QUIET: '1',\n MERCATO_QUIET: '1',\n QUEUE_BASE_DIR: EPHEMERAL_QUEUE_BASE_DIR,\n NODE_NO_WARNINGS: '1',\n PORT: String(applicationPort),\n PW_CAPTURE_SCREENSHOTS: options.captureScreenshots ? '1' : '0',\n ...(options.environmentOverrides ?? {}),\n })\n\n const runtimeLock = await acquireEphemeralRuntimeLock(options.logPrefix)\n let applicationProcess: ChildProcess | null = null\n let isStopped = false\n const stop = async (): Promise<void> => {\n if (isStopped) return\n isStopped = true\n try {\n if (applicationProcess && !applicationProcess.killed) {\n applicationProcess.kill('SIGTERM')\n }\n await databaseContainer.stop()\n await clearEphemeralEnvironmentState()\n } finally {\n await runtimeLock.release()\n }\n }\n\n try {\n const appReadyTimeoutMs = resolveAppReadyTimeoutMs(options.logPrefix)\n const buildCacheTtlSeconds = resolveBuildCacheTtlSeconds(options.logPrefix)\n const environmentFingerprint = buildEnvironmentFingerprint(commandEnvironment)\n let sourceFingerprintValue: string | null = null\n let needsBuild = true\n let shouldPersistBuildCache = true\n\n try {\n sourceFingerprintValue = await buildSourceFingerprint()\n needsBuild = options.forceRebuild\n ? true\n : await shouldRebuildBuildArtifacts(buildCacheTtlSeconds, options.logPrefix, {\n environmentFingerprint,\n precomputedSourceFingerprint: sourceFingerprintValue ?? undefined,\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n shouldPersistBuildCache = false\n needsBuild = true\n sourceFingerprintValue = null\n console.warn(\n `[${options.logPrefix}] Build cache check failed (${message}). Rebuilding with cache bypass.`,\n )\n }\n\n console.log(`[${options.logPrefix}] Ephemeral database ready at ${databaseHost}:${databasePort}`)\n console.log(`[${options.logPrefix}] Initializing application data (includes migrations)...`)\n await runTimedStep(options.logPrefix, 'Initializing application data', { expectedSeconds: 45 }, async () =>\n runYarnCommand(['initialize'], commandEnvironment, {\n silent: !options.verbose,\n }, appDirectory))\n\n if (!needsBuild) {\n console.log(\n `[${options.logPrefix}] Build cache valid (within ${BUILD_CACHE_TTL_ENV_VAR}=${buildCacheTtlSeconds}s). Skipping build pipeline.`,\n )\n } else {\n if (options.forceRebuild) {\n console.log(`[${options.logPrefix}] --force-rebuild enabled. Running full build pipeline.`)\n } else {\n console.log(`[${options.logPrefix}] Build artifacts missing, stale, or out of date; rebuilding artifacts.`)\n }\n if (PROJECT_SUPPORTS_PACKAGE_BUILDS) {\n console.log(`[${options.logPrefix}] Building packages...`)\n await runTimedStep(options.logPrefix, 'Building packages', { expectedSeconds: 20 }, async () =>\n runYarnCommand(['build:packages'], commandEnvironment, {\n silent: !options.verbose,\n }))\n } else {\n console.log(`[${options.logPrefix}] Skipping package build step (no build:packages script at project root).`)\n }\n\n console.log(`[${options.logPrefix}] Regenerating module artifacts...`)\n await rm(APP_MODULES_CHECKSUM_PATH, {\n force: true,\n })\n await runTimedStep(options.logPrefix, 'Regenerating module artifacts', { expectedSeconds: 8 }, async () =>\n runYarnCommand(['generate'], commandEnvironment, {\n silent: !options.verbose,\n }, appDirectory))\n\n if (PROJECT_SUPPORTS_PACKAGE_BUILDS) {\n console.log(`[${options.logPrefix}] Rebuilding packages after generation...`)\n await runTimedStep(options.logPrefix, 'Rebuilding packages after generation', { expectedSeconds: 20 }, async () =>\n runYarnCommand(['build:packages'], commandEnvironment, {\n silent: !options.verbose,\n }))\n }\n\n console.log(`[${options.logPrefix}] Building application...`)\n await resetNextBuildOutputDirectories(options.logPrefix)\n await runTimedStep(options.logPrefix, 'Building application', { expectedSeconds: 76 }, async () =>\n runYarnCommand(['build'], commandEnvironment, {\n silent: !options.verbose,\n }, appDirectory))\n }\n\n if (shouldPersistBuildCache && sourceFingerprintValue) {\n await writeBuildCacheState(sourceFingerprintValue, { environmentFingerprint })\n }\n\n console.log(`[${options.logPrefix}] Starting application on ${applicationBaseUrl}...`)\n const startedAppProcess = startYarnCommand(['start'], commandEnvironment, {\n silent: !options.verbose,\n }, appDirectory)\n applicationProcess = startedAppProcess\n\n await runTimedStep(\n options.logPrefix,\n 'Waiting for application readiness',\n { expectedSeconds: Math.max(12, Math.ceil(appReadyTimeoutMs / 1000)) },\n async () =>\n waitForApplicationReadiness(applicationBaseUrl, startedAppProcess, {\n timeoutMs: appReadyTimeoutMs,\n }),\n )\n console.log(`[${options.logPrefix}] Application is ready at ${applicationBaseUrl}`)\n await writeEphemeralEnvironmentState({\n baseUrl: applicationBaseUrl,\n port: applicationPort,\n logPrefix: options.logPrefix,\n captureScreenshots: options.captureScreenshots,\n })\n return {\n baseUrl: applicationBaseUrl,\n port: applicationPort,\n databaseUrl,\n commandEnvironment,\n ownedByCurrentProcess: true,\n stop,\n }\n } catch (error) {\n await stop()\n throw error\n }\n } finally {\n await setupLock.release()\n }\n}\n\nasync function keepEnvironmentRunningForever(options: { logPrefix: string; stop: () => Promise<void> }): Promise<void> {\n const onSignal = async (signal: string): Promise<void> => {\n console.log(`[${options.logPrefix}] Received ${signal}, stopping ephemeral environment...`)\n await options.stop()\n process.exit(0)\n }\n\n process.once('SIGINT', () => void onSignal('SIGINT'))\n process.once('SIGTERM', () => void onSignal('SIGTERM'))\n await new Promise<void>(() => {})\n}\n\nexport async function runIntegrationTestsInEphemeralEnvironment(rawArgs: string[]): Promise<void> {\n const options = parseOptions(rawArgs)\n const startOptions: Pick<EphemeralRuntimeOptions, 'verbose' | 'captureScreenshots' | 'forceRebuild' | 'reuseExisting'> = {\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n forceRebuild: options.forceRebuild,\n reuseExisting: options.reuseExisting,\n }\n let environment: EphemeralEnvironmentHandle | null = null\n let testRunResult: IntegrationTestRunResult\n\n try {\n console.log('[integration] Running Playwright suite...')\n if (options.reuseExisting) {\n console.log('[integration] Checking whether an existing ephemeral environment can be reused...')\n } else {\n console.log('[integration] --no-reuse-env enabled: always booting a fresh ephemeral environment.')\n }\n const environmentState = await runIntegrationTestSuiteWithRecovery(\n startOptions,\n options,\n async (runtimeEnvironment) => {\n console.log('[integration] Ensuring Playwright Chromium is installed...')\n await runNpxCommand(['playwright', 'install', 'chromium'], runtimeEnvironment.commandEnvironment)\n },\n )\n environment = environmentState.environment\n testRunResult = environmentState.testRunResult\n\n if (!environment.ownedByCurrentProcess) {\n console.log('[integration] Attached to an already running ephemeral environment from .ai/qa/ephemeral-env.json.')\n }\n if (testRunResult.retried) {\n console.log('[integration] Retried integration tests after restarting ephemeral environment.')\n }\n const effectiveCaptureScreenshots = environment.commandEnvironment.PW_CAPTURE_SCREENSHOTS === '1'\n console.log(\n `[integration] Screenshot capture is ${effectiveCaptureScreenshots ? 'enabled' : 'disabled'} (override with --screenshots / --no-screenshots)`,\n )\n\n if (testRunResult.error) {\n throw testRunResult.error\n }\n\n if (options.keep) {\n console.log('[integration] --keep enabled: leaving app and database running. Press Ctrl+C to stop.')\n await keepEnvironmentRunningForever({\n logPrefix: 'integration',\n stop: environment.stop,\n })\n }\n } finally {\n if (!options.keep) {\n await environment?.stop()\n }\n }\n}\n\nexport async function runEphemeralAppForQa(rawArgs: string[]): Promise<void> {\n const options = parseEphemeralAppOptions(rawArgs)\n const environment = await startEphemeralEnvironment({\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n forceRebuild: options.forceRebuild,\n reuseExisting: options.reuseExisting,\n logPrefix: 'ephemeral',\n })\n\n console.log(`[ephemeral] Ready for QA exploration at ${environment.baseUrl}`)\n console.log('[ephemeral] Use Playwright MCP against this URL to avoid interference with other local instances.')\n console.log('[ephemeral] Default credentials: admin@acme.com / secret')\n if (environment.ownedByCurrentProcess) {\n console.log('[ephemeral] Press Ctrl+C to stop.')\n } else {\n console.log('[ephemeral] Reused existing environment. Press Ctrl+C to exit without stopping the shared runtime.')\n }\n\n await keepEnvironmentRunningForever({\n logPrefix: 'ephemeral',\n stop: environment.stop,\n })\n}\n\nexport async function runInteractiveIntegrationInEphemeralEnvironment(rawArgs: string[]): Promise<void> {\n const options = parseInteractiveIntegrationOptions(rawArgs)\n const environment = await startEphemeralEnvironment({\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n forceRebuild: options.forceRebuild,\n reuseExisting: options.reuseExisting,\n logPrefix: 'interactive',\n })\n\n const rl = createInterface({ input, output })\n let specFiles = await listIntegrationSpecFiles()\n let activeFilter = ''\n\n console.log('[interactive] \uD83C\uDFAF Integration menu ready.')\n if (!environment.ownedByCurrentProcess) {\n console.log('[interactive] \uD83D\uDD01 Reusing existing environment from .ai/qa/ephemeral-env.json.')\n }\n console.log(`[interactive] \uD83C\uDF10 Running against ${environment.baseUrl}`)\n console.log('[interactive] \u2328\uFE0F Enter a number to run, type text (for example \"crm\") to filter, \"a\" to clear filter, \"r\" to refresh, \"h\" for HTML report, \"q\" to quit.')\n\n try {\n while (true) {\n const normalizedFilter = activeFilter.trim().toLowerCase()\n const visibleTargets = normalizedFilter.length === 0\n ? specFiles\n : specFiles.filter((target) => {\n const haystack = `${target.path} ${target.description}`.toLowerCase()\n return haystack.includes(normalizedFilter)\n })\n\n console.log('\\n[interactive] \uD83D\uDCDA Available targets:')\n if (normalizedFilter.length > 0) {\n console.log(` \uD83D\uDD0E Filter: \"${activeFilter}\" (${visibleTargets.length}/${specFiles.length})`)\n }\n if (normalizedFilter.length > 0) {\n console.log(` 0) Run all filtered tests (${visibleTargets.length})`)\n } else {\n console.log(' 0) Run all tests')\n }\n visibleTargets.forEach((target, index) => {\n console.log(` ${index + 1}) ${target.path} - ${target.description}`)\n })\n console.log(' h) Open HTML report')\n console.log(' a) Clear filter')\n console.log(' r) Refresh test list')\n console.log(' q) Quit')\n\n const rawChoice = (await rl.question('\\n[interactive] \uD83D\uDC49 Select option: ')).trim()\n if (!rawChoice) {\n continue\n }\n\n const normalizedChoice = rawChoice.toLowerCase()\n if (normalizedChoice === 'q') {\n break\n }\n if (normalizedChoice === 'r') {\n specFiles = await listIntegrationSpecFiles()\n if (activeFilter.trim().length > 0) {\n console.log(`[interactive] \uD83D\uDD04 Refreshed test list (${specFiles.length} files), keeping filter \"${activeFilter}\".`)\n } else {\n console.log(`[interactive] \uD83D\uDD04 Refreshed test list (${specFiles.length} files).`)\n }\n continue\n }\n if (normalizedChoice === 'a') {\n activeFilter = ''\n console.log('[interactive] \uD83E\uDDF9 Filter cleared.')\n console.log(`[interactive] \uD83D\uDD04 Refreshed test list (${specFiles.length} files).`)\n continue\n }\n if (normalizedChoice === 'h') {\n console.log('[interactive] \uD83D\uDCCA Opening HTML report...')\n try {\n await openIntegrationHtmlReport(environment)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Failed to open report: ${message}`)\n }\n continue\n }\n\n const parsedIndex = Number.parseInt(rawChoice, 10)\n if (!Number.isFinite(parsedIndex) || parsedIndex < 0) {\n activeFilter = rawChoice\n const filteredCount = specFiles.filter((target) => {\n const haystack = `${target.path} ${target.description}`.toLowerCase()\n return haystack.includes(activeFilter.trim().toLowerCase())\n }).length\n if (filteredCount === 0) {\n console.error(`[interactive] \u26A0\uFE0F No tests matched filter \"${activeFilter}\".`)\n } else {\n console.log(`[interactive] \uD83D\uDD0E Filtered list to \"${activeFilter}\" (${filteredCount} matches).`)\n }\n continue\n }\n\n if (parsedIndex === 0) {\n if (normalizedFilter.length > 0) {\n if (visibleTargets.length === 0) {\n console.error(`[interactive] \u26A0\uFE0F No tests matched filter \"${activeFilter}\".`)\n continue\n }\n console.log(\n `[interactive] \uD83E\uDDEA Running ${visibleTargets.length} filtered test(s) for \"${activeFilter}\"...`,\n )\n try {\n await runPlaywrightSelection(\n environment,\n visibleTargets.map((target) => target.path),\n options,\n )\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Test run failed: ${message}`)\n }\n } else {\n console.log('[interactive] \uD83E\uDDEA Running full integration suite...')\n try {\n await runPlaywrightSelection(environment, null, options)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Test run failed: ${message}`)\n }\n }\n const nextAction = await promptAfterRun(rl, environment)\n if (nextAction === 'quit') {\n break\n }\n continue\n }\n\n const selectedTarget = visibleTargets[parsedIndex - 1]\n if (!selectedTarget) {\n console.error(`[interactive] \u26A0\uFE0F Selection out of range: ${parsedIndex}`)\n continue\n }\n\n console.log(`[interactive] \uD83E\uDDEA Running ${selectedTarget.path}...`)\n try {\n await runPlaywrightSelection(environment, selectedTarget.path, options)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Test run failed: ${message}`)\n }\n const nextAction = await promptAfterRun(rl, environment)\n if (nextAction === 'quit') {\n break\n }\n }\n } finally {\n rl.close()\n await environment.stop()\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,wBAAwB;AAEjC,SAAS,oBAAoB;AAC7B,SAAS,YAAY,oBAAoB;AACzC,SAAS,OAAO,SAAS,UAAU,IAAI,MAAM,iBAAiB;AAC9D,SAAS,kBAAkB;AAC3B,OAAO,UAAU;AACjB,SAAS,uBAAuC;AAChD,SAAS,SAAS,OAAO,UAAU,cAAc;AACjD,OAAO,WAAW;AAClB,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,gCAAgC,0CAA0C;AACnF,SAAS,8BAA8B,4BAA4B;AAoH5D,SAAS,yCAAyC,SAG7C;AACV,SAAO,QAAQ,kBAAkB,SAAS,QAAQ,oCAAoC;AACxF;AAeA,MAAM,+BAA+B;AACrC,MAAM,wBAAwB;AAC9B,MAAM,6BAA6B;AACnC,MAAM,gCAAgC,IAAI;AAC1C,MAAM,6BAA6B;AACnC,MAAM,kCAAkC;AACxC,MAAM,4BAA4B;AAClC,MAAM,0BAA0B;AAChC,MAAM,sCAAgD;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,MAAM,qCAAqC;AAC3C,MAAM,2CAA2C;AACjD,MAAM,sCAAsC;AAC5C,MAAM,oBAAoB;AAC1B,MAAM,MAAM,mBAAmB;AAC/B,MAAM,uBAAuB,IAAI;AACjC,MAAM,eAAe,IAAI;AACzB,MAAM,2BAA2B,IAAI,YAAY,oBAAoB;AACrE,MAAM,yBAAyB,IAAI,YAAY,kBAAkB;AACjE,MAAM,8BAA8B,KAAK,KAAK,sBAAsB,OAAO,MAAM,wBAAwB;AAEzG,SAAS,4BAA4B,YAAqC;AACxE,aAAW,aAAa,YAAY;AAClC,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,YAAwD;AACpF,QAAM,YAAY,oBAAI,IAAY;AAClC,aAAW,aAAa,YAAY;AAClC,QAAI,aAAa,WAAW,SAAS,GAAG;AACtC,gBAAU,IAAI,SAAS;AAAA,IACzB;AAAA,EACF;AACA,SAAO,MAAM,KAAK,SAAS;AAC7B;AAEA,SAAS,mBAAmB,aAA6C;AACvE,MAAI;AACF,UAAM,MAAM,KAAK,MAAM,aAAa,KAAK,KAAK,aAAa,cAAc,GAAG,MAAM,CAAC;AAGnF,WAAO,IAAI,WAAW,CAAC;AAAA,EACzB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,MAAM,iBAAiB,mBAAmB,oBAAoB;AAC9D,MAAM,oBAAoB;AAAA,EACxB,KAAK,KAAK,cAAc,gBAAgB;AAAA,EACxC,KAAK,KAAK,cAAc,gBAAgB;AAAA,EACxC,KAAK,KAAK,cAAc,iBAAiB;AAC3C;AACA,MAAM,4BAA4B,KAAK,KAAK,cAAc,YAAY,aAAa,4BAA4B;AAC/G,MAAM,kCAAkC,OAAO,eAAe,gBAAgB,MAAM;AACpF,MAAM,0BAA0B,KAAK,KAAK,sBAAsB,OAAO,MAAM,oBAAoB;AACjG,MAAM,0BAA0B,KAAK,KAAK,sBAAsB,OAAO,MAAM,oBAAoB;AACjG,MAAM,iCAAiC,KAAK,KAAK,sBAAsB,OAAO,MAAM,kBAAkB;AACtG,MAAM,mCAAmC,KAAK,KAAK,sBAAsB,OAAO,MAAM,4BAA4B;AAClH,MAAM,0BAA0B,KAAK,KAAK,sBAAsB,OAAO,MAAM,wBAAwB;AACrG,MAAM,2BAA2B,KAAK,KAAK,cAAc,YAAY,OAAO;AAC5E,MAAM,qCAAqC;AAC3C,MAAM,+BAA+B,KAAK,KAAK,sBAAsB,OAAO,MAAM,gBAAgB,cAAc;AAChH,MAAM,+BAA+B,KAAK,KAAK,sBAAsB,OAAO,MAAM,OAAO;AACzF,MAAM,gCAAgC;AAAA,EACpC,KAAK,KAAK,cAAc,YAAY,MAAM;AAAA,EAC1C,KAAK,KAAK,cAAc,OAAO;AACjC;AACA,MAAM,sBAAsB,qBAAqB;AAAA,EAC/C,KAAK,KAAK,cAAc,YAAY,QAAQ,UAAU;AAAA,EACtD,KAAK,KAAK,cAAc,SAAS,UAAU;AAAA,EAC3C,KAAK,KAAK,cAAc,YAAY,aAAa,sBAAsB;AAAA,EACvE,KAAK,KAAK,0BAA0B,QAAQ,UAAU;AAAA,EACtD,KAAK,KAAK,wBAAwB,QAAQ,UAAU;AACtD,CAAC;AACD,MAAM,wBAAwB,qBAAqB;AAAA,EACjD,KAAK,KAAK,cAAc,KAAK;AAAA,EAC7B,KAAK,KAAK,cAAc,cAAc;AAAA,EACtC;AAAA,EACA,KAAK,KAAK,cAAc,eAAe;AAAA,EACvC,yBAAyB,KAAK,KAAK,0BAA0B,KAAK,GAAG,KAAK,KAAK,0BAA0B,MAAM,CAAC;AAAA,EAChH,KAAK,KAAK,0BAA0B,cAAc;AAAA,EAClD,KAAK,KAAK,0BAA0B,eAAe;AAAA,EACnD,yBAAyB,KAAK,KAAK,wBAAwB,KAAK,GAAG,KAAK,KAAK,wBAAwB,MAAM,CAAC;AAAA,EAC5G,KAAK,KAAK,wBAAwB,cAAc;AAAA,EAChD,KAAK,KAAK,wBAAwB,eAAe;AAAA,EACjD,KAAK,KAAK,sBAAsB,cAAc;AAAA,EAC9C,KAAK,KAAK,sBAAsB,oBAAoB;AAAA,EACpD,KAAK,KAAK,sBAAsB,WAAW;AAC7C,CAAC;AACD,MAAM,wBAAwB,CAAC,QAAQ,WAAW,OAAO,SAAS,SAAS,OAAO,aAAa;AAC/F,MAAM,0BAAkD;AAAA,EACtD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,OAAO;AAAA,EACP,KAAK;AAAA,EACL,aAAa;AACf;AACA,MAAM,4BAA4B;AAClC,MAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,MAAM,qCAAqC,oBAAI,IAAI;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AA2ED,SAAS,oBAA4B;AACnC,SAAO,QAAQ,aAAa,UAAU,aAAa;AACrD;AAEA,SAAS,iBAAiB,WAAiD;AACzE,SAAO;AAAA,IACL,GAAG,QAAQ;AAAA,IACX,GAAG;AAAA,EACL;AACF;AAEA,SAAS,4BAA4B,aAAwC;AAC3E,QAAM,aAAa,OAAO,KAAK,WAAW,EACvC,OAAO,CAAC,QAAQ,IAAI,WAAW,cAAc,CAAC,EAC9C,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC;AAClD,QAAM,OAAO,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,sBAAsB,GAAG,UAAU,CAAC,CAAC;AACzE,QAAM,mBAAmB,KAAK,IAAI,CAAC,QAAQ,GAAG,GAAG,IAAI,YAAY,GAAG,KAAK,EAAE,EAAE;AAC7E,SAAO,WAAW,QAAQ,EAAE,OAAO,iBAAiB,KAAK,IAAI,GAAG,MAAM,EAAE,OAAO,KAAK;AACtF;AAEA,eAAe,gCAAgC,WAAkC;AAC/E,aAAW,mBAAmB,+BAA+B;AAC3D,QAAI,CAAC,WAAW,eAAe,GAAG;AAChC;AAAA,IACF;AACA,UAAM,GAAG,iBAAiB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC1D,YAAQ,IAAI,IAAI,SAAS,0CAA0C,eAAe,GAAG;AAAA,EACvF;AACF;AAEA,SAAS,eACP,MACA,aACA,OAA6B,CAAC,GAC9B,MAAc,sBACC;AACf,SAAO,kBAAkB,CAAC,OAAO,GAAG,IAAI,GAAG,aAAa,MAAM,GAAG;AACnE;AAEA,eAAe,aACb,WACA,OACA,SACA,MACY;AACZ,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,aAAa,KAAK,IAAI,GAAG,QAAQ,yBAAyB,CAAC,IAAI;AACrE,QAAM,QAAQ,YAAY,MAAM;AAC9B,UAAM,iBAAiB,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI,CAAC;AAC9E,UAAM,mBAAmB,KAAK,IAAI,GAAG,QAAQ,kBAAkB,cAAc;AAC7E,YAAQ,IAAI,IAAI,SAAS,KAAK,KAAK,OAAO,cAAc,eAAe,gBAAgB,QAAQ;AAAA,EACjG,GAAG,UAAU;AAEb,MAAI;AACF,UAAM,SAAS,MAAM,KAAK;AAC1B,UAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI,CAAC;AAC/E,YAAQ,IAAI,IAAI,SAAS,KAAK,KAAK,iBAAiB,eAAe,IAAI;AACvE,WAAO;AAAA,EACT,UAAE;AACA,kBAAc,KAAK;AAAA,EACrB;AACF;AAEA,SAAS,wCAAwC,OAAwB;AACvE,SAAO,oCAAoC,KAAK,CAAC,YAAY,QAAQ,KAAK,KAAK,CAAC;AAClF;AAEA,SAAS,mBAAmB,OAAuB;AACjD,SAAO,MAAM,QAAQ,mBAAmB,EAAE;AAC5C;AAEA,SAAS,0BAA0B,MAAoE;AACrG,QAAM,aAAa,KAAK,KAAK;AAC7B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,WAAW,MAAM,yBAAyB;AAC9D,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,MAAM,KAAK,WAAW,SAAS,qBAAqB,CAAC;AAC7E,QAAM,oBAAoB,gBAAgB,GAAG,EAAE;AAC/C,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,YAAY,CAAC;AAC5B,QAAM,cAAc,OAAO,WAAW,kBAAkB,CAAC,KAAK,EAAE;AAChE,QAAM,OAAO,kBAAkB,CAAC;AAChC,MAAI,CAAC,OAAO,SAAS,WAAW,KAAK,cAAc,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,SAAS,MAAM,KAAK,MAAM,cAAc,GAAI,IAAI,KAAK,MAAM,WAAW;AACzF,SAAO;AAAA,IACL,MAAM,WAAW,YAAO,OAAO,YAAY,MAAM,MAAM,SAAS;AAAA,IAChE;AAAA,EACF;AACF;AAEA,eAAe,+BACb,SACA,aACA,aACA,OAAiC,CAAC,GACM;AACxC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,gBAAgB,oBAAoB,SAAS,WAAW;AAC9D,UAAM,gBAAgB,MAAM,cAAc,SAAS,cAAc,MAAM;AAAA,MACrE,KAAK;AAAA,MACL,KAAK;AAAA,MACL,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,MAChC,GAAG,cAAc;AAAA,IACnB,CAAC;AAED,QAAIA,UAAS;AACb,QAAI,mCAAmC;AACvC,QAAI,qBAAqB;AACzB,QAAI,qBAAqB;AACzB,QAAI,2BAA2B;AAC/B,QAAI,oBAAoB;AACxB,QAAI,mBAAkC,QAAQ,QAAQ;AAEtD,UAAM,qBAAqB,KAAK;AAChC,UAAM,wBAAwB,oBAAoB,+BAA+B;AACjF,UAAM,4BAA4B,oBAAoB,6BAA6B;AACnF,UAAM,qBAAqB,oBAAoB,sBAAsB;AAErE,UAAM,8BAA8B,MAAM;AACxC,UAAI,CAAC,sBAAsB,sBAAsB,kCAAkC;AACjF;AAAA,MACF;AACA,UAAI,2BAA2B,uBAAuB;AACpD;AAAA,MACF;AACA,YAAM,MAAM,KAAK,IAAI;AACrB,UAAI,MAAM,oBAAoB,oBAAoB;AAChD;AAAA,MACF;AACA,0BAAoB;AACpB,yBAAmB,iBAChB,KAAK,YAAY;AAChB,cAAM,cAAc,MAAM,yBAAyB,mBAAmB,OAAO;AAC7E,YAAI,eAAe,CAAC,oBAAoB;AACtC,6CAAmC;AACnC,+BAAqB;AACrB,wBAAc,KAAK,SAAS;AAAA,QAC9B;AAAA,MACF,CAAC,EACA,MAAM,MAAM,MAAS;AAAA,IAC1B;AAEA,UAAM,oBAAoB,CAAC,SAAiB;AAC1C,YAAM,SAAS,0BAA0B,IAAI;AAC7C,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AACA,UAAI,OAAO,SAAS,QAAQ;AAC1B,mCAA2B;AAC3B;AAAA,MACF;AAEA,UAAI,OAAO,cAAc,2BAA2B;AAClD,oCAA4B;AAC5B,oCAA4B;AAC5B;AAAA,MACF;AAEA,iCAA2B;AAAA,IAC7B;AAEA,UAAM,cAAc,CAAC,OAAwB,WAAgC;AAC3E,YAAM,OAAO,MAAM,SAAS;AAC5B,YAAM,iBAAiB,mBAAmB,IAAI;AAC9C,UAAI,WAAW,UAAU;AACvB,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B,OAAO;AACL,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B;AAEA,MAAAA,WAAU;AACV,UAAIA,QAAO,SAAS,MAAS;AAC3B,QAAAA,UAASA,QAAO,MAAM,IAAO;AAAA,MAC/B;AAEA,UACE,CAAC,oCACD,KAAK,gCACL,wCAAwC,cAAc,GACtD;AACA,2CAAmC;AACnC,YAAI,KAAK,+BAA+B;AACtC,+BAAqB;AACrB,wBAAc,KAAK,SAAS;AAAA,QAC9B;AAAA,MACF;AAEA,4BAAsB;AACtB,UAAI,eAAe,mBAAmB,QAAQ,IAAI;AAClD,aAAO,gBAAgB,GAAG;AACxB,cAAM,cAAc,mBAAmB,MAAM,GAAG,YAAY,EAAE,QAAQ,OAAO,EAAE;AAC/E,0BAAkB,WAAW;AAC7B,6BAAqB,mBAAmB,MAAM,eAAe,CAAC;AAC9D,uBAAe,mBAAmB,QAAQ,IAAI;AAAA,MAChD;AAAA,IACF;AAEA,kBAAc,QAAQ,GAAG,QAAQ,CAAC,UAAU;AAC1C,kBAAY,OAAO,QAAQ;AAAA,IAC7B,CAAC;AACD,kBAAc,QAAQ,GAAG,QAAQ,CAAC,UAAU;AAC1C,kBAAY,OAAO,QAAQ;AAAA,IAC7B,CAAC;AACD,kBAAc,GAAG,SAAS,MAAM;AAChC,kBAAc,GAAG,QAAQ,CAAC,SAAwB;AAChD,UAAI,mBAAmB,KAAK,EAAE,SAAS,GAAG;AACxC,0BAAkB,mBAAmB,QAAQ,CAAC;AAAA,MAChD;AACA,uBAAiB,QAAQ,MAAM;AAC7B,gBAAQ;AAAA,UACN,UAAU;AAAA,UACV,QAAQA,QAAO,KAAK;AAAA,UACpB,kCAAkC,oCAAoC;AAAA,QACxE,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,4BACP,cACA,MACA,QACyB;AACzB,QAAM,QAAQ,IAAI;AAAA,IAChB,mBAAmB,YAAY,IAAI,KAAK,KAAK,GAAG,CAAC,UAAU,OAAO,YAAY,SAAS;AAAA,EACzF;AACA,QAAM,mCAAmC,OAAO;AAChD,QAAM,gBAAgB,OAAO;AAC7B,SAAO;AACT;AAEA,eAAe,mCACb,MACA,aACA,OAAiC,CAAC,GACnB;AACf,QAAM,SAAS,MAAM,+BAA+B,kBAAkB,GAAG,CAAC,OAAO,GAAG,IAAI,GAAG,aAAa;AAAA,IACtG,8BAA8B,KAAK;AAAA,IACnC,+BAA+B,KAAK;AAAA,IACpC,8BAA8B,KAAK;AAAA,EACrC,CAAC;AAED,MAAI,OAAO,aAAa,GAAG;AACzB;AAAA,EACF;AAEA,QAAM,4BAA4B,QAAQ,CAAC,OAAO,GAAG,IAAI,GAAG,MAAM;AACpE;AAEA,eAAe,kCACb,MACA,aACA,OAAiC,CAAC,GACnB;AACf,QAAM,SAAS,QAAQ,aAAa,UAAU,YAAY;AAC1D,QAAM,SAAS,MAAM,+BAA+B,QAAQ,MAAM,aAAa;AAAA,IAC7E,8BAA8B,KAAK;AAAA,IACnC,+BAA+B,KAAK;AAAA,IACpC,8BAA8B,KAAK;AAAA,EACrC,CAAC;AAED,MAAI,OAAO,aAAa,GAAG;AACzB;AAAA,EACF;AAEA,QAAM,4BAA4B,OAAO,MAAM,MAAM;AACvD;AAEA,SAAS,kBACP,aACA,aACA,OAA6B,CAAC,GAC9B,MAAc,sBACC;AACf,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,aAA2B,KAAK,SAAS,CAAC,UAAU,QAAQ,MAAM,IAAI;AAC5E,UAAM,gBAAgB,oBAAoB,kBAAkB,GAAG,WAAW;AAC1E,UAAM,UAAwB,MAAM,cAAc,SAAS,cAAc,MAAM;AAAA,MAC7E;AAAA,MACA,KAAK;AAAA,MACL,OAAO;AAAA,MACP,GAAG,cAAc;AAAA,IACnB,CAAC;AACD,QAAI,iBAAiB;AACrB,QAAI,KAAK,QAAQ;AACf,cAAQ,QAAQ,GAAG,QAAQ,CAAC,UAA2B;AACrD,0BAAkB,MAAM,SAAS;AAAA,MACnC,CAAC;AACD,cAAQ,QAAQ,GAAG,QAAQ,CAAC,UAA2B;AACrD,0BAAkB,MAAM,SAAS;AAAA,MACnC,CAAC;AAAA,IACH;AACA,YAAQ,GAAG,SAAS,MAAM;AAC1B,YAAQ,GAAG,QAAQ,CAAC,SAAwB;AAC1C,UAAI,SAAS,GAAG;AACd,gBAAQ;AACR;AAAA,MACF;AACA,YAAM,QAAQ,KAAK,UAAU,eAAe,KAAK,EAAE,SAAS,IACxD;AAAA;AAAA,EAAmB,eAAe,KAAK,EAAE,MAAM,IAAI,EAAE,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC,KAC1E;AACJ,aAAO,IAAI,MAAM,wBAAwB,YAAY,KAAK,GAAG,CAAC,UAAU,QAAQ,SAAS,IAAI,KAAK,EAAE,CAAC;AAAA,IACvG,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,cAAc,MAAgB,aAA+C;AACpF,QAAM,SAAS,QAAQ,aAAa,UAAU,YAAY;AAC1D,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,gBAAgB,oBAAoB,QAAQ,IAAI;AACtD,UAAM,UAAU,MAAM,cAAc,SAAS,cAAc,MAAM;AAAA,MAC/D,KAAK;AAAA,MACL,KAAK;AAAA,MACL,OAAO;AAAA,MACP,GAAG,cAAc;AAAA,IACnB,CAAC;AACD,YAAQ,GAAG,SAAS,MAAM;AAC1B,YAAQ,GAAG,QAAQ,CAAC,SAAS;AAC3B,UAAI,SAAS,GAAG;AACd,gBAAQ;AACR;AAAA,MACF;AACA,aAAO,IAAI,MAAM,uBAAuB,KAAK,KAAK,GAAG,CAAC,UAAU,QAAQ,SAAS,GAAG,CAAC;AAAA,IACvF,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,oBACP,aACA,aACA,OAA6B,CAAC,GAC9B,MAAc,sBACA;AACd,QAAM,aAA2B,KAAK,SAAS,CAAC,UAAU,QAAQ,MAAM,IAAI;AAC5E,QAAM,gBAAgB,oBAAoB,kBAAkB,GAAG,WAAW;AAC1E,QAAM,gBAA8B,MAAM,cAAc,SAAS,cAAc,MAAM;AAAA,IACnF;AAAA,IACA,KAAK;AAAA,IACL,OAAO;AAAA,IACP,GAAG,cAAc;AAAA,EACnB,CAAC;AACD,MAAI,KAAK,QAAQ;AACf,kBAAc,QAAQ,GAAG,QAAQ,MAAM;AAAA,IAAC,CAAC;AACzC,kBAAc,QAAQ,GAAG,QAAQ,MAAM;AAAA,IAAC,CAAC;AAAA,EAC3C;AACA,SAAO;AACT;AAEA,SAAS,iBACP,MACA,aACA,OAA6B,CAAC,GAC9B,MAAc,sBACA;AACd,SAAO,oBAAoB,CAAC,OAAO,GAAG,IAAI,GAAG,aAAa,MAAM,GAAG;AACrE;AAEA,eAAe,kCAAiD;AAC9D,QAAM,mBAAmB,MAAM,qBAAqB,UAAU,CAAC,MAAM,CAAC;AACtE,MAAI,iBAAiB,SAAS,GAAG;AAC/B;AAAA,EACF;AAEA,QAAM,kBAAkB,iBAAiB,OAAO,KAAK;AACrD,MAAI,WAAW;AACf,MAAI,iBAAiB,SAAS,IAAI;AAChC,eAAW;AAAA,EACb,WAAW,gBAAgB,SAAS,qCAAqC,GAAG;AAC1E,eAAW;AAAA,EACb;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,MACE;AAAA,MACA,UAAU,mBAAmB,oBAAoB;AAAA,MACjD,eAAe,QAAQ;AAAA,IACzB,EAAE,KAAK,GAAG;AAAA,EACZ;AACF;AAEA,SAAS,sBAA4B;AACnC,QAAM,QAAQ,OAAO,SAAS,QAAQ,SAAS,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE;AAC5E,MAAI,SAAS,IAAI;AACf;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR;AAAA,MACE;AAAA,MACA,wBAAwB,QAAQ,SAAS,IAAI;AAAA,MAC7C;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,EACZ;AACF;AAEA,SAAS,sBAAsB,SAA+C;AAC5E,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAQ,GAAG,SAAS,MAAM;AAC1B,YAAQ,GAAG,QAAQ,CAAC,SAAS,QAAQ,IAAI,CAAC;AAAA,EAC5C,CAAC;AACH;AAEA,SAAS,MAAM,cAAqC;AAClD,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,eAAW,SAAS,YAAY;AAAA,EAClC,CAAC;AACH;AAEO,SAAS,4BAA4B,WAA2B;AACrE,QAAM,WAAW,QAAQ,IAAI,uBAAuB;AACpD,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AACA,QAAM,SAAS,OAAO,SAAS,UAAU,EAAE;AAC3C,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,YAAQ;AAAA,MACN,IAAI,SAAS,aAAa,uBAAuB,WAAW,QAAQ,oBAAoB,+BAA+B;AAAA,IACzH;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,yBAAyB,WAA2B;AAClE,QAAM,WAAW,QAAQ,IAAI,yBAAyB;AACtD,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AACA,QAAM,gBAAgB,OAAO,SAAS,UAAU,EAAE;AAClD,MAAI,CAAC,OAAO,SAAS,aAAa,KAAK,gBAAgB,GAAG;AACxD,YAAQ;AAAA,MACN,IAAI,SAAS,aAAa,yBAAyB,WAAW,QAAQ,oBAAoB,+BAA+B,GAAI;AAAA,IAC/H;AACA,WAAO;AAAA,EACT;AACA,SAAO,gBAAgB;AACzB;AAEA,SAAS,mBAAmB,YAA+B,CAAC,GAK1D;AACA,SAAO;AAAA,IACL,eAAe,UAAU,iBAAiB;AAAA,IAC1C,YAAY,UAAU,cAAc;AAAA,IACpC,gBAAgB,UAAU,kBAAkB;AAAA,IAC5C,aAAa,UAAU,eAAe;AAAA,EACxC;AACF;AAEA,SAAS,6BAA6B,WAA4B;AAChE,SAAO,mCAAmC,IAAI,SAAS,KAAK,UAAU,WAAW,GAAG;AACtF;AAEA,eAAe,sBAAsB,WAAmB,aAAwC;AAC9F,QAAM,aAAa,KAAK,UAAU,SAAS;AAC3C,QAAM,YAAY,MAAM,KAAK,UAAU;AACvC,MAAI,UAAU,OAAO,GAAG;AACtB,WAAO,CAAC,KAAK,SAAS,aAAa,UAAU,CAAC;AAAA,EAChD;AACA,MAAI,CAAC,UAAU,YAAY,GAAG;AAC5B,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAU,MAAM,QAAQ,YAAY,EAAE,eAAe,KAAK,CAAC;AACjE,QAAM,QAAkB,CAAC;AACzB,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,YAAY,KAAK,6BAA6B,MAAM,IAAI,GAAG;AACnE;AAAA,IACF;AACA,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,SAAS,MAAM,sBAAsB,KAAK,KAAK,YAAY,MAAM,IAAI,GAAG,WAAW;AACzF,YAAM,KAAK,GAAG,MAAM;AACpB;AAAA,IACF;AACA,QAAI,CAAC,MAAM,OAAO,GAAG;AACnB;AAAA,IACF;AACA,UAAM,KAAK,KAAK,KAAK,YAAY,MAAM,IAAI,CAAC;AAAA,EAC9C;AACA,SAAO;AACT;AAEA,eAAe,uBAAuB,UAA6B,CAAC,GAA2B;AAC7F,QAAM,EAAE,YAAY,YAAY,IAAI,mBAAmB,OAAO;AAC9D,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,gBAA0B,CAAC;AAEjC,aAAW,aAAa,YAAY;AAClC,QAAI;AACJ,QAAI;AACF,kBAAY,MAAM,sBAAsB,WAAW,WAAW;AAAA,IAChE,SAAS,OAAO;AACd,UAAK,MAAgC,SAAS,UAAU;AACtD,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAEA,eAAW,YAAY,WAAW;AAChC,YAAM,eAAe,KAAK,WAAW,QAAQ,IAAI,WAAW,KAAK,QAAQ,aAAa,QAAQ;AAC9F,UAAI,CAAC,UAAU,IAAI,YAAY,GAAG;AAChC,kBAAU,IAAI,YAAY;AAC1B,sBAAc,KAAK,YAAY;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,mBAA6B,CAAC;AACpC,aAAW,YAAY,cAAc,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC,GAAG;AACvE,UAAM,WAAW,MAAM,KAAK,QAAQ;AACpC,QAAI,CAAC,SAAS,OAAO,GAAG;AACtB;AAAA,IACF;AACA,UAAM,eAAe,KAAK,SAAS,aAAa,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AAClF,qBAAiB,KAAK,GAAG,YAAY,IAAI,SAAS,IAAI,IAAI,KAAK,MAAM,SAAS,OAAO,CAAC,EAAE;AAAA,EAC1F;AAEA,MAAI,iBAAiB,WAAW,GAAG;AACjC,WAAO;AAAA,EACT;AAEA,SAAO,WAAW,QAAQ,EAAE,OAAO,iBAAiB,KAAK,IAAI,GAAG,MAAM,EAAE,OAAO,KAAK;AACtF;AAEA,eAAe,0BACb,aACA,UAA6B,CAAC,GACZ;AAClB,QAAM,EAAE,YAAY,YAAY,IAAI,mBAAmB,OAAO;AAC9D,QAAM,YAAY,oBAAI,IAAY;AAElC,aAAW,aAAa,YAAY;AAClC,QAAI;AACJ,QAAI;AACF,kBAAY,MAAM,sBAAsB,WAAW,WAAW;AAAA,IAChE,SAAS,OAAO;AACd,UAAK,MAAgC,SAAS,UAAU;AACtD;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAEA,eAAW,YAAY,WAAW;AAChC,YAAM,eAAe,KAAK,WAAW,QAAQ,IAAI,WAAW,KAAK,QAAQ,aAAa,QAAQ;AAC9F,UAAI,UAAU,IAAI,YAAY,GAAG;AAC/B;AAAA,MACF;AACA,gBAAU,IAAI,YAAY;AAE1B,UAAI;AACJ,UAAI;AACF,mBAAW,MAAM,KAAK,YAAY;AAAA,MACpC,SAAS,OAAO;AACd,YAAK,MAAgC,SAAS,UAAU;AACtD,iBAAO;AAAA,QACT;AACA,cAAM;AAAA,MACR;AACA,UAAI,SAAS,OAAO,KAAK,SAAS,UAAU,aAAa;AACvD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,oBAAoB,gBAAyD;AAC1F,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,SAAS,gBAAgB,MAAM;AAAA,EACjD,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AAEA,MAAI,SAAkB;AACtB,MAAI;AACF,aAAS,KAAK,MAAM,OAAO;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,WAAO;AAAA,EACT;AACA,QAAM,aAAa;AACnB,MAAI,WAAW,YAAY,2BAA2B;AACpD,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,YAAY,YAAY,CAAC,OAAO,SAAS,WAAW,OAAO,GAAG;AAClF,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,sBAAsB,YAAY,WAAW,kBAAkB,WAAW,GAAG;AACjG,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,2BAA2B,YAAY,WAAW,uBAAuB,WAAW,GAAG;AAC3G,WAAO;AAAA,EACT;AACA,MAAI,CAAC,MAAM,QAAQ,WAAW,aAAa,KAAK,WAAW,cAAc,WAAW,GAAG;AACrF,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,gBAAgB,YAAY,WAAW,YAAY,WAAW,GAAG;AACrF,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,WAAW;AAAA,IACpB,mBAAmB,WAAW;AAAA,IAC9B,wBAAwB,WAAW;AAAA,IACnC,eAAe,WAAW,cAAc,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ;AAAA,IACpG,aAAa,WAAW;AAAA,EAC1B;AACF;AAEA,eAAe,qBACb,mBACA,UAA6B,CAAC,GACf;AACf,QAAM,WAAW,mBAAmB,OAAO;AAC3C,QAAM,yBAAyB,QAAQ,0BAA0B;AACjE,MAAI,CAAC,wBAAwB;AAC3B,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,QAAM,MAAM,KAAK,QAAQ,SAAS,cAAc,GAAG,EAAE,WAAW,KAAK,CAAC;AACtE,QAAM;AAAA,IACJ,SAAS;AAAA,IACT,GAAG,KAAK;AAAA,MACN;AAAA,QACE,SAAS;AAAA,QACT,SAAS,KAAK,IAAI;AAAA,QAClB;AAAA,QACA;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,aAAa,SAAS;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAAA,IACD;AAAA,EACF;AACF;AAEA,eAAe,uBAAuB,UAAoC;AACxE,MAAI;AACF,UAAM,gBAAgB,MAAM,KAAK,QAAQ;AACzC,WAAO,CAAC,cAAc,OAAO,KAAK,cAAc,QAAQ;AAAA,EAC1D,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAsB,0BACpB,YACA,WACA,UAA6B,CAAC,GACZ;AAClB,MAAI,cAAc,GAAG;AACnB,YAAQ,IAAI,IAAI,SAAS,2BAA2B,uBAAuB,cAAc,UAAU,GAAG;AACtG,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,mBAAmB,OAAO;AAC3C,QAAM,2BAA2B,QAAQ,gCAAiC,MAAM,uBAAuB,QAAQ;AAC/G,QAAM,gCAAgC,QAAQ,0BAA0B;AACxE,MAAI,CAAC,0BAA0B;AAC7B,YAAQ;AAAA,MACN,IAAI,SAAS;AAAA,IACf;AACA,WAAO;AAAA,EACT;AACA,MAAI,CAAC,+BAA+B;AAClC,YAAQ,IAAI,IAAI,SAAS,+EAA+E;AACxG,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,MAAM,oBAAoB,SAAS,cAAc;AAC/D,MAAI,CAAC,OAAO;AACV,YAAQ,IAAI,IAAI,SAAS,8DAA8D,SAAS,cAAc,IAAI;AAClH,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,gBAAgB,SAAS,aAAa;AAC9C,YAAQ,IAAI,IAAI,SAAS,oEAAoE;AAC7F,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,KAAK,OAAO,KAAK,IAAI,IAAI,MAAM,WAAW,GAAI;AACtE,MAAI,kBAAkB,YAAY;AAChC,YAAQ;AAAA,MACN,IAAI,SAAS,0CAA0C,eAAe,aAAa,uBAAuB,IAAI,UAAU;AAAA,IAC1H;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,sBAAsB,0BAA0B;AACxD,YAAQ,IAAI,IAAI,SAAS,gEAAgE;AACzF,WAAO;AAAA,EACT;AACA,MAAI,MAAM,2BAA2B,+BAA+B;AAClE,YAAQ,IAAI,IAAI,SAAS,6EAA6E;AACtG,WAAO;AAAA,EACT;AAEA,aAAW,gBAAgB,SAAS,eAAe;AACjD,QAAI,MAAM,uBAAuB,YAAY,GAAG;AAC9C,cAAQ,IAAI,IAAI,SAAS,kDAAkD,YAAY,GAAG;AAC1F,aAAO;AAAA,IACT;AAAA,EACF;AAEA,UAAQ;AAAA,IACN,IAAI,SAAS,sDAAsD,eAAe,UAAU,UAAU;AAAA,EACxG;AACA,SAAO;AACT;AAEA,eAAsB,4BACpB,YACA,WACA,UAA6B,CAAC,GACZ;AAClB,SAAO,CAAE,MAAM,0BAA0B,YAAY,WAAW,OAAO;AACzE;AAEA,eAAe,cAA+B;AAC5C,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,aAAa;AAC5B,WAAO,GAAG,SAAS,MAAM;AACzB,WAAO,OAAO,GAAG,aAAa,MAAM;AAClC,YAAM,UAAU,OAAO,QAAQ;AAC/B,UAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,eAAO,MAAM;AACb,eAAO,IAAI,MAAM,8BAA8B,CAAC;AAChD;AAAA,MACF;AACA,YAAM,OAAO,QAAQ;AACrB,aAAO,MAAM,CAAC,eAAe;AAC3B,YAAI,YAAY;AACd,iBAAO,UAAU;AACjB;AAAA,QACF;AACA,gBAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAe,gBAAgB,MAAgC;AAC7D,QAAM,UAAU,CAAC,SAA0C,IAAI,QAAQ,CAAC,YAAY;AAClF,UAAM,SAAS,aAAa;AAC5B,WAAO,KAAK,SAAS,CAAC,UAAU;AAC9B,YAAM,YAAa,MAAgC;AACnD,UAAI,cAAc,gBAAgB;AAChC,gBAAQ,IAAI;AACZ;AAAA,MACF;AACA,cAAQ,KAAK;AAAA,IACf,CAAC;AACD,WAAO,OAAO,MAAM,MAAM,MAAM;AAC9B,aAAO,MAAM,MAAM;AACjB,gBAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AAED,QAAM,mBAAmB,MAAM,QAAQ,WAAW;AAClD,MAAI,qBAAqB,OAAO;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,mBAAmB,MAAM,QAAQ,KAAK;AAC5C,MAAI,qBAAqB,OAAO;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,qBAAqB,QAAQ,qBAAqB;AAC3D;AAEA,eAAe,iBAAiB,eAAwC;AACtE,MAAI,MAAM,gBAAgB,aAAa,GAAG;AACxC,WAAO;AAAA,EACT;AACA,QAAM,eAAe,MAAM,YAAY;AACvC,UAAQ,IAAI,oBAAoB,aAAa,iCAAiC,YAAY,GAAG;AAC7F,SAAO;AACT;AAEA,eAAsB,+BAA+BC,QAKnC;AAChB,QAAM,UAAqC;AAAA,IACzC,QAAQ;AAAA,IACR,SAASA,OAAM;AAAA,IACf,MAAMA,OAAM;AAAA,IACZ,QAAQA,OAAM;AAAA,IACd,oBAAoBA,OAAM;AAAA,IAC1B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACA,QAAM,UAAU,yBAAyB,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AAC1F;AAEA,eAAsB,iCAAgD;AACpE,QAAM,GAAG,yBAAyB,EAAE,OAAO,KAAK,CAAC;AACjD,QAAM,GAAG,gCAAgC,EAAE,OAAO,KAAK,CAAC;AAC1D;AAEA,eAAsB,gCAA2E;AAC/F,MAAI,aAAa;AACjB,MAAI;AACF,iBAAa,MAAM,SAAS,yBAAyB,MAAM;AAAA,EAC7D,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AAEA,MAAI,SAAkB;AACtB,MAAI;AACF,aAAS,KAAK,MAAM,UAAU;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS;AACf,MAAI,OAAO,WAAW,WAAW;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,OAAO,YAAY,YAAY,OAAO,QAAQ,WAAW,GAAG;AACrE,WAAO;AAAA,EACT;AACA,MAAI,OAAO,OAAO,SAAS,YAAY,CAAC,OAAO,SAAS,OAAO,IAAI,KAAK,OAAO,OAAO,GAAG;AACvF,WAAO;AAAA,EACT;AACA,MAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,WAAW,GAAG;AACnE,WAAO;AAAA,EACT;AACA,MAAI,OAAO,OAAO,uBAAuB,WAAW;AAClD,WAAO;AAAA,EACT;AACA,MAAI,OAAO,OAAO,cAAc,YAAY,OAAO,UAAU,WAAW,GAAG;AACzE,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,SAAS,OAAO;AAAA,IAChB,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO;AAAA,IACf,oBAAoB,OAAO;AAAA,IAC3B,WAAW,OAAO;AAAA,EACpB;AACF;AAEA,SAAS,mBAAmB,MAAuB;AACjD,SAAO,CAAC,2DAA2D,KAAK,IAAI;AAC9E;AAEA,SAAS,oCAAoC,QAAyB;AACpE,SAAO,WAAW,OAAQ,UAAU,OAAO,SAAS;AACtD;AAEA,eAAe,eAAe,SAAgD;AAC5E,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG,OAAO,UAAU;AAAA,MAC/C,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ,CAAC;AACD,QAAI,CAAC,oCAAoC,SAAS,MAAM,GAAG;AACzD,aAAO;AAAA,QACL,QAAQ,SAAS;AAAA,QACjB,SAAS;AAAA,QACT,QAAQ,uBAAuB,SAAS,MAAM;AAAA,MAChD;AAAA,IACF;AACA,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,QACL,QAAQ,SAAS;AAAA,QACjB,SAAS;AAAA,QACT,QAAQ,gCAAgC,SAAS,MAAM;AAAA,MACzD;AAAA,IACF;AACA,UAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE;AACjD,QAAI,CAAC,mBAAmB,IAAI,GAAG;AAC7B,aAAO;AAAA,QACL,QAAQ,SAAS;AAAA,QACjB,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ,sBAAsB,OAAO;AAAA,IACvC;AAAA,EACF;AACF;AAEA,eAAe,0BAA0B,SAAmD;AAC1F,MAAI;AACF,UAAM,OAAO,IAAI,gBAAgB;AACjC,SAAK,IAAI,SAAS,yCAAyC;AAC3D,SAAK,IAAI,YAAY,kBAAkB;AACvC,UAAM,WAAW,MAAM,MAAM,GAAG,OAAO,mBAAmB;AAAA,MACxD,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,SAAS;AAAA,IACtB,CAAC;AAED,UAAM,UAAU,SAAS,WAAW,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW;AACrH,WAAO;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB;AAAA,MACA,QAAQ,UACJ,iCAAiC,SAAS,MAAM,KAChD,4CAA4C,SAAS,MAAM;AAAA,IACjE;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ,gCAAgC,OAAO;AAAA,IACjD;AAAA,EACF;AACF;AAEA,eAAe,sBAAsB,SAAuD;AAC1F,MAAI;AACF,UAAM,OAAO,IAAI,gBAAgB;AACjC,SAAK,IAAI,SAAS,gBAAgB;AAClC,SAAK,IAAI,YAAY,QAAQ;AAC7B,UAAM,gBAAgB,MAAM,MAAM,GAAG,OAAO,mBAAmB;AAAA,MAC7D,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,SAAS;AAAA,IACtB,CAAC;AAED,UAAM,UAAU,MAAM,cAAc,KAAK,EAAE,MAAM,MAAM,EAAE;AACzD,QAAI,QAAuB;AAC3B,QAAI,SAAS;AACX,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,OAAO;AACjC,gBAAQ,OAAO,OAAO,UAAU,YAAY,OAAO,MAAM,SAAS,IAAI,OAAO,QAAQ;AAAA,MACvF,QAAQ;AACN,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,QAAI,CAAC,cAAc,MAAM,CAAC,OAAO;AAC/B,aAAO;AAAA,QACL,aAAa,cAAc;AAAA,QAC3B,WAAW;AAAA,QACX,SAAS;AAAA,QACT,QAAQ,cAAc,KAClB,sDACA,iCAAiC,cAAc,MAAM;AAAA,MAC3D;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,MAAM,GAAG,OAAO,oCAAoC;AAAA,MAC5E,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,MAChC;AAAA,IACF,CAAC;AAED,UAAM,UAAU,YAAY,WAAW;AACvC,WAAO;AAAA,MACL,aAAa,cAAc;AAAA,MAC3B,WAAW,YAAY;AAAA,MACvB;AAAA,MACA,QAAQ,UACJ,yDACA,oDAAoD,YAAY,MAAM;AAAA,IAC5E;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO;AAAA,MACL,aAAa;AAAA,MACb,WAAW;AAAA,MACX,SAAS;AAAA,MACT,QAAQ,yCAAyC,OAAO;AAAA,IAC1D;AAAA,EACF;AACF;AAEA,eAAe,0BAA0B,SAA2D;AAClG,QAAM,CAAC,UAAU,SAAS,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC3D,eAAe,OAAO;AAAA,IACtB,0BAA0B,OAAO;AAAA,IACjC,sBAAsB,OAAO;AAAA,EAC/B,CAAC;AAED,SAAO;AAAA,IACL,OAAO,SAAS,WAAW,QAAQ,WAAW,cAAc;AAAA,IAC5D;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,gCAAgC,WAA8D;AAC3G,QAAM,MAAM,KAAK,QAAQ,uBAAuB,GAAG,EAAE,WAAW,KAAK,CAAC;AACtE,QAAM,oBAAoB,KAAK,IAAI,IAAI;AACvC,MAAI,gBAAgB;AAEpB,SAAO,MAAM;AACX,QAAI;AACF,YAAM,MAAM,uBAAuB;AACnC,YAAM,gBAAgB,KAAK,KAAK,yBAAyB,YAAY;AACrE,YAAM;AAAA,QACJ;AAAA,QACA,GAAG,KAAK,UAAU,EAAE,KAAK,QAAQ,KAAK,QAAQ,WAAW,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,GAAG,MAAM,CAAC,CAAC;AAAA;AAAA,QACzG;AAAA,MACF;AACA,aAAO;AAAA,QACL,SAAS,YAAY;AACnB,gBAAM,GAAG,yBAAyB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,QACpE;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAK,MAAgC,SAAS,UAAU;AACtD,cAAM;AAAA,MACR;AACA,UAAI,MAAM,mCAAmC,SAAS,GAAG;AACvD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,wBAAwB,oBAAoB,KAAK,IAAI;AAC3D,QAAI,yBAAyB,GAAG;AAC9B,YAAM,IAAI;AAAA,QACR,mBAAmB,gCAAgC,GAAI,qDAAqD,uBAAuB;AAAA,MACrI;AAAA,IACF;AAEA,QAAI,CAAC,eAAe;AAClB,cAAQ,IAAI,IAAI,SAAS,gFAAgF;AACzG,sBAAgB;AAAA,IAClB;AACA,UAAM,MAAM,KAAK,IAAI,4BAA4B,qBAAqB,CAAC;AAAA,EACzE;AACF;AAEA,SAAS,iBAAiB,WAA4B;AACpD,MAAI;AACF,YAAQ,KAAK,WAAW,CAAC;AACzB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAQ,MAAgC,SAAS;AAAA,EACnD;AACF;AAEA,eAAe,uBAAuB,YAA4C;AAChF,MAAI;AACF,UAAM,QAAQ,MAAM,KAAK,UAAU;AACnC,WAAO,KAAK,IAAI,IAAI,MAAM;AAAA,EAC5B,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,mCAAmC,WAAqC;AACrF,QAAM,gBAAgB,KAAK,KAAK,yBAAyB,YAAY;AACrE,MAAI,WAA0B;AAE9B,MAAI,kBAAkB;AACtB,MAAI;AACF,UAAM,cAAc,MAAM,SAAS,eAAe,MAAM;AACxD,UAAM,SAAS,KAAK,MAAM,WAAW;AACrC,QAAI,OAAO,OAAO,QAAQ,YAAY,OAAO,UAAU,OAAO,GAAG,KAAK,OAAO,MAAM,GAAG;AACpF,iBAAW,OAAO;AAAA,IACpB;AAAA,EACF,QAAQ;AACN,sBAAkB;AAAA,EACpB;AAEA,MAAI,aAAa,MAAM;AACrB,UAAM,UAAU,MAAM,uBAAuB,uBAAuB;AACpE,QAAI,YAAY,MAAM;AACpB,aAAO;AAAA,IACT;AACA,QAAI,mBAAmB,UAAU,+BAA+B;AAC9D,YAAM,GAAG,yBAAyB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAClE,cAAQ,IAAI,IAAI,SAAS,yEAAyE;AAClG,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,QAAQ,GAAG;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,GAAG,yBAAyB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAClE,UAAQ,IAAI,IAAI,SAAS,kEAAkE,QAAQ,GAAG;AACtG,SAAO;AACT;AAaA,eAAe,8BAA8B,UAA6D;AACxG,QAAM,YAAY,KAAK,KAAK,UAAU,YAAY;AAClD,MAAI,cAAc;AAClB,MAAI;AACF,kBAAc,MAAM,SAAS,WAAW,MAAM;AAAA,EAChD,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AAEA,MAAI,SAAkB;AACtB,MAAI;AACF,aAAS,KAAK,MAAM,WAAW;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS;AACf,MAAI,OAAO,OAAO,QAAQ,YAAY,CAAC,OAAO,UAAU,OAAO,GAAG,KAAK,OAAO,MAAM,GAAG;AACrF,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,KAAK,OAAO;AAAA,IACZ,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AAAA,IAC5D,YAAY,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa;AAAA,EAC1E;AACF;AAEA,eAAe,+BACb,WACA,SACkB;AAClB,QAAM,QAAQ,MAAM,8BAA8B,QAAQ,QAAQ;AAClE,QAAM,UAAU,MAAM,uBAAuB,QAAQ,QAAQ;AAC7D,MAAI,CAAC,OAAO;AACV,QAAI,YAAY,QAAQ,UAAU,+BAA+B;AAC/D,YAAM,GAAG,QAAQ,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC3D,cAAQ,IAAI,IAAI,SAAS,qEAAqE;AAC9F,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,iBAAiB,MAAM,GAAG,GAAG;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,GAAG,QAAQ,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC3D,UAAQ,IAAI,IAAI,SAAS,8DAA8D,MAAM,GAAG,GAAG;AACnG,SAAO;AACT;AAEA,eAAsB,4BACpB,WACA,UAAuC,CAAC,GACG;AAC3C,QAAM,kBAAyD;AAAA,IAC7D,UAAU,QAAQ,YAAY;AAAA,IAC9B,kBAAkB,QAAQ,oBAAoB;AAAA,EAChD;AAEA,QAAM,MAAM,KAAK,QAAQ,gBAAgB,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAEvE,MAAI;AACF,UAAM,MAAM,gBAAgB,QAAQ;AAAA,EACtC,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,YAAM;AAAA,IACR;AAEA,QAAI,MAAM,+BAA+B,WAAW,eAAe,GAAG;AACpE,aAAO,4BAA4B,WAAW,eAAe;AAAA,IAC/D;AAEA,UAAM,QAAQ,MAAM,8BAA8B,gBAAgB,QAAQ;AAC1E,UAAM,cAAc,OAAO,SAAS,gBAAgB,MAAM,MAAM,MAAM;AACtE,UAAM,WAAW,OAAO,MAAM,SAAS,MAAM,GAAG,MAAM;AACtD,UAAM,IAAI;AAAA,MACR,IAAI,SAAS,oDAAoD,WAAW,GAAG,QAAQ;AAAA,IACzF;AAAA,EACF;AAEA,QAAM,YAAY,KAAK,KAAK,gBAAgB,UAAU,YAAY;AAClE,QAAM;AAAA,IACJ;AAAA,IACA,GAAG,KAAK,UAAU,EAAE,KAAK,QAAQ,KAAK,QAAQ,WAAW,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,GAAG,MAAM,CAAC,CAAC;AAAA;AAAA,IACzG;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,YAAY;AACnB,YAAM,GAAG,gBAAgB,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACrE;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,SAAiB,oBAAgD;AACjG,QAAM,wBAAwB,QAAQ,IAAI,gCAAgC;AAC1E,SAAO,iBAAiB;AAAA,IACtB,UAAU;AAAA,IACV,SAAS;AAAA,IACT,qBAAqB;AAAA,IACrB,UAAU;AAAA,IACV,YAAY,QAAQ,IAAI,cAAc;AAAA,IACtC,8BAA8B,QAAQ,IAAI,gCAAgC;AAAA,IAC1E,qBAAqB;AAAA,IACrB,8BAA8B;AAAA,IAC9B,kCAAkC,QAAQ,IAAI,oCAAoC;AAAA,IAClF,uCAAuC,QAAQ,IAAI,yCAAyC;AAAA,IAC5F,cAAc;AAAA,IACd,8BAA8B;AAAA,IAC9B,gCAAgC,QAAQ,IAAI,kCAAkC;AAAA,IAC9E,uBAAuB;AAAA,IACvB,6BAA6B;AAAA,IAC7B,6BAA6B;AAAA,IAC7B,kDAAkD;AAAA,IAClD,2BAA2B;AAAA,IAC3B,IAAI;AAAA,IACJ,qCAAqC,QAAQ,IAAI,uCAAuC;AAAA,IACxF,cAAc;AAAA,IACd,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,wBAAwB,qBAAqB,MAAM;AAAA,EACrD,CAAC;AACH;AAEA,eAAsB,4BAA4B,SAA8E;AAC9H,QAAM,QAAQ,MAAM,8BAA8B;AAClD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,0BAA0B,MAAM,WAAW,QAAQ,wBAAwB;AACrF,YAAQ;AAAA,MACN,IAAI,QAAQ,SAAS,4CAA4C,MAAM,MAAM,8BAA8B,QAAQ,sBAAsB;AAAA,IAC3I;AACA,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,MAAM,yBAAyB,MAAM,OAAO;AAChE,MAAI,aAAa;AACf,YAAQ,IAAI,IAAI,QAAQ,SAAS,2CAA2C,uBAAuB,GAAG;AACtG,UAAM,+BAA+B;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,4BAA4B,QAAQ,SAAS;AACrE,QAAM,cAAc,KAAK,MAAM,MAAM,SAAS;AAC9C,MAAI,OAAO,SAAS,WAAW,GAAG;AAChC,UAAM,wBAAwB,KAAK,OAAO,KAAK,IAAI,IAAI,eAAe,GAAI;AAC1E,QAAI,wBAAwB,iBAAiB;AAC3C,cAAQ;AAAA,QACN,IAAI,QAAQ,SAAS,uCAAuC,qBAAqB,oBAAoB,uBAAuB,IAAI,eAAe;AAAA,MACjJ;AACA,YAAM,+BAA+B;AACrC,aAAO;AAAA,IACT;AAEA,UAAM,0BAA0B,MAAM,0BAA0B,WAAW;AAC3E,QAAI,yBAAyB;AAC3B,cAAQ;AAAA,QACN,IAAI,QAAQ,SAAS;AAAA,MACvB;AACA,YAAM,+BAA+B;AACrC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,QAAQ,uBAAuB,MAAM,oBAAoB;AAC3D,YAAQ;AAAA,MACN,IAAI,QAAQ,SAAS,6CAA6C,uBAAuB,KAAK,MAAM,qBAAqB,YAAY,UAAU;AAAA,IACjJ;AAAA,EACF;AACA,UAAQ,IAAI,IAAI,QAAQ,SAAS,+CAA+C,MAAM,OAAO,GAAG;AAChG,SAAO;AAAA,IACL,SAAS,MAAM;AAAA,IACf,MAAM,MAAM;AAAA,IACZ,aAAa;AAAA,IACb,oBAAoB,yBAAyB,MAAM,SAAS,MAAM,kBAAkB;AAAA,IACpF,uBAAuB;AAAA,IACvB,MAAM,YAAY;AAAA,IAAC;AAAA,EACrB;AACF;AAEA,eAAe,4BACb,SACA,YACA,SACe;AACf,QAAM,iBAAiB,KAAK,IAAI;AAChC,QAAM,cAAc,sBAAsB,UAAU;AACpD,QAAM,2BAA2B;AACjC,MAAI,YAAoD;AAExD,SAAO,KAAK,IAAI,IAAI,iBAAiB,QAAQ,WAAW;AACtD,UAAM,SAAS,MAAM,QAAQ,KAAK;AAAA,MAChC,0BAA0B,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,MAAM,SAAkB,MAAM,EAAE;AAAA,MACtF,YAAY,KAAK,CAAC,UAAU,EAAE,MAAM,QAAiB,KAAK,EAAE;AAAA,MAC5D,MAAM,qBAAqB,EAAE,KAAK,OAAO,EAAE,MAAM,UAAmB,EAAE;AAAA,IACxE,CAAC;AAED,QAAI,OAAO,SAAS,SAAS;AAC3B,kBAAY,OAAO;AACnB,UAAI,CAAC,OAAO,MAAM,OAAO;AACvB;AAAA,MACF;AACA,YAAM,gBAAgB,MAAM,QAAQ,KAAK;AAAA,QACvC,YAAY,KAAK,MAAM,IAAI;AAAA,QAC3B,MAAM,wBAAwB,EAAE,KAAK,MAAM,KAAK;AAAA,MAClD,CAAC;AACD,UAAI,eAAe;AACjB,cAAM,IAAI,MAAM,+DAA+D;AAAA,MACjF;AACA;AAAA,IACF;AACA,QAAI,OAAO,SAAS,QAAQ;AAC1B,YAAM,IAAI,MAAM,2DAA2D,OAAO,QAAQ,SAAS,GAAG;AAAA,IACxG;AAAA,EACF;AAEA,QAAM,qBAAqB,WAAW,SAAS,UAAU;AACzD,QAAM,oBAAoB,WAAW,QAAQ,UAAU;AACvD,QAAM,0BAA0B,WAAW,cAAc,UAAU;AACnE,QAAM,IAAI;AAAA,IACR,2CAA2C,QAAQ,YAAY,GAAI,yBACpD,kBAAkB,KAAK,iBAAiB,KAAK,uBAAuB;AAAA,EACrF;AACF;AAEO,SAAS,aAAa,SAAuC;AAClE,MAAI,OAAO;AACX,MAAI,SAAwB;AAC5B,MAAI,qBAAqC;AACzC,MAAI,UAAU;AACd,MAAI,eAAe;AACnB,MAAI,gBAAgB;AAEpB,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GAAG;AACtD,UAAM,WAAW,QAAQ,KAAK;AAC9B,QAAI,aAAa,UAAU;AACzB,aAAO;AACP;AAAA,IACF;AACA,QAAI,aAAa,iBAAiB;AAChC,2BAAqB;AACrB;AAAA,IACF;AACA,QAAI,aAAa,oBAAoB;AACnC,2BAAqB;AACrB;AAAA,IACF;AACA,QAAI,aAAa,aAAa;AAC5B,gBAAU;AACV;AAAA,IACF;AACA,QAAI,aAAa,mBAAmB;AAClC,qBAAe;AACf;AAAA,IACF;AACA,QAAI,aAAa,kBAAkB;AACjC,sBAAgB;AAChB;AAAA,IACF;AACA,QAAI,aAAa,YAAY;AAC3B,YAAM,YAAY,QAAQ,QAAQ,CAAC;AACnC,UAAI,CAAC,aAAa,UAAU,WAAW,IAAI,GAAG;AAC5C,cAAM,IAAI,MAAM,4BAA4B;AAAA,MAC9C;AACA,eAAS;AACT,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,WAAW,WAAW,GAAG;AACpC,YAAM,cAAc,SAAS,MAAM,YAAY,MAAM,EAAE,KAAK;AAC5D,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI,MAAM,4BAA4B;AAAA,MAC9C;AACA,eAAS;AACT;AAAA,IACF;AACA,QAAI,CAAC,SAAS,WAAW,IAAI,KAAK,CAAC,QAAQ;AACzC,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,WAAW,IAAI,GAAG;AAC7B,YAAM,IAAI,MAAM,mBAAmB,QAAQ,EAAE;AAAA,IAC/C;AAAA,EACF;AAEA,QAAM,4BAA4B,QAAQ,IAAI,OAAO;AACrD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,oBAAoB,sBAAsB;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,yBAAyB,SAAwC;AAC/E,MAAI,UAAU;AACd,MAAI,qBAAqC;AACzC,MAAI,eAAe;AACnB,MAAI,gBAAgB;AAEpB,aAAW,YAAY,SAAS;AAC9B,QAAI,aAAa,aAAa;AAC5B,gBAAU;AACV;AAAA,IACF;AACA,QAAI,aAAa,iBAAiB;AAChC,2BAAqB;AACrB;AAAA,IACF;AACA,QAAI,aAAa,oBAAoB;AACnC,2BAAqB;AACrB;AAAA,IACF;AACA,QAAI,aAAa,mBAAmB;AAClC,qBAAe;AACf;AAAA,IACF;AACA,QAAI,aAAa,kBAAkB;AACjC,sBAAgB;AAChB;AAAA,IACF;AACA,UAAM,IAAI,MAAM,mBAAmB,QAAQ,EAAE;AAAA,EAC/C;AAEA,QAAM,4BAA4B,QAAQ,IAAI,OAAO;AACrD,SAAO;AAAA,IACL;AAAA,IACA,oBAAoB,sBAAsB;AAAA,IAC1C;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,mCAAmC,SAAkD;AACnG,MAAI,UAAU;AACd,MAAI,qBAAqC;AACzC,MAAI,UAAyB;AAC7B,MAAI,UAAyB;AAC7B,MAAI,eAAe;AACnB,MAAI,gBAAgB;AAEpB,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GAAG;AACtD,UAAM,WAAW,QAAQ,KAAK;AAC9B,QAAI,aAAa,aAAa;AAC5B,gBAAU;AACV;AAAA,IACF;AACA,QAAI,aAAa,iBAAiB;AAChC,2BAAqB;AACrB;AAAA,IACF;AACA,QAAI,aAAa,oBAAoB;AACnC,2BAAqB;AACrB;AAAA,IACF;AACA,QAAI,aAAa,mBAAmB;AAClC,qBAAe;AACf;AAAA,IACF;AACA,QAAI,aAAa,kBAAkB;AACjC,sBAAgB;AAChB;AAAA,IACF;AACA,QAAI,aAAa,aAAa;AAC5B,YAAM,QAAQ,QAAQ,QAAQ,CAAC;AAC/B,UAAI,CAAC,SAAS,MAAM,WAAW,IAAI,GAAG;AACpC,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AACA,YAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,UAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,cAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,MACrD;AACA,gBAAU;AACV,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,WAAW,YAAY,GAAG;AACrC,YAAM,QAAQ,SAAS,MAAM,aAAa,MAAM;AAChD,YAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,UAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,cAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,MACrD;AACA,gBAAU;AACV;AAAA,IACF;AACA,QAAI,aAAa,aAAa;AAC5B,YAAM,QAAQ,QAAQ,QAAQ,CAAC;AAC/B,UAAI,CAAC,SAAS,MAAM,WAAW,IAAI,GAAG;AACpC,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AACA,YAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,UAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,cAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,MACrD;AACA,gBAAU;AACV,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,WAAW,YAAY,GAAG;AACrC,YAAM,QAAQ,SAAS,MAAM,aAAa,MAAM;AAChD,YAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,UAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,cAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,MACrD;AACA,gBAAU;AACV;AAAA,IACF;AACA,UAAM,IAAI,MAAM,mBAAmB,QAAQ,EAAE;AAAA,EAC/C;AAEA,QAAM,4BAA4B,QAAQ,IAAI,OAAO;AACrD,SAAO;AAAA,IACL;AAAA,IACA,oBAAoB,sBAAsB;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,gCAAgC,SAA+C;AAC7F,MAAI,SAAwB;AAC5B,MAAI,qBAAqC;AACzC,MAAI,UAAU;AACd,MAAI,UAAyB;AAC7B,MAAI,UAAyB;AAC7B,MAAI,QAAuB;AAC3B,MAAI,OAAO;AACX,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,gBAAgB;AAEpB,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GAAG;AACtD,UAAM,WAAW,QAAQ,KAAK;AAC9B,QAAI,aAAa,YAAY;AAC3B,YAAM,YAAY,QAAQ,QAAQ,CAAC;AACnC,UAAI,CAAC,aAAa,UAAU,WAAW,IAAI,GAAG;AAC5C,cAAM,IAAI,MAAM,4BAA4B;AAAA,MAC9C;AACA,eAAS;AACT,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,WAAW,WAAW,GAAG;AACpC,YAAM,cAAc,SAAS,MAAM,YAAY,MAAM,EAAE,KAAK;AAC5D,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI,MAAM,4BAA4B;AAAA,MAC9C;AACA,eAAS;AACT;AAAA,IACF;AACA,QAAI,CAAC,SAAS,WAAW,IAAI,KAAK,CAAC,QAAQ;AACzC,eAAS;AACT;AAAA,IACF;AACA,QAAI,aAAa,aAAa;AAC5B,gBAAU;AACV;AAAA,IACF;AACA,QAAI,aAAa,iBAAiB;AAChC,2BAAqB;AACrB;AAAA,IACF;AACA,QAAI,aAAa,oBAAoB;AACnC,2BAAqB;AACrB;AAAA,IACF;AACA,QAAI,aAAa,aAAa;AAC5B,YAAM,QAAQ,QAAQ,QAAQ,CAAC;AAC/B,UAAI,CAAC,SAAS,MAAM,WAAW,IAAI,GAAG;AACpC,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AACA,YAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,UAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,cAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,MACrD;AACA,gBAAU;AACV,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,WAAW,YAAY,GAAG;AACrC,YAAM,QAAQ,SAAS,MAAM,aAAa,MAAM;AAChD,YAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,UAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,cAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,MACrD;AACA,gBAAU;AACV;AAAA,IACF;AACA,QAAI,aAAa,aAAa;AAC5B,YAAM,QAAQ,QAAQ,QAAQ,CAAC;AAC/B,UAAI,CAAC,SAAS,MAAM,WAAW,IAAI,GAAG;AACpC,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AACA,YAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,UAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,cAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,MACrD;AACA,gBAAU;AACV,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,WAAW,YAAY,GAAG;AACrC,YAAM,QAAQ,SAAS,MAAM,aAAa,MAAM;AAChD,YAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,UAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,cAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,MACrD;AACA,gBAAU;AACV;AAAA,IACF;AACA,QAAI,aAAa,WAAW;AAC1B,YAAM,QAAQ,QAAQ,QAAQ,CAAC;AAC/B,UAAI,CAAC,SAAS,MAAM,WAAW,IAAI,GAAG;AACpC,cAAM,IAAI,MAAM,2BAA2B;AAAA,MAC7C;AACA,UAAI,CAAC,aAAa,KAAK,KAAK,GAAG;AAC7B,cAAM,IAAI,MAAM,0BAA0B,KAAK,wBAAwB;AAAA,MACzE;AACA,cAAQ;AACR,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,WAAW,UAAU,GAAG;AACnC,YAAM,QAAQ,SAAS,MAAM,WAAW,MAAM;AAC9C,UAAI,CAAC,aAAa,KAAK,KAAK,GAAG;AAC7B,cAAM,IAAI,MAAM,0BAA0B,KAAK,wBAAwB;AAAA,MACzE;AACA,cAAQ;AACR;AAAA,IACF;AACA,QAAI,aAAa,UAAU;AACzB,aAAO;AACP;AAAA,IACF;AACA,QAAI,aAAa,iBAAiB;AAChC,kBAAY;AACZ;AAAA,IACF;AACA,QAAI,aAAa,mBAAmB;AAClC,qBAAe;AACf;AAAA,IACF;AACA,QAAI,aAAa,kBAAkB;AACjC,sBAAgB;AAChB;AAAA,IACF;AACA,UAAM,IAAI,MAAM,mBAAmB,QAAQ,EAAE;AAAA,EAC/C;AAEA,QAAM,4BAA4B,QAAQ,IAAI,OAAO;AACrD,SAAO;AAAA,IACL;AAAA,IACA,oBAAoB,sBAAsB;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,oCAAoC,SAAmD;AAC9F,MAAI,OAAO;AACX,MAAI,SAAS;AACb,aAAW,YAAY,SAAS;AAC9B,QAAI,aAAa,UAAU;AACzB,aAAO;AACP;AAAA,IACF;AACA,QAAI,aAAa,YAAY;AAC3B,eAAS;AACT;AAAA,IACF;AACA,UAAM,IAAI,MAAM,mBAAmB,QAAQ,EAAE;AAAA,EAC/C;AACA,SAAO,EAAE,MAAM,OAAO;AACxB;AAEA,SAAS,cAAc,UAA0B;AAC/C,SAAO,SAAS,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AAC1C;AAEA,eAAe,+BAAyE;AACtF,SAAO,mCAAmC,sBAAsB,4BAA4B;AAC9F;AAEA,eAAe,uBAAuB,cAAuC;AAC3E,QAAM,eAAe,KAAK,KAAK,sBAAsB,YAAY;AACjE,MAAI;AACF,UAAM,SAAS,MAAM,SAAS,cAAc,MAAM;AAClD,UAAM,qBAAqB,OAAO,MAAM,wCAAwC;AAChF,QAAI,qBAAqB,CAAC,GAAG;AAC3B,aAAO,mBAAmB,CAAC,EAAE,KAAK;AAAA,IACpC;AACA,UAAM,qBAAqB,OAAO,MAAM,+BAA+B;AACvE,QAAI,qBAAqB,CAAC,GAAG;AAC3B,aAAO,mBAAmB,CAAC,EAAE,KAAK;AAAA,IACpC;AAAA,EACF,QAAQ;AACN,WAAO,KAAK,SAAS,cAAc,UAAU;AAAA,EAC/C;AACA,SAAO,KAAK,SAAS,cAAc,UAAU;AAC/C;AAEA,eAAe,2BAA6D;AAC1E,QAAM,kBAAkB,MAAM,6BAA6B;AAC3D,QAAM,cAAc,gBAAgB,IAAI,CAAC,UAAU,MAAM,IAAI;AAC7D,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,YAAY,IAAI,OAAO,cAAc;AAAA,MACnC,MAAM;AAAA,MACN,aAAa,MAAM,uBAAuB,QAAQ;AAAA,IACpD,EAAE;AAAA,EACJ;AACA,SAAO;AACT;AAEA,eAAe,wBACb,eACA,WACA,UACmB;AACnB,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,QAAQ,eAAe,EAAE,eAAe,KAAK,CAAC;AAAA,EAChE,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,aAAO,CAAC;AAAA,IACV;AACA,UAAM;AAAA,EACR;AACA,QAAM,YAAsB,CAAC;AAC7B,aAAW,SAAS,SAAS;AAC3B,UAAM,eAAe,KAAK,KAAK,eAAe,MAAM,IAAI;AACxD,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,cAAc,MAAM,wBAAwB,cAAc,WAAW,QAAQ;AACnF,gBAAU,KAAK,GAAG,WAAW;AAC7B;AAAA,IACF;AACA,QAAI,CAAC,MAAM,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,SAAS,GAAG;AACtD;AAAA,IACF;AACA,UAAM,eAAe,KAAK,SAAS,UAAU,YAAY;AACzD,cAAU,KAAK,cAAc,YAAY,CAAC;AAAA,EAC5C;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAA8B;AACvD,QAAM,QAAQ,MAAM,MAAM,sBAAsB;AAChD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,WAAW,MAAM,CAAC,GAAG,YAAY;AACvC,QAAM,WAAW,MAAM,CAAC;AACxB,MAAI,CAAC,YAAY,CAAC,UAAU;AAC1B,WAAO;AAAA,EACT;AACA,SAAO,MAAM,QAAQ,IAAI,QAAQ;AACnC;AAEA,SAAS,0BAA0B,cAA8B;AAC/D,QAAM,aAAa,cAAc,YAAY;AAC7C,QAAM,SAAS,GAAG,cAAc,KAAK,SAAS,sBAAsB,4BAA4B,CAAC,CAAC;AAClG,QAAM,cAAc,WAAW,QAAQ,MAAM;AAC7C,MAAI,gBAAgB,IAAI;AACtB,WAAO;AAAA,EACT;AACA,QAAM,WAAW,WAAW,MAAM,cAAc,OAAO,MAAM;AAC7D,SAAO,SAAS,MAAM,GAAG,EAAE,CAAC,KAAK;AACnC;AAEA,SAAS,8BAA8B,QAA+B;AACpE,QAAM,QAAQ,OAAO,MAAM,qBAAqB;AAChD,SAAO,QAAQ,CAAC,KAAK;AACvB;AAEA,SAAS,eAAe,WAAmB,aAA6B;AACtE,MAAI,eAAe,GAAG;AACpB,WAAO;AAAA,EACT;AACA,SAAO,KAAK,MAAO,YAAY,cAAe,GAAK,IAAI;AACzD;AAEA,SAAS,cAAc,OAA8B;AACnD,MAAI,UAAU,MAAM;AAClB,WAAO;AAAA,EACT;AACA,SAAO,GAAG,MAAM,QAAQ,CAAC,CAAC;AAC5B;AAEA,eAAsB,iCAAiC,SAAkC;AACvF,QAAM,UAAU,oCAAoC,OAAO;AAC3D,QAAM,eAAe,KAAK,KAAK,sBAAsB,OAAO,MAAM,WAAW;AAC7E,QAAM,aAAa,MAAM,6BAA6B,GAAG,IAAI,CAAC,UAAU,MAAM,IAAI;AAClF,QAAM,gBAAgB,MAAM,wBAAwB,cAAc,OAAO,oBAAoB;AAC7F,QAAM,iBAAiB,MAAM,8BAA8B;AAE3D,QAAM,cAAc,oBAAI,IAAY;AACpC,QAAM,kBAAkB,oBAAI,IAAY;AACxC,QAAM,gBAAgB,oBAAI,IAAoB;AAE9C,aAAW,YAAY,WAAW;AAChC,UAAM,SAAS,kBAAkB,KAAK,SAAS,QAAQ,CAAC;AACxD,UAAM,eAAe,SAAS,8BAA8B,MAAM,IAAI;AACtE,QAAI,QAAQ;AACV,kBAAY,IAAI,MAAM;AAAA,IACxB;AACA,UAAM,SAAS,eACX,OAAO,QAAQ,uBAAuB,EAAE,KAAK,CAAC,CAAC,EAAE,kBAAkB,MAAM,uBAAuB,YAAY,IAAI,CAAC,IACjH,0BAA0B,QAAQ;AACtC,QAAI,QAAQ;AACV,oBAAc,IAAI,SAAS,cAAc,IAAI,MAAM,KAAK,KAAK,CAAC;AAAA,IAChE;AAAA,EACF;AAEA,aAAW,gBAAgB,eAAe;AACxC,UAAM,SAAS,kBAAkB,KAAK,SAAS,YAAY,CAAC;AAC5D,QAAI,QAAQ;AACV,sBAAgB,IAAI,MAAM;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,qBAAqB,MAAM,KAAK,eAAe,EAAE,OAAO,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AACzF,QAAM,uBAAuB,MAAM,KAAK,eAAe,EACpD,OAAO,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,EACnC,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC;AAClD,QAAM,0BAA0B,MAAM,KAAK,WAAW,EACnD,OAAO,CAAC,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAAC,EACvC,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC;AAElD,QAAM,aAAa,oBAAI,IAAY;AACnC,aAAW,cAAc,iBAAiB;AACxC,UAAM,WAAW,8BAA8B,UAAU;AACzD,QAAI,UAAU;AACZ,iBAAW,IAAI,QAAQ;AAAA,IACzB;AAAA,EACF;AACA,aAAW,UAAU,aAAa;AAChC,UAAM,WAAW,8BAA8B,MAAM;AACrD,QAAI,UAAU;AACZ,iBAAW,IAAI,QAAQ;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,KAAK,UAAU,EACvC,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC,EAC/C,IAAI,CAAC,iBAAiB;AACrB,UAAM,gBAAgB,MAAM,KAAK,eAAe,EAAE,OAAO,CAAC,OAAO,GAAG,WAAW,MAAM,YAAY,GAAG,CAAC,EAAE;AACvG,UAAM,uBAAuB,mBAAmB,OAAO,CAAC,OAAO,GAAG,WAAW,MAAM,YAAY,GAAG,CAAC,EAAE;AACrG,UAAM,YAAY,MAAM,KAAK,WAAW,EAAE,OAAO,CAAC,OAAO,GAAG,WAAW,MAAM,YAAY,GAAG,CAAC,EAAE;AAC/F,UAAMC,mBAAkB,gBAAgB,IAAI,eAAe,sBAAsB,aAAa,IAAI;AAClG,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAAA;AAAA,IACF;AAAA,EACF,CAAC;AAEH,QAAM,yBAAyB,sBAAsB,OAAO,CAAC,YAAY,cAAc,IAAI,MAAM,KAAK,KAAK,CAAC;AAC5G,QAAM,yBAAyB,sBAAsB,OAAO,CAAC,YAAY,cAAc,IAAI,MAAM,KAAK,OAAO,CAAC;AAC9G,QAAM,kBAAkB,eAAe,mBAAmB,QAAQ,gBAAgB,IAAI;AAEtF,QAAM,SAAoC;AAAA,IACxC,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,SAAS;AAAA,IACT,WAAW;AAAA,MACT,OAAO,gBAAgB;AAAA,MACvB,SAAS,mBAAmB;AAAA,MAC5B,WAAW,qBAAqB;AAAA,MAChC;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,OAAO,YAAY;AAAA,MACnB,cAAc,YAAY,OAAO,wBAAwB;AAAA,MACzD,iBAAiB,wBAAwB;AAAA,IAC3C;AAAA,IACA,YAAY;AAAA,IACZ,qBAAqB;AAAA,MACnB,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,QAAQ,MAAM;AAChB,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,OAAO;AACL,YAAQ,IAAI,6CAA6C;AACzD,YAAQ,IAAI,4BAA4B,OAAO,WAAW,EAAE;AAC5D,iCAA6B,OAAO,OAAO;AAC3C,YAAQ;AAAA,MACN,iCAAiC,OAAO,UAAU,OAAO,IAAI,OAAO,UAAU,KAAK,KAAK,cAAc,OAAO,UAAU,eAAe,CAAC;AAAA,IACzI;AACA,YAAQ,IAAI,gCAAgC,OAAO,MAAM,KAAK,EAAE;AAChE,YAAQ,IAAI,yCAAyC,OAAO,MAAM,YAAY,EAAE;AAChF,YAAQ,IAAI,uCAAuC,OAAO,MAAM,eAAe,EAAE;AACjF,YAAQ;AAAA,MACN,2CAA2C,OAAO,oBAAoB,QAAQ,MAAM,IAAI,sBAAsB,MAAM,KAAK,OAAO,oBAAoB,QAAQ,KAAK,IAAI,KAAK,GAAG;AAAA,IAC/K;AACA,QAAI,OAAO,oBAAoB,QAAQ,SAAS,GAAG;AACjD,cAAQ,IAAI,wCAAwC,OAAO,oBAAoB,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,IACrG;AACA,YAAQ,IAAI,gCAAgC;AAC5C,eAAW,YAAY,OAAO,YAAY;AACxC,YAAM,SAAS,OAAO,QAAQ,uBAAuB,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,MAAM,SAAS,SAAS,IAAI,IAAI,CAAC;AACrG,YAAM,cAAc,SAAS,KAAK,MAAM,MAAM;AAC9C,cAAQ;AAAA,QACN,OAAO,SAAS,IAAI,GAAG,WAAW,eAAe,SAAS,oBAAoB,IAAI,SAAS,aAAa,WAAW,SAAS,SAAS,cAAc,cAAc,SAAS,eAAe,CAAC;AAAA,MAC5L;AAAA,IACF;AACA,QAAI,OAAO,qBAAqB,SAAS,GAAG;AAC1C,cAAQ,IAAI,wDAAwD;AACpE,iBAAW,cAAc,OAAO,sBAAsB;AACpD,gBAAQ,IAAI,OAAO,UAAU,EAAE;AAAA,MACjC;AAAA,IACF;AACA,QAAI,OAAO,wBAAwB,SAAS,GAAG;AAC7C,cAAQ,IAAI,mDAAmD;AAC/D,iBAAW,UAAU,OAAO,yBAAyB;AACnD,gBAAQ,IAAI,OAAO,MAAM,EAAE;AAAA,MAC7B;AAAA,IACF;AACA,wCAAoC,OAAO,OAAO;AAAA,EACpD;AAEA,MAAI,QAAQ,WAAW,OAAO,qBAAqB,SAAS,KAAK,OAAO,oBAAoB,QAAQ,SAAS,IAAI;AAC/G,UAAM,IAAI;AAAA,MACR,6DAA6D,OAAO,qBAAqB,MAAM,8BAA8B,OAAO,oBAAoB,QAAQ,MAAM;AAAA,IACxK;AAAA,EACF;AACF;AAEA,eAAe,eAAe,eAAsC;AAClE,QAAM,GAAG,eAAe,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACxD,QAAM,MAAM,eAAe,EAAE,WAAW,KAAK,CAAC;AAChD;AAEA,SAAS,mBAAsE;AAC7E,QAAM,eAAe,KAAK,KAAK,sBAAsB,OAAO,MAAM,gBAAgB,YAAY,QAAQ;AACtG,QAAM,kBAAkB,KAAK,KAAK,sBAAsB,OAAO,MAAM,gBAAgB,YAAY,MAAM;AACvG,SAAO,EAAE,cAAc,gBAAgB;AACzC;AAEA,eAAe,yBAAyB,aAAgC,cAAsB,iBAAwC;AACpI,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,cAAc,QAAQ,WAAW;AACzC;AAEA,SAAS,eAAe,OAAkD;AACxE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,mBAAmB,QAAiC,KAA4B;AACvF,QAAM,QAAQ,OAAO,GAAG;AACxB,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,QAAiC,KAA4B;AACvF,QAAM,QAAQ,OAAO,GAAG;AACxB,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,eAAe,gCAA2E;AACxF,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,SAAS,8BAA8B,MAAM;AAAA,EAClE,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,UAAU;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,eAAe,MAAM,GAAG;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,OAAO;AAC1B,MAAI,CAAC,eAAe,UAAU,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,mBAAmB,YAAY,UAAU,KAAK;AAC7D,QAAM,SAAS,mBAAmB,YAAY,YAAY,KAAK;AAC/D,QAAM,QAAQ,mBAAmB,YAAY,OAAO,KAAK;AACzD,QAAM,UAAU,mBAAmB,YAAY,SAAS,KAAK;AAE7D,SAAO;AAAA,IACL,QAAQ,SAAS,IAAI,WAAW;AAAA,IAChC,OAAO,SAAS,SAAS,QAAQ;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,mBAAmB,YAAY,UAAU;AAAA,IACrD,WAAW,mBAAmB,YAAY,WAAW;AAAA,EACvD;AACF;AAEA,SAAS,6BAA6B,SAAiD;AACrF,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAI,wGAAwG;AACpH;AAAA,EACF;AACA,UAAQ,IAAI,sCAAsC;AAClD,UAAQ,IAAI,aAAa,QAAQ,MAAM,EAAE;AACzC,UAAQ,IAAI,aAAa,QAAQ,MAAM,EAAE;AACzC,UAAQ,IAAI,aAAa,QAAQ,MAAM,EAAE;AACzC,UAAQ,IAAI,YAAY,QAAQ,KAAK,EAAE;AACvC,UAAQ,IAAI,cAAc,QAAQ,OAAO,EAAE;AAC3C,UAAQ,IAAI,YAAY,QAAQ,KAAK,EAAE;AACzC;AAEA,SAAS,oCAAoC,SAAiD;AAC5F,MAAI,CAAC,SAAS;AACZ;AAAA,EACF;AACA,UAAQ;AAAA,IACN,uCAAuC,QAAQ,MAAM,YAAY,QAAQ,MAAM,WAAW,QAAQ,KAAK,aAAa,QAAQ,OAAO,WAAW,QAAQ,KAAK;AAAA,EAC7J;AACF;AAEA,eAAsB,6BAA6B,SAAkC;AACnF,QAAM,UAAU,gCAAgC,OAAO;AACvD,QAAM,gBAAgB,iBAAiB;AACvC,QAAM,eAAe,cAAc,YAAY;AAC/C,QAAM,eAAe,cAAc,eAAe;AAElD,QAAM,eAAwC;AAAA,IAC5C,SAAS,QAAQ;AAAA,IACjB,oBAAoB,QAAQ;AAAA,IAC5B,cAAc,QAAQ;AAAA,IACtB,eAAe,QAAQ;AAAA,IACvB,WAAW;AAAA,IACX,sBAAsB;AAAA,MACpB,kBAAkB,cAAc;AAAA,IAClC;AAAA,EACF;AAEA,MAAI,eAA6B;AACjC,QAAM,qBAAqB,OAAOC,iBAAmE;AACnG,YAAQ,IAAI,6EAA6E;AACzF,YAAQ,IAAI,yDAAyD;AACrE,UAAM,cAAc,CAAC,cAAc,WAAW,UAAU,GAAGA,aAAY,kBAAkB;AACzF,QAAI;AACF,YAAM;AAAA,QACJA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,UACE,SAAS,QAAQ;AAAA,UACjB,oBAAoB,QAAQ;AAAA,UAC5B,SAAS,QAAQ;AAAA,UACjB,SAAS,QAAQ;AAAA,UACjB,OAAO,QAAQ;AAAA,QACjB;AAAA,MACF;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,mBAAmB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACjF,UAAI,8BAA8B,gBAAgB,GAAG;AACnD,gBAAQ,MAAM,kGAAkG;AAAA,MAClH;AACA,cAAQ,MAAM,qCAAqC,iBAAiB,OAAO,EAAE;AAC7E,cAAQ,MAAM,6EAA6E;AAC3F,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,cAAc,MAAM,0BAA0B,YAAY;AAC9D,MAAI;AACF,mBAAe,MAAM,mBAAmB,WAAW;AACnD,QAAI,gBAAgB,8BAA8B,YAAY,GAAG;AAC/D,cAAQ,IAAI,+EAA+E;AAC3F,YAAM,YAAY,KAAK;AACvB,oBAAc,MAAM,0BAA0B,YAAY;AAC1D,qBAAe,MAAM,mBAAmB,WAAW;AAAA,IACrD;AAAA,EACF,UAAE;AACA,UAAM,YAAY,KAAK;AAAA,EACzB;AAEA,UAAQ,IAAI,+CAA+C;AAC3D,MAAI,sBAAoC;AACxC,MAAI;AACF,UAAM,yBAAyB,YAAY,oBAAoB,cAAc,cAAc,cAAc,eAAe;AAAA,EAC1H,SAAS,OAAO;AACd,0BAAsB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,EAChF;AAEA,MAAI,qBAAqB;AACvB,QAAI,CAAC,QAAQ,WAAW;AACtB,YAAM,GAAG,cAAc,cAAc,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACvE;AACA,UAAM;AAAA,EACR;AAEA,QAAM,cAAc,KAAK,KAAK,cAAc,iBAAiB,uBAAuB;AACpF,QAAM,aAAa,MAAM,SAAS,aAAa,MAAM;AACrD,QAAM,UAAU,KAAK,MAAM,UAAU;AAQrC,QAAM,SAAS,QAAQ,SAAS,CAAC;AACjC,QAAM,iBAAiB,MAAM,8BAA8B;AAC3D,QAAMH,UAAS;AAAA,IACb,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,iBAAiB,cAAc,KAAK,SAAS,sBAAsB,cAAc,eAAe,CAAC;AAAA,IACjG,sBAAsB,cAAc,KAAK,SAAS,sBAAsB,cAAc,YAAY,CAAC;AAAA,IACnG,SAAS;AAAA,IACT,QAAQ;AAAA,MACN,OAAO,OAAO,SAAS;AAAA,MACvB,YAAY,OAAO,cAAc;AAAA,MACjC,WAAW,OAAO,aAAa;AAAA,MAC/B,UAAU,OAAO,YAAY;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,UAAUA,QAAO,OAAO,OAAO,OAAO;AAC5C,QAAM,eAAeA,QAAO,OAAO,YAAY,OAAO;AACtD,QAAM,cAAcA,QAAO,OAAO,WAAW,OAAO;AACpD,QAAM,YAAYA,QAAO,OAAO,UAAU,OAAO;AACjD,QAAM,cAAcA,QAAO,OAAO,OAAO,WAAW;AACpD,QAAM,YAAYA,QAAO,OAAO,OAAO,SAAS;AAChD,QAAM,mBAAmBA,QAAO,OAAO,YAAY,WAAW;AAC9D,QAAM,iBAAiBA,QAAO,OAAO,YAAY,SAAS;AAC1D,QAAM,kBAAkBA,QAAO,OAAO,WAAW,WAAW;AAC5D,QAAM,gBAAgBA,QAAO,OAAO,WAAW,SAAS;AACxD,QAAM,gBAAgBA,QAAO,OAAO,UAAU,WAAW;AACzD,QAAM,cAAcA,QAAO,OAAO,UAAU,SAAS;AAErD,MAAI,CAAC,QAAQ,WAAW;AACtB,UAAM,GAAG,cAAc,cAAc,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACvE;AAEA,UAAQ,IAAI,6BAA6B;AACzC,UAAQ,IAAI,YAAY,WAAW,IAAI,SAAS,KAAK,OAAO,IAAI;AAChE,UAAQ,IAAI,iBAAiB,gBAAgB,IAAI,cAAc,KAAK,YAAY,IAAI;AACpF,UAAQ,IAAI,gBAAgB,eAAe,IAAI,aAAa,KAAK,WAAW,IAAI;AAChF,UAAQ,IAAI,eAAe,aAAa,IAAI,WAAW,KAAK,SAAS,IAAI;AACzE,+BAA6BA,QAAO,OAAO;AAC3C,UAAQ,IAAI,2BAA2BA,QAAO,eAAe,aAAa;AAE1E,MAAI,QAAQ,MAAM;AAChB,YAAQ,IAAI,KAAK,UAAUA,SAAQ,MAAM,CAAC,CAAC;AAC3C,QAAI,cAAc;AAChB,YAAM;AAAA,IACR;AACA;AAAA,EACF;AAEA,UAAQ,IAAI,2CAA2C,OAAO,iBAAiB,YAAY,gBAAgB,WAAW,eAAe,SAAS,GAAG;AACjJ,sCAAoCA,QAAO,OAAO;AAClD,UAAQ,IAAI,wGAAwG;AAEpH,MAAI,cAAc;AAChB,UAAM;AAAA,EACR;AACF;AAEA,eAAe,uBACb,aACA,WACA,SACe;AACf,QAAM,OAAO,CAAC,cAAc,QAAQ,YAAY,kCAAkC;AAClF,MAAI,QAAQ,YAAY,MAAM;AAC5B,SAAK,KAAK,aAAa,OAAO,QAAQ,OAAO,CAAC;AAAA,EAChD;AACA,MAAI,QAAQ,YAAY,MAAM;AAC5B,SAAK,KAAK,aAAa,OAAO,QAAQ,OAAO,CAAC;AAAA,EAChD;AACA,MAAI,QAAQ,OAAO;AACjB,SAAK,KAAK,WAAW,QAAQ,KAAK;AAAA,EACpC;AACA,MAAI,MAAM,QAAQ,SAAS,KAAK,UAAU,SAAS,GAAG;AACpD,SAAK,KAAK,GAAG,SAAS;AAAA,EACxB,WAAW,OAAO,cAAc,YAAY,UAAU,SAAS,GAAG;AAChE,SAAK,KAAK,SAAS;AAAA,EACrB;AACA,QAAM,kCAAkC,MAAM,YAAY,oBAAoB;AAAA,IAC5E,8BAA8B;AAAA,IAC9B,+BAA+B;AAAA,IAC/B,8BAA8B;AAAA,MAC5B,SAAS,YAAY;AAAA,IACvB;AAAA,EACF,CAAC;AACH;AAOA,eAAe,4BACb,aACA,SACe;AACf,QAAM,WAAW,CAAC,kBAAkB;AACpC,MAAI,QAAQ,QAAQ;AAClB,aAAS,KAAK,QAAQ,MAAM;AAAA,EAC9B;AACA,QAAM,mCAAmC,UAAU,YAAY,oBAAoB;AAAA,IACjF,8BAA8B;AAAA,IAC9B,+BAA+B;AAAA,IAC/B,8BAA8B;AAAA,MAC5B,SAAS,YAAY;AAAA,IACvB;AAAA,EACF,CAAC;AACH;AAEA,eAAe,yBAAyB,SAAmC;AACzE,QAAM,YAAY,MAAM,0BAA0B,OAAO;AACzD,SAAO,CAAC,UAAU;AACpB;AAEA,SAAS,8BAA8B,OAAyB;AAC9D,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO;AAAA,EACT;AACA,SAAQ,MAAkC,qCAAqC;AACjF;AAEA,SAAS,eAAe,OAAuB;AAC7C,SAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACjE;AAEA,eAAe,0BACb,aACA,oBACA,wBACuB;AACvB,MAAI;AACF,UAAM,uBAAuB,WAAW;AACxC,UAAM,4BAA4B,aAAa,kBAAkB;AACjE,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,eAAe,KAAK;AAAA,EAC7B;AACF;AAEA,eAAe,yBACb,OACA,SACwD;AACxD,QAAM,aAAa,8BAA8B,KAAK;AACtD,MAAI,YAAY;AACd,WAAO,EAAE,aAAa,MAAM,YAAY,KAAK;AAAA,EAC/C;AACA,SAAO;AAAA,IACL,aAAa,MAAM,yBAAyB,OAAO;AAAA,IACnD,YAAY;AAAA,EACd;AACF;AAEA,eAAe,oCACb,cACA,oBACA,wBAIC;AACD,MAAI,cAAc,MAAM,0BAA0B;AAAA,IAChD,GAAG;AAAA,IACH,WAAW;AAAA,EACb,CAAC;AAED,QAAM,oBAAoB,MAAM,0BAA0B,aAAa,oBAAoB,sBAAsB;AACjH,MAAI,CAAC,mBAAmB;AACtB,WAAO,EAAE,aAAa,eAAe,EAAE,SAAS,OAAO,OAAO,KAAK,EAAE;AAAA,EACvE;AAEA,QAAM,UAAU,MAAM,yBAAyB,mBAAmB,YAAY,OAAO;AACrF,MAAI,CAAC,QAAQ,aAAa;AACxB,WAAO,EAAE,aAAa,eAAe,EAAE,SAAS,OAAO,OAAO,kBAAkB,EAAE;AAAA,EACpF;AAEA,MAAI,QAAQ,YAAY;AACtB,YAAQ,MAAM,+FAA+F;AAAA,EAC/G;AACA,UAAQ,MAAM,kGAAkG;AAChH,UAAQ,MAAM,qEAAqE;AAEnF,MAAI;AACF,UAAM,YAAY,KAAK;AAAA,EACzB,SAAS,WAAW;AAClB,YAAQ,MAAM,0EAA0E,eAAe,SAAS,EAAE,OAAO,EAAE;AAAA,EAC7H;AAEA,gBAAc,MAAM,0BAA0B;AAAA,IAC5C,GAAG;AAAA,IACH,WAAW;AAAA,EACb,CAAC;AACD,QAAM,aAAa,MAAM,0BAA0B,aAAa,oBAAoB,sBAAsB;AAC1G,SAAO;AAAA,IACL;AAAA,IACA,eAAe;AAAA,MACb,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAe,0BAA0B,aAAwD;AAC/F,QAAM,cAAc,CAAC,cAAc,eAAe,0BAA0B,GAAG,YAAY,kBAAkB;AAC/G;AAEA,eAAe,eACb,IACA,aAC0B;AAC1B,QAAM,kBACJ,MAAM,GAAG;AAAA,IACP;AAAA,EACF,GAEC,KAAK,EACL,YAAY;AAEf,MAAI,mBAAmB,KAAK;AAC1B,YAAQ,IAAI,gDAAyC;AACrD,QAAI;AACF,YAAM,0BAA0B,WAAW;AAAA,IAC7C,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,cAAQ,MAAM,+CAA0C,OAAO,EAAE;AAAA,IACnE;AACA,WAAO;AAAA,EACT;AAEA,MAAI,mBAAmB,KAAK;AAC1B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAsB,0BAA0B,SAAuE;AACrH,sBAAoB;AAGpB,QAAM,eAAe,MAAM,6BAA6B,QAAQ,SAAS;AACzE,MAAI,cAAc;AAChB,YAAQ,IAAI,cAAc,aAAa;AACvC,YAAQ,IAAI,wCAAwC,aAAa;AAAA,EACnE;AAEA,QAAM,gCAAgC;AAEtC,QAAM,YAAY,MAAM,gCAAgC,QAAQ,SAAS;AACzE,MAAI;AACF,UAAM,kCAAkC,MAAM,8BAA8B;AAC5E,QAAI,QAAQ,kBAAkB,OAAO;AACnC,cAAQ;AAAA,QACN,IAAI,QAAQ,SAAS;AAAA,MACvB;AAAA,IACF;AACA,QAAI,QAAQ,kBAAkB,OAAO;AACnC,YAAM,sBAAsB,MAAM,4BAA4B,OAAO;AACrE,UAAI,qBAAqB;AACvB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,wBAAwB,yCAAyC;AAAA,MACrE,eAAe,QAAQ;AAAA,MACvB;AAAA,IACF,CAAC;AACD,UAAM,kBAAkB,wBACpB,MAAM,YAAY,IAClB,MAAM,iBAAiB,0BAA0B;AACrD,QAAI,QAAQ,kBAAkB,OAAO;AACnC,cAAQ;AAAA,QACN,IAAI,QAAQ,SAAS,0DAA0D,eAAe;AAAA,MAChG;AAAA,IACF,WAAW,uBAAuB;AAChC,cAAQ;AAAA,QACN,IAAI,QAAQ,SAAS,oGAAoG,eAAe;AAAA,MAC1I;AAAA,IACF;AACA,UAAM,qBAAqB,oBAAoB,eAAe;AAC9D,UAAM,eAAe;AACrB,UAAM,eAAe;AACrB,UAAM,mBAAmB;AAEzB,UAAM,oBAAoB,MAAM,IAAI,iBAAiB,aAAa,EAC/D,gBAAgB;AAAA,MACf,aAAa;AAAA,MACb,eAAe;AAAA,MACf,mBAAmB;AAAA,IACrB,CAAC,EACA,iBAAiB,IAAI,EACrB,MAAM;AAET,UAAM,eAAe,kBAAkB,QAAQ;AAC/C,UAAM,eAAe,kBAAkB,cAAc,IAAI;AACzD,UAAM,cAAc,cAAc,YAAY,IAAI,gBAAgB,IAAI,YAAY,IAAI,YAAY,IAAI,YAAY;AAClH,UAAM,GAAG,yBAAyB,EAAE,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM,MAAS;AACxE,UAAM,GAAG,0BAA0B,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM,MAAS;AAC1F,UAAM,wBAAwB,QAAQ,IAAI,gCAAgC;AAC1E,UAAM,qBAAqB,iBAAiB;AAAA,MAC1C,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,MACnB,UAAU;AAAA,MACV,SAAS;AAAA,MACT,qBAAqB;AAAA,MACrB,YAAY,QAAQ,IAAI,cAAc;AAAA,MACtC,8BAA8B,QAAQ,IAAI,gCAAgC;AAAA,MAC1E,UAAU;AAAA,MACV,aAAa;AAAA,MACb,aAAa;AAAA,MACb,sBAAsB;AAAA,MACtB,yBAAyB;AAAA,MACzB,4BAA4B;AAAA,MAC5B,mCAAmC;AAAA,MACnC,qBAAqB;AAAA,MACrB,8BAA8B;AAAA,MAC9B,kCAAkC,QAAQ,IAAI,oCAAoC;AAAA,MAClF,uCAAuC,QAAQ,IAAI,yCAAyC;AAAA,MAC5F,cAAc;AAAA,MACd,8BAA8B;AAAA,MAC9B,2BAA2B;AAAA,MAC3B,gCAAgC,QAAQ,IAAI,kCAAkC;AAAA,MAC9E,uBAAuB;AAAA,MACvB,6BAA6B;AAAA,MAC7B,6BAA6B;AAAA,MAC7B,kDAAkD;AAAA,MAClD,2BAA2B;AAAA,MAC3B,IAAI;AAAA,MACJ,qCAAqC,QAAQ,IAAI,uCAAuC;AAAA,MACxF,oBAAoB;AAAA,MACpB,sBAAsB;AAAA,MACtB,cAAc;AAAA,MACd,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,MAAM,OAAO,eAAe;AAAA,MAC5B,wBAAwB,QAAQ,qBAAqB,MAAM;AAAA,MAC3D,GAAI,QAAQ,wBAAwB,CAAC;AAAA,IACvC,CAAC;AAED,UAAM,cAAc,MAAM,4BAA4B,QAAQ,SAAS;AACvE,QAAI,qBAA0C;AAC9C,QAAI,YAAY;AAChB,UAAM,OAAO,YAA2B;AACtC,UAAI,UAAW;AACf,kBAAY;AACZ,UAAI;AACF,YAAI,sBAAsB,CAAC,mBAAmB,QAAQ;AACpD,6BAAmB,KAAK,SAAS;AAAA,QACnC;AACA,cAAM,kBAAkB,KAAK;AAC7B,cAAM,+BAA+B;AAAA,MACvC,UAAE;AACA,cAAM,YAAY,QAAQ;AAAA,MAC5B;AAAA,IACF;AAEA,QAAI;AACF,YAAM,oBAAoB,yBAAyB,QAAQ,SAAS;AACpE,YAAM,uBAAuB,4BAA4B,QAAQ,SAAS;AAC1E,YAAM,yBAAyB,4BAA4B,kBAAkB;AAC7E,UAAI,yBAAwC;AAC5C,UAAI,aAAa;AACjB,UAAI,0BAA0B;AAE9B,UAAI;AACF,iCAAyB,MAAM,uBAAuB;AACtD,qBAAa,QAAQ,eACjB,OACA,MAAM,4BAA4B,sBAAsB,QAAQ,WAAW;AAAA,UACzE;AAAA,UACA,8BAA8B,0BAA0B;AAAA,QAC1D,CAAC;AAAA,MACP,SAAS,OAAO;AACd,cAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,kCAA0B;AAC1B,qBAAa;AACb,iCAAyB;AACzB,gBAAQ;AAAA,UACN,IAAI,QAAQ,SAAS,+BAA+B,OAAO;AAAA,QAC7D;AAAA,MACF;AAEA,cAAQ,IAAI,IAAI,QAAQ,SAAS,iCAAiC,YAAY,IAAI,YAAY,EAAE;AAChG,cAAQ,IAAI,IAAI,QAAQ,SAAS,0DAA0D;AAC3F,YAAM,aAAa,QAAQ,WAAW,iCAAiC,EAAE,iBAAiB,GAAG,GAAG,YAC9F,eAAe,CAAC,YAAY,GAAG,oBAAoB;AAAA,QACjD,QAAQ,CAAC,QAAQ;AAAA,MACnB,GAAG,YAAY,CAAC;AAElB,UAAI,CAAC,YAAY;AACf,gBAAQ;AAAA,UACN,IAAI,QAAQ,SAAS,+BAA+B,uBAAuB,IAAI,oBAAoB;AAAA,QACrG;AAAA,MACF,OAAO;AACL,YAAI,QAAQ,cAAc;AACxB,kBAAQ,IAAI,IAAI,QAAQ,SAAS,yDAAyD;AAAA,QAC5F,OAAO;AACL,kBAAQ,IAAI,IAAI,QAAQ,SAAS,yEAAyE;AAAA,QAC5G;AACA,YAAI,iCAAiC;AACnC,kBAAQ,IAAI,IAAI,QAAQ,SAAS,wBAAwB;AACzD,gBAAM,aAAa,QAAQ,WAAW,qBAAqB,EAAE,iBAAiB,GAAG,GAAG,YAClF,eAAe,CAAC,gBAAgB,GAAG,oBAAoB;AAAA,YACrD,QAAQ,CAAC,QAAQ;AAAA,UACnB,CAAC,CAAC;AAAA,QACN,OAAO;AACL,kBAAQ,IAAI,IAAI,QAAQ,SAAS,2EAA2E;AAAA,QAC9G;AAEA,gBAAQ,IAAI,IAAI,QAAQ,SAAS,oCAAoC;AACrE,cAAM,GAAG,2BAA2B;AAAA,UAClC,OAAO;AAAA,QACT,CAAC;AACD,cAAM,aAAa,QAAQ,WAAW,iCAAiC,EAAE,iBAAiB,EAAE,GAAG,YAC7F,eAAe,CAAC,UAAU,GAAG,oBAAoB;AAAA,UAC/C,QAAQ,CAAC,QAAQ;AAAA,QACnB,GAAG,YAAY,CAAC;AAElB,YAAI,iCAAiC;AACnC,kBAAQ,IAAI,IAAI,QAAQ,SAAS,2CAA2C;AAC5E,gBAAM,aAAa,QAAQ,WAAW,wCAAwC,EAAE,iBAAiB,GAAG,GAAG,YACrG,eAAe,CAAC,gBAAgB,GAAG,oBAAoB;AAAA,YACrD,QAAQ,CAAC,QAAQ;AAAA,UACnB,CAAC,CAAC;AAAA,QACN;AAEA,gBAAQ,IAAI,IAAI,QAAQ,SAAS,2BAA2B;AAC5D,cAAM,gCAAgC,QAAQ,SAAS;AACvD,cAAM,aAAa,QAAQ,WAAW,wBAAwB,EAAE,iBAAiB,GAAG,GAAG,YACrF,eAAe,CAAC,OAAO,GAAG,oBAAoB;AAAA,UAC5C,QAAQ,CAAC,QAAQ;AAAA,QACnB,GAAG,YAAY,CAAC;AAAA,MACpB;AAEA,UAAI,2BAA2B,wBAAwB;AACrD,cAAM,qBAAqB,wBAAwB,EAAE,uBAAuB,CAAC;AAAA,MAC/E;AAEA,cAAQ,IAAI,IAAI,QAAQ,SAAS,6BAA6B,kBAAkB,KAAK;AACrF,YAAM,oBAAoB,iBAAiB,CAAC,OAAO,GAAG,oBAAoB;AAAA,QACxE,QAAQ,CAAC,QAAQ;AAAA,MACnB,GAAG,YAAY;AACf,2BAAqB;AAErB,YAAM;AAAA,QACJ,QAAQ;AAAA,QACR;AAAA,QACA,EAAE,iBAAiB,KAAK,IAAI,IAAI,KAAK,KAAK,oBAAoB,GAAI,CAAC,EAAE;AAAA,QACrE,YACE,4BAA4B,oBAAoB,mBAAmB;AAAA,UACjE,WAAW;AAAA,QACb,CAAC;AAAA,MACL;AACA,cAAQ,IAAI,IAAI,QAAQ,SAAS,6BAA6B,kBAAkB,EAAE;AAClF,YAAM,+BAA+B;AAAA,QACnC,SAAS;AAAA,QACT,MAAM;AAAA,QACN,WAAW,QAAQ;AAAA,QACnB,oBAAoB,QAAQ;AAAA,MAC9B,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,uBAAuB;AAAA,QACvB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,KAAK;AACX,YAAM;AAAA,IACR;AAAA,EACF,UAAE;AACA,UAAM,UAAU,QAAQ;AAAA,EAC1B;AACF;AAEA,eAAe,8BAA8B,SAA0E;AACrH,QAAM,WAAW,OAAO,WAAkC;AACxD,YAAQ,IAAI,IAAI,QAAQ,SAAS,cAAc,MAAM,qCAAqC;AAC1F,UAAM,QAAQ,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,KAAK,UAAU,MAAM,KAAK,SAAS,QAAQ,CAAC;AACpD,UAAQ,KAAK,WAAW,MAAM,KAAK,SAAS,SAAS,CAAC;AACtD,QAAM,IAAI,QAAc,MAAM;AAAA,EAAC,CAAC;AAClC;AAEA,eAAsB,0CAA0C,SAAkC;AAChG,QAAM,UAAU,aAAa,OAAO;AACpC,QAAM,eAAmH;AAAA,IACvH,SAAS,QAAQ;AAAA,IACjB,oBAAoB,QAAQ;AAAA,IAC5B,cAAc,QAAQ;AAAA,IACtB,eAAe,QAAQ;AAAA,EACzB;AACA,MAAI,cAAiD;AACrD,MAAI;AAEJ,MAAI;AACF,YAAQ,IAAI,2CAA2C;AACvD,QAAI,QAAQ,eAAe;AACzB,cAAQ,IAAI,mFAAmF;AAAA,IACjG,OAAO;AACL,cAAQ,IAAI,qFAAqF;AAAA,IACnG;AACA,UAAM,mBAAmB,MAAM;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,OAAO,uBAAuB;AAC5B,gBAAQ,IAAI,4DAA4D;AACxE,cAAM,cAAc,CAAC,cAAc,WAAW,UAAU,GAAG,mBAAmB,kBAAkB;AAAA,MAClG;AAAA,IACF;AACA,kBAAc,iBAAiB;AAC/B,oBAAgB,iBAAiB;AAEjC,QAAI,CAAC,YAAY,uBAAuB;AACtC,cAAQ,IAAI,oGAAoG;AAAA,IAClH;AACA,QAAI,cAAc,SAAS;AACzB,cAAQ,IAAI,iFAAiF;AAAA,IAC/F;AACA,UAAM,8BAA8B,YAAY,mBAAmB,2BAA2B;AAC9F,YAAQ;AAAA,MACN,uCAAuC,8BAA8B,YAAY,UAAU;AAAA,IAC7F;AAEA,QAAI,cAAc,OAAO;AACvB,YAAM,cAAc;AAAA,IACtB;AAEA,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,uFAAuF;AACnG,YAAM,8BAA8B;AAAA,QAClC,WAAW;AAAA,QACX,MAAM,YAAY;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF,UAAE;AACA,QAAI,CAAC,QAAQ,MAAM;AACjB,YAAM,aAAa,KAAK;AAAA,IAC1B;AAAA,EACF;AACF;AAEA,eAAsB,qBAAqB,SAAkC;AAC3E,QAAM,UAAU,yBAAyB,OAAO;AAChD,QAAM,cAAc,MAAM,0BAA0B;AAAA,IAClD,SAAS,QAAQ;AAAA,IACjB,oBAAoB,QAAQ;AAAA,IAC5B,cAAc,QAAQ;AAAA,IACtB,eAAe,QAAQ;AAAA,IACvB,WAAW;AAAA,EACb,CAAC;AAED,UAAQ,IAAI,2CAA2C,YAAY,OAAO,EAAE;AAC5E,UAAQ,IAAI,mGAAmG;AAC/G,UAAQ,IAAI,0DAA0D;AACtE,MAAI,YAAY,uBAAuB;AACrC,YAAQ,IAAI,mCAAmC;AAAA,EACjD,OAAO;AACL,YAAQ,IAAI,oGAAoG;AAAA,EAClH;AAEA,QAAM,8BAA8B;AAAA,IAClC,WAAW;AAAA,IACX,MAAM,YAAY;AAAA,EACpB,CAAC;AACH;AAEA,eAAsB,gDAAgD,SAAkC;AACtG,QAAM,UAAU,mCAAmC,OAAO;AAC1D,QAAM,cAAc,MAAM,0BAA0B;AAAA,IAClD,SAAS,QAAQ;AAAA,IACjB,oBAAoB,QAAQ;AAAA,IAC5B,cAAc,QAAQ;AAAA,IACtB,eAAe,QAAQ;AAAA,IACvB,WAAW;AAAA,EACb,CAAC;AAED,QAAM,KAAK,gBAAgB,EAAE,OAAO,OAAO,CAAC;AAC5C,MAAI,YAAY,MAAM,yBAAyB;AAC/C,MAAI,eAAe;AAEnB,UAAQ,IAAI,iDAA0C;AACtD,MAAI,CAAC,YAAY,uBAAuB;AACtC,YAAQ,IAAI,sFAA+E;AAAA,EAC7F;AACA,UAAQ,IAAI,2CAAoC,YAAY,OAAO,EAAE;AACrE,UAAQ,IAAI,mKAAyJ;AAErK,MAAI;AACF,WAAO,MAAM;AACX,YAAM,mBAAmB,aAAa,KAAK,EAAE,YAAY;AACzD,YAAM,iBAAiB,iBAAiB,WAAW,IAC/C,YACA,UAAU,OAAO,CAAC,WAAW;AAC3B,cAAM,WAAW,GAAG,OAAO,IAAI,IAAI,OAAO,WAAW,GAAG,YAAY;AACpE,eAAO,SAAS,SAAS,gBAAgB;AAAA,MAC3C,CAAC;AAEL,cAAQ,IAAI,8CAAuC;AACnD,UAAI,iBAAiB,SAAS,GAAG;AAC/B,gBAAQ,IAAI,wBAAiB,YAAY,MAAM,eAAe,MAAM,IAAI,UAAU,MAAM,GAAG;AAAA,MAC7F;AACA,UAAI,iBAAiB,SAAS,GAAG;AAC/B,gBAAQ,IAAI,gCAAgC,eAAe,MAAM,GAAG;AAAA,MACtE,OAAO;AACL,gBAAQ,IAAI,oBAAoB;AAAA,MAClC;AACA,qBAAe,QAAQ,CAAC,QAAQ,UAAU;AACxC,gBAAQ,IAAI,KAAK,QAAQ,CAAC,KAAK,OAAO,IAAI,MAAM,OAAO,WAAW,EAAE;AAAA,MACtE,CAAC;AACD,cAAQ,IAAI,uBAAuB;AACnC,cAAQ,IAAI,mBAAmB;AAC/B,cAAQ,IAAI,wBAAwB;AACpC,cAAQ,IAAI,WAAW;AAEvB,YAAM,aAAa,MAAM,GAAG,SAAS,2CAAoC,GAAG,KAAK;AACjF,UAAI,CAAC,WAAW;AACd;AAAA,MACF;AAEA,YAAM,mBAAmB,UAAU,YAAY;AAC/C,UAAI,qBAAqB,KAAK;AAC5B;AAAA,MACF;AACA,UAAI,qBAAqB,KAAK;AAC5B,oBAAY,MAAM,yBAAyB;AAC3C,YAAI,aAAa,KAAK,EAAE,SAAS,GAAG;AAClC,kBAAQ,IAAI,gDAAyC,UAAU,MAAM,4BAA4B,YAAY,IAAI;AAAA,QACnH,OAAO;AACL,kBAAQ,IAAI,gDAAyC,UAAU,MAAM,UAAU;AAAA,QACjF;AACA;AAAA,MACF;AACA,UAAI,qBAAqB,KAAK;AAC5B,uBAAe;AACf,gBAAQ,IAAI,yCAAkC;AAC9C,gBAAQ,IAAI,gDAAyC,UAAU,MAAM,UAAU;AAC/E;AAAA,MACF;AACA,UAAI,qBAAqB,KAAK;AAC5B,gBAAQ,IAAI,gDAAyC;AACrD,YAAI;AACF,gBAAM,0BAA0B,WAAW;AAAA,QAC7C,SAAS,OAAO;AACd,gBAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,kBAAQ,MAAM,+CAA0C,OAAO,EAAE;AAAA,QACnE;AACA;AAAA,MACF;AAEA,YAAM,cAAc,OAAO,SAAS,WAAW,EAAE;AACjD,UAAI,CAAC,OAAO,SAAS,WAAW,KAAK,cAAc,GAAG;AACpD,uBAAe;AACf,cAAM,gBAAgB,UAAU,OAAO,CAAC,WAAW;AACjD,gBAAM,WAAW,GAAG,OAAO,IAAI,IAAI,OAAO,WAAW,GAAG,YAAY;AACpE,iBAAO,SAAS,SAAS,aAAa,KAAK,EAAE,YAAY,CAAC;AAAA,QAC5D,CAAC,EAAE;AACH,YAAI,kBAAkB,GAAG;AACvB,kBAAQ,MAAM,uDAA6C,YAAY,IAAI;AAAA,QAC7E,OAAO;AACL,kBAAQ,IAAI,6CAAsC,YAAY,MAAM,aAAa,YAAY;AAAA,QAC/F;AACA;AAAA,MACF;AAEA,UAAI,gBAAgB,GAAG;AACrB,YAAI,iBAAiB,SAAS,GAAG;AAC/B,cAAI,eAAe,WAAW,GAAG;AAC/B,oBAAQ,MAAM,uDAA6C,YAAY,IAAI;AAC3E;AAAA,UACF;AACA,kBAAQ;AAAA,YACN,mCAA4B,eAAe,MAAM,0BAA0B,YAAY;AAAA,UACzF;AACA,cAAI;AACF,kBAAM;AAAA,cACJ;AAAA,cACA,eAAe,IAAI,CAAC,WAAW,OAAO,IAAI;AAAA,cAC1C;AAAA,YACF;AAAA,UACF,SAAS,OAAO;AACd,kBAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,oBAAQ,MAAM,yCAAoC,OAAO,EAAE;AAAA,UAC7D;AAAA,QACF,OAAO;AACL,kBAAQ,IAAI,2DAAoD;AAChE,cAAI;AACF,kBAAM,uBAAuB,aAAa,MAAM,OAAO;AAAA,UACzD,SAAS,OAAO;AACd,kBAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,oBAAQ,MAAM,yCAAoC,OAAO,EAAE;AAAA,UAC7D;AAAA,QACF;AACA,cAAMI,cAAa,MAAM,eAAe,IAAI,WAAW;AACvD,YAAIA,gBAAe,QAAQ;AACzB;AAAA,QACF;AACA;AAAA,MACF;AAEA,YAAM,iBAAiB,eAAe,cAAc,CAAC;AACrD,UAAI,CAAC,gBAAgB;AACnB,gBAAQ,MAAM,sDAA4C,WAAW,EAAE;AACvE;AAAA,MACF;AAEA,cAAQ,IAAI,mCAA4B,eAAe,IAAI,KAAK;AAChE,UAAI;AACF,cAAM,uBAAuB,aAAa,eAAe,MAAM,OAAO;AAAA,MACxE,SAAS,OAAO;AACd,cAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,gBAAQ,MAAM,yCAAoC,OAAO,EAAE;AAAA,MAC7D;AACA,YAAM,aAAa,MAAM,eAAe,IAAI,WAAW;AACvD,UAAI,eAAe,QAAQ;AACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF,UAAE;AACA,OAAG,MAAM;AACT,UAAM,YAAY,KAAK;AAAA,EACzB;AACF;",
4
+ "sourcesContent": ["import { GenericContainer } from 'testcontainers'\nimport type { ChildProcess, StdioOptions } from 'node:child_process'\nimport { createServer } from 'node:net'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { mkdir, readdir, readFile, rm, stat, writeFile } from 'node:fs/promises'\nimport { createHash } from 'node:crypto'\nimport path from 'node:path'\nimport { createInterface, type Interface } from 'node:readline/promises'\nimport { stdin as input, stdout as output } from 'node:process'\nimport spawn from 'cross-spawn'\nimport { resolveEnvironment } from '../resolver'\nimport { resolveSpawnCommand } from '../spawn'\nimport { discoverIntegrationSpecFiles as discoverIntegrationSpecFilesShared } from './integration-discovery'\nimport { resolveDockerHostFromContext, runCommandAndCapture } from './runtime-utils'\n\ntype EphemeralRuntimeOptions = {\n verbose: boolean\n captureScreenshots: boolean\n logPrefix: string\n forceRebuild?: boolean\n reuseExisting?: boolean\n requiredExistingSource?: string\n environmentOverrides?: NodeJS.ProcessEnv\n}\n\nexport type EphemeralEnvironmentHandle = {\n baseUrl: string\n port: number\n databaseUrl: string\n commandEnvironment: NodeJS.ProcessEnv\n ownedByCurrentProcess: boolean\n stop: () => Promise<void>\n}\n\ntype IntegrationOptions = {\n keep: boolean\n filter: string | null\n captureScreenshots: boolean\n verbose: boolean\n forceRebuild: boolean\n reuseExisting: boolean\n}\n\ntype EphemeralAppOptions = {\n verbose: boolean\n captureScreenshots: boolean\n forceRebuild: boolean\n reuseExisting: boolean\n}\n\ntype InteractiveIntegrationOptions = {\n verbose: boolean\n captureScreenshots: boolean\n workers: number | null\n retries: number | null\n forceRebuild: boolean\n reuseExisting: boolean\n}\n\ntype IntegrationSpecTarget = {\n path: string\n description: string\n}\n\ntype DiscoveredIntegrationSpecFile = {\n path: string\n moduleName: string | null\n isOverlay: boolean\n requiredModules: string[]\n}\n\ntype IntegrationCoverageOptions = {\n filter: string | null\n captureScreenshots: boolean\n verbose: boolean\n workers: number | null\n retries: number | null\n shard: string | null\n json: boolean\n keepRawV8: boolean\n forceRebuild: boolean\n reuseExisting: boolean\n}\n\ntype IntegrationSpecCoverageOptions = {\n json: boolean\n strict: boolean\n}\n\ntype IntegrationCoverageReport = {\n generatedAt: string\n testRun: IntegrationTestRunSummary | null\n scenarios: {\n total: number\n covered: number\n uncovered: number\n coveragePercent: number\n }\n tests: {\n total: number\n withScenario: number\n withoutScenario: number\n }\n categories: Array<{\n code: string\n scenarioCount: number\n coveredScenarioCount: number\n testCount: number\n coveragePercent: number | null\n }>\n requiredTestFolders: {\n present: string[]\n missing: string[]\n }\n uncoveredScenarioIds: string[]\n testsWithoutScenarioIds: string[]\n}\n\ntype IntegrationTestRunSummary = {\n status: 'passed' | 'failed'\n total: number\n passed: number\n failed: number\n flaky: number\n skipped: number\n durationMs: number | null\n startTime: string | null\n}\n\nexport function shouldUseIsolatedPortForFreshEnvironment(options: {\n reuseExisting: boolean | undefined\n existingStateBeforeReuseAttempt: EphemeralEnvironmentState | null\n}): boolean {\n return options.reuseExisting === false || options.existingStateBeforeReuseAttempt !== null\n}\n\ntype EphemeralEnvironmentState = {\n status: 'running'\n baseUrl: string\n port: number\n databaseUrl: string\n queueBaseDir: string\n source: string\n captureScreenshots: boolean\n startedAt: string\n}\n\ntype PlaywrightRunOptions = Pick<InteractiveIntegrationOptions, 'verbose' | 'captureScreenshots' | 'workers' | 'retries'> & {\n shard?: string | null\n}\n\nconst DEFAULT_APP_READY_TIMEOUT_MS = 90_000\nconst APP_READY_INTERVAL_MS = 1_000\nconst DEFAULT_EPHEMERAL_APP_PORT = 5001\nconst EPHEMERAL_ENV_LOCK_TIMEOUT_MS = 5 * 60_000\nconst EPHEMERAL_ENV_LOCK_POLL_MS = 500\nconst DEFAULT_BUILD_CACHE_TTL_SECONDS = 600\nconst APP_READY_TIMEOUT_ENV_VAR = 'OM_INTEGRATION_APP_READY_TIMEOUT_SECONDS'\nconst BUILD_CACHE_TTL_ENV_VAR = 'OM_INTEGRATION_BUILD_CACHE_TTL_SECONDS'\nconst PLAYWRIGHT_ENV_UNAVAILABLE_PATTERNS: RegExp[] = [\n /net::ERR_CONNECTION_REFUSED/i,\n /Failed to connect to .* (localhost|127\\.0\\.0\\.1)/i,\n /Error: connect ECONNREFUSED/i,\n /Error: read ECONNRESET/i,\n /socket hang up/i,\n /ERR_CONNECTION_RESET/i,\n /ERR_ADDRESS_UNREACHABLE/i,\n]\nconst PLAYWRIGHT_QUICK_FAILURE_THRESHOLD = 6\nconst PLAYWRIGHT_QUICK_FAILURE_MAX_DURATION_MS = 1_500\nconst PLAYWRIGHT_HEALTH_PROBE_INTERVAL_MS = 3_000\nconst ANSI_ESCAPE_REGEX = /\\x1b\\[[0-?]*[ -/]*[@-~]/g // NOSONAR \u2014 ANSI escape sequence pattern\nconst env = resolveEnvironment()\nconst projectRootDirectory = env.rootDir\nconst appDirectory = env.appDir\nconst corePackageRootDirectory = env.packageRoot('@open-mercato/core')\nconst uiPackageRootDirectory = env.packageRoot('@open-mercato/ui')\nconst EPHEMERAL_RUNTIME_LOCK_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-runtime.lock')\n\nfunction resolveFirstExistingPath(...candidates: string[]): string | null {\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n return null\n}\n\nfunction collectExistingPaths(candidates: Array<string | null | undefined>): string[] {\n const collected = new Set<string>()\n for (const candidate of candidates) {\n if (candidate && existsSync(candidate)) {\n collected.add(candidate)\n }\n }\n return Array.from(collected)\n}\n\nfunction readPackageScripts(packageRoot: string): Record<string, string> {\n try {\n const raw = JSON.parse(readFileSync(path.join(packageRoot, 'package.json'), 'utf8')) as {\n scripts?: Record<string, string>\n }\n return raw.scripts ?? {}\n } catch {\n return {}\n }\n}\n\nconst projectScripts = readPackageScripts(projectRootDirectory)\nconst appNextConfigPath = resolveFirstExistingPath(\n path.join(appDirectory, 'next.config.ts'),\n path.join(appDirectory, 'next.config.js'),\n path.join(appDirectory, 'next.config.mjs'),\n)\nconst APP_MODULES_CHECKSUM_PATH = path.join(appDirectory, '.mercato', 'generated', 'modules.generated.checksum')\nconst PROJECT_SUPPORTS_PACKAGE_BUILDS = typeof projectScripts['build:packages'] === 'string'\nconst EPHEMERAL_ENV_FILE_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.json')\nconst EPHEMERAL_ENV_LOCK_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.lock')\nconst LEGACY_EPHEMERAL_ENV_FILE_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.md')\nconst EPHEMERAL_BUILD_CACHE_STATE_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-build-cache.json')\nconst EPHEMERAL_CACHE_DB_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-cache.sqlite')\nconst EPHEMERAL_QUEUE_BASE_DIR = path.join(appDirectory, '.mercato', 'queue')\nconst PLAYWRIGHT_INTEGRATION_CONFIG_PATH = '.ai/qa/tests/playwright.config.ts'\nconst PLAYWRIGHT_RESULTS_JSON_PATH = path.join(projectRootDirectory, '.ai', 'qa', 'test-results', 'results.json')\nconst LEGACY_INTEGRATION_TEST_ROOT = path.join(projectRootDirectory, '.ai', 'qa', 'tests')\nconst NEXT_BUILD_OUTPUT_DIRECTORIES = [\n path.join(appDirectory, '.mercato', 'next'),\n path.join(appDirectory, '.next'),\n]\nconst APP_BUILD_ARTIFACTS = collectExistingPaths([\n path.join(appDirectory, '.mercato', 'next', 'BUILD_ID'),\n path.join(appDirectory, '.next', 'BUILD_ID'),\n path.join(appDirectory, '.mercato', 'generated', 'modules.generated.ts'),\n path.join(corePackageRootDirectory, 'dist', 'index.js'),\n path.join(uiPackageRootDirectory, 'dist', 'index.js'),\n])\nconst APP_BUILD_INPUT_PATHS = collectExistingPaths([\n path.join(appDirectory, 'src'),\n path.join(appDirectory, 'package.json'),\n appNextConfigPath,\n path.join(appDirectory, 'tsconfig.json'),\n resolveFirstExistingPath(path.join(corePackageRootDirectory, 'src'), path.join(corePackageRootDirectory, 'dist')),\n path.join(corePackageRootDirectory, 'package.json'),\n path.join(corePackageRootDirectory, 'tsconfig.json'),\n resolveFirstExistingPath(path.join(uiPackageRootDirectory, 'src'), path.join(uiPackageRootDirectory, 'dist')),\n path.join(uiPackageRootDirectory, 'package.json'),\n path.join(uiPackageRootDirectory, 'tsconfig.json'),\n path.join(projectRootDirectory, 'package.json'),\n path.join(projectRootDirectory, 'tsconfig.base.json'),\n path.join(projectRootDirectory, 'yarn.lock'),\n])\nconst EXPECTED_TEST_FOLDERS = ['auth', 'catalog', 'crm', 'sales', 'admin', 'api', 'integration'] as const\nconst FOLDER_TO_CATEGORY_CODE: Record<string, string> = {\n admin: 'ADMIN',\n auth: 'AUTH',\n catalog: 'CAT',\n crm: 'CRM',\n sales: 'SALES',\n api: 'API',\n integration: 'INT',\n}\nconst BUILD_CACHE_STATE_VERSION = 2\nconst BUILD_CACHE_ENV_KEYS = [\n 'NODE_ENV',\n 'OM_ENABLE_ENTERPRISE_MODULES',\n 'OM_ENABLE_ENTERPRISE_MODULES_SSO',\n 'OM_ENABLE_ENTERPRISE_MODULES_SECURITY',\n] as const\nconst IGNORED_EPHEMERAL_BUILD_CACHE_DIRS = new Set([\n 'node_modules',\n '.next',\n 'dist',\n '.turbo',\n '.yarn',\n '.cache',\n 'tmp',\n 'temp',\n 'coverage',\n '.git',\n '.ai',\n])\n\ntype BuildCacheState = {\n version: number\n builtAt: number\n sourceFingerprint: string\n environmentFingerprint: string\n artifactPaths: string[]\n projectRoot: string\n}\n\ntype BuildCacheOptions = {\n artifactPaths?: string[]\n inputPaths?: string[]\n cacheStatePath?: string\n projectRoot?: string\n precomputedSourceFingerprint?: string\n environmentFingerprint?: string\n}\n\ntype CommandOutputMonitoringResult = {\n exitCode: number | null\n output: string\n environmentUnavailableFromOutput: boolean\n}\n\ntype IntegrationCommandError = Error & {\n environmentUnavailableFromOutput?: boolean\n commandOutput?: string\n}\n\ntype CommandMonitoringOptions = {\n detectEnvironmentUnavailable?: boolean\n abortOnEnvironmentUnavailable?: boolean\n playwrightFailureHealthCheck?: PlaywrightFailureHealthCheckOptions\n}\n\ntype LoginPageProbeResult = {\n status: number | null\n healthy: boolean\n detail: string\n}\n\ntype BackendLoginProbeResult = {\n status: number | null\n healthy: boolean\n detail: string\n}\n\ntype AuthenticatedApiProbeResult = {\n loginStatus: number | null\n apiStatus: number | null\n healthy: boolean\n detail: string\n}\n\ntype ApplicationReadinessProbeResult = {\n ready: boolean\n frontend: LoginPageProbeResult\n backend: BackendLoginProbeResult\n authenticated: AuthenticatedApiProbeResult\n}\n\ntype PlaywrightFailureHealthCheckOptions = {\n baseUrl: string\n consecutiveFailureThreshold?: number\n quickFailureMaxDurationMs?: number\n minProbeIntervalMs?: number\n}\n\ntype TimedStepOptions = {\n expectedSeconds: number\n updateIntervalSeconds?: number\n}\n\nfunction resolveYarnBinary(): string {\n return process.platform === 'win32' ? 'yarn.cmd' : 'yarn'\n}\n\nfunction buildEnvironment(overrides: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n return {\n ...process.env,\n ...overrides,\n }\n}\n\nfunction buildEnvironmentFingerprint(environment: NodeJS.ProcessEnv): string {\n const publicKeys = Object.keys(environment)\n .filter((key) => key.startsWith('NEXT_PUBLIC_'))\n .sort((left, right) => left.localeCompare(right))\n const keys = Array.from(new Set([...BUILD_CACHE_ENV_KEYS, ...publicKeys]))\n const fingerprintParts = keys.map((key) => `${key}=${environment[key] ?? ''}`)\n return createHash('sha256').update(fingerprintParts.join('\\n'), 'utf8').digest('hex')\n}\n\nasync function resetNextBuildOutputDirectories(logPrefix: string): Promise<void> {\n for (const outputDirectory of NEXT_BUILD_OUTPUT_DIRECTORIES) {\n if (!existsSync(outputDirectory)) {\n continue\n }\n await rm(outputDirectory, { recursive: true, force: true })\n console.log(`[${logPrefix}] Reset Next build output directory at ${outputDirectory}.`)\n }\n}\n\nfunction runYarnCommand(\n args: string[],\n environment: NodeJS.ProcessEnv,\n opts: { silent?: boolean } = {},\n cwd: string = projectRootDirectory,\n): Promise<void> {\n return runYarnRawCommand(['run', ...args], environment, opts, cwd)\n}\n\nasync function runTimedStep<T>(\n logPrefix: string,\n label: string,\n options: TimedStepOptions,\n task: () => Promise<T>,\n): Promise<T> {\n const startedAt = Date.now()\n const intervalMs = Math.max(1, options.updateIntervalSeconds ?? 2) * 1000\n const timer = setInterval(() => {\n const elapsedSeconds = Math.max(1, Math.floor((Date.now() - startedAt) / 1000))\n const remainingSeconds = Math.max(0, options.expectedSeconds - elapsedSeconds)\n console.log(`[${logPrefix}] ${label}... ${elapsedSeconds}s elapsed, ~${remainingSeconds}s left`)\n }, intervalMs)\n\n try {\n const result = await task()\n const durationSeconds = Math.max(1, Math.floor((Date.now() - startedAt) / 1000))\n console.log(`[${logPrefix}] ${label} completed in ${durationSeconds}s.`)\n return result\n } finally {\n clearInterval(timer)\n }\n}\n\nfunction isPlaywrightEnvironmentUnavailableChunk(chunk: string): boolean {\n return PLAYWRIGHT_ENV_UNAVAILABLE_PATTERNS.some((pattern) => pattern.test(chunk))\n}\n\nfunction stripAnsiSequences(value: string): string {\n return value.replace(ANSI_ESCAPE_REGEX, '')\n}\n\nfunction parsePlaywrightResultLine(line: string): { kind: 'pass' | 'fail'; durationMs: number } | null {\n const normalized = line.trim()\n if (!normalized) {\n return null\n }\n\n const symbolMatch = normalized.match(/^\\s*([\u2713\u2714\u2718xX])\\s+\\d+\\s+/u)\n if (!symbolMatch) {\n return null\n }\n\n const durationMatches = Array.from(normalized.matchAll(/\\(([\\d.]+)(ms|s)\\)/g))\n const lastDurationMatch = durationMatches.at(-1)\n if (!lastDurationMatch) {\n return null\n }\n\n const symbol = symbolMatch[1]\n const rawDuration = Number.parseFloat(lastDurationMatch[1] ?? '')\n const unit = lastDurationMatch[2]\n if (!Number.isFinite(rawDuration) || rawDuration < 0) {\n return null\n }\n\n const durationMs = unit === 's' ? Math.round(rawDuration * 1000) : Math.round(rawDuration)\n return {\n kind: symbol === '\u2718' || symbol.toLowerCase() === 'x' ? 'fail' : 'pass',\n durationMs,\n }\n}\n\nasync function runCommandWithOutputMonitoring(\n command: string,\n commandArgs: string[],\n environment: NodeJS.ProcessEnv,\n opts: CommandMonitoringOptions = {},\n): Promise<CommandOutputMonitoringResult> {\n return new Promise((resolve, reject) => {\n const resolvedSpawn = resolveSpawnCommand(command, commandArgs)\n const commandHandle = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd: projectRootDirectory,\n env: environment,\n stdio: ['ignore', 'pipe', 'pipe'],\n ...resolvedSpawn.spawnOptions,\n })\n\n let output = ''\n let environmentUnavailableFromOutput = false\n let terminatedByOutput = false\n let trailingOutputLine = ''\n let consecutiveQuickFailures = 0\n let lastHealthProbeAt = 0\n let healthProbeQueue: Promise<void> = Promise.resolve()\n\n const failureHealthCheck = opts.playwrightFailureHealthCheck\n const quickFailureThreshold = failureHealthCheck?.consecutiveFailureThreshold ?? PLAYWRIGHT_QUICK_FAILURE_THRESHOLD\n const quickFailureMaxDurationMs = failureHealthCheck?.quickFailureMaxDurationMs ?? PLAYWRIGHT_QUICK_FAILURE_MAX_DURATION_MS\n const minProbeIntervalMs = failureHealthCheck?.minProbeIntervalMs ?? PLAYWRIGHT_HEALTH_PROBE_INTERVAL_MS\n\n const maybeProbeEnvironmentHealth = () => {\n if (!failureHealthCheck || terminatedByOutput || environmentUnavailableFromOutput) {\n return\n }\n if (consecutiveQuickFailures < quickFailureThreshold) {\n return\n }\n const now = Date.now()\n if (now - lastHealthProbeAt < minProbeIntervalMs) {\n return\n }\n lastHealthProbeAt = now\n healthProbeQueue = healthProbeQueue\n .then(async () => {\n const unavailable = await isEnvironmentUnavailable(failureHealthCheck.baseUrl)\n if (unavailable && !terminatedByOutput) {\n environmentUnavailableFromOutput = true\n terminatedByOutput = true\n commandHandle.kill('SIGTERM')\n }\n })\n .catch(() => undefined)\n }\n\n const processOutputLine = (line: string) => {\n const parsed = parsePlaywrightResultLine(line)\n if (!parsed) {\n return\n }\n if (parsed.kind === 'pass') {\n consecutiveQuickFailures = 0\n return\n }\n\n if (parsed.durationMs <= quickFailureMaxDurationMs) {\n consecutiveQuickFailures += 1\n maybeProbeEnvironmentHealth()\n return\n }\n\n consecutiveQuickFailures = 0\n }\n\n const handleChunk = (chunk: Buffer | string, stream: 'stdout' | 'stderr') => {\n const text = chunk.toString()\n const normalizedText = stripAnsiSequences(text)\n if (stream === 'stdout') {\n process.stdout.write(text)\n } else {\n process.stderr.write(text)\n }\n\n output += text\n if (output.length > 120_000) {\n output = output.slice(-80_000)\n }\n\n if (\n !environmentUnavailableFromOutput &&\n opts.detectEnvironmentUnavailable &&\n isPlaywrightEnvironmentUnavailableChunk(normalizedText)\n ) {\n environmentUnavailableFromOutput = true\n if (opts.abortOnEnvironmentUnavailable) {\n terminatedByOutput = true\n commandHandle.kill('SIGTERM')\n }\n }\n\n trailingOutputLine += normalizedText\n let newlineIndex = trailingOutputLine.indexOf('\\n')\n while (newlineIndex >= 0) {\n const currentLine = trailingOutputLine.slice(0, newlineIndex).replace(/\\r$/, '')\n processOutputLine(currentLine)\n trailingOutputLine = trailingOutputLine.slice(newlineIndex + 1)\n newlineIndex = trailingOutputLine.indexOf('\\n')\n }\n }\n\n commandHandle.stdout?.on('data', (chunk) => {\n handleChunk(chunk, 'stdout')\n })\n commandHandle.stderr?.on('data', (chunk) => {\n handleChunk(chunk, 'stderr')\n })\n commandHandle.on('error', reject)\n commandHandle.on('exit', (code: number | null) => {\n if (trailingOutputLine.trim().length > 0) {\n processOutputLine(trailingOutputLine.trimEnd())\n }\n healthProbeQueue.finally(() => {\n resolve({\n exitCode: code,\n output: output.trim(),\n environmentUnavailableFromOutput: environmentUnavailableFromOutput || terminatedByOutput,\n })\n })\n })\n })\n}\n\nfunction createMonitoredCommandError(\n commandLabel: string,\n args: string[],\n result: CommandOutputMonitoringResult,\n): IntegrationCommandError {\n const error = new Error(\n `Command failed: ${commandLabel} ${args.join(' ')} (exit ${result.exitCode ?? 'unknown'}).`,\n ) as IntegrationCommandError\n error.environmentUnavailableFromOutput = result.environmentUnavailableFromOutput\n error.commandOutput = result.output\n return error\n}\n\nasync function runYarnCommandWithOutputMonitoring(\n args: string[],\n environment: NodeJS.ProcessEnv,\n opts: CommandMonitoringOptions = {},\n): Promise<void> {\n const result = await runCommandWithOutputMonitoring(resolveYarnBinary(), ['run', ...args], environment, {\n detectEnvironmentUnavailable: opts.detectEnvironmentUnavailable,\n abortOnEnvironmentUnavailable: opts.abortOnEnvironmentUnavailable,\n playwrightFailureHealthCheck: opts.playwrightFailureHealthCheck,\n })\n\n if (result.exitCode === 0) {\n return\n }\n\n throw createMonitoredCommandError('yarn', ['run', ...args], result)\n}\n\nasync function runNpxCommandWithOutputMonitoring(\n args: string[],\n environment: NodeJS.ProcessEnv,\n opts: CommandMonitoringOptions = {},\n): Promise<void> {\n const binary = process.platform === 'win32' ? 'npx.cmd' : 'npx'\n const result = await runCommandWithOutputMonitoring(binary, args, environment, {\n detectEnvironmentUnavailable: opts.detectEnvironmentUnavailable,\n abortOnEnvironmentUnavailable: opts.abortOnEnvironmentUnavailable,\n playwrightFailureHealthCheck: opts.playwrightFailureHealthCheck,\n })\n\n if (result.exitCode === 0) {\n return\n }\n\n throw createMonitoredCommandError('npx', args, result)\n}\n\nfunction runYarnRawCommand(\n commandArgs: string[],\n environment: NodeJS.ProcessEnv,\n opts: { silent?: boolean } = {},\n cwd: string = projectRootDirectory,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const outputMode: StdioOptions = opts.silent ? ['ignore', 'pipe', 'pipe'] : 'inherit'\n const resolvedSpawn = resolveSpawnCommand(resolveYarnBinary(), commandArgs)\n const command: ChildProcess = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd,\n env: environment,\n stdio: outputMode,\n ...resolvedSpawn.spawnOptions,\n })\n let bufferedOutput = ''\n if (opts.silent) {\n command.stdout?.on('data', (chunk: Buffer | string) => {\n bufferedOutput += chunk.toString()\n })\n command.stderr?.on('data', (chunk: Buffer | string) => {\n bufferedOutput += chunk.toString()\n })\n }\n command.on('error', reject)\n command.on('exit', (code: number | null) => {\n if (code === 0) {\n resolve()\n return\n }\n const extra = opts.silent && bufferedOutput.trim().length > 0\n ? `\\nLast output:\\n${bufferedOutput.trim().split('\\n').slice(-20).join('\\n')}`\n : ''\n reject(new Error(`Command failed: yarn ${commandArgs.join(' ')} (exit ${code ?? 'unknown'})${extra}`))\n })\n })\n}\n\nfunction runNpxCommand(args: string[], environment: NodeJS.ProcessEnv): Promise<void> {\n const binary = process.platform === 'win32' ? 'npx.cmd' : 'npx'\n return new Promise((resolve, reject) => {\n const resolvedSpawn = resolveSpawnCommand(binary, args)\n const command = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd: projectRootDirectory,\n env: environment,\n stdio: 'inherit',\n ...resolvedSpawn.spawnOptions,\n })\n command.on('error', reject)\n command.on('exit', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n reject(new Error(`Command failed: npx ${args.join(' ')} (exit ${code ?? 'unknown'})`))\n })\n })\n}\n\nfunction startYarnRawCommand(\n commandArgs: string[],\n environment: NodeJS.ProcessEnv,\n opts: { silent?: boolean } = {},\n cwd: string = projectRootDirectory,\n): ChildProcess {\n const outputMode: StdioOptions = opts.silent ? ['ignore', 'pipe', 'pipe'] : 'inherit'\n const resolvedSpawn = resolveSpawnCommand(resolveYarnBinary(), commandArgs)\n const processHandle: ChildProcess = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd,\n env: environment,\n stdio: outputMode,\n ...resolvedSpawn.spawnOptions,\n })\n if (opts.silent) {\n processHandle.stdout?.on('data', () => {})\n processHandle.stderr?.on('data', () => {})\n }\n return processHandle\n}\n\nfunction startYarnCommand(\n args: string[],\n environment: NodeJS.ProcessEnv,\n opts: { silent?: boolean } = {},\n cwd: string = projectRootDirectory,\n): ChildProcess {\n return startYarnRawCommand(['run', ...args], environment, opts, cwd)\n}\n\nasync function assertContainerRuntimeAvailable(): Promise<void> {\n const dockerInfoResult = await runCommandAndCapture('docker', ['info'])\n if (dockerInfoResult.code === 0) {\n return\n }\n\n const normalizedError = dockerInfoResult.stderr.trim()\n let guidance = 'Container runtime is unavailable. Start Docker Desktop (or another Docker-compatible runtime) and retry.'\n if (dockerInfoResult.code === -1) {\n guidance = 'Docker CLI is not available in PATH. Install Docker Desktop (or Docker CLI + runtime), then retry.'\n } else if (normalizedError.includes('Cannot connect to the Docker daemon')) {\n guidance = 'Docker CLI is installed but daemon is not running. Start Docker Desktop, wait until it is healthy, then run `docker info` and retry.'\n }\n\n throw new Error(\n [\n 'Unable to start ephemeral integration environment.',\n `Cause: ${normalizedError || 'docker info failed'}`,\n `What to do: ${guidance}`,\n ].join(' '),\n )\n}\n\nfunction assertNode24Runtime(): void {\n const major = Number.parseInt(process.versions.node.split('.')[0] ?? '0', 10)\n if (major >= 24) {\n return\n }\n throw new Error(\n [\n 'Unsupported Node.js runtime for ephemeral integration tests.',\n `Cause: Detected Node ${process.versions.node}, but this repository requires Node 24.x.`,\n 'What to do: switch your shell to Node 24 (for example `nvm use 24`), reinstall dependencies (`yarn install`), then retry `yarn test:integration:ephemeral`.',\n ].join(' '),\n )\n}\n\nfunction getProcessExitPromise(command: ChildProcess): Promise<number | null> {\n return new Promise((resolve, reject) => {\n command.on('error', reject)\n command.on('exit', (code) => resolve(code))\n })\n}\n\nfunction delay(milliseconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, milliseconds)\n })\n}\n\nexport function resolveBuildCacheTtlSeconds(logPrefix: string): number {\n const rawValue = process.env[BUILD_CACHE_TTL_ENV_VAR]\n if (!rawValue) {\n return DEFAULT_BUILD_CACHE_TTL_SECONDS\n }\n const parsed = Number.parseInt(rawValue, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n console.warn(\n `[${logPrefix}] Invalid ${BUILD_CACHE_TTL_ENV_VAR} value \"${rawValue}\". Using default ${DEFAULT_BUILD_CACHE_TTL_SECONDS}s.`,\n )\n return DEFAULT_BUILD_CACHE_TTL_SECONDS\n }\n return parsed\n}\n\nexport function resolveAppReadyTimeoutMs(logPrefix: string): number {\n const rawValue = process.env[APP_READY_TIMEOUT_ENV_VAR]\n if (!rawValue) {\n return DEFAULT_APP_READY_TIMEOUT_MS\n }\n const parsedSeconds = Number.parseInt(rawValue, 10)\n if (!Number.isFinite(parsedSeconds) || parsedSeconds < 1) {\n console.warn(\n `[${logPrefix}] Invalid ${APP_READY_TIMEOUT_ENV_VAR} value \"${rawValue}\". Using default ${DEFAULT_APP_READY_TIMEOUT_MS / 1000}s.`,\n )\n return DEFAULT_APP_READY_TIMEOUT_MS\n }\n return parsedSeconds * 1000\n}\n\nfunction buildCacheDefaults(overrides: BuildCacheOptions = {}): {\n artifactPaths: string[]\n inputPaths: string[]\n cacheStatePath: string\n projectRoot: string\n} {\n return {\n artifactPaths: overrides.artifactPaths ?? APP_BUILD_ARTIFACTS,\n inputPaths: overrides.inputPaths ?? APP_BUILD_INPUT_PATHS,\n cacheStatePath: overrides.cacheStatePath ?? EPHEMERAL_BUILD_CACHE_STATE_PATH,\n projectRoot: overrides.projectRoot ?? projectRootDirectory,\n }\n}\n\nfunction isIgnoredBuildCacheDirectory(entryName: string): boolean {\n return IGNORED_EPHEMERAL_BUILD_CACHE_DIRS.has(entryName) || entryName.startsWith('.')\n}\n\nasync function getAllBuildInputFiles(inputPath: string, projectRoot: string): Promise<string[]> {\n const normalized = path.normalize(inputPath)\n const pathStats = await stat(normalized)\n if (pathStats.isFile()) {\n return [path.relative(projectRoot, normalized)]\n }\n if (!pathStats.isDirectory()) {\n return []\n }\n\n const entries = await readdir(normalized, { withFileTypes: true })\n const files: string[] = []\n for (const entry of entries) {\n if (entry.isDirectory() && isIgnoredBuildCacheDirectory(entry.name)) {\n continue\n }\n if (entry.isDirectory()) {\n const nested = await getAllBuildInputFiles(path.join(normalized, entry.name), projectRoot)\n files.push(...nested)\n continue\n }\n if (!entry.isFile()) {\n continue\n }\n files.push(path.join(normalized, entry.name))\n }\n return files\n}\n\nasync function buildSourceFingerprint(options: BuildCacheOptions = {}): Promise<string | null> {\n const { inputPaths, projectRoot } = buildCacheDefaults(options)\n const seenPaths = new Set<string>()\n const absoluteFiles: string[] = []\n\n for (const inputPath of inputPaths) {\n let collected: string[]\n try {\n collected = await getAllBuildInputFiles(inputPath, projectRoot)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n\n for (const filePath of collected) {\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(projectRoot, filePath)\n if (!seenPaths.has(resolvedPath)) {\n seenPaths.add(resolvedPath)\n absoluteFiles.push(resolvedPath)\n }\n }\n }\n\n if (absoluteFiles.length === 0) {\n return null\n }\n\n const fingerprintParts: string[] = []\n for (const filePath of absoluteFiles.sort((a, b) => a.localeCompare(b))) {\n const fileStat = await stat(filePath)\n if (!fileStat.isFile()) {\n continue\n }\n const relativePath = path.relative(projectRoot, filePath).split(path.sep).join('/')\n fingerprintParts.push(`${relativePath}:${fileStat.size}:${Math.floor(fileStat.mtimeMs)}`)\n }\n\n if (fingerprintParts.length === 0) {\n return null\n }\n\n return createHash('sha256').update(fingerprintParts.join('\\n'), 'utf8').digest('hex')\n}\n\nasync function hasBuildInputChangesSince(\n timestampMs: number,\n options: BuildCacheOptions = {},\n): Promise<boolean> {\n const { inputPaths, projectRoot } = buildCacheDefaults(options)\n const seenPaths = new Set<string>()\n\n for (const inputPath of inputPaths) {\n let collected: string[]\n try {\n collected = await getAllBuildInputFiles(inputPath, projectRoot)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n continue\n }\n throw error\n }\n\n for (const filePath of collected) {\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(projectRoot, filePath)\n if (seenPaths.has(resolvedPath)) {\n continue\n }\n seenPaths.add(resolvedPath)\n\n let fileStat: Awaited<ReturnType<typeof stat>>\n try {\n fileStat = await stat(resolvedPath)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return true\n }\n throw error\n }\n if (fileStat.isFile() && fileStat.mtimeMs > timestampMs) {\n return true\n }\n }\n }\n\n return false\n}\n\nasync function readBuildCacheState(cacheStatePath: string): Promise<BuildCacheState | null> {\n let rawText: string\n try {\n rawText = await readFile(cacheStatePath, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n\n let parsed: unknown = null\n try {\n parsed = JSON.parse(rawText)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object') {\n return null\n }\n const maybeState = parsed as Partial<BuildCacheState>\n if (maybeState.version !== BUILD_CACHE_STATE_VERSION) {\n return null\n }\n if (typeof maybeState.builtAt !== 'number' || !Number.isFinite(maybeState.builtAt)) {\n return null\n }\n if (typeof maybeState.sourceFingerprint !== 'string' || maybeState.sourceFingerprint.length === 0) {\n return null\n }\n if (typeof maybeState.environmentFingerprint !== 'string' || maybeState.environmentFingerprint.length === 0) {\n return null\n }\n if (!Array.isArray(maybeState.artifactPaths) || maybeState.artifactPaths.length === 0) {\n return null\n }\n if (typeof maybeState.projectRoot !== 'string' || maybeState.projectRoot.length === 0) {\n return null\n }\n\n return {\n version: BUILD_CACHE_STATE_VERSION,\n builtAt: maybeState.builtAt,\n sourceFingerprint: maybeState.sourceFingerprint,\n environmentFingerprint: maybeState.environmentFingerprint,\n artifactPaths: maybeState.artifactPaths.filter((entry): entry is string => typeof entry === 'string'),\n projectRoot: maybeState.projectRoot,\n }\n}\n\nasync function writeBuildCacheState(\n sourceFingerprint: string,\n options: BuildCacheOptions = {},\n): Promise<void> {\n const defaults = buildCacheDefaults(options)\n const environmentFingerprint = options.environmentFingerprint ?? ''\n if (!environmentFingerprint) {\n throw new Error('Build cache state requires an environment fingerprint.')\n }\n await mkdir(path.dirname(defaults.cacheStatePath), { recursive: true })\n await writeFile(\n defaults.cacheStatePath,\n `${JSON.stringify(\n {\n version: BUILD_CACHE_STATE_VERSION,\n builtAt: Date.now(),\n sourceFingerprint,\n environmentFingerprint,\n artifactPaths: defaults.artifactPaths,\n projectRoot: defaults.projectRoot,\n },\n null,\n 2,\n )}\\n`,\n 'utf8',\n )\n}\n\nasync function isBuildArtifactMissing(filePath: string): Promise<boolean> {\n try {\n const artifactStats = await stat(filePath)\n return !artifactStats.isFile() || artifactStats.size <= 0\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return true\n }\n throw error\n }\n}\n\nexport async function shouldReuseBuildArtifacts(\n ttlSeconds: number,\n logPrefix: string,\n options: BuildCacheOptions = {},\n): Promise<boolean> {\n if (ttlSeconds <= 0) {\n console.log(`[${logPrefix}] Build cache disabled: ${BUILD_CACHE_TTL_ENV_VAR} is set to ${ttlSeconds}.`)\n return false\n }\n\n const defaults = buildCacheDefaults(options)\n const currentSourceFingerprint = options.precomputedSourceFingerprint ?? (await buildSourceFingerprint(defaults))\n const currentEnvironmentFingerprint = options.environmentFingerprint ?? ''\n if (!currentSourceFingerprint) {\n console.log(\n `[${logPrefix}] Build cache disabled: unable to collect source fingerprints from tracked sources.`,\n )\n return false\n }\n if (!currentEnvironmentFingerprint) {\n console.log(`[${logPrefix}] Build cache disabled: missing environment fingerprint for cache validation.`)\n return false\n }\n\n const state = await readBuildCacheState(defaults.cacheStatePath)\n if (!state) {\n console.log(`[${logPrefix}] Build cache disabled: missing or invalid cache metadata (${defaults.cacheStatePath}).`)\n return false\n }\n\n if (state.projectRoot !== defaults.projectRoot) {\n console.log(`[${logPrefix}] Build cache disabled: project root changed since cache creation.`)\n return false\n }\n\n const buildAgeSeconds = Math.floor((Date.now() - state.builtAt) / 1000)\n if (buildAgeSeconds > ttlSeconds) {\n console.log(\n `[${logPrefix}] Build cache disabled: last build age ${buildAgeSeconds}s exceeds ${BUILD_CACHE_TTL_ENV_VAR}=${ttlSeconds}s.`,\n )\n return false\n }\n\n if (state.sourceFingerprint !== currentSourceFingerprint) {\n console.log(`[${logPrefix}] Build cache disabled: source files changed since last build.`)\n return false\n }\n if (state.environmentFingerprint !== currentEnvironmentFingerprint) {\n console.log(`[${logPrefix}] Build cache disabled: build-shaping environment changed since last build.`)\n return false\n }\n\n for (const artifactPath of defaults.artifactPaths) {\n if (await isBuildArtifactMissing(artifactPath)) {\n console.log(`[${logPrefix}] Build cache disabled: missing build artifact ${artifactPath}.`)\n return false\n }\n }\n\n console.log(\n `[${logPrefix}] Reusing existing build artifacts (last build age ${buildAgeSeconds}s, TTL ${ttlSeconds}s).`,\n )\n return true\n}\n\nexport async function shouldRebuildBuildArtifacts(\n ttlSeconds: number,\n logPrefix: string,\n options: BuildCacheOptions = {},\n): Promise<boolean> {\n return !(await shouldReuseBuildArtifacts(ttlSeconds, logPrefix, options))\n}\n\nasync function getFreePort(): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = createServer()\n server.on('error', reject)\n server.listen(0, '127.0.0.1', () => {\n const address = server.address()\n if (!address || typeof address === 'string') {\n server.close()\n reject(new Error('Unable to allocate free port'))\n return\n }\n const port = address.port\n server.close((closeError) => {\n if (closeError) {\n reject(closeError)\n return\n }\n resolve(port)\n })\n })\n })\n}\n\nasync function isPortAvailable(port: number): Promise<boolean> {\n const canBind = (host: string): Promise<boolean | null> => new Promise((resolve) => {\n const server = createServer()\n server.once('error', (error) => {\n const errorCode = (error as NodeJS.ErrnoException).code\n if (errorCode === 'EAFNOSUPPORT') {\n resolve(null)\n return\n }\n resolve(false)\n })\n server.listen(port, host, () => {\n server.close(() => {\n resolve(true)\n })\n })\n })\n\n const ipv4Availability = await canBind('127.0.0.1')\n if (ipv4Availability === false) {\n return false\n }\n\n const ipv6Availability = await canBind('::1')\n if (ipv6Availability === false) {\n return false\n }\n\n return ipv4Availability === true || ipv6Availability === true\n}\n\nasync function getPreferredPort(preferredPort: number): Promise<number> {\n if (await isPortAvailable(preferredPort)) {\n return preferredPort\n }\n const fallbackPort = await getFreePort()\n console.log(`[ephemeral] Port ${preferredPort} is busy, using fallback port ${fallbackPort}.`)\n return fallbackPort\n}\n\nexport async function writeEphemeralEnvironmentState(input: {\n baseUrl: string\n port: number\n databaseUrl: string\n queueBaseDir: string\n logPrefix: string\n captureScreenshots: boolean\n}): Promise<void> {\n const content: EphemeralEnvironmentState = {\n status: 'running',\n baseUrl: input.baseUrl,\n port: input.port,\n databaseUrl: input.databaseUrl,\n queueBaseDir: input.queueBaseDir,\n source: input.logPrefix,\n captureScreenshots: input.captureScreenshots,\n startedAt: new Date().toISOString(),\n }\n await writeFile(EPHEMERAL_ENV_FILE_PATH, `${JSON.stringify(content, null, 2)}\\n`, 'utf8')\n}\n\nexport async function clearEphemeralEnvironmentState(): Promise<void> {\n await rm(EPHEMERAL_ENV_FILE_PATH, { force: true })\n await rm(LEGACY_EPHEMERAL_ENV_FILE_PATH, { force: true })\n}\n\nexport async function readEphemeralEnvironmentState(): Promise<EphemeralEnvironmentState | null> {\n let sourceText = ''\n try {\n sourceText = await readFile(EPHEMERAL_ENV_FILE_PATH, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n\n let parsed: unknown = null\n try {\n parsed = JSON.parse(sourceText)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object') {\n return null\n }\n\n const record = parsed as Partial<EphemeralEnvironmentState>\n if (record.status !== 'running') {\n return null\n }\n if (typeof record.baseUrl !== 'string' || record.baseUrl.length === 0) {\n return null\n }\n if (typeof record.port !== 'number' || !Number.isFinite(record.port) || record.port < 1) {\n return null\n }\n if (typeof record.databaseUrl !== 'string' || record.databaseUrl.length === 0) {\n return null\n }\n if (typeof record.queueBaseDir !== 'string' || record.queueBaseDir.length === 0) {\n return null\n }\n if (typeof record.source !== 'string' || record.source.length === 0) {\n return null\n }\n if (typeof record.captureScreenshots !== 'boolean') {\n return null\n }\n if (typeof record.startedAt !== 'string' || record.startedAt.length === 0) {\n return null\n }\n\n return {\n status: 'running',\n baseUrl: record.baseUrl,\n port: record.port,\n databaseUrl: record.databaseUrl,\n queueBaseDir: record.queueBaseDir,\n source: record.source,\n captureScreenshots: record.captureScreenshots,\n startedAt: record.startedAt,\n }\n}\n\nfunction isLoginHtmlHealthy(html: string): boolean {\n return !/Application error: a client-side exception has occurred/i.test(html)\n}\n\nfunction isSuccessfulBrowserNavigationStatus(status: number): boolean {\n return status === 200 || (status >= 300 && status < 400)\n}\n\nasync function probeLoginPage(baseUrl: string): Promise<LoginPageProbeResult> {\n try {\n const response = await fetch(`${baseUrl}/login`, {\n method: 'GET',\n redirect: 'manual',\n })\n if (!isSuccessfulBrowserNavigationStatus(response.status)) {\n return {\n status: response.status,\n healthy: false,\n detail: `GET /login returned ${response.status}`,\n }\n }\n if (response.status !== 200) {\n return {\n status: response.status,\n healthy: true,\n detail: `GET /login returned redirect ${response.status}`,\n }\n }\n const html = await response.text().catch(() => '')\n if (!isLoginHtmlHealthy(html)) {\n return {\n status: response.status,\n healthy: false,\n detail: 'GET /login returned client-side exception HTML',\n }\n }\n return {\n status: response.status,\n healthy: true,\n detail: 'GET /login returned healthy HTML',\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n status: null,\n healthy: false,\n detail: `GET /login failed: ${message}`,\n }\n }\n}\n\nasync function probeBackendLoginEndpoint(baseUrl: string): Promise<BackendLoginProbeResult> {\n try {\n const form = new URLSearchParams()\n form.set('email', 'integration-healthcheck@example.invalid')\n form.set('password', 'invalid-password')\n const response = await fetch(`${baseUrl}/api/auth/login`, {\n method: 'POST',\n redirect: 'manual',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: form.toString(),\n })\n\n const healthy = response.status === 200 || response.status === 400 || response.status === 401 || response.status === 403\n return {\n status: response.status,\n healthy,\n detail: healthy\n ? `POST /api/auth/login returned ${response.status}`\n : `POST /api/auth/login returned unexpected ${response.status}`,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n status: null,\n healthy: false,\n detail: `POST /api/auth/login failed: ${message}`,\n }\n }\n}\n\nasync function probeAuthenticatedApi(baseUrl: string): Promise<AuthenticatedApiProbeResult> {\n try {\n const form = new URLSearchParams()\n form.set('email', 'admin@acme.com')\n form.set('password', 'secret')\n const loginResponse = await fetch(`${baseUrl}/api/auth/login`, {\n method: 'POST',\n redirect: 'manual',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: form.toString(),\n })\n\n const rawBody = await loginResponse.text().catch(() => '')\n let token: string | null = null\n if (rawBody) {\n try {\n const parsed = JSON.parse(rawBody) as { token?: unknown }\n token = typeof parsed.token === 'string' && parsed.token.length > 0 ? parsed.token : null\n } catch {\n token = null\n }\n }\n\n if (!loginResponse.ok || !token) {\n return {\n loginStatus: loginResponse.status,\n apiStatus: null,\n healthy: false,\n detail: loginResponse.ok\n ? 'POST /api/auth/login did not return an auth token'\n : `POST /api/auth/login returned ${loginResponse.status}`,\n }\n }\n\n const apiResponse = await fetch(`${baseUrl}/api/customers/people?pageSize=1`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n })\n\n const healthy = apiResponse.status === 200\n return {\n loginStatus: loginResponse.status,\n apiStatus: apiResponse.status,\n healthy,\n detail: healthy\n ? 'Authenticated GET /api/customers/people returned 200'\n : `Authenticated GET /api/customers/people returned ${apiResponse.status}`,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n loginStatus: null,\n apiStatus: null,\n healthy: false,\n detail: `Authenticated readiness probe failed: ${message}`,\n }\n }\n}\n\nasync function probeApplicationReadiness(baseUrl: string): Promise<ApplicationReadinessProbeResult> {\n const [frontend, backend, authenticated] = await Promise.all([\n probeLoginPage(baseUrl),\n probeBackendLoginEndpoint(baseUrl),\n probeAuthenticatedApi(baseUrl),\n ])\n\n return {\n ready: frontend.healthy && backend.healthy && authenticated.healthy,\n frontend,\n backend,\n authenticated,\n }\n}\n\nasync function acquireEphemeralEnvironmentLock(logPrefix: string): Promise<{ release: () => Promise<void> }> {\n await mkdir(path.dirname(EPHEMERAL_ENV_LOCK_PATH), { recursive: true })\n const deadlineTimestamp = Date.now() + EPHEMERAL_ENV_LOCK_TIMEOUT_MS\n let waitingLogged = false\n\n while (true) {\n try {\n await mkdir(EPHEMERAL_ENV_LOCK_PATH)\n const lockOwnerPath = path.join(EPHEMERAL_ENV_LOCK_PATH, 'owner.json')\n await writeFile(\n lockOwnerPath,\n `${JSON.stringify({ pid: process.pid, source: logPrefix, acquiredAt: new Date().toISOString() }, null, 2)}\\n`,\n 'utf8',\n )\n return {\n release: async () => {\n await rm(EPHEMERAL_ENV_LOCK_PATH, { recursive: true, force: true })\n },\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error\n }\n if (await clearStaleEphemeralEnvironmentLock(logPrefix)) {\n continue\n }\n }\n\n const remainingMilliseconds = deadlineTimestamp - Date.now()\n if (remainingMilliseconds <= 0) {\n throw new Error(\n `Timed out after ${EPHEMERAL_ENV_LOCK_TIMEOUT_MS / 1000}s waiting for ephemeral environment setup lock at ${EPHEMERAL_ENV_LOCK_PATH}.`,\n )\n }\n\n if (!waitingLogged) {\n console.log(`[${logPrefix}] Waiting for another process to finish preparing the ephemeral environment...`)\n waitingLogged = true\n }\n await delay(Math.min(EPHEMERAL_ENV_LOCK_POLL_MS, remainingMilliseconds))\n }\n}\n\nfunction isProcessRunning(processId: number): boolean {\n try {\n process.kill(processId, 0)\n return true\n } catch (error) {\n return (error as NodeJS.ErrnoException).code !== 'ESRCH'\n }\n}\n\nasync function getPathAgeMilliseconds(targetPath: string): Promise<number | null> {\n try {\n const stats = await stat(targetPath)\n return Date.now() - stats.mtimeMs\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n}\n\nasync function clearStaleEphemeralEnvironmentLock(logPrefix: string): Promise<boolean> {\n const lockOwnerPath = path.join(EPHEMERAL_ENV_LOCK_PATH, 'owner.json')\n let ownerPid: number | null = null\n\n let ownerReadFailed = false\n try {\n const ownerSource = await readFile(lockOwnerPath, 'utf8')\n const parsed = JSON.parse(ownerSource) as { pid?: unknown }\n if (typeof parsed.pid === 'number' && Number.isInteger(parsed.pid) && parsed.pid > 0) {\n ownerPid = parsed.pid\n }\n } catch {\n ownerReadFailed = true\n }\n\n if (ownerPid === null) {\n const lockAge = await getPathAgeMilliseconds(EPHEMERAL_ENV_LOCK_PATH)\n if (lockAge === null) {\n return false\n }\n if (ownerReadFailed && lockAge > EPHEMERAL_ENV_LOCK_TIMEOUT_MS) {\n await rm(EPHEMERAL_ENV_LOCK_PATH, { recursive: true, force: true })\n console.log(`[${logPrefix}] Removed stale ephemeral environment lock with invalid owner metadata.`)\n return true\n }\n return false\n }\n\n if (isProcessRunning(ownerPid)) {\n return false\n }\n\n await rm(EPHEMERAL_ENV_LOCK_PATH, { recursive: true, force: true })\n console.log(`[${logPrefix}] Removed stale ephemeral environment lock from exited process ${ownerPid}.`)\n return true\n}\n\ntype EphemeralRuntimeLockOptions = {\n lockPath?: string\n isProcessRunning?: (processId: number) => boolean\n}\n\ntype EphemeralRuntimeLockOwner = {\n pid: number\n source?: string\n acquiredAt?: string\n}\n\nasync function readEphemeralRuntimeLockOwner(lockPath: string): Promise<EphemeralRuntimeLockOwner | null> {\n const ownerPath = path.join(lockPath, 'owner.json')\n let ownerSource = ''\n try {\n ownerSource = await readFile(ownerPath, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n\n let parsed: unknown = null\n try {\n parsed = JSON.parse(ownerSource)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object') {\n return null\n }\n\n const record = parsed as Partial<EphemeralRuntimeLockOwner>\n if (typeof record.pid !== 'number' || !Number.isInteger(record.pid) || record.pid < 1) {\n return null\n }\n\n return {\n pid: record.pid,\n source: typeof record.source === 'string' ? record.source : undefined,\n acquiredAt: typeof record.acquiredAt === 'string' ? record.acquiredAt : undefined,\n }\n}\n\nasync function clearStaleEphemeralRuntimeLock(\n logPrefix: string,\n options: Required<EphemeralRuntimeLockOptions>,\n): Promise<boolean> {\n const owner = await readEphemeralRuntimeLockOwner(options.lockPath)\n const lockAge = await getPathAgeMilliseconds(options.lockPath)\n if (!owner) {\n if (lockAge !== null && lockAge > EPHEMERAL_ENV_LOCK_TIMEOUT_MS) {\n await rm(options.lockPath, { recursive: true, force: true })\n console.log(`[${logPrefix}] Removed stale ephemeral runtime lock with invalid owner metadata.`)\n return true\n }\n return false\n }\n\n if (options.isProcessRunning(owner.pid)) {\n return false\n }\n\n await rm(options.lockPath, { recursive: true, force: true })\n console.log(`[${logPrefix}] Removed stale ephemeral runtime lock from exited process ${owner.pid}.`)\n return true\n}\n\nexport async function acquireEphemeralRuntimeLock(\n logPrefix: string,\n options: EphemeralRuntimeLockOptions = {},\n): Promise<{ release: () => Promise<void> }> {\n const resolvedOptions: Required<EphemeralRuntimeLockOptions> = {\n lockPath: options.lockPath ?? EPHEMERAL_RUNTIME_LOCK_PATH,\n isProcessRunning: options.isProcessRunning ?? isProcessRunning,\n }\n\n await mkdir(path.dirname(resolvedOptions.lockPath), { recursive: true })\n\n try {\n await mkdir(resolvedOptions.lockPath)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error\n }\n\n if (await clearStaleEphemeralRuntimeLock(logPrefix, resolvedOptions)) {\n return acquireEphemeralRuntimeLock(logPrefix, resolvedOptions)\n }\n\n const owner = await readEphemeralRuntimeLockOwner(resolvedOptions.lockPath)\n const ownerSource = owner?.source ? ` started by \"${owner.source}\"` : ''\n const ownerPid = owner?.pid ? ` (pid ${owner.pid})` : ''\n throw new Error(\n `[${logPrefix}] Another ephemeral environment is already active${ownerSource}${ownerPid}. Reuse the running environment or stop it before starting a fresh ephemeral run, because a second build/generate pipeline would overwrite shared workspace artifacts.`,\n )\n }\n\n const ownerPath = path.join(resolvedOptions.lockPath, 'owner.json')\n await writeFile(\n ownerPath,\n `${JSON.stringify({ pid: process.pid, source: logPrefix, acquiredAt: new Date().toISOString() }, null, 2)}\\n`,\n 'utf8',\n )\n\n return {\n release: async () => {\n await rm(resolvedOptions.lockPath, { recursive: true, force: true })\n },\n }\n}\n\nfunction buildReusableEnvironment(\n baseUrl: string,\n databaseUrl: string,\n queueBaseDir: string,\n captureScreenshots: boolean,\n): NodeJS.ProcessEnv {\n const enterpriseModulesFlag = process.env.OM_ENABLE_ENTERPRISE_MODULES ?? 'false'\n return buildEnvironment({\n DATABASE_URL: databaseUrl,\n BASE_URL: baseUrl,\n APP_URL: baseUrl,\n NEXT_PUBLIC_APP_URL: baseUrl,\n NODE_ENV: 'production',\n JWT_SECRET: process.env.JWT_SECRET ?? 'om-ephemeral-integration-jwt-secret',\n OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? 'om-ephemeral-integration-mfa-setup-secret',\n OM_INTEGRATION_TEST: 'true',\n OM_ENABLE_ENTERPRISE_MODULES: enterpriseModulesFlag,\n OM_ENABLE_ENTERPRISE_MODULES_SSO: process.env.OM_ENABLE_ENTERPRISE_MODULES_SSO ?? enterpriseModulesFlag,\n OM_ENABLE_ENTERPRISE_MODULES_SECURITY: process.env.OM_ENABLE_ENTERPRISE_MODULES_SECURITY ?? enterpriseModulesFlag,\n OM_TEST_MODE: '1',\n OM_TEST_AUTH_RATE_LIMIT_MODE: 'opt-in',\n OM_WEBHOOKS_ALLOW_PRIVATE_URLS: process.env.OM_WEBHOOKS_ALLOW_PRIVATE_URLS ?? '1',\n ENABLE_CRUD_API_CACHE: 'true',\n MOCK_GATEWAY_WEBHOOK_SECRET: 'open-mercato-mock-dev-webhook-secret',\n MOCK_CARRIER_WEBHOOK_SECRET: 'open-mercato-mock-dev-carrier-webhook-secret',\n NEXT_PUBLIC_OM_EXAMPLE_INJECTION_WIDGETS_ENABLED: 'true',\n NEXT_PUBLIC_UMES_DEVTOOLS: 'true',\n CI: 'true',\n TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? 'om-ephemeral-integration-fallback-key',\n OM_CLI_QUIET: '1',\n MERCATO_QUIET: '1',\n QUEUE_BASE_DIR: queueBaseDir,\n NODE_NO_WARNINGS: '1',\n PW_CAPTURE_SCREENSHOTS: captureScreenshots ? '1' : '0',\n })\n}\n\nexport async function tryReuseExistingEnvironment(options: EphemeralRuntimeOptions): Promise<EphemeralEnvironmentHandle | null> {\n const state = await readEphemeralEnvironmentState()\n if (!state) {\n return null\n }\n\n if (options.requiredExistingSource && state.source !== options.requiredExistingSource) {\n console.log(\n `[${options.logPrefix}] Existing ephemeral environment source \"${state.source}\" does not match required \"${options.requiredExistingSource}\".`,\n )\n return null\n }\n\n const unavailable = await isEnvironmentUnavailable(state.baseUrl)\n if (unavailable) {\n console.log(`[${options.logPrefix}] Found stale ephemeral state. Clearing ${EPHEMERAL_ENV_FILE_PATH}.`)\n await clearEphemeralEnvironmentState()\n return null\n }\n\n const cacheTtlSeconds = resolveBuildCacheTtlSeconds(options.logPrefix)\n const startedAtMs = Date.parse(state.startedAt)\n if (Number.isFinite(startedAtMs)) {\n const environmentAgeSeconds = Math.floor((Date.now() - startedAtMs) / 1000)\n if (environmentAgeSeconds > cacheTtlSeconds) {\n console.log(\n `[${options.logPrefix}] Existing ephemeral environment is ${environmentAgeSeconds}s old, exceeding ${BUILD_CACHE_TTL_ENV_VAR}=${cacheTtlSeconds}s. Rebuilding.`,\n )\n await clearEphemeralEnvironmentState()\n return null\n }\n\n const sourceChangedSinceStart = await hasBuildInputChangesSince(startedAtMs)\n if (sourceChangedSinceStart) {\n console.log(\n `[${options.logPrefix}] Source files changed since the current ephemeral environment started. Rebuilding.`,\n )\n await clearEphemeralEnvironmentState()\n return null\n }\n }\n\n if (options.captureScreenshots !== state.captureScreenshots) {\n console.log(\n `[${options.logPrefix}] Reusing screenshot capture setting from ${EPHEMERAL_ENV_FILE_PATH}: ${state.captureScreenshots ? 'enabled' : 'disabled'}.`,\n )\n }\n console.log(`[${options.logPrefix}] Reusing existing ephemeral environment at ${state.baseUrl}.`)\n return {\n baseUrl: state.baseUrl,\n port: state.port,\n databaseUrl: state.databaseUrl,\n commandEnvironment: buildReusableEnvironment(\n state.baseUrl,\n state.databaseUrl,\n state.queueBaseDir,\n state.captureScreenshots,\n ),\n ownedByCurrentProcess: false,\n stop: async () => {},\n }\n}\n\nasync function waitForApplicationReadiness(\n baseUrl: string,\n appProcess: ChildProcess,\n options: { timeoutMs: number },\n): Promise<void> {\n const startTimestamp = Date.now()\n const exitPromise = getProcessExitPromise(appProcess)\n const readinessStabilizationMs = 600\n let lastProbe: ApplicationReadinessProbeResult | null = null\n\n while (Date.now() - startTimestamp < options.timeoutMs) {\n const result = await Promise.race([\n probeApplicationReadiness(baseUrl).then((probe) => ({ kind: 'probe' as const, probe })),\n exitPromise.then((code) => ({ kind: 'exit' as const, code })),\n delay(APP_READY_INTERVAL_MS).then(() => ({ kind: 'timeout' as const })),\n ])\n\n if (result.kind === 'probe') {\n lastProbe = result.probe\n if (!result.probe.ready) {\n continue\n }\n const processExited = await Promise.race([\n exitPromise.then(() => true),\n delay(readinessStabilizationMs).then(() => false),\n ])\n if (processExited) {\n throw new Error('Application process exited immediately after readiness probe.')\n }\n return\n }\n if (result.kind === 'exit') {\n throw new Error(`Application process exited before readiness check (exit ${result.code ?? 'unknown'})`)\n }\n }\n\n const lastFrontendDetail = lastProbe?.frontend.detail ?? 'GET /login was never observed'\n const lastBackendDetail = lastProbe?.backend.detail ?? 'POST /api/auth/login was never observed'\n const lastAuthenticatedDetail = lastProbe?.authenticated.detail ?? 'Authenticated API probe was never observed'\n throw new Error(\n `Application did not become ready within ${options.timeoutMs / 1000} seconds. ` +\n `Last probe: ${lastFrontendDetail}; ${lastBackendDetail}; ${lastAuthenticatedDetail}`,\n )\n}\n\nexport function parseOptions(rawArgs: string[]): IntegrationOptions {\n let keep = false\n let filter: string | null = null\n let captureScreenshots: boolean | null = null\n let verbose = false\n let forceRebuild = false\n let reuseExisting = true\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const argument = rawArgs[index]\n if (argument === '--keep') {\n keep = true\n continue\n }\n if (argument === '--screenshots') {\n captureScreenshots = true\n continue\n }\n if (argument === '--no-screenshots') {\n captureScreenshots = false\n continue\n }\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n if (argument === '--force-rebuild') {\n forceRebuild = true\n continue\n }\n if (argument === '--no-reuse-env') {\n reuseExisting = false\n continue\n }\n if (argument === '--filter') {\n const nextValue = rawArgs[index + 1]\n if (!nextValue || nextValue.startsWith('--')) {\n throw new Error('Missing value for --filter')\n }\n filter = nextValue\n index += 1\n continue\n }\n if (argument.startsWith('--filter=')) {\n const filterValue = argument.slice('--filter='.length).trim()\n if (!filterValue) {\n throw new Error('Missing value for --filter')\n }\n filter = filterValue\n continue\n }\n if (!argument.startsWith('--') && !filter) {\n filter = argument\n continue\n }\n if (argument.startsWith('--')) {\n throw new Error(`Unknown option: ${argument}`)\n }\n }\n\n const defaultCaptureScreenshots = process.env.CI !== 'true'\n return {\n keep,\n filter,\n captureScreenshots: captureScreenshots ?? defaultCaptureScreenshots,\n verbose,\n forceRebuild,\n reuseExisting,\n }\n}\n\nexport function parseEphemeralAppOptions(rawArgs: string[]): EphemeralAppOptions {\n let verbose = false\n let captureScreenshots: boolean | null = null\n let forceRebuild = false\n let reuseExisting = true\n\n for (const argument of rawArgs) {\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n if (argument === '--screenshots') {\n captureScreenshots = true\n continue\n }\n if (argument === '--no-screenshots') {\n captureScreenshots = false\n continue\n }\n if (argument === '--force-rebuild') {\n forceRebuild = true\n continue\n }\n if (argument === '--no-reuse-env') {\n reuseExisting = false\n continue\n }\n throw new Error(`Unknown option: ${argument}`)\n }\n\n const defaultCaptureScreenshots = process.env.CI !== 'true'\n return {\n verbose,\n captureScreenshots: captureScreenshots ?? defaultCaptureScreenshots,\n forceRebuild,\n reuseExisting,\n }\n}\n\nexport function parseInteractiveIntegrationOptions(rawArgs: string[]): InteractiveIntegrationOptions {\n let verbose = false\n let captureScreenshots: boolean | null = null\n let workers: number | null = null\n let retries: number | null = null\n let forceRebuild = false\n let reuseExisting = true\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const argument = rawArgs[index]\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n if (argument === '--screenshots') {\n captureScreenshots = true\n continue\n }\n if (argument === '--no-screenshots') {\n captureScreenshots = false\n continue\n }\n if (argument === '--force-rebuild') {\n forceRebuild = true\n continue\n }\n if (argument === '--no-reuse-env') {\n reuseExisting = false\n continue\n }\n if (argument === '--workers') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --workers')\n }\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new Error(`Invalid --workers value: ${value}`)\n }\n workers = parsed\n index += 1\n continue\n }\n if (argument.startsWith('--workers=')) {\n const value = argument.slice('--workers='.length)\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new Error(`Invalid --workers value: ${value}`)\n }\n workers = parsed\n continue\n }\n if (argument === '--retries') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --retries')\n }\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new Error(`Invalid --retries value: ${value}`)\n }\n retries = parsed\n index += 1\n continue\n }\n if (argument.startsWith('--retries=')) {\n const value = argument.slice('--retries='.length)\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new Error(`Invalid --retries value: ${value}`)\n }\n retries = parsed\n continue\n }\n throw new Error(`Unknown option: ${argument}`)\n }\n\n const defaultCaptureScreenshots = process.env.CI !== 'true'\n return {\n verbose,\n captureScreenshots: captureScreenshots ?? defaultCaptureScreenshots,\n workers,\n retries,\n forceRebuild,\n reuseExisting,\n }\n}\n\nexport function parseIntegrationCoverageOptions(rawArgs: string[]): IntegrationCoverageOptions {\n let filter: string | null = null\n let captureScreenshots: boolean | null = null\n let verbose = false\n let workers: number | null = null\n let retries: number | null = null\n let shard: string | null = null\n let json = false\n let keepRawV8 = false\n let forceRebuild = false\n let reuseExisting = true\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const argument = rawArgs[index]\n if (argument === '--filter') {\n const nextValue = rawArgs[index + 1]\n if (!nextValue || nextValue.startsWith('--')) {\n throw new Error('Missing value for --filter')\n }\n filter = nextValue\n index += 1\n continue\n }\n if (argument.startsWith('--filter=')) {\n const filterValue = argument.slice('--filter='.length).trim()\n if (!filterValue) {\n throw new Error('Missing value for --filter')\n }\n filter = filterValue\n continue\n }\n if (!argument.startsWith('--') && !filter) {\n filter = argument\n continue\n }\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n if (argument === '--screenshots') {\n captureScreenshots = true\n continue\n }\n if (argument === '--no-screenshots') {\n captureScreenshots = false\n continue\n }\n if (argument === '--workers') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --workers')\n }\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new Error(`Invalid --workers value: ${value}`)\n }\n workers = parsed\n index += 1\n continue\n }\n if (argument.startsWith('--workers=')) {\n const value = argument.slice('--workers='.length)\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new Error(`Invalid --workers value: ${value}`)\n }\n workers = parsed\n continue\n }\n if (argument === '--retries') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --retries')\n }\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new Error(`Invalid --retries value: ${value}`)\n }\n retries = parsed\n index += 1\n continue\n }\n if (argument.startsWith('--retries=')) {\n const value = argument.slice('--retries='.length)\n const parsed = Number.parseInt(value, 10)\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new Error(`Invalid --retries value: ${value}`)\n }\n retries = parsed\n continue\n }\n if (argument === '--shard') {\n const value = rawArgs[index + 1]\n if (!value || value.startsWith('--')) {\n throw new Error('Missing value for --shard')\n }\n if (!/^\\d+\\/\\d+$/.test(value)) {\n throw new Error(`Invalid --shard value: ${value}. Expected format: N/M`)\n }\n shard = value\n index += 1\n continue\n }\n if (argument.startsWith('--shard=')) {\n const value = argument.slice('--shard='.length)\n if (!/^\\d+\\/\\d+$/.test(value)) {\n throw new Error(`Invalid --shard value: ${value}. Expected format: N/M`)\n }\n shard = value\n continue\n }\n if (argument === '--json') {\n json = true\n continue\n }\n if (argument === '--keep-raw-v8') {\n keepRawV8 = true\n continue\n }\n if (argument === '--force-rebuild') {\n forceRebuild = true\n continue\n }\n if (argument === '--no-reuse-env') {\n reuseExisting = false\n continue\n }\n throw new Error(`Unknown option: ${argument}`)\n }\n\n const defaultCaptureScreenshots = process.env.CI !== 'true'\n return {\n filter,\n captureScreenshots: captureScreenshots ?? defaultCaptureScreenshots,\n verbose,\n workers,\n retries,\n shard,\n json,\n keepRawV8,\n forceRebuild,\n reuseExisting,\n }\n}\n\nfunction parseIntegrationSpecCoverageOptions(rawArgs: string[]): IntegrationSpecCoverageOptions {\n let json = false\n let strict = false\n for (const argument of rawArgs) {\n if (argument === '--json') {\n json = true\n continue\n }\n if (argument === '--strict') {\n strict = true\n continue\n }\n throw new Error(`Unknown option: ${argument}`)\n }\n return { json, strict }\n}\n\nfunction normalizePath(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\nasync function discoverIntegrationSpecFiles(): Promise<DiscoveredIntegrationSpecFile[]> {\n return discoverIntegrationSpecFilesShared(projectRootDirectory, LEGACY_INTEGRATION_TEST_ROOT)\n}\n\nasync function extractSpecDescription(relativePath: string): Promise<string> {\n const absolutePath = path.join(projectRootDirectory, relativePath)\n try {\n const source = await readFile(absolutePath, 'utf8')\n const describeTitleMatch = source.match(/test\\.describe\\(\\s*['\"`]([^'\"`]+)['\"`]/)\n if (describeTitleMatch?.[1]) {\n return describeTitleMatch[1].trim()\n }\n const testCaseTitleMatch = source.match(/TC-[A-Z]+-\\d+\\s*:\\s*([^\\n*]+)/)\n if (testCaseTitleMatch?.[1]) {\n return testCaseTitleMatch[1].trim()\n }\n } catch {\n return path.basename(relativePath, '.spec.ts')\n }\n return path.basename(relativePath, '.spec.ts')\n}\n\nasync function listIntegrationSpecFiles(): Promise<IntegrationSpecTarget[]> {\n const discoveredSpecs = await discoverIntegrationSpecFiles()\n const sortedFiles = discoveredSpecs.map((entry) => entry.path)\n const targets = await Promise.all(\n sortedFiles.map(async (filePath) => ({\n path: filePath,\n description: await extractSpecDescription(filePath),\n })),\n )\n return targets\n}\n\nasync function collectFilesByExtension(\n directoryPath: string,\n extension: string,\n rootPath: string,\n): Promise<string[]> {\n let entries\n try {\n entries = await readdir(directoryPath, { withFileTypes: true })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return []\n }\n throw error\n }\n const collected: string[] = []\n for (const entry of entries) {\n const absolutePath = path.join(directoryPath, entry.name)\n if (entry.isDirectory()) {\n const nestedFiles = await collectFilesByExtension(absolutePath, extension, rootPath)\n collected.push(...nestedFiles)\n continue\n }\n if (!entry.isFile() || !entry.name.endsWith(extension)) {\n continue\n }\n const relativePath = path.relative(rootPath, absolutePath)\n collected.push(normalizePath(relativePath))\n }\n return collected\n}\n\nfunction extractTestCaseId(value: string): string | null {\n const match = value.match(/TC-([A-Z]+)-(\\d{3})/i)\n if (!match) {\n return null\n }\n const category = match[1]?.toUpperCase()\n const sequence = match[2]\n if (!category || !sequence) {\n return null\n }\n return `TC-${category}-${sequence}`\n}\n\nfunction findFolderSegmentFromPath(relativePath: string): string {\n const normalized = normalizePath(relativePath)\n const marker = `${normalizePath(path.relative(projectRootDirectory, LEGACY_INTEGRATION_TEST_ROOT))}/`\n const markerIndex = normalized.indexOf(marker)\n if (markerIndex === -1) {\n return ''\n }\n const trailing = normalized.slice(markerIndex + marker.length)\n return trailing.split('/')[0] ?? ''\n}\n\nfunction extractCategoryCodeFromCaseId(caseId: string): string | null {\n const match = caseId.match(/^TC-([A-Z]+)-\\d{3}$/)\n return match?.[1] ?? null\n}\n\nfunction computePercent(numerator: number, denominator: number): number {\n if (denominator <= 0) {\n return 100\n }\n return Math.round((numerator / denominator) * 10000) / 100\n}\n\nfunction formatPercent(value: number | null): string {\n if (value === null) {\n return 'n/a'\n }\n return `${value.toFixed(2)}%`\n}\n\nexport async function runIntegrationSpecCoverageReport(rawArgs: string[]): Promise<void> {\n const options = parseIntegrationSpecCoverageOptions(rawArgs)\n const scenarioRoot = path.join(projectRootDirectory, '.ai', 'qa', 'scenarios')\n const testFiles = (await discoverIntegrationSpecFiles()).map((entry) => entry.path)\n const scenarioFiles = await collectFilesByExtension(scenarioRoot, '.md', projectRootDirectory)\n const testRunSummary = await readIntegrationTestRunSummary()\n\n const testCaseIds = new Set<string>()\n const scenarioCaseIds = new Set<string>()\n const testsByFolder = new Map<string, number>()\n\n for (const testFile of testFiles) {\n const caseId = extractTestCaseId(path.basename(testFile))\n const categoryCode = caseId ? extractCategoryCodeFromCaseId(caseId) : null\n if (caseId) {\n testCaseIds.add(caseId)\n }\n const folder = categoryCode\n ? Object.entries(FOLDER_TO_CATEGORY_CODE).find(([, mappedCategoryCode]) => mappedCategoryCode === categoryCode)?.[0]\n : findFolderSegmentFromPath(testFile)\n if (folder) {\n testsByFolder.set(folder, (testsByFolder.get(folder) ?? 0) + 1)\n }\n }\n\n for (const scenarioFile of scenarioFiles) {\n const caseId = extractTestCaseId(path.basename(scenarioFile))\n if (caseId) {\n scenarioCaseIds.add(caseId)\n }\n }\n\n const coveredScenarioIds = Array.from(scenarioCaseIds).filter((id) => testCaseIds.has(id))\n const uncoveredScenarioIds = Array.from(scenarioCaseIds)\n .filter((id) => !testCaseIds.has(id))\n .sort((left, right) => left.localeCompare(right))\n const testsWithoutScenarioIds = Array.from(testCaseIds)\n .filter((id) => !scenarioCaseIds.has(id))\n .sort((left, right) => left.localeCompare(right))\n\n const categories = new Set<string>()\n for (const scenarioId of scenarioCaseIds) {\n const category = extractCategoryCodeFromCaseId(scenarioId)\n if (category) {\n categories.add(category)\n }\n }\n for (const testId of testCaseIds) {\n const category = extractCategoryCodeFromCaseId(testId)\n if (category) {\n categories.add(category)\n }\n }\n\n const categoryRows = Array.from(categories)\n .sort((left, right) => left.localeCompare(right))\n .map((categoryCode) => {\n const scenarioCount = Array.from(scenarioCaseIds).filter((id) => id.startsWith(`TC-${categoryCode}-`)).length\n const coveredScenarioCount = coveredScenarioIds.filter((id) => id.startsWith(`TC-${categoryCode}-`)).length\n const testCount = Array.from(testCaseIds).filter((id) => id.startsWith(`TC-${categoryCode}-`)).length\n const coveragePercent = scenarioCount > 0 ? computePercent(coveredScenarioCount, scenarioCount) : null\n return {\n code: categoryCode,\n scenarioCount,\n coveredScenarioCount,\n testCount,\n coveragePercent,\n }\n })\n\n const presentRequiredFolders = EXPECTED_TEST_FOLDERS.filter((folder) => (testsByFolder.get(folder) ?? 0) > 0)\n const missingRequiredFolders = EXPECTED_TEST_FOLDERS.filter((folder) => (testsByFolder.get(folder) ?? 0) === 0)\n const coveragePercent = computePercent(coveredScenarioIds.length, scenarioCaseIds.size)\n\n const report: IntegrationCoverageReport = {\n generatedAt: new Date().toISOString(),\n testRun: testRunSummary,\n scenarios: {\n total: scenarioCaseIds.size,\n covered: coveredScenarioIds.length,\n uncovered: uncoveredScenarioIds.length,\n coveragePercent,\n },\n tests: {\n total: testCaseIds.size,\n withScenario: testCaseIds.size - testsWithoutScenarioIds.length,\n withoutScenario: testsWithoutScenarioIds.length,\n },\n categories: categoryRows,\n requiredTestFolders: {\n present: presentRequiredFolders,\n missing: missingRequiredFolders,\n },\n uncoveredScenarioIds,\n testsWithoutScenarioIds,\n }\n\n if (options.json) {\n console.log(JSON.stringify(report, null, 2))\n } else {\n console.log('[coverage] Integration test coverage report')\n console.log(`[coverage] Generated at: ${report.generatedAt}`)\n logIntegrationTestRunSummary(report.testRun)\n console.log(\n `[coverage] Scenario coverage: ${report.scenarios.covered}/${report.scenarios.total} (${formatPercent(report.scenarios.coveragePercent)})`,\n )\n console.log(`[coverage] Tests discovered: ${report.tests.total}`)\n console.log(`[coverage] Tests linked to scenarios: ${report.tests.withScenario}`)\n console.log(`[coverage] Tests without scenarios: ${report.tests.withoutScenario}`)\n console.log(\n `[coverage] Required folders with tests: ${report.requiredTestFolders.present.length}/${EXPECTED_TEST_FOLDERS.length} (${report.requiredTestFolders.present.join(', ') || '-'})`,\n )\n if (report.requiredTestFolders.missing.length > 0) {\n console.log(`[coverage] Missing required folders: ${report.requiredTestFolders.missing.join(', ')}`)\n }\n console.log('[coverage] Category breakdown:')\n for (const category of report.categories) {\n const folder = Object.entries(FOLDER_TO_CATEGORY_CODE).find(([, code]) => code === category.code)?.[0]\n const folderLabel = folder ? ` (${folder})` : ''\n console.log(\n ` - ${category.code}${folderLabel}: scenarios ${category.coveredScenarioCount}/${category.scenarioCount}, tests ${category.testCount}, coverage ${formatPercent(category.coveragePercent)}`,\n )\n }\n if (report.uncoveredScenarioIds.length > 0) {\n console.log('[coverage] Missing test implementations for scenarios:')\n for (const scenarioId of report.uncoveredScenarioIds) {\n console.log(` - ${scenarioId}`)\n }\n }\n if (report.testsWithoutScenarioIds.length > 0) {\n console.log('[coverage] Tests without matching scenario files:')\n for (const testId of report.testsWithoutScenarioIds) {\n console.log(` - ${testId}`)\n }\n }\n logIntegrationTestRunOneLineSummary(report.testRun)\n }\n\n if (options.strict && (report.uncoveredScenarioIds.length > 0 || report.requiredTestFolders.missing.length > 0)) {\n throw new Error(\n `Coverage check failed in strict mode: uncovered scenarios=${report.uncoveredScenarioIds.length}, missing required folders=${report.requiredTestFolders.missing.length}`,\n )\n }\n}\n\nasync function resetDirectory(directoryPath: string): Promise<void> {\n await rm(directoryPath, { recursive: true, force: true })\n await mkdir(directoryPath, { recursive: true })\n}\n\nfunction getCoveragePaths(): { rawDirectory: string; reportDirectory: string } {\n const rawDirectory = path.join(projectRootDirectory, '.ai', 'qa', 'test-results', 'coverage', 'raw-v8')\n const reportDirectory = path.join(projectRootDirectory, '.ai', 'qa', 'test-results', 'coverage', 'code')\n return { rawDirectory, reportDirectory }\n}\n\nasync function generateC8CoverageReport(environment: NodeJS.ProcessEnv, rawDirectory: string, reportDirectory: string): Promise<void> {\n const c8Args = [\n 'c8',\n 'report',\n '--temp-directory',\n rawDirectory,\n '--report-dir',\n reportDirectory,\n '--reporter',\n 'text-summary',\n '--reporter',\n 'json-summary',\n '--reporter',\n 'lcov',\n '--reporter',\n 'html',\n '--exclude-after-remap',\n '--exclude',\n '**/node_modules/**',\n '--exclude',\n '**/*.spec.ts',\n '--exclude',\n '.ai/**',\n '--exclude',\n 'apps/docs/**',\n '--exclude',\n 'packages/cli/**',\n '--exclude',\n 'coverage/**',\n ]\n await runNpxCommand(c8Args, environment)\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction readOptionalNumber(record: Record<string, unknown>, key: string): number | null {\n const value = record[key]\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return null\n }\n return value\n}\n\nfunction readOptionalString(record: Record<string, unknown>, key: string): string | null {\n const value = record[key]\n return typeof value === 'string' ? value : null\n}\n\nasync function readIntegrationTestRunSummary(): Promise<IntegrationTestRunSummary | null> {\n let resultsRaw: string\n try {\n resultsRaw = await readFile(PLAYWRIGHT_RESULTS_JSON_PATH, 'utf8')\n } catch {\n return null\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(resultsRaw)\n } catch {\n return null\n }\n\n if (!isObjectRecord(parsed)) {\n return null\n }\n const statsValue = parsed.stats\n if (!isObjectRecord(statsValue)) {\n return null\n }\n\n const passed = readOptionalNumber(statsValue, 'expected') ?? 0\n const failed = readOptionalNumber(statsValue, 'unexpected') ?? 0\n const flaky = readOptionalNumber(statsValue, 'flaky') ?? 0\n const skipped = readOptionalNumber(statsValue, 'skipped') ?? 0\n\n return {\n status: failed > 0 ? 'failed' : 'passed',\n total: passed + failed + flaky + skipped,\n passed,\n failed,\n flaky,\n skipped,\n durationMs: readOptionalNumber(statsValue, 'duration'),\n startTime: readOptionalString(statsValue, 'startTime'),\n }\n}\n\nfunction logIntegrationTestRunSummary(summary: IntegrationTestRunSummary | null): void {\n if (!summary) {\n console.log('[coverage] Integration test results: unavailable (.ai/qa/test-results/results.json missing or invalid)')\n return\n }\n console.log('[coverage] Integration test results:')\n console.log(` status: ${summary.status}`)\n console.log(` passed: ${summary.passed}`)\n console.log(` failed: ${summary.failed}`)\n console.log(` flaky: ${summary.flaky}`)\n console.log(` skipped: ${summary.skipped}`)\n console.log(` total: ${summary.total}`)\n}\n\nfunction logIntegrationTestRunOneLineSummary(summary: IntegrationTestRunSummary | null): void {\n if (!summary) {\n return\n }\n console.log(\n `[coverage] Test run summary: passed=${summary.passed}, failed=${summary.failed}, flaky=${summary.flaky}, skipped=${summary.skipped}, total=${summary.total}`,\n )\n}\n\nexport async function runIntegrationCoverageReport(rawArgs: string[]): Promise<void> {\n const options = parseIntegrationCoverageOptions(rawArgs)\n const coveragePaths = getCoveragePaths()\n await resetDirectory(coveragePaths.rawDirectory)\n await resetDirectory(coveragePaths.reportDirectory)\n\n const startOptions: EphemeralRuntimeOptions = {\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n forceRebuild: options.forceRebuild,\n reuseExisting: options.reuseExisting,\n logPrefix: 'coverage',\n environmentOverrides: {\n NODE_V8_COVERAGE: coveragePaths.rawDirectory,\n },\n }\n\n let testRunError: Error | null = null\n const runCoverageAttempt = async (environment: EphemeralEnvironmentHandle): Promise<Error | null> => {\n console.log('[coverage] Running Playwright integration suite with V8 coverage enabled...')\n console.log('[coverage] Ensuring Playwright Chromium is installed...')\n await runNpxCommand(['playwright', 'install', 'chromium'], environment.commandEnvironment)\n try {\n await runPlaywrightSelection(\n environment,\n options.filter,\n {\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n workers: options.workers,\n retries: options.retries,\n shard: options.shard,\n },\n )\n return null\n } catch (error) {\n const coverageRunError = error instanceof Error ? error : new Error(String(error))\n if (isEnvironmentUnavailableError(coverageRunError)) {\n console.error('[coverage] Playwright output indicates connection loss to the ephemeral app during coverage run.')\n }\n console.error(`[coverage] Playwright run failed: ${coverageRunError.message}`)\n console.error('[coverage] Continuing to generate coverage report from collected V8 data...')\n return coverageRunError\n }\n }\n\n let environment = await startEphemeralEnvironment(startOptions)\n try {\n testRunError = await runCoverageAttempt(environment)\n if (testRunError && isEnvironmentUnavailableError(testRunError)) {\n console.log('[coverage] Rebuilding ephemeral environment and retrying coverage run once...')\n await environment.stop()\n environment = await startEphemeralEnvironment(startOptions)\n testRunError = await runCoverageAttempt(environment)\n }\n } finally {\n await environment.stop()\n }\n\n console.log('[coverage] Generating code coverage report...')\n let coverageReportError: Error | null = null\n try {\n await generateC8CoverageReport(environment.commandEnvironment, coveragePaths.rawDirectory, coveragePaths.reportDirectory)\n } catch (error) {\n coverageReportError = error instanceof Error ? error : new Error(String(error))\n }\n\n if (coverageReportError) {\n if (!options.keepRawV8) {\n await rm(coveragePaths.rawDirectory, { recursive: true, force: true })\n }\n throw coverageReportError\n }\n\n const summaryPath = path.join(coveragePaths.reportDirectory, 'coverage-summary.json')\n const summaryRaw = await readFile(summaryPath, 'utf8')\n const summary = JSON.parse(summaryRaw) as {\n total?: {\n lines?: { total?: number; covered?: number; pct?: number }\n statements?: { total?: number; covered?: number; pct?: number }\n functions?: { total?: number; covered?: number; pct?: number }\n branches?: { total?: number; covered?: number; pct?: number }\n }\n }\n const totals = summary.total ?? {}\n const testRunSummary = await readIntegrationTestRunSummary()\n const output = {\n generatedAt: new Date().toISOString(),\n reportDirectory: normalizePath(path.relative(projectRootDirectory, coveragePaths.reportDirectory)),\n rawCoverageDirectory: normalizePath(path.relative(projectRootDirectory, coveragePaths.rawDirectory)),\n testRun: testRunSummary,\n totals: {\n lines: totals.lines ?? null,\n statements: totals.statements ?? null,\n functions: totals.functions ?? null,\n branches: totals.branches ?? null,\n },\n }\n\n const linePct = output.totals.lines?.pct ?? 0\n const statementPct = output.totals.statements?.pct ?? 0\n const functionPct = output.totals.functions?.pct ?? 0\n const branchPct = output.totals.branches?.pct ?? 0\n const lineCovered = output.totals.lines?.covered ?? 0\n const lineTotal = output.totals.lines?.total ?? 0\n const statementCovered = output.totals.statements?.covered ?? 0\n const statementTotal = output.totals.statements?.total ?? 0\n const functionCovered = output.totals.functions?.covered ?? 0\n const functionTotal = output.totals.functions?.total ?? 0\n const branchCovered = output.totals.branches?.covered ?? 0\n const branchTotal = output.totals.branches?.total ?? 0\n\n if (!options.keepRawV8) {\n await rm(coveragePaths.rawDirectory, { recursive: true, force: true })\n }\n\n console.log('[coverage] Coverage totals:')\n console.log(` lines: ${lineCovered}/${lineTotal} (${linePct}%)`)\n console.log(` statements: ${statementCovered}/${statementTotal} (${statementPct}%)`)\n console.log(` functions: ${functionCovered}/${functionTotal} (${functionPct}%)`)\n console.log(` branches: ${branchCovered}/${branchTotal} (${branchPct}%)`)\n logIntegrationTestRunSummary(output.testRun)\n console.log(`[coverage] HTML report: ${output.reportDirectory}/index.html`)\n\n if (options.json) {\n console.log(JSON.stringify(output, null, 2))\n if (testRunError) {\n throw testRunError\n }\n return\n }\n\n console.log(`[coverage] Code coverage summary: lines=${linePct}%, statements=${statementPct}%, functions=${functionPct}%, branches=${branchPct}%`)\n logIntegrationTestRunOneLineSummary(output.testRun)\n console.log('[coverage] Use --json for machine-readable output or --keep-raw-v8 to keep raw process coverage files.')\n\n if (testRunError) {\n throw testRunError\n }\n}\n\nasync function runPlaywrightSelection(\n environment: EphemeralEnvironmentHandle,\n selection: string | string[] | null,\n options: PlaywrightRunOptions,\n): Promise<void> {\n const args = ['playwright', 'test', '--config', PLAYWRIGHT_INTEGRATION_CONFIG_PATH]\n if (options.workers !== null) {\n args.push('--workers', String(options.workers))\n }\n if (options.retries !== null) {\n args.push('--retries', String(options.retries))\n }\n if (options.shard) {\n args.push('--shard', options.shard)\n }\n if (Array.isArray(selection) && selection.length > 0) {\n args.push(...selection)\n } else if (typeof selection === 'string' && selection.length > 0) {\n args.push(selection)\n }\n await runNpxCommandWithOutputMonitoring(args, environment.commandEnvironment, {\n detectEnvironmentUnavailable: true,\n abortOnEnvironmentUnavailable: true,\n playwrightFailureHealthCheck: {\n baseUrl: environment.baseUrl,\n },\n })\n}\n\ntype IntegrationTestRunResult = {\n retried: boolean\n error: Error | null\n}\n\nasync function runIntegrationTestSuiteOnce(\n environment: EphemeralEnvironmentHandle,\n options: IntegrationOptions,\n): Promise<void> {\n const testArgs = ['test:integration']\n if (options.filter) {\n testArgs.push(options.filter)\n }\n await runYarnCommandWithOutputMonitoring(testArgs, environment.commandEnvironment, {\n detectEnvironmentUnavailable: true,\n abortOnEnvironmentUnavailable: true,\n playwrightFailureHealthCheck: {\n baseUrl: environment.baseUrl,\n },\n })\n}\n\nasync function isEnvironmentUnavailable(baseUrl: string): Promise<boolean> {\n const readiness = await probeApplicationReadiness(baseUrl)\n return !readiness.ready\n}\n\nfunction isEnvironmentUnavailableError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false\n }\n return (error as IntegrationCommandError).environmentUnavailableFromOutput === true\n}\n\nfunction normalizeError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error))\n}\n\nasync function runIntegrationTestAttempt(\n environment: EphemeralEnvironmentHandle,\n integrationOptions: IntegrationOptions,\n prepareTestEnvironment: (environment: EphemeralEnvironmentHandle) => Promise<void>,\n): Promise<Error | null> {\n try {\n await prepareTestEnvironment(environment)\n await runIntegrationTestSuiteOnce(environment, integrationOptions)\n return null\n } catch (error) {\n return normalizeError(error)\n }\n}\n\nasync function detectEnvironmentFailure(\n error: Error,\n baseUrl: string,\n): Promise<{ unavailable: boolean; fromOutput: boolean }> {\n const fromOutput = isEnvironmentUnavailableError(error)\n if (fromOutput) {\n return { unavailable: true, fromOutput: true }\n }\n return {\n unavailable: await isEnvironmentUnavailable(baseUrl),\n fromOutput: false,\n }\n}\n\nasync function runIntegrationTestSuiteWithRecovery(\n startOptions: Pick<EphemeralRuntimeOptions, 'verbose' | 'captureScreenshots' | 'forceRebuild' | 'reuseExisting'>,\n integrationOptions: IntegrationOptions,\n prepareTestEnvironment: (environment: EphemeralEnvironmentHandle) => Promise<void>,\n): Promise<{\n environment: EphemeralEnvironmentHandle\n testRunResult: IntegrationTestRunResult\n}> {\n let environment = await startEphemeralEnvironment({\n ...startOptions,\n logPrefix: 'integration',\n })\n\n const firstAttemptError = await runIntegrationTestAttempt(environment, integrationOptions, prepareTestEnvironment)\n if (!firstAttemptError) {\n return { environment, testRunResult: { retried: false, error: null } }\n }\n\n const failure = await detectEnvironmentFailure(firstAttemptError, environment.baseUrl)\n if (!failure.unavailable) {\n return { environment, testRunResult: { retried: false, error: firstAttemptError } }\n }\n\n if (failure.fromOutput) {\n console.error('[integration] Playwright output indicates connection loss to the app. Restarting environment.')\n }\n console.error('[integration] The ephemeral integration environment became unreachable while tests were running.')\n console.error('[integration] Rebuilding ephemeral environment and rerunning tests.')\n\n try {\n await environment.stop()\n } catch (stopError) {\n console.error(`[integration] Failed to stop old ephemeral environment before restart: ${normalizeError(stopError).message}`)\n }\n\n environment = await startEphemeralEnvironment({\n ...startOptions,\n logPrefix: 'integration',\n })\n const retryError = await runIntegrationTestAttempt(environment, integrationOptions, prepareTestEnvironment)\n return {\n environment,\n testRunResult: {\n retried: true,\n error: retryError,\n },\n }\n}\n\nasync function openIntegrationHtmlReport(environment: EphemeralEnvironmentHandle): Promise<void> {\n await runNpxCommand(['playwright', 'show-report', '.ai/qa/test-results/html'], environment.commandEnvironment)\n}\n\nasync function promptAfterRun(\n rl: Interface,\n environment: EphemeralEnvironmentHandle,\n): Promise<'menu' | 'quit'> {\n const followUpChoice = (\n await rl.question(\n '\\n[interactive] \uD83D\uDD01 Press any key then Enter to return to menu, \uD83D\uDCCA \"h\" for HTML report, or \uD83D\uDEAA \"q\" to quit: ',\n )\n )\n .trim()\n .toLowerCase()\n\n if (followUpChoice === 'h') {\n console.log('[interactive] \uD83D\uDCCA Opening HTML report...')\n try {\n await openIntegrationHtmlReport(environment)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Failed to open report: ${message}`)\n }\n return 'menu'\n }\n\n if (followUpChoice === 'q') {\n return 'quit'\n }\n\n return 'menu'\n}\n\nexport async function startEphemeralEnvironment(options: EphemeralRuntimeOptions): Promise<EphemeralEnvironmentHandle> {\n assertNode24Runtime()\n\n // Auto-detect Docker socket from active context for non-standard setups (e.g., Colima)\n const dockerConfig = await resolveDockerHostFromContext(options.logPrefix)\n if (dockerConfig) {\n process.env.DOCKER_HOST = dockerConfig.dockerHost\n process.env.TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE = dockerConfig.socketOverride\n }\n\n await assertContainerRuntimeAvailable()\n\n const setupLock = await acquireEphemeralEnvironmentLock(options.logPrefix)\n try {\n const existingStateBeforeReuseAttempt = await readEphemeralEnvironmentState()\n if (options.reuseExisting === false) {\n console.log(\n `[${options.logPrefix}] --no-reuse-env enabled. Skipping reuse checks and starting a new ephemeral environment.`,\n )\n }\n if (options.reuseExisting !== false) {\n const existingEnvironment = await tryReuseExistingEnvironment(options)\n if (existingEnvironment) {\n return existingEnvironment\n }\n }\n\n const shouldUseIsolatedPort = shouldUseIsolatedPortForFreshEnvironment({\n reuseExisting: options.reuseExisting,\n existingStateBeforeReuseAttempt,\n })\n const applicationPort = shouldUseIsolatedPort\n ? await getFreePort()\n : await getPreferredPort(DEFAULT_EPHEMERAL_APP_PORT)\n if (options.reuseExisting === false) {\n console.log(\n `[${options.logPrefix}] Starting a fresh ephemeral instance on isolated port ${applicationPort} because --no-reuse-env is enabled.`,\n )\n } else if (shouldUseIsolatedPort) {\n console.log(\n `[${options.logPrefix}] Existing ephemeral environment could not be reused. Starting a fresh instance on isolated port ${applicationPort}.`,\n )\n }\n const applicationBaseUrl = `http://127.0.0.1:${applicationPort}`\n const databaseName = 'mercato_test'\n const databaseUser = 'mercato'\n const databasePassword = 'secret'\n\n const databaseContainer = await new GenericContainer('postgres:16')\n .withEnvironment({\n POSTGRES_DB: databaseName,\n POSTGRES_USER: databaseUser,\n POSTGRES_PASSWORD: databasePassword,\n })\n .withExposedPorts(5432)\n .start()\n\n const databaseHost = databaseContainer.getHost()\n const databasePort = databaseContainer.getMappedPort(5432)\n const databaseUrl = `postgres://${databaseUser}:${databasePassword}@${databaseHost}:${databasePort}/${databaseName}`\n await rm(EPHEMERAL_CACHE_DB_PATH, { force: true }).catch(() => undefined)\n await rm(EPHEMERAL_QUEUE_BASE_DIR, { recursive: true, force: true }).catch(() => undefined)\n const enterpriseModulesFlag = process.env.OM_ENABLE_ENTERPRISE_MODULES ?? 'false'\n const commandEnvironment = buildEnvironment({\n DATABASE_URL: databaseUrl,\n CACHE_STRATEGY: 'sqlite',\n CACHE_SQLITE_PATH: EPHEMERAL_CACHE_DB_PATH,\n BASE_URL: applicationBaseUrl,\n APP_URL: applicationBaseUrl,\n NEXT_PUBLIC_APP_URL: applicationBaseUrl,\n JWT_SECRET: process.env.JWT_SECRET ?? 'om-ephemeral-integration-jwt-secret',\n OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? 'om-ephemeral-integration-mfa-setup-secret',\n NODE_ENV: 'production',\n DB_POOL_MIN: '0',\n DB_POOL_MAX: '5',\n DB_POOL_IDLE_TIMEOUT: '1000',\n DB_POOL_ACQUIRE_TIMEOUT: '10000',\n DB_IDLE_SESSION_TIMEOUT_MS: '30000',\n DB_IDLE_IN_TRANSACTION_TIMEOUT_MS: '30000',\n OM_INTEGRATION_TEST: 'true',\n OM_ENABLE_ENTERPRISE_MODULES: enterpriseModulesFlag,\n OM_ENABLE_ENTERPRISE_MODULES_SSO: process.env.OM_ENABLE_ENTERPRISE_MODULES_SSO ?? enterpriseModulesFlag,\n OM_ENABLE_ENTERPRISE_MODULES_SECURITY: process.env.OM_ENABLE_ENTERPRISE_MODULES_SECURITY ?? enterpriseModulesFlag,\n OM_TEST_MODE: '1',\n OM_TEST_AUTH_RATE_LIMIT_MODE: 'opt-in',\n OM_DISABLE_EMAIL_DELIVERY: '1',\n OM_WEBHOOKS_ALLOW_PRIVATE_URLS: process.env.OM_WEBHOOKS_ALLOW_PRIVATE_URLS ?? '1',\n ENABLE_CRUD_API_CACHE: 'true',\n MOCK_GATEWAY_WEBHOOK_SECRET: 'open-mercato-mock-dev-webhook-secret',\n MOCK_CARRIER_WEBHOOK_SECRET: 'open-mercato-mock-dev-carrier-webhook-secret',\n NEXT_PUBLIC_OM_EXAMPLE_INJECTION_WIDGETS_ENABLED: 'true',\n NEXT_PUBLIC_UMES_DEVTOOLS: 'true',\n CI: 'true',\n TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? 'om-ephemeral-integration-fallback-key',\n AUTO_SPAWN_WORKERS: 'false',\n AUTO_SPAWN_SCHEDULER: 'false',\n OM_CLI_QUIET: '1',\n MERCATO_QUIET: '1',\n QUEUE_BASE_DIR: EPHEMERAL_QUEUE_BASE_DIR,\n NODE_NO_WARNINGS: '1',\n PORT: String(applicationPort),\n PW_CAPTURE_SCREENSHOTS: options.captureScreenshots ? '1' : '0',\n ...(options.environmentOverrides ?? {}),\n })\n\n const runtimeLock = await acquireEphemeralRuntimeLock(options.logPrefix)\n let applicationProcess: ChildProcess | null = null\n let isStopped = false\n const stop = async (): Promise<void> => {\n if (isStopped) return\n isStopped = true\n try {\n if (applicationProcess && !applicationProcess.killed) {\n applicationProcess.kill('SIGTERM')\n }\n await databaseContainer.stop()\n await clearEphemeralEnvironmentState()\n } finally {\n await runtimeLock.release()\n }\n }\n\n try {\n const appReadyTimeoutMs = resolveAppReadyTimeoutMs(options.logPrefix)\n const buildCacheTtlSeconds = resolveBuildCacheTtlSeconds(options.logPrefix)\n const environmentFingerprint = buildEnvironmentFingerprint(commandEnvironment)\n let sourceFingerprintValue: string | null = null\n let needsBuild = true\n let shouldPersistBuildCache = true\n\n try {\n sourceFingerprintValue = await buildSourceFingerprint()\n needsBuild = options.forceRebuild\n ? true\n : await shouldRebuildBuildArtifacts(buildCacheTtlSeconds, options.logPrefix, {\n environmentFingerprint,\n precomputedSourceFingerprint: sourceFingerprintValue ?? undefined,\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n shouldPersistBuildCache = false\n needsBuild = true\n sourceFingerprintValue = null\n console.warn(\n `[${options.logPrefix}] Build cache check failed (${message}). Rebuilding with cache bypass.`,\n )\n }\n\n console.log(`[${options.logPrefix}] Ephemeral database ready at ${databaseHost}:${databasePort}`)\n console.log(`[${options.logPrefix}] Initializing application data (includes migrations)...`)\n await runTimedStep(options.logPrefix, 'Initializing application data', { expectedSeconds: 45 }, async () =>\n runYarnCommand(['initialize'], commandEnvironment, {\n silent: !options.verbose,\n }, appDirectory))\n\n if (!needsBuild) {\n console.log(\n `[${options.logPrefix}] Build cache valid (within ${BUILD_CACHE_TTL_ENV_VAR}=${buildCacheTtlSeconds}s). Skipping build pipeline.`,\n )\n } else {\n if (options.forceRebuild) {\n console.log(`[${options.logPrefix}] --force-rebuild enabled. Running full build pipeline.`)\n } else {\n console.log(`[${options.logPrefix}] Build artifacts missing, stale, or out of date; rebuilding artifacts.`)\n }\n if (PROJECT_SUPPORTS_PACKAGE_BUILDS) {\n console.log(`[${options.logPrefix}] Building packages...`)\n await runTimedStep(options.logPrefix, 'Building packages', { expectedSeconds: 20 }, async () =>\n runYarnCommand(['build:packages'], commandEnvironment, {\n silent: !options.verbose,\n }))\n } else {\n console.log(`[${options.logPrefix}] Skipping package build step (no build:packages script at project root).`)\n }\n\n console.log(`[${options.logPrefix}] Regenerating module artifacts...`)\n await rm(APP_MODULES_CHECKSUM_PATH, {\n force: true,\n })\n await runTimedStep(options.logPrefix, 'Regenerating module artifacts', { expectedSeconds: 8 }, async () =>\n runYarnCommand(['generate'], commandEnvironment, {\n silent: !options.verbose,\n }, appDirectory))\n\n if (PROJECT_SUPPORTS_PACKAGE_BUILDS) {\n console.log(`[${options.logPrefix}] Rebuilding packages after generation...`)\n await runTimedStep(options.logPrefix, 'Rebuilding packages after generation', { expectedSeconds: 20 }, async () =>\n runYarnCommand(['build:packages'], commandEnvironment, {\n silent: !options.verbose,\n }))\n }\n\n console.log(`[${options.logPrefix}] Building application...`)\n await resetNextBuildOutputDirectories(options.logPrefix)\n await runTimedStep(options.logPrefix, 'Building application', { expectedSeconds: 76 }, async () =>\n runYarnCommand(['build'], commandEnvironment, {\n silent: !options.verbose,\n }, appDirectory))\n }\n\n if (shouldPersistBuildCache && sourceFingerprintValue) {\n await writeBuildCacheState(sourceFingerprintValue, { environmentFingerprint })\n }\n\n console.log(`[${options.logPrefix}] Starting application on ${applicationBaseUrl}...`)\n const startedAppProcess = startYarnCommand(['start'], commandEnvironment, {\n silent: !options.verbose,\n }, appDirectory)\n applicationProcess = startedAppProcess\n\n await runTimedStep(\n options.logPrefix,\n 'Waiting for application readiness',\n { expectedSeconds: Math.max(12, Math.ceil(appReadyTimeoutMs / 1000)) },\n async () =>\n waitForApplicationReadiness(applicationBaseUrl, startedAppProcess, {\n timeoutMs: appReadyTimeoutMs,\n }),\n )\n console.log(`[${options.logPrefix}] Application is ready at ${applicationBaseUrl}`)\n await writeEphemeralEnvironmentState({\n baseUrl: applicationBaseUrl,\n port: applicationPort,\n databaseUrl,\n queueBaseDir: EPHEMERAL_QUEUE_BASE_DIR,\n logPrefix: options.logPrefix,\n captureScreenshots: options.captureScreenshots,\n })\n return {\n baseUrl: applicationBaseUrl,\n port: applicationPort,\n databaseUrl,\n commandEnvironment,\n ownedByCurrentProcess: true,\n stop,\n }\n } catch (error) {\n await stop()\n throw error\n }\n } finally {\n await setupLock.release()\n }\n}\n\nasync function keepEnvironmentRunningForever(options: { logPrefix: string; stop: () => Promise<void> }): Promise<void> {\n const onSignal = async (signal: string): Promise<void> => {\n console.log(`[${options.logPrefix}] Received ${signal}, stopping ephemeral environment...`)\n await options.stop()\n process.exit(0)\n }\n\n process.once('SIGINT', () => void onSignal('SIGINT'))\n process.once('SIGTERM', () => void onSignal('SIGTERM'))\n await new Promise<void>(() => {})\n}\n\nexport async function runIntegrationTestsInEphemeralEnvironment(rawArgs: string[]): Promise<void> {\n const options = parseOptions(rawArgs)\n const startOptions: Pick<EphemeralRuntimeOptions, 'verbose' | 'captureScreenshots' | 'forceRebuild' | 'reuseExisting'> = {\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n forceRebuild: options.forceRebuild,\n reuseExisting: options.reuseExisting,\n }\n let environment: EphemeralEnvironmentHandle | null = null\n let testRunResult: IntegrationTestRunResult\n\n try {\n console.log('[integration] Running Playwright suite...')\n if (options.reuseExisting) {\n console.log('[integration] Checking whether an existing ephemeral environment can be reused...')\n } else {\n console.log('[integration] --no-reuse-env enabled: always booting a fresh ephemeral environment.')\n }\n const environmentState = await runIntegrationTestSuiteWithRecovery(\n startOptions,\n options,\n async (runtimeEnvironment) => {\n console.log('[integration] Ensuring Playwright Chromium is installed...')\n await runNpxCommand(['playwright', 'install', 'chromium'], runtimeEnvironment.commandEnvironment)\n },\n )\n environment = environmentState.environment\n testRunResult = environmentState.testRunResult\n\n if (!environment.ownedByCurrentProcess) {\n console.log('[integration] Attached to an already running ephemeral environment from .ai/qa/ephemeral-env.json.')\n }\n if (testRunResult.retried) {\n console.log('[integration] Retried integration tests after restarting ephemeral environment.')\n }\n const effectiveCaptureScreenshots = environment.commandEnvironment.PW_CAPTURE_SCREENSHOTS === '1'\n console.log(\n `[integration] Screenshot capture is ${effectiveCaptureScreenshots ? 'enabled' : 'disabled'} (override with --screenshots / --no-screenshots)`,\n )\n\n if (testRunResult.error) {\n throw testRunResult.error\n }\n\n if (options.keep) {\n console.log('[integration] --keep enabled: leaving app and database running. Press Ctrl+C to stop.')\n await keepEnvironmentRunningForever({\n logPrefix: 'integration',\n stop: environment.stop,\n })\n }\n } finally {\n if (!options.keep) {\n await environment?.stop()\n }\n }\n}\n\nexport async function runEphemeralAppForQa(rawArgs: string[]): Promise<void> {\n const options = parseEphemeralAppOptions(rawArgs)\n const environment = await startEphemeralEnvironment({\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n forceRebuild: options.forceRebuild,\n reuseExisting: options.reuseExisting,\n logPrefix: 'ephemeral',\n })\n\n console.log(`[ephemeral] Ready for QA exploration at ${environment.baseUrl}`)\n console.log('[ephemeral] Use Playwright MCP against this URL to avoid interference with other local instances.')\n console.log('[ephemeral] Default credentials: admin@acme.com / secret')\n if (environment.ownedByCurrentProcess) {\n console.log('[ephemeral] Press Ctrl+C to stop.')\n } else {\n console.log('[ephemeral] Reused existing environment. Press Ctrl+C to exit without stopping the shared runtime.')\n }\n\n await keepEnvironmentRunningForever({\n logPrefix: 'ephemeral',\n stop: environment.stop,\n })\n}\n\nexport async function runInteractiveIntegrationInEphemeralEnvironment(rawArgs: string[]): Promise<void> {\n const options = parseInteractiveIntegrationOptions(rawArgs)\n const environment = await startEphemeralEnvironment({\n verbose: options.verbose,\n captureScreenshots: options.captureScreenshots,\n forceRebuild: options.forceRebuild,\n reuseExisting: options.reuseExisting,\n logPrefix: 'interactive',\n })\n\n const rl = createInterface({ input, output })\n let specFiles = await listIntegrationSpecFiles()\n let activeFilter = ''\n\n console.log('[interactive] \uD83C\uDFAF Integration menu ready.')\n if (!environment.ownedByCurrentProcess) {\n console.log('[interactive] \uD83D\uDD01 Reusing existing environment from .ai/qa/ephemeral-env.json.')\n }\n console.log(`[interactive] \uD83C\uDF10 Running against ${environment.baseUrl}`)\n console.log('[interactive] \u2328\uFE0F Enter a number to run, type text (for example \"crm\") to filter, \"a\" to clear filter, \"r\" to refresh, \"h\" for HTML report, \"q\" to quit.')\n\n try {\n while (true) {\n const normalizedFilter = activeFilter.trim().toLowerCase()\n const visibleTargets = normalizedFilter.length === 0\n ? specFiles\n : specFiles.filter((target) => {\n const haystack = `${target.path} ${target.description}`.toLowerCase()\n return haystack.includes(normalizedFilter)\n })\n\n console.log('\\n[interactive] \uD83D\uDCDA Available targets:')\n if (normalizedFilter.length > 0) {\n console.log(` \uD83D\uDD0E Filter: \"${activeFilter}\" (${visibleTargets.length}/${specFiles.length})`)\n }\n if (normalizedFilter.length > 0) {\n console.log(` 0) Run all filtered tests (${visibleTargets.length})`)\n } else {\n console.log(' 0) Run all tests')\n }\n visibleTargets.forEach((target, index) => {\n console.log(` ${index + 1}) ${target.path} - ${target.description}`)\n })\n console.log(' h) Open HTML report')\n console.log(' a) Clear filter')\n console.log(' r) Refresh test list')\n console.log(' q) Quit')\n\n const rawChoice = (await rl.question('\\n[interactive] \uD83D\uDC49 Select option: ')).trim()\n if (!rawChoice) {\n continue\n }\n\n const normalizedChoice = rawChoice.toLowerCase()\n if (normalizedChoice === 'q') {\n break\n }\n if (normalizedChoice === 'r') {\n specFiles = await listIntegrationSpecFiles()\n if (activeFilter.trim().length > 0) {\n console.log(`[interactive] \uD83D\uDD04 Refreshed test list (${specFiles.length} files), keeping filter \"${activeFilter}\".`)\n } else {\n console.log(`[interactive] \uD83D\uDD04 Refreshed test list (${specFiles.length} files).`)\n }\n continue\n }\n if (normalizedChoice === 'a') {\n activeFilter = ''\n console.log('[interactive] \uD83E\uDDF9 Filter cleared.')\n console.log(`[interactive] \uD83D\uDD04 Refreshed test list (${specFiles.length} files).`)\n continue\n }\n if (normalizedChoice === 'h') {\n console.log('[interactive] \uD83D\uDCCA Opening HTML report...')\n try {\n await openIntegrationHtmlReport(environment)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Failed to open report: ${message}`)\n }\n continue\n }\n\n const parsedIndex = Number.parseInt(rawChoice, 10)\n if (!Number.isFinite(parsedIndex) || parsedIndex < 0) {\n activeFilter = rawChoice\n const filteredCount = specFiles.filter((target) => {\n const haystack = `${target.path} ${target.description}`.toLowerCase()\n return haystack.includes(activeFilter.trim().toLowerCase())\n }).length\n if (filteredCount === 0) {\n console.error(`[interactive] \u26A0\uFE0F No tests matched filter \"${activeFilter}\".`)\n } else {\n console.log(`[interactive] \uD83D\uDD0E Filtered list to \"${activeFilter}\" (${filteredCount} matches).`)\n }\n continue\n }\n\n if (parsedIndex === 0) {\n if (normalizedFilter.length > 0) {\n if (visibleTargets.length === 0) {\n console.error(`[interactive] \u26A0\uFE0F No tests matched filter \"${activeFilter}\".`)\n continue\n }\n console.log(\n `[interactive] \uD83E\uDDEA Running ${visibleTargets.length} filtered test(s) for \"${activeFilter}\"...`,\n )\n try {\n await runPlaywrightSelection(\n environment,\n visibleTargets.map((target) => target.path),\n options,\n )\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Test run failed: ${message}`)\n }\n } else {\n console.log('[interactive] \uD83E\uDDEA Running full integration suite...')\n try {\n await runPlaywrightSelection(environment, null, options)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Test run failed: ${message}`)\n }\n }\n const nextAction = await promptAfterRun(rl, environment)\n if (nextAction === 'quit') {\n break\n }\n continue\n }\n\n const selectedTarget = visibleTargets[parsedIndex - 1]\n if (!selectedTarget) {\n console.error(`[interactive] \u26A0\uFE0F Selection out of range: ${parsedIndex}`)\n continue\n }\n\n console.log(`[interactive] \uD83E\uDDEA Running ${selectedTarget.path}...`)\n try {\n await runPlaywrightSelection(environment, selectedTarget.path, options)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`[interactive] \u274C Test run failed: ${message}`)\n }\n const nextAction = await promptAfterRun(rl, environment)\n if (nextAction === 'quit') {\n break\n }\n }\n } finally {\n rl.close()\n await environment.stop()\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["output", "input", "coveragePercent", "environment", "nextAction"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/cli",
3
- "version": "0.6.3-develop.3562.1.71049275ff",
3
+ "version": "0.6.3-develop.3574.1.f3c5dcf345",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -59,8 +59,8 @@
59
59
  "@mikro-orm/decorators": "^7.0.17",
60
60
  "@mikro-orm/migrations": "^7.0.17",
61
61
  "@mikro-orm/postgresql": "^7.0.17",
62
- "@open-mercato/queue": "0.6.3-develop.3562.1.71049275ff",
63
- "@open-mercato/shared": "0.6.3-develop.3562.1.71049275ff",
62
+ "@open-mercato/queue": "0.6.3-develop.3574.1.f3c5dcf345",
63
+ "@open-mercato/shared": "0.6.3-develop.3574.1.f3c5dcf345",
64
64
  "cross-spawn": "^7.0.6",
65
65
  "pg": "8.21.0",
66
66
  "semver": "^7.8.0",
@@ -70,10 +70,10 @@
70
70
  "typescript": "^6.0.3"
71
71
  },
72
72
  "peerDependencies": {
73
- "@open-mercato/shared": "0.6.3-develop.3562.1.71049275ff"
73
+ "@open-mercato/shared": "0.6.3-develop.3574.1.f3c5dcf345"
74
74
  },
75
75
  "devDependencies": {
76
- "@open-mercato/shared": "0.6.3-develop.3562.1.71049275ff",
76
+ "@open-mercato/shared": "0.6.3-develop.3574.1.f3c5dcf345",
77
77
  "@types/jest": "^30.0.0",
78
78
  "jest": "^30.4.2",
79
79
  "ts-jest": "^29.4.9"
@@ -78,6 +78,7 @@ const resolveBuildCacheFingerprint = async (
78
78
  }
79
79
 
80
80
  describe('integration cache and options', () => {
81
+ const REUSE_ENV_TEST_TIMEOUT_MS = 60000
81
82
  const ephemeralEnvFilePath = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.json')
82
83
  const ephemeralLegacyEnvFilePath = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.md')
83
84
  const originalCacheTtl = process.env[CACHE_TTL_ENV_VAR]
@@ -130,12 +131,20 @@ describe('integration cache and options', () => {
130
131
  await writeEphemeralEnvironmentState({
131
132
  baseUrl,
132
133
  port: 5001,
134
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
135
+ queueBaseDir: '/tmp/open-mercato-queue',
133
136
  logPrefix: 'integration',
134
137
  captureScreenshots: true,
135
138
  })
136
139
 
137
140
  const state = await readEphemeralEnvironmentState()
138
- expect(state).toMatchObject({ baseUrl, port: 5001, captureScreenshots: true })
141
+ expect(state).toMatchObject({
142
+ baseUrl,
143
+ port: 5001,
144
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
145
+ queueBaseDir: '/tmp/open-mercato-queue',
146
+ captureScreenshots: true,
147
+ })
139
148
 
140
149
  const environment = await tryReuseExistingEnvironment({
141
150
  verbose: false,
@@ -151,12 +160,16 @@ describe('integration cache and options', () => {
151
160
  ownedByCurrentProcess: false,
152
161
  })
153
162
  expect(environment?.commandEnvironment.OM_INTEGRATION_TEST).toBe('true')
163
+ expect(environment?.commandEnvironment.DATABASE_URL).toBe(
164
+ 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
165
+ )
166
+ expect(environment?.commandEnvironment.QUEUE_BASE_DIR).toBe('/tmp/open-mercato-queue')
154
167
  expect(environment?.commandEnvironment.PW_CAPTURE_SCREENSHOTS).toBe('1')
155
168
  expect(environment?.commandEnvironment.NEXT_PUBLIC_OM_EXAMPLE_CHECKOUT_TEST_INJECTIONS_ENABLED).toBeUndefined()
156
169
  } finally {
157
170
  fetchSpy.mockRestore()
158
171
  }
159
- }, 60000)
172
+ }, REUSE_ENV_TEST_TIMEOUT_MS)
160
173
 
161
174
  it('reuses an existing environment with checkout wrapper injections only when explicitly enabled', async () => {
162
175
  const baseUrl = 'http://127.0.0.1:5001'
@@ -167,6 +180,8 @@ describe('integration cache and options', () => {
167
180
  await writeEphemeralEnvironmentState({
168
181
  baseUrl,
169
182
  port: 5001,
183
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
184
+ queueBaseDir: '/tmp/open-mercato-queue',
170
185
  logPrefix: 'integration',
171
186
  captureScreenshots: true,
172
187
  })
@@ -184,7 +199,7 @@ describe('integration cache and options', () => {
184
199
  } finally {
185
200
  fetchSpy.mockRestore()
186
201
  }
187
- }, 60000)
202
+ }, REUSE_ENV_TEST_TIMEOUT_MS)
188
203
 
189
204
  it('reuses an existing environment when /login returns a redirect status other than 302', async () => {
190
205
  const baseUrl = 'http://127.0.0.1:5001'
@@ -196,6 +211,8 @@ describe('integration cache and options', () => {
196
211
  await writeEphemeralEnvironmentState({
197
212
  baseUrl,
198
213
  port: 5001,
214
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
215
+ queueBaseDir: '/tmp/open-mercato-queue',
199
216
  logPrefix: 'integration',
200
217
  captureScreenshots: true,
201
218
  })
@@ -216,7 +233,7 @@ describe('integration cache and options', () => {
216
233
  } finally {
217
234
  fetchSpy.mockRestore()
218
235
  }
219
- }, 60000)
236
+ }, REUSE_ENV_TEST_TIMEOUT_MS)
220
237
 
221
238
  it('reuses an existing environment when /login returns healthy HTML without static asset references', async () => {
222
239
  const baseUrl = 'http://127.0.0.1:5001'
@@ -231,6 +248,8 @@ describe('integration cache and options', () => {
231
248
  await writeEphemeralEnvironmentState({
232
249
  baseUrl,
233
250
  port: 5001,
251
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
252
+ queueBaseDir: '/tmp/open-mercato-queue',
234
253
  logPrefix: 'integration',
235
254
  captureScreenshots: false,
236
255
  })
@@ -251,7 +270,7 @@ describe('integration cache and options', () => {
251
270
  } finally {
252
271
  fetchSpy.mockRestore()
253
272
  }
254
- }, 60000)
273
+ }, REUSE_ENV_TEST_TIMEOUT_MS)
255
274
 
256
275
  it('falls back to rebuilding when the ephemeral environment state is unreachable', async () => {
257
276
  const baseUrl = 'http://127.0.0.1:5001'
@@ -261,6 +280,8 @@ describe('integration cache and options', () => {
261
280
  await writeEphemeralEnvironmentState({
262
281
  baseUrl,
263
282
  port: 5001,
283
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
284
+ queueBaseDir: '/tmp/open-mercato-queue',
264
285
  logPrefix: 'integration',
265
286
  captureScreenshots: false,
266
287
  })
@@ -289,6 +310,8 @@ describe('integration cache and options', () => {
289
310
  await writeEphemeralEnvironmentState({
290
311
  baseUrl,
291
312
  port: 5001,
313
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
314
+ queueBaseDir: '/tmp/open-mercato-queue',
292
315
  logPrefix: 'integration',
293
316
  captureScreenshots: true,
294
317
  })
@@ -138,6 +138,8 @@ type EphemeralEnvironmentState = {
138
138
  status: 'running'
139
139
  baseUrl: string
140
140
  port: number
141
+ databaseUrl: string
142
+ queueBaseDir: string
141
143
  source: string
142
144
  captureScreenshots: boolean
143
145
  startedAt: string
@@ -1168,6 +1170,8 @@ async function getPreferredPort(preferredPort: number): Promise<number> {
1168
1170
  export async function writeEphemeralEnvironmentState(input: {
1169
1171
  baseUrl: string
1170
1172
  port: number
1173
+ databaseUrl: string
1174
+ queueBaseDir: string
1171
1175
  logPrefix: string
1172
1176
  captureScreenshots: boolean
1173
1177
  }): Promise<void> {
@@ -1175,6 +1179,8 @@ export async function writeEphemeralEnvironmentState(input: {
1175
1179
  status: 'running',
1176
1180
  baseUrl: input.baseUrl,
1177
1181
  port: input.port,
1182
+ databaseUrl: input.databaseUrl,
1183
+ queueBaseDir: input.queueBaseDir,
1178
1184
  source: input.logPrefix,
1179
1185
  captureScreenshots: input.captureScreenshots,
1180
1186
  startedAt: new Date().toISOString(),
@@ -1219,6 +1225,12 @@ export async function readEphemeralEnvironmentState(): Promise<EphemeralEnvironm
1219
1225
  if (typeof record.port !== 'number' || !Number.isFinite(record.port) || record.port < 1) {
1220
1226
  return null
1221
1227
  }
1228
+ if (typeof record.databaseUrl !== 'string' || record.databaseUrl.length === 0) {
1229
+ return null
1230
+ }
1231
+ if (typeof record.queueBaseDir !== 'string' || record.queueBaseDir.length === 0) {
1232
+ return null
1233
+ }
1222
1234
  if (typeof record.source !== 'string' || record.source.length === 0) {
1223
1235
  return null
1224
1236
  }
@@ -1233,6 +1245,8 @@ export async function readEphemeralEnvironmentState(): Promise<EphemeralEnvironm
1233
1245
  status: 'running',
1234
1246
  baseUrl: record.baseUrl,
1235
1247
  port: record.port,
1248
+ databaseUrl: record.databaseUrl,
1249
+ queueBaseDir: record.queueBaseDir,
1236
1250
  source: record.source,
1237
1251
  captureScreenshots: record.captureScreenshots,
1238
1252
  startedAt: record.startedAt,
@@ -1614,9 +1628,15 @@ export async function acquireEphemeralRuntimeLock(
1614
1628
  }
1615
1629
  }
1616
1630
 
1617
- function buildReusableEnvironment(baseUrl: string, captureScreenshots: boolean): NodeJS.ProcessEnv {
1631
+ function buildReusableEnvironment(
1632
+ baseUrl: string,
1633
+ databaseUrl: string,
1634
+ queueBaseDir: string,
1635
+ captureScreenshots: boolean,
1636
+ ): NodeJS.ProcessEnv {
1618
1637
  const enterpriseModulesFlag = process.env.OM_ENABLE_ENTERPRISE_MODULES ?? 'false'
1619
1638
  return buildEnvironment({
1639
+ DATABASE_URL: databaseUrl,
1620
1640
  BASE_URL: baseUrl,
1621
1641
  APP_URL: baseUrl,
1622
1642
  NEXT_PUBLIC_APP_URL: baseUrl,
@@ -1639,6 +1659,7 @@ function buildReusableEnvironment(baseUrl: string, captureScreenshots: boolean):
1639
1659
  TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? 'om-ephemeral-integration-fallback-key',
1640
1660
  OM_CLI_QUIET: '1',
1641
1661
  MERCATO_QUIET: '1',
1662
+ QUEUE_BASE_DIR: queueBaseDir,
1642
1663
  NODE_NO_WARNINGS: '1',
1643
1664
  PW_CAPTURE_SCREENSHOTS: captureScreenshots ? '1' : '0',
1644
1665
  })
@@ -1695,8 +1716,13 @@ export async function tryReuseExistingEnvironment(options: EphemeralRuntimeOptio
1695
1716
  return {
1696
1717
  baseUrl: state.baseUrl,
1697
1718
  port: state.port,
1698
- databaseUrl: '',
1699
- commandEnvironment: buildReusableEnvironment(state.baseUrl, state.captureScreenshots),
1719
+ databaseUrl: state.databaseUrl,
1720
+ commandEnvironment: buildReusableEnvironment(
1721
+ state.baseUrl,
1722
+ state.databaseUrl,
1723
+ state.queueBaseDir,
1724
+ state.captureScreenshots,
1725
+ ),
1700
1726
  ownedByCurrentProcess: false,
1701
1727
  stop: async () => {},
1702
1728
  }
@@ -3030,6 +3056,8 @@ export async function startEphemeralEnvironment(options: EphemeralRuntimeOptions
3030
3056
  await writeEphemeralEnvironmentState({
3031
3057
  baseUrl: applicationBaseUrl,
3032
3058
  port: applicationPort,
3059
+ databaseUrl,
3060
+ queueBaseDir: EPHEMERAL_QUEUE_BASE_DIR,
3033
3061
  logPrefix: options.logPrefix,
3034
3062
  captureScreenshots: options.captureScreenshots,
3035
3063
  })