← Commit history

README + skills for the extension-lane world: no CfT in the lead, CDP off by default, isolation per lane, landed, vault, trusted input; stale lane rules removed

John Lauer ·7594d3b6ce ·1mo ago ·parent ea4b25c
4 files changed +46−29
README.md+26−15
@@ -8,16 +8,16 @@ > click, pup does silently for the AI. The goal is an AI that can drive the web the way you would.  **pup is the AI's own browser: a real, full Chrome/Edge window on the user's desktop that the AI drives-with complete programmatic control, but a _sandbox_.** It runs in a fresh, isolated profile that is-never the user's real signed-in browser, and opens in the **background by default** so it never disrupts-them. That trade is exactly why pup exists alongside **nb / nbe** (the native browser and its extension):+with complete programmatic control, but a _sandbox_.** It runs in a profile pup owns (the shared, durable+**adom-you** jar, or a throwaway one when asked), never the user's real signed-in browser, and opens in the+**background by default** so it never disrupts them. That trade is exactly why pup exists alongside **nb / nbe** (the native browser and its extension): nb/nbe drive the user's _real_ browser, their cookies, SSO, saved logins, their identity, for when a task needs to BE the user. pup is the opposite trade: no borrowed identity, but **total control**, a real, disposable browser the AI owns end to end (open/close windows + tabs, navigate, screenshot, eval JS, record). Logged out by design, it's the safe, fully-drivable default for automation, testing, scraping public pages, and showing wiki pages; reach for nb/nbe only when you genuinely need the user's-real logins. pup drives **Chrome for Testing**, the automation build (why: [docs/WHY-CFT.md](/blob/app/pup-bridge/docs/WHY-CFT.md));-pup installs and maintains it by itself, with the machine's installed Chrome/Edge as fallbacks.+real logins. pup runs its own browser build and keeps it current by itself; to the user, and in every reply+an AI writes, these are simply **pup windows**.  **The core goal: an AI-driven browser that can do everything it needs to for you - the best assistant in the world.** By default every pup window surfs on the shared durable **adom-you** profile, and every@@ -26,13 +26,21 @@ usernames and passwords on every site it has ever seen, which is what makes a tr AI browser possible. Isolated throwaway profiles exist for the cases that need them (logged-out testing, acting as another user), but they build nothing: adom-you is the default on purpose. -**pup drives Chrome for Testing (CfT), the build Google ships for automation.** Branded Chrome-fights automation in ways that matter here: the "controlled by automated test software" banner-blips over the window during real driving and cannot be suppressed, and Chrome 137 removed every-silent way to load pup's toolbar extension. CfT has none of those fights, pins a deterministic-version, and lets the Adom Pup toolbar ride every launch as a flag. The full technical record,-including what we tried and verified on branded Chrome, is in-[docs/WHY-CFT.md](/blob/app/pup-bridge/docs/WHY-CFT.md).+**How pup drives a window (September 2026).** Every pup window runs on pup's own **extension lane**: pup's+extension inside the browser polls the bridge and runs the commands, and there is **no debug port**, which is+what the vendor edges (st.com, mouser, arrow) detect and wall. That lane does everything now: trusted mouse+and keyboard input that lands inside cross-origin frames (it drives reCAPTCHA tiles), element and full-page+screenshots, recording through Bridge's native recorder, `pup_fetch_url`, HTTP Basic-Auth answered from the+vault, and one browser **per profile**, so `isolated:true` is a real throwaway jar that ends with its window.+The older DevTools (CDP) lane is **off by default** and opens only when a user enables it for a box. Windows are+born **behind your work and stay there**: a measured ship gate samples the screen twice a second through a+cold start, navigates and warm opens, and passes only when a pup window was never on top.++**Every open and navigate answers `landed`**: the final URL and title, whether it is a sign-in page, and+whether the shared profile is already signed in there, so an AI never asks you to sign in where you already+are. Passwords live in pup's own vault (one DPAPI-protected file per user, no Windows credential cap), captured+as you sign in on either lane, filled on return, importable from your Chrome/Edge in one consent, with+Google account discovery and sign-in as verbs.  > To drive the user's **real, signed-in** Chrome/Edge (their cookies, SSO, saved logins), that's the > **Adom browser extension's `nbrowser_*` verbs**, a separate bridge, not pup.@@ -234,7 +242,7 @@ So it is **opt-in and leased**:  | Verb pair | Captures | How it works under the hood | |---|---|---|-| **`pup_record_start` / `pup_record_stop`** | ONE pup **tab/window**, the page content | **CDP `Page.startScreencast`** (JPEG frames, up to ~50 fps) piped to **ffmpeg**, encoded to **VP9** in real time → one `.webm`. Tab-scoped at the protocol level, so it captures the exact tab even in the **background**, no `getDisplayMedia`, no picker, no foreground. |+| **`pup_record_start` / `pup_record_stop`** | ONE pup **tab/window**, the page content | **Bridge's native recorder** (Windows Graphics Capture, hardware H.264 MP4; a covered window records live) keyed on the window; where that recorder is absent, the DevTools screencast (JPEG frames → ffmpeg VP9 `.webm`) is the fallback, and its encode is a pollable job (`artifactReady`), never a truncated file. | | **`desktop_record_start` / `desktop_record_stop`** (ab-core's capability, served by pup on its behalf until adom-bridge#143 lands) | the WHOLE **desktop** (multiple apps, dialogs) | Screen capture via **MediaRecorder** → one `.webm`; ffmpeg remuxes it to stamp a proper Duration. |  ```bash@@ -296,13 +304,16 @@ This bridge is cloud-owned here (extracted from `adom-bridge/plugins/puppeteer`, kicad/fusion bridges). Bridge ships a bundled seed and auto-pulls newer versions from this page.  - Clone the source: `adom-wiki repo clone adom/pup-bridge`-- Runtime lives in `src/` (`server.js`, `chrome.js`, `bridge.json`, …); the release zip is `src/` at zip-root.+- Runtime: the Rust exe in `rust/` (12 crates; every Win32 call behind the traits in `host`), packaged by `tools/ship.sh`; the release zip is the exe + `bridge.json`. `src/` is the earlier Node shell, kept buildable for macOS until the Mac port of `host-mac` lands.+- Why pup runs its own browser build rather than the user's branded Chrome: [docs/WHY-CFT.md](/blob/app/pup-bridge/docs/WHY-CFT.md) (maintainer reasoning; users just see pup windows). - **Maintainer skills** (`pup-bridge-dev`, `pup-bridge-publish`) are **source-only**, in `dev-skills/` +   `publish-skills/`, not shipped in the pkg (per the Bridge SDK a pkg ships only user skills). Skill map:  | Skill | Ships in pkg? | What it's for | |---|---|---|-| `pup` (root SKILL.md) | ✅ user | Start here, mental model (CDP-launched fresh process of the installed browser, rendered-but-backgrounded), when-vs-extension, quick start |+| `pup` (root SKILL.md) | ✅ user | Start here, mental model (pup's own browser on the extension lane, no debug port, rendered but born behind your work), when-vs-nb, quick start |+| `pup-lanes` | ✅ user | The extension lane (default, everything) versus the CDP lane (off by default); what still needs CDP and what to do instead |+| `pup-credentials` | ✅ user | The vault, capture and autofill, Basic-Auth, Google sign-in, importing your browser logins, `landed`, the per-site login recipes | | `pup-windows-sessions-tabs` | ✅ user | sessionIds, window ownership (don't steal another thread's window), background-vs-foreground, many tabs in one window | | `pup-screenshots-recording` | ✅ user | Screenshots (full-page/full-res) + recording; driving/verifying tricky pages (shadow DOM, nested scroll) | | `pup-browsers-and-chrome` | ✅ user | Browser detection/launch, `pup_use`, installing Chrome/CfT (incl. UAC-notify), readiness, cold-start errors |
SKILL.md+10−6
@@ -400,8 +400,9 @@ Nothing here needed nb. Conditions that matter:  1. **Drive the site through pup, not a hand-rolled Chrome.** Re-measured 2026-09-14 with screenshots:    analog.com rendered fully in pup on CfT 152 on the adom-you profile. A second arm meant to be a-   fresh jar was NOT one: `isolated:true` does not create a separate profile (pup-bridge#112), so that-   run used adom-you twice. Whether profile state matters is UNTESTED, not ruled out. An earlier version+   fresh jar was NOT one: before 2.0.659 `isolated:true` did not create a separate profile (pup-bridge#112),+   so that run used adom-you twice. Since 2.0.659 an isolated window is its own extension-lane browser with an+   empty jar (measured), so the fresh-jar arm can be re-run; until it is, profile state stays UNTESTED. An earlier version    of this skill claimed the CfT 148 to 152 bump was the fix. That claim came from comparing pup against    raw `shell_execute` Chrome launches that lacked pup's flag set (no `--disable-infobars`, different    feature disables, no identity shim), which is not a valid comparison. What makes these sites load is@@ -443,10 +444,13 @@ chars WITH a title is a bot wall, not a slow load. `pup_annotate`, `pup_screenshot` (a covered window included), `pup_screenshot_element`, `pup_screenshot_full_res`, `pup_record_start` / `pup_record_stop` (through ab's native recorder), and `pup_eval` on pages whose CSP or Trusted Types refuse injected script (Google Calendar, Admin, the wiki),-which it retries through DevTools on its own. Still CDP-only, answered with `lane_needs_cdp` and the fix:-selector-driven `pup_download`, `realKeystrokes` logins, iframe targeting, separate profiles, `highFps`,-`webSecurity:false`. Do not reopen with `lane:"cdp"` for input or eval; the `pup-lanes` skill is the-authority on what each lane does.+which it retries through DevTools on its own. Still CDP-only (answered with `lane_needs_cdp`): selector-driven+`pup_download` (a URL download works on this lane), `realKeystrokes` logins, iframe targeting, `highFps`,+`webSecurity:false`. Everything else moved to this lane: `isolated:true` and `profile` open their own+extension-lane browser (2.0.659), `pup_input_dispatch` is trusted input and takes a `selector` (2.0.648/649),+HTTP Basic-Auth is answered from the vault (2.0.644), and `pup_fetch_url` runs here (2.0.648). The CDP lane is+OFF by default since 2.0.652 (`cdp_lane_disabled`; a user enables it per box with `pup_configure {cdpLane:"on"}`).+Do not reopen with `lane:"cdp"` for input or eval; the `pup-lanes` skill is the authority on what each lane does.  **When it will NOT help.** A site that denies a profile with no established trust denies every client, including the user's real Chrome driven by the real extension (analog.com does exactly this on a cold
skills/pup-lanes/SKILL.md+7−6
@@ -9,7 +9,8 @@ description: "Parent skill: pup. The two ways pup drives a pup window (never nam The point of the September 2026 work (John, 2026-09-13 and 14) was one thing: pup windows that load EVERY website without the site blocking us. That turned out to be the extension lane. So it is the default, and the CDP lane opens only when an AI writes `lane:"cdp"` because the task needs something-only CDP can do. pup no longer falls back to CDP on its own for any reason.+only CDP can do AND the user has turned that lane on for the box (`cdpLane`, off by default since 2.0.652:+`cdp_lane_disabled` otherwise). pup no longer falls back to CDP on its own for any reason.  ## What each lane is @@ -17,7 +18,7 @@ only CDP can do. pup no longer falls back to CDP on its own for any reason. |---|---|---| | How pup drives the window | pup's own MV3 extension polls the bridge and runs the commands inside Chrome | Chrome DevTools Protocol over `--remote-debugging-port` | | Debug port | none | yes, and vendor edges detect it (measured: st.com and mouser RST the HTTP/2 stream, arrow denies) |-| Profile | the shared adom-you browser, one process, every thread's windows in it | any profile; on adom-you it TAKES the profile from the extension lane and closes those windows |+| Profile | one browser per profile: adom-you is shared by every thread; `isolated:true` and `profile:"<name>"` get their own lane browser, extension and queue (2.0.659) | any profile; on adom-you it TAKES the profile from the extension lane and closes those windows | | Toolbar | four icons: pup dots, pen, identity tile, nbe | three icons (nbe rides the extension lane only) | | Taskbar identity, tiles, overlays, jump lists | yes: branded BEFORE the first show (2.0.567), tile and overlay badge drawn in the binary | yes | | Annotate (pen, snip) | yes (2.0.569, Trusted-Types safe since 2.0.570) | yes |@@ -33,7 +34,7 @@ only CDP can do. pup no longer falls back to CDP on its own for any reason. - Since 2.0.578 the extension lane ALSO has trusted input (`pup_click`, `pup_hover`, `pup_type`, `pup_press_key`, `pup_scroll`, `pup_fill`), element and full-resolution screenshots, `pup_select` (a `<select>` by value or label, 2.0.592), and CSP-proof `pup_eval` (a page whose Content-Security-Policy or Trusted Types policy refuses the injected eval is retried through DevTools automatically, 2.0.591; Google Calendar and Admin are the everyday cases). They ride nbe's DevTools driver inside the lane (`chrome.debugger`, attached to one tab on demand, detached after nbe's idle window; no debug port, no automation flag, `navigator.webdriver` stays false, no bar). Since 2.0.581 recording (`pup_record_start` / `pup_record_stop`) works on this lane too: it rides ab's native recorder (Windows Graphics Capture, hardware H.264 MP4, keyed on the window handle), which records a covered window live and emits frames only when the content changes. Still CDP-only: selector-driven `pup_download`, `realKeystrokes` logins, iframe targeting, separate profiles (backlog: pup-bridge#113), `highFps`, `webSecurity:false`. Those answer `lane_needs_cdp` with the fix.  **CDP lane**-- Pro: everything DevTools can do: trusted mouse and keyboard events, cross-origin iframes, `Runtime.evaluate` that ignores page CSP, element and full-res screenshots, annotate, recording, emulation, separate profiles, anti-throttle for a live view.+- Pro: everything DevTools can do: trusted mouse and keyboard events, cross-origin iframes, `Runtime.evaluate` that ignores page CSP, element and full-res screenshots, annotate, recording, emulation, anti-throttle for a live view. - Con: the debug port is a detection surface. A CDP window is what gets you "Access Denied" on the hard vendor sites. - Con: `lane:"cdp"` on adom-you evicts the extension lane: pup closes every extension-lane window to hand the profile over, because Chrome runs one process per profile. Other threads lose their windows. That is why it is opt-in. - Con: three toolbar icons, no nbe.@@ -41,9 +42,9 @@ only CDP can do. pup no longer falls back to CDP on its own for any reason. ## The rule  1. Open windows with no `lane`. You get the extension lane.-2. Do not pass `profile`, `isolated`, `highFps` or `webSecurity:false` unless you also pass `lane:"cdp"`. Without it pup refuses with `cdp_lane_required` and says why. Since 2.0.563 nothing silently opens on CDP.-3. Pass `lane:"cdp"` only when the task needs a CDP-only feature, say which one in `reason`, and expect vendor sites to wall that window.-   A pup update reaches a running extension lane on its own: pup re-stages the extension and asks the worker to reload in place (2.0.569), so no window has to close for a new build to take effect. `pup_status.extensionLane.workerVersion` shows what the lane is running.+2. `profile` and `isolated` need no lane (2.0.659: their own extension-lane browser). Only `highFps` and `webSecurity:false` still need `lane:"cdp"`; without it pup refuses with `cdp_lane_required` and says why. Since 2.0.563 nothing silently opens on CDP.+3. Pass `lane:"cdp"` only when the task needs a CDP-only feature, say which one in `reason`, expect vendor sites to wall that window, and expect `cdp_lane_disabled` unless the user enabled the lane on that box.+   A pup update reaches a running extension lane on its own: pup re-stages the extension, cycles the lane browser and relaunches every window from its file on the new extension (2.0.647; the 2.0.569 in-place reload broke the channel and is gone), so a new build takes effect without anyone closing a window. `pup_status.extensionLane.workerVersion` shows what the lane is running. 4. If a verb answers `lane_needs_cdp`, first ask whether the task can be done without it (a screenshot instead of an eval on a CSP page, a URL download instead of a click). Only then reopen with `lane:"cdp"`.  ## How you tell them apart
skills/pup-why-cft/SKILL.md+3−2
@@ -53,8 +53,9 @@ CfT 152. itself. Those two differ in far more than the build number (pup passes `--disable-infobars`, a different feature-disable set and the identity shim; the raw launches visibly showed the automation infobar). Re-measured with screenshots on 2026-09-14, analog.com rendered fine in pup on CfT 152 on the-adom-you profile. The intended fresh-jar arm was not fresh: `isolated:true` keeps the adom-you-profile (pup-bridge#112), so profile state remains UNTESTED.+adom-you profile. The intended fresh-jar arm was not fresh: before 2.0.659 `isolated:true` kept the adom-you+profile (pup-bridge#112). Since 2.0.659 it is its own extension-lane browser with an empty jar, so the arm can be+re-run; until it is, profile state remains UNTESTED.  **What is actually established:** sites in this class load when driven through pup's own launch path. Which element of that launch is decisive has NOT been isolated, and it has NOT been shown to be the