{
  "schema_version": 1,
  "type": "app",
  "slug": "pup-bridge",
  "title": "Pup - Puppeteer Bridge",
  "brief": "pup is the AI's own browser: a real, full Chrome on the user's desktop that the AI fully controls (a sandbox, not the user's signed-in browser). Rides Bridge; pup_* verbs open windows and tabs, navigate, screenshot, and eval JS.",
  "version": "2.0.18",
  "tags": [
    "skills",
    "pup",
    "puppeteer",
    "browser",
    "adom-bridge",
    "bridge",
    "pup-bridge"
  ],
  "license": "MIT",
  "discovery_triggers": [
    "pup",
    "open in pup",
    "open my app in pup",
    "open it in pup",
    "open this in pup",
    "show me in pup",
    "show it in pup",
    "open a pup window",
    "pup window",
    "screenshot my app",
    "screenshot the page",
    "browser screenshot",
    "pup screenshot",
    "record the window",
    "record a browser window",
    "record a pup",
    "record my app",
    "new pup tab",
    "pup tabs",
    "browser tabs",
    "close the pup window",
    "reload the page in pup",
    "eval js in the page",
    "drive a browser",
    "headful browser automation",
    "visual debug",
    "puppeteer",
    "puppeteer bridge",
    "pup bridge",
    "chrome for testing",
    "chrome automation bridge",
    "pup_open_window",
    "pup_screenshot",
    "pup_record_start",
    "pup_readiness",
    "fork the pup bridge",
    "puppeteer bridge source"
  ],
  "discovery_pitch": "Use pup to drive Chrome from the cloud: open/close browser windows + tabs, navigate, screenshot, eval JS, and record windows. It drives the browser ALREADY on the machine, installed Chrome, else Microsoft Edge (every Windows PC has Edge), with a fresh isolated profile, so usually NO download and it doesn't disrupt the user; Chrome for Testing is fetched only as a last resort. For 'is it ready' use pup_readiness. Or pass nativeBrowser+nativeProfile to drive the user's REAL signed-in Chrome/Edge/Brave. Call the adom-bridge-cli pup_* verbs.",
  "sample_prompts": [
    {
      "label": "Open in pup",
      "prompt": "Open my app in pup (pup_open_window) and screenshot it"
    },
    {
      "label": "Screenshot a page",
      "prompt": "Screenshot https://example.com in pup"
    },
    {
      "label": "Record a window",
      "prompt": "Record a 30-second video of this pup tab (pup_record_start/stop)"
    },
    {
      "label": "Many tabs, one window",
      "prompt": "Open these 5 URLs as tabs in one pup window"
    },
    {
      "label": "Drive my real Chrome",
      "prompt": "Open the GCP console in my real signed-in Chrome via pup native mode"
    },
    {
      "label": "Read the bridge source (dev)",
      "prompt": "Download the puppeteer-bridge zip from the wiki and walk me through server.js"
    }
  ],
  "install": {
    "binary_name": "pup-bridge",
    "install_dir": "",
    "install_hint": "",
    "version_cmd": ""
  },
  "readme": "# pup: the Puppeteer bridge\n\n**pup is the AI's own browser: a real, full Chrome/Edge window on the user's desktop that the AI drives\nwith complete programmatic control, but a _sandbox_.** It runs in a fresh, isolated profile that is\nnever the user's real signed-in browser, and opens in the **background by default** so it never disrupts\nthem. That trade is exactly why pup exists alongside **nb / nbe** (the native browser and its extension):\nnb/nbe drive the user's _real_ browser, their cookies, SSO, saved logins, their identity, for when a\ntask needs to BE the user. pup is the opposite trade: no borrowed identity, but **total control**, a\nreal, disposable browser the AI owns end to end (open/close windows + tabs, navigate, screenshot, eval\nJS, record). Logged out by design, it's the safe, fully-drivable default for automation, testing,\nscraping public pages, and showing wiki pages; reach for nb/nbe only when you genuinely need the user's\nreal logins. pup drives the browser **already on the machine** (installed Chrome, else Microsoft Edge;\nevery Windows PC ships Edge), so the common case needs no download.\n\n**The core goal: an AI-driven browser that can do everything it needs to for you - the best assistant\nin the world.** By default every pup window surfs on the shared durable **adom-you** profile, and every\nlogin made there enriches a shared credential store. Over time that store lets pup automatically enter\nusernames and passwords on every site it has ever seen, which is what makes a truly self-sufficient\nAI browser possible. Isolated throwaway profiles exist for the cases that need them (logged-out\ntesting, acting as another user), but they build nothing: adom-you is the default on purpose.\n\n> To drive the user's **real, signed-in** Chrome/Edge (their cookies, SSO, saved logins), that's the\n> **Adom browser extension's `nbrowser_*` verbs**, a separate bridge, not pup.\n\nCanonical page: **https://wiki.adom.inc/adom/pup-bridge**\n\n## Install vs Download, which is which (and why the version numbers differ)\n\nThe page header shows **two** things, for two different places. Most people need only the first.\n\n| On the page | What it is | Who runs it | You usually… |\n|---|---|---|---|\n| **Install**, `adom-wiki pkg install …` | The **AI skill pack**, the `pup` skills that teach a cloud/container AI how to drive the bridge. Docs only, no runtime; drops into `~/.claude/skills` + `~/.codex/skills`. | your **container / cloud AI** | **run this** (or it arrives via `sync_skills`) |\n| **Download for your machine**, `adom-bridge-puppeteer-v<ver>.zip` | The **bridge runtime**, the actual Node program (browser detection + driving) that runs on the desktop. | **Bridge**, on the user's PC | **do nothing**, Bridge **auto-installs & auto-updates** it; the manual download is only for offline/manual installs |\n\n**Why two different version numbers?** They're independent artifacts. The **Install (pkg)** version bumps\nwhenever the *skills/docs* change (often). The **Download (runtime)** version bumps only when the *bridge\ncode* changes (rarely). So it's normal to see e.g. Install `v1.8.27` and Download `v1.8.20`, nothing is\nout of sync; they just version on their own clocks.\n\n*(There's also a third copy, the runtime is **bundled inside the Bridge installer** as a first-run\nseed, superseded by a newer cache copy via `updateManifestUrl`. You never touch it directly.)*\n\n## Use it\n\n```bash\n# everyday: open + screenshot. Opens in the BACKGROUND automatically, no need to lower it,\n# and it's fully drivable/screenshottable while hidden, so the user is never interrupted.\nadom-bridge-cli pup_open_window '{\"sessionId\":\"myapp-web\",\"owner\":\"myapp\",\"url\":\"http://localhost:3000\"}'\nadom-bridge-cli pup_screenshot  '{\"sessionId\":\"myapp-web\"}'\n\n# readiness (use pup_readiness, NOT pup_status). On a box with Chrome or Edge this is\n# instantly {ready:true} with no download. Only a box with no Chromium at all fetches Chrome for\n# Testing in the background, poll until ready, then open.\nadom-bridge-cli pup_readiness '{}'      # → {ready:true, browserKind:\"chrome\"|\"edge\"|...}\n```\n\n- **Task-prefix your `sessionId` + pass `owner`**, sessions are shared across every AI thread on the\n  desktop; that lets pup protect your window from another thread navigating it away.\n- **`foreground:true` is the only way to show a window**, sizing/positioning does not foreground it.\n\nFull everyday usage (tabs, recording, window ownership, cold-start playbook) is in the `pup` skill\n(`SKILL.md`).\n\n## Window-type taskbar icons: read a pup window at a glance\n\n![The pup window-type icon family](docs/icons/family-v1.png)\n\nEvery pup window's **taskbar icon states what kind of thing it is showing**. All five share the same\ndrawing (the teal Adom tile carrying a solid browser window) and differ only in the window's\n*content*: a monochrome glyph on the 24x24 Adom house grid, per the brand icon law (single color,\nno gradients, no emoji):\n\n| Icon | Window content | Means |\n|---|---|---|\n| ![wiki](docs/icons/pup-cat-wiki.png) | open book | **Adom wiki, public view**: logged out, what the world sees |\n| ![wiki signed in](docs/icons/pup-cat-wiki-in.png) | book + person | **Adom wiki, signed in**: the user's logged-in view (private source, drafts, owner cards) |\n| ![adom app](docs/icons/pup-cat-app.png) | the Adom mark | **An Adom app**: localhost or a cloud-slug proxy URL |\n| ![web](docs/icons/pup-cat-web.png) | globe | **The web**: any other site (ti.com, digikey, ...) |\n| ![mixed](docs/icons/pup-cat-mixed.png) | two panes | **Mixed**: the window's tabs span more than one category |\n\n- The category is derived from **all tabs** in the window; it updates **live** (add a digikey tab\n  to a wiki window and the icon flips to *mixed* within about a second).\n- The **overlay badge** riding the icon's corner is separate and sacred: it is the **active tab's\n  own favicon**, so you always see which site you are looking at. In grouped-taskbar mode it shows\n  window/tab counters instead.\n- The **tab title** carries the same login signal in text: a solid dot (`●   Logged in`) or hollow dot\n  (`○   Public`) leads the title of every Adom wiki tab.\n- Under the hood, each window's identity (icon, name, Alt-Tab entry) rides a per-session Windows\n  AppUserModelID that **carries the category**: the only way Win11 allows a taskbar tile to change\n  live. Grouped mode instead keeps one stable, pinnable `Adom.Pup` identity.\n\n### Using pup's icons in your own tool (HD browser picker, launchers, menus)\n\nIf you are building a surface that offers \"open a pup window\" (a browser picker, a launcher tile, a\nmenu item), **use pup's real icon, not a stand-in.** The canonical, self-describing asset set lives\nin the wiki repo at [`assets/pup-icons/`](assets/pup-icons/), in three formats:\n\n- **SVG** (`pup-cat-*.svg`), scalable, the right choice for a web/Tauri picker.\n- **PNG** (`pup-cat-*-{32,48,128,256,512}.png`), raster fallback / retina.\n- **ICO** (`pup-cat-*.ico`), Windows multi-size, for taskbar/shortcut contexts (256px frame is\n  PNG-compressed, per the Vista+ rule, so it never renders as a generic document).\n\n**For a launcher/picker item, use `pup-cat-default`**, the neutral teal browser-window tile. It is\nwhat a pup window's taskbar button looks like before its content is known, so the picker previews the\nreal result. The five category icons above (`wiki`, `wiki-in`, `app`, `web`, `mixed`) are for\n*showing an existing window's kind*, not for a generic \"open pup\" action.\n\nFetch any asset from the wiki without cloning:\n\n```\nhttps://wiki.adom.inc/api/v1/pages/pup-bridge/files/assets/pup-icons/pup-cat-default.svg\nhttps://wiki.adom.inc/api/v1/pages/pup-bridge/files/assets/pup-icons/manifest.json\n```\n\n[`assets/pup-icons/manifest.json`](assets/pup-icons/manifest.json) is machine-readable: it maps each\nicon id to its meaning, its glyph, and its file in every format, and names\n`recommended_for_launcher` so a tool can pick the right one programmatically. Brand rule if you ever\nredraw one: teal tile `#00b8b0` + dark-teal window body `#003d40` + a single-color teal glyph, no\ngradients, shadows, or emoji.\n\n## Real windows, one per type\n\nFull windows as pup opens them (title bar, tabs, page). Note the tab title glyphs on the wiki pair\nand the signed-in header on the second:\n\n**Adom wiki, PUBLIC** (tab: `○ Public`, page header shows Login):\n\n![A pup window on the Adom wiki, public view](docs/screenshots/window-wiki-public.png)\n\n**Adom wiki, SIGNED IN** (tab: `● Logged in`, page header shows the user's name):\n\n![A pup window on the Adom wiki, signed in](docs/screenshots/window-wiki-signedin.png)\n\n**An Adom app** (here: the shotlog viewer on a cloud slug URL):\n\n![A pup window on an Adom app](docs/screenshots/window-adom-app.png)\n\n**The web** (ti.com):\n\n![A pup window on the open web](docs/screenshots/window-web.png)\n\n**Mixed** (a digikey tab and a wiki tab in one window):\n\n![A pup window with mixed content](docs/screenshots/window-mixed.png)\n\n## Overlay badges: the corner of the taskbar icon\n\n![The overlay badges pup places on its taskbar icons](docs/icons/overlays-v1.png)\n\nThe base icon states the window TYPE; the small overlay riding its lower-right corner carries\nLIVE detail, composited exactly like this:\n\n| Overlay | When | What it tells you |\n|---|---|---|\n| the active tab's **favicon** on a dark rounded plate | split mode, page serves a favicon | which site the active tab is on, at a glance |\n| a **count badge** (white digit, dark plate) | split mode, 2+ tabs and no favicon | how many tabs the window holds |\n| the **dual counter** (dark = windows, teal = total tabs) | grouped mode | how much is stacked under the single Adom Pup button |\n\nThe overlay never carries branding or state that belongs to the base icon: it is live per-window\ndetail only, and the favicon always wins the slot when one exists.\n\n## The Adom wiki: logged-in vs public view, and the taskbar toggle\n\npup can show any Adom wiki page from **two viewpoints**, and both the AI and the user can switch:\n\n- **Public (default)**: a fresh logged-out profile: exactly what the world sees. Use it to verify\n  what a publish actually exposed.\n- **Signed in**: `pup_open_window {..., wikiView:\"authed\"}` routes to a reserved persistent\n  profile whose cookie jar holds the user's ~30-day SSO session. One login serves **every** AI\n  thread on the machine. First use returns `wikiLoginNeeded:true`; the user signs in once, in that\n  window.\n\n**The user can flip a wiki window themselves**: right-click its taskbar button: the jump list\ncarries **\"Adom wiki: switch to logged-in view\"** (or \"...switch to public view\"). Clicking it\nrelaunches that same window under the other cookie jar, brings it to the front, and shows an\non-screen caption while it works (\"Switching to the logged-in view of the Adom wiki\", then\n\"Adom wiki: now the LOGGED-IN view (Their Name)\"). The AI-side equivalent is the\n`pup_wiki_set_view` verb, which exists for that jump-list click: AI threads should pass\n`wikiView` on open instead.\n\n## One session, one OS window\n\nEvery pup session gets its **own OS window**, even when sessions share a browser profile (as all\nsigned-in wiki windows share the authed cookie jar). This is what makes per-window identity\npossible: a window's title belongs to its active tab, so windows that share sessions as tabs\ncannot be found, branded, flashed, or given jump lists individually. Sharing a profile shares the\ncookies; it never merges windows.\n\n## Recording\n\npup can record what it drives, a **single tab/window** or the **whole desktop**, straight from the\ncloud, with no HUD and no need to bring the window forward.\n\n![Example pup recording, driving the Adom wiki, captured in the background](https://wiki.adom.inc/api/v1/pages/pup-bridge/files/pup-recording-demo.gif)\n\n*Above: a GIF preview of a real `pup_record` capture (≈8.6 s, the tab navigating the Adom wiki, recorded in the background on a VM). The native capture is the WebM linked below, this GIF is just an inline preview.*\n\n### High-FPS windows: recording something the user is not looking at\n\npup windows are backgrounded by design, and Chrome throttles a window that is occluded, so\nrecording one normally yields a **1-2 fps** video. pup can disable Chrome's power-saving to keep a\nwindow painting at full rate, but a window in that mode can never idle down (three of them once\ndrained a laptop overnight, wiki issue #14).\n\nSo it is **opt-in and leased**:\n\n- **Default** is Chrome's own power behaviour. Normal windows throttle when occluded and cost\n  nothing in the background. Right for driving, scraping and screenshots.\n- **`pup_open_window {highFps:true}`** renders at full rate while occluded, for background\n  recording. It holds a lease (default 20 min), and **an active recording holds that lease open\n  indefinitely, so a take is never cut off**. On lapse the window is *downgraded* back to normal\n  power by relaunching with its tabs intact, never closed.\n- **`pup_highfps_extend {sessionId, minutes}`** negotiates more time up front.\n\n**Full details, defaults, activity signals, and rules of thumb: [RECORDING.md](RECORDING.md).**\n\n### Two recorders, pick by what you're capturing\n\n| Verb pair | Captures | How it works under the hood |\n|---|---|---|\n| **`pup_record_start` / `pup_record_stop`** | ONE pup **tab/window**, the page content | **CDP `Page.startScreencast`** (JPEG frames, up to ~50 fps) piped to **ffmpeg**, encoded to **VP9** in real time → one `.webm`. Tab-scoped at the protocol level, so it captures the exact tab even in the **background**, no `getDisplayMedia`, no picker, no foreground. |\n| **`desktop_record_start` / `desktop_record_stop`** | the WHOLE **desktop** (multiple apps, dialogs) | Screen capture via **MediaRecorder** → one `.webm`; ffmpeg remuxes it to stamp a proper Duration. |\n\n```bash\nadom-bridge-cli pup_record_start '{\"sessionId\":\"demo-web\"}'          # → { recordingId }\n# ...drive the scene: navigate, click, type, scroll...\nadom-bridge-cli pup_record_stop  '{\"sessionId\":\"demo-web\",\"recordingId\":\"<id>\"}'   # → { path: \"...webm\" }\n```\n\n**ffmpeg** is required for recording. The bridge auto-detects it (a WinGet `Gyan.FFmpeg` install, PATH,\nor common dirs) and re-checks **lazily on `record_start`**, so if it's missing you can\n`winget install Gyan.FFmpeg` and just retry, no bridge restart. `pup_record_status` /\n`pup_record_list` (and the `desktop_record_*` equivalents) report in-flight and finished captures.\n\n### Formats, one native format, easy conversion\n\npup records to **one** format natively: **WebM (VP9)**, for both recorders. It doesn't offer a format\nswitch; instead, convert with the bundled ffmpeg when you need MP4 or GIF. Real numbers from the ≈8.6 s\ndemo above (1264×705):\n\n| Format | Codec | Size | How you get it | Best for | Watch out for |\n|---|---|---|---|---|---|\n| **WebM** ([view](https://wiki.adom.inc/api/v1/pages/pup-bridge/files/pup-recording-demo.webm)) | VP9 | **143 KB** | pup's **native** output, no step | Chrome/Edge/Firefox, small + high quality, the source of truth | Older **Safari**, PowerPoint, and some chat apps don't accept VP9/WebM |\n| **MP4** ([view](https://wiki.adom.inc/api/v1/pages/pup-bridge/files/pup-recording-demo.mp4)) | H.264 | **135 KB** | transcode (below) | **Universal**, Safari, iOS, PowerPoint, Slack/Teams, \"send it to anyone\" | H.264 needs **even width & height**, odd dims (like 705) fail at frame 0; the `scale` filter forces even |\n| **GIF** ([view](https://wiki.adom.inc/api/v1/pages/pup-bridge/files/pup-recording-demo.gif)) |, | **192 KB** | transcode (below) | Auto-playing, looping **inline preview** in any README/chat/GitHub, no player, no click (like the one above) | No audio, capped colors, and it balloons fast at higher fps/resolution/length, keep it short + downscaled |\n\n```bash\n# → MP4 (H.264, universal). The scale filter forces EVEN dimensions (H.264 rejects odd w/h → frame 0).\nffmpeg -i rec.webm -vf \"scale=trunc(iw/2)*2:trunc(ih/2)*2\" -c:v libx264 -crf 23 -pix_fmt yuv420p -movflags +faststart rec.mp4\n\n# → GIF (silent, looping inline preview). Palette pass keeps colors clean; drop fps/scale to shrink.\nffmpeg -i rec.webm -vf \"fps=12,scale=640:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse\" rec.gif\n```\n\n**Rule of thumb:** keep **WebM** for archiving + web embeds; make an **MP4** the moment a human on Safari/\nPowerPoint/phone needs it; make a short **GIF** only for an inline auto-play preview.\n\n## Source & development\n\nThis bridge is cloud-owned here (extracted from `adom-bridge/plugins/puppeteer`, mirroring the\nkicad/fusion bridges). Bridge ships a bundled seed and auto-pulls newer versions from this page.\n\n- Clone the source: `adom-wiki repo clone adom/pup-bridge`\n- Runtime lives in `src/` (`server.js`, `chrome.js`, `bridge.json`, …); the release zip is `src/` at zip-root.\n- **Maintainer skills** (`pup-bridge-dev`, `pup-bridge-publish`) are **source-only**, in `dev-skills/` +\n  `publish-skills/`, not shipped in the pkg (per the Bridge SDK a pkg ships only user skills). Skill map:\n\n| Skill | Ships in pkg? | What it's for |\n|---|---|---|\n| `pup` (root SKILL.md) | ✅ user | Start here, mental model (CDP-launched fresh process of the installed browser, rendered-but-backgrounded), when-vs-extension, quick start |\n| `pup-windows-sessions-tabs` | ✅ user | sessionIds, window ownership (don't steal another thread's window), background-vs-foreground, many tabs in one window |\n| `pup-screenshots-recording` | ✅ user | Screenshots (full-page/full-res) + recording; driving/verifying tricky pages (shadow DOM, nested scroll) |\n| `pup-browsers-and-chrome` | ✅ user | Browser detection/launch, `pup_use`, installing Chrome/CfT (incl. UAC-notify), readiness, cold-start errors |\n| `pup-adom-wiki` | ✅ user | Driving + verifying `wiki.adom.inc` pages in pup (view/screenshot/verify; the login situation) |\n| `pup-bridge-dev` / `pup-bridge-publish` | ❌ source-only | MAINTAINERS: bridge internals + the publish/release recipe (in `dev-skills/`/`publish-skills/`, not shipped) |\n- Ownership boundary: `CLAUDE.md`. Publish recipe: `PUBLISHING.md`. History: `CHANGELOG.md`.\n\n## Extend pup, add your own pup skill (third parties)\n\nBuilt a skill that drives pup for a specific job (a site-specific scraper, a visual test flow, a\ndomain widget)? You don't need write access here, surface it from this page with a **breadcrumb**:\n\n1. **Publish your skill** to your own wiki page (see the `adom-wiki` / `wiki-skillpack` skills). Make it a\n   normal user skill so `pkg install` drops it into a container's `~/.claude/skills`.\n2. **Drop a breadcrumb on this page** pointing at it:\n   ```bash\n   adom-wiki breadcrumb post adom/pup-bridge \\\n     --label \"Your skill name, one-line what it does\" \\\n     --target-url \"https://wiki.adom.inc/<owner>/<your-slug>\" \\\n     --category \"skill\"\n   ```\n   It's **pending until the page owner approves it**, then it shows in this page's **Breadcrumbs** tab.\n3. **Discovery is automatic:** an agent working with pup can list related third-party skills with\n   `adom-wiki breadcrumb list adom/pup-bridge`, approved breadcrumbs are how pup finds\n   community skills that build on it.\n\nKeep breadcrumbs on-topic (they genuinely extend pup / browser-driving); off-topic ones get rejected.\n\n## Related\n\n- [Bridge SDK guide](https://wiki.adom.inc/adom/adom-bridge-sdk), `bridge.json` schema, packaging, lifecycle\n- [KiCad bridge](https://wiki.adom.inc/adom/kicad-bridge) · [Fusion 360 bridge](https://wiki.adom.inc/adom/fusion-bridge)\n- [Bridge (parent app)](https://wiki.adom.inc/adom/adom-bridge)\n\nMIT licensed.\n",
  "author": "John Lauer <john@adom.inc>",
  "visibility": {
    "public": true
  },
  "hero": {
    "type": "image",
    "path": "hero-v9.png"
  },
  "metadata": {},
  "created_at": "2026-05-28T05:28:43.991Z",
  "skills": [],
  "author_name": "John Lauer",
  "description": "The pup SKILL PACK — 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 — 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": [
    "pup",
    "puppeteer",
    "browser",
    "adom-bridge",
    "bridge",
    "skills",
    "pup-bridge"
  ],
  "files": [
    "SKILL.md",
    "skills/pup-windows-sessions-tabs/SKILL.md",
    "skills/pup-screenshots-recording/SKILL.md",
    "skills/pup-browsers-and-chrome/SKILL.md",
    "skills/pup-adom-wiki/SKILL.md",
    "skills/pup-vendor-login/SKILL.md",
    "install.sh",
    "uninstall.sh",
    "README.md",
    "package.json"
  ],
  "scripts": {
    "install": "./install.sh",
    "uninstall": "./uninstall.sh"
  },
  "dependencies": {
    "adom/adom-bridge": "^2.0.0"
  },
  "org": "adom",
  "contributors": [
    "Kyle Bergstedt <kyle@adom.inc>",
    "Colby Knox"
  ],
  "authors_json": [
    "john"
  ],
  "updated_at": "2026-08-09T13:54:01.806Z"
}