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
dev-skills/pup-bridge-publish.mddeleted−207@@ -1,207 +0,0 @@-name: pup-bridge-publish-user-invocable: false-description: "DEVELOPER skill — the exact, battle-tested recipe for publishing a new version of the Adom Desktop Puppeteer (pup) bridge to wiki.adom.inc, plus every gotcha hit live. NOT for general users. Read before cutting a release: which artifact goes where (pkg=skills, release=bridge zip), version-lockstep, the `files` allowlist + `skills/**` glob trap, keeping the tarball lean (NO zip / NO src / NO heroes), keeping dev/publish skills SOURCE-ONLY (not SKILL.md), deploying skills to .claude AND .codex, scrubbing stale retired-wiki (wiki-ufypy5dpx93o.adom.cloud) URLs, user-first discovery triggers, sha matching, and verify steps. Trigger words: publish pup bridge, ship pup bridge, release pup, pkg publish, repo push, adom-wiki release, bridge manifest, pup version bump, no zip in tarball, dev skill source only, scrub old wiki url, codex skills, discovery triggers, adom-desktop-puppeteer-bridge publish."--# pup-bridge-publish — shipping a new pup bridge version--The pup bridge is cloud-owned at `wiki.adom.inc/adom/adom-desktop-puppeteer-bridge`. This is the-step-by-step ship recipe + the traps that cost real time. Companion: `pup-bridge-dev` (architecture /-ownership), `PUBLISHING.md` (terse recipe), `CLAUDE.md` (ownership boundary).--## What goes WHERE — three artifacts, three homes (memorize this)--| Artifact | Home | Command | Carries |-|---|---|---|---|-| **bridge runtime `.zip`** | a **Release** asset | `adom-wiki release upload` | `src/` at zip-root (server.js, chrome.js, bridge.json, node deps). The thing AD runs. |-| **streaming manifest JSON** | the **git repo** | `adom-wiki repo push` | points at the release zip URL + its sha256/size |-| **container skills tarball** | a **Package** | `adom-wiki pkg publish` | `SKILL.md` + `skills/*` (the Claude skills). NO runtime. |--> The `.zip` is a RELEASE, never a git file: `*.zip` is gitignored and `repo push --files X.zip`-> reports `ok` but silently skips it (the URL then 404s). Binaries → `release upload`.--## Auth (once per container)--```bash-export ADOM_WIKI_TOKEN=$(cat /var/run/adom/api-key 2>/dev/null) # container default; or session.json's session_token-adom-wiki whoami # MUST show a real user (e.g. [email protected]). Strict-auth rejects the shared "Developer" token.-```-Every mutation needs a real `--changelog` / `-m` (≥10 chars, ≥2 words) or the server 400s.--## The recipe--### 1. Bump version IN LOCKSTEP, and keep it > the AD bundled seed--```bash-printf '1.1.1' > src/BRIDGE_VERSION-sed -i 's/"version": "1.1.0"/"version": "1.1.1"/' src/bridge.json # bridge runtime-sed -i 's/"version": "1.1.0"/"version": "1.1.1"/' package.json # adompkg descriptor (the pkg)-```-`src/BRIDGE_VERSION` and `src/bridge.json` MUST match (AD uses BRIDGE_VERSION to detect a stale running-process). Keep the number **above** the seed in `adom-desktop/plugins/puppeteer` so cache-over-bundled wins.--### 2. Build the bridge zip (source-only, `src/` at zip ROOT — no top-level dir)--`zip` may be absent → Python. node_modules is NEVER included (AD `npm install`s it on spawn; the seed-ships it; an 88 MB zip would blow wiki limits):--```python-import zipfile, os, hashlib-root, out = "src", "adom-bridge-puppeteer-v1.1.1.zip"-with zipfile.ZipFile(out, "w", zipfile.ZIP_DEFLATED) as z:- for dp, dirs, files in os.walk(root):- for skip in ("node_modules","screenshots","profiles"):- if skip in dirs: dirs.remove(skip)- for f in files: z.write(os.path.join(dp,f), os.path.relpath(os.path.join(dp,f), root))-print("sha256:", hashlib.sha256(open(out,"rb").read()).hexdigest(), "size:", os.path.getsize(out))-# SANITY: assert chrome.js + your change are inside before shipping.-```--### 3. Publish the zip as a Release (releases PRESERVE your sha)--```bash-adom-wiki release create adom/adom-desktop-puppeteer-bridge 1.1.1 --title "..." --changelog "<≥2 words>"-adom-wiki release upload adom/adom-desktop-puppeteer-bridge 1.1.1 adom-bridge-puppeteer-v1.1.1.zip --json-# the response's assets[].sha256/size are what the manifest MUST carry. Then VERIFY the PUBLIC url:-curl -sL https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.1.1/adom-bridge-puppeteer-v1.1.1.zip | sha256sum-```--### 4. Point the manifest at the release + push it (git repo)--Edit `adom-bridge-puppeteer-manifest.json` → `version`, `url` (the release download URL), `sha256`,-`size` (from step 3 — **must match the served asset or `bridge_install` rejects it**). Then:--```bash-adom-wiki repo push adom/adom-desktop-puppeteer-bridge \- --files adom-bridge-puppeteer-manifest.json src/bridge.json src/BRIDGE_VERSION src/server.js src/chrome.js \- -m "v1.1.1: <what changed>"-```--### 5. Publish the container skills as a pkg — keep it LEAN, and MIND THE TRAPS--```bash-adom-wiki pkg pack # ALWAYS pack + inspect BEFORE publish-tar tzf *.tgz # confirm: SKILL.md + skills/*/SKILL.md + install.sh, and NOTHING heavy-adom-wiki pkg publish --org adom --version 1.1.1-adom-wiki pkg notes adom/[email protected] -m "Container skills: <what changed>"-```--The pkg description lives in the root **`package.json`** `description` — keep it explicit that this is-**container-side skills only; the bridge runtime is the Release zip + bundled in Adom Desktop.**--## Traps hit live (don't relearn these)--- **`pkg pack` includes EVERYTHING by default** → a 16 MB tarball (all the hero PNGs + `src/` runtime).- Fix: the heroes are gitignored (`*.png`) since they're already page assets, AND `package.json` has a- **`files` allowlist**. With both, the tarball drops to ~12 KB.-- **`files` directory entries need a GLOB.** Listing `"skills"` (bare dir) silently includes ZERO skill- files. Use **`"skills/**"`** (and/or the explicit `"skills/<name>/SKILL.md"`). Always `tar tzf` to- confirm your skills actually made it in — a missing skill = an empty Skills tab.-- **`pkg pack` honors `.gitignore`, not a separate npmignore.** So you can't gitignore something you- need in git (e.g. `src/`) to drop it from the pkg — use the `files` allowlist for that.-- **A RELEASE shows up in `adom-wiki pkg info` as a row with `type:null`** (wiki UI conflation). The real- pkg rows are `type:"app"`. Use `adom-wiki release list` for true releases; don't think your pkg shipped- just because a version appears in `pkg info`.-- **sha/size mismatch → `bridge_install` rejects the manifest.** Releases preserve the uploaded sha, so- use the `release upload` response values verbatim and re-download to confirm.-- **The Skills tab + `skill_count` + `adom-wiki skills install` come from the GIT REPO, not the pkg.**- The wiki indexes **every `SKILL.md`** in the page repo (root = main skill; `<dir>/SKILL.md` = sub-skills)- — `page.skills` is null; it's a repo scan. So a file named `SKILL.md` ANYWHERE in the repo becomes an- indexed, tab-listed, `skills install`-able skill. (This is *separate* from `pkg install`, which installs- the pkg tarball governed by the `files` allowlist.) Corollary → see "Keep dev/publish skills source-only".--## Verify (every ship)--```bash-# manifest serves at the updateManifestUrl path:-curl -s https://wiki.adom.inc/api/v1/pages/adom-desktop-puppeteer-bridge/files/adom-bridge-puppeteer-manifest.json | jq .sha256-# live install + new verbs on a real desktop (multi-desktop → --target; `adom-desktop targets` lists them):-adom-desktop --target <name> bridge_install '{"manifestUrl":".../files/adom-bridge-puppeteer-manifest.json","force":true}'-adom-desktop --target <name> browser_readiness '{}'-# render the page in pup + READ the screenshot (curl 200 is NOT verification). Confirm version + Skills tab.-```--## Keep dev/publish skills SOURCE-ONLY (not on the Skills tab, not installed)--Everyday users should get ONLY the `pup` user skill — not the dev/publish skills. But the wiki indexes-every `SKILL.md` in the repo (above), so a dev skill named `SKILL.md` would show on the Skills tab AND-install via `skills install`. The fix: keep dev/publish skills as **source-only docs that are NOT named-`SKILL.md`** — they live in `dev-skills/` as `pup-bridge-dev.md` / `pup-bridge-publish.md`. Then they are:--- **not indexed** (`skill_count` stays 1), **not on the Skills tab**, **not `skills install`-able**;-- still in git → available via `adom-wiki repo clone` (and the Files tab);-- excluded from the pkg too (the `files` allowlist lists only `SKILL.md` + `skills/**`).--`dev-skills/README.md` tells a developer how to load one as a live skill (copy it to-`~/.claude/skills/<name>/SKILL.md`). **Verify after publish:** `skill_count` should be **1** —-`curl -s https://wiki.adom.inc/api/pages/adom/adom-desktop-puppeteer-bridge | jq '.page.skill_count'`.--## Keep the pkg tarball LEAN — NO zip, NO src/, NO heroes--The pkg tarball must be the `pup` user skill ONLY — never the bridge runtime zip, `src/`, or hero PNGs.-Guards: the `package.json` `files` allowlist (`SKILL.md`, `skills/**`, `install.sh`, `uninstall.sh`,-`README.md`, `package.json`) **plus** `.gitignore` (`*.zip`, `*.png`, `*.bundle`, `*.tgz`, the old-`*-source.tar.gz`). **ALWAYS** `adom-wiki pkg pack` then `tar tzf *.tgz` and confirm there is **no-`*.zip`, no `src/`, no `*.png`**. A lean tarball is ~10 KB; if it's megabytes, something heavy leaked in-(it was 16 MB before the guards). `rm -f *.tgz` after inspecting.--## Skills install to BOTH .claude AND .codex--`install.sh` deploys the user skill into **both `~/.claude/skills/` and `~/.codex/skills/`** (Codex only-if `~/.codex` exists); `uninstall.sh` removes from both. Codex is a real second agent skills home now —-don't ship an install.sh that only does `.claude`.--## Scrub stale retired-wiki URLs (the #1 fork/extract gotcha)--**The only wiki host is `wiki.adom.inc`. `wiki-ufypy5dpx93o.adom.cloud` is RETIRED** — as are the-`/static/apps/...` and `/wiki/apps/...` path formats. When you fork/extract a page, the inherited-`README.md` and the `page.json` `readme` body carry OLD URLs (this bit us live — a dead `static/apps`-zip link). Before every publish:--```bash-grep -rnI 'wiki-ufypy5dpx93o\|adom\.cloud\|/static/apps\|/wiki/apps' . --exclude-dir=node_modules-```--Fix every hit (README + the `page.json` `readme` body are the usual culprits), then VERIFY the **live**-entity (not just local):--```bash-curl -s https://wiki.adom.inc/api/pages/adom/adom-desktop-puppeteer-bridge | grep -c wiki-ufypy5dpx93o # want 0-```--Also `repo rm` any stale source-mirror artifacts left on the page (old `*-source.tar.gz` / `*.bundle`).-(`https://adom.inc/fonts/...` is fine — that's the brand font CDN, not a wiki host.)--## Canonical wiki.adom.inc URL formats--- **Page:** `https://wiki.adom.inc/adom/<slug>`-- **File (served, anon):** `https://wiki.adom.inc/api/v1/pages/<slug>/files/<name>`-- **Release download:** `https://wiki.adom.inc/download/adom/<slug>/<ver>/<file>`-- **Sibling pages:** `/adom/adom-desktop-bridges`, `/adom/adom-desktop-kicad-bridge`,- `/adom/adom-desktop-fusion-bridge`, `/adom/adom-desktop`--## Discovery triggers — lead with everyday USER phrases--Lead `discovery_triggers` with everyday phrases, not dev jargon — the single most important is bare-**`pup`**, plus `open in pup`, `open my app in pup`, `screenshot the page`, `record a browser window`,-etc. The wiki **auto-generates** the discover snippet from `discovery_triggers` + `discovery_pitch`-(there is no separate "upload a snippet" — those two fields ARE the snippet). Set them via-`adom-wiki discover triggers <ref> --add ...` OR `page.json` `discovery_triggers`/`discovery_pitch` + push.-**Verify:** `adom-wiki discover preview "open my app in pup"` should rank this page #1.--## ⚠ Node-bridge gotcha: the cache copy needs node_modules (don't outrun the bundled seed)--pup is a **Node** bridge with heavy native deps (puppeteer, sharp, keytar). The release zip is-SOURCE-ONLY (no node_modules). kicad/fusion (Python) stream fine, but a wiki-streamed pup **cache** copy-**crashes** `MODULE_NOT_FOUND` because AD spawns `node server.js` without installing node_modules (the-bespoke `start_browser_bridge` npm-installs only the BUNDLED copy; the cache copy gets nothing). So:--- **The working runtime delivery for pup is the BUNDLED NSIS seed** (it keeps node_modules). Wiki-stream- the SKILLS (pkg) freely; the RUNTIME effectively ships with the AD installer until AD is fixed.-- **Do NOT publish a wiki RUNTIME (`src/`) version NEWER than the AD bundled seed** — a box with our- `updateManifestUrl` persisted would pull the newer source-only zip into the cache and crash (it- supersedes the good bundled copy). Keep the wiki runtime version == the bundled seed version.-- The real fix is AD-side (give cache-installed node bridges their node_modules — `npm install` the cache- or reuse the bundled node_modules). Tracked in `HANDOFF-TO-ADOM-DESKTOP.md`. Once it ships, normal- wiki-streaming + `updateManifestUrl` auto-update works for pup like the other bridges.