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
Publish 2.0.132
4 files changed
+24−15
SKILL.md+4−3@@ -92,9 +92,10 @@ assistant in the world**. The engine of that goal is the shared durable **adom-y - **Isolation is the exception, not a style choice — and it is REASON-GATED (v2.0.101).** `isolated:true` without an `isolationReason` (min 10 chars: why this window must NOT be adom-you) is refused with `isolation_reason_required`. Legit reasons: testing logged-out- views, acting as a different user, untrusted pages. `webSecurity:false` and- `wikiView:"public"` carry their own built-in reason. An isolated window's logins are thrown- away: they build nothing.+ views, acting as a different user, untrusted pages. `webSecurity:false` carries its own+ built-in reason. An isolated window's logins are thrown+ away: they build nothing. (`wikiView:"public"` no longer isolates at all as of 2.0.132 —+ the wiki's server-side `?view=public` param renders the anonymous view in the same window.) - A non-adom-you window shows the ANONYMOUS identity tile in the toolbar (the pup four-dot mark on a dark disc, where signed-in windows show the user's avatar) so a not-you window is visible at a glance. The dashboard additionally shows a "surfing as adom-you" chip per window: if your
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "pup-bridge",- "version": "2.0.131",+ "version": "2.0.132", "type": "app", "description": "The pup SKILL PACK \u2014 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 \u2014 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. The pkg version is kept in lockstep with the Release version so the page's max version row always carries BOTH a pkg tarball (skills) and a runtime zip (bridge) \u2014 a skills-only or runtime-only bump on the top row breaks constraint installs. TL;DR: pkg install = the skills for your AI; the bridge = the Release zip, which Adom Desktop manages for you.", "keywords": [
page.json+12−7@@ -4,13 +4,12 @@ "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.131",+ "version": "2.0.132", "tags": [ "skills", "pup", "puppeteer", "browser",- "ab", "adom-bridge", "bridge", "pup-bridge"@@ -88,7 +87,7 @@ "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\u2026 |\n|---|---|---|---|\n| **Install**, `adom-wiki pkg install \u2026` | 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 '{}' # \u2192 {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 (`\u25cf Logged in`) or hollow dot\n (`\u25cb 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: `\u25cb Public`, page header shows Login):\n\n\n\n**Adom wiki, SIGNED IN** (tab: `\u25cf 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 (\u22488.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 \u2192 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** \u2192 one `.webm`; ffmpeg remuxes it to stamp a proper Duration. |\n\n```bash\nadom-bridge-cli pup_record_start '{\"sessionId\":\"demo-web\"}' # \u2192 { recordingId }\n# ...drive the scene: navigate, click, type, scroll...\nadom-bridge-cli pup_record_stop '{\"sessionId\":\"demo-web\",\"recordingId\":\"<id>\"}' # \u2192 { 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 \u22488.6 s\ndemo above (1264\u00d7705):\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# \u2192 MP4 (H.264, universal). The scale filter forces EVEN dimensions (H.264 rejects odd w/h \u2192 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# \u2192 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`, \u2026); 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) | \u2705 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` | \u2705 user | sessionIds, window ownership (don't steal another thread's window), background-vs-foreground, many tabs in one window |\n| `pup-screenshots-recording` | \u2705 user | Screenshots (full-page/full-res) + recording; driving/verifying tricky pages (shadow DOM, nested scroll) |\n| `pup-browsers-and-chrome` | \u2705 user | Browser detection/launch, `pup_use`, installing Chrome/CfT (incl. UAC-notify), readiness, cold-start errors |\n| `pup-adom-wiki` | \u2705 user | Driving + verifying `wiki.adom.inc` pages in pup (view/screenshot/verify; the login situation) |\n| `pup-bridge-dev` / `pup-bridge-publish` | \u274c 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) \u00b7 [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",+ "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@@ -101,15 +100,15 @@ "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 Bridge Puppeteer (pup) bridge (pup_* 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: Bridge 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 Bridge manages for you.",+ "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. The pkg version is kept in lockstep with the Release version so the page's max version row always carries BOTH a pkg tarball (skills) and a runtime zip (bridge) — a skills-only or runtime-only bump on the top row breaks constraint installs. TL;DR: pkg install = the skills for your AI; the bridge = the Release zip, which Adom Desktop manages for you.", "keywords": [- "ab", "pup", "puppeteer", "browser", "adom-bridge", "bridge",- "skills"+ "skills",+ "pup-bridge" ], "files": [ "SKILL.md",@@ -117,6 +116,8 @@ "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",+ "skills/pup-settings/SKILL.md", "install.sh", "uninstall.sh", "README.md",@@ -129,5 +130,9 @@ "dependencies": { "adom/adom-bridge": "^2.0.0" },- "org": "adom"+ "org": "adom",+ "contributors": [+ "Kyle Bergstedt <[email protected]>",+ "Colby Knox"+ ] }
skills/pup-adom-wiki/SKILL.md+7−4@@ -52,10 +52,13 @@ pup can now open a wiki page from **either viewpoint**, and the killer use is sh opens in the ONE shared `adom-you` profile — the same jar every other pup window uses — so once the user has signed into the wiki once, EVERY wiki window (and every other pup window) is already logged in. `wikiView:"authed"` is now just the explicit name for this default.-- **Public / anonymous (EXPLICIT):** `pup_open_window {url:"...", wikiView:"public"}` — this is- the ONLY wiki view that gets a separate jar: a fresh logged-OUT isolated profile, because showing- "what the world sees" requires being logged out. It does NOT accumulate anything and is only for- a deliberate publish-visibility check.+- **Public / anonymous (EXPLICIT):** `pup_open_window {url:"...", wikiView:"public"}` — the+ SERVER renders the page exactly as a signed-out visitor sees it, via the `?view=public` URL+ param (adom/wiki#126: the request's user is nulled for that one render, the response is+ byte-identical to a logged-out visitor's, and private pages 404). The window STAYS on the+ shared profile with the session untouched — no isolated jar, no relaunch. Only for a+ deliberate publish-visibility check. (Pre-2.0.132 this minted a throwaway logged-out+ profile; the param replaced that entirely.) **Use ONE window normally.** Don't open two windows for the same page — that double-reloads and annoys. Just pick the view the task needs. The ONLY time to compare both is a deliberate