core-agent-ide/codex-rs/tui/src
Yaroslav Volovich 32da5eb358
feat(tui): prevent macOS idle sleep while turns run (#11711)
## Summary
- add a shared `codex-core` sleep inhibitor that uses native macOS IOKit
assertions (`IOPMAssertionCreateWithName` / `IOPMAssertionRelease`)
instead of spawning `caffeinate`
- wire sleep inhibition to turn lifecycle in `tui` (`TurnStarted`
enables; `TurnComplete` and abort/error finalization disable)
- gate this behavior behind a `/experimental` feature toggle
(`[features].prevent_idle_sleep`) instead of a dedicated `[tui]` config
flag
- expose the toggle in `/experimental` on macOS; keep it under
development on other platforms
- keep behavior no-op on non-macOS targets

<img width="1326" height="577" alt="image"
src="https://github.com/user-attachments/assets/73fac06b-97ae-46a2-800a-30f9516cf8a3"
/>

## Testing
- `cargo check -p codex-core -p codex-tui`
- `cargo test -p codex-core sleep_inhibitor::tests -- --nocapture`
- `cargo test -p codex-core
tui_config_missing_notifications_field_defaults_to_enabled --
--nocapture`
- `cargo test -p codex-core prevent_idle_sleep_is_ -- --nocapture`

## Semantics and API references
- This PR targets `caffeinate -i` semantics: prevent *idle system sleep*
while allowing display idle sleep.
- `caffeinate -i` mapping in Apple open source (`assertionMap`):
  - `kIdleAssertionFlag -> kIOPMAssertionTypePreventUserIdleSystemSleep`
- Source:
https://github.com/apple-oss-distributions/PowerManagement/blob/PowerManagement-1846.60.12/caffeinate/caffeinate.c#L52-L54
- Apple IOKit docs for assertion types and API:
-
https://developer.apple.com/documentation/iokit/iopmlib_h/iopmassertiontypes
-
https://developer.apple.com/documentation/iokit/1557092-iopmassertioncreatewithname
  - https://developer.apple.com/library/archive/qa/qa1340/_index.html

## Codex Electron vs this PR (full stack path)
- Codex Electron app requests sleep blocking with
`powerSaveBlocker.start("prevent-app-suspension")`:
-
https://github.com/openai/codex/blob/main/codex/codex-vscode/electron/src/electron-message-handler.ts
- Electron maps that string to Chromium wake lock type
`kPreventAppSuspension`:
-
https://github.com/electron/electron/blob/main/shell/browser/api/electron_api_power_save_blocker.cc
- Chromium macOS backend maps wake lock types to IOKit assertion
constants and calls IOKit:
  - `kPreventAppSuspension -> kIOPMAssertionTypeNoIdleSleep`
- `kPreventDisplaySleep / kPreventDisplaySleepAllowDimming ->
kIOPMAssertionTypeNoDisplaySleep`
-
https://github.com/chromium/chromium/blob/main/services/device/wake_lock/power_save_blocker/power_save_blocker_mac.cc

## Why this PR uses a different macOS constant name
- This PR uses `"PreventUserIdleSystemSleep"` directly, via
`IOPMAssertionCreateWithName`, in
`codex-rs/core/src/sleep_inhibitor.rs`.
- Apple’s IOKit header documents `kIOPMAssertionTypeNoIdleSleep` as
deprecated and recommends `kIOPMAssertPreventUserIdleSystemSleep` /
`kIOPMAssertionTypePreventUserIdleSystemSleep`:
-
https://github.com/apple-oss-distributions/IOKitUser/blob/IOKitUser-100222.60.2/pwr_mgt.subproj/IOPMLib.h#L1000-L1030
- So Chromium and this PR are using different constant names, but
semantically equivalent idle-system-sleep prevention behavior.

## Future platform support
The architecture is intentionally set up for multi-platform extensions:
- UI code (`tui`) only calls `SleepInhibitor::set_turn_running(...)` on
turn lifecycle boundaries.
- Platform-specific behavior is isolated in
`codex-rs/core/src/sleep_inhibitor.rs` behind `cfg(...)` blocks.
- Feature exposure is centralized in `core/src/features.rs` and surfaced
via `/experimental`.
- Adding new OS backends should not require additional TUI wiring; only
the backend internals and feature stage metadata need to change.

Potential follow-up implementations:
- Windows:
- Add a backend using Win32 power APIs
(`SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED)` as
baseline).
- Optionally move to `PowerCreateRequest` / `PowerSetRequest` /
`PowerClearRequest` for richer assertion semantics.
- Linux:
- Add a backend using logind inhibitors over D-Bus
(`org.freedesktop.login1.Manager.Inhibit` with `what="sleep"`).
  - Keep a no-op fallback where logind/D-Bus is unavailable.

This PR keeps the cross-platform API surface minimal so future PRs can
add Windows/Linux support incrementally with low churn.

---------

Co-authored-by: jif-oai <jif@openai.com>
2026-02-13 10:31:39 -08:00
..
bin replace tui_markdown with a custom markdown renderer (#3396) 2025-09-10 12:13:53 -07:00
bottom_pane [apps] Add is_enabled to app info. (#11417) 2026-02-13 00:30:52 +00:00
chatwidget feat(tui): prevent macOS idle sleep while turns run (#11711) 2026-02-13 10:31:39 -08:00
exec_cell feat: split codex-common into smaller utils crates (#11422) 2026-02-11 12:59:24 +00:00
notifications Added tui.notifications_method config option (#10043) 2026-01-28 12:00:32 -08:00
onboarding Promote Windows Sandbox (#11341) 2026-02-11 11:48:33 -08:00
public_widgets Persist text elements through TUI input and history (#9393) 2026-01-19 23:49:34 -08:00
render chore: upgrade to Rust 1.92.0 (#8860) 2026-01-16 11:12:52 -08:00
snapshots feat(tui): add sortable resume picker with created/updated timestamp toggle (#10752) 2026-02-05 09:08:31 -08:00
status feat: introduce Permissions (#11633) 2026-02-12 14:42:54 -08:00
streaming feat(tui): pace catch-up stream chunking with hysteresis (#10461) 2026-02-03 15:01:51 -08:00
tui feat(tui): pace catch-up stream chunking with hysteresis (#10461) 2026-02-03 15:01:51 -08:00
additional_dirs.rs feat: make sandbox read access configurable with ReadOnlyAccess (#11387) 2026-02-11 18:31:14 -08:00
app.rs feat: switch on dying sub-agents (#11477) 2026-02-13 18:29:03 +00:00
app_backtrack.rs tui: queue non-pending rollback trims in app-event order (#11373) 2026-02-10 18:53:43 -08:00
app_event.rs sandbox NUX metrics update (#11667) 2026-02-13 10:01:47 -08:00
app_event_sender.rs tui: switch to using tokio + EventStream for processing crossterm events (#2489) 2025-08-20 17:11:09 +00:00
ascii_animation.rs chore: remove model upgrade popup (#4332) 2025-09-27 13:25:09 -07:00
chatwidget.rs feat(tui): prevent macOS idle sleep while turns run (#11711) 2026-02-13 10:31:39 -08:00
cli.rs feat: split codex-common into smaller utils crates (#11422) 2026-02-11 12:59:24 +00:00
clipboard_paste.rs Fixed TUI regression related to image paste in WSL (#9473) 2026-01-18 23:02:02 -08:00
collab.rs Add resume_agent collab tool (#10903) 2026-02-07 17:31:45 +01:00
collaboration_modes.rs Sync collaboration mode naming across Default prompt, tools, and TUI (#10666) 2026-02-04 23:03:28 -08:00
color.rs update composer + user message styling (#4240) 2025-09-26 16:35:56 -07:00
custom_terminal.rs Teach codex to test itself (#11531) 2026-02-11 20:03:19 -08:00
cwd_prompt.rs Ask for cwd choice when resuming session from different cwd (#9731) 2026-01-24 21:57:19 -08:00
debug_config.rs feat: introduce Permissions (#11633) 2026-02-12 14:42:54 -08:00
diff_render.rs feat(tui): add /statusline command for interactive status line configuration (#10546) 2026-02-05 08:50:21 -08:00
exec_command.rs fix(windows) shell_command on windows, minor parsing (#6811) 2025-11-17 22:23:53 -08:00
external_editor.rs feat: open prompt in configured external editor (#7606) 2025-12-22 15:12:23 -08:00
file_search.rs app-server: add fuzzy search sessions for streaming file search (#10268) 2026-02-12 10:49:44 -08:00
frames.rs Login flow polish (#3632) 2025-09-15 00:42:53 -07:00
get_git_diff.rs Show progress indicator for /diff command (#2245) 2025-08-15 15:32:41 -07:00
history_cell.rs feat: split codex-common into smaller utils crates (#11422) 2026-02-11 12:59:24 +00:00
insert_history.rs fix(tui): propagate errors in insert_history_lines_to_writer (#4266) 2025-10-30 18:07:51 -07:00
key_hint.rs Add vim navigation keys to transcript pager (#7550) 2025-12-09 10:23:11 -08:00
lib.rs Persist complete TurnContextItem state via canonical conversion (#11656) 2026-02-12 17:22:44 -08:00
live_wrap.rs Stream model responses (#1810) 2025-08-05 04:23:22 +00:00
main.rs feat: split codex-common into smaller utils crates (#11422) 2026-02-11 12:59:24 +00:00
markdown.rs tui: drop citation rendering (#4855) 2025-10-20 21:08:19 +00:00
markdown_render.rs Changed default wrap algorithm from OptimalFit to FirstFit (#7960) 2025-12-12 21:47:37 -08:00
markdown_render_tests.rs tui: centralize markdown styling and make inline code cyan (#7023) 2025-11-20 21:06:22 +00:00
markdown_stream.rs tui: drop citation rendering (#4855) 2025-10-20 21:08:19 +00:00
mention_codec.rs TUI/Core: preserve duplicate skill/app mention selection across submit + resume (#10855) 2026-02-06 15:59:00 -08:00
model_migration.rs Use markdown for migration screen (#8952) 2026-01-13 07:41:42 +00:00
oss_selection.rs chore: nuke chat/completions API (#10157) 2026-02-03 11:31:57 +00:00
pager_overlay.rs tui: queue non-pending rollback trims in app-event order (#11373) 2026-02-10 18:53:43 -08:00
resume_picker.rs fix: reduce usage of open_if_present (#11344) 2026-02-10 19:25:07 +00:00
selection_list.rs splash screen (#8270) 2025-12-18 10:59:53 -08:00
session_log.rs tui: bring the transcript closer to display mode (#4848) 2025-10-07 16:18:48 -07:00
shimmer.rs tui: hardcode xterm palette, shimmer blends between fg and bg (#4957) 2025-10-08 20:23:13 +00:00
skills_helpers.rs feat: split codex-common into smaller utils crates (#11422) 2026-02-11 12:59:24 +00:00
slash_command.rs add a slash command to grant sandbox read access to inaccessible directories (#11512) 2026-02-12 12:48:36 -08:00
status_indicator_widget.rs fix(tui): keep unified exec summary on working line (#10962) 2026-02-09 14:25:32 -08:00
style.rs Make plan highlight use popup grey background (#10253) 2026-01-30 12:39:15 -08:00
terminal_palette.rs perf(tui2): cache transcript view rendering (#8693) 2026-01-03 11:44:27 -08:00
test_backend.rs feat: Constrain values for approval_policy (#7778) 2025-12-17 16:19:27 +00:00
text_formatting.rs feat(tui): add /statusline command for interactive status line configuration (#10546) 2026-02-05 08:50:21 -08:00
tooltips.rs Point Codex App tooltip links to app landing page (#11515) 2026-02-12 23:35:57 -08:00
tui.rs fix(tui): flush input buffer on init to prevent early exit on Windows (#10729) 2026-02-05 00:59:32 -08:00
ui_consts.rs Fixes (#4458) 2025-09-30 00:10:04 +00:00
update_action.rs fix: use brew upgrade --cask codex to avoid warnings and ambiguity (#9823) 2026-01-26 16:21:09 -08:00
update_prompt.rs fix: update brew auto update version check (#6238) 2025-11-10 09:05:00 -08:00
updates.rs updates: use brew api for version check (#10809) 2026-02-05 15:12:27 -08:00
version.rs Added CLI version to /status output (#3223) 2025-09-05 16:27:31 -07:00
wrapping.rs Changed default wrap algorithm from OptimalFit to FirstFit (#7960) 2025-12-12 21:47:37 -08:00