How to keep builds and coding agents running when you leave your Mac
You start a long job (a coding agent on a real task, a full test run, a big build), go for lunch, and come back to find it did four minutes of work and then waited for fifty-six. Almost always, one of three things happened. Each has a simple fix.
1. Your Mac went to sleep
A sleeping Mac runs nothing: not the job, not its tests, not the network connection it depends on. macOS puts a Mac to sleep after it's been idle for a while, and a MacBook sleeps as soon as you close the lid.
Keep it awake for one job: caffeinate
caffeinate ships with macOS. Put it in front of a command, and the Mac stays awake until that command finishes:
caffeinate -i npm run build
-i prevents idle sleep. Add -s to also prevent system sleep while the Mac is on power, or -d to keep the display on. To cover something that's already running, point caffeinate at its process ID:
caffeinate -i -w 48213
To see what's currently keeping your Mac awake (or not), run pmset -g assertions. Every flag is explained in caffeinate: keep your Mac awake from the terminal.
Keep it awake while plugged in: System Settings
- MacBooks: System Settings → Battery → Options → turn on Prevent automatic sleeping on power adapter when the display is off.
- Desktop Macs: System Settings → Energy → turn on Prevent automatic sleeping when the display is off.
The display can still turn off, which saves power, while the work carries on.
The lid
Closing a MacBook's lid puts it to sleep, and caffeinate doesn't change that. The supported exception is closed-display mode: the Mac is on power with an external display, keyboard and mouse connected. Some third-party utilities offer a lid-closed mode too; read their caveats about heat before using one in a bag. The simplest rule: if an agent is working, leave the lid open and the charger in.
2. The session died when you left
If the job runs in a terminal window and you reach it over SSH, it's tied to that connection. When your phone drops the connection, the program can be killed with it. Two ways around this:
- A terminal multiplexer. Start
tmux(orscreen) first, run the job inside it, and reattach later withtmux attach. The session belongs to tmux, not to your connection. You have to remember to do it before starting the job. - A session that lives on the Mac by design. In PandaSend, every terminal runs in a background process on your Mac. Closing the window, losing your phone's signal or even quitting and updating the app doesn't end it. You open the same session again from whichever device you have.
For non-interactive jobs, nohup your-command > job.log 2>&1 & also works, but a job that asks questions needs a live terminal to ask them in. More options, from disown to launchd, in keeping a process running after you close the terminal.
3. The job is waiting for you
Coding agents ask before they edit files or run commands, and that's a feature. It does mean that an hour-long task can spend most of the hour waiting for a "y".
- Pre-approve the boring parts. Most coding agents let you allow specific tools and commands in advance, and deploy and release scripts usually have a non-interactive flag. Allow only what you'd be happy to approve without looking.
- Break big tasks into steps that can each finish without you, and give each one a way to check its own work, such as a test command.
- Answer from wherever you are. This is what PandaSend is for: the question shows up in the session on your phone, you type the answer, and the job carries on while you finish your coffee.
A setup that works
- Plug the Mac in and turn on the "prevent automatic sleeping" setting above, or run agents under
caffeinate -i. - Start the job in a session that outlives your connection: tmux, or a PandaSend session.
- Pre-approve the safe, repetitive actions; keep approval for anything destructive.
- Check in from your phone when you like, and answer when it asks.
None of this is complicated, but skipping any one of the three is how an afternoon of agent work turns into ten minutes.