Skip to main content

scud/commands/
run.rs

1//! Run command - Launch a single AI agent with an arbitrary prompt
2//!
3//! This provides a quick way to spin up an agent without needing a task in the graph.
4//! Useful for ad-hoc tasks, testing harnesses, or one-off operations.
5
6use anyhow::Result;
7use colored::Colorize;
8use std::path::PathBuf;
9
10use crate::commands::spawn::terminal::{self, Harness};
11
12/// Main entry point for the run command
13pub 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    // Check tmux is available
23    terminal::check_tmux_available()?;
24
25    // Parse harness
26    let harness = Harness::parse(harness_arg)?;
27
28    // Generate unique ID for this run
29    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    // Generate session name
35    let session_name = session.unwrap_or_else(|| "scud-run".to_string());
36
37    // Get working directory
38    let working_dir = project_root
39        .clone()
40        .unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
41
42    // Display what we're doing
43    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    // Truncate long prompts for display
52    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    // Spawn the agent
61    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            // Attach if requested
83            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}