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
README.md+179−179@@ -1,186 +1,186 @@-# Reference bridge: Puppeteer - +# Adom Desktop - Puppeteer Bridge+    -## Source code + contributing (2026-05) - -The Puppeteer (Chrome) bridge moved out of `adom-inc/adom-desktop`'s monorepo into its own dedicated repo so the community can extend it without coordinating with Adom Desktop's release cycle. - -### Where the source lives - -The canonical repo is **[`adom-inc/adom-bridge-puppeteer`](https://github.com/adom-inc/adom-bridge-puppeteer)** on GitHub. It's private today and will go public after a review pass. - -In the meantime, the full source — code, history, contributing guide, license — is **mirrored on this wiki page**: - -| Download | What it is | How to use | -|---|---|---| -| [`adom-bridge-puppeteer-source.tar.gz`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer-source.tar.gz) | Clean source tree, no `.git` directory. ~98 KB. | `tar xzf adom-bridge-puppeteer-source.tar.gz && cd adom-bridge-puppeteer/` | -| [`adom-bridge-puppeteer.bundle`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer.bundle) | Git bundle with full commit history. ~157 KB. | `git clone https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer.bundle adom-bridge-puppeteer && cd adom-bridge-puppeteer && git log` | - -No GitHub account needed to download either — both URLs are public. - -### How to contribute - -We accept community improvements. Most useful targets right now: - -- **macOS / Linux ports** — bridge currently Windows-only; cross-platform PRs welcome. -- **New browser-automation verbs** — Puppeteer surface is big; we wrap a useful subset. Add more if you need them. -- **Recording features** — desktop recorder is new (v1.8.x); plenty of polish room (annotations, audio, GIF export). - -Two contribution paths, depending on your access: - -**With a GitHub account (preferred):** wait until we make the repo public, then fork on GitHub and open a PR. We're aiming to flip the repo public in the next maintenance pass. - -**Without GitHub access (patch-by-email-style, available right now):** Clone the bundle, make your changes, generate a patch with `git format-patch origin/main..HEAD --stdout > my-changes.patch`, and email it to **`[email protected]`**. Adom maintainers will review and apply. - -See `CONTRIBUTING.md` inside the tarball/bundle for the full PR + ship workflow. - -### How shipping works after merge - -1. Maintainer merges your PR into `main` -2. Maintainer tags `v<X.Y.Z>` + runs `bash scripts/release-bridge.sh puppeteer` on their box -3. New zip + manifest published to this wiki page (replaces current version) -4. Every Adom Desktop install running v1.7.19+ auto-picks up your change within 4 hours OR immediately via `adom-desktop refresh_bridges` - -No NSIS installer rebuild required. Your code reaches real users in ~30s after merge. - -### License - -MIT — see the `LICENSE` file in the tarball. - - - -The Puppeteer bridge is one of three reference implementations bundled with Adom Desktop. It wraps `puppeteer-core` + Chrome for Testing to give Docker-side Claude full headful browser automation on the user's desktop — multi-window, multi-tab, file uploads, network interception, video recording. - -If you're authoring a new third-party bridge, see the [bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges) first. Use this page when you want to see how a Node-based bridge is wired. - -## Quick facts - -| | | -|---|---| -| Name | `puppeteer` | -| Display | Puppeteer (Chrome for Testing) | -| Spawn kind | Node (`server.js`) | -| Port | 8851 | -| Verb prefixes | `browser_*`, `desktop_recorder_*`, `desktop_record_*` (22 verbs) | -| Source zip | [`puppeteer-bridge-v1.0.0.zip`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-v1.0.0.zip) | -| Manifest | [`puppeteer-bridge-manifest.json`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-manifest.json) | -| User-facing skill | [`pup-SKILL.md`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/pup-SKILL.md) | - -## What it does - -- **Sessions + tabs** — `browser_open_window` spawns Chrome for Testing with a per-session profile (cookies, IndexedDB, localStorage isolated). `browser_open_tab` / `browser_close_tab` manage tabs within a session. -- **Navigation + introspection** — `browser_navigate`, `browser_back/forward/reload`, `browser_screenshot` (full-page or viewport), `browser_evaluate` (run JS, return result). -- **Input synthesis** — `browser_click`, `browser_type`, `browser_press_key`, `browser_input_dispatch` (low-level CDP `Input.dispatchKeyEvent` for cases where typing through React state handlers fails). -- **Recording** — `browser_record_start` per-tab via CDP `Page.startScreencast`, `desktop_record_start` for full-desktop via `getDisplayMedia` + `MediaRecorder` in a hidden Chrome window. -- **Network capture** — `browser_fetch_url` runs `fetch()` from inside the page context (uses session cookies); useful for endpoints that gate by SameSite/CORS. - -## `bridge.json` - -```json -{ - "manifest_version": 1, - "name": "puppeteer", - "displayName": "Puppeteer (Chrome for Testing)", - "version": "1.0.0", - "description": "Headful browser automation via puppeteer-core + Chrome for Testing. Multi-window, multi-tab, recording, file uploads, network interception.", - "homepage": "https://github.com/adom-inc/adom-desktop", - "author": "Adom Inc.", - "license": "MIT", - "spawn": { - "kind": "node", - "entrypoint": "server.js", - "port": 8851, - "healthEndpoint": "http://127.0.0.1:8851/status", - "stopMethod": "kill", - "killImageName": "node.exe" - }, - "verbPrefixes": ["browser_", "desktop_recorder_", "desktop_record_"], - "verbs": [ - "browser_open_window", "browser_open_tab", "browser_close_tab", "browser_close_window", - "browser_navigate", "browser_back", "browser_forward", "browser_reload", - "browser_click", "browser_type", "browser_press_key", - "browser_screenshot", "browser_evaluate", "browser_fetch_url", - "browser_input_dispatch", - "browser_record_start", "browser_record_stop", "browser_record_status", "browser_record_list", - "desktop_recorder_open", "desktop_record_start", "desktop_record_stop" - ], - "dependencies": { "node": ">=20", "chrome": ">=120" }, - "category": "Browser Automation", - "tags": ["puppeteer", "chrome", "headful", "recording"] -} -``` - -Note: `verbPrefixes` is an array with THREE entries (`browser_*`, `desktop_recorder_*`, `desktop_record_*`). One bridge can own multiple prefixes. - -## Architecture highlights - -``` -puppeteer/ -├── server.js ← HTTP entry point; routes /command → handler functions -├── credential_vault.js ← Per-session cookie/storage isolation -├── adom-icon.svg ← Window icon for spawned Chrome instances -└── (npm install lays down node_modules + puppeteer-core) -``` - -The bridge intentionally keeps minimal on-disk state — `puppeteer-core` does the heavy lifting and Chrome for Testing is downloaded into `~/.cache/puppeteer/` on first run. The bridge code itself is one large `server.js` (~2k lines) using `http.createServer` for the JSON-over-HTTP dispatch layer (same shape as the hello sample, just more handlers). - -## Session model - -```bash -# Open a window for session "design-review" with its own Chrome profile -adom-desktop browser_open_window '{"sessionId":"design-review","profile":"design-review","url":"https://staging.example.com"}' - -# Add a tab in the same window -adom-desktop browser_open_tab '{"sessionId":"design-review","url":"https://staging.example.com/cart"}' - -# Screenshot the active tab -adom-desktop browser_screenshot '{"sessionId":"design-review"}' - -# Evaluate JS in the page (returns the resolved value) -adom-desktop browser_evaluate '{"sessionId":"design-review","expr":"document.querySelectorAll(\"button\").length"}' - -# Close the whole window when done -adom-desktop browser_close_window '{"sessionId":"design-review"}' -``` - -The `sessionId` is the persistence key — close + reopen the same session and you get the cookies + localStorage from before. `profile` defaults to the sessionId but can be shared across sessions for IndexedDB / login state sharing. - -## Recording example - -```bash -# Per-tab recording → CDP screencast → JPEG frames → ffmpeg-mux'd tar on stop -adom-desktop browser_record_start '{"sessionId":"design-review","tabId":"tab-1","fps":30}' -# … drive the page … -adom-desktop browser_record_stop '{"recordingId":"rec-tab-…"}' - -# Full-desktop recording → hidden Chrome window with getDisplayMedia + MediaRecorder → WebM -adom-desktop desktop_recorder_open -adom-desktop desktop_record_start '{"reason":"Demoing the alignment dialog flow","monitor":"primary"}' -# … drive the desktop … -adom-desktop desktop_record_stop -``` - -Reason is required for desktop recording so the user always knows why the recorder activated — it's shown in the HUD panel that opens. - -## Reference: install the source locally to read - -```bash -curl -L https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-v1.0.0.zip -o /tmp/puppeteer-bridge.zip -mkdir -p /tmp/puppeteer-bridge && cd /tmp/puppeteer-bridge && python3 -c "import zipfile; zipfile.ZipFile('/tmp/puppeteer-bridge.zip').extractall()" -ls -la -``` - -Open `server.js` to see the dispatch shape, recorder lifecycle, and per-session profile management. - -## Related - -- **[Bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges)** — `bridge.json` schema, packaging recipe, lifecycle -- **[KiCad bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-kicad-bridge)** — most complex of the three; multi-instance, reverse-bridge -- **[Fusion 360 bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-fusion-bridge)** — passthrough-to-add-in pattern +## Source code + contributing (2026-05)++The Puppeteer (Chrome) bridge moved out of `adom-inc/adom-desktop`'s monorepo into its own dedicated repo so the community can extend it without coordinating with Adom Desktop's release cycle.++### Where the source lives++The canonical repo is **[`adom-inc/adom-bridge-puppeteer`](https://github.com/adom-inc/adom-bridge-puppeteer)** on GitHub. It's private today and will go public after a review pass.++In the meantime, the full source — code, history, contributing guide, license — is **mirrored on this wiki page**:++| Download | What it is | How to use |+|---|---|---|+| [`adom-bridge-puppeteer-source.tar.gz`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer-source.tar.gz) | Clean source tree, no `.git` directory. ~98 KB. | `tar xzf adom-bridge-puppeteer-source.tar.gz && cd adom-bridge-puppeteer/` |+| [`adom-bridge-puppeteer.bundle`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer.bundle) | Git bundle with full commit history. ~157 KB. | `git clone https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer.bundle adom-bridge-puppeteer && cd adom-bridge-puppeteer && git log` |++No GitHub account needed to download either — both URLs are public.++### How to contribute++We accept community improvements. Most useful targets right now:++- **macOS / Linux ports** — bridge currently Windows-only; cross-platform PRs welcome.+- **New browser-automation verbs** — Puppeteer surface is big; we wrap a useful subset. Add more if you need them.+- **Recording features** — desktop recorder is new (v1.8.x); plenty of polish room (annotations, audio, GIF export).++Two contribution paths, depending on your access:++**With a GitHub account (preferred):** wait until we make the repo public, then fork on GitHub and open a PR. We're aiming to flip the repo public in the next maintenance pass.++**Without GitHub access (patch-by-email-style, available right now):** Clone the bundle, make your changes, generate a patch with `git format-patch origin/main..HEAD --stdout > my-changes.patch`, and email it to **`[email protected]`**. Adom maintainers will review and apply.++See `CONTRIBUTING.md` inside the tarball/bundle for the full PR + ship workflow.++### How shipping works after merge++1. Maintainer merges your PR into `main`+2. Maintainer tags `v<X.Y.Z>` + runs `bash scripts/release-bridge.sh puppeteer` on their box+3. New zip + manifest published to this wiki page (replaces current version)+4. Every Adom Desktop install running v1.7.19+ auto-picks up your change within 4 hours OR immediately via `adom-desktop refresh_bridges`++No NSIS installer rebuild required. Your code reaches real users in ~30s after merge.++### License++MIT — see the `LICENSE` file in the tarball.++---+++The Puppeteer bridge is one of three reference implementations bundled with Adom Desktop. It wraps `puppeteer-core` + Chrome for Testing to give Docker-side Claude full headful browser automation on the user's desktop — multi-window, multi-tab, file uploads, network interception, video recording.++If you're authoring a new third-party bridge, see the [bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges) first. Use this page when you want to see how a Node-based bridge is wired.++## Quick facts++| | |+|---|---|+| Name | `puppeteer` |+| Display | Puppeteer (Chrome for Testing) |+| Spawn kind | Node (`server.js`) |+| Port | 8851 |+| Verb prefixes | `browser_*`, `desktop_recorder_*`, `desktop_record_*` (22 verbs) |+| Source zip | [`puppeteer-bridge-v1.0.0.zip`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-v1.0.0.zip) |+| Manifest | [`puppeteer-bridge-manifest.json`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-manifest.json) |+| User-facing skill | [`pup-SKILL.md`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/pup-SKILL.md) |++## What it does++- **Sessions + tabs** — `browser_open_window` spawns Chrome for Testing with a per-session profile (cookies, IndexedDB, localStorage isolated). `browser_open_tab` / `browser_close_tab` manage tabs within a session.+- **Navigation + introspection** — `browser_navigate`, `browser_back/forward/reload`, `browser_screenshot` (full-page or viewport), `browser_evaluate` (run JS, return result).+- **Input synthesis** — `browser_click`, `browser_type`, `browser_press_key`, `browser_input_dispatch` (low-level CDP `Input.dispatchKeyEvent` for cases where typing through React state handlers fails).+- **Recording** — `browser_record_start` per-tab via CDP `Page.startScreencast`, `desktop_record_start` for full-desktop via `getDisplayMedia` + `MediaRecorder` in a hidden Chrome window.+- **Network capture** — `browser_fetch_url` runs `fetch()` from inside the page context (uses session cookies); useful for endpoints that gate by SameSite/CORS.++## `bridge.json`++```json+{+ "manifest_version": 1,+ "name": "puppeteer",+ "displayName": "Puppeteer (Chrome for Testing)",+ "version": "1.0.0",+ "description": "Headful browser automation via puppeteer-core + Chrome for Testing. Multi-window, multi-tab, recording, file uploads, network interception.",+ "homepage": "https://github.com/adom-inc/adom-desktop",+ "author": "Adom Inc.",+ "license": "MIT",+ "spawn": {+ "kind": "node",+ "entrypoint": "server.js",+ "port": 8851,+ "healthEndpoint": "http://127.0.0.1:8851/status",+ "stopMethod": "kill",+ "killImageName": "node.exe"+ },+ "verbPrefixes": ["browser_", "desktop_recorder_", "desktop_record_"],+ "verbs": [+ "browser_open_window", "browser_open_tab", "browser_close_tab", "browser_close_window",+ "browser_navigate", "browser_back", "browser_forward", "browser_reload",+ "browser_click", "browser_type", "browser_press_key",+ "browser_screenshot", "browser_evaluate", "browser_fetch_url",+ "browser_input_dispatch",+ "browser_record_start", "browser_record_stop", "browser_record_status", "browser_record_list",+ "desktop_recorder_open", "desktop_record_start", "desktop_record_stop"+ ],+ "dependencies": { "node": ">=20", "chrome": ">=120" },+ "category": "Browser Automation",+ "tags": ["puppeteer", "chrome", "headful", "recording"]+}+```++Note: `verbPrefixes` is an array with THREE entries (`browser_*`, `desktop_recorder_*`, `desktop_record_*`). One bridge can own multiple prefixes.++## Architecture highlights++```+puppeteer/+├── server.js ← HTTP entry point; routes /command → handler functions+├── credential_vault.js ← Per-session cookie/storage isolation+├── adom-icon.svg ← Window icon for spawned Chrome instances+└── (npm install lays down node_modules + puppeteer-core)+```++The bridge intentionally keeps minimal on-disk state — `puppeteer-core` does the heavy lifting and Chrome for Testing is downloaded into `~/.cache/puppeteer/` on first run. The bridge code itself is one large `server.js` (~2k lines) using `http.createServer` for the JSON-over-HTTP dispatch layer (same shape as the hello sample, just more handlers).++## Session model++```bash+# Open a window for session "design-review" with its own Chrome profile+adom-desktop browser_open_window '{"sessionId":"design-review","profile":"design-review","url":"https://staging.example.com"}'++# Add a tab in the same window+adom-desktop browser_open_tab '{"sessionId":"design-review","url":"https://staging.example.com/cart"}'++# Screenshot the active tab+adom-desktop browser_screenshot '{"sessionId":"design-review"}'++# Evaluate JS in the page (returns the resolved value)+adom-desktop browser_evaluate '{"sessionId":"design-review","expr":"document.querySelectorAll(\"button\").length"}'++# Close the whole window when done+adom-desktop browser_close_window '{"sessionId":"design-review"}'+```++The `sessionId` is the persistence key — close + reopen the same session and you get the cookies + localStorage from before. `profile` defaults to the sessionId but can be shared across sessions for IndexedDB / login state sharing.++## Recording example++```bash+# Per-tab recording → CDP screencast → JPEG frames → ffmpeg-mux'd tar on stop+adom-desktop browser_record_start '{"sessionId":"design-review","tabId":"tab-1","fps":30}'+# … drive the page …+adom-desktop browser_record_stop '{"recordingId":"rec-tab-…"}'++# Full-desktop recording → hidden Chrome window with getDisplayMedia + MediaRecorder → WebM+adom-desktop desktop_recorder_open+adom-desktop desktop_record_start '{"reason":"Demoing the alignment dialog flow","monitor":"primary"}'+# … drive the desktop …+adom-desktop desktop_record_stop+```++Reason is required for desktop recording so the user always knows why the recorder activated — it's shown in the HUD panel that opens.++## Reference: install the source locally to read++```bash+curl -L https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-v1.0.0.zip -o /tmp/puppeteer-bridge.zip+mkdir -p /tmp/puppeteer-bridge && cd /tmp/puppeteer-bridge && python3 -c "import zipfile; zipfile.ZipFile('/tmp/puppeteer-bridge.zip').extractall()"+ls -la+```++Open `server.js` to see the dispatch shape, recorder lifecycle, and per-session profile management.++## Related++- **[Bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges)** — `bridge.json` schema, packaging recipe, lifecycle+- **[KiCad bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-kicad-bridge)** — most complex of the three; multi-instance, reverse-bridge+- **[Fusion 360 bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-fusion-bridge)** — passthrough-to-add-in pattern - **[adom-desktop main page](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop)** — install the parent app first