app
Pup - the AI's own browser
Public Made by Adomby adom
pup gives your AI a real browser on your desktop that it drives completely, in the background, signed in as you: windows that never jump in front of your work, one shared profile that learns your logins, and every window labeled on the taskbar with its AI thread's name.
← Commit history
Skill sweep, browser-policy pass: the /pup mental model and the entire /pup-browsers-and-chrome sub-skill still taught the mid-2026 native-first policy (drives the browser already on the machine, CfT is the last resort), which docs/WHY-CFT.md reversed for good on 2026-08-10 (automation banner; branded Chrome 137+ removed --load-extension, which the toolbar needs). Both now teach CfT-first with installed Chrome/Edge as the spawn-verified fallback ladder, which is also what pup_readiness reports on a live box (browserKind: chrome-for-testing). The stale native-first editorial in chrome.js is flagged in place with a warning note, with the base order deliberately unchanged because it IS the fallback ladder. Also: the no-semicolons pup_eval reminder in the screenshots skill updated for the 2.0.274 statement support.
4 files changed
+40−20
SKILL.md+17−11@@ -131,12 +131,15 @@ credential is persisted, not just used once. pup is a small **Node bridge** that Bridge spawns on the user's machine. When you open a window it does NOT attach to the user's running browser and does NOT run headless. It: -1. **Launches a brand-new process of the browser ALREADY installed** on the machine — **installed Chrome- first, else Microsoft Edge**. On **Windows** every PC ships Edge, so there's almost always a candidate- and **no download**. On **macOS** nothing is guaranteed: Safari is not CDP-drivable, and Edge is not- preinstalled — so on a Mac with no Chrome, pup falls through to downloading Chrome (or cached Chrome- for Testing). Don't promise the user "no download" off Windows; check `pup_readiness` instead. It- uses their *browser binary*, never their *profile*.+1. **Launches a brand-new browser process — Chrome for Testing by policy** (2026-08-10, pup 2.0.53+;+ the full dated record is `docs/WHY-CFT.md`). CfT is the build Google ships FOR automation: no+ "controlled by automated test software" banner flicker, and it still honors `--load-extension`,+ which branded Chrome 137+ removed — the pup toolbar family ONLY loads on CfT. Installed Chrome,+ then Edge, remain the spawn-verified FALLBACK ladder (used while CfT is still downloading, or if+ the cached CfT breaks), so an open never hard-fails; but do not describe pup as "driving the+ installed browser" — that was the mid-2026 policy and it was reversed. Check `pup_readiness`+ for which browser a box actually runs. Either way pup uses a *browser binary*, never the user's+ *profile*. 2. **…with a pup-managed `--user-data-dir` + a CDP debugging port** (`--remote-debugging-port`), driven over the Chrome DevTools Protocol. This is a profile **pup owns and persists**, never the user's own signed-in OS Chrome/Edge profile. By default every window shares ONE durable profile (`adom-you`), so logins,@@ -152,10 +155,12 @@ does NOT attach to the user's running browser and does NOT run headless. It: `SWP_NOACTIVATE`; macOS: the browser process is **hidden**, the Cmd+H state — same contract), so it renders **without stealing focus and without covering the user's active window**. You drive and screenshot it fully while it stays hidden. `foreground:true` is the ONLY thing that shows it.-4. **Spawn-verifies + falls through.** The pick order is **Chrome → Edge → cached Chrome for Testing**; pup- actually launches each and, if one won't start (corrupt install), falls to the next — so an open never- hard-fails on a broken browser. The one that launches is **cached as the default**. Only a box with *no*- Chromium at all fetches **Chrome for Testing** (~150 MB, last resort).+4. **Spawn-verifies + falls through.** The effective order is **pinned/cached default first** (CfT,+ per policy) **→ installed Chrome → Edge → cached CfT**; pup actually launches each and, if one+ won't start (corrupt install), falls to the next — so an open never hard-fails on a broken+ browser. The one that launches is **cached as the default** and goes first next time. On a box+ where CfT is not yet cached, `pup_prewarm` fetches it (~150 MB, once) so the first real open is+ instant. 5. **Is addressed by your `--ai-thread` name** (zero-id: omit ids and your thread's window is implied), and **one window holds many tabs**. An explicit `window` label (legacy alias: `sessionId`) is needed only when one thread deliberately runs several windows.@@ -324,7 +329,8 @@ adom-bridge-cli --ai-thread "<your thread>" pup_screenshot '{}' `pup-windows-sessions-tabs`. - **`ok:true` means navigation *started*, not that content rendered** — sanity-check with `pup_eval` on `document.title` (404s / login walls change it) or a screenshot.-- **On a fresh PC it's usually a non-event** — pup drives the installed Chrome/Edge with no download. The+- **On a fresh PC the first open may include the one-time CfT fetch** (~150 MB; `pup_prewarm` does+ it ahead of time, and installed Chrome/Edge serve as the interim fallback so nothing blocks). The rare "no browser at all" / Node-provisioning / disk cases are all in `pup-browsers-and-chrome`. ## macOS differences (v1.9.74+) — same verbs, mac-native mechanics
skills/pup-browsers-and-chrome/SKILL.md+15−8@@ -10,11 +10,17 @@ description: "How pup (Puppeteer bridge) picks and launches a browser, and every ## 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:+**POLICY (2026-08-10, pup 2.0.53+): pup's driving browser is Chrome for Testing.** The dated record+of why is `docs/WHY-CFT.md` on the wiki page — the policy has flipped twice, and the current flip is+final: branded Chrome asserts the "controlled by automated test software" banner during real+automation, and branded Chrome 137+ removed `--load-extension`, which the pup toolbar family needs.+This section previously opened with "pup drives the browser already on the machine"; that was the+mid-2026 policy and is REVERSED. What survives of it is the fallback ladder below, which is why a+missing or still-downloading CfT never blocks an open. On every open pup 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**.+1. **Pinned/cached default first (CfT, per policy) → installed Chrome → Edge → cached CfT.** Every+ Windows PC ships Edge, so there is always an interim candidate while CfT downloads. 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).@@ -22,8 +28,9 @@ builds a candidate list and **spawn-verifies** it: 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.+5. **The CfT fetch (~150 MB) happens once** — at prewarm, at first need, or when pinned via+ `pup_use {browser:"cft"}`. Installed Chrome/Edge are the FALLBACK, not the destination: expect a+ healthy box to report `browserKind: chrome-for-testing` in `pup_readiness`. ## "Is it ready / which browser?" — `pup_readiness` (READ-ONLY) @@ -72,14 +79,14 @@ adom-bridge-cli pup_use '{"browser":"chrome","install":true}' 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)+## Installing / prewarming Chrome for Testing (the policy browser) ```bash adom-bridge-cli pup_prewarm '{}' # fetch CfT WITHOUT opening a window, then pin it (poll readiness) adom-bridge-cli pup_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+Worth running on ANY fresh box so the first real open skips the download (the fallback ladder covers the gap meanwhile). **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.
skills/pup-screenshots-recording/SKILL.md+3−1@@ -100,6 +100,8 @@ result just means a wrong selector on plain DOM. nested-scroll SPA it returns just the viewport and a `nestedScroll:true` hint — use `pup_screenshot_element` for one region, or `pup_scroll` through the container. -Reminder: `pup_eval` allows **no semicolons** — use the comma operator or an IIFE. If a+Reminder: since v2.0.274 `pup_eval` accepts statement lists (semicolons fine — a syntax error in+the expression form retries with devtools-console semantics, and bad code fails honestly with+`eval_failed`); a comma-operator/IIFE still gives the cleanest single-expression result. If a screenshot lands on the wrong content, don't trust it — it almost always means an inner scroll container; re-scroll the element, don't nudge the window.
src/chrome.js+5@@ -179,6 +179,11 @@ function markVerified(cand) { // Each entry is a fully-launchable {kind, executablePath, source}. The launch path // tries them top-to-bottom and spawn-verifies each, so a broken top pick falls through. function launchCandidates() {+ // ⚠ 2026-08-22: the EDITORIAL below is STALE POLICY — kept for the history, but the current+ // policy is CFT-FIRST again (2026-08-10, docs/WHY-CFT.md: the automation banner + branded Chrome+ // 137 removing --load-extension, which the toolbar family needs). The BASE ORDER here stays+ // native-first ON PURPOSE: it is the fallback ladder, and the pinned/cached CfT default that+ // readDefault() promotes to the front is what implements the policy. Do not "fix" this order. // v1.9.90 (John's call, verified against this code): NATIVE-FIRST. The installed browser comes // FIRST — installed Chrome, else Edge (ships on every Windows PC) — driven with a FRESH // --user-data-dir AND the noBrowserIdentityFlags (server.js) that kill the sign-in / "set up a