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
Skills v1.8.30: teach auto-flash + updateNote/lastAgentUpdate signalling, keystroke-safe raise, open_tab tabId/tabCount, browser_render_html (UTF-8 HTML render)
4 files changed
+55−7
CHANGELOG.md+24@@ -1,5 +1,29 @@ # Changelog — Adom Desktop Puppeteer Bridge +## 1.8.23 — 2026-07-10 — Agent-update signalling (auto-flash), keystroke-safe raise, render_html++Field report from an agent that staged a 4-tab task and lost track of which window it was updating.+All five items shipped (AD relays verb args verbatim → no AD-side change):++- **Auto-flash on agent updates.** Mutating verbs (`open_window`/`open_tab`/`navigate`/`reload`/`back`/+ `forward`/`switch_tab`/`click`/`type`/`press_key`/`input_dispatch`/`eval`/`evaluate`) flash the+ window's taskbar via real `FlashWindowEx` (`FLASHW_TRAY|FLASHW_TIMERNOFG`) so the user notices the+ agent touched it — **never steals focus**, **self-suppresses while foreground**, **clears on click**.+ Debounced: one flash per window per ~5s burst. Suppress per-call with `{silent:true}`, treat a read as+ read-only with `browser_eval {readOnly:true}`, or silence a whole session with+ `browser_open_window {autoFlash:false}`.+- **`updateNote` + `lastAgentUpdate`.** Pass `updateNote` on any mutating verb; pup records+ `{tabId,verb,note,ts}` and surfaces it top-level **and per-tab** in `browser_list_tabs` /+ `list_windows` / status — answers "which tab did the agent just change?".+- **Raise no longer leaks keystrokes.** `browser_raise_os_window`/`focus_window` blur the page's active+ element before `bringToFront()`. Docs steer agents to `browser_alert_window` (or the auto-flash) for+ "I updated this", reserving raise for an explicit show-me.+- **`browser_open_tab` returns `tabId` + `tabCount`** explicitly (no more diffing `list_tabs`).+- **New `browser_render_html {sessionId,html,waitUntil?,updateNote?,silent?}`** — renders a local HTML+ string via `page.setContent` (UTF-8-correct; a `data:` URL mojibakes accented chars without a charset).+- Note: `desktop_screenshot_window titleContains/sessionId` is an **AD-core** verb — routed to AD, not+ pup. The `fullPage` nested-scroll `nestedScroll:true` warning shipped in 1.8.21.+ ## 1.6.0 → 1.8.17 — 2026-07 — Generic browser, background-by-default, cross-thread ownership, bridge→AD notify Consolidated summary of the arc since 1.1.0 (per-release detail lives in the wiki Releases tab):
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-desktop-puppeteer-bridge",- "version": "1.8.29",+ "version": "1.8.30", "type": "app", "description": "The pup SKILL PACK \u2014 the AI skills that teach a cloud/container AI how to drive the Adom Desktop Puppeteer (pup) bridge (browser_* verbs): the everyday `pup` skill plus focused sub-skills for windows/sessions/tabs, screenshots+recording, browsers+Chrome install, and driving the Adom wiki. Installs into ~/.claude/skills + ~/.codex/skills. DOCS ONLY \u2014 this is NOT the bridge runtime. The bridge itself (the Node program that drives the browser) runs on the DESKTOP: Adom Desktop bundles it and auto-installs/updates it, and it's published separately on the Releases tab as adom-bridge-puppeteer-v<ver>.zip. So the pkg version (skills, bumps often) and the Release version (runtime, bumps rarely) differ on purpose. TL;DR: pkg install = the skills for your AI; the bridge = the Release zip, which Adom Desktop manages for you.", "keywords": [
skills/pup-screenshots-recording/SKILL.md+4@@ -34,6 +34,10 @@ adom-desktop browser_screenshot '{"sessionId":"mytask-web","tabId":"tab-2"}' # a child popups). - **Sanity-check, don't assume:** a page that 404'd or hit a login wall still screenshots — pair with `browser_eval` on `document.title` when in doubt.+- **Rendering your OWN HTML to screenshot it?** Use **`browser_render_html {sessionId, html}`** — it renders+ the string via `page.setContent`, which is **UTF-8-correct**. (A `data:text/html,…` URL mojibakes accented+ characters — `Café` → `Café` — unless you hand-add `;charset=utf-8`; `render_html` just does it right.)+ Then screenshot/drive it like any page. Great for previewing generated markup without writing a temp file. ## Recording — two recorders, pick by what you're capturing
skills/pup-windows-sessions-tabs/SKILL.md+26−6@@ -58,9 +58,29 @@ windows, no focus stolen) and stays fully drivable + screenshottable there — y at an exact size/spot **for clean screenshot framing** while it stays in the background. So you can frame a shot without ever disturbing the user's main work. - **`browser_alert_window`** flashes the taskbar (a non-intrusive "it's ready/done" nudge) — prefer it over- raising the window.+ raising the window. Use it for an explicit end-of-task "it's ready". - `browser_raise_os_window` / `browser_focus_window` bring a window forward (use sparingly, only to show- the user); `browser_lower_os_window` tucks it back.+ the user); `browser_lower_os_window` tucks it back. **Raise steals focus and can leak a mid-typed+ keystroke into the page** (pup blurs the page's focused element first to reduce it) — to just signal "I+ updated this window", use the auto-flash / `browser_alert_window`, NOT raise.++## Signalling what you changed — auto-flash + `updateNote` (so the user follows along)++When you drive a background window the user can't tell you touched it — and across several tabs they lose+track of WHICH one you just changed. pup handles both, automatically:++- **Auto-flash:** every **mutating** verb (`navigate`, `reload`, `back`/`forward`, `switch_tab`, `click`,+ `type`, `press_key`, `input_dispatch`, `eval`, `open_tab`, `open_window`) flashes that window's taskbar+ icon orange — **without stealing focus**, self-suppressed while it's foreground, and cleared when the+ user clicks it. It's **debounced to one flash per window per ~5s burst**, so a whole `open→navigate→+ fill→screenshot` sequence flashes once, not five times.+- **Tune it:** `{"silent":true}` on any one call suppresses that flash; `browser_open_window+ {"autoFlash":false}` silences the whole session (for a background poller); and a pure read should pass+ `browser_eval {"readOnly":true}` so a polling loop doesn't flash or count as an update.+- **Say what you did:** pass **`updateNote":"<short what-I-did>"`** on any mutating verb. pup records+ `lastAgentUpdate {tabId, verb, note, ts}` and surfaces it **top-level and per-tab** in+ `browser_list_tabs` / `browser_list_windows` — so the user (or a Session Monitor) sees which tab you+ staged and why. Add an `updateNote` on the meaningful steps of a multi-tab task. ```bash # default: background — drive it invisibly, user never sees a thing@@ -77,14 +97,14 @@ separate windows: ```bash adom-desktop browser_open_window '{"sessionId":"task-web","owner":"task","url":"https://first.example.com"}'-adom-desktop browser_open_tab '{"sessionId":"task-web","url":"https://second.example.com"}' # → { tabId: "tab-2" }+adom-desktop browser_open_tab '{"sessionId":"task-web","url":"https://second.example.com"}' # → { tabId: "tab-2", tabCount: 2 } adom-desktop browser_switch_tab '{"sessionId":"task-web","tabId":"tab-2"}' adom-desktop browser_screenshot '{"sessionId":"task-web","tabId":"tab-2"}' # tabId optional — omit for the active tab adom-desktop browser_close_tab '{"sessionId":"task-web","tabId":"tab-2"}' ``` -- `browser_open_tab` returns a `tabId`; pass it to `switch`/`close`/`screenshot`/`eval`/`navigate` (omit to- target the active tab).+- `browser_open_tab` returns `{tabId, tabCount, activeTabId}`; pass the `tabId` to+ `switch`/`close`/`screenshot`/`eval`/`navigate` (omit to target the active tab). - **Closing the last tab closes the window.** - Popup tabs (e.g. a PDF the page opens) auto-attach and appear in `browser_list_tabs`; a closed popup's last URL is retained so you can `browser_fetch_url` it if you missed it.@@ -109,7 +129,7 @@ blocks all change the title) or a `browser_screenshot` when the title isn't disc | Verb | Does | |---|---|-| `browser_open_window` | Create (or reuse) a session/window. Args: `sessionId`, `owner`, `url?`, `profile?`, `foreground?`, `width/height/x/y?`, `takeover?` |+| `browser_open_window` | Create (or reuse) a session/window. Args: `sessionId`, `owner`, `url?`, `profile?`, `foreground?`, `width/height/x/y?`, `takeover?`, `updateNote?`, `autoFlash?` (false = silence session) | | `browser_navigate` | Drive an existing tab to a URL (no new window) — `sessionId`, `url`, `tabId?` | | `browser_open_tab` / `browser_switch_tab` / `browser_close_tab` / `browser_list_tabs` | Tabs within one window | | `browser_switch_window` / `browser_list_windows` | Multiple sessions |