{"slug": "claude-awake-keep-your-mac-awake-even-lid-closed-while-claude-code-is-working", "title": "claude-awake: keep your Mac awake (even lid-closed) while Claude Code is working — heartbeat hooks + pmset watchdog", "summary": "A developer created claude-awake, a pair of scripts that keep a Mac awake (even with the lid closed) while Claude Code is actively running tasks, using heartbeat hooks and a pmset watchdog. The daemon checks session state files and thermal throttling to decide whether to disable sleep, and restores sleep if the watchdog exits or the Mac overheats.", "body_md": "|\n#!/bin/bash |\n|\n# claude-awake-daemon.sh — the SINGLE authority on `pmset disablesleep`. |\n|\n# |\n|\n# Every POLL seconds it looks at two things and decides whether the Mac may sleep: |\n|\n# 1. the per-session state files written by claude-awake-hook.sh |\n|\n# (a file is \"active\" only if it was refreshed within STALE_MIN — a heartbeat, |\n|\n# so a crashed/killed Claude can't pin sleep open forever) |\n|\n# 2. the thermal state (CPU_Scheduler_Limit / CPU_Speed_Limit < 100 = throttling) |\n|\n# |\n|\n# ≥1 active session AND not overheating → disablesleep 1 |\n|\n# (the lid can be closed and the Mac stays awake to finish the task) |\n|\n# otherwise (all idle/closed, OR too hot) → disablesleep 0 |\n|\n# (normal sleep — closing the lid sleeps it, so the battery doesn't drain; |\n|\n# overheat → it's allowed to sleep & cool instead of cooking in clamshell) |\n|\n# |\n|\n# Idle Claude instances (open but not running a task) keep NO active file, so they |\n|\n# do NOT hold sleep open. Restores sleep if the watchdog itself exits. |\n|\n# |\n|\n# Run it via the LaunchAgent (RunAtLoad + KeepAlive). Needs passwordless sudo for |\n|\n# the two exact pmset commands — see the setup notes printed by the assistant. |\n|\n|\n|\nSTATE_DIR=\"$HOME/.claude/awake-state\" |\n|\nLOG=\"$HOME/.claude/awake.log\" |\n|\nPOLL=20 # seconds between checks |\n|\nSTALE_MIN=30 # a session file not refreshed within this many minutes = stale → ignored |\n|\nCOOL_LIMIT=100 # CPU_Scheduler_Limit / CPU_Speed_Limit below this = throttling (hot) |\n|\n|\n|\nmkdir -p \"$STATE_DIR\" 2>/dev/null |\n|\nlog() { printf '%s %s\\n' \"$(date '+%F %T')\" \"$*\" >>\"$LOG\"; } |\n|\n|\n|\napplied=\"\" # last value we actually pushed to pmset (avoid redundant calls) |\n|\nset_sleep() { # $1: 1 = disable sleep (stay awake), 0 = enable sleep (allow sleep) |\n|\n[ \"$applied\" = \"$1\" ] && return |\n|\nif sudo -n /usr/bin/pmset -a disablesleep \"$1\" 2>>\"$LOG\"; then |\n|\napplied=\"$1\" |\n|\nlog \"disablesleep=$1 $([ \"$1\" = 1 ] && echo '→ staying awake (lid-close OK)' || echo '→ sleep allowed')\" |\n|\nelse |\n|\nlog \"pmset FAILED — set up passwordless sudo for pmset (see /etc/sudoers.d/claude-pmset)\" |\n|\nfi |\n|\n} |\n|\n|\n|\noverheating() { # 0 = hot/throttling, 1 = ok |\n|\nlocal therm field val |\n|\ntherm=\"$(pmset -g therm 2>/dev/null)\" |\n|\nfor field in CPU_Scheduler_Limit CPU_Speed_Limit; do |\n|\nval=\"$(printf '%s' \"$therm\" | sed -n \"s/.*$field[[:space:]]*=[[:space:]]*\\([0-9]*\\).*/\\1/p\" | head -1)\" |\n|\n[ -n \"$val\" ] && [ \"$val\" -lt \"$COOL_LIMIT\" ] && return 0 |\n|\ndone |\n|\nreturn 1 |\n|\n} |\n|\n|\n|\nactive_count() { find \"$STATE_DIR\" -type f -mmin \"-$STALE_MIN\" 2>/dev/null | wc -l | tr -d ' '; } |\n|\n|\n|\n# Never leave sleep disabled if the watchdog dies / is restarted. |\n|\ntrap 'sudo -n /usr/bin/pmset -a disablesleep 0 2>/dev/null; log \"watchdog exit → sleep ENABLED\"; exit 0' INT TERM |\n|\n|\n|\nlog \"watchdog up (poll ${POLL}s, stale ${STALE_MIN}m, cool<${COOL_LIMIT})\" |\n|\nwhile true; do |\n|\nif [ \"$(active_count)\" -gt 0 ] && ! overheating; then |\n|\nset_sleep 1 |\n|\nelse |\n|\nset_sleep 0 |\n|\nfi |\n|\nfind \"$STATE_DIR\" -type f -mmin \"+$STALE_MIN\" -delete 2>/dev/null # reap stale markers |\n|\nsleep \"$POLL\" |\n|\ndone |", "url": "https://wpnews.pro/news/claude-awake-keep-your-mac-awake-even-lid-closed-while-claude-code-is-working", "canonical_source": "https://gist.github.com/whitefoxx/3579ba4370bdc82eacb0e7ab1f29057b", "published_at": "2026-08-02 05:07:59+00:00", "updated_at": "2026-08-03 07:31:33.352332+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools"], "entities": ["Claude Code", "Mac", "pmset"], "alternates": {"html": "https://wpnews.pro/news/claude-awake-keep-your-mac-awake-even-lid-closed-while-claude-code-is-working", "markdown": "https://wpnews.pro/news/claude-awake-keep-your-mac-awake-even-lid-closed-while-claude-code-is-working.md", "text": "https://wpnews.pro/news/claude-awake-keep-your-mac-awake-even-lid-closed-while-claude-code-is-working.txt", "jsonld": "https://wpnews.pro/news/claude-awake-keep-your-mac-awake-even-lid-closed-while-claude-code-is-working.jsonld"}}