Would love to learn more about your setup as I put something fairly similar for myself and looking for ways to improve it even further.
My goal is to have agents work independently from any of my devices (hence VM setup) and to access any session at any time.
My setup so far:
A simple VM on Google Cloud. Always on. Repo lives in there. Claude Code, Codex, Gemini installed as CLIs.
The agents run inside terminal sessions on the VM, managed by zmx (small Zig project, keeps a raw PTY around). Session keeps running regardless of what’s connected.
From the Mac, transport is Eternal Terminal on port 2022. ET is like SSH but reconnects silently. I never see the disconnect.
From the phone, transport is mosh. UDP based, roams gracefully (cellular to wifi and back). Client is Moshi (iOS), renders the terminal and manages tmux sessions well. Moshi needs alternate screen for scrollback, so on the phone path zmx is wrapped in tmux. The tmux is just an adapter for the phone client, not the persistence layer.
The point: both transports attach to the same zmx session. Same scrollback, same prompt, same agent state. Laptop, phone, both at once, all clients of the same long running shell on the VM.
The annoying part was scrollback: duplicated history, lack of native scroll, lagging. zmx avoids the alternate screen (tmux uses it by default, which makes scrolling agent output awkward). Combined with Claude’s --no-flicker flag, the terminal’s own scrollback ends up actually usable.
I wanted to avoid manually switching scroll modes and re-attaching. Moshi sees all my current sessions on the Mac, I just tap and swipe between them. Awesome.
A few shell functions hide the layering on the Mac with a few commands and keyboard shortcuts.