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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Desktop notifications for `--live` mode — fires when the watched
//! session grows with a new error tool_result, or when it stops growing
//! for a user-specified duration. Opt-in via `--features notifications`.
//!
//! # Why feature-gated
//!
//! `notify-rust` pulls in platform-native bindings: D-Bus on Linux,
//! AppKit on macOS, WinRT on Windows. Users who don't run `agx --live`
//! don't need any of that. Gating keeps the default binary lean and
//! lets this feature co-exist with the equally optional
//! `embedding-search` and `otel-proto` features without coupling.
//!
//! # Fallback behavior
//!
//! Without the feature:
//! - `error(…)` / `idle(…)` are no-ops; they return `Ok(())` without
//! doing anything. Callers never need a `cfg!` check.
//! - `FEATURE_DISABLED_MESSAGE` exists for the Cli dispatch in
//! main.rs to print a one-time rebuild hint when the user passes
//! `--notify-on-error` / `--notify-on-idle` on a feature-off build.
//!
//! With the feature:
//! - `error(step_label)` fires a notification with title "agx: error
//! in live session" and the step label as the body. Best-effort —
//! OS notification failures return `Err` but the live loop is
//! expected to `.ok()` them so transient D-Bus hiccups don't crash
//! the TUI.
//! - `idle(duration_s)` fires a notification with title "agx: live
//! session idle" when the file has not grown for the configured
//! duration.
//!
//! # Scope
//!
//! This module deliberately doesn't own the *when* to fire — that's
//! `tui.rs`'s business. The module is a thin wrapper over
//! `notify-rust`'s notification API so the tui.rs event loop can
//! stay format-native without dragging platform deps into its tree.
use Result;
/// User-facing message shown the first time a notification flag is
/// used on a feature-off build. Tells users exactly how to rebuild.
/// Public because the bin crate's main.rs prints it from its CLI
/// dispatch layer.
pub const FEATURE_DISABLED_MESSAGE: &str = "--notify-on-* requires rebuilding agx with `cargo install agx --features notifications` or `cargo build --release --features notifications`";
/// Fire an error notification. Best-effort — failures return `Err` but
/// the live loop should `.ok()` them so transient OS-notification
/// hiccups never crash the TUI.
/// Fire an idle notification. Best-effort.