1pub mod agent_init;
2pub mod chat;
3pub mod commands;
4pub mod render;
5pub mod replay;
6pub mod tui;
7
8use crate::cli::commands::{Cli, Commands, ConfigCommand};
9use crate::cli::render::LiveRender;
10use crate::config::{load_settings, write_default_project_config};
11use clap::Parser;
12
13pub async fn run() -> anyhow::Result<()> {
14 let cli = Cli::parse();
15 let cwd = std::env::current_dir()?;
16
17 match cli.command {
18 Commands::Chat {
19 debug,
20 max_turns,
21 agent,
22 } => {
23 let settings = load_settings(&cwd, agent)?;
24 let settings = apply_max_turns(settings, max_turns);
25 if let Some(debug_path) = debug {
26 chat::run_chat_with_debug(settings, &cwd, debug_path).await
28 } else {
29 chat::run_chat(settings, &cwd).await
30 }
31 }
32 Commands::Replay {
33 dir,
34 delay,
35 loop_replay,
36 } => {
37 replay::replay_frames(&dir, delay, loop_replay)?;
38 Ok(())
39 }
40 Commands::Run {
41 prompt,
42 debug,
43 max_turns,
44 agent,
45 } => {
46 let settings = load_settings(&cwd, agent)?;
47 let settings = apply_max_turns(settings, max_turns);
48 if let Some(debug_path) = debug {
49 chat::run_prompt_with_debug(settings, &cwd, debug_path, prompt).await
50 } else {
51 let render = LiveRender::new();
52 render.begin_turn();
53 chat::run_single_prompt_with_events(settings, &cwd, prompt, render).await?;
54 Ok(())
55 }
56 }
57 Commands::Tools => {
58 let settings = load_settings(&cwd, None)?;
59 let registry = crate::tool::registry::ToolRegistry::new(&settings, &cwd);
60 for name in registry.names() {
61 println!("{}", name);
62 }
63 Ok(())
64 }
65 Commands::Config { command } => match command {
66 ConfigCommand::Init => {
67 let path = write_default_project_config(&cwd)?;
68 println!("wrote {}", path.display());
69 Ok(())
70 }
71 ConfigCommand::Show => {
72 let settings = load_settings(&cwd, None)?;
73 let txt = serde_json::to_string_pretty(&settings)?;
74 println!("{}", txt);
75 Ok(())
76 }
77 },
78 Commands::Agents => {
79 let loader = crate::agent::AgentLoader::new()?;
80 let agents = loader.load_agents()?;
81 let registry = crate::agent::AgentRegistry::new(agents);
82
83 println!("Available agents:");
84 for agent in registry.list_agents() {
85 let mode = if agent.mode == crate::agent::AgentMode::Primary {
86 "primary"
87 } else {
88 "subagent"
89 };
90 println!(
91 " {} ({}) - {} - {}",
92 agent.name, agent.display_name, mode, agent.description
93 );
94 }
95 Ok(())
96 }
97 }
98}
99
100fn apply_max_turns(
101 mut settings: crate::config::Settings,
102 max_turns: Option<usize>,
103) -> crate::config::Settings {
104 if let Some(max_turns) = max_turns {
105 settings.agent.max_steps = max_turns;
106 }
107 settings
108}