1use crate::cli_logic;
2use clap::{Parser, Subcommand};
3use std::path::PathBuf;
4
5#[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 None => cli_logic::handle_interactive_mode().await,
99 }
100 }
101}
102
103#[derive(Subcommand)]
105pub enum Commands {
106 Run {
108 tool: String,
110 #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
112 args: Vec<String>,
113 },
114
115 Install {
117 tool: String,
119 },
120
121 Update {
123 package: Option<String>,
125 },
126
127 List,
129
130 Info {
132 tool: String,
134 },
135
136 Auth {
138 #[command(subcommand)]
139 action: AuthCommands,
140 },
141
142 Templates {
144 #[command(subcommand)]
145 action: TemplateCommands,
146 },
147
148 Config {
150 #[command(subcommand)]
151 action: ConfigCommands,
152 },
153
154 Cache {
156 #[command(subcommand)]
157 action: CacheCommands,
158 },
159
160 Benchmark {
162 #[command(subcommand)]
163 action: BenchmarkCommands,
164 },
165}
166
167#[derive(Subcommand)]
168pub enum ConfigCommands {
169 Reset,
171
172 Show,
174
175 Path,
177}
178
179#[derive(Subcommand)]
180pub enum CacheCommands {
181 Clear,
183
184 Status,
186
187 Refresh {
189 #[arg(long, default_value = "3600")]
191 ttl: u64,
192 },
193}
194
195#[derive(Subcommand)]
196pub enum TemplateCommands {
197 Init,
199
200 Create {
202 name: String,
204 },
205
206 List,
208
209 Apply {
211 name: String,
213 },
214}
215
216#[derive(Subcommand)]
217#[command(disable_help_subcommand = true)]
218pub enum AuthCommands {
219 Manage,
221
222 Help {
224 tool: String,
226 },
227
228 Set {
230 #[arg(long)]
232 tool: Option<String>,
233 },
234}
235
236#[derive(Subcommand)]
237pub enum BenchmarkCommands {
238 List,
240
241 Run {
243 #[arg(long)]
245 scenario: String,
246
247 #[arg(long)]
249 tool: String,
250
251 #[arg(long)]
253 export_json: Option<PathBuf>,
254 },
255
256 Validate {
258 #[arg(long)]
260 scenario_file: PathBuf,
261 },
262}