app
Pup - Puppeteer Bridge
Public Made by Adomby adom
pup is the AI's own browser: a real, full Chrome on the user's desktop that the AI fully controls (a sandbox, not the user's signed-in browser). Rides Bridge; pup_* verbs open windows and tabs, navigate, screenshot, and eval JS.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
{
"schema_version": 1,
"type": "app",
"slug": "pup-bridge",
"title": "Pup - Puppeteer Bridge",
"brief": "pup is the AI's own browser: a real, full Chrome on the user's desktop that the AI fully controls (a sandbox, not the user's signed-in browser). Rides Bridge; pup_* verbs open windows and tabs, navigate, screenshot, and eval JS.",
"version": "2.0.18",
"tags": [
"skills",
"pup",
"puppeteer",
"browser",
"adom-bridge",
"bridge",
"pup-bridge"
],
"license": "MIT",
"discovery_triggers": [
"pup",
"open in pup",
"open my app in pup",
"open it in pup",
"open this in pup",
"show me in pup",
"show it in pup",
"open a pup window",
"pup window",
"screenshot my app",
"screenshot the page",
"browser screenshot",
"pup screenshot",
"record the window",
"record a browser window",
"record a pup",
"record my app",
"new pup tab",
"pup tabs",
"browser tabs",
"close the pup window",
"reload the page in pup",
"eval js in the page",
"drive a browser",
"headful browser automation",
"visual debug",
"puppeteer",
"puppeteer bridge",
"pup bridge",
"chrome for testing",
"chrome automation bridge",
"pup_open_window",
"pup_screenshot",
"pup_record_start",
"pup_readiness",
"fork the pup bridge",
"puppeteer bridge source"
],
"discovery_pitch": "Use pup to drive Chrome from the cloud: open/close browser windows + tabs, navigate, screenshot, eval JS, and record windows. It drives the browser ALREADY on the machine, installed Chrome, else Microsoft Edge (every Windows PC has Edge), with a fresh isolated profile, so usually NO download and it doesn't disrupt the user; Chrome for Testing is fetched only as a last resort. For 'is it ready' use pup_readiness. Or pass nativeBrowser+nativeProfile to drive the user's REAL signed-in Chrome/Edge/Brave. Call the adom-bridge-cli pup_* verbs.",
"sample_prompts": [
{
"label": "Open in pup",
"prompt": "Open my app in pup (pup_open_window) and screenshot it"
},
{
"label": "Screenshot a page",
"prompt": "Screenshot https://example.com in pup"
},
{
"label": "Record a window",
"prompt": "Record a 30-second video of this pup tab (pup_record_start/stop)"
},
{
"label": "Many tabs, one window",
"prompt": "Open these 5 URLs as tabs in one pup window"
},
{
"label": "Drive my real Chrome",
"prompt": "Open the GCP console in my real signed-in Chrome via pup native mode"
},
{
"label": "Read the bridge source (dev)",
"prompt": "Download the puppeteer-bridge zip from the wiki and walk me through server.js"
}
],
"install": {
"binary_name": "pup-bridge",
"install_dir": "",
"install_hint": "",
"version_cmd": ""
},
"readme": "# pup: the Puppeteer bridge\n\n**pup is the AI's own browser: a real, full Chrome/Edge window on the user's desktop that the AI drives\nwith complete programmatic control, but a _sandbox_.** It runs in a fresh, isolated profile that is\nnever the user's real signed-in browser, and opens in the **background by default** so it never disrupts\nthem. That trade is exactly why pup exists alongside **nb / nbe** (the native browser and its extension):\nnb/nbe drive the user's _real_ browser, their cookies, SSO, saved logins, their identity, for when a\ntask needs to BE the user. pup is the opposite trade: no borrowed identity, but **total control**, a\nreal, disposable browser the AI owns end to end (open/close windows + tabs, navigate, screenshot, eval\nJS, record). Logged out by design, it's the safe, fully-drivable default for automation, testing,\nscraping public pages, and showing wiki pages; reach for nb/nbe only when you genuinely need the user's\nreal logins. pup drives the browser **already on the machine** (installed Chrome, else Microsoft Edge;\nevery Windows PC ships Edge), so the common case needs no download.\n\n**The core goal: an AI-driven browser that can do everything it needs to for you - the best assistant\nin the world.** By default every pup window surfs on the shared durable **adom-you** profile, and every\nlogin made there enriches a shared credential store. Over time that store lets pup automatically enter\nusernames and passwords on every site it has ever seen, which is what makes a truly self-sufficient\nAI browser possible. Isolated throwaway profiles exist for the cases that need them (logged-out\ntesting, acting as another user), but they build nothing: adom-you is the default on purpose.\n\n> To drive the user's **real, signed-in** Chrome/Edge (their cookies, SSO, saved logins), that's the\n> **Adom browser extension's `nbrowser_*` verbs**, a separate bridge, not pup.\n\nCanonical page: **https://wiki.adom.inc/adom/pup-bridge**\n\n## Install vs Download, which is which (and why the version numbers differ)\n\nThe page header shows **two** things, for two different places. Most people need only the first.\n\n| On the page | What it is | Who runs it | You usually… |\n|---|---|---|---|\n| **Install**, `adom-wiki pkg install …` | The **AI skill pack**, the `pup` skills that teach a cloud/container AI how to drive the bridge. Docs only, no runtime; drops into `~/.claude/skills` + `~/.codex/skills`. | your **container / cloud AI** | **run this** (or it arrives via `sync_skills`) |\n| **Download for your machine**, `adom-bridge-puppeteer-v<ver>.zip` | The **bridge runtime**, the actual Node program (browser detection + driving) that runs on the desktop. | **Bridge**, on the user's PC | **do nothing**, Bridge **auto-installs & auto-updates** it; the manual download is only for offline/manual installs |\n\n**Why two different version numbers?** They're independent artifacts. The **Install (pkg)** version bumps\nwhenever the *skills/docs* change (often). The **Download (runtime)** version bumps only when the *bridge\ncode* changes (rarely). So it's normal to see e.g. Install `v1.8.27` and Download `v1.8.20`, nothing is\nout of sync; they just version on their own clocks.\n\n*(There's also a third copy, the runtime is **bundled inside the Bridge installer** as a first-run\nseed, superseded by a newer cache copy via `updateManifestUrl`. You never touch it directly.)*\n\n## Use it\n\n```bash\n# everyday: open + screenshot. Opens in the BACKGROUND automatically, no need to lower it,\n# and it's fully drivable/screenshottable while hidden, so the user is never interrupted.\nadom-bridge-cli pup_open_window '{\"sessionId\":\"myapp-web\",\"owner\":\"myapp\",\"url\":\"http://localhost:3000\"}'\nadom-bridge-cli pup_screenshot '{\"sessionId\":\"myapp-web\"}'\n\n# readiness (use pup_readiness, NOT pup_status). On a box with Chrome or Edge this is\n# instantly {ready:true} with no download. Only a box with no Chromium at all fetches Chrome for\n# Testing in the background, poll until ready, then open.\nadom-bridge-cli pup_readiness '{}' # → {ready:true, browserKind:\"chrome\"|\"edge\"|...}\n```\n\n- **Task-prefix your `sessionId` + pass `owner`**, sessions are shared across every AI thread on the\n desktop; that lets pup protect your window from another thread navigating it away.\n- **`foreground:true` is the only way to show a window**, sizing/positioning does not foreground it.\n\nFull everyday usage (tabs, recording, window ownership, cold-start playbook) is in the `pup` skill\n(`SKILL.md`).\n\n## Window-type taskbar icons: read a pup window at a glance\n\n\n\nEvery pup window's **taskbar icon states what kind of thing it is showing**. All five share the same\ndrawing (the teal Adom tile carrying a solid browser window) and differ only in the window's\n*content*: a monochrome glyph on the 24x24 Adom house grid, per the brand icon law (single color,\nno gradients, no emoji):\n\n| Icon | Window content | Means |\n|---|---|---|\n|  | open book | **Adom wiki, public view**: logged out, what the world sees |\n|  | book + person | **Adom wiki, signed in**: the user's logged-in view (private source, drafts, owner cards) |\n|  | the Adom mark | **An Adom app**: localhost or a cloud-slug proxy URL |\n|  | globe | **The web**: any other site (ti.com, digikey, ...) |\n|  | two panes | **Mixed**: the window's tabs span more than one category |\n\n- The category is derived from **all tabs** in the window; it updates **live** (add a digikey tab\n to a wiki window and the icon flips to *mixed* within about a second).\n- The **overlay badge** riding the icon's corner is separate and sacred: it is the **active tab's\n own favicon**, so you always see which site you are looking at. In grouped-taskbar mode it shows\n window/tab counters instead.\n- The **tab title** carries the same login signal in text: a solid dot (`● Logged in`) or hollow dot\n (`○ Public`) leads the title of every Adom wiki tab.\n- Under the hood, each window's identity (icon, name, Alt-Tab entry) rides a per-session Windows\n AppUserModelID that **carries the category**: the only way Win11 allows a taskbar tile to change\n live. Grouped mode instead keeps one stable, pinnable `Adom.Pup` identity.\n\n### Using pup's icons in your own tool (HD browser picker, launchers, menus)\n\nIf you are building a surface that offers \"open a pup window\" (a browser picker, a launcher tile, a\nmenu item), **use pup's real icon, not a stand-in.** The canonical, self-describing asset set lives\nin the wiki repo at [`assets/pup-icons/`](assets/pup-icons/), in three formats:\n\n- **SVG** (`pup-cat-*.svg`), scalable, the right choice for a web/Tauri picker.\n- **PNG** (`pup-cat-*-{32,48,128,256,512}.png`), raster fallback / retina.\n- **ICO** (`pup-cat-*.ico`), Windows multi-size, for taskbar/shortcut contexts (256px frame is\n PNG-compressed, per the Vista+ rule, so it never renders as a generic document).\n\n**For a launcher/picker item, use `pup-cat-default`**, the neutral teal browser-window tile. It is\nwhat a pup window's taskbar button looks like before its content is known, so the picker previews the\nreal result. The five category icons above (`wiki`, `wiki-in`, `app`, `web`, `mixed`) are for\n*showing an existing window's kind*, not for a generic \"open pup\" action.\n\nFetch any asset from the wiki without cloning:\n\n```\nhttps://wiki.adom.inc/api/v1/pages/pup-bridge/files/assets/pup-icons/pup-cat-default.svg\nhttps://wiki.adom.inc/api/v1/pages/pup-bridge/files/assets/pup-icons/manifest.json\n```\n\n[`assets/pup-icons/manifest.json`](assets/pup-icons/manifest.json) is machine-readable: it maps each\nicon id to its meaning, its glyph, and its file in every format, and names\n`recommended_for_launcher` so a tool can pick the right one programmatically. Brand rule if you ever\nredraw one: teal tile `#00b8b0` + dark-teal window body `#003d40` + a single-color teal glyph, no\ngradients, shadows, or emoji.\n\n## Real windows, one per type\n\nFull windows as pup opens them (title bar, tabs, page). Note the tab title glyphs on the wiki pair\nand the signed-in header on the second:\n\n**Adom wiki, PUBLIC** (tab: `○ Public`, page header shows Login):\n\n\n\n**Adom wiki, SIGNED IN** (tab: `● Logged in`, page header shows the user's name):\n\n\n\n**An Adom app** (here: the shotlog viewer on a cloud slug URL):\n\n\n\n**The web** (ti.com):\n\n\n\n**Mixed** (a digikey tab and a wiki tab in one window):\n\n\n\n## Overlay badges: the corner of the taskbar icon\n\n\n\nThe base icon states the window TYPE; the small overlay riding its lower-right corner carries\nLIVE detail, composited exactly like this:\n\n| Overlay | When | What it tells you |\n|---|---|---|\n| the active tab's **favicon** on a dark rounded plate | split mode, page serves a favicon | which site the active tab is on, at a glance |\n| a **count badge** (white digit, dark plate) | split mode, 2+ tabs and no favicon | how many tabs the window holds |\n| the **dual counter** (dark = windows, teal = total tabs) | grouped mode | how much is stacked under the single Adom Pup button |\n\nThe overlay never carries branding or state that belongs to the base icon: it is live per-window\ndetail only, and the favicon always wins the slot when one exists.\n\n## The Adom wiki: logged-in vs public view, and the taskbar toggle\n\npup can show any Adom wiki page from **two viewpoints**, and both the AI and the user can switch:\n\n- **Public (default)**: a fresh logged-out profile: exactly what the world sees. Use it to verify\n what a publish actually exposed.\n- **Signed in**: `pup_open_window {..., wikiView:\"authed\"}` routes to a reserved persistent\n profile whose cookie jar holds the user's ~30-day SSO session. One login serves **every** AI\n thread on the machine. First use returns `wikiLoginNeeded:true`; the user signs in once, in that\n window.\n\n**The user can flip a wiki window themselves**: right-click its taskbar button: the jump list\ncarries **\"Adom wiki: switch to logged-in view\"** (or \"...switch to public view\"). Clicking it\nrelaunches that same window under the other cookie jar, brings it to the front, and shows an\non-screen caption while it works (\"Switching to the logged-in view of the Adom wiki\", then\n\"Adom wiki: now the LOGGED-IN view (Their Name)\"). The AI-side equivalent is the\n`pup_wiki_set_view` verb, which exists for that jump-list click: AI threads should pass\n`wikiView` on open instead.\n\n## One session, one OS window\n\nEvery pup session gets its **own OS window**, even when sessions share a browser profile (as all\nsigned-in wiki windows share the authed cookie jar). This is what makes per-window identity\npossible: a window's title belongs to its active tab, so windows that share sessions as tabs\ncannot be found, branded, flashed, or given jump lists individually. Sharing a profile shares the\ncookies; it never merges windows.\n\n## Recording\n\npup can record what it drives, a **single tab/window** or the **whole desktop**, straight from the\ncloud, with no HUD and no need to bring the window forward.\n\n\n\n*Above: a GIF preview of a real `pup_record` capture (≈8.6 s, the tab navigating the Adom wiki, recorded in the background on a VM). The native capture is the WebM linked below, this GIF is just an inline preview.*\n\n### High-FPS windows: recording something the user is not looking at\n\npup windows are backgrounded by design, and Chrome throttles a window that is occluded, so\nrecording one normally yields a **1-2 fps** video. pup can disable Chrome's power-saving to keep a\nwindow painting at full rate, but a window in that mode can never idle down (three of them once\ndrained a laptop overnight, wiki issue #14).\n\nSo it is **opt-in and leased**:\n\n- **Default** is Chrome's own power behaviour. Normal windows throttle when occluded and cost\n nothing in the background. Right for driving, scraping and screenshots.\n- **`pup_open_window {highFps:true}`** renders at full rate while occluded, for background\n recording. It holds a lease (default 20 min), and **an active recording holds that lease open\n indefinitely, so a take is never cut off**. On lapse the window is *downgraded* back to normal\n power by relaunching with its tabs intact, never closed.\n- **`pup_highfps_extend {sessionId, minutes}`** negotiates more time up front.\n\n**Full details, defaults, activity signals, and rules of thumb: [RECORDING.md](RECORDING.md).**\n\n### Two recorders, pick by what you're capturing\n\n| Verb pair | Captures | How it works under the hood |\n|---|---|---|\n| **`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. |\n| **`desktop_record_start` / `desktop_record_stop`** | the WHOLE **desktop** (multiple apps, dialogs) | Screen capture via **MediaRecorder** → one `.webm`; ffmpeg remuxes it to stamp a proper Duration. |\n\n```bash\nadom-bridge-cli pup_record_start '{\"sessionId\":\"demo-web\"}' # → { recordingId }\n# ...drive the scene: navigate, click, type, scroll...\nadom-bridge-cli pup_record_stop '{\"sessionId\":\"demo-web\",\"recordingId\":\"<id>\"}' # → { path: \"...webm\" }\n```\n\n**ffmpeg** is required for recording. The bridge auto-detects it (a WinGet `Gyan.FFmpeg` install, PATH,\nor common dirs) and re-checks **lazily on `record_start`**, so if it's missing you can\n`winget install Gyan.FFmpeg` and just retry, no bridge restart. `pup_record_status` /\n`pup_record_list` (and the `desktop_record_*` equivalents) report in-flight and finished captures.\n\n### Formats, one native format, easy conversion\n\npup records to **one** format natively: **WebM (VP9)**, for both recorders. It doesn't offer a format\nswitch; instead, convert with the bundled ffmpeg when you need MP4 or GIF. Real numbers from the ≈8.6 s\ndemo above (1264×705):\n\n| Format | Codec | Size | How you get it | Best for | Watch out for |\n|---|---|---|---|---|---|\n| **WebM** ([view](https://wiki.adom.inc/api/v1/pages/pup-bridge/files/pup-recording-demo.webm)) | VP9 | **143 KB** | pup's **native** output, no step | Chrome/Edge/Firefox, small + high quality, the source of truth | Older **Safari**, PowerPoint, and some chat apps don't accept VP9/WebM |\n| **MP4** ([view](https://wiki.adom.inc/api/v1/pages/pup-bridge/files/pup-recording-demo.mp4)) | H.264 | **135 KB** | transcode (below) | **Universal**, Safari, iOS, PowerPoint, Slack/Teams, \"send it to anyone\" | H.264 needs **even width & height**, odd dims (like 705) fail at frame 0; the `scale` filter forces even |\n| **GIF** ([view](https://wiki.adom.inc/api/v1/pages/pup-bridge/files/pup-recording-demo.gif)) |, | **192 KB** | transcode (below) | Auto-playing, looping **inline preview** in any README/chat/GitHub, no player, no click (like the one above) | No audio, capped colors, and it balloons fast at higher fps/resolution/length, keep it short + downscaled |\n\n```bash\n# → MP4 (H.264, universal). The scale filter forces EVEN dimensions (H.264 rejects odd w/h → frame 0).\nffmpeg -i rec.webm -vf \"scale=trunc(iw/2)*2:trunc(ih/2)*2\" -c:v libx264 -crf 23 -pix_fmt yuv420p -movflags +faststart rec.mp4\n\n# → GIF (silent, looping inline preview). Palette pass keeps colors clean; drop fps/scale to shrink.\nffmpeg -i rec.webm -vf \"fps=12,scale=640:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse\" rec.gif\n```\n\n**Rule of thumb:** keep **WebM** for archiving + web embeds; make an **MP4** the moment a human on Safari/\nPowerPoint/phone needs it; make a short **GIF** only for an inline auto-play preview.\n\n## Source & development\n\nThis bridge is cloud-owned here (extracted from `adom-bridge/plugins/puppeteer`, mirroring the\nkicad/fusion bridges). Bridge ships a bundled seed and auto-pulls newer versions from this page.\n\n- Clone the source: `adom-wiki repo clone adom/pup-bridge`\n- Runtime lives in `src/` (`server.js`, `chrome.js`, `bridge.json`, …); the release zip is `src/` at zip-root.\n- **Maintainer skills** (`pup-bridge-dev`, `pup-bridge-publish`) are **source-only**, in `dev-skills/` +\n `publish-skills/`, not shipped in the pkg (per the Bridge SDK a pkg ships only user skills). Skill map:\n\n| Skill | Ships in pkg? | What it's for |\n|---|---|---|\n| `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 |\n| `pup-windows-sessions-tabs` | ✅ user | sessionIds, window ownership (don't steal another thread's window), background-vs-foreground, many tabs in one window |\n| `pup-screenshots-recording` | ✅ user | Screenshots (full-page/full-res) + recording; driving/verifying tricky pages (shadow DOM, nested scroll) |\n| `pup-browsers-and-chrome` | ✅ user | Browser detection/launch, `pup_use`, installing Chrome/CfT (incl. UAC-notify), readiness, cold-start errors |\n| `pup-adom-wiki` | ✅ user | Driving + verifying `wiki.adom.inc` pages in pup (view/screenshot/verify; the login situation) |\n| `pup-bridge-dev` / `pup-bridge-publish` | ❌ source-only | MAINTAINERS: bridge internals + the publish/release recipe (in `dev-skills/`/`publish-skills/`, not shipped) |\n- Ownership boundary: `CLAUDE.md`. Publish recipe: `PUBLISHING.md`. History: `CHANGELOG.md`.\n\n## Extend pup, add your own pup skill (third parties)\n\nBuilt a skill that drives pup for a specific job (a site-specific scraper, a visual test flow, a\ndomain widget)? You don't need write access here, surface it from this page with a **breadcrumb**:\n\n1. **Publish your skill** to your own wiki page (see the `adom-wiki` / `wiki-skillpack` skills). Make it a\n normal user skill so `pkg install` drops it into a container's `~/.claude/skills`.\n2. **Drop a breadcrumb on this page** pointing at it:\n ```bash\n adom-wiki breadcrumb post adom/pup-bridge \\\n --label \"Your skill name, one-line what it does\" \\\n --target-url \"https://wiki.adom.inc/<owner>/<your-slug>\" \\\n --category \"skill\"\n ```\n It's **pending until the page owner approves it**, then it shows in this page's **Breadcrumbs** tab.\n3. **Discovery is automatic:** an agent working with pup can list related third-party skills with\n `adom-wiki breadcrumb list adom/pup-bridge`, approved breadcrumbs are how pup finds\n community skills that build on it.\n\nKeep breadcrumbs on-topic (they genuinely extend pup / browser-driving); off-topic ones get rejected.\n\n## Related\n\n- [Bridge SDK guide](https://wiki.adom.inc/adom/adom-bridge-sdk), `bridge.json` schema, packaging, lifecycle\n- [KiCad bridge](https://wiki.adom.inc/adom/kicad-bridge) · [Fusion 360 bridge](https://wiki.adom.inc/adom/fusion-bridge)\n- [Bridge (parent app)](https://wiki.adom.inc/adom/adom-bridge)\n\nMIT licensed.\n",
"author": "John Lauer <[email protected]>",
"visibility": {
"public": true
},
"hero": {
"type": "image",
"path": "hero-v9.png"
},
"metadata": {},
"created_at": "2026-05-28T05:28:43.991Z",
"skills": [],
"author_name": "John Lauer",
"description": "The pup SKILL PACK — the AI skills that teach a cloud/container AI how to drive the Adom Desktop Puppeteer (pup) bridge (browser_* verbs): the everyday `pup` skill plus focused sub-skills for windows/sessions/tabs, screenshots+recording, browsers+Chrome install, and driving the Adom wiki. Installs into ~/.claude/skills + ~/.codex/skills. DOCS ONLY — this is NOT the bridge runtime. The bridge itself (the Node program that drives the browser) runs on the DESKTOP: Adom Desktop bundles it and auto-installs/updates it, and it's published separately on the Releases tab as adom-bridge-puppeteer-v<ver>.zip. So the pkg version (skills, bumps often) and the Release version (runtime, bumps rarely) differ on purpose. TL;DR: pkg install = the skills for your AI; the bridge = the Release zip, which Adom Desktop manages for you.",
"keywords": [
"pup",
"puppeteer",
"browser",
"adom-bridge",
"bridge",
"skills",
"pup-bridge"
],
"files": [
"SKILL.md",
"skills/pup-windows-sessions-tabs/SKILL.md",
"skills/pup-screenshots-recording/SKILL.md",
"skills/pup-browsers-and-chrome/SKILL.md",
"skills/pup-adom-wiki/SKILL.md",
"skills/pup-vendor-login/SKILL.md",
"install.sh",
"uninstall.sh",
"README.md",
"package.json"
],
"scripts": {
"install": "./install.sh",
"uninstall": "./uninstall.sh"
},
"dependencies": {
"adom/adom-bridge": "^2.0.0"
},
"org": "adom",
"contributors": [
"Kyle Bergstedt <[email protected]>",
"Colby Knox"
],
"authors_json": [
"john"
],
"updated_at": "2026-08-09T13:54:01.806Z"
}