shuttle

Architecture

Processes

agent (Claude Code, Codex, Cursor)
  │ MCP, JSON-RPC over stdio
  ▼
shuttle mcp ───────── one per agent session; a thin proxy
  │ desk wire (u32 length + JSON) over a 0600 unix socket or a local-only named pipe
  ▼
shuttle serve ─────── one per user; owns the desktop, the model keys and the safety controls
  ├── desk verbs ─────────── AX (macOS), UI Automation (Windows), AT-SPI (Linux)
  ├── cua-driver ─────────── the bundled driver, a child on the daemon's own socket or pipe: input, window focus, launch, capture
  ├── node ───────────────── child process per gui_plan / script_run, running the runtime;
  │                          desk.mts (desk.mjs in the archives) calls back over the same desk wire
  └── service plugins ────── long-lived children from the plugin directory, none by default; the daemon
                             splices each call of a service tool to the service's own socket

What shuttle never does

shuttle is thin and embeddable: it sends each model call once, non-streaming, to the one OpenAI-compatible endpoint and the decisions URL it is configured with. It never speaks a vendor’s native API, streams, caches, retries or fails over across vendors, routes between models, or bills. Anyone who needs those points base_url and decisions_url at a gateway that does them. Beyond that configured endpoint, shuttle depends on no hosted service.

Components

Path Role
crates/desk-core (shuttle-desk-core, lib desk_core) The desk wire, the desk call arguments and the pure window and name matching every desk backend shares
crates/desk (shuttle-desk) The desk verbs over the macOS AX, Windows UIA and Linux AT-SPI trees, the cua-driver client, and on Linux XTest typing, MIT-SHM capture and launch scopes
crates/android (shuttle-android) The desk verbs on an Android device over adb: the UI server’s element trees and screenshots, input (taps and single keys), screencap as the fallback and a scrcpy paste
android/ui The UI server the Android desk pushes to the device and runs under app_process, built into shuttle-ui.jar
crates/models (shuttle-models) The model calls: chat completions and decisions over one OpenAI-compatible endpoint, a model name per role; usable as a library with a Config value
crates/shuttle The shuttle binary: the MCP proxy (mcp), the daemon with its script runner and service plugins (serve), desk VERB, stop and resume, and the safety controls (kill hotkey, indicator, confirm dialog)
runtime/lib desk.mts (the desk API for scripts) and gui_plan.mts (the plan executor, flows and replays)
runtime/test Node tests that drive the runtime against fake desk sockets and fake model servers
packaging The release archive builder, the runtime type stripper, the third-party pins, the macOS bundle template and the installers