aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-26 13:42:29 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-26 13:53:37 +0300
commit843653c0f56390373ba018f5f380011e3af3c14b (patch)
tree93f7e6c782f3be2bed48a4ca5c3ee54aaebd1120 /src
parent6c4a947244b7be05496f9d3bd5ad2d00a69cca03 (diff)
fix: detect codex background terminal waits
Diffstat (limited to 'src')
-rw-r--r--src/detect.rs51
1 files changed, 40 insertions, 11 deletions
diff --git a/src/detect.rs b/src/detect.rs
index 38ec562b..32b7a6cd 100644
--- a/src/detect.rs
+++ b/src/detect.rs
@@ -783,13 +783,7 @@ fn has_visible_working(agent: Agent, content: &str, state: AgentState) -> bool {
fn has_codex_visible_working(content: &str) -> bool {
let lines: Vec<&str> = content.lines().collect();
- let Some(working_index) = lines.iter().rposition(|line| {
- let trimmed = line.trim_start();
- let lower = trimmed.to_lowercase();
- trimmed.starts_with('•')
- && trimmed.contains("Working (")
- && (lower.contains("esc to interrupt") || lower.contains("esc…"))
- }) else {
+ let Some(working_index) = lines.iter().rposition(|line| codex_live_working_line(line)) else {
return false;
};
@@ -803,10 +797,22 @@ fn has_codex_visible_working(content: &str) -> bool {
}
fn has_codex_working_header(content: &str) -> bool {
- content.lines().any(|line| {
- let trimmed = line.trim_start();
- trimmed.starts_with('•') && trimmed.contains("Working (")
- })
+ content.lines().any(codex_working_status_line)
+}
+
+fn codex_live_working_line(line: &str) -> bool {
+ let trimmed = line.trim_start();
+ let lower = trimmed.to_lowercase();
+ codex_working_status_line(line)
+ && (trimmed.contains("Waiting for background terminal")
+ || lower.contains("esc to interrupt")
+ || lower.contains("esc…"))
+}
+
+fn codex_working_status_line(line: &str) -> bool {
+ let trimmed = line.trim_start();
+ trimmed.starts_with('•')
+ && (trimmed.contains("Working (") || trimmed.contains("Waiting for background terminal ("))
}
fn has_codex_prompt(content: &str) -> bool {
@@ -1759,6 +1765,18 @@ mod tests {
}
#[test]
+ fn codex_background_terminal_wait_is_visible_working() {
+ let detection = detect_agent(
+ Some(Agent::Codex),
+ "• Waiting for background terminal (0s • esc to …\n └ cargo test -p codex-core -- --exact…\n\n\n› Ask Codex to do anything",
+ );
+
+ assert_eq!(detection.state, AgentState::Working);
+ assert!(detection.visible_working);
+ assert!(!detection.visible_idle);
+ }
+
+ #[test]
fn codex_working_header_without_interrupt_is_not_visible_working() {
let detection = detect_agent(
Some(Agent::Codex),
@@ -1781,6 +1799,17 @@ mod tests {
}
#[test]
+ fn codex_old_background_terminal_wait_before_later_block_is_not_visible_working() {
+ let detection = detect_agent(
+ Some(Agent::Codex),
+ "• Waiting for background terminal (0s • esc to …\n └ cargo test -p codex-core\n\n• Ran git status --short\n └ M src/detect.rs\n\n› Implement {feature}",
+ );
+
+ assert_eq!(detection.state, AgentState::Working);
+ assert!(!detection.visible_working);
+ }
+
+ #[test]
fn codex_idle() {
assert_eq!(detect_codex("❯ "), AgentState::Idle);
}