← Commit history

Migrate asset from Helium wiki

Kyle Bergstedt ·52534ca588 ·4mo ago ·parent 727e1dd
1 file changed +213
pup-SKILL.mdadded+213
@@ -0,0 +1,213 @@+---+name: pup+user-invocable: true+description: "Control Puppeteer browser windows on the user's desktop via the adom-desktop CLI. Use for: opening/closing browser windows, reloading pages, taking screenshots, evaluating JS, flashing taskbar alerts, navigating URLs, checking errors, managing multi-session Chrome. Trigger words: pup, puppeteer, browser window, browser reload, browser screenshot, pup reload, pup screenshot, pup alert, browser debug, visual debug, open in browser, reload browser, flash taskbar, browser_reload, browser_alert_window, browser_open_window, browser_screenshot, browser_eval."+---++# Pup — Puppeteer Browser Control++Control Chrome browser windows on the user's desktop via the `adom-desktop` CLI.++## How to Run Commands++All `browser_*` commands are run via the `adom-desktop` CLI using Bash:++```bash+adom-desktop <command> '<json_args>'+```++**Examples:**+```bash+adom-desktop browser_reload '{"sessionId":"dart2"}'+adom-desktop browser_alert_window '{"sessionId":"dart2"}'+adom-desktop browser_screenshot '{"sessionId":"dart2"}'+adom-desktop browser_open_window '{"sessionId":"myapp","profile":"myapp","url":"http://localhost:3000"}'+adom-desktop browser_eval '{"sessionId":"dart2","expr":"document.title"}'+```++**IMPORTANT:** These are NOT MCP tools. They are Bash commands. Use the Bash tool to run them.++## Available Commands++### Session Management+| Command | Description | Required Args |+|---|---|---|+| `browser_open_window` | **Spawns a new pup window**. Only use when there isn't an existing session of that name. | `sessionId`, `profile`, `url` |+| `browser_close_window` | Close a specific session | `sessionId` |+| `browser_focus_window` | Bring window to foreground | `sessionId` (optional) |+| `browser_alert_window` | Flash taskbar icon (non-intrusive) | `sessionId` (optional) |+| `browser_switch_window` | Switch global active session | `sessionId` |+| `browser_list_windows` | List all open sessions | none |++### ⚠ Don't double-open windows — `browser_navigate` reuses, `browser_open_window` spawns++If a session already exists (verify with `browser_list_windows` or `browser_list_tabs`), point an existing tab at a new URL with **`browser_navigate`** — passing `tabId` if you want to be explicit:++```bash+adom-desktop browser_navigate '{"sessionId":"chip-fetcher","tabId":"tab-1","url":"<new-url>"}'+```++Using `browser_open_window` against a session that's already alive **spawns a second physical pup window** with the same title. The new tab is tracked but the old window is orphaned — the user sees two windows showing the same content. Verified painful 2026-05-04: opened a chip-fetcher dashboard verification tab while the original UL Pro detail tab was still active; user noticed the duplicate before I did. Cleanup required `desktop_close_window` and a tracked-tab marker dance.++**Decision tree:**+- Need a new session entirely (different `sessionId`) → `browser_open_window`.+- Need to reuse an existing session's tab → `browser_navigate` (with `tabId` if multiple tabs).+- Need a second tab in the same session → `browser_open_tab` (not `browser_open_window`).++### ⚠ Cross-sessionId duplicates — same app, two windows++The double-open trap above catches *same-sessionId* re-opens. There's a second flavor that catches you across conversation boundaries: **a previous session left a pup window open under one `sessionId`, and the new conversation opens the same app under a different `sessionId`** — adom-desktop happily creates a second window because the keys differ. The user sees two pup windows showing the same content.++**Always run `browser_status '{}'` before `browser_open_window`** at the start of a new conversation, especially after a context compaction. Look for any session whose URL maps to the app you're about to open. Reuse it (`browser_navigate`) instead of creating a peer.++Verified 2026-05-07 with chipsmith: an earlier session had `sessionId: cs-v2` open at `…/proxy/8872/`. New conversation opened `sessionId: chipsmith` at the same port — two windows for the same chip. User noticed the duplicate first.++When closing a duplicate, prefer the OLDER one (lower `cb=` timestamp in URL); the newer one usually has the working state you just built up.++### Page Commands (all accept optional `sessionId`)+| Command | Description | Key Args |+|---|---|---|+| `browser_reload` | Reload page + clear error log | `sessionId` |+| `browser_navigate` | Navigate to new URL | `url`, `sessionId` |+| `browser_screenshot` | Capture page screenshot (lossless PNG) | `sessionId`, `maxWidth`, `fullPage` |+| `browser_eval` | Evaluate JS expression in page | `expr`, `sessionId` |+| `browser_errors` | Get console/page errors | `sessionId` |+| `browser_wait` | Wait for content to settle | `ms` (default 3000) |+| `browser_status` | Check all sessions | none |+| `browser_close` | Close ALL sessions | none |++## Common Patterns++### Reload + Alert (after code changes)+```bash+adom-desktop browser_reload '{"sessionId":"dart2"}' && \+adom-desktop browser_alert_window '{"sessionId":"dart2"}'+```++### Debug Loop+1. Edit code+2. `browser_reload`+3. `browser_wait` (3-5s for 3D tiles)+4. `browser_screenshot`+5. `browser_errors`+6. Analyze, repeat if needed++### Check Connectivity+```bash+adom-desktop ping+```++## Pick ONE surface — respect the user's window-mode preference++Hydrogen stores a per-session **window mode** preference: `webview` (default) or `pup`. Check it before opening a window:++```bash+adom-cli hydrogen probe  # → { ..., "window_mode": "webview" | "pup" }+```++- **`webview`** → open as a Hydrogen webview tab (`webview open-or-refresh`)+- **`pup`** → open via Adom Desktop (`pup browser_open_window`). If Adom Desktop isn't reachable, fall back to webview and warn.++**Never open the same content in both at once.** User+feedback 2026-04-26: *"why the fuck did you open something in pup+and some stuff in webview. pick one or the other."*++Two costs of dual-opening:+1. Two copies of the page → user sees changes in one but not the+   other → "why doesn't my upload show up?" or "which one is+   real?".+2. Background WS / polling traffic doubles, which makes the+   Cloudflare-blipping problem worse.++When window-mode is `webview`, the decision rule:++| Use case | Surface | Why |+|---|---|---|+| Automated test, screenshot, eval, ralph loop, scripted multi-step demo | **pup** (even in webview mode — this is automation, not user-facing) | scriptable; doesn't compete with the user's tabs; pup's `browser_eval` works on every tab |+| Showing the user a finished result they should look at | **Hydrogen webview tab** (`adom-cli hydrogen webview open-or-refresh`) | the tab persists in their workspace; they can interact normally |+| Both at once for the SAME content | **don't** | pick whichever role the situation calls for and stick with it |++When window-mode is `pup`, everything goes through Adom Desktop — including user-facing results.++If you've opened the user's Hydrogen tab for a dashboard / viewer,+use **that** tab for screenshots too via `adom-cli hydrogen+screenshot panel --name "<tab-name>"`. Don't ALSO open a pup+window of the same URL. If you started in pup for testing and the+user wants to see the final state, route them to a Hydrogen tab+once and close the pup window.++Memory rule still applies for testing: pup is the testing surface,+NOT Hydrogen. The point of THIS rule is: don't open both for the+SAME content at the SAME time.++## Multi-URL workflows — ONE window, MANY tabs++When you'd open more than one URL for the same user task (vendor+fetch, multi-doc review, compare-pages workflows), put them in+**tabs of one window**, not separate windows. User feedback+2026-04-26: *"when you make all those pup windows, they clutter+up the user's desktop, so you should open all of those as tabs+in one pup window."*++```bash+# 1) Create the window with the first URL.+adom-desktop browser_open_window '{+  "sessionId":"my-task","profile":"my-task",+  "url":"https://first.example.com"+}'++# 2) Add the rest as tabs in the SAME session.+adom-desktop browser_open_tab '{"sessionId":"my-task","url":"https://second.example.com"}'+adom-desktop browser_open_tab '{"sessionId":"my-task","url":"https://third.example.com"}'++# 3) Activate a specific tab when you want to screenshot or eval it.+adom-desktop browser_switch_tab '{"sessionId":"my-task","tabId":"tab-2"}'+adom-desktop browser_screenshot   '{"sessionId":"my-task","maxWidth":1500}'+adom-desktop browser_eval         '{"sessionId":"my-task","expr":"document.title"}'+```++`browser_open_tab` lives alongside the documented `browser_*`+verbs. Same JSON-args convention; same `sessionId` semantics.++Pick a stable `profile` name across runs of the same task so the+cookie jar persists — the user logs in once and reuses for 12++months. Cross-vendor cookie blending is fine because cookies are+per-domain.++## Verify what you opened — `"ok": true` is not enough++`browser_open_window` / `browser_open_tab` returns `"ok": true` as+soon as the navigation starts, NOT when the page actually+rendered useful content. Always sanity-check the result:++```bash+# Title check — fastest. 404s, anti-bot blocks, and login walls+# all change the title.+adom-desktop browser_eval '{"sessionId":"my-task","expr":"document.title"}'++# Screenshot — slowest, most thorough. Use when title isn't+# discriminating (e.g. SPA that updates title async).+adom-desktop browser_screenshot '{"sessionId":"my-task"}'+```++**Never blindly template a part number into a vendor URL pattern+without verifying the page exists.** The cost of a 404 you didn't+catch is the user spotting it instead. (Real example: shipped a+manufacturer-search-URL pattern that 404'd on `ti.com/product/`+and `nxp.com/` for parts those vendors don't make. Using a+`google.com/search?q=…` link routes through Google's resolver+and gets a real product hit on the first result.)++## Key Rules++- **Always pass `sessionId`** — never use `'{}'` as args. The default targets the *active* session which may not be what you want.+- **`adom-desktop browser_<cmd> <json>` — never `adom-desktop pup <cmd> --flags`.** There is no `pup` subcommand at the top level; that pattern fails with "Invalid JSON args".+- **No semicolons in `browser_eval`** — use comma operator or IIFE instead.+- **Sessions persist** — IndexedDB, cookies, localStorage survive restarts. Profile name is the persistence key.+- **Each session = independent Chrome window** — crash-isolated. Multiple tabs share one session and one cookie jar.+- **Never kill Chrome broadly** — use `browser_close_window` for specific sessions.+- **Always reload + alert after browser-facing code changes** — the user expects to see updates immediately.++## Full Reference++For detailed docs (profiles, sleep/wake recovery, troubleshooting, first-time setup), see `~/.claude/skills/adom/guides/pup.md`.