Skip to main content

oven_cli/cli/
mod.rs

1pub mod clean;
2pub mod look;
3pub mod off;
4pub mod on;
5pub mod prep;
6pub mod report;
7pub mod ticket;
8
9use clap::{Args, Parser, Subcommand};
10
11#[derive(Parser)]
12#[command(name = "oven", about = "let 'em cook", version)]
13pub struct Cli {
14    #[command(flatten)]
15    pub global: GlobalOpts,
16    #[command(subcommand)]
17    pub command: Commands,
18}
19
20#[derive(Args)]
21pub struct GlobalOpts {
22    /// Enable verbose output
23    #[arg(global = true, short, long)]
24    pub verbose: bool,
25    /// Suppress non-essential output
26    #[arg(global = true, short, long)]
27    pub quiet: bool,
28}
29
30#[derive(Subcommand)]
31pub enum Commands {
32    /// Set up project (recipe.toml, agents, db)
33    Prep(PrepArgs),
34    /// Start the pipeline
35    On(OnArgs),
36    /// Stop a detached run
37    Off,
38    /// View pipeline logs
39    Look(LookArgs),
40    /// Show run details and costs
41    Report(ReportArgs),
42    /// Remove worktrees, logs, merged branches
43    Clean(CleanArgs),
44    /// Local issue management
45    Ticket(TicketArgs),
46}
47
48#[derive(Args)]
49pub struct PrepArgs {
50    /// Overwrite existing config
51    #[arg(long)]
52    pub force: bool,
53}
54
55#[derive(Args)]
56pub struct OnArgs {
57    /// Comma-separated issue numbers
58    pub ids: Option<String>,
59    /// Run in background
60    #[arg(short, long)]
61    pub detached: bool,
62    /// Auto-merge PRs when done
63    #[arg(short, long)]
64    pub merge: bool,
65    /// Skip author validation for explicit issue IDs
66    #[arg(long)]
67    pub trust: bool,
68    /// Internal: pre-generated run ID (used by detached mode)
69    #[arg(long, hide = true)]
70    pub run_id: Option<String>,
71}
72
73#[derive(Args)]
74pub struct LookArgs {
75    /// Run ID to view
76    pub run_id: Option<String>,
77    /// Filter to a specific agent
78    #[arg(long)]
79    pub agent: Option<String>,
80}
81
82#[derive(Args)]
83pub struct ReportArgs {
84    /// Run ID to report on
85    pub run_id: Option<String>,
86    /// Show all runs
87    #[arg(long)]
88    pub all: bool,
89    /// Output as JSON
90    #[arg(long)]
91    pub json: bool,
92    /// Show the dependency graph
93    #[arg(long)]
94    pub graph: bool,
95}
96
97#[derive(Args)]
98pub struct CleanArgs {
99    /// Only remove logs
100    #[arg(long)]
101    pub only_logs: bool,
102    /// Only remove worktrees
103    #[arg(long)]
104    pub only_trees: bool,
105    /// Only remove merged branches
106    #[arg(long)]
107    pub only_branches: bool,
108}
109
110#[derive(Args)]
111pub struct TicketArgs {
112    #[command(subcommand)]
113    pub command: TicketCommands,
114}
115
116#[derive(Subcommand)]
117pub enum TicketCommands {
118    /// Create a local issue
119    Create(TicketCreateArgs),
120    /// List local issues
121    List(TicketListArgs),
122    /// View a local issue
123    View(TicketViewArgs),
124    /// Close a local issue
125    Close(TicketCloseArgs),
126    /// Add or remove a label on a local issue
127    Label(TicketLabelArgs),
128    /// Open a local issue in $EDITOR
129    Edit(TicketEditArgs),
130}
131
132#[derive(Args)]
133pub struct TicketCreateArgs {
134    /// Issue title
135    pub title: String,
136    /// Issue body
137    #[arg(long)]
138    pub body: Option<String>,
139    /// Add o-ready label immediately
140    #[arg(long)]
141    pub ready: bool,
142    /// Target repo for multi-repo routing
143    #[arg(long)]
144    pub repo: Option<String>,
145}
146
147#[derive(Args)]
148pub struct TicketListArgs {
149    /// Filter by label
150    #[arg(long)]
151    pub label: Option<String>,
152    /// Filter by status (open/closed)
153    #[arg(long)]
154    pub status: Option<String>,
155}
156
157#[derive(Args)]
158pub struct TicketViewArgs {
159    /// Issue ID
160    pub id: u32,
161}
162
163#[derive(Args)]
164pub struct TicketCloseArgs {
165    /// Issue ID
166    pub id: u32,
167}
168
169#[derive(Args)]
170pub struct TicketLabelArgs {
171    /// Issue ID
172    pub id: u32,
173    /// Label to add or remove
174    pub label: String,
175    /// Remove the label instead of adding it
176    #[arg(long)]
177    pub remove: bool,
178}
179
180#[derive(Args)]
181pub struct TicketEditArgs {
182    /// Issue ID
183    pub id: u32,
184}
185
186#[cfg(test)]
187mod tests {
188    use super::*;
189
190    #[test]
191    fn verify_cli() {
192        use clap::CommandFactory;
193        Cli::command().debug_assert();
194    }
195}