agent_first_mail/cli/cases.rs
1use clap::{Args, Subcommand};
2
3#[derive(Subcommand, Debug)]
4pub enum CaseCommand {
5 /// Create a new case and return its stable UID/ref.
6 Create(CaseCreateArgs),
7 /// List compact active case locators.
8 List,
9 /// Show a case's case.md (active or archived) without changing workspace state.
10 Show {
11 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
12 case_ref: String,
13 },
14 /// Add a message to this existing case.
15 Add {
16 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
17 case_ref: String,
18 /// Message id to add.
19 message_id: String,
20 /// Short summary for this message in the case.
21 #[arg(long)]
22 summary: Option<String>,
23 /// Why this message belongs in this case; required by default.
24 #[arg(long)]
25 reason: Option<String>,
26 },
27 /// Move this case to another group.
28 Move {
29 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
30 case_ref: String,
31 /// Destination group.
32 group: String,
33 },
34 /// Rename this active case's human-readable name without changing its UID.
35 Rename {
36 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
37 case_ref: String,
38 /// New human-readable case name.
39 #[arg(long)]
40 name: String,
41 /// Why this name better represents the case; required by default.
42 #[arg(long)]
43 reason: Option<String>,
44 },
45 /// Show or edit active case notes.
46 Notes {
47 #[command(subcommand)]
48 action: CaseNotesAction,
49 },
50 /// Archive this active case.
51 Archive {
52 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
53 case_ref: String,
54 /// Why this case is ready to archive; required by default.
55 #[arg(long)]
56 reason: Option<String>,
57 },
58 /// Reopen this case as active work without changing its tags.
59 Reopen {
60 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
61 case_ref: String,
62 /// Why this case should be reopened; required by default.
63 #[arg(long)]
64 reason: Option<String>,
65 },
66 /// Add a case organization tag.
67 Tag {
68 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
69 case_ref: String,
70 /// Case organization tag.
71 tag: String,
72 /// Why this tag is useful; required by default.
73 #[arg(long)]
74 reason: Option<String>,
75 },
76 /// Remove a case organization tag.
77 Untag {
78 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
79 case_ref: String,
80 /// Case organization tag.
81 tag: String,
82 /// Why this tag should be removed; required by default.
83 #[arg(long)]
84 reason: Option<String>,
85 },
86 /// Create, edit, validate, queue, or remove local case drafts.
87 Draft {
88 #[command(subcommand)]
89 action: CaseDraftAction,
90 },
91 /// Merge another case into this case.
92 Merge {
93 /// Primary case ref.
94 case_ref: String,
95 /// Case ref to merge into the primary case.
96 other_case_ref: String,
97 /// Why these cases should be merged; required by default.
98 #[arg(long)]
99 reason: Option<String>,
100 },
101}
102
103#[derive(Args, Debug, Clone)]
104pub struct CaseCreateArgs {
105 /// Human-readable case name used in case.md and the directory suffix.
106 #[arg(long)]
107 pub name: String,
108 /// Destination group. Defaults to the configured default group.
109 #[arg(long)]
110 pub group: Option<String>,
111 /// Optional first message to add to the case.
112 #[arg(long)]
113 pub message: Option<String>,
114 /// Short summary for the first message.
115 #[arg(long)]
116 pub summary: Option<String>,
117 /// Why this case is being created.
118 #[arg(long)]
119 pub reason: Option<String>,
120}
121
122#[derive(Subcommand, Debug)]
123pub enum CaseNotesAction {
124 /// Show notes markdown.
125 Show {
126 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
127 case_ref: String,
128 },
129 /// Append text to notes markdown.
130 Append {
131 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
132 case_ref: String,
133 /// Markdown text to append.
134 #[arg(long)]
135 text: String,
136 },
137 /// Replace notes markdown with text.
138 Replace {
139 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
140 case_ref: String,
141 /// Markdown text to write.
142 #[arg(long)]
143 text: String,
144 },
145}
146
147#[derive(Subcommand, Debug)]
148pub enum CaseDraftAction {
149 /// Scaffold a new outbound draft (not a reply) in this case.
150 New {
151 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
152 case_ref: String,
153 /// Recipient address. Repeatable.
154 #[arg(long = "to", required = true)]
155 to: Vec<String>,
156 /// Cc address. Repeatable.
157 #[arg(long = "cc")]
158 cc: Vec<String>,
159 /// Draft subject.
160 #[arg(long)]
161 subject: String,
162 /// Workspace identity slug to send as. Defaults to the configured default identity.
163 #[arg(long)]
164 identity: Option<String>,
165 /// Draft body text.
166 #[arg(long, conflicts_with = "body_file")]
167 body: Option<String>,
168 /// Path to a file whose contents become the draft body.
169 #[arg(long = "body-file")]
170 body_file: Option<String>,
171 },
172 /// Scaffold a reply draft to a message, prefilled and quoting the original.
173 Reply {
174 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
175 case_ref: String,
176 /// Message id in this case to reply to.
177 message_id: String,
178 /// Workspace identity slug to send as. Defaults to the configured default identity.
179 #[arg(long)]
180 identity: Option<String>,
181 /// Draft body text. Replaces the default reply template when provided.
182 #[arg(long, conflicts_with = "body_file")]
183 body: Option<String>,
184 /// Path to a file whose contents become the draft body.
185 #[arg(long = "body-file")]
186 body_file: Option<String>,
187 /// Reply to all original recipients (To and Cc), not just the sender.
188 #[arg(long)]
189 all: bool,
190 },
191 /// Change an existing editable draft in place.
192 Change {
193 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
194 case_ref: String,
195 /// Draft markdown file under the case drafts directory.
196 draft_name: String,
197 /// Replacement subject.
198 #[arg(long)]
199 subject: Option<String>,
200 /// Replacement To list. Repeatable; when provided it replaces all To recipients.
201 #[arg(long = "to")]
202 to: Vec<String>,
203 /// Replacement Cc list. Repeatable; when provided it replaces all Cc recipients.
204 #[arg(long = "cc", conflicts_with = "clear_cc")]
205 cc: Vec<String>,
206 /// Clear all Cc recipients.
207 #[arg(long)]
208 clear_cc: bool,
209 /// Change the workspace identity slug used by this draft.
210 #[arg(long)]
211 identity: Option<String>,
212 /// Replacement draft body text.
213 #[arg(long, conflicts_with = "body_file")]
214 body: Option<String>,
215 /// Path to a file whose contents replace the draft body.
216 #[arg(long = "body-file")]
217 body_file: Option<String>,
218 },
219 /// Show an existing draft in a review-friendly JSON shape.
220 Show {
221 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
222 case_ref: String,
223 /// Draft markdown file under the case drafts directory.
224 draft_name: String,
225 },
226 /// Validate a draft under the case drafts directory.
227 Validate {
228 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
229 case_ref: String,
230 /// Draft markdown file under the case drafts directory.
231 draft_name: String,
232 },
233 /// Queue this draft to be saved to the remote Drafts mailbox.
234 Save {
235 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
236 case_ref: String,
237 /// Draft markdown file under the case drafts directory.
238 draft_name: String,
239 },
240 /// Queue this draft to be sent and recorded in the case after push succeeds.
241 Send {
242 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
243 case_ref: String,
244 /// Draft markdown file under the case drafts directory.
245 draft_name: String,
246 },
247 /// Copy or reference a file and add it to a draft's attachments.
248 Attach {
249 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
250 case_ref: String,
251 /// Draft markdown file under the case drafts directory.
252 draft_name: String,
253 /// Local file path to attach.
254 path: String,
255 },
256 /// Remove a local draft and any queued outbound item for it.
257 Remove {
258 /// Case ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix.
259 case_ref: String,
260 /// Draft markdown file under the case drafts directory.
261 draft_name: String,
262 /// Why this draft should be removed; required by default.
263 #[arg(long)]
264 reason: Option<String>,
265 },
266}