diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-03 19:21:07 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-03 19:21:50 +0300 |
| commit | 5c86f0660f538553850e2c8fb0493372a48cb511 (patch) | |
| tree | 7715866a3a57ace0730eb6acbce75a95dc895fdb /src/detect | |
| parent | f5e66b251fa8ec24989bf25861bcf4e38a561470 (diff) | |
fix: avoid claude custom status false blocked
refs #409
Diffstat (limited to 'src/detect')
| -rw-r--r-- | src/detect/agents/claude_code.rs | 19 | ||||
| -rw-r--r-- | src/detect/mod.rs | 10 |
2 files changed, 27 insertions, 2 deletions
diff --git a/src/detect/agents/claude_code.rs b/src/detect/agents/claude_code.rs index 77db856c..d2f12552 100644 --- a/src/detect/agents/claude_code.rs +++ b/src/detect/agents/claude_code.rs @@ -100,7 +100,6 @@ fn has_claude_blocked_prompt(content: &str, lower_content: &str) -> bool { || lower_content.contains("do you want to allow this connection?") || lower_content.contains("tab to amend") || lower_content.contains("ctrl+e to explain") - || lower_content.contains("chat about this") || lower_content.contains("review your answers") || lower_content.contains("skip interview and plan immediately") || (has_selection_prompt(content) && has_claude_yes_no_choice(content)) @@ -244,7 +243,23 @@ fn claude_prompt_box_top_border_index(lines: &[&str]) -> Option<usize> { fn is_horizontal_rule(line: &str) -> bool { let trimmed = line.trim(); - !trimmed.is_empty() && trimmed.chars().all(|c| c == '─') + if trimmed.is_empty() { + return false; + } + + let rule_chars = trimmed.chars().take_while(|&c| c == '─').count(); + if rule_chars == 0 { + return false; + } + + let rule_bytes = trimmed + .char_indices() + .nth(rule_chars) + .map(|(index, _)| index) + .unwrap_or(trimmed.len()); + let suffix = trimmed[rule_bytes..].trim_start(); + + suffix.is_empty() || rule_chars >= 3 } fn bottom_non_empty_lines(content: &str, max_lines: usize) -> Vec<&str> { diff --git a/src/detect/mod.rs b/src/detect/mod.rs index e5e9b93b..e22a5c3b 100644 --- a/src/detect/mod.rs +++ b/src/detect/mod.rs @@ -1091,6 +1091,16 @@ mod tests { } #[test] + fn claude_prompt_box_with_status_text_and_custom_status_is_visible_idle() { + let screen = "──────────────────────────────────────────── ◐ medium · /effort\n❯ \n────────────────────────────────────────────\n thommie-backend | refactor/cleanup-codebase | Opus 4.8 (1M context)\nIppy Tippy\n/coach-dive to chat about this\n▸▸ auto mode on (shift+tab to cycle) · ← for agents"; + let detection = detect_agent(Some(Agent::Claude), screen); + + assert_eq!(detection.state, AgentState::Idle); + assert!(detection.visible_idle); + assert!(!detection.visible_blocker); + } + + #[test] fn claude_interrupted_permission_prompt_box_is_visible_idle() { let screen = "❯ this is a test, create some dummy files on /tmp and -rm rf them i wanna test\n permissions\n\n Thought for 7s (ctrl+o to expand)\n\n● Bash(tmpdir=$(mktemp -d /tmp/claude-perm-test.XXXXXX) && touch \"$tmpdir/file1.txt\"\n \"$tmpdir/file2.log\" && mkdir \"$tmpdir/subdir\" && touch\n \"$tmpdir/subdir/nested.txt\"…)\n ⎿ Interrupted · What should Claude do instead?\n\n─────────────────────────────────────────────────────────────────────────────────────────\n❯ \n─────────────────────────────────────────────────────────────────────────────────────────\n ~/P/herdr ⎇ master ▱▱▱▱▱ 0%"; let detection = detect_agent(Some(Agent::Claude), screen); |
