← Commit history
Add shipping-the-bridge skill: how AD picks up a bridge update (release artifact not git Files; .zip blocked so .bin; canonical URL; bridge_install vs refresh_bridges; update VERB_META+bridge.json+describe when adding a verb)
4 files changed
+94−3
install.sh+1−1@@ -3,7 +3,7 @@ # (The extension itself loads into Chrome/Edge via "Load unpacked" from extension/, or the Web Store.) set -e DEST="${HOME}/.claude/skills"-for name in cross-platform-dev driving-the-extension native-browser-safety installing-the-extension uninstalling-the-extension native-browser-recording driving-the-extension-demo driving-the-desktop driving-sites driving-gusto reading-google-messages; do+for name in cross-platform-dev driving-the-extension native-browser-safety installing-the-extension uninstalling-the-extension native-browser-recording driving-the-extension-demo driving-the-desktop driving-sites driving-gusto reading-google-messages shipping-the-bridge; do mkdir -p "$DEST/$name" cp "skills/$name/SKILL.md" "$DEST/$name/SKILL.md" echo "installed skill: $name"
package.json+2−1@@ -42,7 +42,8 @@ "screenshots/extensions-adom-card.png", "screenshots/install-folder-picker.png", "screenshots/uninstall-confirm-bubble.png",- "screenshots/hero-v7.png"+ "screenshots/hero-v7.png",+ "skills/shipping-the-bridge/SKILL.md" ], "scripts": { "install": "./install.sh",
skills/shipping-the-bridge/SKILL.mdadded+90@@ -0,0 +1,90 @@+---+name: shipping-the-bridge+description: How to ship an update to the native-browser BRIDGE so adom-desktop (AD) actually picks it up. The cardinal fact AIs get wrong: AD reads ONLY the bridge RELEASE ARTIFACT (a manifest + a zip), NEVER the git Files tab - so `adom-wiki repo push` of bridge/server.js updates what humans browse but does NOT reach AD. Covers building the manifest + versioned zip, the wiki .zip-upload trap (host the bytes as .bin), the canonical owner-scoped file URL, bridge_install (first time, records the manifest URL) vs refresh_bridges (after; no manual kill on AD 1.9.27+), verifying with bridge_check_updates + nbrowser_describe, and the "when you add a verb, update three places" rule. Use when changing bridge/server.js or bridge.json, cutting a new bridge version, adding an nbrowser_ verb, or when "AD is still running the old bridge". Part of the adom-browser-extension. See also cross-platform-dev (the OS/dev flow) and installing-the-extension (the bridge_install precondition).+---+Part of **adom-browser-extension**. OS/dev flow: **cross-platform-dev**. Install precondition: **installing-the-extension**.++# Shipping a bridge update (so adom-desktop picks it up)++The bridge (`bridge/server.js` + `bridge/bridge.json`) runs on the user's laptop, spawned by AD from+its writable **`bridges-cache`**. Updating it is NOT a normal git push.++## ⛔ The cardinal fact: AD reads the RELEASE ARTIFACT, not the git Files+There are two independent wiki layers (same split as README vs the package registry):+- **Git Files** (`adom-wiki repo push`) - what humans browse. **AD never reads this for bridge code.**+- **The bridge release artifact** - a `native-browser-bridge-manifest.json` (version + zip url + sha256)+ plus a **versioned zip**. This is the ONLY thing AD pulls.++So pushing `bridge/server.js` to the repo changes nothing for AD. You must publish a new artifact.++## The artifact+- `native-browser-bridge-manifest.json` = `{ "manifest_version":1, "version", "url", "sha256", "size", "released_at" }`.+- A zip with `bridge.json` + `server.js` + `package.json` + `BRIDGE_VERSION` **at the ZIP ROOT** (no+ `bridge/` prefix). AD requires `bridge.json` at the zip root.++## ⛔ The wiki silently rejects `.zip` uploads+`POST .../files` with a `.zip` returns `{ok:true, commit:null}` but the file **never lands** (a `.png`+through the same path commits fine). So host the zip **bytes** under a **`.bin`** name+(`native-browser-bridge-v<ver>.bin`) and point the manifest `url` at that. AD just HTTP-GETs the `url`+and unzips the bytes - the extension is cosmetic. (`adom-wiki repo push` also drops binaries except PNG;+use `adom-wiki api` for the `.bin`.)++## Steps+1. **Bump the version in ALL THREE files** (or AD sees no update): `bridge/bridge.json` `version`,+ `bridge/package.json` `version`, `bridge/BRIDGE_VERSION`.+2. **Build the zip** - there is NO `zip` binary in the container; use Python `zipfile`, files at root:+ ```python+ import zipfile,hashlib,os,json,datetime+ src="bridge"; out="/tmp/native-browser-bridge-v<ver>.zip"+ with zipfile.ZipFile(out,"w",zipfile.ZIP_DEFLATED) as z:+ for f in ["server.js","bridge.json","package.json","BRIDGE_VERSION"]:+ z.write(os.path.join(src,f), arcname=f) # arcname = root+ raw=open(out,"rb").read(); sha=hashlib.sha256(raw).hexdigest(); size=len(raw)+ ```+3. **Write the manifest** with `url:"native-browser-bridge-v<ver>.bin"`, the `sha256`, `size`,+ `released_at` (UTC, e.g. `datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%dT%H:%M:%SZ")`).+4. **Upload the payload as `.bin`** (base64) via `adom-wiki api`:+ `adom-wiki api -X POST /api/pages/adom/adom-browser-extension/files --body '<json with files[0]={path,content(base64),encoding:"base64"}>'`.+ (CLI args cap ~128KB each; the bridge zip is ~25KB so inline is fine. For bigger payloads write the+ body to a file and pass it.)+5. **Push the manifest + the bumped source** as text: `adom-wiki repo push adom-browser-extension --files+ native-browser-bridge-manifest.json bridge/bridge.json bridge/package.json bridge/BRIDGE_VERSION bridge/server.js -m "..."`.+6. **Verify the artifact is live + intact** (AD sha256-checks on download): GET the `.bin`, confirm bytes+ == `size` and `sha256sum` == the manifest sha.++## Use the CANONICAL file URL (not the legacy alias)+The durable, documented route is **owner-scoped, no `/v1`**:+```+https://wiki.adom.inc/api/pages/<owner>/<slug>/files/<file>+ e.g. https://wiki.adom.inc/api/pages/adom/adom-browser-extension/files/native-browser-bridge-manifest.json+```+The `/api/v1/pages/<slug>/...` form is a legacy slug-only alias that still resolves but is fragile (breaks+on fork / when v1 retires). Always give AD the canonical URL.++## Make AD pick it up+- **First time on a machine:** `adom-desktop bridge_install '{"manifestUrl":"<canonical manifest url>"}'`.+ This downloads + sha-verifies + extracts the zip into `bridges-cache`, AND **persists the manifest URL**+ so the bridge auto-updates from its own page (AD 1.9.26+ tracks per-bridge manifest URLs).+- **Every update after that:** `adom-desktop refresh_bridges '{"name":"native-browser"}'` (or AD's+ on-launch + 4-hourly auto-sync). **AD 1.9.27+ auto-reaps the running process and respawns on the new+ code - NO manual `bridge_kill` needed.** (`action:"updated", from, to`.)+- The running bridge respawns on the new code on the next `nbrowser_*` call.++## Verify the update landed+- `adom-desktop bridge_check_updates` -> for `native-browser`: `current` == new version,+ `wikiHosted:true`, `updateAvailable:false`.+- A live `adom-desktop nbrowser_describe '{}'` -> serves the current verb set (proves the new code is running).++## When you ADD or change a verb, update THREE places (or it breaks)+1. `bridge/bridge.json` `verbs[]` - so AD ROUTES the verb to this bridge.+2. The `VERB_META` table in `server.js` - `hint` / `related` / `pitfalls` (feeds both the response `_hint`+ and `nbrowser_describe`).+3. The `nbrowser_describe` entry in `server.js` - the input/output schema for AD's Verbs tab (AD 1.9.23+).+Miss (1) and AD won't route it; miss (2)/(3) and it ships undocumented.++## Mental model + gotchas+- **Two layers:** git Files = humans; release artifact = AD. Don't confuse a `repo push` with shipping.+- **`.zip` is blocked** on the wiki API (silent) - always `.bin`.+- **No `zip` binary** in the container - Python `zipfile`.+- **Bump all three version files** together; a half-bump means AD sees no update or a mismatched runtime+ version string.
uninstall.sh+1−1@@ -1,5 +1,5 @@ #!/usr/bin/env bash DEST="${HOME}/.claude/skills"-for name in cross-platform-dev driving-the-extension native-browser-safety installing-the-extension uninstalling-the-extension native-browser-recording driving-the-extension-demo driving-the-desktop driving-sites driving-gusto reading-google-messages; do+for name in cross-platform-dev driving-the-extension native-browser-safety installing-the-extension uninstalling-the-extension native-browser-recording driving-the-extension-demo driving-the-desktop driving-sites driving-gusto reading-google-messages shipping-the-bridge; do rm -rf "$DEST/$name" && echo "removed skill: $name" done