aboutsummaryrefslogtreecommitdiff
path: root/src/detect/agents/opencode.rs
blob: 219f69ed1a2a516b219acd9548561d73518a0862 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use super::super::{has_interrupt_pattern, AgentState};

pub(super) fn detect(content: &str) -> AgentState {
    // Blocked
    if content.contains("△ Permission required") || has_opencode_question_prompt(content) {
        return AgentState::Blocked;
    }

    // Working
    if has_interrupt_pattern(&content.to_lowercase())
        || has_opencode_interrupt_footer(content)
        || has_opencode_progress_run(content)
    {
        return AgentState::Working;
    }

    AgentState::Idle
}

fn has_opencode_question_prompt(content: &str) -> bool {
    let lower = content.to_lowercase();
    let has_enter_action = lower.contains("enter confirm")
        || lower.contains("enter submit")
        || lower.contains("enter toggle");
    let has_question_nav = content.contains("↑↓ select") || content.contains("⇆ tab");

    lower.contains("esc dismiss") && has_enter_action && has_question_nav
}

fn has_opencode_interrupt_footer(content: &str) -> bool {
    content.lines().any(|line| {
        let lower = line.to_lowercase();
        if !(lower.contains("esc interrupt") || lower.contains("esc again to interrupt")) {
            return false;
        }

        lower.contains("opencode")
    })
}

fn has_opencode_progress_run(line: &str) -> bool {
    let mut run = 0usize;
    for ch in line.chars() {
        if matches!(ch, '■' | '⬝') {
            run += 1;
            if run >= 4 {
                return true;
            }
        } else {
            run = 0;
        }
    }
    false
}