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