fix terminal corruption that could happen when onboarding and update banner (#5269)

Instead of printing characters before booting the app, make the upgrade
banner a history cell so it's well-behaved.

<img width="771" height="586" alt="Screenshot 2025-10-16 at 4 20 51 PM"
src="https://github.com/user-attachments/assets/90629d47-2c3d-4970-a826-283795ab34e5"
/>

---------

Co-authored-by: Josh McKinney <joshka@openai.com>
This commit is contained in:
Jeremy Rose
2025-10-20 14:40:14 -07:00
committed by GitHub
parent 5c680c6587
commit 58159383c4
9 changed files with 157 additions and 130 deletions

View File

@@ -15,6 +15,8 @@ use crate::style::user_message_style;
use crate::text_formatting::format_and_truncate_tool_result;
use crate::text_formatting::truncate_text;
use crate::ui_consts::LIVE_PREFIX_COLS;
use crate::updates::UpdateAction;
use crate::version::CODEX_CLI_VERSION;
use crate::wrapping::RtOptions;
use crate::wrapping::word_wrap_line;
use crate::wrapping::word_wrap_lines;
@@ -264,6 +266,60 @@ impl HistoryCell for PlainHistoryCell {
}
}
#[cfg_attr(debug_assertions, allow(dead_code))]
#[derive(Debug)]
pub(crate) struct UpdateAvailableHistoryCell {
latest_version: String,
update_action: Option<UpdateAction>,
}
#[cfg_attr(debug_assertions, allow(dead_code))]
impl UpdateAvailableHistoryCell {
pub(crate) fn new(latest_version: String, update_action: Option<UpdateAction>) -> Self {
Self {
latest_version,
update_action,
}
}
}
impl HistoryCell for UpdateAvailableHistoryCell {
fn display_lines(&self, width: u16) -> Vec<Line<'static>> {
use ratatui_macros::line;
use ratatui_macros::text;
let update_instruction = if let Some(update_action) = self.update_action {
line!["Run ", update_action.command_str().cyan(), " to update."]
} else {
line![
"See ",
"https://github.com/openai/codex".cyan().underlined(),
" for installation options."
]
};
let content = text![
line![
padded_emoji("").bold().cyan(),
"Update available!".bold().cyan(),
" ",
format!("{CODEX_CLI_VERSION} -> {}", self.latest_version).bold(),
],
update_instruction,
"",
"See full release notes:",
"https://github.com/openai/codex/releases/latest"
.cyan()
.underlined(),
];
let inner_width = content
.width()
.min(usize::from(width.saturating_sub(4)))
.max(1);
with_border_with_inner_width(content.lines, inner_width)
}
}
#[derive(Debug)]
pub(crate) struct PrefixedWrappedHistoryCell {
text: Text<'static>,