From d477341e6af816ff4396042b084a0378ef437b4a Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Sat, 30 May 2026 23:54:41 +0300 Subject: refactor: split agent detection by agent Move screen detection into per-agent modules and keep visible-state arbitration centralized in terminal state. Tighten Codex prompt-scoped working detection and Claude hook/screen recovery for stale blocked and idle reports. Add a focused just recipe for single-test runs. refs #349 refs #352 --- src/detect/agents/kimi.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/detect/agents/kimi.rs (limited to 'src/detect/agents/kimi.rs') diff --git a/src/detect/agents/kimi.rs b/src/detect/agents/kimi.rs new file mode 100644 index 00000000..73d1a8b0 --- /dev/null +++ b/src/detect/agents/kimi.rs @@ -0,0 +1,48 @@ +use super::super::AgentState; + +pub(super) fn detect(content: &str) -> AgentState { + if has_kimi_blocked_prompt(content) { + return AgentState::Blocked; + } + + if has_kimi_working_status(content) { + return AgentState::Working; + } + + AgentState::Idle +} + +fn has_kimi_blocked_prompt(content: &str) -> bool { + let lower = content.to_lowercase(); + lower.contains("requesting approval") + && (lower.contains("approve once") || lower.contains("approve for this session")) + && lower.contains("reject") + && (lower.contains("1/2/3/4 choose") || lower.contains("↵ confirm")) +} + +fn has_kimi_working_status(content: &str) -> bool { + content.lines().any(|line| { + let trimmed = line.trim(); + if matches!( + trimmed, + "🌕" | "🌖" | "🌗" | "🌘" | "🌑" | "🌒" | "🌓" | "🌔" + ) { + return true; + } + + let mut chars = trimmed.chars(); + let Some(first) = chars.next() else { + return false; + }; + if !('\u{2800}'..='\u{28FF}').contains(&first) { + return false; + } + + let rest = chars + .as_str() + .trim_start_matches(|c| ('\u{2800}'..='\u{28FF}').contains(&c)) + .trim_start() + .to_lowercase(); + rest.starts_with("thinking...") || rest.starts_with("using ") + }) +} -- cgit v1.2.3