Reference bridge: Puppeteer
UnreviewedReference implementation of the Puppeteer bridge — Node + puppeteer-core + Chrome for Testing for headful browser automation, multi-window, per-tab CDP screencast recording.
Reference bridge: Puppeteer
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 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 |
Clean source tree, no .git directory. ~98 KB. |
tar xzf adom-bridge-puppeteer-source.tar.gz && cd adom-bridge-puppeteer/ |
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
- Maintainer merges your PR into
main - Maintainer tags
v<X.Y.Z>+ runsbash scripts/release-bridge.sh puppeteeron their box - New zip + manifest published to this wiki page (replaces current version)
- 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 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 |
| Manifest | puppeteer-bridge-manifest.json |
| User-facing skill | pup-SKILL.md |
What it does
- Sessions + tabs —
browser_open_windowspawns Chrome for Testing with a per-session profile (cookies, IndexedDB, localStorage isolated).browser_open_tab/browser_close_tabmanage 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 CDPInput.dispatchKeyEventfor cases where typing through React state handlers fails). - Recording —
browser_record_startper-tab via CDPPage.startScreencast,desktop_record_startfor full-desktop viagetDisplayMedia+MediaRecorderin a hidden Chrome window. - Network capture —
browser_fetch_urlrunsfetch()from inside the page context (uses session cookies); useful for endpoints that gate by SameSite/CORS.
bridge.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
# 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
# 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
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 —
bridge.jsonschema, packaging recipe, lifecycle - KiCad bridge reference — most complex of the three; multi-instance, reverse-bridge
- Fusion 360 bridge reference — passthrough-to-add-in pattern
- adom-desktop main page — install the parent app first