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 321-340 of 572
10px inset on every side of the work-area placement (John: 'reduce it by 10px on all sides so i can tell you literally did this purposely') — position = work area X+10,Y+10, size = work area minus 20 in each dimension. A pup window now sits visibly, deliberately framed inside the work area: taskbar never covered, a uniform 10px margin proving the geometry is computed, not accidental.
Park and window-sizing now use the primary monitor's WORK AREA instead of raw resolution (John: 'use the work area'). All four GetSystemMetrics(0)/(1) sites swapped for Screen.PrimaryScreen.WorkingArea, with position taken from the work area's X/Y — so a taskbar on ANY edge (bottom, left, top) is respected and no strip of a pup window ever hides behind it. Same behavior as a genuinely maximized window.
Drop --window-position=-32000 and --window-size from background launches (John: 'if --no-startup-window then stop fighting it'). With no-startup-window Chrome starts with NO window, so the off-screen position arg protected nothing on the main path — while silently poisoning every window Chrome itself creates (popups, target=_blank, restores) with an off-screen DEFAULT position, which is the likely mechanism behind windows found stranded at -32768 even after being foregrounded. Geometry now has exactly one owner: the park (on-screen, bottom z, full size, no-activate).
Emergency follow-up to 1.9.133, which shipped with a JS SYNTAX ERROR (a python-style # comment inside the PS-lines array — my parse check ran AFTER the ship gate instead of before, the documented patch/ship desync repeated). Also fixes the size John hit immediately: the CDP park kept 1280x800, so on-screen-parked windows appeared small; now near-fullscreen fallback at the CDP site and the SetWindowPos park corrects to the true screen work area right after. Park contract: on-screen, bottom z-order, no-activate, full size.
Background windows now park ON-SCREEN at the BOTTOM of the z-order instead of at -32000,-32000 (John's design, implemented immediately after the trap bit him twice in one hour: agenda-monday, then the gmail window whose taskbar click showed nothing). Both park sites changed — the CDP Browser.setWindowBounds park and the SetWindowPos park, which already used HWND_BOTTOM + SWP_NOACTIVATE so only the coordinates were wrong. Background still means: no focus steal, covers nothing the user works on (it is BEHIND everything). But the window is now always at real screen coordinates, so a user's plain taskbar click is pure native Windows foregrounding of a correctly-placed window — no pup code in that path, nothing to catch, the failure is structurally impossible. Known accepted tradeoff: bottom-z windows show in desktop peek. The -32000 launch-instant args remain as belt-and-suspenders for the pre-park moment only.
Clean up zombie sessions automatically and REPORT the cleanup to the next caller (John's design). Two parts. (1) Zombie detection was gated on _lostBrowser, a flag only set when a DISCONNECT EVENT fires — a Chrome killed outright (the bridge-restart tree kill) never emits one, so those sessions sat with 0 tabs, no flag, and were never dropped. That is exactly the four zombies John found cluttering browser_list_windows for every thread. Zero tabs plus a dead CDP port is now sufficient, with a _launchInFlight guard so a session mid-launch is never mistaken for one. (2) A cleanup REPORT QUEUE: each janitorial action (zombie session dropped, orphaned browser processes reaped) is recorded and attached to the NEXT verb response as _cleanupReport, then dropped — report-once. Per John, the receiving thread is usually NOT the one whose window was cleaned; that is accepted, it can ignore the note, and the information still reaches the user eventually instead of never. Verb-scoped so AD's health poll cannot swallow it, capped at 12 entries, and added to the output-merge list because anything left on the outer envelope is silently dropped on a SUCCESSFUL call.