prowl-tools 0.1.7 → 0.1.9
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.
- package/README.md +56 -7
- package/dist/{chunk-R7NUH44M.js → chunk-2RNOK64Y.js} +314 -399
- package/dist/chunk-2RNOK64Y.js.map +1 -0
- package/dist/{chunk-O3OUTZ2P.js → chunk-JFJQNJSJ.js} +394 -2
- package/dist/chunk-JFJQNJSJ.js.map +1 -0
- package/dist/index.cjs +1564 -692
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +597 -40
- package/dist/index.js.map +1 -1
- package/dist/lib.cjs +650 -346
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.cts +95 -17
- package/dist/lib.d.ts +95 -17
- package/dist/lib.js +3 -3
- package/dist/{loader-X37URHUV.js → loader-JTHA4BYG.js} +2 -2
- package/examples/hunts/form.yml +53 -0
- package/examples/hunts/macos-hello.yml +49 -0
- package/package.json +1 -1
- package/dist/chunk-O3OUTZ2P.js.map +0 -1
- package/dist/chunk-R7NUH44M.js.map +0 -1
- /package/dist/{loader-X37URHUV.js.map → loader-JTHA4BYG.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/program.ts","../package.json","../src/cli/commands/run.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/cli/commands/update-baselines.ts","../src/cli/commands/analyze.ts","../src/cli/commands/generate.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/commands/macdriver.ts","../src/cli/index.ts"],"sourcesContent":["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\";\nimport { buildMacdriverCommand } from \"./commands/macdriver.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 program.addCommand(buildMacdriverCommand());\n\n return program;\n}\n","{\n \"name\": \"prowl-tools\",\n \"version\": \"0.1.7\",\n \"description\": \"E2E testing for native macOS apps and web apps from declarative YAML hunts.\",\n \"type\": \"module\",\n \"license\": \"Apache-2.0\",\n \"author\": \"Prowl Tools\",\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 \"e2e\",\n \"macos\",\n \"desktop-testing\",\n \"accessibility\",\n \"playwright\",\n \"yaml\",\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 \"optionalDependencies\": {\n \"appium-uiautomator2-server\": \"10.6.2\",\n \"appium-webdriveragent\": \"16.4.0\"\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 { normalizeHuntName } from \"../../config/hunt-name.js\";\nimport { printHuntHeader, printStepResult, printHuntSummary } from \"../output.js\";\nimport { resultMascot } from \"../mascot.js\";\n\n/** Build the `prowl run` command and normalize path-like hunt arguments. */\nexport function buildRunCommand(): Command {\n const command = new Command(\"run\")\n .argument(\n \"<hunt-name>\",\n \"Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)\"\n )\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 (huntArg, options) => {\n const huntName = normalizeHuntName(huntArg);\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 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 if (\"assertWithAI\" in step) return `assertWithAI \"${truncate(step.assertWithAI, 60)}\"`;\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 if (result.status === \"warn\") {\n const note = result.value ? chalk.gray(` \\u2014 ${result.value}`) : \"\";\n console.log(` ${chalk.yellow(\"\\u25cb\")} ${label} ${duration}${note}`);\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(\" See \") + chalk.cyan(`${CONFIG_DIR}/hunts/login-flow.yml`) + chalk.gray(\" for a fuller example.\") + \"\\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 {\n launchBrowser,\n closeBrowser,\n saveStorageState,\n createPlaywrightDriver,\n type BrowserSession\n} from \"../../browser/controller.js\";\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 session: BrowserSession | null = null;\n try {\n const { config, configDir } = loadConfig(options.config);\n if (config.target.type !== \"web\") {\n throw new Error(\"`prowl login` captures browser auth state and only applies to web targets.\");\n }\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 session = await launchBrowser({\n headless: false,\n slowMo: 0,\n timeout: config.browser.timeout,\n trace: false,\n recordHar: false,\n runDir: configDir\n });\n const driver = createPlaywrightDriver(session.page);\n await driver.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 saveStorageState(session, 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 (session) {\n await closeBrowser(session);\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 { normalizeHuntName } from \"../../config/hunt-name.js\";\nimport { runHunt } from \"../../runner/index.js\";\nimport { createDebouncer, getWatchTargets } from \"../watch-utils.js\";\nimport { printHuntHeader, printStepResult, printHuntSummary } from \"../output.js\";\n\n/** Build the `prowl watch` command and normalize path-like hunt arguments. */\nexport function buildWatchCommand(): Command {\n const command = new Command(\"watch\")\n .argument(\n \"<hunt-name>\",\n \"Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)\"\n )\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 (huntArg, options) => {\n const huntName = normalizeHuntName(huntArg);\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 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 type { BrowserChannel, Config, Target, Viewport } from \"../../types/index.js\";\nimport { launchBrowser, closeBrowser, createPlaywrightDriver } from \"../../browser/controller.js\";\nimport { parseBrowserEngine } from \"../../browser/engines.js\";\nimport { analyzePage } from \"../../analyzer/index.js\";\nimport { analyzeMacApp, type MacAnalysisElement } from \"../../analyzer/mac.js\";\nimport { analyzeAndroidApp, type AndroidAnalysisElement } from \"../../analyzer/android.js\";\nimport { analyzeIosApp, type IosAnalysisElement } from \"../../analyzer/ios.js\";\nimport { launchMacSession } from \"../../browser/mac-helper.js\";\nimport { launchAndroidSession } from \"../../browser/android-helper.js\";\nimport { launchIosSession } from \"../../browser/ios-helper.js\";\nimport {\n assertTargetAppAllowed,\n assertAndroidAppAllowed,\n assertIosAppAllowed\n} from \"../../config/target.js\";\nimport { findConfigPath, loadConfig, resolveViewport } from \"../../config/loader.js\";\n\n/** The three native targets `prowl analyze` supports alongside the web target. */\ntype NativePlatform = \"macos\" | \"android\" | \"ios\";\n\n/** Parse a viewport flag into a named preset or an explicit width/height pair. */\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\n/** Optional config load; returns null only when no default config exists. */\nfunction tryLoadConfig(configPath?: string): Config | null {\n const configLocation = configPath !== undefined\n ? configPath\n : findConfigPath(process.cwd());\n if (configLocation === null) {\n return null;\n }\n\n try {\n return loadConfig(configLocation).config;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown configuration error\";\n throw new Error(`Failed to load config at ${configLocation}: ${message}`);\n }\n}\n\n/** Whether an `--app` value looks like an Android `.apk` (decisive for inference). */\nfunction looksLikeApk(app: string): boolean {\n return /\\.apk$/i.test(app.trim());\n}\n\n/**\n * Decide which native platform a forced `--app` targets. Order: an explicit\n * `--platform` wins; otherwise a loaded config's native `target.type`; otherwise\n * inference from the app value (`.apk` → android, else macOS to preserve the\n * original `--app` = macOS behavior). `.app` paths and bare bundle ids are\n * ambiguous between macOS and iOS, so those default to macOS unless `--platform`\n * or a config says otherwise.\n */\nfunction pickNativePlatform(platformFlag: string | undefined, config: Config | null, app: string): NativePlatform {\n if (platformFlag !== undefined) {\n const normalized = platformFlag.trim().toLowerCase();\n if (normalized === \"macos\" || normalized === \"android\" || normalized === \"ios\") {\n return normalized;\n }\n throw new Error(`Unknown --platform \"${platformFlag}\". Use one of: macos, android, ios.`);\n }\n const configType = config?.target.type;\n if (configType === \"macos\" || configType === \"android\" || configType === \"ios\") {\n return configType;\n }\n return looksLikeApk(app) ? \"android\" : \"macos\";\n}\n\n/** Web target: analyze a page's DOM via Playwright. Behavior is unchanged from the original command. */\nasync function runWebAnalyze(url: string, options: Record<string, unknown>): Promise<void> {\n const engine = parseBrowserEngine(options.browser as string | undefined);\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 session = await launchBrowser({\n headless: !options.headed,\n slowMo: 0,\n timeout: 30000,\n trace: false,\n recordHar: false,\n runDir: process.cwd(),\n engine,\n channel,\n viewport\n });\n const driver = createPlaywrightDriver(session.page);\n\n try {\n await driver.goto(url, { waitUntil: \"networkidle\" });\n const result = await analyzePage(driver);\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 closeBrowser(session);\n }\n}\n\n/** Print one macOS analysis element in the human-readable analyze output. */\nfunction printMacElement(el: MacAnalysisElement): void {\n const role = chalk.cyan(el.role);\n const [best] = el.selectors;\n const selectorStr = best ? chalk.yellow(best) : chalk.gray(\"(no selector)\");\n const label = el.title ?? el.description ?? el.value;\n const labelStr = label ? ` ${chalk.gray(`\"${label}\"`)}` : \"\";\n const disabled = el.enabled === false ? chalk.gray(\" (disabled)\") : \"\";\n console.log(` ${role} ${selectorStr}${labelStr}${disabled}`);\n}\n\n/** macOS target: dump interactive elements, windows, and status-menu items with ranked selectors. */\nasync function runMacAnalyze(app: string, config: Config | null, options: Record<string, unknown>): Promise<void> {\n const allowedApps = config?.guardrails.allowedApps ?? [];\n assertTargetAppAllowed(allowedApps, app);\n\n const session = await launchMacSession({ app, timeoutMs: config?.browser.timeout });\n try {\n const result = await analyzeMacApp(session.client, { app: session.bundleId });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`\\n ${chalk.bold(\"App Analysis:\")} ${result.app}\\n`);\n\n if (result.windows.length > 0) {\n console.log(chalk.bold(\" Windows:\"));\n for (const win of result.windows) {\n const title = win.title ? chalk.gray(`\"${win.title}\"`) : chalk.gray(\"(untitled)\");\n console.log(` ${title} ${chalk.yellow(win.selector)}`);\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 printMacElement(el);\n }\n console.log();\n }\n\n if (result.menuItems.length > 0) {\n console.log(chalk.bold(\" Menu Bar:\"));\n for (const el of result.menuItems) {\n printMacElement(el);\n }\n console.log();\n }\n\n console.log(\n chalk.gray(\n ` ${result.elements.length} elements, ${result.windows.length} windows, ${result.menuItems.length} menu items\\n`\n )\n );\n }\n } finally {\n await session.client.close();\n }\n}\n\n/** Print one Android analysis element in the human-readable analyze output. */\nfunction printAndroidElement(el: AndroidAnalysisElement): void {\n const role = chalk.cyan(el.className);\n const [best] = el.selectors;\n const selectorStr = best ? chalk.yellow(best) : chalk.gray(\"(no selector)\");\n const label = el.contentDesc ?? el.text;\n const labelStr = label ? ` ${chalk.gray(`\"${label}\"`)}` : \"\";\n const disabled = el.enabled === false ? chalk.gray(\" (disabled)\") : \"\";\n console.log(` ${role} ${selectorStr}${labelStr}${disabled}`);\n}\n\n/** Android target: dump interactive elements with ranked selectors from the UI hierarchy. */\nasync function runAndroidAnalyze(\n app: string,\n config: Config | null,\n options: Record<string, unknown>,\n deviceSerial?: string\n): Promise<void> {\n const allowedApps = config?.guardrails.allowedApps ?? [];\n // Fail fast on a disallowed package id (mirrors the run path's pre-launch\n // guardrail). For `.apk` paths the launcher performs the thorough check after\n // resolving the package name, so we defer to it there.\n if (!looksLikeApk(app)) {\n assertAndroidAppAllowed(allowedApps, app);\n }\n\n const session = await launchAndroidSession({\n app,\n ...(deviceSerial ? { deviceSerial } : {}),\n timeoutMs: config?.browser.timeout,\n allowedApps\n });\n try {\n const sourceFn = session.client.source;\n if (typeof sourceFn !== \"function\") {\n throw new Error(\n \"The Android agent client does not expose source(); a live uiautomator2 session is required to analyze.\"\n );\n }\n const result = await analyzeAndroidApp(\n { source: () => sourceFn.call(session.client) },\n { app: session.package }\n );\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`\\n ${chalk.bold(\"App Analysis:\")} ${result.app}\\n`);\n\n if (result.elements.length > 0) {\n console.log(chalk.bold(\" Interactive Elements:\"));\n for (const el of result.elements) {\n printAndroidElement(el);\n }\n console.log();\n }\n\n console.log(chalk.gray(` ${result.elements.length} elements\\n`));\n }\n } finally {\n await session.teardown();\n }\n}\n\n/** Print one iOS analysis element in the human-readable analyze output. */\nfunction printIosElement(el: IosAnalysisElement): void {\n const role = chalk.cyan(el.type);\n const [best] = el.selectors;\n const selectorStr = best ? chalk.yellow(best) : chalk.gray(\"(no selector)\");\n const label = el.label ?? el.value ?? el.name;\n const labelStr = label ? ` ${chalk.gray(`\"${label}\"`)}` : \"\";\n const disabled = el.enabled === false ? chalk.gray(\" (disabled)\") : \"\";\n console.log(` ${role} ${selectorStr}${labelStr}${disabled}`);\n}\n\n/** iOS target: dump interactive elements and windows with ranked selectors from the UI hierarchy. */\nasync function runIosAnalyze(\n app: string,\n config: Config | null,\n options: Record<string, unknown>,\n udid?: string\n): Promise<void> {\n const allowedApps = config?.guardrails.allowedApps ?? [];\n // Fail fast on a disallowed bundle id (mirrors the run path's pre-launch\n // guardrail). For `.app` paths the launcher performs the thorough check after\n // reading CFBundleIdentifier, so we defer to it there.\n if (!/\\//.test(app) && !/\\.app$/i.test(app.trim())) {\n assertIosAppAllowed(allowedApps, app);\n }\n\n const session = await launchIosSession({\n app,\n ...(udid ? { udid } : {}),\n timeoutMs: config?.browser.timeout,\n allowedApps\n });\n try {\n const sourceFn = session.client.source;\n if (typeof sourceFn !== \"function\") {\n throw new Error(\n \"The iOS agent client does not expose source(); a live WebDriverAgent session is required to analyze.\"\n );\n }\n const result = await analyzeIosApp(\n { source: () => sourceFn.call(session.client) },\n { app: session.bundleId }\n );\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`\\n ${chalk.bold(\"App Analysis:\")} ${result.app}\\n`);\n\n if (result.windows.length > 0) {\n console.log(chalk.bold(\" Windows:\"));\n for (const win of result.windows) {\n const title = win.label ?? win.name;\n const titleStr = title ? chalk.gray(`\"${title}\"`) : chalk.gray(\"(untitled)\");\n console.log(` ${titleStr} ${chalk.yellow(win.selector)}`);\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 printIosElement(el);\n }\n console.log();\n }\n\n console.log(chalk.gray(` ${result.elements.length} elements, ${result.windows.length} windows\\n`));\n }\n } finally {\n await session.teardown();\n }\n}\n\n/** Route a forced `--app` (or a config native target) to the right native analyzer. */\nasync function runNativeAnalyze(\n platform: NativePlatform,\n app: string,\n config: Config | null,\n options: Record<string, unknown>,\n device: { deviceSerial?: string; udid?: string }\n): Promise<void> {\n if (platform === \"android\") {\n await runAndroidAnalyze(app, config, options, device.deviceSerial);\n return;\n }\n if (platform === \"ios\") {\n await runIosAnalyze(app, config, options, device.udid);\n return;\n }\n await runMacAnalyze(app, config, options);\n}\n\n/** Build the `prowl analyze` command for web URLs and the macOS/Android/iOS targets. */\nexport function buildAnalyzeCommand(): Command {\n const command = new Command(\"analyze\")\n .argument(\"[url]\", \"URL to analyze (web target)\")\n .description(\"Analyze a page or native app to discover interactive elements and selectors\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--app <app>\", \"Native app to analyze: bundle id / package / .app / .apk (macOS, Android, or iOS)\")\n .option(\"--platform <name>\", \"Native platform for --app: macos, android, or ios (else inferred)\")\n .option(\"--device <serial>\", \"Android adb device serial (native Android target)\")\n .option(\"--udid <udid>\", \"iOS simulator UDID (native iOS target)\")\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 | undefined, options) => {\n try {\n if (options.app && url) {\n throw new Error(\"Pass either a URL argument (web) or --app (native), not both.\");\n }\n\n // Explicit --app forces a native target. Config is optional (guardrails/timeout/platform).\n if (options.app) {\n const config = tryLoadConfig(options.config as string | undefined);\n const platform = pickNativePlatform(options.platform as string | undefined, config, options.app as string);\n await runNativeAnalyze(platform, options.app as string, config, options, {\n deviceSerial: options.device as string | undefined,\n udid: options.udid as string | undefined\n });\n return;\n }\n\n // A positional URL always means the web target (byte-identical to the original command).\n if (url) {\n await runWebAnalyze(url, options);\n return;\n }\n\n // No positional and no --app: fall back to the loaded config's target.\n const config = tryLoadConfig(options.config as string | undefined);\n const target: Target | undefined = config?.target;\n if (target?.type === \"macos\") {\n await runMacAnalyze(target.app, config, options);\n return;\n }\n if (target?.type === \"android\") {\n await runAndroidAnalyze(target.app, config, options, (options.device as string | undefined) ?? target.deviceSerial);\n return;\n }\n if (target?.type === \"ios\") {\n await runIosAnalyze(target.app, config, options, (options.udid as string | undefined) ?? target.udid);\n return;\n }\n\n throw new Error(\n \"analyze needs a target: pass a URL for the web target, or use --app \" +\n \"<bundle-id|package|.app|.apk> (optionally with --platform), or set a native target.type \" +\n \"in .prowl/config.yml.\"\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 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 { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { loadConfig } from \"../../config/loader.js\";\nimport { normalizeHuntName } from \"../../config/hunt-name.js\";\nimport { readHuntHistory } from \"../../runner/history.js\";\nimport type { HistoryEntry } from \"../../types/index.js\";\n\n/** Build the `prowl history` command and normalize path-like hunt arguments. */\nexport function buildHistoryCommand(): Command {\n const command = new Command(\"history\")\n .argument(\n \"<hunt-name>\",\n \"Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)\"\n )\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((huntArg: string, options) => {\n const huntName = normalizeHuntName(huntArg);\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","/**\n * PROWL-074 / PROWL-052 — `prowl macdriver` subcommand group: manage the\n * prebuilt, signed macOS helper (`prowl-macdriver`) so the macOS target works\n * without Xcode or a Swift toolchain.\n *\n * prowl macdriver install download + verify + install the pinned helper\n * prowl macdriver status report resolved binary, versions, TCC guidance\n *\n * This is deliberately NOT a general `prowl doctor` (that's PROWL-026); it stays\n * scoped to the macdriver helper.\n */\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { MACDRIVER_VERSION, macdriverReleaseTag } from \"../../browser/macdriver-release.js\";\nimport {\n collectMacdriverStatus,\n installMacdriver,\n tccGuidance\n} from \"../../browser/macdriver-install.js\";\n\nfunction buildInstallCommand(): Command {\n return new Command(\"install\")\n .description(\"Download and install the prebuilt, signed prowl-macdriver helper\")\n .option(\"--force\", \"Reinstall even if the pinned version is already present\")\n .action(async (options: { force?: boolean }) => {\n try {\n console.log(\n chalk.cyan(\n `Installing prowl-macdriver ${MACDRIVER_VERSION} (${macdriverReleaseTag(MACDRIVER_VERSION)})…`\n )\n );\n const result = await installMacdriver({ force: options.force });\n if (result.alreadyInstalled) {\n console.log(\n chalk.green(`Already installed at ${result.binaryPath}`) +\n chalk.dim(\" (use --force to reinstall)\")\n );\n } else {\n console.log(chalk.green(`Installed prowl-macdriver ${result.version} → ${result.binaryPath}`));\n }\n console.log(\"\");\n console.log(tccGuidance());\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Install failed\";\n console.error(chalk.red(`Error: ${message}`));\n process.exitCode = 1;\n }\n });\n}\n\nfunction buildStatusCommand(): Command {\n return new Command(\"status\")\n .description(\"Report the resolved prowl-macdriver binary, installed versions, and permissions guidance\")\n .action(async () => {\n try {\n const status = await collectMacdriverStatus();\n\n console.log(chalk.bold(\"prowl-macdriver status\"));\n console.log(` pinned version: ${status.pinnedVersion}`);\n\n if (status.resolved) {\n const label =\n status.resolved.source === \"env\"\n ? \"PROWL_MACDRIVER_BIN override\"\n : status.resolved.source === \"user-install\"\n ? \"user install (~/.prowl/macdriver)\"\n : \"repo source build (macdriver/.build)\";\n console.log(` resolved binary: ${status.resolved.path}`);\n console.log(` resolved via: ${label}`);\n console.log(\n ` runs: ${\n status.probedVersion\n ? chalk.green(`yes (reports ${status.probedVersion})`)\n : chalk.yellow(\"no (binary did not respond to `version`)\")\n }`\n );\n } else {\n console.log(` resolved binary: ${chalk.yellow(\"none\")}`);\n console.log(chalk.dim(\" search order: PROWL_MACDRIVER_BIN → ~/.prowl/macdriver → macdriver/.build\"));\n console.log(chalk.cyan(\" Run `prowl macdriver install` to install the prebuilt helper.\"));\n }\n\n if (status.installed.length > 0) {\n console.log(\" installed versions:\");\n for (const entry of status.installed) {\n const marker = entry.version === status.pinnedVersion ? chalk.green(\" (pinned)\") : \"\";\n console.log(` - ${entry.version}${marker} ${chalk.dim(entry.binaryPath)}`);\n }\n } else {\n console.log(\" installed versions: none\");\n }\n\n console.log(\"\");\n console.log(tccGuidance());\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Status failed\";\n console.error(chalk.red(`Error: ${message}`));\n process.exitCode = 1;\n }\n });\n}\n\nexport function buildMacdriverCommand(): Command {\n const command = new Command(\"macdriver\").description(\n \"Manage the macOS helper binary (prowl-macdriver) for the macOS target\"\n );\n command.addCommand(buildInstallCommand());\n command.addCommand(buildStatusCommand());\n return command;\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":["Command","chalk","chalk","chalk","Command","chalk","Command","chalk","path","chalk","Command","path","Command","chalk","Command","chalk","Command","chalk","fs","chalk","Command","path","Command","chalk","fs","Command","chalk","chalk","Command","fs","path","Command","chalk","Command","path","fs","chalk","Command","chalk","chalk","Command","config","fs","path","Command","chalk","Command","chalk","loadConfig","path","fs","Command","chalk","Command","chalk","Command","chalk","Command","chalk","formatTable","stripAnsi","pad","Command","z","path","path","fs","path","z","errorMessage","Command","chalk","Command","Command","chalk","program","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/program.ts","../package.json","../src/cli/commands/run.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/cli/commands/update-baselines.ts","../src/cli/commands/analyze.ts","../src/cli/commands/generate.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/commands/macdriver.ts","../src/cli/commands/doctor.ts","../src/doctor/checks.ts","../src/cli/index.ts"],"sourcesContent":["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\";\nimport { buildMacdriverCommand } from \"./commands/macdriver.js\";\nimport { buildDoctorCommand } from \"./commands/doctor.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 program.addCommand(buildMacdriverCommand());\n program.addCommand(buildDoctorCommand());\n\n return program;\n}\n","{\n \"name\": \"prowl-tools\",\n \"version\": \"0.1.9\",\n \"description\": \"E2E testing for native macOS apps and web apps from declarative YAML hunts.\",\n \"type\": \"module\",\n \"license\": \"Apache-2.0\",\n \"author\": \"Prowl Tools\",\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 \"e2e\",\n \"macos\",\n \"desktop-testing\",\n \"accessibility\",\n \"playwright\",\n \"yaml\",\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 \"optionalDependencies\": {\n \"appium-uiautomator2-server\": \"10.6.2\",\n \"appium-webdriveragent\": \"16.4.0\"\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 { normalizeHuntName } from \"../../config/hunt-name.js\";\nimport { printHuntHeader, printStepResult, printHuntSummary } from \"../output.js\";\nimport { resultMascot } from \"../mascot.js\";\n\n/** Build the `prowl run` command and normalize path-like hunt arguments. */\nexport function buildRunCommand(): Command {\n const command = new Command(\"run\")\n .argument(\n \"<hunt-name>\",\n \"Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)\"\n )\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 (huntArg, options) => {\n const huntName = normalizeHuntName(huntArg);\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 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 if (\"assertWithAI\" in step) return `assertWithAI \"${truncate(step.assertWithAI, 60)}\"`;\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 if (result.status === \"warn\") {\n const note = result.value ? chalk.gray(` \\u2014 ${result.value}`) : \"\";\n console.log(` ${chalk.yellow(\"\\u25cb\")} ${label} ${duration}${note}`);\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 os from \"node:os\";\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\ninterface StagedTemplateFile {\n source: string;\n relativePath: string;\n}\n\ninterface DestinationBackup {\n destination: string;\n backup: string;\n}\n\ninterface DestinationRollback {\n prowlDirExisted: boolean;\n backupDir: string;\n backups: DestinationBackup[];\n createdFiles: string[];\n createdDirs: string[];\n}\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\nfunction isInsideDir(parent: string, child: string): boolean {\n const relative = path.relative(parent, child);\n return relative.length > 0 && !relative.startsWith(\"..\") && !path.isAbsolute(relative);\n}\n\nfunction lstatIfExists(target: string): fs.Stats | null {\n try {\n return fs.lstatSync(target);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\" || code === \"ENOTDIR\") {\n return null;\n }\n throw error;\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction assertNoSymlinkDestination(prowlDir: string, destination: string): void {\n const relative = path.relative(prowlDir, destination);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Refusing to write outside ${CONFIG_DIR}: ${destination}`);\n }\n\n const parts = relative.split(path.sep).filter((part) => part.length > 0);\n let current = prowlDir;\n const rootStat = lstatIfExists(current);\n if (rootStat?.isSymbolicLink()) {\n throw new Error(\n `${CONFIG_DIR} scaffold destination path contains a symlink: ${current}. ` +\n `Replace it with a real file or directory before running prowl init --force.`\n );\n }\n if (rootStat && !rootStat.isDirectory()) {\n throw new Error(`${CONFIG_DIR} scaffold path is not a directory: ${current}`);\n }\n\n for (let index = 0; index < parts.length; index += 1) {\n current = path.join(current, parts[index] ?? \"\");\n const stat = lstatIfExists(current);\n if (stat?.isSymbolicLink()) {\n throw new Error(\n `${CONFIG_DIR} scaffold destination path contains a symlink: ${current}. ` +\n `Replace it with a real file or directory before running prowl init --force.`\n );\n }\n if (stat && index < parts.length - 1 && !stat.isDirectory()) {\n throw new Error(`${CONFIG_DIR} scaffold parent path is not a directory: ${current}`);\n }\n }\n}\n\nfunction gitignoreTemplate(): string {\n return [\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}\n\nfunction stageScaffoldTemplates(examplesDir: string): { stageDir: string; files: StagedTemplateFile[] } {\n const stageDir = fs.mkdtempSync(path.join(os.tmpdir(), \"prowl-init-\"));\n const files: StagedTemplateFile[] = [];\n\n try {\n copyFile(path.join(examplesDir, \"config.yml\"), path.join(stageDir, \"config.yml\"));\n files.push({ source: path.join(stageDir, \"config.yml\"), relativePath: \"config.yml\" });\n\n const exampleHuntsDir = path.join(examplesDir, \"hunts\");\n const huntFiles = fs.readdirSync(exampleHuntsDir).filter((f) => f.endsWith(\".yml\"));\n for (const huntFile of huntFiles) {\n const relativePath = path.join(\"hunts\", huntFile);\n copyFile(path.join(exampleHuntsDir, huntFile), path.join(stageDir, relativePath));\n files.push({ source: path.join(stageDir, relativePath), relativePath });\n }\n\n const gitignorePath = path.join(stageDir, \".gitignore\");\n fs.writeFileSync(gitignorePath, gitignoreTemplate());\n files.push({ source: gitignorePath, relativePath: \".gitignore\" });\n\n return { stageDir, files };\n } catch (error) {\n fs.rmSync(stageDir, { recursive: true, force: true });\n throw error;\n }\n}\n\nfunction trackCreatedParentDirs(destination: string, prowlDir: string, createdDirs: Set<string>): void {\n let dir = path.dirname(destination);\n while (isInsideDir(prowlDir, dir) && !fs.existsSync(dir)) {\n createdDirs.add(dir);\n dir = path.dirname(dir);\n }\n}\n\nfunction prepareDestinationRollback(prowlDir: string, files: StagedTemplateFile[]): DestinationRollback {\n const backupDir = fs.mkdtempSync(path.join(os.tmpdir(), \"prowl-init-rollback-\"));\n const backups: DestinationBackup[] = [];\n const createdFiles: string[] = [];\n const createdDirs = new Set<string>();\n const prowlDirExisted = fs.existsSync(prowlDir);\n\n try {\n for (const file of files) {\n const destination = path.join(prowlDir, file.relativePath);\n assertNoSymlinkDestination(prowlDir, destination);\n\n const stat = lstatIfExists(destination);\n if (stat) {\n if (!stat.isFile()) {\n throw new Error(`${CONFIG_DIR} scaffold destination is not a regular file: ${destination}`);\n }\n const backup = path.join(backupDir, file.relativePath);\n copyFile(destination, backup);\n backups.push({ destination, backup });\n } else {\n createdFiles.push(destination);\n }\n\n if (prowlDirExisted) {\n trackCreatedParentDirs(destination, prowlDir, createdDirs);\n }\n }\n\n return {\n prowlDirExisted,\n backupDir,\n backups,\n createdFiles,\n createdDirs: [...createdDirs].sort((a, b) => b.length - a.length)\n };\n } catch (error) {\n fs.rmSync(backupDir, { recursive: true, force: true });\n throw error;\n }\n}\n\nfunction rollbackDestination(prowlDir: string, rollback: DestinationRollback): void {\n if (!rollback.prowlDirExisted) {\n fs.rmSync(prowlDir, { recursive: true, force: true });\n return;\n }\n\n for (const file of rollback.createdFiles) {\n fs.rmSync(file, { force: true });\n }\n for (const backup of rollback.backups) {\n try {\n copyFile(backup.backup, backup.destination);\n } catch (error) {\n throw new Error(\n `Failed to restore ${backup.destination} from backup ${backup.backup}: ${errorMessage(error)}`\n );\n }\n }\n for (const dir of rollback.createdDirs) {\n try {\n fs.rmdirSync(dir);\n } catch {\n // Preserve any user/concurrent files created after rollback tracking.\n }\n }\n}\n\n/**\n * Scaffold a `.prowl/` directory under `root` from the package's bundled\n * `examples/` templates: `config.yml`, the starter hunts, and a `.gitignore`\n * that keeps run artifacts and secrets out of version control. This is the\n * single code path both `prowl init` and `prowl doctor --fix` use so the\n * templates are never duplicated. Throws (rather than exiting) when the bundled\n * examples are missing, so callers can decide how to surface the failure.\n */\nexport function scaffoldProwlDir(root: string): void {\n const prowlDir = path.join(root, CONFIG_DIR);\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 throw new Error(\"Examples not found in package. Reinstall prowl-tools.\");\n }\n\n const staged = stageScaffoldTemplates(examplesDir);\n let rollback: DestinationRollback | null = null;\n let keepBackup = false;\n try {\n rollback = prepareDestinationRollback(prowlDir, staged.files);\n for (const file of staged.files) {\n copyFile(file.source, path.join(prowlDir, file.relativePath));\n }\n } catch (error) {\n if (rollback) {\n try {\n rollbackDestination(prowlDir, rollback);\n } catch (rollbackError) {\n keepBackup = true;\n throw new Error(\n `Scaffold failed: ${errorMessage(error)}. Rollback failed: ${errorMessage(rollbackError)}. ` +\n `Backup preserved at ${rollback.backupDir}.`\n );\n }\n }\n throw error;\n } finally {\n if (rollback && !keepBackup) {\n fs.rmSync(rollback.backupDir, { recursive: true, force: true });\n }\n fs.rmSync(staged.stageDir, { recursive: true, force: true });\n }\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 try {\n scaffoldProwlDir(root);\n } catch (error) {\n console.error(chalk.red(error instanceof Error ? error.message : \"init failed\"));\n process.exitCode = 1;\n return;\n }\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(\" See \") + chalk.cyan(`${CONFIG_DIR}/hunts/login-flow.yml`) + chalk.gray(\" (auth) and \") + chalk.cyan(`${CONFIG_DIR}/hunts/form.yml`) + chalk.gray(\" (web forms) for fuller examples.\"));\n console.log(chalk.gray(\" Desktop-first? \") + chalk.cyan(`${CONFIG_DIR}/hunts/macos-hello.yml`) + chalk.gray(\" is a macOS starter (experimental — see its comments to enable).\") + \"\\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 {\n launchBrowser,\n closeBrowser,\n saveStorageState,\n createPlaywrightDriver,\n type BrowserSession\n} from \"../../browser/controller.js\";\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 session: BrowserSession | null = null;\n try {\n const { config, configDir } = loadConfig(options.config);\n if (config.target.type !== \"web\") {\n throw new Error(\"`prowl login` captures browser auth state and only applies to web targets.\");\n }\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 session = await launchBrowser({\n headless: false,\n slowMo: 0,\n timeout: config.browser.timeout,\n trace: false,\n recordHar: false,\n runDir: configDir\n });\n const driver = createPlaywrightDriver(session.page);\n await driver.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 saveStorageState(session, 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 (session) {\n await closeBrowser(session);\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 { normalizeHuntName } from \"../../config/hunt-name.js\";\nimport { runHunt } from \"../../runner/index.js\";\nimport { createDebouncer, getWatchTargets } from \"../watch-utils.js\";\nimport { printHuntHeader, printStepResult, printHuntSummary } from \"../output.js\";\n\n/** Build the `prowl watch` command and normalize path-like hunt arguments. */\nexport function buildWatchCommand(): Command {\n const command = new Command(\"watch\")\n .argument(\n \"<hunt-name>\",\n \"Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)\"\n )\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 (huntArg, options) => {\n const huntName = normalizeHuntName(huntArg);\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 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 type { BrowserChannel, Config, Target, Viewport } from \"../../types/index.js\";\nimport { launchBrowser, closeBrowser, createPlaywrightDriver } from \"../../browser/controller.js\";\nimport { parseBrowserEngine } from \"../../browser/engines.js\";\nimport { analyzePage } from \"../../analyzer/index.js\";\nimport { analyzeMacApp, type MacAnalysisElement } from \"../../analyzer/mac.js\";\nimport { analyzeAndroidApp, type AndroidAnalysisElement } from \"../../analyzer/android.js\";\nimport { analyzeIosApp, type IosAnalysisElement } from \"../../analyzer/ios.js\";\nimport { launchMacSession } from \"../../browser/mac-helper.js\";\nimport { launchAndroidSession } from \"../../browser/android-helper.js\";\nimport { launchIosSession } from \"../../browser/ios-helper.js\";\nimport {\n assertTargetAppAllowed,\n assertAndroidAppAllowed,\n assertIosAppAllowed\n} from \"../../config/target.js\";\nimport { findConfigPath, loadConfig, resolveViewport } from \"../../config/loader.js\";\n\n/** The three native targets `prowl analyze` supports alongside the web target. */\ntype NativePlatform = \"macos\" | \"android\" | \"ios\";\n\n/** Parse a viewport flag into a named preset or an explicit width/height pair. */\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\n/** Optional config load; returns null only when no default config exists. */\nfunction tryLoadConfig(configPath?: string): Config | null {\n const configLocation = configPath !== undefined\n ? configPath\n : findConfigPath(process.cwd());\n if (configLocation === null) {\n return null;\n }\n\n try {\n return loadConfig(configLocation).config;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown configuration error\";\n throw new Error(`Failed to load config at ${configLocation}: ${message}`);\n }\n}\n\n/** Whether an `--app` value looks like an Android `.apk` (decisive for inference). */\nfunction looksLikeApk(app: string): boolean {\n return /\\.apk$/i.test(app.trim());\n}\n\n/**\n * Decide which native platform a forced `--app` targets. Order: an explicit\n * `--platform` wins; otherwise a loaded config's native `target.type`; otherwise\n * inference from the app value (`.apk` → android, else macOS to preserve the\n * original `--app` = macOS behavior). `.app` paths and bare bundle ids are\n * ambiguous between macOS and iOS, so those default to macOS unless `--platform`\n * or a config says otherwise.\n */\nfunction pickNativePlatform(platformFlag: string | undefined, config: Config | null, app: string): NativePlatform {\n if (platformFlag !== undefined) {\n const normalized = platformFlag.trim().toLowerCase();\n if (normalized === \"macos\" || normalized === \"android\" || normalized === \"ios\") {\n return normalized;\n }\n throw new Error(`Unknown --platform \"${platformFlag}\". Use one of: macos, android, ios.`);\n }\n const configType = config?.target.type;\n if (configType === \"macos\" || configType === \"android\" || configType === \"ios\") {\n return configType;\n }\n return looksLikeApk(app) ? \"android\" : \"macos\";\n}\n\n/** Web target: analyze a page's DOM via Playwright. Behavior is unchanged from the original command. */\nasync function runWebAnalyze(url: string, options: Record<string, unknown>): Promise<void> {\n const engine = parseBrowserEngine(options.browser as string | undefined);\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 session = await launchBrowser({\n headless: !options.headed,\n slowMo: 0,\n timeout: 30000,\n trace: false,\n recordHar: false,\n runDir: process.cwd(),\n engine,\n channel,\n viewport\n });\n const driver = createPlaywrightDriver(session.page);\n\n try {\n await driver.goto(url, { waitUntil: \"networkidle\" });\n const result = await analyzePage(driver);\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 closeBrowser(session);\n }\n}\n\n/** Print one macOS analysis element in the human-readable analyze output. */\nfunction printMacElement(el: MacAnalysisElement): void {\n const role = chalk.cyan(el.role);\n const [best] = el.selectors;\n const selectorStr = best ? chalk.yellow(best) : chalk.gray(\"(no selector)\");\n const label = el.title ?? el.description ?? el.value;\n const labelStr = label ? ` ${chalk.gray(`\"${label}\"`)}` : \"\";\n const disabled = el.enabled === false ? chalk.gray(\" (disabled)\") : \"\";\n console.log(` ${role} ${selectorStr}${labelStr}${disabled}`);\n}\n\n/** macOS target: dump interactive elements, windows, and status-menu items with ranked selectors. */\nasync function runMacAnalyze(app: string, config: Config | null, options: Record<string, unknown>): Promise<void> {\n const allowedApps = config?.guardrails.allowedApps ?? [];\n assertTargetAppAllowed(allowedApps, app);\n\n const session = await launchMacSession({ app, timeoutMs: config?.browser.timeout });\n try {\n const result = await analyzeMacApp(session.client, { app: session.bundleId });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`\\n ${chalk.bold(\"App Analysis:\")} ${result.app}\\n`);\n\n if (result.windows.length > 0) {\n console.log(chalk.bold(\" Windows:\"));\n for (const win of result.windows) {\n const title = win.title ? chalk.gray(`\"${win.title}\"`) : chalk.gray(\"(untitled)\");\n console.log(` ${title} ${chalk.yellow(win.selector)}`);\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 printMacElement(el);\n }\n console.log();\n }\n\n if (result.menuItems.length > 0) {\n console.log(chalk.bold(\" Menu Bar:\"));\n for (const el of result.menuItems) {\n printMacElement(el);\n }\n console.log();\n }\n\n console.log(\n chalk.gray(\n ` ${result.elements.length} elements, ${result.windows.length} windows, ${result.menuItems.length} menu items\\n`\n )\n );\n }\n } finally {\n await session.client.close();\n }\n}\n\n/** Print one Android analysis element in the human-readable analyze output. */\nfunction printAndroidElement(el: AndroidAnalysisElement): void {\n const role = chalk.cyan(el.className);\n const [best] = el.selectors;\n const selectorStr = best ? chalk.yellow(best) : chalk.gray(\"(no selector)\");\n const label = el.contentDesc ?? el.text;\n const labelStr = label ? ` ${chalk.gray(`\"${label}\"`)}` : \"\";\n const disabled = el.enabled === false ? chalk.gray(\" (disabled)\") : \"\";\n console.log(` ${role} ${selectorStr}${labelStr}${disabled}`);\n}\n\n/** Android target: dump interactive elements with ranked selectors from the UI hierarchy. */\nasync function runAndroidAnalyze(\n app: string,\n config: Config | null,\n options: Record<string, unknown>,\n deviceSerial?: string\n): Promise<void> {\n const allowedApps = config?.guardrails.allowedApps ?? [];\n // Fail fast on a disallowed package id (mirrors the run path's pre-launch\n // guardrail). For `.apk` paths the launcher performs the thorough check after\n // resolving the package name, so we defer to it there.\n if (!looksLikeApk(app)) {\n assertAndroidAppAllowed(allowedApps, app);\n }\n\n const session = await launchAndroidSession({\n app,\n ...(deviceSerial ? { deviceSerial } : {}),\n timeoutMs: config?.browser.timeout,\n allowedApps\n });\n try {\n const sourceFn = session.client.source;\n if (typeof sourceFn !== \"function\") {\n throw new Error(\n \"The Android agent client does not expose source(); a live uiautomator2 session is required to analyze.\"\n );\n }\n const result = await analyzeAndroidApp(\n { source: () => sourceFn.call(session.client) },\n { app: session.package }\n );\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`\\n ${chalk.bold(\"App Analysis:\")} ${result.app}\\n`);\n\n if (result.elements.length > 0) {\n console.log(chalk.bold(\" Interactive Elements:\"));\n for (const el of result.elements) {\n printAndroidElement(el);\n }\n console.log();\n }\n\n console.log(chalk.gray(` ${result.elements.length} elements\\n`));\n }\n } finally {\n await session.teardown();\n }\n}\n\n/** Print one iOS analysis element in the human-readable analyze output. */\nfunction printIosElement(el: IosAnalysisElement): void {\n const role = chalk.cyan(el.type);\n const [best] = el.selectors;\n const selectorStr = best ? chalk.yellow(best) : chalk.gray(\"(no selector)\");\n const label = el.label ?? el.value ?? el.name;\n const labelStr = label ? ` ${chalk.gray(`\"${label}\"`)}` : \"\";\n const disabled = el.enabled === false ? chalk.gray(\" (disabled)\") : \"\";\n console.log(` ${role} ${selectorStr}${labelStr}${disabled}`);\n}\n\n/** iOS target: dump interactive elements and windows with ranked selectors from the UI hierarchy. */\nasync function runIosAnalyze(\n app: string,\n config: Config | null,\n options: Record<string, unknown>,\n udid?: string\n): Promise<void> {\n const allowedApps = config?.guardrails.allowedApps ?? [];\n // Fail fast on a disallowed bundle id (mirrors the run path's pre-launch\n // guardrail). For `.app` paths the launcher performs the thorough check after\n // reading CFBundleIdentifier, so we defer to it there.\n if (!/\\//.test(app) && !/\\.app$/i.test(app.trim())) {\n assertIosAppAllowed(allowedApps, app);\n }\n\n const session = await launchIosSession({\n app,\n ...(udid ? { udid } : {}),\n timeoutMs: config?.browser.timeout,\n allowedApps\n });\n try {\n const sourceFn = session.client.source;\n if (typeof sourceFn !== \"function\") {\n throw new Error(\n \"The iOS agent client does not expose source(); a live WebDriverAgent session is required to analyze.\"\n );\n }\n const result = await analyzeIosApp(\n { source: () => sourceFn.call(session.client) },\n { app: session.bundleId }\n );\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`\\n ${chalk.bold(\"App Analysis:\")} ${result.app}\\n`);\n\n if (result.windows.length > 0) {\n console.log(chalk.bold(\" Windows:\"));\n for (const win of result.windows) {\n const title = win.label ?? win.name;\n const titleStr = title ? chalk.gray(`\"${title}\"`) : chalk.gray(\"(untitled)\");\n console.log(` ${titleStr} ${chalk.yellow(win.selector)}`);\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 printIosElement(el);\n }\n console.log();\n }\n\n console.log(chalk.gray(` ${result.elements.length} elements, ${result.windows.length} windows\\n`));\n }\n } finally {\n await session.teardown();\n }\n}\n\n/** Route a forced `--app` (or a config native target) to the right native analyzer. */\nasync function runNativeAnalyze(\n platform: NativePlatform,\n app: string,\n config: Config | null,\n options: Record<string, unknown>,\n device: { deviceSerial?: string; udid?: string }\n): Promise<void> {\n if (platform === \"android\") {\n await runAndroidAnalyze(app, config, options, device.deviceSerial);\n return;\n }\n if (platform === \"ios\") {\n await runIosAnalyze(app, config, options, device.udid);\n return;\n }\n await runMacAnalyze(app, config, options);\n}\n\n/** Build the `prowl analyze` command for web URLs and the macOS/Android/iOS targets. */\nexport function buildAnalyzeCommand(): Command {\n const command = new Command(\"analyze\")\n .argument(\"[url]\", \"URL to analyze (web target)\")\n .description(\"Analyze a page or native app to discover interactive elements and selectors\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--app <app>\", \"Native app to analyze: bundle id / package / .app / .apk (macOS, Android, or iOS)\")\n .option(\"--platform <name>\", \"Native platform for --app: macos, android, or ios (else inferred)\")\n .option(\"--device <serial>\", \"Android adb device serial (native Android target)\")\n .option(\"--udid <udid>\", \"iOS simulator UDID (native iOS target)\")\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 | undefined, options) => {\n try {\n if (options.app && url) {\n throw new Error(\"Pass either a URL argument (web) or --app (native), not both.\");\n }\n\n // Explicit --app forces a native target. Config is optional (guardrails/timeout/platform).\n if (options.app) {\n const config = tryLoadConfig(options.config as string | undefined);\n const platform = pickNativePlatform(options.platform as string | undefined, config, options.app as string);\n await runNativeAnalyze(platform, options.app as string, config, options, {\n deviceSerial: options.device as string | undefined,\n udid: options.udid as string | undefined\n });\n return;\n }\n\n // A positional URL always means the web target (byte-identical to the original command).\n if (url) {\n await runWebAnalyze(url, options);\n return;\n }\n\n // No positional and no --app: fall back to the loaded config's target.\n const config = tryLoadConfig(options.config as string | undefined);\n const target: Target | undefined = config?.target;\n if (target?.type === \"macos\") {\n await runMacAnalyze(target.app, config, options);\n return;\n }\n if (target?.type === \"android\") {\n await runAndroidAnalyze(target.app, config, options, (options.device as string | undefined) ?? target.deviceSerial);\n return;\n }\n if (target?.type === \"ios\") {\n await runIosAnalyze(target.app, config, options, (options.udid as string | undefined) ?? target.udid);\n return;\n }\n\n throw new Error(\n \"analyze needs a target: pass a URL for the web target, or use --app \" +\n \"<bundle-id|package|.app|.apk> (optionally with --platform), or set a native target.type \" +\n \"in .prowl/config.yml.\"\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 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 { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { loadConfig } from \"../../config/loader.js\";\nimport { normalizeHuntName } from \"../../config/hunt-name.js\";\nimport { readHuntHistory } from \"../../runner/history.js\";\nimport type { HistoryEntry } from \"../../types/index.js\";\n\n/** Build the `prowl history` command and normalize path-like hunt arguments. */\nexport function buildHistoryCommand(): Command {\n const command = new Command(\"history\")\n .argument(\n \"<hunt-name>\",\n \"Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)\"\n )\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((huntArg: string, options) => {\n const huntName = normalizeHuntName(huntArg);\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","/**\n * PROWL-074 / PROWL-052 — `prowl macdriver` subcommand group: manage the\n * prebuilt, signed macOS helper (`prowl-macdriver`) so the macOS target works\n * without Xcode or a Swift toolchain.\n *\n * prowl macdriver install download + verify + install the pinned helper\n * prowl macdriver status report resolved binary, versions, TCC guidance\n *\n * This is deliberately NOT a general `prowl doctor` (that's PROWL-026); it stays\n * scoped to the macdriver helper.\n */\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { MACDRIVER_VERSION, macdriverReleaseTag } from \"../../browser/macdriver-release.js\";\nimport {\n collectMacdriverStatus,\n installMacdriver,\n tccGuidance\n} from \"../../browser/macdriver-install.js\";\n\nfunction buildInstallCommand(): Command {\n return new Command(\"install\")\n .description(\"Download and install the prebuilt, signed prowl-macdriver helper\")\n .option(\"--force\", \"Reinstall even if the pinned version is already present\")\n .action(async (options: { force?: boolean }) => {\n try {\n console.log(\n chalk.cyan(\n `Installing prowl-macdriver ${MACDRIVER_VERSION} (${macdriverReleaseTag(MACDRIVER_VERSION)})…`\n )\n );\n const result = await installMacdriver({ force: options.force });\n if (result.alreadyInstalled) {\n console.log(\n chalk.green(`Already installed at ${result.binaryPath}`) +\n chalk.dim(\" (use --force to reinstall)\")\n );\n } else {\n console.log(chalk.green(`Installed prowl-macdriver ${result.version} → ${result.binaryPath}`));\n }\n console.log(\"\");\n console.log(tccGuidance());\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Install failed\";\n console.error(chalk.red(`Error: ${message}`));\n process.exitCode = 1;\n }\n });\n}\n\nfunction buildStatusCommand(): Command {\n return new Command(\"status\")\n .description(\"Report the resolved prowl-macdriver binary, installed versions, and permissions guidance\")\n .action(async () => {\n try {\n const status = await collectMacdriverStatus();\n\n console.log(chalk.bold(\"prowl-macdriver status\"));\n console.log(` pinned version: ${status.pinnedVersion}`);\n\n if (status.resolved) {\n const label =\n status.resolved.source === \"env\"\n ? \"PROWL_MACDRIVER_BIN override\"\n : status.resolved.source === \"user-install\"\n ? \"user install (~/.prowl/macdriver)\"\n : \"repo source build (macdriver/.build)\";\n console.log(` resolved binary: ${status.resolved.path}`);\n console.log(` resolved via: ${label}`);\n console.log(\n ` runs: ${\n status.probedVersion\n ? chalk.green(`yes (reports ${status.probedVersion})`)\n : chalk.yellow(\"no (binary did not respond to `version`)\")\n }`\n );\n } else {\n console.log(` resolved binary: ${chalk.yellow(\"none\")}`);\n console.log(chalk.dim(\" search order: PROWL_MACDRIVER_BIN → ~/.prowl/macdriver → macdriver/.build\"));\n console.log(chalk.cyan(\" Run `prowl macdriver install` to install the prebuilt helper.\"));\n }\n\n if (status.installed.length > 0) {\n console.log(\" installed versions:\");\n for (const entry of status.installed) {\n const marker = entry.version === status.pinnedVersion ? chalk.green(\" (pinned)\") : \"\";\n console.log(` - ${entry.version}${marker} ${chalk.dim(entry.binaryPath)}`);\n }\n } else {\n console.log(\" installed versions: none\");\n }\n\n console.log(\"\");\n console.log(tccGuidance());\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Status failed\";\n console.error(chalk.red(`Error: ${message}`));\n process.exitCode = 1;\n }\n });\n}\n\nexport function buildMacdriverCommand(): Command {\n const command = new Command(\"macdriver\").description(\n \"Manage the macOS helper binary (prowl-macdriver) for the macOS target\"\n );\n command.addCommand(buildInstallCommand());\n command.addCommand(buildStatusCommand());\n return command;\n}\n","/**\n * PROWL-026 / P6-003 — `prowl doctor`: check that the environment is set up to\n * run Prowl hunts, and (`--fix`) attempt the two safe auto-repairs.\n *\n * All the logic and every side effect live behind the injectable seam in\n * `../../doctor/checks.js`; this file only wires the command up and renders the\n * results. Output is color-coded (green ✓ / red ✗ / yellow ⚠ / gray ○) with a\n * one-line summary; the exit code is 1 when any check failed (warnings are OK).\n */\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport {\n runDoctor,\n defaultDoctorDeps,\n type CheckResult,\n type CheckStatus,\n type DoctorDeps,\n type DoctorReport\n} from \"../../doctor/checks.js\";\n\nfunction symbol(status: CheckStatus): string {\n switch (status) {\n case \"pass\":\n return chalk.green(\"✓\"); // ✓\n case \"fail\":\n return chalk.red(\"✗\"); // ✗\n case \"warn\":\n return chalk.yellow(\"⚠\"); // ⚠\n case \"skip\":\n return chalk.gray(\"○\"); // ○\n }\n}\n\nfunction renderResult(result: CheckResult): void {\n console.log(` ${symbol(result.status)} ${chalk.bold(result.name)}`);\n console.log(` ${chalk.gray(result.message)}`);\n}\n\nfunction renderReport(report: DoctorReport, fixRequested: boolean): void {\n console.log(chalk.bold(\"\\nprowl doctor\\n\"));\n\n for (const result of report.results) {\n renderResult(result);\n }\n\n if (fixRequested) {\n console.log(\"\");\n if (report.fixes.length === 0) {\n console.log(chalk.gray(\" No auto-fixable issues to repair.\"));\n } else {\n console.log(chalk.bold(\" Attempted fixes:\"));\n for (const fix of report.fixes) {\n if (fix.error) {\n console.log(` ${chalk.red(\"✗\")} ${fix.name} — ${chalk.gray(fix.error)}`);\n } else {\n console.log(` ${chalk.green(\"✓\")} ${fix.name}`);\n }\n }\n }\n }\n\n const counts = { pass: 0, warn: 0, fail: 0, skip: 0 };\n for (const result of report.results) {\n counts[result.status] += 1;\n }\n\n const parts = [\n chalk.green(`${counts.pass} passed`),\n counts.warn > 0 ? chalk.yellow(`${counts.warn} warning${counts.warn === 1 ? \"\" : \"s\"}`) : null,\n counts.fail > 0 ? chalk.red(`${counts.fail} failed`) : null,\n counts.skip > 0 ? chalk.gray(`${counts.skip} skipped`) : null\n ].filter((part): part is string => part !== null);\n\n console.log(\"\\n \" + parts.join(chalk.gray(\", \")));\n\n if (counts.fail > 0) {\n console.log(chalk.red.bold(\" Environment has problems — fix the failures above, then re-run `prowl doctor`.\\n\"));\n } else if (counts.warn > 0) {\n console.log(chalk.yellow.bold(\" Environment is usable, with warnings.\\n\"));\n } else {\n console.log(chalk.green.bold(\" Environment is healthy.\\n\"));\n }\n}\n\nexport function buildDoctorCommand(deps: DoctorDeps = defaultDoctorDeps()): Command {\n return new Command(\"doctor\")\n .description(\"Check that your environment is set up to run Prowl hunts\")\n .option(\"--fix\", \"Attempt safe auto-repairs: install Chromium and scaffold a missing .prowl/\")\n .action(async (options: { fix?: boolean }) => {\n try {\n const report = await runDoctor(deps, { fix: options.fix });\n renderReport(report, Boolean(options.fix));\n if (!report.ok) {\n process.exitCode = 1;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"doctor failed\";\n console.error(chalk.red(`Error: ${message}\\nRe-run \\`prowl doctor\\`; if it fails again, report the error.`));\n process.exitCode = 1;\n }\n });\n}\n","/**\n * PROWL-026 / P6-003 — `prowl doctor` environment health check.\n *\n * The checks are pure functions over an injected {@link DoctorDeps} seam (Node\n * version, platform, cwd, env, a Playwright probe, a command runner, config\n * loading, macdriver status, and the two `--fix` repairs). Nothing here touches\n * the real system unless {@link defaultDoctorDeps} wires in the real\n * implementations, so Vitest can drive every pass/fail/warn/skip/fix path\n * without a real Node, browser, config, or native toolchain.\n *\n * A check is `{ name, status, message, fixable }`:\n * - `pass` (green ✓) — healthy.\n * - `warn` (yellow ⚠) — non-blocking; a hunt can still run (e.g. no `.prowl/`\n * yet, which `prowl init` creates on demand).\n * - `fail` (red ✗) — breaks runs; drives the exit code to 1.\n * - `skip` (gray ○) — not applicable / a prerequisite check already failed.\n *\n * Only two repairs are ever attempted by `--fix`: installing Chromium and\n * scaffolding `.prowl/` via the same code path `prowl init` uses. Every other\n * failing check prints its manual remedy. System tools are never installed.\n */\nimport { execFile } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport type { Config } from \"../types/index.js\";\nimport { loadConfig as loadProwlConfig, CONFIG_DIR } from \"../config/loader.js\";\nimport { collectMacdriverStatus, type MacdriverStatus } from \"../browser/macdriver-install.js\";\nimport { scaffoldProwlDir } from \"../cli/commands/init.js\";\n\nconst execFileAsync = promisify(execFile);\n\n/** Minimum supported Node.js major version. */\nexport const MIN_NODE_MAJOR = 20;\n\n/** Stable check names — also used to route `--fix` repairs to the right check. */\nexport const CHECK_NODE = \"Node.js version\";\nexport const CHECK_PLAYWRIGHT = \"Playwright installed\";\nexport const CHECK_CHROMIUM = \"Chromium browser\";\nexport const CHECK_PROWL_DIR = \".prowl/ directory\";\nexport const CHECK_CONFIG = \"config.yml valid\";\nexport const CHECK_MACOS = \"macOS helper (prowl-macdriver)\";\nexport const CHECK_IOS = \"iOS tooling (xcrun simctl)\";\nexport const CHECK_ANDROID = \"Android tooling (adb)\";\nexport const INSTALL_CHROMIUM_TIMEOUT_MS = 300000;\n\nexport type CheckStatus = \"pass\" | \"fail\" | \"warn\" | \"skip\";\n\nexport interface CheckResult {\n name: string;\n status: CheckStatus;\n message: string;\n /** Whether `prowl doctor --fix` can repair this failing/warning check. */\n fixable: boolean;\n}\n\n/** Result of probing whether Playwright and its Chromium browser are present. */\nexport interface PlaywrightProbeResult {\n playwrightInstalled: boolean;\n chromiumPath: string | null;\n chromiumInstalled: boolean;\n}\n\nexport interface CommandResult {\n stdout?: string | Buffer;\n stderr?: string | Buffer;\n}\n\n/** A command runner used for cheap tool-reachability probes (xcrun, adb). */\nexport type CommandRunner = (file: string, args: string[]) => Promise<CommandResult>;\n\n/** Every side effect `prowl doctor` performs, injectable for tests. */\nexport interface DoctorDeps {\n nodeVersion: string;\n platform: NodeJS.Platform;\n cwd: string;\n env: NodeJS.ProcessEnv;\n probePlaywright: () => Promise<PlaywrightProbeResult>;\n runCommand: CommandRunner;\n prowlDirExists: (cwd: string) => boolean;\n loadConfig: () => { config: Config };\n collectMacdriverStatus: (options?: { env?: NodeJS.ProcessEnv }) => Promise<MacdriverStatus>;\n /** `--fix`: install Chromium with Prowl's resolved Playwright dependency. */\n installChromium: () => Promise<void>;\n /** `--fix`: scaffold `.prowl/` via the same code path `prowl init` uses. */\n scaffoldProwlDir: (cwd: string) => void;\n}\n\nexport interface FixOutcome {\n name: string;\n error?: string;\n}\n\nexport interface DoctorReport {\n results: CheckResult[];\n fixes: FixOutcome[];\n /** True when no check failed (warnings are acceptable). */\n ok: boolean;\n}\n\nfunction nodeMajor(version: string): number {\n const cleaned = version.startsWith(\"v\") ? version.slice(1) : version;\n return Number.parseInt(cleaned.split(\".\")[0] ?? \"\", 10);\n}\n\nexport function checkNode(nodeVersion: string): CheckResult {\n const major = nodeMajor(nodeVersion);\n if (Number.isFinite(major) && major >= MIN_NODE_MAJOR) {\n return {\n name: CHECK_NODE,\n status: \"pass\",\n message: `Node ${nodeVersion} (>= ${MIN_NODE_MAJOR} required)`,\n fixable: false\n };\n }\n return {\n name: CHECK_NODE,\n status: \"fail\",\n message:\n `Node ${nodeVersion} is too old — Prowl needs Node >= ${MIN_NODE_MAJOR}. ` +\n \"Upgrade with nvm (`nvm install 20`), Homebrew (`brew install node`), or nodejs.org.\",\n fixable: false\n };\n}\n\nexport function checkPlaywright(probe: PlaywrightProbeResult): CheckResult {\n if (probe.playwrightInstalled) {\n return { name: CHECK_PLAYWRIGHT, status: \"pass\", message: \"Playwright is installed\", fixable: false };\n }\n return {\n name: CHECK_PLAYWRIGHT,\n status: \"fail\",\n message:\n \"Playwright is not installed. It ships as a dependency of prowl-tools — reinstall with \" +\n \"`npm install` (local) or `npm install -g prowl-tools` (global).\",\n fixable: false\n };\n}\n\nexport function checkChromium(probe: PlaywrightProbeResult): CheckResult {\n if (!probe.playwrightInstalled) {\n return {\n name: CHECK_CHROMIUM,\n status: \"skip\",\n message: \"Skipped — Playwright is not installed\",\n fixable: false\n };\n }\n if (probe.chromiumInstalled) {\n return {\n name: CHECK_CHROMIUM,\n status: \"pass\",\n message: `Chromium is available${probe.chromiumPath ? ` (${probe.chromiumPath})` : \"\"}`,\n fixable: false\n };\n }\n return {\n name: CHECK_CHROMIUM,\n status: \"fail\",\n message:\n \"Chromium is not installed. Run `npx playwright install chromium` \" +\n \"(or `prowl doctor --fix`).\",\n fixable: true\n };\n}\n\nexport function checkProwlDir(exists: boolean): CheckResult {\n if (exists) {\n return { name: CHECK_PROWL_DIR, status: \"pass\", message: `${CONFIG_DIR}/ exists`, fixable: false };\n }\n return {\n name: CHECK_PROWL_DIR,\n status: \"warn\",\n message:\n `No ${CONFIG_DIR}/ directory here. Run \\`prowl init\\` (or \\`prowl doctor --fix\\`) ` +\n \"to scaffold config and starter hunts.\",\n fixable: true\n };\n}\n\nexport function checkConfig(\n prowlDirExists: boolean,\n loadConfig: () => { config: Config }\n): { result: CheckResult; config: Config | null } {\n if (!prowlDirExists) {\n return {\n result: {\n name: CHECK_CONFIG,\n status: \"skip\",\n message: `Skipped — no ${CONFIG_DIR}/ directory`,\n fixable: false\n },\n config: null\n };\n }\n try {\n const { config } = loadConfig();\n return {\n result: {\n name: CHECK_CONFIG,\n status: \"pass\",\n message: `Valid (target: ${config.target.type})`,\n fixable: false\n },\n config\n };\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n return {\n result: {\n name: CHECK_CONFIG,\n status: \"fail\",\n message: `Invalid config: ${detail}`,\n fixable: false\n },\n config: null\n };\n }\n}\n\ntype MacdriverSource = \"env\" | \"user-install\" | \"source-build\";\n\nfunction macdriverSourceLabel(source: MacdriverSource): string {\n switch (source) {\n case \"env\":\n return \"PROWL_MACDRIVER_BIN override\";\n case \"user-install\":\n return \"user install (~/.prowl/macdriver)\";\n case \"source-build\":\n return \"repo source build\";\n }\n}\n\nexport async function checkMacTarget(\n collect: DoctorDeps[\"collectMacdriverStatus\"],\n env: NodeJS.ProcessEnv\n): Promise<CheckResult> {\n let status: MacdriverStatus;\n try {\n status = await collect({ env });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n return {\n name: CHECK_MACOS,\n status: \"fail\",\n message: `Could not inspect prowl-macdriver status (${detail}). Run \\`prowl macdriver status\\` for details.`,\n fixable: false\n };\n }\n\n if (status.resolved && status.probedVersion) {\n return {\n name: CHECK_MACOS,\n status: \"pass\",\n message:\n `Resolved via ${macdriverSourceLabel(status.resolved.source)}: ${status.resolved.path} ` +\n `(reports ${status.probedVersion}). ` +\n \"Verify Accessibility/Screen Recording permissions with `prowl macdriver status`.\",\n fixable: false\n };\n }\n if (status.resolved) {\n return {\n name: CHECK_MACOS,\n status: \"fail\",\n message:\n `prowl-macdriver resolved via ${macdriverSourceLabel(status.resolved.source)} ` +\n `(${status.resolved.path}), but the helper version probe failed. ` +\n \"Run `prowl macdriver status` for details.\",\n fixable: false\n };\n }\n return {\n name: CHECK_MACOS,\n status: \"fail\",\n message:\n \"prowl-macdriver helper not found. Install it with `prowl macdriver install`, \" +\n \"then check permissions with `prowl macdriver status`.\",\n fixable: false\n };\n}\n\nexport async function checkIosTarget(\n platform: NodeJS.Platform,\n run: CommandRunner\n): Promise<CheckResult> {\n if (platform !== \"darwin\") {\n return {\n name: CHECK_IOS,\n status: \"fail\",\n message: `The iOS target requires macOS; xcrun simctl is unavailable on ${platform}.`,\n fixable: false\n };\n }\n try {\n await run(\"xcrun\", [\"simctl\", \"help\"]);\n return { name: CHECK_IOS, status: \"pass\", message: \"xcrun simctl is reachable\", fixable: false };\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n return {\n name: CHECK_IOS,\n status: \"fail\",\n message:\n `xcrun simctl is not reachable (${detail}). Install Xcode and its command-line tools ` +\n \"(`xcode-select --install`), then open Xcode once to finish setup.\",\n fixable: false\n };\n }\n}\n\nexport async function checkAndroidTarget(run: CommandRunner): Promise<CheckResult> {\n try {\n await run(\"adb\", [\"version\"]);\n return { name: CHECK_ANDROID, status: \"pass\", message: \"adb is reachable\", fixable: false };\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n return {\n name: CHECK_ANDROID,\n status: \"fail\",\n message:\n `adb is not reachable (${detail}). Install Android platform-tools and add it to your PATH ` +\n \"(e.g. `brew install --cask android-platform-tools`, or via Android Studio's SDK Manager).\",\n fixable: false\n };\n }\n}\n\n/** Run every applicable check once and return the results in display order. */\nexport async function runDoctorChecks(deps: DoctorDeps): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n const probe = await deps.probePlaywright();\n results.push(checkNode(deps.nodeVersion));\n results.push(checkPlaywright(probe));\n results.push(checkChromium(probe));\n\n const prowlExists = deps.prowlDirExists(deps.cwd);\n results.push(checkProwlDir(prowlExists));\n\n const { result: configResult, config } = checkConfig(prowlExists, deps.loadConfig);\n results.push(configResult);\n\n // Target-aware checks run only for a valid config, and only for the\n // configured target (desktop-first: macOS is checked in depth; the web\n // target needs nothing beyond the core checks above).\n if (config) {\n switch (config.target.type) {\n case \"macos\":\n results.push(await checkMacTarget(deps.collectMacdriverStatus, deps.env));\n break;\n case \"ios\":\n results.push(await checkIosTarget(deps.platform, deps.runCommand));\n break;\n case \"android\":\n results.push(await checkAndroidTarget(deps.runCommand));\n break;\n default:\n break;\n }\n }\n\n return results;\n}\n\n/**\n * Run the checks, optionally apply the two safe `--fix` repairs to fixable\n * non-passing checks, then re-run every check so the report reflects the\n * post-fix state. Exit-worthiness (`ok`) is decided on the final results.\n */\nexport async function runDoctor(\n deps: DoctorDeps,\n options: { fix?: boolean } = {}\n): Promise<DoctorReport> {\n let results = await runDoctorChecks(deps);\n const fixes: FixOutcome[] = [];\n\n if (options.fix) {\n for (const result of results) {\n if (!result.fixable || result.status === \"pass\" || result.status === \"skip\") {\n continue;\n }\n try {\n if (result.name === CHECK_CHROMIUM) {\n await deps.installChromium();\n fixes.push({ name: result.name });\n } else if (result.name === CHECK_PROWL_DIR) {\n deps.scaffoldProwlDir(deps.cwd);\n fixes.push({ name: result.name });\n }\n } catch (error) {\n fixes.push({\n name: result.name,\n error: error instanceof Error ? error.message : String(error)\n });\n }\n }\n\n if (fixes.length > 0) {\n results = await runDoctorChecks(deps);\n }\n }\n\n const ok = !results.some((result) => result.status === \"fail\");\n return { results, fixes, ok };\n}\n\nasync function defaultProbePlaywright(): Promise<PlaywrightProbeResult> {\n try {\n const pw = await import(\"playwright\");\n let chromiumPath: string | null = null;\n try {\n chromiumPath = pw.chromium.executablePath();\n } catch {\n chromiumPath = null;\n }\n const chromiumInstalled = chromiumPath ? fs.existsSync(chromiumPath) : false;\n return { playwrightInstalled: true, chromiumPath, chromiumInstalled };\n } catch {\n return { playwrightInstalled: false, chromiumPath: null, chromiumInstalled: false };\n }\n}\n\nconst defaultRunCommand: CommandRunner = async (file, args) =>\n execFileAsync(file, args, { timeout: 5000 }) as Promise<CommandResult>;\n\nfunction createLocalRequire(): NodeRequire {\n if (typeof __filename === \"string\") {\n return createRequire(__filename);\n }\n return createRequire(import.meta.url);\n}\n\nexport function resolvePlaywrightCliPath(requireFn: NodeRequire = createLocalRequire()): string {\n return path.join(path.dirname(requireFn.resolve(\"playwright/package.json\")), \"cli.js\");\n}\n\nexport function playwrightInstallChromiumCommand(): { file: string; args: string[] } {\n return {\n file: process.execPath,\n args: [resolvePlaywrightCliPath(), \"install\", \"chromium\"]\n };\n}\n\nasync function defaultInstallChromium(): Promise<void> {\n const command = playwrightInstallChromiumCommand();\n // Five-minute ceiling: a first-time Chromium download can be large.\n await execFileAsync(command.file, command.args, { timeout: INSTALL_CHROMIUM_TIMEOUT_MS });\n}\n\n/** Real implementations of every seam, for production use. */\nexport function defaultDoctorDeps(): DoctorDeps {\n return {\n nodeVersion: process.versions.node,\n platform: process.platform,\n cwd: process.cwd(),\n env: process.env,\n probePlaywright: defaultProbePlaywright,\n runCommand: defaultRunCommand,\n prowlDirExists: (cwd) => fs.existsSync(path.join(cwd, CONFIG_DIR)),\n loadConfig: () => loadProwlConfig(),\n collectMacdriverStatus,\n installChromium: defaultInstallChromium,\n scaffoldProwlDir\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":["Command","chalk","chalk","chalk","Command","chalk","Command","chalk","path","chalk","Command","path","Command","chalk","Command","chalk","Command","chalk","fs","chalk","Command","path","Command","chalk","fs","Command","chalk","chalk","Command","fs","path","Command","chalk","Command","path","fs","chalk","Command","chalk","chalk","Command","config","fs","path","Command","chalk","Command","chalk","loadConfig","path","fs","Command","chalk","Command","chalk","Command","chalk","Command","chalk","formatTable","stripAnsi","pad","Command","z","path","path","fs","os","path","errorMessage","z","errorMessage","Command","chalk","Command","Command","chalk","chalk","Command","fs","path","loadConfig","fs","path","chalk","Command","program","Command"]}
|