Skip to main content

claude_launcher/
lib.rs

1pub fn generate_applescript(
2    _task: &str,
3    current_dir: &str,
4    prompt_file: &str,
5    _is_first: bool,
6) -> String {
7    // Create a wrapper script that reads the prompt file and passes it to claude
8    // This avoids both the raw mode error and AppleScript escaping issues
9    let wrapper_script = format!("{}.wrapper.sh", prompt_file);
10    
11    // Create the wrapper script content
12    let wrapper_content = format!(
13        r#"#!/bin/bash
14cd "{}"
15PROMPT=$(cat "{}")
16claude --dangerously-skip-permissions "$PROMPT"
17rm "{}"
18rm "{}"
19"#,
20        current_dir, prompt_file, prompt_file, wrapper_script
21    );
22    
23    // Write the wrapper script (create parent directory if needed)
24    if let Some(parent) = std::path::Path::new(&wrapper_script).parent() {
25        let _ = std::fs::create_dir_all(parent);
26    }
27    std::fs::write(&wrapper_script, wrapper_content)
28        .expect("Failed to write wrapper script");
29    
30    // Make it executable
31    std::process::Command::new("chmod")
32        .arg("+x")
33        .arg(&wrapper_script)
34        .output()
35        .expect("Failed to make wrapper script executable");
36    
37    // Use the wrapper script in AppleScript
38    let shell_command = format!("{}", wrapper_script);
39
40    // Both first and additional tabs use the same AppleScript
41    format!(
42        r#"tell application "iTerm"
43    tell current window
44        create tab with default profile
45        tell current session
46            write text "{}"
47        end tell
48    end tell
49end tell"#,
50        shell_command
51    )
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57    use tempfile::TempDir;
58
59    #[test]
60    fn test_generate_applescript_first_tab() {
61        let temp_dir = TempDir::new().unwrap();
62        let dir_path = temp_dir.path().to_str().unwrap();
63        let prompt_file = format!("{}/agent_prompt_task_1.txt", dir_path);
64        
65        let script = generate_applescript(
66            "test task",
67            dir_path,
68            &prompt_file,
69            true,
70        );
71
72        assert!(script.contains("tell application \"iTerm\""));
73        assert!(script.contains("create tab with default profile"));
74        assert!(script.contains(&format!("{}.wrapper.sh", prompt_file)));
75    }
76
77    #[test]
78    fn test_generate_applescript_additional_tab() {
79        let temp_dir = TempDir::new().unwrap();
80        let dir_path = temp_dir.path().to_str().unwrap();
81        let prompt_file = format!("{}/agent_prompt_task_2.txt", dir_path);
82        
83        let script = generate_applescript(
84            "another task",
85            dir_path,
86            &prompt_file,
87            false,
88        );
89
90        assert!(script.contains("tell application \"iTerm\""));
91        assert!(script.contains("create tab with default profile"));
92        assert!(script.contains(&format!("{}.wrapper.sh", prompt_file)));
93    }
94
95    #[test]
96    fn test_command_structure() {
97        let temp_dir = TempDir::new().unwrap();
98        let dir_path = temp_dir.path().to_str().unwrap();
99        let prompt_file = format!("{}/agent_prompt_task_1.txt", dir_path);
100        
101        let script = generate_applescript(
102            "test",
103            dir_path,
104            &prompt_file,
105            true,
106        );
107
108        assert!(script.contains(&format!("{}.wrapper.sh", prompt_file)));
109    }
110}