app / adom-desktop
!

Not installable via adompkg

This app has no published release. adompkg install kyle/adom-desktop will not work until a maintainer publishes a tarball with install.sh and uninstall.sh.

See the publishing docs for the package.json schema and tarball layout required to ship this app.

Adom Desktop

Bridge between Claude (running in an Adom Docker container) and the user's desktop applications. One install gives Claude every desktop verb it needs — KiCad, Fusion 360, Chrome, file transfer, screenshots, shell, notifications, screen recording — over a single CLI binary that auto-updates from this wiki.

v1.8.31 highlights:

  • Direct API with port resilience — fallback chain 8770→8779, discovery file at ~/.adom/direct-api-port, per-verb command timeouts, graceful shutdown on app exit. Docker connects in <100ms even after laptop sleep/wake.
  • Dynamic bridge ports — every bridge binds to an OS-assigned ephemeral port. No more collisions with Hydrogen Desktop's 8772/8773/8851. Third-party bridges no longer need to pick a number.
  • Bridge ecosystem v1.8.0+ — three official bridges (KiCad, Fusion 360, Puppeteer) + two sample templates (Python, Rust) + a community-curated bridges registry. Install any bridge with adom-desktop bridge_install '{"manifestUrl":"…"}'.
  • Auto-update from the wiki (v1.3.39+) — polls version.json every 4h. Settings → Updates lets users pick prompt / auto / off.
  • Single-instance enforcementtauri-plugin-single-instance ensures only one GUI runs even if autostart + manual launch overlap.

What it is

Adom Desktop is a small Tauri 2 (Rust + WebView2/WebKit) desktop application that runs on the user's machine and acts as a WebSocket relay between Docker Claude and local applications. The architecture has three layers:

