diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-17 20:06:52 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-17 20:07:18 +0300 |
| commit | f161be04613211d8fee7ef18e6e506df09da3ba1 (patch) | |
| tree | ec65649c42f95104ec04c33d19c056f169a41189 /src/terminal/state.rs | |
| parent | 45a4318bbbcb2c91d95faee6f31e5846ae3f9ec0 (diff) | |
fix: detect Grok Build agent state
refs #133
Diffstat (limited to 'src/terminal/state.rs')
| -rw-r--r-- | src/terminal/state.rs | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/src/terminal/state.rs b/src/terminal/state.rs index f9d5b522..8c27f1a5 100644 --- a/src/terminal/state.rs +++ b/src/terminal/state.rs @@ -78,11 +78,13 @@ impl TerminalState { let previous_detected_agent = self.detected_agent; self.detected_agent = agent; self.fallback_state = fallback_state; - if previous_detected_agent.is_some() - && agent != previous_detected_agent - && self.hook_authority.as_ref().is_some_and(|authority| { - crate::detect::parse_agent_label(&authority.agent_label) == previous_detected_agent - }) + if self.hook_authority_conflicts_with_detected_agent(agent) + || (previous_detected_agent.is_some() + && agent != previous_detected_agent + && self.hook_authority.as_ref().is_some_and(|authority| { + crate::detect::parse_agent_label(&authority.agent_label) + == previous_detected_agent + })) { self.hook_authority = None; } @@ -117,6 +119,9 @@ impl TerminalState { let previous_agent_label = self.effective_agent_label().map(str::to_string); let previous_known_agent = self.effective_known_agent(); let previous_state = self.state; + if self.known_agent_label_conflicts_with_detected_agent(&agent_label) { + return None; + } self.hook_authority = Some(HookAuthority { source, agent_label, @@ -127,6 +132,24 @@ impl TerminalState { self.recompute_effective_state(previous_agent_label, previous_known_agent, previous_state) } + fn hook_authority_conflicts_with_detected_agent(&self, detected_agent: Option<Agent>) -> bool { + let Some(detected_agent) = detected_agent else { + return false; + }; + self.hook_authority.as_ref().is_some_and(|authority| { + crate::detect::parse_agent_label(&authority.agent_label) + .is_some_and(|hook_agent| hook_agent != detected_agent) + }) + } + + fn known_agent_label_conflicts_with_detected_agent(&self, agent_label: &str) -> bool { + let Some(detected_agent) = self.detected_agent else { + return false; + }; + crate::detect::parse_agent_label(agent_label) + .is_some_and(|hook_agent| hook_agent != detected_agent) + } + fn accept_hook_report(&mut self, source: &str, seq: Option<u64>) -> bool { let Some(seq) = seq else { return !self.hook_report_sequences.contains_key(source); @@ -418,6 +441,44 @@ mod tests { } #[test] + fn known_hook_authority_does_not_override_different_detected_agent() { + let mut terminal = test_terminal(); + terminal.set_detected_state(Some(Agent::Grok), AgentState::Working); + let change = terminal.set_hook_authority( + "herdr:claude".into(), + "claude".into(), + AgentState::Blocked, + None, + None, + ); + + assert!(change.is_none()); + assert!(terminal.hook_authority.is_none()); + assert_eq!(terminal.detected_agent, Some(Agent::Grok)); + assert_eq!(terminal.effective_agent_label(), Some("grok")); + assert_eq!(terminal.state, AgentState::Working); + } + + #[test] + fn detected_agent_clears_conflicting_known_hook_authority() { + let mut terminal = test_terminal(); + terminal.set_hook_authority( + "herdr:claude".into(), + "claude".into(), + AgentState::Blocked, + None, + None, + ); + + terminal.set_detected_state(Some(Agent::Grok), AgentState::Working); + + assert!(terminal.hook_authority.is_none()); + assert_eq!(terminal.detected_agent, Some(Agent::Grok)); + assert_eq!(terminal.effective_agent_label(), Some("grok")); + assert_eq!(terminal.state, AgentState::Working); + } + + #[test] fn border_label_prefers_manual_label_over_agent_label() { let mut terminal = test_terminal(); terminal.set_detected_state(Some(Agent::Claude), AgentState::Idle); |
