I caught myself walking back to my laptop at 11pm for the third time that night, just to check what the OpenClaw agent was doing on it. So I built the iOS app I kept wishing existed. iOS went live last week.
This is the technical writeup — the architecture, the WebSocket pipeline, and the bug that made me question my entire life for two days.
What I built
Aerostack — a phone-native control plane for OpenClaw / Claude Code-style agents running on your own machine (laptop, desktop, home server, VPS). Live thinking stream, swipe-to-approve with glob policies, edit-args-before-approve, agent chat from your phone, MCP / skills / plugins / channels manageable from the device.
Stack:
Mobile: Flutter 3.27 (Dart 3.11) + Riverpod 3 + GoRouter
WebSocket: web_socket_channel (Dart side) ↔ Cloudflare Durable Object (relay side)
Daemon: TypeScript / Node ( aerostack/gateway on npm, MIT) — runs on your machine
Relay: Cloudflare Workers + Durable Objects — stateless, no DB writes for prompts/transcripts
Storage on…