← back

Moving Claude and Codex off my laptop

A cloud VM, persistent terminal sessions, and the same Claude Code session on Mac and phone. The friction, the setup, and the open question.


I got hooked on coding with agents, building a few things for our company and for fun.

Often on the move so keeping the laptop open while agents run is super annoying. The sessions get interrupted anyway, connectivity changes.

Can’t check progress from mobile. Can’t give Claude the next thing to do. /remote-control in Claude exists but it sucks. The agent still runs on my laptop, close the lid and it stops.

Some people set up a Mac mini at home. That feels weird. The agents run in the cloud, the repo lives on GitHub. Why pipe all of this through a box in my flat?

A VM in the cloud feels more right. Never sleeps, repo lives there, no desktop dependency, reasonable security.

This Ona piece captured the feeling well: https://ona.com/stories/the-last-year-of-localhost.

I gave plain SSH a try. Half baked. Lag, drops on every network blip, reconnect dance is a disaster.

People often suggest tmux for the persistence side, so I tried that and ended up assembling something with more layers to make it feel smooth.

Here’s the setup:

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.

Every person I’ve shown this to has the same wtf/wow reaction. They watch me start something on my laptop, close the lid, pull out my phone, pick up exactly where the agent was.

And really, this should be how it works from day one. How did we end up with the bar so low that such a basic flow gets treated as a revelation?

Everything is in the cloud, but somehow agents inherited the localhost assumption from the previous era.

I thought it would be cool to package this so people don’t have to assemble the layers themselves.

So few things I’d love thoughts on:

  1. How are you working with coding agents from outside your laptop? Anyone else ended up here?

  2. What’s your take on this stack? What would you do differently?

  3. Anyone want to collab on turning this into a clean CLI? Open source, no commercial gatekeeping.

Honestly I think Anthropic, OpenAI and Google should ship this themselves at some point. Until they do, here we are.