Skip to content

Decaffeinate - v1.0.0

Choose a tag to compare

@dstmrk dstmrk released this 22 Oct 21:29
· 10 commits to main since this release
4df3ab3

What it does

  • Keeps a MacBook awake with the lid closed, using the system sleep setting (pmset disablesleep). Power assertions like caffeinate don'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 .dmg with 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 pmset sleep 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 same pmset setting.

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