skill
ffpup — Firefox (BiDi) bridge
Public Unreviewedby barrett-land
Firefox automation bridge for Adom Desktop — the WebDriver-BiDi sibling of the pup (Chrome) bridge.
← Commit history
Publish 0.1.1
6 files changed
+216−32
README.md+4−23@@ -1,25 +1,6 @@-# ffpup — Firefox (WebDriver BiDi) bridge for Adom Desktop+# ffpup skill -The BiDi sibling of the `pup` (Chrome) bridge. Drives the user's REAL Firefox over-WebDriver BiDi — **trusted input** (`isTrusted=true` on clicks AND keystrokes),-persistent logged-in profiles, and **no "controlled by automation" infobar**.-Uses the system Firefox — no browser download.+Consumer skill for the **ffpup** Adom Desktop bridge — drive the user's real Firefox over+WebDriver BiDi via `adom-desktop ffbrowser_*` verbs. See `SKILL.md`. -## Install-```-adom-desktop bridge_install '{"manifestUrl":"https://wiki.adom.inc/api/v1/pages/adom-desktop-ffpup-bridge/files/ffpup-manifest.json"}'-```--## Verbs (`ffbrowser_` prefix, mirroring pup's `browser_`)-`ffbrowser_open_window`, `open_tab`, `close_tab`, `switch_tab`, `list_tabs`,-`close_window`, `navigate`, `reload`, `evaluate`, `screenshot`,-`input_dispatch` (click|move|type|key), `errors`, `status`--## Example-```-adom-desktop ffbrowser_open_window '{"sessionId":"x","profile":"x","url":"https://example.com"}'-adom-desktop ffbrowser_input_dispatch '{"sessionId":"x","type":"type","selector":"input[name=q]","text":"hello"}'-adom-desktop ffbrowser_screenshot '{"sessionId":"x"}'-```--Requires **Node >= 18** and a **system Firefox (>= 121)**. Vendors `puppeteer-core` (CommonJS).+Install: `adom-wiki pkg install barrett-land/adom-desktop-ffpup-bridge`
SKILL.mdadded+91@@ -0,0 +1,91 @@+---+name: adom-desktop-ffpup-bridge+description: >+ Drive the user's REAL Firefox from a cloud/WSL container via the adom-desktop `ffbrowser_*`+ verbs — the WebDriver-BiDi sibling of the pup (Chrome) bridge. Use to open/close Firefox+ windows and tabs, navigate/reload, take screenshots, evaluate JS on the page, and dispatch+ TRUSTED input (real `isTrusted=true` clicks + keystrokes) into Firefox. Persistent+ logged-in profiles; no "controlled by automation" infobar; uses the system Firefox (no+ browser download). Trigger words — ffpup, firefox automation, drive firefox, control+ firefox, automate firefox, screenshot firefox, test my site in firefox, open firefox and,+ run javascript in firefox, firefox bidi, webdriver bidi, trusted click firefox.+user-invocable: true+---++Parent skill: **adom-desktop-ffpup-bridge**++# ffpup — Firefox (WebDriver BiDi) bridge++ffpup is an Adom Desktop **bridge**: a local server AD spawns on the user's machine that+drives their **real Firefox** over WebDriver BiDi. It is the Firefox counterpart to `pup`+(Chrome). You call its verbs through the adom-desktop CLI; every verb is prefixed+`ffbrowser_` (mirroring pup's `browser_`).++**When to use ffpup vs siblings:**+- **ffpup** — automate/test/screenshot/script **Firefox** specifically; trusted input;+ persistent Firefox profiles that keep logins across runs.+- **pup** — the same but for Chrome (fresh Chrome-for-Testing profile, no saved logins).+- **native-browser extension** — logging into a site / filling a form on a page the user is+ already signed into, in their everyday browser. If the task is "log in for me", prefer that.++## FIRST-TIME / COLD-START — read before you panic++ffpup needs (1) the ffpup bridge installed in Adom Desktop and (2) a **system Firefox ≥ 121**+on the user's machine. AD provisions the Node runtime itself — you never install Node.++1. **Is the bridge installed?** `adom-desktop bridge_list` — look for `ffpup`. If absent:+ ```+ adom-desktop bridge_install '{"manifestUrl":"https://wiki.adom.inc/api/v1/pages/adom-desktop-ffpup-bridge/files/ffpup-manifest.json"}'+ ```+2. **Is it alive / what sessions exist?** `adom-desktop ffbrowser_status` — this is your+ read-only readiness + session probe. Call it before opening a new window (see Sessions).+3. If a call fails, **read the `error` / `_hint` and relay it to the user unchanged**, then+ act on it — don't declare defeat on the first not-ready response.++## Core verbs (the 80% path)++| Command | Description | Key args |+|---|---|---|+| `ffbrowser_open_window` | Open (or reuse) a Firefox window/session | `sessionId`*, `profile`*, `url`, `freshProfile` |+| `ffbrowser_navigate` | Navigate the active tab | `sessionId`, `url`* |+| `ffbrowser_reload` | Reload the active tab | `sessionId` |+| `ffbrowser_screenshot` | PNG of the active tab (returns `path` + `base64`) | `sessionId`, `fullPage` |+| `ffbrowser_evaluate` | Run JS in the page, return the value | `sessionId`, `expr`* |+| `ffbrowser_input_dispatch` | Trusted input: `click`\|`move`\|`type`\|`key` | `sessionId`, `type`*, `selector`\|`x,y`, `text`, `key` |+| `ffbrowser_open_tab` / `_close_tab` / `_switch_tab` / `_list_tabs` | Tab management | `sessionId`, `tabId`, `url` |+| `ffbrowser_close_window` | Close a session (and its browser if unshared) | `sessionId` |+| `ffbrowser_errors` | Page console/JS errors captured for the tab | `sessionId` |+| `ffbrowser_status` | All sessions + active session (read-only) | — |++\* required. Every verb takes/returns JSON; pass args as a single JSON object.++### Examples+```bash+adom-desktop ffbrowser_open_window '{"sessionId":"demo","profile":"demo","url":"https://example.com"}'+adom-desktop ffbrowser_input_dispatch '{"sessionId":"demo","type":"type","selector":"input[name=q]","text":"hello"}'+adom-desktop ffbrowser_input_dispatch '{"sessionId":"demo","type":"key","key":"Enter"}'+adom-desktop ffbrowser_screenshot '{"sessionId":"demo"}'+```++## Conventions that make ffpup work the first time++- **Trusted input is the whole point.** `ffbrowser_input_dispatch` produces real+ `isTrusted=true` events (clicks AND keystrokes) — use it instead of clicking via+ `ffbrowser_evaluate`, which produces synthetic (untrusted) events sites can reject.+- **`ok:true` is not enough — verify.** Verbs return when the action *starts*. After a+ navigate/click, confirm with a cheap `ffbrowser_evaluate` (`document.title`, a selector's+ text) or a `ffbrowser_screenshot` before reporting success — login walls, 404s, and empty+ states land silently.+- **Sessions: reuse, don't reopen.** Call `ffbrowser_status` first; if a matching `sessionId`+ is live, reuse it (opening the same `sessionId` just navigates). Pick a **stable+ `profile`** so cookies/logins persist across runs; share a profile between sessions to+ share logins. This is why ffpup keeps you signed in where pup can't.+- **Background by default.** ffpup drives the AI's workspace, not the user's screen. Don't+ force-foreground Firefox except to SHOW the user something.+- **Relay `_hint` verbatim.** On any not-ready/failure, surface the bridge's `_hint`/`error`+ to the user unchanged and branch on it.++## Requirements+- Adom Desktop with the ffpup bridge installed (`bridge_install`, above).+- A **system Firefox ≥ 121** on the user's machine (ffpup uses it — no browser download).+- Node is provisioned by Adom Desktop; you never install it.
install.shadded+21@@ -0,0 +1,21 @@+#!/bin/bash+set -e+PKG_DIR="$(cd "$(dirname "$0")" && pwd)"+NAME="adom-desktop-ffpup-bridge"++install_to() {+ local root="$1"+ [ -d "$root" ] || return 0+ local dest="$root/$NAME"+ mkdir -p "$dest"+ for f in "$PKG_DIR"/*; do+ base=$(basename "$f")+ case "$base" in package.json|install.sh|uninstall.sh) continue ;; esac+ cp -r "$f" "$dest/"+ done+ echo "Installed $NAME -> $dest"+}++# A container may run Claude OR Codex — install the user skill into both homes.+install_to "$HOME/.claude/skills"+install_to "$HOME/.codex/skills"
package.json+56−8@@ -1,12 +1,60 @@ {- "name": "adom-ffpup-bridge",+ "slug": "adom-desktop-ffpup-bridge", "version": "0.1.1",- "description": "ffpup — Firefox (WebDriver BiDi) bridge for Adom Desktop. Sibling of the puppeteer (Chrome) bridge.",- "main": "server.js",+ "type": "skill",+ "description": "Drive the user's REAL Firefox from a container via adom-desktop's ffbrowser_* verbs \u2014 the WebDriver-BiDi sibling of the pup (Chrome) bridge. Open/close Firefox windows & tabs, navigate, screenshot, evaluate JS, and dispatch trusted (isTrusted=true) clicks + keystrokes. Persistent logged-in Firefox profiles; no automation infobar; uses the system Firefox.",+ "tags": [+ "adom-desktop",+ "bridge",+ "firefox",+ "webdriver-bidi",+ "ffpup",+ "puppeteer"+ ],+ "dependencies": {+ "adom/adom-desktop": "^1.9.0"+ },+ "discovery_triggers": [+ "automate firefox",+ "drive firefox",+ "control firefox",+ "open firefox and",+ "screenshot in firefox",+ "take a screenshot in firefox",+ "test my site in firefox",+ "run my web app in firefox",+ "run javascript in firefox",+ "fill out a form in firefox",+ "click a button in firefox",+ "type into firefox",+ "firefox automation",+ "firefox webdriver bidi",+ "drive my real firefox",+ "ffpup"+ ],+ "discovery_pitch": "ffpup drives the user's REAL Firefox over WebDriver BiDi (trusted input, persistent logged-in profiles, no automation infobar). Check `adom-desktop bridge_list` for `ffpup`; if missing, `adom-desktop bridge_install {manifestUrl}` from the ffpup page. Then drive its `ffbrowser_*` verbs. If this container lacks the skill, `adom-wiki pkg install barrett-land/adom-desktop-ffpup-bridge` or `adom-desktop sync_skills`.",+ "files": [+ "SKILL.md",+ "README.md",+ "install.sh",+ "uninstall.sh"+ ], "scripts": {- "start": "node server.js"+ "install": "./install.sh",+ "uninstall": "./uninstall.sh" },- "dependencies": {- "puppeteer-core": "^24.43.1"- }-}+ "sample_prompts": [+ {+ "label": "Screenshot in Firefox",+ "prompt": "screenshot my site in Firefox"+ },+ {+ "label": "Drive Firefox",+ "prompt": "open my web app in Firefox and click through the signup flow"+ },+ {+ "label": "Trusted click",+ "prompt": "click the Submit button in Firefox with a real trusted click"+ }+ ]+}
page.json+39−1@@ -28,5 +28,43 @@ "label": "Trusted click", "prompt": "click the Submit button in Firefox with a real trusted click" }- ]+ ],+ "version": "0.1.1",+ "description": "Drive the user's REAL Firefox from a container via adom-desktop's ffbrowser_* verbs — the WebDriver-BiDi sibling of the pup (Chrome) bridge. Open/close Firefox windows & tabs, navigate, screenshot, evaluate JS, and dispatch trusted (isTrusted=true) clicks + keystrokes. Persistent logged-in Firefox profiles; no automation infobar; uses the system Firefox.",+ "dependencies": {+ "adom/adom-desktop": "^1.9.0"+ },+ "discovery_triggers": [+ "automate firefox",+ "drive firefox",+ "control firefox",+ "open firefox and",+ "screenshot in firefox",+ "take a screenshot in firefox",+ "test my site in firefox",+ "run my web app in firefox",+ "run javascript in firefox",+ "fill out a form in firefox",+ "click a button in firefox",+ "type into firefox",+ "firefox automation",+ "firefox webdriver bidi",+ "drive my real firefox",+ "ffpup"+ ],+ "discovery_pitch": "ffpup drives the user's REAL Firefox over WebDriver BiDi (trusted input, persistent logged-in profiles, no automation infobar). Check `adom-desktop bridge_list` for `ffpup`; if missing, `adom-desktop bridge_install {manifestUrl}` from the ffpup page. Then drive its `ffbrowser_*` verbs. If this container lacks the skill, `adom-wiki pkg install barrett-land/adom-desktop-ffpup-bridge` or `adom-desktop sync_skills`.",+ "files": [+ "SKILL.md",+ "README.md",+ "install.sh",+ "uninstall.sh"+ ],+ "scripts": {+ "install": "./install.sh",+ "uninstall": "./uninstall.sh"+ },+ "author": {+ "name": "barrett-land",+ "email": "[email protected]"+ } }
uninstall.shadded+5@@ -0,0 +1,5 @@+#!/bin/bash+set -e+NAME="adom-desktop-ffpup-bridge"+rm -rf "$HOME/.claude/skills/$NAME" "$HOME/.codex/skills/$NAME"+echo "Uninstalled $NAME"