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
Download Amped.app from the latest release,
unzip it, and move it to /Applications. macOS 26 (Tahoe) or newer.
The build is not notarized. The first time you open it, right-click the app and choose Open.
Check for Updates looks at that releases page and, when a newer build exists, opens it so you can download and replace the app.
The menu
Click the pill in the menu bar:
| Toggle | What it does |
|---|---|
| Keep Awake (When Lid Is Open) | Prevents idle sleep while the lid is open. Uses an IOKit power assertion (same mechanism as caffeinate). No password needed. |
| When Lid Is Closed | One choice: Off, Keep Awake but Lock the Screen, or Keep Awake and Keep Screen Unlocked. Off lets the lid sleep the Mac. The other two keep it running with pmset -a disablesleep 1. Keep Awake but Lock the Screen locks the screen and turns the display off when you close the lid without an external display. Suppressing sleep also suppresses the usual lock-on-sleep, which is why Amped locks instead. Keep Awake and Keep Screen Unlocked leaves the desktop unlocked and turns the built-in backlight off, so the screen keeps drawing and can still be controlled. Anyone who opens the lid can use the Mac without a password. |
| Auto-off at 20% Battery | Safety 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 Login | Registers 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 preference is 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 choose Keep Awake but Lock the Screen or Keep Awake and Keep Screen Unlocked, Amped offers to set the helper up. Approve "Amped" once under System Settings → General → Login Items & Extensions, and from then on that choice 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:
| 1 | brew install xcodegen librsvg |
| 2 | ./build.sh # ad-hoc local build → ./dist (helper inactive; password fallback) |
| 3 | open 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):
| 1 | DEVELOPMENT_TEAM=82K3YC8HVF |
| 2 | CODE_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:
| 1 | cp -R dist/Amped.app /Applications/ # run from a stable location |
| 2 | open /Applications/Amped.app |
Then: choose Keep Awake but Lock the Screen → Set Up Helper… → approve Amped in System Settings → choose it 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):
| 1 | xcrun 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:
| 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.
Pushing to main publishes an unsigned GitHub Release. See docs/RELEASING.md.
Notarization is separate, and it is not part of that release yet.
To work on it in Xcode:
| 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 (
pillfamily) — 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.shrenders it into the asset catalog at all macOS sizes. To make a proper Liquid Glass icon, openamped.svgin Icon Composer, refine the layers, and export an.iconto 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
| 1 | Sources/ (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 |
| 13 | Helper/ (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 |
| 17 | Shared/ (compiled into both targets) |
| 18 | HelperProtocol.swift the XPC contract |
| 19 | HelperConstants.swift identifiers / service names |
| 20 | CodeSigning.swift Team-ID requirement helpers |
| 21 | icon/ amped.svg + render script |
| 22 | project.yml XcodeGen project (app + helper targets) |
| 23 | build.sh one-shot local / signed build |
| 24 | notarize.sh notarytool submit + stapler staple |
| 25 | .env.example signing / notary config template |