Remove the Plan mode composer nudge (#40200)

## What changed

- Keep the normal composer footer visible when a draft contains the word `plan`.
- Remove the contextual “Create a plan?” prompt, its Escape dismissal behavior, and its per-thread dismissal state.

## Testing

- Update wide and narrow composer snapshots to cover the standard footer for plan-related drafts.

GitOrigin-RevId: 1a3c8cfce9d4effa2149790975133f652aa7c914
This commit is contained in:
Eric Traut authored and copyberry committed 2026-08-23 07:24:57 +00:00
1 parent 4582c0a498
commit 83d1fe0e67
14 files changed
+22 -295

No files matched your search

-25
View File
@@ -667,11 +667,6 @@ pub(crate) struct ChatWidget {
#[cfg(test)]
pet_image_support_override: Option<crate::pets::PetImageSupport>,
thread_id: Option<ThreadId>,
/// Nudge dismissals that should survive draft edits within the current thread scope.
///
/// The nudge is only a discovery aid, so once a user dismisses it or enters Plan mode we keep it
/// hidden for that thread instead of resurfacing it on every matching draft.
dismissed_plan_mode_nudge_scopes: HashSet<PlanModeNudgeScope>,
thread_name: Option<String>,
thread_rename_block_message: Option<String>,
active_side_conversation: bool,
@@ -835,31 +830,12 @@ enum SessionConfiguredDisplay {
SideConversation,
}
/// Scope used to keep Plan-mode nudge dismissal local to one conversation context.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
enum PlanModeNudgeScope {
/// Drafts entered before the server has assigned a thread id.
NewThread,
/// Drafts associated with one configured thread.
Thread(ThreadId),
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub(crate) enum TurnAbortReason {
Interrupted,
BudgetLimited,
}
/// Returns whether `text` contains the standalone word `plan`.
///
/// This intentionally mirrors the App suggestion heuristic instead of trying to infer broader
/// planning intent from substrings such as `planning`. Slash and shell drafts still match here so
/// callers can keep lexical matching separate from presentation policy.
fn contains_plan_keyword(text: &str) -> bool {
text.split(|ch: char| !ch.is_alphanumeric() && ch != '_')
.any(|word| word.eq_ignore_ascii_case("plan"))
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum ThreadItemRenderSource {
Live,
@@ -1224,7 +1200,6 @@ impl ChatWidget {
if let Some(pet) = self.ambient_pet.as_ref() {
pet.schedule_next_frame();
}
self.refresh_plan_mode_nudge();
self.refresh_goal_status_indicator_for_time_tick();
if self.terminal_title_shows_action_required() != self.last_terminal_title_requires_action {
self.refresh_terminal_title();