← Commit history
SKILL.md+36
@@ -277,6 +277,8 @@ adom-bridge --target all hydrogen_status        # every box at once, results key  **No-target behavior:** with exactly ONE Bridge connected, no `--target` is needed (back-compat). With MULTIPLE connected and no `--target`, the call FAILS with `{error:"ambiguous_target", connected:[...], _hint}` (exit 1) - it won't guess which box. A bad name → `{error:"target_not_found", requested, connected:[...]}` (exit 1). Set each Bridge's name with the `--client-name <name>` launch flag (Hydrogen passes this when spawning the embedded Bridge), the Settings field, or `config.json` `client_name`. Full design + the relay-routing internals: [`skills/MULTI_AD_ADDRESSING.md`](MULTI_AD_ADDRESSING.md). +**1.9.219 - the Adom Mesh on macOS.** `--target <name>` now tries the **mesh** first (end-to-end encrypted QUIC between the two boxes' node keys, carried through the Adom mesh relay across networks) and falls back to the cloud command relay; a mesh answer carries `route.via:"mesh"`. Off by default; `desktop_mesh_set_mode {"mode":"relay"}` turns it on. Verbs: `desktop_mesh_status`, `desktop_mesh_peers`, `desktop_mesh_trust` (list/raise/revoke/deny, never approve), `desktop_mesh_set_mode`, `desktop_mesh_pull_files`. A Mac and a Windows Bridge (2.1.40+) of the same account are peers. **1.9.224:** the Mesh view, the MESH JOIN card and Settings > Adom Mesh are in Bridge's own window (`desktop_ui_panel {"panel":"mesh","action":"show"}` raises it), and the cross-box permission mirror is on: a prompt raised on any of the user's boxes shows on every other one, decided with a one-shot nonce. What is and is not ported, and what the tests proved: [`skills/MESH.md`](MESH.md).+ #### Direct HTTP API for sibling apps (v1.8.25+)  If you're authoring a sibling Tauri app on the same machine (Adom Hydrogen, or any future "Adom-family" app), you can skip the CLI binary entirely and POST commands straight into the running adom-bridge GUI on `127.0.0.1:47200` (was `127.0.0.1:8770` through v1.8.32 - moved to be a better neighbor to Hydrogen on 47080+ and avoid the 8000-range collision risk). The endpoint runs inside the GUI process (loopback-only bind), uses the same dispatcher the WS path uses, and returns the same JSON shape as `adom-bridge <verb>` - including every `_hint` field.@@ -2029,3 +2031,37 @@ adom-bridge wiki_exec '{"args":["repo","push","adom/my-board","--files","board.k - Container-side publishing of the CONTAINER's own files still uses your local `adom-wiki` directly; `wiki_exec` is for files that live on the Mac.  Note (v1.9.117): Bridge's Settings panel no longer has a KiCad section - bridges own their app-specific config (Bridge stays generic). `kicad_library_paths` / `project_watch` keep working from `~/.adom/config.json` and the `set_project_watch` / `trigger_project_watch` verbs.++### The project watcher (Bridge core owns this - bridges implement nothing)++**This section is the AUTHORITATIVE shape, and external manifests point AT IT BY NAME**+(the kicad bridge's `bridge.json` names this file + the heading "project watcher", at file+level rather than by line so it survives edits). So: renaming this heading or moving it to+another file breaks a pointer you cannot see from this repo. Retitle deliberately, and if you+do, say so on the agent bus — the whole point of the arrangement is that only ONE copy of+this fact exists, which makes the pointer load-bearing.++A bridge's `bridge.json` should POINT here, never transcribe it: a copied struct in a discovery manifest cannot be noticed when it+drifts (KICAD declined to copy it for exactly that reason, 2026-09-17). Source of truth is+`ProjectWatchConfig` in `src-tauri/src/state.rs`; the loop is `src-tauri/src/project_watch.rs`.++Config key `project_watch` in `~/.adom/config.json`:++| Field | Type | Default | Meaning |+| --- | --- | --- | --- |+| `enabled` | bool | - | watcher on/off |+| `project_path` | string | - | directory watched (recursively) |+| `poll_interval_secs` | u64 | `2` | filesystem poll cadence |+| `debounce_secs` | u64 | `1` | quiet period before a change is reported |++Verbs: **`set_project_watch`** (writes the config + starts/stops the loop) and+**`trigger_project_watch`** (forces an immediate re-sync). Both are Tier-2 gated for relay+callers. A bridge does NOT implement either - Bridge core watches the files and pushes+updates, which is why the kicad bridge's tree contains no watcher code at all.++⚠ There is **no version/runtime floor in the bridge.json schema.** `BridgeSpawn`+(`bridge_registry.rs`) parses exactly `{kind, entrypoint, port, persistent, healthEndpoint,+stopMethod, killImageName}` - nothing else. A `python: ">=3.11"`-style field in a manifest is+human documentation and gates NOTHING; the interpreter is whatever `runtime_cache` resolves+(pinned managed Python, or a system one that reports a parseable version). Do not "fix" such+a field believing it constrains a spawn.
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-bridge-macos",-  "version": "1.9.209",+  "version": "1.9.224",   "type": "app",   "brief": "Adom Bridge is a small operating system for AI on your Mac: it gives an AI real hands on your native desktop, including your signed-in browser, KiCad, Fusion 360, the shell, files, windows and screenshots. It provisions its own Node and Python so bridges run without touching your setup, and it talks straight to your machine. It ships with Adom Hydrogen and installs standalone too, so if you drive your Mac with Claude Desktop or another AI, this is what gives that AI hands.",   "description": "Install this package in a cloud or Adom Hydrogen container, not on the Mac. It delivers the Claude skill set that teaches an AI every desktop verb (shell, files, screenshots, windows, notifications, KiCad, Fusion 360, browser automation), plus the Linux adom-bridge CLI when one is staged (publishes from the mac release flow are skills-only; the install degrades gracefully and keeps any CLI already on PATH). The CLI drives the Adom Bridge app running on your Mac over the relay; the macOS app itself is the separate DMG in the Download box, not part of this package. Run adom-wiki pkg update to keep the skills current.",
page.json+1−1
@@ -1,6 +1,6 @@ {   "name": "adom-desktop-macos",-  "version": "1.9.209",+  "version": "1.9.224",   "type": "app",   "description": "Install this package in a cloud or Adom Hydrogen container, not on the Mac. It delivers the Claude skill set that teaches an AI every desktop verb (shell, files, screenshots, windows, notifications, KiCad, Fusion 360, browser automation), plus the Linux adom-bridge CLI when one is staged (publishes from the mac release flow are skills-only; the install degrades gracefully and keeps any CLI already on PATH). The CLI drives the Adom Bridge app running on your Mac over the relay; the macOS app itself is the separate DMG in the Download box, not part of this package. Run adom-wiki pkg update to keep the skills current.",   "dependencies": {},
skills/adom-bridge-bridge-sdk/SKILL.md+46−7
@@ -1,6 +1,6 @@ --- name: adom-bridge-bridge-sdk-description: Author, PUBLISH, and make-discoverable an adom-bridge bridge — a small local server that adds a namespace of verbs (kicad_, fusion_, browser_, your_prefix_) to adom-bridge. Use when building, publishing, updating, prewarming, or debugging a bridge, or deciding what skills to ship. Covers the Adom Bridge-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 [server deps in the zip; the pkg declares dependencies:{adom/adom-bridge}], manifest + runtime-asset placement); the pkg carries ONLY user skills while dev + publish skills live in your source repo (not the pkg); the THREE things you publish (runtime Release zip + manifest, container skills pkg, wiki discovery_triggers); prewarm; and the auto-discover → install-check → use flow.+description: Author, PUBLISH, and make-discoverable an adom-bridge bridge — a small local server that adds a namespace of verbs (kicad_, fusion_, browser_, your_prefix_) to adom-bridge. Use when building, publishing, updating, prewarming, or debugging a bridge, or deciding what skills to ship. Covers the Adom Bridge-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 [server deps in the zip; the pkg declares the platform-correct Adom Bridge dep: mac adom/adom-bridge-macos, Windows adom/adom-bridge], manifest + runtime-asset placement); the pkg carries ONLY user skills while dev + publish skills live in your source repo (not the pkg); the THREE things you publish (runtime Release zip + manifest, container skills pkg, wiki discovery_triggers); prewarm; and the auto-discover → install-check → use flow. ---  # Bridge SDK — build, publish, and surface a bridge for Adom Bridge@@ -29,9 +29,9 @@ A **bridge** is a small local program (Python, Node, Rust, anything) that Adom B | **Installed by** | `bridge_install {manifestUrl}` → Adom Bridge 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`.** | ONLY: ROOT `SKILL.md`, `skills/<name>/SKILL.md` (user skills), `package.json`, `install.sh`, `uninstall.sh`. **Text only — the whole tarball should be a few KB.** | | **NEVER contains** | the skills pkg | **ANY image (hero / screenshots — those are WIKI PAGE assets, see below), any binary, the Release zip, `src/`, `node_modules`, dev/publish skills, or the server's npm deps.** If `tar tzf` shows a `.png`/`.jpg`/`.zip`/`.exe`, you bundled bloat — remove it. |-| **its `package.json`** | (node) the **bridge SERVER's runtime deps** Adom Bridge installs at spawn: `dependencies:{ puppeteer, … }` | the **pkg manifest**: `files[]` (user skills), `discovery_triggers`, scripts, **AND `dependencies:{"adom/adom-bridge":"^1.9.x"}`** (the container needs the Adom Bridge CLI + core skills to drive you) — but NOT the server's npm deps |+| **its `package.json`** | (node) the **bridge SERVER's runtime deps** Adom Bridge installs at spawn: `dependencies:{ puppeteer, … }` | the **pkg manifest**: `files[]` (user skills), `discovery_triggers`, scripts, **AND the Adom Bridge dep for your line** — mac: `dependencies:{"adom/adom-bridge-macos":"^1.9.x"}`, Windows: `{"adom/adom-bridge":"^2.1.x"}` (the container needs the Adom Bridge CLI + core skills to drive you) — but NOT the server's npm deps | -**Yes, a node bridge has TWO `package.json` files and they are NOT interchangeable.** One rides inside the Release zip and lists the **bridge server's** runtime deps (puppeteer, sharp, ...) that Adom Bridge installs on the *desktop* at spawn. The other is the **pkg manifest** in the skills tarball: it lists your user-skill `files[]` + `discovery_triggers` AND declares **`dependencies:{"adom/adom-bridge":"^1.9.x"}`** — `pkg install` resolves that npm-style, so installing your bridge's skill pkg also pulls the adom-bridge CLI + core skills the container needs to drive you. What the pkg manifest must NOT list is the **server's** npm deps (those are desktop-side, in the zip) — put them there and you bloat every container install, since the container never runs your server.+**Yes, a node bridge has TWO `package.json` files and they are NOT interchangeable.** One rides inside the Release zip and lists the **bridge server's** runtime deps (puppeteer, sharp, ...) that Adom Bridge installs on the *desktop* at spawn. The other is the **pkg manifest** in the skills tarball: it lists your user-skill `files[]` + `discovery_triggers` AND declares the Adom Bridge dep for your line (**mac: `dependencies:{"adom/adom-bridge-macos":"^1.9.x"}`**; Windows: `{"adom/adom-bridge":"^2.1.x"}`) — `pkg install` resolves that npm-style, so installing your bridge's skill pkg also pulls the adom-bridge CLI + core skills the container needs to drive you. What the pkg manifest must NOT list is the **server's** npm deps (those are desktop-side, in the zip) — put them there and you bloat every container install, since the container never runs your server.  **Where each file physically lives (this is the map that ends the inconsistency):** - **`bridge.json`** → the **root of the Release zip** (Adom Bridge reads it post-unzip). Carries `version` + `updateManifestUrl`.@@ -201,7 +201,7 @@ When a maintainer says *"audit your code, skills, README, and wiki page against  **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`).-- [ ] The **server's** runtime deps live in the **ZIP's** `package.json` (node) / `requirements.txt` (python). The **pkg's** `package.json` declares `dependencies:{"adom/adom-bridge":"^1.9.x"}` (so `pkg install` pulls the Adom Bridge CLI + core skills) and does NOT list the server's npm deps.+- [ ] The **server's** runtime deps live in the **ZIP's** `package.json` (node) / `requirements.txt` (python). The **pkg's** `package.json` declares the Adom Bridge dep **for your platform line** — mac `{"adom/adom-bridge-macos":"^1.9.x"}`, Windows `{"adom/adom-bridge":"^2.1.x"}` (so `pkg install` pulls the Adom Bridge CLI + core skills) — and does NOT list the server's npm deps. - [ ] 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. - [ ] **PAYLOAD:** `unzip -l <your zip> | sort -k1 -n -r | head` shows **runtime only** — no `.mp4`/`.png`/`.jpg`/screenshots/CHANGELOG/`.github`. A runtime zip is normally well under 1 MB; if yours is bigger, justify every large entry. `tar tzf <your tgz>` shows **skills only** — zero media, zero binaries. Media belongs on the PAGE. *(→ Payload rules)*@@ -231,7 +231,7 @@ When a maintainer says *"audit your code, skills, README, and wiki page against **Skills & docs** (what the container + humans read): - [ ] Your pkg ships **ONLY your USER skill(s)** — a real `skills/<name>/SKILL.md` (core user skill + user sub-skills) 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 are in your source REPO, NOT the pkg** — not in `files[]`, not scoped in via `user-invocable:false`. A developer gets them by cloning the source; the normal user never needs them. Open-vs-closed source is irrelevant (it only sets repo visibility). *(→ Where every file lives)*-- [ ] Your pkg's `package.json` declares `dependencies:{"adom/adom-bridge":"^1.9.x"}` so `pkg install` pulls the Adom Bridge CLI + core skills the container needs. *(→ Where every file lives)*+- [ ] Your pkg's `package.json` declares the Adom Bridge dep for your line (mac `{"adom/adom-bridge-macos":"^1.9.x"}`, Windows `{"adom/adom-bridge":"^2.1.x"}`) so `pkg install` pulls the Adom Bridge CLI + core skills the container needs — and NOT the other line's, which would drag the wrong CLI onto the box. *(→ 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). @@ -323,14 +323,53 @@ Your runtime runs on the user's DESKTOP; the AI driving it runs in a cloud/WSL2  - **The pkg carries ONLY your USER skill(s).** Each is a real `skills/<name>/SKILL.md`. A ROOT `SKILL.md` (required by the registry) is the pack entry point: `user-invocable: true`, a `description` full of trigger words. Large surface → a core user skill + user sub-skills, but **every skill in the pkg is a *user* skill.** - **DEV + PUBLISH skills do NOT go in the pkg — they live in your source repo** (a developer gets them by cloning to edit the bridge). Do NOT list them in `files[]`, and do NOT "scope" them in with `user-invocable:false` (that still ships them and bloats every container install).-- **Declare `dependencies:{"adom/adom-bridge":"^1.9.x"}`** in `package.json` — `pkg install` resolves it npm-style, so installing your bridge's skill pkg also pulls the Adom Bridge CLI + core skills the container needs to drive you.+- **Declare the Adom Bridge dependency for YOUR LINE** in `package.json` — `pkg install` resolves it npm-style, so installing your bridge's skill pkg also pulls the Adom Bridge CLI + core skills the container needs to drive you. **The slug is platform-specific and there are two live lines:**++  | Your bridge ships for | Depend on | Current | Why |+  | --- | --- | --- | --- |+  | **macOS** | `{"adom/adom-bridge-macos": "^1.9.<your floor>"}` | 1.9.209 | the mac line (page "Adom Bridge (macOS)") |+  | **Windows** | `{"adom/adom-bridge": "^2.1.<your floor>"}` | 2.1.129 | John's line (page "Adom Bridge") |++  **Pin the floor you ACTUALLY require — do not copy `^1.9.x` literally.** A caret range is+  `>= the version you name` and `< the next major`, and an `x` placeholder reads as `.0`: so+  `^1.9.x` means **>=1.9.0**, which happily accepts a CLI hundreds of patches older than the+  verbs your skills tell it to call. Name the oldest Bridge that can actually run your bridge.+  Worked example (fusion mac, 2026-09-17): it needs the direct-API `notify_user` added in+  **1.9.84** and managed runtimes from 1.9.47, so its floor is `^1.9.84`. **Be precise about+  the blast radius, though** — on `adom/adom-bridge-macos` the window `[1.9.0, 1.9.84)` is+  currently EMPTY (35 releases: 1.4.0–1.4.2, then the 1.9 series starts at 1.9.156), so no+  install can land in that hole today. That is an accident of publish history, not a property+  of the range, and **it is a fact about ONE page**: the same sub-window on `adom/adom-bridge`+  holds **40 publishable rows (1.9.33 … 1.9.81)** of the 137 its `^1.9.x` matches, so a+  Windows-line bridge pinning `^1.9.0` really can land 40 versions below a 1.9.84-era+  requirement. "A caret cannot reach a too-old build" is never true of the registry, only ever+  of a particular page on a particular day. Pin the real floor because the declaration should+  state your requirement, not because today's registry happens to be forgiving.++  **Be honest about what a floor is doing, too.** On `adom/adom-bridge-macos` today, `^1.9.84`+  and `^1.9.79` each exclude ZERO published releases (everything resolvable is >=1.9.156), so on+  that page a floor is **documentation, not enforcement** — it states the requirement correctly+  and would only bite if an older row were backfilled. Still write it: `^1.9.x` states no+  requirement at all, and a correct declaration survives a registry that changes under you.+  Just do not report "we pinned the floor" as if it were protecting someone when it is not yet. A second reason to pin it honestly: the fusion case degrades at RUNTIME rather+  than crashing (its client is best-effort and falls back to handing the AI a payload), but the+  shipped SKILL text tells the AI the direct call works — so the failure is an AI following an+  instruction its CLI cannot honour. The skills are the half that hard-depends. Equally, `"*"` declares no+  requirement at all; it may resolve to the right LINE, but it is how a box ends up with a CLI+  too old for the skills shipped beside it.++  ⚠ **This guidance used to say `{"adom/adom-bridge":"^1.9.x"}` unconditionally, and that is wrong in BOTH halves for a mac bridge** (found live 2026-09-17: the fusion mac pkg shipped it, and the kicad mac pkg still carries `^2.0.3`). `adom/adom-bridge` is the WINDOWS line and is at 2.1.129. **What actually happens is worse than a failure: it succeeds.** Measured against the live registry 2026-09-17 — that page carries 363 releases, 137 of them in the `^1.9.x` window (1.9.33 … 1.9.233), and the resolver takes the MAX satisfying row, so `{"adom/adom-bridge":"^1.9.x"}` resolves cleanly to **1.9.233** and installs John's Windows-line CLI onto the Mac. No error, no stale-looking version — just the wrong platform's CLI, which names the built-in app namespace `"desktop"` and is answered by the mac relay seat with `Unknown app: desktop`. (An earlier revision of this section said it "resolves to a stale 1.9.x, or fails outright"; that was a guess and it was wrong — corrected after querying both pages.) A mac bridge that declares it also drags John's Windows-line CLI onto the Mac, where it overwrites `~/.local/bin/adom-bridge`; that CLI names the built-in app namespace `"desktop"`, which the mac relay seat answers with `Unknown app: desktop`. Note `adom/adom-desktop` 301s onto `adom/adom-bridge`, so the retired alias lands on the Windows line too.++  ⚠ **Known schema gap — a bridge that ships to BOTH lines cannot express this today.** `dependencies` is a single flat map with no platform keys, so there is no value that is correct for Windows and macOS at once; whichever you pick is wrong for the other line's users. Until the registry supports platform-keyed deps, the supported answer is **publish a separate per-platform package** (`…-bridge` and `…-bridge-macos`), each declaring its own line's dependency. Do NOT "split the difference" with a range that matches neither.++  **Who actually has one (verified against the registry 2026-09-17):** `adom/adom-bridge-macos` (1.9.209), `adom/fusion-bridge-macos` (1.8.5), `adom/adom-browser-extension-macos` (1.0.3) and `adom/hydrogen-macos` (0.1.419) each have their own package. **KiCad is the outstanding instance and the reason this gap is not academic:** the mac line has its own *manifest*, but no package — `adom/kicad-bridge-macos` does not exist, so it still rides John's shared `adom/kicad-bridge` (1.0.142) skills pkg, and *that* is precisely why its `adom/adom-bridge` dependency cannot be scoped to a platform. An earlier revision of this skill claimed kicad already did the per-platform split; it does not (corrected after KICAD checked the registry). Tracking the real fix — a `platformDependencies` sibling map merged over `dependencies` for the resolved platform — at **adom/adom-wiki-cli#58**. - **Each sub-skill's body opens with a `Parent skill:` line** (first line after the frontmatter): `Parent skill: **adom-bridge-<bridge>-bridge**`. - **List every user-skill path EXPLICITLY — no globs — in `package.json` `files[]` AND `install.sh`/`uninstall.sh`** (one `install_skill <dest> <src>` line each, kept in sync). The publish linter REQUIRES explicit listing. (The old "use `skills/**`" advice is dead.)  ```bash # Stage dir: ROOT SKILL.md + skills/<name>/SKILL.md per USER skill (dev/publish stay in the repo), # package.json {name:"adom-bridge-<bridge>-bridge", version, discovery_triggers,-#               dependencies:{"adom/adom-bridge":"^1.9.x"},+#               dependencies:{"adom/adom-bridge-macos":"^1.9.x"},   # mac line; Windows bridges: {"adom/adom-bridge":"^2.1.x"} — see the table above #               files:[ every USER-skill path, explicitly ], scripts:{install,uninstall}}. # TWO traps that still bite — verify each with `tar tzf` before publishing: #  1. ⚠ pkg pack/publish HONORS the stage dir's .gitignore — a gitignored skills/ ships
skills/adom-bridge-direct-api/SKILL.md+10
@@ -5,6 +5,16 @@ description: Direct HTTP API on the Adom Bridge app. Use when authoring a siblin  # Direct HTTP API: discover via `~/.adom/direct-api-port` +> **`output` is a JSON *string*, not an object.** `POST /command` answers+> `{success, output, error, ...}` where `output` is the verb's JSON payload+> serialized as a string (the relay envelope's shape, kept for Hydrogen). Parse+> it before reading `data.windows`, `peers`, `files`, etc. Two agents in two+> days (NB 2026-10-14, FUSION 2026-10-15) read the top level, found nothing,+> and reported "desktop_list_windows returns 0 windows" against a bridge that+> was returning 22-26 rows. If your reader sees `success: true` and no rows,+> check that it unwrapped `output` first.++ > **Port is not guaranteed fixed.** Adom Bridge's direct API binds `127.0.0.1:47200` when it can, and falls back (range walk, then an OS-assigned ephemeral port) when that port is unavailable. **Sibling apps MUST read the discovery file** `~/.adom/direct-api-port` (single-line `host:port`, e.g. `127.0.0.1:47200`) before any hardcoded probe. The legacy 47200..47209 scan stays as a back-compat fallback.  Sibling apps running on the same Mac as Adom Bridge can POST JSON commands directly into the running app process: no CLI process spawn, no WebSocket relay, no auth-token dance. The endpoint lives inside the app itself (loopback-only `127.0.0.1` bind, can't be reached off-box), uses the same dispatcher as the WebSocket path, and returns the same JSON shape, including every `_hint` field, that `adom-bridge <verb>` returns from the CLI.
skills/adom-bridge-macos/SKILL.md+36
@@ -277,6 +277,8 @@ adom-bridge --target all hydrogen_status        # every box at once, results key  **No-target behavior:** with exactly ONE Bridge connected, no `--target` is needed (back-compat). With MULTIPLE connected and no `--target`, the call FAILS with `{error:"ambiguous_target", connected:[...], _hint}` (exit 1) - it won't guess which box. A bad name → `{error:"target_not_found", requested, connected:[...]}` (exit 1). Set each Bridge's name with the `--client-name <name>` launch flag (Hydrogen passes this when spawning the embedded Bridge), the Settings field, or `config.json` `client_name`. Full design + the relay-routing internals: [`skills/MULTI_AD_ADDRESSING.md`](MULTI_AD_ADDRESSING.md). +**1.9.219 - the Adom Mesh on macOS.** `--target <name>` now tries the **mesh** first (end-to-end encrypted QUIC between the two boxes' node keys, carried through the Adom mesh relay across networks) and falls back to the cloud command relay; a mesh answer carries `route.via:"mesh"`. Off by default; `desktop_mesh_set_mode {"mode":"relay"}` turns it on. Verbs: `desktop_mesh_status`, `desktop_mesh_peers`, `desktop_mesh_trust` (list/raise/revoke/deny, never approve), `desktop_mesh_set_mode`, `desktop_mesh_pull_files`. A Mac and a Windows Bridge (2.1.40+) of the same account are peers. **1.9.224:** the Mesh view, the MESH JOIN card and Settings > Adom Mesh are in Bridge's own window (`desktop_ui_panel {"panel":"mesh","action":"show"}` raises it), and the cross-box permission mirror is on: a prompt raised on any of the user's boxes shows on every other one, decided with a one-shot nonce. What is and is not ported, and what the tests proved: [`skills/MESH.md`](MESH.md).+ #### Direct HTTP API for sibling apps (v1.8.25+)  If you're authoring a sibling Tauri app on the same machine (Adom Hydrogen, or any future "Adom-family" app), you can skip the CLI binary entirely and POST commands straight into the running adom-bridge GUI on `127.0.0.1:47200` (was `127.0.0.1:8770` through v1.8.32 - moved to be a better neighbor to Hydrogen on 47080+ and avoid the 8000-range collision risk). The endpoint runs inside the GUI process (loopback-only bind), uses the same dispatcher the WS path uses, and returns the same JSON shape as `adom-bridge <verb>` - including every `_hint` field.@@ -2029,3 +2031,37 @@ adom-bridge wiki_exec '{"args":["repo","push","adom/my-board","--files","board.k - Container-side publishing of the CONTAINER's own files still uses your local `adom-wiki` directly; `wiki_exec` is for files that live on the Mac.  Note (v1.9.117): Bridge's Settings panel no longer has a KiCad section - bridges own their app-specific config (Bridge stays generic). `kicad_library_paths` / `project_watch` keep working from `~/.adom/config.json` and the `set_project_watch` / `trigger_project_watch` verbs.++### The project watcher (Bridge core owns this - bridges implement nothing)++**This section is the AUTHORITATIVE shape, and external manifests point AT IT BY NAME**+(the kicad bridge's `bridge.json` names this file + the heading "project watcher", at file+level rather than by line so it survives edits). So: renaming this heading or moving it to+another file breaks a pointer you cannot see from this repo. Retitle deliberately, and if you+do, say so on the agent bus — the whole point of the arrangement is that only ONE copy of+this fact exists, which makes the pointer load-bearing.++A bridge's `bridge.json` should POINT here, never transcribe it: a copied struct in a discovery manifest cannot be noticed when it+drifts (KICAD declined to copy it for exactly that reason, 2026-09-17). Source of truth is+`ProjectWatchConfig` in `src-tauri/src/state.rs`; the loop is `src-tauri/src/project_watch.rs`.++Config key `project_watch` in `~/.adom/config.json`:++| Field | Type | Default | Meaning |+| --- | --- | --- | --- |+| `enabled` | bool | - | watcher on/off |+| `project_path` | string | - | directory watched (recursively) |+| `poll_interval_secs` | u64 | `2` | filesystem poll cadence |+| `debounce_secs` | u64 | `1` | quiet period before a change is reported |++Verbs: **`set_project_watch`** (writes the config + starts/stops the loop) and+**`trigger_project_watch`** (forces an immediate re-sync). Both are Tier-2 gated for relay+callers. A bridge does NOT implement either - Bridge core watches the files and pushes+updates, which is why the kicad bridge's tree contains no watcher code at all.++⚠ There is **no version/runtime floor in the bridge.json schema.** `BridgeSpawn`+(`bridge_registry.rs`) parses exactly `{kind, entrypoint, port, persistent, healthEndpoint,+stopMethod, killImageName}` - nothing else. A `python: ">=3.11"`-style field in a manifest is+human documentation and gates NOTHING; the interpreter is whatever `runtime_cache` resolves+(pinned managed Python, or a system one that reports a parseable version). Do not "fix" such+a field believing it constrains a spawn.