Keep a MacBook running AI agents (Claude Code, Codex, etc.) around the clock — with the lid closed and the screen off — and how to undo it all.
"software engineers before vs after agents" — via @cormachayden_ on X. This repo is the fix for the laptop on the right.
- macOS System Settings' "never sleep" / "Prevent automatic sleeping" option only prevents idle sleep while the lid is open.
- Closing the lid always forces sleep, killing every running agent, SSH session, and background job. There is no setting in the UI to change this.
- If you block lid-close sleep the hard way (below), macOS then leaves the screen on inside the closed lid — wasted power and heat — because the display normally only turns off as part of full sleep.
This repo fixes all three, and everything is reversible.
./install.shThat's it. It asks for sudo once, then: close the lid → Mac keeps running, screen turns off within ~2 seconds. Reopen the lid (tap a key) to wake the display.
If keyboard or mouse input wakes an external display while the lid remains closed, enable the optional keep-displays-off mode:
./install.sh --keep-displays-offThis checks for recent keyboard and mouse activity every ~2 seconds while the
lid is closed, and re-blanks all connected displays only after input occurs.
Re-run ./install.sh without the flag to return to the default
close-transition-only behavior.
To also silence app and notification audio while the lid is closed, preserving and restoring your previous mute state when it opens:
./install.sh --keep-displays-off --mute-when-closedBoth options use the same lightweight lid watcher; no extra background process is installed. Omit either flag when re-running the installer to disable that option.
To revert everything back to normal macOS behavior:
./uninstall.shsudo pmset -a sleep 0 # never sleep on AC power or battery
# or, safer if the Mac is sometimes unplugged:
sudo pmset -c sleep 0 # never sleep on charger onlysudo pmset -a disablesleep 1This is the key one — it's what the Settings app can't do. After this, closing the lid does nothing to the system.
With disablesleep 1, macOS no longer blanks the screen on lid close, so a tiny
watcher does it instead: lid-display-off.sh polls the lid
sensor (ioreg … AppleClamshellState) every 2 seconds and runs
pmset displaysleepnow the moment the lid closes. Only the display sleeps — agents
keep running. A LaunchAgent (template) keeps the watcher
alive and starts it at login.
By default, display blanking happens only when the lid changes from open to closed. In
--keep-displays-off mode, it also checks macOS's keyboard/mouse idle timer
while the lid is closed and runs pmset displaysleepnow only after recent input.
This prevents keyboard or mouse activity from leaving an external display awake
without repeatedly issuing display-sleep commands when nobody is interacting
with the Mac.
With --mute-when-closed, the same watcher remembers the current macOS output
mute state once, then reasserts mute every ~2 seconds while the lid is closed.
This also retries failed mute commands and re-mutes the current output if an app,
volume control, or audio-route change unmutes it. Audio enforcement works in both
display modes; --keep-displays-off is not required for repeated muting.
When the lid opens, the watcher restores the remembered mute state, retrying if
restoration fails. The original state survives mute failures and watcher restarts.
pmset -g custom # sleep should be 0
pmset -g | grep SleepDisabled # should be 1
ioreg -r -k AppleClamshellState -d 4 | grep Clam # Yes = lid closed
launchctl list | grep lidwatch # watcher runningBest proof: close the lid and SSH in from your phone.
- Keep it plugged in. With
sleep 0on battery the Mac runs until the battery hits 0% and dies anyway. - Heat. Lid-closed running blocks some venting; avoid heavy sustained loads on a pillow/blanket, give it airflow.
- Manual sleep stops working. While
disablesleep 1is set, Apple menu → Sleep does nothing. Undo first if you actually want to sleep it. - Keep-displays-off mode is strict. Keyboard and mouse activity may briefly wake a display, but the watcher blanks it again within ~2 seconds. Open the lid or reinstall without the flag when you need to use an attached display normally.
- Mute-when-closed affects output audio. Alarms or other software that bypasses the normal macOS output-mute control may behave differently.
- Muting is polled, not instantaneous. A sound can briefly get through before the next ~2-second check after closing the lid or an external unmute. Muting also depends on macOS accepting the audio command; failures are retried.
- Instant screen-off shortcut:
Ctrl + Shift + Power (Touch ID key)blanks the display immediately at any time without sleeping anything.
sudo pmset -a disablesleep 0
sudo pmset -a sleep 1
launchctl bootout gui/$(id -u)/com.$(whoami).lidwatch
rm ~/Library/LaunchAgents/com.$(whoami).lidwatch.plist ~/bin/lid-display-off.sh| File | Purpose |
|---|---|
install.sh |
One-shot setup: pmset changes + installs & starts the watcher |
uninstall.sh |
Reverts everything to macOS defaults |
lid-display-off.sh |
Watcher: manages display blanking and optional lid-closed muting |
lidwatch.plist.template |
LaunchAgent that runs the watcher at login |
tests/test-lid-display-off.sh |
Verifies display and mute modes with mocked macOS commands |