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    /// Show agent progress and status from the database
81    #[arg(long)]
82    pub stream: bool,
83}
84
85#[derive(Args)]
86pub struct ReportArgs {
87    /// Run ID to report on
88    pub run_id: Option<String>,
89    /// Show all runs
90    #[arg(long)]
91    pub all: bool,
92    /// Output as JSON
93    #[arg(long)]
94    pub json: bool,
95    /// Show the dependency graph
96    #[arg(long)]
97    pub graph: bool,
98}
99
100#[derive(Args)]
101pub struct CleanArgs {
102    /// Only remove logs
103    #[arg(long)]
104    pub only_logs: bool,
105    /// Only remove worktrees
106    #[arg(long)]
107    pub only_trees: bool,
108    /// Only remove merged branches
109    #[arg(long)]
110    pub only_branches: bool,
111}
112
113#[derive(Args)]
114pub struct TicketArgs {
115    #[command(subcommand)]
116    pub command: TicketCommands,
117}
118
119#[derive(Subcommand)]
120pub enum TicketCommands {
121    /// Create a local issue
122    Create(TicketCreateArgs),
123    /// List local issues
124    List(TicketListArgs),
125    /// View a local issue
126    View(TicketViewArgs),
127    /// Close a local issue
128    Close(TicketCloseArgs),
129    /// Add or remove a label on a local issue
130    Label(TicketLabelArgs),
131    /// Open a local issue in $EDITOR
132    Edit(TicketEditArgs),
133}
134
135#[derive(Args)]
136pub struct TicketCreateArgs {
137    /// Issue title
138    pub title: String,
139    /// Issue body
140    #[arg(long)]
141    pub body: Option<String>,
142    /// Add o-ready label immediately
143    #[arg(long)]
144    pub ready: bool,
145    /// Target repo for multi-repo routing
146    #[arg(long)]
147    pub repo: Option<String>,
148}
149
150#[derive(Args)]
151pub struct TicketListArgs {
152    /// Filter by label
153    #[arg(long)]
154    pub label: Option<String>,
155    /// Filter by status (open/closed)
156    #[arg(long)]
157    pub status: Option<String>,
158}
159
160#[derive(Args)]
161pub struct TicketViewArgs {
162    /// Issue ID
163    pub id: u32,
164}
165
166#[derive(Args)]
167pub struct TicketCloseArgs {
168    /// Issue ID
169    pub id: u32,
170}
171
172#[derive(Args)]
173pub struct TicketLabelArgs {
174    /// Issue ID
175    pub id: u32,
176    /// Label to add or remove
177    pub label: String,
178    /// Remove the label instead of adding it
179    #[arg(long)]
180    pub remove: bool,
181}
182
183#[derive(Args)]
184pub struct TicketEditArgs {
185    /// Issue ID
186    pub id: u32,
187}
188
189#[cfg(test)]
190mod tests {
191    use super::*;
192
193    #[test]
194    fn verify_cli() {
195        use clap::CommandFactory;
196        Cli::command().debug_assert();
197    }
198}