mps/cli.rs
1use clap::{Parser, Subcommand};
2
3#[derive(Parser)]
4#[command(name = "mps", version, about = "Plain-text personal productivity CLI")]
5pub struct Cli {
6 /// Path to config file (default: ~/.mps_config.yaml)
7 #[arg(long, global = true)]
8 pub config_path: Option<String>,
9
10 /// Recreate config even if it exists
11 #[arg(long, global = true, default_value_t = false)]
12 pub force: bool,
13
14 #[command(subcommand)]
15 pub command: Option<Commands>,
16}
17
18#[derive(Subcommand)]
19pub enum Commands {
20 /// Open a date's .mps file in $EDITOR (default: today)
21 Open {
22 /// Date to open (today, yesterday, YYYYMMDD, last friday, …)
23 datesign: Option<String>,
24 },
25
26 /// List elements for a date as an indented tree
27 List {
28 /// Date (default: today)
29 datesign: Option<String>,
30 /// Filter by element type: task, note, log, reminder
31 #[arg(short = 't', long)]
32 r#type: Option<String>,
33 /// Filter by tag name
34 #[arg(short = 'g', long)]
35 tag: Option<String>,
36 /// Filter tasks by status: open, done
37 #[arg(short = 's', long)]
38 status: Option<String>,
39 /// Show elements from SINCE up to DATESIGN
40 #[arg(short = 'S', long)]
41 since: Option<String>,
42 /// Show human-readable ref column (task-1, mps-1.2, …)
43 #[arg(short = 'r', long)]
44 refs: bool,
45 /// List elements across all dates in the archive
46 #[arg(short = 'a', long)]
47 all: bool,
48 },
49
50 /// Append an element to today's file without opening an editor
51 Append {
52 /// Element type: task, note, log, reminder (aliases from config are resolved)
53 kind: String,
54 /// Element body text
55 body: Vec<String>,
56 /// Comma-separated tags (e.g. work,backend)
57 #[arg(long)]
58 tags: Option<String>,
59 /// Task status: open (default) or done
60 #[arg(long)]
61 status: Option<String>,
62 /// Time for reminders (e.g. 5pm, 10:30)
63 #[arg(long)]
64 at: Option<String>,
65 /// Start time for logs (HH:MM)
66 #[arg(long)]
67 start_time: Option<String>,
68 /// End time for logs (HH:MM)
69 #[arg(long)]
70 end_time: Option<String>,
71 },
72
73 /// Update an element's attributes in-place
74 Update {
75 /// Element ref: human (task-1) or epoch (20260428.1)
76 ref_path: String,
77 /// Set task status: open or done
78 #[arg(long)]
79 status: Option<String>,
80 /// Set log start time (HH:MM)
81 #[arg(long = "start-time")]
82 start_time: Option<String>,
83 /// Set log end time (HH:MM)
84 #[arg(long = "end-time")]
85 end_time: Option<String>,
86 /// Set reminder time
87 #[arg(long)]
88 at: Option<String>,
89 /// Date context for human refs (default: today)
90 #[arg(short = 'd', long)]
91 date: Option<String>,
92 },
93
94 /// Mark a task as done (shorthand for update REFPATH --status done)
95 Done {
96 /// Element ref: human (task-1) or epoch (20260428.1)
97 ref_path: String,
98 /// Date context for human refs (default: today)
99 #[arg(short = 'd', long)]
100 date: Option<String>,
101 },
102
103 /// Full-text search across all .mps files
104 Search {
105 /// Search query
106 query: String,
107 /// Filter by element type
108 #[arg(short = 't', long)]
109 r#type: Option<String>,
110 /// Filter by tag
111 #[arg(short = 'g', long)]
112 tag: Option<String>,
113 /// Search from this date onward
114 #[arg(short = 'S', long)]
115 since: Option<String>,
116 },
117
118 /// Show element counts and log durations
119 Stats {
120 /// Date (default: today)
121 datesign: Option<String>,
122 /// Stats from SINCE up to DATESIGN
123 #[arg(short = 'S', long)]
124 since: Option<String>,
125 /// Stats across all dates in the archive
126 #[arg(short = 'a', long)]
127 all: bool,
128 },
129
130 /// Show tag usage frequency bar chart
131 Tags {
132 /// Date (default: today)
133 datesign: Option<String>,
134 /// Filter by element type
135 #[arg(short = 't', long)]
136 r#type: Option<String>,
137 /// Filter tasks by status
138 #[arg(short = 's', long)]
139 status: Option<String>,
140 /// Tags from SINCE up to DATESIGN
141 #[arg(short = 'S', long)]
142 since: Option<String>,
143 /// Count tags across all dates
144 #[arg(short = 'a', long)]
145 all: bool,
146 },
147
148 /// Export elements to JSON or CSV on stdout
149 Export {
150 /// Date (default: today)
151 datesign: Option<String>,
152 /// Output format: json (default), csv
153 #[arg(short = 'f', long, default_value = "json")]
154 format: String,
155 /// Filter by element type
156 #[arg(short = 't', long)]
157 r#type: Option<String>,
158 /// Export from SINCE up to DATESIGN
159 #[arg(short = 'S', long)]
160 since: Option<String>,
161 },
162
163 /// View or edit MPS configuration
164 Config {
165 /// Subcommand: show (default) or edit
166 subcommand: Option<String>,
167 },
168
169 /// Run git commands inside the storage directory
170 Git {
171 /// Git subcommand and args (auto = full cycle, autocommit = stage+commit)
172 #[arg(trailing_var_arg = true)]
173 args: Vec<String>,
174 },
175
176 /// Stage, commit, pull, and push (equivalent to git auto)
177 Autogit,
178
179 /// Run any shell command inside the storage directory
180 Cmd {
181 /// Command and arguments
182 #[arg(trailing_var_arg = true)]
183 args: Vec<String>,
184 },
185
186 /// Print version
187 Version,
188}