Problem: You start a Claude Code task or an army of Claude Code agents, then you realize you need to step away. You can't close your Mac laptop because it would stop Claude from running. You have 2 bad options - do you walk around with your laptop open or do you stop Claude?
Solution: Claude Caffeine is a lightweight menu bar app that keeps your Mac awake only while Claude Code is working — including with the lid closed. The moment Claude goes idle, normal sleep resumes. No config, no account, runs entirely locally.
| Close the lid, keep Claude running | Close your MacBook and walk away. Claude keeps working. When Claude goes idle, your Mac will go to sleep. When you open the lid, a popover shows how long it ran while closed. |
| See your API spend at a glance | Menu bar shows cost today and this week; submenu breaks it down by project. For API users only (pay-per-token); estimates use Anthropic’s published rates. |
Plus: task-completion notifications with sound, configurable keep-awake timer for Claude Remote sessions, low-battery protection, and clean shutdown so sleep always restores on quit.
macOS 13 (Ventura) or later.
brew install --cask jmslau/tap/claude-caffeine
xattr -d com.apple.quarantine /Applications/Claude\ Caffeine.app
open /Applications/Claude\ Caffeine.appThe xattr command clears the macOS Gatekeeper warning (the app isn’t notarized yet). Or go to System Settings → Privacy & Security and click Open Anyway after the first launch attempt.
brew upgrade --cask jmslau/tap/claude-caffeine
xattr -d com.apple.quarantine /Applications/Claude\ Caffeine.app
open /Applications/Claude\ Caffeine.appIf brew upgrade fails with "App source is not there", run brew uninstall --cask claude-caffeine then reinstall with the install command above.
Build from source
git clone https://github.com/jmslau/claude-caffeine.git
cd claude-caffeine
swift build -c release
./scripts/make-app-bundle.sh
cp -r dist/Claude\ Caffeine.app /Applications/
open /Applications/Claude\ Caffeine.appThe app monitors Claude Code activity using native hooks.
- Hooks — Claude Code is configured to trigger scripts on session events (UserPromptSubmit, PreToolUse, Stop, etc.). These scripts manage session files under
~/.claude/caffeine_sessions/. - Heartbeat — To handle manual interrupts (like pressing Escape) or crashes, the app uses a 5-minute heartbeat timeout and PID liveness checks.
If any valid session is active, the Mac stays awake. When sessions time out or end, the sleep lock is released.
The standout feature: your MacBook stays awake with the lid shut while Claude is working. When you open the lid, you get a clear summary of how long Claude ran while it was closed.
On first launch you’ll be prompted to install a small privileged helper (admin password once). You can skip it — the app still prevents idle sleep, just not lid-close sleep. Install or remove it anytime from the menu.
Under the hood: A scoped sudoers entry lets your user run a script that toggles pmset disablesleep. Lid state comes from the IOKit clamshell sensor, so it’s reliable regardless of display settings.
Thermal note: With the lid closed, cooling is reduced. Use a hard surface or stand for long sessions.
If the app exits without cleanup:
sudo pmset -a disablesleep 0The app reads Claude Code session logs (~/.claude/projects/) to estimate API cost from token usage. In the menu bar you see:
- Cost today and session count
- Cost this week (rolling 7 days)
- Cost by project in a submenu
Pricing follows Anthropic’s standard API table (per-model input/output and 5m prompt-cache write / cache-hit rates). Each billable assistant row in the JSONL is costed by its own model; rows with model: "<synthetic>" are excluded (same as common community parsers). Estimates do not include fast mode, Batch API, geo routing premiums, or a split between 5m vs 1h cache writes (logs only expose aggregate cache token counts). Costs refresh every 30 seconds.
Note: These are estimates for API (pay-per-token) usage. If you’re on Claude Pro or Max, the numbers won’t match your actual bill.
You can hide the cost meter from the menu: Show Cost Meter toggle.
By default, your Mac sleeps as soon as Claude goes idle. If you're using Claude Remote (controlling Claude Code from your phone), you may want the Mac to stay awake longer — or indefinitely.
From the menu, choose Keep Awake After Idle and pick a duration:
| Option | Use case |
|---|---|
| Off (default) | Mac sleeps when Claude goes idle |
| 1–4 Hours | Lid closed in your backpack; saves battery |
| 12 Hours | Overnight unattended session |
| Forever | Plugged in at home, using Claude Remote all day |
The menu shows a countdown while idle. Low-battery protection still applies regardless of the setting.
| Icon | Meaning |
|---|---|
| Animated bolt | Claude is working — Mac is being kept awake |
| Padlock on laptop | Closed-lid mode on, waiting for activity |
| Moon with zzz | Idle — no active Claude Code sessions |
| Warning triangle | Scan issue — lock held during grace period |
The menu shows live status: process state, active sessions, closed-lid state, today/week cost (if enabled), and last check time.
- Keep Awake After Idle — How long to hold the sleep lock after Claude goes idle (Off, 1h, 2h, 4h, 12h, Forever).
- Show Cost Meter — Show or hide the cost display in the menu bar (on by default).
- Notifications — Toggle completion notifications and sound separately.
swift build # debug build
swift test # run tests
swift run # run from sourceRelease build and cask update:
./scripts/release.sh X.X.X- Updated pricing for Opus 4.7 — Opus 4.5, 4.6, and 4.7 use Anthropic’s current standard API rates ($5 / $25 per MTok in/out, with 5m cache write and cache-hit pricing). Legacy Opus 4 / 4.1 and snapshot-style ids keep the older tier.
- Session cost parsing — Skips
<synthetic>assistant rows; only counts assistant usage rows with an explicitinput_tokensfield (aligned with common JSONL parsers). Token counts coerce safely from JSON numbers or strings. - Haiku 4.5 pricing — Corrected to the published Haiku 4.5 tier vs Haiku 3.5.
- Regression tests — Expanded coverage for tiers, cache math, malformed JSON lines, and week vs today rollups.
- Auto-Resume shell profile safety — Profile injection no longer uses multiline Swift interpolation for the
~/.zshrcsnippet, and enabling Auto-Resume strips accidental “Swift template” garbage lines sosource ~/.zshrccannot break from a bad install. Toggle Auto-Resume off and on once to repair an affected profile.
- Hook-based activity detection — Migrated from legacy process/file polling to native Claude Code hooks (
settings.json). Faster, more reliable, and lower overhead. - Heartbeat monitoring — Robust detection of manual terminal interrupts (Escape key) and crashes via a 5-minute heartbeat timeout and PID liveness checks.
- Auto-Resume after limit reached — You kick off Claude before going to bed, and it uses up token limit in the first 10 mins. Claude Caffeine will now auto-resume Claude after the token limit is reset.
- Smarter completion notifications — Reduced false-positive "task completed" sounds caused by CPU fluctuations when Claude is idle. A new multi-layer detection system uses CPU smoothing (3-sample sliding window), hysteresis with separate enter/exit thresholds, file-activity corroboration, and a 60-second cooldown between notifications.
- Thermal protection — Releases the sleep lock and suspends closed-lid mode when macOS reports a critical thermal state, letting your Mac cool down automatically.
- Keep Awake After Idle — Designed for Claude Remote sessions, you can now keep your computer awake even after Claude goes idle. Configurable timer (1h, 2h, 4h, 12h, Forever) to hold the sleep lock after Claude becomes idle.
- Auto-dim screen when lid is closed - Save more battery. While Claude Caffeine will keep your laptop awake to run Claude, it will auto dim the screen when the lid is closed to save battery. When you open your lid again, it will automatically resume to the previous brightness.
- Closed-lid popover redesign — Duration in large bold text for quick reading.
- Improved duration formatting — "15 sec", "9 mins 11 sec", or "2 hours 13 mins".
- Lower summary threshold — Popover after 10 seconds of closed-lid activity (was 60).
- IOKit lid detection — Uses hardware clamshell sensor for reliability when
pmset disablesleepis active.
- App icon — Custom coffee cup + lightning bolt in Claude terracotta.
- App renamed — "Claude Caffeine.app" in Applications.
- Gatekeeper — Added
xattrinstructions for unsigned app warning.
- Closed-lid summary popover — Shows how long Claude ran while the lid was closed when you open it.
- Show Cost Meter toggle — Hide/show cost in menu bar; API pricing disclaimer.
- Session cost tracking — From
~/.claude/projects/JSONL; per-model pricing including cache tokens. - Cost by project — Submenu with per-project breakdown.
- Task completion notifications — Notification + sound with duration and cost delta.
- Animated menu bar icon — Bolt animates when Claude is active; live today cost.
- Per-model pricing — Accurate for mixed-model sessions.
- API pricing disclaimer — Cost estimates for pay-per-token API users only.
- Initial release: sleep prevention, closed-lid mode, detection, low battery protection, clean shutdown.
brew uninstall claude-caffeineIf you installed the closed-lid helper, remove it first via Closed-Lid Mode → Uninstall Helper, or:
sudo rm /private/etc/sudoers.d/claude_caffeine
rm -rf ~/Library/ClaudeCaffeineMIT

