mirror of
https://github.com/openai/codex.git
synced 2026-10-19 08:16:48 +00:00
Remove randomized greetings from TUI session headers (#49395)
## What changed Remove startup greeting phrases and the shared greeting state from startup drafts, session headers, and the empty-state animation. Raw session headers now consistently include `model:` and `directory:` fields. ## Testing Update startup and fresh-thread snapshots to omit greetings, and adjust raw-header assertions to check model and directory fields. GitOrigin-RevId: 531b5ba42d7a88f86b1c7f69030f3560abc25198
This commit is contained in:
@@ -181,14 +181,6 @@ async fn empty_state_animation_preserves_header_cursor_and_footer() -> Result<()
|
||||
let size = Size::new(/*width*/ 120, /*height*/ 44);
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
tui.set_owned_screen(/*owned*/ true)?;
|
||||
app.chat_widget
|
||||
.empty_state_animation
|
||||
.borrow()
|
||||
.greeting
|
||||
.set(crate::empty_state_animation::Greeting {
|
||||
phrase: "Pull up a prompt.",
|
||||
})
|
||||
.expect("initial greeting");
|
||||
app.queue_clear_ui_header(&mut tui);
|
||||
app.transcript_cells
|
||||
.push(Arc::new(history_cell::StartupWarningsCell::mcp(
|
||||
@@ -209,7 +201,6 @@ async fn empty_state_animation_preserves_header_cursor_and_footer() -> Result<()
|
||||
let after = crate::custom_terminal::test_support::last_rendered_buffer(&tui.terminal);
|
||||
assert!(has_blossom(&tui));
|
||||
assert_eq!(tui.terminal.last_known_cursor_pos, cursor);
|
||||
assert!(text(&before).contains("Pull up a prompt."));
|
||||
assert_eq!(
|
||||
&after.content[after.index_of(/*x*/ 0, before_bottom.y)..],
|
||||
&before.content[before.index_of(/*x*/ 0, before_bottom.y)..]
|
||||
@@ -222,14 +213,6 @@ async fn empty_state_animation_preserves_header_cursor_and_footer() -> Result<()
|
||||
text(&before)
|
||||
)
|
||||
);
|
||||
// Editing, clearing, and resizing must never choose another phrase.
|
||||
let phrase_pos = after
|
||||
.content
|
||||
.iter()
|
||||
.position(|cell| cell.symbol() == "P")
|
||||
.expect("the phrase is visible above the composer");
|
||||
assert_eq!(after.content[phrase_pos].fg, crate::style::accent_color());
|
||||
|
||||
let short = Size::new(/*width*/ 120, /*height*/ 12);
|
||||
draw(&mut app, &mut tui, short)?;
|
||||
assert!(!has_blossom(&tui));
|
||||
@@ -242,12 +225,6 @@ async fn empty_state_animation_preserves_header_cursor_and_footer() -> Result<()
|
||||
app.chat_widget.apply_external_edit(String::new());
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
assert!(has_blossom(&tui));
|
||||
assert!(
|
||||
text(crate::custom_terminal::test_support::last_rendered_buffer(
|
||||
&tui.terminal
|
||||
))
|
||||
.contains("Pull up a prompt.")
|
||||
);
|
||||
assert_eq!(app.transcript_cells.len(), history_len);
|
||||
app.local_settings.tui.animations = false;
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
@@ -269,7 +246,7 @@ async fn empty_state_animation_preserves_header_cursor_and_footer() -> Result<()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn submitting_a_draft_keeps_greeting_and_dismisses_logo_even_after_clear() -> Result<()> {
|
||||
async fn submitting_a_draft_dismisses_logo_even_after_clear() -> Result<()> {
|
||||
let (mut app, _events, _ops) = crate::app::tests::make_test_app_with_channels().await;
|
||||
app.local_settings.tui.animations = true;
|
||||
let size = Size::new(/*width*/ 120, /*height*/ 44);
|
||||
@@ -282,20 +259,12 @@ async fn submitting_a_draft_keeps_greeting_and_dismisses_logo_even_after_clear()
|
||||
.start_fresh();
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
assert!(has_blossom(&tui));
|
||||
let greeting = *app
|
||||
.chat_widget
|
||||
.empty_state_animation
|
||||
.borrow()
|
||||
.greeting
|
||||
.get()
|
||||
.expect("choose a greeting for the fresh thread");
|
||||
app.chat_widget
|
||||
.apply_external_edit("first prompt".to_string());
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
let drafting = crate::custom_terminal::test_support::last_rendered_buffer(&tui.terminal);
|
||||
assert!(!has_blossom(&tui));
|
||||
assert!(text(drafting).contains("first prompt"));
|
||||
assert!(text(drafting).contains(greeting.phrase));
|
||||
app.chat_widget.apply_external_edit(String::new());
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
assert!(has_blossom(&tui));
|
||||
@@ -305,14 +274,9 @@ async fn submitting_a_draft_keeps_greeting_and_dismisses_logo_even_after_clear()
|
||||
.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
assert!(!has_blossom(&tui));
|
||||
let submitted = crate::custom_terminal::test_support::last_rendered_buffer(&tui.terminal);
|
||||
assert_eq!(text(submitted).matches(greeting.phrase).count(), 1);
|
||||
// The header is also stable when it scrolls out and back into the viewport.
|
||||
let short = Size::new(/*width*/ 120, /*height*/ 8);
|
||||
draw(&mut app, &mut tui, short)?;
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
let restored = crate::custom_terminal::test_support::last_rendered_buffer(&tui.terminal);
|
||||
assert!(text(restored).contains(greeting.phrase));
|
||||
assert!(!has_blossom(&tui));
|
||||
app.reset_transcript_state_after_clear();
|
||||
draw(&mut app, &mut tui, size)?;
|
||||
|
||||
@@ -316,18 +316,13 @@ impl App {
|
||||
&self,
|
||||
version: &'static str,
|
||||
) -> history_cell::SessionHeaderHistoryCell {
|
||||
let mut header = history_cell::SessionHeaderHistoryCell::new(
|
||||
history_cell::SessionHeaderHistoryCell::new(
|
||||
self.chat_widget.model_display_name().to_string(),
|
||||
self.chat_widget.current_reasoning_effort(),
|
||||
self.config.cwd.to_path_buf(),
|
||||
version,
|
||||
)
|
||||
.with_yolo_mode(history_cell::is_yolo_mode(&self.config));
|
||||
history_cell::set_session_greeting(
|
||||
&mut header,
|
||||
&self.chat_widget.empty_state_animation.borrow().greeting,
|
||||
);
|
||||
header
|
||||
.with_yolo_mode(history_cell::is_yolo_mode(&self.config))
|
||||
}
|
||||
|
||||
pub(super) fn clear_ui_header_lines(&self, width: u16) -> Vec<Line<'static>> {
|
||||
|
||||
@@ -1108,7 +1108,7 @@ impl App {
|
||||
ThreadAttachPresentation::Fresh | ThreadAttachPresentation::FreshWithDraft
|
||||
) {
|
||||
self.chat_widget.mark_fresh_task_for_sparkle(&started);
|
||||
// FreshWithDraft inherits its provisional greeting and replay at the handoff.
|
||||
// FreshWithDraft inherits its provisional replay at the handoff.
|
||||
if matches!(presentation, ThreadAttachPresentation::Fresh) {
|
||||
self.chat_widget
|
||||
.empty_state_animation
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ enabled:
|
||||
>_ OpenAI Codex (v0.0.0)
|
||||
/tmp/project
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ disabled:
|
||||
>_ OpenAI Codex (v0.0.0)
|
||||
/tmp/project
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -86,16 +86,6 @@ async fn command_center_new_keeps_startup_draft_visible_through_handoff() -> Res
|
||||
app.chat_widget.composer_text_with_pending(),
|
||||
"draft during startup"
|
||||
);
|
||||
assert_eq!(
|
||||
app.chat_widget
|
||||
.empty_state_animation
|
||||
.borrow()
|
||||
.greeting
|
||||
.get()
|
||||
.unwrap()
|
||||
.phrase,
|
||||
"Pull up a prompt."
|
||||
);
|
||||
|
||||
while let Ok(event) = events.try_recv() {
|
||||
Box::pin(app.handle_event(&mut tui, &mut server, event)).await?;
|
||||
|
||||
+4
-5
@@ -1,6 +1,5 @@
|
||||
---
|
||||
source: tui/src/app/tests/startup_frame_tests.rs
|
||||
assertion_line: 72
|
||||
expression: "normalize_snapshot_paths(normalize_agent_center_snapshot(snapshots.join(\"\\n\\n\")))"
|
||||
---
|
||||
80 columns
|
||||
@@ -8,8 +7,6 @@ expression: "normalize_snapshot_paths(normalize_agent_center_snapshot(snapshots.
|
||||
>_ OpenAI Codex (v0.0.0)
|
||||
/tmp/project
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
• Conversation continues here.
|
||||
|
||||
|
||||
@@ -20,6 +17,8 @@ expression: "normalize_snapshot_paths(normalize_agent_center_snapshot(snapshots.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
› Ask Codex to do anything
|
||||
|
||||
GPT-5.6-Sol default · /tmp/project
|
||||
@@ -30,8 +29,6 @@ expression: "normalize_snapshot_paths(normalize_agent_center_snapshot(snapshots.
|
||||
>_ OpenAI Codex (v0.0.0)
|
||||
/tmp/project
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
• Conversation continues here.
|
||||
|
||||
|
||||
@@ -42,6 +39,8 @@ expression: "normalize_snapshot_paths(normalize_agent_center_snapshot(snapshots.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
› Ask Codex to do anything
|
||||
|
||||
GPT-5.6-Sol default · /tmp/pr…
|
||||
|
||||
@@ -21,14 +21,8 @@ async fn owned_startup_hides_tip_in_transcript() -> Result<()> {
|
||||
let mut app = crate::app::test_support::make_test_app().await;
|
||||
app.local_settings.tui.show_tooltips = true;
|
||||
app.local_settings.tui.animations = false;
|
||||
let greeting = Arc::new(std::sync::OnceLock::new());
|
||||
greeting
|
||||
.set(crate::empty_state_animation::Greeting {
|
||||
phrase: "Pull up a prompt.",
|
||||
})
|
||||
.unwrap();
|
||||
let session = test_thread_session(ThreadId::new(), app.config.cwd.to_path_buf());
|
||||
let mut session_info = new_session_info(
|
||||
let session_info = new_session_info(
|
||||
&app.config,
|
||||
&app.local_settings,
|
||||
&session.model,
|
||||
@@ -38,7 +32,6 @@ async fn owned_startup_hides_tip_in_transcript() -> Result<()> {
|
||||
Some("Use /mcp to list configured MCP tools.".into()),
|
||||
/*auth_plan*/ None,
|
||||
);
|
||||
history_cell::set_session_greeting(&mut session_info, &greeting);
|
||||
app.transcript_cells = vec![
|
||||
Arc::new(session_info),
|
||||
Arc::new(AgentMessageCell::new(
|
||||
@@ -80,9 +73,8 @@ async fn owned_startup_hides_tip_in_transcript() -> Result<()> {
|
||||
.map(ToString::to_string)
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
assert!(text.contains("Pull up a prompt."));
|
||||
assert!(text.contains("Use /mcp"));
|
||||
assert!(!text.contains("model:"));
|
||||
assert_eq!(text.contains("model:"), mode == HistoryRenderMode::Raw);
|
||||
assert!(!text.contains('╭'));
|
||||
}
|
||||
app.transcript_view.begin_search();
|
||||
|
||||
@@ -64,8 +64,7 @@ impl ChatWidget {
|
||||
};
|
||||
|
||||
let empty_state_animation = crate::empty_state_animation::EmptyStateAnimation::default();
|
||||
let mut header = Self::placeholder_session_header_cell(&config);
|
||||
history_cell::set_session_greeting(header.as_mut(), &empty_state_animation.greeting);
|
||||
let header = Self::placeholder_session_header_cell(&config);
|
||||
let active_cell = Some(header);
|
||||
|
||||
let current_cwd = Some(config.cwd.to_path_buf());
|
||||
|
||||
@@ -201,7 +201,7 @@ impl ChatWidget {
|
||||
let model_for_header = self.current_model().to_string();
|
||||
if display == SessionConfiguredDisplay::Normal {
|
||||
let startup_tooltip_override = self.startup_tooltip_override.take();
|
||||
let mut session_info_cell = history_cell::new_session_info(
|
||||
let session_info_cell = history_cell::new_session_info(
|
||||
&self.config,
|
||||
&self.local_settings,
|
||||
&model_for_header,
|
||||
@@ -211,10 +211,6 @@ impl ChatWidget {
|
||||
startup_tooltip_override,
|
||||
self.plan_type,
|
||||
);
|
||||
history_cell::set_session_greeting(
|
||||
&mut session_info_cell,
|
||||
&self.empty_state_animation.borrow().greeting,
|
||||
);
|
||||
self.apply_session_info_cell(session_info_cell);
|
||||
} else if self
|
||||
.transcript
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
//! Visible time pauses while hidden. Fresh conversations start settled and can replay on a click.
|
||||
|
||||
mod geometry;
|
||||
mod greetings;
|
||||
mod lighting;
|
||||
mod paths;
|
||||
mod policy;
|
||||
mod renderer;
|
||||
mod sequence;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
@@ -24,7 +22,6 @@ use ratatui::style::Color;
|
||||
|
||||
use crate::motion::MotionMode;
|
||||
use crate::terminal_palette;
|
||||
pub(crate) use greetings::Greeting;
|
||||
use lighting::Lighting;
|
||||
pub(crate) use policy::Presentation;
|
||||
pub(crate) use policy::is_startup_cell;
|
||||
@@ -45,9 +42,6 @@ pub(crate) enum ComposerState {
|
||||
#[derive(Default)]
|
||||
pub(crate) struct EmptyStateAnimation {
|
||||
eligible: bool,
|
||||
// Initialized once for fresh threads; never initialized for a resumed or forked thread.
|
||||
// Headers retain the selection after the temporary blossom is dismissed.
|
||||
pub(crate) greeting: Arc<OnceLock<Greeting>>,
|
||||
spin_elapsed: Duration,
|
||||
last_frame: Option<Instant>,
|
||||
fade_elapsed: Duration,
|
||||
@@ -67,7 +61,6 @@ impl EmptyStateAnimation {
|
||||
pub(crate) fn start_fresh(&mut self) {
|
||||
self.cancel_replay();
|
||||
self.eligible = true;
|
||||
self.greeting.get_or_init(Greeting::choose);
|
||||
self.spin_elapsed = Duration::ZERO;
|
||||
self.last_frame = None;
|
||||
self.fade_elapsed = Duration::ZERO;
|
||||
@@ -75,16 +68,12 @@ impl EmptyStateAnimation {
|
||||
self.opacity = 1.0;
|
||||
}
|
||||
|
||||
/// Keep the provisional pose and phrase in headers already bound to the live thread.
|
||||
/// Keep the provisional pose when handing off to the live thread.
|
||||
pub(crate) fn continue_from(&mut self, source: &mut Self) {
|
||||
let mut previous = std::mem::take(source);
|
||||
if !previous.is_eligible() {
|
||||
previous.start_fresh();
|
||||
}
|
||||
if let Some(greeting) = previous.greeting.get() {
|
||||
let _ = self.greeting.set(*greeting);
|
||||
}
|
||||
previous.greeting = Arc::clone(&self.greeting);
|
||||
*self = previous;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
//! Startup phrases retained from the approved greeting list (PR #10248).
|
||||
//! One selection is shared by the provisional, live, and committed session headers.
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub(crate) struct Greeting {
|
||||
pub(crate) phrase: &'static str,
|
||||
}
|
||||
|
||||
impl Greeting {
|
||||
pub(super) fn choose() -> Self {
|
||||
Self {
|
||||
phrase: GREETINGS[rand::rng().random_range(0..GREETINGS.len())],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const GREETINGS: &[&str] = &[
|
||||
"Whoa, fancy meeting you here!",
|
||||
"Look who’s at the keyboard.",
|
||||
"Hello, you. Got an idea?",
|
||||
"Nice to see you in these parts.",
|
||||
"Pull up a prompt.",
|
||||
"What brings you to this corner of the terminal?",
|
||||
"Hey there. Big plans or little fixes?",
|
||||
"What are we getting into today?",
|
||||
"Got something you want to try?",
|
||||
"What’s today’s little adventure?",
|
||||
"Anything interesting on the docket?",
|
||||
"Take your time. The cursor can wait.",
|
||||
"A half-formed idea will do.",
|
||||
"Come on in. There’s room for an idea.",
|
||||
"You, me, and a blinking cursor.",
|
||||
"It takes two to tango. What’s our first step?",
|
||||
"You bring the idea. I’ll bring the brackets.",
|
||||
"Your move, teammate.",
|
||||
"What are we cooking up?",
|
||||
"Shall we turn “what if” into something?",
|
||||
"What’s the first thing on our napkin sketch?",
|
||||
"Bring your unfinished thoughts.",
|
||||
"You set the direction. We’ll work out the steps.",
|
||||
"Ah, the terminal. A classic meeting spot.",
|
||||
"Nice place you’ve got here. Very monospace.",
|
||||
"Welcome to our little rectangle of possibility.",
|
||||
"A cursor blinks. The plot thickens.",
|
||||
"The prompt is yours.",
|
||||
"Fancy a little quality terminal time?",
|
||||
"How’s life between the brackets?",
|
||||
"Shall we give this cursor a purpose?",
|
||||
"A fresh prompt. An open question.",
|
||||
"Your keyboard has entered the chat.",
|
||||
"Hello, world. Hello, you.",
|
||||
"Welcome to the blinking edge of possibility.",
|
||||
"Any loose ends? Semicolons count.",
|
||||
"Shall we make this terminal earn its keep?",
|
||||
"Got an itch to fix a thing?",
|
||||
"Show me the bit that’s being weird.",
|
||||
"Greetings, fellow tinkerer.",
|
||||
"Well, well, well. An idea approaches.",
|
||||
"What’s today’s side quest?",
|
||||
"Is this a plan day or a poke-around day?",
|
||||
"Practical, peculiar, or a little of both?",
|
||||
"Rough sketches welcome.",
|
||||
"Shall we see where this goes?",
|
||||
"All right. What have you got?",
|
||||
"Back for another round?",
|
||||
"Same terminal, new possibilities.",
|
||||
"Welcome back. Familiar territory or a fresh adventure?",
|
||||
"Follow the white cursor.",
|
||||
"Welcome to the command line, Neo.",
|
||||
"A glitch in the Matrix, or just a missing semicolon?",
|
||||
"How deep does this codebase go?",
|
||||
"Speak, friend, and enter a prompt.",
|
||||
"One prompt to begin the journey.",
|
||||
"May the source be with you.",
|
||||
"These might be the bugs you’re looking for.",
|
||||
"A new prompt awakens.",
|
||||
"Forty-two is an answer. What’s the question?",
|
||||
"It’s dangerous to code alone. Take a prompt.",
|
||||
"The code must flow.",
|
||||
"You rang? Metaphorically. You typed.",
|
||||
"Hello again, carbon-based collaborator.",
|
||||
"This looks like the start of a perfectly reasonable rabbit hole.",
|
||||
"Shall we turn “huh?” into “aha!”?",
|
||||
"Well, this terminal just got interesting.",
|
||||
"The source is strong with this one.",
|
||||
"There’s a perfectly good prompt with your name on it.",
|
||||
"Here for a quick fix or the extended edition?",
|
||||
"What’s the latest from your side of the keyboard?",
|
||||
"Got a minute and a mildly unreasonable idea?",
|
||||
"A hunch is a perfectly respectable starting point.",
|
||||
"Hello again. What’s the plot this time?",
|
||||
"Shall we make a little something out of nothing?",
|
||||
"Welcome to the neighborhood. Lots of characters here.",
|
||||
"Nice terminal. Does it come in widescreen?",
|
||||
"Your cursor called. It wants a plot.",
|
||||
"Shall we put some verbs after that cursor?",
|
||||
"Welcome. There’s no dress code, just code.",
|
||||
"This terminal has excellent conversational potential.",
|
||||
"Got an idea that won’t stay on the napkin?",
|
||||
"What are we building in this episode?",
|
||||
"Bring a question. Bonus points if it’s a weird one.",
|
||||
"What are we poking with a metaphorical stick?",
|
||||
"Shall we make the thing that makes the other thing easier?",
|
||||
"Welcome to the part where the idea gets interesting.",
|
||||
"A long time ago, in a directory not so far away…",
|
||||
];
|
||||
@@ -1,10 +1,6 @@
|
||||
//! Session headers, onboarding guidance, and transcript cards.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use super::*;
|
||||
use crate::empty_state_animation::Greeting;
|
||||
use crate::line_truncation::line_width;
|
||||
use crate::line_truncation::truncate_line_with_ellipsis_if_overflow;
|
||||
use crate::style::accent_color;
|
||||
@@ -110,17 +106,6 @@ impl HistoryCell for SessionNoticeCell {
|
||||
#[derive(Debug)]
|
||||
pub struct SessionInfoCell(CompositeHistoryCell);
|
||||
|
||||
/// Bind provisional and configured banners to the thread's chosen greeting.
|
||||
pub(crate) fn set_session_greeting(cell: &mut dyn HistoryCell, greeting: &Arc<OnceLock<Greeting>>) {
|
||||
if let Some(header) = cell.as_any_mut().downcast_mut::<SessionHeaderHistoryCell>() {
|
||||
header.greeting = Arc::clone(greeting);
|
||||
} else if let Some(info) = cell.as_any_mut().downcast_mut::<SessionInfoCell>() {
|
||||
for part in &mut info.0.parts {
|
||||
set_session_greeting(part.as_mut(), greeting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Fullscreen transcript presentation omits tips; scrollback retains the original cells.
|
||||
pub(crate) fn fullscreen_session_lines(
|
||||
cell: &dyn HistoryCell,
|
||||
@@ -292,7 +277,6 @@ pub(crate) struct SessionHeaderHistoryCell {
|
||||
reasoning_effort: Option<ReasoningEffortConfig>,
|
||||
directory: PathBuf,
|
||||
yolo_mode: bool,
|
||||
greeting: Arc<OnceLock<Greeting>>,
|
||||
}
|
||||
|
||||
impl SessionHeaderHistoryCell {
|
||||
@@ -308,7 +292,6 @@ impl SessionHeaderHistoryCell {
|
||||
reasoning_effort,
|
||||
directory,
|
||||
yolo_mode: false,
|
||||
greeting: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,13 +354,6 @@ impl HistoryCell for SessionHeaderHistoryCell {
|
||||
"YOLO mode".magenta().bold(),
|
||||
]));
|
||||
}
|
||||
if let Some(greeting) = self.greeting.get() {
|
||||
// The tip/help that follows has its own normal composite separator.
|
||||
lines.extend([
|
||||
Line::default(),
|
||||
Line::from(vec![" ".into(), greeting.phrase.fg(accent_color())]),
|
||||
]);
|
||||
}
|
||||
lines
|
||||
.into_iter()
|
||||
.map(|line| truncate_line_with_ellipsis_if_overflow(line, width))
|
||||
@@ -385,13 +361,6 @@ impl HistoryCell for SessionHeaderHistoryCell {
|
||||
}
|
||||
|
||||
fn raw_lines(&self) -> Vec<Line<'static>> {
|
||||
if self.greeting.get().is_some() {
|
||||
return self
|
||||
.display_lines(u16::MAX)
|
||||
.into_iter()
|
||||
.map(|line| Line::from(line.to_string()))
|
||||
.collect();
|
||||
}
|
||||
let mut lines = vec![
|
||||
Line::from(format!("OpenAI Codex (v{})", self.version)),
|
||||
Line::from(format!(
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ cursor=Some((13, 12))
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-13
@@ -1,6 +1,5 @@
|
||||
---
|
||||
source: tui/src/startup_draft_tests.rs
|
||||
assertion_line: 285
|
||||
expression: "snapshots.join(\"\\n---\\n\")"
|
||||
---
|
||||
resume lookup fallback:
|
||||
@@ -8,8 +7,6 @@ before:
|
||||
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
Resuming session…
|
||||
|
||||
› draft while loading
|
||||
@@ -20,8 +17,6 @@ after:
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
› draft while loading
|
||||
|
||||
@@ -32,8 +27,6 @@ before:
|
||||
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
Forking session…
|
||||
|
||||
› draft while loading
|
||||
@@ -44,8 +37,6 @@ after:
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
› draft while loading
|
||||
|
||||
@@ -59,8 +50,6 @@ after:
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
› Ask Codex to do anything
|
||||
|
||||
@@ -74,8 +63,6 @@ after:
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
› Ask Codex to do anything
|
||||
|
||||
|
||||
-7
@@ -1,6 +1,5 @@
|
||||
---
|
||||
source: tui/src/startup_draft_tests.rs
|
||||
assertion_line: 154
|
||||
expression: "snapshots.join(\"\\n---\\n\")"
|
||||
---
|
||||
empty (48 columns):
|
||||
@@ -8,8 +7,6 @@ empty (48 columns):
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
› Ask Codex to do anything
|
||||
|
||||
@@ -40,8 +37,6 @@ multiline (48 columns):
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
› first startup line
|
||||
second startup line
|
||||
@@ -53,8 +48,6 @@ narrow (18 columns):
|
||||
>_ OpenAI Codex…
|
||||
loading
|
||||
|
||||
Pull up a promp…
|
||||
|
||||
|
||||
› first startup
|
||||
line
|
||||
|
||||
-3
@@ -1,6 +1,5 @@
|
||||
---
|
||||
source: tui/src/startup_draft_tests.rs
|
||||
assertion_line: 802
|
||||
expression: frames
|
||||
---
|
||||
before onboarding: hidden (0x0 viewport)
|
||||
@@ -10,8 +9,6 @@ after onboarding:
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
› Ask Codex to do anything
|
||||
|
||||
|
||||
+1
-4
@@ -1,6 +1,5 @@
|
||||
---
|
||||
source: tui/src/startup_draft_tests.rs
|
||||
assertion_line: 194
|
||||
expression: "frames.join(\"\\n---\\n\").replace(crate::version::CODEX_CLI_VERSION, \"<VERSION>\")"
|
||||
---
|
||||
terminal_app_over_ssh=false, owned=true
|
||||
@@ -8,7 +7,7 @@ terminal_app_over_ssh=false, owned=true
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,8 +25,6 @@ terminal_app_over_ssh=true, owned=false
|
||||
>_ OpenAI Codex (v<VERSION>)
|
||||
loading
|
||||
|
||||
Pull up a prompt.
|
||||
|
||||
|
||||
› Ask Codex to do anything
|
||||
|
||||
|
||||
@@ -202,8 +202,7 @@ impl StartupDraftPump {
|
||||
) {
|
||||
blossom.start_fresh();
|
||||
}
|
||||
let mut header = startup_session_header(/*config*/ None);
|
||||
history_cell::set_session_greeting(header.as_mut(), &blossom.greeting);
|
||||
let header = startup_session_header(/*config*/ None);
|
||||
Self {
|
||||
header,
|
||||
blossom: std::cell::RefCell::new(blossom),
|
||||
@@ -262,7 +261,6 @@ impl StartupDraftPump {
|
||||
local_settings.tui.animations && local_settings.tui.effects.welcome,
|
||||
);
|
||||
self.header = startup_session_header(Some(config));
|
||||
history_cell::set_session_greeting(self.header.as_mut(), &self.blossom.borrow().greeting);
|
||||
self.bottom_pane.set_status_line_enabled(
|
||||
local_settings
|
||||
.tui
|
||||
|
||||
@@ -29,15 +29,8 @@ where
|
||||
{
|
||||
let (tx, rx) = unbounded_channel();
|
||||
let mut blossom = crate::empty_state_animation::EmptyStateAnimation::default();
|
||||
blossom
|
||||
.greeting
|
||||
.set(crate::empty_state_animation::Greeting {
|
||||
phrase: "Pull up a prompt.",
|
||||
})
|
||||
.expect("initial greeting");
|
||||
blossom.start_fresh();
|
||||
let mut header = startup_session_header(/*config*/ None);
|
||||
crate::history_cell::set_session_greeting(header.as_mut(), &blossom.greeting);
|
||||
let header = startup_session_header(/*config*/ None);
|
||||
StartupDraftPump {
|
||||
header,
|
||||
blossom: std::cell::RefCell::new(blossom),
|
||||
@@ -100,13 +93,6 @@ fn startup_draft_renders_full_empty_and_multiline_composer_frames() {
|
||||
] {
|
||||
let mut pump = startup_test_pump(std::iter::empty());
|
||||
pump.session_action = session_action;
|
||||
// Resume and fork have no fresh-thread greeting. Exercise the real initial state.
|
||||
if matches!(
|
||||
session_action,
|
||||
StartupDraftSessionAction::Resume | StartupDraftSessionAction::Fork
|
||||
) {
|
||||
pump.header = startup_session_header(/*config*/ None);
|
||||
}
|
||||
pump.bottom_pane
|
||||
.set_composer_text(text.to_string(), Vec::new(), Vec::new());
|
||||
let renderable =
|
||||
@@ -314,15 +300,15 @@ async fn startup_draft_hydrates_its_header_without_moving_the_composer() {
|
||||
startup_draft_renderable(&pump.header, &pump.bottom_pane, pump.session_action)
|
||||
.desired_height(width);
|
||||
|
||||
assert_eq!(pump.header.raw_lines()[2].to_string().trim(), "loading");
|
||||
assert_eq!(pump.header.raw_lines()[2].to_string(), "directory: loading");
|
||||
pump.apply_config(&config);
|
||||
let expected_directory = crate::history_cell::SessionHeaderHistoryCell::format_directory_inner(
|
||||
config.cwd.as_path(),
|
||||
/*max_width*/ None,
|
||||
);
|
||||
assert_eq!(
|
||||
pump.header.raw_lines()[2].to_string().trim(),
|
||||
expected_directory
|
||||
pump.header.raw_lines()[2].to_string(),
|
||||
format!("directory: {expected_directory}")
|
||||
);
|
||||
assert_eq!(
|
||||
startup_draft_renderable(&pump.header, &pump.bottom_pane, pump.session_action)
|
||||
|
||||
Reference in New Issue
Block a user