aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJJ Liebig <jonathan.liebig@gmail.com>2026-09-05 02:14:07 +0200
committerGitHub <noreply@github.com>2026-09-05 02:14:07 +0200
commit987651a760cdfe4cd9493388e8c16b8f99643a05 (patch)
treeac40df14ab6b2a270cf8a862b2cc838e2ae1b0d9
parent8162e26509f7b91eb8dcfd47387d43af3f348bbb (diff)
fix: detect codex startup update prompts (#3636)
refs #3632
-rw-r--r--distribution/agent-detection/codex.toml13
-rw-r--r--src/detect/manifest/tests.rs41
-rw-r--r--src/detect/manifests/codex.toml13
3 files changed, 63 insertions, 4 deletions
diff --git a/distribution/agent-detection/codex.toml b/distribution/agent-detection/codex.toml
index 6833f390..884492c4 100644
--- a/distribution/agent-detection/codex.toml
+++ b/distribution/agent-detection/codex.toml
@@ -1,7 +1,7 @@
id = "codex"
-version = "2026.08.28.1"
+version = "2026.09.05.1"
min_engine_version = 3
-updated_at = "2026-08-28T00:00:00Z"
+updated_at = "2026-09-05T00:00:00Z"
[[rules]]
id = "osc_title_blocked"
@@ -43,6 +43,15 @@ all = [
]
[[rules]]
+id = "startup_update"
+state = "blocked"
+priority = 950
+region = "bottom_non_empty_lines(20)"
+visible_blocker = true
+contains = ["Update available!", "Update now"]
+regex = ['Skip\s+until\s+next\s+version', 'Press enter to continue\s*\z']
+
+[[rules]]
id = "live_strong_blocker"
state = "blocked"
priority = 900
diff --git a/src/detect/manifest/tests.rs b/src/detect/manifest/tests.rs
index 63345636..00730a44 100644
--- a/src/detect/manifest/tests.rs
+++ b/src/detect/manifest/tests.rs
@@ -932,6 +932,47 @@ fn codex_trust_directory_requires_live_top_region() {
}
#[test]
+fn codex_startup_update_requires_complete_live_chooser() {
+ let chooser = "Update available! 0.153.0 -> 9.8.7\n\
+ Run bun add -g @openai/codex to update.\n\n\
+ › 1. Update now\n\
+ 2. Skip until next version\n\n\
+ Press enter to continue \n";
+ let wrapped = "✨ Update available! 0.153.0\n\n\
+ Release notes: https://example\n\n\
+ › 1. Update now (runs `npm\n\
+ install -g\n\
+ @openai/codex`)\n\
+ 2. Skip\n\
+ 3. Skip until next\n\
+ version\n\n\
+ Press enter to continue\n";
+
+ for screen in [chooser, wrapped] {
+ let result = osc_explain(Agent::Codex, screen, "project", "");
+ assert_eq!(result.state, AgentState::Blocked);
+ assert_eq!(
+ result.matched_rule.as_ref().map(|rule| rule.id.as_str()),
+ Some("startup_update")
+ );
+ assert!(result.visible_blocker);
+ }
+
+ for screen in [
+ chooser.replace("Update now", "Install"),
+ format!("{wrapped}\n› Ask Codex to do anything\n"),
+ ] {
+ let result = osc_explain(Agent::Codex, &screen, "project", "");
+ assert_eq!(result.state, AgentState::Idle);
+ assert_ne!(
+ result.matched_rule.as_ref().map(|rule| rule.id.as_str()),
+ Some("startup_update")
+ );
+ assert!(!result.visible_blocker);
+ }
+}
+
+#[test]
fn codex_background_terminal_screen_does_not_override_osc_idle() {
// Background terminal tasks can be long-lived helpers such as dev servers.
// They should not make Codex look busy once the foreground turn is idle.
diff --git a/src/detect/manifests/codex.toml b/src/detect/manifests/codex.toml
index 6833f390..884492c4 100644
--- a/src/detect/manifests/codex.toml
+++ b/src/detect/manifests/codex.toml
@@ -1,7 +1,7 @@
id = "codex"
-version = "2026.08.28.1"
+version = "2026.09.05.1"
min_engine_version = 3
-updated_at = "2026-08-28T00:00:00Z"
+updated_at = "2026-09-05T00:00:00Z"
[[rules]]
id = "osc_title_blocked"
@@ -43,6 +43,15 @@ all = [
]
[[rules]]
+id = "startup_update"
+state = "blocked"
+priority = 950
+region = "bottom_non_empty_lines(20)"
+visible_blocker = true
+contains = ["Update available!", "Update now"]
+regex = ['Skip\s+until\s+next\s+version', 'Press enter to continue\s*\z']
+
+[[rules]]
id = "live_strong_blocker"
state = "blocked"
priority = 900