1use clap::{Args, Parser, Subcommand};
2use clap_complete::Shell;
3
4use crate::output::OutputFormat;
5
6#[derive(Debug, Parser)]
7#[command(
8 name = "teams",
9 version,
10 about = "Microsoft Teams from your terminal, for humans and agents",
11 after_help = "Get started:\n teams init Guided setup\n teams tui --demo Explore without an account\n teams doctor Diagnose configuration and access\n teams schema --command 'messages send'\n Inspect the automation contract"
12)]
13pub struct Cli {
14 #[arg(long, global = true, env = "TEAMS_PROFILE")]
16 pub profile: Option<String>,
17 #[arg(short = 'o', long, global = true, value_enum, default_value = "auto")]
19 pub output: OutputFormat,
20 #[arg(long, global = true)]
22 pub quiet: bool,
23 #[arg(long, short = 'y', global = true)]
25 pub yes: bool,
26 #[arg(long, global = true, hide = true)]
28 pub json: bool,
29 #[command(subcommand)]
30 pub command: Option<Command>,
31}
32
33#[derive(Debug, Subcommand)]
34pub enum Command {
35 Init(InitArgs),
37 Auth {
39 #[command(subcommand)]
40 command: AuthCommand,
41 },
42 Profile {
44 #[command(subcommand)]
45 command: ProfileCommand,
46 },
47 Config {
49 #[command(subcommand)]
50 command: ConfigCommand,
51 },
52 Whoami,
54 List(OffsetPageArgs),
56 Channels {
58 #[command(subcommand)]
59 command: ChannelsCommand,
60 },
61 Chats {
63 #[command(subcommand)]
64 command: ChatsCommand,
65 },
66 Messages {
68 #[command(subcommand)]
69 command: MessagesCommand,
70 },
71 Tui(TuiArgs),
73 Doctor {
75 #[arg(long)]
77 offline: bool,
78 },
79 Capabilities,
81 Schema {
83 #[arg(long)]
84 command: Option<String>,
85 },
86 Completions { shell: Shell },
88}
89
90#[derive(Debug, Args)]
91pub struct InitArgs {
92 #[arg(long, env = "TEAMS_CLIENT_ID")]
94 pub client_id: Option<String>,
95 #[arg(long, default_value = "organizations", env = "TEAMS_TENANT")]
97 pub tenant: String,
98 #[arg(long)]
100 pub no_login: bool,
101 #[arg(long)]
103 pub device_code: bool,
104 #[arg(long)]
106 pub channel_history: bool,
107 #[arg(long, env = "TEAMS_READ_ONLY")]
109 pub read_only: bool,
110}
111
112#[derive(Debug, Subcommand)]
113pub enum ConfigCommand {
114 Show,
116 Path,
118}
119
120#[derive(Debug, Subcommand)]
121pub enum AuthCommand {
122 Login {
124 #[arg(long)]
126 device_code: bool,
127 #[arg(long)]
129 channel_history: bool,
130 },
131 Logout,
133 Status {
135 #[arg(long)]
137 offline: bool,
138 },
139}
140
141#[derive(Debug, Subcommand)]
142pub enum ProfileCommand {
143 List,
145 Use { name: String },
147 Remove { name: String },
149}
150
151#[derive(Debug, Subcommand)]
152pub enum ChannelsCommand {
153 List {
155 team: String,
156 #[command(flatten)]
157 page: OffsetPageArgs,
158 },
159}
160
161#[derive(Debug, Subcommand)]
162pub enum ChatsCommand {
163 List(PageArgs),
164}
165
166#[derive(Debug, Args, Clone)]
167pub struct PageArgs {
168 #[arg(long, default_value_t = 50, value_parser = clap::value_parser!(u16).range(1..=50))]
170 pub limit: u16,
171 #[arg(long)]
173 pub cursor: Option<String>,
174 #[arg(long)]
176 pub fields: Option<String>,
177}
178
179#[derive(Debug, Args, Clone)]
180pub struct OffsetPageArgs {
181 #[arg(long, default_value_t = 50, value_parser = clap::value_parser!(u16).range(1..=100))]
183 pub limit: u16,
184 #[arg(long, default_value_t = 0)]
186 pub offset: usize,
187 #[arg(long)]
189 pub fields: Option<String>,
190}
191
192#[derive(Debug, Subcommand)]
193pub enum MessagesCommand {
194 List {
196 #[arg(long, conflicts_with = "team", required_unless_present = "team")]
197 chat: Option<String>,
198 #[arg(long, requires = "channel", required_unless_present = "chat")]
199 team: Option<String>,
200 #[arg(long, requires = "team")]
201 channel: Option<String>,
202 #[command(flatten)]
203 page: PageArgs,
204 },
205 Send {
207 #[arg(long, conflicts_with = "team", required_unless_present = "team")]
208 chat: Option<String>,
209 #[arg(long, requires = "channel", required_unless_present = "chat")]
210 team: Option<String>,
211 #[arg(long, requires = "team")]
212 channel: Option<String>,
213 #[arg(long)]
215 body: String,
216 },
217}
218
219#[derive(Debug, Args)]
220pub struct TuiArgs {
221 #[arg(long)]
223 pub demo: bool,
224 #[arg(long, requires = "demo")]
226 pub snapshot: bool,
227 #[arg(long, default_value_t = 100, hide = true)]
228 pub width: u16,
229 #[arg(long, default_value_t = 30, hide = true)]
230 pub height: u16,
231}