README.md

Amped ⚊

A tiny, completely native macOS menu bar app that keeps your Mac awake — an Amphetamine-style alternative whose party trick is keeping the Mac awake with the lid closed, using pmset disablesleep rather than caffeinate alone.

No window, no settings sheet, no Dock icon. Just a pill in your menu bar and a handful of switches.

Install

sh
1brew install --cask gustaferiksson/tap/amped

Or grab the notarized Amped.app from the latest release and drop it in /Applications. macOS 26 (Tahoe) or newer.

The menu

Click the pill in the menu bar:

ToggleWhat it does
Keep AwakePrevents idle sleep while the lid is open. Uses an IOKit power assertion (same mechanism as caffeinate). No password needed.
Allow Lid ClosedAlso stays awake with the lid closed (clamshell). Runs pmset -a disablesleep 1, the only thing that overrides clamshell sleep. An independent switch — it keeps the Mac awake on its own (it holds the idle-sleep assertion internally) without flipping the Keep Awake toggle.
Lock Screen on Lid CloseSecurity guard for lid-closed mode: the instant the lid shuts, Amped locks the screen so the Mac keeps running but stays behind your password. Without it, suppressing sleep also suppresses the usual lock-on-sleep, leaving a closed lid awake and unlocked. On by default; remembered between launches.
Auto-off at 20% BatterySafety net: when on battery and the charge drops to 20% or below, Amped releases everything so the Mac can sleep normally. Remembered between launches.
Launch at LoginRegisters Amped as a login item (via SMAppService) so the pill is there every time you log in.

The menu bar pill reflects the state at a glance:

  • pill — sleep allowed (off)
  • pill.fill — awake (lid open)
  • pills.fill — awake with the lid closed

A status line shows the current state and battery level. ⌘Q quits.

On launch Amped starts with everything off (so it never surprises you by blocking sleep or prompting). Only the Auto-off and Lock Screen on Lid Close preferences are remembered. When it quits it always restores normal sleep behaviour.

How lid-closed mode stays passwordless

Keeping a Mac awake with the lid shut requires flipping the system disablesleep flag, which only root can do. Amped does this through a small privileged helper — a root LaunchDaemon embedded in the app bundle that the app talks to over XPC. The XPC channel is locked to Amped's own Developer-ID Team ID (setCodeSigningRequirement), so nothing but Amped's signed app can reach the helper, and the helper does exactly one thing: pmset disablesleep on/off.

The first time you enable Allow Lid Closed, Amped offers to set the helper up. Approve "Amped" once under System Settings → General → Login Items & Extensions, and from then on the lid toggle is silent — which also lets Auto-off at 20% drop clamshell mode while the lid is shut and you're away. Prefer not to? Just This Time keeps the Mac awake now with a single password prompt and installs nothing. Remove the helper anytime from that same System Settings pane (it's visible there, unlike a hidden sudoers rule); the setup offer reappears the next time you enable lid-closed mode.

The helper only runs in a properly signed build. In an unsigned local build it can't be approved, so lid mode falls back to a password prompt on every toggle. Build signed (below) to exercise the real path.

Build & run

Requires Xcode, plus two Homebrew tools:

sh
1brew install xcodegen librsvg
2./build.sh # ad-hoc local build → ./dist (helper inactive; password fallback)
3open dist/Amped.app # the pill appears in your menu bar

Signed build (helper works)

Signing config lives in .env (git-ignored; copy from .env.example):

sh
1DEVELOPMENT_TEAM=82K3YC8HVF
2CODE_SIGN_IDENTITY="Developer ID Application"

Then ./build.sh produces a build that meets Apple's notarization requirements: Developer ID signing, Hardened Runtime on both the app and the helper, a secure timestamp, and no get-task-allow entitlement. Install and try it:

sh
1cp -R dist/Amped.app /Applications/ # run from a stable location
2open /Applications/Amped.app

Then: enable Allow Lid Closed → Set Up Helper… → approve Amped in System Settings → toggle Allow Lid Closed again — it's now silent. (No Team ID is hard-coded: the app reads its own at runtime to pin the XPC channel to the same team.)

Notarize & ship

One-time: create a notarytool keychain profile (the password is an app-specific password from appleid.apple.com, not your Apple ID password):

sh
1xcrun notarytool store-credentials "Amped" \
2 --apple-id "you@example.com" --team-id 82K3YC8HVF --password "xxxx-xxxx-xxxx-xxxx"

Set NOTARY_PROFILE=Amped in .env, then after a signed ./build.sh:

sh
1./notarize.sh # ditto-zips, notarytool submit --wait, stapler staple, verifies

Distribute the stapled dist/Amped.app (zip or DMG). altool is dead since Nov 2023 — this uses notarytool.

For automated releases — push a v* tag and CI produces the notarized GitHub Release and bumps the Homebrew cask — see docs/RELEASING.md.

To work on it in Xcode:

sh
1./icon/generate-icons.sh && xcodegen generate && open Amped.xcodeproj

(The .xcodeproj is generated from project.yml and is git-ignored.)

The icon

  • Menu bar: an SF Symbol (pill family) — Apple permits SF Symbols in your own UI, and they adapt to light/dark and the focus state automatically.
  • App icon: icon/amped.svg (a two-tone capsule). icon/generate-icons.sh renders it into the asset catalog at all macOS sizes. To make a proper Liquid Glass icon, open amped.svg in Icon Composer, refine the layers, and export an .icon to drop into the project.

A note on the App Store

The lid-closed feature relies on pmset disablesleep / a privileged helper, which a sandboxed App Store build cannot do. Ship it as a notarized Developer ID app. An App Store version would have to drop the clamshell feature.

Project layout

1Sources/ (the app)
2 AmpedApp.swift @main App + MenuBarExtra
3 MenuContent.swift the dropdown (toggles + status + quit)
4 MenuBarLabel.swift the pill SF Symbol that reflects state
5 SleepController.swift state, battery polling, auto-off safety net
6 PowerAssertion.swift IOKit power assertion wrapper (idle sleep)
7 Privileged.swift routes pmset to the helper, else an admin prompt
8 HelperClient.swift registers/calls the helper (SMAppService + XPC)
9 Battery.swift battery % + on-battery via IOKit power sources
10 LoginItem.swift launch-at-login via SMAppService
11 Prompts.swift first-use helper-setup dialogs
12 AppDelegate.swift restores normal sleep on quit
13Helper/ (the privileged root daemon)
14 main.swift XPC listener entry point
15 HelperService.swift runs pmset as root; pins the client by Team ID
16 dev.gustaf.Amped.Helper.plist LaunchDaemon definition
17Shared/ (compiled into both targets)
18 HelperProtocol.swift the XPC contract
19 HelperConstants.swift identifiers / service names
20 CodeSigning.swift Team-ID requirement helpers
21icon/ amped.svg + render script
22project.yml XcodeGen project (app + helper targets)
23build.sh one-shot local / signed build
24notarize.sh notarytool submit + stapler staple
25.env.example signing / notary config template