Pup - Puppeteer Bridge
Public Made by Adomby adom
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.
Releases 572
Standalone per-platform binaries to download and run, no tools needed. The newest is pinned on top.
Fixes a data-loss race in pup_quit_idle_browsers that could close a browser holding live windows. It judged idle purely by adopted in-memory sessions, so right after a bridge restart, before re-adoption runs, a warm browser still holding real windows looked session-less and got closed, taking every window with it. It now inspects the browsers ACTUAL open pages before closing and skips any browser that still holds a non-blank page, or that cannot be inspected, so a browser mid-re-adoption or user-held is never reaped
All releases showing 361-380 of 572
CRITICAL delivery fix found while testing the bug-report invitation: anything sendJSON attached to the OUTER response envelope was DROPPED on every SUCCESSFUL call. The conventional success shape is {success:true, output:''} and AD/the CLI unwrap output into the top level, discarding the rest of the envelope — measured: a browser_navigate success returned {durationMs, ok, sessionId, status, tabId, url} with NO _hint, _next, related, pitfalls or _reportIssues, even though sendJSON had set them. Failures survived only because their handlers write those fields on the outer object. So the canonical VERB_META hints — the SDK's whole 'every response teaches the caller' principle — were reaching callers only on failure, exactly backwards. sendJSON now merges the advisory fields INSIDE output when output is a JSON object string, never overwriting what a handler already set there.
Third attempt at the once-per-process bug-report invitation, this time with the actual cause. Machine traffic was eating it at TWO layers, each failing silently: AD's /health and /status probes flow through the same sendJSON chokepoint (fixed in 1.9.96 by requiring a verb), and AD ALSO calls pup's declared statusVerb (browser_readiness) through /command on spawn, so it arrived as a real verb and consumed the invite anyway. The orientation invite now fires on the first SUBSTANTIVE verb (an open/drive — the moment John described, 'when typical verbs are being invoked like open browser'), while read-only probes and enumerations neither consume nor carry it. A FAILURE still always carries the invitation regardless of verb, because that is when the evidence exists.
Fix the once-per-process bug-report invitation never reaching an AI: AD probes /health (and /status for the bridge chip) every ~15s and those replies flow through the same sendJSON chokepoint, so the first health probe after a spawn consumed the invitation and the first real verb carried nothing (measured after a restart). The invite is now VERB-SCOPED — it only counts responses that belong to an actual AI-facing command (res._adomCommand), so a machine-facing probe can neither consume the orientation invite nor advance the periodic counter.
Ask the AI to report bugs, in the response it actually reads (John's ask). pup now attaches a _reportIssues invitation naming its own wiki repo (adom/adom-desktop-puppeteer-bridge) with the exact adom-wiki issue list/create commands and what evidence to include. Deliberately throttled so it is signal, not noise: ALWAYS on a failure (the moment a bug is most likely and the evidence is still in hand), ONCE per bridge process on the first verb (orientation before anything breaks), and every 40th call after that. It also points AD-core problems at adom/adom-desktop instead, so reports land on the repo that owns the code. Injected at the sendJSON chokepoint so all 155 response sites are covered, and never overrides a hint a handler already set. Opt out with browser_configure {reportIssues:'off'}.
Fix issue #22 Finding 4 (AdityaAngajala): a stalled background Chrome-for-Testing prewarm blocked EVERY browser_open_window on a machine that had system Chrome AND Edge, while browser_readiness simultaneously reported browserSource:'system' with a valid chrome.exe. Two defects, both mine from the native-first change: (1) getOrLaunchBrowser still kicked the retired v1.8.71 'converge this box to CfT' background prewarm on a native launch — I removed that same kick from chrome.warmup() in v1.9.90 and missed this one, so a native launch still started a ~150 MB download nobody asked for. Removed; native-first fetches CfT only as the genuine last resort. (2) chrome.readiness() computed ready = found && !installing, conflating 'a background download is in flight' with 'nothing is drivable' — so an in-flight or STALLED last-resort download made the whole subsystem not-ready and the open gate refused on !rd.ready. ready now means only 'a drivable browser exists'; installing stays a separate informational field and never gates drivability.
Fix issue #16's residual: browser_list_windows reporting 0 windows while the windows are open and drivable by sessionId. Root cause: getActiveSession() was a RESOLVER that silently PURGED the session map — it deleted every session whose isSessionAlive() was false, with no _lostBrowser guard (unlike resolveSession, which deliberately keeps disconnected entries for rescan). And isSessionAlive() consulted ONLY the browsers map, so the instant handleBrowserDisconnect deleted that entry on a CDP blip, every session on the profile read as dead. Net effect: one call after a transient disconnect wiped the ENTIRE session map, destroying the exact entries the disconnect handler had just preserved for recovery. Fixes: (1) getActiveSession is now non-destructive — it marks _lostBrowser instead of deleting; removal belongs to the close/rescan paths. (2) isSessionAlive falls back to asking the session's own page whether its browser is still connected, so a drivable session can never report as not-alive. (3) Hardened the v1.9.89 orphan reap with the same lesson: it now REFUSES to sweep when the session map is empty while session files still exist on disk (recovery pending), so it can never mistake the user's live windows for orphans.
Reconcile the repo/release divergence (issue #19): merge Kyle's ten unreleased macOS fixes onto the true 1.9.90 tree. Takes his win32 self-guards on the three powershell.exe spawn primitives (removes a latent mac trap), the desktop_taskbar mac-gating rationale, platform-accurate describe hints for browser_wiki_set_view / browser_alert_window / browser_close / browser_configure, browser_configure now reporting platform + taskbarSupported, and the mac-aware Chrome .dmg install hint (no UAC/awaiting_uac phase on darwin). Reconciles his local _isWin against the module-level one added in 1.9.89. Also fixes bridge.json platforms.macos.supported, which had declared FALSE since the macOS port actually shipped in 1.9.74 and is the machine-read manifest a host reads to decide platform support. All 1.9.86-1.9.90 work verified intact (reap fix, wiki auto-sign, native-first).
Flip pup's default browser to NATIVE-FIRST. launchCandidates() now orders the user's installed Chrome, then Edge (ships on every Windows PC), FIRST, driven with a fresh isolated profile PLUS the noBrowserIdentityFlags that suppress Chrome's sign-in / set-up-a-work-profile merge dialog. Chrome-for-Testing is now the genuine LAST RESORT, fetched only when the box has no installed Chromium at all; warmup() no longer force-downloads CfT when a native browser is present. This makes native as clean as CfT (the identity-dialog reason for CfT-first was already invalidated: CfT shows the same dialog, the flags are the real fix and apply to any Chromium), with no 150MB download, always the user's current battle-tested build, and all taskbar identity overrides work identically. browser_use {browser:cft} still pins CfT for a managed/enterprise box whose policies interfere. Cold-start gate + hints updated; decision doc flipped.
Fix browser_close leaving core-pegging renderer orphans that froze the desktop. The teardown reap was fire-and-forget with an 8s full-Win32_Process enumeration that TIMED OUT exactly when the box was CPU-pegged by the runaway renderers it existed to kill (AdomLapper: 88-98% CPU, dwm starved, forced reboot; 6 CfT procs survived a close, 4 renderers near 100%). Now the reap is AWAITED, VERIFIED, and load-tolerant: WMI image-name filter is pushed server-side so only chrome/msedge rows materialize (fast at 98% CPU), close() awaits the profile-scoped kill of the parent tree PLUS any reparented renderer orphans, and every close response returns chromeProcsRemaining (should be 0). Adds a boot + periodic orphan sweep (reaps pup chrome whose profile has no live session, spared by profile) and a verified close-all sweep.
Wiki auto-sign: pup now signs its wiki window in AUTOMATICALLY from the user's identity that AD already stores at ~/.adom/session.json on the same desktop (mints a single-use browser-session magic link server-side from that bearer token and navigates the vault window to it), instead of ever making the user hand-type a login into pup's no-memory browser. Applies to BOTH the jump-list logged-in-view toggle and the AI wikiView:authed open path; manual /login is now only the fallback when AD itself is signed out or the session expired.
Recover from the 1.9.86 mac-parity regression: rebase onto Kyle's 1.9.85 unified base and re-apply only the puppeteer 24.43.1 / CfT 148 bump. Restores darwin support, recorder-icon.ico, and the AD-base resolver that 1.9.86 dropped.
Cache-bust re-cut of the puppeteer 24.43.1 / CfT 148 bump (1.9.85 release URL served a stale edge-cached zip)
Reunifies the two divergent release lines: John's 1.9.76-1.9.84 Windows work + the mac-parity line (hidden-app background, mac lower/raise/alert, dmg Chrome install, verified-AD-base resolver). Restores pup-cat category icons + recorder icons to the zip. Supersedes 1.9.75 and 1.9.84.
Extend the wiki sign-in auth re-check to ~90s so a real manual SSO+2FA sign-in also flips the glyph/label/icon to logged-in when it completes, stopping early on success or if the window closes
Wiki sign-in: after navigating to the login page, re-check auth in the background and flip the glyph/tab-label/category-icon to logged-in when the hydrogen SSO auto-completes (an already-alive SSO session lands back signed in with no form to fill)
Wiki logged-in toggle: when no wiki session exists yet, navigate THIS window to the sign-in page and raise it, instead of showing a dead-end sign-in-in-this-window toast on the public page
Make the orphan-renderer reap NON-BLOCKING: the v1.9.78 reap ran a synchronous 8s PowerShell CIM query on the close path, freezing the event loop and making the bridge unresponsive to AD's health check (self-inflicted restart). Fire-and-forget async instead
Reclassify a timed-out/detached tab op as the structured renderer-crashed error at the dispatch catch (first-verb fast-fail for issue #16)
Reclassify a timed-out/detached tab op as the structured renderer-crashed error at the dispatch catch, so even the first verb that discovers a crash returns the reload-to-recover hint instead of a generic 20s timeout