syncable_cli/cli.rs
1use clap::{Parser, Subcommand, ValueEnum};
2use std::path::PathBuf;
3
4#[derive(Parser)]
5#[command(name = "sync-ctl")]
6#[command(version = env!("CARGO_PKG_VERSION"))]
7#[command(about = "Generate Infrastructure as Code from your codebase")]
8#[command(
9 long_about = "A powerful CLI tool that analyzes your codebase and automatically generates optimized Infrastructure as Code configurations including Dockerfiles, Docker Compose files, and Terraform configurations"
10)]
11pub struct Cli {
12 #[command(subcommand)]
13 pub command: Commands,
14
15 /// Path to configuration file
16 #[arg(short, long, global = true, value_name = "FILE")]
17 pub config: Option<PathBuf>,
18
19 /// Enable verbose logging (-v for info, -vv for debug, -vvv for trace)
20 #[arg(short, long, global = true, action = clap::ArgAction::Count)]
21 pub verbose: u8,
22
23 /// Suppress all output except errors
24 #[arg(short, long, global = true)]
25 pub quiet: bool,
26
27 /// Output in JSON format where applicable
28 #[arg(long, global = true)]
29 pub json: bool,
30
31 /// Clear the update check cache and force a new check
32 #[arg(long, global = true)]
33 pub clear_update_cache: bool,
34
35 /// Disable telemetry data collection
36 #[arg(long, global = true)]
37 pub disable_telemetry: bool,
38}
39
40#[derive(Subcommand)]
41pub enum Commands {
42 /// Analyze a project and display detected components
43 Analyze {
44 /// Path to the project directory to analyze
45 #[arg(value_name = "PROJECT_PATH")]
46 path: PathBuf,
47
48 /// Output analysis results in JSON format
49 #[arg(short, long)]
50 json: bool,
51
52 /// Show detailed analysis information (legacy format)
53 #[arg(short, long, conflicts_with = "display")]
54 detailed: bool,
55
56 /// Display format for analysis results
57 #[arg(long, value_enum, default_value = "matrix")]
58 display: Option<DisplayFormat>,
59
60 /// Only analyze specific aspects (languages, frameworks, dependencies)
61 #[arg(long, value_delimiter = ',')]
62 only: Option<Vec<String>>,
63
64 /// Color scheme for terminal output (auto-detect, dark, light)
65 #[arg(long, value_enum, default_value = "auto")]
66 color_scheme: Option<ColorScheme>,
67 },
68
69 /// Generate IaC files for a project
70 Generate {
71 /// Path to the project directory to analyze
72 #[arg(value_name = "PROJECT_PATH")]
73 path: PathBuf,
74
75 /// Output directory for generated files
76 #[arg(short, long, value_name = "OUTPUT_DIR")]
77 output: Option<PathBuf>,
78
79 /// Generate Dockerfile
80 #[arg(long)]
81 dockerfile: bool,
82
83 /// Generate Docker Compose file
84 #[arg(long)]
85 compose: bool,
86
87 /// Generate Terraform configuration
88 #[arg(long)]
89 terraform: bool,
90
91 /// Generate all supported IaC files
92 #[arg(long, conflicts_with_all = ["dockerfile", "compose", "terraform"])]
93 all: bool,
94
95 /// Perform a dry run without creating files
96 #[arg(long)]
97 dry_run: bool,
98
99 /// Overwrite existing files
100 #[arg(long)]
101 force: bool,
102 },
103
104 /// Validate existing IaC files against best practices
105 Validate {
106 /// Path to the directory containing IaC files
107 #[arg(value_name = "PATH")]
108 path: PathBuf,
109
110 /// Types of files to validate
111 #[arg(long, value_delimiter = ',')]
112 types: Option<Vec<String>>,
113
114 /// Fix issues automatically where possible
115 #[arg(long)]
116 fix: bool,
117 },
118
119 /// Show supported languages and frameworks
120 Support {
121 /// Show only languages
122 #[arg(long)]
123 languages: bool,
124
125 /// Show only frameworks
126 #[arg(long)]
127 frameworks: bool,
128
129 /// Show detailed information
130 #[arg(short, long)]
131 detailed: bool,
132 },
133
134 /// Analyze project dependencies in detail
135 Dependencies {
136 /// Path to the project directory to analyze
137 #[arg(value_name = "PROJECT_PATH")]
138 path: PathBuf,
139
140 /// Show license information for dependencies
141 #[arg(long)]
142 licenses: bool,
143
144 /// Check for known vulnerabilities
145 #[arg(long)]
146 vulnerabilities: bool,
147
148 /// Show only production dependencies
149 #[arg(long, conflicts_with = "dev_only")]
150 prod_only: bool,
151
152 /// Show only development dependencies
153 #[arg(long, conflicts_with = "prod_only")]
154 dev_only: bool,
155
156 /// Output format
157 #[arg(long, value_enum, default_value = "table")]
158 format: OutputFormat,
159 },
160
161 /// Check dependencies for known vulnerabilities
162 Vulnerabilities {
163 /// Check vulnerabilities in a specific path
164 #[arg(default_value = ".")]
165 path: PathBuf,
166
167 /// Show only vulnerabilities with severity >= threshold
168 #[arg(long, value_enum)]
169 severity: Option<SeverityThreshold>,
170
171 /// Output format
172 #[arg(long, value_enum, default_value = "table")]
173 format: OutputFormat,
174
175 /// Export report to file
176 #[arg(long)]
177 output: Option<PathBuf>,
178 },
179
180 /// Perform comprehensive security analysis
181 Security {
182 /// Path to the project directory to analyze
183 #[arg(value_name = "PROJECT_PATH", default_value = ".")]
184 path: PathBuf,
185
186 /// Security scan mode (lightning, fast, balanced, thorough, paranoid)
187 #[arg(long, value_enum, default_value = "thorough")]
188 mode: SecurityScanMode,
189
190 /// Include low severity findings
191 #[arg(long)]
192 include_low: bool,
193
194 /// Skip secrets detection
195 #[arg(long)]
196 no_secrets: bool,
197
198 /// Skip code pattern analysis
199 #[arg(long)]
200 no_code_patterns: bool,
201
202 /// Skip infrastructure analysis (not implemented yet)
203 #[arg(long, hide = true)]
204 no_infrastructure: bool,
205
206 /// Skip compliance checks (not implemented yet)
207 #[arg(long, hide = true)]
208 no_compliance: bool,
209
210 /// Compliance frameworks to check (not implemented yet)
211 #[arg(long, value_delimiter = ',', hide = true)]
212 frameworks: Vec<String>,
213
214 /// Output format
215 #[arg(long, value_enum, default_value = "table")]
216 format: OutputFormat,
217
218 /// Export report to file
219 #[arg(long)]
220 output: Option<PathBuf>,
221
222 /// Exit with error code on security findings
223 #[arg(long)]
224 fail_on_findings: bool,
225 },
226
227 /// Manage vulnerability scanning tools
228 Tools {
229 #[command(subcommand)]
230 command: ToolsCommand,
231 },
232
233 /// Start an interactive AI chat session to analyze and understand your project
234 Chat {
235 /// Path to the project directory (default: current directory)
236 #[arg(value_name = "PROJECT_PATH", default_value = ".")]
237 path: PathBuf,
238
239 /// LLM provider to use (uses saved preference by default)
240 #[arg(long, value_enum, default_value = "auto")]
241 provider: ChatProvider,
242
243 /// Model to use (e.g., gpt-4o, claude-3-5-sonnet-latest, llama3.2)
244 #[arg(long)]
245 model: Option<String>,
246
247 /// Run a single query instead of interactive mode
248 #[arg(long)]
249 query: Option<String>,
250
251 /// Resume a previous session (accepts: "latest", session number, or UUID)
252 #[arg(long, short = 'r')]
253 resume: Option<String>,
254
255 /// List available sessions for this project and exit
256 #[arg(long)]
257 list_sessions: bool,
258 },
259
260 /// Authenticate with the Syncable platform
261 Auth {
262 #[command(subcommand)]
263 command: AuthCommand,
264 },
265}
266
267#[derive(Subcommand)]
268pub enum ToolsCommand {
269 /// Check which vulnerability scanning tools are installed
270 Status {
271 /// Output format
272 #[arg(long, value_enum, default_value = "table")]
273 format: OutputFormat,
274
275 /// Check tools for specific languages only
276 #[arg(long, value_delimiter = ',')]
277 languages: Option<Vec<String>>,
278 },
279
280 /// Install missing vulnerability scanning tools
281 Install {
282 /// Install tools for specific languages only
283 #[arg(long, value_delimiter = ',')]
284 languages: Option<Vec<String>>,
285
286 /// Also install OWASP Dependency Check (large download)
287 #[arg(long)]
288 include_owasp: bool,
289
290 /// Perform a dry run to show what would be installed
291 #[arg(long)]
292 dry_run: bool,
293
294 /// Skip confirmation prompts
295 #[arg(short, long)]
296 yes: bool,
297 },
298
299 /// Verify that installed tools are working correctly
300 Verify {
301 /// Test tools for specific languages only
302 #[arg(long, value_delimiter = ',')]
303 languages: Option<Vec<String>>,
304
305 /// Show detailed verification output
306 #[arg(short, long)]
307 detailed: bool,
308 },
309
310 /// Show tool installation guides for manual setup
311 Guide {
312 /// Show guide for specific languages only
313 #[arg(long, value_delimiter = ',')]
314 languages: Option<Vec<String>>,
315
316 /// Show platform-specific instructions
317 #[arg(long)]
318 platform: Option<String>,
319 },
320}
321
322/// Authentication subcommands for the Syncable platform
323#[derive(Subcommand)]
324pub enum AuthCommand {
325 /// Log in to Syncable (opens browser for authentication)
326 Login {
327 /// Don't open browser automatically
328 #[arg(long)]
329 no_browser: bool,
330 },
331
332 /// Log out and clear stored credentials
333 Logout,
334
335 /// Show current authentication status
336 Status,
337
338 /// Print current access token (for scripting)
339 Token {
340 /// Print raw token without formatting
341 #[arg(long)]
342 raw: bool,
343 },
344}
345
346#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
347pub enum OutputFormat {
348 Table,
349 Json,
350}
351
352#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
353pub enum DisplayFormat {
354 /// Compact matrix/dashboard view (modern, easy to scan)
355 Matrix,
356 /// Detailed vertical view (legacy format with all details)
357 Detailed,
358 /// Brief summary only
359 Summary,
360}
361
362#[derive(Clone, Copy, Debug, ValueEnum)]
363pub enum ColorScheme {
364 /// Auto-detect terminal background (default)
365 Auto,
366 /// Dark background terminal colors
367 Dark,
368 /// Light background terminal colors
369 Light,
370}
371
372#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
373pub enum SeverityThreshold {
374 Low,
375 Medium,
376 High,
377 Critical,
378}
379
380#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
381pub enum SecurityScanMode {
382 /// Lightning fast scan - critical files only (.env, configs)
383 Lightning,
384 /// Fast scan - smart sampling with priority patterns
385 Fast,
386 /// Balanced scan - good coverage with performance optimizations (recommended)
387 Balanced,
388 /// Thorough scan - comprehensive analysis of all files
389 Thorough,
390 /// Paranoid scan - most comprehensive including low-severity findings
391 Paranoid,
392}
393
394#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Default)]
395pub enum ChatProvider {
396 /// OpenAI (GPT-4o, GPT-4, etc.)
397 Openai,
398 /// Anthropic (Claude 3)
399 Anthropic,
400 /// AWS Bedrock (Claude via AWS)
401 Bedrock,
402 /// Ollama (local LLM, no API key needed)
403 Ollama,
404 /// Use saved default from config file
405 #[default]
406 Auto,
407}
408
409impl Cli {
410 /// Initialize logging based on verbosity level
411 pub fn init_logging(&self) {
412 if self.quiet {
413 return;
414 }
415
416 let level = match self.verbose {
417 0 => log::LevelFilter::Warn,
418 1 => log::LevelFilter::Info,
419 2 => log::LevelFilter::Debug,
420 _ => log::LevelFilter::Trace,
421 };
422
423 env_logger::Builder::from_default_env()
424 .filter_level(level)
425 .init();
426 }
427}