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 Whoami,
41 List(OffsetPageArgs),
43 Channels {
45 #[command(subcommand)]
46 command: ChannelsCommand,
47 },
48 Chats {
50 #[command(subcommand)]
51 command: ChatsCommand,
52 },
53 Messages {
55 #[command(subcommand)]
56 command: MessagesCommand,
57 },
58 Tui(TuiArgs),
60 Doctor,
62 Capabilities,
64 Schema {
66 #[arg(long)]
67 command: Option<String>,
68 },
69 Completions { shell: Shell },
71}
72
73#[derive(Debug, Args)]
74pub struct InitArgs {
75 #[arg(long, env = "TEAMS_CLIENT_ID")]
77 pub client_id: Option<String>,
78 #[arg(long, default_value = "organizations", env = "TEAMS_TENANT")]
80 pub tenant: String,
81 #[arg(long)]
83 pub no_login: bool,
84 #[arg(long)]
86 pub device_code: bool,
87 #[arg(long)]
89 pub channel_history: bool,
90}
91
92#[derive(Debug, Subcommand)]
93pub enum AuthCommand {
94 Login {
96 #[arg(long)]
98 device_code: bool,
99 #[arg(long)]
101 channel_history: bool,
102 },
103 Logout,
105 Status,
107}
108
109#[derive(Debug, Subcommand)]
110pub enum ChannelsCommand {
111 List {
113 team: String,
114 #[command(flatten)]
115 page: OffsetPageArgs,
116 },
117}
118
119#[derive(Debug, Subcommand)]
120pub enum ChatsCommand {
121 List(PageArgs),
122}
123
124#[derive(Debug, Args, Clone)]
125pub struct PageArgs {
126 #[arg(long, default_value_t = 50, value_parser = clap::value_parser!(u16).range(1..=50))]
128 pub limit: u16,
129 #[arg(long)]
131 pub cursor: Option<String>,
132 #[arg(long)]
134 pub fields: Option<String>,
135}
136
137#[derive(Debug, Args, Clone)]
138pub struct OffsetPageArgs {
139 #[arg(long, default_value_t = 50, value_parser = clap::value_parser!(u16).range(1..=100))]
141 pub limit: u16,
142 #[arg(long, default_value_t = 0)]
144 pub offset: usize,
145 #[arg(long)]
147 pub fields: Option<String>,
148}
149
150#[derive(Debug, Subcommand)]
151pub enum MessagesCommand {
152 List {
154 #[arg(long, conflicts_with = "team", required_unless_present = "team")]
155 chat: Option<String>,
156 #[arg(long, requires = "channel", required_unless_present = "chat")]
157 team: Option<String>,
158 #[arg(long, requires = "team")]
159 channel: Option<String>,
160 #[command(flatten)]
161 page: PageArgs,
162 },
163 Send {
165 #[arg(long, conflicts_with = "team", required_unless_present = "team")]
166 chat: Option<String>,
167 #[arg(long, requires = "channel", required_unless_present = "chat")]
168 team: Option<String>,
169 #[arg(long, requires = "team")]
170 channel: Option<String>,
171 #[arg(long)]
173 body: String,
174 },
175}
176
177#[derive(Debug, Args)]
178pub struct TuiArgs {
179 #[arg(long)]
181 pub demo: bool,
182 #[arg(long, requires = "demo")]
184 pub snapshot: bool,
185 #[arg(long, default_value_t = 100, hide = true)]
186 pub width: u16,
187 #[arg(long, default_value_t = 30, hide = true)]
188 pub height: u16,
189}