mirror of
https://github.com/openai/codex.git
synced 2026-11-12 21:20:34 +00:00
Merge a265928c96 into sapling-pr-archive-bolinfest
This commit is contained in:
+1
-1
@@ -4,4 +4,4 @@ For information about AGENTS.md, see [this documentation](https://developers.ope
|
||||
|
||||
## Hierarchical agents message
|
||||
|
||||
When the `hierarchical_agents` feature flag is enabled (via `[features]` in `config.toml`), Codex appends additional guidance about AGENTS.md scope and precedence to the user instructions message and emits that message even when no AGENTS.md is present.
|
||||
When the `child_agents_md` feature flag is enabled (via `[features]` in `config.toml`), Codex appends additional guidance about AGENTS.md scope and precedence to the user instructions message and emits that message even when no AGENTS.md is present.
|
||||
|
||||
@@ -21,3 +21,9 @@ Codex can run a notification hook when the agent finishes a turn. See the config
|
||||
## JSON Schema
|
||||
|
||||
The generated JSON Schema for `config.toml` lives at `codex-rs/core/config.schema.json`.
|
||||
|
||||
## Notices
|
||||
|
||||
Codex stores "do not show again" flags for some UI prompts under the `[notice]` table.
|
||||
|
||||
Ctrl+C/Ctrl+D quitting uses a ~1 second double-press hint (`ctrl + c again to quit`).
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# Exit and shutdown flow (tui + tui2)
|
||||
|
||||
This document describes how exit, shutdown, and interruption work in the Rust TUIs (`codex-rs/tui`
|
||||
and `codex-rs/tui2`). It is intended for Codex developers and Codex itself when reasoning about
|
||||
future exit/shutdown changes.
|
||||
|
||||
This doc replaces earlier separate history and design notes. High-level history is summarized
|
||||
below; full details are captured in PR #8936.
|
||||
|
||||
## Terms
|
||||
|
||||
- **Exit**: end the UI event loop and terminate the process.
|
||||
- **Shutdown**: request a graceful agent/core shutdown (`Op::Shutdown`) and wait for
|
||||
`ShutdownComplete` so cleanup can run.
|
||||
- **Interrupt**: cancel a running operation (`Op::Interrupt`).
|
||||
|
||||
## Event model (AppEvent)
|
||||
|
||||
Exit is coordinated via a single event with explicit modes:
|
||||
|
||||
- `AppEvent::Exit(ExitMode::ShutdownFirst)`
|
||||
- Prefer this for user-initiated quits so cleanup runs.
|
||||
- `AppEvent::Exit(ExitMode::Immediate)`
|
||||
- Escape hatch for immediate exit. This bypasses shutdown and can drop
|
||||
in-flight work (e.g., tasks, rollout flush, child process cleanup).
|
||||
|
||||
`App` is the coordinator: it submits `Op::Shutdown` and it exits the UI loop only when
|
||||
`ExitMode::Immediate` arrives (typically after `ShutdownComplete`).
|
||||
|
||||
## User-triggered quit flows
|
||||
|
||||
### Ctrl+C
|
||||
|
||||
Priority order in the UI layer:
|
||||
|
||||
1. Active modal/view gets the first chance to consume (`BottomPane::on_ctrl_c`).
|
||||
- If the modal handles it, the quit flow stops.
|
||||
- When a modal/popup handles Ctrl+C, the quit shortcut is cleared so dismissing a modal cannot
|
||||
accidentally prime a subsequent Ctrl+C to quit.
|
||||
2. If the user has already armed Ctrl+C and the 1 second window has not expired, the second Ctrl+C
|
||||
triggers shutdown-first quit immediately.
|
||||
3. Otherwise, `ChatWidget` arms Ctrl+C and shows the quit hint (`ctrl + c again to quit`) for
|
||||
1 second.
|
||||
4. If cancellable work is active (streaming/tools/review), `ChatWidget` submits `Op::Interrupt`.
|
||||
|
||||
### Ctrl+D
|
||||
|
||||
- Only participates in quit when the composer is empty **and** no modal is active.
|
||||
- On first press, show the quit hint (same as Ctrl+C) and start the 1 second timer.
|
||||
- If pressed again while the hint is visible, request shutdown-first quit.
|
||||
- With any modal/popup open, key events are routed to the view and Ctrl+D does not attempt to
|
||||
quit.
|
||||
|
||||
### Slash commands
|
||||
|
||||
- `/quit`, `/exit`, `/logout` request shutdown-first quit **without** a prompt,
|
||||
because slash commands are harder to trigger accidentally and imply clear intent to quit.
|
||||
|
||||
### /new
|
||||
|
||||
- Uses shutdown without exit (suppresses `ShutdownComplete`) so the app can
|
||||
start a fresh session without terminating.
|
||||
|
||||
## Shutdown completion and suppression
|
||||
|
||||
`ShutdownComplete` is the signal that core cleanup has finished. The UI treats it as the boundary
|
||||
for exit:
|
||||
|
||||
- `ChatWidget` requests `Exit(Immediate)` on `ShutdownComplete`.
|
||||
- `App` can suppress a single `ShutdownComplete` when shutdown is used as a
|
||||
cleanup step (e.g., `/new`).
|
||||
|
||||
## Edge cases and invariants
|
||||
|
||||
- **Review mode** counts as cancellable work. Ctrl+C should interrupt review, not
|
||||
quit.
|
||||
- **Modal open** means Ctrl+C/Ctrl+D should not quit unless the modal explicitly
|
||||
declines to handle Ctrl+C.
|
||||
- **Immediate exit** is not a normal user path; it is a fallback for shutdown
|
||||
completion or an emergency exit. Use it sparingly because it skips cleanup.
|
||||
|
||||
## Testing expectations
|
||||
|
||||
At a minimum, we want coverage for:
|
||||
|
||||
- Ctrl+C while working interrupts, does not quit.
|
||||
- Ctrl+C while idle and empty shows quit hint, then shutdown-first quit on second press.
|
||||
- Ctrl+D with modal open does not quit.
|
||||
- `/quit` / `/exit` / `/logout` quit without prompt, but still shutdown-first.
|
||||
- Ctrl+D while idle and empty shows quit hint, then shutdown-first quit on second press.
|
||||
|
||||
## History (high level)
|
||||
|
||||
Codex has historically mixed "exit immediately" and "shutdown-first" across quit gestures, largely
|
||||
due to incremental changes and regressions in state tracking. This doc reflects the current
|
||||
unified, shutdown-first approach. See PR #8936 for the detailed history and rationale.
|
||||
Reference in New Issue
Block a user