app
Adom Bridge
Public Made by Adomby adom
Adom Bridge unleashes your AI onto your full PC: full power, full safety. The AI breaks out of the container it runs in and onto your real machine, managing and running your entire laptop as you: launch apps, move files, drive any window, control KiCad, Fusion 360 or your real signed-in browser. Works with any AI, cloud or local (Claude Desktop, Claude Code, Codex), no Hydrogen required. Bridge and its bridges are an operating system for AI, with managed Node and Python runtimes, and a human-onl
← Commit history
VERBS.md+16−16@@ -11,14 +11,14 @@ There are three transports; all three dispatch through the same code (`commands: | Transport | Who uses it | Shape | |---|---|---| | **CLI** | Humans; cloud AIs on a Docker container | `adom-desktop <verb> '<json args>'` — e.g. `adom-desktop desktop_screenshot_screen`, `adom-desktop kicad_open_board '{"filePath":"C:/x.kicad_pcb"}'` |-| **Direct API** (loopback) | HD + sibling Tauri apps on the same box | `POST http://127.0.0.1:47200/command` with `{command, args, target?}` — loopback-only, can't be reached off-box |+| **Direct API** (loopback) | Hydrogen + sibling Tauri apps on the same box | `POST http://127.0.0.1:47200/command` with `{command, args, target?}` — loopback-only, can't be reached off-box | | **Relay** (WebSocket) | Cloud AIs reaching a Windows laptop cross-machine | The CLI's `desktop_command` path over `wss://…/proxy/8765/` | ### The `{app, command, args}` envelope Every dispatch carries an optional `app` namespace, a `command` (the verb), and `args`. -- **`app` is OPTIONAL as of v1.9.84** — it's inferred from the command: `kicad_*`→`kicad`, `fusion_*`→`fusion360`, `browser_*`→`browser`, `hd_*`→`hd`, `aps_*`→`aps`, any installed bridge's prefix→`dynamic`, otherwise `desktop`. Pass `app` explicitly only to override the inference.+- **`app` is OPTIONAL as of v1.9.84** — it's inferred from the command: `kicad_*`→`kicad`, `fusion_*`→`fusion360`, `browser_*`→`browser`, `hd_*`→`hydrogen`, `aps_*`→`aps`, any installed bridge's prefix→`dynamic`, otherwise `desktop`. Pass `app` explicitly only to override the inference. - **Desktop verbs**: the `desktop_` prefix is optional (`desktop_taskbar` == `taskbar`). - **Bundled-bridge verbs** carry their prefix on the CLI (`kicad_*`, `fusion_*`, `browser_*`). Internally the direct API strips kicad/fusion prefixes but keeps browser's — the CLI verb name is what you use. - **Third-party bridge verbs** route via `{app:"dynamic", command:"<full verb>"}` — see `bridge_list` for what's installed.@@ -29,7 +29,7 @@ One relay can hold several ADs (a laptop + an Azure VM …). Address one with th ### Approval gating (relay callers only) -Verbs that execute an arbitrary exe / write / delete / drive input / touch the registry are **gated for RELAY (cloud-AI) callers** — allowed only with a human "auto-approve shell" grant. HD and other loopback/local callers are trusted by transport and never gated. The Tier-2 gated set: `shell_execute`, `run_script`, the `wsl_*` exec verbs, `launch_process`, `write_file`, `delete_file`, `registry_set`, `registry_delete`, `process_kill`, and the SendInput/UIA action verbs (`desktop_click`, `desktop_type`, `desktop_ui_*` action verbs, …). Read verbs (`list_dir`, `read_file`, `registry_get`, `process_list`, `net_stats`, `desktop_ui_tree`, …) stay ungated.+Verbs that execute an arbitrary exe / write / delete / drive input / touch the registry are **gated for RELAY (cloud-AI) callers** — allowed only with a human "auto-approve shell" grant. Hydrogen and other loopback/local callers are trusted by transport and never gated. The Tier-2 gated set: `shell_execute`, `run_script`, the `wsl_*` exec verbs, `launch_process`, `write_file`, `delete_file`, `registry_set`, `registry_delete`, `process_kill`, and the SendInput/UIA action verbs (`desktop_click`, `desktop_type`, `desktop_ui_*` action verbs, …). Read verbs (`list_dir`, `read_file`, `registry_get`, `process_list`, `net_stats`, `desktop_ui_tree`, …) stay ungated. --- @@ -61,11 +61,11 @@ Verbs that execute an arbitrary exe / write / delete / drive input / touch the r | Verb | What it does | Key args | |---|---|---|-| `desktop_window_show` | Show + focus AD's main window (HD's tray "Open Adom Desktop"). | — |+| `desktop_window_show` | Show + focus AD's main window (Hydrogen's tray "Open Adom Desktop"). | — | | `desktop_window_hide` | Hide AD's main window; app keeps running. | — | | `desktop_shutdown` | Graceful AD exit — stop bridges then exit (~500ms after the response). | — | | `desktop_logout` | Clear AD's cached Adom Cloud session. | — |-| `desktop_embedded_status` | Is AD running embedded under HD; how it entered (`launch-flag` vs `runtime-adopt`). | — |+| `desktop_embedded_status` | Is AD running embedded under Hydrogen; how it entered (`launch-flag` vs `runtime-adopt`). | — | | `desktop_embedded_enter` | Runtime-adopt: switch a running standalone AD into embedded mode. | — | | `desktop_embedded_release` | Revert to standalone (AD keeps running). | — | | `relaunch_self` | Visible self-restart for dev iter — spawns `ad-relauncher.exe` (stop→deploy→launch→verify). | `sourceExe`, `destExe`, `port`, `noAutoStart` |@@ -210,7 +210,7 @@ These stream binary/base64 and are refused by the direct API (`errorCode:"cli_re |---|---|---| | `send_files` | Send files from a container to the desktop (Downloads, or `dest`). Up to ~190 MB/batch. | `filePaths`*, `targetApp`, `destinationFolder`, `dest` | | `pull_file` | Pull files from the desktop back to the container (1 MiB binary frames, sha256-verified). Honors `--target`. | `filePaths`*, `saveTo` |-| `hd_send_files` | Send files DIRECTLY into HD's WSL2 project (correct ownership + no /mnt/c cache-lag). | `filePaths`*, `subdir` |+| `hd_send_files` | Send files DIRECTLY into Hydrogen's WSL2 project (correct ownership + no /mnt/c cache-lag). | `filePaths`*, `subdir` | ## Bridges — lifecycle & management @@ -399,25 +399,25 @@ Drives PUPPETEER-controlled Chrome for Testing (isolated profile, no saved login ## Adom Hydrogen (`hd_*`) -Built-in proxy handlers to HD's local control API (port discovered from `ports.json`, never hardcoded). When HD isn't running, these return a clean `{ok:false, error:"HD not running"}`.+Built-in proxy handlers to Hydrogen's local control API (port discovered from `ports.json`, never hardcoded). When Hydrogen isn't running, these return a clean `{ok:false, error:"Hydrogen not running"}`. | Verb | What it does | Key args | |---|---|---| | `hd_status` | Composed + relayed snapshot: `processPresent` / `controlApiReachable` / `embedded` (three orthogonal signals, churn-honest) + SHAs + narrative. | — |-| `hd_api` | Generic HTTP pass-through to any HD control endpoint (auto-discovers the port). | `method`, `path`*, `body`, `port` |-| `hd_log` | Tail HD's log file from disk (works even when HD is down). | `tail` |-| `hd_open_url` | Open a URL in a specific browser profile via HD's endpoint. | `url`*, `browser`, `profileDir` |-| `hd_browser_profiles` | Enumerate browsers + profiles HD detects. | — |-| `hd_screenshot` | Capture the HD window as a lossless PNG. | — |-| `hd_build` | Full HD rebuild (async: git pull → pnpm → cargo). Returns `{pid, logPath}`. | `show`, `lingerSecs` |-| `hd_build_frontend` / `hd_build_rust` | Frontend-only / Rust-only HD build (async). | `show`, `lingerSecs` |+| `hd_api` | Generic HTTP pass-through to any Hydrogen control endpoint (auto-discovers the port). | `method`, `path`*, `body`, `port` |+| `hd_log` | Tail Hydrogen's log file from disk (works even when Hydrogen is down). | `tail` |+| `hd_open_url` | Open a URL in a specific browser profile via Hydrogen's endpoint. | `url`*, `browser`, `profileDir` |+| `hd_browser_profiles` | Enumerate browsers + profiles Hydrogen detects. | — |+| `hd_screenshot` | Capture the Hydrogen window as a lossless PNG. | — |+| `hd_build` | Full Hydrogen rebuild (async: git pull → pnpm → cargo). Returns `{pid, logPath}`. | `show`, `lingerSecs` |+| `hd_build_frontend` / `hd_build_rust` | Frontend-only / Rust-only Hydrogen build (async). | `show`, `lingerSecs` | | `hd_build_status` | Sync build-state probe (compiledCrates, relinkOnly, exeChanged, exeLocked+holderPids …). | — | | `hd_build_log` / `hd_build_tail` | Full build log / streaming tail (`offset`→`newOffset`). | (`tail`: `offset`) |-| `hd_launch` | Start HD's debug binary detached (guards: build_in_progress / build_failed / already_running). | `killExisting` |+| `hd_launch` | Start Hydrogen's debug binary detached (guards: build_in_progress / build_failed / already_running). | `killExisting` | | `hd_stop` | Kill adom-hydrogen.exe (`wasRunning` distinguishes killed vs nothing-to-do). | — | | `hd_restart` | Stop + launch in one call. | — | | `hd_ship` | Atomic "rebuild from the exact SHA I pushed + relaunch + verify it's running". | `expectSha`*, `clean` |-| `hd_shot` | Capture a named HD region (titlebar/vscode/setup-panel/…) → full + safe PNG, auto-pulled. | `region`*, `resizeMax`, `format` |+| `hd_shot` | Capture a named Hydrogen region (titlebar/vscode/setup-panel/…) → full + safe PNG, auto-pulled. | `region`*, `resizeMax`, `format` | *Moved to the internal hd-dev build (public AD refuses with `verb_moved_to_hd_dev`, use `hd_api` as the workaround): `hd_eval`, `hd_iframe_eval`, `hd_reload_vscode`, `hd_container_exec`.*