diff options
Diffstat (limited to 'crates/dinggerd/src/watcher.rs')
| -rw-r--r-- | crates/dinggerd/src/watcher.rs | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/crates/dinggerd/src/watcher.rs b/crates/dinggerd/src/watcher.rs index 77b9259..aee8d5e 100644 --- a/crates/dinggerd/src/watcher.rs +++ b/crates/dinggerd/src/watcher.rs @@ -35,7 +35,7 @@ use std::collections::HashMap; use detect_core::{detect_agent_with_osc, Agent, AgentState}; use tracing::{debug, info, warn}; -use crate::hooks; +use crate::hooks::{self, Observation}; use crate::importance::Importance; use crate::notify::{play_sound, send_notification, NotificationKind}; use crate::tmux; @@ -376,7 +376,12 @@ impl Watcher { // finished between two ticks is still a completion. let mut alerts = Vec::new(); for observed in observations { - let next = advance(track, observed, pane.attended, acked, now); + let mut next = advance(track, observed.state, pane.attended, acked, now); + // A cancelled run did not finish: idle, as if seen. + if observed.cancelled && next.state == AgentState::Idle { + next.seen = true; + next.held = false; + } if next.state != track.state { info!( target = %pane.display_target, @@ -386,7 +391,7 @@ impl Watcher { ); // Notify on transitions observed by this process, not // when resuming from options written before a restart. - if !restored { + if !restored && !observed.cancelled { alerts.extend(notification_kind_for_transition(track.state, next.state)); } } @@ -615,14 +620,14 @@ impl Watcher { /// The pane's raw agent states this tick, in order, or `None` when the /// screen is a viewer (transcript, picker) that says nothing about state. -fn observe(pane: &tmux::Pane, listed: std::time::Instant) -> Option<Vec<AgentState>> { +fn observe(pane: &tmux::Pane, listed: std::time::Instant) -> Option<Vec<Observation>> { if pane.dead { - return Some(vec![AgentState::Idle]); + return Some(vec![Observation::plain(AgentState::Idle)]); } let Some(agent) = pane.agent else { // The agent is gone; its last hook report must not outlive it. hooks::drop_reports(&pane.pane_id, listed); - return Some(vec![AgentState::Unknown]); + return Some(vec![Observation::plain(AgentState::Unknown)]); }; // Agent-reported state is authoritative; it survives restarts through // the `@dingger_hook` option until the extension reports again. @@ -630,7 +635,7 @@ fn observe(pane: &tmux::Pane, listed: std::time::Instant) -> Option<Vec<AgentSta return Some(states); } if let Some(state) = parse_state(&pane.written_hook) { - return Some(vec![state]); + return Some(vec![Observation::plain(state)]); } let screen = match tmux::capture_pane(&pane.pane_id) { Ok(screen) => screen, @@ -642,7 +647,7 @@ fn observe(pane: &tmux::Pane, listed: std::time::Instant) -> Option<Vec<AgentSta // tmux pane_title carries the last OSC title the application set; tmux // does not re-expose OSC progress sequences. let detection = detect_agent_with_osc(Some(agent), &screen, &pane.pane_title, ""); - (!detection.skip_state_update).then(|| vec![detection.state]) + (!detection.skip_state_update).then(|| vec![Observation::plain(detection.state)]) } /// The host name tmux uses as a pane's default title. |
