Drive iOS Simulators (simctl, macOS + Xcode) and Android Emulators (adb) from a workspace tab: list/boot devices, install & launch apps, open deep links, screenshot, and (Android) tap/swipe/type, exposed as the grant-gated simulator.control capability.
The public home of
ryu-simulator. Source, builds, and releases live here — binaries for every platform are attached to each release.This tree is generated from the Ryu monorepo, so commits pushed here directly are replaced on the next sync. Pull requests are welcome — open them here and they are ported into the monorepo, then flow back out. Ryu as a whole: https://github.com/amajorai/ryu
App: Install (opens the Ryu desktop app and asks you to confirm)
CLI:
ryu apps add @ryu/simulatorThe source of record for this app: a dependency-free Bun/TypeScript
sidecar/ Ryu runs locally as a grant-gated control capability, plus the
manifest ui/. The sidecar builds standalone — cd sidecar && bun install && bun run build compiles a single ryu-simulator executable; each release attaches
the per-platform binaries.
Apache-2.0 — see LICENSE.
sidecar/—ryu-simulator(out-of-process, Node/Bun). A dependency-free control server (@ryu/simulator-sidecar) wrappingsimctl+adbbehind a loopback HTTP surface. No dependency onapps/core; compiled bybun build --compileinto aryu-simulatorbinary resolved viaRYU_SIMULATOR_BINelseryu-simulatoronPATH(~/.ryu/bin). Seesidecar/README.mdfor the full control API.ui/— the manifest (manifest.json). No companion UI of its own; the desktop Simulator panel (a dedicatedsimulatorworkspace TabKind) is the consumer.runnables: [].
- Sidecar:
simulatoron:7994,command: "ryu-simulator",command_env: RYU_SIMULATOR_BIN,port_env: RYU_SIMULATOR_PORT,health_path: /health,lazy: truewithidle_stop_secs: 300. Declared HTTP routes:/,/health,/capabilities,/devices, and per-deviceboot/shutdown/install/launch/openurl/screenshot/tap/swipe/text/key. - Provides: capability
simulator.control(v1.0.0) → sidecarsimulator, route/, grantsimulator:control. - Grant:
simulator:control.
- Android: full control —
adb shell inputgives tap/swipe/text/key for free. - iOS:
simctlgives boot/install/launch/openurl/screenshot cleanly, but has no public coordinate tap/swipe. Those return anunsupportedresult for an iOS device; adding facebook/idb is the upgrade path.
The sidecar binds loopback only and fail-closes: every route except GET /health
requires a bearer resolved as RYU_EXT_TOKEN (Core's per-plugin secret, re-stamped on
each proxied hop) else RYU_SIMULATOR_TOKEN. If neither is set, protected routes
reject with 401.
Any control server that honors the same /devices* loopback contract and bearer auth
can replace the sidecar without touching Core — the command_env override points Core
at an alternative binary. The capability, not the process, is what the desktop panel
and agents bind to.