aboutsummaryrefslogtreecommitdiff
path: root/crates/detect-core/src/manifests/codex.toml
diff options
context:
space:
mode:
Diffstat (limited to 'crates/detect-core/src/manifests/codex.toml')
-rw-r--r--crates/detect-core/src/manifests/codex.toml129
1 files changed, 129 insertions, 0 deletions
diff --git a/crates/detect-core/src/manifests/codex.toml b/crates/detect-core/src/manifests/codex.toml
new file mode 100644
index 0000000..d35820c
--- /dev/null
+++ b/crates/detect-core/src/manifests/codex.toml
@@ -0,0 +1,129 @@
+id = "codex"
+version = "2026.10.11.1"
+min_engine_version = 3
+updated_at = "2026-10-11T00:00:00Z"
+
+[[rules]]
+id = "osc_title_blocked"
+state = "blocked"
+priority = 1100
+region = "osc_title"
+visible_blocker = true
+contains = ["Action Required"]
+
+[[rules]]
+id = "osc_title_working"
+state = "working"
+priority = 1050
+region = "osc_title"
+visible_working = true
+regex = ['(?:^| )[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏](?: |$)']
+
+[[rules]]
+id = "transcript_viewer"
+state = "unknown"
+priority = 1000
+region = "after_last_prompt_marker"
+skip_state_update = true
+contains = ["↑/↓ to scroll", "pgup/pgdn to", "home/end to jump", "q to quit"]
+any = [
+ { contains = ["esc to edit prev"] },
+ { contains = ["esc/← to edit prev"] },
+]
+
+[[rules]]
+id = "trust_directory"
+state = "blocked"
+priority = 950
+region = "top_non_empty_lines(20)"
+visible_blocker = true
+all = [
+ { any = [
+ { regex = ['\A> You are in [^\r\n]+(?:\r?\n|$)'] },
+ { contains = ["Folder access"] },
+ ] },
+ { any = [
+ { regex = ['(?s)Do\s+you\s+trust\s+the\s+contents\s+of\s+this\s+directory\?'] },
+ { all = [
+ { contains = ["Trust this folder?", "Codex can read, edit, and run files here"] },
+ { any = [
+ { contains = ["Trust and continue"] },
+ { contains = ["enter continue"] },
+ ] },
+ ] },
+ ] },
+]
+
+[[rules]]
+id = "startup_update"
+state = "blocked"
+priority = 950
+region = "bottom_non_empty_lines(20)"
+visible_blocker = true
+# Keep the legacy dialog; the shared picker (0.159+) has a different heading
+# and footer. Choices can scroll out of a short viewport, but both gates must
+# remain visible. The passive update history notice has neither picker footer.
+any = [
+ { all = [
+ { contains = ["Update available!", "Update now"] },
+ { regex = ['Skip\s+until\s+next\s+version', 'Press enter to continue\s*\z'] },
+ ] },
+ { all = [
+ { regex = ['(?m)^\s*Update\s+available\s+·'] },
+ { regex = ['enter\s+continue\s+·\s+esc\s+skip\s*\z'] },
+ ] },
+]
+
+[[rules]]
+id = "live_strong_blocker"
+state = "blocked"
+priority = 900
+region = "after_last_prompt_marker"
+visible_blocker = true
+any = [
+ { contains = ["press enter to confirm or esc to cancel"] },
+ { contains = ["enter to submit answer"] },
+ { contains = ["enter to submit all"] },
+ { contains = ["allow command?"] },
+ { contains = ["All Results", "Filesystem Only", "Plugins"] },
+]
+
+[[rules]]
+id = "weak_blocker"
+state = "blocked"
+priority = 600
+region = "whole_recent_without_current_prompt_marker"
+# Sparkles can replace the space after ›. A later response marker makes that prompt stale.
+not = [{ regex = ['(?m)^›[⠁⠂⠄⠈⠐⠠⡀⢀][^\n]*(?:\n(?:[^•■✗✓\n][^\n]*)?)*\z'] }]
+any = [
+ { contains = ["[y/n]"] },
+ { contains = ["yes (y)"] },
+ { contains = ["do you want to"], any = [{ contains = ["yes"] }, { contains = ["❯"] }] },
+ { contains = ["would you like to"], any = [{ contains = ["yes"] }, { contains = ["❯"] }] },
+]
+
+[[rules]]
+id = "screen_working_fallback"
+state = "working"
+priority = 500
+region = "before_current_prompt_marker"
+visible_working = true
+# Support animated and reduced-motion status, including dynamic activity labels.
+# The interrupt hint can be remapped, unbound, or hidden, and queued inputs can
+# sit below the status. Require the live timer suffix with no later response.
+any = [{ contains = [" to interrupt)"] }, { contains = ["s)"] }]
+regex = ['(?m)^(?:[•◦][ \t]+)?[^\s›•◦■✗✓─][^\r\n]* \((?:[0-9]+[hm] )*[0-9]+s(?: • [^\r\n]+? to interrupt)?\)(?: · [^\r\n]*)?(?:\r?\n(?:[^•◦›■✗✓─\r\n][^\r\n]*|•[ \t]+(?:Queued\s+follow-up\s+inputs|Messages\s+to\s+be\s+submitted\s+after\s+next\s+tool\s+call(?:\s+\(press\s+[^\r\n]+?\s+to\s+interrupt\s+and\s+send\s+immediately\))?|Messages\s+to\s+be\s+submitted\s+at\s+end\s+of\s+turn)|›[⠁⠂⠄⠈⠐⠠⡀⢀][^\r\n]*)?)*\s*\z']
+# A failed reconnect keeps its final elapsed timer but is no longer working.
+not = [{ line_regex = ['^(?:[•◦][ \t]+)?Reconnect failed — check the endpoint, then relaunch \([0-9hms ]+\)$'] }]
+
+[[rules]]
+id = "osc_title_idle"
+state = "idle"
+priority = 100
+region = "osc_title"
+visible_idle = true
+regex = ['\S']
+not = [
+ { regex = ['(?:^| )[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏](?: |$)'] },
+ { contains = ["Action Required"] },
+]