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.
Releases 1153
Standalone per-platform binaries to download and run, no tools needed. The newest is pinned on top.
Annotate's quick colors are red, blue and green: the muddy yellow/orange third color is gone from the trio and from Multi's automatic cycle (red, blue, green, purple), so every mark has a color anyone can name to the AI. Yellow stays in the More flyout, and every swatch shows its color name on hover (John, 2026-10-07).
Stable link for websites and docs: /download/adom/pup-bridge/latest
All releases showing 741-760 of 1153
Fix sleep/wake window loss: the 8s reaper was racing sleep-recovery and killing recovered windows. On wake, rescan reattaches a page then prunes it as the dead pre-sleep tab, leaving the session at 0 tabs with _lostBrowser already cleared, so the reaper deleted it before the healer relaunched. Now: re-mark any post-prune empty session as lost + refresh its heal window; the reaper never reaps a session the healer is still trying to recover (until it explicitly gives up)
Birth-time handle resolution: each new window is born at a unique off-screen position and its OS handle captured while off-screen and small (before park maximizes it), the only unambiguous moment for a same-profile window; the resolver trusts this birth handle ahead of all geometry heuristics. Finally resolves multi-window profiles the width-wiggle never could
Reliable wiggle-free handle resolution: a profile process with exactly one window resolves to that window directly (works on maximized windows, which the width-wiggle never could); multi-window profiles still leave bare rather than guess until birth-time resolution lands
Make window-handle resolution conservative (correct-or-bare, never wrong): raise the wiggle serialization timeout above the enumeration time so concurrent wiggles cannot collapse multiple windows onto one handle; use a distinctive narrow marker width real windows never sit at; verify the width actually applied; require EXACTLY ONE match or leave the window bare rather than paint a guessed/shared handle
Kill overlay drift at the source: one centralized debounced overlay re-sync now fires for every mutating verb (navigate/reload/back/forward/switch_tab/click/type/eval) plus close_tab/close_window, clearing the favicon cache and repainting via the ungated applyAppOverlay (refreshWindowChrome was a no-op under minimalTouch), without touching the cached handle so no routine verb triggers the wiggle
Fix window-handle desync + stuck regenerate: time-box the width-wiggle lock so a hung holder cannot deadlock the whole chain (was leaving every window hwnd=None); persist the resolved OS handle to the session file and restore+validate it on respawn so windows stop re-wiggling after every ship; regenerate button preempts a wedged busy flag, per-window timeouts, and always clears the flag
Regenerate-overlays button now runs the sweep in the background and answers instantly (dashboard icons update live via SSE); header shows regenerating/last-sweep status; per-window drift report logged
Dashboard taskbar strip now shows the teal pup tile for every pup window (matching the real taskbar) instead of Chrome's exe logo for un-stamped windows; add a Regenerate All Overlay Icons header button that re-runs the from-scratch overlay algorithm on every window and reports which windows drifted
Fix missing taskbar overlay: hwndBelongsToPup now requires a real top-level visible Chrome_WidgetWin_1 frame, not just any window owned by the profile process. A stale same-process utility handle (18) was passing the pid-only check forever, so overlays painted onto a non-taskbar window and never appeared
Fix duplicate tab on burst opens: the popup-tracker was double-attaching pup's own in-window window.open blanks (which addTabToSession already adopts); it now skips any tab tagged with the pupclaim_ window.name marker
Fix in-window tab adoption: identify the window.open tab by a unique per-call window.name marker instead of set-difference, which under a burst of adds could adopt the wrong new target and duplicate tabs
Fix orphaned about:blank tabs: adopt the window.open tab by target set-difference instead of a racy opener match, which used to leave a stray blank tab beside the real one whenever the anchor page was mid-navigation
Serialize the width-wiggle resolution so it is actually unique (1.9.290 collapsed everything onto one hwnd because the enforcer fires resolves CONCURRENTLY - their width changes and window enumerations overlapped, so every session matched whichever window was momentarily at a marker width). A global lock now guarantees exactly one wiggle (set unique width -> enumerate -> restore) runs at a time, with the lock released on every path including the error path (hoisted release handle so the outer catch frees it - no deadlock).
Robust observer-proof window resolution via UNIQUE-WIDTH WIGGLE (finally kills the dup-hwnd bug for all windows, clean titles kept). With titleTag off, the transient-title approach was fought by each page's own title observer (un-disconnectable on pre-1.9.288 pages), so same-profile windows parked at the identical rect collapsed onto one hwnd. New approach: when the tag is off, pup gives the window being resolved a UNIQUE width via CDP Browser.setWindowBounds (pup controls this directly, no page script can fight it), matches the one OS window at that exact width, then restores - deterministic and unambiguous even for many same-profile windows. Guarded to never resize a foreground window the user is looking at (falls back to plain bounds there); the window is off-screen during most resolves so the width change is invisible. Title-tag-ON path still uses the exact persistent-tag find. Together with the reconciler's duplicate-hwnd self-heal (clears any shared cache to force re-resolve), every window binds to its own unique handle.
Duplicate-hwnd self-heal: the reconciler now detects any OS handle claimed by more than one live session and clears the cached hwnd on all of them, forcing each to re-resolve to its own unique window (reliable now that 1.9.288 stopped the tag-strip observer from fighting the transient resolution). This corrects stale wrong-hwnd caches that per-profile validation cannot catch (two windows of the same Chrome process), so John's wildlife-compare/haircut-review shared-handle case self-heals within a sweep instead of persisting. Verified: two fresh same-profile windows resolve to distinct handles.