From 9709ba6938bd720fea6d8dd15346adf9db2b7f4b Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Mon, 1 Jun 2026 23:47:40 +0300 Subject: fix: detect kiro subagent approvals refs #388 --- src/detect/agents/kiro.rs | 32 +++++++++++++++++++++++++------- src/detect/mod.rs | 6 ++++++ 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/detect/agents/kiro.rs b/src/detect/agents/kiro.rs index 5ef1fbca..f40b9bcb 100644 --- a/src/detect/agents/kiro.rs +++ b/src/detect/agents/kiro.rs @@ -3,16 +3,11 @@ use super::super::AgentState; /// Kiro CLI detection. /// /// Kiro exposes reliable working and idle terminal markers. Tool approval -/// prompts render with a stable "requires approval" line and an action menu. +/// prompts render with stable approval wording and an action menu. pub(super) fn detect(content: &str) -> AgentState { let lower = content.to_lowercase(); - let has_approval_request = lower.contains("requires approval"); - let has_approval_actions = lower.contains("yes, single permission") - || lower.contains("trust, always allow") - || lower.contains("no (tab to edit)") - || lower.contains("esc to close"); - if has_approval_request && has_approval_actions { + if has_kiro_blocked_prompt(&lower) { return AgentState::Blocked; } @@ -25,6 +20,29 @@ pub(super) fn detect(content: &str) -> AgentState { AgentState::Idle } +fn has_kiro_blocked_prompt(lower_content: &str) -> bool { + has_tool_approval_prompt(lower_content) || has_subagent_approval_prompt(lower_content) +} + +fn has_tool_approval_prompt(lower_content: &str) -> bool { + let has_approval_request = lower_content.contains("requires approval"); + let has_approval_actions = lower_content.contains("yes, single permission") + || lower_content.contains("trust, always allow") + || lower_content.contains("no (tab to edit)") + || lower_content.contains("esc to close"); + has_approval_request && has_approval_actions +} + +fn has_subagent_approval_prompt(lower_content: &str) -> bool { + let has_approval_request = (lower_content.contains("tool approval") + || lower_content.contains("tool approvals")) + && lower_content.contains("pending from subagents"); + let has_approval_actions = lower_content.contains("approve all pending") + || lower_content.contains("configure individually") + || lower_content.contains("exit (cancel subagents)"); + has_approval_request && has_approval_actions +} + fn has_kiro_tool_spinner(content: &str) -> bool { content.lines().any(|line| { let trimmed = line.trim_start(); diff --git a/src/detect/mod.rs b/src/detect/mod.rs index b9806b19..e5f84628 100644 --- a/src/detect/mod.rs +++ b/src/detect/mod.rs @@ -1899,6 +1899,12 @@ mod tests { assert_eq!(detect_state(Some(Agent::Kiro), screen), AgentState::Blocked); } + #[test] + fn kiro_blocked_on_subagent_tool_approval_prompt() { + let screen = " Please delegate to a sub-agent to search the web\n\n● Orchestrating (1 agent)\n esc to cancel\n ctrl+g open agent monitor\n ● web-research kiro_default ⚠ tool approval needed\n\n ◐ Tasks · 1 done · 2 remaining ctrl+x to expand\n──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n ⚠ 3 tool approvals pending from subagents\n ❯ (a) Approve all pending\n (f) Approve all pending and auto-approve all future requests\n (c) Configure individually (agent monitor)\n (x) Exit (cancel subagents) %"; + assert_eq!(detect_state(Some(Agent::Kiro), screen), AgentState::Blocked); + } + #[test] fn kiro_does_not_treat_stale_failure_spinner_as_working() { let screen = "● 1 MCP failure — see /mcp\n─────────────────────────────────────────────────────\nKiro · auto · ◔ 6%\n\n ask a question or describe a task ↵"; -- cgit v1.2.3