app
Adom Bridge (macOS)
Public Made by Adomby adom
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.
← Commit history
Delete skills/adom-desktop-embedded
2 files changed
−159
skills/adom-desktop-embedded/._SKILL.mddeleted⋯ 1 unchanged line ⋯
skills/adom-desktop-embedded/SKILL.mddeleted−159@@ -1,159 +0,0 @@-name: adom-desktop-embedded-description: Adom Bridge's EMBEDDED mode under Adom Hydrogen - what it means when Hydrogen owns Bridge, the lifecycle contract (Bridge stays up; exit when Hydrogen exits is opt-in flag-only), embedded permissions (Hydrogen's auto_approve on /embedded/enter, forwarding gated commands to Hydrogen's /permission/request, status.permissions.shell.embeddedPolicy), inspecting Hydrogen with hd_status and the hd_ verb family, and the read-only Hydrogen-managed relay entry. Use when reasoning about embedded vs standalone behavior, why Bridge survived (or should survive) a Hydrogen crash, why a gated command is waiting on Hydrogen instead of showing a Bridge dialog, or how to drive/inspect Hydrogen from a cloud caller.--# Adom Bridge embedded mode (under Adom Hydrogen)--## What embedded mode is--Adom Hydrogen bundles the signed Adom Bridge installer, installs it, and at-runtime spawns Bridge as its child:--```-adom-desktop --embedded --start-hidden --relay-url ws://127.0.0.1:8765 --relay-name adom-hydrogen [--session-token <hydrogen token>]-```--Install locations on macOS: a Hydrogen-managed Bridge lives under-`~/Library/Application Support/adom/bridge/` (Hydrogen 0.1.238+); a-standalone install is `Adom Bridge.app` in `/Applications`. Either way the-bundle id is `inc.adom.desktop` and the CLI binary names are unchanged-(`adom-desktop` / `adom-desktop-cli`).--While embedded:--- Bridge's window is hidden and Bridge HIDES its menu-bar item; Hydrogen is- the app the human sees. With the window hidden, Bridge runs under the- Accessory activation policy, so there is no Dock icon and no Cmd-Tab- entry either. Bridge keeps serving everything (relay, direct API on- 127.0.0.1:47200, bridges) the whole time.-- Bridge writes an `embedded.json` marker (with `entered_via`) so a restart- re-embeds if Hydrogen is still alive.-- Hydrogen injects a relay-back server entry tagged `added_by:"hd-spawn"`- (see the read-only rule below).-- Sign-in is shared either way: one Adom sign-in serves both apps through a- shared keychain item, so an embedded Bridge is signed in whenever Hydrogen- is (and vice versa).--Entry paths: `POST /embedded/enter` on the direct API, or the `--embedded`-launch flag. Hydrogen polls `GET http://127.0.0.1:47200/health` after-spawning.--## The lifecycle contract (AD_LIFECYCLE.md, on one page)--1. **Bridge stays up.** It is the recovery channel for the machine: if- Bridge exited whenever Hydrogen exited, one bad Hydrogen exit would leave- the box unreachable to any remote agent (no log reads, no relaunch, no- rollback).-2. **The ONLY thing that exits Bridge is an explicit shutdown**:- `desktop_shutdown` / `POST /command {"command":"shutdown"}`, or the user- quitting Bridge themselves.-3. **"Embedded" is a display state, not a lifecycle.** Hydrogen gone means- Bridge drops the costume and reverts to a normal standalone menu-bar- agent.--What happens when Hydrogen goes away:--| How Hydrogen goes away | What Bridge does |-|---|---|-| Graceful: Hydrogen sends `POST /embedded/release` before stopping | Revert to standalone (menu-bar item back, relay preserved), regardless of how Bridge entered embedded. |-| Ungraceful: Hydrogen's GUI crashes or is killed, no release sent | The `embedded_monitor` (10s probes, 3-miss debounce, ~30s) notices and reverts to standalone. Same end state. |-| A kill takes Hydrogen's whole process tree | Bridge dies WITH Hydrogen because it is Hydrogen's direct child process. This is the OS killing a child, NOT a lifecycle rule firing. Check for the tree-kill before blaming any Bridge logic. |--Reverting (`revert_to_standalone`) shows the menu-bar item again and keeps-the WS connection and the hd-spawn server entry; the supervisor reconnects-with backoff, so a remote caller sees `status=reconnecting`, never a-vanished row (Hydrogen's relay can outlive Hydrogen's GUI).--**Exit-with-Hydrogen is opt-in, flag-only (v1.9.165).** The only way to make-Bridge disposable is the spawner passing `--exit-when-hd-exits` on the-command line. Hydrogen does not pass it, so in practice Bridge always-survives. There is no config key (the old `config.exit_when_hd_exits` is-inert) and no Settings checkbox. The one flag-gated exit lives in-`embedded_monitor::transition_to_standalone`.--Forensics: both transitions write to `startup.log` (`EXIT:` / `REVERT:`-lines). No `crash.log` plus a `startup.log` that runs to `===` means it was-not a panic; an absent process with no crash.log is the signature of an-external (tree) kill.--## Embedded permissions: Hydrogen owns the prompt--Hydrogen sends `auto_approve` in `POST /embedded/enter`; it is authoritative:--- **absent**: Bridge keeps standalone behavior (older Hydrogen; the feature- is inert until Hydrogen opts in).-- **`false`** (the new-contract default): Bridge does NOT auto-approve and- shows no UI of its own. For each gated command from a remote relay caller,- Bridge FORWARDS the request to Hydrogen's `POST /permission/request`- (control port discovered fresh from Hydrogen's ports.json each call,- blocking up to 180s) and applies Hydrogen's decision: `allow_once`,- `allow_1h`, `allow_24h`, `bypass_while_running`, or `deny` (refused with- `errorCode:denied_by_user`; do not auto-retry). `auto_approve:false`- overrides any standing grant (the `--shell-approval` flag, Settings- checkbox, or timer) for relay callers, so the forward always triggers; a- forwarded allow_1h/24h/bypass sets a dedicated grant window that is- honored without re-forwarding.-- **`true`**: auto-approve (the user explicitly opted in); behaves like a- standing grant.--Fail-safe: if Hydrogen is unreachable, Bridge falls back to its OWN approval-dialog (the window summons itself from the menu bar; never hard-deny, never-silent-approve). Coverage runs through one chokepoint-(`consult_embedded_gate`): `shell_execute`, `run_script`, and the Tier-2-class (`launch_process`, `wiki_exec`, `write_file`, `delete_file`,-`process_kill`). Gated verbs accept a `reason` arg that is shown verbatim-(attributed as "The AI says:") on Hydrogen's modal and Bridge's dialog. Only-remote relay callers are gated; local callers (CLI, Hydrogen, bridges) are-trusted by transport.--**Discoverability:** `status.permissions.shell.embeddedPolicy` reports-`"standalone"` | `"forward-to-hd"` | `"auto-approve"`. If a gated call seems-to hang while embedded, a human is likely looking at Hydrogen's prompt; poll-rather than re-issue.--## Inspecting state: hd_status's three orthogonal signals--Hydrogen is killed and respawned many times a day (upgrades, restarts), often-onto a different control port. `hd_status` therefore never collapses its view-into one boolean; it reports THREE independent signals:--- `processPresent`: a process-list check (ps/pgrep on macOS), sampled with- retry to ride the ~1s kill-then-respawn gap.-- `controlApiReachable`: TCP to Hydrogen's control port, discovered fresh per- call (ports.json, never cached or hardcoded).-- `embedded`: Bridge's own state (its `AppState` / embedded marker).--`running = processPresent || controlApiReachable`. A mismatch between the-three is normal mid-churn; do not treat a single snapshot as Hydrogen being-dead (Bridge itself requires 3 consecutive misses over ~30s before leaving-embedded mode).--## The hd_* verb family--Bridge exposes `hd_*` verbs for driving and observing Hydrogen itself-(`hd_status`, `hd_stop` / `hd_restart`, `hd_send_files`). Architectural rule:-Bridge owns host/process facts (process present, install path); anything-about Hydrogen's OWN runtime state is fetched from Hydrogen's control API-endpoints (`GET /health`, `GET /buildinfo`, `GET /workspace/health`) and-relayed verbatim. The Hydrogen BUILD verbs (`hd_ship`, `hd_build_*`) are part-of the Windows dev pipeline and return a clean "not supported on macOS yet"-error on this fork.--Updates while embedded follow the same split: Bridge checks, downloads,-verifies and STAGES its own update (`GET /update/status` shows-`update_ready:true` when staged); Hydrogen owns the apply timing and triggers-`POST /update/apply`. Embedded Bridge never auto-applies.--## The Hydrogen-managed relay entry is READ-ONLY--The server entry Hydrogen injects at spawn is tagged `added_by == "hd-spawn"`-and is ephemeral (stripped on config persist, re-added each Hydrogen launch).-While embedded it cannot be disconnected, edited, or removed; the backend-refuses (`is_hd_managed` guard plus `HD_MANAGED_REFUSAL`) on-`disconnect_server`, `remove_server`, `update_server`, the upsert branch of-`add_server`, and the relay `server_add` / `server_remove` handlers, because-any of those would break the embedded session. The UI shows it as a "Managed-by HD" row with a locked note instead of editable fields. Do not try to work-around the refusal; the entry is torn down automatically when Bridge reverts-to standalone.