[object Object]

← back to Cli Printing Press

feat(skills): offer browser-sniff backend install at preflight (#1132)

8990fc242ff1a4ec7c57892e2896f5cd77fd7be2 · 2026-05-11 19:10:53 -0700 · Trevin Chow

* feat(skills): offer browser-sniff backend install at preflight

Adds a [browser-tools-missing] preflight signal and setup-checks handler
that strongly offers to install browser-use and agent-browser when
either is absent. Fires every run with no decline cache so a clean
session that later needs browser discovery does not hit a mid-flight
install gate.

Also drops `uvx browser-use --help` from Step 1 and preflight detection.
That probe silently downloads and caches browser-use into uv's tool
cache, which is an unconsented install; downstream capture commands
invoke `browser-use` directly, so a uvx-cache-only state would lie to
detection. Step 1b reframed as a fallback for users who decline at
preflight.

* fix(skills): use uv tool install for browser-use; conditional preflight prompt

Two review-feedback fixes:

1. Switch `uv pip install browser-use` to `uv tool install browser-use`
   in both setup-checks.md section 5 and browser-sniff-capture.md
   Step 1b. `uv pip install` targets the active venv and would not put
   `browser-use` in PATH outside that venv, causing the post-install
   `command -v` verification to lie about success. `uv tool install`
   creates an isolated env and symlinks the entry-point into
   `~/.local/bin`, which is on PATH after uv's shell setup.

2. Make the preflight question text conditional on which tool is
   actually missing. "browser-use and/or agent-browser are not
   installed" was technically accurate but misleading when only one
   was missing. Now: both-missing keeps the original wording;
   single-missing rows name the specific tool.

Files touched

Diff

commit 8990fc242ff1a4ec7c57892e2896f5cd77fd7be2
Author: Trevin Chow <trevin@trevinchow.com>
Date:   Mon May 11 19:10:53 2026 -0700

    feat(skills): offer browser-sniff backend install at preflight (#1132)
    
    * feat(skills): offer browser-sniff backend install at preflight
    
    Adds a [browser-tools-missing] preflight signal and setup-checks handler
    that strongly offers to install browser-use and agent-browser when
    either is absent. Fires every run with no decline cache so a clean
    session that later needs browser discovery does not hit a mid-flight
    install gate.
    
    Also drops `uvx browser-use --help` from Step 1 and preflight detection.
    That probe silently downloads and caches browser-use into uv's tool
    cache, which is an unconsented install; downstream capture commands
    invoke `browser-use` directly, so a uvx-cache-only state would lie to
    detection. Step 1b reframed as a fallback for users who decline at
    preflight.
    
    * fix(skills): use uv tool install for browser-use; conditional preflight prompt
    
    Two review-feedback fixes:
    
    1. Switch `uv pip install browser-use` to `uv tool install browser-use`
       in both setup-checks.md section 5 and browser-sniff-capture.md
       Step 1b. `uv pip install` targets the active venv and would not put
       `browser-use` in PATH outside that venv, causing the post-install
       `command -v` verification to lie about success. `uv tool install`
       creates an isolated env and symlinks the entry-point into
       `~/.local/bin`, which is on PATH after uv's shell setup.
    
    2. Make the preflight question text conditional on which tool is
       actually missing. "browser-use and/or agent-browser are not
       installed" was technically accurate but misleading when only one
       was missing. Now: both-missing keeps the original wording;
       single-missing rows name the specific tool.
---
 skills/printing-press/SKILL.md                     | 33 +++++++++++-
 .../references/browser-sniff-capture.md            | 20 +++++--
 skills/printing-press/references/setup-checks.md   | 62 +++++++++++++++++++++-
 3 files changed, 107 insertions(+), 8 deletions(-)

diff --git a/skills/printing-press/SKILL.md b/skills/printing-press/SKILL.md
index 28156f95..5a154c94 100644
--- a/skills/printing-press/SKILL.md
+++ b/skills/printing-press/SKILL.md
@@ -271,6 +271,35 @@ elif [ "$_should_check" = "true" ] && command -v go >/dev/null 2>&1; then
   printf "last_check=%s\nlatest=%s\nmode=standalone\n" "$_now_ts" "${_latest:-$_installed}" > "$PRESS_VERCHECK_FILE" 2>/dev/null || true
 fi
 
+# --- Browser-sniff backend advisory (fail-open, every-run) ---
+# browser-use and agent-browser are the preferred Phase 1.7 browser-sniff
+# backends. They are not hard requirements — vendor-spec, --spec, and --har
+# runs never invoke them — but when discovery does need them, mid-flight
+# install prompts are disruptive. Emit a marker every run so setup-checks.md
+# can strongly offer install. No decline caching: a run that didn't need them
+# yesterday may need them today, and the prompt cost is small.
+_browser_use_missing=true
+_agent_browser_missing=true
+# Use `command -v` only. Do NOT use `uvx browser-use --help` as a fallback
+# probe: when uvx exists but browser-use doesn't, that command silently
+# downloads and caches the package, which would be an unconsented install.
+# Downstream capture commands also invoke `browser-use` directly (not via
+# uvx), so a uvx-cache-only state would lie to the detection.
+if command -v browser-use >/dev/null 2>&1; then
+  _browser_use_missing=false
+fi
+if command -v agent-browser >/dev/null 2>&1; then
+  _agent_browser_missing=false
+fi
+
+if [ "$_browser_use_missing" = "true" ] || [ "$_agent_browser_missing" = "true" ]; then
+  echo ""
+  echo "[browser-tools-missing] one or more browser-sniff backends not installed"
+  echo "PRESS_BROWSER_USE_MISSING=$_browser_use_missing"
+  echo "PRESS_AGENT_BROWSER_MISSING=$_agent_browser_missing"
+  echo ""
+fi
+
 # --- Codex mode detection (must run as part of setup, not a separate step) ---
 # Codex mode: opt-in only. User must pass "codex" or "--codex" to enable.
 if echo "$ARGUMENTS" | grep -qiE '(^| )(--?codex|codex)( |$)'; then
@@ -304,9 +333,9 @@ CODEX_CONSECUTIVE_FAILURES=0
 ```
 <!-- PRESS_SETUP_CONTRACT_END -->
 
-**MANDATORY: Read and apply [references/setup-checks.md](references/setup-checks.md) immediately after the setup contract bash block runs, before any other action.** It handles four signals the contract emits to stdout: `[setup-error]` (refuse to run, surface the install instructions), `[repo-upgrade-available]` (interactive `AskUserQuestion` prompt + optional repo pull), the min-binary-version compatibility check (hard stop if binary is too old), and `[upgrade-available]` (interactive `AskUserQuestion` prompt + optional standalone binary upgrade). Skipping the reference will cause the skill to proceed with a missing or out-of-date binary. Do not skip.
+**MANDATORY: Read and apply [references/setup-checks.md](references/setup-checks.md) immediately after the setup contract bash block runs, before any other action.** It handles five signals the contract emits to stdout: `[setup-error]` (refuse to run, surface the install instructions), `[repo-upgrade-available]` (interactive `AskUserQuestion` prompt + optional repo pull), the min-binary-version compatibility check (hard stop if binary is too old), `[upgrade-available]` (interactive `AskUserQuestion` prompt + optional standalone binary upgrade), and `[browser-tools-missing]` (interactive `AskUserQuestion` prompt + optional install of browser-use and/or agent-browser). Skipping the reference will cause the skill to proceed with a missing or out-of-date binary, or hit a mid-flight install prompt if browser-sniff is later needed. Do not skip.
 
-Only after preflight completes successfully (no `[setup-error]`; any `[repo-upgrade-available]` or `[upgrade-available]` was offered to the user) should you proceed to the Orientation & Briefing section below.
+Only after preflight completes successfully (no `[setup-error]`; any `[repo-upgrade-available]`, `[upgrade-available]`, or `[browser-tools-missing]` was offered to the user) should you proceed to the Orientation & Briefing section below.
 
 ## Orientation & Briefing
 
diff --git a/skills/printing-press/references/browser-sniff-capture.md b/skills/printing-press/references/browser-sniff-capture.md
index ca8c7912..8265bd4c 100644
--- a/skills/printing-press/references/browser-sniff-capture.md
+++ b/skills/printing-press/references/browser-sniff-capture.md
@@ -58,8 +58,13 @@ When a proxy pattern is detected:
 Check which browser automation tools are available:
 
 ```bash
-# Prefer browser-use (CLI-driven, Performance API collection)
-if command -v browser-use >/dev/null 2>&1 || uvx browser-use --help >/dev/null 2>&1; then
+# Prefer browser-use (CLI-driven, Performance API collection).
+# Use `command -v` only. Do NOT use `uvx browser-use --help` as a fallback
+# probe: when uvx exists but browser-use doesn't, that command silently
+# downloads and caches the package, which is an unconsented install.
+# The capture commands below invoke `browser-use` directly (not via uvx),
+# so a uvx-cache-only state would lie to the detection.
+if command -v browser-use >/dev/null 2>&1; then
   SNIFF_BACKEND="browser-use"
 # Fall back to agent-browser only if it can provide equivalent network capture artifacts.
 elif command -v agent-browser >/dev/null 2>&1; then
@@ -92,7 +97,9 @@ If either MCP flag is true, extend the status report:
 
 > "Using **<tool>** for traffic capture. Fallbacks available: chrome-MCP, computer-use." (list whichever flags are true)
 
-#### Step 1b: Install capture tool (if none found)
+#### Step 1b: Install capture tool (fallback — preflight should have prompted first)
+
+Preflight (`references/setup-checks.md` section 5) offers to install browser-use and agent-browser on every run, so most users arrive at Step 1 with one or both already installed. This step is a fallback for the case where the user declined the preflight prompt and the current run actually needs a browser backend.
 
 If neither tool is installed, offer to install via `AskUserQuestion`. Do not install automatically:
 
@@ -106,9 +113,12 @@ If neither tool is installed, offer to install via `AskUserQuestion`. Do not ins
 **If user picks browser-use:**
 
 ```bash
-# Detect Python package manager
+# Detect Python package manager. Use `uv tool install` (not `uv pip install`):
+# `uv pip install` targets the active venv and won't put the binary in PATH
+# outside it; `uv tool install` creates an isolated env and symlinks the
+# entry-point into `~/.local/bin`.
 if command -v uv >/dev/null 2>&1; then
-  uv pip install browser-use
+  uv tool install browser-use
 elif command -v pip >/dev/null 2>&1; then
   pip install browser-use
 else
diff --git a/skills/printing-press/references/setup-checks.md b/skills/printing-press/references/setup-checks.md
index dfd71044..d550c511 100644
--- a/skills/printing-press/references/setup-checks.md
+++ b/skills/printing-press/references/setup-checks.md
@@ -1,6 +1,6 @@
 # Setup Checks
 
-Post-contract checks the skill must run after executing the bash setup contract block in `SKILL.md`. These handle four signals the contract emits to stdout: `[setup-error]`, `[repo-upgrade-available]`, `[upgrade-available]`, and the `min-binary-version` compatibility check.
+Post-contract checks the skill must run after executing the bash setup contract block in `SKILL.md`. These handle five signals the contract emits to stdout: `[setup-error]`, `[repo-upgrade-available]`, `[upgrade-available]`, `[browser-tools-missing]`, and the `min-binary-version` compatibility check.
 
 Apply these in order. Each section is conditional — do nothing if its trigger isn't present.
 
@@ -105,3 +105,63 @@ These two commands update skill files that live outside the repo; they only take
 If the upgrade command fails (network error, auth error, etc.), surface the failure to the user and continue with the current binary — do not block the run on a failed upgrade. The user can re-run later.
 
 If no `[upgrade-available]` line was emitted, skip this section entirely.
+
+## 5. Interactive browser-sniff backend install prompt
+
+If the setup contract output contains a line starting with `[browser-tools-missing]`, parse the follow-up lines:
+
+- `PRESS_BROWSER_USE_MISSING=<true|false>`
+- `PRESS_AGENT_BROWSER_MISSING=<true|false>`
+
+Then ask the user via `AskUserQuestion` before continuing setup. The prompt fires every run when either tool is missing — there is no decline cache. Re-prompting is intentional: browser-use and agent-browser are the preferred Phase 1.7 backends, and mid-flight install gates during generation are more disruptive than one short preflight prompt.
+
+- **question** (compose based on which are missing — pick the matching row):
+  - Both missing: `"browser-use and agent-browser are not installed. These are the preferred Phase 1.7 browser-sniff backends — broadly useful for future runs and avoids mid-flight install prompts. (chrome-MCP is a narrow-case fallback, not a substitute.) Install now?"`
+  - Only `browser-use` missing: `"browser-use is not installed. It is the preferred Phase 1.7 browser-sniff primary backend — broadly useful for future runs and avoids mid-flight install prompts. Install now?"`
+  - Only `agent-browser` missing: `"agent-browser is not installed. It is the secondary browser-sniff backend (used for cookie capture from running Chrome) — broadly useful for future runs and avoids mid-flight install prompts. Install now?"`
+- **header:** `"Browser-sniff backends"`
+- **multiSelect:** `false`
+- **options:** compose based on which are missing — see below.
+
+**Option composition.**
+
+- Both missing → (1) **Install both** (Recommended), (2) **Install browser-use only**, (3) **Install agent-browser only**, (4) **Skip for this run**.
+- Only `browser-use` missing → (1) **Install browser-use** (Recommended), (2) **Skip for this run**.
+- Only `agent-browser` missing → (1) **Install agent-browser** (Recommended), (2) **Skip for this run**.
+
+**Install commands.**
+
+For `browser-use`:
+
+```bash
+# Use `uv tool install` (not `uv pip install`). `uv pip install` targets the
+# active venv and won't put the binary in PATH outside it; `uv tool install`
+# creates an isolated env and symlinks the entry-point into `~/.local/bin`.
+if command -v uv >/dev/null 2>&1; then
+  uv tool install browser-use
+elif command -v pip >/dev/null 2>&1; then
+  pip install browser-use
+else
+  echo "Neither uv nor pip found. Install Python first: https://www.python.org/downloads/"
+fi
+```
+
+For `agent-browser`:
+
+```bash
+if command -v brew >/dev/null 2>&1; then
+  brew install agent-browser
+elif command -v npm >/dev/null 2>&1; then
+  npm install -g agent-browser
+else
+  echo "Neither brew nor npm found. Install Node.js first: https://nodejs.org/"
+fi
+```
+
+After install, verify with `command -v <tool>` and confirm to the user: `"Installed <tool>."` **Continue this current setup run with the newly available tools — do not stop, do not skip the remaining checks (min-binary-version compatibility, etc.).**
+
+If an install command fails (no Python, no Node.js, network error), surface the failure to the user and continue without the missing backend. Do not block the run on a failed install — runs using vendor specs, `--spec`, or `--har` do not need these tools, and the lazy Step 1b prompt in `browser-sniff-capture.md` remains as a fallback if browser-sniff is later invoked.
+
+If the user picks **Skip for this run**, continue without prompting further this run. The decision is not cached — the prompt re-fires on the next run if the tool is still missing.
+
+If no `[browser-tools-missing]` line was emitted, skip this section entirely.

← d4c8bfbf chore(main): release 4.4.0 (#1073)  ·  back to Cli Printing Press  ·  docs(cli): refresh solution docs (#1146) 44e7efe4 →