Adom Desktop - Puppeteer Bridge
Public Made by Adomby adom
The Adom Desktop Puppeteer (pup) bridge — drive a real headful browser on the user's desktop from the cloud: open/screenshot/eval/record. Cold-start drives the browser ALREADY on the machine (installed Chrome, else Microsoft Edge — every Windows PC ships with Edge) with a fresh isolated profile, so the common case needs NO download; Chrome for Testing is fetched only as a last resort. Two artifacts: the Releases zip is the bridge runtime (also bundled in Adom Desktop); the pkg installs the container-side Claude skills.
name: pup-browsers-and-chrome user-invocable: true description: "How pup (Puppeteer bridge) picks and launches a browser, and every cold-start / readiness case. Covers: the installed-browser-first architecture (launches a FRESH CDP-driven process of installed Chrome → else Edge → else cached Chrome for Testing, spawn-verified with fallthrough, caches the winner as default); browser_use to pin chrome/edge/cft/auto; INSTALLING real Google Chrome on an Edge-only box (browser_use install:true) including the UAC-approval-notify flow on locked-down machines; installing/prewarming Chrome for Testing; browser_readiness (READ-ONLY — the right 'is it ready / which browser' probe, NOT browser_status); the cold-start error table (node_not_found, bridge_restarting, chrome_for_testing_installing, chrome_install_no_disk, CfT 'skipped' is not a failure); AD-managed Node provisioning (no install needed on AD >=1.9.63); and the shell-approval gate. Read on any browser-pick question, a fresh/first-run PC, an install/prewarm, a not-ready error, or a shell-approval prompt. Trigger words: browser_readiness, browser_use, browser_prewarm, chrome for testing, install chrome, chrome_for_testing_installing, node_not_found, bridge_restarting, chrome_install_no_disk, cold start pup, which browser, edge only box, UAC approve chrome, request_shell_approval, shell command approval, adom runtimes, pup not ready."
Parent skill: adom-desktop-puppeteer-bridge · See also: pup (start here), pup-windows-sessions-tabs, pup-screenshots-recording.
pup — browsers, Chrome install & cold-start
How pup picks + launches a browser (the architecture)
pup drives the browser already on the machine — it does NOT ship or require its own. On every open it builds a candidate list and spawn-verifies it:
- Chrome → Edge → cached Chrome for Testing (a pinned default, if set, goes first). Every Windows PC ships Edge, so there's almost always a candidate with no download.
- It launches a fresh process of that browser binary with an isolated
--user-data-dir+ a CDP--remote-debugging-port— a clean empty profile driven over the DevTools Protocol, never the user's signed-in profile, and a real rendered window (not headless). - If the top pick is present but won't start (corrupt/partial install), pup falls through to the next — so an open never hard-fails on one broken browser.
- The browser that actually launched is cached as the default (persisted across bridge restarts) so it isn't re-probed each time.
- Chrome for Testing is the last resort — fetched (~150 MB) only if the box has no Chrome and no Edge and no cached CfT.
"Is it ready / which browser?" — browser_readiness (READ-ONLY)
adom-desktop browser_readiness '{}'
# → {ready, browserKind:"chrome"|"edge"|"chrome-for-testing", browserSource, browserExecutablePath,
# candidates:[…the full fallthrough list…], defaultBrowser, diskFreeMb, chromeStablePhase, …}
browser_readinessis the right probe — it never triggers a download and tells you exactly which browser will be driven + the candidate list + the default.browser_statusis NOT a readiness check — it only lists open sessions.- AD-core
bridge_readinessis the platform-level "is this bridge up?" probe.
Pinning a browser — browser_use
pup auto-picks, but you can override (persists across restarts; launch still spawn-verifies + falls back):
adom-desktop browser_use '{"browser":"chrome"}' # pin installed Chrome
adom-desktop browser_use '{"browser":"edge"}' # pin Edge
adom-desktop browser_use '{"browser":"cft"}' # install Chrome for Testing (~150 MB once) + pin it
adom-desktop browser_use '{"browser":"auto"}' # back to auto-pick
Every browser_open_window response also carries browser (what was driven), availableBrowsers, and
defaultBrowser — surface it if the user asks which browser pup is using.
Installing real Google Chrome on an Edge-only box
If the user specifically wants Chrome:
adom-desktop browser_use '{"browser":"chrome","install":true}'
- Downloads Google's official installer and installs Chrome, then pins it. On a normal PC this is silent (user-scoped, no prompt).
- On a locked-down box (a VM / managed device) it needs a Windows UAC. pup escalates automatically and, on AD ≥ 1.9.84, fires a native "click YES to finish installing Chrome" notification from the bridge itself — on the machine with the prompt and pinged to whatever device the user is attending (cross-AD). If the prompt expires it re-notifies with a one-tap "Approve now". All autonomous — no AI turn needed. On older AD (no bridge-notify) it raises the UAC once and returns a hint for you to relay ("go to the box and click YES"), then you re-run the verb.
- Poll
browser_readiness:chromeStablePhasegoesinstalling → awaiting_uac(waiting on the user's click)→ ready;browserKindflips to"chrome". pup keeps driving Edge meanwhile, so nothing is blocked.elevate:"auto"|true|falseon the call tunes the prompt behavior.
Installing / prewarming Chrome for Testing (last resort)
adom-desktop browser_prewarm '{}' # fetch CfT WITHOUT opening a window, then pin it (poll readiness)
adom-desktop browser_use '{"browser":"cft"}' # same, via the pin path
Only needed on a box with no Chrome and no Edge. CfT reported as skipped is NOT a failure — on AD
≥ 1.9.76 the prewarm is conditional, so a box with a system browser skips the ~150 MB download and
bridge_readiness shows the asset {present:false, skipped:true}. That's the intended
installed-browser-first behavior; don't retry or report an error.
Cold-start error table — what a browser_open_window response can mean
| Response | Means | Do |
|---|---|---|
ok:true / a real session |
A browser was found + launched | Proceed — the common case |
errorCode:"node_not_found" / "could not run npm" |
The bridge's Node runtime isn't ready yet | AD ≥ 1.9.63 provisions Node for you — check adom-desktop runtimes '{}'; if installing, wait a few seconds and retry. No user action. Known AD false-negative: if runtimes shows node ready AND browser_readiness works but other verbs still say node_not_found, it's an AD verb-gate bug — do NOT loop desktop_install_node; tell the user to update AD |
errorCode:"bridge_restarting" (stillRunning:true) |
AD ≥ 1.9.77: verb landed in the brief gap while the bridge respawns after an install/update | Poll browser_readiness until it answers, then retry the same verb — not a failure |
errorCode:"chrome_for_testing_installing" (installing:true) |
RARE — no Chrome AND no Edge, so pup is fetching CfT in the background | Poll browser_readiness until {ready:true}, then re-issue. Faster: ask the user to install Chrome/Edge (Edge ships with Windows) |
errorCode:"chrome_install_no_disk" |
No browser + too little disk for CfT (readiness.diskFreeMb) |
Tell the user how much is free vs the ~800 MB needed; ask them to free space or install Edge. Do NOT retry the download |
errorCode:"chrome_install_failed" / chrome_download_network / chrome_install_permission |
No browser AND the CfT fallback download failed | Read readiness.lastError; ask the user to install Chrome or Edge |
Always surface a verb's _hint verbatim when it reports not-ready or failure.
Node provisioning — you do NOTHING (AD ≥ 1.9.63)
pup is a Node process, but you no longer install Node. AD provisions the runtime itself — a system Node
if on PATH, else a portable no-UAC copy it downloads to ~/.adom/adom-runtimes/ and prewarms, then
spawns the bridge by absolute path. Do NOT run desktop_install_node / npm installers / ask the user to
install Node. On a truly fresh box it may be installing for a few seconds after first launch — check
adom-desktop runtimes '{}' ({state: absent|installing|ready|failed}) and retry once ready. (Legacy
desktop_install_node — which pops a UAC — is only for AD older than 1.9.63.)
The shell-approval gate (rarely relevant to pup)
Core AD verbs and pup's own browser_* / desktop_record_* verbs run with NO desktop prompt. Only
open-ended shell_execute / run_script pop AD's "Shell command needs approval" dialog — which you
almost never need (prefer typed verbs). If one returns needs_approval / human_only on AD ≥ 1.9.86:
run adom-desktop --target <box> request_shell_approval (re-surfaces the dialog), ask the user to click
Approve/Bypass, then retry your original verb. Never call shell_auto_approve (human-only, refuses).
This is AD's own gate, NOT a Windows UAC.
---
name: pup-browsers-and-chrome
user-invocable: true
description: "How pup (Puppeteer bridge) picks and launches a browser, and every cold-start / readiness case. Covers: the installed-browser-first architecture (launches a FRESH CDP-driven process of installed Chrome → else Edge → else cached Chrome for Testing, spawn-verified with fallthrough, caches the winner as default); browser_use to pin chrome/edge/cft/auto; INSTALLING real Google Chrome on an Edge-only box (browser_use install:true) including the UAC-approval-notify flow on locked-down machines; installing/prewarming Chrome for Testing; browser_readiness (READ-ONLY — the right 'is it ready / which browser' probe, NOT browser_status); the cold-start error table (node_not_found, bridge_restarting, chrome_for_testing_installing, chrome_install_no_disk, CfT 'skipped' is not a failure); AD-managed Node provisioning (no install needed on AD >=1.9.63); and the shell-approval gate. Read on any browser-pick question, a fresh/first-run PC, an install/prewarm, a not-ready error, or a shell-approval prompt. Trigger words: browser_readiness, browser_use, browser_prewarm, chrome for testing, install chrome, chrome_for_testing_installing, node_not_found, bridge_restarting, chrome_install_no_disk, cold start pup, which browser, edge only box, UAC approve chrome, request_shell_approval, shell command approval, adom runtimes, pup not ready."
---
**Parent skill:** adom-desktop-puppeteer-bridge · See also: `pup` (start here), `pup-windows-sessions-tabs`, `pup-screenshots-recording`.
# pup — browsers, Chrome install & cold-start
## How pup picks + launches a browser (the architecture)
pup drives the browser **already on the machine** — it does NOT ship or require its own. On every open it
builds a candidate list and **spawn-verifies** it:
1. **Chrome → Edge → cached Chrome for Testing** (a pinned default, if set, goes first). Every Windows PC
ships Edge, so there's almost always a candidate with **no download**.
2. It **launches a fresh process** of that browser binary with an **isolated `--user-data-dir` + a CDP
`--remote-debugging-port`** — a clean empty profile driven over the DevTools Protocol, never the user's
signed-in profile, and a **real rendered window** (not headless).
3. If the top pick is present but **won't start** (corrupt/partial install), pup **falls through** to the
next — so an open never hard-fails on one broken browser.
4. The browser that actually launched is **cached as the default** (persisted across bridge restarts) so it
isn't re-probed each time.
5. **Chrome for Testing is the last resort** — fetched (~150 MB) only if the box has *no* Chrome and *no*
Edge and *no* cached CfT.
## "Is it ready / which browser?" — `browser_readiness` (READ-ONLY)
```bash
adom-desktop browser_readiness '{}'
# → {ready, browserKind:"chrome"|"edge"|"chrome-for-testing", browserSource, browserExecutablePath,
# candidates:[…the full fallthrough list…], defaultBrowser, diskFreeMb, chromeStablePhase, …}
```
- **`browser_readiness`** is the right probe — it never triggers a download and tells you exactly which
browser will be driven + the candidate list + the default.
- **`browser_status` is NOT a readiness check** — it only lists open sessions.
- AD-core **`bridge_readiness`** is the platform-level "is this bridge up?" probe.
## Pinning a browser — `browser_use`
pup auto-picks, but you can override (persists across restarts; launch still spawn-verifies + falls back):
```bash
adom-desktop browser_use '{"browser":"chrome"}' # pin installed Chrome
adom-desktop browser_use '{"browser":"edge"}' # pin Edge
adom-desktop browser_use '{"browser":"cft"}' # install Chrome for Testing (~150 MB once) + pin it
adom-desktop browser_use '{"browser":"auto"}' # back to auto-pick
```
Every `browser_open_window` response also carries `browser` (what was driven), `availableBrowsers`, and
`defaultBrowser` — surface it if the user asks which browser pup is using.
## Installing real Google Chrome on an Edge-only box
If the user specifically wants Chrome:
```bash
adom-desktop browser_use '{"browser":"chrome","install":true}'
```
- Downloads Google's official installer and installs Chrome, then pins it. **On a normal PC this is
silent** (user-scoped, no prompt).
- **On a locked-down box (a VM / managed device) it needs a Windows UAC.** pup escalates automatically and,
on **AD ≥ 1.9.84**, fires a native "**click YES to finish installing Chrome**" notification **from the
bridge itself** — on the machine with the prompt **and** pinged to whatever device the user is attending
(cross-AD). If the prompt expires it re-notifies with a one-tap "Approve now". All autonomous — no AI turn
needed. On older AD (no bridge-notify) it raises the UAC once and returns a hint for **you** to relay
("go to the box and click YES"), then you re-run the verb.
- **Poll `browser_readiness`**: `chromeStablePhase` goes `installing → awaiting_uac` (waiting on the user's
click) `→ ready`; `browserKind` flips to `"chrome"`. pup keeps driving Edge meanwhile, so nothing is
blocked. `elevate:"auto"|true|false` on the call tunes the prompt behavior.
## Installing / prewarming Chrome for Testing (last resort)
```bash
adom-desktop browser_prewarm '{}' # fetch CfT WITHOUT opening a window, then pin it (poll readiness)
adom-desktop browser_use '{"browser":"cft"}' # same, via the pin path
```
Only needed on a box with no Chrome and no Edge. **CfT reported as `skipped` is NOT a failure** — on AD
≥ 1.9.76 the prewarm is conditional, so a box with a system browser skips the ~150 MB download and
`bridge_readiness` shows the asset `{present:false, skipped:true}`. That's the intended
installed-browser-first behavior; don't retry or report an error.
## Cold-start error table — what a `browser_open_window` response can mean
| Response | Means | Do |
|---|---|---|
| `ok:true` / a real session | A browser was found + launched | Proceed — the common case |
| `errorCode:"node_not_found"` / "could not run npm" | The bridge's Node runtime isn't ready yet | **AD ≥ 1.9.63 provisions Node for you** — check `adom-desktop runtimes '{}'`; if `installing`, wait a few seconds and **retry**. No user action. **Known AD false-negative:** if `runtimes` shows node `ready` AND `browser_readiness` works but other verbs still say `node_not_found`, it's an AD verb-gate bug — do NOT loop `desktop_install_node`; tell the user to update AD |
| `errorCode:"bridge_restarting"` (`stillRunning:true`) | AD ≥ 1.9.77: verb landed in the brief gap while the bridge respawns after an install/update | Poll `browser_readiness` until it answers, then retry the same verb — not a failure |
| `errorCode:"chrome_for_testing_installing"` (`installing:true`) | RARE — no Chrome AND no Edge, so pup is fetching CfT in the background | Poll `browser_readiness` until `{ready:true}`, then re-issue. Faster: ask the user to install Chrome/Edge (Edge ships with Windows) |
| `errorCode:"chrome_install_no_disk"` | No browser + too little disk for CfT (`readiness.diskFreeMb`) | Tell the user how much is free vs the ~800 MB needed; ask them to free space or install Edge. Do NOT retry the download |
| `errorCode:"chrome_install_failed"` / `chrome_download_network` / `chrome_install_permission` | No browser AND the CfT fallback download failed | Read `readiness.lastError`; ask the user to install Chrome or Edge |
**Always surface a verb's `_hint` verbatim** when it reports not-ready or failure.
## Node provisioning — you do NOTHING (AD ≥ 1.9.63)
pup is a Node process, but **you no longer install Node.** AD provisions the runtime itself — a system Node
if on PATH, else a portable **no-UAC** copy it downloads to `~/.adom/adom-runtimes/` and prewarms, then
spawns the bridge by absolute path. Do NOT run `desktop_install_node` / npm installers / ask the user to
install Node. On a truly fresh box it may be `installing` for a few seconds after first launch — check
`adom-desktop runtimes '{}'` (`{state: absent|installing|ready|failed}`) and retry once `ready`. (Legacy
`desktop_install_node` — which pops a UAC — is only for AD older than 1.9.63.)
## The shell-approval gate (rarely relevant to pup)
Core AD verbs and pup's own `browser_*` / `desktop_record_*` verbs run with **NO desktop prompt**. Only
open-ended `shell_execute` / `run_script` pop AD's "Shell command needs approval" dialog — which you
almost never need (prefer typed verbs). If one returns `needs_approval` / `human_only` on **AD ≥ 1.9.86**:
run `adom-desktop --target <box> request_shell_approval` (re-surfaces the dialog), ask the user to click
Approve/Bypass, then **retry your original verb**. Never call `shell_auto_approve` (human-only, refuses).
This is AD's own gate, NOT a Windows UAC.