terminal_jarvis/
cli.rs

1use crate::cli_logic;
2use clap::{Parser, Subcommand};
3use std::path::PathBuf;
4
5/// Terminal Jarvis - A unified interface for AI coding tools
6#[derive(Parser)]
7#[command(name = "terminal-jarvis")]
8#[command(about = "A thin Rust wrapper for managing and running AI coding tools")]
9#[command(version = env!("CARGO_PKG_VERSION"))]
10#[command(
11    long_about = "Terminal Jarvis provides a unified interface for managing multiple AI coding tools like claude-code, gemini-cli, qwen-code, opencode, aider, amp, and goose."
12)]
13pub struct Cli {
14    #[command(subcommand)]
15    pub command: Option<Commands>,
16}
17
18impl Default for Cli {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl Cli {
25    pub fn new() -> Self {
26        Self::parse()
27    }
28
29    pub async fn run(self) -> anyhow::Result<()> {
30        match self.command {
31            Some(Commands::Run { tool, args }) => cli_logic::handle_run_tool(&tool, &args).await,
32
33            Some(Commands::Install { tool }) => cli_logic::handle_install_tool(&tool).await,
34
35            Some(Commands::Update { package }) => {
36                cli_logic::handle_update_packages(package.as_deref()).await
37            }
38
39            Some(Commands::List) => cli_logic::handle_list_tools().await,
40
41            Some(Commands::Info { tool }) => cli_logic::handle_tool_info(&tool).await,
42
43            Some(Commands::Auth { action }) => match action {
44                AuthCommands::Manage => cli_logic::handle_authentication_menu().await,
45                AuthCommands::Help { tool } => cli_logic::handle_auth_help(&tool).await,
46                AuthCommands::Set { tool } => {
47                    if let Some(t) = tool {
48                        cli_logic::handle_auth_set(&t).await
49                    } else {
50                        cli_logic::handle_authentication_menu().await
51                    }
52                }
53            },
54
55            Some(Commands::Templates { action }) => match action {
56                TemplateCommands::Init => cli_logic::handle_templates_init().await,
57
58                TemplateCommands::Create { name } => {
59                    cli_logic::handle_templates_create(&name).await
60                }
61
62                TemplateCommands::List => cli_logic::handle_templates_list().await,
63
64                TemplateCommands::Apply { name } => cli_logic::handle_templates_apply(&name).await,
65            },
66
67            Some(Commands::Config { action }) => match action {
68                ConfigCommands::Reset => cli_logic::handle_config_reset().await,
69
70                ConfigCommands::Show => cli_logic::handle_config_show().await,
71
72                ConfigCommands::Path => cli_logic::handle_config_path().await,
73            },
74
75            Some(Commands::Cache { action }) => match action {
76                CacheCommands::Clear => cli_logic::handle_cache_clear().await,
77
78                CacheCommands::Status => cli_logic::handle_cache_status().await,
79
80                CacheCommands::Refresh { ttl } => cli_logic::handle_cache_refresh(ttl).await,
81            },
82
83            Some(Commands::Benchmark { action }) => match action {
84                BenchmarkCommands::List => cli_logic::handle_benchmark_list().await,
85
86                BenchmarkCommands::Run {
87                    scenario,
88                    tool,
89                    export_json,
90                } => cli_logic::handle_benchmark_run(&scenario, &tool, export_json.as_ref()).await,
91
92                BenchmarkCommands::Validate { scenario_file } => {
93                    cli_logic::handle_benchmark_validate(&scenario_file).await
94                }
95            },
96
97            // (Duplicate Auth handler removed; handled above)
98            None => cli_logic::handle_interactive_mode().await,
99        }
100    }
101}
102
103/// Terminal Jarvis - A unified interface for AI coding tools
104#[derive(Subcommand)]
105pub enum Commands {
106    /// Run a specific AI coding tool
107    Run {
108        /// The tool to run (claude, gemini, qwen, opencode, llxprt, codex, aider, amp, goose, crush)
109        tool: String,
110        /// Arguments to pass to the tool
111        #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
112        args: Vec<String>,
113    },
114
115    /// Install a specific AI coding tool
116    Install {
117        /// The tool to install
118        tool: String,
119    },
120
121    /// Update packages
122    Update {
123        /// Specific package to update (optional - updates all if not specified)
124        package: Option<String>,
125    },
126
127    /// List available tools
128    List,
129
130    /// Show information about a specific tool
131    Info {
132        /// The tool to show information about
133        tool: String,
134    },
135
136    /// Authentication management commands
137    Auth {
138        #[command(subcommand)]
139        action: AuthCommands,
140    },
141
142    /// Template management commands
143    Templates {
144        #[command(subcommand)]
145        action: TemplateCommands,
146    },
147
148    /// Configuration management commands
149    Config {
150        #[command(subcommand)]
151        action: ConfigCommands,
152    },
153
154    /// Version cache management commands
155    Cache {
156        #[command(subcommand)]
157        action: CacheCommands,
158    },
159
160    /// Benchmark management commands
161    Benchmark {
162        #[command(subcommand)]
163        action: BenchmarkCommands,
164    },
165}
166
167#[derive(Subcommand)]
168pub enum ConfigCommands {
169    /// Reset configuration to defaults
170    Reset,
171
172    /// Show current configuration
173    Show,
174
175    /// Show configuration file path
176    Path,
177}
178
179#[derive(Subcommand)]
180pub enum CacheCommands {
181    /// Clear the version cache
182    Clear,
183
184    /// Show cache status
185    Status,
186
187    /// Refresh cache with latest version
188    Refresh {
189        /// Cache TTL in seconds (default: 3600)
190        #[arg(long, default_value = "3600")]
191        ttl: u64,
192    },
193}
194
195#[derive(Subcommand)]
196pub enum TemplateCommands {
197    /// Initialize template repository (requires gh CLI)
198    Init,
199
200    /// Create a new template
201    Create {
202        /// Name of the template
203        name: String,
204    },
205
206    /// List available templates
207    List,
208
209    /// Apply a template
210    Apply {
211        /// Name of the template to apply
212        name: String,
213    },
214}
215
216#[derive(Subcommand)]
217#[command(disable_help_subcommand = true)]
218pub enum AuthCommands {
219    /// Open interactive authentication menu
220    Manage,
221
222    /// Show auth help for a tool
223    Help {
224        /// Tool name (e.g., claude, gemini, goose)
225        tool: String,
226    },
227
228    /// Set and save credentials for a tool (guided)
229    Set {
230        /// Optional tool name; if omitted, opens interactive menu
231        #[arg(long)]
232        tool: Option<String>,
233    },
234}
235
236#[derive(Subcommand)]
237pub enum BenchmarkCommands {
238    /// List all available benchmark scenarios
239    List,
240
241    /// Run a benchmark scenario against a tool
242    Run {
243        /// Benchmark scenario ID to run
244        #[arg(long)]
245        scenario: String,
246
247        /// Tool name to test
248        #[arg(long)]
249        tool: String,
250
251        /// Optional path to export results as JSON
252        #[arg(long)]
253        export_json: Option<PathBuf>,
254    },
255
256    /// Validate a benchmark scenario file
257    Validate {
258        /// Path to the scenario TOML file
259        #[arg(long)]
260        scenario_file: PathBuf,
261    },
262}