1use structopt::StructOpt;
2
3use super::args::{AiProviderArg, AiSessionModeArg, AuthorArg, SideArg, StateArg};
4
5#[derive(Debug, StructOpt)]
6#[structopt(
7 name = "parley",
8 about = "Local AI code review sessions for git changes"
9)]
10pub struct Cli {
11 #[structopt(subcommand)]
12 pub command: Command,
13}
14
15#[derive(Debug, StructOpt)]
16pub enum Command {
17 #[structopt(name = "tui")]
18 Tui {
19 #[structopt(long)]
20 review: Option<String>,
21 #[structopt(long)]
22 theme: Option<String>,
23 #[structopt(long)]
24 no_mouse: bool,
25 },
26 #[structopt(name = "review")]
27 Review {
28 #[structopt(subcommand)]
29 command: ReviewCommand,
30 },
31 #[structopt(name = "mcp")]
32 Mcp,
33}
34
35#[derive(Debug, StructOpt)]
36pub enum ReviewCommand {
37 #[structopt(name = "create")]
38 Create { name: String },
39 #[structopt(name = "start")]
40 Start { name: String },
41 #[structopt(name = "list")]
42 List,
43 #[structopt(name = "show")]
44 Show {
45 name: String,
46 #[structopt(long)]
47 json: bool,
48 },
49 #[structopt(name = "set-state")]
50 SetState { name: String, state: StateArg },
51 #[structopt(name = "add-comment")]
52 AddComment {
53 name: String,
54 #[structopt(long)]
55 file: String,
56 #[structopt(long)]
57 side: SideArg,
58 #[structopt(long)]
59 old_line: Option<u32>,
60 #[structopt(long)]
61 new_line: Option<u32>,
62 #[structopt(long)]
63 body: String,
64 #[structopt(long, default_value = "user")]
65 author: AuthorArg,
66 },
67 #[structopt(name = "add-reply")]
68 AddReply {
69 name: String,
70 #[structopt(long)]
71 comment_id: u64,
72 #[structopt(long)]
73 body: String,
74 #[structopt(long, default_value = "ai")]
75 author: AuthorArg,
76 },
77 #[structopt(name = "mark-addressed")]
78 MarkAddressed {
79 name: String,
80 #[structopt(long)]
81 comment_id: u64,
82 #[structopt(long, default_value = "user")]
83 author: AuthorArg,
84 },
85 #[structopt(name = "mark-open")]
86 MarkOpen {
87 name: String,
88 #[structopt(long)]
89 comment_id: u64,
90 #[structopt(long, default_value = "user")]
91 author: AuthorArg,
92 },
93 #[structopt(name = "run-ai-session")]
94 RunAiSession {
95 name: String,
96 #[structopt(long)]
97 provider: AiProviderArg,
98 #[structopt(long)]
99 mode: Option<AiSessionModeArg>,
100 #[structopt(long = "comment-id")]
101 comment_ids: Vec<u64>,
102 },
103 #[structopt(name = "done")]
104 Done { name: String },
105 #[structopt(name = "resolve")]
106 Resolve { name: String },
107}
108
109#[cfg(test)]
110mod tests {
111 use structopt::StructOpt;
112
113 use super::{Cli, Command};
114
115 #[test]
116 fn tui_command_parses_no_mouse_flag() {
117 let cli = Cli::from_iter_safe(["parley", "tui", "--review", "main", "--no-mouse"])
118 .expect("cli should parse");
119
120 match cli.command {
121 Command::Tui {
122 review,
123 theme,
124 no_mouse,
125 } => {
126 assert_eq!(review.as_deref(), Some("main"));
127 assert_eq!(theme, None);
128 assert!(no_mouse);
129 }
130 other => panic!("unexpected command: {other:?}"),
131 }
132 }
133}