- Shell 69.6%
- Swift 28.1%
- Makefile 2.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
0.1.x reference-counted Claude Code *sessions* from SessionStart/SessionEnd,
so a session left open in a terminal kept the Mac awake for as long as the
process lived — whether or not anything was running. An idle session
forgotten overnight was enough to keep the Mac up until morning.
Keep-awake is now driven by turns. The hooks (UserPromptSubmit -> busy,
Stop -> idle, SessionEnd -> end) write one marker per session, and a small
Swift agent (src/, built as clawdphetamine.app) owns an Amphetamine session
while any marker is live, ending it once the last turn has been idle for ten
minutes.
Three ways the Mac could stay awake for good are closed with it:
* Stop does not fire when a turn is interrupted, so a "busy" marker is only
trusted while the session transcript is still being written to — twenty
minutes of silence and it is dropped.
* The Amphetamine sessions the agent starts are finite (60 minutes, renewed
while the work continues), so even a killed agent cannot keep the Mac
awake beyond the hour.
* On shutdown the agent ends the session only while it still looks like the
one it started; a session you started yourself is never touched.
`clawdphetamine install` removes the 0.1.x hooks on upgrade.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
| assets | ||
| bin | ||
| src | ||
| test | ||
| .gitignore | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
clawdphetamine
Keeps your Mac awake — via Amphetamine — exactly while Claude Code is working.
Long agent runs die quietly when the Mac goes to sleep. clawdphetamine keeps it awake for the length of a turn and a short grace period after it, then lets the Mac sleep again — including when you leave a Claude Code session open in a terminal overnight.
A tiny background agent (clawdphetamine.app, ~120 KB of Swift, no menu-bar
icon) owns an Amphetamine session while work is in flight. Claude Code hooks tell
it when that is:
| hook | verb | effect |
|---|---|---|
UserPromptSubmit |
busy |
a turn started — start the agent, start a keep-awake session |
Stop |
idle |
the turn ended — release after the grace window (10 min) |
SessionEnd |
end |
the session is gone — drop its marker |
Requirements
- macOS 11+ with Amphetamine installed and running (free, Mac App Store)
- Claude Code
- Homebrew to install
Install
brew tap olerap/tap https://git.oles.network/olerap/homebrew-tap.git
brew trust olerap/tap
brew install clawdphetamine
clawdphetamine install
clawdphetamine install merges the three hooks into ~/.claude/settings.json
(idempotently — existing settings are preserved and backed up first):
{
"hooks": {
"UserPromptSubmit": [ { "hooks": [ { "type": "command", "command": "/opt/homebrew/bin/clawdphetamine-hook busy", "timeout": 10 } ] } ],
"Stop": [ { "hooks": [ { "type": "command", "command": "/opt/homebrew/bin/clawdphetamine-hook idle", "timeout": 10 } ] } ],
"SessionEnd": [ { "hooks": [ { "type": "command", "command": "/opt/homebrew/bin/clawdphetamine-hook end", "timeout": 10 } ] } ]
}
}
Hooks take effect for sessions started afterwards. The first time the agent starts an Amphetamine session, macOS asks for Automation permission for clawdphetamine — approve it (see Troubleshooting).
Upgrading from 0.1.x? Run
clawdphetamine installonce. 0.1.x kept the Mac awake for a whole Claude Code session viaSessionStart/SessionEnd, so an idle session left open in a terminal kept the Mac awake indefinitely. Those hooks are removed automatically.
Usage
Normally you never run anything yourself — the hooks do.
| command | what it does |
|---|---|
clawdphetamine status |
tracked sessions, agent and Amphetamine state, hook installation |
clawdphetamine reset |
clear tracked sessions, stop the agent, end its keep-awake session |
clawdphetamine install |
add the hooks to ~/.claude/settings.json |
clawdphetamine uninstall |
remove exactly those hooks again |
$ clawdphetamine status
clawdphetamine 0.2.0
Amphetamine: installed: yes, running: yes
Keep-awake: active (started by clawdphetamine, 52m left)
Agent: running (pid 41207)
Claude sessions: 2
- pid 48112 busy last activity 2s ago
- pid 49203 idle last activity 4m ago
Hooks: installed (/Users/you/.claude/settings.json)
Display sleep: allow
State dir: /Users/you/.local/state/clawdphetamine
Configuration
Optional config file ~/.config/clawdphetamine/config:
# allow — Mac stays awake, display may sleep (default)
# prevent — display is kept awake too
# default — defer to Amphetamine's own default-session preferences
display_sleep = allow
The CLAWDPHETAMINE_DISPLAY_SLEEP environment variable overrides the file for
the CLI; the agent reads the file.
How it works
- The hook writes one marker per Claude Code session in
~/.local/state/clawdphetamine/sessions/, named after theclaudepid. Line 1 isbusyoridle; line 2 is that session's transcript path. - The agent polls the markers every 5 s. A marker counts as live while it is
busy, or wentidleless than 10 minutes ago. When none are left it ends its Amphetamine session and quits — its own process is the refcount. - A
busymarker is only trusted while something is actually happening. Claude Code appends to the transcript with every message and tool call, so its mtime is an activity heartbeat: 20 minutes of complete silence and the marker is dropped. This matters becauseStopdoes not fire when you interrupt a turn — without the heartbeat an interrupted turn would keep the Mac awake for as long as the terminal stayed open. - A marker whose pid is gone is always pruned (crash/quit safety).
- The Amphetamine sessions the agent starts are finite (60 minutes, renewed while work continues). If the agent is ever killed outright, the Mac falls asleep within the hour instead of never.
- Sessions clawdphetamine did not start — yours from the menu bar, Trigger-based ones — are never ended, and while one is active the agent does not start its own; the Mac is being kept awake either way.
Troubleshooting
macOS Automation permission (the usual suspect). The agent talks to
Amphetamine over Apple events, which triggers a consent prompt the first time.
If it was denied or never answered, clawdphetamine status shows Keep-awake: unknown (osascript failed — check Automation permissions). Fix: System Settings
→ Privacy & Security → Automation → clawdphetamine → enable Amphetamine.
Amphetamine isn't running. The agent keeps polling and does nothing rather than break your session. Open Amphetamine.app and, ideally, add it as a login item (Amphetamine → Preferences → Launch at login).
Mac stays awake although nothing is running. clawdphetamine status shows
what is tracked and who owns the keep-awake session; clawdphetamine reset
clears everything and ends a session the agent left behind.
Hooks don't seem to fire. They apply only to sessions started after
clawdphetamine install. Check clawdphetamine status (Hooks: line) and look
for the entries in ~/.claude/settings.json. Claude Code shows hook errors in
its debug output (claude --debug).
Uninstall
clawdphetamine uninstall # removes the hooks
clawdphetamine reset # clears state, stops the agent
brew uninstall clawdphetamine
Development
brew install shellcheck bats-core librsvg # dev tools only
make check # shellcheck + bats suites
make build # build/clawdphetamine.app
make install # copy it to ~/Applications
bin/ holds the CLI and the hook (bash), src/ the agent (Swift), test/ the
bats suites (Amphetamine, pgrep and open are mocked), assets/ the icon sources.