Skip to main content

nuviz_cli/
cli.rs

1use clap::{Parser, Subcommand};
2
3#[derive(Parser)]
4#[command(name = "nuviz")]
5#[command(about = "Terminal-native ML training visualization")]
6#[command(version)]
7pub struct Cli {
8    #[command(subcommand)]
9    pub command: Commands,
10
11    /// Base directory for experiments [default: ~/.nuviz/experiments]
12    #[arg(long, global = true)]
13    pub dir: Option<String>,
14}
15
16#[derive(Subcommand)]
17pub enum Commands {
18    /// Real-time training monitoring (TUI dashboard)
19    Watch(WatchArgs),
20
21    /// List all experiments
22    Ls(LsArgs),
23
24    /// Experiment metrics leaderboard
25    Leaderboard(LeaderboardArgs),
26
27    /// Multi-experiment curve comparison (TUI)
28    Compare(CompareArgs),
29
30    /// Ablation experiment matrix view
31    Matrix(MatrixArgs),
32
33    /// Per-scene metric breakdown
34    Breakdown(BreakdownArgs),
35
36    /// Export experiment data as CSV or JSON
37    Export(ExportArgs),
38
39    /// Browse experiment images in terminal
40    Image(ImageArgs),
41
42    /// Visual diff between two experiments
43    Diff(DiffArgs),
44
45    /// Point cloud (PLY) statistics and inspection
46    View(ViewArgs),
47
48    /// Tag experiments for organization
49    Tag(TagArgs),
50
51    /// Clean up low-value experiments
52    Cleanup(CleanupArgs),
53
54    /// Print reproduction guide for an experiment
55    Reproduce(ReproduceArgs),
56}
57
58#[derive(Parser)]
59pub struct WatchArgs {
60    /// Experiment name(s) to watch
61    pub experiments: Vec<String>,
62
63    /// Watch the latest N experiments in a project
64    #[arg(long)]
65    pub latest: Option<usize>,
66
67    /// Filter by project name
68    #[arg(long)]
69    pub project: Option<String>,
70
71    /// Use polling instead of inotify (for NFS/WSL)
72    #[arg(long)]
73    pub poll: bool,
74}
75
76#[derive(Parser)]
77pub struct LsArgs {
78    /// Filter by project name
79    #[arg(long)]
80    pub project: Option<String>,
81
82    /// Sort by field: name, date, steps
83    #[arg(long, default_value = "date")]
84    pub sort: String,
85}
86
87#[derive(Parser)]
88pub struct LeaderboardArgs {
89    /// Filter by project name
90    #[arg(long)]
91    pub project: Option<String>,
92
93    /// Metric to sort by
94    #[arg(long)]
95    pub sort: Option<String>,
96
97    /// Show only top N experiments
98    #[arg(long)]
99    pub top: Option<usize>,
100
101    /// Sort in ascending order (default: descending)
102    #[arg(long)]
103    pub asc: bool,
104
105    /// Output format: table, markdown, latex, csv
106    #[arg(long, default_value = "table")]
107    pub format: String,
108
109    /// Aggregate multi-seed runs (show mean ± std)
110    #[arg(long)]
111    pub aggregate: bool,
112}
113
114#[derive(Parser)]
115pub struct CompareArgs {
116    /// Experiment names to compare
117    pub experiments: Vec<String>,
118
119    /// Filter by project name
120    #[arg(long)]
121    pub project: Option<String>,
122
123    /// Metric to display
124    #[arg(long)]
125    pub metric: Option<String>,
126
127    /// Alignment mode: step or wall_time
128    #[arg(long, default_value = "step")]
129    pub align: String,
130
131    /// Use polling for file watching (NFS/WSL)
132    #[arg(long)]
133    pub poll: bool,
134}
135
136#[derive(Parser)]
137pub struct MatrixArgs {
138    /// Parameter for matrix rows
139    #[arg(long)]
140    pub rows: String,
141
142    /// Parameter for matrix columns
143    #[arg(long)]
144    pub cols: String,
145
146    /// Metric to display in cells
147    #[arg(long)]
148    pub metric: String,
149
150    /// Filter by project name
151    #[arg(long)]
152    pub project: Option<String>,
153
154    /// Output format: table, latex, markdown, csv
155    #[arg(long, default_value = "table")]
156    pub format: String,
157}
158
159#[derive(Parser)]
160pub struct BreakdownArgs {
161    /// Experiment name
162    pub experiment: String,
163
164    /// Output as LaTeX table
165    #[arg(long)]
166    pub latex: bool,
167
168    /// Output as Markdown table
169    #[arg(long)]
170    pub markdown: bool,
171
172    /// Compare with a second experiment (show deltas)
173    #[arg(long)]
174    pub diff: Option<String>,
175
176    /// Filter by project name
177    #[arg(long)]
178    pub project: Option<String>,
179}
180
181#[derive(Parser)]
182pub struct ExportArgs {
183    /// Experiment name
184    pub experiment: String,
185
186    /// Output format: csv or json
187    #[arg(long, default_value = "csv")]
188    pub format: String,
189
190    /// Export only specific metric(s)
191    #[arg(long)]
192    pub metric: Option<Vec<String>>,
193
194    /// Filter by project name
195    #[arg(long)]
196    pub project: Option<String>,
197}
198
199#[derive(Parser)]
200pub struct ImageArgs {
201    /// Experiment name
202    pub experiment: String,
203
204    /// Filter by step number
205    #[arg(long)]
206    pub step: Option<u64>,
207
208    /// Filter by image tag (e.g., "render", "depth")
209    #[arg(long)]
210    pub tag: Option<String>,
211
212    /// Show only the most recent image
213    #[arg(long)]
214    pub latest: bool,
215
216    /// Show side-by-side with another tag (e.g., --side-by-side gt)
217    #[arg(long)]
218    pub side_by_side: Option<String>,
219
220    /// Filter by project name
221    #[arg(long)]
222    pub project: Option<String>,
223}
224
225#[derive(Parser)]
226pub struct DiffArgs {
227    /// First experiment name
228    pub experiment_a: String,
229
230    /// Second experiment name
231    pub experiment_b: String,
232
233    /// Specific step to compare
234    #[arg(long)]
235    pub step: Option<u64>,
236
237    /// Image tag to compare (default: render)
238    #[arg(long, default_value = "render")]
239    pub tag: String,
240
241    /// Show per-pixel error heatmap
242    #[arg(long)]
243    pub heatmap: bool,
244
245    /// Filter by scene name
246    #[arg(long)]
247    pub scene: Option<String>,
248
249    /// Filter by project name
250    #[arg(long)]
251    pub project: Option<String>,
252}
253
254#[derive(Parser)]
255pub struct ViewArgs {
256    /// Path to PLY file, or experiment name to find latest PLY
257    pub path: String,
258
259    /// Show attribute distribution histograms
260    #[arg(long)]
261    pub histogram: bool,
262
263    /// Filter by project name
264    #[arg(long)]
265    pub project: Option<String>,
266}
267
268#[derive(Parser)]
269pub struct TagArgs {
270    /// Experiment name
271    pub experiment: String,
272
273    /// Tag to add
274    pub tag: Option<String>,
275
276    /// Remove a tag
277    #[arg(long)]
278    pub remove: Option<String>,
279
280    /// List all tags
281    #[arg(long)]
282    pub list: bool,
283}
284
285#[derive(Parser)]
286pub struct CleanupArgs {
287    /// Filter by project name
288    #[arg(long)]
289    pub project: Option<String>,
290
291    /// Keep top N experiments by metric (default: 5)
292    #[arg(long)]
293    pub keep_top: Option<usize>,
294
295    /// Metric to rank by (default: loss)
296    #[arg(long)]
297    pub metric: Option<String>,
298
299    /// Actually delete (default is dry-run)
300    #[arg(long)]
301    pub force: bool,
302}
303
304#[derive(Parser)]
305pub struct ReproduceArgs {
306    /// Experiment name
307    pub experiment: String,
308}