[codex-tui] exit when terminal is dumb (#9293)

Using terminal with TERM=dumb specifically mean that TUIs and the like
don't work. Ensure that codex doesn't run in these environments and exit
with odd errors like crossterm's "Error: The cursor position could not
be read within a normal duration"

---------

Co-authored-by: Josh McKinney <joshka@openai.com>
This commit is contained in:
Jeff Mickey
2026-01-20 16:17:38 -08:00
committed by GitHub
parent 80f80181c2
commit c14e6813fb
3 changed files with 60 additions and 1 deletions

View File

@@ -47,6 +47,8 @@ pub enum TerminalName {
Vte,
/// Windows Terminal emulator.
WindowsTerminal,
/// Dumb terminal (TERM=dumb).
Dumb,
/// Unknown or missing terminal identification.
Unknown,
}
@@ -131,7 +133,12 @@ impl TerminalInfo {
/// Creates terminal metadata from a `TERM` capability value.
fn from_term(term: String, multiplexer: Option<Multiplexer>) -> Self {
Self::new(TerminalName::Unknown, None, None, Some(term), multiplexer)
let name = if term == "dumb" {
TerminalName::Dumb
} else {
TerminalName::Unknown
};
Self::new(name, None, None, Some(term), multiplexer)
}
/// Creates terminal metadata for unknown terminals.
@@ -166,6 +173,7 @@ impl TerminalInfo {
TerminalName::GnomeTerminal => "gnome-terminal".to_string(),
TerminalName::Vte => format_terminal_version("VTE", &self.version),
TerminalName::WindowsTerminal => "WindowsTerminal".to_string(),
TerminalName::Dumb => "dumb".to_string(),
TerminalName::Unknown => "unknown".to_string(),
}
};
@@ -435,6 +443,7 @@ fn terminal_name_from_term_program(value: &str) -> Option<TerminalName> {
"gnometerminal" => Some(TerminalName::GnomeTerminal),
"vte" => Some(TerminalName::Vte),
"windowsterminal" => Some(TerminalName::WindowsTerminal),
"dumb" => Some(TerminalName::Dumb),
_ => None,
}
}
@@ -1136,6 +1145,15 @@ mod tests {
"term_fallback_user_agent"
);
let env = FakeEnvironment::new().with_var("TERM", "dumb");
let terminal = detect_terminal_info_from_env(&env);
assert_eq!(
terminal,
terminal_info(TerminalName::Dumb, None, None, Some("dumb"), None),
"dumb_term_info"
);
assert_eq!(terminal.user_agent_token(), "dumb", "dumb_term_user_agent");
let env = FakeEnvironment::new();
let terminal = detect_terminal_info_from_env(&env);
assert_eq!(