track/cli/mod.rs
1//! Command-line interface definitions for the track CLI.
2//!
3//! This module defines the CLI structure using `clap`, including all commands,
4//! subcommands, and their arguments. The actual command handling logic is in the
5//! [`handler`] module.
6
7pub mod handler;
8pub mod handlers;
9
10use clap::{Parser, Subcommand, ValueEnum};
11
12/// Types of completion data that can be output
13#[derive(Debug, Clone, ValueEnum)]
14pub enum CompletionType {
15 /// Task IDs and names for 'track switch'
16 Tasks,
17 /// TODO IDs and content for current task
18 Todos,
19 /// Link IDs and URLs for current task
20 Links,
21 /// Repository IDs and paths for current task
22 Repos,
23}
24
25/// Main CLI structure for the track application.
26#[derive(Parser)]
27#[command(name = "track")]
28#[command(about = "WorkTracker CLI - Manage your development tasks and context", long_about = None)]
29pub struct Cli {
30 #[command(subcommand)]
31 pub command: Commands,
32}
33
34#[derive(Subcommand)]
35pub enum Commands {
36 /// Create a new task and switch to it
37 New {
38 /// Task name
39 name: String,
40
41 /// Task description
42 #[arg(short, long)]
43 description: Option<String>,
44
45 /// Ticket ID (e.g., PROJ-123, owner/repo/456)
46 #[arg(short, long)]
47 ticket: Option<String>,
48
49 /// Ticket URL
50 #[arg(long)]
51 ticket_url: Option<String>,
52
53 /// Template task reference (ID, ticket, or alias) to copy TODOs from
54 #[arg(long)]
55 template: Option<String>,
56 },
57
58 /// List tasks
59 List {
60 /// Include archived tasks
61 #[arg(short, long)]
62 all: bool,
63 },
64
65 /// Switch to a different task
66 Switch {
67 /// Task ID or ticket reference (e.g., 1 or t:PROJ-123)
68 task_ref: String,
69 },
70
71 /// Show detailed information about the current task
72 Status {
73 /// Task ID or ticket reference (e.g., 1 or t:PROJ-123)
74 id: Option<String>,
75
76 /// Output in JSON format
77 #[arg(short, long)]
78 json: bool,
79
80 /// Show all scraps
81 #[arg(short, long)]
82 all: bool,
83 },
84
85 /// View or set task description
86 Desc {
87 /// Description text (if omitted, displays current description)
88 description: Option<String>,
89
90 /// Target task ID (defaults to current task)
91 #[arg(short, long)]
92 task: Option<i64>,
93 },
94
95 /// Link a ticket to a task
96 Ticket {
97 /// Ticket ID
98 ticket_id: String,
99
100 /// Ticket URL
101 url: String,
102
103 /// Target task ID (defaults to current task)
104 #[arg(long)]
105 task: Option<i64>,
106 },
107
108 /// Archive a task
109 Archive {
110 /// Task ID or ticket reference (defaults to current task)
111 task_ref: Option<String>,
112 },
113
114 /// TODO management
115 #[command(subcommand)]
116 Todo(TodoCommands),
117
118 /// Link management
119 #[command(subcommand)]
120 Link(LinkCommands),
121
122 /// Scrap (work notes) management
123 #[command(subcommand)]
124 Scrap(ScrapCommands),
125
126 /// Sync repositories and setup task branches
127 Sync,
128
129 /// Repository management
130 #[command(subcommand)]
131 Repo(RepoCommands),
132
133 /// Task alias management
134 #[command(subcommand)]
135 Alias(AliasCommands),
136
137 /// Show help optimized for LLM agents
138 LlmHelp,
139
140 /// Generate shell completion script
141 Completion {
142 /// Shell to generate completions for
143 #[arg(value_enum)]
144 shell: clap_complete::Shell,
145
146 /// Generate dynamic completion script (with real-time data)
147 #[arg(short, long)]
148 dynamic: bool,
149 },
150
151 /// Output completion candidates (hidden, for shell completion scripts)
152 #[command(hide = true)]
153 #[command(name = "_complete")]
154 Complete {
155 /// Type of completion data to output
156 #[arg(value_enum)]
157 completion_type: CompletionType,
158 },
159
160 /// Configuration management
161 #[command(subcommand)]
162 Config(ConfigCommands),
163
164 /// Start web-based user interface
165 Webui {
166 /// Port to listen on
167 #[arg(short, long, default_value = "3000")]
168 port: u16,
169
170 /// Open browser automatically
171 #[arg(short, long)]
172 open: bool,
173 },
174}
175
176#[derive(Subcommand)]
177pub enum TodoCommands {
178 /// Add a new TODO
179 Add {
180 /// TODO content
181 text: String,
182
183 /// Create worktrees for this TODO
184 #[arg(short, long)]
185 worktree: bool,
186 },
187
188 /// List TODOs
189 List,
190
191 /// Update TODO status
192 Update {
193 /// TODO ID
194 id: i64,
195
196 /// New status (done or cancelled; reopen to pending is not allowed)
197 status: String,
198 },
199
200 /// Complete a TODO (merges worktree if exists)
201 Done {
202 /// TODO ID
203 id: i64,
204 },
205
206 /// Create or show worktrees for a TODO in the current repo
207 Workspace {
208 /// TODO ID
209 id: i64,
210
211 /// Recreate worktrees from the latest bookmark
212 #[arg(long)]
213 recreate: bool,
214
215 /// Force recreation even if uncommitted changes exist
216 #[arg(short, long)]
217 force: bool,
218
219 /// Operate on all registered repos for the task
220 #[arg(long)]
221 all: bool,
222 },
223
224 /// Delete a TODO
225 Delete {
226 /// TODO ID
227 id: i64,
228
229 /// Skip confirmation prompt
230 #[arg(short, long)]
231 force: bool,
232 },
233
234 /// Move a TODO to the front (make it the next todo to work on)
235 Next {
236 /// TODO ID
237 id: i64,
238 },
239}
240
241#[derive(Subcommand)]
242pub enum LinkCommands {
243 /// Add a new link
244 Add {
245 /// URL
246 url: String,
247
248 /// Link title (defaults to URL)
249 title: Option<String>,
250 },
251
252 /// List links
253 List,
254
255 /// Delete a link
256 Delete {
257 /// Link index (1-based)
258 index: usize,
259 },
260}
261
262#[derive(Subcommand)]
263pub enum ScrapCommands {
264 /// Add a new scrap (work note)
265 Add {
266 /// Scrap content
267 content: String,
268 },
269
270 /// List scraps
271 List,
272}
273
274#[derive(Subcommand)]
275pub enum RepoCommands {
276 /// Add a repository to the current task
277 Add {
278 /// Repository path (defaults to current directory)
279 path: Option<String>,
280
281 /// Base branch to use (defaults to current branch)
282 #[arg(short, long)]
283 base: Option<String>,
284 },
285
286 /// List repositories
287 List,
288
289 /// Remove a repository
290 Remove {
291 /// Repository ID
292 id: i64,
293 },
294}
295
296#[derive(Subcommand)]
297pub enum AliasCommands {
298 /// Set an alias for the current task
299 Set {
300 /// Alias name
301 alias: String,
302
303 /// Target task ID (defaults to current task)
304 #[arg(short, long)]
305 task: Option<i64>,
306
307 /// Force overwrite if alias already exists on another task
308 #[arg(short, long)]
309 force: bool,
310 },
311
312 /// Remove the alias from the current task
313 Remove {
314 /// Target task ID (defaults to current task)
315 #[arg(short, long)]
316 task: Option<i64>,
317 },
318}
319
320#[derive(Subcommand)]
321pub enum ConfigCommands {
322 /// Set a configuration value (e.g. vcs-mode jj|git)
323 Set {
324 /// Configuration key (e.g. vcs-mode)
325 key: String,
326
327 /// Configuration value
328 value: String,
329 },
330
331 /// Set Google Calendar ID for today task
332 SetCalendar {
333 /// Google Calendar ID
334 calendar_id: String,
335 },
336
337 /// Show current configuration
338 Show,
339}