← Commit history

Teach the highFps decision in the pup skill and record the issue-14 root cause (global power flags, not un-reaped sessions) in the maintainer skill

John Lauer ·528463978b ·3mo ago ·parent c18b064
2 files changed +49−18
SKILL.md+23−18
@@ -29,8 +29,7 @@ does NOT attach to the user's running browser and does NOT run headless. It:    below.) 3. **Renders a REAL window, but keeps it in the BACKGROUND.** It is *not* headless — a real GPU-composited    window, so `browser_screenshot` / recording are true-to-life and canvas/WebGL/media render correctly.-   But pup immediately z-orders it to the **bottom** (Windows: Win32 `SetWindowPos` with-   `SWP_NOACTIVATE`; macOS: the browser process is **hidden**, the Cmd+H state — same contract), so it+   But pup immediately z-orders it to the **bottom** (Win32 `SetWindowPos` with `SWP_NOACTIVATE`), so it    renders **without stealing focus and without covering the user's active window**. You drive and    screenshot it fully while it stays hidden. `foreground:true` is the ONLY thing that shows it. 4. **Spawn-verifies + falls through.** The pick order is **Chrome → Edge → cached Chrome for Testing**; pup@@ -82,22 +81,6 @@ adom-desktop browser_screenshot  '{"sessionId":"mytask-web"}' - **On a fresh PC it's usually a non-event** — pup drives the installed Chrome/Edge with no download. The   rare "no browser at all" / Node-provisioning / disk cases are all in `pup-browsers-and-chrome`. -## macOS differences (v1.9.74+) — same verbs, mac-native mechanics--Every `browser_*` verb works on macOS; only the OS-presentation layer differs:--- **Background = hidden app.** A background open launches the session's browser process hidden-  (the Cmd+H state) — truly invisible, still fully drivable/screenshottable/recordable.-  `browser_lower_os_window` re-hides; `browser_raise_os_window` (with `foregroundReason`)-  unhides + activates. One session = one browser process, so a shared-profile window group-  hides/shows together.-- **`browser_alert_window` = un-hide (not focused) + a native toast** whose click focuses the-  window — macOS has no taskbar to flash. `{stop:true}` dismisses the toast.-- **No taskbar identity on mac** — the per-window icons/badges/jump-lists below are-  Windows-only; on mac the window title's `(session: <id>)` suffix is the identity.-- **Recording** needs ffmpeg (`brew install ffmpeg` — the error hint says so; re-detects-  without a restart).- ## Taskbar preference — the USER can ask for "combined mode"  pup windows each get their own taskbar button by default ("split": one button per window, badged@@ -133,6 +116,28 @@ logged-in view" / "...to public view") — a USER affordance that relaunches tha other cookie jar with on-screen captions. Its callback verb `browser_wiki_set_view` is not for AI threads; pass `wikiView:"authed"|"public"` on browser_open_window instead. Details: `pup-adom-wiki`. +## Recording: normal windows vs `highFps` (power matters)++pup windows are backgrounded by design, and **Chrome throttles an occluded window** — so recording+one at normal power yields a **1-2 fps** video. pup can disable Chrome's power saving to keep it+painting at full rate, but such a window **can never idle down** (three of them once drained a+laptop overnight).++So it is opt-in and **leased**:++- **Default = normal power.** Throttles when occluded, costs nothing in the background. Use this for+  driving, scraping, screenshots, waiting — i.e. almost always. Never ask for `highFps` for these.+- **`browser_open_window {highFps:true}`** for recording a window the user is NOT watching. Lease is+  **20 min** by default (max 120).+- **A running recording holds the lease open indefinitely — you cannot be cut off mid-take.**+- On lapse pup **downgrades** the window (relaunches it with its tabs, at normal power). It is NOT+  closed; content survives.+- **`browser_highfps_extend {sessionId, minutes}`** if you know up front you need longer without+  recording the whole time. You do NOT need to extend during a take.++Every `browser_open_window` response carries a power hint telling you which mode you got and how to+switch. Full detail: the bridge's `RECORDING.md`.+ ## Key rules (the essentials — details in the sub-skills)  - **Always pass `sessionId`** on session-scoped verbs — `'{}'` targets the *active* session, which may not
dev-skills/pup-bridge-debug/SKILL.md+26
@@ -688,3 +688,29 @@ window?" was unanswerable after the fact. There is now one compact line per verb  It includes only the args that change behaviour (sessionId, url, foreground, foregroundReason, view, tabId, owner) and skips `bridge_log_read` so reading the log does not pollute it.++## Battery drain / idle CPU: the four power flags were global (issue #14, fixed v1.9.76)++A user reported 3 pup Chrome processes running 2 days at ~6.5% CPU each, holding a Modern Standby+laptop out of deep idle and flattening the battery overnight. The filed root cause was "sessions were+never reaped." **That was wrong, and reaping would not have fixed it.**++The real cause: pup launched EVERY window with all four of Chrome's power-saving mechanisms disabled+(`--disable-renderer-backgrounding`, `--disable-backgrounding-occluded-windows`,+`--disable-background-timer-throttling`, `--disable-features=CalculateNativeWinOcclusion`). They exist+so a BACKGROUND RECORDING streams full-rate frames instead of the ~1-2 fps an occluded window paints.+Applied globally, they mean a pup window can never enter a low-power state. The tell John spotted:+"people leave Chrome open all the time and laptops sleep fine" — a normal Chrome THROTTLES when+occluded; ours structurally could not.++Fix: the flags are now **opt-in** (`highFps:true`) and **leased** (default 20 min, max 120). An+active recording holds the lease open indefinitely (authoritative via `tabRecordStatusImpl` /+`desktopRecorder.current`, not a heuristic), so a take is never cut off. On lapse the session is+**downgraded** by relaunching without the flags carrying its tabs, never closed.++**Do not re-add these flags globally.** If a recording looks choppy, the window needed `highFps`, not+a global flag. Docs: `RECORDING.md`.++**Lesson beyond this bug:** a filed issue can have a correct symptom and a wrong root cause. This one+was well written and specific, and still misattributed. Check the report's causal claim against your+own code before building the fix it asks for.