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
Cache-bust all freshened images to -v2 names (in-place /files blobs were cache-shadowing the old versions in README embeds): arch-flow, core-vs-bridge, settings, 4 toasts
8 files changed
+264−7
README.md+7−7@@ -14,7 +14,7 @@ ## How it works -+ The cloud AI never touches your machine directly. It sends a verb to the **relay**; Adom Bridge, connected out to that relay from your desktop, executes it against Windows or forwards it to a bridge, and streams the result back. A co-resident sibling app (Hydrogen) can skip the relay and POST straight to the **loopback HTTP API** at `127.0.0.1`. @@ -189,7 +189,7 @@ These verbs inspect any icon you pass and return an `iconCheck` that explains, i ## Settings -<img src="docs/settings.png" alt="Settings" width="780">+<img src="docs/settings-v2.png" alt="Settings" width="780"> Auto-connect behavior, the update channel (**prompt** / auto / off) and *restart when idle to finish updates*, the shell-approval preference, Hydrogen integration (including *exit when Hydrogen exits*), and runtime prewarming. While embedded in Hydrogen, Hydrogen-owned preferences show as *managed by Hydrogen*. @@ -209,7 +209,7 @@ Adom Bridge speaks to you through native Windows toasts via `notify_user`, under **Basic alert.** Awareness: a build finished, a file is ready. Auto-dismisses in about 7 seconds. Add `"durationLong":true` to hold it around 25 seconds; `"level":"error"` and up do that automatically, and `"emergency"` also flashes the taskbar. -+ ```bash adom-bridge-cli notify_user '{"title":"Export done","body":"gerbers.zip is ready in C:/exports."}'@@ -225,7 +225,7 @@ The response says whether the target resolved, so the AI finds out at send time **Sticky choice with buttons that round-trip.** Stays on screen until the user clicks (no auto-dismiss). Give it an `id` you choose, then read the click back. -+ ```bash adom-bridge-cli notify_user '{"id":"deploy-42","title":"Ship v2 to production?","body":"The build is green and staged.","scenario":"reminder","buttons":[{"label":"Ship it"},{"label":"Hold"}]}'@@ -233,7 +233,7 @@ adom-bridge-cli notify_user '{"id":"deploy-42","title":"Ship v2 to production?", **Progress bar.** For a long job (a gerber export, a render). Re-fire with the SAME `id` as the job advances toward `1.0`. `body` is optional here. -+ ```bash adom-bridge-cli notify_user '{"id":"job-1","title":"Exporting gerbers","progress":{"title":"myboard.kicad_pcb","value":0.6,"status":"Plotting copper layers...","valueOverride":"6 / 10 layers"}}'@@ -241,7 +241,7 @@ adom-bridge-cli notify_user '{"id":"job-1","title":"Exporting gerbers","progress **Reply input.** The text field renders, but Windows does not return typed text over protocol activation, so it is display-only today. For a real choice, use buttons. -+ ```bash adom-bridge-cli notify_user '{"title":"Quick note","body":"Leave a note for the next run.","scenario":"reminder","inputs":[{"id":"reply","type":"text","placeholder":"Type a reply..."}],"buttons":[{"label":"Send"}]}'@@ -269,7 +269,7 @@ Deep dive: [notifications](docs/notifications.md). ## Verbs -+ Adom Bridge core owns the generic verbs (`desktop_*`, `shell`, `ui_*`, files, `notify_user`, multi-machine). Each bridge owns its own prefix and ships its own verbs; the app relays them verbatim and stays generic. Invoke the same way on every transport, for identical JSON back:
docs/arch-flow-v2.svgadded+161@@ -0,0 +1,161 @@+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1120 1440" font-family="'Familjen Grotesk','Satoshi',-apple-system,'Segoe UI',sans-serif">+ <defs>+ <marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">+ <path d="M0 0 L10 5 L0 10 z" fill="#2dd4bf"/>+ </marker>+ <marker id="arrUp" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">+ <path d="M0 0 L10 5 L0 10 z" fill="#64748b"/>+ </marker>+ <style>+ .box{rx:14;stroke-width:1.5}+ .h{fill:#e2e8f0;font-weight:700}+ .t{fill:#94a3b8;font-size:14px}+ .mono{font-family:'JetBrains Mono',ui-monospace,monospace;fill:#5eead4;font-size:12.5px}+ .lbl{fill:#64748b;font-size:12px;font-style:italic}+ .tier{fill:#2dd4bf;font-size:12px;font-weight:700;letter-spacing:2px}+ </style>+ </defs>++ <rect x="0" y="0" width="1120" height="1440" fill="#0b0f14"/>+ <text x="560" y="46" text-anchor="middle" class="h" font-size="26">Adom Bridge — how it works</text>+ <text x="560" y="72" text-anchor="middle" class="t">One local bridge between Adom's cloud AI and your Windows machine · v2.0.7</text>++ <!-- TIER 1: CLOUD -->+ <rect x="360" y="100" width="400" height="72" rx="14" fill="#0e1a2b" stroke="#1e3a5f"/>+ <text x="560" y="132" text-anchor="middle" class="h" font-size="16">Adom Cloud — Claude Code / AI</text>+ <text x="560" y="154" text-anchor="middle" class="t">runs in your local container: WSL2 (Windows) / Lima (macOS) via Hydrogen — Docker cloud later</text>++ <!-- arrow 1->2 -->+ <line x1="560" y1="172" x2="560" y2="212" stroke="#2dd4bf" stroke-width="2" marker-end="url(#arr)"/>+ <line x1="600" y1="212" x2="600" y2="172" stroke="#64748b" stroke-width="1.3" marker-end="url(#arrUp)"/>+ <text x="620" y="196" class="lbl">commands, files, notifications ⇅ results</text>++ <!-- TIER 2: RELAY -->+ <rect x="300" y="216" width="520" height="86" rx="14" fill="#101826" stroke="#334155"/>+ <text x="560" y="246" text-anchor="middle" class="h" font-size="16">Adom Relay · Hydrogen-managed (local) or cloud (e.g. galliaApril)</text>+ <text x="560" y="268" text-anchor="middle" class="t">routes by <tspan class="mono">clientName</tspan> — one relay ⇄ many desktops</text>+ <text x="560" y="288" text-anchor="middle" class="mono">--target <name> · --target all · ambiguous_target guard</text>++ <!-- arrow 2->3 -->+ <line x1="560" y1="302" x2="560" y2="344" stroke="#2dd4bf" stroke-width="2" marker-end="url(#arr)"/>+ <text x="580" y="328" class="lbl">WebSocket wss:// (auth: clientName + token, 15s keepalive)</text>++ <!-- TIER 3: ADOM BRIDGE -->+ <rect x="40" y="348" width="1040" height="516" rx="18" fill="#0d1420" stroke="#2dd4bf" stroke-width="2"/>+ <text x="64" y="384" class="h" font-size="19">ADOM BRIDGE</text>+ <text x="235" y="384" class="t">Tauri v2 · Rust · signed · runs in your tray</text>++ <!-- INBOUND column -->+ <text x="70" y="420" class="tier">▸ WHAT CONNECTS TO BRIDGE</text>+ <g>+ <rect x="70" y="432" width="470" height="70" rx="10" fill="#111c2e" stroke="#1e3a5f"/>+ <text x="86" y="458" class="h" font-size="14">Relay WS client</text>+ <text x="86" y="480" class="t">the cloud path — ws_client.rs, auto-reconnect <5s</text>+ <text x="86" y="496" class="mono">wss:// → relay → cloud AI</text>++ <rect x="70" y="510" width="470" height="70" rx="10" fill="#111c2e" stroke="#1e3a5f"/>+ <text x="86" y="536" class="h" font-size="14">Direct HTTP API</text>+ <text x="86" y="558" class="t">sibling apps (Hydrogen) + the CLI's auto-route</text>+ <text x="86" y="574" class="mono">127.0.0.1:47200 (host.docker.internal:47200 from Hydrogen's container)</text>++ <rect x="70" y="588" width="470" height="70" rx="10" fill="#111c2e" stroke="#1e3a5f"/>+ <text x="86" y="614" class="h" font-size="14">Control API — sugar routes</text>+ <text x="86" y="636" class="t">Hydrogen drives embedded mode + Bridge's auto-update</text>+ <text x="86" y="652" class="mono">POST /embedded/enter·release /update/status·check·apply</text>++ <rect x="70" y="666" width="470" height="70" rx="10" fill="#111c2e" stroke="#1e3a5f"/>+ <text x="86" y="692" class="h" font-size="14">TCP tunnels + RDP</text>+ <text x="86" y="714" class="t">reach a cloud-only service through the laptop</text>+ <text x="86" y="730" class="mono">127.0.0.1:<port> ⇄ relay ⇄ upstream · tunnel open|rdp</text>+ </g>++ <!-- OUTBOUND column -->+ <text x="586" y="420" class="tier">▸ WHAT BRIDGE DRIVES</text>+ <g>+ <rect x="586" y="432" width="470" height="150" rx="10" fill="#0f1d1a" stroke="#134e4a"/>+ <text x="602" y="458" class="h" font-size="14">Your Windows OS · core verbs</text>+ <text x="602" y="482" class="mono">shell / run_script / wsl_exec</text>+ <text x="602" y="502" class="mono">send_files · pull_file</text>+ <text x="602" y="522" class="mono">screenshot_window · screenshot_screen</text>+ <text x="602" y="542" class="mono">ui_click · click · type · press_key (UIA + SendInput)</text>+ <text x="602" y="562" class="mono">notify_user (toasts) · tray · caption · taskbar</text>++ <rect x="586" y="590" width="470" height="68" rx="10" fill="#0f1d1a" stroke="#134e4a"/>+ <text x="602" y="616" class="h" font-size="14">Managed runtimes · no UAC, no firewall</text>+ <text x="602" y="638" class="t">Bridge provisions Node + Python for bridges</text>+ <text x="602" y="654" class="mono">system-first, else portable download → ~/.adom/adom-runtimes</text>++ <rect x="586" y="666" width="470" height="70" rx="10" fill="#0f1d1a" stroke="#134e4a"/>+ <text x="602" y="692" class="h" font-size="14">Bridges · spawned children</text>+ <text x="602" y="714" class="t">routed by verb prefix — HTTP on a stable internal port</text>+ <text x="602" y="730" class="mono">127.0.0.1:<ephemeral> · ADOM_BIND_HOST=127.0.0.1</text>+ </g>++ <!-- arrow 3->4 -->+ <line x1="820" y1="736" x2="820" y2="792" stroke="#2dd4bf" stroke-width="2" marker-end="url(#arr)"/>+ <text x="840" y="770" class="lbl">spawns + supervises · stable port · auto-update from the wiki</text>++ <!-- TIER 4: BRIDGES -->+ <text x="70" y="912" class="tier">▸ BRIDGES (each ships its own verbs; see the core-vs-bridge diagram)</text>+ <g font-size="13">+ <!-- pup -->+ <rect x="40" y="928" width="200" height="118" rx="12" fill="#101826" stroke="#334155"/>+ <text x="58" y="954" class="h">pup</text>+ <text x="58" y="974" class="t">Node · cloud-owned</text>+ <text x="58" y="996" class="t" font-size="12">drives a fresh</text>+ <text x="58" y="1012" class="t" font-size="12">automation browser</text>+ <text x="58" y="1034" class="mono" font-size="11">pup_*</text>++ <!-- kicad -->+ <rect x="256" y="928" width="200" height="118" rx="12" fill="#101826" stroke="#334155"/>+ <text x="274" y="954" class="h">KiCad</text>+ <text x="274" y="974" class="t">Python · cloud-owned</text>+ <text x="274" y="996" class="t" font-size="12">7/8/9/10 side-by-side</text>+ <text x="274" y="1012" class="t" font-size="12">EDA automation</text>+ <text x="274" y="1034" class="mono" font-size="11">kicad_*</text>++ <!-- fusion -->+ <rect x="472" y="928" width="200" height="118" rx="12" fill="#101826" stroke="#334155"/>+ <text x="490" y="954" class="h">Fusion 360</text>+ <text x="490" y="974" class="t">Python · cloud-owned</text>+ <text x="490" y="996" class="t" font-size="12">CAD + EAGLE PCB</text>+ <text x="490" y="1012" class="t" font-size="12">+ APS cloud search</text>+ <text x="490" y="1034" class="mono" font-size="11">fusion_* · aps_*</text>++ <!-- native-browser -->+ <rect x="688" y="928" width="200" height="118" rx="12" fill="#101826" stroke="#334155"/>+ <text x="706" y="954" class="h">Native browser (nb)</text>+ <text x="706" y="974" class="t">nbe extension · cloud-owned</text>+ <text x="706" y="996" class="t" font-size="12">your REAL Chrome/Edge</text>+ <text x="706" y="1012" class="t" font-size="12">— logged-in sessions</text>+ <text x="706" y="1034" class="mono" font-size="11">nbrowser_*</text>++ <!-- hd -->+ <rect x="904" y="928" width="176" height="118" rx="12" fill="#101826" stroke="#334155"/>+ <text x="922" y="954" class="h">Hydrogen</text>+ <text x="922" y="974" class="t">external-http</text>+ <text x="922" y="996" class="t" font-size="12">proxies Hydrogen's</text>+ <text x="922" y="1012" class="t" font-size="12">control API</text>+ <text x="922" y="1034" class="mono" font-size="11">hd_*</text>+ </g>+ <text x="40" y="1076" class="t" font-size="13">+ third-party bridges installed with <tspan class="mono">bridge_install {manifestUrl}</tspan> — same contract, auto-updated from their own wiki page.</text>++ <!-- ENDPOINTS LEGEND -->+ <rect x="40" y="1110" width="1040" height="290" rx="16" fill="#0d1420" stroke="#334155"/>+ <text x="64" y="1146" class="h" font-size="17">Exposed endpoints (all loopback / localhost only)</text>+ <g font-size="13">+ <text x="64" y="1182" class="mono" font-size="14">127.0.0.1:47200</text>+ <text x="330" y="1182" class="t">Direct HTTP API — <tspan class="mono" font-size="12">POST /command</tspan>, <tspan class="mono" font-size="12">GET /status</tspan>, <tspan class="mono" font-size="12">GET /ping</tspan>. Sibling apps + the CLI auto-route here.</text>+ <text x="64" y="1214" class="mono" font-size="14">127.0.0.1:47200</text>+ <text x="330" y="1214" class="t">Control sugar — <tspan class="mono" font-size="12">/embedded/enter·release</tspan>, <tspan class="mono" font-size="12">/update/status·check·apply</tspan>. Hydrogen drives these.</text>+ <text x="64" y="1246" class="mono" font-size="14">127.0.0.1:47210</text>+ <text x="330" y="1246" class="t">ad-relauncher HTTP — swap-binary-and-restart state (dev/update path).</text>+ <text x="64" y="1278" class="mono" font-size="14">127.0.0.1:<stable></text>+ <text x="330" y="1278" class="t">Per-bridge HTTP — internal, persisted to <tspan class="mono" font-size="12">~/.adom/bridge-ports.json</tspan>. Callers never touch it; go through verbs.</text>+ <text x="64" y="1310" class="mono" font-size="14">127.0.0.1:<dynamic></text>+ <text x="330" y="1310" class="t">Tunnel listeners — one per open tunnel; bytes pumped over the relay WS to a cloud-side upstream.</text>+ <text x="64" y="1342" class="mono" font-size="14">wss:// (outbound)</text>+ <text x="330" y="1342" class="t">Relay client — Bridge dials OUT to the cloud relay; nothing inbound from the internet. Discovery file: <tspan class="mono" font-size="12">~/.adom/direct-api-port</tspan>.</text>+ <text x="64" y="1378" class="lbl" font-size="12.5">Ports are picked ephemerally and written to discovery files — never hardcoded (Hyper-V/Docker silently reserve fixed ranges). See skills/PORTS.md.</text>+ </g>+</svg>
docs/core-vs-bridge-v2.svgadded+96@@ -0,0 +1,96 @@+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1120 900" font-family="'Familjen Grotesk','Satoshi',-apple-system,'Segoe UI',sans-serif">+ <defs>+ <marker id="a2" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">+ <path d="M0 0 L10 5 L0 10 z" fill="#2dd4bf"/>+ </marker>+ <style>+ .h{fill:#e2e8f0;font-weight:700}+ .t{fill:#94a3b8;font-size:13px}+ .mono{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12.5px}+ .tier{font-size:12px;font-weight:700;letter-spacing:2px}+ </style>+ </defs>+ <rect x="0" y="0" width="1120" height="900" fill="#0b0f14"/>+ <text x="560" y="46" text-anchor="middle" class="h" font-size="25">Core verbs vs bridge verbs — the line of demarcation</text>+ <text x="560" y="72" text-anchor="middle" class="t">Bridge OWNS + IMPLEMENTS core verbs. For bridge verbs, Bridge is a transparent RELAY — it routes by prefix and forwards args verbatim.</text>++ <!-- CORE side -->+ <rect x="40" y="100" width="480" height="710" rx="18" fill="#0f1d1a" stroke="#134e4a" stroke-width="2"/>+ <text x="64" y="138" class="tier" fill="#2dd4bf">▸ BRIDGE CORE (Bridge implements these)</text>+ <text x="64" y="162" class="t">Built into the Tauri app. Touch the OS directly. Gated verbs need shell-approval.</text>++ <g class="mono" fill="#5eead4">+ <text x="64" y="200" class="h" font-size="14" fill="#e2e8f0">Desktop / OS</text>+ <text x="64" y="224">desktop_list_windows · screenshot_window · screenshot_screen</text>+ <text x="64" y="246">desktop_click · type · press_key · hover · cursor (SendInput)</text>+ <text x="64" y="268">desktop_ui_click · ui_set · find_control · ui_tree (UIA)</text>+ <text x="64" y="290">desktop_open_url · open_folder · bring_to_front · find_window</text>+ <text x="64" y="312">caption · taskbar · flash_window · display</text>++ <text x="64" y="352" class="h" font-size="14" fill="#e2e8f0">Shell / scripts (gated)</text>+ <text x="64" y="376">shell_execute · run_script · wsl_exec · wsl_exec_async</text>+ <text x="64" y="398">wsl_recover · wsl_import · wsl_export · wsl_list</text>++ <text x="64" y="438" class="h" font-size="14" fill="#e2e8f0">Files</text>+ <text x="64" y="462">send_files · pull_file</text>++ <text x="64" y="502" class="h" font-size="14" fill="#e2e8f0">Notify / approvals</text>+ <text x="64" y="526">notify_user · notify_response · shell_auto_approve · revoke_approvals</text>++ <text x="64" y="566" class="h" font-size="14" fill="#e2e8f0">Connectivity</text>+ <text x="64" y="590">server_add · server_list · targets · tunnel (open|rdp|check)</text>++ <text x="64" y="630" class="h" font-size="14" fill="#e2e8f0">Bridge lifecycle (Bridge manages the bridges)</text>+ <text x="64" y="654">bridge_install · bridge_list · bridge_info · bridge_kill</text>+ <text x="64" y="676">refresh_bridges · bridge_check_updates · restart_bridge · runtimes</text>++ <text x="64" y="716" class="h" font-size="14" fill="#e2e8f0">Sibling apps</text>+ <text x="64" y="740">aps_* (Autodesk cloud OAuth — Bridge-native) · timeouts · commands</text>+ </g>+ <text x="64" y="784" class="t" font-size="12">These never leave Bridge — no bridge involved. Bridge authors their result + <tspan class="mono">_hint</tspan>.</text>++ <!-- THE LINE -->+ <line x1="560" y1="110" x2="560" y2="800" stroke="#334155" stroke-width="2" stroke-dasharray="6 6"/>+ <rect x="500" y="420" width="120" height="60" rx="10" fill="#0b0f14" stroke="#2dd4bf"/>+ <text x="560" y="446" text-anchor="middle" class="h" font-size="13">route by</text>+ <text x="560" y="466" text-anchor="middle" class="mono" fill="#5eead4" font-size="13">verbPrefix</text>++ <!-- BRIDGE side -->+ <rect x="600" y="100" width="480" height="710" rx="18" fill="#101826" stroke="#334155" stroke-width="2"/>+ <text x="624" y="138" class="tier" fill="#93c5fd">▸ BRIDGE VERBS (the bridge implements these)</text>+ <text x="624" y="162" class="t">Bridge forwards the FULL args object verbatim to the bridge over HTTP. Bridge never</text>+ <text x="624" y="180" class="t">strips, reshapes, or interprets them — the bridge validates + owns its verbs.</text>++ <g>+ <rect x="624" y="200" width="432" height="86" rx="10" fill="#0d1420" stroke="#334155"/>+ <text x="642" y="226" class="h" font-size="14">pup · cloud-owned</text>+ <text x="642" y="248" class="mono" fill="#93c5fd">pup_open_window · navigate · eval · screenshot · record_*</text>+ <text x="642" y="270" class="t">→ a fresh Chrome-for-Testing (or your Edge) automation browser</text>++ <rect x="624" y="298" width="432" height="86" rx="10" fill="#0d1420" stroke="#334155"/>+ <text x="642" y="324" class="h" font-size="14">KiCad · cloud-owned</text>+ <text x="642" y="346" class="mono" fill="#93c5fd">kicad_open_board · install_symbol · run_drc · export_*</text>+ <text x="642" y="368" class="t">→ KiCad 7/8/9/10 side-by-side</text>++ <rect x="624" y="396" width="432" height="86" rx="10" fill="#0d1420" stroke="#334155"/>+ <text x="642" y="422" class="h" font-size="14">Fusion 360 · cloud-owned</text>+ <text x="642" y="444" class="mono" fill="#93c5fd">fusion_start · import_step · export_gerbers · board_info · walk_cloud_tree</text>+ <text x="642" y="466" class="t">→ Fusion 360 CAD + EAGLE electronics</text>++ <rect x="624" y="494" width="432" height="86" rx="10" fill="#0d1420" stroke="#334155"/>+ <text x="642" y="520" class="h" font-size="14">Native browser (nb) · cloud-owned (nbe extension)</text>+ <text x="642" y="542" class="mono" fill="#93c5fd">nbrowser_open · nbrowser_eval · nbrowser_status</text>+ <text x="642" y="564" class="t">→ your REAL logged-in Chrome / Edge</text>++ <rect x="624" y="592" width="432" height="70" rx="10" fill="#0d1420" stroke="#334155"/>+ <text x="642" y="618" class="h" font-size="14">Hydrogen · external-http</text>+ <text x="642" y="640" class="mono" fill="#93c5fd">hd_status · hd_api · hd_launch · hd_ship</text>+ <text x="642" y="656" class="t">→ relays HD's own control API</text>++ <rect x="624" y="672" width="432" height="88" rx="10" fill="#0d1420" stroke="#334155"/>+ <text x="642" y="698" class="h" font-size="14">Third-party · bridge_install</text>+ <text x="642" y="720" class="mono" fill="#93c5fd"><prefix>_* (blender_* · rdp_* · anything you publish)</text>+ <text x="642" y="742" class="t">→ same contract; declares detect / timeouts / statusVerb in bridge.json</text>+ </g>+ <text x="624" y="792" class="t" font-size="12">A bridge adds/renames args with ZERO Bridge change. See skills/BRIDGE_SDK.md.</text>+</svg>
docs/settings-v2.pngadded⋯ 1 unchanged line ⋯
docs/toast-basic-v2.pngadded⋯ 1 unchanged line ⋯
docs/toast-buttons-v2.pngadded⋯ 1 unchanged line ⋯
docs/toast-input-v2.pngadded⋯ 1 unchanged line ⋯
docs/toast-progress-v2.pngadded⋯ 1 unchanged line ⋯