Skip to main content

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        /// Filter character entries by person name
49        #[arg(short = 'n', long)]
50        name: Option<String>,
51    },
52
53    /// Append an element to today's file without opening an editor
54    Append {
55        /// Element type: task, note, log, reminder (aliases from config are resolved)
56        kind: String,
57        /// Element body text
58        body: Vec<String>,
59        /// Comma-separated tags (e.g. work,backend)
60        #[arg(long)]
61        tags: Option<String>,
62        /// Task status: open (default) or done
63        #[arg(long)]
64        status: Option<String>,
65        /// Time for reminders (e.g. 5pm, 10:30)
66        #[arg(long)]
67        at: Option<String>,
68        /// Start time for logs (HH:MM)
69        #[arg(long)]
70        start_time: Option<String>,
71        /// End time for logs (HH:MM)
72        #[arg(long)]
73        end_time: Option<String>,
74        /// Person name for character entries
75        #[arg(short = 'n', long)]
76        name: Option<String>,
77    },
78
79    /// Update an element's attributes in-place
80    Update {
81        /// Element ref: human (task-1) or epoch (20260428.1)
82        ref_path: String,
83        /// Set task status: open or done
84        #[arg(long)]
85        status: Option<String>,
86        /// Set log start time (HH:MM)
87        #[arg(long = "start-time")]
88        start_time: Option<String>,
89        /// Set log end time (HH:MM)
90        #[arg(long = "end-time")]
91        end_time: Option<String>,
92        /// Set reminder time
93        #[arg(long)]
94        at: Option<String>,
95        /// Date context for human refs (default: today)
96        #[arg(short = 'd', long)]
97        date: Option<String>,
98    },
99
100    /// Mark a task as done (shorthand for update REFPATH --status done)
101    Done {
102        /// Element ref: human (task-1) or epoch (20260428.1)
103        ref_path: String,
104        /// Date context for human refs (default: today)
105        #[arg(short = 'd', long)]
106        date: Option<String>,
107    },
108
109    /// Full-text search across all .mps files
110    Search {
111        /// Search query
112        query: String,
113        /// Filter by element type
114        #[arg(short = 't', long)]
115        r#type: Option<String>,
116        /// Filter by tag
117        #[arg(short = 'g', long)]
118        tag: Option<String>,
119        /// Search from this date onward
120        #[arg(short = 'S', long)]
121        since: Option<String>,
122        /// Filter character entries by person name
123        #[arg(short = 'n', long)]
124        name: Option<String>,
125    },
126
127    /// Show element counts and log durations
128    Stats {
129        /// Date (default: today)
130        datesign: Option<String>,
131        /// Stats from SINCE up to DATESIGN
132        #[arg(short = 'S', long)]
133        since: Option<String>,
134        /// Stats across all dates in the archive
135        #[arg(short = 'a', long)]
136        all: bool,
137    },
138
139    /// Show tag usage frequency bar chart
140    Tags {
141        /// Date (default: today)
142        datesign: Option<String>,
143        /// Filter by element type
144        #[arg(short = 't', long)]
145        r#type: Option<String>,
146        /// Filter tasks by status
147        #[arg(short = 's', long)]
148        status: Option<String>,
149        /// Tags from SINCE up to DATESIGN
150        #[arg(short = 'S', long)]
151        since: Option<String>,
152        /// Count tags across all dates
153        #[arg(short = 'a', long)]
154        all: bool,
155        /// Filter character entries by person name
156        #[arg(short = 'n', long)]
157        name: Option<String>,
158    },
159
160    /// Export elements to JSON or CSV on stdout
161    Export {
162        /// Date (default: today)
163        datesign: Option<String>,
164        /// Output format: json (default), csv
165        #[arg(short = 'f', long, default_value = "json")]
166        format: String,
167        /// Filter by element type
168        #[arg(short = 't', long)]
169        r#type: Option<String>,
170        /// Export from SINCE up to DATESIGN
171        #[arg(short = 'S', long)]
172        since: Option<String>,
173    },
174
175    /// View or edit MPS configuration
176    Config {
177        /// Subcommand: show (default) or edit
178        subcommand: Option<String>,
179    },
180
181    /// Run git commands inside the storage directory
182    Git {
183        /// Git subcommand and args (auto = full cycle, autocommit = stage+commit)
184        #[arg(trailing_var_arg = true)]
185        args: Vec<String>,
186    },
187
188    /// Stage, commit, pull, and push (equivalent to git auto)
189    Autogit,
190
191    /// Run any shell command inside the storage directory
192    Cmd {
193        /// Command and arguments
194        #[arg(trailing_var_arg = true)]
195        args: Vec<String>,
196    },
197
198    /// Print version
199    Version,
200}