prowl-tools 0.1.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/hunt-name.ts","../src/config/schema.ts","../src/config/loader.ts","../src/runner/visual.ts","../src/cli/program.ts","../package.json","../src/cli/commands/run.ts","../src/runner/index.ts","../src/config/interpolate.ts","../src/browser/controller.ts","../src/runner/steps.ts","../src/browser/actions.ts","../src/runner/healing.ts","../src/runner/assertions.ts","../src/runner/tracing.ts","../src/reporter/result.ts","../src/reporter/summary.ts","../src/reporter/junit.ts","../src/reporter/index.ts","../src/utils/timestamp.ts","../src/runner/history.ts","../src/cli/output.ts","../src/cli/mascot.ts","../src/cli/commands/init.ts","../src/cli/commands/login.ts","../src/cli/commands/list.ts","../src/cli/commands/watch.ts","../src/cli/watch-utils.ts","../src/cli/commands/ci.ts","../src/runner/suite.ts","../src/reporter/ci-summary.ts","../src/utils/concurrency.ts","../src/runner/flaky.ts","../src/backlog/fingerprint.ts","../src/runner/clustering.ts","../src/backlog/index.ts","../src/backlog/parse.ts","../src/backlog/write.ts","../src/cli/commands/update-baselines.ts","../src/cli/commands/analyze.ts","../src/analyzer/index.ts","../src/cli/commands/generate.ts","../src/generator/index.ts","../src/generator/prompt.ts","../src/generator/ai.ts","../src/cli/commands/history.ts","../src/cli/commands/flaky.ts","../src/cli/commands/mcp.ts","../src/mcp/server.ts","../src/mcp/tools.ts","../src/mcp/projects.ts","../src/cli/index.ts"],"sourcesContent":["const HUNT_NAME_PATTERN = /^[A-Za-z0-9_-]+(?:\\/[A-Za-z0-9_-]+)*$/;\n\nexport function isValidHuntName(name: string): boolean {\n return HUNT_NAME_PATTERN.test(name);\n}\n\nexport function assertValidHuntName(name: string): void {\n if (!isValidHuntName(name)) {\n throw new Error(\n `Invalid hunt name: \"${name}\". Use only letters, numbers, hyphens, underscores, and forward slashes.`\n );\n }\n}\n","import { z } from \"zod\";\nimport type { Step } from \"../types/index.js\";\nimport { isValidHuntName } from \"./hunt-name.js\";\n\nexport const configSchema = z\n .object({\n target: z.object({\n url: z.string().min(1)\n }),\n browser: z\n .object({\n headless: z.boolean().optional(),\n slowMo: z.number().optional(),\n timeout: z.number().optional(),\n engine: z.enum([\"chromium\", \"firefox\", \"webkit\"]).optional(),\n channel: z.enum([\n \"chromium\",\n \"chrome\", \"chrome-beta\", \"chrome-canary\", \"chrome-dev\",\n \"msedge\", \"msedge-beta\", \"msedge-canary\", \"msedge-dev\"\n ]).optional(),\n viewport: z\n .union([\n z.enum([\"mobile\", \"tablet\", \"desktop\"]),\n z.object({ width: z.number().int().positive(), height: z.number().int().positive() }).strict()\n ])\n .optional()\n })\n .optional(),\n artifacts: z\n .object({\n screenshots: z.enum([\"on-failure\", \"all\"]).optional(),\n networkHar: z.boolean().optional(),\n console: z.boolean().optional(),\n junit: z.boolean().optional()\n })\n .optional(),\n assertions: z\n .object({\n noConsoleErrors: z.boolean().optional(),\n noNetworkErrors: z.boolean().optional(),\n maxTotalTimeMs: z.number().optional(),\n networkIgnorePatterns: z.array(z.string()).optional()\n })\n .optional(),\n guardrails: z\n .object({\n maxSteps: z.number().optional(),\n allowedDomains: z.array(z.string()).optional(),\n forbiddenSelectors: z.array(z.string()).optional(),\n selfHealing: z.boolean().optional()\n })\n .optional(),\n auth: z\n .object({\n storageStatePath: z.string().optional()\n })\n .optional(),\n history: z\n .object({\n maxRuns: z.number().int().positive().optional()\n })\n .optional(),\n bugLog: z\n .object({\n enabled: z.boolean().optional(),\n backlogPath: z.string().min(1).optional(),\n resolvedPath: z.string().min(1).optional()\n })\n .strict()\n .optional(),\n tracing: z\n .object({\n header: z.string().min(1).optional()\n })\n .strict()\n .optional(),\n reliability: z\n .object({\n flakyThreshold: z.number().min(0).max(1).optional()\n })\n .strict()\n .optional()\n })\n .strict();\n\nexport const navigateStepSchema = z.object({ navigate: z.string().min(1) }).strict();\nexport const clickStepSchema = z\n .object({\n click: z.union([z.object({ selector: z.string().min(1) }).strict(), z.string().min(1)])\n })\n .strict();\n\nconst singleKeyValueSchema = z\n .record(z.string().min(1), z.string())\n .refine((record) => Object.keys(record).length === 1, {\n message: \"Expected exactly one key-value pair\"\n });\n\nexport const fillStepSchema = z\n .object({\n fill: z.union([\n z.object({ selector: z.string().min(1), value: z.string() }).strict(),\n singleKeyValueSchema\n ])\n })\n .strict();\nexport const typeStepSchema = z.object({ type: z.string() }).strict();\nexport const pressStepSchema = z\n .object({\n press: z.object({ selector: z.string().min(1), key: z.string().min(1) }).strict()\n })\n .strict();\nexport const waitForSelectorStepSchema = z\n .object({\n waitForSelector: z\n .object({ selector: z.string().min(1), timeout: z.number().optional() })\n .strict()\n })\n .strict();\nexport const waitStepSchema = z\n .object({\n wait: z.union([\n z.string().min(1),\n z.object({ for: z.string().min(1), timeout: z.number().optional() }).strict()\n ])\n })\n .strict();\nexport const waitForUrlStepSchema = z\n .object({\n waitForUrl: z.object({ value: z.string().min(1), timeout: z.number().optional() }).strict()\n })\n .strict();\nexport const waitForNetworkIdleStepSchema = z\n .object({\n waitForNetworkIdle: z.object({ timeout: z.number().optional() }).strict()\n })\n .strict();\nexport const selectOptionStepSchema = z\n .object({\n selectOption: z.object({ selector: z.string().min(1), value: z.string() }).strict()\n })\n .strict();\nexport const selectStepSchema = z\n .object({\n select: singleKeyValueSchema\n })\n .strict();\nexport const onDialogStepSchema = z\n .object({\n onDialog: z.object({ action: z.enum([\"accept\", \"dismiss\"]) }).strict()\n })\n .strict();\nexport const setInputFilesStepSchema = z\n .object({\n setInputFiles: z\n .object({\n selector: z.string().min(1),\n files: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)])\n })\n .strict()\n })\n .strict();\nexport const inlineAssertStepSchema = z\n .object({\n assert: z\n .object({\n visible: z.string().min(1).optional(),\n notVisible: z.string().min(1).optional(),\n urlIncludes: z.string().min(1).optional(),\n urlEquals: z.string().min(1).optional()\n })\n .strict()\n .refine(\n (value) =>\n [value.visible, value.notVisible, value.urlIncludes, value.urlEquals].filter(\n (entry) => entry !== undefined\n ).length === 1,\n {\n message: \"assert requires exactly one of visible, notVisible, urlIncludes, urlEquals\"\n }\n )\n })\n .strict();\nexport const runHuntStepSchema = z\n .object({\n runHunt: z.union([\n z\n .string()\n .min(1)\n .refine(isValidHuntName, {\n message:\n \"Invalid hunt name. Use only letters, numbers, hyphens, underscores, and forward slashes.\"\n }),\n z\n .object({\n name: z\n .string()\n .min(1)\n .refine(isValidHuntName, {\n message:\n \"Invalid hunt name. Use only letters, numbers, hyphens, underscores, and forward slashes.\"\n }),\n vars: z.record(z.string(), z.string()).optional()\n })\n .strict()\n ])\n })\n .strict();\nexport const hoverStepSchema = z\n .object({\n hover: z.object({ selector: z.string().min(1) }).strict()\n })\n .strict();\nexport const scrollStepSchema = z\n .object({\n scroll: z\n .object({\n direction: z.enum([\"up\", \"down\", \"left\", \"right\"]),\n amount: z.number().optional()\n })\n .strict()\n })\n .strict();\nexport const scrollToStepSchema = z\n .object({\n scrollTo: z.object({ selector: z.string().min(1) }).strict()\n })\n .strict();\nexport const screenshotStepSchema = z\n .object({\n screenshot: z.object({ name: z.string().optional() }).strict()\n })\n .strict();\n\n// Recursive step schemas use z.lazy() to reference stepSchema before it's defined\nexport const ifStepSchema = z\n .object({\n if: z\n .object({\n visible: z.string().min(1).optional(),\n notVisible: z.string().min(1).optional(),\n then: z.lazy(() => z.array(stepSchema).min(1)),\n else: z.lazy(() => z.array(stepSchema).min(1)).optional()\n })\n .strict()\n .refine(\n (value) =>\n [value.visible, value.notVisible].filter((v) => v !== undefined).length === 1,\n { message: \"if requires exactly one of visible or notVisible\" }\n )\n })\n .strict();\n\nexport const repeatStepSchema = z\n .object({\n repeat: z\n .object({\n times: z.number().int().positive().optional(),\n while: z\n .object({\n visible: z.string().min(1).optional(),\n notVisible: z.string().min(1).optional()\n })\n .strict()\n .refine(\n (value) =>\n [value.visible, value.notVisible].filter((v) => v !== undefined).length === 1,\n { message: \"while requires exactly one of visible or notVisible\" }\n )\n .optional(),\n maxIterations: z.number().int().positive().optional(),\n steps: z.lazy(() => z.array(stepSchema).min(1))\n })\n .strict()\n .refine((value) => !(value.times !== undefined && value.while !== undefined), {\n message: \"repeat requires either times or while, not both\"\n })\n .refine((value) => value.times !== undefined || value.while !== undefined, {\n message: \"repeat requires either times or while\"\n })\n .refine((value) => !(value.while !== undefined && value.maxIterations === undefined), {\n message: \"while requires maxIterations\"\n })\n })\n .strict();\n\nexport const mockRouteStepSchema = z\n .object({\n mockRoute: z\n .object({\n url: z.string().min(1),\n response: z\n .object({\n status: z.number().int(),\n contentType: z.string().min(1).optional(),\n body: z.string().min(1).optional(),\n file: z.string().min(1).optional()\n })\n .strict()\n .refine(\n (value) =>\n [value.body, value.file].filter((v) => v !== undefined).length === 1,\n { message: \"response requires exactly one of body or file\" }\n )\n })\n .strict()\n })\n .strict();\n\nexport const unmockRouteStepSchema = z\n .object({\n unmockRoute: z.union([\n z.string().min(1),\n z.object({ url: z.string().min(1) }).strict()\n ])\n })\n .strict();\n\nexport const evalScriptStepSchema = z\n .object({\n evalScript: z.union([\n z.string().min(1),\n z\n .object({\n expression: z.string().min(1),\n as: z.string().min(1).optional()\n })\n .strict()\n ])\n })\n .strict();\n\nexport const runScriptStepSchema = z\n .object({\n runScript: z.object({ file: z.string().min(1) }).strict()\n })\n .strict();\n\nexport const assertScreenshotStepSchema = z\n .object({\n assertScreenshot: z\n .object({\n name: z.string().min(1),\n threshold: z.number().min(0).max(1).optional()\n })\n .strict()\n })\n .strict();\n\nexport const copyTextStepSchema = z\n .object({\n copyText: z\n .object({\n selector: z.string().min(1),\n as: z.string().min(1)\n })\n .strict()\n })\n .strict();\n\nexport const waitForDownloadStepSchema = z\n .object({\n waitForDownload: z.union([\n z\n .object({\n filename: z.string().min(1).optional(),\n timeout: z.number().int().positive().optional()\n })\n .strict(),\n z.null()\n ])\n })\n .strict();\n\nexport const stepSchema: z.ZodType<Step> = z.union([\n navigateStepSchema,\n clickStepSchema,\n fillStepSchema,\n typeStepSchema,\n pressStepSchema,\n waitStepSchema,\n selectOptionStepSchema,\n selectStepSchema,\n onDialogStepSchema,\n setInputFilesStepSchema,\n inlineAssertStepSchema,\n runHuntStepSchema,\n waitForSelectorStepSchema,\n waitForUrlStepSchema,\n waitForNetworkIdleStepSchema,\n hoverStepSchema,\n scrollStepSchema,\n scrollToStepSchema,\n screenshotStepSchema,\n ifStepSchema,\n repeatStepSchema,\n mockRouteStepSchema,\n unmockRouteStepSchema,\n evalScriptStepSchema,\n runScriptStepSchema,\n assertScreenshotStepSchema,\n copyTextStepSchema,\n waitForDownloadStepSchema\n]);\n\nexport const assertionSchema = z.union([\n z.object({ selectorExists: z.string().min(1) }).strict(),\n z.object({ selectorNotExists: z.string().min(1) }).strict(),\n z.object({ urlIncludes: z.string().min(1) }).strict(),\n z.object({ urlEquals: z.string().min(1) }).strict(),\n z.object({ noConsoleErrors: z.boolean() }).strict(),\n z.object({ noNetworkErrors: z.boolean() }).strict()\n]);\n\nexport const huntSchema = z\n .object({\n name: z.string().optional(),\n description: z.string().optional(),\n tags: z.array(z.string().min(1)).optional(),\n vars: z.record(z.string(), z.string()).optional(),\n steps: z.array(stepSchema),\n assertions: z.array(assertionSchema).optional(),\n retry: z\n .object({\n maxRetries: z.number().int().min(0),\n delay: z.number().int().min(0).optional()\n })\n .strict()\n .optional()\n })\n .strict();\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"yaml\";\nimport dotenv from \"dotenv\";\nimport type { BrowserChannel, BrowserEngine, Config, Hunt, Viewport } from \"../types/index.js\";\nimport { configSchema, huntSchema } from \"./schema.js\";\nimport { assertValidHuntName } from \"./hunt-name.js\";\n\nconst DEFAULT_CONFIG: Config = {\n target: {\n url: \"http://localhost:3000\"\n },\n browser: {\n headless: true,\n slowMo: 0,\n timeout: 30000,\n engine: \"chromium\",\n viewport: { width: 1280, height: 720 }\n },\n artifacts: {\n screenshots: \"on-failure\",\n networkHar: false,\n console: true,\n junit: false\n },\n assertions: {\n noConsoleErrors: true,\n noNetworkErrors: true,\n maxTotalTimeMs: 30000,\n networkIgnorePatterns: []\n },\n guardrails: {\n maxSteps: 50,\n allowedDomains: [\"localhost\", \"127.0.0.1\", \"0.0.0.0\"],\n forbiddenSelectors: [\"[data-danger]\", \".delete-btn\"],\n selfHealing: false\n },\n auth: {\n storageStatePath: \".prowl/auth-state.json\"\n },\n history: {\n maxRuns: 100\n }\n};\n\nexport const CONFIG_DIR = \".prowl\";\nexport const LEGACY_CONFIG_DIR = \".prowlqa\";\n\nlet legacyDirWarned = false;\n\n/** Warn (once per process) when a project still uses the legacy .prowlqa/ directory. */\nexport function warnLegacyConfigDir(): void {\n if (legacyDirWarned) {\n return;\n }\n legacyDirWarned = true;\n console.warn(\n 'Warning: the \".prowlqa/\" config directory is deprecated; rename it to \".prowl/\". ' +\n 'Support for \".prowlqa/\" will be removed in a future release.'\n );\n}\n\nexport function findConfigPath(startDir: string): string | null {\n let current = startDir;\n while (current) {\n // Prefer the new .prowl/ directory; fall back to the legacy .prowlqa/ at the same level.\n for (const dir of [CONFIG_DIR, LEGACY_CONFIG_DIR]) {\n const candidate = path.join(current, dir, \"config.yml\");\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n }\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return null;\n}\n\nconst VIEWPORT_PRESETS: Record<string, Viewport> = {\n mobile: { width: 375, height: 812 },\n tablet: { width: 768, height: 1024 },\n desktop: { width: 1280, height: 720 }\n};\n\nexport function resolveViewport(\n value: string | Viewport | undefined\n): Viewport {\n if (value === undefined) {\n return DEFAULT_CONFIG.browser.viewport;\n }\n if (typeof value === \"string\") {\n const preset = VIEWPORT_PRESETS[value];\n if (!preset) {\n throw new Error(`Unknown viewport preset: \"${value}\". Use mobile, tablet, or desktop.`);\n }\n return preset;\n }\n return value;\n}\n\nfunction mergeConfig(partial: Partial<Config>): Config {\n return {\n target: {\n url: partial.target?.url ?? DEFAULT_CONFIG.target.url\n },\n browser: {\n headless: partial.browser?.headless ?? DEFAULT_CONFIG.browser.headless,\n slowMo: partial.browser?.slowMo ?? DEFAULT_CONFIG.browser.slowMo,\n timeout: partial.browser?.timeout ?? DEFAULT_CONFIG.browser.timeout,\n engine: (partial.browser as { engine?: BrowserEngine } | undefined)?.engine ?? DEFAULT_CONFIG.browser.engine,\n channel: (partial.browser as { channel?: BrowserChannel } | undefined)?.channel,\n viewport: resolveViewport((partial.browser as { viewport?: string | Viewport } | undefined)?.viewport)\n },\n artifacts: {\n screenshots: partial.artifacts?.screenshots ?? DEFAULT_CONFIG.artifacts.screenshots,\n networkHar: partial.artifacts?.networkHar ?? DEFAULT_CONFIG.artifacts.networkHar,\n console: partial.artifacts?.console ?? DEFAULT_CONFIG.artifacts.console,\n junit: partial.artifacts?.junit ?? DEFAULT_CONFIG.artifacts.junit\n },\n assertions: {\n noConsoleErrors:\n partial.assertions?.noConsoleErrors ?? DEFAULT_CONFIG.assertions.noConsoleErrors,\n noNetworkErrors:\n partial.assertions?.noNetworkErrors ?? DEFAULT_CONFIG.assertions.noNetworkErrors,\n maxTotalTimeMs:\n partial.assertions?.maxTotalTimeMs ?? DEFAULT_CONFIG.assertions.maxTotalTimeMs,\n networkIgnorePatterns:\n partial.assertions?.networkIgnorePatterns ??\n DEFAULT_CONFIG.assertions.networkIgnorePatterns\n },\n guardrails: {\n maxSteps: partial.guardrails?.maxSteps ?? DEFAULT_CONFIG.guardrails.maxSteps,\n allowedDomains: partial.guardrails?.allowedDomains ?? DEFAULT_CONFIG.guardrails.allowedDomains,\n forbiddenSelectors:\n partial.guardrails?.forbiddenSelectors ?? DEFAULT_CONFIG.guardrails.forbiddenSelectors,\n selfHealing: partial.guardrails?.selfHealing ?? DEFAULT_CONFIG.guardrails.selfHealing\n },\n auth: {\n storageStatePath: partial.auth?.storageStatePath ?? (partial.auth !== undefined ? DEFAULT_CONFIG.auth.storageStatePath : undefined)\n },\n history: {\n maxRuns: partial.history?.maxRuns ?? DEFAULT_CONFIG.history.maxRuns\n },\n bugLog: partial.bugLog,\n tracing: partial.tracing,\n reliability: partial.reliability\n };\n}\n\nexport function ensureAllowedDomain(allowed: string[], urlValue: string): string[] {\n try {\n const host = new URL(urlValue).hostname;\n if (!allowed.includes(host)) {\n return [...allowed, host];\n }\n } catch {\n return allowed;\n }\n return allowed;\n}\n\nexport function loadConfig(configPath?: string): {\n config: Config;\n configPath: string;\n configDir: string;\n} {\n const resolvedPath = configPath\n ? path.resolve(configPath)\n : findConfigPath(process.cwd());\n\n if (!resolvedPath) {\n throw new Error(\"Could not find .prowl/config.yml. Run `prowl init` first.\");\n }\n\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`Config file not found at ${resolvedPath}`);\n }\n\n const configDir = path.dirname(resolvedPath);\n if (path.basename(configDir) === LEGACY_CONFIG_DIR) {\n warnLegacyConfigDir();\n }\n dotenv.config({ path: path.join(configDir, \".env\"), override: false });\n\n const raw = fs.readFileSync(resolvedPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n const validated = configSchema.parse(parsed);\n const config = mergeConfig(validated as Partial<Config>);\n\n config.guardrails.allowedDomains = ensureAllowedDomain(\n config.guardrails.allowedDomains,\n config.target.url\n );\n\n return { config, configPath: resolvedPath, configDir };\n}\n\nexport function loadHunt(huntName: string, configDir: string): Hunt {\n assertValidHuntName(huntName);\n const huntPath = path.join(configDir, \"hunts\", `${huntName}.yml`);\n if (!fs.existsSync(huntPath)) {\n throw new Error(`Hunt file not found: ${huntPath}`);\n }\n const raw = fs.readFileSync(huntPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n const validated = huntSchema.parse(parsed);\n return validated as Hunt;\n}\n\nexport function loadHuntTags(huntName: string, configDir: string): string[] {\n assertValidHuntName(huntName);\n const huntPath = path.join(configDir, \"hunts\", `${huntName}.yml`);\n if (!fs.existsSync(huntPath)) {\n return [];\n }\n const raw = fs.readFileSync(huntPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n return Array.isArray(parsed.tags) ? parsed.tags : [];\n}\n\nexport function loadHuntMeta(huntName: string, configDir: string): { description?: string; tags: string[] } {\n assertValidHuntName(huntName);\n const huntPath = path.join(configDir, \"hunts\", `${huntName}.yml`);\n if (!fs.existsSync(huntPath)) {\n return { tags: [] };\n }\n const raw = fs.readFileSync(huntPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n return {\n description: typeof parsed.description === \"string\" ? parsed.description : undefined,\n tags: Array.isArray(parsed.tags) ? parsed.tags : []\n };\n}\n\nexport function listHunts(configDir: string): string[] {\n const huntsDir = path.join(configDir, \"hunts\");\n if (!fs.existsSync(huntsDir)) {\n return [];\n }\n const stats = fs.statSync(huntsDir);\n if (!stats.isDirectory()) {\n throw new Error(`Hunts path is not a directory: ${huntsDir}`);\n }\n\n const results: string[] = [];\n\n function scanDir(dir: string) {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(\".yml\")) {\n const fullPath = path.join(dir, entry.name);\n const relative = path.relative(huntsDir, fullPath);\n results.push(relative.replace(/\\.yml$/, \"\"));\n } else if (entry.isDirectory()) {\n scanDir(path.join(dir, entry.name));\n }\n }\n }\n\n scanDir(huntsDir);\n return results.sort((a, b) => a.localeCompare(b));\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { PNG } from \"pngjs\";\nimport pixelmatch from \"pixelmatch\";\n\nexport type ComparisonResult = {\n match: boolean;\n diffPercentage: number;\n diffImagePath?: string;\n};\n\nexport async function compareScreenshots(\n baselinePath: string,\n currentPath: string,\n diffPath: string,\n threshold: number\n): Promise<ComparisonResult> {\n const baselineData = PNG.sync.read(fs.readFileSync(baselinePath));\n const currentData = PNG.sync.read(fs.readFileSync(currentPath));\n\n const { width, height } = baselineData;\n\n if (currentData.width !== width || currentData.height !== height) {\n const diff = new PNG({ width, height });\n fs.writeFileSync(diffPath, PNG.sync.write(diff));\n return {\n match: false,\n diffPercentage: 1,\n diffImagePath: diffPath\n };\n }\n\n const diff = new PNG({ width, height });\n const diffPixels = pixelmatch(\n baselineData.data,\n currentData.data,\n diff.data,\n width,\n height,\n { threshold: 0.1 }\n );\n\n const totalPixels = width * height;\n const diffPercentage = diffPixels / totalPixels;\n\n fs.writeFileSync(diffPath, PNG.sync.write(diff));\n\n return {\n match: diffPercentage <= threshold,\n diffPercentage,\n diffImagePath: diffPath\n };\n}\n\nexport function ensureBaselineDir(configDir: string): string {\n const baselineDir = path.join(configDir, \"baselines\");\n fs.mkdirSync(baselineDir, { recursive: true });\n return baselineDir;\n}\n","import { Command } from \"commander\";\nimport pkg from \"../../package.json\";\nimport { buildRunCommand } from \"./commands/run.js\";\nimport { buildInitCommand } from \"./commands/init.js\";\nimport { buildLoginCommand } from \"./commands/login.js\";\nimport { buildListCommand } from \"./commands/list.js\";\nimport { buildWatchCommand } from \"./commands/watch.js\";\nimport { buildCiCommand } from \"./commands/ci.js\";\nimport { buildUpdateBaselinesCommand } from \"./commands/update-baselines.js\";\nimport { buildAnalyzeCommand } from \"./commands/analyze.js\";\nimport { buildGenerateCommand } from \"./commands/generate.js\";\nimport { buildHistoryCommand } from \"./commands/history.js\";\nimport { buildFlakyCommand } from \"./commands/flaky.js\";\nimport { buildMcpCommand } from \"./commands/mcp.js\";\n\nexport const CLI_VERSION = pkg.version;\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name(\"prowl\")\n .description(\"CLI-first QA testing tool for deterministic Playwright flows\")\n .version(CLI_VERSION);\n\n program.addCommand(buildRunCommand());\n program.addCommand(buildCiCommand());\n program.addCommand(buildWatchCommand());\n program.addCommand(buildInitCommand());\n program.addCommand(buildLoginCommand());\n program.addCommand(buildListCommand());\n program.addCommand(buildUpdateBaselinesCommand());\n program.addCommand(buildAnalyzeCommand());\n program.addCommand(buildGenerateCommand());\n program.addCommand(buildHistoryCommand());\n program.addCommand(buildFlakyCommand());\n program.addCommand(buildMcpCommand());\n\n return program;\n}\n","{\n \"name\": \"prowl-tools\",\n \"version\": \"0.1.3\",\n \"description\": \"CLI-first QA testing tool for deterministic Playwright flows.\",\n \"type\": \"module\",\n \"license\": \"Apache-2.0\",\n \"author\": \"Michael Tookes\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/prowl-tools/prowl.git\"\n },\n \"homepage\": \"https://prowl.tools\",\n \"bugs\": {\n \"url\": \"https://github.com/prowl-tools/prowl/issues\"\n },\n \"keywords\": [\n \"testing\",\n \"qa\",\n \"playwright\",\n \"yaml\",\n \"e2e\",\n \"browser-testing\",\n \"automation\",\n \"web-testing\",\n \"cli\"\n ],\n \"main\": \"dist/lib.cjs\",\n \"module\": \"dist/lib.js\",\n \"types\": \"dist/lib.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/lib.d.ts\",\n \"default\": \"./dist/lib.js\"\n },\n \"require\": {\n \"types\": \"./dist/lib.d.cts\",\n \"default\": \"./dist/lib.cjs\"\n }\n }\n },\n \"bin\": {\n \"prowl\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"examples\",\n \"LICENSE\",\n \"README.md\",\n \"NOTICE\"\n ],\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"lint\": \"eslint .\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.29.0\",\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"dotenv\": \"^16.6.1\",\n \"ora\": \"^8.1.1\",\n \"pixelmatch\": \"^7.1.0\",\n \"playwright\": \"^1.50.1\",\n \"pngjs\": \"^7.0.0\",\n \"yaml\": \"^2.6.1\",\n \"zod\": \"^3.23.8\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.13.1\",\n \"@types/pngjs\": \"^6.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^7.18.0\",\n \"@typescript-eslint/parser\": \"^7.18.0\",\n \"eslint\": \"^8.57.1\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.7.3\",\n \"vitest\": \"^2.1.8\"\n }\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { runHunt } from \"../../runner/index.js\";\nimport { loadConfig, loadHuntTags } from \"../../config/loader.js\";\nimport { printHuntHeader, printStepResult, printHuntSummary } from \"../output.js\";\nimport { resultMascot } from \"../mascot.js\";\n\nexport function buildRunCommand(): Command {\n const command = new Command(\"run\")\n .argument(\"<hunt-name>\", \"Hunt name or path (e.g. homepage or admin/users-crud)\")\n .option(\"--url <target>\", \"Override target URL\")\n .option(\"--headed\", \"Show browser window\")\n .option(\"--slow-mo <ms>\", \"Slow down Playwright actions\", (value) => Number(value))\n .option(\"--trace\", \"Capture Playwright trace\")\n .option(\"--browser <engine>\", \"Browser engine: chromium, firefox, or webkit\")\n .option(\"--channel <name>\", \"Browser channel: chrome, msedge, chrome-beta, etc.\")\n .option(\"--viewport <size>\", \"Viewport size: WxH (e.g. 1920x1080) or preset (mobile, tablet, desktop)\")\n .option(\"--include-tags <tags>\", \"Only run hunts matching these tags (comma-separated)\")\n .option(\"--exclude-tags <tags>\", \"Skip hunts matching these tags (comma-separated)\")\n .option(\"--junit\", \"Generate JUnit XML report\")\n .option(\"--config <path>\", \"Custom config path\")\n .option(\"--json\", \"Output results as JSON\")\n .action(async (huntName, options) => {\n try {\n if (options.includeTags || options.excludeTags) {\n const { configDir } = loadConfig(options.config);\n const tags = loadHuntTags(huntName, configDir);\n const includeTags = options.includeTags\n ? (options.includeTags as string).split(\",\").map((t: string) => t.trim())\n : undefined;\n const excludeTags = options.excludeTags\n ? (options.excludeTags as string).split(\",\").map((t: string) => t.trim())\n : undefined;\n\n if (includeTags && !includeTags.some((t: string) => tags.includes(t))) {\n if (options.json) {\n console.log(JSON.stringify({ status: \"skipped\", hunt: huntName, reason: \"no matching include tags\" }));\n } else {\n console.log(chalk.yellow(` Skipped \"${huntName}\" — no matching include tags`));\n }\n return;\n }\n if (excludeTags && excludeTags.some((t: string) => tags.includes(t))) {\n if (options.json) {\n console.log(JSON.stringify({ status: \"skipped\", hunt: huntName, reason: \"matched exclude tags\" }));\n } else {\n console.log(chalk.yellow(` Skipped \"${huntName}\" — matched exclude tags`));\n }\n return;\n }\n }\n\n if (!options.json) {\n printHuntHeader(huntName);\n }\n\n const { result, runDir } = await runHunt({\n huntName,\n urlOverride: options.url,\n headed: Boolean(options.headed),\n slowMo: Number.isFinite(options.slowMo) ? options.slowMo : undefined,\n trace: Boolean(options.trace),\n browser: options.browser,\n channel: options.channel,\n viewport: options.viewport,\n junit: Boolean(options.junit),\n configPath: options.config,\n onStep: options.json\n ? undefined\n : (stepResult, step, index) => {\n printStepResult(stepResult, step, index);\n }\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(resultMascot(result.status, huntName));\n printHuntSummary(result, runDir);\n }\n process.exitCode = result.exitCode;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Run failed\";\n if (options.json) {\n console.log(JSON.stringify({ status: \"fail\", exitCode: 1, hunt: huntName, error: message }));\n } else {\n console.log(resultMascot(\"fail\", huntName));\n console.error(`\\n Error: ${message}\\n`);\n }\n process.exitCode = 1;\n }\n });\n\n return command;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { AssertionResult, BrowserChannel, RunResult, Step, StepResult, TraceCorrelation } from \"../types/index.js\";\nimport { loadConfig, loadHunt, ensureAllowedDomain, resolveViewport } from \"../config/loader.js\";\nimport { interpolateHunt } from \"../config/interpolate.js\";\nimport { launchBrowser, closeBrowser } from \"../browser/controller.js\";\nimport { captureFinalScreenshot, executeSteps, type StepCallback } from \"./steps.js\";\nimport { evaluateAssertions, type ConsoleEntry, type NetworkEntry } from \"./assertions.js\";\nimport { captureTraceCorrelation, DEFAULT_TRACE_HEADER } from \"./tracing.js\";\nimport { writeReports } from \"../reporter/index.js\";\nimport { timestamp } from \"../utils/timestamp.js\";\nimport { appendEntry as appendHistoryEntry } from \"./history.js\";\n\nexport type RunOptions = {\n huntName: string;\n urlOverride?: string;\n headed?: boolean;\n slowMo?: number;\n trace?: boolean;\n configPath?: string;\n onStep?: StepCallback;\n browser?: \"chromium\" | \"firefox\" | \"webkit\";\n channel?: BrowserChannel;\n viewport?: string;\n junit?: boolean;\n};\n\nfunction parseViewportFlag(value: string): string | { width: number; height: number } {\n const match = /^(\\d+)x(\\d+)$/i.exec(value);\n if (match) {\n return { width: Number(match[1]), height: Number(match[2]) };\n }\n return value;\n}\n\nfunction resolvePath(configDir: string, inputPath: string): string {\n if (path.isAbsolute(inputPath)) {\n return inputPath;\n }\n const projectRoot = path.dirname(configDir);\n return path.join(projectRoot, inputPath);\n}\n\nfunction buildRunResult(options: {\n status: \"pass\" | \"fail\";\n startedAt: string;\n durationMs: number;\n hunt: string;\n targetUrl: string;\n steps: StepResult[];\n assertions: AssertionResult[];\n artifacts: RunResult[\"artifacts\"];\n traceCorrelations?: TraceCorrelation[];\n}): RunResult {\n return {\n status: options.status,\n exitCode: options.status === \"pass\" ? 0 : 1,\n startedAt: options.startedAt,\n durationMs: options.durationMs,\n hunt: options.hunt,\n targetUrl: options.targetUrl,\n steps: options.steps,\n assertions: options.assertions,\n artifacts: options.artifacts,\n // Omit entirely when there are no correlations, so passing/clean runs stay tidy.\n ...(options.traceCorrelations && options.traceCorrelations.length > 0\n ? { traceCorrelations: options.traceCorrelations }\n : {})\n };\n}\n\nfunction writeConsoleLog(runDir: string, entries: ConsoleEntry[]): string {\n const fileName = \"console.log\";\n const filePath = path.join(runDir, fileName);\n const lines = entries.map((entry) => {\n const location = entry.location ? ` (${entry.location})` : \"\";\n return `[${entry.type}] ${entry.text}${location}`;\n });\n fs.writeFileSync(filePath, `${lines.join(\"\\n\")}\\n`);\n return fileName;\n}\n\nasync function executeHuntAttempt(\n options: RunOptions,\n config: ReturnType<typeof loadConfig>[\"config\"],\n configDir: string,\n interpolatedHunt: ReturnType<typeof interpolateHunt>[\"hunt\"],\n redactedFillSteps: Set<string>,\n randomVars: ReturnType<typeof interpolateHunt>[\"randomVars\"],\n redactionValues: readonly string[],\n targetUrl: string,\n allowedDomains: string[]\n): Promise<{ result: RunResult; runDir: string; steps: Step[] }> {\n const headless = options.headed ? false : config.browser.headless;\n const slowMo = options.slowMo ?? config.browser.slowMo;\n const maxSteps = config.guardrails.maxSteps;\n\n const runDir = path.join(configDir, \"runs\", timestamp());\n fs.mkdirSync(runDir, { recursive: true });\n\n const storageStatePath = config.auth.storageStatePath\n ? resolvePath(configDir, config.auth.storageStatePath)\n : undefined;\n\n const engine = options.browser ?? config.browser.engine;\n const channel = options.channel ?? config.browser.channel;\n const viewport = options.viewport\n ? resolveViewport(parseViewportFlag(options.viewport))\n : config.browser.viewport;\n\n const session = await launchBrowser({\n headless,\n slowMo,\n timeout: config.browser.timeout,\n storageStatePath,\n trace: Boolean(options.trace),\n recordHar: config.artifacts.networkHar,\n runDir,\n engine,\n channel,\n viewport\n });\n\n let result: RunResult;\n try {\n const consoleEntries: ConsoleEntry[] = [];\n const networkEntries: NetworkEntry[] = [];\n const traceCorrelations: TraceCorrelation[] = [];\n const traceHeader = config.tracing?.header ?? DEFAULT_TRACE_HEADER;\n\n session.page.on(\"console\", (message) => {\n consoleEntries.push({\n type: message.type(),\n text: message.text(),\n location: message.location().url\n });\n });\n\n session.page.on(\"response\", (response) => {\n if (response.status() >= 400) {\n networkEntries.push({ url: response.url(), status: response.status() });\n captureTraceCorrelation(response, traceHeader, traceCorrelations, redactionValues);\n }\n });\n\n const startedAt = new Date().toISOString();\n const startTime = Date.now();\n\n let stepResults: StepResult[] = [];\n let stepScreenshots: string[] = [];\n let stepFailed = false;\n\n try {\n const stepExecution = await executeSteps({\n page: session.page,\n steps: interpolatedHunt.steps,\n targetUrl,\n runDir,\n screenshotsMode: config.artifacts.screenshots,\n forbiddenSelectors: config.guardrails.forbiddenSelectors,\n allowedDomains,\n maxSteps,\n maxTotalTimeMs: config.assertions.maxTotalTimeMs,\n selfHealing: config.guardrails.selfHealing,\n redactedFillSteps,\n randomVars,\n configDir,\n huntStack: [options.huntName],\n onStep: options.onStep\n });\n\n stepResults = stepExecution.results;\n stepScreenshots = stepExecution.screenshots;\n stepFailed = stepExecution.failed;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Step execution failed\";\n stepResults = [\n {\n type: \"steps\",\n status: \"fail\",\n durationMs: 0,\n error: message\n }\n ];\n stepFailed = true;\n }\n\n let finalScreenshot: string | undefined;\n try {\n finalScreenshot = await captureFinalScreenshot(session.page, runDir);\n } catch {\n finalScreenshot = undefined;\n }\n\n const assertionResults = await evaluateAssertions({\n page: session.page,\n config,\n huntAssertions: interpolatedHunt.assertions,\n consoleEntries,\n networkEntries\n });\n\n const durationMs = Date.now() - startTime;\n const assertionsFailed = assertionResults.some((assertion) => assertion.status === \"fail\");\n\n const status: \"pass\" | \"fail\" = stepFailed || assertionsFailed ? \"fail\" : \"pass\";\n\n const artifacts: RunResult[\"artifacts\"] = {\n screenshots: finalScreenshot\n ? [...stepScreenshots, finalScreenshot]\n : stepScreenshots,\n trace: session.tracePath ? \"trace.zip\" : undefined,\n networkHar: config.artifacts.networkHar ? \"network.har\" : undefined\n };\n\n if (config.artifacts.console) {\n artifacts.console = writeConsoleLog(runDir, consoleEntries);\n }\n\n const runResult = buildRunResult({\n status,\n startedAt,\n durationMs,\n hunt: options.huntName,\n targetUrl,\n steps: stepResults,\n assertions: assertionResults,\n artifacts,\n traceCorrelations\n });\n\n result = writeReports(runDir, runResult, { junit: options.junit ?? config.artifacts.junit });\n } finally {\n await closeBrowser(session);\n }\n\n return { result, runDir, steps: interpolatedHunt.steps };\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function runHunt(\n options: RunOptions\n): Promise<{ result: RunResult; runDir: string; steps: Step[] }> {\n const { config, configDir } = loadConfig(options.configPath);\n const hunt = loadHunt(options.huntName, configDir);\n const {\n hunt: interpolatedHunt,\n redactedFillSteps,\n randomVars,\n redactionValues = []\n } = interpolateHunt(\n hunt,\n process.env\n );\n\n const targetUrl = options.urlOverride ?? config.target.url;\n const allowedDomains = ensureAllowedDomain([...config.guardrails.allowedDomains], targetUrl);\n const maxSteps = config.guardrails.maxSteps;\n\n if (interpolatedHunt.steps.length > maxSteps) {\n throw new Error(`Hunt has ${interpolatedHunt.steps.length} steps. Max allowed is ${maxSteps}.`);\n }\n\n const maxRetries = hunt.retry?.maxRetries ?? 0;\n const retryDelay = hunt.retry?.delay ?? 0;\n\n let lastResult: { result: RunResult; runDir: string; steps: Step[] } | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (attempt > 0 && retryDelay > 0) {\n await delay(retryDelay);\n }\n\n lastResult = await executeHuntAttempt(\n options,\n config,\n configDir,\n interpolatedHunt,\n redactedFillSteps,\n randomVars,\n redactionValues,\n targetUrl,\n allowedDomains\n );\n\n if (lastResult.result.status === \"pass\") {\n if (attempt > 0) {\n lastResult.result.artifacts.summary =\n `Passed on attempt ${attempt + 1} of ${maxRetries + 1}`;\n }\n recordHistory(configDir, lastResult, config.history.maxRuns);\n return lastResult;\n }\n }\n\n if (maxRetries > 0 && lastResult) {\n lastResult.result.artifacts.summary =\n `Failed after ${maxRetries + 1} attempts`;\n }\n\n if (lastResult) {\n recordHistory(configDir, lastResult, config.history.maxRuns);\n }\n\n return lastResult!;\n}\n\nfunction recordHistory(\n configDir: string,\n outcome: { result: RunResult; runDir: string },\n maxRuns: number\n): void {\n try {\n const relativeRunDir = path.relative(configDir, outcome.runDir);\n appendHistoryEntry(\n configDir,\n {\n hunt: outcome.result.hunt,\n status: outcome.result.status,\n durationMs: outcome.result.durationMs,\n startedAt: outcome.result.startedAt,\n runDir: relativeRunDir || undefined\n },\n maxRuns\n );\n } catch {\n // History is observability only; a write failure must never break a run.\n }\n}\n","import crypto from \"node:crypto\";\nimport type { Assertion, Hunt, Step } from \"../types/index.js\";\n\nexport type InterpolatedHunt = {\n hunt: Hunt;\n redactedFillSteps: Set<string>;\n randomVars: Record<string, string>;\n redactionValues: string[];\n};\n\nexport type InterpolationResult = {\n value: string;\n usedVars: string[];\n};\n\nconst VAR_PATTERN = /\\{\\{([A-Z0-9_]+)\\}\\}/g;\n\nfunction collectInterpolatedValues(input: unknown, vars: Record<string, string>, values: Set<string>): void {\n if (typeof input === \"string\") {\n for (const match of input.matchAll(VAR_PATTERN)) {\n const varValue = vars[match[1]];\n if (varValue) values.add(varValue);\n }\n return;\n }\n\n if (Array.isArray(input)) {\n for (const item of input) {\n collectInterpolatedValues(item, vars, values);\n }\n return;\n }\n\n if (input && typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n collectInterpolatedValues(key, vars, values);\n collectInterpolatedValues(value, vars, values);\n }\n }\n}\n\nexport function interpolateString(\n input: string,\n vars: Record<string, string>\n): InterpolationResult {\n const usedVars: string[] = [];\n const value = input.replace(VAR_PATTERN, (_, name: string) => {\n const varValue = vars[name];\n if (varValue === undefined) {\n throw new Error(`Missing variable: ${name}`);\n }\n usedVars.push(name);\n return varValue;\n });\n return { value, usedVars };\n}\n\nconst RANDOM_FIRST_NAMES = [\"Alex\", \"Jordan\", \"Morgan\", \"Taylor\", \"Casey\", \"Riley\", \"Quinn\", \"Avery\"];\nconst RANDOM_LAST_NAMES = [\"Smith\", \"Johnson\", \"Brown\", \"Davis\", \"Wilson\", \"Clark\", \"Hall\", \"Young\"];\n\ntype RandomSource = {\n random: () => number;\n randomBytes: (size: number) => Buffer;\n randomUUID: () => string;\n};\n\nexport function generateRandomVars(randomSource?: Partial<RandomSource>): Record<string, string> {\n const random = randomSource?.random ?? Math.random;\n const randomBytes = randomSource?.randomBytes ?? crypto.randomBytes;\n const randomUUID = randomSource?.randomUUID ?? crypto.randomUUID;\n const hex = randomBytes(4).toString(\"hex\");\n const firstIndex = Math.floor(random() * RANDOM_FIRST_NAMES.length);\n const lastIndex = Math.floor(random() * RANDOM_LAST_NAMES.length);\n const num = Math.floor(random() * 9000) + 1000;\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let text = \"\";\n for (let i = 0; i < 8; i++) {\n text += chars[Math.floor(random() * chars.length)];\n }\n return {\n RANDOM_EMAIL: `prowl_${hex}@test.com`,\n RANDOM_NAME: `${RANDOM_FIRST_NAMES[firstIndex]} ${RANDOM_LAST_NAMES[lastIndex]}`,\n RANDOM_NUMBER: String(num),\n RANDOM_UUID: randomUUID(),\n RANDOM_TEXT: text\n };\n}\n\nfunction interpolateStep(\n step: Step,\n vars: Record<string, string>,\n stepPath: string,\n redacted: Set<string>\n): Step {\n const isExplicitFill = (\n value: { selector: string; value: string } | Record<string, string>\n ): value is { selector: string; value: string } =>\n typeof (value as { selector?: unknown }).selector === \"string\" &&\n typeof (value as { value?: unknown }).value === \"string\";\n\n const interpolateSinglePair = (record: Record<string, string>): Record<string, string> => {\n const entries = Object.entries(record);\n if (entries.length !== 1) {\n throw new Error(\"Shorthand step expects exactly one key-value pair\");\n }\n const [key, value] = entries[0];\n return {\n [interpolateString(key, vars).value]: interpolateString(value, vars).value\n };\n };\n\n if (\"navigate\" in step) {\n const result = interpolateString(step.navigate, vars);\n return { navigate: result.value };\n }\n if (\"click\" in step) {\n if (typeof step.click === \"string\") {\n return { click: interpolateString(step.click, vars).value };\n }\n const result = interpolateString(step.click.selector, vars);\n return { click: { selector: result.value } };\n }\n if (\"fill\" in step) {\n if (isExplicitFill(step.fill)) {\n const selectorResult = interpolateString(step.fill.selector, vars);\n const valueResult = interpolateString(step.fill.value, vars);\n if (valueResult.usedVars.length > 0) {\n redacted.add(stepPath);\n }\n return { fill: { selector: selectorResult.value, value: valueResult.value } };\n }\n const [rawLabel, rawValue] = Object.entries(step.fill)[0] ?? [];\n if (rawLabel === undefined || rawValue === undefined) {\n throw new Error(\"Shorthand fill expects exactly one key-value pair\");\n }\n const labelResult = interpolateString(rawLabel, vars);\n const valueResult = interpolateString(rawValue, vars);\n if (valueResult.usedVars.length > 0) {\n redacted.add(stepPath);\n }\n return {\n fill: {\n [labelResult.value]: valueResult.value\n }\n };\n }\n if (\"type\" in step) {\n const valueResult = interpolateString(step.type, vars);\n if (valueResult.usedVars.length > 0) {\n redacted.add(stepPath);\n }\n return { type: valueResult.value };\n }\n if (\"selectOption\" in step) {\n const selectorResult = interpolateString(step.selectOption.selector, vars);\n const valueResult = interpolateString(step.selectOption.value, vars);\n return { selectOption: { selector: selectorResult.value, value: valueResult.value } };\n }\n if (\"select\" in step) {\n return { select: interpolateSinglePair(step.select) };\n }\n if (\"press\" in step) {\n const selectorResult = interpolateString(step.press.selector, vars);\n const keyResult = interpolateString(step.press.key, vars);\n return { press: { selector: selectorResult.value, key: keyResult.value } };\n }\n if (\"onDialog\" in step) {\n return { onDialog: { action: step.onDialog.action } };\n }\n if (\"setInputFiles\" in step) {\n const selectorResult = interpolateString(step.setInputFiles.selector, vars);\n const rawFiles = step.setInputFiles.files;\n const files = Array.isArray(rawFiles)\n ? rawFiles.map((f) => interpolateString(f, vars).value)\n : interpolateString(rawFiles, vars).value;\n return { setInputFiles: { selector: selectorResult.value, files } };\n }\n if (\"runHunt\" in step) {\n if (typeof step.runHunt === \"string\") {\n return { runHunt: interpolateString(step.runHunt, vars).value };\n }\n const nameResult = interpolateString(step.runHunt.name, vars);\n const interpolatedVars: Record<string, string> = {};\n for (const [key, value] of Object.entries(step.runHunt.vars ?? {})) {\n interpolatedVars[key] = interpolateString(value, vars).value;\n }\n return {\n runHunt: {\n name: nameResult.value,\n ...(Object.keys(interpolatedVars).length > 0 ? { vars: interpolatedVars } : {})\n }\n };\n }\n if (\"assert\" in step) {\n if (step.assert.visible !== undefined) {\n return { assert: { visible: interpolateString(step.assert.visible, vars).value } };\n }\n if (step.assert.notVisible !== undefined) {\n return { assert: { notVisible: interpolateString(step.assert.notVisible, vars).value } };\n }\n if (step.assert.urlIncludes !== undefined) {\n return { assert: { urlIncludes: interpolateString(step.assert.urlIncludes, vars).value } };\n }\n if (step.assert.urlEquals !== undefined) {\n return { assert: { urlEquals: interpolateString(step.assert.urlEquals, vars).value } };\n }\n return step;\n }\n if (\"wait\" in step) {\n if (typeof step.wait === \"string\") {\n return { wait: interpolateString(step.wait, vars).value };\n }\n return {\n wait: {\n for: interpolateString(step.wait.for, vars).value,\n timeout: step.wait.timeout\n }\n };\n }\n if (\"waitForSelector\" in step) {\n const selectorResult = interpolateString(step.waitForSelector.selector, vars);\n return {\n waitForSelector: {\n selector: selectorResult.value,\n timeout: step.waitForSelector.timeout\n }\n };\n }\n if (\"waitForUrl\" in step) {\n const valueResult = interpolateString(step.waitForUrl.value, vars);\n return {\n waitForUrl: {\n value: valueResult.value,\n timeout: step.waitForUrl.timeout\n }\n };\n }\n if (\"waitForNetworkIdle\" in step) {\n return { waitForNetworkIdle: { timeout: step.waitForNetworkIdle.timeout } };\n }\n if (\"hover\" in step) {\n const selectorResult = interpolateString(step.hover.selector, vars);\n return { hover: { selector: selectorResult.value } };\n }\n if (\"scroll\" in step) {\n return { scroll: { direction: step.scroll.direction, amount: step.scroll.amount } };\n }\n if (\"scrollTo\" in step) {\n const selectorResult = interpolateString(step.scrollTo.selector, vars);\n return { scrollTo: { selector: selectorResult.value } };\n }\n if (\"screenshot\" in step) {\n return { screenshot: { name: step.screenshot.name } };\n }\n if (\"if\" in step) {\n const condition = step.if;\n const thenSteps = condition.then.map((s, i) =>\n interpolateStep(s, vars, `${stepPath}.if.then.${i}`, redacted)\n );\n const elseSteps = condition.else?.map((s, i) =>\n interpolateStep(s, vars, `${stepPath}.if.else.${i}`, redacted)\n );\n return {\n if: {\n ...(condition.visible !== undefined\n ? { visible: interpolateString(condition.visible, vars).value }\n : {}),\n ...(condition.notVisible !== undefined\n ? { notVisible: interpolateString(condition.notVisible, vars).value }\n : {}),\n then: thenSteps,\n ...(elseSteps !== undefined ? { else: elseSteps } : {})\n }\n };\n }\n if (\"repeat\" in step) {\n const repeat = step.repeat;\n const subSteps = repeat.steps.map((s, i) =>\n interpolateStep(s, vars, `${stepPath}.repeat.steps.${i}`, redacted)\n );\n return {\n repeat: {\n ...(repeat.times !== undefined ? { times: repeat.times } : {}),\n ...(repeat.while !== undefined\n ? {\n while: {\n ...(repeat.while.visible !== undefined\n ? { visible: interpolateString(repeat.while.visible, vars).value }\n : {}),\n ...(repeat.while.notVisible !== undefined\n ? { notVisible: interpolateString(repeat.while.notVisible, vars).value }\n : {})\n }\n }\n : {}),\n ...(repeat.maxIterations !== undefined ? { maxIterations: repeat.maxIterations } : {}),\n steps: subSteps\n }\n };\n }\n if (\"mockRoute\" in step) {\n const mock = step.mockRoute;\n return {\n mockRoute: {\n url: interpolateString(mock.url, vars).value,\n response: {\n status: mock.response.status,\n ...(mock.response.contentType !== undefined\n ? { contentType: interpolateString(mock.response.contentType, vars).value }\n : {}),\n ...(mock.response.body !== undefined\n ? { body: interpolateString(mock.response.body, vars).value }\n : {}),\n ...(mock.response.file !== undefined\n ? { file: interpolateString(mock.response.file, vars).value }\n : {})\n }\n }\n };\n }\n if (\"unmockRoute\" in step) {\n if (typeof step.unmockRoute === \"string\") {\n return { unmockRoute: interpolateString(step.unmockRoute, vars).value };\n }\n return {\n unmockRoute: { url: interpolateString(step.unmockRoute.url, vars).value }\n };\n }\n if (\"evalScript\" in step) {\n if (typeof step.evalScript === \"string\") {\n return { evalScript: interpolateString(step.evalScript, vars).value };\n }\n return {\n evalScript: {\n expression: interpolateString(step.evalScript.expression, vars).value,\n ...(step.evalScript.as !== undefined ? { as: step.evalScript.as } : {})\n }\n };\n }\n if (\"runScript\" in step) {\n return {\n runScript: { file: interpolateString(step.runScript.file, vars).value }\n };\n }\n if (\"assertScreenshot\" in step) {\n return {\n assertScreenshot: {\n name: interpolateString(step.assertScreenshot.name, vars).value,\n ...(step.assertScreenshot.threshold !== undefined\n ? { threshold: step.assertScreenshot.threshold }\n : {})\n }\n };\n }\n if (\"copyText\" in step) {\n return {\n copyText: {\n selector: interpolateString(step.copyText.selector, vars).value,\n as: step.copyText.as\n }\n };\n }\n if (\"waitForDownload\" in step) {\n if (step.waitForDownload === null) {\n return { waitForDownload: null };\n }\n return {\n waitForDownload: {\n ...(step.waitForDownload.filename !== undefined\n ? { filename: interpolateString(step.waitForDownload.filename, vars).value }\n : {}),\n ...(step.waitForDownload.timeout !== undefined\n ? { timeout: step.waitForDownload.timeout }\n : {})\n }\n };\n }\n return step;\n}\n\nfunction interpolateAssertion(assertion: Assertion, vars: Record<string, string>): Assertion {\n if (\"selectorExists\" in assertion) {\n return { selectorExists: interpolateString(assertion.selectorExists, vars).value };\n }\n if (\"selectorNotExists\" in assertion) {\n return { selectorNotExists: interpolateString(assertion.selectorNotExists, vars).value };\n }\n if (\"urlIncludes\" in assertion) {\n return { urlIncludes: interpolateString(assertion.urlIncludes, vars).value };\n }\n if (\"urlEquals\" in assertion) {\n return { urlEquals: interpolateString(assertion.urlEquals, vars).value };\n }\n if (\"noConsoleErrors\" in assertion) {\n return { noConsoleErrors: assertion.noConsoleErrors };\n }\n if (\"noNetworkErrors\" in assertion) {\n return { noNetworkErrors: assertion.noNetworkErrors };\n }\n return assertion;\n}\n\nexport function interpolateHunt(\n hunt: Hunt,\n env: NodeJS.ProcessEnv,\n randomVars: Record<string, string> = generateRandomVars()\n): InterpolatedHunt {\n const redactedFillSteps = new Set<string>();\n\n const envVars = Object.fromEntries(\n Object.entries(env).filter(([, value]) => value !== undefined) as Array<[string, string]>\n );\n const baseVars = { ...randomVars, ...envVars };\n\n const resolvedHuntVars: Record<string, string> = {};\n for (const [key, value] of Object.entries(hunt.vars ?? {})) {\n resolvedHuntVars[key] = interpolateString(value, baseVars).value;\n }\n\n const vars = { ...baseVars, ...resolvedHuntVars };\n const redactionValues = new Set<string>();\n collectInterpolatedValues(hunt.steps, vars, redactionValues);\n collectInterpolatedValues(hunt.assertions, vars, redactionValues);\n\n const steps = hunt.steps.map((step, index) =>\n interpolateStep(step, vars, `${index}`, redactedFillSteps)\n );\n const assertions = hunt.assertions?.map((assertion) => interpolateAssertion(assertion, vars));\n return {\n hunt: {\n ...hunt,\n steps,\n assertions\n },\n redactedFillSteps,\n randomVars,\n redactionValues: [...redactionValues]\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { chromium, firefox, webkit, type Browser, type BrowserContext, type Page } from \"playwright\";\nimport type { BrowserChannel, BrowserEngine, Viewport } from \"../types/index.js\";\n\nconst ENGINES = { chromium, firefox, webkit } as const;\n\nexport type BrowserSession = {\n browser: Browser;\n context: BrowserContext;\n page: Page;\n tracePath?: string;\n};\n\nexport type BrowserOptions = {\n headless: boolean;\n slowMo: number;\n timeout: number;\n storageStatePath?: string;\n trace: boolean;\n recordHar: boolean;\n runDir: string;\n engine?: BrowserEngine;\n channel?: BrowserChannel;\n viewport?: Viewport;\n};\n\nexport async function launchBrowser(options: BrowserOptions): Promise<BrowserSession> {\n const engine = ENGINES[options.engine ?? \"chromium\"];\n const browser = await engine.launch({\n headless: options.headless,\n slowMo: options.slowMo,\n channel: options.channel\n });\n\n const contextOptions: Parameters<typeof browser.newContext>[0] = {};\n\n if (options.viewport) {\n contextOptions.viewport = options.viewport;\n }\n\n if (options.storageStatePath) {\n if (fs.existsSync(options.storageStatePath)) {\n contextOptions.storageState = options.storageStatePath;\n } else {\n console.warn(`Auth state file not found: ${options.storageStatePath}. Run \"prowl login\" to create it.`);\n }\n }\n\n if (options.recordHar) {\n contextOptions.recordHar = { path: path.join(options.runDir, \"network.har\") };\n }\n\n const context = await browser.newContext(contextOptions);\n const page = await context.newPage();\n page.setDefaultTimeout(options.timeout);\n page.setDefaultNavigationTimeout(options.timeout);\n\n let tracePath: string | undefined;\n if (options.trace) {\n tracePath = path.join(options.runDir, \"trace.zip\");\n await context.tracing.start({ screenshots: true, snapshots: true, sources: true });\n }\n\n return { browser, context, page, tracePath };\n}\n\nexport async function closeBrowser(session: BrowserSession): Promise<void> {\n if (session.tracePath) {\n await session.context.tracing.stop({ path: session.tracePath });\n }\n await session.context.close();\n await session.browser.close();\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { Download, Page } from \"playwright\";\nimport {\n clickElement,\n fillElement,\n pressKey,\n selectOption,\n setupDialogHandler,\n setInputFiles\n} from \"../browser/actions.js\";\nimport type { Step, StepResult } from \"../types/index.js\";\nimport { loadHunt } from \"../config/loader.js\";\nimport { interpolateHunt } from \"../config/interpolate.js\";\nimport { healSelector } from \"./healing.js\";\n\nexport type StepCallback = (result: StepResult, step: Step, index: number) => void;\n\nexport type StepExecutionContext = {\n page: Page;\n steps: Step[];\n targetUrl: string;\n runDir: string;\n screenshotsMode: \"on-failure\" | \"all\";\n forbiddenSelectors: string[];\n allowedDomains: string[];\n maxSteps: number;\n selfHealing?: boolean;\n maxTotalTimeMs: number;\n redactedFillSteps: Set<string>;\n configDir: string;\n onStep?: StepCallback;\n huntStack?: string[];\n activeMocks?: Map<string, () => Promise<void>>;\n runtimeVars?: Map<string, string>;\n randomVars?: Record<string, string>;\n pendingDownload?: Promise<Download>;\n runStartedAtMs?: number;\n stepPathPrefix?: string;\n};\n\nexport type StepExecutionResult = {\n results: StepResult[];\n screenshots: string[];\n failed: boolean;\n error?: string;\n};\n\nconst ALWAYS_ALLOWED_PROTOCOLS = [\"about:\", \"data:\"];\n\nfunction unwrapTextSelector(value: string): string | null {\n const trimmed = value.trim();\n if (trimmed.startsWith('text=\"') && trimmed.endsWith('\"')) {\n return trimmed.slice(6, -1);\n }\n if (trimmed.startsWith(\"text='\") && trimmed.endsWith(\"'\")) {\n return trimmed.slice(6, -1);\n }\n if (trimmed.startsWith(\"text=\")) {\n return trimmed.slice(5);\n }\n return null;\n}\n\n// Substring match: if both the selector and forbidden pattern are text= selectors,\n// the selector's text is checked for whether it *contains* the forbidden text.\n// For example, forbidden 'text=\"Delete\"' would match selector 'text=\"Delete All\"'.\nfunction matchesForbiddenPattern(selector: string, forbidden: string): boolean {\n const selectorText = unwrapTextSelector(selector);\n if (selectorText === null) {\n return false;\n }\n\n const forbiddenText = unwrapTextSelector(forbidden);\n if (forbiddenText !== null) {\n return selectorText.includes(forbiddenText);\n }\n\n return selectorText.includes(forbidden);\n}\n\n// Uses substring matching: a selector is forbidden if it contains any forbidden\n// pattern as a substring (e.g., forbidden \"[data-danger]\" matches \"[data-danger].active\"),\n// or if the text-based pattern match above succeeds.\nfunction isForbiddenSelector(selector: string, forbiddenSelectors: string[]): boolean {\n return forbiddenSelectors.some(\n (forbidden) => selector.includes(forbidden) || matchesForbiddenPattern(selector, forbidden)\n );\n}\n\nfunction assertAllowedSelector(selector: string, forbiddenSelectors: string[]): void {\n if (isForbiddenSelector(selector, forbiddenSelectors)) {\n throw new Error(`Forbidden selector: ${selector}`);\n }\n}\n\n/**\n * Resolve the selector an explicit-selector action should operate on. Asserts it\n * is allowed, then — when `guardrails.selfHealing` is on and the selector matches\n * nothing — attempts to heal to an equivalent selector. A healed selector is also\n * re-checked against the forbidden list. Returns the selector to use plus, when\n * healing occurred, the original selector for reporting.\n */\nasync function resolveActionSelector(\n context: StepExecutionContext,\n selector: string\n): Promise<{ selector: string; healedFrom?: string }> {\n assertAllowedSelector(selector, context.forbiddenSelectors);\n\n if (!context.selfHealing) {\n return { selector };\n }\n\n let matched = false;\n try {\n matched = (await context.page.locator(selector).count()) > 0;\n } catch {\n // Unparseable/odd selector — let the real action surface the error.\n return { selector };\n }\n if (matched) {\n return { selector };\n }\n\n const healed = await healSelector(context.page, selector, { enabled: true });\n if (!healed) {\n return { selector };\n }\n\n assertAllowedSelector(healed.selector, context.forbiddenSelectors);\n console.warn(\n `Self-healed selector: \"${selector}\" → \"${healed.selector}\" (${healed.strategy}). ` +\n \"Update your hunt to use a stable selector.\"\n );\n return { selector: healed.selector, healedFrom: healed.healedFrom };\n}\n\nfunction assertWithinMaxSteps(stepCount: number, maxSteps: number, huntName?: string): void {\n if (stepCount > maxSteps) {\n if (huntName) {\n throw new Error(`Hunt \"${huntName}\" has ${stepCount} steps. Max allowed is ${maxSteps}.`);\n }\n throw new Error(`Hunt has ${stepCount} steps. Max allowed is ${maxSteps}.`);\n }\n}\n\nfunction getStepType(step: Step): string {\n if (\"navigate\" in step) return \"navigate\";\n if (\"click\" in step) return \"click\";\n if (\"fill\" in step) return \"fill\";\n if (\"type\" in step) return \"type\";\n if (\"selectOption\" in step) return \"selectOption\";\n if (\"select\" in step) return \"select\";\n if (\"onDialog\" in step) return \"onDialog\";\n if (\"setInputFiles\" in step) return \"setInputFiles\";\n if (\"runHunt\" in step) return \"runHunt\";\n if (\"assert\" in step) return \"assert\";\n if (\"press\" in step) return \"press\";\n if (\"wait\" in step) return \"wait\";\n if (\"waitForSelector\" in step) return \"waitForSelector\";\n if (\"waitForUrl\" in step) return \"waitForUrl\";\n if (\"waitForNetworkIdle\" in step) return \"waitForNetworkIdle\";\n if (\"hover\" in step) return \"hover\";\n if (\"scroll\" in step) return \"scroll\";\n if (\"scrollTo\" in step) return \"scrollTo\";\n if (\"screenshot\" in step) return \"screenshot\";\n if (\"if\" in step) return \"if\";\n if (\"repeat\" in step) return \"repeat\";\n if (\"mockRoute\" in step) return \"mockRoute\";\n if (\"unmockRoute\" in step) return \"unmockRoute\";\n if (\"evalScript\" in step) return \"evalScript\";\n if (\"runScript\" in step) return \"runScript\";\n if (\"assertScreenshot\" in step) return \"assertScreenshot\";\n if (\"copyText\" in step) return \"copyText\";\n if (\"waitForDownload\" in step) return \"waitForDownload\";\n return \"step\";\n}\n\nconst RUNTIME_VAR_PATTERN = /\\{\\{([A-Z0-9_]+)\\}\\}/g;\n\nfunction substituteRuntimeVars(input: string, vars: Map<string, string>): string {\n return input.replace(RUNTIME_VAR_PATTERN, (match, name: string) => {\n const value = vars.get(name);\n return value !== undefined ? value : match;\n });\n}\n\nfunction applyRuntimeVars(step: Step, vars: Map<string, string>): Step {\n const sub = (s: string) => substituteRuntimeVars(s, vars);\n\n if (\"navigate\" in step) return { navigate: sub(step.navigate) };\n if (\"click\" in step) {\n if (typeof step.click === \"string\") return { click: sub(step.click) };\n return { click: { selector: sub(step.click.selector) } };\n }\n if (\"fill\" in step) {\n if (\"selector\" in step.fill && \"value\" in step.fill) {\n const f = step.fill as { selector: string; value: string };\n return { fill: { selector: sub(f.selector), value: sub(f.value) } };\n }\n const [key, value] = Object.entries(step.fill)[0];\n return { fill: { [sub(key)]: sub(value) } };\n }\n if (\"type\" in step) return { type: sub(step.type) };\n if (\"assert\" in step) {\n const a = step.assert;\n if (a.visible !== undefined) return { assert: { visible: sub(a.visible) } };\n if (a.notVisible !== undefined) return { assert: { notVisible: sub(a.notVisible) } };\n if (a.urlIncludes !== undefined) return { assert: { urlIncludes: sub(a.urlIncludes) } };\n if (a.urlEquals !== undefined) return { assert: { urlEquals: sub(a.urlEquals) } };\n return step;\n }\n if (\"wait\" in step) {\n if (typeof step.wait === \"string\") return { wait: sub(step.wait) };\n return { wait: { for: sub(step.wait.for), timeout: step.wait.timeout } };\n }\n if (\"waitForSelector\" in step) {\n return { waitForSelector: { selector: sub(step.waitForSelector.selector), timeout: step.waitForSelector.timeout } };\n }\n if (\"evalScript\" in step) {\n if (typeof step.evalScript === \"string\") return { evalScript: sub(step.evalScript) };\n return {\n evalScript: {\n expression: sub(step.evalScript.expression),\n ...(step.evalScript.as !== undefined ? { as: step.evalScript.as } : {})\n }\n };\n }\n if (\"assertScreenshot\" in step) {\n return {\n assertScreenshot: {\n name: sub(step.assertScreenshot.name),\n ...(step.assertScreenshot.threshold !== undefined ? { threshold: step.assertScreenshot.threshold } : {})\n }\n };\n }\n if (\"copyText\" in step) {\n return { copyText: { selector: sub(step.copyText.selector), as: step.copyText.as } };\n }\n if (\"waitForDownload\" in step) {\n if (step.waitForDownload === null) return step;\n return {\n waitForDownload: {\n ...(step.waitForDownload.filename !== undefined ? { filename: sub(step.waitForDownload.filename) } : {}),\n ...(step.waitForDownload.timeout !== undefined ? { timeout: step.waitForDownload.timeout } : {})\n }\n };\n }\n return step;\n}\n\nfunction isExplicitFillStep(\n value: { selector: string; value: string } | Record<string, string>\n): value is { selector: string; value: string } {\n return (\n typeof (value as { selector?: unknown }).selector === \"string\" &&\n typeof (value as { value?: unknown }).value === \"string\"\n );\n}\n\nfunction ensureAllowedUrl(urlValue: string, allowedDomains: string[]): void {\n for (const protocol of ALWAYS_ALLOWED_PROTOCOLS) {\n if (urlValue.startsWith(protocol)) {\n return;\n }\n }\n const url = new URL(urlValue);\n if (!allowedDomains.includes(url.hostname)) {\n throw new Error(`Navigation to disallowed domain: ${url.hostname}`);\n }\n}\n\nfunction resolveNavigationTarget(targetUrl: string, value: string): string {\n try {\n return new URL(value, targetUrl).toString();\n } catch {\n return value;\n }\n}\n\nfunction escapeForText(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction escapeForAttribute(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction exactTextSelector(text: string): string {\n return `text=\"${escapeForText(text)}\"`;\n}\n\nfunction textContainsSelector(text: string): string {\n return `text=${escapeForText(text)}`;\n}\n\nfunction getSinglePair(value: Record<string, string>, stepType: string): [string, string] {\n const entries = Object.entries(value);\n if (entries.length !== 1) {\n throw new Error(`${stepType} shorthand expects exactly one key-value pair`);\n }\n return entries[0];\n}\n\nasync function clickByTextWithFallback(\n page: Page,\n text: string,\n forbiddenSelectors: string[]\n): Promise<string> {\n const roleSelector = `role=button[name=\"${escapeForAttribute(text)}\"]`;\n assertAllowedSelector(roleSelector, forbiddenSelectors);\n const button = page.getByRole(\"button\", { name: text });\n if (await button.count()) {\n await button.first().click();\n return roleSelector;\n }\n\n const selector = exactTextSelector(text);\n assertAllowedSelector(selector, forbiddenSelectors);\n await page.locator(selector).first().click();\n return selector;\n}\n\nasync function fillByLabelOrPlaceholder(\n page: Page,\n label: string,\n value: string,\n forbiddenSelectors: string[]\n): Promise<string> {\n const labelSelector = `label=\"${escapeForAttribute(label)}\"`;\n assertAllowedSelector(labelSelector, forbiddenSelectors);\n const byLabel = page.getByLabel(label, { exact: true });\n if (await byLabel.count()) {\n await byLabel.first().fill(value);\n return labelSelector;\n }\n\n const placeholder = `input[placeholder=\"${escapeForAttribute(label)}\"], textarea[placeholder=\"${escapeForAttribute(label)}\"]`;\n assertAllowedSelector(placeholder, forbiddenSelectors);\n const byPlaceholder = page.locator(placeholder);\n if (await byPlaceholder.count()) {\n await byPlaceholder.first().fill(value);\n return placeholder;\n }\n\n throw new Error(`Could not resolve fill shorthand for \"${label}\"`);\n}\n\nasync function selectByLabelOrFallback(\n page: Page,\n label: string,\n value: string,\n forbiddenSelectors: string[]\n): Promise<string> {\n const labelSelector = `label=\"${escapeForAttribute(label)}\"`;\n assertAllowedSelector(labelSelector, forbiddenSelectors);\n const byLabel = page.getByLabel(label, { exact: true });\n if (await byLabel.count()) {\n await byLabel.first().selectOption(value);\n return labelSelector;\n }\n\n const ariaSelector = `select[aria-label=\"${escapeForAttribute(label)}\"]`;\n assertAllowedSelector(ariaSelector, forbiddenSelectors);\n const byAria = page.locator(ariaSelector);\n if (await byAria.count()) {\n await byAria.first().selectOption(value);\n return ariaSelector;\n }\n\n const placeholderSelector = `select[placeholder=\"${escapeForAttribute(label)}\"]`;\n assertAllowedSelector(placeholderSelector, forbiddenSelectors);\n const byPlaceholder = page.locator(placeholderSelector);\n if (await byPlaceholder.count()) {\n await byPlaceholder.first().selectOption(value);\n return placeholderSelector;\n }\n\n throw new Error(`Could not resolve select shorthand for \"${label}\"`);\n}\n\n// Playwright engine prefixes (e.g. `css=`, `xpath=…`, `text=\"…\"`) that mark a\n// value as an explicit selector rather than text to match.\nconst SELECTOR_ENGINE_PREFIX = /^(?:css|xpath|text|id|role|data-testid)=/i;\nconst HTML_TYPE_SELECTORS = new Set([\n \"a\",\n \"article\",\n \"aside\",\n \"body\",\n \"button\",\n \"canvas\",\n \"dialog\",\n \"div\",\n \"fieldset\",\n \"footer\",\n \"form\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"header\",\n \"html\",\n \"iframe\",\n \"img\",\n \"input\",\n \"label\",\n \"li\",\n \"main\",\n \"nav\",\n \"ol\",\n \"option\",\n \"p\",\n \"section\",\n \"select\",\n \"span\",\n \"table\",\n \"tbody\",\n \"td\",\n \"textarea\",\n \"th\",\n \"thead\",\n \"tr\",\n \"ul\"\n]);\n\nfunction isKnownCssTypeSelector(value: string): boolean {\n return value === \"*\" || value.includes(\"-\") || HTML_TYPE_SELECTORS.has(value.toLowerCase());\n}\n\nfunction readCssTypeSelector(value: string, start: number): { end: number; isKnown: boolean } | null {\n const match = /^(?:[A-Za-z][\\w-]*|\\*)/.exec(value.slice(start));\n if (!match) return null;\n return { end: start + match[0].length, isKnown: isKnownCssTypeSelector(match[0]) };\n}\n\nfunction readCssStructuralSelectorPart(value: string, start: number): number | null {\n const rest = value.slice(start);\n const classOrId = /^[.#][A-Za-z_][\\w-]*/.exec(rest);\n if (classOrId) return start + classOrId[0].length;\n\n const attribute = /^\\[[A-Za-z_][\\w:-]*(?:\\s*(?:[~|^$*]?=)\\s*(?:\"[^\"]*\"|'[^']*'|[^\\]\\s]+))?\\]/.exec(rest);\n if (attribute) return start + attribute[0].length;\n\n return null;\n}\n\nfunction readCssCompoundSelector(value: string, start: number): { end: number; hasStructuralPart: boolean } | null {\n let cursor = start;\n const type = readCssTypeSelector(value, cursor);\n if (type) {\n cursor = type.end;\n }\n\n let hasStructuralPart = false;\n for (;;) {\n const next = readCssStructuralSelectorPart(value, cursor);\n if (next === null) break;\n hasStructuralPart = true;\n cursor = next;\n }\n\n if (cursor === start) return null;\n if (type && !type.isKnown) return null;\n return { end: cursor, hasStructuralPart };\n}\n\nfunction readCssSelectorSeparator(value: string, start: number): number | null {\n let cursor = start;\n let sawWhitespace = false;\n while (/\\s/.test(value[cursor] ?? \"\")) {\n sawWhitespace = true;\n cursor += 1;\n }\n\n if (/[>+~]/.test(value[cursor] ?? \"\")) {\n cursor += 1;\n while (/\\s/.test(value[cursor] ?? \"\")) {\n cursor += 1;\n }\n return cursor;\n }\n\n return sawWhitespace ? cursor : null;\n}\n\nfunction isCssSelectorSequence(value: string): boolean {\n const first = readCssCompoundSelector(value, 0);\n if (!first) return false;\n\n let cursor = first.end;\n let sawSeparator = false;\n let hasStructuralPart = first.hasStructuralPart;\n\n while (cursor < value.length) {\n const afterSeparator = readCssSelectorSeparator(value, cursor);\n if (afterSeparator === null) return false;\n\n const next = readCssCompoundSelector(value, afterSeparator);\n if (!next) return false;\n\n sawSeparator = true;\n hasStructuralPart = hasStructuralPart || next.hasStructuralPart;\n cursor = next.end;\n }\n\n return sawSeparator && hasStructuralPart;\n}\n\n// A visibility value is treated as a selector only when it has a clear\n// structural signature: a leading class/id/attribute token, a supported CSS\n// compound/sequence, or explicit Playwright engine prefix (incl. `//` xpath).\n// Everything else — including prose that merely contains punctuation such as\n// \"name:\" or a sentence ending in \".\" — is matched as text, so assertions read\n// the way they are written. For exotic selectors (pseudo-classes), use an\n// explicit engine prefix like `css=input:checked`.\nexport function looksLikeSelector(value: string): boolean {\n const trimmed = value.trim();\n if (trimmed.length === 0) return false;\n if (SELECTOR_ENGINE_PREFIX.test(trimmed) || trimmed.startsWith(\"//\")) return true;\n if (/^[.#]/.test(trimmed)) return true; // leading class or id selector\n const compound = readCssCompoundSelector(trimmed, 0);\n if (compound?.end === trimmed.length && compound.hasStructuralPart) return true;\n if (isCssSelectorSequence(trimmed)) return true;\n return false;\n}\n\nexport function toVisibilitySelector(value: string): string {\n if (looksLikeSelector(value)) return value;\n return textContainsSelector(value);\n}\n\nasync function runInlineAssert(\n page: Page,\n assertion: {\n visible?: string;\n notVisible?: string;\n urlIncludes?: string;\n urlEquals?: string;\n },\n forbiddenSelectors: string[]\n): Promise<string> {\n if (assertion.visible !== undefined) {\n const selector = toVisibilitySelector(assertion.visible);\n assertAllowedSelector(selector, forbiddenSelectors);\n const count = await page.locator(selector).count();\n if (count === 0) {\n throw new Error(`Expected visible: ${assertion.visible}`);\n }\n return `visible:${assertion.visible}`;\n }\n\n if (assertion.notVisible !== undefined) {\n const selector = toVisibilitySelector(assertion.notVisible);\n assertAllowedSelector(selector, forbiddenSelectors);\n const count = await page.locator(selector).count();\n if (count > 0) {\n throw new Error(`Expected not visible: ${assertion.notVisible}`);\n }\n return `notVisible:${assertion.notVisible}`;\n }\n\n if (assertion.urlIncludes !== undefined) {\n const current = page.url();\n if (!current.includes(assertion.urlIncludes)) {\n throw new Error(`URL did not include ${assertion.urlIncludes}`);\n }\n return `urlIncludes:${assertion.urlIncludes}`;\n }\n\n if (assertion.urlEquals !== undefined) {\n const current = page.url();\n if (current !== assertion.urlEquals) {\n throw new Error(`URL did not equal ${assertion.urlEquals}`);\n }\n return `urlEquals:${assertion.urlEquals}`;\n }\n\n throw new Error(\"assert step is missing an assertion type\");\n}\n\nfunction screenshotPath(screenshotsDir: string, fileName: string): string {\n return path.join(screenshotsDir, fileName);\n}\n\nfunction stepPath(prefix: string | undefined, index: number): string {\n return prefix ? `${prefix}.${index}` : `${index}`;\n}\n\nfunction isWaitForDownloadStep(step: Step | undefined): step is Extract<Step, { waitForDownload: unknown }> {\n return step !== undefined && \"waitForDownload\" in step;\n}\n\nfunction armDownloadListener(page: Page, timeout: number): Promise<Download> {\n const downloadPromise = page.waitForEvent(\"download\", { timeout });\n void downloadPromise.catch(() => undefined);\n return downloadPromise;\n}\n\nfunction validateDownloadFilename(suggestedFilename: string): string {\n const safeFilename = suggestedFilename.trim();\n const allowedFilenamePattern = /^[^<>:\"/\\\\|?*]+$/;\n const hasControlCharacter = Array.from(safeFilename).some((char) => char.charCodeAt(0) < 32);\n\n if (\n safeFilename.length === 0\n || safeFilename !== suggestedFilename\n || safeFilename !== path.basename(safeFilename)\n || safeFilename.includes(\"..\")\n || /[/\\\\]/.test(safeFilename)\n || hasControlCharacter\n || !allowedFilenamePattern.test(safeFilename)\n ) {\n throw new Error(`Invalid download filename: \"${suggestedFilename}\"`);\n }\n\n return safeFilename;\n}\n\nasync function captureScreenshot(page: Page, filePath: string): Promise<void> {\n try {\n await page.screenshot({ path: filePath, fullPage: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Screenshot failed\";\n throw new Error(`Failed to capture screenshot at ${filePath}: ${message}`);\n }\n}\n\nasync function executeNestedSteps(\n context: StepExecutionContext,\n overrides: Partial<StepExecutionContext> & Pick<StepExecutionContext, \"steps\">\n): Promise<StepExecutionResult> {\n const nestedContext: StepExecutionContext = {\n ...context,\n ...overrides,\n pendingDownload: context.pendingDownload\n };\n const result = await executeSteps(nestedContext);\n context.pendingDownload = nestedContext.pendingDownload;\n if (nestedContext.randomVars !== undefined) {\n context.randomVars = nestedContext.randomVars;\n }\n return result;\n}\n\nexport async function executeSteps(context: StepExecutionContext): Promise<StepExecutionResult> {\n const screenshotsDir = path.join(context.runDir, \"screenshots\");\n fs.mkdirSync(screenshotsDir, { recursive: true });\n const currentHuntName = context.huntStack?.[context.huntStack.length - 1];\n assertWithinMaxSteps(context.steps.length, context.maxSteps, currentHuntName);\n\n const results: StepResult[] = [];\n const screenshots: string[] = [];\n const runStartedAtMs = context.runStartedAtMs ?? Date.now();\n context.runStartedAtMs = runStartedAtMs;\n\n const addScreenshot = async (fileName: string): Promise<string> => {\n const fullPath = screenshotPath(screenshotsDir, fileName);\n await captureScreenshot(context.page, fullPath);\n const relative = path.join(\"screenshots\", fileName);\n screenshots.push(relative);\n return relative;\n };\n\n for (let index = 0; index < context.steps.length; index += 1) {\n const currentStepPath = stepPath(context.stepPathPrefix, index);\n if (Date.now() - runStartedAtMs > context.maxTotalTimeMs) {\n results.push({\n type: \"timeout\",\n status: \"fail\",\n durationMs: 0,\n error: `Max total time exceeded (${context.maxTotalTimeMs}ms)`\n });\n return { results, screenshots, failed: true, error: \"Max total time exceeded\" };\n }\n\n const runtimeVars = context.runtimeVars ?? new Map<string, string>();\n context.runtimeVars = runtimeVars;\n\n let step = context.steps[index];\n if (runtimeVars.size > 0) {\n step = applyRuntimeVars(step, runtimeVars);\n }\n const nextStep = context.steps[index + 1];\n if (\n !isWaitForDownloadStep(step)\n && context.pendingDownload === undefined\n && isWaitForDownloadStep(nextStep)\n ) {\n context.pendingDownload = armDownloadListener(\n context.page,\n nextStep.waitForDownload?.timeout ?? 30000\n );\n }\n const stepStart = Date.now();\n const stepType = getStepType(step);\n let stepResult: StepResult | null = null;\n\n try {\n if (\"navigate\" in step) {\n const destination = resolveNavigationTarget(context.targetUrl, step.navigate);\n ensureAllowedUrl(destination, context.allowedDomains);\n await context.page.goto(destination);\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = { type: \"navigate\", status: \"pass\", durationMs: Date.now() - stepStart };\n } else if (\"click\" in step) {\n let selector: string;\n let healedFrom: string | undefined;\n if (typeof step.click === \"string\") {\n selector = await clickByTextWithFallback(\n context.page,\n step.click,\n context.forbiddenSelectors\n );\n } else {\n const resolved = await resolveActionSelector(context, step.click.selector);\n await clickElement(context.page, resolved.selector);\n selector = resolved.selector;\n healedFrom = resolved.healedFrom;\n }\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = {\n type: \"click\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector,\n ...(healedFrom ? { healedFrom } : {})\n };\n } else if (\"fill\" in step) {\n let selector: string;\n let value: string;\n let healedFrom: string | undefined;\n if (isExplicitFillStep(step.fill)) {\n const resolved = await resolveActionSelector(context, step.fill.selector);\n await fillElement(context.page, resolved.selector, step.fill.value);\n selector = resolved.selector;\n healedFrom = resolved.healedFrom;\n value = step.fill.value;\n } else {\n const [label, shorthandValue] = getSinglePair(step.fill, \"fill\");\n selector = await fillByLabelOrPlaceholder(\n context.page,\n label,\n shorthandValue,\n context.forbiddenSelectors\n );\n value = shorthandValue;\n }\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = {\n type: \"fill\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector,\n value: context.redactedFillSteps.has(currentStepPath) ? \"[REDACTED]\" : value,\n ...(healedFrom ? { healedFrom } : {})\n };\n } else if (\"type\" in step) {\n assertAllowedSelector(\":focus\", context.forbiddenSelectors);\n await fillElement(context.page, \":focus\", step.type);\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = {\n type: \"type\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector: \":focus\",\n value: context.redactedFillSteps.has(currentStepPath) ? \"[REDACTED]\" : step.type\n };\n } else if (\"selectOption\" in step) {\n const resolved = await resolveActionSelector(context, step.selectOption.selector);\n await selectOption(context.page, resolved.selector, step.selectOption.value);\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = {\n type: \"selectOption\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector: resolved.selector,\n value: step.selectOption.value,\n ...(resolved.healedFrom ? { healedFrom: resolved.healedFrom } : {})\n };\n } else if (\"select\" in step) {\n const [label, value] = getSinglePair(step.select, \"select\");\n const selector = await selectByLabelOrFallback(\n context.page,\n label,\n value,\n context.forbiddenSelectors\n );\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = {\n type: \"select\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector,\n value\n };\n } else if (\"onDialog\" in step) {\n setupDialogHandler(context.page, step.onDialog.action);\n stepResult = {\n type: \"onDialog\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: step.onDialog.action\n };\n } else if (\"setInputFiles\" in step) {\n const resolvedInput = await resolveActionSelector(context, step.setInputFiles.selector);\n const rawFiles = step.setInputFiles.files;\n const resolveFile = (f: string) =>\n path.isAbsolute(f) ? f : path.join(context.configDir, f);\n const resolvedFiles = Array.isArray(rawFiles)\n ? rawFiles.map(resolveFile)\n : resolveFile(rawFiles);\n await setInputFiles(context.page, resolvedInput.selector, resolvedFiles);\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n const filesLabel = Array.isArray(rawFiles) ? rawFiles.join(\", \") : rawFiles;\n stepResult = {\n type: \"setInputFiles\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector: resolvedInput.selector,\n ...(resolvedInput.healedFrom ? { healedFrom: resolvedInput.healedFrom } : {}),\n value: filesLabel\n };\n } else if (\"runHunt\" in step) {\n const huntName = typeof step.runHunt === \"string\" ? step.runHunt : step.runHunt.name;\n const overrideVars = typeof step.runHunt === \"string\" ? undefined : step.runHunt.vars;\n const stack = context.huntStack ?? [];\n if (stack.includes(huntName)) {\n throw new Error(`Circular hunt dependency: ${[...stack, huntName].join(\" → \")}`);\n }\n const subHunt = loadHunt(huntName, context.configDir);\n if (overrideVars) {\n subHunt.vars = { ...subHunt.vars, ...overrideVars };\n }\n const {\n hunt: interpolatedSubHunt,\n redactedFillSteps: subRedacted,\n randomVars\n } = interpolateHunt(\n subHunt,\n process.env,\n context.randomVars\n );\n assertWithinMaxSteps(interpolatedSubHunt.steps.length, context.maxSteps, huntName);\n const subResult = await executeNestedSteps(context, {\n steps: interpolatedSubHunt.steps,\n redactedFillSteps: subRedacted,\n randomVars,\n stepPathPrefix: undefined,\n huntStack: [...stack, huntName],\n onStep: context.onStep\n });\n for (const sr of subResult.results) {\n results.push({ ...sr, type: `${huntName} > ${sr.type}` });\n }\n screenshots.push(...subResult.screenshots);\n if (subResult.failed) {\n return {\n results,\n screenshots,\n failed: true,\n error: `Sub-hunt \"${huntName}\" failed: ${subResult.error}`\n };\n }\n stepResult = {\n type: \"runHunt\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: huntName\n };\n } else if (\"press\" in step) {\n const resolved = await resolveActionSelector(context, step.press.selector);\n await pressKey(context.page, resolved.selector, step.press.key);\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = {\n type: \"press\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector: resolved.selector,\n ...(resolved.healedFrom ? { healedFrom: resolved.healedFrom } : {})\n };\n } else if (\"assert\" in step) {\n const value = await runInlineAssert(context.page, step.assert, context.forbiddenSelectors);\n stepResult = {\n type: \"assert\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value\n };\n } else if (\"wait\" in step) {\n const text = typeof step.wait === \"string\" ? step.wait : step.wait.for;\n const timeout = typeof step.wait === \"string\" ? undefined : step.wait.timeout;\n const selector = `text=${escapeForText(text)}`;\n assertAllowedSelector(selector, context.forbiddenSelectors);\n await context.page.waitForSelector(selector, { timeout });\n stepResult = {\n type: \"wait\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector\n };\n } else if (\"waitForSelector\" in step) {\n assertAllowedSelector(step.waitForSelector.selector, context.forbiddenSelectors);\n await context.page.waitForSelector(step.waitForSelector.selector, {\n timeout: step.waitForSelector.timeout\n });\n stepResult = {\n type: \"waitForSelector\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector: step.waitForSelector.selector\n };\n } else if (\"waitForUrl\" in step) {\n await context.page.waitForURL(\n (url) => url.toString().includes(step.waitForUrl.value),\n { timeout: step.waitForUrl.timeout }\n );\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = {\n type: \"waitForUrl\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: step.waitForUrl.value\n };\n } else if (\"waitForNetworkIdle\" in step) {\n await context.page.waitForLoadState(\"networkidle\", {\n timeout: step.waitForNetworkIdle.timeout\n });\n stepResult = {\n type: \"waitForNetworkIdle\",\n status: \"pass\",\n durationMs: Date.now() - stepStart\n };\n } else if (\"hover\" in step) {\n const resolved = await resolveActionSelector(context, step.hover.selector);\n await context.page.locator(resolved.selector).hover();\n ensureAllowedUrl(context.page.url(), context.allowedDomains);\n stepResult = {\n type: \"hover\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector: resolved.selector,\n ...(resolved.healedFrom ? { healedFrom: resolved.healedFrom } : {})\n };\n } else if (\"scroll\" in step) {\n const amount = step.scroll.amount ?? 500;\n const scrollMap: Record<string, [number, number]> = {\n up: [0, -amount],\n down: [0, amount],\n left: [-amount, 0],\n right: [amount, 0]\n };\n const [x, y] = scrollMap[step.scroll.direction];\n await context.page.evaluate(([sx, sy]) => window.scrollBy(sx, sy), [x, y] as [number, number]);\n stepResult = {\n type: \"scroll\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: `${step.scroll.direction} ${amount}px`\n };\n } else if (\"scrollTo\" in step) {\n const resolved = await resolveActionSelector(context, step.scrollTo.selector);\n await context.page.locator(resolved.selector).scrollIntoViewIfNeeded();\n stepResult = {\n type: \"scrollTo\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector: resolved.selector,\n ...(resolved.healedFrom ? { healedFrom: resolved.healedFrom } : {})\n };\n } else if (\"screenshot\" in step) {\n const name = step.screenshot.name ?? `manual_step_${index + 1}.png`;\n if (/[/\\\\]|\\.\\./.test(name)) {\n throw new Error(`Invalid screenshot name: \"${name}\" must not contain path separators or \"..\"`);\n }\n const fileName = name.endsWith(\".png\") ? name : `${name}.png`;\n const relative = await addScreenshot(fileName);\n stepResult = {\n type: \"screenshot\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n screenshot: relative\n };\n } else if (\"if\" in step) {\n const condition = step.if;\n const selector = condition.visible ?? condition.notVisible!;\n assertAllowedSelector(selector, context.forbiddenSelectors);\n const count = await context.page.locator(selector).count();\n const conditionMet = condition.visible !== undefined ? count > 0 : count === 0;\n\n if (conditionMet) {\n const subResult = await executeNestedSteps(context, {\n steps: condition.then,\n stepPathPrefix: `${currentStepPath}.if.then`\n });\n for (const sr of subResult.results) {\n results.push({ ...sr, type: `if > ${sr.type}` });\n }\n screenshots.push(...subResult.screenshots);\n if (subResult.failed) {\n return {\n results,\n screenshots,\n failed: true,\n error: subResult.error\n };\n }\n stepResult = {\n type: \"if\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: `condition met, executed ${condition.then.length} steps`\n };\n } else {\n if (condition.else && condition.else.length > 0) {\n const subResult = await executeNestedSteps(context, {\n steps: condition.else,\n stepPathPrefix: `${currentStepPath}.if.else`\n });\n for (const sr of subResult.results) {\n results.push({ ...sr, type: `if > ${sr.type}` });\n }\n screenshots.push(...subResult.screenshots);\n if (subResult.failed) {\n return {\n results,\n screenshots,\n failed: true,\n error: subResult.error\n };\n }\n stepResult = {\n type: \"if\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: `condition not met, executed ${condition.else.length} else steps`\n };\n } else {\n stepResult = {\n type: \"if\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: \"condition not met, skipped\"\n };\n }\n }\n } else if (\"repeat\" in step) {\n const repeat = step.repeat;\n let totalSubSteps = 0;\n\n if (repeat.times !== undefined) {\n const totalPlanned = repeat.times * repeat.steps.length;\n if (totalPlanned + totalSubSteps > context.maxSteps) {\n throw new Error(`Repeat exceeded maxSteps guardrail (${context.maxSteps})`);\n }\n for (let i = 0; i < repeat.times; i++) {\n totalSubSteps += repeat.steps.length;\n const subResult = await executeNestedSteps(context, {\n steps: repeat.steps,\n stepPathPrefix: `${currentStepPath}.repeat.steps`\n });\n for (const sr of subResult.results) {\n results.push({ ...sr, type: `repeat[${i}] > ${sr.type}` });\n }\n screenshots.push(...subResult.screenshots);\n if (subResult.failed) {\n return {\n results,\n screenshots,\n failed: true,\n error: subResult.error\n };\n }\n }\n } else if (repeat.while !== undefined) {\n const maxIter = repeat.maxIterations!;\n const whileSelector = repeat.while.visible ?? repeat.while.notVisible!;\n assertAllowedSelector(whileSelector, context.forbiddenSelectors);\n for (let i = 0; i < maxIter; i++) {\n const whileCount = await context.page.locator(whileSelector).count();\n const shouldContinue = repeat.while.visible !== undefined ? whileCount > 0 : whileCount === 0;\n if (!shouldContinue) break;\n\n totalSubSteps += repeat.steps.length;\n if (totalSubSteps > context.maxSteps) {\n throw new Error(`Repeat exceeded maxSteps guardrail (${context.maxSteps})`);\n }\n const subResult = await executeNestedSteps(context, {\n steps: repeat.steps,\n stepPathPrefix: `${currentStepPath}.repeat.steps`\n });\n for (const sr of subResult.results) {\n results.push({ ...sr, type: `repeat[${i}] > ${sr.type}` });\n }\n screenshots.push(...subResult.screenshots);\n if (subResult.failed) {\n return {\n results,\n screenshots,\n failed: true,\n error: subResult.error\n };\n }\n }\n }\n\n stepResult = {\n type: \"repeat\",\n status: \"pass\",\n durationMs: Date.now() - stepStart\n };\n } else if (\"mockRoute\" in step) {\n const mock = step.mockRoute;\n const mocks = context.activeMocks ?? new Map<string, () => Promise<void>>();\n context.activeMocks = mocks;\n\n let responseBody: string;\n if (mock.response.body !== undefined) {\n responseBody = mock.response.body;\n } else {\n const responseFile = mock.response.file;\n if (!responseFile) {\n throw new Error(\"mock.response must include either body or file\");\n }\n const candidateFilePath = path.isAbsolute(responseFile)\n ? responseFile\n : path.join(context.configDir, responseFile);\n const resolvedConfigDir = path.resolve(context.configDir);\n const resolvedFilePath = path.resolve(candidateFilePath);\n const relativePath = path.relative(resolvedConfigDir, resolvedFilePath);\n const isWithinConfigDir =\n relativePath === \"\"\n || (\n relativePath !== \"..\"\n && !relativePath.startsWith(`..${path.sep}`)\n && !path.isAbsolute(relativePath)\n );\n if (!isWithinConfigDir) {\n throw new Error(\"mock.response.file must resolve within config directory\");\n }\n responseBody = await fs.promises.readFile(resolvedFilePath, \"utf-8\");\n }\n\n const contentType = mock.response.contentType ?? \"application/json\";\n const status = mock.response.status;\n\n await context.page.route(mock.url, (route) => {\n route.fulfill({\n status,\n contentType,\n body: responseBody\n });\n });\n\n mocks.set(mock.url, async () => {\n await context.page.unroute(mock.url);\n });\n\n stepResult = {\n type: \"mockRoute\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: mock.url\n };\n } else if (\"unmockRoute\" in step) {\n const url = typeof step.unmockRoute === \"string\" ? step.unmockRoute : step.unmockRoute.url;\n const mocks = context.activeMocks;\n if (!mocks || !mocks.has(url)) {\n throw new Error(`No active mock for URL: ${url}`);\n }\n const cleanup = mocks.get(url)!;\n await cleanup();\n mocks.delete(url);\n\n stepResult = {\n type: \"unmockRoute\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: url\n };\n } else if (\"evalScript\" in step) {\n const expression = typeof step.evalScript === \"string\"\n ? step.evalScript\n : step.evalScript.expression;\n const result = await context.page.evaluate(expression);\n const resultStr = String(result);\n if (typeof step.evalScript !== \"string\" && step.evalScript.as) {\n runtimeVars.set(step.evalScript.as, resultStr);\n }\n stepResult = {\n type: \"evalScript\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: resultStr.length > 200 ? resultStr.slice(0, 200) + \"\\u2026\" : resultStr\n };\n } else if (\"runScript\" in step) {\n const filePath = path.isAbsolute(step.runScript.file)\n ? step.runScript.file\n : path.join(context.configDir, step.runScript.file);\n const fileContents = fs.readFileSync(filePath, \"utf-8\");\n await context.page.evaluate(fileContents);\n stepResult = {\n type: \"runScript\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: step.runScript.file\n };\n } else if (\"assertScreenshot\" in step) {\n const { compareScreenshots, ensureBaselineDir } = await import(\"./visual.js\");\n const name = step.assertScreenshot.name;\n const threshold = step.assertScreenshot.threshold ?? 0.1;\n const baselineDir = ensureBaselineDir(context.configDir);\n const baselinePath = path.join(baselineDir, `${name}.png`);\n const currentScreenshotPath = path.join(context.runDir, \"screenshots\", `${name}-current.png`);\n fs.mkdirSync(path.dirname(currentScreenshotPath), { recursive: true });\n await context.page.screenshot({ path: currentScreenshotPath, fullPage: true });\n screenshots.push(path.join(\"screenshots\", `${name}-current.png`));\n\n if (!fs.existsSync(baselinePath)) {\n fs.copyFileSync(currentScreenshotPath, baselinePath);\n stepResult = {\n type: \"assertScreenshot\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: \"baseline created\"\n };\n } else {\n const diffPath = path.join(context.runDir, \"screenshots\", `${name}-diff.png`);\n const comparison = await compareScreenshots(baselinePath, currentScreenshotPath, diffPath, threshold);\n if (comparison.match) {\n stepResult = {\n type: \"assertScreenshot\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: `diff: ${(comparison.diffPercentage * 100).toFixed(2)}%`\n };\n } else {\n screenshots.push(path.join(\"screenshots\", `${name}-diff.png`));\n throw new Error(\n `Visual regression: ${(comparison.diffPercentage * 100).toFixed(2)}% diff exceeds threshold ${(threshold * 100).toFixed(0)}%`\n );\n }\n }\n } else if (\"copyText\" in step) {\n assertAllowedSelector(step.copyText.selector, context.forbiddenSelectors);\n const text = await context.page.locator(step.copyText.selector).textContent();\n if (text === null) {\n throw new Error(`No text content found for selector: ${step.copyText.selector}`);\n }\n runtimeVars.set(step.copyText.as, text);\n stepResult = {\n type: \"copyText\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n selector: step.copyText.selector,\n value: \"[REDACTED]\"\n };\n } else if (\"waitForDownload\" in step) {\n const opts = step.waitForDownload;\n const downloadPromise = context.pendingDownload ?? armDownloadListener(\n context.page,\n opts?.timeout ?? 30000\n );\n context.pendingDownload = undefined;\n const download = await downloadPromise;\n const suggestedFilename = validateDownloadFilename(download.suggestedFilename());\n if (opts?.filename !== undefined && suggestedFilename !== opts.filename) {\n throw new Error(\n `Download filename mismatch: expected \"${opts.filename}\", got \"${suggestedFilename}\"`\n );\n }\n const savePath = path.join(context.runDir, suggestedFilename);\n await download.saveAs(savePath);\n stepResult = {\n type: \"waitForDownload\",\n status: \"pass\",\n durationMs: Date.now() - stepStart,\n value: suggestedFilename\n };\n }\n\n if (!stepResult) {\n throw new Error(\"Unknown step type\");\n }\n\n if (context.screenshotsMode === \"all\" && stepResult.type !== \"screenshot\") {\n const fileName = `step_${index + 1}.png`;\n await addScreenshot(fileName);\n }\n\n results.push(stepResult);\n context.onStep?.(stepResult, step, index);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Step failed\";\n stepResult = {\n type: stepResult?.type ?? stepType,\n status: \"fail\",\n durationMs: Date.now() - stepStart,\n error: message\n };\n\n if (context.screenshotsMode === \"on-failure\") {\n const fileName = `failure_step_${index + 1}.png`;\n await addScreenshot(fileName);\n }\n\n results.push(stepResult);\n context.onStep?.(stepResult, step, index);\n return { results, screenshots, failed: true, error: message };\n }\n }\n\n return { results, screenshots, failed: false };\n}\n\nexport async function captureFinalScreenshot(page: Page, runDir: string): Promise<string> {\n const screenshotsDir = path.join(runDir, \"screenshots\");\n fs.mkdirSync(screenshotsDir, { recursive: true });\n const fileName = \"final.png\";\n const filePath = screenshotPath(screenshotsDir, fileName);\n await captureScreenshot(page, filePath);\n return path.join(\"screenshots\", fileName);\n}\n","import type { Page } from \"playwright\";\n\nexport async function clickElement(page: Page, selector: string): Promise<void> {\n await page.locator(selector).click();\n}\n\nexport async function fillElement(page: Page, selector: string, value: string): Promise<void> {\n await page.locator(selector).fill(value);\n}\n\nexport async function pressKey(page: Page, selector: string, key: string): Promise<void> {\n await page.locator(selector).press(key);\n}\n\nexport async function selectOption(page: Page, selector: string, value: string): Promise<void> {\n await page.locator(selector).selectOption(value);\n}\n\nexport function setupDialogHandler(page: Page, action: \"accept\" | \"dismiss\"): void {\n page.once(\"dialog\", async (dialog) => {\n if (action === \"accept\") {\n await dialog.accept();\n } else {\n await dialog.dismiss();\n }\n });\n}\n\nexport async function setInputFiles(page: Page, selector: string, files: string | string[]): Promise<void> {\n await page.locator(selector).setInputFiles(files);\n}\n","import type { Locator, Page } from \"playwright\";\n\n/**\n * Self-healing selectors (PROWL-023). When an explicit selector matches nothing,\n * derive the human \"intent\" from the selector and try alternative strategies —\n * fuzzy text, ARIA label, and structural (interactive element + text) — healing\n * ONLY to a candidate that resolves to exactly one element. Opt-in via\n * `guardrails.selfHealing`; never guesses among multiple matches.\n */\n\nexport type HealResult = {\n /** The candidate selector that uniquely matched. */\n selector: string;\n /** The original selector that failed. */\n healedFrom: string;\n /** Which strategy produced the match (for reporting). */\n strategy: \"text\" | \"aria\" | \"structural\";\n};\n\nconst INTERACTIVE_TAGS = [\"button\", \"a\", \"input\", \"select\", \"textarea\"];\n\n/**\n * Pull human-meaningful words out of a raw selector. Reads id (`#submit-btn`),\n * class tokens (`.login-form`), and attribute values (`[data-testid=\"sign-in\"]`,\n * `[aria-label='Close']`), splitting on separators and camelCase. Returns the\n * lowercased words (de-duped, in order) and a space-joined label. Mapping is\n * intentionally literal/predictable — no noise-word filtering.\n */\nexport function extractSelectorIntent(selector: string): { words: string[]; label: string } {\n const raw: string[] = [];\n\n // #id and .class tokens\n for (const match of selector.matchAll(/[#.]([A-Za-z_][\\w-]*)/g)) {\n raw.push(match[1]);\n }\n // attribute values: [attr=\"value\"] / [attr='value'] / [attr=value]\n for (const match of selector.matchAll(/\\[[A-Za-z_:-]+\\s*[~|^$*]?=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\]\\s]+))\\]/g)) {\n const value = match[1] ?? match[2] ?? match[3];\n if (value) raw.push(value);\n }\n\n const words: string[] = [];\n for (const token of raw) {\n for (const part of splitToken(token)) {\n const lower = part.toLowerCase();\n if (lower.length > 0 && !words.includes(lower)) {\n words.push(lower);\n }\n }\n }\n\n return { words, label: words.join(\" \") };\n}\n\nfunction splitToken(token: string): string[] {\n return token\n // camelCase / PascalCase boundaries\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n // separators\n .split(/[\\s\\-_.:]+/)\n .filter((part) => part.length > 0);\n}\n\n/**\n * Build candidate Playwright selectors for a derived intent, in AC priority order:\n * (1) fuzzy text, (2) ARIA label, (3) structural (interactive element + text).\n * Returns [] when the selector carried no usable words.\n */\nexport function buildHealCandidates(selector: string): Array<{ selector: string; strategy: HealResult[\"strategy\"] }> {\n const { words, label } = extractSelectorIntent(selector);\n if (words.length === 0) return [];\n\n const escaped = label.replace(/\"/g, '\\\\\"');\n const candidates: Array<{ selector: string; strategy: HealResult[\"strategy\"] }> = [];\n\n // 1. Similar text content (case-insensitive substring via Playwright text engine)\n candidates.push({ selector: `text=${label}`, strategy: \"text\" });\n\n // 2. Similar ARIA label (case-insensitive attribute substring)\n candidates.push({ selector: `[aria-label*=\"${escaped}\" i]`, strategy: \"aria\" });\n\n // 3. Nearby element with matching structure: an interactive element containing the text\n for (const tag of INTERACTIVE_TAGS) {\n candidates.push({ selector: `${tag}:has-text(\"${escaped}\")`, strategy: \"structural\" });\n }\n\n return candidates;\n}\n\n/**\n * Attempt to heal a failed selector. Returns a HealResult only when a candidate\n * resolves to exactly one element; otherwise null. Counting is delegated so this\n * is unit-testable with a fake page.\n */\nexport async function healSelector(\n page: Pick<Page, \"locator\">,\n selector: string,\n options: { enabled: boolean }\n): Promise<HealResult | null> {\n if (!options.enabled) return null;\n\n for (const candidate of buildHealCandidates(selector)) {\n let count: number;\n try {\n const locator: Pick<Locator, \"count\"> = page.locator(candidate.selector);\n count = await locator.count();\n } catch {\n continue; // ignore candidates Playwright can't parse\n }\n if (count === 1) {\n return { selector: candidate.selector, healedFrom: selector, strategy: candidate.strategy };\n }\n }\n\n return null;\n}\n","import type { Page } from \"playwright\";\nimport type { Assertion, AssertionResult, Config } from \"../types/index.js\";\n\nexport type ConsoleEntry = {\n type: string;\n text: string;\n location?: string;\n};\n\nexport type NetworkEntry = {\n url: string;\n status: number;\n};\n\nfunction shouldIgnoreNetwork(url: string, patterns: string[]): boolean {\n return patterns.some((pattern) => url.includes(pattern));\n}\n\nfunction filterNetworkEntries(entries: NetworkEntry[], patterns: string[]): NetworkEntry[] {\n if (patterns.length === 0) {\n return entries;\n }\n return entries.filter((entry) => !shouldIgnoreNetwork(entry.url, patterns));\n}\n\nfunction mergeAssertions(config: Config, huntAssertions: Assertion[] = []): Assertion[] {\n let noConsoleErrors = config.assertions.noConsoleErrors;\n let noNetworkErrors = config.assertions.noNetworkErrors;\n\n for (const assertion of huntAssertions) {\n if (\"noConsoleErrors\" in assertion) {\n noConsoleErrors = assertion.noConsoleErrors;\n }\n if (\"noNetworkErrors\" in assertion) {\n noNetworkErrors = assertion.noNetworkErrors;\n }\n }\n\n const merged: Assertion[] = [];\n if (noConsoleErrors) {\n merged.push({ noConsoleErrors: true });\n }\n if (noNetworkErrors) {\n merged.push({ noNetworkErrors: true });\n }\n\n for (const assertion of huntAssertions) {\n if (\"noConsoleErrors\" in assertion || \"noNetworkErrors\" in assertion) {\n continue;\n }\n merged.push(assertion);\n }\n\n return merged;\n}\n\nexport async function evaluateAssertions(options: {\n page: Page;\n config: Config;\n huntAssertions?: Assertion[];\n consoleEntries: ConsoleEntry[];\n networkEntries: NetworkEntry[];\n}): Promise<AssertionResult[]> {\n const assertions = mergeAssertions(options.config, options.huntAssertions);\n const results: AssertionResult[] = [];\n const networkEntries = filterNetworkEntries(\n options.networkEntries,\n options.config.assertions.networkIgnorePatterns\n );\n\n for (const assertion of assertions) {\n try {\n if (\"selectorExists\" in assertion) {\n const count = await options.page.locator(assertion.selectorExists).count();\n results.push({\n type: \"selectorExists\",\n value: assertion.selectorExists,\n status: count > 0 ? \"pass\" : \"fail\",\n error: count > 0 ? undefined : \"Selector not found\"\n });\n continue;\n }\n if (\"selectorNotExists\" in assertion) {\n const count = await options.page.locator(assertion.selectorNotExists).count();\n results.push({\n type: \"selectorNotExists\",\n value: assertion.selectorNotExists,\n status: count === 0 ? \"pass\" : \"fail\",\n error: count === 0 ? undefined : \"Selector exists\"\n });\n continue;\n }\n if (\"urlIncludes\" in assertion) {\n const current = options.page.url();\n const pass = current.includes(assertion.urlIncludes);\n results.push({\n type: \"urlIncludes\",\n value: assertion.urlIncludes,\n status: pass ? \"pass\" : \"fail\",\n error: pass ? undefined : `URL did not include ${assertion.urlIncludes}`\n });\n continue;\n }\n if (\"urlEquals\" in assertion) {\n const current = options.page.url();\n const pass = current === assertion.urlEquals;\n results.push({\n type: \"urlEquals\",\n value: assertion.urlEquals,\n status: pass ? \"pass\" : \"fail\",\n error: pass ? undefined : `URL did not equal ${assertion.urlEquals}`\n });\n continue;\n }\n if (\"noConsoleErrors\" in assertion) {\n const errors = options.consoleEntries.filter((entry) => entry.type === \"error\");\n const pass = errors.length === 0;\n results.push({\n type: \"noConsoleErrors\",\n value: true,\n status: pass ? \"pass\" : \"fail\",\n error: pass ? undefined : `${errors.length} console error(s)`\n });\n continue;\n }\n if (\"noNetworkErrors\" in assertion) {\n const pass = networkEntries.length === 0;\n results.push({\n type: \"noNetworkErrors\",\n value: true,\n status: pass ? \"pass\" : \"fail\",\n error: pass ? undefined : `${networkEntries.length} network error(s)`\n });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Assertion failed\";\n const type = Object.keys(assertion)[0] ?? \"assertion\";\n results.push({\n type,\n status: \"fail\",\n error: message\n });\n }\n }\n\n return results;\n}\n","import type { Response } from \"playwright\";\nimport type { TraceCorrelation } from \"../types/index.js\";\n\n/** Default response header carrying a distributed-trace id (W3C Trace Context). */\nexport const DEFAULT_TRACE_HEADER = \"traceparent\";\n\n/**\n * Extract a trace id from a trace header value.\n *\n * For the W3C `traceparent` format (`version-traceid-spanid-flags`, e.g.\n * `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01`) the 32-hex trace id\n * is returned. For a non-standard header that simply carries an id, the trimmed\n * raw value is used. Returns undefined for an empty value.\n */\nexport function parseTraceId(headerValue: string): string | undefined {\n const raw = headerValue.trim();\n if (raw.length === 0) return undefined;\n\n const parts = raw.split(\"-\");\n if (parts.length >= 3 && /^[0-9a-f]{32}$/i.test(parts[1])) {\n return parts[1];\n }\n\n return raw;\n}\n\nfunction readHeader(headers: Record<string, string>, headerName: string): string | undefined {\n const normalizedName = headerName.toLowerCase();\n return headers[normalizedName];\n}\n\nfunction redactValues(text: string, values: readonly string[]): string {\n let redacted = text;\n for (const value of values) {\n if (value.length === 0) continue;\n redacted = redacted.split(value).join(\"[REDACTED]\");\n }\n return redacted;\n}\n\n/**\n * If a failing response carries the configured trace header, record a correlation\n * linking the response URL/status to its trace id. No-op when the header is absent\n * or empty, so passing apps produce no noise.\n */\nexport function captureTraceCorrelation(\n response: Pick<Response, \"url\" | \"status\" | \"headers\">,\n headerName: string,\n sink: TraceCorrelation[],\n redactionValues: readonly string[] = []\n): void {\n const value = readHeader(response.headers(), headerName);\n if (!value) return;\n\n const traceId = parseTraceId(value);\n if (!traceId) return;\n\n sink.push({\n url: redactValues(response.url(), redactionValues),\n status: response.status(),\n traceId,\n header: value\n });\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RunResult } from \"../types/index.js\";\n\nexport function writeResult(runDir: string, result: RunResult): string {\n const fileName = \"result.json\";\n const fullPath = path.join(runDir, fileName);\n fs.writeFileSync(fullPath, JSON.stringify(result, null, 2));\n return fileName;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { AssertionResult, RunResult, StepResult } from \"../types/index.js\";\n\nexport function escapeMd(text: string): string {\n return text.replace(/([|`*_{}[\\]()#+\\-!\\\\])/g, \"\\\\$1\");\n}\n\nfunction formatStep(step: StepResult): string {\n const base = `- [${step.status.toUpperCase()}] ${step.type} (${step.durationMs}ms)`;\n const selector = step.selector ? ` selector=${step.selector}` : \"\";\n const healed = step.healedFrom ? ` healed-from=${escapeMd(step.healedFrom)}` : \"\";\n const value = step.value ? ` value=${escapeMd(step.value)}` : \"\";\n const error = step.error ? ` error=${escapeMd(step.error)}` : \"\";\n return `${base}${selector}${healed}${value}${error}`;\n}\n\nfunction formatAssertion(assertion: AssertionResult): string {\n const value = assertion.value !== undefined ? ` value=${typeof assertion.value === \"string\" ? escapeMd(assertion.value) : assertion.value}` : \"\";\n const error = assertion.error ? ` error=${escapeMd(assertion.error)}` : \"\";\n return `- [${assertion.status.toUpperCase()}] ${assertion.type}${value}${error}`;\n}\n\nexport function writeSummary(runDir: string, result: RunResult): string {\n const lines: string[] = [];\n lines.push(\"# Prowl Run Summary\");\n lines.push(\"\");\n lines.push(`Status: ${result.status.toUpperCase()}`);\n lines.push(`Hunt: ${result.hunt}`);\n lines.push(`Target: ${result.targetUrl}`);\n lines.push(`Started: ${result.startedAt}`);\n lines.push(`Duration: ${result.durationMs}ms`);\n lines.push(\"\");\n lines.push(\"## Steps\");\n for (const step of result.steps) {\n lines.push(formatStep(step));\n }\n\n const healed = result.steps.filter((step) => step.healedFrom);\n if (healed.length > 0) {\n lines.push(\"\");\n lines.push(\"## Self-Healed Selectors\");\n lines.push(\"These selectors no longer matched and were auto-healed. Update your hunt to use the healed selector (or a stable `data-testid`):\");\n for (const step of healed) {\n lines.push(`- ${escapeMd(step.healedFrom ?? \"\")} → ${escapeMd(step.selector ?? \"\")}`);\n }\n }\n\n lines.push(\"\");\n lines.push(\"## Assertions\");\n for (const assertion of result.assertions) {\n lines.push(formatAssertion(assertion));\n }\n if (result.traceCorrelations && result.traceCorrelations.length > 0) {\n lines.push(\"\");\n lines.push(\"## Trace Correlations\");\n for (const correlation of result.traceCorrelations) {\n lines.push(\n `- [${correlation.status}] ${escapeMd(correlation.url)} traceId=${escapeMd(correlation.traceId)}`\n );\n }\n }\n\n lines.push(\"\");\n lines.push(\"## Artifacts\");\n const artifacts = result.artifacts;\n if (artifacts.summary) {\n lines.push(`- summary: ${artifacts.summary}`);\n }\n if (artifacts.console) {\n lines.push(`- console: ${artifacts.console}`);\n }\n if (artifacts.trace) {\n lines.push(`- trace: ${artifacts.trace}`);\n }\n if (artifacts.networkHar) {\n lines.push(`- network: ${artifacts.networkHar}`);\n }\n if (artifacts.junit) {\n lines.push(`- junit: ${artifacts.junit}`);\n }\n if (artifacts.screenshots && artifacts.screenshots.length > 0) {\n for (const screenshot of artifacts.screenshots) {\n lines.push(`- screenshot: ${screenshot}`);\n }\n }\n\n const fileName = \"summary.md\";\n const fullPath = path.join(runDir, fileName);\n fs.writeFileSync(fullPath, `${lines.join(\"\\n\")}\\n`);\n return fileName;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RunResult } from \"../types/index.js\";\n\nexport function escapeXml(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n\nexport function writeJunit(runDir: string, result: RunResult): string {\n const totalTests = result.steps.length + result.assertions.length;\n const failures =\n result.steps.filter((s) => s.status === \"fail\").length +\n result.assertions.filter((a) => a.status === \"fail\").length;\n const timeSeconds = (result.durationMs / 1000).toFixed(3);\n const huntName = escapeXml(result.hunt);\n\n const lines: string[] = [];\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n lines.push(\"<testsuites>\");\n lines.push(\n ` <testsuite name=\"${huntName}\" tests=\"${totalTests}\" failures=\"${failures}\" errors=\"0\" time=\"${timeSeconds}\" timestamp=\"${escapeXml(result.startedAt)}\">`\n );\n\n for (let i = 0; i < result.steps.length; i++) {\n const step = result.steps[i];\n const stepTime = (step.durationMs / 1000).toFixed(3);\n const caseName = escapeXml(`step ${i + 1}: ${step.type}`);\n\n if (step.status === \"fail\") {\n const failureText = step.error ?? `Step ${step.type} failed with no error provided`;\n const escapedFailureText = escapeXml(failureText);\n lines.push(` <testcase name=\"${caseName}\" classname=\"${huntName}\" time=\"${stepTime}\">`);\n lines.push(` <failure message=\"${escapedFailureText}\" type=\"step\">${escapedFailureText}</failure>`);\n lines.push(\" </testcase>\");\n } else {\n lines.push(` <testcase name=\"${caseName}\" classname=\"${huntName}\" time=\"${stepTime}\"/>`);\n }\n }\n\n for (const assertion of result.assertions) {\n const caseName = escapeXml(`assertion: ${assertion.type}`);\n\n if (assertion.status === \"fail\") {\n const failureText = assertion.error ?? `Assertion ${assertion.type} failed with no error provided`;\n const escapedFailureText = escapeXml(failureText);\n lines.push(` <testcase name=\"${caseName}\" classname=\"${huntName}\" time=\"0\">`);\n lines.push(` <failure message=\"${escapedFailureText}\" type=\"assertion\">${escapedFailureText}</failure>`);\n lines.push(\" </testcase>\");\n } else {\n lines.push(` <testcase name=\"${caseName}\" classname=\"${huntName}\" time=\"0\"/>`);\n }\n }\n\n lines.push(\" </testsuite>\");\n lines.push(\"</testsuites>\");\n\n const fileName = \"junit.xml\";\n const fullPath = path.join(runDir, fileName);\n fs.writeFileSync(fullPath, `${lines.join(\"\\n\")}\\n`);\n return fileName;\n}\n","import type { RunResult } from \"../types/index.js\";\nimport { writeResult } from \"./result.js\";\nimport { writeSummary } from \"./summary.js\";\nimport { writeJunit } from \"./junit.js\";\n\nexport type ReportOptions = {\n junit?: boolean;\n};\n\nexport function writeReports(runDir: string, result: RunResult, options?: ReportOptions): RunResult {\n const summary = writeSummary(runDir, result);\n const updated: RunResult = {\n ...result,\n artifacts: {\n ...result.artifacts,\n summary\n }\n };\n\n if (options?.junit) {\n updated.artifacts.junit = writeJunit(runDir, updated);\n }\n\n writeResult(runDir, updated);\n\n return updated;\n}\n","export function timestamp(prefix?: string): string {\n const now = new Date();\n const pad = (value: number): string => value.toString().padStart(2, \"0\");\n const pad3 = (value: number): string => value.toString().padStart(3, \"0\");\n const ts = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}_${pad(\n now.getHours()\n )}-${pad(now.getMinutes())}-${pad(now.getSeconds())}-${pad3(now.getMilliseconds())}`;\n return prefix ? `${prefix}-${ts}` : ts;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { HistoryEntry, HistoryFile } from \"../types/index.js\";\n\nconst HISTORY_FILE = \"history.json\";\nconst LOCK_FILE_SUFFIX = \".lock\";\nconst LOCK_RETRY_MS = 10;\nconst LOCK_TIMEOUT_MS = 5000;\nconst SLEEP_BUFFER = new Int32Array(new SharedArrayBuffer(4));\n\nfunction historyPath(configDir: string): string {\n return path.join(configDir, HISTORY_FILE);\n}\n\nfunction isHistoryEntry(value: unknown): value is HistoryEntry {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const entry = value as Record<string, unknown>;\n return (\n typeof entry.hunt === \"string\" &&\n (entry.status === \"pass\" || entry.status === \"fail\") &&\n typeof entry.durationMs === \"number\" &&\n Number.isFinite(entry.durationMs) &&\n typeof entry.startedAt === \"string\" &&\n (entry.runDir === undefined || typeof entry.runDir === \"string\")\n );\n}\n\nexport function readHistory(configDir: string): HistoryFile {\n const filePath = historyPath(configDir);\n if (!fs.existsSync(filePath)) {\n return { entries: [] };\n }\n try {\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const parsed = JSON.parse(raw) as unknown;\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"entries\" in parsed &&\n Array.isArray((parsed as { entries: unknown }).entries)\n ) {\n const validatedEntries = (parsed as { entries: unknown[] }).entries.filter(isHistoryEntry);\n return { entries: validatedEntries };\n }\n return { entries: [] };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`Failed to read history file at ${filePath}: ${message}`);\n return { entries: [] };\n }\n}\n\nexport function readHuntHistory(configDir: string, huntName: string): HistoryEntry[] {\n const { entries } = readHistory(configDir);\n return entries.filter((entry) => entry.hunt === huntName);\n}\n\nexport function pruneEntries(entries: HistoryEntry[], maxRuns: number): HistoryEntry[] {\n const perHunt = new Map<string, HistoryEntry[]>();\n for (const entry of entries) {\n const list = perHunt.get(entry.hunt) ?? [];\n list.push(entry);\n perHunt.set(entry.hunt, list);\n }\n\n const keptEntries = new Set<HistoryEntry>();\n for (const list of perHunt.values()) {\n const kept = list.length > maxRuns ? list.slice(list.length - maxRuns) : list;\n for (const entry of kept) {\n keptEntries.add(entry);\n }\n }\n return entries.filter((entry) => keptEntries.has(entry));\n}\n\nfunction sleepSync(ms: number): void {\n Atomics.wait(SLEEP_BUFFER, 0, 0, ms);\n}\n\nfunction withHistoryLock<T>(configDir: string, fn: () => T): T {\n const filePath = historyPath(configDir);\n const lockPath = `${filePath}${LOCK_FILE_SUFFIX}`;\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n const startedAt = Date.now();\n\n while (Date.now() - startedAt < LOCK_TIMEOUT_MS) {\n let fd: number;\n try {\n fd = fs.openSync(lockPath, \"wx\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\") {\n sleepSync(LOCK_RETRY_MS);\n continue;\n }\n throw error;\n }\n\n try {\n return fn();\n } finally {\n try {\n fs.closeSync(fd);\n } catch {\n // Ignore close failures during cleanup.\n }\n fs.rmSync(lockPath, { force: true });\n }\n }\n\n throw new Error(\n `Failed to acquire history lock before timeout (${LOCK_TIMEOUT_MS}ms): ${lockPath}; started waiting at ${new Date(startedAt).toISOString()}`\n );\n}\n\nexport function appendEntry(\n configDir: string,\n entry: HistoryEntry,\n maxRuns: number\n): void {\n const filePath = historyPath(configDir);\n withHistoryLock(configDir, () => {\n const current = readHistory(configDir);\n const next = pruneEntries([...current.entries, entry], maxRuns);\n const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;\n fs.writeFileSync(tempPath, `${JSON.stringify({ entries: next }, null, 2)}\\n`);\n fs.renameSync(tempPath, filePath);\n });\n}\n","import chalk from \"chalk\";\nimport type { Step, StepResult, RunResult } from \"../types/index.js\";\n\nexport function describeStep(step: Step): string {\n if (\"navigate\" in step) return `navigate \"${step.navigate}\"`;\n if (\"click\" in step) {\n if (typeof step.click === \"string\") return `click \"${step.click}\"`;\n return `click \"${step.click.selector}\"`;\n }\n if (\"fill\" in step) {\n if (\"selector\" in step.fill && \"value\" in step.fill) {\n return `fill \"${(step.fill as { selector: string }).selector}\"`;\n }\n const label = Object.keys(step.fill)[0];\n return `fill \"${label}\"`;\n }\n if (\"type\" in step) return `type \"${truncate(step.type, 20)}\"`;\n if (\"selectOption\" in step) return `selectOption \"${step.selectOption.selector}\"`;\n if (\"select\" in step) {\n const label = Object.keys(step.select)[0];\n return `select \"${label}\"`;\n }\n if (\"onDialog\" in step) return `onDialog ${step.onDialog.action}`;\n if (\"setInputFiles\" in step) return `setInputFiles \"${step.setInputFiles.selector}\"`;\n if (\"runHunt\" in step) {\n const name = typeof step.runHunt === \"string\" ? step.runHunt : step.runHunt.name;\n return `runHunt \"${name}\"`;\n }\n if (\"press\" in step) return `press \"${step.press.key}\"`;\n if (\"assert\" in step) {\n const a = step.assert;\n if (a.visible) return `assert visible \"${a.visible}\"`;\n if (a.notVisible) return `assert notVisible \"${a.notVisible}\"`;\n if (a.urlIncludes) return `assert urlIncludes \"${a.urlIncludes}\"`;\n if (a.urlEquals) return `assert urlEquals \"${a.urlEquals}\"`;\n return \"assert\";\n }\n if (\"wait\" in step) {\n if (typeof step.wait === \"string\") return `wait \"${step.wait}\"`;\n return `wait \"${step.wait.for}\"`;\n }\n if (\"waitForSelector\" in step) return `waitForSelector \"${step.waitForSelector.selector}\"`;\n if (\"waitForUrl\" in step) return `waitForUrl \"${step.waitForUrl.value}\"`;\n if (\"waitForNetworkIdle\" in step) return \"waitForNetworkIdle\";\n if (\"hover\" in step) return `hover \"${step.hover.selector}\"`;\n if (\"scroll\" in step) return `scroll ${step.scroll.direction} ${step.scroll.amount ?? 500}px`;\n if (\"scrollTo\" in step) return `scrollTo \"${step.scrollTo.selector}\"`;\n if (\"screenshot\" in step) return `screenshot \"${step.screenshot.name ?? \"auto\"}\"`;\n if (\"if\" in step) {\n if (step.if.visible !== undefined) return `if visible \"${step.if.visible}\"`;\n if (step.if.notVisible !== undefined) return `if notVisible \"${step.if.notVisible}\"`;\n return \"if condition unspecified\";\n }\n if (\"repeat\" in step) {\n if (step.repeat.times !== undefined) return `repeat ${step.repeat.times} times`;\n if (step.repeat.while?.visible !== undefined) {\n return `repeat while visible \"${step.repeat.while.visible}\"`;\n }\n if (step.repeat.while?.notVisible !== undefined) {\n return `repeat while not visible \"${step.repeat.while.notVisible}\"`;\n }\n return \"repeat while condition unspecified\";\n }\n if (\"mockRoute\" in step) return `mockRoute \"${step.mockRoute.url}\"`;\n if (\"unmockRoute\" in step) return `unmockRoute \"${step.unmockRoute.url}\"`;\n if (\"evalScript\" in step) {\n if (typeof step.evalScript === \"string\") return `evalScript \"${truncate(step.evalScript, 40)}\"`;\n const asLabel = step.evalScript.as ? ` as ${step.evalScript.as}` : \"\";\n return `evalScript \"${truncate(step.evalScript.expression, 40)}\"${asLabel}`;\n }\n if (\"runScript\" in step) return `runScript \"${step.runScript.file}\"`;\n if (\"assertScreenshot\" in step) {\n const th = step.assertScreenshot.threshold !== undefined ? ` (threshold: ${step.assertScreenshot.threshold})` : \"\";\n return `assertScreenshot \"${step.assertScreenshot.name}\"${th}`;\n }\n return \"unknown step\";\n}\n\nexport function truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return text.slice(0, max - 1) + \"\\u2026\";\n}\n\nexport function printHuntHeader(huntName: string): void {\n console.log(`\\n ${chalk.cyan(\"\\u25CF\")} ${chalk.bold(\"Running hunt:\")} ${huntName}`);\n}\n\nexport function printStepResult(result: StepResult, step: Step | undefined, _index: number): void {\n const label = step ? describeStep(step) : result.type;\n const duration = chalk.gray(`(${result.durationMs}ms)`);\n\n if (result.status === \"pass\") {\n console.log(` ${chalk.green(\"\\u2713\")} ${label} ${duration}`);\n } else {\n const error = result.error ? chalk.gray(` \\u2014 ${result.error}`) : \"\";\n console.log(` ${chalk.red(\"\\u2717\")} ${label} ${duration}${error}`);\n }\n}\n\nexport function printHuntSummary(result: RunResult, runDir: string): void {\n const passed = result.steps.filter((s) => s.status === \"pass\").length;\n const total = result.steps.length;\n const status =\n result.status === \"pass\"\n ? chalk.green.bold(\"PASS\")\n : chalk.red.bold(\"FAIL\");\n const stepCount = chalk.gray(`${passed}/${total} steps`);\n const duration = chalk.gray(`(${result.durationMs}ms)`);\n\n console.log(`\\n ${status} ${chalk.bold(result.hunt)} ${duration} ${stepCount}`);\n console.log(` ${chalk.gray(\"Artifacts:\")} ${runDir}\\n`);\n}\n","import chalk from \"chalk\";\n\nconst FIGLET_LOGO = [\n \" ____ ____ ___ _ _ _ ___ _\",\n \"| _ \\\\| _ \\\\ / _ \\\\| | | | | / _ \\\\ / \\\\\",\n \"| |_) | |_) | | | | | | | | | | | |/ _ \\\\\",\n \"| __/| _ <| |_| | |/\\\\| | |__| |_| / ___ \\\\\",\n \"|_| |_| \\\\_\\\\\\\\___/|_/ \\\\_\\\\____\\\\\\\\__\\\\_\\\\_/ \\\\_\\\\\",\n];\n\nexport function welcomeBanner(): string {\n const logo = FIGLET_LOGO.map((line) => chalk.cyan(line)).join(\"\\n\");\n return `\\n${logo}\\n\\n ${chalk.gray(\"QA testing for the web\")}\\n`;\n}\n\nexport function resultMascot(state: \"pass\" | \"fail\", huntName: string): string {\n const isPassing = state === \"pass\";\n const icon = isPassing ? \"\\u2713\" : \"\\u2717\";\n const label = isPassing ? \"PASS\" : \"FAIL\";\n const color = isPassing ? chalk.green : chalk.red;\n\n const content = ` ${icon} ${label} ${huntName} `;\n // Strip ANSI for width calculation\n const innerWidth = content.length;\n const top = ` \\u250C${\"─\".repeat(innerWidth)}\\u2510`;\n const mid = ` \\u2502${content}\\u2502`;\n const bot = ` \\u2514${\"─\".repeat(innerWidth)}\\u2518`;\n\n return color(`${top}\\n${mid}\\n${bot}`);\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { welcomeBanner } from \"../mascot.js\";\nimport { CONFIG_DIR } from \"../../config/loader.js\";\n\nfunction getPackageRoot(): string {\n const currentFile = fileURLToPath(import.meta.url);\n let dir = path.dirname(currentFile);\n const root = path.parse(dir).root;\n\n while (dir !== root) {\n if (fs.existsSync(path.join(dir, \"package.json\"))) {\n return dir;\n }\n dir = path.dirname(dir);\n }\n\n if (fs.existsSync(path.join(root, \"package.json\"))) {\n return root;\n }\n\n throw new Error(\"Cannot find package root. Reinstall prowl-tools.\");\n}\n\nfunction copyFile(source: string, destination: string): void {\n fs.mkdirSync(path.dirname(destination), { recursive: true });\n fs.copyFileSync(source, destination);\n}\n\nexport function buildInitCommand(): Command {\n const command = new Command(\"init\")\n .option(\"--force\", `Overwrite existing ${CONFIG_DIR} directory`)\n .action((options) => {\n const root = process.cwd();\n const prowlDir = path.join(root, CONFIG_DIR);\n if (fs.existsSync(prowlDir) && !options.force) {\n console.error(\n chalk.red(\n `${CONFIG_DIR} already exists. Run with --force to reinitialize prowl configuration without deleting existing files.`\n )\n );\n process.exitCode = 1;\n return;\n }\n\n const packageRoot = getPackageRoot();\n const examplesDir = path.join(packageRoot, \"examples\");\n const exampleConfig = path.join(examplesDir, \"config.yml\");\n const exampleHuntsDir = path.join(examplesDir, \"hunts\");\n\n if (!fs.existsSync(exampleConfig) || !fs.existsSync(exampleHuntsDir)) {\n console.error(chalk.red(\"Examples not found in package. Reinstall prowl-tools.\"));\n process.exitCode = 1;\n return;\n }\n\n copyFile(exampleConfig, path.join(prowlDir, \"config.yml\"));\n\n const huntFiles = fs.readdirSync(exampleHuntsDir).filter((f) => f.endsWith(\".yml\"));\n for (const huntFile of huntFiles) {\n copyFile(\n path.join(exampleHuntsDir, huntFile),\n path.join(prowlDir, \"hunts\", huntFile)\n );\n }\n\n // Create .gitignore to keep artifacts and secrets out of version control\n const gitignore = [\n \"# Run artifacts (screenshots, logs, reports)\",\n \"runs/\",\n \"\",\n \"# Auth state (tokens, cookies)\",\n \"auth-state.json\",\n \"\",\n \"# Environment variables (credentials)\",\n \".env\",\n \"\",\n ].join(\"\\n\");\n fs.writeFileSync(path.join(prowlDir, \".gitignore\"), gitignore);\n\n console.log(welcomeBanner());\n console.log(chalk.green(` Initialized ${CONFIG_DIR} directory.`));\n console.log(chalk.gray(\" Run \") + chalk.bold(\"prowl run hello\") + chalk.gray(\" to get started.\"));\n console.log(chalk.gray(\" Browse hunt templates at \") + chalk.cyan(\"https://hub.prowl.tools\") + \"\\n\");\n });\n\n return command;\n}\n","import path from \"node:path\";\nimport readline from \"node:readline\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { chromium, type Browser, type BrowserContext } from \"playwright\";\nimport { loadConfig } from \"../../config/loader.js\";\n\nfunction resolvePath(configDir: string, inputPath: string): string {\n if (path.isAbsolute(inputPath)) {\n return inputPath;\n }\n const projectRoot = path.dirname(configDir);\n return path.join(projectRoot, inputPath);\n}\n\nfunction waitForEnter(prompt: string): Promise<void> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n rl.question(prompt, () => {\n rl.close();\n resolve();\n });\n });\n}\n\nexport function buildLoginCommand(): Command {\n const command = new Command(\"login\")\n .option(\"--url <target>\", \"Override target URL\")\n .option(\"--config <path>\", \"Custom config path\")\n .action(async (options) => {\n let browser: Browser | null = null;\n let context: BrowserContext | null = null;\n try {\n const { config, configDir } = loadConfig(options.config);\n const targetUrl = options.url ?? config.target.url;\n const storageStatePath = config.auth.storageStatePath\n ? resolvePath(configDir, config.auth.storageStatePath)\n : resolvePath(configDir, \".prowl/auth-state.json\");\n\n browser = await chromium.launch({ headless: false });\n context = await browser.newContext();\n const page = await context.newPage();\n await page.goto(targetUrl);\n\n console.log(chalk.green(\"Browser opened. Log in manually.\"));\n await waitForEnter(\"Press Enter to save auth state and close the browser... \");\n\n await context.storageState({ path: storageStatePath });\n console.log(chalk.green(`Saved auth state to ${storageStatePath}`));\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Login failed\";\n console.error(chalk.red(`Error: ${message}`));\n process.exitCode = 1;\n } finally {\n if (context) {\n await context.close();\n }\n if (browser) {\n await browser.close();\n }\n }\n });\n\n return command;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { loadConfig, listHunts, loadHuntMeta } from \"../../config/loader.js\";\nimport { truncate } from \"../output.js\";\n\nexport function buildListCommand(): Command {\n const command = new Command(\"list\")\n .option(\"--config <path>\", \"Custom config path\")\n .option(\"--json\", \"Output as JSON array\")\n .action((options) => {\n try {\n const { configDir } = loadConfig(options.config);\n const hunts = listHunts(configDir);\n\n if (hunts.length === 0) {\n const huntsPath = `${configDir}/hunts`;\n console.log(chalk.yellow(`No hunts found in ${huntsPath}.`));\n return;\n }\n\n const metas = hunts.map((name) => ({\n name,\n ...loadHuntMeta(name, configDir)\n }));\n\n if (options.json) {\n console.log(JSON.stringify(metas, null, 2));\n return;\n }\n\n const maxName = Math.max(...metas.map((m) => m.name.length));\n\n metas.forEach((m) => {\n const padded = m.name.padEnd(maxName);\n const desc = m.description ? ` ${truncate(m.description, 40)}` : \"\";\n const tags = m.tags.length > 0 ? chalk.gray(` [${m.tags.join(\", \")}]`) : \"\";\n console.log(` ${padded}${desc}${tags}`);\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"List failed\";\n console.error(chalk.red(`Error: ${message}`));\n process.exitCode = 1;\n }\n });\n\n return command;\n}\n","import fs from \"node:fs\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { loadConfig } from \"../../config/loader.js\";\nimport { runHunt } from \"../../runner/index.js\";\nimport { createDebouncer, getWatchTargets } from \"../watch-utils.js\";\nimport { printHuntHeader, printStepResult, printHuntSummary } from \"../output.js\";\n\nexport function buildWatchCommand(): Command {\n const command = new Command(\"watch\")\n .argument(\"<hunt-name>\", \"Hunt name or path (e.g. homepage or admin/users-crud)\")\n .option(\"--url <target>\", \"Override target URL\")\n .option(\"--headed\", \"Show browser window\")\n .option(\"--slow-mo <ms>\", \"Slow down Playwright actions\", (value) => Number(value))\n .option(\"--trace\", \"Capture Playwright trace\")\n .option(\"--config <path>\", \"Custom config path\")\n .action(async (huntName, options) => {\n const { configDir } = loadConfig(options.config);\n const watchTargets = getWatchTargets(configDir, huntName);\n\n let running = false;\n let pending = false;\n let stopped = false;\n\n const runOnce = async () => {\n if (stopped) {\n return;\n }\n\n if (running) {\n pending = true;\n return;\n }\n\n running = true;\n do {\n pending = false;\n try {\n printHuntHeader(huntName);\n\n const { result, runDir } = await runHunt({\n huntName,\n urlOverride: options.url,\n headed: Boolean(options.headed),\n slowMo: Number.isFinite(options.slowMo) ? options.slowMo : undefined,\n trace: Boolean(options.trace),\n configPath: options.config,\n onStep(stepResult, step, index) {\n printStepResult(stepResult, step, index);\n }\n });\n\n printHuntSummary(result, runDir);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Run failed\";\n console.error(chalk.red(`Error: ${message}`));\n }\n } while (pending && !stopped);\n running = false;\n };\n\n const debounced = createDebouncer(300, () => {\n void runOnce();\n });\n\n const unwatch: Array<() => void> = [];\n for (const target of watchTargets) {\n fs.watchFile(target, { interval: 150 }, (curr, prev) => {\n if (curr.mtimeMs === prev.mtimeMs && curr.size === prev.size) {\n return;\n }\n console.log(chalk.gray(`Change detected: ${target}`));\n debounced.trigger();\n });\n unwatch.push(() => fs.unwatchFile(target));\n }\n\n const stop = () => {\n if (stopped) {\n return;\n }\n stopped = true;\n debounced.cancel();\n unwatch.forEach((dispose) => dispose());\n process.off(\"SIGINT\", stop);\n console.log(chalk.yellow(\"\\nWatch stopped.\"));\n process.exit(0);\n };\n\n process.on(\"SIGINT\", stop);\n\n console.log(chalk.gray(`Watching hunt: ${huntName}`));\n console.log(chalk.gray(`Files: ${watchTargets.join(\", \")}`));\n await runOnce();\n });\n\n return command;\n}\n","import path from \"node:path\";\n\nexport function getWatchTargets(configDir: string, huntName: string): string[] {\n return [\n path.join(configDir, \"hunts\", `${huntName}.yml`),\n path.join(configDir, \"config.yml\"),\n path.join(configDir, \".env\")\n ];\n}\n\nexport function createDebouncer(delayMs: number, fn: () => void): {\n trigger: () => void;\n cancel: () => void;\n} {\n let timer: NodeJS.Timeout | undefined;\n\n return {\n trigger: () => {\n if (timer) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = undefined;\n fn();\n }, delayMs);\n },\n cancel: () => {\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n }\n };\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { runSuite } from \"../../runner/suite.js\";\nimport { printHuntHeader, printStepResult, printHuntSummary } from \"../output.js\";\nimport { resultMascot } from \"../mascot.js\";\nimport { printCiSummary } from \"../../reporter/ci-summary.js\";\nimport type { CiHuntResult } from \"../../types/index.js\";\n\nfunction parseTagList(value: string | undefined, flag: \"--include-tags\" | \"--exclude-tags\"): string[] | undefined {\n if (value === undefined) return undefined;\n const tags = value\n .split(\",\")\n .map((tag) => tag.trim())\n .filter(Boolean);\n if (tags.length === 0) {\n throw new Error(`${flag} requires at least one non-empty tag`);\n }\n return tags;\n}\n\nfunction printFailureDetails(results: CiHuntResult[]): void {\n for (const hunt of results) {\n if (hunt.status === \"fail\" && hunt.error) {\n console.error(` ${chalk.red(\"Error\")} ${hunt.hunt}: ${hunt.error}`);\n }\n }\n}\n\nexport function buildCiCommand(): Command {\n const command = new Command(\"ci\")\n .description(\"Run all hunts and produce a combined pass/fail result for CI pipelines\")\n .option(\"--config <path>\", \"Custom config path\")\n .option(\"--url <target>\", \"Override target URL\")\n .option(\"--headed\", \"Show browser window\")\n .option(\"--slow-mo <ms>\", \"Slow down Playwright actions\", (value) => Number(value))\n .option(\"--trace\", \"Capture Playwright traces\")\n .option(\"--browser <engine>\", \"Browser engine: chromium, firefox, or webkit\")\n .option(\"--channel <name>\", \"Browser channel: chrome, msedge, chrome-beta, etc.\")\n .option(\"--viewport <size>\", \"Viewport size: WxH (e.g. 1920x1080) or preset (mobile, tablet, desktop)\")\n .option(\"--junit\", \"Generate JUnit XML reports\")\n .option(\"--include-tags <tags>\", \"Only run hunts matching these tags (comma-separated)\")\n .option(\"--exclude-tags <tags>\", \"Skip hunts matching these tags (comma-separated)\")\n .option(\"--json\", \"Output results as JSON\")\n .option(\"--parallel <count>\", \"Run hunts in parallel with N workers\", (value) => {\n const n = Number(value);\n if (!Number.isInteger(n) || n < 1) {\n throw new Error(\"--parallel must be a positive integer\");\n }\n return n;\n })\n .action(async (options) => {\n const includeTags = parseTagList(options.includeTags as string | undefined, \"--include-tags\");\n const excludeTags = parseTagList(options.excludeTags as string | undefined, \"--exclude-tags\");\n\n const parallel = options.parallel as number | undefined;\n const isParallel = parallel !== undefined && parallel > 1;\n // Suppress per-hunt progress output for JSON and parallel runs (parallel output would interleave).\n const showProgress = !options.json && !isParallel;\n\n const { result, resultPath } = await runSuite({\n configPath: options.config,\n urlOverride: options.url,\n headed: Boolean(options.headed),\n slowMo: Number.isFinite(options.slowMo) ? options.slowMo : undefined,\n trace: Boolean(options.trace),\n browser: options.browser,\n channel: options.channel,\n viewport: options.viewport,\n junit: Boolean(options.junit),\n includeTags,\n excludeTags,\n parallel,\n hooks: {\n onHuntStart: showProgress ? (huntName) => printHuntHeader(huntName) : undefined,\n onStep: showProgress\n ? (stepResult, step, index) => printStepResult(stepResult, step, index)\n : undefined,\n onHuntSuccess: showProgress\n ? (huntName, runResult, runDir) => {\n console.log(resultMascot(runResult.status, huntName));\n printHuntSummary(runResult, runDir);\n }\n : undefined,\n onHuntFailure: showProgress\n ? (huntName, message) => {\n console.log(resultMascot(\"fail\", huntName));\n console.error(`\\n Error: ${message}\\n`);\n }\n : undefined,\n onHuntSkipped: options.json\n ? undefined\n : (huntName, reason) => {\n const why = reason === \"include\" ? \"no matching include tags\" : \"matched exclude tags\";\n console.log(chalk.yellow(` ○ Skipped \"${huntName}\" — ${why}`));\n }\n }\n });\n\n if (result.status === \"no-hunts\") {\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(chalk.yellow(\"\\n No hunts found. Create hunts in .prowl/hunts/\\n\"));\n }\n process.exitCode = 2;\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n printCiSummary(result.hunts, result.durationMs, result.flaky, result.clusters);\n if (!showProgress) {\n printFailureDetails(result.hunts);\n }\n if (resultPath) {\n console.log(`\\n CI Result: ${chalk.gray(resultPath)}\\n`);\n }\n if (result.status === \"all-skipped\") {\n console.log(chalk.yellow(\" All hunts were skipped by tag filters.\\n\"));\n }\n }\n\n if (result.status === \"fail\") {\n process.exitCode = 1;\n } else if (result.status === \"all-skipped\") {\n process.exitCode = 2;\n } else {\n process.exitCode = 0;\n }\n });\n\n return command;\n}\n","import path from \"node:path\";\nimport { runHunt, type RunOptions } from \"./index.js\";\nimport { loadConfig, listHunts, loadHuntTags } from \"../config/loader.js\";\nimport { writeCiResult, resolveCiStatus, countCiResults } from \"../reporter/ci-summary.js\";\nimport { timestamp } from \"../utils/timestamp.js\";\nimport { runWithConcurrency } from \"../utils/concurrency.js\";\nimport type { CiFailureCluster, CiFlakyHunt, CiHuntResult, CiResult, RunResult } from \"../types/index.js\";\nimport { rankFlaky, DEFAULT_FLAKY_THRESHOLD } from \"./flaky.js\";\nimport { clusterFailures } from \"./clustering.js\";\nimport { extractFailures } from \"../backlog/index.js\";\n\nexport type SkipReason = \"include\" | \"exclude\";\ntype SuiteHookResult = void | Promise<void>;\n\nexport interface RunSuiteHooks {\n onHuntStart?: (huntName: string) => SuiteHookResult;\n onStep?: RunOptions[\"onStep\"];\n onHuntSuccess?: (huntName: string, result: RunResult, runDir: string) => SuiteHookResult;\n onHuntFailure?: (huntName: string, message: string) => SuiteHookResult;\n onHuntSkipped?: (huntName: string, reason: SkipReason) => SuiteHookResult;\n}\n\nexport interface RunSuiteOptions {\n configPath?: string;\n urlOverride?: string;\n headed?: boolean;\n slowMo?: number;\n trace?: boolean;\n browser?: RunOptions[\"browser\"];\n channel?: RunOptions[\"channel\"];\n viewport?: string;\n junit?: boolean;\n includeTags?: string[];\n excludeTags?: string[];\n parallel?: number;\n hooks?: RunSuiteHooks;\n}\n\nexport interface RunSuiteResult {\n result: CiResult;\n /** Path to the written ci-result.json, or null when there were no hunts to run. */\n resultPath: string | null;\n}\n\nfunction normalizeTagFilter(tags: string[] | undefined): string[] | undefined {\n const normalized = tags?.map((tag) => tag.trim()).filter(Boolean);\n return normalized && normalized.length > 0 ? normalized : undefined;\n}\n\nasync function callHook(callback: (() => SuiteHookResult | undefined) | undefined): Promise<void> {\n if (!callback) return;\n try {\n await callback();\n } catch {\n // Presentation hooks must never change suite or hunt outcomes.\n }\n}\n\nfunction safeOnStep(hooks: RunSuiteHooks): RunOptions[\"onStep\"] {\n if (!hooks.onStep) return undefined;\n return (result, step, index) => {\n try {\n hooks.onStep?.(result, step, index);\n } catch {\n // Presentation hooks must never change suite or hunt outcomes.\n }\n };\n}\n\nfunction firstRunFailureMessage(result: RunResult): string | undefined {\n const failedStep = result.steps.find((step) => step.status === \"fail\" && step.error);\n if (failedStep?.error) return failedStep.error;\n\n const failedAssertion = result.assertions.find((assertion) => assertion.status === \"fail\" && assertion.error);\n return failedAssertion?.error;\n}\n\n/**\n * Runs every hunt in the project and aggregates a CiResult. Side-effect-free with\n * respect to the console and process exit — callers provide hooks for presentation\n * and inspect the returned status for exit codes.\n */\nexport async function runSuite(options: RunSuiteOptions = {}): Promise<RunSuiteResult> {\n const startedAt = new Date().toISOString();\n const startTime = Date.now();\n const hooks = options.hooks ?? {};\n\n const { config, configDir } = loadConfig(options.configPath);\n const hunts = listHunts(configDir);\n\n if (hunts.length === 0) {\n return {\n result: {\n status: \"no-hunts\",\n startedAt,\n durationMs: 0,\n totalHunts: 0,\n passed: 0,\n failed: 0,\n skipped: 0,\n hunts: []\n },\n resultPath: null\n };\n }\n\n const includeTags = normalizeTagFilter(options.includeTags);\n const excludeTags = normalizeTagFilter(options.excludeTags);\n const resultsByIndex: Array<CiHuntResult | undefined> = new Array(hunts.length);\n const onStep = safeOnStep(hooks);\n\n // Phase 1: Tag filtering (always sequential, preserves hunt order)\n const huntsToRun: Array<{ huntName: string; index: number }> = [];\n for (let index = 0; index < hunts.length; index++) {\n const huntName = hunts[index];\n if (includeTags || excludeTags) {\n const tags = loadHuntTags(huntName, configDir);\n\n if (includeTags && !includeTags.some((t) => tags.includes(t))) {\n await callHook(() => hooks.onHuntSkipped?.(huntName, \"include\"));\n resultsByIndex[index] = { hunt: huntName, status: \"skipped\", durationMs: 0 };\n continue;\n }\n if (excludeTags && excludeTags.some((t) => tags.includes(t))) {\n await callHook(() => hooks.onHuntSkipped?.(huntName, \"exclude\"));\n resultsByIndex[index] = { hunt: huntName, status: \"skipped\", durationMs: 0 };\n continue;\n }\n }\n huntsToRun.push({ huntName, index });\n }\n\n // Phase 2: Build a task per hunt to run\n const buildTask = (huntName: string) => async (): Promise<CiHuntResult> => {\n const huntStart = Date.now();\n try {\n await callHook(() => hooks.onHuntStart?.(huntName));\n\n const { result, runDir } = await runHunt({\n huntName,\n urlOverride: options.urlOverride,\n headed: options.headed,\n slowMo: options.slowMo,\n trace: options.trace,\n browser: options.browser,\n channel: options.channel,\n viewport: options.viewport,\n junit: options.junit,\n configPath: options.configPath,\n onStep\n });\n\n const error = result.status === \"fail\" ? firstRunFailureMessage(result) ?? \"Run failed\" : undefined;\n if (error) {\n await callHook(() => hooks.onHuntFailure?.(huntName, error));\n } else {\n await callHook(() => hooks.onHuntSuccess?.(huntName, result, runDir));\n }\n\n return {\n hunt: huntName,\n status: result.status,\n durationMs: result.durationMs,\n runDir,\n error\n };\n } catch (error) {\n const durationMs = Date.now() - huntStart;\n const message = error instanceof Error ? error.message : \"Run failed\";\n await callHook(() => hooks.onHuntFailure?.(huntName, message));\n return {\n hunt: huntName,\n status: \"fail\",\n durationMs,\n error: message\n };\n }\n };\n\n // Phase 3: Execute (parallel when requested, otherwise sequential in hunt order)\n const parallel = options.parallel;\n if (parallel !== undefined && parallel > 1) {\n const tasks = huntsToRun.map((entry) => ({ ...entry, task: buildTask(entry.huntName) }));\n const parallelResults = await runWithConcurrency(\n tasks.map((entry) => entry.task),\n parallel\n );\n for (let i = 0; i < parallelResults.length; i++) {\n const pr = parallelResults[i];\n const task = tasks[i];\n if (pr.status === \"fulfilled\") {\n resultsByIndex[task.index] = pr.value;\n } else {\n const message = pr.reason instanceof Error ? pr.reason.message : \"Run failed\";\n resultsByIndex[task.index] = {\n hunt: task.huntName,\n status: \"fail\",\n durationMs: 0,\n error: message\n };\n }\n }\n } else {\n for (const { huntName, index } of huntsToRun) {\n resultsByIndex[index] = await buildTask(huntName)();\n }\n }\n\n const totalDurationMs = Date.now() - startTime;\n const results: CiHuntResult[] = resultsByIndex.map((result, index) => {\n return result ?? {\n hunt: hunts[index],\n status: \"fail\",\n durationMs: 0,\n error: \"Run did not produce a result\"\n };\n });\n\n // Flag flaky hunts among those that actually ran this suite, using accumulated\n // run history (which already includes this run's entries). Omitted when none.\n const threshold = config.reliability?.flakyThreshold ?? DEFAULT_FLAKY_THRESHOLD;\n const ranThisSuite = new Set(\n results.filter((r) => r.status !== \"skipped\").map((r) => r.hunt)\n );\n const flaky: CiFlakyHunt[] = rankFlaky(configDir, { threshold })\n .filter((entry) => entry.flaky && ranThisSuite.has(entry.hunt))\n .map((entry) => ({ hunt: entry.hunt, score: entry.score }));\n\n // Cluster failures from this suite by shared cause; surface only multi-hunt\n // clusters (a single failing hunt is just that failure, not a \"cluster\").\n const clusters: CiFailureCluster[] = clusterFailures(\n extractFailures({ result: { hunts: results } as CiResult, resultPath: null })\n ).filter((cluster) => cluster.count > 1);\n\n const ciRunDir = path.join(configDir, \"runs\", timestamp(\"ci\"));\n const resultPath = writeCiResult(ciRunDir, results, startedAt, totalDurationMs, flaky, clusters);\n\n const { passed, failed, skipped } = countCiResults(results);\n\n return {\n result: {\n status: resolveCiStatus(results),\n startedAt,\n durationMs: totalDurationMs,\n totalHunts: results.length,\n passed,\n failed,\n skipped,\n hunts: results,\n ...(flaky.length > 0 ? { flaky } : {}),\n ...(clusters.length > 0 ? { clusters } : {})\n },\n resultPath\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport chalk from \"chalk\";\nimport type { CiFailureCluster, CiFlakyHunt, CiHuntResult, CiResult, CiStatus } from \"../types/index.js\";\n\nexport type CiCounts = {\n passed: number;\n failed: number;\n skipped: number;\n};\n\nexport function countCiResults(results: CiHuntResult[]): CiCounts {\n return {\n passed: results.filter((r) => r.status === \"pass\").length,\n failed: results.filter((r) => r.status === \"fail\").length,\n skipped: results.filter((r) => r.status === \"skipped\").length\n };\n}\n\nexport function resolveCiStatus(results: CiHuntResult[]): CiStatus {\n if (results.length === 0) return \"no-hunts\";\n const { failed, passed } = countCiResults(results);\n if (failed > 0) return \"fail\";\n if (passed > 0) return \"pass\";\n return \"all-skipped\";\n}\n\nexport function printCiSummary(\n results: CiHuntResult[],\n totalDurationMs: number,\n flaky: CiFlakyHunt[] = [],\n clusters: CiFailureCluster[] = []\n): void {\n const { passed, failed, skipped } = countCiResults(results);\n\n const lineWidth = 45;\n console.log(`\\n ── CI Summary ${\"─\".repeat(lineWidth - 15)}`);\n\n for (const r of results) {\n const icon = r.status === \"pass\" ? chalk.green(\"✓\") : r.status === \"fail\" ? chalk.red(\"✗\") : chalk.yellow(\"○\");\n const name = r.status === \"fail\" ? chalk.red(r.hunt) : r.status === \"skipped\" ? chalk.yellow(r.hunt) : r.hunt;\n const duration = r.status === \"skipped\" ? \"\" : chalk.gray(`(${r.durationMs}ms)`);\n const pad = \" \".repeat(Math.max(1, 40 - r.hunt.length));\n console.log(` ${icon} ${name}${pad}${duration}`);\n }\n\n console.log(` ${\"─\".repeat(lineWidth)}`);\n\n const parts: string[] = [];\n if (passed > 0) parts.push(chalk.green(`${passed} passed`));\n if (failed > 0) parts.push(chalk.red(`${failed} failed`));\n if (skipped > 0) parts.push(chalk.yellow(`${skipped} skipped`));\n parts.push(chalk.gray(`(${totalDurationMs}ms)`));\n\n console.log(` ${parts.join(\" \")}`);\n\n if (flaky.length > 0) {\n console.log(`\\n ${chalk.yellow(\"Flaky hunts\")} (oscillating pass/fail):`);\n for (const entry of flaky) {\n console.log(` ${chalk.yellow(\"~\")} ${entry.hunt} ${chalk.gray(`(score ${entry.score.toFixed(2)})`)}`);\n }\n }\n\n if (clusters.length > 0) {\n console.log(`\\n ${chalk.red(\"Failure clusters\")} (shared root causes):`);\n for (const cluster of clusters) {\n console.log(` ${chalk.red(\"✗\")} ${cluster.cause} ${chalk.gray(`(${cluster.count} hunts: ${cluster.hunts.join(\", \")})`)}`);\n }\n }\n}\n\nexport function writeCiResult(\n ciRunDir: string,\n results: CiHuntResult[],\n startedAt: string,\n totalDurationMs: number,\n flaky: CiFlakyHunt[] = [],\n clusters: CiFailureCluster[] = []\n): string {\n const { passed, failed, skipped } = countCiResults(results);\n\n const ciResult: CiResult = {\n status: resolveCiStatus(results),\n startedAt,\n durationMs: totalDurationMs,\n totalHunts: results.length,\n passed,\n failed,\n skipped,\n hunts: results,\n ...(flaky.length > 0 ? { flaky } : {}),\n ...(clusters.length > 0 ? { clusters } : {})\n };\n\n fs.mkdirSync(ciRunDir, { recursive: true });\n const filePath = path.join(ciRunDir, \"ci-result.json\");\n fs.writeFileSync(filePath, JSON.stringify(ciResult, null, 2) + \"\\n\");\n return filePath;\n}\n","export type ConcurrencyResult<T> =\n | { status: \"fulfilled\"; value: T }\n | { status: \"rejected\"; reason: unknown };\n\nexport async function runWithConcurrency<T>(\n tasks: Array<() => Promise<T>>,\n concurrency: number\n): Promise<Array<ConcurrencyResult<T>>> {\n const normalizedConcurrency =\n Number.isFinite(concurrency) && concurrency > 0\n ? Math.floor(concurrency)\n : 1;\n const results: Array<ConcurrencyResult<T>> = new Array(tasks.length);\n let nextIndex = 0;\n\n async function worker(): Promise<void> {\n while (nextIndex < tasks.length) {\n const index = nextIndex;\n nextIndex += 1;\n try {\n const value = await tasks[index]();\n results[index] = { status: \"fulfilled\", value };\n } catch (reason) {\n results[index] = { status: \"rejected\", reason };\n }\n }\n }\n\n const workers = Array.from(\n { length: Math.min(normalizedConcurrency, tasks.length) },\n () => worker()\n );\n await Promise.all(workers);\n return results;\n}\n","import type { HistoryEntry } from \"../types/index.js\";\nimport { readHistory } from \"./history.js\";\n\nexport const DEFAULT_FLAKY_THRESHOLD = 0.3;\n\nexport type FlakyScore = {\n hunt: string;\n /** Oscillation rate in [0,1]: share of consecutive run pairs whose status changed. */\n score: number;\n runs: number;\n flaky: boolean;\n};\n\n/**\n * Flake score for a single hunt's run history (oldest→newest): the fraction of\n * consecutive run pairs where the status flipped (pass↔fail). 0 = perfectly\n * stable, 1 = flips every run. Needs at least 2 runs; fewer returns 0.\n */\nexport function computeFlakeScore(entries: HistoryEntry[], lastN?: number): number {\n const slice = lastN !== undefined && lastN > 0 ? entries.slice(-lastN) : entries;\n if (slice.length < 2) return 0;\n\n let transitions = 0;\n for (let i = 1; i < slice.length; i++) {\n if (slice[i].status !== slice[i - 1].status) {\n transitions += 1;\n }\n }\n return transitions / (slice.length - 1);\n}\n\nexport type RankFlakyOptions = {\n /** Only score the most recent N runs per hunt. */\n lastN?: number;\n /** Score at/above this is flagged flaky. Defaults to DEFAULT_FLAKY_THRESHOLD. */\n threshold?: number;\n};\n\n/**\n * Rank every hunt in the project's history by flake score, highest first.\n * Hunts are tie-broken by run count (more runs first) then name for stable output.\n */\nexport function rankFlaky(configDir: string, options: RankFlakyOptions = {}): FlakyScore[] {\n const threshold = options.threshold ?? DEFAULT_FLAKY_THRESHOLD;\n const { entries } = readHistory(configDir);\n\n const byHunt = new Map<string, HistoryEntry[]>();\n for (const entry of entries) {\n const list = byHunt.get(entry.hunt) ?? [];\n list.push(entry);\n byHunt.set(entry.hunt, list);\n }\n\n const scores: FlakyScore[] = [];\n for (const [hunt, huntEntries] of byHunt) {\n const considered = options.lastN !== undefined && options.lastN > 0\n ? huntEntries.slice(-options.lastN)\n : huntEntries;\n const score = computeFlakeScore(considered);\n scores.push({\n hunt,\n score,\n runs: considered.length,\n flaky: score >= threshold\n });\n }\n\n scores.sort((a, b) => b.score - a.score || b.runs - a.runs || a.hunt.localeCompare(b.hunt));\n return scores;\n}\n","import { createHash } from \"node:crypto\";\n\n/**\n * A single failure worth logging as a bug: a specific hunt failing at a specific\n * spot. `stepType`/`selector`/`stepIndex` are absent when the hunt threw before\n * producing step results (e.g. a missing hunt file).\n */\nexport interface BugFailure {\n hunt: string;\n stepIndex?: number;\n stepType?: string;\n selector?: string;\n error: string;\n runDir?: string;\n}\n\n/**\n * Reduce an error message to its stable \"class\" by removing volatile details\n * (timeout durations, pixel coordinates, hex ids) so the same underlying failure\n * keeps the same fingerprint across runs.\n */\nexport function normalizeError(error: string): string {\n return error\n .toLowerCase()\n .replace(/0x[0-9a-f]+/g, \"\") // hex ids\n .replace(/\\b\\d+(?:\\.\\d+)?\\s*(?:ms|s|px)\\b/g, \"\") // unit-qualified timings/coordinates\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Stable label for the failing spot within a hunt, e.g. `4:click@#submit`.\n * Used in the human-readable marker. Returns `-` when no step is known.\n */\nexport function stepLabel(failure: BugFailure): string {\n if (failure.stepType === undefined && failure.selector === undefined) {\n return \"-\";\n }\n const index = failure.stepIndex === undefined ? \"?\" : String(failure.stepIndex);\n const type = failure.stepType ?? \"?\";\n const selector = failure.selector ? `@${failure.selector}` : \"\";\n return `${index}:${type}${selector}`;\n}\n\n/** Keep untrusted metadata from changing the hidden HTML-comment shape. */\nfunction sanitizeMarkerValue(value: string): string {\n return value\n .replace(/\\r?\\n/g, \" \")\n .replace(/-->/g, \"--&gt;\")\n .trim();\n}\n\n/**\n * Identifies \"the same bug\" across runs: the hunt, the failing step's type and\n * selector, and the normalized error class. The step *index* is deliberately\n * excluded so reordering/inserting steps in a hunt does not spawn a duplicate.\n */\nexport function computeFingerprint(failure: BugFailure): string {\n const parts = [\n failure.hunt,\n failure.stepType ?? \"\",\n failure.selector ?? \"\",\n normalizeError(failure.error)\n ];\n return createHash(\"sha1\").update(parts.join(\"|\")).digest(\"hex\").slice(0, 8);\n}\n\n/** Hidden HTML-comment marker embedded in each ticket so re-runs can recognize it. */\nexport function buildMarker(failure: BugFailure, hash: string): string {\n const hunt = sanitizeMarkerValue(failure.hunt);\n const step = sanitizeMarkerValue(stepLabel(failure));\n return `<!-- prowl:fp=${hash} hunt=${hunt} step=${step} -->`;\n}\n","import type { BugFailure } from \"../backlog/fingerprint.js\";\nimport { normalizeError } from \"../backlog/fingerprint.js\";\nimport type { CiFailureCluster } from \"../types/index.js\";\n\n/**\n * Failure clustering (PROWL-034). Groups failures that share a common cause —\n * the same normalized error on the same step type and selector — so a single\n * root cause (e.g. one renamed selector breaking 5 hunts) surfaces as one\n * cluster instead of N independent failures.\n */\nexport type FailureCluster = CiFailureCluster;\n\nfunction clusterKey(failure: BugFailure, normalizedError: string): string {\n return [failure.stepType ?? \"\", failure.selector ?? \"\", normalizedError].join(\"|\");\n}\n\nfunction describeCause(failure: BugFailure, error: string): string {\n const where = failure.stepType\n ? `${failure.stepType}${failure.selector ? ` (${failure.selector})` : \"\"}`\n : \"run\";\n return `${where}: ${error}`;\n}\n\n/**\n * Group failures by shared cause. Returns clusters sorted by size (largest first),\n * then by cause for stable output. Every failure lands in a cluster — single-hunt\n * clusters are included so the full picture is preserved; callers can filter to\n * `count > 1` to show only shared root causes.\n */\nexport function clusterFailures(failures: BugFailure[]): FailureCluster[] {\n const groups = new Map<string, { sample: BugFailure; error: string; hunts: Set<string> }>();\n\n for (const failure of failures) {\n const error = normalizeError(failure.error);\n const key = clusterKey(failure, error);\n const existing = groups.get(key);\n if (existing) {\n existing.hunts.add(failure.hunt);\n } else {\n groups.set(key, { sample: failure, error, hunts: new Set([failure.hunt]) });\n }\n }\n\n const clusters: FailureCluster[] = [];\n for (const { sample, error, hunts } of groups.values()) {\n clusters.push({\n cause: describeCause(sample, error),\n stepType: sample.stepType,\n selector: sample.selector,\n error,\n count: hunts.size,\n hunts: [...hunts].sort()\n });\n }\n\n clusters.sort((a, b) => b.count - a.count || a.cause.localeCompare(b.cause));\n return clusters;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { CiHuntResult, RunResult } from \"../types/index.js\";\nimport type { RunSuiteResult } from \"../runner/suite.js\";\nimport { type BugFailure, buildMarker, computeFingerprint } from \"./fingerprint.js\";\nimport { classifyFingerprint, extractFingerprints, nextTicketId } from \"./parse.js\";\nimport { insertTickets, renderTicket } from \"./write.js\";\n\nexport type { BugFailure } from \"./fingerprint.js\";\nexport { SECTION_HEADING } from \"./write.js\";\n\nexport interface UpdateBacklogOptions {\n /** Project root containing docs/. Defaults to process.cwd(). */\n projectRoot?: string;\n /** Overrides the backlog path (default: <projectRoot>/docs/backlog.md). */\n backlogPath?: string;\n /** Overrides the resolved path (default: <projectRoot>/docs/resolved.md). */\n resolvedPath?: string;\n /** Date stamp for new tickets (default: today, YYYY-MM-DD). */\n date?: string;\n}\n\nexport interface BugLogSummary {\n /** QA-NNN ids created for brand-new failures. */\n created: string[];\n /** QA-NNN ids created for failures that recurred after being resolved. */\n regressions: string[];\n /** QA-NNN ids of already-open tickets that were left untouched. */\n skipped: string[];\n backlogPath: string;\n}\n\n/** Read optional backlog state, returning empty content only when the file is absent. */\nfunction readFileOrEmpty(filePath: string): string {\n try {\n return fs.readFileSync(filePath, \"utf-8\");\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === \"ENOENT\") return \"\";\n throw new Error(`Failed to read \"${filePath}\": ${err.message}`);\n }\n}\n\n/** Convert a failed CI hunt result into the most specific backlog failure available. */\nfunction buildFailure(hunt: CiHuntResult): BugFailure {\n const failure: BugFailure = {\n hunt: hunt.hunt,\n error: hunt.error ?? \"Run failed\",\n runDir: hunt.runDir\n };\n\n if (!hunt.runDir) return failure;\n\n let run: RunResult;\n try {\n const resultJson = readFileOrEmpty(path.join(hunt.runDir, \"result.json\"));\n if (!resultJson) return failure;\n run = JSON.parse(resultJson) as RunResult;\n } catch (error) {\n if (!(error instanceof SyntaxError)) throw error;\n return failure; // Malformed result.json; keep the message-only failure.\n }\n if (!run || !Array.isArray(run.steps)) return failure;\n\n const stepIndex = run.steps.findIndex((step) => step.status === \"fail\");\n if (stepIndex !== -1) {\n const step = run.steps[stepIndex];\n failure.stepIndex = stepIndex;\n failure.stepType = step.type;\n failure.selector = step.selector;\n if (step.error) failure.error = step.error;\n return failure;\n }\n\n const failedAssertion = run.assertions?.find((assertion) => assertion.status === \"fail\");\n if (failedAssertion) {\n failure.stepType = `assert:${failedAssertion.type}`;\n if (failedAssertion.error) failure.error = failedAssertion.error;\n }\n\n return failure;\n}\n\n/** Extract one BugFailure per failed hunt from a completed suite run. */\nexport function extractFailures(suiteResult: RunSuiteResult): BugFailure[] {\n return suiteResult.result.hunts\n .filter((hunt) => hunt.status === \"fail\")\n .map(buildFailure);\n}\n\n/**\n * Logs failures from a completed suite run as deduplicated bug tickets in the\n * target project's backlog. New failures get a fresh QA-NNN ticket; failures that\n * already have an open ticket are skipped; failures matching a resolved ticket are\n * logged as regressions that reference the old id. Idempotent across runs.\n */\nexport function updateBacklogFromSuite(\n suiteResult: RunSuiteResult,\n options: UpdateBacklogOptions = {}\n): BugLogSummary {\n const projectRoot = options.projectRoot ?? process.cwd();\n const backlogPath = options.backlogPath ?? path.join(projectRoot, \"docs\", \"backlog.md\");\n const resolvedPath = options.resolvedPath ?? path.join(projectRoot, \"docs\", \"resolved.md\");\n const date = options.date ?? new Date().toISOString().slice(0, 10);\n\n const summary: BugLogSummary = { created: [], regressions: [], skipped: [], backlogPath };\n\n const failures = extractFailures(suiteResult);\n if (failures.length === 0) return summary;\n\n const backlogContent = readFileOrEmpty(backlogPath);\n const resolvedContent = readFileOrEmpty(resolvedPath);\n\n const activeFps = extractFingerprints(backlogContent);\n const resolvedFps = extractFingerprints(resolvedContent);\n\n let counter = Number(nextTicketId([backlogContent, resolvedContent]).slice(3));\n const makeId = (): string => `QA-${String(counter++).padStart(3, \"0\")}`;\n\n const seenThisRun = new Set<string>();\n const ticketsToAdd: string[] = [];\n\n for (const failure of failures) {\n const fp = computeFingerprint(failure);\n if (seenThisRun.has(fp)) continue;\n seenThisRun.add(fp);\n\n const classification = classifyFingerprint(fp, activeFps, resolvedFps);\n if (classification.kind === \"open\") {\n summary.skipped.push(classification.ticketId);\n continue;\n }\n\n const id = makeId();\n const regressionOf = classification.kind === \"regression\" ? classification.resolvedId : undefined;\n ticketsToAdd.push(renderTicket({ id, failure, marker: buildMarker(failure, fp), regressionOf, date }));\n\n if (regressionOf) {\n summary.regressions.push(id);\n } else {\n summary.created.push(id);\n }\n }\n\n if (ticketsToAdd.length > 0) {\n fs.mkdirSync(path.dirname(backlogPath), { recursive: true });\n fs.writeFileSync(backlogPath, insertTickets(backlogContent, ticketsToAdd));\n }\n\n return summary;\n}\n","const MARKER_FP = /<!--\\s*prowl:fp=([0-9a-f]+)/;\nconst TICKET_ID = /\\bQA-(\\d+)\\b/;\nconst TICKET_ID_GLOBAL = /\\bQA-(\\d+)\\b/g;\nconst HEADING = /^#{1,6}\\s/;\n\n/**\n * Map each embedded fingerprint to the QA-NNN ticket id that owns it, by pairing\n * every `prowl:fp=` marker with the most recent ticket heading above it.\n */\nexport function extractFingerprints(content: string): Map<string, string> {\n const map = new Map<string, string>();\n let currentId: string | undefined;\n\n for (const line of content.split(\"\\n\")) {\n if (HEADING.test(line)) {\n const idMatch = TICKET_ID.exec(line);\n currentId = idMatch ? `QA-${idMatch[1]}` : undefined;\n }\n const fpMatch = MARKER_FP.exec(line);\n if (fpMatch && currentId) {\n map.set(fpMatch[1], currentId);\n }\n }\n\n return map;\n}\n\n/** The next available QA-NNN id across all provided file contents (max + 1, zero-padded). */\nexport function nextTicketId(contents: string[]): string {\n let max = 0;\n for (const content of contents) {\n for (const match of content.matchAll(TICKET_ID_GLOBAL)) {\n const n = Number(match[1]);\n if (n > max) max = n;\n }\n }\n return `QA-${String(max + 1).padStart(3, \"0\")}`;\n}\n\nexport type Classification =\n | { kind: \"new\" }\n | { kind: \"open\"; ticketId: string }\n | { kind: \"regression\"; resolvedId: string };\n\n/**\n * Decide how to handle a failure fingerprint:\n * - already tracked in the active backlog -> `open` (skip, no duplicate)\n * - previously resolved -> `regression` (link the old id)\n * - otherwise -> `new`\n */\nexport function classifyFingerprint(\n fp: string,\n activeFps: Map<string, string>,\n resolvedFps: Map<string, string>\n): Classification {\n const openId = activeFps.get(fp);\n if (openId) return { kind: \"open\", ticketId: openId };\n\n const resolvedId = resolvedFps.get(fp);\n if (resolvedId) return { kind: \"regression\", resolvedId };\n\n return { kind: \"new\" };\n}\n","import type { BugFailure } from \"./fingerprint.js\";\n\n/** Heading of the dedicated, agent-owned section in the target project's backlog. */\nexport const SECTION_HEADING = \"## QA Findings (automated)\";\n\nexport interface RenderTicketOptions {\n id: string;\n failure: BugFailure;\n marker: string;\n /** When set, this failure previously had a resolved ticket — link it as a regression. */\n regressionOf?: string;\n /** YYYY-MM-DD */\n date: string;\n}\n\n/** Render one failure as a markdown QA ticket with stable machine-readable metadata. */\nexport function renderTicket(opts: RenderTicketOptions): string {\n const { id, failure, marker, regressionOf, date } = opts;\n\n const spot = failure.stepType\n ? `${failure.stepType}${failure.selector ? ` (${failure.selector})` : \"\"}`\n : \"run failed before steps executed\";\n\n const lines: string[] = [];\n lines.push(`### ${id}: ${failure.hunt} — ${spot}`);\n lines.push(marker);\n lines.push(`**Logged**: ${date}`);\n if (regressionOf) {\n lines.push(`**Regression of**: ${regressionOf} (previously resolved — see resolved.md)`);\n }\n lines.push(`**Hunt**: ${failure.hunt}`);\n const stepDesc = failure.stepType\n ? `step ${failure.stepIndex ?? \"?\"} — ${failure.stepType}${failure.selector ? ` ${failure.selector}` : \"\"}`\n : \"n/a (hunt did not produce step results)\";\n lines.push(`**Failing step**: ${stepDesc}`);\n lines.push(`**Error**: ${failure.error}`);\n if (failure.runDir) {\n lines.push(`**Artifacts**: ${failure.runDir}`);\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Append rendered tickets into the agent-owned section, creating the section at\n * the end of the file if it does not exist. Existing content is preserved.\n */\nexport function insertTickets(content: string, tickets: string[]): string {\n if (tickets.length === 0) return content;\n const block = tickets.join(\"\\n\\n\");\n\n const headingIndex = content.indexOf(SECTION_HEADING);\n if (headingIndex === -1) {\n const base = content.replace(/\\n*$/, \"\");\n const prefix = base ? `${base}\\n\\n` : \"\";\n return `${prefix}${SECTION_HEADING}\\n\\n${block}\\n`;\n }\n\n // Insert at the end of the section: just before the next top-level heading, or EOF.\n const afterHeading = headingIndex + SECTION_HEADING.length;\n const rest = content.slice(afterHeading);\n const nextHeadingRel = rest.search(/\\n## /);\n const insertAt = nextHeadingRel === -1 ? content.length : afterHeading + nextHeadingRel;\n\n const before = content.slice(0, insertAt).replace(/\\n*$/, \"\");\n const after = content.slice(insertAt);\n return `${before}\\n\\n${block}\\n${after}`;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { loadConfig } from \"../../config/loader.js\";\n\nexport function buildUpdateBaselinesCommand(): Command {\n const command = new Command(\"update-baselines\")\n .description(\"Accept current screenshots as new visual regression baselines\")\n .option(\"--run <dir>\", \"Specific run directory to use\")\n .option(\"--name <name>\", \"Update only a specific baseline by name\")\n .option(\"--config <path>\", \"Custom config path\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (options) => {\n try {\n const { configDir } = loadConfig(options.config);\n const baselinesDir = path.join(configDir, \"baselines\");\n fs.mkdirSync(baselinesDir, { recursive: true });\n\n let runDir: string;\n if (options.run) {\n runDir = path.isAbsolute(options.run) ? options.run : path.resolve(options.run);\n } else {\n const runsDir = path.join(configDir, \"runs\");\n if (!fs.existsSync(runsDir)) {\n console.error(chalk.red(\" No runs directory found. Run a hunt first.\"));\n process.exitCode = 1;\n return;\n }\n const entries = fs.readdirSync(runsDir)\n .filter((e) => fs.statSync(path.join(runsDir, e)).isDirectory())\n .sort()\n .reverse();\n if (entries.length === 0) {\n console.error(chalk.red(\" No run directories found. Run a hunt first.\"));\n process.exitCode = 1;\n return;\n }\n runDir = path.join(runsDir, entries[0]);\n }\n\n const screenshotsDir = path.join(runDir, \"screenshots\");\n if (!fs.existsSync(screenshotsDir)) {\n console.error(chalk.red(` No screenshots found in ${runDir}`));\n process.exitCode = 1;\n return;\n }\n\n const screenshots = fs.readdirSync(screenshotsDir)\n .filter((f) => f.endsWith(\"-current.png\"));\n\n if (screenshots.length === 0) {\n console.log(chalk.yellow(\" No assertScreenshot results found in this run.\"));\n return;\n }\n\n const nameFilter = options.name as string | undefined;\n const filtered = nameFilter\n ? screenshots.filter((f) => f === `${nameFilter}-current.png`)\n : screenshots;\n\n if (filtered.length === 0) {\n console.log(chalk.yellow(` No screenshot matching \"${nameFilter}\" found.`));\n return;\n }\n\n let updated = 0;\n for (const file of filtered) {\n const baselineName = file.replace(\"-current.png\", \".png\");\n const sourcePath = path.join(screenshotsDir, file);\n const destPath = path.join(baselinesDir, baselineName);\n const exists = fs.existsSync(destPath);\n\n fs.copyFileSync(sourcePath, destPath);\n updated++;\n const status = exists ? chalk.yellow(\"updated\") : chalk.green(\"created\");\n console.log(` ${status} ${baselineName}`);\n }\n\n console.log(chalk.green(`\\n ${updated} baseline(s) updated in ${baselinesDir}\\n`));\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Update baselines failed\";\n console.error(`\\n Error: ${message}\\n`);\n process.exitCode = 1;\n }\n });\n\n return command;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { chromium, firefox, webkit } from \"playwright\";\nimport type { BrowserEngine, BrowserChannel, Viewport } from \"../../types/index.js\";\nimport { analyzePage } from \"../../analyzer/index.js\";\nimport { resolveViewport } from \"../../config/loader.js\";\n\nconst ENGINES = { chromium, firefox, webkit } as const;\n\nfunction parseViewportFlag(value: string): string | { width: number; height: number } {\n const match = /^(\\d+)x(\\d+)$/i.exec(value);\n if (match) {\n return { width: Number(match[1]), height: Number(match[2]) };\n }\n return value;\n}\n\nexport function buildAnalyzeCommand(): Command {\n const command = new Command(\"analyze\")\n .argument(\"<url>\", \"URL to analyze\")\n .description(\"Analyze a page to discover interactive elements and selectors\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--browser <engine>\", \"Browser engine: chromium, firefox, or webkit\")\n .option(\"--channel <name>\", \"Browser channel: chrome, msedge, etc.\")\n .option(\"--viewport <size>\", \"Viewport size: WxH or preset (mobile, tablet, desktop)\")\n .option(\"--headed\", \"Show browser window\")\n .option(\"--config <path>\", \"Custom config path\")\n .action(async (url: string, options) => {\n try {\n const engine = (options.browser as BrowserEngine) ?? \"chromium\";\n const channel = options.channel as BrowserChannel | undefined;\n const viewport: Viewport = options.viewport\n ? resolveViewport(parseViewportFlag(options.viewport as string))\n : { width: 1280, height: 720 };\n\n const browserEngine = ENGINES[engine];\n const browser = await browserEngine.launch({\n headless: !options.headed,\n channel\n });\n\n const context = await browser.newContext({ viewport });\n const page = await context.newPage();\n\n try {\n await page.goto(url, { waitUntil: \"networkidle\" });\n const result = await analyzePage(page);\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`\\n ${chalk.bold(\"Page Analysis:\")} ${result.title}`);\n console.log(` ${chalk.gray(\"URL:\")} ${result.url}\\n`);\n\n if (result.forms.length > 0) {\n console.log(chalk.bold(\" Forms:\"));\n for (const form of result.forms) {\n const method = form.method ? chalk.cyan(form.method) : \"\";\n const action = form.action ? chalk.gray(form.action) : \"\";\n console.log(` [${form.index}] ${method} ${action} (${form.fieldCount} fields)`);\n }\n console.log();\n }\n\n if (result.elements.length > 0) {\n console.log(chalk.bold(\" Interactive Elements:\"));\n for (const el of result.elements) {\n const tag = chalk.cyan(el.tag);\n const type = el.type ? chalk.gray(`[${el.type}]`) : \"\";\n const bestSelector = el.selectors.testId\n ?? el.selectors.label\n ?? el.selectors.ariaLabel\n ?? el.selectors.css\n ?? el.selectors.name\n ?? \"\";\n const selectorStr = bestSelector ? chalk.yellow(bestSelector) : chalk.gray(\"(no selector)\");\n const req = el.required ? chalk.red(\" *\") : \"\";\n const form = el.formGroup !== undefined ? chalk.gray(` form[${el.formGroup}]`) : \"\";\n console.log(` ${tag}${type} ${selectorStr}${req}${form}`);\n }\n console.log();\n }\n\n if (result.links.length > 0) {\n console.log(chalk.bold(\" Links:\"));\n for (const link of result.links.slice(0, 20)) {\n const text = link.text || chalk.gray(\"(no text)\");\n console.log(` ${text} ${chalk.gray(\"→\")} ${chalk.blue(link.href)}`);\n }\n if (result.links.length > 20) {\n console.log(chalk.gray(` ... and ${result.links.length - 20} more`));\n }\n console.log();\n }\n\n console.log(chalk.gray(` ${result.elements.length} elements, ${result.forms.length} forms, ${result.links.length} links\\n`));\n }\n } finally {\n await context.close();\n await browser.close();\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Analysis failed\";\n if (options.json) {\n console.log(JSON.stringify({ error: message }));\n } else {\n console.error(`\\n Error: ${message}\\n`);\n }\n process.exitCode = 1;\n }\n });\n\n return command;\n}\n","import type { Page } from \"playwright\";\n\nexport type PageElement = {\n tag: string;\n type?: string;\n selectors: Record<string, string>;\n role?: string;\n label?: string;\n placeholder?: string;\n required: boolean;\n formGroup?: number;\n};\n\nexport type PageForm = {\n index: number;\n action?: string;\n method?: string;\n fieldCount: number;\n};\n\nexport type PageLink = {\n text: string;\n href: string;\n selector: string;\n};\n\nexport type AnalysisResult = {\n url: string;\n title: string;\n elements: PageElement[];\n forms: PageForm[];\n links: PageLink[];\n};\n\ntype RawElement = {\n tag: string;\n type?: string;\n testId?: string;\n ariaLabel?: string;\n role?: string;\n id?: string;\n name?: string;\n label?: string;\n placeholder?: string;\n required: boolean;\n formIndex: number;\n text?: string;\n href?: string;\n};\n\ntype RawForm = {\n index: number;\n action?: string;\n method?: string;\n fieldCount: number;\n};\n\ntype RawAnalysis = {\n title: string;\n url: string;\n elements: RawElement[];\n forms: RawForm[];\n};\n\nexport async function analyzePage(page: Page): Promise<AnalysisResult> {\n const raw = await page.evaluate(() => {\n const forms = Array.from(document.querySelectorAll(\"form\"));\n const formData = forms.map((form, index) => ({\n index,\n action: form.getAttribute(\"action\") || undefined,\n method: (form.getAttribute(\"method\") || \"GET\").toUpperCase(),\n fieldCount: form.querySelectorAll(\"input, textarea, select\").length\n }));\n\n function getFormIndex(el: Element): number {\n const form = el.closest(\"form\");\n if (!form) return -1;\n return forms.indexOf(form);\n }\n\n function getLabel(el: Element): string | undefined {\n const id = el.getAttribute(\"id\");\n if (id) {\n const label = document.querySelector(`label[for=\"${id}\"]`);\n if (label) return label.textContent?.trim() || undefined;\n }\n const parentLabel = el.closest(\"label\");\n if (parentLabel) return parentLabel.textContent?.trim() || undefined;\n return undefined;\n }\n\n const selectors = \"input, textarea, select, button, [role=button], a\";\n const rawElements = Array.from(document.querySelectorAll(selectors));\n\n const elements = rawElements\n .filter((el) => {\n if (el.tagName.toLowerCase() === \"input\" && el.getAttribute(\"type\") === \"hidden\") {\n return false;\n }\n return true;\n })\n .map((el) => {\n const tag = el.tagName.toLowerCase();\n const type = el.getAttribute(\"type\") || undefined;\n const testId = el.getAttribute(\"data-testid\") || undefined;\n const ariaLabel = el.getAttribute(\"aria-label\") || undefined;\n const role = el.getAttribute(\"role\") || undefined;\n const id = el.getAttribute(\"id\") || undefined;\n const name = el.getAttribute(\"name\") || undefined;\n const label = getLabel(el);\n const placeholder = el.getAttribute(\"placeholder\") || undefined;\n const required = el.hasAttribute(\"required\");\n const formIndex = getFormIndex(el);\n const text = el.textContent?.trim() || undefined;\n const href = el.getAttribute(\"href\") || undefined;\n\n return {\n tag,\n type: type || undefined,\n testId,\n ariaLabel,\n role,\n id,\n name,\n label,\n placeholder,\n required,\n formIndex,\n text: tag === \"a\" || tag === \"button\" || role === \"button\" ? text : undefined,\n href: tag === \"a\" ? href : undefined\n };\n });\n\n return {\n title: document.title,\n url: window.location.href,\n elements,\n forms: formData\n };\n }) as RawAnalysis;\n\n const elements: PageElement[] = raw.elements\n .filter((el) => el.tag !== \"a\")\n .map((el) => {\n const selectors: Record<string, string> = {};\n if (el.testId) selectors.testId = `[data-testid=\"${el.testId}\"]`;\n if (el.ariaLabel) selectors.ariaLabel = el.ariaLabel;\n if (el.label) selectors.label = el.label;\n if (el.id) selectors.css = `#${el.id}`;\n if (el.name) selectors.name = `[name=\"${el.name}\"]`;\n if (el.placeholder) selectors.placeholder = el.placeholder;\n if (el.text) selectors.text = el.text;\n if (el.role) selectors.role = el.role;\n\n return {\n tag: el.tag,\n ...(el.type ? { type: el.type } : {}),\n selectors,\n ...(el.role ? { role: el.role } : {}),\n ...(el.label ? { label: el.label } : {}),\n ...(el.placeholder ? { placeholder: el.placeholder } : {}),\n required: el.required,\n ...(el.formIndex >= 0 ? { formGroup: el.formIndex } : {})\n };\n });\n\n const links: PageLink[] = raw.elements\n .filter((el) => el.tag === \"a\" && el.href)\n .map((el) => {\n let selector: string;\n if (el.testId) {\n selector = `[data-testid=\"${el.testId}\"]`;\n } else if (el.href) {\n selector = `a[href=\"${el.href}\"]`;\n } else {\n selector = `a`;\n }\n return {\n text: el.text || \"\",\n href: el.href!,\n selector\n };\n });\n\n const forms: PageForm[] = raw.forms;\n\n return {\n url: raw.url,\n title: raw.title,\n elements,\n forms,\n links\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { generateHunt } from \"../../generator/index.js\";\nimport type { AnalysisResult } from \"../../analyzer/index.js\";\n\nasync function readStdin(): Promise<string | null> {\n if (process.stdin.isTTY) return null;\n\n return new Promise((resolve) => {\n let data = \"\";\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => { data += chunk; });\n process.stdin.on(\"end\", () => resolve(data || null));\n // Timeout after 100ms if no data\n setTimeout(() => resolve(data || null), 100);\n });\n}\n\nexport function buildGenerateCommand(): Command {\n const command = new Command(\"generate\")\n .description(\"Generate a hunt file from page analysis and intent using AI\")\n .option(\"--url <url>\", \"URL to analyze and generate for\")\n .option(\"--intent <description>\", \"What to test (required)\")\n .option(\"--output <name>\", \"Hunt file name (saved to .prowl/hunts/)\")\n .option(\"--stdout\", \"Print YAML to stdout instead of saving\")\n .option(\"--browser <engine>\", \"Browser engine for analysis\")\n .option(\"--viewport <size>\", \"Viewport for analysis\")\n .option(\"--config <path>\", \"Custom config path\")\n .action(async (options) => {\n try {\n const intent = options.intent as string;\n if (!intent) {\n console.error(chalk.red(\" --intent is required\"));\n process.exitCode = 1;\n return;\n }\n\n let analysis: AnalysisResult | undefined;\n\n // Try reading piped stdin first\n const stdinData = await readStdin();\n if (stdinData) {\n try {\n analysis = JSON.parse(stdinData) as AnalysisResult;\n } catch {\n console.error(chalk.red(\" Failed to parse piped JSON input\"));\n process.exitCode = 1;\n return;\n }\n }\n\n if (!analysis && !options.url) {\n console.error(chalk.red(\" Either --url or piped analysis JSON is required\"));\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora(\"Generating hunt...\").start();\n\n try {\n const yamlStr = await generateHunt({\n url: options.url,\n analysis,\n intent,\n browser: options.browser,\n viewport: options.viewport\n });\n\n spinner.succeed(\"Hunt generated\");\n\n if (options.stdout) {\n console.log(yamlStr);\n } else if (options.output) {\n let configDir: string | undefined;\n try {\n const { loadConfig } = await import(\"../../config/loader.js\");\n const result = loadConfig(options.config);\n configDir = result.configDir;\n } catch {\n configDir = path.join(process.cwd(), \".prowl\");\n }\n\n const huntsDir = path.join(configDir, \"hunts\");\n fs.mkdirSync(huntsDir, { recursive: true });\n const fileName = options.output.endsWith(\".yml\")\n ? options.output\n : `${options.output}.yml`;\n const filePath = path.join(huntsDir, fileName);\n fs.writeFileSync(filePath, yamlStr + \"\\n\", \"utf-8\");\n console.log(chalk.green(` Saved to ${filePath}`));\n } else {\n // Default: print to stdout\n console.log(yamlStr);\n }\n } catch (error) {\n spinner.fail(\"Generation failed\");\n throw error;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Generation failed\";\n console.error(`\\n Error: ${message}\\n`);\n process.exitCode = 1;\n }\n });\n\n return command;\n}\n","import yaml from \"yaml\";\nimport { chromium } from \"playwright\";\nimport type { AnalysisResult } from \"../analyzer/index.js\";\nimport { analyzePage } from \"../analyzer/index.js\";\nimport { buildGenerationPrompt, extractYamlFromResponse } from \"./prompt.js\";\nimport { generateWithAi, resolveAiConfig } from \"./ai.js\";\nimport type { AiConfig } from \"./ai.js\";\nimport { huntSchema } from \"../config/schema.js\";\n\nexport type GenerateOptions = {\n url?: string;\n analysis?: AnalysisResult;\n intent: string;\n browser?: string;\n viewport?: string;\n aiConfig?: AiConfig;\n};\n\nexport async function generateHunt(options: GenerateOptions): Promise<string> {\n let analysis = options.analysis;\n\n if (!analysis && options.url) {\n const browser = await chromium.launch({ headless: true });\n const context = await browser.newContext();\n const page = await context.newPage();\n try {\n await page.goto(options.url, { waitUntil: \"networkidle\" });\n analysis = await analyzePage(page);\n } finally {\n await context.close();\n await browser.close();\n }\n }\n\n if (!analysis) {\n throw new Error(\"Either --url or piped analysis JSON is required\");\n }\n\n const config = options.aiConfig ?? resolveAiConfig();\n const prompt = buildGenerationPrompt(analysis, options.intent);\n const response = await generateWithAi(prompt, config);\n const yamlStr = extractYamlFromResponse(response);\n\n // Validate generated YAML\n const parsed = yaml.parse(yamlStr);\n huntSchema.parse(parsed);\n\n return yamlStr;\n}\n","import type { AnalysisResult } from \"../analyzer/index.js\";\n\nconst STEP_REFERENCE = `\n## Prowl Step Types\n\n### Navigation & Waiting\n- navigate: \"/path\" — navigate to URL (relative to target)\n- wait: \"Text\" — wait for text to appear\n- wait: { for: \"Text\", timeout: 5000 } — with timeout\n- waitForSelector: { selector: \"#el\", timeout: 5000 }\n- waitForUrl: { value: \"/path\", timeout: 5000 }\n- waitForNetworkIdle: { timeout: 5000 }\n\n### Interaction\n- click: \"Button Text\" — click by text (tries role=button first)\n- click: { selector: \"[data-testid=btn]\" } — click by selector\n- fill: { \"Label\": \"value\" } — fill by label/placeholder\n- fill: { selector: \"#input\", value: \"text\" } — fill by selector\n- type: \"text\" — type into focused element\n- press: { selector: \"#input\", key: \"Enter\" }\n- hover: { selector: \"#menu\" }\n- selectOption: { selector: \"select\", value: \"option\" }\n- select: { \"Label\": \"value\" } — select by label\n- setInputFiles: { selector: \"#file\", files: \"path.png\" }\n- onDialog: { action: \"accept\" } — handle browser dialogs\n\n### Assertions\n- assert: { visible: \"Text\" }\n- assert: { notVisible: \"Error\" }\n- assert: { urlIncludes: \"/dashboard\" }\n- assert: { urlEquals: \"https://...\" }\n\n### Scrolling & Screenshots\n- scroll: { direction: \"down\", amount: 500 }\n- scrollTo: { selector: \"#section\" }\n- screenshot: { name: \"step-name\" }\n\n### Script Execution\n- evalScript: \"document.title\" — evaluate JS expression\n- evalScript: { expression: \"expr\", as: \"VAR\" } — capture to variable\n- runScript: { file: \"scripts/setup.js\" }\n\n### Visual Regression\n- assertScreenshot: { name: \"baseline-name\", threshold: 0.1 }\n\n### Control Flow\n- if: { visible: \".banner\", then: [steps...] }\n- repeat: { times: 3, steps: [steps...] }\n- repeat: { while: { visible: \".more\" }, maxIterations: 10, steps: [steps...] }\n- runHunt: \"other-hunt\" — run another hunt file\n- mockRoute: { url: \"**/api/data\", response: { status: 200, body: \"{}\" } }\n- unmockRoute: { url: \"**/api/data\" }\n`.trim();\n\nexport function buildGenerationPrompt(analysis: AnalysisResult, intent: string): string {\n return `You are a QA test generator for Prowl. Generate a YAML hunt file that tests the described intent using the page analysis data below.\n\n${STEP_REFERENCE}\n\n## Page Analysis\n\\`\\`\\`json\n${JSON.stringify(analysis, null, 2)}\n\\`\\`\\`\n\n## Test Intent\n${intent}\n\n## Instructions\n1. Output ONLY a valid Prowl YAML hunt between \\`\\`\\`yaml fences\n2. Use shorthand syntax when possible (click: \"Text\", fill: { \"Label\": \"value\" })\n3. Prefer stable selectors: data-testid > aria-label > text > CSS selectors\n4. Include assertions to verify expected outcomes\n5. Add a descriptive name and description\n6. Keep steps focused and minimal — test exactly what the intent describes\n\n\\`\\`\\`yaml\n`;\n}\n\nexport function extractYamlFromResponse(response: string): string {\n const fenceMatch = response.match(/```ya?ml\\n?([\\s\\S]*?)```/);\n if (fenceMatch) {\n return fenceMatch[1].trim();\n }\n return response.trim();\n}\n","export type AiProvider = \"anthropic\" | \"openai\";\n\nexport type AiConfig = {\n provider: AiProvider;\n model: string;\n apiKey: string;\n};\n\nexport function resolveAiConfig(): AiConfig {\n const provider = (process.env.PROWL_AI_PROVIDER ?? \"anthropic\") as AiProvider;\n if (provider !== \"anthropic\" && provider !== \"openai\") {\n throw new Error(`Unsupported AI provider: ${provider}. Use \"anthropic\" or \"openai\".`);\n }\n\n const apiKey = process.env.PROWL_AI_KEY;\n if (!apiKey) {\n throw new Error(\n \"PROWL_AI_KEY environment variable is required. Set it to your Anthropic or OpenAI API key.\"\n );\n }\n\n const defaultModel = provider === \"anthropic\"\n ? \"claude-sonnet-4-5-20250929\"\n : \"gpt-4o\";\n const model = process.env.PROWL_AI_MODEL ?? defaultModel;\n\n return { provider, model, apiKey };\n}\n\nexport async function generateWithAi(prompt: string, config: AiConfig): Promise<string> {\n if (config.provider === \"anthropic\") {\n return generateWithAnthropic(prompt, config);\n }\n return generateWithOpenAi(prompt, config);\n}\n\nasync function generateWithAnthropic(prompt: string, config: AiConfig): Promise<string> {\n const response = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": config.apiKey,\n \"anthropic-version\": \"2023-06-01\"\n },\n body: JSON.stringify({\n model: config.model,\n max_tokens: 4096,\n messages: [\n { role: \"user\", content: prompt }\n ]\n })\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Anthropic API error (${response.status}): ${body}`);\n }\n\n const data = await response.json() as {\n content: Array<{ type: string; text?: string }>;\n };\n\n const textBlock = data.content.find((c) => c.type === \"text\");\n if (!textBlock?.text) {\n throw new Error(\"Anthropic API returned no text content\");\n }\n\n return textBlock.text;\n}\n\nasync function generateWithOpenAi(prompt: string, config: AiConfig): Promise<string> {\n const response = await fetch(\"https://api.openai.com/v1/chat/completions\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${config.apiKey}`\n },\n body: JSON.stringify({\n model: config.model,\n messages: [\n { role: \"user\", content: prompt }\n ],\n max_tokens: 4096\n })\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`OpenAI API error (${response.status}): ${body}`);\n }\n\n const data = await response.json() as {\n choices: Array<{ message: { content: string } }>;\n };\n\n if (!data.choices?.[0]?.message?.content) {\n throw new Error(\"OpenAI API returned no content\");\n }\n\n return data.choices[0].message.content;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { loadConfig } from \"../../config/loader.js\";\nimport { readHuntHistory } from \"../../runner/history.js\";\nimport type { HistoryEntry } from \"../../types/index.js\";\n\nexport function buildHistoryCommand(): Command {\n const command = new Command(\"history\")\n .argument(\"<hunt-name>\", \"Hunt name or path (e.g. homepage or admin/users-crud)\")\n .description(\"Show run history for a hunt\")\n .option(\"--config <path>\", \"Custom config path\")\n .option(\"--limit <n>\", \"Show the last N runs (default: 20)\", (value) => {\n const n = Number(value);\n if (!Number.isInteger(n) || n < 1) {\n throw new Error(\"--limit must be a positive integer\");\n }\n return n;\n })\n .option(\"--json\", \"Output as JSON\")\n .action((huntName: string, options) => {\n try {\n const { configDir } = loadConfig(options.config);\n const entries = readHuntHistory(configDir, huntName);\n const limit = (options.limit as number | undefined) ?? 20;\n const recent = entries.slice(-limit);\n\n if (options.json) {\n console.log(JSON.stringify(recent, null, 2));\n return;\n }\n\n if (recent.length === 0) {\n console.log(\n chalk.yellow(\n `\\n No history found for \"${huntName}\". Run it at least once with \\`prowl run ${huntName}\\`.\\n`\n )\n );\n return;\n }\n\n console.log();\n console.log(` ${chalk.bold(huntName)} — last ${recent.length} of ${entries.length} runs`);\n console.log();\n console.log(formatTable(recent));\n console.log();\n } catch (error) {\n const message = error instanceof Error ? error.message : \"history failed\";\n if (options.json) {\n console.log(JSON.stringify({ error: message }));\n } else {\n console.error(chalk.red(`Error: ${message}`));\n }\n process.exitCode = 1;\n }\n });\n\n return command;\n}\n\nfunction formatTable(entries: HistoryEntry[]): string {\n const headers = [\"Status\", \"Started\", \"Duration\"];\n const rows = entries.map((entry) => [\n formatStatus(entry.status),\n entry.startedAt,\n formatDuration(entry.durationMs)\n ]);\n\n const widths = headers.map((header, index) =>\n Math.max(\n stripAnsi(header).length,\n ...rows.map((row) => stripAnsi(row[index]).length)\n )\n );\n\n const headerLine = ` ${headers.map((h, i) => pad(h, widths[i])).join(\" \")}`;\n const rule = ` ${widths.map((w) => \"-\".repeat(w)).join(\" \")}`;\n const body = rows\n .map((row) => ` ${row.map((cell, i) => pad(cell, widths[i])).join(\" \")}`)\n .join(\"\\n\");\n\n return `${headerLine}\\n${rule}\\n${body}`;\n}\n\nfunction formatStatus(status: \"pass\" | \"fail\"): string {\n return status === \"pass\" ? chalk.green(\"pass\") : chalk.red(\"fail\");\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\nfunction pad(value: string, width: number): string {\n const bareLength = stripAnsi(value).length;\n if (bareLength >= width) {\n return value;\n }\n return `${value}${\" \".repeat(width - bareLength)}`;\n}\n\nfunction stripAnsi(value: string): string {\n // Remove ANSI color codes so width calculations work with chalk output.\n // Control char escape is intentional; this is the standard ANSI SGR pattern.\n // eslint-disable-next-line no-control-regex\n return value.replace(/\u001b\\[[0-9;]*m/g, \"\");\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { loadConfig } from \"../../config/loader.js\";\nimport { rankFlaky, DEFAULT_FLAKY_THRESHOLD, type FlakyScore } from \"../../runner/flaky.js\";\n\nexport function buildFlakyCommand(): Command {\n const command = new Command(\"flaky\")\n .description(\"Rank hunts by flake score (pass/fail oscillation) from run history\")\n .option(\"--config <path>\", \"Custom config path\")\n .option(\"--limit <n>\", \"Only score the most recent N runs per hunt\", (value) => {\n const n = Number(value);\n if (!Number.isInteger(n) || n < 1) {\n throw new Error(\"--limit must be a positive integer\");\n }\n return n;\n })\n .option(\"--threshold <value>\", \"Flaky threshold 0-1 (overrides config)\", (value) => {\n const n = Number(value);\n if (!Number.isFinite(n) || n < 0 || n > 1) {\n throw new Error(\"--threshold must be a number between 0 and 1\");\n }\n return n;\n })\n .option(\"--json\", \"Output as JSON\")\n .action((options) => {\n try {\n const { config, configDir } = loadConfig(options.config);\n const threshold =\n (options.threshold as number | undefined) ??\n config.reliability?.flakyThreshold ??\n DEFAULT_FLAKY_THRESHOLD;\n\n const scores = rankFlaky(configDir, {\n lastN: options.limit as number | undefined,\n threshold\n });\n\n if (options.json) {\n console.log(JSON.stringify(scores, null, 2));\n return;\n }\n\n if (scores.length === 0) {\n console.log(\n chalk.yellow(\n \"\\n No run history found. Run hunts with `prowl run` or `prowl ci` first.\\n\"\n )\n );\n return;\n }\n\n console.log();\n console.log(` ${chalk.bold(\"Flake scores\")} (threshold ${threshold})`);\n console.log();\n console.log(formatTable(scores));\n console.log();\n } catch (error) {\n const message = error instanceof Error ? error.message : \"flaky failed\";\n if (options.json) {\n console.log(JSON.stringify({ error: message }));\n } else {\n console.error(chalk.red(`Error: ${message}`));\n }\n process.exitCode = 1;\n }\n });\n\n return command;\n}\n\nfunction formatTable(scores: FlakyScore[]): string {\n const headers = [\"Hunt\", \"Score\", \"Runs\", \"Flaky\"];\n const rows = scores.map((s) => [\n s.hunt,\n s.score.toFixed(2),\n String(s.runs),\n s.flaky ? chalk.red(\"yes\") : chalk.green(\"no\")\n ]);\n\n const widths = headers.map((header, index) =>\n Math.max(stripAnsi(header).length, ...rows.map((row) => stripAnsi(row[index]).length))\n );\n\n const headerLine = ` ${headers.map((h, i) => pad(h, widths[i])).join(\" \")}`;\n const rule = ` ${widths.map((w) => \"-\".repeat(w)).join(\" \")}`;\n const body = rows\n .map((row) => ` ${row.map((cell, i) => pad(cell, widths[i])).join(\" \")}`)\n .join(\"\\n\");\n\n return `${headerLine}\\n${rule}\\n${body}`;\n}\n\nfunction pad(value: string, width: number): string {\n const bareLength = stripAnsi(value).length;\n return bareLength >= width ? value : `${value}${\" \".repeat(width - bareLength)}`;\n}\n\nfunction stripAnsi(value: string): string {\n // eslint-disable-next-line no-control-regex\n return value.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n","import { Command } from \"commander\";\nimport { startMcpServer } from \"../../mcp/server.js\";\n\n/** Convert MCP startup failures into concise CLI output. */\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** Build the CLI command that starts the stdio MCP server. */\nexport function buildMcpCommand(): Command {\n return new Command(\"mcp\")\n .description(\"Start an MCP server (stdio) exposing Prowl tools to AI agents\")\n .option(\n \"--projects <path>\",\n \"Path to a project registry (YAML) so tools can target multiple repos by name\"\n )\n .action(async (options) => {\n try {\n await startMcpServer({ registryPath: options.projects });\n } catch (error) {\n console.error(`Failed to start MCP server: ${errorMessage(error)}`);\n process.exit(1);\n }\n });\n}\n","import { z } from \"zod\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport pkg from \"../../package.json\";\nimport { listHuntsTool, runHuntTool, runSuiteTool } from \"./tools.js\";\nimport {\n type ProjectRegistry,\n type ResolvedProject,\n listRegisteredProjects,\n loadProjectRegistry,\n resolveProject\n} from \"./projects.js\";\n\nexport interface BuildMcpServerOptions {\n /** When provided, a `project` tool argument selects a registered project. */\n registry?: ProjectRegistry | null;\n}\n\nexport interface StartMcpServerOptions {\n /** Path to a project registry file (overrides env/default discovery). */\n registryPath?: string;\n}\n\ntype TextToolResult = { content: Array<{ type: \"text\"; text: string }> };\n\n/** Serialize a tool payload into the MCP text-content response format. */\nfunction textResult(data: unknown): { content: Array<{ type: \"text\"; text: string }> } {\n return { content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }] };\n}\n\n/** Convert unknown thrown values into user-facing error text. */\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** JSON-stringify diagnostic values without throwing from circular structures. */\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value) ?? \"undefined\";\n } catch {\n return \"[unserializable]\";\n }\n}\n\n/** Run a tool implementation and rethrow failures with tool-specific context. */\nasync function toolResult(\n toolName: string,\n args: unknown,\n action: () => unknown | Promise<unknown>\n): Promise<TextToolResult> {\n try {\n return textResult(await action());\n } catch (error) {\n throw new Error(`${toolName} failed for args=${safeStringify(args)}: ${errorMessage(error)}`, {\n cause: error\n });\n }\n}\n\nconst PROJECT_ARG_DESCRIPTION =\n \"Registered project name to target (from the registry). Omit to use the current working directory.\";\n\n/**\n * Builds an MCP server exposing Prowl as named tools. By default it operates on\n * the current working directory's `.prowl/` project, exactly like the CLI. When a\n * project registry is provided, tools accept an optional `project` argument to\n * target any registered repo. The agent gets a fixed tool surface — it never\n * chooses shell commands.\n */\nexport function buildMcpServer(options: BuildMcpServerOptions = {}): McpServer {\n const registry = options.registry ?? null;\n const server = new McpServer({ name: \"prowl\", version: pkg.version });\n\n // Resolve an optional `project` arg. Throws a helpful error if a project is\n // named but no registry is configured.\n const projectFor = (project?: string): ResolvedProject | null => {\n if (!project) return null;\n if (!registry) {\n throw new Error(\n `No project registry is configured, so project \"${project}\" cannot be resolved. ` +\n \"Start the server with `prowl mcp --projects <path>` (or set PROWL_PROJECTS).\"\n );\n }\n return resolveProject(registry, project);\n };\n\n const configPathFor = (project?: string): string | undefined => {\n return projectFor(project)?.configPath;\n };\n\n server.registerTool(\n \"list_projects\",\n {\n description: \"List the projects registered with this server. Empty when no registry is configured.\",\n inputSchema: z.object({}).strict()\n },\n async (args) => toolResult(\"list_projects\", args, () => ({ projects: listRegisteredProjects(registry) }))\n );\n\n server.registerTool(\n \"list_hunts\",\n {\n description: \"List all hunts in the target project, in run order.\",\n inputSchema: {\n project: z.string().min(1).describe(PROJECT_ARG_DESCRIPTION).optional()\n }\n },\n async (args) => toolResult(\"list_hunts\", args, () => listHuntsTool(configPathFor(args.project)))\n );\n\n server.registerTool(\n \"run_suite\",\n {\n description:\n \"Run all hunts and, by default, log any failures as deduplicated bug tickets in the project backlog. Returns pass/fail/skip counts and the QA-NNN ticket ids created.\",\n inputSchema: {\n project: z.string().min(1).describe(PROJECT_ARG_DESCRIPTION).optional(),\n includeTags: z.array(z.string()).optional(),\n excludeTags: z.array(z.string()).optional(),\n parallel: z.number().int().min(1).optional(),\n logBugs: z.boolean().optional()\n }\n },\n async (args) => toolResult(\"run_suite\", args, () => {\n const project = projectFor(args.project);\n return runSuiteTool(args, { configPath: project?.configPath, projectRoot: project?.root });\n })\n );\n\n server.registerTool(\n \"run_hunt\",\n {\n description: \"Run a single hunt by name and return its full result.\",\n inputSchema: {\n hunt: z.string().min(1),\n project: z.string().min(1).describe(PROJECT_ARG_DESCRIPTION).optional()\n }\n },\n async (args) => toolResult(\"run_hunt\", args, () => runHuntTool(args, configPathFor(args.project)))\n );\n\n return server;\n}\n\n/** Starts the MCP server over stdio and resolves once connected. */\nexport async function startMcpServer(options: StartMcpServerOptions = {}): Promise<void> {\n const registry = loadProjectRegistry(options.registryPath);\n const server = buildMcpServer({ registry });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","import path from \"node:path\";\nimport { runHunt } from \"../runner/index.js\";\nimport { runSuite } from \"../runner/suite.js\";\nimport { updateBacklogFromSuite } from \"../backlog/index.js\";\nimport { loadConfig, listHunts } from \"../config/loader.js\";\nimport type { RunResult } from \"../types/index.js\";\n\n/** Arguments accepted by the MCP `run_suite` tool. */\nexport interface RunSuiteToolArgs {\n includeTags?: string[];\n excludeTags?: string[];\n parallel?: number;\n /** Log failures to the project backlog (default true). */\n logBugs?: boolean;\n}\n\n/** JSON payload returned by the MCP `run_suite` tool. */\nexport interface RunSuiteToolResult {\n status: string;\n totalHunts: number;\n passed: number;\n failed: number;\n skipped: number;\n resultPath: string | null;\n bugs: {\n created: string[];\n regressions: string[];\n alreadyOpen: string[];\n backlogPath: string | null;\n };\n}\n\nexport interface RunSuiteToolOptions {\n /** Config path for a registered project; omitted uses cwd discovery. */\n configPath?: string;\n /** Authoritative project root for backlog writes; defaults to config parent. */\n projectRoot?: string;\n}\n\n/**\n * Hunt names in run order. Targets the project resolved from `configPath` (a\n * registered project's config), or the current working directory when omitted.\n */\nexport function listHuntsTool(configPath?: string): { hunts: string[] } {\n const { configDir } = loadConfig(configPath);\n return { hunts: listHunts(configDir) };\n}\n\n/**\n * Run the full hunt suite and (by default) log any failures as deduplicated bug\n * tickets in the project backlog. Returns pass/fail counts plus the QA-NNN ticket\n * ids the bug-logger created. Targets the project resolved from `configPath`, or\n * the current working directory when omitted.\n */\nexport async function runSuiteTool(\n args: RunSuiteToolArgs = {},\n options: RunSuiteToolOptions = {}\n): Promise<RunSuiteToolResult> {\n const { configPath: resolvedConfigPath, configDir, config } = loadConfig(options.configPath);\n const projectRoot = options.projectRoot ?? path.dirname(configDir);\n const suite = await runSuite({\n configPath: resolvedConfigPath,\n includeTags: args.includeTags,\n excludeTags: args.excludeTags,\n parallel: args.parallel\n });\n\n // Precedence: a per-call logBugs arg wins, then config.bugLog.enabled, else on by default.\n const bugLogCfg = config.bugLog ?? {};\n const logBugs = args.logBugs ?? bugLogCfg.enabled ?? true;\n\n // Config paths resolve against the project root (not the server cwd) so MCP\n // multi-project mode writes into the correct repo. When only backlogPath is set,\n // resolvedPath defaults to a sibling resolved.md so the pair stays together.\n const backlogPath = bugLogCfg.backlogPath\n ? path.resolve(projectRoot, bugLogCfg.backlogPath)\n : undefined;\n const resolvedPath = bugLogCfg.resolvedPath\n ? path.resolve(projectRoot, bugLogCfg.resolvedPath)\n : backlogPath\n ? path.join(path.dirname(backlogPath), \"resolved.md\")\n : undefined;\n\n const bugs = logBugs\n ? updateBacklogFromSuite(suite, { projectRoot, backlogPath, resolvedPath })\n : { created: [], regressions: [], skipped: [], backlogPath: null };\n\n const { status, totalHunts, passed, failed, skipped } = suite.result;\n return {\n status,\n totalHunts,\n passed,\n failed,\n skipped,\n resultPath: suite.resultPath,\n bugs: {\n created: bugs.created,\n regressions: bugs.regressions,\n alreadyOpen: bugs.skipped,\n backlogPath: bugs.backlogPath\n }\n };\n}\n\n/**\n * Run a single hunt by name and return its full result plus the run directory.\n * Targets the project resolved from `configPath`, or the cwd when omitted.\n */\nexport async function runHuntTool(\n args: { hunt: string },\n configPath?: string\n): Promise<RunResult & { runDir: string }> {\n const { result, runDir } = await runHunt({\n huntName: args.hunt,\n ...(configPath ? { configPath } : {})\n });\n return { ...result, runDir };\n}\n","import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport yaml from \"yaml\";\nimport { z } from \"zod\";\n\nconst projectEntrySchema = z\n .object({\n root: z.string().min(1),\n /** Optional override; defaults to <root>/.prowl/config.yml (legacy: .prowlqa/). */\n configPath: z.string().min(1).optional()\n })\n .strict();\n\nconst projectRegistrySchema = z\n .object({\n projects: z.record(z.string().min(1), projectEntrySchema)\n })\n .strict();\n\nexport type ProjectEntry = z.infer<typeof projectEntrySchema>;\n\nexport interface ProjectRegistry {\n projects: Record<string, ProjectEntry>;\n registryPath: string;\n}\n\nexport interface ResolvedProject {\n name: string;\n root: string;\n configPath: string;\n}\n\n/** Default registry location used when neither CLI flag nor env var is set. */\nfunction defaultRegistryPath(): string {\n return path.join(os.homedir(), \".prowl\", \"projects.yml\");\n}\n\n/** Legacy registry location (pre-rename), still honored for back-compat. */\nfunction legacyRegistryPath(): string {\n return path.join(os.homedir(), \".prowlqa\", \"projects.yml\");\n}\n\n/** Resolve a project's config path within its root, preferring .prowl/ over legacy .prowlqa/. */\nfunction resolveProjectConfigPath(root: string): string {\n const preferred = path.join(root, \".prowl\", \"config.yml\");\n if (fs.existsSync(preferred)) return preferred;\n const legacy = path.join(root, \".prowlqa\", \"config.yml\");\n if (fs.existsSync(legacy)) return legacy;\n return preferred;\n}\n\n/** Resolve a project entry path relative to the registry file that declared it. */\nfunction resolveRegistryRelativePath(registry: ProjectRegistry, inputPath: string): string {\n return path.isAbsolute(inputPath)\n ? inputPath\n : path.resolve(path.dirname(registry.registryPath), inputPath);\n}\n\n/**\n * Resolve which registry file to use, in priority order: an explicit path\n * (`prowl mcp --projects`), the `PROWL_PROJECTS` env var (or legacy\n * `PROWLQA_PROJECTS`), then the default `~/.prowl/projects.yml` (or legacy\n * `~/.prowlqa/projects.yml`). Returns null when no registry is configured.\n */\nexport function resolveRegistryPath(explicitPath?: string): string | null {\n if (explicitPath) return path.resolve(explicitPath);\n const envPath = process.env.PROWL_PROJECTS ?? process.env.PROWLQA_PROJECTS;\n if (envPath) return path.resolve(envPath);\n const fallback = defaultRegistryPath();\n if (fs.existsSync(fallback)) return fallback;\n const legacy = legacyRegistryPath();\n return fs.existsSync(legacy) ? legacy : null;\n}\n\n/** Load and validate the project registry, or return null when none is configured. */\nexport function loadProjectRegistry(explicitPath?: string): ProjectRegistry | null {\n const registryPath = resolveRegistryPath(explicitPath);\n if (!registryPath) return null;\n if (!fs.existsSync(registryPath)) {\n throw new Error(`Project registry not found at ${registryPath}`);\n }\n const raw = fs.readFileSync(registryPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n const validated = projectRegistrySchema.parse(parsed);\n return { projects: validated.projects, registryPath };\n}\n\n/** Resolve a project name to its root and config path; throws if the name is unknown. */\nexport function resolveProject(registry: ProjectRegistry, name: string): ResolvedProject {\n const entry = registry.projects[name];\n if (!entry) {\n const known = Object.keys(registry.projects).sort().join(\", \") || \"(none)\";\n throw new Error(`Unknown project \"${name}\". Registered projects: ${known}`);\n }\n const root = resolveRegistryRelativePath(registry, entry.root);\n const configPath = entry.configPath\n ? resolveRegistryRelativePath(registry, entry.configPath)\n : resolveProjectConfigPath(root);\n return { name, root, configPath };\n}\n\n/** List registered projects as `{ name, root }` pairs (empty when no registry). */\nexport function listRegisteredProjects(registry: ProjectRegistry | null): Array<{ name: string; root: string }> {\n if (!registry) return [];\n return Object.entries(registry.projects).map(([name, entry]) => ({\n name,\n root: resolveRegistryRelativePath(registry, entry.root)\n }));\n}\n","#!/usr/bin/env node\nimport { buildProgram } from \"./program.js\";\n\nconst program = buildProgram();\n\nprogram.parseAsync(process.argv).catch((error) => {\n const message = error instanceof Error ? error.message : \"Command failed\";\n console.error(message);\n process.exit(1);\n});\n"],"mappings":"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","names":["path","fs","dotenv","yaml","fs","diff","pixelmatch","path","import_node_fs","import_node_path","import_commander","import_chalk","import_node_fs","import_node_path","crypto","stepPath","valueResult","import_node_fs","import_node_path","fs","path","import_node_fs","import_node_path","path","fs","compareScreenshots","ensureBaselineDir","import_node_fs","import_node_path","path","fs","import_node_fs","import_node_path","path","fs","import_node_fs","import_node_path","path","fs","pad","pad3","import_node_fs","import_node_path","path","fs","path","fs","chalk","import_chalk","chalk","chalk","import_node_fs","import_node_path","import_commander","import_chalk","path","fs","chalk","import_node_path","import_chalk","import_commander","import_playwright","resolvePath","path","readline","chalk","import_commander","import_chalk","chalk","import_node_fs","import_chalk","import_commander","import_node_path","path","chalk","fs","import_commander","import_chalk","import_node_path","import_node_fs","import_node_path","import_chalk","chalk","pad","fs","path","import_node_crypto","import_node_fs","import_node_path","fs","path","path","chalk","import_node_fs","import_node_path","import_commander","import_chalk","path","fs","chalk","import_commander","import_chalk","import_playwright","forms","elements","ENGINES","parseViewportFlag","chalk","import_node_fs","import_node_path","import_commander","import_chalk","import_yaml","import_playwright","yaml","chalk","ora","loadConfig","path","fs","import_commander","import_chalk","chalk","import_commander","import_chalk","chalk","formatTable","stripAnsi","pad","import_commander","import_zod","import_node_path","path","import_node_fs","import_node_path","import_yaml","import_zod","path","os","fs","yaml","errorMessage","program"]}