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, global = true, hide = true)]
25 pub json: bool,
26 #[command(subcommand)]
27 pub command: Option<Command>,
28}
29
30#[derive(Debug, Subcommand)]
31pub enum Command {
32 Init(InitArgs),
34 Auth {
36 #[command(subcommand)]
37 command: AuthCommand,
38 },
39 Config {
41 #[command(subcommand)]
42 command: ConfigCommand,
43 },
44 Whoami,
46 List(OffsetPageArgs),
48 Channels {
50 #[command(subcommand)]
51 command: ChannelsCommand,
52 },
53 Chats {
55 #[command(subcommand)]
56 command: ChatsCommand,
57 },
58 Messages {
60 #[command(subcommand)]
61 command: MessagesCommand,
62 },
63 Tui(TuiArgs),
65 Doctor,
67 Capabilities,
69 Schema {
71 #[arg(long)]
72 command: Option<String>,
73 },
74 Completions { shell: Shell },
76}
77
78#[derive(Debug, Args)]
79pub struct InitArgs {
80 #[arg(long, env = "TEAMS_CLIENT_ID")]
82 pub client_id: Option<String>,
83 #[arg(long, default_value = "organizations", env = "TEAMS_TENANT")]
85 pub tenant: String,
86 #[arg(long)]
88 pub no_login: bool,
89 #[arg(long)]
91 pub device_code: bool,
92 #[arg(long)]
94 pub channel_history: bool,
95 #[arg(long, env = "TEAMS_READ_ONLY")]
97 pub read_only: bool,
98}
99
100#[derive(Debug, Subcommand)]
101pub enum ConfigCommand {
102 Show,
104 Path,
106}
107
108#[derive(Debug, Subcommand)]
109pub enum AuthCommand {
110 Login {
112 #[arg(long)]
114 device_code: bool,
115 #[arg(long)]
117 channel_history: bool,
118 },
119 Logout,
121 Status,
123}
124
125#[derive(Debug, Subcommand)]
126pub enum ChannelsCommand {
127 List {
129 team: String,
130 #[command(flatten)]
131 page: OffsetPageArgs,
132 },
133}
134
135#[derive(Debug, Subcommand)]
136pub enum ChatsCommand {
137 List(PageArgs),
138}
139
140#[derive(Debug, Args, Clone)]
141pub struct PageArgs {
142 #[arg(long, default_value_t = 50, value_parser = clap::value_parser!(u16).range(1..=50))]
144 pub limit: u16,
145 #[arg(long)]
147 pub cursor: Option<String>,
148 #[arg(long)]
150 pub fields: Option<String>,
151}
152
153#[derive(Debug, Args, Clone)]
154pub struct OffsetPageArgs {
155 #[arg(long, default_value_t = 50, value_parser = clap::value_parser!(u16).range(1..=100))]
157 pub limit: u16,
158 #[arg(long, default_value_t = 0)]
160 pub offset: usize,
161 #[arg(long)]
163 pub fields: Option<String>,
164}
165
166#[derive(Debug, Subcommand)]
167pub enum MessagesCommand {
168 List {
170 #[arg(long, conflicts_with = "team", required_unless_present = "team")]
171 chat: Option<String>,
172 #[arg(long, requires = "channel", required_unless_present = "chat")]
173 team: Option<String>,
174 #[arg(long, requires = "team")]
175 channel: Option<String>,
176 #[command(flatten)]
177 page: PageArgs,
178 },
179 Send {
181 #[arg(long, conflicts_with = "team", required_unless_present = "team")]
182 chat: Option<String>,
183 #[arg(long, requires = "channel", required_unless_present = "chat")]
184 team: Option<String>,
185 #[arg(long, requires = "team")]
186 channel: Option<String>,
187 #[arg(long)]
189 body: String,
190 },
191}
192
193#[derive(Debug, Args)]
194pub struct TuiArgs {
195 #[arg(long)]
197 pub demo: bool,
198 #[arg(long, requires = "demo")]
200 pub snapshot: bool,
201 #[arg(long, default_value_t = 100, hide = true)]
202 pub width: u16,
203 #[arg(long, default_value_t = 30, hide = true)]
204 pub height: u16,
205}