diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-01 23:47:40 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-01 23:47:40 +0300 |
| commit | 9709ba6938bd720fea6d8dd15346adf9db2b7f4b (patch) | |
| tree | 4da522fa3a5e43ef25bef2a12b12734caa839688 | |
| parent | 36a4608603a82dbf32ec8a013dd47047cf02c6a3 (diff) | |
fix: detect kiro subagent approvals
refs #388
| -rw-r--r-- | docs/next/CHANGELOG.md | 1 | ||||
| -rw-r--r-- | src/detect/agents/kiro.rs | 32 | ||||
| -rw-r--r-- | src/detect/mod.rs | 6 |
3 files changed, 32 insertions, 7 deletions
diff --git a/docs/next/CHANGELOG.md b/docs/next/CHANGELOG.md index 130143cc..37b315c8 100644 --- a/docs/next/CHANGELOG.md +++ b/docs/next/CHANGELOG.md @@ -10,6 +10,7 @@ - Native agent session restore is now enabled by default for supported panes with current official integrations. Set `[session] resume_agents_on_restore = false` to disable it. ### Fixed +- Kiro sub-agent tool approval prompts are now detected as blocked instead of working. (#388) - Pane input no longer waits behind the PTY actor's idle read poll, restoring responsive typing at quiet shell prompts. (#379) - Pane apps that query OSC 4 ANSI palette colors now receive the active terminal palette response, so OpenCode and similar TUIs can enable system-theme behavior inside Herdr. (#387) - Pane text selection now derives its highlight colors from the host terminal or active Herdr palette instead of forcing the theme's blue accent. (#298) 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 @@ -1900,6 +1900,12 @@ mod tests { } #[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 ↵"; assert_eq!(detect_state(Some(Agent::Kiro), screen), AgentState::Idle); |
