From 91ca551df80b77d9434587007bcc912b08915868 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Wed, 29 Apr 2026 08:56:02 -0700 Subject: [PATCH] Use /goal resume for paused goals (#20082) ## Why The paused goal statusline currently points users at `/goal` to unpause a goal, but bare `/goal` is the summary command and does not change the goal state. Instead of making `/goal` mutate state only when a goal is paused, this gives the action an explicit command that reads naturally in the UI. ## What Changed - Replace `/goal unpause` with `/goal resume` for reactivating a paused goal. - Update the paused goal statusline and `/goal` summary copy to point at `/goal resume`. --- codex-rs/tui/src/app_event.rs | 2 +- codex-rs/tui/src/bottom_pane/footer.rs | 2 +- codex-rs/tui/src/chatwidget/goal_menu.rs | 2 +- codex-rs/tui/src/chatwidget/slash_dispatch.rs | 2 +- .../codex_tui__chatwidget__tests__goal_menu_paused.snap | 2 +- codex-rs/tui/src/chatwidget/tests/slash_commands.rs | 2 +- codex-rs/tui/src/chatwidget/tests/status_and_layout.rs | 5 +---- 7 files changed, 7 insertions(+), 10 deletions(-) diff --git a/codex-rs/tui/src/app_event.rs b/codex-rs/tui/src/app_event.rs index ee0de5082..65943ee48 100644 --- a/codex-rs/tui/src/app_event.rs +++ b/codex-rs/tui/src/app_event.rs @@ -220,7 +220,7 @@ pub(crate) enum AppEvent { mode: ThreadGoalSetMode, }, - /// Pause or unpause the current thread goal. + /// Pause or resume the current thread goal. SetThreadGoalStatus { thread_id: ThreadId, status: ThreadGoalStatus, diff --git a/codex-rs/tui/src/bottom_pane/footer.rs b/codex-rs/tui/src/bottom_pane/footer.rs index 3fc18bb14..c17f8fb4f 100644 --- a/codex-rs/tui/src/bottom_pane/footer.rs +++ b/codex-rs/tui/src/bottom_pane/footer.rs @@ -548,7 +548,7 @@ pub(crate) fn goal_status_indicator_line( "Pursuing goal".to_string() } } - GoalStatusIndicator::Paused => "Goal paused (/goal to unpause)".to_string(), + GoalStatusIndicator::Paused => "Goal paused (/goal resume)".to_string(), GoalStatusIndicator::BudgetLimited { usage } => { if let Some(usage) = usage { format!("Goal unmet ({usage})") diff --git a/codex-rs/tui/src/chatwidget/goal_menu.rs b/codex-rs/tui/src/chatwidget/goal_menu.rs index 74c8cde88..86562778e 100644 --- a/codex-rs/tui/src/chatwidget/goal_menu.rs +++ b/codex-rs/tui/src/chatwidget/goal_menu.rs @@ -45,7 +45,7 @@ fn goal_summary_lines(goal: &AppThreadGoal) -> Vec> { } let command_hint = match goal.status { AppThreadGoalStatus::Active => "Commands: /goal pause, /goal clear", - AppThreadGoalStatus::Paused => "Commands: /goal unpause, /goal clear", + AppThreadGoalStatus::Paused => "Commands: /goal resume, /goal clear", AppThreadGoalStatus::BudgetLimited | AppThreadGoalStatus::Complete => { "Commands: /goal clear" } diff --git a/codex-rs/tui/src/chatwidget/slash_dispatch.rs b/codex-rs/tui/src/chatwidget/slash_dispatch.rs index 4936f385b..82f366fbb 100644 --- a/codex-rs/tui/src/chatwidget/slash_dispatch.rs +++ b/codex-rs/tui/src/chatwidget/slash_dispatch.rs @@ -617,7 +617,7 @@ impl ChatWidget { let control_command = match trimmed.to_ascii_lowercase().as_str() { "clear" => Some(GoalControlCommand::Clear), "pause" => Some(GoalControlCommand::SetStatus(AppThreadGoalStatus::Paused)), - "unpause" => Some(GoalControlCommand::SetStatus(AppThreadGoalStatus::Active)), + "resume" => Some(GoalControlCommand::SetStatus(AppThreadGoalStatus::Active)), _ => None, }; if let Some(command) = control_command { diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__goal_menu_paused.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__goal_menu_paused.snap index 83fe79578..a02e353cb 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__goal_menu_paused.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__goal_menu_paused.snap @@ -8,4 +8,4 @@ Objective: Keep improving the bare goal command until it feels calm and useful. Time used: 1m Tokens used: 12.5K -Commands: /goal unpause, /goal clear +Commands: /goal resume, /goal clear diff --git a/codex-rs/tui/src/chatwidget/tests/slash_commands.rs b/codex-rs/tui/src/chatwidget/tests/slash_commands.rs index a0ba30e64..339021e2d 100644 --- a/codex-rs/tui/src/chatwidget/tests/slash_commands.rs +++ b/codex-rs/tui/src/chatwidget/tests/slash_commands.rs @@ -810,7 +810,7 @@ async fn goal_control_slash_commands_emit_goal_events() { let cases = [ ("/goal clear", None), ("/goal pause", Some(AppThreadGoalStatus::Paused)), - ("/goal unpause", Some(AppThreadGoalStatus::Active)), + ("/goal resume", Some(AppThreadGoalStatus::Active)), ]; for (command, status) in cases { diff --git a/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs b/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs index c71c57dfe..eff2c409e 100644 --- a/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs +++ b/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs @@ -1901,10 +1901,7 @@ fn goal_status_indicator_line_formats_goal_text() { }, "Goal unmet (4K / 5K tokens)", ), - ( - GoalStatusIndicator::Paused, - "Goal paused (/goal to unpause)", - ), + (GoalStatusIndicator::Paused, "Goal paused (/goal resume)"), ( GoalStatusIndicator::BudgetLimited { usage: None }, "Goal abandoned",