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
v2.0.260: Hand the keyboard focus back when an on-screen birth takes the foreground. Measured live the moment R1 landed: --no-startup-window was not the only thing suppressing Chrome's foreground grab, the off-screen birth was doing half the work, because Chrome does not bother activating a window that is nowhere. Born at a real rect it activates, and every open logged a steal. Per R2 the WINDOW is left exactly where it is and nothing re-parks it, but the user's keyboard focus is not the window's z-order: letting their typing land in a browser that just appeared is not a flaw worth accepting when handing focus back costs one call. This is the v1.9.253 handback restored (it was deleted only because the off-screen birth made it unreachable), one shot at birth, never on a timer, and it reports honestly when it does not take.
4 files changed
+26−12
adom-bridge-puppeteer-manifest.json+5−5@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "puppeteer",- "version": "2.0.259",- "url": "https://wiki.adom.inc/download/adom/pup-bridge/2.0.259/adom-bridge-puppeteer-v2.0.259.zip",- "sha256": "61c2b327f109ef50e91bce8b0874a1e2a59093519cbe3468bb0cb090e504d83b",- "size": 956135,+ "version": "2.0.260",+ "url": "https://wiki.adom.inc/download/adom/pup-bridge/2.0.260/adom-bridge-puppeteer-v2.0.260.zip",+ "sha256": "4c881020b6b5ff80d22c78f4bb5b132a2c66c719ae9293cf35fce1291617feda",+ "size": 956454, "verbPrefixes": [ "browser_", "desktop_recorder_",@@ -12,5 +12,5 @@ ], "healthEndpoint": "/status", "statusVerb": "browser_readiness",- "released_at": "2026-08-20T12:27:31.602721Z"+ "released_at": "2026-08-20T12:30:00.666330Z" }
src/BRIDGE_VERSION+1−1@@ -1 +1 @@-2.0.259+2.0.260
src/bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "puppeteer", "displayName": "Puppeteer (Chrome for Testing + Native)",- "version": "2.0.259",+ "version": "2.0.260", "description": "Drives a browser ALREADY on the machine \u2014 installed Chrome, else Microsoft Edge (every Windows PC ships with Edge) \u2014 launched with a FRESH isolated profile, so the common case has NO ~150 MB Chrome-for-Testing download and it never touches the user's real tabs/logins. Binds its local server to LOOPBACK (127.0.0.1) only, so no Windows Firewall 'allow Node through the firewall' prompt ever pops. Chrome for Testing is fetched only as a LAST RESORT if the machine has no Chromium browser at all. SPAWN-VERIFIED fallback: pup tries each detected browser (Chrome \u2192 Edge \u2192 CfT) and actually launches it, falling through to the next if one won't start (and handling browsers like Edge that relaunch onto another PID), so a corrupt/partial install never hard-fails an open. The browser that launches is cached as the default (persisted across restarts) so it isn't re-probed each time. On spawn the bridge SELF-WARMS: detects browsers + disk, and only if the box has no Chrome/Edge and no cached CfT does it background-fetch CfT so the first open is instant. pup_use pins a specific browser (chrome | edge | cft | auto); {browser:'chrome',install:true} downloads & installs REAL Google Chrome (user-scoped, no admin) on an Edge-only box. pup_readiness (READ-ONLY) reports which browser will be used + the full candidate list + the default + free disk. Every failure returns a specific errorCode + _hint (chrome_install_no_disk, chrome_download_network, chrome_install_permission, chrome_stable_not_detected, \u2026). Launches with FULL browser permissions by default for full debug (strictPermissions:true opts out). Headful automation: open/close windows+tabs, navigate, screenshot, eval JS, record. pup is a GENERIC, non-profile browser only \u2014 every session is a fresh isolated Chrome/Edge process, never the user's real signed-in browser; profile defaults to sessionId. To drive the user's REAL Chrome/Edge (their profile, cookies, SSO), use the Adom browser EXTENSION's nbrowser_* verbs \u2014 a separate bridge, not pup's job. macOS (v1.9.74+): full parity with mac-native mechanics \u2014 background-by-default is the app-level hide (windows stay drivable/screenshottable while hidden), raise/lower map to unhide+activate/hide, pup_alert_window posts a native toast whose click focuses the window, pup_use {browser:'chrome',install:true} installs Chrome from the official dmg, and taskbar identity/badging remains Windows-only.", "homepage": "https://wiki.adom.inc/adom/adom-bridge", "author": "Adom Inc.",
src/server.js+19−5@@ -10231,11 +10231,25 @@ async function createPageInNewWindow(browser, profileName) { else if (fresh) console.log(`[hwnd] birth capture on "${profileName}" produced no handle — will resolve later`); try { const nowFg = await osGetForegroundWindow();- // Diagnostic only. The playbook (dev-skills/pup-bridge-dev, SOLVED PLAYBOOK) says this can- // never show a steal: with --no-startup-window the browser is a background process and the OS- // denies it the foreground. Measured TRUE on 2026-07-31. If this line EVER logs a steal, the- // playbook assumption broke - investigate, do not add re-park loops (they are banned there).- if (prevFg && nowFg && String(nowFg) !== String(prevFg)) console.log(`[focus] MEASURED: createTarget(newWindow) moved the OS foreground (${prevFg} -> ${nowFg}) — PLAYBOOK ASSUMPTION BROKEN, investigate`);+ // v2.0.259, MEASURED on ConfRoomROG the moment birth moved on-screen: `--no-startup-window`+ // was NOT the only thing suppressing the foreground grab — the off-screen birth was doing half+ // the work, because Chrome does not bother activating a window that is nowhere. Born at a real+ // rect, Chrome activates it, and this logged a steal on EVERY open.+ //+ // R2 says accept a foreground window rather than fight it, and we do: the WINDOW is left where+ // it is (nothing re-parks it, nothing moves it). But the user's KEYBOARD focus is a different+ // thing from the window's z-order, and letting their typing land in a browser that just+ // appeared is not a flaw worth accepting when handing it back costs one call. This is the+ // v1.9.253 handback, restored: it was deleted only because the off-screen birth made it+ // unreachable. One shot, at birth, never on a timer — it is not a re-park loop.+ if (prevFg && nowFg && String(nowFg) !== String(prevFg)) {+ console.log(`[focus] createTarget took the foreground (${prevFg} -> ${nowFg}); the window STAYS where it is (R2), handing your keyboard focus straight back to ${prevFg}`);+ try { await chrome.abCommand('desktop_bring_to_front', { hwnd: Number(prevFg) }, { timeoutMs: 4000 }); } catch (e) {}+ try {+ const after = await osGetForegroundWindow();+ if (after && String(after) !== String(prevFg)) console.log(`[focus] handback did not take (foreground is ${after}) — reporting it rather than pretending; the window is still on-screen and clickable, which is the requirement`);+ } catch (e) {}+ } } catch (e) {} return fresh; } catch (e) {