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: launch park bottoms unconditionally, escape hatch documented as dead end (OS foreground reassignment after window destruction is not a user click)
1 file changed
+35−21
dev-skills/pup-bridge-dev/SKILL.md+35−21@@ -256,12 +256,16 @@ tiny Win32 call, no PS window-hunting, no timers, no loops.** Lives in `tryDetac "window exists" event. No wait loop, no polling.** 3. `parkSessionWindowDirect(page, sessionId)`: - hwnd via **AD `desktop_find_window`** (native, matches the "(session: <id>" title suffix the- welcome page just set; ~4 quick retries).- - `osBottomUnlessForeground(hwnd)` — the ONE residual Win32 PS call (3 lines): reads- `GetForegroundWindow()`; if it's the pup window, that can ONLY be a user's taskbar click- during the launch gap (the launch flag makes Chrome self-raise impossible) → CDP places- on-screen + AD `desktop_bring_to_front`, report `user-foreground`. Otherwise- `SetWindowPos(HWND_BOTTOM, NOMOVE|NOSIZE|NOACTIVATE)` — z-order only.+ welcome page just set), retried together with the bottoming below (~8 × 300ms).+ - **Z-bottom UNCONDITIONALLY** (`osBottomUnlessForeground(hwnd, force=true)` — the ONE residual+ Win32 PS call): `SetWindowPos(HWND_BOTTOM, NOMOVE|NOSIZE|NOACTIVATE)`, z-order only. There is+ deliberately **NO user-click escape hatch at park time** — see the dead ends: "foreground at+ park" has non-user causes and honoring it forced never-clicked windows onto John's screen.+ - **HARD RULE: never move the window on-screen until 'bottomed' is CONFIRMED.** If bottoming+ can't be confirmed after the retries, return an honest `park-failed` and leave the window+ invisible off-screen — the self-heal (reattach / open_tab / switch_tab / any status query)+ retries it. An un-bottomed window moved on-screen lands ON TOP of the user's work (the+ nxp.com pop, v1.8.59). - **Geometry via CDP `Browser.setWindowBounds`** addressed by windowId — parking the WRONG window is structurally impossible (the PS EnumWindows/pid-hunt version parked a phantom under parallel opens and the window stayed invisible off-screen). Sequence: `normal` → move to@@ -269,6 +273,10 @@ tiny Win32 call, no PS window-hunting, no timers, no loops.** Lives in `tryDetac `screen.availWidth` — the probe can fail mid-navigation and ships undersized windows). - **Self-verify POSITION** via CDP `getWindowBounds` (left/top > -5000), NOT focus — a focus-only verify passed while the window sat off-screen ("backgrounded" lie).+ - **The launch-gap contract:** a user who clicks the taskbar button within the ~2s before the+ park lands may see nothing (window still off-screen) or get parked once — they click ONCE+ more and the window comes up and STAYS (nothing re-parks after the park exits). That is the+ accepted trade; do not "improve" it with foreground detection. 4. The open response awaits the verdict (`_bgPromise`); badge (`badgePupTaskbar`) + flash fire the INSTANT the park lands — no blind 1.5s/3.5s badge timers. 5. Nothing ever re-parks. `foreground:true` opens skip all of this and launch maximized on-screen.@@ -351,7 +359,15 @@ must clear it first. loop, you have re-broken the launch flag — fix that instead. - **`document.hasFocus()` (CDP) as the user-click signal** → LIES for CDP-created windows: reports internal focus even when the OS never foregrounded them. False-fired `user-foreground` on EVERY- open (1.8.53). The only honest signal is Win32 `GetForegroundWindow()`.+ open (1.8.53).+- **`GetForegroundWindow()` at PARK TIME as the user-click signal (the launch-gap escape hatch,+ 1.8.52-1.8.59)** → even the honest OS signal is NOT a user signal during the launch gap: Windows+ REASSIGNS the foreground to a brand-new window when the previous foreground window was just+ destroyed (a bridge-update restart killing pup windows did exactly this), plus creation blips.+ Honoring it force-foregrounded windows the user NEVER clicked (nxp.com, another thread's cpconn)+ — the #1 forbidden behavior. REMOVED in 1.8.60: the launch park bottoms unconditionally; a user+ who clicked during the ~2s gap clicks once more and it sticks. GetForegroundWindow remains valid+ AFTER startup (the late re-park paths), where a destroyed-foreground handoff can't target the window. - **PS window-hunting (EnumWindows / `MainWindowHandle` / pid+CIM child walks) to find the window** → heavy (~1-2s process+compile per park = the whole "first 2 seconds" gap) AND mis-resolved under parallel opens (parked the wrong/phantom window; the real one stayed invisible off-screen while the@@ -378,21 +394,19 @@ and use normally**. Both must hold at once. Get the handoff right: - **The moment the user takes a window, it becomes a normal foreground window** — visible, on-screen, usable, and it **STAYS** that way. pup must never fight a deliberate user action. -**How pup tells a user-raise from Chrome's self-raise — FINAL ANSWER (v1.8.51+): it doesn't have-to, because Chrome can no longer self-raise.** `--no-startup-window` makes "pup window is-OS-foreground" (`GetForegroundWindow`, read inside `osBottomUnlessForeground`) mean exactly ONE-thing: the user clicked it. No `GetLastInputInfo`, no input-timing, no heuristics — all of those-were shipped and all false-fired (see dead ends).+**How pup tells a user-raise from Chrome's self-raise — FINAL ANSWER (v1.8.60): it doesn't detect+user-raises AT ALL, in either direction.** `--no-startup-window` means Chrome can't self-raise, and+pup makes exactly ONE park then exits — so there is nothing to detect and nothing that can fight+the user. Every detection signal was shipped and every one false-fired (`GetLastInputInfo`,+`document.hasFocus()`, even `GetForegroundWindow` at park time — see dead ends). -**When the user has the window (at park time or ever after):**-1. **Bring it ON-SCREEN and SHOW it** (CDP place + AD `desktop_bring_to_front`). The window may- still be at its off-screen launch coords, so *just bailing out* activates an **invisible**- window — the user clicks the taskbar and sees NOTHING (the v1.8.44 regression, and again the- v1.8.51 launch-gap bug).-2. **Leave it alone forever.** There are no re-park passes to latch off anymore — after the single- park, nothing in pup can background a window the user holds. The only re-park paths left are the- explicit `browser_lower_os_window` verb and the off-screen SELF-HEAL (which checks bounds first- and never touches an on-screen window).+**The contract:**+1. **During the ~2s launch gap** a taskbar click may show nothing (window still off-screen) or be+ parked once. The user clicks ONCE more and the window comes up — cheap, bounded, honest.+2. **After the park, the user owns every raise, forever.** Nothing in pup can background a window+ the user brought up. The only re-park paths left are the explicit `browser_lower_os_window`+ verb and the off-screen SELF-HEAL (which checks bounds first and never touches an on-screen+ window). ## The taskbar flash — pulse vs. the persistent tint (clearing it programmatically)