aboutsummaryrefslogtreecommitdiff
path: root/src/detect/manifests
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-10 15:24:24 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-10 15:33:45 +0300
commit36a1b7f86444871f0c38ff36510a6e3c2eec48c6 (patch)
tree4a2d100eef7f26af7feaa93ce661423c3994c54e /src/detect/manifests
parent8d13492926829c5cf0ea42c8613344cd65ff59fa (diff)
feat: distribute agent detection manifests
Diffstat (limited to 'src/detect/manifests')
-rw-r--r--src/detect/manifests/amp.toml29
-rw-r--r--src/detect/manifests/antigravity.toml33
-rw-r--r--src/detect/manifests/claude.toml179
-rw-r--r--src/detect/manifests/cline.toml26
-rw-r--r--src/detect/manifests/codex.toml105
-rw-r--r--src/detect/manifests/cursor.toml57
-rw-r--r--src/detect/manifests/droid.toml48
-rw-r--r--src/detect/manifests/gemini.toml25
-rw-r--r--src/detect/manifests/github-copilot.toml30
-rw-r--r--src/detect/manifests/grok.toml28
-rw-r--r--src/detect/manifests/hermes.toml30
-rw-r--r--src/detect/manifests/kilo.toml24
-rw-r--r--src/detect/manifests/kimi.toml77
-rw-r--r--src/detect/manifests/kiro.toml51
-rw-r--r--src/detect/manifests/opencode.toml37
-rw-r--r--src/detect/manifests/pi.toml13
-rw-r--r--src/detect/manifests/qodercli.toml38
17 files changed, 830 insertions, 0 deletions
diff --git a/src/detect/manifests/amp.toml b/src/detect/manifests/amp.toml
new file mode 100644
index 00000000..97ac99e0
--- /dev/null
+++ b/src/detect/manifests/amp.toml
@@ -0,0 +1,29 @@
+id = "amp"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["amp-local"]
+
+[[rules]]
+id = "approval_footer"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+any = [
+ { contains = ["waiting for approval"] },
+ { contains = ["invoke tool"] },
+ { contains = ["run this command?"] },
+ { contains = ["allow editing file:"] },
+ { contains = ["allow creating file:"] },
+ { contains = ["confirm tool call"] },
+ { contains = ["approve"], any = [{ contains = ["allow all for this session"] }, { contains = ["allow all for every session"] }, { contains = ["allow file for every session"] }, { contains = ["deny with feedback"] }] },
+]
+
+[[rules]]
+id = "esc_cancel_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+contains = ["esc to cancel"]
diff --git a/src/detect/manifests/antigravity.toml b/src/detect/manifests/antigravity.toml
new file mode 100644
index 00000000..4e6e70b5
--- /dev/null
+++ b/src/detect/manifests/antigravity.toml
@@ -0,0 +1,33 @@
+id = "agy"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["antigravity", "antigravity-cli"]
+
+[[rules]]
+id = "permission_prompt"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+contains = ["requesting permission for:"]
+any = [
+ { contains = ["do you want to proceed?"] },
+ { contains = ["tab amend", "edit command"] },
+]
+
+[[rules]]
+id = "spinner_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+line_regex = ['^\s*[\u2800-\u28FF]+\s+\p{Alphabetic}+\w*ing\b']
+
+[[rules]]
+id = "background_tasks_working"
+state = "working"
+priority = 90
+region = "bottom_non_empty_lines(5)"
+visible_working = true
+line_regex = ['(?i).*[1-9][0-9]*\s*·?\s+tasks?.*/tasks']
diff --git a/src/detect/manifests/claude.toml b/src/detect/manifests/claude.toml
new file mode 100644
index 00000000..84177af6
--- /dev/null
+++ b/src/detect/manifests/claude.toml
@@ -0,0 +1,179 @@
+id = "claude"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["claude-code"]
+
+[[rules]]
+id = "transcript_viewer"
+state = "unknown"
+priority = 1000
+region = "bottom_non_empty_lines(3)"
+skip_state_update = true
+contains = ["showing detailed transcript"]
+any = [
+ { contains = ["ctrl+o", "to toggle"] },
+ { contains = ["ctrl+e", "show all"] },
+ { contains = ["ctrl+e", "collapse"] },
+ { contains = ["↑↓ scroll"] },
+ { contains = ["? for shortcuts"] },
+]
+
+[[rules]]
+id = "live_prompt_box"
+state = "idle"
+priority = 950
+region = "prompt_box_body"
+visible_idle = true
+line_regex = ['^\s*❯']
+not = [
+ { contains = ["enter to select"] },
+ { contains = ["esc to cancel"] },
+ { contains = ["tab/arrow keys"] },
+ { contains = ["arrow keys to navigate"] },
+ { contains = ["↑/↓ to navigate"] },
+]
+
+[[rules]]
+id = "model_picker_menu"
+state = "unknown"
+priority = 900
+region = "whole_recent"
+skip_state_update = true
+contains = ["select model", "enter to set as default", "esc to cancel"]
+not = [
+ { contains = ["do you want to proceed?"] },
+ { contains = ["enter to select"] },
+]
+
+[[rules]]
+id = "live_blocked_form"
+state = "blocked"
+priority = 980
+region = "after_last_horizontal_rule"
+visible_blocker = true
+contains = ["enter to select", "esc to cancel"]
+any = [
+ { contains = ["tab/arrow keys to navigate"] },
+ { contains = ["arrow keys to navigate"] },
+ { contains = ["arrows to navigate"] },
+ { contains = ["↑/↓ to navigate"] },
+ { contains = ["↑↓ to navigate"] },
+]
+
+[[rules]]
+id = "dynamic_workflow_prompt"
+state = "blocked"
+priority = 980
+region = "whole_recent"
+visible_blocker = true
+contains = ["run a dynamic workflow?", "esc to cancel"]
+
+[[rules]]
+id = "generic_permission_prompt"
+state = "blocked"
+priority = 840
+region = "after_last_horizontal_rule"
+visible_blocker = true
+contains = ["do you want to proceed?", "esc to cancel"]
+all = [
+ { any = [
+ { line_regex = ['(?i)^\s*❯?\s*1\.\s*yes\b'] },
+ { line_regex = ['(?i)^\s*2\.\s*yes\b'] },
+ { line_regex = ['(?i)^\s*2\.\s*no\b'] },
+ { line_regex = ['(?i)^\s*3\.\s*no\b'] },
+ ] },
+]
+
+[[rules]]
+id = "bash_permission_prompt"
+state = "blocked"
+priority = 850
+region = "whole_recent"
+visible_blocker = true
+contains = ["do you want to proceed?"]
+any = [
+ { contains = ["bash command"] },
+ { contains = ["bash("] },
+ { contains = ["contains expansion"] },
+ { contains = ["tab to amend"] },
+ { contains = ["ctrl+e to explain"] },
+]
+all = [
+ { any = [{ line_regex = ['(?i)^\s*❯?\s*yes\b'] }, { line_regex = ['(?i)^\s*1\.\s*yes\b'] }, { line_regex = ['(?i)^\s*2\.\s*no\b'] }] },
+]
+
+[[rules]]
+id = "interrupt_chrome_working"
+state = "working"
+priority = 970
+region = "above_prompt_box"
+visible_working = true
+any = [
+ { contains = ["esc to interrupt"] },
+ { contains = ["ctrl+c to interrupt"] },
+]
+
+[[rules]]
+id = "spinner_activity_working"
+state = "working"
+priority = 960
+region = "above_prompt_box"
+visible_working = true
+line_regex = ['^\s*[·✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❇❈❉❊❋✢✣✤✥✦✧✨⊛⊕⊙◉◎◍⁂⁕※⍟☼★☆]\s+.*\p{Alphabetic}.*…']
+
+[[rules]]
+id = "ascii_spinner_activity_working"
+state = "working"
+priority = 960
+region = "above_prompt_box"
+visible_working = true
+line_regex = ['^\s*\*\s+\p{Alphabetic}.*…\s*\([^)]*\b[1-9][0-9]*s\b[^)]*\)']
+
+[[rules]]
+id = "latest_background_status_working"
+state = "working"
+priority = 960
+region = "last_non_empty_above_prompt_box"
+visible_working = true
+any = [
+ { regex = ['(?i)^\W*waiting for [1-9][0-9]* background agents? to finish$'] },
+ { regex = ['(?i).*\b[1-9][0-9]* shells? still running\b'] },
+ { regex = ['(?i).*\b[1-9][0-9]* local agents? still running\b'] },
+]
+
+[[rules]]
+id = "bottom_agent_status_working"
+state = "working"
+priority = 955
+region = "bottom_non_empty_lines(10)"
+visible_working = true
+line_regex = ['^\s*◯\s+(?:Explore|Agent)\b.*\b[1-9][0-9]*s\b(?:\s*·.*)?$']
+
+[[rules]]
+id = "dynamic_workflow_progress_working"
+state = "working"
+priority = 965
+region = "bottom_non_empty_lines(10)"
+visible_working = true
+line_regex = ['^\s*[◯●]\s+.*\b(?:[0-9]+/[1-9][0-9]*) agents done\b.*\b[1-9][0-9]*s\b']
+
+[[rules]]
+id = "legacy_no_prompt_blocker"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+any = [
+ { contains = ["do you want to"], any = [{ contains = ["yes"] }, { contains = ["❯"] }] },
+ { contains = ["would you like to"], any = [{ contains = ["yes"] }, { contains = ["❯"] }] },
+ { contains = ["waiting for permission"] },
+ { contains = ["do you want to allow this connection?"] },
+ { contains = ["tab to amend"] },
+ { contains = ["ctrl+e to explain"] },
+ { contains = ["do you want to proceed?", "esc to cancel"] },
+ { contains = ["review your answers"] },
+ { contains = ["skip interview and plan immediately"] },
+]
+not = [
+ { regex = ['(?m)^\s*❯\s*$'] },
+]
diff --git a/src/detect/manifests/cline.toml b/src/detect/manifests/cline.toml
new file mode 100644
index 00000000..b30f4417
--- /dev/null
+++ b/src/detect/manifests/cline.toml
@@ -0,0 +1,26 @@
+id = "cline"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+
+[[rules]]
+id = "tool_permission"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+any = [
+ { contains = ["let cline use this tool"] },
+ { contains = ["[act mode]", "execute command?", "yes"] },
+ { contains = ["[act mode]", "use this tool?", "yes"] },
+ { contains = ["[plan mode]", "execute command?", "yes"] },
+ { contains = ["[plan mode]", "use this tool?", "yes"] },
+]
+
+[[rules]]
+id = "default_cline_working"
+state = "working"
+priority = -10
+region = "whole_recent"
+visible_working = true
+regex = ['(?s).+']
diff --git a/src/detect/manifests/codex.toml b/src/detect/manifests/codex.toml
new file mode 100644
index 00000000..cd09e4b0
--- /dev/null
+++ b/src/detect/manifests/codex.toml
@@ -0,0 +1,105 @@
+id = "codex"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+
+[[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 = "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?"] },
+]
+
+[[rules]]
+id = "current_live_working"
+state = "working"
+priority = 710
+region = "current_prompt_block_marker"
+visible_working = true
+any = [
+ { line_regex = ['(?i)^\s*• queued follow-up inputs'] },
+ { line_regex = ['(?i)^\s*• messages to be submitted after next tool call'] },
+ { contains = ["Waiting for background terminal"] },
+ { contains = ["background terminal running"] },
+ { contains = ["/ps to view"] },
+ { contains = ["/stop to close"] },
+ { regex = ['(?i)^\s*•.*\([0-9]+[hms](?: [0-9]+[hms]){0,2}.*esc\s*(…|to interrupt|to .+…)'] },
+]
+
+[[rules]]
+id = "current_working_status"
+state = "working"
+priority = 700
+region = "current_prompt_block_marker"
+any = [
+ { line_regex = ['(?i)^\s*• queued follow-up inputs'] },
+ { line_regex = ['(?i)^\s*• messages to be submitted after next tool call'] },
+ { contains = ["Working ("] },
+ { contains = ["Waiting for background terminal ("] },
+ { contains = ["Booting MCP server:"] },
+ { contains = ["reviewing approval request ("] },
+ { regex = ['(?i)reviewing .* approval requests \('] },
+ { regex = ['(?i)^\s*•.*\([0-9]+[hms](?: [0-9]+[hms]){0,2}\).* • esc(…| to interrupt| to .+…)'] },
+]
+
+[[rules]]
+id = "current_working_status_with_detail"
+state = "working"
+priority = 690
+region = "after_current_prompt_block_marker"
+any = [
+ { contains = ["Queued follow-up inputs"] },
+ { contains = ["Messages to be submitted after next tool call"] },
+]
+
+[[rules]]
+id = "weak_blocker"
+state = "blocked"
+priority = 600
+region = "whole_recent"
+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 = "fallback_working"
+state = "working"
+priority = 500
+region = "whole_recent_without_current_prompt_marker"
+visible_working = true
+any = [
+ { line_regex = ['(?i)^\s*•.*\([0-9]+[hms](?: [0-9]+[hms]){0,2}.*esc\s*(…|to interrupt|to .+…)'] },
+ { contains = ["esc to interrupt"] },
+ { all = [{ contains = ["ctrl+c to interrupt"] }, { line_regex = ['(?i)^\s*•'] }] },
+ { all = [{ contains = ["press esc to interrupt"] }, { line_regex = ['(?i)^\s*•'] }] },
+]
+
+[[rules]]
+id = "fallback_status_working"
+state = "working"
+priority = 490
+region = "whole_recent_without_current_prompt_marker"
+any = [
+ { line_regex = ['(?i)^\s*•.*(Working \(|Waiting for background terminal \(|Booting MCP server:|reviewing approval request \(|reviewing .* approval requests \()'] },
+]
diff --git a/src/detect/manifests/cursor.toml b/src/detect/manifests/cursor.toml
new file mode 100644
index 00000000..c97c03d8
--- /dev/null
+++ b/src/detect/manifests/cursor.toml
@@ -0,0 +1,57 @@
+id = "cursor"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["cursor-agent"]
+
+[[rules]]
+id = "write_file_approval"
+state = "blocked"
+priority = 320
+region = "bottom_non_empty_lines(8)"
+visible_blocker = true
+contains = ["write to this file?", "proceed (y)"]
+any = [
+ { contains = ["reject & propose changes"] },
+ { contains = ["esc or n or p"] },
+ { contains = ["add write("] },
+]
+
+[[rules]]
+id = "approval_prompt"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+any = [
+ { contains = ["waiting for approval", "run this command?"], any = [{ contains = ["run (once) (y)"] }, { contains = ["skip (esc or n)"] }] },
+ { contains = ["(y) (enter)"] },
+ { line_regex = ['(?i)^\s*allow .*\(y\)'] },
+ { contains = ["keep (n)"] },
+ { contains = ["skip (esc or n)"] },
+ { line_regex = ['(?i)^\s*(run |.*\(y\).*(allow|run \(once\)|→ run))'] },
+]
+
+[[rules]]
+id = "stop_hint_working"
+state = "working"
+priority = 100
+region = "bottom_non_empty_lines(6)"
+visible_working = true
+contains = ["ctrl+c to stop"]
+
+[[rules]]
+id = "background_task_status_working"
+state = "working"
+priority = 95
+region = "bottom_non_empty_lines(5)"
+visible_working = true
+line_regex = ['(?i)\b[1-9][0-9]*\s+background\s+tasks?\b']
+
+[[rules]]
+id = "spinner_working"
+state = "working"
+priority = 90
+region = "bottom_non_empty_lines(8)"
+visible_working = true
+line_regex = ['^\s*(⬡|⬢|[\u2800-\u28FF]+)\s+\p{Alphabetic}+\w*ing\b']
diff --git a/src/detect/manifests/droid.toml b/src/detect/manifests/droid.toml
new file mode 100644
index 00000000..c41d71b4
--- /dev/null
+++ b/src/detect/manifests/droid.toml
@@ -0,0 +1,48 @@
+id = "droid"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+
+[[rules]]
+id = "execute_selection_blocker"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+contains = ["enter to select", "esc to cancel"]
+any = [
+ { contains = ["↑↓ to navigate"] },
+ { contains = ["use ↑↓ to navigate"] },
+]
+all = [
+ { any = [{ contains = ["> yes, allow"] }, { contains = ["> no, cancel"] }] },
+]
+
+[[rules]]
+id = "selection_menu_blocker"
+state = "blocked"
+priority = 290
+region = "bottom_non_empty_lines(8)"
+visible_blocker = true
+contains = ["enter select", "esc cancel"]
+any = [
+ { contains = ["↑/↓ navigate"] },
+ { contains = ["↑↓ navigate"] },
+]
+
+[[rules]]
+id = "spinner_stop_working"
+state = "working"
+priority = 110
+region = "whole_recent"
+visible_working = true
+contains = ["esc to stop"]
+line_regex = ['^\s*[\u2800-\u28FF]']
+
+[[rules]]
+id = "stop_hint_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+contains = ["esc to stop"]
diff --git a/src/detect/manifests/gemini.toml b/src/detect/manifests/gemini.toml
new file mode 100644
index 00000000..9d7a28e1
--- /dev/null
+++ b/src/detect/manifests/gemini.toml
@@ -0,0 +1,25 @@
+id = "gemini"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+
+[[rules]]
+id = "apply_or_allow_change"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+any = [
+ { contains = ["│ Apply this change"] },
+ { contains = ["│ Allow execution"] },
+ { all = [{ contains = ["yes"] }, { any = [{ contains = ["waiting for user confirmation"] }, { contains = ["│ Do you want to proceed"] }, { contains = ["do you want to proceed?"] }] }] },
+ { line_regex = ['(?i)^\s*❯.*(yes|allow)'] },
+]
+
+[[rules]]
+id = "esc_cancel_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+contains = ["esc to cancel"]
diff --git a/src/detect/manifests/github-copilot.toml b/src/detect/manifests/github-copilot.toml
new file mode 100644
index 00000000..dcd8e2ee
--- /dev/null
+++ b/src/detect/manifests/github-copilot.toml
@@ -0,0 +1,30 @@
+id = "copilot"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["github-copilot", "ghcs"]
+
+[[rules]]
+id = "selection_blocker"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+contains = ["esc to cancel"]
+any = [
+ { contains = ["enter to select"] },
+ { contains = ["enter to confirm"] },
+ { contains = ["enter to submit"] },
+]
+
+[[rules]]
+id = "working_cancel_hint"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+any = [
+ { contains = ["esc to cancel"] },
+ { contains = ["esc cancel"] },
+ { contains = ["esc again to cancel"] },
+]
diff --git a/src/detect/manifests/grok.toml b/src/detect/manifests/grok.toml
new file mode 100644
index 00000000..f4b6537f
--- /dev/null
+++ b/src/detect/manifests/grok.toml
@@ -0,0 +1,28 @@
+id = "grok"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["grok-build"]
+
+[[rules]]
+id = "permission_scope_selector"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+contains = ["yes, proceed", "no, reject"]
+any = [
+ { contains = ["use ← → to choose permission whitelist scope"] },
+ { contains = ["←/→:scope"] },
+]
+
+[[rules]]
+id = "waiting_tool_working"
+state = "working"
+priority = 120
+region = "whole_recent"
+visible_working = true
+any = [
+ { all = [{ contains = ["ctrl+c:cancel", "ctrl+enter:interject"] }, { contains = ["waiting"] }] },
+ { line_regex = ['^\s*[\u2800-\u28FF]\s+(Run|Read|Search|List)\b'] },
+]
diff --git a/src/detect/manifests/hermes.toml b/src/detect/manifests/hermes.toml
new file mode 100644
index 00000000..d45fe32a
--- /dev/null
+++ b/src/detect/manifests/hermes.toml
@@ -0,0 +1,30 @@
+id = "hermes"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["hermes-agent"]
+
+[[rules]]
+id = "dangerous_command_approval"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+any = [
+ { contains = ["dangerous command"] },
+ { contains = ["allow once", "allow for this session", "deny"] },
+]
+all = [
+ { any = [{ contains = ["enter to confirm"] }, { contains = ["↑/↓ to select"] }, { contains = ["show full command"] }] },
+]
+
+[[rules]]
+id = "interrupt_status_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+any = [
+ { contains = ["msg=interrupt"] },
+ { contains = ["ctrl+c cancel"] },
+]
diff --git a/src/detect/manifests/kilo.toml b/src/detect/manifests/kilo.toml
new file mode 100644
index 00000000..4ef004e1
--- /dev/null
+++ b/src/detect/manifests/kilo.toml
@@ -0,0 +1,24 @@
+id = "kilo"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["kilo-code", "kilo code", "herdr:kilo"]
+
+[[rules]]
+id = "opencode_permission"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+any = [
+ { contains = ["△ Permission required"] },
+ { contains = ["esc dismiss"], any = [{ contains = ["enter confirm"] }, { contains = ["enter submit"] }, { contains = ["enter toggle"] }], all = [{ any = [{ contains = ["↑↓ select"] }, { contains = ["⇆ tab"] }] }] },
+]
+
+[[rules]]
+id = "esc_interrupt_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+contains = ["esc interrupt"]
diff --git a/src/detect/manifests/kimi.toml b/src/detect/manifests/kimi.toml
new file mode 100644
index 00000000..b4d0100f
--- /dev/null
+++ b/src/detect/manifests/kimi.toml
@@ -0,0 +1,77 @@
+id = "kimi"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["kimi-code", "kimi code"]
+
+[[rules]]
+id = "current_approval_panel"
+state = "blocked"
+priority = 400
+region = "whole_recent"
+visible_blocker = true
+contains = ["↵ confirm"]
+any = [
+ { contains = ["run this command?"] },
+ { contains = ["write this file?"] },
+ { contains = ["apply these edits?"] },
+ { contains = ["stop this task?"] },
+ { contains = ["ready to build with this plan?"] },
+ { line_regex = ['(?i)^\s*▶?\s*approve .*\?$'] },
+]
+all = [
+ { contains = [" choose"] },
+ { any = [{ contains = ["approve"] }, { contains = ["reject"] }, { contains = ["revise"] }] },
+]
+
+[[rules]]
+id = "question_panel"
+state = "blocked"
+priority = 390
+region = "whole_recent"
+visible_blocker = true
+contains = ["↑↓ select", "esc cancel"]
+line_regex = ['^\s*question\s*$', '^\s*\? ']
+any = [
+ { contains = ["↵ choose"] },
+ { contains = ["↵ toggle"] },
+ { contains = ["↵ save"] },
+]
+
+[[rules]]
+id = "legacy_approval_panel"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+contains = ["requesting approval", "reject"]
+any = [
+ { contains = ["approve once"] },
+ { contains = ["approve for this session"] },
+]
+all = [
+ { any = [{ contains = ["1/2/3/4 choose"] }, { contains = ["↵ confirm"] }] },
+]
+
+[[rules]]
+id = "background_agent_status_working"
+state = "working"
+priority = 120
+region = "bottom_non_empty_lines(3)"
+visible_working = true
+line_regex = ['(?i)\bkimi[-\w.]*\s+thinking\b.*\[[1-9][0-9]*\s+agents?\s+running\]']
+
+[[rules]]
+id = "moon_spinner_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+line_regex = ['^\s*(🌕|🌖|🌗|🌘|🌑|🌒|🌓|🌔)\s*$']
+
+[[rules]]
+id = "braille_spinner_working"
+state = "working"
+priority = 90
+region = "whole_recent"
+visible_working = true
+line_regex = ['(?i)^\s*[\u2800-\u28FF]+\s*(thinking\.\.\.|working\.\.\.|using )']
diff --git a/src/detect/manifests/kiro.toml b/src/detect/manifests/kiro.toml
new file mode 100644
index 00000000..9b0fb3d0
--- /dev/null
+++ b/src/detect/manifests/kiro.toml
@@ -0,0 +1,51 @@
+id = "kiro"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["kiro-cli"]
+
+[[rules]]
+id = "tool_approval"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+contains = ["requires approval"]
+any = [
+ { contains = ["yes, single permission"] },
+ { contains = ["trust, always allow"] },
+ { contains = ["no (tab to edit)"] },
+ { contains = ["esc to close"] },
+]
+
+[[rules]]
+id = "subagent_approval"
+state = "blocked"
+priority = 290
+region = "whole_recent"
+visible_blocker = true
+contains = ["pending from subagents"]
+any = [
+ { contains = ["tool approval"] },
+ { contains = ["tool approvals"] },
+]
+all = [
+ { any = [{ contains = ["approve all pending"] }, { contains = ["configure individually"] }, { contains = ["exit (cancel subagents)"] }] },
+]
+
+[[rules]]
+id = "kiro_working_marker"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+contains = ["kiro is working"]
+
+[[rules]]
+id = "tool_spinner_working"
+state = "working"
+priority = 90
+region = "whole_recent"
+visible_working = true
+contains = ["esc to cancel"]
+line_regex = ['^\s*(◔|◑|◕|●)\s+\p{Alphabetic}']
diff --git a/src/detect/manifests/opencode.toml b/src/detect/manifests/opencode.toml
new file mode 100644
index 00000000..52452383
--- /dev/null
+++ b/src/detect/manifests/opencode.toml
@@ -0,0 +1,37 @@
+id = "opencode"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["open-code", "herdr:opencode"]
+
+[[rules]]
+id = "permission_required"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+any = [
+ { contains = ["△ Permission required"] },
+ { contains = ["esc dismiss"], any = [{ contains = ["enter confirm"] }, { contains = ["enter submit"] }, { contains = ["enter toggle"] }], all = [{ any = [{ contains = ["↑↓ select"] }, { contains = ["⇆ tab"] }] }] },
+]
+
+[[rules]]
+id = "interrupt_hint_working"
+state = "working"
+priority = 110
+region = "whole_recent"
+visible_working = true
+any = [
+ { contains = ["esc to interrupt"] },
+ { contains = ["ctrl+c to interrupt"] },
+ { contains = ["press esc to interrupt"] },
+ { line_regex = ['(?i).*opencode.*esc (again to )?interrupt'] },
+]
+
+[[rules]]
+id = "progress_bar_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+regex = ['(■|⬝){4,}']
diff --git a/src/detect/manifests/pi.toml b/src/detect/manifests/pi.toml
new file mode 100644
index 00000000..a58d30e9
--- /dev/null
+++ b/src/detect/manifests/pi.toml
@@ -0,0 +1,13 @@
+id = "pi"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["herdr:pi"]
+
+[[rules]]
+id = "working_literal"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+contains = ["Working..."]
diff --git a/src/detect/manifests/qodercli.toml b/src/detect/manifests/qodercli.toml
new file mode 100644
index 00000000..51ca805e
--- /dev/null
+++ b/src/detect/manifests/qodercli.toml
@@ -0,0 +1,38 @@
+id = "qodercli"
+version = "2026.06.10.1"
+min_engine_version = 1
+updated_at = "2026-06-10T00:00:00Z"
+aliases = ["qoderclicn", "qoder", "qodercn"]
+
+[[rules]]
+id = "confirmation_or_input_blocker"
+state = "blocked"
+priority = 300
+region = "whole_recent"
+visible_blocker = true
+any = [
+ { contains = ["waiting for user confirmation"], any = [{ contains = ["yes"] }, { contains = ["no"] }, { contains = ["allow"] }, { contains = ["reject"] }] },
+ { contains = ["awaiting approval"], any = [{ contains = ["allow"] }, { contains = ["reject"] }] },
+ { contains = ["permission required"] },
+ { contains = ["allow once or always?"] },
+ { contains = ["asking user"] },
+ { contains = ["enter your response"] },
+ { contains = ["review your answers:"] },
+ { contains = ["shell awaiting input"] },
+]
+
+[[rules]]
+id = "cancel_hint_working"
+state = "working"
+priority = 100
+region = "whole_recent"
+visible_working = true
+contains = ["(esc to cancel,"]
+
+[[rules]]
+id = "spinner_working"
+state = "working"
+priority = 90
+region = "whole_recent"
+visible_working = true
+line_regex = ['^\s*[\u2800-\u28FF]\s+.*\p{Alphabetic}']