Close the lid. Walk away. Let
claudekeep cooking in your bag.
A macOS menu bar utility that keeps your Mac awake — even with the lid closed — while Claude Code or Codex CLI is mid-turn, and lets it sleep the moment they finish.
Download: grab the latest
MacLid.zipfrom the Releases page, unzip, and dragMacLid.appto~/Applications(or anywhere you like). Open it, click the menu bar ☕, and toggle Awake.
- Awake — master keep-awake toggle, holding
PreventUserIdleSystemSleep. - Wait for AI agent turn — when on, the system-sleep assertion is only held while at least one tracked agent is in turn or waiting on input. Live status for each agent is shown inline.
- Timer — auto-disarm after 15 m / 30 m / 1 h / 2 h / 4 h.
- Stay awake with lid closed — runs
pmset -a disablesleep 1. By default each toggle prompts for an admin password (osascript). Use More → "Install silent lid helper" to install a tightly-scoped/etc/sudoers.d/maclidrule (one prompt, silent forever after). - Keep display awake — holds
PreventUserIdleDisplaySleep. - More — install/remove silent helper, reinstall agent hooks, reset agent state, open the data dir.
Requires the Xcode 15+ Command Line Tools (Swift 5.9, macOS 13 SDK).
make app # produces ./MacLid.app
make run # builds and launches
make install-user # copies to ~/Applications/MacLid.appOn first launch, MacLid drops two tiny shell scripts into
~/.mac-lid/hooks/ and registers them as hooks in Claude Code's
~/.claude/settings.json and Codex CLI's ~/.codex/config.toml.
- Claude Code:
UserPromptSubmit→in_turn,Stop→idle,Notification→waiting,SessionStart/SessionEnd→idle. - Codex CLI:
UserPromptSubmit→in_turn,Stop→idle,SessionStart→idle, plus thenotifycommand as a backup foragent-turn-complete.
Each hook writes a JSON state file at ~/.mac-lid/state/<agent>.json
via atomic rename. MacLid watches that directory with DispatchSource.
If you don't want MacLid touching your agent configs, choose Remove agent hooks from the More menu.
IOPMAssertion types do not override clamshell sleep on macOS — only
pmset -a disablesleep 1 does, and that requires root. There are three
ways MacLid drives that:
sudorule (recommended) — Menu → More → "Install silent lid helper". Asks for your password once, writes a 1-line file to/etc/sudoers.d/maclidwhitelisting onlypmset -a disablesleep 0|1. Subsequent toggles are silent.- XPC helper via
SMAppService— for users who install MacLid into/Applications(Apple gates daemon registration to that path). The bundle shipsContents/Library/LaunchDaemons/com.schemalabs.maclid.helper.plistready to register. - osascript prompt (default fallback) — every toggle asks for an admin password.
If MacLid is force-killed while the toggle is on, your Mac will keep
SleepDisabled 1 until you re-launch MacLid (which resyncs) or run
sudo pmset -a disablesleep 0 manually.
Sources/MacLid/
├── MacLidApp.swift # @main, MenuBarExtra
├── AppModel.swift # cross-cutting state
├── TimerController.swift
├── Power/
│ ├── AssertionManager.swift # IOKit IOPMAssertion wrapper
│ └── ClamshellManager.swift # pmset disablesleep via osascript
├── Agents/
│ ├── AgentState.swift
│ └── AgentStateStore.swift # FS watcher
├── Integration/
│ └── HookInstaller.swift # writes settings.json / config.toml
└── Views/
├── MenuPanel.swift
├── ToggleRow.swift
└── AgentStatusRow.swift
Resources/
├── Info.plist
└── Hooks/
├── claude-state.sh
└── codex-state.sh
MIT — © 2026 Emmanuel Haankwenda.
Inspired by a tweet from @amideau showing a similar menu mockup. Built with Claude Code.