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
SDK audit pass (v1.2.3): homepage -> wiki.adom.inc/adom/adom-desktop (per AD-thread directive; was already own-page wiki, github was the stale seed); inject _next+pitfalls on every verb response; discovery_pitch as instruction
6 files changed
+15−42
adom-bridge-puppeteer-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "puppeteer",- "version": "1.2.2",- "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.2.2/adom-bridge-puppeteer-v1.2.2.zip",- "sha256": "6eb5070e7046f87630813dc61583f100d99d2b0884b5d3c953bc960b0c338b8f",- "size": 127893,+ "version": "1.2.3",+ "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.2.3/adom-bridge-puppeteer-v1.2.3.zip",+ "sha256": "995ee3218a2827b45dbfc6918dac62b977732dc16c84501adb7c563c5c85eb59",+ "size": 128005, "verbPrefixes": [ "browser_", "desktop_recorder_",
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-desktop-puppeteer-bridge",- "version": "1.2.2",+ "version": "1.2.3", "type": "app", "description": "CONTAINER-SIDE install — the everyday `pup` user skill only. This pkg drops the `pup` skill (drive the browser bridge: open/close/tabs/screenshot/record, background-by-default) into ~/.claude/skills/ AND ~/.codex/skills/. It does NOT install the developer/publishing skills (pup-bridge-dev, pup-bridge-publish) — those are source-only; clone the repo (adom-wiki repo clone adom/adom-desktop-puppeteer-bridge) to get them from dev-skills/. It also does NOT contain the bridge runtime: the bridge (Node + Chrome for Testing) lives on the DESKTOP — bundled inside Adom Desktop and published here on the Releases tab as adom-bridge-puppeteer-v<ver>.zip, which Adom Desktop streams into its bridges-cache. TL;DR: `pkg install` = the pup user skill; dev skills = clone the source; the bridge = the Release zip + bundled in Adom Desktop.", "keywords": [
page.json+4−34@@ -4,15 +4,8 @@ "slug": "adom-desktop-puppeteer-bridge", "title": "Adom Desktop - Puppeteer Bridge", "brief": "The Adom Desktop Puppeteer (pup) bridge — drive Chrome for Testing (or the user's real Chrome/Edge/Brave) from the cloud: open/screenshot/eval/record, with cold-start self-heal that auto-installs Chrome for Testing on a fresh PC. Two artifacts: the Releases zip is the bridge runtime (also bundled in Adom Desktop); the pkg installs the container-side Claude skills.",- "version": "1.2.2",- "tags": [- "skills",- "pup",- "puppeteer",- "browser",- "adom-desktop",- "bridge"- ],+ "version": "1.1.0",+ "tags": [], "license": "MIT", "discovery_triggers": [ "pup",@@ -53,7 +46,7 @@ "fork the pup bridge", "puppeteer bridge source" ],- "discovery_pitch": "Drive Chrome from the cloud with the pup (Puppeteer) bridge: open/close browser windows + tabs, navigate, screenshot, eval JS, and record windows — driving Chrome for Testing or the user's REAL Chrome/Edge/Brave, in the background so it doesn't disrupt the user. Cold-start self-heal auto-installs Chrome for Testing on a fresh PC. The skill calls the adom-desktop CLI (browser_* verbs); this pkg installs the container-side skills, the bridge runtime ships in Adom Desktop + as the release zip.",+ "discovery_pitch": "Use pup to drive Chrome from the cloud: open/close browser windows + tabs, navigate, screenshot, eval JS, and record windows — driving Chrome for Testing or the user's REAL Chrome/Edge/Brave, in the background so it doesn't disrupt the user. On a fresh PC, Adom Desktop background-fetches Chrome for Testing (Tier-1 prewarm) — poll bridge_readiness, then open. Call the adom-desktop browser_* verbs; the pkg installs the container-side skills.", "sample_prompts": [ { "label": "Open in pup",@@ -103,28 +96,5 @@ "created_at": "2026-05-28T05:28:43.991Z", "updated_at": "2026-06-16T12:43:19.735Z", "skills": [],- "author_name": "John Lauer",- "description": "CONTAINER-SIDE install — the everyday `pup` user skill only. This pkg drops the `pup` skill (drive the browser bridge: open/close/tabs/screenshot/record, background-by-default) into ~/.claude/skills/ AND ~/.codex/skills/. It does NOT install the developer/publishing skills (pup-bridge-dev, pup-bridge-publish) — those are source-only; clone the repo (adom-wiki repo clone adom/adom-desktop-puppeteer-bridge) to get them from dev-skills/. It also does NOT contain the bridge runtime: the bridge (Node + Chrome for Testing) lives on the DESKTOP — bundled inside Adom Desktop and published here on the Releases tab as adom-bridge-puppeteer-v<ver>.zip, which Adom Desktop streams into its bridges-cache. TL;DR: `pkg install` = the pup user skill; dev skills = clone the source; the bridge = the Release zip + bundled in Adom Desktop.",- "keywords": [- "pup",- "puppeteer",- "browser",- "adom-desktop",- "bridge",- "skills"- ],- "files": [- "SKILL.md",- "skills/**",- "install.sh",- "uninstall.sh",- "README.md",- "package.json"- ],- "dependencies": {},- "scripts": {- "install": "./install.sh",- "uninstall": "./uninstall.sh"- },- "org": "adom"+ "author_name": "John Lauer" }
src/BRIDGE_VERSION+1−1@@ -1 +1 @@-1.2.2+1.2.3
src/bridge.json+2−2@@ -2,9 +2,9 @@ "manifest_version": 1, "name": "puppeteer", "displayName": "Puppeteer (Chrome for Testing + Native)",- "version": "1.2.2",+ "version": "1.2.3", "description": "Launches with FULL browser permissions by default (all granted — notifications/geolocation/camera/mic/midi/sensors/clipboard/wake-lock/…) so no permission prompt ever blocks full debug; strictPermissions:true opts out. Tier-1 cold-start (for AD v1.9.47+ two-tier model): pup brings its OWN browser (Chrome for Testing), so it needs no detect-block. It declares prewarm:[chrome-for-testing] so Adom Desktop fetches Chrome in the BACKGROUND and reports readiness via bridge_readiness. The bridge server starts fine WITHOUT Chrome; browser_readiness is a READ-ONLY probe (ready = server-up AND Chrome cached; never triggers a download); browser_open returns a non-blocking {installing:true} (never blocks/crashes) until Chrome is cached; browser_prewarm is an explicit bridge-side fetch fallback. Headful browser automation. Default path drives Chrome for Testing (CfT) with managed pup profiles. v1.0.6+ optional native-drive: pass nativeBrowser+nativeProfile (from desktop_list_browsers) to browser_open_window to drive the user's REAL Chrome/Edge/Brave with the actual signed-in account + org policies + device enrollment intact. Smart flow: if the browser is CLOSED, AD launches it fresh immediately with NO prompt (nothing to disrupt) and reports back ready-to-drive (launchedFresh:true); if it's OPEN without the port, AD returns errorCode:'native_relaunch_required' so the caller asks the user, then re-call with nativeRelaunch:true. AD then closes only that browser's own PIDs cleanly (WM_CLOSE — Sessions saved; CfT bridge sessions + other Chromium left untouched) and relaunches with --restore-last-session so every tab/window comes back. If the debug port is policy-blocked (e.g. Google Workspace's RemoteDebuggingAllowed disabled — affects Chrome browser-wide, all profiles), native drive returns errorCode:'native_cdp_blocked' with a `diagnosis` plus an `alternatives` list of other installed browsers — Edge usually escapes Google management. The generic CfT path (browser_open_window with no nativeBrowser) always works as a fallback.",- "homepage": "https://wiki.adom.inc/adom/adom-desktop-puppeteer-bridge",+ "homepage": "https://wiki.adom.inc/adom/adom-desktop", "author": "Adom Inc.", "license": "MIT", "spawn": {
src/server.js+3@@ -2822,6 +2822,9 @@ function sendJSON(res, obj, status = 200) { if (meta) { if (obj._hint === undefined && meta.hint) obj._hint = meta.hint; if (obj.related === undefined && Array.isArray(meta.related) && meta.related.length) obj.related = meta.related;+ // SDK "THE ONE PRINCIPLE": every verb response carries _next (the obvious next verbs) too.+ if (obj._next === undefined && (Array.isArray(meta.next) || Array.isArray(meta.related))) obj._next = meta.next || meta.related;+ if (obj.pitfalls === undefined && Array.isArray(meta.pitfalls) && meta.pitfalls.length) obj.pitfalls = meta.pitfalls; } } res.writeHead(status, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });