mirror of
https://github.com/openai/codex.git
synced 2026-05-01 11:52:10 +03:00
tui: exit session on Ctrl+C in cwd change prompt (#12040)
## Summary - change the cwd-change prompt (shown when resuming/forking across different directories) so `Ctrl+C`/`Ctrl+D` exits the session instead of implicitly selecting "Use session directory" - introduce explicit prompt and resolver exit outcomes so this intent is propagated cleanly through both startup resume/fork and in-app `/resume` flows - add a unit test that verifies `Ctrl+C` exits rather than selecting an option ## Why Previously, pressing `Ctrl+C` on this prompt silently picked one of the options, which made it hard to abort. This aligns the prompt with the expected quit behavior. ## Codex author `codex resume 019c6d39-bbfb-7dc3-8008-1388a054e86d`
This commit is contained in:
committed by
GitHub
parent
c4bb7db159
commit
709e2133bb
@@ -44,6 +44,7 @@ use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_oss::ensure_oss_provider_ready;
|
||||
use codex_utils_oss::get_default_model_for_oss_provider;
|
||||
use cwd_prompt::CwdPromptAction;
|
||||
use cwd_prompt::CwdPromptOutcome;
|
||||
use cwd_prompt::CwdSelection;
|
||||
use std::fs::OpenOptions;
|
||||
use std::path::Path;
|
||||
@@ -672,8 +673,22 @@ async fn run_ratatui_app(
|
||||
};
|
||||
let fallback_cwd = match action_and_path_if_resume_or_fork {
|
||||
Some((action, path)) => {
|
||||
resolve_cwd_for_resume_or_fork(&mut tui, ¤t_cwd, path, action, allow_prompt)
|
||||
match resolve_cwd_for_resume_or_fork(&mut tui, ¤t_cwd, path, action, allow_prompt)
|
||||
.await?
|
||||
{
|
||||
ResolveCwdOutcome::Continue(cwd) => cwd,
|
||||
ResolveCwdOutcome::Exit => {
|
||||
restore();
|
||||
session_log::log_session_end();
|
||||
return Ok(AppExitInfo {
|
||||
token_usage: codex_core::protocol::TokenUsage::default(),
|
||||
thread_id: None,
|
||||
thread_name: None,
|
||||
update_action: None,
|
||||
exit_reason: ExitReason::UserRequested,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
@@ -780,25 +795,35 @@ pub(crate) fn cwds_differ(current_cwd: &Path, session_cwd: &Path) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum ResolveCwdOutcome {
|
||||
Continue(Option<PathBuf>),
|
||||
Exit,
|
||||
}
|
||||
|
||||
pub(crate) async fn resolve_cwd_for_resume_or_fork(
|
||||
tui: &mut Tui,
|
||||
current_cwd: &Path,
|
||||
path: &Path,
|
||||
action: CwdPromptAction,
|
||||
allow_prompt: bool,
|
||||
) -> color_eyre::Result<Option<PathBuf>> {
|
||||
) -> color_eyre::Result<ResolveCwdOutcome> {
|
||||
let Some(history_cwd) = read_session_cwd(path).await else {
|
||||
return Ok(None);
|
||||
return Ok(ResolveCwdOutcome::Continue(None));
|
||||
};
|
||||
if allow_prompt && cwds_differ(current_cwd, &history_cwd) {
|
||||
let selection =
|
||||
let selection_outcome =
|
||||
cwd_prompt::run_cwd_selection_prompt(tui, action, current_cwd, &history_cwd).await?;
|
||||
return Ok(Some(match selection {
|
||||
CwdSelection::Current => current_cwd.to_path_buf(),
|
||||
CwdSelection::Session => history_cwd,
|
||||
}));
|
||||
return Ok(match selection_outcome {
|
||||
CwdPromptOutcome::Selection(CwdSelection::Current) => {
|
||||
ResolveCwdOutcome::Continue(Some(current_cwd.to_path_buf()))
|
||||
}
|
||||
CwdPromptOutcome::Selection(CwdSelection::Session) => {
|
||||
ResolveCwdOutcome::Continue(Some(history_cwd))
|
||||
}
|
||||
CwdPromptOutcome::Exit => ResolveCwdOutcome::Exit,
|
||||
});
|
||||
}
|
||||
Ok(Some(history_cwd))
|
||||
Ok(ResolveCwdOutcome::Continue(Some(history_cwd)))
|
||||
}
|
||||
|
||||
#[expect(
|
||||
|
||||
Reference in New Issue
Block a user