Adrafinil: a macOS menu bar app that keeps your Mac awake only while AI coding agents work
Keep your Mac awake only while AI coding agents are working
At a glance
- What is it?
- Adrafinil holds sleep assertions only while an agent session is active, using hooks, a reference-counted daemon and a privileged helper for clamshell sleep. It is deliberately not an always-on caffeinate replacement.
- Who is it for?
- Adopt Adrafinil if you run Claude Code, Codex, Cursor or a similar agent on a Mac that must survive a closed lid mid-task, and you are willing to grant one privileged helper at install. Skip it if you are on macOS 15 Sequoia (use valentine's backport fork), if you want an unconditional always-on wake utility, or if you cannot grant admin rights and still need the CLI on PATH.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 25 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 18, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: agents outlive the lid
A coding agent started at midnight is still mid-task when you close the lid. macOS treats that as a request to sleep, and the session dies or stalls. The usual fix is an always-on wake utility: caffeinate, Amphetamine, a pmset disablesleep toggle. Those keep the machine wired whether or not anything is running, which is exactly the wrong default for a laptop in a bag.
Adrafinil inverts the default. The README describes it as a macOS menu bar app that prevents sleep, including clamshell sleep, "exclusively while an AI coding agent has an active session." With zero sessions, sleep behavior is untouched. The target user is someone running Claude Code, Codex, Cursor, Gemini CLI, Aider, Hermes, OpenCode, Cline or Pi on a Mac and leaving long turns unattended. The project is MIT licensed, written in Swift, and the last push to main was on 2026-08-24.
Reference-counted assertions and the privileged helper split
The mechanism is a reference count over sleep assertions. Each agent turn acquires one, each turn end releases one, and sleep unblocks only when the last holder lets go. Overlapping sessions stack cleanly rather than fighting. The README claims acquire and release round-trip to the daemon in under 50ms, which matters because those calls sit inside an agent's hook path.
Two processes do the work. An unprivileged daemon owns all policy: which sessions exist, when to release, when to cut out on heat. A separate privileged helper, installed through SMAppService, exposes exactly one operation, setSleepBlocked(Bool). That is a sensible split. The helper is small enough to audit, and the interesting logic stays in a process that does not run as root.
The two sleep paths are different mechanisms. Idle sleep is held with a standard IOPMAssertion. Clamshell, lid-closed sleep needs pmset disablesleep, which is why root is required at all. The README states the author verified on-device that the cleaner private IOPMrootDomain paths do not keep a displayless lid-closed Mac awake, which is why the blunt pmset route was chosen. That is an honest trade-off: a public, coarser API over a private one that did not do the job.
Installing Adrafinil and holding sleep through one agent turn
The README points at a signed, notarized disk image on the releases page. Open it, drag Adrafinil to Applications, launch. The first launch asks for admin rights once to register the privileged helper. Homebrew users get the same DMG from the official cask:
brew install --cask adrafinilRequirements are narrow. macOS Tahoe 26.4 is what the author builds and tests on; earlier 26.x likely works but is untested. On macOS 15 Sequoia the README points to valentine's backport fork. Building from source needs Xcode 26+ with Swift 6 strict concurrency.
Building yourself is an Xcode flow, not a make target:
git clone https://github.com/kageroumado/adrafinil.git
cd adrafinil
open Adrafinil.xcodeprojSelect the Adrafinil scheme and Run. You must set a development team for code signing, because the daemon ships as a LaunchAgent and the helper as a LaunchDaemon.
For day-to-day use, the README describes a one-click installer that wires Adrafinil into the hook systems of nine agents. After that, an agent turn triggers acquire on start and release on end, and the menu bar shows awake while work is in flight. If you want to see the CLI the hooks call, the README names adrafinil acquire and adrafinil release, plus adrafinil hold for an agent that wants to stay awake past its reply. A non-admin install drops the CLI in ~/.local/bin instead of /usr/local/bin, so check which path your hooks reference.
Where Adrafinil is the wrong tool
The privileged helper is the first boundary. Overriding clamshell sleep requires root, and the standard install registers that helper through SMAppService. If your policy forbids a root LaunchDaemon, the lid-closed behavior is out of reach, and you are left with a more complicated caffeinate.
The second boundary is the platform. macOS 26.4 is the tested target, not a floor the README promises to support. Sequoia users are explicitly routed to a third-party backport fork, which means the maintainer of that fork, not this repository, owns your bug reports.
The third is failure detection. Hook integration only covers agents whose hooks are installed. The optional process-sniffing mode is a fallback for agents without hooks, but it depends on recognizing a running binary, and the README does not document a coverage list for that mode. If your agent is not among the nine named hook integrations and its process name is not recognized, Adrafinil simply will not acquire. You will discover this the way everyone discovers sleep bugs: by finding a dead session in the morning.
There is also a bag risk the project acknowledges. A lid-closed Mac with assertions held can heat up. The thermal cutout force-releases all assertions when skin or CPU temperature crosses a threshold, and idle release drops assertions whose owning process died or went CPU-idle for N minutes. Both are mitigations, not guarantees, and the README does not state the threshold values or the idle window.
Adrafinil versus caffeinate and Amphetamine
The comparison is about when the assertion exists, not whether it exists. caffeinate and Amphetamine are stimulants in the README's framing: they keep the machine awake for as long as you ask, independent of what is running. You start caffeinate, you stop caffeinate. Nothing in between knows whether an agent has work left.
Adrafinil is event-driven. Sleep is blocked when a session acquires an assertion and unblocked when the last one releases. That reference count is the whole difference. With three overlapping agent sessions, caffeinate would need three matching invocations or one long-running process you remember to kill; Adrafinil's count returns to zero on the last release without you tracking anything.
The cost of that design is dependency on integration. caffeinate works with any process because it does not care what the process is. Adrafinil works with agents it has been wired into, plus whatever its process sniffing recognizes. If your workflow is a long rsync or a local build, the manual Keep awake button covers it, but you are back to starting and stopping a hold by hand. That is the honest boundary between the two tools: one is unconditional and dumb, the other is conditional and needs to be told.
Maintenance, licence and what an upgrade costs you
The repository is not archived, and the last push was on 2026-08-24, three weeks before this writing. Releases v1.5.4, v1.6.0 and v1.7.0 landed within four days of each other in August 2026, which suggests the project was moving quickly at that point. Treat that as a snapshot, not a promise.
Upgrade cost is mostly hook drift. The one-click installer writes entries into the hook configs of nine different agents, and each of those agents ships its own config format and its own release cadence. When an agent changes how hooks are declared, the entry Adrafinil wrote can stop firing, and the symptom is silent: no error, just a Mac that sleeps mid-turn. The README does document a clean uninstall that removes every hook entry the app added, which is the right shape for this problem, but it also means re-running the installer after an agent upgrade is a reasonable habit.
The licence is MIT. That permits commercial use, modification and redistribution, and it ships with no warranty. The privileged helper is the part worth reading before you deploy this on a managed fleet: it runs as root, and while the README states it exposes only setSleepBlocked(Bool), that claim is about the code, not about your threat model. Nothing here is legal advice; if your organization has a policy on root LaunchDaemons, read Docs/ARCHITECTURE.md and the helper source first.
Editorial conclusion
Adopt Adrafinil if you run Claude Code, Codex, Cursor or a similar agent on a Mac that must survive a closed lid mid-task, and you are willing to grant one privileged helper at install. Skip it if you are on macOS 15 Sequoia (use valentine's backport fork), if you want an unconditional always-on wake utility, or if you cannot grant admin rights and still need the CLI on PATH. Before trusting it, verify three things yourself: that the one-click installer wrote the hook entries into each agent's config, that a manual Keep awake hold releases on Let it sleep, and that the thermal cutout fires in your lid-closed workload.
Frequently asked questions
What is Adrafinil used for?
Adrafinil is a macOS menu bar app that keeps the Mac awake only while an AI coding agent has an active session, including through a closed lid. With no agents running, normal sleep behavior is untouched.
Is Adrafinil a stimulant?
The README frames it as the opposite of one. It contrasts Adrafinil with caffeinate and Amphetamine, which it calls stimulants that keep the machine wired forever, and describes Adrafinil as doing nothing until an agent acquires it.
Does Adrafinil work without any agents running?
Yes, through the manual Keep awake button, which places a time-boxed hold even with no agents running. Let it sleep clears everything. The automatic path requires an agent session or optional process sniffing.
Which macOS versions does Adrafinil require?
The README says macOS Tahoe 26.4 is what the author builds and tests on, and that earlier 26.x likely runs it but is untested. On macOS 15 Sequoia it points to valentine's backport fork.
How do I install Adrafinil?
Download the signed, notarized disk image from the releases page, drag Adrafinil to Applications and launch; the first launch asks for admin rights once to register the privileged helper. Alternatively, the README gives brew install --cask adrafinil.
Can Adrafinil keep a Mac awake with the lid closed?
Yes, that is the clamshell case it is built for, and it is why root is needed. The README states Adrafinil uses pmset disablesleep for lid-closed sleep, isolated in a privileged helper that only exposes setSleepBlocked(Bool).
Community notes