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
Dev skill: no-startup-window is THE architecture; every re-park loop variant is a documented dead end with the versions that proved it
1 file changed
+28−3
dev-skills/pup-bridge-dev/SKILL.md+28−3@@ -234,7 +234,27 @@ the user's keystrokes land in the invisible pup window. Requirements that must h R1 never visually pop / cover the user's work · R2 the window is reachable (taskbar-clickable) · R3 CDP `browser_screenshot` still works · R4 never steal keyboard focus · R5 no console/terminal flash. -**The working design (4 techniques layered — all four are required):**+**The working design (v1.8.51+). The KEY insight, found after a week of warring with re-park loops:+`--no-startup-window` eliminates the focus steal at the SOURCE, so there is NO war to fight.**++Windows only grants a process the right to take the foreground AT LAUNCH. With `--no-startup-window`+the browser process starts with NO window at all; pup creates the window via CDP (`newPage()`) moments+later, by which time the browser is a background process and **the OS itself denies it the foreground**.+No steal is possible → no watchdog, no timers, no re-park passes exist → **a user's taskbar click at ANY+moment (200ms in or 2 minutes in) has nothing running against it and always sticks.** Do NOT add any+loop that re-parks after the initial park — every such loop, no matter how clever (input-timing, short+windows, stability watches), eventually yanks a real user's click. John proved each variant failed.++The full background open sequence (`tryDetachedLaunch` + `osBackgroundWatchdog`):+1. Spawn with `--no-startup-window --window-position=-32000,-32000` (no `--start-maximized`).+2. Connect CDP; `newPage()` creates the window (off-screen, unfocused — the OS denied foreground).+3. ONE hidden-PS park: wait for the window to EXIST (EnumWindows @50ms, pid-list refresh only every+ 500ms — refreshing every tick blew the process budget under parallel opens), hand focus back IF+ somehow taken (normally a no-op), `SetWindowPos(HWND_BOTTOM, 0,0,scrW,scrH, SWP_NOACTIVATE)`,+ self-verify, EXIT. The open response awaits this verdict (`background: backgrounded`).+4. Nothing ever re-parks. `foreground:true` opens skip all of this and launch maximized on-screen.++**The 4 techniques (still true, now mostly belt-and-suspenders):** 1. **Launch OFF-SCREEN** → satisfies R1. Background windows launch with `--window-position=-32000,-32000` (NOT `--start-maximized`; strip it when `!foreground`). The window is@@ -295,8 +315,13 @@ must clear it first. AND keeps it rendering. (`osMinimizeToBackground` may still be in the tree, unused — do not wire it back.) - **`MainWindowHandle` to resolve the window** → returns a hidden Chrome helper on some boxes; you park a phantom and the real window never moves. Enumerate `Chrome_WidgetWin_1` instead (technique #2).-- **A long/aggressive re-park retry loop** → fights the user's click (yanks the window back). Keep it short- (~1.2s) and input-aware (technique #3).+- **ANY re-park loop after the initial park — blind timers, input-aware, short-windowed, stability+ watches — ALL of them** → each variant was shipped (1.8.44→1.8.50) and each one eventually yanked a+ real user's taskbar click back to the background. Input heuristics (`GetLastInputInfo`) false-fire+ whenever the user types anywhere; foreground checks can't tell an early click from a self-raise; even+ a 50ms-reaction stability watch fought a click in the first 2s. The ONLY correct fix is+ `--no-startup-window`: no steal can happen, so no loop is needed. If you think you need a re-park+ loop, you have re-broken the launch flag — fix that instead. - **`WS_EX_NOACTIVATE` on the window** → Chrome self-activates anyway (so it doesn't fix R4), AND a non-activatable window can't be brought up by a taskbar click (breaks R2). Rejected. - **Minimize→re-show loop as the focus drop** → on an on-screen window the minimize/restore is a visible