Files
Eric Traut 9d87b771ce Add session delete commands in CLI and TUI (#27476)
## Summary

The app server exposes `thread/delete`, but users cannot invoke it from
the CLI or TUI. Because deletion is irreversible, the user-facing
commands need deliberate confirmation and safer handling of name-based
targets.

- Add `codex delete <SESSION>` with interactive confirmation,
restricting `--force` to UUID targets.
- Resolve exact names across active and archived sessions, including
renamed sessions, and validate prompted UUID targets before
confirmation.
- Add a `/delete` command with a confirmation popup that warns the
current session and its subagent threads will be permanently deleted.

## Manual testing

- Deleted by UUID with `--force` and verified the rollout, session-index
entry, and database row were removed.
- Exercised name-based confirmation for both cancellation and
affirmative deletion; cancellation preserved the session and
confirmation removed it.
- Verified deletion refuses to proceed without `--force`, while
`--force` rejects names, including duplicate names.
- Verified duplicate-name confirmation displays the concrete UUID
selected.
- Deleted an archived session by name.
- Verified an already-missing UUID fails before displaying a
confirmation prompt.
- Exercised `/delete` in the TUI: the popup defaults to No, cancellation
preserves the session, and confirmation deletes the session and exits.
- Verified that `codex delete` works for both archived and non-archived
sessions.
2026-06-10 18:04:02 -07:00

18 lines
588 B
Rust

use predicates::prelude::*;
#[test]
fn missing_session_fails_before_delete_confirmation() -> anyhow::Result<()> {
let codex_home = tempfile::tempdir()?;
let mut cmd = assert_cmd::Command::new(codex_utils_cargo_bin::cargo_bin("codex")?);
cmd.env("CODEX_HOME", codex_home.path())
.args(["delete", "123e4567-e89b-12d3-a456-426614174000"]);
cmd.assert()
.failure()
.stderr(predicate::str::contains(
"No active or archived session found matching",
))
.stderr(predicate::str::contains("cannot confirm").not());
Ok(())
}