---
name: adom-desktop-local-ai
description: Drive this Mac from a LOCAL AI tool (Claude Desktop, Claude Code, Codex, or any agent running on the same machine) through Adom Bridge's bundled CLI, adom-desktop-cli. No relay, no cloud container, no --target. Use when the user says "Claude Desktop, control my Mac", "use Adom Bridge from Claude Code on my Mac", "local AI, drive my desktop", or when you find the bundled adom-desktop-cli. Covers the bundled CLI, the auto-linked consumer skills, loopback direct-API routing, and a starter verb cookbook.
---

# Adom Bridge from a local AI (same-Mac, no relay)

Adom Bridge (formerly Adom Desktop) is the automation surface for this Mac. It
runs as a menu-bar agent: signed-in launches go straight to the menu bar with
no window and no Dock icon, and the window is summoned from the menu-bar item
(or by launching the app again). If Bridge is installed here, any AI tool
running on the SAME machine (Claude Desktop, Claude Code, Codex, a local
script or agent) can drive the desktop through the bundled CLI. The
cloud-container path over the WebSocket relay is a different setup and is
covered elsewhere (see "When you DO need the relay" below).

## What the Mac install lays down for local AIs

- **The bundled CLI** lives inside the app bundle at
  `Adom Bridge.app/Contents/Resources/adom-desktop-cli`. Standalone installs
  put the app in `/Applications`; on machines managed by Adom Hydrogen the
  bundle lives under `~/Library/Application Support/adom/bridge/`. Invoke it
  by full path, or symlink it somewhere on your PATH.
- **Consumer skills are auto-linked into your agents.** The app bundles the
  consumer skill set, and on EVERY launch Bridge copies each skill into BOTH
  `~/.claude/skills/<slug>/` and `~/.codex/skills/<slug>/`. So a local
  Claude Desktop / Claude Code / Codex picks up Bridge's docs with zero user
  steps.

Auto-link behavior (from `src-tauri/src/skills_install.rs`):

- **Idempotent and cheap.** A skill is (re)written only when the destination
  is missing or its bytes differ from the bundled copy. A steady-state launch
  does zero disk writes.
- **`.adom-managed` marker.** Each directory Bridge creates carries a
  `.adom-managed` marker file. Bridge refreshes a skill (on an upgrade) only
  when the marker is present.
- **Never clobbers your own skills.** A same-slug directory WITHOUT the
  marker (hand-made, or installed by a package) is left untouched.
- **Opt out:** launch Bridge with `ADOM_SKILLS_LINK=0` to disable the
  auto-link.
- Runs in both standalone and embedded (under Adom Hydrogen) modes, and is
  best-effort: it can never fail or delay Bridge's launch.

## How a local AI calls Bridge

Run the CLI with a verb and a JSON args object, and NO `--target`:

```
adom-desktop-cli <verb> '<json-args>'
```

With no target set, the CLI short-circuits to the app's **loopback direct
API**: it reads `~/.adom/direct-api-port` (written by the app at bind time,
contents `host:port`, e.g. `127.0.0.1:47200`), falls back to probing
`127.0.0.1:47200` and scanning `47201..47209` if the file is missing, and
POSTs straight into the running app process. No relay, no container, no
WebSocket, no auth-token dance. Responses are the same JSON shape as every
other path, including `_hint`, `errorCode`, and `status` fields.

**Local callers are trusted by transport.** The direct API binds
`127.0.0.1` only, so a caller on this machine already got here by being
installed on this machine. The shell approval gate applies only to remote
relay (cloud AI) callers; the local CLI is not gated.

## Verb discovery

```
adom-desktop-cli commands
```

lists every available verb with args and return shapes (aliases: `help`,
`list_commands`). Unknown-verb responses also carry a hint pointing at the
discovery list.

## Starter cookbook

```bash
# Is Bridge up? (ping uses its own direct-API path)
adom-desktop-cli ping

# Enumerate visible top-level windows (returns window ids + titles)
adom-desktop-cli desktop_list_windows

# Capture one window, chrome included (lossless PNG)
adom-desktop-cli desktop_screenshot_window '{"hwnd": 123456}'
# ...or match by title:
adom-desktop-cli desktop_screenshot_window '{"titleContains": "TextEdit"}'

# Whole-screen capture
adom-desktop-cli desktop_screenshot_screen

# Show the user a native macOS notification
adom-desktop-cli notify_user '{"title":"Build done","body":"All tests passed"}'

# Launch an app (path-verified; fails loudly instead of an OS error dialog)
adom-desktop-cli launch '{"path":"/usr/bin/open","args":["-a","Safari"]}'

# Run a shell command through Bridge's structured verb
adom-desktop-cli shell_execute '{"command":"echo hello"}'
```

Prefer Bridge's structured verbs (`launch`, `find_exe`, `desktop_*`,
`notify_user`) over raw shell where one exists: they validate inputs and
return structured JSON with hints. For multi-line or quoted scripts use
`run_script` with `interpreter` set to `bash`, `zsh`, or `sh`.

## When you DO need the relay

The direct API only reaches the Bridge on THIS machine. To drive a REMOTE
machine (another computer's Bridge connected to the same relay), the CLI
routes over the relay with `--target <clientName>`; a cloud container always
uses the relay. That path, including multi-machine addressing and targeting
rules, is documented in the main `adom-desktop` skill (`skills/SKILL.md`) and
`skills/MULTI_AD_ADDRESSING.md`. This skill is only about the local,
no-relay case.

## Sibling apps: skip the CLI entirely

A sibling app or local process can also POST JSON commands directly to
Bridge's loopback HTTP API (`POST http://127.0.0.1:<port>/command` with
`{"command": "...", "args": {...}}`, port discovered from
`~/.adom/direct-api-port`) without spawning the CLI at all. The full
contract, including port discovery, endpoints, and update routes, is in the
`adom-desktop-direct-api` skill (`skills/DIRECT_API.md`).
