← Commit history

Billboard: 'Your mesh, and prompts that follow you' section linking docs/mesh.md

John Lauer ·15b0bf4524 ·1mo ago ·parent 86495c1
1 file changed +325−161
README.md+325−161
@@ -1,310 +1,474 @@ # 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 + 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+---++## Install++### From your Adom workspace (recommended)++Hydrogen installs and manages ab for you. Standalone, from a cloud container:++```bash+adom-wiki pkg install adom/adom-bridge   # Linux CLI + skills into a container ``` -That installs the **container-side** pieces: the `adom-bridge` binary (SHA256-verified against this page's `version.json`) and the Claude skill bundle into `~/.claude/skills/`:+### Direct download (Windows) -| 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 |+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).++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).++### Uninstall -`adom-wiki pkg update` keeps it current. The **KiCad** and **Fusion 360** bridge skills install from their own cloud-owned bridge pages.+Add/Remove Programs, *Adom Bridge*, or `adom-bridge --uninstall`.++---  ## Adom Anywhere: use Adom from Claude Desktop or Codex -You do not need the cloud, and you do not need to be an Adom container user. Installing Adom Bridge makes a local Claude Desktop, Claude Code, or Codex a full Adom ecosystem citizen: it drives your PC (no relay, no setup), automates a real browser via the bundled pup bridge, authors wiki pages with the bundled `adom-wiki.exe`, and reaches into your cloud Hydrogen workspace (webviews, sandboxes, screenshots) with the bundled `adom-cli.exe`. Auth rides your one Adom Bridge sign-in, and the ecosystem skills are delivered and kept fresh automatically, each stamped with a note explaining how it applies on a container-less Windows PC. The one thing a local agent cannot do is run wiki-published Linux binaries; that needs an Adom container, which is what [Adom Hydrogen](https://wiki.adom.inc/adom/hydrogen) provides. Full story: [Adom Anywhere](docs/adom-anywhere.md); local routing details: [using Adom Bridge from a local AI](docs/local-ai.md).+You do not need the cloud, and you do not need to be an Adom container user. Installing Adom Bridge makes a local Claude Desktop, Claude Code, or Codex a full Adom ecosystem citizen: it drives your PC (no relay, no setup), automates a real browser via the bundled pup bridge, authors wiki pages with the bundled `adom-wiki.exe`, and reaches into your cloud Hydrogen workspace (webviews, sandboxes, screenshots) with the bundled `adom-cli.exe`. Auth rides your one Adom Bridge sign-in, and the ecosystem skills are delivered and kept fresh automatically, each stamped with a note explaining how it applies on a container-less Windows PC. The one thing a local agent cannot do is run wiki-published Linux binaries; that needs an Adom container, which is what [Adom Hydrogen](https://wiki.adom.inc/adom/hydrogen) provides.++Full story (what gets installed, how the CLIs work on Windows, the skill translation layer): [docs/adom-anywhere.md](docs/adom-anywhere.md). Local routing details: [docs/local-ai.md](docs/local-ai.md).  ## Sign in once, connect everywhere -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).+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). -## Many machines, many containers+## Published binaries -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).+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. -## Your mesh, and prompts that follow you+| Artifact | Platform | What it is | How to get it |+|---|---|---|---|+| 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: -Every Adom Bridge signed into your account finds the others through the Adom Mesh: relay mode by default (nothing listens on your PC; boxes talk through the Adom-hosted mesh relay, end-to-end encrypted on per-machine keys), direct mode on the same network if you switch it on. A human trusts each new machine into the mesh with one click that settles every box. And a permission prompt raised on any of your machines appears on all of them, with a chip naming the box it belongs to; decide it wherever you are, in Adom Bridge or (2.1.74) in Hydrogen's own dialog, and the decision lands on the origin. Deep dive: [the Adom Mesh and cross-box permission prompts](docs/mesh.md).+- **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). -## Running under Hydrogen+--- -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).+## Staying current: three update tiers -## The laptop GUI+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. -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).+| 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. | -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.+**Normal: the opt-in banner.** In the default `prompt` mode you decide when. Nothing installs until you click. -Deep dives: [presence, tray and icon states](docs/presence.md) and [the managed Node and Python runtimes](docs/runtimes.md).+<p align="center">+  <img src="screenshots/update-normal.png" alt="Normal update: footer banner with Install now / Later" width="720">+</p> -## Downloads+**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. -Everything a real user installs comes from this page.+<p align="center">+  <img src="screenshots/update-high.png" alt="High-priority update: informational toast, auto-installing in the background" width="380">+</p> -| 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` 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. |+**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. -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.+<p align="center">+  <img src="screenshots/update-emergency.png" alt="Emergency update: red forced-restart countdown with Restart now" width="720">+</p> -## Staying current: updates and the restart schedule+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. -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`:+### When a normal update actually installs (the restart schedule) -| Tier | How it is presented | Overrides your mode? |+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:24680`, and so on) and type (`COMMAND` / `DESKTOP` / `AUTH`). The direct badge always reflects the API's actual bound port. 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"> -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.+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. -## Window identity (branding a window the AI drives)+#### KiCad (`kicad_*`) -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.+<img src="screenshots/bridge-card-kicad.png" alt="KiCad bridge card" width="440">++Schematic and PCB automation: DRC/ERC, gerber and STEP export, 3D board render, and netlist/footprint queries. -- `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.+#### Fusion 360 (`fusion_*`) plus APS (`aps_*`) -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.+<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_*`)++<img src="screenshots/bridge-card-blender.png" alt="Blender bridge card" width="440">++Headless Python scripting and renders.++#### Hydrogen (`hd_*`)++<img src="screenshots/bridge-card-hd.png" alt="Hydrogen bridge card" width="440">++The local dev-environment app ab can embed into; ab relays ah's runtime state and drives its lifecycle.++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 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`, `delete_file`, `registry_*`, `process_kill`, `wsl_*`) require a human grant when they arrive over the *relay*:++- **+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. -**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 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). -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.+--- -Deep dive: [permissions](docs/permissions.md) (what each Approve choice means, and how to revoke).+Deep dive: [docs/permissions.md](docs/permissions.md) (what each Approve choice means, and how to revoke). -## Notifications+## 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. | -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.+### A toast can do two DIFFERENT things: don't confuse them -**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.+These are separate axes. Most confusion comes from conflating them: -![Basic alert toast](docs/toast-basic.png)+**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 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 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 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 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 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 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 --target AdomLapper screenshot_screen   # one named machine+adom-bridge --target all bridge_list                # fan out to every ab+adom-bridge 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_AB_ADDRESSING.md](skills/MULTI_AB_ADDRESSING.md). -![Reply input toast](docs/toast-input.png)+--- -```bash-adom-bridge 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.+Your own boxes also find each other through the **Adom Mesh** (relay mode by default, nothing listening; direct mode on the same network if you switch it on), a human trusts each new machine in with one click, and a permission prompt raised on any of them appears on all of them, in Adom Bridge and (2.1.74) in Hydrogen's dialog, with a chip naming the box. Deep dive: [docs/mesh.md](docs/mesh.md). -![Shell approval toast](docs/approve-bar.png)+## Embedded in Hydrogen -**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:+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). -```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-```+### The taskbar icon tells you the mode -Or skip the polling entirely with `"wait":true`, which blocks until you act (or `timeoutSec` elapses) and hands the AI your answer directly.+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. -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.+| 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. -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: [notifications](docs/notifications.md).+Deep dive: [docs/hydrogen-desktop.md](docs/hydrogen-desktop.md).  ## Verbs -![Core vs bridge verbs](docs/core-vs-bridge.svg)+<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. -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:+Three ways to invoke, all returning identical JSON:  ```bash-adom-bridge screenshot_window '{"hwnd": 12345}'              # CLI (relay / direct API)-adom-bridge --target AzureVM list_windows                    # target a named machine-curl -s -X POST 127.0.0.1:24680/command \-  -d '{"command":"notify_user","args":{"title":"Hi"}}'        # loopback direct API+# 1. CLI (cloud container): routes over the relay, or the direct API when co-resident+adom-bridge 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 --target AzureVM list_windows ``` -`adom-bridge help` and `GET /commands` are the live discovery surfaces for the full verb set.+`adom-bridge help` and `GET /commands` are the live discovery surfaces. **The complete list is in [VERBS.md](VERBS.md).** -Deep dive on the CLI itself: [the CLI guide](docs/cli.md).+--- -## The built-in web pages+Deep dive on the CLI itself: [docs/cli.md](docs/cli.md). -Adom Bridge serves a couple of small pages on its loopback HTTP API (the stable port `127.0.0.1:24680`), so you can inspect it from a normal browser:+## Documentation -- **`http://127.0.0.1:24680/verbs`** is a browsable API Explorer: every verb, grouped into tabs by category and with one tab per installed bridge, each with a plain-English description and a copy-to-clipboard curl command. The footer tooltip in the laptop GUI links straight to it. `GET /health`, `/status`, and `/commands` return the same information as JSON.+Every sub-readme, and the section it backs: -- **Web Control (detection).** A page served from `https://wiki.adom.inc` can `fetch('http://127.0.0.1:24680/health')` (and `/status`) to detect whether Adom Bridge is running, so the wiki can light up actions like "open this component in KiCad." The detection reads are deliberately tight: Adom Bridge returns CORS headers only for the exact origin `https://wiki.adom.inc` (never a wildcard, never a user-provisionable `*.adom.cloud` host) with a loopback-Host check to defeat DNS rebinding, and it handles the Private-Network-Access preflight.+| 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_AB_ADDRESSING.md](skills/MULTI_AB_ADDRESSING.md) | Addressing many desktops on one relay |+| [docs/mesh.md](docs/mesh.md) | The Adom Mesh: modes, per-machine trust, and permission prompts that follow you across your boxes and into Hydrogen |+| [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) |++---++## For developers++**Two binaries, two build paths:**++```bash+# 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+``` -- **Web Control (running a verb).** A web page can also `POST /command` to ask Adom Bridge to run a verb, but only with the user's permission. Every web request pops a native Adom Bridge prompt in its own window (Allow once / Allow 1 hr / Deny); nothing runs until the user clicks. The consent prompt, not the origin string, is the real gate, so this holds even for the wiki's readme, which renders in a sandboxed `Origin: null` iframe. The whole surface has a master off switch in Settings > Web Control, and detection keeps working while it is off so a page can tell the user how to turn it back on. Local callers (the CLI, Hydrogen, bridges) are never affected: this is only about web pages in a browser.+**Project layout:** -- **Web Control (optional wiki handshake).** For users who want more than the consent prompt, Settings > Web Control has a "Require wiki handshake" toggle (off by default). When on, a web page must prove it is really the Adom wiki acting as you before Adom Bridge will even show the prompt: Adom Bridge publishes a per-launch secret to your Adom account's cloud key-value (`bridge.webcontrol`), and only `wiki.adom.inc`, signed in as you, can read it and present it back in an `X-Adom-WebControl-Secret` header. A random site like evil.com cannot read your account key-value, so it is refused outright. This is a stronger gate layered on top of the consent prompt, not a replacement for it, and it could become the default in the future. Full model: the `adom-bridge-web-integration` skill; the mechanism and the security layers, with diagrams: [talking to Adom Bridge from a web page](docs/web-control.md).+```+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`. -### Try it live+Contributor guide and the full set of engineering rules: [CLAUDE.md](CLAUDE.md). Bridge authoring: [skills/BRIDGE_SDK.md](skills/BRIDGE_SDK.md). -If you are reading this on the Adom wiki with Adom Bridge running, the **Overview** tab shows a live panel: pick a security mode (consent-only or the optional wiki handshake) and run a verb against your own machine, with a permission prompt you click. (The interactive panel needs the HTML view of this page; this plain-text version just describes it.)+--- -## 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.