[ Docker container ]                [ User's machine ]
                                          │
  adom-desktop CLI  ◄──── HTTP/WS ────►  Adom Desktop (Tauri GUI)
       (Linux)                            │
                                          ├── KiCad bridge        (port-assigned at spawn)
                                          ├── Fusion 360 bridge   (port-assigned at spawn)
                                          ├── Puppeteer bridge    (port-assigned at spawn)
                                          ├── 3rd-party bridges   (port-assigned at spawn)
                                          ├── Direct API endpoint (8770→8779 fallback)
                                          └── File / shell / notify primitives

Every desktop integration is implemented as a bridge — an independently-versioned process Adom Desktop spawns on demand, with a bridge.json manifest declaring verb prefixes (kicad_*, fusion_*, browser_*, etc.). Adom Desktop allocates an ephemeral port at spawn time, passes it as --port <N>, and polls /status until ready.

Same install gives Claude:

  • KiCad (via adom-bridge-kicad) — open boards/schematics, install symbols/footprints, DRC, screenshot editor windows, watch projects for changes
  • Fusion 360 (via adom-bridge-fusion) — launch Fusion, export STEP/IGES/STL/3MF/USDZ/OBJ/DXF/DWG/Gerbers, search cloud files, run EAGLE library commands
  • Browser (via adom-bridge-puppeteer) — Chrome for Testing on the desktop, multi-tab + multi-session, screencast recording, full-desktop screen recording with HUD
  • File transferpush_file / pull_file for moving artifacts between Docker and the desktop
  • Shellshell_execute runs commands on the user's machine with their identity
  • Notifications — native OS toasts with optional action buttons
  • Screenshotsdesktop_list_windows, desktop_screenshot_window, desktop_screenshot_screen

Plus a bridge SDK so the community can ship bridges for Altium, MATLAB, instrument SDKs, anything else — without coordinating with the Adom Desktop release cycle.


Install (per platform)

Docker side (Linux CLI)

# v1.4.x+: get the latest CLI binary from the wiki (single static file)
adom-wiki asset get apps/adom-desktop docker_binary -o /usr/local/bin/adom-desktop
chmod +x /usr/local/bin/adom-desktop
adom-desktop --version   # adom-desktop 1.8.31 (<sha>, built <ts>)
adom-desktop install     # deploys the skill, starts the relay on :8765/:8766

The CLI auto-detects the user's desktop via the direct API (~/.adom/direct-api-port, fallback range 8770-8779) and falls back to the WebSocket relay when not in direct mode.

Windows

Download the latest installer (Adom Desktop_<version>_x64-setup.exe). NSIS installer with POSTINSTALL auto-launch. v1.3.39+ auto-updates from the wiki on every launch + every 4h.

macOS

Download the .dmg from the wiki or GitHub Releases. Mount → drag to Applications → strip Gatekeeper quarantine on first launch:

xattr -cr "/Applications/Adom Desktop.app"

Linux (Ubuntu / Debian)

Either the .deb package or the standalone binary from the wiki:

sudo dpkg -i Adom-Desktop_<version>_amd64.deb
# OR standalone:
chmod +x adom-desktop-ubuntu-<version> && ./adom-desktop-ubuntu-<version>
# Optional runtime deps for full feature parity:
sudo apt install wmctrl xdotool imagemagick scrot libnotify-bin

Auto-start the relay on every Docker session

The relay is NOT started automatically when the Docker container boots. Every time this skill is invoked, run this idempotent block at the top of the session before any other adom-desktop subcommand:

if ! curl -sf http://127.0.0.1:8766/health >/dev/null 2>&1; then
  nohup adom-desktop serve > /tmp/adom-desktop-relay.log 2>&1 &
  disown
  for _ in 1 2 3 4 5 6; do
    sleep 0.5
    curl -sf http://127.0.0.1:8766/health >/dev/null 2>&1 && break
  done
fi
adom-desktop ping

nohup ... & disown (NOT plain &) is critical. Without nohup + disown the relay dies as soon as the tool call that started it ends, and the next adom-desktop command fails with Cannot reach relay server (port 8766).

If ping succeeds → desktop is connected, proceed. If it returns No desktop client connected → run adom-desktop setup_desktop and ask the user to verify the desktop app is running.


Bridge ecosystem

Bridge Status Verbs Wiki page
KiCad Official, bundled kicad_* (board/schematic open + DRC + symbol/footprint install + watch + screenshot) adom-desktop-kicad-bridge
Fusion 360 Official, bundled fusion_* (open + export STEP/IGES/STL/3MF/USDZ/OBJ/DXF/DWG/Gerbers + cloud search + EAGLE) adom-desktop-fusion-bridge
Puppeteer Official, bundled browser_* + desktop_* (browser automation + screen recording + multi-tab) adom-desktop-puppeteer-bridge
hello-python Sample hellopy_* (ping + echo, ~80 lines stdlib) adom-desktop-hello-python-bridge
hello-rust Sample hellors_* (ping + echo, ~140 lines, single static binary) adom-desktop-hello-rust-bridge

Browse the full bridges registry for everything installable + the submission flow for community bridges. Read the bridge SDK guide for the bridge.json schema, packaging, and lifecycle.

# Install any bridge from a manifest URL
adom-desktop bridge_install '{"manifestUrl":"https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/hello-python-bridge-manifest.json"}'

# Lifecycle controls
adom-desktop bridge_list
adom-desktop bridge_pause '{"name":"hello-python"}'
adom-desktop bridge_resume '{"name":"hello-python"}'
adom-desktop bridge_uninstall '{"name":"hello-python"}'

# Refresh any bridges with newer wiki manifests
adom-desktop refresh_bridges

Direct API (v1.8.31+)

When the Docker container and the user's machine can talk directly (cloud workspace + local laptop), the CLI prefers the direct API over the WebSocket relay:

  • Discovery file at ~/.adom/direct-api-port (host:port format) — written by Adom Desktop on every successful bind
  • Fallback port range 8770→8779 — if 8770 is held by a zombie socket from a previous session, Adom Desktop walks the range with SO_REUSEADDR until it finds a free port
  • Per-verb command timeouts — search / walk verbs get 620s; exports get 320s; everything else 120s
  • Graceful shutdown — Tauri's RunEvent::Exit triggers direct_api::shutdown() which cleans the discovery file
  • Live-owner probe before walking — 1s timeout (HD's Python bridges' slow /health works inside that window)

Override the bind address via ADOM_DIRECT_LISTEN_ADDR (default 127.0.0.1).


Screen recording (v1.3.30+)

Two recording surfaces:

  • Full desktop via Chrome getDisplayMedia + MediaRecorder in a small always-on-top HUD window. Reason is required and shown in the HUD. WebM output, audio optional. Single recorder window stays open across multiple clips in a session.
  • Per-tab via CDP Page.startScreencast — JPEG frames + concat manifest, muxed to WebM via ffmpeg. Concurrent recordings across multiple pup tabs are fine; no HUD.
# Desktop recording (HUD-visible)
adom-desktop desktop_record_start '{"reason":"Demo of pin-1 sign-off","monitor":"primary","fps":30}'
# ... drive activity ...
adom-desktop desktop_record_stop
adom-desktop desktop_recorder_close

# Per-tab recording (headless, concurrent OK)
adom-desktop browser_record_start '{"sessionId":"align","tabId":"tab-1"}'
adom-desktop browser_record_stop  '{"sessionId":"align","recordingId":"…"}'

Architecture notes for contributors

  • Two binaries: the CLI (~5 MB, cli/target/release/adom-desktop.exe, has serve command) vs. the Tauri GUI (~16 MB, src-tauri/target/release/adom-desktop.exe, connects to relay as client). Never copy one over the other.
  • Build matrix in CLAUDE.md documents which changes need which rebuilds. Plugin-only edits don't require a Tauri rebuild — sync to src-tauri/target/release/plugins/ + kill python.exe / node.exe so the next CLI call respawns the bridge from the new code.
  • Version bumps via python scripts/bump-version.py patch — propagates to VERSION + cli/Cargo.toml + src-tauri/tauri.conf.json together.
  • Releases are two artifacts on one tag: Windows installer built locally + Linux CLI built on Docker (scripts/release-publish.sh handles both).
  • Single source of truth for Docker Claude's knowledge of the CLI is cli/src/commands.rs's help map. Every new verb / arg / behavior change must update it before shipping.

Full contributor docs: CLAUDE.md in the repo.


Repo + license

The three official bridges live in their own repos:

(Private as of this version, going public after a review pass. Source is mirrored on each bridge's wiki page as a tarball + git bundle — no GitHub account required to fork.)