diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-01 03:50:45 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-01 04:16:36 +0300 |
| commit | 1d56cd0e18fc69a85a0889ca6f9a9f3069a4be3a (patch) | |
| tree | f18bc80137a6dcfbccc7aa3666b94649197dbae5 /src | |
| parent | 2fcf9b678d0f154b2d41aa5fafa25aaa73ec7f17 (diff) | |
feat: detect kilo code cli
refs #270
Diffstat (limited to 'src')
| -rw-r--r-- | src/config/model.rs | 3 | ||||
| -rw-r--r-- | src/config/sound.rs | 3 | ||||
| -rw-r--r-- | src/detect/agents/kilo.rs | 9 | ||||
| -rw-r--r-- | src/detect/agents/mod.rs | 2 | ||||
| -rw-r--r-- | src/detect/mod.rs | 50 | ||||
| -rw-r--r-- | src/main.rs | 2 |
6 files changed, 67 insertions, 2 deletions
diff --git a/src/config/model.rs b/src/config/model.rs index 0776e09b..c312acfa 100644 --- a/src/config/model.rs +++ b/src/config/model.rs @@ -414,7 +414,8 @@ pub struct ExperimentalConfig { /// list means apply to any focused pane. Unknown agent names are ignored; /// if the list contains no valid names, the reveal does not apply. /// Accepted names: pi, claude, codex, gemini, cursor, cline, opencode, - /// copilot, kimi, kiro, droid, amp, grok, hermes. Default: empty. + /// copilot, kimi, kiro, droid, amp, grok, hermes, kilo, qodercli, qoder. + /// Default: empty. pub cjk_ime_agents: Vec<String>, /// Cursor shape rendered for the IME anchor when /// `reveal_hidden_cursor_for_cjk_ime` is enabled. Default: "steady_block". diff --git a/src/config/sound.rs b/src/config/sound.rs index e4f15108..50b2355b 100644 --- a/src/config/sound.rs +++ b/src/config/sound.rs @@ -40,6 +40,7 @@ pub struct AgentSoundOverrides { pub amp: AgentSoundSetting, pub grok: AgentSoundSetting, pub hermes: AgentSoundSetting, + pub kilo: AgentSoundSetting, pub qodercli: AgentSoundSetting, } @@ -131,6 +132,7 @@ impl AgentSoundOverrides { Some(Agent::Amp) => self.amp, Some(Agent::Grok) => self.grok, Some(Agent::Hermes) => self.hermes, + Some(Agent::Kilo) => self.kilo, Some(Agent::Qodercli) => self.qodercli, None => AgentSoundSetting::Default, } @@ -167,6 +169,7 @@ impl Default for AgentSoundOverrides { amp: AgentSoundSetting::Default, grok: AgentSoundSetting::Default, hermes: AgentSoundSetting::Default, + kilo: AgentSoundSetting::Default, qodercli: AgentSoundSetting::Default, } } diff --git a/src/detect/agents/kilo.rs b/src/detect/agents/kilo.rs new file mode 100644 index 00000000..1ab3651a --- /dev/null +++ b/src/detect/agents/kilo.rs @@ -0,0 +1,9 @@ +use super::super::AgentState; + +pub(super) fn detect(content: &str) -> AgentState { + if content.to_lowercase().contains("esc interrupt") { + return AgentState::Working; + } + + super::opencode::detect(content) +} diff --git a/src/detect/agents/mod.rs b/src/detect/agents/mod.rs index 87b4043f..4597c122 100644 --- a/src/detect/agents/mod.rs +++ b/src/detect/agents/mod.rs @@ -9,6 +9,7 @@ pub(super) mod gemini; pub(super) mod github_copilot; pub(super) mod grok; pub(super) mod hermes; +pub(super) mod kilo; pub(super) mod kimi; pub(super) mod kiro; pub(super) mod opencode; @@ -34,6 +35,7 @@ pub(super) fn detect(agent: Agent, screen_content: &str) -> AgentDetection { Agent::Amp => amp::detect(screen_content), Agent::Grok => grok::detect(screen_content), Agent::Hermes => hermes::detect(screen_content), + Agent::Kilo => kilo::detect(screen_content), Agent::Qodercli => qodercli::detect(screen_content), }; diff --git a/src/detect/mod.rs b/src/detect/mod.rs index cf600f51..b9806b19 100644 --- a/src/detect/mod.rs +++ b/src/detect/mod.rs @@ -54,6 +54,7 @@ pub enum Agent { Amp, Grok, Hermes, + Kilo, Qodercli, } @@ -74,6 +75,7 @@ pub fn agent_label(agent: Agent) -> &'static str { Agent::Amp => "amp", Agent::Grok => "grok", Agent::Hermes => "hermes", + Agent::Kilo => "kilo", Agent::Qodercli => "qodercli", } } @@ -96,6 +98,7 @@ pub fn parse_agent_label(agent: &str) -> Option<Agent> { "amp" | "amp-local" => Some(Agent::Amp), "grok" | "grok-build" => Some(Agent::Grok), "hermes" | "hermes-agent" => Some(Agent::Hermes), + "kilo" | "kilo-code" | "kilo code" => Some(Agent::Kilo), "qodercli" | "qoderclicn" | "qoder" | "qodercn" => Some(Agent::Qodercli), _ => None, } @@ -122,6 +125,7 @@ pub fn identify_agent(process_name: &str) -> Option<Agent> { "amp" | "amp-local" => Some(Agent::Amp), "grok" | "grok-build" => Some(Agent::Grok), "hermes" | "hermes-agent" => Some(Agent::Hermes), + "kilo" | "kilo-code" | "kilo code" => Some(Agent::Kilo), "qodercli" | "qoderclicn" | "qoder" | "qodercn" => Some(Agent::Qodercli), _ => None, } @@ -255,6 +259,11 @@ fn detect_qodercli(content: &str) -> AgentState { detect_state(Some(Agent::Qodercli), content) } +#[cfg(test)] +fn detect_kilo(content: &str) -> AgentState { + detect_state(Some(Agent::Kilo), content) +} + // --------------------------------------------------------------------------- // Shared helpers // --------------------------------------------------------------------------- @@ -567,6 +576,11 @@ mod tests { AgentState::Working, ), (Agent::Hermes, "msg=interrupt", AgentState::Working), + ( + Agent::Kilo, + "Ask · DeepSeek V4 Pro\nesc interrupt", + AgentState::Working, + ), (Agent::Qodercli, "\u{280B} Thinking...", AgentState::Working), ]; @@ -604,6 +618,8 @@ mod tests { assert_eq!(identify_agent("grok-build"), Some(Agent::Grok)); assert_eq!(identify_agent("hermes"), Some(Agent::Hermes)); assert_eq!(identify_agent("hermes-agent"), Some(Agent::Hermes)); + assert_eq!(identify_agent("kilo"), Some(Agent::Kilo)); + assert_eq!(identify_agent("kilo-code"), Some(Agent::Kilo)); } #[test] @@ -623,6 +639,7 @@ mod tests { assert_eq!(parse_agent_label("kiro-cli"), Some(Agent::Kiro)); assert_eq!(parse_agent_label("grok-build"), Some(Agent::Grok)); assert_eq!(parse_agent_label("hermes-agent"), Some(Agent::Hermes)); + assert_eq!(parse_agent_label("kilo-code"), Some(Agent::Kilo)); } #[test] @@ -634,6 +651,7 @@ mod tests { assert_eq!(agent_label(Agent::Kiro), "kiro"); assert_eq!(agent_label(Agent::Grok), "grok"); assert_eq!(agent_label(Agent::Hermes), "hermes"); + assert_eq!(agent_label(Agent::Kilo), "kilo"); } #[test] @@ -1581,6 +1599,38 @@ mod tests { assert_eq!(detect_opencode("> "), AgentState::Idle); } + // ---- Kilo ---- + + #[test] + fn kilo_waiting_question_prompt() { + assert_eq!( + detect_kilo( + "Write the following joke to ~/joke.md?\n\ + 1. Yes, write it\n\ + 2. No, thanks\n\ + 3. Type your own answer\n\ + ↑↓ select enter submit esc dismiss", + ), + AgentState::Blocked + ); + } + + #[test] + fn kilo_working() { + assert_eq!( + detect_kilo("Ask · DeepSeek V4 Pro\nesc interrupt\n12.8K (1%) · $0.01"), + AgentState::Working + ); + } + + #[test] + fn kilo_idle() { + assert_eq!( + detect_kilo("Ask anything... \"Fix broken tests\"\nCode · DeepSeek V4 Pro"), + AgentState::Idle + ); + } + // ---- GitHub Copilot ---- #[test] diff --git a/src/main.rs b/src/main.rs index b317c2da..b7b11b16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -265,7 +265,7 @@ pane_history = false # matches one of these names. Empty means apply to any focused pane. # If the list contains no valid names, the reveal does not apply. # Accepted: pi, claude, codex, gemini, cursor, cline, opencode, copilot, -# kimi, kiro, droid, amp, grok, hermes, qodercli, qoder. +# kimi, kiro, droid, amp, grok, hermes, kilo, qodercli, qoder. # cjk_ime_agents = [] # Cursor shape rendered when reveal_hidden_cursor_for_cjk_ime is true. # Values: block, steady_block (default), underline, steady_underline, bar, steady_bar. |
