prowl-tools 0.1.3 → 0.1.4

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/LICENSE CHANGED
@@ -175,7 +175,7 @@
175
175
 
176
176
  END OF TERMS AND CONDITIONS
177
177
 
178
- Copyright 2026 Michael Tookes
178
+ Copyright 2026 Genkei Labs
179
179
 
180
180
  Licensed under the Apache License, Version 2.0 (the "License");
181
181
  you may not use this file except in compliance with the License.
package/NOTICE CHANGED
@@ -1,5 +1,5 @@
1
1
  Prowl
2
- Copyright (c) 2026 Michael Tookes
2
+ Copyright (c) 2026 Genkei Labs
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5
5
  this file except in compliance with the License. You may obtain a copy of the
package/README.md CHANGED
@@ -422,15 +422,19 @@ assertions:
422
422
  Config lives at `.prowl/config.yml`. All options with defaults:
423
423
 
424
424
  ```yaml
425
- # The base URL for all hunt navigation
425
+ # Execution target. Defaults to the web target; existing configs work unchanged.
426
426
  target:
427
- url: "http://localhost:3000" # Required
427
+ type: "web" # "web" (default) or "macos" (experimental)
428
+ url: "http://localhost:3000" # Required for web targets
429
+ # For the experimental macOS target instead:
430
+ # type: "macos"
431
+ # app: "com.example.App" # bundle id or /path/to/App.app (see "macOS Target")
428
432
 
429
433
  # Browser settings
430
434
  browser:
431
435
  headless: true # false = show the browser window
432
436
  slowMo: 0 # ms delay between actions (debugging)
433
- timeout: 30000 # default page operation timeout
437
+ timeout: 30000 # default page operation timeout; macOS app launch timeout
434
438
 
435
439
  # What gets saved per run
436
440
  artifacts:
@@ -454,6 +458,7 @@ guardrails:
454
458
  forbiddenSelectors: # selectors that steps cannot use
455
459
  - "[data-danger]"
456
460
  - ".delete-btn"
461
+ allowedApps: [] # macOS target only: bundle IDs, bundle names, or .app paths
457
462
 
458
463
  # Auth state from `prowl login`
459
464
  auth:
@@ -897,6 +902,113 @@ Templates cover auth flows (OAuth, 2FA), e-commerce (Stripe), admin panels, SaaS
897
902
 
898
903
  ---
899
904
 
905
+ ## macOS Target (Experimental)
906
+
907
+ > **Experimental (PROWL-048).** Prowl can drive **native macOS apps** — including
908
+ > menu bar extras (`NSStatusItem` + `NSMenu`) — through Apple's Accessibility API,
909
+ > in addition to the web. The API, selector dialect, and step coverage may change.
910
+ > **Distribution is deferred:** the required helper binary is **not** shipped in the
911
+ > npm package; you build it locally (below).
912
+
913
+ ### Enabling it
914
+
915
+ 1. **Build the helper** (one time; requires the Swift toolchain / Xcode CLT):
916
+
917
+ ```bash
918
+ cd macdriver
919
+ swift build -c release
920
+ ```
921
+
922
+ Prowl finds the binary at `macdriver/.build/release/prowl-macdriver`, or at
923
+ `$PROWL_MACDRIVER_BIN` if set. If it is missing, Prowl fails with a clear
924
+ "build the helper" message rather than crashing.
925
+
926
+ 2. **Point your config at a macOS target:**
927
+
928
+ ```yaml
929
+ target:
930
+ type: macos
931
+ app: "com.example.App" # bundle id, or an absolute /path/to/App.app
932
+ guardrails:
933
+ allowedApps: # optional scope; empty = allow the target app
934
+ - "com.example.App"
935
+ ```
936
+
937
+ When `target.app` is an app path, `allowedApps` may list the exact `.app`
938
+ path, the app bundle name (`Example` for `Example.app`), or the bundle id
939
+ from `Contents/Info.plist` when that file is readable.
940
+
941
+ 3. **Grant Accessibility permission** (see below), then run a hunt as usual:
942
+ `prowl run my-macos-hunt`.
943
+
944
+ ### Accessibility & Screen Recording permission
945
+
946
+ The **process that hosts** Prowl (your terminal — Terminal, iTerm, VS Code, or a CI
947
+ agent) must be granted **Accessibility** permission: **System Settings → Privacy &
948
+ Security → Accessibility**, then enable that app. macOS attributes the grant to the
949
+ hosting app, not to `prowl-macdriver`. Preflight from the helper:
950
+
951
+ ```bash
952
+ macdriver/.build/release/prowl-macdriver check # prints {"trusted": <bool>}; prompts on first run
953
+ ```
954
+
955
+ The `screenshot`/`assertScreenshot` steps additionally need **Screen Recording**
956
+ permission for the hosting app.
957
+
958
+ **CI notes (macOS runners):** headless CI cannot click "Allow" in a dialog, so grant
959
+ the permissions non-interactively before the run. On a self-hosted runner you can
960
+ pre-authorize the agent's host app with a TCC profile via MDM, or (on ephemeral
961
+ runners where it's acceptable) seed the TCC database, e.g.:
962
+
963
+ ```bash
964
+ sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" \
965
+ "INSERT OR REPLACE INTO access VALUES('kTCCServiceAccessibility','<runner-app-bundle-id>',0,2,2,1,NULL,NULL,NULL,'UNUSED',NULL,0,1,NULL,NULL,NULL);"
966
+ ```
967
+
968
+ GitHub-hosted macOS runners do not grant Accessibility, so the macOS target is aimed
969
+ at self-hosted / MDM-managed runners for now.
970
+
971
+ ### Selector dialect (macOS)
972
+
973
+ Native selectors address accessibility identifiers, roles, and labels:
974
+
975
+ | Selector | Matches |
976
+ |---|---|
977
+ | `id=openSettings` | element whose `AXIdentifier` equals `openSettings` |
978
+ | `role=button[name="Save"]` | an `AXButton` whose title/description/value contains `Save` |
979
+ | `label="Email"` | element whose accessibility label equals `Email` |
980
+ | `text="Save"` or bare `Save` | element whose title/description/value contains the text |
981
+ | `statusItem` | opens the app's menu bar status-item menu |
982
+ | `menu=Preferences…` | opens the status-item menu and clicks that item |
983
+
984
+ `forbiddenSelectors` still applies (text patterns match via the same substring
985
+ semantics as the web target). Prefer `id=` (accessibility identifiers) — the native
986
+ analog of `data-testid`.
987
+
988
+ ### Step compatibility
989
+
990
+ Portable steps run on **both** targets; web-only steps are rejected up front on the
991
+ macOS target (with a clear error), and `prowl login` / URL guardrails do not apply.
992
+
993
+ | Portable (web + macOS) | Web-only (rejected on macOS) |
994
+ |---|---|
995
+ | `click`, `fill`, `type`, `press` | `navigate`, `waitForUrl`, `waitForNetworkIdle` |
996
+ | `wait`, `waitForSelector` | `mockRoute` / `unmockRoute` |
997
+ | `assert: visible` / `notVisible` | `evalScript`, `runScript` |
998
+ | `screenshot`, `assertScreenshot` | `onDialog`, `select` / `selectOption` |
999
+ | `hover`, `scrollTo` | `setInputFiles`, `waitForDownload` |
1000
+ | `repeat`, `if`, `runHunt`, `copyText` | `scroll` (directional), `assert: urlIncludes` / `urlEquals` |
1001
+
1002
+ Notes: `press` maps Enter/Return/Space onto the element's activate action (other keys
1003
+ are unsupported); `type` fills the focused control; app teardown quits the target app
1004
+ after the run.
1005
+
1006
+ > Docs follow-up: the customer-facing docs site (`prowl-docs`) should gain a "macOS
1007
+ > target" page mirroring this section (target type + step-compatibility matrix +
1008
+ > permission setup); tracked separately from this repo.
1009
+
1010
+ ---
1011
+
900
1012
  ## Troubleshooting
901
1013
 
902
1014
  ### "Could not find .prowl/config.yml"
@@ -7,6 +7,9 @@ import dotenv from "dotenv";
7
7
  // src/config/schema.ts
8
8
  import { z } from "zod";
9
9
 
10
+ // src/types/index.ts
11
+ var SUPPORTED_BROWSER_ENGINES = ["chromium", "firefox", "webkit"];
12
+
10
13
  // src/config/hunt-name.ts
11
14
  var HUNT_NAME_PATTERN = /^[A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)*$/;
12
15
  function isValidHuntName(name) {
@@ -21,15 +24,22 @@ function assertValidHuntName(name) {
21
24
  }
22
25
 
23
26
  // src/config/schema.ts
27
+ var webTargetSchema = z.object({
28
+ type: z.literal("web").optional(),
29
+ url: z.string().min(1)
30
+ }).strict();
31
+ var macosTargetSchema = z.object({
32
+ type: z.literal("macos"),
33
+ app: z.string().min(1)
34
+ }).strict();
35
+ var targetSchema = z.union([macosTargetSchema, webTargetSchema]);
24
36
  var configSchema = z.object({
25
- target: z.object({
26
- url: z.string().min(1)
27
- }),
37
+ target: targetSchema,
28
38
  browser: z.object({
29
39
  headless: z.boolean().optional(),
30
40
  slowMo: z.number().optional(),
31
41
  timeout: z.number().optional(),
32
- engine: z.enum(["chromium", "firefox", "webkit"]).optional(),
42
+ engine: z.enum(SUPPORTED_BROWSER_ENGINES).optional(),
33
43
  channel: z.enum([
34
44
  "chromium",
35
45
  "chrome",
@@ -61,6 +71,7 @@ var configSchema = z.object({
61
71
  guardrails: z.object({
62
72
  maxSteps: z.number().optional(),
63
73
  allowedDomains: z.array(z.string()).optional(),
74
+ allowedApps: z.array(z.string()).optional(),
64
75
  forbiddenSelectors: z.array(z.string()).optional(),
65
76
  selfHealing: z.boolean().optional()
66
77
  }).optional(),
@@ -308,9 +319,11 @@ var huntSchema = z.object({
308
319
  }).strict();
309
320
 
310
321
  // src/config/loader.ts
322
+ var DEFAULT_WEB_URL = "http://localhost:3000";
311
323
  var DEFAULT_CONFIG = {
312
324
  target: {
313
- url: "http://localhost:3000"
325
+ type: "web",
326
+ url: DEFAULT_WEB_URL
314
327
  },
315
328
  browser: {
316
329
  headless: true,
@@ -334,6 +347,7 @@ var DEFAULT_CONFIG = {
334
347
  guardrails: {
335
348
  maxSteps: 50,
336
349
  allowedDomains: ["localhost", "127.0.0.1", "0.0.0.0"],
350
+ allowedApps: [],
337
351
  forbiddenSelectors: ["[data-danger]", ".delete-btn"],
338
352
  selfHealing: false
339
353
  },
@@ -391,11 +405,18 @@ function resolveViewport(value) {
391
405
  }
392
406
  return value;
393
407
  }
408
+ function resolveTarget(target) {
409
+ if (target && target.type === "macos") {
410
+ return { type: "macos", app: target.app };
411
+ }
412
+ return {
413
+ type: "web",
414
+ url: target?.url ?? DEFAULT_WEB_URL
415
+ };
416
+ }
394
417
  function mergeConfig(partial) {
395
418
  return {
396
- target: {
397
- url: partial.target?.url ?? DEFAULT_CONFIG.target.url
398
- },
419
+ target: resolveTarget(partial.target),
399
420
  browser: {
400
421
  headless: partial.browser?.headless ?? DEFAULT_CONFIG.browser.headless,
401
422
  slowMo: partial.browser?.slowMo ?? DEFAULT_CONFIG.browser.slowMo,
@@ -419,6 +440,7 @@ function mergeConfig(partial) {
419
440
  guardrails: {
420
441
  maxSteps: partial.guardrails?.maxSteps ?? DEFAULT_CONFIG.guardrails.maxSteps,
421
442
  allowedDomains: partial.guardrails?.allowedDomains ?? DEFAULT_CONFIG.guardrails.allowedDomains,
443
+ allowedApps: partial.guardrails?.allowedApps ?? DEFAULT_CONFIG.guardrails.allowedApps,
422
444
  forbiddenSelectors: partial.guardrails?.forbiddenSelectors ?? DEFAULT_CONFIG.guardrails.forbiddenSelectors,
423
445
  selfHealing: partial.guardrails?.selfHealing ?? DEFAULT_CONFIG.guardrails.selfHealing
424
446
  },
@@ -461,10 +483,12 @@ function loadConfig(configPath) {
461
483
  const parsed = yaml.parse(raw) ?? {};
462
484
  const validated = configSchema.parse(parsed);
463
485
  const config = mergeConfig(validated);
464
- config.guardrails.allowedDomains = ensureAllowedDomain(
465
- config.guardrails.allowedDomains,
466
- config.target.url
467
- );
486
+ if (config.target.type === "web") {
487
+ config.guardrails.allowedDomains = ensureAllowedDomain(
488
+ config.guardrails.allowedDomains,
489
+ config.target.url
490
+ );
491
+ }
468
492
  return { config, configPath: resolvedPath, configDir };
469
493
  }
470
494
  function loadHunt(huntName, configDir) {
@@ -528,6 +552,7 @@ function listHunts(configDir) {
528
552
  }
529
553
 
530
554
  export {
555
+ SUPPORTED_BROWSER_ENGINES,
531
556
  configSchema,
532
557
  stepSchema,
533
558
  huntSchema,
@@ -543,4 +568,4 @@ export {
543
568
  loadHuntMeta,
544
569
  listHunts
545
570
  };
546
- //# sourceMappingURL=chunk-NXXGJOBG.js.map
571
+ //# sourceMappingURL=chunk-MBAIGNVO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/loader.ts","../src/config/schema.ts","../src/types/index.ts","../src/config/hunt-name.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"yaml\";\nimport dotenv from \"dotenv\";\nimport type { BrowserChannel, BrowserEngine, Config, Hunt, Target, Viewport } from \"../types/index.js\";\nimport { configSchema, huntSchema } from \"./schema.js\";\nimport { assertValidHuntName } from \"./hunt-name.js\";\n\nconst DEFAULT_WEB_URL = \"http://localhost:3000\";\n\nconst DEFAULT_CONFIG: Config = {\n target: {\n type: \"web\",\n url: DEFAULT_WEB_URL\n },\n browser: {\n headless: true,\n slowMo: 0,\n timeout: 30000,\n engine: \"chromium\",\n viewport: { width: 1280, height: 720 }\n },\n artifacts: {\n screenshots: \"on-failure\",\n networkHar: false,\n console: true,\n junit: false\n },\n assertions: {\n noConsoleErrors: true,\n noNetworkErrors: true,\n maxTotalTimeMs: 30000,\n networkIgnorePatterns: []\n },\n guardrails: {\n maxSteps: 50,\n allowedDomains: [\"localhost\", \"127.0.0.1\", \"0.0.0.0\"],\n allowedApps: [],\n forbiddenSelectors: [\"[data-danger]\", \".delete-btn\"],\n selfHealing: false\n },\n auth: {\n storageStatePath: \".prowl/auth-state.json\"\n },\n history: {\n maxRuns: 100\n }\n};\n\nexport const CONFIG_DIR = \".prowl\";\nexport const LEGACY_CONFIG_DIR = \".prowlqa\";\n\nlet legacyDirWarned = false;\n\n/** Warn (once per process) when a project still uses the legacy .prowlqa/ directory. */\nexport function warnLegacyConfigDir(): void {\n if (legacyDirWarned) {\n return;\n }\n legacyDirWarned = true;\n console.warn(\n 'Warning: the \".prowlqa/\" config directory is deprecated; rename it to \".prowl/\". ' +\n 'Support for \".prowlqa/\" will be removed in a future release.'\n );\n}\n\nexport function findConfigPath(startDir: string): string | null {\n let current = startDir;\n while (current) {\n // Prefer the new .prowl/ directory; fall back to the legacy .prowlqa/ at the same level.\n for (const dir of [CONFIG_DIR, LEGACY_CONFIG_DIR]) {\n const candidate = path.join(current, dir, \"config.yml\");\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n }\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return null;\n}\n\nconst VIEWPORT_PRESETS: Record<string, Viewport> = {\n mobile: { width: 375, height: 812 },\n tablet: { width: 768, height: 1024 },\n desktop: { width: 1280, height: 720 }\n};\n\nexport function resolveViewport(\n value: string | Viewport | undefined\n): Viewport {\n if (value === undefined) {\n return DEFAULT_CONFIG.browser.viewport;\n }\n if (typeof value === \"string\") {\n const preset = VIEWPORT_PRESETS[value];\n if (!preset) {\n throw new Error(`Unknown viewport preset: \"${value}\". Use mobile, tablet, or desktop.`);\n }\n return preset;\n }\n return value;\n}\n\n/**\n * Normalize the validated target into a canonical discriminated shape. A target\n * with `type: \"macos\"` becomes a macOS target; anything else (including the\n * legacy `{ url }` with no `type`) resolves to the web target, so pre-existing\n * configs are untouched.\n */\nfunction resolveTarget(target: Config[\"target\"] | undefined): Target {\n if (target && (target as { type?: string }).type === \"macos\") {\n return { type: \"macos\", app: (target as { app: string }).app };\n }\n return {\n type: \"web\",\n url: (target as { url?: string } | undefined)?.url ?? DEFAULT_WEB_URL\n };\n}\n\nfunction mergeConfig(partial: Partial<Config>): Config {\n return {\n target: resolveTarget(partial.target),\n browser: {\n headless: partial.browser?.headless ?? DEFAULT_CONFIG.browser.headless,\n slowMo: partial.browser?.slowMo ?? DEFAULT_CONFIG.browser.slowMo,\n timeout: partial.browser?.timeout ?? DEFAULT_CONFIG.browser.timeout,\n engine: (partial.browser as { engine?: BrowserEngine } | undefined)?.engine ?? DEFAULT_CONFIG.browser.engine,\n channel: (partial.browser as { channel?: BrowserChannel } | undefined)?.channel,\n viewport: resolveViewport((partial.browser as { viewport?: string | Viewport } | undefined)?.viewport)\n },\n artifacts: {\n screenshots: partial.artifacts?.screenshots ?? DEFAULT_CONFIG.artifacts.screenshots,\n networkHar: partial.artifacts?.networkHar ?? DEFAULT_CONFIG.artifacts.networkHar,\n console: partial.artifacts?.console ?? DEFAULT_CONFIG.artifacts.console,\n junit: partial.artifacts?.junit ?? DEFAULT_CONFIG.artifacts.junit\n },\n assertions: {\n noConsoleErrors:\n partial.assertions?.noConsoleErrors ?? DEFAULT_CONFIG.assertions.noConsoleErrors,\n noNetworkErrors:\n partial.assertions?.noNetworkErrors ?? DEFAULT_CONFIG.assertions.noNetworkErrors,\n maxTotalTimeMs:\n partial.assertions?.maxTotalTimeMs ?? DEFAULT_CONFIG.assertions.maxTotalTimeMs,\n networkIgnorePatterns:\n partial.assertions?.networkIgnorePatterns ??\n DEFAULT_CONFIG.assertions.networkIgnorePatterns\n },\n guardrails: {\n maxSteps: partial.guardrails?.maxSteps ?? DEFAULT_CONFIG.guardrails.maxSteps,\n allowedDomains: partial.guardrails?.allowedDomains ?? DEFAULT_CONFIG.guardrails.allowedDomains,\n allowedApps: partial.guardrails?.allowedApps ?? DEFAULT_CONFIG.guardrails.allowedApps,\n forbiddenSelectors:\n partial.guardrails?.forbiddenSelectors ?? DEFAULT_CONFIG.guardrails.forbiddenSelectors,\n selfHealing: partial.guardrails?.selfHealing ?? DEFAULT_CONFIG.guardrails.selfHealing\n },\n auth: {\n storageStatePath: partial.auth?.storageStatePath ?? (partial.auth !== undefined ? DEFAULT_CONFIG.auth.storageStatePath : undefined)\n },\n history: {\n maxRuns: partial.history?.maxRuns ?? DEFAULT_CONFIG.history.maxRuns\n },\n bugLog: partial.bugLog,\n tracing: partial.tracing,\n reliability: partial.reliability\n };\n}\n\nexport function ensureAllowedDomain(allowed: string[], urlValue: string): string[] {\n try {\n const host = new URL(urlValue).hostname;\n if (!allowed.includes(host)) {\n return [...allowed, host];\n }\n } catch {\n return allowed;\n }\n return allowed;\n}\n\nexport function loadConfig(configPath?: string): {\n config: Config;\n configPath: string;\n configDir: string;\n} {\n const resolvedPath = configPath\n ? path.resolve(configPath)\n : findConfigPath(process.cwd());\n\n if (!resolvedPath) {\n throw new Error(\"Could not find .prowl/config.yml. Run `prowl init` first.\");\n }\n\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`Config file not found at ${resolvedPath}`);\n }\n\n const configDir = path.dirname(resolvedPath);\n if (path.basename(configDir) === LEGACY_CONFIG_DIR) {\n warnLegacyConfigDir();\n }\n dotenv.config({ path: path.join(configDir, \".env\"), override: false });\n\n const raw = fs.readFileSync(resolvedPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n const validated = configSchema.parse(parsed);\n const config = mergeConfig(validated as Partial<Config>);\n\n // allowedDomains only applies to the web target; the macOS target scopes on\n // bundle IDs / process names via guardrails.allowedApps instead.\n if (config.target.type === \"web\") {\n config.guardrails.allowedDomains = ensureAllowedDomain(\n config.guardrails.allowedDomains,\n config.target.url\n );\n }\n\n return { config, configPath: resolvedPath, configDir };\n}\n\nexport function loadHunt(huntName: string, configDir: string): Hunt {\n assertValidHuntName(huntName);\n const huntPath = path.join(configDir, \"hunts\", `${huntName}.yml`);\n if (!fs.existsSync(huntPath)) {\n throw new Error(`Hunt file not found: ${huntPath}`);\n }\n const raw = fs.readFileSync(huntPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n const validated = huntSchema.parse(parsed);\n return validated as Hunt;\n}\n\nexport function loadHuntTags(huntName: string, configDir: string): string[] {\n assertValidHuntName(huntName);\n const huntPath = path.join(configDir, \"hunts\", `${huntName}.yml`);\n if (!fs.existsSync(huntPath)) {\n return [];\n }\n const raw = fs.readFileSync(huntPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n return Array.isArray(parsed.tags) ? parsed.tags : [];\n}\n\nexport function loadHuntMeta(huntName: string, configDir: string): { description?: string; tags: string[] } {\n assertValidHuntName(huntName);\n const huntPath = path.join(configDir, \"hunts\", `${huntName}.yml`);\n if (!fs.existsSync(huntPath)) {\n return { tags: [] };\n }\n const raw = fs.readFileSync(huntPath, \"utf-8\");\n const parsed = yaml.parse(raw) ?? {};\n return {\n description: typeof parsed.description === \"string\" ? parsed.description : undefined,\n tags: Array.isArray(parsed.tags) ? parsed.tags : []\n };\n}\n\nexport function listHunts(configDir: string): string[] {\n const huntsDir = path.join(configDir, \"hunts\");\n if (!fs.existsSync(huntsDir)) {\n return [];\n }\n const stats = fs.statSync(huntsDir);\n if (!stats.isDirectory()) {\n throw new Error(`Hunts path is not a directory: ${huntsDir}`);\n }\n\n const results: string[] = [];\n\n function scanDir(dir: string) {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(\".yml\")) {\n const fullPath = path.join(dir, entry.name);\n const relative = path.relative(huntsDir, fullPath);\n results.push(relative.replace(/\\.yml$/, \"\"));\n } else if (entry.isDirectory()) {\n scanDir(path.join(dir, entry.name));\n }\n }\n }\n\n scanDir(huntsDir);\n return results.sort((a, b) => a.localeCompare(b));\n}\n","import { z } from \"zod\";\nimport { SUPPORTED_BROWSER_ENGINES, type Step } from \"../types/index.js\";\nimport { isValidHuntName } from \"./hunt-name.js\";\n\n// Web target keeps `type` optional so pre-existing configs (`target: { url }`)\n// parse unchanged and default to the web target.\nconst webTargetSchema = z\n .object({\n type: z.literal(\"web\").optional(),\n url: z.string().min(1)\n })\n .strict();\n\n// macOS native target (experimental, PROWL-048): requires `type: \"macos\"` and an\n// app (bundle id or .app path); `url` is not accepted.\nconst macosTargetSchema = z\n .object({\n type: z.literal(\"macos\"),\n app: z.string().min(1)\n })\n .strict();\n\n// macos is tried first because it is the only branch with `type: \"macos\"`; a bare\n// `{ url }` (no type) falls through to web. An object with neither `url` nor a\n// macos `app` matches neither branch and is rejected with a union error.\nexport const targetSchema = z.union([macosTargetSchema, webTargetSchema]);\n\nexport const configSchema = z\n .object({\n target: targetSchema,\n browser: z\n .object({\n headless: z.boolean().optional(),\n slowMo: z.number().optional(),\n timeout: z.number().optional(),\n engine: z.enum(SUPPORTED_BROWSER_ENGINES).optional(),\n channel: z.enum([\n \"chromium\",\n \"chrome\", \"chrome-beta\", \"chrome-canary\", \"chrome-dev\",\n \"msedge\", \"msedge-beta\", \"msedge-canary\", \"msedge-dev\"\n ]).optional(),\n viewport: z\n .union([\n z.enum([\"mobile\", \"tablet\", \"desktop\"]),\n z.object({ width: z.number().int().positive(), height: z.number().int().positive() }).strict()\n ])\n .optional()\n })\n .optional(),\n artifacts: z\n .object({\n screenshots: z.enum([\"on-failure\", \"all\"]).optional(),\n networkHar: z.boolean().optional(),\n console: z.boolean().optional(),\n junit: z.boolean().optional()\n })\n .optional(),\n assertions: z\n .object({\n noConsoleErrors: z.boolean().optional(),\n noNetworkErrors: z.boolean().optional(),\n maxTotalTimeMs: z.number().optional(),\n networkIgnorePatterns: z.array(z.string()).optional()\n })\n .optional(),\n guardrails: z\n .object({\n maxSteps: z.number().optional(),\n allowedDomains: z.array(z.string()).optional(),\n allowedApps: z.array(z.string()).optional(),\n forbiddenSelectors: z.array(z.string()).optional(),\n selfHealing: z.boolean().optional()\n })\n .optional(),\n auth: z\n .object({\n storageStatePath: z.string().optional()\n })\n .optional(),\n history: z\n .object({\n maxRuns: z.number().int().positive().optional()\n })\n .optional(),\n bugLog: z\n .object({\n enabled: z.boolean().optional(),\n backlogPath: z.string().min(1).optional(),\n resolvedPath: z.string().min(1).optional()\n })\n .strict()\n .optional(),\n tracing: z\n .object({\n header: z.string().min(1).optional()\n })\n .strict()\n .optional(),\n reliability: z\n .object({\n flakyThreshold: z.number().min(0).max(1).optional()\n })\n .strict()\n .optional()\n })\n .strict();\n\nexport const navigateStepSchema = z.object({ navigate: z.string().min(1) }).strict();\nexport const clickStepSchema = z\n .object({\n click: z.union([z.object({ selector: z.string().min(1) }).strict(), z.string().min(1)])\n })\n .strict();\n\nconst singleKeyValueSchema = z\n .record(z.string().min(1), z.string())\n .refine((record) => Object.keys(record).length === 1, {\n message: \"Expected exactly one key-value pair\"\n });\n\nexport const fillStepSchema = z\n .object({\n fill: z.union([\n z.object({ selector: z.string().min(1), value: z.string() }).strict(),\n singleKeyValueSchema\n ])\n })\n .strict();\nexport const typeStepSchema = z.object({ type: z.string() }).strict();\nexport const pressStepSchema = z\n .object({\n press: z.object({ selector: z.string().min(1), key: z.string().min(1) }).strict()\n })\n .strict();\nexport const waitForSelectorStepSchema = z\n .object({\n waitForSelector: z\n .object({ selector: z.string().min(1), timeout: z.number().optional() })\n .strict()\n })\n .strict();\nexport const waitStepSchema = z\n .object({\n wait: z.union([\n z.string().min(1),\n z.object({ for: z.string().min(1), timeout: z.number().optional() }).strict()\n ])\n })\n .strict();\nexport const waitForUrlStepSchema = z\n .object({\n waitForUrl: z.object({ value: z.string().min(1), timeout: z.number().optional() }).strict()\n })\n .strict();\nexport const waitForNetworkIdleStepSchema = z\n .object({\n waitForNetworkIdle: z.object({ timeout: z.number().optional() }).strict()\n })\n .strict();\nexport const selectOptionStepSchema = z\n .object({\n selectOption: z.object({ selector: z.string().min(1), value: z.string() }).strict()\n })\n .strict();\nexport const selectStepSchema = z\n .object({\n select: singleKeyValueSchema\n })\n .strict();\nexport const onDialogStepSchema = z\n .object({\n onDialog: z.object({ action: z.enum([\"accept\", \"dismiss\"]) }).strict()\n })\n .strict();\nexport const setInputFilesStepSchema = z\n .object({\n setInputFiles: z\n .object({\n selector: z.string().min(1),\n files: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)])\n })\n .strict()\n })\n .strict();\nexport const inlineAssertStepSchema = z\n .object({\n assert: z\n .object({\n visible: z.string().min(1).optional(),\n notVisible: z.string().min(1).optional(),\n urlIncludes: z.string().min(1).optional(),\n urlEquals: z.string().min(1).optional()\n })\n .strict()\n .refine(\n (value) =>\n [value.visible, value.notVisible, value.urlIncludes, value.urlEquals].filter(\n (entry) => entry !== undefined\n ).length === 1,\n {\n message: \"assert requires exactly one of visible, notVisible, urlIncludes, urlEquals\"\n }\n )\n })\n .strict();\nexport const runHuntStepSchema = z\n .object({\n runHunt: z.union([\n z\n .string()\n .min(1)\n .refine(isValidHuntName, {\n message:\n \"Invalid hunt name. Use only letters, numbers, hyphens, underscores, and forward slashes.\"\n }),\n z\n .object({\n name: z\n .string()\n .min(1)\n .refine(isValidHuntName, {\n message:\n \"Invalid hunt name. Use only letters, numbers, hyphens, underscores, and forward slashes.\"\n }),\n vars: z.record(z.string(), z.string()).optional()\n })\n .strict()\n ])\n })\n .strict();\nexport const hoverStepSchema = z\n .object({\n hover: z.object({ selector: z.string().min(1) }).strict()\n })\n .strict();\nexport const scrollStepSchema = z\n .object({\n scroll: z\n .object({\n direction: z.enum([\"up\", \"down\", \"left\", \"right\"]),\n amount: z.number().optional()\n })\n .strict()\n })\n .strict();\nexport const scrollToStepSchema = z\n .object({\n scrollTo: z.object({ selector: z.string().min(1) }).strict()\n })\n .strict();\nexport const screenshotStepSchema = z\n .object({\n screenshot: z.object({ name: z.string().optional() }).strict()\n })\n .strict();\n\n// Recursive step schemas use z.lazy() to reference stepSchema before it's defined\nexport const ifStepSchema = z\n .object({\n if: z\n .object({\n visible: z.string().min(1).optional(),\n notVisible: z.string().min(1).optional(),\n then: z.lazy(() => z.array(stepSchema).min(1)),\n else: z.lazy(() => z.array(stepSchema).min(1)).optional()\n })\n .strict()\n .refine(\n (value) =>\n [value.visible, value.notVisible].filter((v) => v !== undefined).length === 1,\n { message: \"if requires exactly one of visible or notVisible\" }\n )\n })\n .strict();\n\nexport const repeatStepSchema = z\n .object({\n repeat: z\n .object({\n times: z.number().int().positive().optional(),\n while: z\n .object({\n visible: z.string().min(1).optional(),\n notVisible: z.string().min(1).optional()\n })\n .strict()\n .refine(\n (value) =>\n [value.visible, value.notVisible].filter((v) => v !== undefined).length === 1,\n { message: \"while requires exactly one of visible or notVisible\" }\n )\n .optional(),\n maxIterations: z.number().int().positive().optional(),\n steps: z.lazy(() => z.array(stepSchema).min(1))\n })\n .strict()\n .refine((value) => !(value.times !== undefined && value.while !== undefined), {\n message: \"repeat requires either times or while, not both\"\n })\n .refine((value) => value.times !== undefined || value.while !== undefined, {\n message: \"repeat requires either times or while\"\n })\n .refine((value) => !(value.while !== undefined && value.maxIterations === undefined), {\n message: \"while requires maxIterations\"\n })\n })\n .strict();\n\nexport const mockRouteStepSchema = z\n .object({\n mockRoute: z\n .object({\n url: z.string().min(1),\n response: z\n .object({\n status: z.number().int(),\n contentType: z.string().min(1).optional(),\n body: z.string().min(1).optional(),\n file: z.string().min(1).optional()\n })\n .strict()\n .refine(\n (value) =>\n [value.body, value.file].filter((v) => v !== undefined).length === 1,\n { message: \"response requires exactly one of body or file\" }\n )\n })\n .strict()\n })\n .strict();\n\nexport const unmockRouteStepSchema = z\n .object({\n unmockRoute: z.union([\n z.string().min(1),\n z.object({ url: z.string().min(1) }).strict()\n ])\n })\n .strict();\n\nexport const evalScriptStepSchema = z\n .object({\n evalScript: z.union([\n z.string().min(1),\n z\n .object({\n expression: z.string().min(1),\n as: z.string().min(1).optional()\n })\n .strict()\n ])\n })\n .strict();\n\nexport const runScriptStepSchema = z\n .object({\n runScript: z.object({ file: z.string().min(1) }).strict()\n })\n .strict();\n\nexport const assertScreenshotStepSchema = z\n .object({\n assertScreenshot: z\n .object({\n name: z.string().min(1),\n threshold: z.number().min(0).max(1).optional()\n })\n .strict()\n })\n .strict();\n\nexport const copyTextStepSchema = z\n .object({\n copyText: z\n .object({\n selector: z.string().min(1),\n as: z.string().min(1)\n })\n .strict()\n })\n .strict();\n\nexport const waitForDownloadStepSchema = z\n .object({\n waitForDownload: z.union([\n z\n .object({\n filename: z.string().min(1).optional(),\n timeout: z.number().int().positive().optional()\n })\n .strict(),\n z.null()\n ])\n })\n .strict();\n\nexport const stepSchema: z.ZodType<Step> = z.union([\n navigateStepSchema,\n clickStepSchema,\n fillStepSchema,\n typeStepSchema,\n pressStepSchema,\n waitStepSchema,\n selectOptionStepSchema,\n selectStepSchema,\n onDialogStepSchema,\n setInputFilesStepSchema,\n inlineAssertStepSchema,\n runHuntStepSchema,\n waitForSelectorStepSchema,\n waitForUrlStepSchema,\n waitForNetworkIdleStepSchema,\n hoverStepSchema,\n scrollStepSchema,\n scrollToStepSchema,\n screenshotStepSchema,\n ifStepSchema,\n repeatStepSchema,\n mockRouteStepSchema,\n unmockRouteStepSchema,\n evalScriptStepSchema,\n runScriptStepSchema,\n assertScreenshotStepSchema,\n copyTextStepSchema,\n waitForDownloadStepSchema\n]);\n\nexport const assertionSchema = z.union([\n z.object({ selectorExists: z.string().min(1) }).strict(),\n z.object({ selectorNotExists: z.string().min(1) }).strict(),\n z.object({ urlIncludes: z.string().min(1) }).strict(),\n z.object({ urlEquals: z.string().min(1) }).strict(),\n z.object({ noConsoleErrors: z.boolean() }).strict(),\n z.object({ noNetworkErrors: z.boolean() }).strict()\n]);\n\nexport const huntSchema = z\n .object({\n name: z.string().optional(),\n description: z.string().optional(),\n tags: z.array(z.string().min(1)).optional(),\n vars: z.record(z.string(), z.string()).optional(),\n steps: z.array(stepSchema),\n assertions: z.array(assertionSchema).optional(),\n retry: z\n .object({\n maxRetries: z.number().int().min(0),\n delay: z.number().int().min(0).optional()\n })\n .strict()\n .optional()\n })\n .strict();\n","export const SUPPORTED_BROWSER_ENGINES = [\"chromium\", \"firefox\", \"webkit\"] as const;\n\nexport type BrowserEngine = (typeof SUPPORTED_BROWSER_ENGINES)[number];\n\nexport type BrowserChannel =\n | \"chromium\"\n | \"chrome\" | \"chrome-beta\" | \"chrome-canary\" | \"chrome-dev\"\n | \"msedge\" | \"msedge-beta\" | \"msedge-canary\" | \"msedge-dev\";\n\nexport type Viewport = {\n width: number;\n height: number;\n};\n\n/** Web execution target (default): drives a browser at `url`. */\nexport type WebTarget = {\n type: \"web\";\n url: string;\n};\n\n/**\n * macOS native execution target (experimental, PROWL-048). `app` is a bundle\n * identifier (e.g. `com.example.App`) or an absolute path to a `.app` bundle.\n * App-path guardrails are matched against the path, bundle name, and\n * `CFBundleIdentifier` from `Contents/Info.plist` when it is readable.\n */\nexport type MacosTarget = {\n type: \"macos\";\n app: string;\n};\n\nexport type Target = WebTarget | MacosTarget;\n\nexport type Config = {\n target: Target;\n browser: {\n headless: boolean;\n slowMo: number;\n timeout: number;\n engine: BrowserEngine;\n channel?: BrowserChannel;\n viewport: Viewport;\n };\n artifacts: {\n screenshots: \"on-failure\" | \"all\";\n networkHar: boolean;\n console: boolean;\n junit: boolean;\n };\n assertions: {\n noConsoleErrors: boolean;\n noNetworkErrors: boolean;\n maxTotalTimeMs: number;\n networkIgnorePatterns: string[];\n };\n guardrails: {\n maxSteps: number;\n allowedDomains: string[];\n /** Native scope analog of `allowedDomains`: allowed bundle IDs, app bundle names, or `.app` paths. */\n allowedApps: string[];\n forbiddenSelectors: string[];\n selfHealing: boolean;\n };\n auth: {\n storageStatePath?: string;\n };\n history: {\n maxRuns: number;\n };\n bugLog?: BugLogConfig;\n tracing?: TracingConfig;\n reliability?: ReliabilityConfig;\n};\n\nexport type ReliabilityConfig = {\n /** Flake score (0-1) at or above which a hunt is flagged flaky (default 0.3). */\n flakyThreshold?: number;\n};\n\nexport type TracingConfig = {\n /** Response header carrying the distributed-trace id (default \"traceparent\"). */\n header?: string;\n};\n\nexport type BugLogConfig = {\n enabled?: boolean;\n backlogPath?: string;\n resolvedPath?: string;\n};\n\nexport type HistoryEntry = {\n hunt: string;\n status: \"pass\" | \"fail\";\n durationMs: number;\n startedAt: string;\n runDir?: string;\n};\n\nexport type HistoryFile = {\n entries: HistoryEntry[];\n};\n\nexport type Hunt = {\n name?: string;\n description?: string;\n tags?: string[];\n vars?: Record<string, string>;\n steps: Step[];\n assertions?: Assertion[];\n retry?: {\n maxRetries: number;\n delay?: number;\n };\n};\n\nexport type NavigateStep = { navigate: string };\nexport type ClickStep = { click: { selector: string } | string };\nexport type FillStep = { fill: { selector: string; value: string } | Record<string, string> };\nexport type TypeStep = { type: string };\nexport type PressStep = { press: { selector: string; key: string } };\nexport type WaitForSelectorStep = { waitForSelector: { selector: string; timeout?: number } };\nexport type WaitStep = { wait: string | { for: string; timeout?: number } };\nexport type WaitForUrlStep = { waitForUrl: { value: string; timeout?: number } };\nexport type WaitForNetworkIdleStep = { waitForNetworkIdle: { timeout?: number } };\nexport type SelectOptionStep = { selectOption: { selector: string; value: string } };\nexport type SelectStep = { select: Record<string, string> };\nexport type OnDialogStep = { onDialog: { action: \"accept\" | \"dismiss\" } };\nexport type SetInputFilesStep = { setInputFiles: { selector: string; files: string | string[] } };\nexport type InlineAssertStep = {\n assert: {\n visible?: string;\n notVisible?: string;\n urlIncludes?: string;\n urlEquals?: string;\n };\n};\nexport type RunHuntStep = { runHunt: string | { name: string; vars?: Record<string, string> } };\nexport type HoverStep = { hover: { selector: string } };\nexport type ScrollStep = { scroll: { direction: \"up\" | \"down\" | \"left\" | \"right\"; amount?: number } };\nexport type ScrollToStep = { scrollTo: { selector: string } };\nexport type ScreenshotStep = { screenshot: { name?: string } };\nexport type IfStep = {\n if: {\n visible?: string;\n notVisible?: string;\n then: Step[];\n else?: Step[];\n };\n};\nexport type RepeatStep = {\n repeat: {\n times?: number;\n while?: { visible?: string; notVisible?: string };\n maxIterations?: number;\n steps: Step[];\n };\n};\nexport type MockRouteStep = {\n mockRoute: {\n url: string;\n response: {\n status: number;\n contentType?: string;\n body?: string;\n file?: string;\n };\n };\n};\nexport type UnmockRouteStep = { unmockRoute: string | { url: string } };\nexport type EvalScriptStep = {\n evalScript: string | { expression: string; as?: string };\n};\nexport type RunScriptStep = {\n runScript: { file: string };\n};\nexport type CopyTextStep = { copyText: { selector: string; as: string } };\nexport type WaitForDownloadStep = {\n waitForDownload: { filename?: string; timeout?: number } | null;\n};\nexport type AssertScreenshotStep = {\n assertScreenshot: {\n name: string;\n threshold?: number;\n };\n};\n\nexport type Step =\n | NavigateStep\n | ClickStep\n | FillStep\n | TypeStep\n | PressStep\n | WaitStep\n | SelectOptionStep\n | SelectStep\n | OnDialogStep\n | SetInputFilesStep\n | InlineAssertStep\n | RunHuntStep\n | WaitForSelectorStep\n | WaitForUrlStep\n | WaitForNetworkIdleStep\n | HoverStep\n | ScrollStep\n | ScrollToStep\n | ScreenshotStep\n | IfStep\n | RepeatStep\n | MockRouteStep\n | UnmockRouteStep\n | EvalScriptStep\n | RunScriptStep\n | AssertScreenshotStep\n | CopyTextStep\n | WaitForDownloadStep;\n\nexport type Assertion =\n | { selectorExists: string }\n | { selectorNotExists: string }\n | { urlIncludes: string }\n | { urlEquals: string }\n | { noConsoleErrors: boolean }\n | { noNetworkErrors: boolean };\n\nexport type StepResult = {\n type: string;\n status: \"pass\" | \"fail\";\n durationMs: number;\n selector?: string;\n value?: string;\n error?: string;\n screenshot?: string;\n /** Original selector when the step was completed via a self-healed selector. */\n healedFrom?: string;\n};\n\nexport type AssertionResult = {\n type: string;\n value?: string | boolean;\n status: \"pass\" | \"fail\";\n error?: string;\n};\n\nexport type RunArtifacts = {\n summary?: string;\n screenshots?: string[];\n console?: string;\n trace?: string;\n networkHar?: string;\n junit?: string;\n};\n\nexport type TraceCorrelation = {\n url: string;\n status: number;\n traceId: string;\n header: string;\n};\n\nexport type RunResult = {\n status: \"pass\" | \"fail\";\n exitCode: 0 | 1;\n startedAt: string;\n durationMs: number;\n hunt: string;\n targetUrl: string;\n steps: StepResult[];\n assertions: AssertionResult[];\n artifacts: RunArtifacts;\n traceCorrelations?: TraceCorrelation[];\n};\n\nexport type CiHuntResult = {\n hunt: string;\n status: \"pass\" | \"fail\" | \"skipped\";\n durationMs: number;\n runDir?: string;\n error?: string;\n};\n\nexport type CiStatus = \"pass\" | \"fail\" | \"no-hunts\" | \"all-skipped\";\n\nexport type CiFlakyHunt = {\n hunt: string;\n score: number;\n};\n\nexport type CiFailureCluster = {\n cause: string;\n stepType?: string;\n selector?: string;\n error: string;\n count: number;\n hunts: string[];\n};\n\nexport type CiResult = {\n status: CiStatus;\n startedAt: string;\n durationMs: number;\n totalHunts: number;\n passed: number;\n failed: number;\n skipped: number;\n hunts: CiHuntResult[];\n /** Hunts whose flake score is at/above the configured threshold (omitted when none). */\n flaky?: CiFlakyHunt[];\n /** Groups of failed hunts sharing a common cause (omitted when none). */\n clusters?: CiFailureCluster[];\n};\n","const HUNT_NAME_PATTERN = /^[A-Za-z0-9_-]+(?:\\/[A-Za-z0-9_-]+)*$/;\n\nexport function isValidHuntName(name: string): boolean {\n return HUNT_NAME_PATTERN.test(name);\n}\n\nexport function assertValidHuntName(name: string): void {\n if (!isValidHuntName(name)) {\n throw new Error(\n `Invalid hunt name: \"${name}\". Use only letters, numbers, hyphens, underscores, and forward slashes.`\n );\n }\n}\n"],"mappings":"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","names":[]}