notedeck-spawn.rs (2979B)
1 //! CLI tool to spawn a new agent in a running notedeck instance. 2 //! 3 //! Usage: 4 //! notedeck-spawn # spawn with current directory 5 //! notedeck-spawn /path/to/dir # spawn with specific directory 6 7 #[cfg(unix)] 8 fn main() { 9 use std::io::{BufRead, BufReader, Write}; 10 use std::os::unix::net::UnixStream; 11 use std::path::PathBuf; 12 13 // Parse arguments 14 let cwd = std::env::args() 15 .nth(1) 16 .map(PathBuf::from) 17 .unwrap_or_else(|| std::env::current_dir().expect("Failed to get current directory")); 18 19 // Canonicalize path 20 let cwd = match cwd.canonicalize() { 21 Ok(p) => p, 22 Err(e) => { 23 eprintln!("Error: Invalid path '{}': {}", cwd.display(), e); 24 std::process::exit(1); 25 } 26 }; 27 28 // Validate it's a directory 29 if !cwd.is_dir() { 30 eprintln!("Error: '{}' is not a directory", cwd.display()); 31 std::process::exit(1); 32 } 33 34 let socket_path = notedeck_dave::ipc::socket_path(); 35 36 // Connect to the running notedeck instance 37 let mut stream = match UnixStream::connect(&socket_path) { 38 Ok(s) => s, 39 Err(e) => { 40 eprintln!("Could not connect to notedeck at {}", socket_path.display()); 41 eprintln!("Error: {}", e); 42 eprintln!(); 43 eprintln!("Is notedeck running? Start it first with `notedeck`"); 44 std::process::exit(1); 45 } 46 }; 47 48 // Send spawn request 49 let request = serde_json::json!({ 50 "type": "spawn_agent", 51 "cwd": cwd 52 }); 53 54 if let Err(e) = writeln!(stream, "{}", request) { 55 eprintln!("Failed to send request: {}", e); 56 std::process::exit(1); 57 } 58 59 // Read response 60 let mut reader = BufReader::new(&stream); 61 let mut response = String::new(); 62 if let Err(e) = reader.read_line(&mut response) { 63 eprintln!("Failed to read response: {}", e); 64 std::process::exit(1); 65 } 66 67 // Parse and display response 68 match serde_json::from_str::<serde_json::Value>(&response) { 69 Ok(json) => { 70 if json.get("status").and_then(|s| s.as_str()) == Some("ok") { 71 if let Some(id) = json.get("session_id") { 72 println!("Agent spawned (session {})", id); 73 } else { 74 println!("Agent spawned"); 75 } 76 } else if let Some(msg) = json.get("message").and_then(|m| m.as_str()) { 77 eprintln!("Error: {}", msg); 78 std::process::exit(1); 79 } else { 80 eprintln!("Unknown response: {}", response); 81 std::process::exit(1); 82 } 83 } 84 Err(e) => { 85 eprintln!("Invalid response: {}", e); 86 eprintln!("Raw: {}", response); 87 std::process::exit(1); 88 } 89 } 90 } 91 92 #[cfg(not(unix))] 93 fn main() { 94 eprintln!("notedeck-spawn is only supported on Unix systems (Linux, macOS)"); 95 std::process::exit(1); 96 }