app
DEPRECATED: Bridge SDK (moved into Adom Bridge)
Public Made by Adomby adom
Bridge SDK guide: bridge.json schema, kind:python/node/exe, hello-python + hello-rust reference templates, packaging + lifecycle commands.
← Commit history
SDK: authoritative two-artifacts + file-placement + dependency + skills-by-openness section; harden no-loose-zip rule + self-audit checklist
3 files changed
+117−6
README.md+39−2@@ -1,6 +1,6 @@ --- name: adom-desktop-bridge-sdk-description: Author, PUBLISH, and make-discoverable an adom-desktop bridge — a small local server that adds a namespace of verbs (kicad_, fusion_, browser_, your_prefix_) to adom-desktop. Use when building, publishing, updating, prewarming, or debugging a bridge, or deciding what skills to ship. Covers the AD-core-vs-author boundary; the #1 rule (rich hints in EVERY verb's OUTPUT, because the AI reads CLI output, never your on-disk skill); bridge.json; the THREE things you publish (runtime Release zip + manifest, container skills pkg, wiki discovery_triggers); prewarm; the publish/dev/user SKILL set you must ship; and the auto-discover → install-check → use flow.+description: Author, PUBLISH, and make-discoverable an adom-desktop bridge — a small local server that adds a namespace of verbs (kicad_, fusion_, browser_, your_prefix_) to adom-desktop. Use when building, publishing, updating, prewarming, or debugging a bridge, or deciding what skills to ship. Covers the AD-core-vs-author boundary; the #1 rule (rich hints in EVERY verb's OUTPUT, because the AI reads CLI output, never your on-disk skill); bridge.json; where every file lives (the Release-zip-vs-skills-pkg split, the TWO package.json files, manifest + runtime-asset placement) and which skills stay private if your bridge is closed-source; the THREE things you publish (runtime Release zip + manifest, container skills pkg, wiki discovery_triggers); prewarm; the publish/dev/user SKILL set you must ship; and the auto-discover → install-check → use flow. --- # Bridge SDK — build, publish, and surface a bridge for Adom Desktop@@ -17,6 +17,34 @@ A **bridge** is a small local program (Python, Node, Rust, anything) that AD spa --- +## Where every file lives — the two artifacts, their deps, and which skills go public++**Two DISTINCT artifacts, two DIFFERENT homes, two DIFFERENT consumers. Crossing them is the #1 inconsistency across bridge repos — pin it here before anything else.** (Live audit 2026-07-06: fusion + pup do this right; kicad had **61** loose `adom-bridge-kicad-v*.zip` on `/files` + a `mesa-llvmpipe-x64.zip`; blender dumped 2 loose zips too.)++| | **RUNTIME artifact** (Artifact 1) | **SKILLS pkg** (Artifact 2) |+|---|---|---|+| **What it is** | your bridge's actual CODE | your consumer `SKILL.md` docs |+| **Runs on** | the user's **DESKTOP** — AD spawns it | **nothing runs it** — docs the CONTAINER reads |+| **Published as** | a versioned **Release** (`release create` + `release upload --platform any`) | an **`adom-wiki pkg`** (`pkg publish --org adom`) |+| **Installed by** | `bridge_install {manifestUrl}` → AD streams, unzips, spawns | `pkg install adom/<slug>` / `sync_skills` → `~/.claude/skills` + `~/.codex/skills` |+| **Contains** | server code + `bridge.json` at the zip **ROOT** + assets. **Node: SOURCE ONLY, no `node_modules`.** | ROOT `SKILL.md` + `skills/<name>/SKILL.md` + `package.json` + `install.sh`/`uninstall.sh`. **Docs only.** |+| **NEVER contains** | the skills pkg | **ANY binary, the Release zip, `src/`, `node_modules`, hero PNGs, or a `dependencies:` block** |+| **its `package.json`** | (node) the **RUNTIME deps** AD installs at spawn: `dependencies:{ puppeteer, … }` | the **skillpack manifest**: `files[]`, `discovery_triggers`, install/uninstall scripts — **NO `dependencies`** |++**Yes, a node bridge has TWO `package.json` files and they are NOT interchangeable.** One rides inside the Release zip and lists the deps AD installs on the *desktop*; the other is the skillpack manifest in the pkg tarball and lists *skill files*, never deps. Put runtime `dependencies` in the **pkg's** package.json and you bloat every container install — the pkg lands in a container that *never runs your bridge*. Put skill metadata in the **zip's** package.json and it does nothing.++**Where each file physically lives (this is the map that ends the inconsistency):**+- **`bridge.json`** → the **root of the Release zip** (AD reads it post-unzip). Carries `version` + `updateManifestUrl`.+- **The Release `.zip`** → a **Release asset** (`release upload … --platform any`). **NEVER a loose `/files` blob.** Loose binaries can't be cleanly deleted from a git page, so every stale version lingers forever (kicad's 61). Copy fusion/pup: releases only.+- **The manifest** (`adom-bridge-<name>-manifest.json`, this naming is the consistent one — keep it) → POSTed to your page **`/files`**. Its `url` points at the **Release download** (`https://wiki.adom.inc/download/adom/<slug>/<ver>/<file>.zip`), base-relative + extension-agnostic. `updateManifestUrl` (in the manifest AND in bridge.json) points back at this manifest.+- **A big RUNTIME ASSET** (a headless-GL pack like Mesa, a browser download) → declare it in **`prewarm.assets`** so AD downloads + manages it, or bundle it in your seed. **NOT a loose `/files` blob** — kicad's `mesa-llvmpipe-x64.zip` on `/files` is the anti-pattern.++**Which skills go PUBLIC depends on whether your bridge is open source:**+- **USER skills ALWAYS ship** in your pkg (public) — the container can't drive your verbs without them.+- **DEV + PUBLISH skills:** ship them in your pkg (scoped `user-invocable:false`, see "The SKILL SET") **only if your bridge is OPEN SOURCE** / you're fine with your release-and-publish process being publicly readable. **If your bridge is CLOSED SOURCE, keep dev + publish skills in your PRIVATE repo and ship ONLY user skills to the wiki** — exactly what **adom-desktop core** does: its `RELEASE` / `WIKI_PUBLISH` / `SIGNING` / `AD_RELAUNCH` skills live only in the private GitHub source and are NEVER in the public pkg (verified: the published adom-desktop pkg carries 9 user/integration skills, zero dev/publish). Don't publish your release dance if your source isn't public.++---+ ## The boundary — what AD owns vs what YOU own The #1 mistake is filing AD bugs for bridge issues. The split:@@ -77,6 +105,12 @@ When a maintainer says *"audit your code, skills, README, and wiki page against - [ ] `detect` declared iff you drive a HOST APP (KiCad/Fusion/Altium…); omitted if you bring your own runtime (pup). `prewarm.assets` declared for heavy downloads (e.g. `chrome-for-testing`). *(→ Cold-start tiers)* - [ ] **`timeouts`** declared if ANY verb can run longer than 60s (a big export/render/cloud-open) — with a matching **`statusVerb`** to poll. Third-party bridges were 60s-capped before v1.9.79; this is how you raise it. *(→ bridge.json)* +**Artifacts & deps** (the two-artifact split — the #1 inconsistency) *(→ Where every file lives)*:+- [ ] Your Release `.zip` is a **Release asset** (`release upload`), NOT a loose `/files` blob — and old version zips are NOT piling up on `/files` (audit for stray `*-v*.zip`).+- [ ] Runtime deps live in the **ZIP's** `package.json` (node) / `requirements.txt` (python); the **skillpack** `package.json` in your pkg has **NO `dependencies`** (it installs into a container that never runs you).+- [ ] A big runtime asset (Mesa, a browser) is a **`prewarm.asset`** or seed-bundled — NOT a loose `/files` blob.+- [ ] Your **manifest** (`adom-bridge-<name>-manifest.json`) is on `/files`; its `url` points at the **Release download**, not at a `/files` blob.+ **Runtime** (Node/Python bridges) *(→ Runtime contract)*: - [ ] You bind **`ADOM_BIND_HOST`** (loopback default), never `0.0.0.0`. - [ ] You do **NOT** bootstrap your own Node/Python — no `winget`/`desktop_install_node`/self-download in code or skills. `spawn.kind` is the declaration; AD provisions it.@@ -94,7 +128,8 @@ When a maintainer says *"audit your code, skills, README, and wiki page against - [ ] Triggers stay in YOUR niche — you don't poach a sibling's (login/forms → native-browser, not pup). `discovery_pitch` is an INSTRUCTION. **Skills & docs** (what the container + humans read):-- [ ] You ship the publish/dev/user **3-skill set** in the SKILLPACK layout: EVERY skill (user + dev + publish) is a real `skills/<name>/SKILL.md` with a `Parent skill:` first body line; dev/publish are scoped by `user-invocable: false` + a DEVELOPER-only description (NOT by hiding them as `dev-skills/*.md` — that convention is dead); every path listed EXPLICITLY (no globs) in `files[]` + install.sh/uninstall.sh. *(→ Artifact 2 + The SKILL SET)*+- [ ] You ship the **USER skill(s)** in the SKILLPACK layout: a real `skills/<name>/SKILL.md` with a `Parent skill:` first body line; every path listed EXPLICITLY (no globs) in `files[]` + install.sh/uninstall.sh. *(→ Artifact 2 + The SKILL SET)*+- [ ] **DEV + PUBLISH skills:** in the pkg (scoped `user-invocable:false` + DEVELOPER-only description, NOT hidden as `dev-skills/*.md` — that convention is dead) **only if your bridge is OPEN SOURCE**; if CLOSED source, they stay in your PRIVATE repo and only user skills ship (the adom-desktop-core model). *(→ Where every file lives)* - [ ] Your USER skill leads with the cold-start "read before you panic" section + the 8 conventions, and points the AI at `bridge_readiness`. *(→ USER-skill conventions)* - [ ] README + wiki page + skills all AGREE with the above (no stale github links, no wrong schema, triggers vetted). @@ -365,6 +400,8 @@ Your `/health` (200) makes the chip green. Optionally return `led` (`green`/`yel `bridge_install {manifestUrl}` · `bridge_list` · `bridge_info`/`bridge_detail {name}` · `bridge_log_read {name, sinceOffset?}` · `bridge_kill {name}` · `bridge_pause {name}` · `refresh_bridges {name?}` · `bridge_check_updates`. A bridge installed via `bridge_install` auto-updates with no further opt-in; `updateManifestUrl` in `bridge.json` makes it durable across republish. +**"My bridge keeps exiting and I can't see why" (read this).** Your own stdout log truncates on every respawn, so a crash-then-restart erases its own cause. `bridge_log_read` therefore also tails **AD's lifecycle audit log** for your bridge, a separate append-only file (`~/.adom/bridge-logs/<name>.ad.log`) that survives respawns, shown under an `===== AD bridge lifecycle =====` header. It records every spawn, reap, duplicate-collapse, and `bridge_kill` with the reason, so you can tell "AD reaped it as a duplicate" or "the `bridge_kill` verb stopped it" or "it was reaped before a fresh spawn" apart from "it crashed on its own." If the audit log shows AD never stopped it, the exit is inside your process.+ --- ## Publish checklist (the whole modern flow)
SKILL.md+39−2@@ -1,6 +1,6 @@ --- name: adom-desktop-bridge-sdk-description: Author, PUBLISH, and make-discoverable an adom-desktop bridge — a small local server that adds a namespace of verbs (kicad_, fusion_, browser_, your_prefix_) to adom-desktop. Use when building, publishing, updating, prewarming, or debugging a bridge, or deciding what skills to ship. Covers the AD-core-vs-author boundary; the #1 rule (rich hints in EVERY verb's OUTPUT, because the AI reads CLI output, never your on-disk skill); bridge.json; the THREE things you publish (runtime Release zip + manifest, container skills pkg, wiki discovery_triggers); prewarm; the publish/dev/user SKILL set you must ship; and the auto-discover → install-check → use flow.+description: Author, PUBLISH, and make-discoverable an adom-desktop bridge — a small local server that adds a namespace of verbs (kicad_, fusion_, browser_, your_prefix_) to adom-desktop. Use when building, publishing, updating, prewarming, or debugging a bridge, or deciding what skills to ship. Covers the AD-core-vs-author boundary; the #1 rule (rich hints in EVERY verb's OUTPUT, because the AI reads CLI output, never your on-disk skill); bridge.json; where every file lives (the Release-zip-vs-skills-pkg split, the TWO package.json files, manifest + runtime-asset placement) and which skills stay private if your bridge is closed-source; the THREE things you publish (runtime Release zip + manifest, container skills pkg, wiki discovery_triggers); prewarm; the publish/dev/user SKILL set you must ship; and the auto-discover → install-check → use flow. --- # Bridge SDK — build, publish, and surface a bridge for Adom Desktop@@ -17,6 +17,34 @@ A **bridge** is a small local program (Python, Node, Rust, anything) that AD spa --- +## Where every file lives — the two artifacts, their deps, and which skills go public++**Two DISTINCT artifacts, two DIFFERENT homes, two DIFFERENT consumers. Crossing them is the #1 inconsistency across bridge repos — pin it here before anything else.** (Live audit 2026-07-06: fusion + pup do this right; kicad had **61** loose `adom-bridge-kicad-v*.zip` on `/files` + a `mesa-llvmpipe-x64.zip`; blender dumped 2 loose zips too.)++| | **RUNTIME artifact** (Artifact 1) | **SKILLS pkg** (Artifact 2) |+|---|---|---|+| **What it is** | your bridge's actual CODE | your consumer `SKILL.md` docs |+| **Runs on** | the user's **DESKTOP** — AD spawns it | **nothing runs it** — docs the CONTAINER reads |+| **Published as** | a versioned **Release** (`release create` + `release upload --platform any`) | an **`adom-wiki pkg`** (`pkg publish --org adom`) |+| **Installed by** | `bridge_install {manifestUrl}` → AD streams, unzips, spawns | `pkg install adom/<slug>` / `sync_skills` → `~/.claude/skills` + `~/.codex/skills` |+| **Contains** | server code + `bridge.json` at the zip **ROOT** + assets. **Node: SOURCE ONLY, no `node_modules`.** | ROOT `SKILL.md` + `skills/<name>/SKILL.md` + `package.json` + `install.sh`/`uninstall.sh`. **Docs only.** |+| **NEVER contains** | the skills pkg | **ANY binary, the Release zip, `src/`, `node_modules`, hero PNGs, or a `dependencies:` block** |+| **its `package.json`** | (node) the **RUNTIME deps** AD installs at spawn: `dependencies:{ puppeteer, … }` | the **skillpack manifest**: `files[]`, `discovery_triggers`, install/uninstall scripts — **NO `dependencies`** |++**Yes, a node bridge has TWO `package.json` files and they are NOT interchangeable.** One rides inside the Release zip and lists the deps AD installs on the *desktop*; the other is the skillpack manifest in the pkg tarball and lists *skill files*, never deps. Put runtime `dependencies` in the **pkg's** package.json and you bloat every container install — the pkg lands in a container that *never runs your bridge*. Put skill metadata in the **zip's** package.json and it does nothing.++**Where each file physically lives (this is the map that ends the inconsistency):**+- **`bridge.json`** → the **root of the Release zip** (AD reads it post-unzip). Carries `version` + `updateManifestUrl`.+- **The Release `.zip`** → a **Release asset** (`release upload … --platform any`). **NEVER a loose `/files` blob.** Loose binaries can't be cleanly deleted from a git page, so every stale version lingers forever (kicad's 61). Copy fusion/pup: releases only.+- **The manifest** (`adom-bridge-<name>-manifest.json`, this naming is the consistent one — keep it) → POSTed to your page **`/files`**. Its `url` points at the **Release download** (`https://wiki.adom.inc/download/adom/<slug>/<ver>/<file>.zip`), base-relative + extension-agnostic. `updateManifestUrl` (in the manifest AND in bridge.json) points back at this manifest.+- **A big RUNTIME ASSET** (a headless-GL pack like Mesa, a browser download) → declare it in **`prewarm.assets`** so AD downloads + manages it, or bundle it in your seed. **NOT a loose `/files` blob** — kicad's `mesa-llvmpipe-x64.zip` on `/files` is the anti-pattern.++**Which skills go PUBLIC depends on whether your bridge is open source:**+- **USER skills ALWAYS ship** in your pkg (public) — the container can't drive your verbs without them.+- **DEV + PUBLISH skills:** ship them in your pkg (scoped `user-invocable:false`, see "The SKILL SET") **only if your bridge is OPEN SOURCE** / you're fine with your release-and-publish process being publicly readable. **If your bridge is CLOSED SOURCE, keep dev + publish skills in your PRIVATE repo and ship ONLY user skills to the wiki** — exactly what **adom-desktop core** does: its `RELEASE` / `WIKI_PUBLISH` / `SIGNING` / `AD_RELAUNCH` skills live only in the private GitHub source and are NEVER in the public pkg (verified: the published adom-desktop pkg carries 9 user/integration skills, zero dev/publish). Don't publish your release dance if your source isn't public.++---+ ## The boundary — what AD owns vs what YOU own The #1 mistake is filing AD bugs for bridge issues. The split:@@ -77,6 +105,12 @@ When a maintainer says *"audit your code, skills, README, and wiki page against - [ ] `detect` declared iff you drive a HOST APP (KiCad/Fusion/Altium…); omitted if you bring your own runtime (pup). `prewarm.assets` declared for heavy downloads (e.g. `chrome-for-testing`). *(→ Cold-start tiers)* - [ ] **`timeouts`** declared if ANY verb can run longer than 60s (a big export/render/cloud-open) — with a matching **`statusVerb`** to poll. Third-party bridges were 60s-capped before v1.9.79; this is how you raise it. *(→ bridge.json)* +**Artifacts & deps** (the two-artifact split — the #1 inconsistency) *(→ Where every file lives)*:+- [ ] Your Release `.zip` is a **Release asset** (`release upload`), NOT a loose `/files` blob — and old version zips are NOT piling up on `/files` (audit for stray `*-v*.zip`).+- [ ] Runtime deps live in the **ZIP's** `package.json` (node) / `requirements.txt` (python); the **skillpack** `package.json` in your pkg has **NO `dependencies`** (it installs into a container that never runs you).+- [ ] A big runtime asset (Mesa, a browser) is a **`prewarm.asset`** or seed-bundled — NOT a loose `/files` blob.+- [ ] Your **manifest** (`adom-bridge-<name>-manifest.json`) is on `/files`; its `url` points at the **Release download**, not at a `/files` blob.+ **Runtime** (Node/Python bridges) *(→ Runtime contract)*: - [ ] You bind **`ADOM_BIND_HOST`** (loopback default), never `0.0.0.0`. - [ ] You do **NOT** bootstrap your own Node/Python — no `winget`/`desktop_install_node`/self-download in code or skills. `spawn.kind` is the declaration; AD provisions it.@@ -94,7 +128,8 @@ When a maintainer says *"audit your code, skills, README, and wiki page against - [ ] Triggers stay in YOUR niche — you don't poach a sibling's (login/forms → native-browser, not pup). `discovery_pitch` is an INSTRUCTION. **Skills & docs** (what the container + humans read):-- [ ] You ship the publish/dev/user **3-skill set** in the SKILLPACK layout: EVERY skill (user + dev + publish) is a real `skills/<name>/SKILL.md` with a `Parent skill:` first body line; dev/publish are scoped by `user-invocable: false` + a DEVELOPER-only description (NOT by hiding them as `dev-skills/*.md` — that convention is dead); every path listed EXPLICITLY (no globs) in `files[]` + install.sh/uninstall.sh. *(→ Artifact 2 + The SKILL SET)*+- [ ] You ship the **USER skill(s)** in the SKILLPACK layout: a real `skills/<name>/SKILL.md` with a `Parent skill:` first body line; every path listed EXPLICITLY (no globs) in `files[]` + install.sh/uninstall.sh. *(→ Artifact 2 + The SKILL SET)*+- [ ] **DEV + PUBLISH skills:** in the pkg (scoped `user-invocable:false` + DEVELOPER-only description, NOT hidden as `dev-skills/*.md` — that convention is dead) **only if your bridge is OPEN SOURCE**; if CLOSED source, they stay in your PRIVATE repo and only user skills ship (the adom-desktop-core model). *(→ Where every file lives)* - [ ] Your USER skill leads with the cold-start "read before you panic" section + the 8 conventions, and points the AI at `bridge_readiness`. *(→ USER-skill conventions)* - [ ] README + wiki page + skills all AGREE with the above (no stale github links, no wrong schema, triggers vetted). @@ -365,6 +400,8 @@ Your `/health` (200) makes the chip green. Optionally return `led` (`green`/`yel `bridge_install {manifestUrl}` · `bridge_list` · `bridge_info`/`bridge_detail {name}` · `bridge_log_read {name, sinceOffset?}` · `bridge_kill {name}` · `bridge_pause {name}` · `refresh_bridges {name?}` · `bridge_check_updates`. A bridge installed via `bridge_install` auto-updates with no further opt-in; `updateManifestUrl` in `bridge.json` makes it durable across republish. +**"My bridge keeps exiting and I can't see why" (read this).** Your own stdout log truncates on every respawn, so a crash-then-restart erases its own cause. `bridge_log_read` therefore also tails **AD's lifecycle audit log** for your bridge, a separate append-only file (`~/.adom/bridge-logs/<name>.ad.log`) that survives respawns, shown under an `===== AD bridge lifecycle =====` header. It records every spawn, reap, duplicate-collapse, and `bridge_kill` with the reason, so you can tell "AD reaped it as a duplicate" or "the `bridge_kill` verb stopped it" or "it was reaped before a fresh spawn" apart from "it crashed on its own." If the audit log shows AD never stopped it, the exit is inside your process.+ --- ## Publish checklist (the whole modern flow)
bridges-SDK.md+39−2@@ -1,6 +1,6 @@ --- name: adom-desktop-bridge-sdk-description: Author, PUBLISH, and make-discoverable an adom-desktop bridge — a small local server that adds a namespace of verbs (kicad_, fusion_, browser_, your_prefix_) to adom-desktop. Use when building, publishing, updating, prewarming, or debugging a bridge, or deciding what skills to ship. Covers the AD-core-vs-author boundary; the #1 rule (rich hints in EVERY verb's OUTPUT, because the AI reads CLI output, never your on-disk skill); bridge.json; the THREE things you publish (runtime Release zip + manifest, container skills pkg, wiki discovery_triggers); prewarm; the publish/dev/user SKILL set you must ship; and the auto-discover → install-check → use flow.+description: Author, PUBLISH, and make-discoverable an adom-desktop bridge — a small local server that adds a namespace of verbs (kicad_, fusion_, browser_, your_prefix_) to adom-desktop. Use when building, publishing, updating, prewarming, or debugging a bridge, or deciding what skills to ship. Covers the AD-core-vs-author boundary; the #1 rule (rich hints in EVERY verb's OUTPUT, because the AI reads CLI output, never your on-disk skill); bridge.json; where every file lives (the Release-zip-vs-skills-pkg split, the TWO package.json files, manifest + runtime-asset placement) and which skills stay private if your bridge is closed-source; the THREE things you publish (runtime Release zip + manifest, container skills pkg, wiki discovery_triggers); prewarm; the publish/dev/user SKILL set you must ship; and the auto-discover → install-check → use flow. --- # Bridge SDK — build, publish, and surface a bridge for Adom Desktop@@ -17,6 +17,34 @@ A **bridge** is a small local program (Python, Node, Rust, anything) that AD spa --- +## Where every file lives — the two artifacts, their deps, and which skills go public++**Two DISTINCT artifacts, two DIFFERENT homes, two DIFFERENT consumers. Crossing them is the #1 inconsistency across bridge repos — pin it here before anything else.** (Live audit 2026-07-06: fusion + pup do this right; kicad had **61** loose `adom-bridge-kicad-v*.zip` on `/files` + a `mesa-llvmpipe-x64.zip`; blender dumped 2 loose zips too.)++| | **RUNTIME artifact** (Artifact 1) | **SKILLS pkg** (Artifact 2) |+|---|---|---|+| **What it is** | your bridge's actual CODE | your consumer `SKILL.md` docs |+| **Runs on** | the user's **DESKTOP** — AD spawns it | **nothing runs it** — docs the CONTAINER reads |+| **Published as** | a versioned **Release** (`release create` + `release upload --platform any`) | an **`adom-wiki pkg`** (`pkg publish --org adom`) |+| **Installed by** | `bridge_install {manifestUrl}` → AD streams, unzips, spawns | `pkg install adom/<slug>` / `sync_skills` → `~/.claude/skills` + `~/.codex/skills` |+| **Contains** | server code + `bridge.json` at the zip **ROOT** + assets. **Node: SOURCE ONLY, no `node_modules`.** | ROOT `SKILL.md` + `skills/<name>/SKILL.md` + `package.json` + `install.sh`/`uninstall.sh`. **Docs only.** |+| **NEVER contains** | the skills pkg | **ANY binary, the Release zip, `src/`, `node_modules`, hero PNGs, or a `dependencies:` block** |+| **its `package.json`** | (node) the **RUNTIME deps** AD installs at spawn: `dependencies:{ puppeteer, … }` | the **skillpack manifest**: `files[]`, `discovery_triggers`, install/uninstall scripts — **NO `dependencies`** |++**Yes, a node bridge has TWO `package.json` files and they are NOT interchangeable.** One rides inside the Release zip and lists the deps AD installs on the *desktop*; the other is the skillpack manifest in the pkg tarball and lists *skill files*, never deps. Put runtime `dependencies` in the **pkg's** package.json and you bloat every container install — the pkg lands in a container that *never runs your bridge*. Put skill metadata in the **zip's** package.json and it does nothing.++**Where each file physically lives (this is the map that ends the inconsistency):**+- **`bridge.json`** → the **root of the Release zip** (AD reads it post-unzip). Carries `version` + `updateManifestUrl`.+- **The Release `.zip`** → a **Release asset** (`release upload … --platform any`). **NEVER a loose `/files` blob.** Loose binaries can't be cleanly deleted from a git page, so every stale version lingers forever (kicad's 61). Copy fusion/pup: releases only.+- **The manifest** (`adom-bridge-<name>-manifest.json`, this naming is the consistent one — keep it) → POSTed to your page **`/files`**. Its `url` points at the **Release download** (`https://wiki.adom.inc/download/adom/<slug>/<ver>/<file>.zip`), base-relative + extension-agnostic. `updateManifestUrl` (in the manifest AND in bridge.json) points back at this manifest.+- **A big RUNTIME ASSET** (a headless-GL pack like Mesa, a browser download) → declare it in **`prewarm.assets`** so AD downloads + manages it, or bundle it in your seed. **NOT a loose `/files` blob** — kicad's `mesa-llvmpipe-x64.zip` on `/files` is the anti-pattern.++**Which skills go PUBLIC depends on whether your bridge is open source:**+- **USER skills ALWAYS ship** in your pkg (public) — the container can't drive your verbs without them.+- **DEV + PUBLISH skills:** ship them in your pkg (scoped `user-invocable:false`, see "The SKILL SET") **only if your bridge is OPEN SOURCE** / you're fine with your release-and-publish process being publicly readable. **If your bridge is CLOSED SOURCE, keep dev + publish skills in your PRIVATE repo and ship ONLY user skills to the wiki** — exactly what **adom-desktop core** does: its `RELEASE` / `WIKI_PUBLISH` / `SIGNING` / `AD_RELAUNCH` skills live only in the private GitHub source and are NEVER in the public pkg (verified: the published adom-desktop pkg carries 9 user/integration skills, zero dev/publish). Don't publish your release dance if your source isn't public.++---+ ## The boundary — what AD owns vs what YOU own The #1 mistake is filing AD bugs for bridge issues. The split:@@ -77,6 +105,12 @@ When a maintainer says *"audit your code, skills, README, and wiki page against - [ ] `detect` declared iff you drive a HOST APP (KiCad/Fusion/Altium…); omitted if you bring your own runtime (pup). `prewarm.assets` declared for heavy downloads (e.g. `chrome-for-testing`). *(→ Cold-start tiers)* - [ ] **`timeouts`** declared if ANY verb can run longer than 60s (a big export/render/cloud-open) — with a matching **`statusVerb`** to poll. Third-party bridges were 60s-capped before v1.9.79; this is how you raise it. *(→ bridge.json)* +**Artifacts & deps** (the two-artifact split — the #1 inconsistency) *(→ Where every file lives)*:+- [ ] Your Release `.zip` is a **Release asset** (`release upload`), NOT a loose `/files` blob — and old version zips are NOT piling up on `/files` (audit for stray `*-v*.zip`).+- [ ] Runtime deps live in the **ZIP's** `package.json` (node) / `requirements.txt` (python); the **skillpack** `package.json` in your pkg has **NO `dependencies`** (it installs into a container that never runs you).+- [ ] A big runtime asset (Mesa, a browser) is a **`prewarm.asset`** or seed-bundled — NOT a loose `/files` blob.+- [ ] Your **manifest** (`adom-bridge-<name>-manifest.json`) is on `/files`; its `url` points at the **Release download**, not at a `/files` blob.+ **Runtime** (Node/Python bridges) *(→ Runtime contract)*: - [ ] You bind **`ADOM_BIND_HOST`** (loopback default), never `0.0.0.0`. - [ ] You do **NOT** bootstrap your own Node/Python — no `winget`/`desktop_install_node`/self-download in code or skills. `spawn.kind` is the declaration; AD provisions it.@@ -94,7 +128,8 @@ When a maintainer says *"audit your code, skills, README, and wiki page against - [ ] Triggers stay in YOUR niche — you don't poach a sibling's (login/forms → native-browser, not pup). `discovery_pitch` is an INSTRUCTION. **Skills & docs** (what the container + humans read):-- [ ] You ship the publish/dev/user **3-skill set** in the SKILLPACK layout: EVERY skill (user + dev + publish) is a real `skills/<name>/SKILL.md` with a `Parent skill:` first body line; dev/publish are scoped by `user-invocable: false` + a DEVELOPER-only description (NOT by hiding them as `dev-skills/*.md` — that convention is dead); every path listed EXPLICITLY (no globs) in `files[]` + install.sh/uninstall.sh. *(→ Artifact 2 + The SKILL SET)*+- [ ] You ship the **USER skill(s)** in the SKILLPACK layout: a real `skills/<name>/SKILL.md` with a `Parent skill:` first body line; every path listed EXPLICITLY (no globs) in `files[]` + install.sh/uninstall.sh. *(→ Artifact 2 + The SKILL SET)*+- [ ] **DEV + PUBLISH skills:** in the pkg (scoped `user-invocable:false` + DEVELOPER-only description, NOT hidden as `dev-skills/*.md` — that convention is dead) **only if your bridge is OPEN SOURCE**; if CLOSED source, they stay in your PRIVATE repo and only user skills ship (the adom-desktop-core model). *(→ Where every file lives)* - [ ] Your USER skill leads with the cold-start "read before you panic" section + the 8 conventions, and points the AI at `bridge_readiness`. *(→ USER-skill conventions)* - [ ] README + wiki page + skills all AGREE with the above (no stale github links, no wrong schema, triggers vetted). @@ -365,6 +400,8 @@ Your `/health` (200) makes the chip green. Optionally return `led` (`green`/`yel `bridge_install {manifestUrl}` · `bridge_list` · `bridge_info`/`bridge_detail {name}` · `bridge_log_read {name, sinceOffset?}` · `bridge_kill {name}` · `bridge_pause {name}` · `refresh_bridges {name?}` · `bridge_check_updates`. A bridge installed via `bridge_install` auto-updates with no further opt-in; `updateManifestUrl` in `bridge.json` makes it durable across republish. +**"My bridge keeps exiting and I can't see why" (read this).** Your own stdout log truncates on every respawn, so a crash-then-restart erases its own cause. `bridge_log_read` therefore also tails **AD's lifecycle audit log** for your bridge, a separate append-only file (`~/.adom/bridge-logs/<name>.ad.log`) that survives respawns, shown under an `===== AD bridge lifecycle =====` header. It records every spawn, reap, duplicate-collapse, and `bridge_kill` with the reason, so you can tell "AD reaped it as a duplicate" or "the `bridge_kill` verb stopped it" or "it was reaped before a fresh spawn" apart from "it crashed on its own." If the audit log shows AD never stopped it, the exit is inside your process.+ --- ## Publish checklist (the whole modern flow)