← Commit history

Delete skills/adom-desktop-embedded

Kyle Bergstedt ·57fcd2bd26 ·2mo ago ·parent b721dcb
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.