Skip to content

Prevent idle sleep while AI coding agents are running - #736

Open
Philotheephilix wants to merge 7 commits into
gnachman:masterfrom
Philotheephilix:feature/keep-awake-while-agent-running
Open

Prevent idle sleep while AI coding agents are running#736
Philotheephilix wants to merge 7 commits into
gnachman:masterfrom
Philotheephilix:feature/keep-awake-while-agent-running

Conversation

@Philotheephilix

Copy link
Copy Markdown

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:

  • Prevent system idle sleep while an AI coding agent is running — takes an NSActivityIdleSystemSleepDisabled assertion via NSProcessInfo while any monitored agent is in a session's foreground-job ancestry.
  • Prevent display sleep while an AI coding agent is running — takes an NSActivityIdleDisplaySleepDisabled assertion, 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 GlobalJobMonitor infrastructure, which already tracks foreground-job ancestry for all sessions.

Testing

  • Run claude in a session → pmset -g assertions shows PreventUserIdleSystemSleep and PreventUserIdleDisplaySleep held by iTerm2.
  • Exit the agent → both assertions are released immediately.
  • Set to AC power only, unplug power → assertions not taken even with agent running.
  • Add a custom agent name in the extra-names field → that process also prevents sleep.

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 gnachman left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/notes-3.7.txt Outdated
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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Philotheephilix

Philotheephilix commented Aug 26, 2026

Copy link
Copy Markdown
Author

All comments has been noted and issues are fixed in commit d50e649

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants