1use anyhow::Result;
7use colored::Colorize;
8use std::path::PathBuf;
9
10use crate::commands::spawn::terminal::{self, Harness};
11
12pub fn run(
14 project_root: Option<PathBuf>,
15 prompt: &str,
16 harness_arg: &str,
17 model: &str,
18 session: Option<String>,
19 attach: bool,
20 name: Option<String>,
21) -> Result<()> {
22 terminal::check_tmux_available()?;
24
25 let harness = Harness::parse(harness_arg)?;
27
28 let run_id = name.unwrap_or_else(|| {
30 let timestamp = chrono::Local::now().format("%H%M%S").to_string();
31 format!("run-{}", timestamp)
32 });
33
34 let session_name = session.unwrap_or_else(|| "scud-run".to_string());
36
37 let working_dir = project_root
39 .clone()
40 .unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
41
42 println!("{}", "SCUD Run".cyan().bold());
44 println!("{}", "═".repeat(50));
45 println!("{:<15} {}", "Harness:".dimmed(), harness.name().green());
46 println!("{:<15} {}", "Model:".dimmed(), model.green());
47 println!("{:<15} {}", "Session:".dimmed(), session_name.cyan());
48 println!("{:<15} {}", "Window:".dimmed(), run_id.cyan());
49 println!();
50 println!("{}", "Prompt:".dimmed());
51 let display_prompt = if prompt.len() > 200 {
53 format!("{}...", &prompt[..200])
54 } else {
55 prompt.to_string()
56 };
57 println!(" {}", display_prompt.italic());
58 println!();
59
60 match terminal::spawn_terminal_with_harness_and_model(
62 &run_id,
63 prompt,
64 &working_dir,
65 &session_name,
66 harness,
67 Some(model),
68 ) {
69 Ok(window_index) => {
70 println!(
71 "{} Agent spawned: {}:{}",
72 "✓".green(),
73 session_name.cyan(),
74 window_index.cyan()
75 );
76 println!();
77 println!(
78 "To attach: {}",
79 format!("tmux attach -t {}:{}", session_name, window_index).cyan()
80 );
81
82 if attach {
84 println!();
85 println!("Attaching to session...");
86 terminal::tmux_attach(&session_name)?;
87 }
88 }
89 Err(e) => {
90 println!("{} Failed to spawn agent: {}", "✗".red(), e);
91 return Err(e);
92 }
93 }
94
95 Ok(())
96}