torvyn_cli/cli.rs
1//! clap derive definitions for the Torvyn CLI.
2//!
3//! This module defines the complete argument schema for the `torvyn` binary.
4//! Every subcommand, flag, and argument is defined here with embedded help text.
5
6use clap::{Parser, Subcommand, ValueEnum};
7use std::path::PathBuf;
8
9// ---------------------------------------------------------------------------
10// Top-level CLI
11// ---------------------------------------------------------------------------
12
13/// Torvyn — Ownership-aware reactive streaming runtime
14///
15/// Build, validate, run, trace, benchmark, and package streaming components.
16///
17/// Getting started? Try: torvyn init my-first-pipeline --template full-pipeline
18#[derive(Parser, Debug)]
19#[command(name = "torvyn", version, about, long_about = None)]
20#[command(propagate_version = true)]
21#[command(
22 after_help = "Getting started? Try: torvyn init my-first-pipeline --template full-pipeline"
23)]
24pub struct Cli {
25 /// Global options available to all subcommands.
26 #[command(flatten)]
27 pub global: GlobalOpts,
28
29 /// The subcommand to execute.
30 #[command(subcommand)]
31 pub command: Command,
32}
33
34// ---------------------------------------------------------------------------
35// Global options
36// ---------------------------------------------------------------------------
37
38/// Global options applied to every subcommand.
39///
40/// ## Invariants
41/// - `verbose` and `quiet` are mutually exclusive (enforced by clap `conflicts_with`).
42/// - `format` defaults to `OutputFormat::Human`.
43/// - `color` defaults to `ColorChoice::Auto`.
44#[derive(Parser, Debug, Clone)]
45pub struct GlobalOpts {
46 /// Increase output verbosity (show debug-level messages).
47 #[arg(long, short = 'v', global = true, conflicts_with = "quiet")]
48 pub verbose: bool,
49
50 /// Suppress non-essential output (errors only).
51 #[arg(long, short = 'q', global = true, conflicts_with = "verbose")]
52 pub quiet: bool,
53
54 /// Output format for command results.
55 #[arg(long, global = true, value_enum, default_value_t = OutputFormat::Human)]
56 pub format: OutputFormat,
57
58 /// Color output control.
59 #[arg(long, global = true, value_enum, default_value_t = ColorChoice::Auto)]
60 pub color: ColorChoice,
61}
62
63// ---------------------------------------------------------------------------
64// Enums
65// ---------------------------------------------------------------------------
66
67/// Output format for CLI results.
68#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
69#[serde(rename_all = "lowercase")]
70pub enum OutputFormat {
71 /// Styled terminal output with colors, tables, and progress indicators.
72 Human,
73 /// Machine-readable JSON output to stdout.
74 Json,
75}
76
77/// Color output control.
78#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
79pub enum ColorChoice {
80 /// Auto-detect terminal color support.
81 Auto,
82 /// Always use color output.
83 Always,
84 /// Never use color output.
85 Never,
86}
87
88/// Project template type for `torvyn init`.
89#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
90#[serde(rename_all = "lowercase")]
91pub enum TemplateKind {
92 /// Data producer (no input, one output).
93 Source,
94 /// Data consumer (one input, no output).
95 Sink,
96 /// Stateless data transformer.
97 Transform,
98 /// Content filter/guard.
99 Filter,
100 /// Multi-output router.
101 Router,
102 /// Stateful windowed aggregator.
103 Aggregator,
104 /// Complete multi-component pipeline with source + transform + sink.
105 FullPipeline,
106 /// Minimal skeleton for experienced users.
107 Empty,
108}
109
110impl TemplateKind {
111 /// Returns a human-readable description of this template.
112 #[allow(dead_code)]
113 pub fn description(&self) -> &'static str {
114 match self {
115 Self::Source => "Data producer (no input, one output)",
116 Self::Sink => "Data consumer (one input, no output)",
117 Self::Transform => "Stateless data transformer",
118 Self::Filter => "Content filter/guard",
119 Self::Router => "Multi-output router",
120 Self::Aggregator => "Stateful windowed aggregator",
121 Self::FullPipeline => "Complete pipeline with source + transform + sink",
122 Self::Empty => "Minimal skeleton for experienced users",
123 }
124 }
125}
126
127/// Implementation language for `torvyn init`.
128#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
129#[serde(rename_all = "lowercase")]
130pub enum Language {
131 /// Rust (primary, fully supported).
132 Rust,
133 /// Go (via TinyGo, limited support).
134 Go,
135 /// Python (via componentize-py, limited support).
136 Python,
137 /// Zig (experimental).
138 Zig,
139}
140
141/// Shell type for shell completion generation.
142#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
143pub enum ShellKind {
144 /// Bash shell completions.
145 Bash,
146 /// Zsh shell completions.
147 Zsh,
148 /// Fish shell completions.
149 Fish,
150 /// PowerShell completions.
151 #[value(name = "powershell")]
152 PowerShell,
153}
154
155/// Sections to show in `torvyn inspect`.
156#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
157#[serde(rename_all = "lowercase")]
158pub enum InspectSection {
159 /// Show all available information.
160 All,
161 /// Show exported and imported interfaces.
162 Interfaces,
163 /// Show required capabilities.
164 Capabilities,
165 /// Show component metadata (version, authors, etc.).
166 Metadata,
167 /// Show binary size breakdown.
168 Size,
169 /// Show WIT contract definitions.
170 Contracts,
171 /// Show embedded benchmark results.
172 Benchmarks,
173}
174
175/// Report format for `torvyn bench`.
176#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
177#[serde(rename_all = "lowercase")]
178pub enum ReportFormat {
179 /// Styled terminal table.
180 Pretty,
181 /// JSON report.
182 Json,
183 /// CSV report.
184 Csv,
185 /// Markdown report.
186 Markdown,
187}
188
189/// Trace output format for `torvyn trace`.
190#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
191#[serde(rename_all = "lowercase")]
192pub enum TraceFormat {
193 /// Pretty-printed tree trace.
194 Pretty,
195 /// JSON trace spans.
196 Json,
197 /// OpenTelemetry Protocol export.
198 Otlp,
199}
200
201// ---------------------------------------------------------------------------
202// Subcommands
203// ---------------------------------------------------------------------------
204
205/// All available subcommands for the `torvyn` binary.
206#[derive(Subcommand, Debug)]
207pub enum Command {
208 /// Create a new Torvyn project.
209 ///
210 /// Scaffolds a complete project with WIT contracts, implementation stubs,
211 /// a Torvyn.toml manifest, and build configuration. The generated project
212 /// compiles and runs out of the box.
213 Init(InitArgs),
214
215 /// Validate contracts, manifest, and project structure.
216 ///
217 /// Performs static analysis: parses WIT contracts, validates the manifest
218 /// schema, resolves references, and checks capability declarations.
219 Check(CheckArgs),
220
221 /// Verify component composition compatibility.
222 ///
223 /// Given a pipeline configuration, verifies that all component interfaces
224 /// are compatible and the topology is valid (DAG, connected, role-consistent).
225 Link(LinkArgs),
226
227 /// Execute a pipeline locally.
228 ///
229 /// Instantiates the Torvyn host runtime, loads components, and runs
230 /// the pipeline. Displays element count, errors, and completion status.
231 Run(RunArgs),
232
233 /// Run with full diagnostic tracing.
234 ///
235 /// Like `run` but with full tracing enabled. Outputs flow timeline
236 /// showing per-stage latency, resource transfers, backpressure events.
237 Trace(TraceArgs),
238
239 /// Benchmark a pipeline.
240 ///
241 /// Runs the pipeline under sustained load with warmup, then produces
242 /// a report with p50/p95/p99/p99.9 latency, throughput, copy count,
243 /// memory, and resource utilization.
244 Bench(BenchArgs),
245
246 /// Package as OCI artifact.
247 ///
248 /// Assembles compiled components, contracts, and metadata into a
249 /// distributable artifact.
250 Pack(PackArgs),
251
252 /// Publish to a registry.
253 ///
254 /// Pushes a packaged artifact to a registry. For Phase 0: local
255 /// directory registry only.
256 Publish(PublishArgs),
257
258 /// Inspect a component or artifact.
259 ///
260 /// Displays metadata, interfaces, capabilities, and size information
261 /// for a compiled .wasm file or packaged artifact.
262 Inspect(InspectArgs),
263
264 /// Check development environment.
265 ///
266 /// Verifies required tools, correct versions, and common misconfigurations.
267 /// Run `torvyn doctor --fix` to attempt automatic repair.
268 Doctor(DoctorArgs),
269
270 /// Generate shell completions.
271 ///
272 /// Prints a completion script to stdout for the specified shell.
273 /// Example: `torvyn completions bash > ~/.bash_completion.d/torvyn`
274 Completions(CompletionsArgs),
275}
276
277// ---------------------------------------------------------------------------
278// Per-command argument structs
279// ---------------------------------------------------------------------------
280
281/// Arguments for `torvyn init`.
282#[derive(Parser, Debug)]
283pub struct InitArgs {
284 /// Directory name and project name.
285 /// If omitted, uses the current directory name.
286 pub project_name: Option<String>,
287
288 /// Project template to use.
289 #[arg(long, short = 't', value_enum, default_value_t = TemplateKind::Transform)]
290 pub template: TemplateKind,
291
292 /// Implementation language.
293 #[arg(long, short = 'l', value_enum, default_value_t = Language::Rust)]
294 pub language: Language,
295
296 /// Skip git repository initialization.
297 #[arg(long)]
298 pub no_git: bool,
299
300 /// Skip example implementation, generate contract stubs only.
301 #[arg(long)]
302 pub no_example: bool,
303
304 /// Torvyn contract version to target.
305 #[arg(long, default_value = "0.1.0")]
306 pub contract_version: String,
307
308 /// Overwrite existing directory contents.
309 #[arg(long)]
310 pub force: bool,
311}
312
313/// Arguments for `torvyn check`.
314#[derive(Parser, Debug)]
315pub struct CheckArgs {
316 /// Path to Torvyn.toml.
317 #[arg(long, default_value = "./Torvyn.toml")]
318 pub manifest: PathBuf,
319
320 /// Treat warnings as errors.
321 #[arg(long)]
322 pub strict: bool,
323}
324
325/// Arguments for `torvyn link`.
326#[derive(Parser, Debug)]
327pub struct LinkArgs {
328 /// Path to Torvyn.toml with flow definition.
329 #[arg(long, default_value = "./Torvyn.toml")]
330 pub manifest: PathBuf,
331
332 /// Specific flow to check (default: all flows).
333 #[arg(long)]
334 pub flow: Option<String>,
335
336 /// Directory containing compiled .wasm components.
337 #[arg(long)]
338 pub components: Option<PathBuf>,
339
340 /// Show full interface compatibility details.
341 #[arg(long)]
342 pub detail: bool,
343}
344
345/// Arguments for `torvyn run`.
346#[derive(Parser, Debug)]
347pub struct RunArgs {
348 /// Path to Torvyn.toml.
349 #[arg(long, default_value = "./Torvyn.toml")]
350 pub manifest: PathBuf,
351
352 /// Flow to execute (default: first defined flow).
353 #[arg(long)]
354 pub flow: Option<String>,
355
356 /// Override source input (file path, stdin, or generator).
357 #[arg(long)]
358 pub input: Option<String>,
359
360 /// Override sink output (file path, stdout).
361 #[arg(long)]
362 pub output: Option<String>,
363
364 /// Process at most N elements then exit.
365 #[arg(long)]
366 pub limit: Option<u64>,
367
368 /// Maximum execution time (e.g., 30s, 5m).
369 #[arg(long)]
370 pub timeout: Option<String>,
371
372 /// Override component configuration values.
373 #[arg(long, value_name = "KEY=VALUE")]
374 pub config: Vec<String>,
375
376 /// Log verbosity.
377 #[arg(long, default_value = "info")]
378 pub log_level: String,
379}
380
381/// Arguments for `torvyn trace`.
382#[derive(Parser, Debug)]
383pub struct TraceArgs {
384 /// Path to Torvyn.toml.
385 #[arg(long, default_value = "./Torvyn.toml")]
386 pub manifest: PathBuf,
387
388 /// Flow to trace (default: first defined flow).
389 #[arg(long)]
390 pub flow: Option<String>,
391
392 /// Override source input.
393 #[arg(long)]
394 pub input: Option<String>,
395
396 /// Trace at most N elements.
397 #[arg(long)]
398 pub limit: Option<u64>,
399
400 /// Write trace data to file (default: stdout).
401 #[arg(long)]
402 pub output_trace: Option<PathBuf>,
403
404 /// Trace output format.
405 #[arg(long, value_enum, default_value_t = TraceFormat::Pretty)]
406 pub trace_format: TraceFormat,
407
408 /// Include buffer content snapshots in trace.
409 #[arg(long)]
410 pub show_buffers: bool,
411
412 /// Highlight backpressure events.
413 #[arg(long)]
414 pub show_backpressure: bool,
415}
416
417/// Arguments for `torvyn bench`.
418#[derive(Parser, Debug)]
419pub struct BenchArgs {
420 /// Path to Torvyn.toml.
421 #[arg(long, default_value = "./Torvyn.toml")]
422 pub manifest: PathBuf,
423
424 /// Flow to benchmark (default: first defined flow).
425 #[arg(long)]
426 pub flow: Option<String>,
427
428 /// Benchmark duration (default: 10s).
429 #[arg(long, default_value = "10s")]
430 pub duration: String,
431
432 /// Warmup period excluded from results (default: 2s).
433 #[arg(long, default_value = "2s")]
434 pub warmup: String,
435
436 /// Override source input (for reproducible benchmarks).
437 #[arg(long)]
438 pub input: Option<String>,
439
440 /// Write report to file (default: stdout).
441 #[arg(long)]
442 pub report: Option<PathBuf>,
443
444 /// Report format.
445 #[arg(long, value_enum, default_value_t = ReportFormat::Pretty)]
446 pub report_format: ReportFormat,
447
448 /// Compare against a previous benchmark result.
449 #[arg(long)]
450 pub compare: Option<PathBuf>,
451
452 /// Save result as a named baseline for future comparison.
453 #[arg(long)]
454 pub baseline: Option<String>,
455}
456
457/// Arguments for `torvyn pack`.
458#[derive(Parser, Debug)]
459pub struct PackArgs {
460 /// Path to Torvyn.toml.
461 #[arg(long, default_value = "./Torvyn.toml")]
462 pub manifest: PathBuf,
463
464 /// Specific component to pack (default: all in project).
465 #[arg(long)]
466 pub component: Option<String>,
467
468 /// Output artifact path (default: .torvyn/artifacts/).
469 #[arg(long)]
470 pub output: Option<PathBuf>,
471
472 /// OCI tag (default: derived from manifest version).
473 #[arg(long)]
474 pub tag: Option<String>,
475
476 /// Include source WIT contracts in artifact metadata.
477 #[arg(long)]
478 pub include_source: bool,
479
480 /// Sign artifact (requires signing key configuration).
481 #[arg(long)]
482 pub sign: bool,
483}
484
485/// Arguments for `torvyn publish`.
486#[derive(Parser, Debug)]
487pub struct PublishArgs {
488 /// Path to packed artifact (default: latest in .torvyn/artifacts/).
489 #[arg(long)]
490 pub artifact: Option<PathBuf>,
491
492 /// Target registry URL (default: from config).
493 #[arg(long)]
494 pub registry: Option<String>,
495
496 /// Override tag.
497 #[arg(long)]
498 pub tag: Option<String>,
499
500 /// Validate publish without actually pushing.
501 #[arg(long)]
502 pub dry_run: bool,
503
504 /// Overwrite existing tag.
505 #[arg(long)]
506 pub force: bool,
507}
508
509/// Arguments for `torvyn inspect`.
510#[derive(Parser, Debug)]
511pub struct InspectArgs {
512 /// Path to .wasm file, OCI artifact, or registry reference.
513 pub target: String,
514
515 /// What section to show.
516 #[arg(long, value_enum, default_value_t = InspectSection::All)]
517 pub show: InspectSection,
518}
519
520/// Arguments for `torvyn doctor`.
521#[derive(Parser, Debug)]
522pub struct DoctorArgs {
523 /// Attempt to fix common issues automatically.
524 #[arg(long)]
525 pub fix: bool,
526}
527
528/// Arguments for `torvyn completions`.
529#[derive(Parser, Debug)]
530pub struct CompletionsArgs {
531 /// Shell to generate completions for.
532 pub shell: ShellKind,
533}