← Commit history

Adom Anywhere: the local Claude Desktop / Codex story (2.0.21)

John Lauer ·18e31383f7 ·2mo ago ·parent 9e73420
1 file changed +338−151
README.md+338−151
@@ -1,289 +1,476 @@ # Adom Bridge -**Unleash your AI onto your full PC: full power, full safety.** Every AI you use today is locked in a box: a cloud agent lives in a container with no hands, and a chat app can talk about your files but cannot touch them. Adom Bridge inverts that. It lets the AI break out of the box it runs in and onto your real machine, so the AI manages and runs your entire laptop as you, without you doing anything manually: launch apps, move files, drive any window, control KiCad, Fusion 360, Altium, Blender, or your real signed-in browser. It does not matter where your AI lives. A cloud agent reaches your desktop over the relay; a local one (Claude Desktop, Claude Code, Codex, anything) drives the same machine over loopback. It ships with **Hydrogen** and installs standalone too, and standalone users get the full value.+<p align="center">+  <img src="screenshots/main-view.png" alt="Adom Bridge main window" width="860">+</p> -**Bridges** make Adom Bridge a small operating system for AI: a bridge teaches it a new verb namespace for any app, and Adom Bridge provisions its own managed Node and Python runtimes, owns the bridge lifecycle, and keeps every bridge in a controlled loopback-only environment. And because unleashing an AI onto a whole machine only works if the human stays in charge, the **permission system** is the other half of the product: side-effecting commands from a remote AI are gated behind a human approval the AI can request but never grant itself, every command is attributed to the AI thread that issued it, and Adom Bridge binds to localhost only. Full power and full safety together are the point.+**Adom Bridge unleashes your AI onto your full PC: full power, full safety.** -![Adom Bridge main window](docs/main-view.png)+Every AI you use today is locked in a box. A cloud agent lives in a container with no hands; a chat app can talk about your files but cannot touch them. Adom Bridge inverts that: it lets the AI break out of the box it runs in and onto your real machine, so the AI manages and runs your entire laptop as you, without you doing anything manually. Launch apps, move files, drive any window, control KiCad, Fusion 360, Altium, Blender, or your real signed-in browser. It does not matter where your AI lives: a cloud agent reaches your desktop over the relay, and a local one (Claude Desktop, Claude Code, Codex, anything) drives the same machine over loopback. You do not need any other Adom product for this; ab ships with **[Hydrogen](https://wiki.adom.inc/adom/hydrogen-desktop)** but installs standalone, and standalone users get the full value.++**Bridges** are how the reach keeps growing, and they make ab a small operating system for AI: a bridge teaches ab a new verb namespace for any app, and ab provisions its own managed Node and Python runtimes, owns the bridge lifecycle (spawn, stable ports, health, auto-respawn, auto-update), and keeps every bridge in a controlled loopback-only environment. Building for the AI-driven desktop feels like building an app for an OS, and installing one is a single verb.++Unleashing an AI onto a whole machine only works if the human stays in charge, so the other half of the product is the **permission system**: side-effecting commands from a remote AI are gated behind a human approval prompt the AI can request but never grant itself, every command is attributed to the AI thread that issued it and visible in the Activity Log, and ab binds to `127.0.0.1` only, so nothing off your machine can reach it. Full power and full safety together are the point. Either one alone is easy; the product is both at once.++It is a lightweight native Tauri 2 app: a system-tray-resident WebSocket client on one side, a Windows automation surface on the other.  - **Full desktop control:** windows, input, screenshots, UI Automation, the shell, files, the registry, WSL.-- **Bridges:** first-class mini-apps. Puppeteer (browser), KiCad, Fusion 360, your real signed-in browser, Blender, or your own.+- **Bridges:** first-class mini-apps that teach ab new tricks. Puppeteer (browser), KiCad, Fusion 360, your real signed-in browser, Blender, or [your own](skills/BRIDGE_SDK.md). - **You are in control:** localhost-only, an install-consent trust model, a visible activity log, and an approval gate for the remote cloud-AI path. - **Multi-machine:** one relay can hold many desktops. Address any of them by name, or fan a command out to all.-- **Self-updating and signed:** every release is Azure code-signed and auto-updates from this page.+- **Self-updating and signed:** every release is Azure code-signed and auto-updates from the wiki.+- **Zero-setup skills for local agents:** the installer bundles ab's consumer skills and links them into your `~/.claude/skills` and `~/.codex/skills` on launch, so a local Claude Desktop or Codex on the same PC has both the CLI (the hands) and its docs (the skills) with no setup.++> **Full verb reference:** [VERBS.md](VERBS.md) lists every dispatchable verb, grouped by namespace.++---++## What's new++- **One bridge, one instance.** Every bridge spawn is serialized behind a per-bridge lock, and a background sweep collapses duplicates by scanning for any process (tracked or not) bound to a bridge's port and health-probing it, then re-pins the relay to the healthy instance. Relay verbs no longer round-robin between two copies of the same bridge.+- **ab restarts and updates itself from the relay.** A new `restart` verb cycles ab in place on a deployed box (stop, relaunch the installed exe, verify) with no redeploy, and the self-update state machine is relay-driveable (`update_status`, `update_check`, `apply_update`, `update_set_mode`), so a headless or fleet machine can be restarted and updated without anyone at the keyboard.+- **Bridge lifecycle audit log.** `bridge_log_read` now surfaces ab's own record of why a bridge started, stopped, or was reaped, in a log that survives respawns, so a bridge author can finally see why their process exited.++Recent highlights: a human-only approval gate (the AI can trigger the prompt with `request_shell_approval` but can never self-grant); ab scrolls its own window (`ad_scroll`); bridges reach the full ab verb set through the loopback direct API; managed no-UAC Node and Python runtimes for bridges; and a full `ui_*` UI Automation verb family.++---  ## How it works -![Architecture](docs/arch-flow.svg)+<p align="center">+  <img src="screenshots/arch-flow.svg" alt="Adom Bridge architecture" width="820">+</p> -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`.+The cloud AI never touches your machine directly. It sends a verb to the **relay** (a WebSocket hub); ab, connected out to that relay from your desktop, receives it, 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 ab's **loopback HTTP API** at `127.0.0.1`. -```-Adom container (this package)            User's laptop-+--------------------------+             +--------------------------+-| adom-bridge-cli + skills|  <-relay->  | Adom Bridge GUI (Tauri) |-| (Claude drives verbs)    |             | KiCad, Fusion, Chrome    |-+--------------------------+             | shell, files, screens    |-                                         +--------------------------+-```+- **Two binaries.** The **GUI** (this app) is the automation surface that runs on your desktop. The **CLI** is the caller: co-resident (Hydrogen, a local script) it uses the loopback direct API; from a cloud container it routes the same verbs over the relay.+- **Bridges** are separate processes ab spawns and supervises. Each owns a verb prefix (`pup_*`, `kicad_*`, and so on) and a small HTTP endpoint; ab relays verbs to it and renders its health.+- **Verbs return identical JSON** on every path (relay, direct-API, CLI), the same `_hint`, `errorCode`, and `status` fields, so a caller writes the code once. -## Install (in an Adom container)+Deep dive: [skills/DIRECT_API.md](skills/DIRECT_API.md) documents the loopback API contract. -```-adom-wiki pkg install adom/adom-bridge-```+--- -That installs the **container-side** pieces: the `adom-bridge-cli` binary (SHA256-verified against this page's `version.json`) and the Claude skill bundle into `~/.claude/skills/`:+## Install -| Skill | What Claude learns |-|---|---|-| `adom-bridge` | the main verb catalog: screenshots, files, shell, windows, notifications |-| `adom-bridge-notify` | native Windows toasts: progress bars, sticky reminders, buttons that round-trip |-| `adom-bridge-sdk` (+ `-manifest`, `-runtime`, `-callback`, `-publish`, `-audit`) | author your own bridge: a skill library split by phase, so only the part you need loads |-| `adom-bridge-ownership` | the boundary: what Adom Bridge core owns versus what a bridge author owns |-| `adom-bridge-multi-machine` | address multiple Adom Bridges on one relay (`--target`, fan-out) |-| `adom-bridge-direct-api` | the loopback HTTP API for sibling apps |-| `adom-bridge-installer`, `adom-bridge-windows-host`, `adom-bridge-discovery` | install, host, and discovery details |+### From your Adom workspace (recommended)++Hydrogen installs and manages ab for you. Standalone, from a cloud container: -`adom-wiki pkg update` keeps it current. The **KiCad** and **Fusion 360** bridge skills install from their own cloud-owned bridge pages.+```bash+adom-wiki pkg install adom/adom-bridge   # Linux CLI + skills into a container+``` -## Drive it from a local AI on the same PC+### Direct download (Windows) -You do not need the cloud. The Windows installer puts `adom-bridge-cli.exe` on PATH and links the Adom Bridge skills into `~/.claude/skills` and `~/.codex/skills` automatically, so Claude Desktop, Claude Code, or Codex on the same machine can drive your desktop immediately with no relay and no setup. Deep dive: [using Adom Bridge from a local AI](docs/local-ai.md).+Download the signed installer from **[wiki.adom.inc/adom/adom-bridge](https://wiki.adom.inc/adom/adom-bridge)** under *Download for your machine* and run it. ab installs to `%LOCALAPPDATA%\Adom Bridge\`, adds a tray icon, and starts on login. From then on it **auto-updates itself** from the wiki (prompt by default; every 4h and on launch). -## Sign in once, connect everywhere+What ships in the installer versus what ab fetches on first launch is documented in [skills/FIRST_INSTALL.md](skills/FIRST_INSTALL.md); the installer internals are in [skills/INSTALLER.md](skills/INSTALLER.md). -Sign in to your Adom account inside the app (Connections panel) and your cloud containers appear in the connection list and connect automatically: no JSON, no copy-paste. An AI in a container registers itself with one command. Deep dive: [sign-in and cloud configuration](docs/auth-and-cloud-config.md).+### Uninstall -## Many machines, many containers+Add/Remove Programs, *Adom Bridge*, or `adom-bridge-cli --uninstall`. -One desktop can connect to many containers, many desktops can share one container, and both at once. Address any desktop by name with `--target`. Deep dive with a topology diagram: [connection topology](docs/topology.md).+--- -## Running under Hydrogen+## Adom Anywhere: use Adom from Claude Desktop or Codex -When Hydrogen is present it runs Adom Bridge embedded: hidden window, Hydrogen-owned permission prompts, and a distinct taskbar tile. If Hydrogen ever goes away, Adom Bridge comes back standalone so your machine stays reachable. Deep dive: [how Adom Bridge interacts with Hydrogen](docs/hydrogen-desktop.md).+You do not need the cloud, and you do not need to be an Adom container user. If you already run Claude Desktop, Claude Code, or Codex on this PC, installing Adom Bridge makes your agent an Adom ecosystem citizen: -## The laptop GUI+- **Drive the PC.** The installer puts `adom-bridge-cli.exe` on PATH and links the full Adom Bridge skill set into `~/.claude/skills` and `~/.codex/skills` automatically. Screenshots, windows, files, shell (human-approved), notifications, KiCad, Fusion 360: all local, no relay, no setup. Deep dive: [docs/local-ai.md](docs/local-ai.md).+- **Automate a real browser.** The pup bridge (bundled) gives your agent multi-session Chrome automation out of the box.+- **Author the wiki.** `adom-wiki.exe` ships on PATH too. Your agent can create and manage pages, files, discussions, and packages on [wiki.adom.inc](https://wiki.adom.inc) using the account you signed in with.+- **Stay current automatically.** Beyond its own skills, Adom Bridge refreshes the wider ecosystem skill packages (the adom core set and the adom-wiki CLI skill) into your agent's skills folder daily, straight from their wiki packages. -The **Windows GUI** installs separately: a signed NSIS installer served from this page (*Download for your machine* above; Hydrogen installs it automatically). It installs to `%LOCALAPPDATA%\Adom Bridge\`, adds a tray icon, starts on login, and **auto-updates itself** from this page's `version.json` (prompt by default; every 4h and on launch).+The one thing a local agent cannot do is RUN the Linux binaries that many wiki packages publish; those need an Adom Linux container. That is exactly what **[Adom Hydrogen](https://wiki.adom.inc/adom/hydrogen)** provides: a full containerized AI workspace on this same PC that pairs with the Adom Bridge you already installed. When your agent hits that boundary, Hydrogen is the answer. -The main window (top) puts everything on one surface: **Connections** (each relay plus the other Adom Bridges on it as peers), the **Activity Log** (every command, badged by source and type, filterable), the **Bridges sidebar** (installed bridges as mini-app cards), the provisioned **Runtimes**, and the footer approval bar.+## Sign in once, connect everywhere -Deep dives: [presence, tray and icon states](docs/presence.md) and [the managed Node and Python runtimes](docs/runtimes.md).+Sign in to your Adom account inside the app (Connections panel) and your cloud containers appear in the connection list and connect automatically: no JSON, no copy-paste. An AI in a container registers itself with one command. Deep dive: [docs/auth-and-cloud-config.md](docs/auth-and-cloud-config.md). -## Downloads+## Published binaries -Everything a real user installs comes from this page.+Every real user download comes from one place: the wiki page **[wiki.adom.inc/adom/adom-bridge](https://wiki.adom.inc/adom/adom-bridge)**. GitHub is a private source backup, not a distribution channel.  | Artifact | Platform | What it is | How to get it | |---|---|---|---|-| Signed installer (NSIS) | Windows x64 | The GUI desktop app. Azure Trusted Signing. Installs to `%LOCALAPPDATA%\Adom Bridge\` and auto-updates. | The *Download for your machine* box at the top of this page. This is the one promoted Windows download. |-| CLI + skills package | Linux (container) | The `adom-bridge-cli` binary and Claude skill set for a cloud container driving your desktop remotely. Not needed if you use Hydrogen, which bundles Adom Bridge. SHA256-verified on install. | `adom-wiki pkg install adom/adom-bridge` |-| `version.json` | manifest | The auto-update manifest the GUI polls: per-platform installer URL, SHA256, and size. | Read automatically by the app; you never fetch it by hand. |+| Signed installer (NSIS) | Windows x64 | The GUI desktop app (this repo's `src-tauri`). Azure Trusted Signing. Installs to `%LOCALAPPDATA%\Adom Bridge\` and auto-updates. | The *Download for your machine* box on the wiki page. This is the one promoted Windows download. |+| CLI + skills package | Linux (container) | The `adom-bridge` CLI and Claude skill set for a cloud container driving your desktop remotely. Not needed if you use Hydrogen, which bundles Adom Bridge. SHA256-verified on install. | `adom-wiki pkg install adom/adom-bridge`, kept current by `adom-wiki pkg update`. |+| `version.json` | manifest | The auto-update manifest the GUI polls: per-platform installer URL, SHA256, and size. | Served at `wiki.adom.inc/api/v1/pages/adom-bridge/files/version.json`. The app reads it automatically; you never fetch it by hand. |++Notes:++- **The Windows GUI installer is the only promoted Windows download.** There is intentionally no standalone Windows CLI download: the CLI ships for Linux containers, and on Windows the GUI is the surface. A developer who wants a Windows CLI builds it from source (`cd cli && cargo build --release`).+- **macOS** is planned; the manifest already reserves a slot for it.+- **Everything is checksum-verified:** the installer against `version.json`, the Linux CLI against the package manifest's `assets` map (server-computed SHA256 per platform). -The Windows GUI installer is the only promoted Windows download. There is intentionally no standalone Windows CLI download. macOS is planned; the manifest reserves a slot for it.+--- -## Staying current: updates and the restart schedule+## Staying current: three update tiers++Adom Bridge polls the wiki manifest on launch and every 4 hours. Every release is Azure code-signed and its installer is SHA256-verified before it runs. What differs between releases is **urgency**: the manifest carries a `priority`, and ab presents each tier differently. You set your preference once in **Settings → Updates** (`prompt` is the default; `auto` and `off` are the alternatives); the tier decides how far ab is allowed to override that preference.++| Tier | When it applies | How ab presents it | Overrides your mode? |+|---|---|---|---|+| **Normal** | Almost every release. | A footer banner: **Install now / Later**. Silent in `auto`, nothing in `off`. | No. Respects `prompt` / `auto` / `off`. |+| **High** | A recommended fix worth not sitting on. | Auto-installs in the background (even in `prompt` mode) with an informational toast, then restarts. | Overrides `prompt`. Still respects `off`. |+| **Emergency** | A bug bad enough to pull from the whole fleet at once (for example, one flooding the network). | A red, non-dismissible **countdown to a forced restart** plus a sticky system toast, then ab Authenticode-verifies the installer and restarts itself. | Overrides everything, even `off`, even when embedded in Hydrogen. | -Adom Bridge polls the wiki manifest on launch and every 4 hours. Every release is Azure code-signed and its installer is SHA256-verified before it runs. What differs is urgency, and the manifest carries a `priority`:+**Normal: the opt-in banner.** In the default `prompt` mode you decide when. Nothing installs until you click. -| Tier | How it is presented | Overrides your mode? |+<p align="center">+  <img src="screenshots/update-normal.png" alt="Normal update: footer banner with Install now / Later" width="720">+</p>++**High: auto-installs, but tells you.** A high-priority update installs itself even if you're on `prompt` (it still won't touch you on `off`), and a toast says so rather than restarting out of nowhere.++<p align="center">+  <img src="screenshots/update-high.png" alt="High-priority update: informational toast, auto-installing in the background" width="380">+</p>++**Emergency: the forced kill switch.** This is the lever for a release that must reach every machine now. ab counts down to an automatic restart (with a **Restart now** shortcut), overriding your update mode and even embedded mode, and it will not run the installer unless Authenticode confirms it was signed by *Adom Industries, Inc.*, so a tampered manifest cannot turn into a fleet-wide install.++<p align="center">+  <img src="screenshots/update-emergency.png" alt="Emergency update: red forced-restart countdown with Restart now" width="720">+</p>++A normal release carries no `priority` at all. The emergency tier is a deliberate, per-incident action, never the default. You can preview any tier's presentation safely with `update_demo {tier}` (`normal` / `high` / `emergency`); it shows the real UI and, for emergency, runs the real download + signature check but never restarts.++### When a normal update actually installs (the restart schedule)++Adom Bridge lives in the tray and can run for days, weeks, or months without a restart. So a `prompt`-mode update that only ever shows a banner would, in practice, never install if you never clicked it. That is the gap the restart schedule closes.++Here is exactly when a downloaded update installs, by mode:++| Your mode | What installs it | When | |---|---|---|-| **Normal** | Almost every release. A footer banner: Install now / Later. Silent in Auto, nothing in Off. | No. |-| **High** | A recommended fix. Auto-installs in the background (even in Prompt) with a heads-up toast, then restarts. | Overrides Prompt; still respects Off. |-| **Emergency** | A bug bad enough to pull from the whole fleet at once. A red, non-dismissible countdown to a forced restart; Adom Bridge Authenticode-verifies the installer (must be signed by Adom Industries) before it runs. | Overrides everything, even Off, even embedded. |+| **Auto** | ab, silently | As soon as the update is downloaded. |+| **Prompt** (default) | You clicking **Install now** | Immediately, whenever you click. |+| **Prompt** (default) | ab, on the idle schedule | After the update has downloaded AND you have been away from the keyboard for about 15 minutes AND ab is not mid-task. It installs and relaunches quietly. |+| **Off** | Nothing | Never (except an Emergency release, which overrides Off by design). | -You set your preference once in **Settings, Updates**: Prompt (default), Auto, or Off. A normal release carries no priority; the emergency tier is a deliberate, per-incident action.+The schedule is **idle-based, not a fixed clock**. A fixed 2am restart could interrupt an overnight render or a long job; instead ab waits for a genuine lull: no keyboard or mouse input for ~15 minutes and no operation in flight. In practice that means the update lands overnight or the next time you step away, with no banner to chase and no manual restart. **Restarting Adom Bridge has no effect on your other apps or your work**: it reconnects to the relay in seconds and picks up exactly where it was. -**When a normal update actually installs.** Adom Bridge lives in the tray and can run for weeks without a restart, so a Prompt-mode update you never click would never install. The restart schedule closes that: once an update is downloaded AND you have been away from the keyboard for about 15 minutes AND Adom Bridge is not mid-task, it installs and relaunches quietly. It is idle-based, not a fixed clock, so it never interrupts active work or an overnight job, and restarting Adom Bridge has no effect on your other apps (it reconnects in seconds). Turn it off in Settings, Updates, "Restart when idle to finish updates," and a Prompt-mode update simply waits for your click. Auto installs immediately; Off never auto-installs (except an Emergency release). Embedded in Hydrogen, Hydrogen owns the restart timing.+Controls: -Deep dive on every update lane (app, bridges, container package, skills) and the network-traffic math: [how updates work](docs/updates.md).+- **Settings → Updates → "Restart when idle to finish updates"** turns the idle schedule on (default) or off. With it off, a `prompt`-mode update simply waits for you to click Install.+- The idle threshold is 15 minutes by default (`update_idle_minutes` in `config.json`).+- Embedded in Hydrogen, ah owns the restart timing (it applies the staged update at a safe moment), so ab does not self-restart there.+- A rarely-idle machine (a shared kiosk always in use) may never hit the idle window; there, click Install or restart ab when convenient. Emergency releases still force through regardless. -## Screenshots+--- -Anything Adom Bridge can see, it can screenshot, losslessly, with **no focus steal** (`PrintWindow` or full-screen DXGI, never a foreground grab). *Every image on this page was produced by these verbs.* `desktop_screenshot_window` returns a **`screenshots[]` array**: the window plus each owned popup or child dialog as its own image (so a confirm bubble hovering over an app comes back alongside the parent, never missed); `desktop_screenshot_screen` grabs the full virtual screen including borderless popups; `pup_screenshot` grabs the pup viewport. Every shot carries a **`coordMap`** so the AI clicks *what it sees* (`{space:"image", shotId, x, y}` to real screen px, no DPI math). It stays generic: Adom Bridge returns the rich array, the AI decides. `ad_scroll` even lets the AI page Adom Bridge's own window to capture content below the fold.+Deep dive on every update lane (app, bridges, container package, skills) and the network-traffic math: [docs/updates.md](docs/updates.md). -## Recording+## The window -![Adom Bridge Recorder](docs/recorder.png)+The main view (top of this page) puts everything on one surface: -Adom Bridge records the desktop or a browser session to video. The recorder HUD (above) **requires a `reason`** shown to the user up front, so a recording never starts silently, with live Screen/Microphone toggles and a Start/Stop control. `desktop_recorder_open {reason}` and `desktop_recorder_close` for the desktop; `pup_record_start` and `pup_record_stop` for the pup browser. Built for smooth, high-frame-rate video, not a choppy screenshot loop.+- **Connections (top-left).** Each relay you are connected to, with a live status dot, plus the *other* Adom Bridges on the same relay (peers). Expand one for **Screenshot / Info / Boot / Block**. Paste a server JSON blob to add a connection, or sign in to auto-discover your cloud servers.+- **Activity Log (center).** Every command, badged by source (`galliaApril`, `direct:47200`, and so on) and type (`COMMAND` / `DESKTOP` / `AUTH`). Filter by activity type or free text; toggle Ping/Pong noise. This is your window into *what is driving the machine and why*.+- **Bridges sidebar (right).** Installed bridges as mini-app cards: hero, health LED, language/source badges, star count, plus **+ Bridge** to install one by manifest URL and **Build your own bridge**. Click a card for a live console, ports/PID, and per-bridge actions.+- **Runtimes.** The Node and Python ab provisions for bridges, a system install if present, else a portable no-UAC copy (see [skills/MANAGED_RUNTIMES.md](skills/MANAGED_RUNTIMES.md)): -Deep dive: [recording](docs/recording.md).+  <img src="screenshots/runtimes.png" alt="Runtimes panel" width="320"> -## Bridges+- **Footer.** The shell-approval bar (below), your signed-in identity, the direct-API port, and this machine's name and version. -Each bridge is a small, independently-versioned process the app spawns, supervises, health-checks, and auto-updates from its own wiki page. Every install ships with the six below, and each shows up in the Bridges sidebar as a card: its billboard, a health LED, and language/source badges.+--- -### Puppeteer (`pup_*`)+Deep dives: [docs/presence.md](docs/presence.md) (the tray, low-memory mode, icon states) and [docs/runtimes.md](docs/runtimes.md) (the managed Node and Python). -![Puppeteer bridge card](docs/bridge-card-puppeteer.png)+## Screenshots, every way to grab one -A dedicated Chrome-for-Testing (or Edge) that Adom Bridge downloads and manages: open windows and tabs, drive pages, evaluate JS, screenshot, and record. No manual browser install.+Anything ab can see, it can screenshot, losslessly (PNG), with **no focus steal** (Win32 `PrintWindow` or full-screen DXGI, never a foreground grab that yanks a window in front of your work). *Every image in this README was produced by these verbs.* -### Native Browser (`nbrowser_*`)+| Verb | Captures |+|---|---|+| `desktop_screenshot_window {hwnd}` | one window including its chrome, and its owned popups (see below) |+| `desktop_screenshot_screen` | the full virtual screen (all monitors), including borderless popups a single-window grab cannot see; auto-downscaled to 1568px or less |+| `desktop_screenshot_all` / `kicad_screenshot_all` | every relevant window at once (for example an app and its error dialogs) |+| `pup_screenshot` / `pup_screenshot_full_res` | the pup browser viewport, or the full-resolution page | -![Native Browser bridge card](docs/bridge-card-native-browser.png)+**The parent/child popup array, and why it is an array rather than a single image.** When an app throws a dialog, confirm bubble, or extension popup on top of its main window, a naive "screenshot the window" would either miss the popup or flatten it. So `desktop_screenshot_window` returns a **`screenshots[]` array**: the parent window plus each owned popup or child dialog as its own image, each with its own `coordMap`. The AI gets the whole picture, the main window and the little "Allow?" bubble hovering over it, and decides what to click. This is deliberately **generic**: ab returns rich data (the array), it does not grow an app-specific "get the confirm dialog" verb. Any app's owned popups surface the same way. -Your *real*, signed-in Chrome or Edge profile, for the logins and forms a throwaway automation profile cannot do. The desktop bridge is bundled and works extension-free out of the box: it discovers your browser profiles, opens URLs in the right signed-in profile (OAuth consent flows), and inventories browser windows. Installing the companion browser extension unlocks full in-page drive: tabs, clicks, JS eval, and background screenshots.+**Zero-math coordinates.** Every screenshot verb returns a **`coordMap`**: `shotId`, image `{w,h}`, the screen rect in input space, `dpiScale`, and an image-to-screen affine. An input verb then accepts `{space:"image", shotId, x, y}` and ab converts to real screen pixels server-side. So the AI clicks *what it sees*, in the exact pixel space of the screenshot it is looking at, with no DPI reasoning and no rect re-fetch. -### KiCad (`kicad_*`)+**Reaching content below the fold.** For ab's own window, `ad_scroll {panel, to, dy}` pages a panel (the bridges sidebar, the activity log) and returns the live scroll geometry, so the AI can scroll, screenshot, and repeat until `atBottom` to capture everything. -![KiCad bridge card](docs/bridge-card-kicad.png)+--- -Schematic and PCB automation: DRC/ERC, gerber and STEP export, 3D board render, and netlist/footprint queries.+## Recording -### Fusion 360 (`fusion_*`) plus APS (`aps_*`)+<p align="center">+  <img src="screenshots/recorder.png" alt="Adom Bridge Recorder HUD" width="340">+</p> -![Fusion 360 bridge card](docs/bridge-card-fusion360.png)+ab records the desktop or a browser session to video. The recorder opens a small HUD (above) that **requires a `reason`**, shown to you right at the top, so a recording never starts silently: you always see *why* your screen is being captured, with live **Screen / Microphone** source toggles and a Start/Stop control. -Parametric modeling scripts and exports, plus fast indexed cloud-file search through Autodesk Platform Services.+- **`desktop_recorder_open {reason}` / `desktop_recorder_close`** open and close the desktop recorder HUD (consent-gated on `reason`).+- **`pup_record_start` / `pup_record_stop`** record the pup browser session directly. -### Blender (`blender_*`)+The capture path is built for **smooth, high-frame-rate video** rather than a choppy screenshot loop: a dedicated capture pipeline with a crisp multi-size HUD icon and a consent-first reason gate, so what you hand back is a real screen recording, not a flipbook. -![Blender bridge card](docs/bridge-card-blender.png)+--- -Headless Python scripting and renders.+Deep dive: [docs/recording.md](docs/recording.md). -### Hydrogen (`hd_*`)+## Window identity (advanced Windows shell) -![Hydrogen bridge card](docs/bridge-card-hd.png)+When an AI drives a window that another process owns (the classic case is a **Chrome for Testing** window, which otherwise reads "Test" with Chrome's icon), that window presents the wrong brand everywhere the Windows shell shows it: the taskbar button, Alt-Tab, the hover name, the right-click jump list, pins. ab exposes a small, generic verb family that fixes this by borrowing an advanced corner of the Windows shell that few APIs expose cleanly: the **Application User Model ID** (AUMID). -The local dev-environment app Adom Bridge can embed into; Adom Bridge relays Hydrogen's runtime state and drives its lifecycle.+- **`desktop_register_app_identity`** teaches Windows what an app id means (name plus icon), HKCU only, no UAC. `shortcut:false` gives a per-session identity with no Start Menu spam.+- **`desktop_set_window_identity`** stamps that id onto a live window plus its title-bar and Alt-Tab icon and the jump-list header.+- **`desktop_set_window_jumplist`** attaches a custom right-click menu and brands its header row.+- **`desktop_unregister_app_identity`** tears a per-session identity down.+- **`desktop_taskbar`** paints a progress bar, an overlay badge, or the hover-preview tooltip (`thumbnailTooltip`, the one uncapped text surface) and clip on any window's button so a user can glance and see what the AI is doing. -Install a third-party bridge by pasting its manifest URL, or `bridge_install {"manifestUrl":"..."}`.+These verbs also inspect any icon you pass and return an `iconCheck` block that explains, in plain terms, why an icon renders as a generic white document (the 256px size must be PNG-compressed; a `.ico` uses a bare path while a `.exe` or `.dll` uses `path,index`; SVG does not load) so the caller can fix the file instead of shipping a broken icon. -Deep dive: [bridges from the user's side](docs/bridges.md) (cards, LEDs, console, installing and updating).+**Full guide: [skills/WINDOW_IDENTITY.md](skills/WINDOW_IDENTITY.md)** covers the AUMID model, the register-plus-stamp two-halves rule, per-session identities, jump-list tasks and header branding, the taskbar overlay, the icon-format rules, the live-tile timing trap, and an end-to-end recipe. It ships as the `adom-bridge-window-identity` skill in the pkg tarball. -## Build your own bridge+--- -The bridges above are not special: they are ordinary bridges, and you can add your own. A bridge is a small local program in any language that serves HTTP on localhost. Adom Bridge spawns it, keeps it alive, and routes a namespace of verbs to it, so `kicad_*` reaches the KiCad bridge and `yourprefix_*` would reach yours.+## Bridges -Adom Bridge core owns the machine: spawning, ports, health, permissions, screenshots, files, windows, and the relay. You own your app and what its verbs mean. Runtimes are handled for you, a portable Node and Python with no elevation prompt, and your bridge inherits the human-approval permission model rather than inventing one.+Bridges are how ab reaches beyond the OS into specific apps. Each is a small, independently-versioned process that ab spawns, supervises, health-checks, and auto-updates from its own wiki page. Every install ships with the six below, and each shows up in the Bridges sidebar as a card: its billboard, a health LED, and language/source badges. -In practice the AI builds the bridge. The reference is a library of skills that ship in this package (`adom-bridge-sdk` and its manifest, runtime, callback, publish and audit companions), so an AI loads only the phase it is working in. Two minimal working bridges, [hello-python](https://wiki.adom.inc/adom/hello-python-bridge) and [hello-rust](https://wiki.adom.inc/adom/hello-rust-bridge), are there to copy.+#### Puppeteer (`pup_*`) -Deep dive: [build your own bridge](docs/bridge-sdk.md), the illustrated tour of what a bridge is, what the user sees, and the three things you publish.+<img src="screenshots/bridge-card-puppeteer.png" alt="Puppeteer bridge card" width="440"> -## The taskbar icon tells you the mode+A dedicated Chrome-for-Testing (or Edge) that ab downloads and manages: open windows and tabs, drive pages, evaluate JS, screenshot, and record. No manual browser install. -Adom Bridge's window carries a mode-specific app identity, so the taskbar button swaps its whole tile AND its name the moment the mode changes: no restart, no flicker.+#### Native Browser (`nbrowser_*`) -| Icon | Mode | Taskbar name | Meaning |-|:---:|:---|:---|:---|-| <img src="docs/taskbar-standalone.png" alt="Standalone: muted Adom tile" width="88"> | **Standalone** | Adom Bridge | Adom Bridge running on its own. The default for a normal install. |-| <img src="docs/taskbar-embedded.png" alt="Embedded: vivid Adom tile" width="88"> | **Embedded** | Adom Bridge Hydrogen Embedded | Hydrogen launched Adom Bridge and drives its lifecycle. |+<img src="screenshots/bridge-card-native-browser.png" alt="Native Browser bridge card" width="440">++Your *real*, signed-in Chrome or Edge profile, for the logins and forms a throwaway automation profile cannot do. The desktop bridge is bundled and works extension-free out of the box: it discovers your browser profiles, opens URLs in the right signed-in profile (OAuth consent flows), and inventories browser windows. Installing the companion browser extension unlocks full in-page drive: tabs, clicks, JS eval, and background screenshots.++#### KiCad (`kicad_*`)++<img src="screenshots/bridge-card-kicad.png" alt="KiCad bridge card" width="440"> -Muted "Adom Bridge" = Adom Bridge by itself; vivid "Adom Bridge Hydrogen Embedded" = Hydrogen has the helm. Each mode is a registered Windows app identity, and flipping the window between them makes the shell rebuild the button with the other identity's icon and name. Because the modes are distinct identities, a taskbar pin made in one mode shows the running window as a separate button while Adom Bridge is in the other mode.+Schematic and PCB automation: DRC/ERC, gerber and STEP export, 3D board render, and netlist/footprint queries.++#### Fusion 360 (`fusion_*`) plus APS (`aps_*`)++<img src="screenshots/bridge-card-fusion360.png" alt="Fusion 360 bridge card" width="440">++Parametric modeling scripts and exports, plus fast indexed cloud-file search through Autodesk Platform Services.++#### Blender (`blender_*`) -## Window identity (branding a window the AI drives)+<img src="screenshots/bridge-card-blender.png" alt="Blender bridge card" width="440"> -The same Windows shell mechanism (the Application User Model ID, or AUMID) is exposed as generic verbs so a bridge can make a window it drives present as *its* app. The motivating case: a Chrome for Testing window that would otherwise read "Test" with Chrome's icon in the taskbar, Alt-Tab, and the right-click menu.+Headless Python scripting and renders.++#### Hydrogen (`hd_*`)++<img src="screenshots/bridge-card-hd.png" alt="Hydrogen bridge card" width="440"> -- `desktop_register_app_identity` teaches Windows what an app id means (name plus icon), HKCU only, no UAC; `shortcut:false` gives a per-session identity with no Start Menu spam.-- `desktop_set_window_identity` stamps that id onto a live window plus its title-bar and Alt-Tab icon and the jump-list header.-- `desktop_set_window_jumplist` attaches a custom right-click menu and brands its header row.-- `desktop_taskbar` paints a progress bar, an overlay badge, and the hover-preview tooltip (`thumbnailTooltip`, the one uncapped text surface) and clip on any window's button.+The local dev-environment app ab can embed into; ab relays ah's runtime state and drives its lifecycle. -These verbs inspect any icon you pass and return an `iconCheck` that explains, in plain terms, why an icon renders as a generic white document (the 256px `.ico` size must be PNG-compressed; SVG does not load; a `.ico` uses a bare path while a `.exe` uses `path,index`), so the caller fixes the file instead of shipping a broken icon. The full guide ships as the `adom-bridge-window-identity` skill.+Install a third-party bridge by pasting its manifest URL into **+ Bridge**, or `bridge_install {"manifestUrl":"..."}`. The KiCad, Fusion, Blender, Puppeteer, and native-browser bridges are developed in their own wiki repos. See the **[Bridge SDK](skills/BRIDGE_SDK.md)** to build one, and [skills/BRIDGE_OWNERSHIP.md](skills/BRIDGE_OWNERSHIP.md) for the boundary between what ab core owns and what a bridge author owns.++---++Deep dive: [docs/bridges.md](docs/bridges.md) (cards, LEDs, console, installing and updating bridges).  ## Settings -![Settings](docs/settings.png)+<p align="center">+  <img src="screenshots/settings.png" alt="Settings" width="720">+</p>++Auto-connect behavior, the update channel (**prompt** / auto / off), the shell-approval preference, Hydrogen integration (including *exit when ah exits*), and runtime prewarming. While embedded in ah, ah-owned preferences show as *managed by Hydrogen*. -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*.+---  ## Security and the approval gate -![Shell approval bar](docs/approve-bar.png)+<p align="center">+  <img src="screenshots/approve-bar.png" alt="Shell approval bar" width="720">+</p> -**The trust boundary is install-consent plus the localhost bind.** Installing the app (and each bridge) is you granting permission for the AI to drive your machine; if you do not want that, uninstall. And the app plus every bridge binds `127.0.0.1` **only, never `0.0.0.0`**, so a caller must already be a program you installed on your own machine to reach it. No network attack surface by construction.+**The trust boundary is two things: install-consent and the localhost bind.** Installing ab (and each bridge) is you granting permission for the AI to drive your machine; if you do not want that, uninstall. And ab, plus every bridge it spawns, binds `127.0.0.1` **only, never `0.0.0.0`**, so a caller must already be a program you installed on your own machine to reach it. There is no network attack surface by construction. -On top of that, the **remote cloud-AI path is approval-gated.** Verbs that run code or change the machine (`shell_execute`, `run_script`, `launch_process`, `write_file`, `registry_*`, `process_kill`, and so on) require a human grant when they arrive over the *relay*: **+1hr / +24hr** (time-boxed), **Bypass** (indefinite), or **Revoke**. The grant is human-only; local callers (your CLI, Hydrogen, bridges) are trusted by transport and never prompt; read-only verbs are never gated.+On top of that, the **remote cloud-AI path is approval-gated.** Verbs that run code or change the machine (`shell_execute`, `run_script`, `launch_process`, `write_file`, `delete_file`, `registry_*`, `process_kill`, `wsl_*`) require a human grant when they arrive over the *relay*: -Deep dive: [permissions](docs/permissions.md) (what each Approve choice means, and how to revoke).+- **+1hr / +24hr** auto-approve for a time-boxed window.+- **Bypass** auto-approves indefinitely (for machines you fully trust); the timed buttons grey out while it is on.+- **Revoke** returns to per-command approval instantly. -## Notifications+The grant is **human-only**: the AI cannot grant it to itself. Local callers (your CLI, Hydrogen, bridges) are trusted by transport and never prompt. Read-only verbs (screenshots, status, window and UI reads) are never gated. Full taxonomy: [skills/PERMISSION_MODEL.md](skills/PERMISSION_MODEL.md). -Adom Bridge speaks to you through native Windows toasts via `notify_user`, under Adom Bridge's own identity (the Adom logo, and Action Center history like any first-class app). A cloud AI or a bridge, even one on a different machine addressed with `target`, fires them to reach you wherever you are. Every image below is the real toast, captured live from the exact call shown.+--- -**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.+Deep dive: [docs/permissions.md](docs/permissions.md) (what each Approve choice means, and how to revoke). -![Basic alert toast](docs/toast-basic.png)+## Notifications and the approval toast++ab speaks to you through **native Windows toasts** via `notify_user`, under Adom Bridge's own identity (the Adom logo, and Action Center history like any first-class app). A cloud AI or a bridge (even one on another machine, addressed with `target`) fires them to reach you wherever you are.++### Every toast type, and when to reach for it++Every image below is the real toast, captured live from the exact call in its row.++| Toast | Call + when to use it |+|---|---|+| <img src="screenshots/toast-basic.png" alt="Basic alert toast" width="330"> | **Basic alert.** `notify_user {"title":"Export done","body":"gerbers.zip is ready in C:/exports."}` Awareness: a build finished, a file is ready. Auto-dismisses in about 7 seconds (`durationLong:true` holds it ~25s; `level:"error"` and up do that automatically, and `"emergency"` also flashes the taskbar). |+| <img src="screenshots/toast-buttons.png" alt="Sticky toast with round-trip buttons" width="330"> | **Sticky choice (buttons that round-trip).** `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"}]}` Stays on screen until the user clicks (no auto-dismiss). Read the click back with `notify_response {"id":"deploy-42"}`. |+| <img src="screenshots/toast-progress.png" alt="Progress bar toast" width="330"> | **Progress bar.** `notify_user {"id":"job-1","title":"Exporting gerbers","progress":{"title":"myboard.kicad_pcb","value":0.6,"status":"Plotting copper layers...","valueOverride":"6 / 10 layers"}}` A long job. Re-fire with the SAME `id` as it advances toward `1.0`. `body` is optional here (1.9.123+). |+| <img src="screenshots/toast-input.png" alt="Reply input toast" width="330"> | **Reply input.** `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"}]}` The field renders, but Windows does not return typed text over protocol activation, so it is display-only today. For a real choice, use buttons. |+| <img src="screenshots/approve-bar.png" alt="The shell-approval toast" width="330"> | **Shell-approval.** Fired by ab itself when a gated command needs a human: *Approve 1 hr / 24 hr / Bypass Permissions*, granted straight from the toast without opening the window. |++### A toast can do two DIFFERENT things: don't confuse them++These are separate axes. Most confusion comes from conflating them:++**Axis 1: get the user's answer back to the AI.** This is the one people look for. There is **no server-push** to a turn-based AI, so there are exactly two ways:  ```bash-adom-bridge-cli notify_user '{"title":"Export done","body":"gerbers.zip is ready in C:/exports."}'+# FAST PATH: wait:true. The notify_user call itself BLOCKS and returns the+# user's choice. Best for a single "ask and get the answer" prompt.+adom-bridge-cli notify_user '{"title":"Ship v2 to prod?","scenario":"reminder","buttons":[{"label":"Ship it"},{"label":"Hold"}],"wait":true,"timeoutSec":120}'+#   -> { "pending": false, "action": "Ship it" }    # returned inline when they click++# FIRE-AND-CONTINUE: don't block; drain events on a later turn. The click is+# recorded durably (a cross-process file), so it survives even on a headless box.+adom-bridge-cli notify_user '{"id":"deploy-42","title":"Ship v2?","scenario":"reminder","buttons":[{"label":"Ship it"},{"label":"Hold"}]}'+adom-bridge notify_events '{"sinceSeq":0}'          # every click since a cursor, no per-id polling+#   -> { "events":[{"id":"deploy-42","action":"Ship it"}], "nextSeq":1 }+adom-bridge notify_response '{"id":"deploy-42"}'    # or poll one id+#   pending -> { "pending": true, "action": null }   |   clicked -> { "pending": false, "action": "Ship it" }+adom-bridge notify_dismiss '{"id":"deploy-42"}'     # retract a sticky reminder once handled ``` -**Click-to-focus: send them where the notification points.** Most notifications are about something else on screen: a browser waiting on a login, a dialog, an app that needs a click. Pass `focus` and clicking the notification brings THAT window to the front, instead of opening Adom Bridge. Name the window by `hwnd` (exact, from `desktop_list_windows`), by `cacheKey`, or by `titleContains`.+**Axis 2: reveal a window on the user's screen (a LOCAL desktop action, not a reply to the AI).** Most notifications are *about* something else on screen: a browser waiting on a login, a dialog, an app that needs a click. Pass `focus` and clicking the toast brings **that** window to the front instead of opening Adom Bridge:  ```bash adom-bridge-cli notify_user '{"title":"Sign-in needed","body":"Confirm in the browser and I will continue.","focus":{"titleContains":"Sign in - Google Chrome"}}' ``` -The response says whether the target resolved, so the AI finds out at send time rather than you finding out by clicking a notification that does nothing. If the window is gone by the time you click, it falls back to opening Adom Bridge, so a click is never dead. The click also counts as an acknowledgement, so the AI learns you engaged even with no buttons on the toast.+Name the window by `hwnd` (exact, from `desktop_list_windows`), `cacheKey`, `titleContains`, `app` (any app by owning process, survives PID churn), or **`host:true`**: the app ab is embedded under (Hydrogen). `host:true` is what makes an approval or prompt toast reveal **ah** on click instead of ab, without the caller needing ah's handle. The response tells you whether the target resolved at send time, so you find out before the user clicks a dead notification. Button clicks deliberately do not steal focus: a toast exists to reach someone without interrupting them. -**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.+The two axes compose: a sticky toast with buttons *and* `focus:{host:true}` reveals ah when clicked **and** reports the click back via `wait`/`notify_events`. The response also carries `_couldHaveDoneBetter` and `_capabilities` whenever a call left something on the table, so an agent learns the verb from using it. Full reference, including the Focus-Assist / Do-Not-Disturb caveat and how to allow-list ab past it: [skills/NOTIFY.md](skills/NOTIFY.md). -![Sticky toast with buttons](docs/toast-buttons.png)+--- -```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"}]}'-```+Deep dive: [docs/notifications.md](docs/notifications.md). -**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.+## Multi-machine -![Progress bar toast](docs/toast-progress.png)+One relay can hold many Adom Bridges: your laptop, an Azure VM, a conference-room box. Each is addressable **by name:**  ```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"}}'+adom-bridge-cli --target AdomLapper screenshot_screen   # one named machine+adom-bridge-cli --target all bridge_list                # fan out to every ab+adom-bridge-cli targets                                 # list connected machines ``` -**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.+From the GUI's Connections panel you can screenshot, get info on, boot, or **block** a peer (a per-peer denylist, so a shared machine cannot drive yours). See [skills/MULTI_AD_ADDRESSING.md](skills/MULTI_AD_ADDRESSING.md). -![Reply input toast](docs/toast-input.png)+--- -```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"}]}'-```+Deep dive with a topology diagram (one-to-many, many-to-one, many-to-many): [docs/topology.md](docs/topology.md). -**Shell-approval.** Fired by Adom Bridge itself when a gated command needs a human: *Approve 1 hr / 24 hr / Bypass Permissions*, granted straight from the toast without opening the window.+## Embedded in Hydrogen -![Shell approval toast](docs/approve-bar.png)+When [Hydrogen](https://wiki.adom.inc/adom/hydrogen-desktop) launches ab, it runs in **embedded mode**: ah-owned settings locked to ah, an optional *exit when ah exits*, and a distinct taskbar icon so you can tell at a glance who is driving. ah owns ab's lifecycle and near-zero-click auto-updates through the direct API. See [skills/DIRECT_API.md](skills/DIRECT_API.md). -**How the AI tracks the response, or expires the notify.** A toast is fire-and-forget, but a clicked button is recorded durably, so the AI learns the outcome even on a headless box:+### The taskbar icon tells you the mode++ab's window carries a mode-specific app identity, so the taskbar button swaps its whole tile AND its name the moment the mode changes: no restart, no flicker, no badge.++| Icon | Mode | Taskbar name | What it means |+|:---:|:---|:---|:---|+| <img src="screenshots/taskbar-standalone.png" alt="Standalone: muted Adom tile" width="96"> | **Standalone** | Adom Bridge | ab is running on its own. You launched it, or it installed and started itself. The default for a normal install. |+| <img src="screenshots/taskbar-embedded.png" alt="Embedded: vivid Adom tile" width="96"> | **Embedded** | Adom Bridge Hydrogen Embedded | Hydrogen launched ab and is driving its lifecycle. The vivid brand teal signals "active under ah". |++In short: muted tile named "Adom Bridge" = ab by itself; vivid tile named "Adom Bridge Hydrogen Embedded" = ah has the helm. Under the hood each mode is a registered Windows app identity (AppUserModelID), and flipping the window between them makes the shell rebuild the button with the other identity's icon and name, which is how the swap happens live. One side effect to know about: because the two modes are distinct identities, a taskbar pin made in one mode shows the running window as a separate button while ab is in the other mode.++---++Deep dive: [docs/hydrogen-desktop.md](docs/hydrogen-desktop.md).++## Verbs++<p align="center">+  <img src="screenshots/core-vs-bridge.svg" alt="Core vs bridge verbs" width="820">+</p>++ab-core owns the generic desktop verbs (`desktop_*`, `shell`, `ui_*`, files, `notify_user`, multi-ab). Each **bridge** owns its own prefix and ships its own verbs; ab relays them verbatim and stays generic, never baking in app-specific logic.++Three ways to invoke, all returning identical JSON:  ```bash-adom-bridge notify_response '{"id":"deploy-42"}'   # pending:true until clicked, then action:"Ship it"-adom-bridge notify_events '{"sinceSeq":0}'          # drain EVERY click since a cursor, no per-id polling-adom-bridge notify_dismiss '{"id":"deploy-42"}'     # retract a sticky toast once you have handled it+# 1. CLI (cloud container): routes over the relay, or the direct API when co-resident+adom-bridge-cli screenshot_window '{"hwnd": 12345}'++# 2. Direct HTTP API (a co-resident sibling app or a bridge calling back): app optional+curl -s -X POST 127.0.0.1:47200/command -d '{"command":"notify_user","args":{"title":"Hi"}}'++# 3. Relay, targeted at a specific machine+adom-bridge-cli --target AzureVM list_windows ``` -Or skip the polling entirely with `"wait":true`, which blocks until you act (or `timeoutSec` elapses) and hands the AI your answer directly.+`adom-bridge-cli help` and `GET /commands` are the live discovery surfaces. **The complete list is in [VERBS.md](VERBS.md).** -Clicking the toast body brings the window named by `focus` to the front, or opens Adom Bridge when no `focus` was given. Button clicks deliberately do not steal focus: a toast exists to reach you without interrupting what you were doing.+--- -The AI does not have to read any of this first. When a call leaves something on the table, such as no `focus`, or buttons on a toast that will vanish before you see it, the response says so and lists what the verb can do. That coaching stops once the AI gets it right. Full reference lives in the `adom-bridge-notify` skill.+Deep dive on the CLI itself: [docs/cli.md](docs/cli.md). -Deep dive: [notifications](docs/notifications.md).+## Documentation -## Verbs+Every sub-readme, and the section it backs:++| Doc | Covers |+|---|---|+| [VERBS.md](VERBS.md) | The full verb reference, grouped by namespace |+| [skills/DIRECT_API.md](skills/DIRECT_API.md) | The loopback HTTP API for co-resident sibling apps and bridges |+| [skills/NOTIFY.md](skills/NOTIFY.md) | `notify_user`: toast types, buttons, progress, and the click round-trip |+| [skills/MULTI_AD_ADDRESSING.md](skills/MULTI_AD_ADDRESSING.md) | Addressing many desktops on one relay |+| [skills/PERMISSION_MODEL.md](skills/PERMISSION_MODEL.md) | The gated-versus-ungated verb taxonomy and the trust boundary |+| [skills/BRIDGE_SDK.md](skills/BRIDGE_SDK.md) | Build your own bridge: `bridge.json`, health and describe contracts, lifecycle |+| [skills/BRIDGE_OWNERSHIP.md](skills/BRIDGE_OWNERSHIP.md) | What ab core owns versus what a bridge author owns |+| [skills/MANAGED_RUNTIMES.md](skills/MANAGED_RUNTIMES.md) | How ab provisions Node and Python for bridges with no UAC and no firewall prompts |+| [skills/FIRST_INSTALL.md](skills/FIRST_INSTALL.md) / [skills/INSTALLER.md](skills/INSTALLER.md) | What ships in the installer versus what is fetched on first launch |+| [skills/WINDOWS_HOST.md](skills/WINDOWS_HOST.md) | Driving ab from a sandboxed Windows host |+| [CLAUDE.md](CLAUDE.md) | The full engineering and release rules (contributor guide) |++--- -![Core vs bridge verbs](docs/core-vs-bridge.svg)+## For developers -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:+**Two binaries, two build paths:**  ```bash-adom-bridge-cli screenshot_window '{"hwnd": 12345}'              # CLI (relay / direct API)-adom-bridge-cli --target AzureVM list_windows                    # target a named machine-curl -s -X POST 127.0.0.1:47200/command \-  -d '{"command":"notify_user","args":{"title":"Hi"}}'        # loopback direct API+# GUI (this app), Windows+cd src-tauri && cargo tauri build --bundles nsis   # signed NSIS installer+cargo build --release                              # fast dev iteration (no bundling)++# CLI, any platform+cd cli && cargo build --release ``` -`adom-bridge-cli help` and `GET /commands` are the live discovery surfaces for the full verb set.+**Project layout:**++```+src-tauri/   Tauri 2 GUI + Windows automation (Rust)     the desktop app+cli/         CLI + relay server (Rust)                   what cloud containers run+src/         Frontend (vanilla HTML/CSS/JS)              the window UI+plugins/     Bundled bridge seeds (pup/kicad/fusion/native-browser)  first-run fallback+skills/      Consumer + author docs (shipped to wiki)+wiki-pkg/    adompkg scaffold (Linux CLI + skills tarball)+```++**Stack:** Tauri 2, Rust (tokio, axum, tokio-tungstenite), a vanilla JS frontend, Azure Trusted Signing. Config lives at `~/.adom/config.json`.++Contributor guide and the full set of engineering rules: [CLAUDE.md](CLAUDE.md). Bridge authoring: [skills/BRIDGE_SDK.md](skills/BRIDGE_SDK.md). -Deep dive on the CLI itself: [the CLI guide](docs/cli.md).+--- -## Versioning+## License -This package version tracks the Adom Bridge release. The scaffold is small; the multi-MB binaries are fetched at install time with SHA256 verification (the manifest's `assets` map carries server-computed checksums per platform).+Proprietary. Copyright 2026 Adom Industries, Inc.