1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use clap::{Parser, Subcommand};
use crate::models::common::Priority;
#[derive(Parser)]
#[command(name = "tally")]
#[command(about = "A task management tool for TODO.md files")]
#[command(version)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
/// Add a new task to TODO.md.
Add {
/// Task text to add.
#[arg(required = true, num_args = 1..)]
description: Vec<String>,
/// Priority for the new task.
#[arg(short, long, value_enum, default_value_t = Priority::Medium)]
priority: Priority,
/// Comma-separated tags to attach.
#[arg(short, long, value_delimiter = ',')]
tags: Option<Vec<String>>,
/// Show what would be added without writing TODO.md.
#[arg(long, default_value_t = false)]
dry_run: bool,
/// Auto-commit updated files after adding.
#[arg(long, default_value_t = false)]
auto: bool,
},
/// Mark a task as completed using fuzzy description matching.
Done {
/// Task text to match.
#[arg(required = true, num_args = 1..)]
description: Vec<String>,
/// Commit hash to associate with completion.
#[arg(short, long)]
commit: Option<String>,
/// Release version to attach at completion time.
#[arg(short, long)]
version: Option<String>,
/// Show what would be changed without writing TODO.md.
#[arg(long, default_value_t = false)]
dry_run: bool,
/// Auto-commit updated files after completion.
#[arg(long, default_value_t = false)]
auto: bool,
},
/// List tasks with optional filters.
List {
/// Filter by one or more comma-separated tags.
#[arg(short, long, value_delimiter = ',')]
tags: Option<Vec<String>>,
/// Filter by priority.
#[arg(short, long, value_enum)]
priority: Option<Priority>,
/// Show only completed tasks.
#[arg(long, default_value_t = false)]
done: bool,
/// Output results as JSON.
#[arg(long, default_value_t = false)]
json: bool,
},
/// Move completed unversioned tasks into CHANGELOG.md under a version.
Semver {
/// Version to assign (for example: 1.2.3 or v1.2.3).
version: String,
/// Show what would be moved without writing files.
#[arg(long, default_value_t = false)]
dry_run: bool,
/// Print a summary of tasks moved for this version.
#[arg(long, default_value_t = false)]
summary: bool,
/// Auto-commit updated files after semver move.
#[arg(long, default_value_t = false)]
auto: bool,
},
/// Render changelog output, optionally filtered by version range.
Changelog {
/// Inclusive lower version bound.
#[arg(long)]
from: Option<String>,
/// Inclusive upper version bound.
#[arg(long)]
to: Option<String>,
},
/// Search released tasks stored in CHANGELOG.md.
Released {
/// Limit search to a specific version.
#[arg(long)]
version: Option<String>,
/// Optional query text to match against released entries.
#[arg(num_args = 1..)]
query: Option<Vec<String>>,
},
/// Remove a released changelog entry by fuzzy description match.
Unrelease {
/// Released task text to match.
#[arg(required = true, num_args = 1..)]
description: Vec<String>,
/// Limit removal to a specific version section.
#[arg(long)]
version: Option<String>,
/// Show what would be removed without writing files.
#[arg(long, default_value_t = false)]
dry_run: bool,
/// Auto-commit updated files after removal.
#[arg(long, default_value_t = false)]
auto: bool,
},
/// Remove a task from TODO.md by fuzzy description match.
Remove {
/// Task text to match.
#[arg(required = true, num_args = 1..)]
description: Vec<String>,
/// Show what would be removed without writing TODO.md.
#[arg(long, default_value_t = false)]
dry_run: bool,
/// Auto-commit updated files after removal.
#[arg(long, default_value_t = false)]
auto: bool,
},
/// Scan for task updates from git commits and/or source TODO markers.
Scan {
/// Auto-accept git-based done matches without prompting.
#[arg(long, default_value_t = false)]
auto: bool,
/// Show what would change without writing files.
#[arg(long, default_value_t = false)]
dry_run: bool,
/// Run only git commit scanning.
#[arg(long, default_value_t = false)]
git: bool,
/// Run only source TODO scanning.
#[arg(long, default_value_t = false)]
source: bool,
},
}