Skip to main content

vtcode_core/terminal_setup/features/
notifications.rs

1//! Notification system configuration for terminal setup
2//!
3//! Generates terminal-specific configuration for system notifications
4//! when tasks complete, including iTerm2 alerts and bell settings.
5
6use crate::terminal_setup::detector::TerminalType;
7
8/// Generate notification configuration for a terminal
9pub fn generate_notification_config(
10    terminal_type: TerminalType,
11    _features: &[crate::terminal_setup::detector::TerminalFeature],
12) -> Result<String, anyhow::Error> {
13    let mut config_lines = Vec::new();
14
15    // Add notification-specific configuration based on terminal type
16    match terminal_type {
17        TerminalType::ITerm2 => {
18            config_lines.push("# iTerm2 Notification Configuration".to_string());
19            config_lines.push("# To enable system notifications for task completion:".to_string());
20            config_lines.push("# 1. Open iTerm2 Preferences".to_string());
21            config_lines.push("# 2. Navigate to Profiles → Terminal".to_string());
22            config_lines.push(
23                "# 3. Enable 'Silence bell' and Filter Alerts → 'Send escape sequence-generated alerts'".to_string(),
24            );
25            config_lines.push("# 4. Set your preferred notification delay".to_string());
26            config_lines.push("#".to_string());
27            config_lines.push("# For shell integration notifications, add to your shell profile:".to_string());
28            config_lines.push("# export ITERM2_SHELL_INTEGRATION_INSTALLED=1".to_string());
29        }
30        TerminalType::VSCode => {
31            config_lines.push("# VS Code Terminal Notification Configuration".to_string());
32            config_lines.push("# VS Code terminal supports system notifications through:".to_string());
33            config_lines.push("# 1. Settings → Terminal → Integrated → Bell Duration".to_string());
34            config_lines.push("# 2. Enable 'Terminal > Integrated: Enable Bell'".to_string());
35            config_lines.push("#".to_string());
36            config_lines.push("# For shell integration with notifications, consider:".to_string());
37            config_lines.push("# - Using 'oh-my-zsh' or 'bash-it' with notification plugins".to_string());
38        }
39        TerminalType::Hyper => {
40            config_lines.push("# Hyper Terminal Notification Configuration".to_string());
41            config_lines.push("# Hyper supports notifications via plugins:".to_string());
42            config_lines.push("# 1. Install hyper-statusline plugin for enhanced integration".to_string());
43            config_lines.push("# 2. Add to ~/.hyper.js plugins array:".to_string());
44            config_lines.push("#    plugins: [\"hyper-statusline\", \"hyper-search\"]".to_string());
45        }
46        TerminalType::WindowsTerminal => {
47            config_lines.push("# Windows Terminal Notification Configuration".to_string());
48            config_lines.push("# Windows Terminal supports notifications through:".to_string());
49            config_lines.push("# 1. Settings → Profiles → Advanced → Bell style".to_string());
50            config_lines.push("# 2. Enable 'Show terminal bell alert' in appearance settings".to_string());
51        }
52        TerminalType::Ghostty => {
53            config_lines.push("# Ghostty Notification Configuration".to_string());
54            config_lines.push("# Ghostty supports system notifications through:".to_string());
55            config_lines.push("# 1. Settings → Terminal → Bell".to_string());
56            config_lines.push("# 2. Enable 'Visual Bell' or 'Audible Bell' as preferred".to_string());
57            config_lines.push("# 3. Configure 'Bell Duration' for visual notifications".to_string());
58            config_lines.push("#".to_string());
59            config_lines.push("# Ghostty also supports shell integration notifications via:".to_string());
60            config_lines.push("# - Terminal bell escape sequences (\\a)".to_string());
61        }
62        TerminalType::WezTerm => {
63            config_lines.push("# WezTerm Notification Configuration".to_string());
64            config_lines.push("# WezTerm supports terminal bell notifications and can".to_string());
65            config_lines.push("# surface desktop alerts depending on OS integration.".to_string());
66            config_lines.push("#".to_string());
67            config_lines.push("# Recommended: keep bell enabled and test with:".to_string());
68            config_lines.push("# echo -e \"\\a\"".to_string());
69        }
70        TerminalType::TerminalApp => {
71            config_lines.push("# Terminal.app Notification Configuration".to_string());
72            config_lines.push("# macOS Terminal supports audible alerts via terminal bell.".to_string());
73            config_lines.push("#".to_string());
74            config_lines.push("# 1. Open Terminal → Settings → Profiles → Advanced".to_string());
75            config_lines.push("# 2. Configure bell/alerts according to preference".to_string());
76            config_lines.push("# 3. Test with: echo -e \"\\a\"".to_string());
77        }
78        TerminalType::Xterm => {
79            config_lines.push("# xterm Notification Configuration".to_string());
80            config_lines.push("# xterm provides reliable bell notifications (audible/visual).".to_string());
81            config_lines.push("#".to_string());
82            config_lines.push("# Ensure bell is enabled in your X resources.".to_string());
83            config_lines.push("# Test with: echo -e \"\\a\"".to_string());
84        }
85        _ => {
86            config_lines.push(format!("# {terminal_type:?} Notification Configuration"));
87            config_lines.push("# This terminal supports standard ANSI bell notifications.".to_string());
88            config_lines.push("# Check your terminal's documentation for specific notification settings.".to_string());
89        }
90    }
91
92    Ok(config_lines.join("\n"))
93}
94
95/// Get notification setup instructions for a terminal
96pub fn get_notification_instructions(terminal_type: TerminalType) -> Vec<String> {
97    match terminal_type {
98        TerminalType::ITerm2 => vec![
99            "1. OPEN: iTerm2 → Preferences → Profiles → Terminal".to_string(),
100            "2. ENABLE: 'Silence bell' and 'Send escape sequence-generated alerts'".to_string(),
101            "3. CONFIGURE: Set preferred notification delay".to_string(),
102            "4. TEST: Run a long command followed by 'echo -e \"\\a\"'".to_string(),
103        ],
104        TerminalType::VSCode => vec![
105            "1. OPEN: VS Code Settings (Cmd/Ctrl + ,)".to_string(),
106            "2. SEARCH: 'terminal integrated bell'".to_string(),
107            "3. ENABLE: 'Terminal > Integrated: Enable Bell'".to_string(),
108            "4. CONFIGURE: Set 'Terminal > Integrated: Bell Duration'".to_string(),
109        ],
110        TerminalType::WindowsTerminal => vec![
111            "1. OPEN: Windows Terminal Settings (Ctrl + ,)".to_string(),
112            "2. SELECT: Your profile".to_string(),
113            "3. GO TO: Appearance section".to_string(),
114            "4. ENABLE: 'Show terminal bell alert'".to_string(),
115        ],
116        TerminalType::Ghostty => vec![
117            "1. OPEN: Ghostty Settings".to_string(),
118            "2. GO TO: Terminal → Bell section".to_string(),
119            "3. ENABLE: 'Visual Bell' or 'Audible Bell' as preferred".to_string(),
120            "4. CONFIGURE: Set 'Bell Duration' for visual notifications".to_string(),
121        ],
122        TerminalType::WezTerm => vec![
123            "1. OPEN: WezTerm settings (~/.wezterm.lua)".to_string(),
124            "2. ENABLE: Bell/alert behavior as preferred".to_string(),
125            "3. TEST: Run 'echo -e \"\\a\"'".to_string(),
126        ],
127        TerminalType::TerminalApp => vec![
128            "1. OPEN: Terminal → Settings → Profiles → Advanced".to_string(),
129            "2. CONFIGURE: Alert/Bell behavior".to_string(),
130            "3. TEST: Run 'echo -e \"\\a\"'".to_string(),
131        ],
132        TerminalType::Xterm => vec![
133            "1. CHECK: xterm bell settings in X resources".to_string(),
134            "2. ENABLE: Audible or visual bell".to_string(),
135            "3. TEST: Run 'echo -e \"\\a\"'".to_string(),
136        ],
137        _ => vec![
138            format!("1. CHECK: Documentation for {:?}", terminal_type),
139            "2. CONFIGURE: Terminal bell/notifications in preferences".to_string(),
140            "3. TEST: Use 'echo -e \"\\a\"' to test bell notification".to_string(),
141        ],
142    }
143}
144
145#[cfg(test)]
146mod tests {
147    use super::*;
148
149    #[test]
150    fn test_notification_config_generation() {
151        let features = vec![
152            crate::terminal_setup::detector::TerminalFeature::Multiline,
153            crate::terminal_setup::detector::TerminalFeature::CopyPaste,
154        ];
155
156        let config = generate_notification_config(TerminalType::ITerm2, &features).unwrap();
157        assert!(config.contains("iTerm2"));
158        assert!(config.contains("Notification"));
159    }
160
161    #[test]
162    fn test_notification_instructions() {
163        let instructions = get_notification_instructions(TerminalType::ITerm2);
164        assert!(instructions.iter().any(|i| i.contains("iTerm2")));
165        assert!(instructions.iter().any(|i| i.contains("Preferences")));
166    }
167}