Repository navigation
Decaffeinate - v1.0.0
What it does
- Keeps a MacBook awake with the lid closed, using the system sleep setting (
pmset disablesleep). Power assertions likecaffeinatedon't survive a lid close. - Switches to Low Power Mode and turns the display off while the lid is closed. When the lid opens, it restores your exact battery and charger settings.
- Lets the Mac sleep anyway on serious heat, or when the battery drops below your limit (15% by default, configurable).
- Keeps working behind the lock screen. Keep awake when screen locked is optional.
- Logging out or switching users gives normal lid-close sleep. A connected external display is treated as a desk setup and left alone.
- Shows your Mac's own measured power draw with the lid open and closed.
- Prevents idle sleep with the lid open while the app is running. The display still turns off.
Setup and distribution
- Ships as a
.dmgwith a universal build (Apple silicon and Intel), for macOS 13+. - The app is ad-hoc signed, not notarized. The README explains the one-time Open Anyway step.
- The first launch asks for admin rights once (Install…). It installs a sudoers rule limited to the exact
pmsetsleep and Low Power commands. - The helper is required at launch. If the rule disappears while the app runs, the install is offered again.
- Uninstall… in the menu turns sleep back on and removes the helper, watchdog, login item and settings. It then moves the app to the Bin.
Safety
- A background watchdog (LaunchAgent) turns lid-close sleep back on within a minute if the app crashes or is force-quit.
- The watchdog does not restore Low Power Mode: it stays on until you open Decaffeinate again or turn it off in System Settings › Battery.
- The app warns at launch and adds a menu item if macOS has the watchdog switched off.
- The sudoers temp file is now created as root, not in the user's temp dir (hardening fix).
Updates and footprint
- The update check is opt-in. Check for updates… checks once, and Check for updates daily is off by default.
- Each check is one anonymous request for this repo's latest release. Nothing is downloaded or installed automatically.
- About 25 MB of memory and about 0% CPU while waiting. The lid timer is coalesced.
- New coffee-cup icon (Lucide) for the menu bar and the app, replacing the flame.
Changes from Pilot Light
- Rebranded to Decaffeinate and restructured into one source file per domain.
- It uses its own helper, so remove Pilot Light's helper first (Remove helper… in its menu, or
sudo rm /etc/sudoers.d/pilotlight). Otherwise the two apps fight over the samepmsetsetting.
What's Changed
- chore: clean up the fork, rebrand to Decaffeinate, add macOS CI by @dstmrk in #1
- perf: coalesce the lid timer and drain run() output before waiting by @dstmrk in #3
- feat: require the helper at launch, replace Remove helper with Uninstall by @dstmrk in #4
- feat: replace the menu bar flame with a coffee cup by @dstmrk in #6
- feat: Lucide coffee icon for the menu bar and the app, rendered at build time by @dstmrk in #7
- ci: publish a .dmg release on v* tags, move timeouts to steps by @dstmrk in #8
- fix: re-offer the helper install when the sudoers rule vanishes while running by @dstmrk in #9
- test: cover isArmed, the sudoers rule and the watchdog whitelist by @dstmrk in #10
- feat: warn when the crash watchdog is not running by @dstmrk in #11
- fix: create the sudoers temp file as root, not in the user's temp dir by @dstmrk in #12
- build: take the default version from the latest git tag by @dstmrk in #13
- docs: say a crash leaves Low Power Mode on until the next launch by @dstmrk in #15
- feat: opt-in update check against this fork's releases by @dstmrk in #16
- refactor: split main.swift into one file per domain under Sources/ by @dstmrk in #17
- ci: attach the dmg to a release published on GitHub by @dstmrk in #18
- ci: run only the jobs a change can affect by @dstmrk in #19
Full Changelog: https://github.com/dstmrk/decaffeinate/commits/v1.0.0