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 with its AI thread's name in your taskbar or dock.
← Commit history
skills: add 'Driving & verifying tricky pages' — shadow-DOM piercing survey, scroll-the-element (not window) for nested scroll containers, count-in-DOM-then-confirm; + pointer from the main skill's key rules. From the adom-desktop download-card audit. pkg 1.8.26
3 files changed
+36−1
SKILL.md+3@@ -91,6 +91,9 @@ adom-desktop browser_screenshot '{"sessionId":"mytask-web"}' - **One window, many tabs** — use `browser_open_tab`, not a second `browser_open_window`, for multi-URL work. - **`browser_readiness`** (not `browser_status`) answers "is it ready / which browser?". - **No semicolons in `browser_eval`** — use the comma operator or an IIFE.+- **Complex page fighting you?** (a `querySelectorAll` comes back empty, or a screenshot overshoots the+ target) — it's usually shadow DOM or a nested scroll container. Verify by DOM, scroll the *element* not+ the window, count before you eyeball. See `pup-screenshots-recording` → "Driving & verifying tricky pages." - **Never broadly kill Chrome** — `browser_close_window` for a specific session. - **Surface a verb's `_hint` verbatim** whenever it reports not-ready or failure. - Full machine-readable catalog: `adom-desktop browser_describe '{}'`.
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-desktop-puppeteer-bridge",- "version": "1.8.25",+ "version": "1.8.26", "type": "app", "description": "CONTAINER-SIDE install \u2014 the pup skill pack in the wiki skillpack layout: the everyday `pup` user skill PLUS two bundled developer sub-skills (pup-bridge-dev, pup-bridge-publish; user-invocable:false, DEVELOPER-only descriptions so they never trigger for everyday users), all dropped into ~/.claude/skills/ AND ~/.codex/skills/ by an explicit install.sh list. It does NOT contain the bridge runtime: the bridge (Node + browser driving) lives on the DESKTOP \u2014 bundled inside Adom Desktop and published on the Releases tab as adom-bridge-puppeteer-v<ver>.zip, which Adom Desktop streams into its bridges-cache. TL;DR: pkg install = the skill pack; the bridge = the Release zip + bundled in Adom Desktop.", "keywords": [
skills/pup-screenshots-recording/SKILL.md+32@@ -59,3 +59,35 @@ adom-desktop browser_lower_os_window '{"sessionId":"demo-web"}' # tuck it away flow for voiceover — pup just produces the raw capture. - A pup window can record from the **background** too, but for a demo the user will actually watch, raise it first (that's an explicit "show me" case where `foreground` is warranted).++## Driving & verifying tricky pages (shadow DOM, nested scroll) — verify by DOM, not by eye++When you need to find, count, or confirm something on a component-heavy page (an app, a wiki widget), a+naive `document.querySelectorAll` plus eyeballing a screenshot can quietly lie. Three traps + fixes,+learned live auditing a "Download for your machine" card:++**1. Shadow DOM — a plain query can't see inside a web component.** If a widget's innards live in a shadow+root, `querySelectorAll` returns empty. But **first check whether it's even shadow DOM** — many "empty"+results just mean your selector is wrong on plain DOM. Deep-survey for shadow roots (and pierce them the+same way if present — recurse into `.shadowRoot`):++```bash+adom-desktop browser_eval '{"sessionId":"...","expr":"(function(){const hosts=[],walk=r=>{for(const el of r.querySelectorAll(\"*\")){if(el.shadowRoot){hosts.push(el.tagName.toLowerCase()),walk(el.shadowRoot)}}};walk(document);return JSON.stringify({shadowHosts:hosts})})()"}'+```++**2. Nested scroll containers — `window.scroll*` does nothing.** Many layouts put content in an INNER+scroll box, so `window.scrollTo` / reading `scrollY` don't move it and your screenshot **overshoots** the+target. Scroll the **element** — `scrollIntoView` walks up to whatever container actually scrolls:++```js+el.scrollIntoView({ block: 'center' }) // NOT window.scrollTo(...)+```++**3. Count in the DOM, confirm with the eye — in that order.** To count cards/links/rows, count in+`browser_eval` using positions (`rect.top + window.scrollY` = document-Y), which is immune to overshot+screenshots. THEN `scrollIntoView` the element and screenshot to confirm visually. Agreement across+DOM-count + position-cluster + screenshot beats any single signal.++Reminder: `browser_eval` allows **no semicolons** — use the comma operator or an IIFE (as above). If a+screenshot lands on the wrong content, don't trust it — it almost always means an inner scroll container;+re-scroll the element, don't nudge the window.