Adom Desktop - Bridge SDK
Public Made by Adomby adom
Bridge SDK guide: bridge.json schema, kind:python/node/exe, hello-python + hello-rust reference templates, packaging + lifecycle commands.
name: shipping-a-bridge description: How to ship + UPDATE a third-party Adom Desktop bridge so AD actually picks it up. The cardinal fact authors get wrong: AD reads ONLY the bridge RELEASE ARTIFACT (a manifest + a zip), NEVER the git Files tab of your wiki page - so pushing your source to the repo updates what humans browse but does NOT reach AD. Covers building the manifest + versioned zip (files at zip root), the wiki .zip-upload trap (host the bytes as .bin), the canonical owner-scoped file URL (not the legacy /api/v1 alias), bridge_install (first time - records the manifest URL for auto-update, AD 1.9.26+) vs refresh_bridges (after; no manual kill on AD 1.9.27+), verifying with bridge_check_updates, and the rule that a new verb must be added to bridge.json verbs[] (and to your describe verb) or AD won't route it. Read when cutting a new bridge version, adding a verb, or when "AD is still running the old bridge". Companion to the bridge SDK guide (bridge.json schema + hello-python/hello-rust templates).
Companion to the adom-desktop-bridges SDK guide (bridge.json schema, kind:python/node/exe, the hello-python / hello-rust templates, scripts/release-bridge.sh). This page is the release + update flow and the traps.
Shipping a bridge update (so adom-desktop picks it up)
Your bridge runs on the user's machine, 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 your git Files
Your wiki page has two independent layers (same split as a README vs a package registry):
- Git Files (
adom-wiki repo push) = what humans browse. AD never reads this for bridge code. - The release artifact = a
<bridge>-bridge-manifest.json(version + zip url + sha256) plus a versioned zip. This is the ONLY thing AD pulls.
So pushing your server.js to the repo changes nothing for AD. You must publish a new artifact and bump
the version.
The artifact
<bridge>-bridge-manifest.json={ "manifest_version":1, "version", "url", "sha256", "size", "released_at" }.- A zip whose ROOT contains
bridge.json+ your server file(s) (no top-level folder). AD requiresbridge.jsonat the zip root. The easiest path isscripts/release-bridge.sh <name>(it builds the zip, sha256s it, writes the manifest). The manual equivalent:
(Note: in the Adom cloud container there is noimport zipfile,hashlib,os out="/tmp/<bridge>-bridge-v<ver>.zip" with zipfile.ZipFile(out,"w",zipfile.ZIP_DEFLATED) as z: for f in ["bridge.json","server.js","package.json","BRIDGE_VERSION"]: # your files, at ROOT z.write(f, arcname=os.path.basename(f)) raw=open(out,"rb").read(); sha=hashlib.sha256(raw).hexdigest(); size=len(raw)zipbinary - use Pythonzipfileas above.)
⛔ Trap: the wiki silently rejects .zip uploads
POST .../files with a .zip returns {ok:true, commit:null} but the file never lands (a .png
commits fine through the same path). So host the zip bytes under a .bin name
(<bridge>-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; push
the .bin with adom-wiki api -X POST .../files as base64, and the manifest + source as text.)
⛔ Use the CANONICAL file URL (not the legacy alias)
Give AD the owner-scoped, no-/v1 route:
https://wiki.adom.inc/api/pages/<owner>/<slug>/files/<bridge>-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). Older docs show the /api/v1/ form; prefer the canonical one.
Bump, build, publish
- Bump the version in every place your runtime + manifest read it - typically
bridge.jsonversion,BRIDGE_VERSION, and yourpackage.jsonversion. A half-bump = AD sees no update, or a mismatched runtime version string. - Build the zip (root layout), compute
sha256+size, write the manifest withurl:"<...>.bin". - Upload the
.bin(base64) + push the manifest + source. - Verify the artifact is live + intact (AD sha256-checks on download): GET the
.bin, confirm bytes ==sizeandsha256sum== the manifestsha256.
Make AD pick it up
- First time on a machine:
adom-desktop bridge_install '{"manifestUrl":"<canonical manifest url>"}'. Downloads + sha-verifies + extracts intobridges-cache, AND persists the manifest URL so the bridge auto-updates from its own page. (AD 1.9.26+ tracks per-bridge manifest URLs - this is what lets a community bridge on its OWN wiki page auto-refresh, not just the bundled ones.) - Every update after that:
adom-desktop refresh_bridges '{"name":"<bridge>"}'(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 manualbridge_kill. Result:action:"updated", from, to. The running bridge respawns on the next verb call.
Verify the update landed
adom-desktop bridge_check_updates-> your bridge showscurrent== new version,wikiHosted:true,updateAvailable:false. (IfwikiHosted:false/latest:null, AD has no tracked manifest URL - re-runbridge_installfrom the canonical URL once to register it.)- Call one of your verbs (or your
<prefix>_describeif you have one) to confirm the new code is running.
Adding a verb? Update routing (and docs)
bridge.jsonverbs[]- AD ROUTES a verb to your bridge only if it is declared here. Miss this and the verb 404s no matter what your server does.- If you expose a
<prefix>_describeverb (AD 1.9.23+ renders it in the GUI Verbs tab), add the new verb's schema there too, so it shows up with input/output docs + the inline runner.
Mental model + the traps, in one line each
- Two layers: git Files = humans; release artifact = AD. A
repo pushis NOT shipping. .zipis silently blocked on the wiki API - host as.bin.- No
zipbinary in the cloud container - Pythonzipfile, files at the zip root. - Canonical owner-scoped URL for the manifest, not
/api/v1/<slug>. - Bump every version file together.
refresh_bridgesself-reaps (AD 1.9.27+) - re-runningbridge_installper update is no longer needed.
---
name: shipping-a-bridge
description: How to ship + UPDATE a third-party Adom Desktop bridge so AD actually picks it up. The cardinal fact authors get wrong: AD reads ONLY the bridge RELEASE ARTIFACT (a manifest + a zip), NEVER the git Files tab of your wiki page - so pushing your source to the repo updates what humans browse but does NOT reach AD. Covers building the manifest + versioned zip (files at zip root), the wiki .zip-upload trap (host the bytes as .bin), the canonical owner-scoped file URL (not the legacy /api/v1 alias), bridge_install (first time - records the manifest URL for auto-update, AD 1.9.26+) vs refresh_bridges (after; no manual kill on AD 1.9.27+), verifying with bridge_check_updates, and the rule that a new verb must be added to bridge.json verbs[] (and to your describe verb) or AD won't route it. Read when cutting a new bridge version, adding a verb, or when "AD is still running the old bridge". Companion to the bridge SDK guide (bridge.json schema + hello-python/hello-rust templates).
---
Companion to the **adom-desktop-bridges** SDK guide (bridge.json schema, kind:python/node/exe, the hello-python / hello-rust templates, `scripts/release-bridge.sh`). This page is the **release + update** flow and the traps.
# Shipping a bridge update (so adom-desktop picks it up)
Your bridge runs on the user's machine, 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 your git Files
Your wiki page has two independent layers (same split as a README vs a package registry):
- **Git Files** (`adom-wiki repo push`) = what humans browse. **AD never reads this for bridge code.**
- **The release artifact** = a `<bridge>-bridge-manifest.json` (version + zip url + sha256) plus a
**versioned zip**. This is the ONLY thing AD pulls.
So pushing your `server.js` to the repo changes nothing for AD. You must publish a new artifact and bump
the version.
## The artifact
- `<bridge>-bridge-manifest.json` = `{ "manifest_version":1, "version", "url", "sha256", "size", "released_at" }`.
- A zip whose ROOT contains `bridge.json` + your server file(s) (no top-level folder). **AD requires
`bridge.json` at the zip root.** The easiest path is `scripts/release-bridge.sh <name>` (it builds the
zip, sha256s it, writes the manifest). The manual equivalent:
```python
import zipfile,hashlib,os
out="/tmp/<bridge>-bridge-v<ver>.zip"
with zipfile.ZipFile(out,"w",zipfile.ZIP_DEFLATED) as z:
for f in ["bridge.json","server.js","package.json","BRIDGE_VERSION"]: # your files, at ROOT
z.write(f, arcname=os.path.basename(f))
raw=open(out,"rb").read(); sha=hashlib.sha256(raw).hexdigest(); size=len(raw)
```
(Note: in the Adom cloud container there is **no `zip` binary** - use Python `zipfile` as above.)
## ⛔ Trap: the wiki silently rejects `.zip` uploads
`POST .../files` with a `.zip` returns `{ok:true, commit:null}` but the file **never lands** (a `.png`
commits fine through the same path). So host the zip **bytes** under a **`.bin`** name
(`<bridge>-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; push
the `.bin` with `adom-wiki api -X POST .../files` as base64, and the manifest + source as text.)
## ⛔ Use the CANONICAL file URL (not the legacy alias)
Give AD the **owner-scoped, no-`/v1`** route:
```
https://wiki.adom.inc/api/pages/<owner>/<slug>/files/<bridge>-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). Older docs show the `/api/v1/` form; prefer the canonical one.
## Bump, build, publish
1. **Bump the version in every place your runtime + manifest read it** - typically `bridge.json` `version`,
`BRIDGE_VERSION`, and your `package.json` `version`. A half-bump = AD sees no update, or a mismatched
runtime version string.
2. Build the zip (root layout), compute `sha256` + `size`, write the manifest with `url:"<...>.bin"`.
3. Upload the `.bin` (base64) + push the manifest + source.
4. **Verify the artifact is live + intact** (AD sha256-checks on download): GET the `.bin`, confirm bytes
== `size` and `sha256sum` == the manifest `sha256`.
## Make AD pick it up
- **First time on a machine:** `adom-desktop bridge_install '{"manifestUrl":"<canonical manifest url>"}'`.
Downloads + sha-verifies + extracts 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 - this is what lets a
community bridge on its OWN wiki page auto-refresh, not just the bundled ones.)
- **Every update after that:** `adom-desktop refresh_bridges '{"name":"<bridge>"}'` (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`.** Result: `action:"updated", from, to`. The running bridge respawns on the next verb call.
## Verify the update landed
- `adom-desktop bridge_check_updates` -> your bridge shows `current` == new version, `wikiHosted:true`,
`updateAvailable:false`. (If `wikiHosted:false`/`latest:null`, AD has no tracked manifest URL - re-run
`bridge_install` from the canonical URL once to register it.)
- Call one of your verbs (or your `<prefix>_describe` if you have one) to confirm the new code is running.
## Adding a verb? Update routing (and docs)
- **`bridge.json` `verbs[]`** - AD ROUTES a verb to your bridge only if it is declared here. Miss this and
the verb 404s no matter what your server does.
- If you expose a **`<prefix>_describe`** verb (AD 1.9.23+ renders it in the GUI Verbs tab), add the new
verb's schema there too, so it shows up with input/output docs + the inline runner.
## Mental model + the traps, in one line each
- **Two layers:** git Files = humans; release artifact = AD. A `repo push` is NOT shipping.
- **`.zip` is silently blocked** on the wiki API - host as `.bin`.
- **No `zip` binary** in the cloud container - Python `zipfile`, files at the zip root.
- **Canonical owner-scoped URL** for the manifest, not `/api/v1/<slug>`.
- **Bump every version file** together.
- **`refresh_bridges` self-reaps** (AD 1.9.27+) - re-running `bridge_install` per update is no longer needed.