prowl-tools 0.1.8 → 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 CHANGED
@@ -145,23 +145,33 @@ prowl init
145
145
 
146
146
  <!-- ILLUSTRATION: Terminal screenshot showing `prowl init` output with raccoon mascot and file listing -->
147
147
 
148
- This creates a `.prowl/` directory with a config file and two starter hunts:
148
+ This creates a `.prowl/` directory with a config file and four starter hunts:
149
149
 
150
150
  ```text
151
151
  .prowl/
152
- ├── config.yml # Target URL, browser settings, guardrails
153
- ├── .gitignore # Keeps runs/, auth-state.json, and .env out of git
152
+ ├── config.yml # Target URL, browser settings, guardrails
153
+ ├── .gitignore # Keeps runs/, auth-state.json, and .env out of git
154
154
  └── hunts/
155
- ├── hello.yml # Minimal smoke test — verifies the app loads
156
- └── login-flow.yml # Fuller example — auth, secrets, assertions
155
+ ├── hello.yml # Minimal smoke test — verifies the app loads
156
+ ├── login-flow.yml # Auth example — fill credentials, verify redirect
157
+ ├── form.yml # Forms example — fill, select, submit, assert
158
+ └── macos-hello.yml # Desktop starter — drive TextEdit (macOS, experimental)
157
159
  ```
158
160
 
161
+ The web starters (`hello`, `login-flow`, `form`) run against the default web
162
+ target as soon as you point `config.yml` at your app. `macos-hello` is the
163
+ desktop-first first-run hunt: it drives TextEdit through the Accessibility API,
164
+ and its inline comments walk you through switching the target to `macos` and the
165
+ one-time setup (`prowl macdriver install`, Accessibility permission). The macOS
166
+ target is experimental — see [macOS Target](#macos-target-experimental).
167
+
159
168
  `prowl init` finishes by pointing you at the first hunt:
160
169
 
161
170
  ```text
162
171
  Initialized .prowl directory.
163
172
  Run prowl run hello to get started.
164
- See .prowl/hunts/login-flow.yml for a fuller example.
173
+ See .prowl/hunts/login-flow.yml (auth) and .prowl/hunts/form.yml (web forms) for fuller examples.
174
+ Desktop-first? .prowl/hunts/macos-hello.yml is a macOS starter (experimental — see its comments to enable).
165
175
  ```
166
176
 
167
177
  ### 3. Configure
@@ -1035,6 +1045,10 @@ prowl login
1035
1045
  prowl init
1036
1046
  prowl init --force # Overwrite existing
1037
1047
 
1048
+ # Doctor — check the environment is ready to run hunts
1049
+ prowl doctor
1050
+ prowl doctor --fix # Install Chromium / scaffold .prowl if missing
1051
+
1038
1052
  # List available hunts
1039
1053
  prowl list
1040
1054
 
@@ -1058,6 +1072,28 @@ prowl mcp --projects ~/.prowl/projects.yml # Drive multiple repos via a regist
1058
1072
  - Must be a positive integer (`>= 1`).
1059
1073
  - Invalid values (for example `0` or `1.5`) fail fast with an argument error.
1060
1074
 
1075
+ ### Environment Check (`prowl doctor`)
1076
+
1077
+ `prowl doctor` verifies your machine is ready to run hunts and prints a
1078
+ color-coded report (green ✓ pass, yellow ⚠ warning, red ✗ failure, gray ○
1079
+ skipped) with a one-line summary. It checks:
1080
+
1081
+ - **Node.js** is version 20 or newer.
1082
+ - **Playwright** is installed, and its **Chromium** browser is available.
1083
+ - A **`.prowl/` directory** exists with a **valid `config.yml`**.
1084
+ - **Target tooling for your configured target only** (desktop-first): the macOS
1085
+ target reuses `prowl macdriver status` to report which helper binary resolved;
1086
+ the iOS target checks that `xcrun simctl` is reachable (macOS only); the
1087
+ Android target checks that `adb` is reachable. Missing native tooling prints
1088
+ the install command — `doctor` never installs system tools for you.
1089
+
1090
+ Warnings do not fail the command; only real failures do (exit code `1`, so it
1091
+ slots into CI). `prowl doctor --fix` performs just the two safe repairs —
1092
+ installing Chromium through Prowl's resolved Playwright dependency and
1093
+ scaffolding a missing `.prowl/` (the same templates `prowl init` writes) — then
1094
+ re-runs the checks and reports the new status. Everything else prints a manual
1095
+ remedy.
1096
+
1061
1097
  ### Run History
1062
1098
 
1063
1099
  Every `prowl run` and `prowl ci` appends an entry to `.prowl/history.json`
@@ -499,10 +499,15 @@ ${macdriverBuildInstructions()}`
499
499
  ${macdriverBuildInstructions()}`);
500
500
  }
501
501
  var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
502
+ function errorMessage(error) {
503
+ return error instanceof Error ? error.message : String(error);
504
+ }
502
505
  var SpawnMacHelperClient = class {
503
506
  child;
504
507
  pending = /* @__PURE__ */ new Map();
505
508
  requestTimeoutMs;
509
+ onEvent;
510
+ onEventError;
506
511
  stdoutBuffer = "";
507
512
  stderrBuffer = "";
508
513
  nextId = 1;
@@ -510,6 +515,9 @@ var SpawnMacHelperClient = class {
510
515
  terminalError;
511
516
  constructor(binaryPath, options = {}) {
512
517
  this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
518
+ this.onEvent = options.onEvent;
519
+ this.onEventError = options.onEventError ?? ((message) => process.stderr.write(`${message}
520
+ `));
513
521
  this.child = spawn(binaryPath, ["serve"], { stdio: ["pipe", "pipe", "pipe"] });
514
522
  this.child.stdout?.setEncoding("utf-8");
515
523
  this.child.stderr?.setEncoding("utf-8");
@@ -546,6 +554,10 @@ var SpawnMacHelperClient = class {
546
554
  } catch {
547
555
  return;
548
556
  }
557
+ if (typeof message.event === "string" && typeof message.id !== "number") {
558
+ this.handleEvent(message);
559
+ return;
560
+ }
549
561
  const id = typeof message.id === "number" ? message.id : void 0;
550
562
  if (id === void 0) {
551
563
  return;
@@ -562,6 +574,18 @@ var SpawnMacHelperClient = class {
562
574
  pending.reject(new Error(typeof message.error === "string" ? message.error : "prowl-macdriver error"));
563
575
  }
564
576
  }
577
+ handleEvent(event) {
578
+ try {
579
+ this.onEvent?.(event);
580
+ } catch (error) {
581
+ try {
582
+ this.onEventError(
583
+ `prowl-macdriver event sink failed for event "${event.event}": ${errorMessage(error)}`
584
+ );
585
+ } catch {
586
+ }
587
+ }
588
+ }
565
589
  failAll(error) {
566
590
  for (const pending of this.pending.values()) {
567
591
  clearTimeout(pending.timer);
@@ -7482,4 +7506,4 @@ export {
7482
7506
  collectMacdriverStatus,
7483
7507
  tccGuidance
7484
7508
  };
7485
- //# sourceMappingURL=chunk-CWLRDV5P.js.map
7509
+ //# sourceMappingURL=chunk-2RNOK64Y.js.map