Prevent idle sleep while AI coding agents are running - #736
Prevent idle sleep while AI coding agents are running#736Philotheephilix wants to merge 7 commits into
Conversation
Adds a new advanced setting keepAwakeWhileAgentRunning (default YES). When enabled, iTerm2 takes an NSActivityIdleSystemSleepDisabled assertion via NSProcessInfo whenever GlobalJobMonitor reports at least one session with "claude" in its foreground-job ancestry, then releases it once all such sessions finish. User-initiated sleep (lid close, Apple menu → Sleep) is unaffected.
Add keepDisplayAwakeWhileAgentRunning (default YES) alongside the existing keepAwakeWhileAgentRunning. This lets users prevent display sleep (screen lock) independently from system idle sleep.
agentRunningDidChange now ORs NSActivityIdleSystemSleepDisabled and NSActivityIdleDisplaySleepDisabled based on their respective settings, re-taking the assertion when options change while an agent is active.
Monitor claude, codex, opencode, cline, and pi via monitoredAgentJobNames instead of hardcoding "claude". Updates setting descriptions and assertion reason string accordingly.
- Replace boolean keep-awake settings with three-state INT_ENUM: Off / AC power only (default) / Always. Re-evaluates on power source changes via iTermPowerManagerStateDidChange. - Add extraAgentJobNames (SETTABLE_STRING, persisted in user defaults) for comma-separated custom agent process names beyond the built-in list (claude, codex, opencode, cline, pi). - Split _agentRunningActivity into _agentSystemActivity and _agentDisplayActivity so system and display assertions are managed independently.
gnachman
left a comment
There was a problem hiding this comment.
A few behavior/doc mismatches from review. The wiring itself (notifications, macros, Swift bridging, assertion balancing) looks correct; these are lower-severity issues.
| DEFINE_FLOAT(updateScreenParamsDelay, 1, SECTION_GENERAL @"Delay after changing number of screens/resolution until refresh (seconds).\nThis works around OS bugs where it takes some time after a screen change before it is safe to resize windows."); | ||
| DEFINE_BOOL(disableAppNap, NO, SECTION_GENERAL @"Disable App Nap.\nChange effective after restarting iTerm2."); | ||
| DEFINE_INT_ENUM(keepAwakeWhileAgentRunning, 1, (@[ @"Off", @"AC power only", @"Always" ]), SECTION_GENERAL @"Prevent system idle sleep while an AI coding agent is running.\nAC power only (the default) prevents idle sleep only when the Mac is plugged in. Always also applies on battery. User-initiated sleep is unaffected."); | ||
| DEFINE_INT_ENUM(keepDisplayAwakeWhileAgentRunning, 1, (@[ @"Off", @"AC power only", @"Always" ]), SECTION_GENERAL @"Prevent display sleep while an AI coding agent is running.\nAC power only (the default) prevents display sleep and screen lock only when the Mac is plugged in. Always also applies on battery. Has no effect if system idle sleep prevention is Off. User-initiated sleep is unaffected."); |
There was a problem hiding this comment.
The help text says "Has no effect if system idle sleep prevention is Off," but in updateAgentKeepAwakeAssertions the display assertion (wantDisplay) is computed independently of keepAwakeWhileAgentRunning. With system=Off and display=Always, NSActivityIdleDisplaySleepDisabled is still taken, and since keeping the display awake inherently keeps the system awake, a user who set system sleep to Off (expecting the Mac to sleep) gets a machine that never idle-sleeps, contradicting this text. Either gate the display assertion on the system setting, or fix the help text.
| built-in model list from iterm2.com (off by | ||
| default), with an Update Now button to check | ||
| on demand. | ||
| - New advanced setting "Prevent idle sleep |
There was a problem hiding this comment.
This release note looks stale relative to what shipped. It describes a single setting named "Prevent idle sleep while a Claude Code agent is running" that is "on by default" and triggers on "claude." The PR actually ships three settings (system sleep, display sleep, extra names), defaults to "AC power only," and monitors five built-in agents (claude, codex, opencode, cline, pi). Worth updating so the notes match the feature.
| } | ||
|
|
||
| // Re-evaluate keep-awake assertions when agent sessions start/stop or power source changes. | ||
| [[NSNotificationCenter defaultCenter] addObserver:self |
There was a problem hiding this comment.
updateAgentKeepAwakeAssertions only runs on iTermGlobalJobMonitorDidChange and iTermPowerManagerStateDidChange. If the user turns the feature Off in Advanced Settings while an agent is running, the held assertion is not released until the next foreground-job or power-source change, so the Mac keeps blocking sleep after the setting says it should not. Adding an iTermAdvancedSettingsDidChange observer that calls updateAgentKeepAwakeAssertions would close the gap.
|
All comments has been noted and issues are fixed in commit d50e649 |
Problem
When an AI coding agent (claude, codex, opencode, cline, pi) runs a long task in a terminal session, the Mac's display sleeps and the screen locks, interrupting the agent mid-run.
What this does
Adds two new Advanced Settings under General:
NSActivityIdleSystemSleepDisabledassertion viaNSProcessInfowhile any monitored agent is in a session's foreground-job ancestry.NSActivityIdleDisplaySleepDisabledassertion, keeping the screen on and preventing the lock screen.Each setting has three options: Off, AC power only (default), Always. Assertions are released as soon as all agent sessions end, and re-evaluated when the power source changes.
A third setting, Additional AI agent process names, accepts a comma-separated list of extra process names (e.g.
aider,cursor) to monitor beyond the built-in set.Detection reuses the existing
GlobalJobMonitorinfrastructure, which already tracks foreground-job ancestry for all sessions.Testing
claudein a session →pmset -g assertionsshowsPreventUserIdleSystemSleepandPreventUserIdleDisplaySleepheld by iTerm2.