mps 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7f0d20f2919cb1ee0ae46a3fe6eaef005af856eabd4650fc5e6e07477b5e7fb3
4
+ data.tar.gz: 259a623e9ee4b8edea593ab16a270b11015a55e3e22564359a424610f0510caa
5
+ SHA512:
6
+ metadata.gz: 4653dca542034d736e5e61c69b2750c5ddb119c141876fac896b3f15e79d3d758f9e299a3ecf75fd17c52c5e7dbd8da9a562be228d760c6e4a7ba290359c83b0
7
+ data.tar.gz: 9cf8bf1273e814ed6708561c1f7cd5b82917e804b0e97e867d34c50bb2f35e762067f3df3493cb59eb4eea3ab0e5b1be9e02c38cbc7fffb43c9b9494c4790be3
@@ -0,0 +1,29 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ - release/*
8
+ pull_request:
9
+ branches:
10
+ - master
11
+ - dev
12
+ - release/*
13
+
14
+ jobs:
15
+ build:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: 3.0.2
23
+ - name: Run the default task
24
+ run: |
25
+ gem update --system
26
+ gem install bundler -v 2.2.13
27
+ bundle add rake
28
+ bundle install
29
+ bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.lock
10
+ *.mps
11
+ /vendor/
12
+ **/**/*.gem
13
+
data/CLAUDE.md ADDED
@@ -0,0 +1,102 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ MPS (MonoPsyches) is a Ruby gem — a plain-text personal productivity CLI. Users store tasks, notes, reminders, and logs in date-stamped `.mps` files (e.g. `20260226.1730000000.mps`) inside a configurable storage directory (`~/.mps/mps/` by default). Files are opened in Vim; git integration handles sync.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ bundle install
14
+
15
+ # Run all tests
16
+ bundle exec rake test:with_groups
17
+
18
+ # Run a single test file
19
+ bundle exec ruby -Itest -Ilib test/config_test.rb
20
+
21
+ # Run a single test by name
22
+ bundle exec ruby -Itest -Ilib test/config_test.rb -n test_name
23
+
24
+ # Build the gem
25
+ gem build mps.gemspec
26
+
27
+ # Run the CLI locally
28
+ bundle exec exe/mps
29
+ ```
30
+
31
+ ```bash
32
+ # List parsed elements from today's (or a given date's) file
33
+ bundle exec exe/mps list [DATESIGN] [--type task|note|log|reminder]
34
+
35
+ # Append a single element without opening Vim
36
+ bundle exec exe/mps append TYPE BODY [--tags work,release] [--at 3pm]
37
+
38
+ # Auto stage, commit, pull, and push inside storage_dir
39
+ bundle exec exe/mps autogit
40
+ ```
41
+
42
+ Set `MPS_DEBUG=true` to enable verbose `require_relative` tracing via the custom `ir()` loader.
43
+
44
+ ## Architecture
45
+
46
+ ### Entry point
47
+ `exe/mps` calls `MPS::CLI::MPS.start(ARGV)` — a Thor-based CLI defined in `lib/cli/mps.rb`. All commands (`open`, `git`, `autogit`, `list`, `append`, `cmd`, `version`) live there and delegate to the library layer.
48
+
49
+ ### Custom loader (`ir`)
50
+ `lib/mps/mps.rb` defines a global helper `ir(relative_path)` that wraps `require_relative` with caller-location resolution. All internal requires use `ir` instead of `require_relative`. This is intentional — don't replace it with standard requires.
51
+
52
+ ### Load order (`lib/mps.rb`)
53
+ ```
54
+ mps/version → mps/mps (defines ir + MPS module methods) →
55
+ mps/constants → mps/config → mps/interpolators → mps/elements → mps/engines → cli/mps
56
+ ```
57
+
58
+ ### Parsing pipeline (`lib/mps/engines/mps.rb`)
59
+ `Engines::MPS.parse_mps_file_to_elments_hash` reads an `.mps` file and uses `StringScanner` to tokenize it. It wraps the raw file contents in a synthetic `@mps[]{}` root element, then does a single-pass scan driven by two regexes from `Constants`: `AT_REGEXP_LA` (lookahead for `@element[args]{`) and `END_CURLY_REGEXP_LA` (lookahead for `}`). A stack tracks nesting; each closed element is instantiated and stored in a flat hash keyed by a dotted ref path (e.g. `"1234567890.1.2"`).
60
+
61
+ ### Elements (`lib/mps/elements/`)
62
+ Each element type (Task, Note, Reminder, Log, MPS) is a class that `include`s the `MPS::Element` mixin. The mixin provides `initialize(args:, refs:, body_str:)`, `display_str`, and `attr_reader :body_str`. Each class must define `SIGNATURE_STAMP` (used when generating filenames/wrapping) and `SIGNATURE_REGEX` (matched against the parsed element sign to dispatch). The engine discovers all element classes dynamically via `MPS::Elements.constants`.
63
+
64
+ ### Interpolators (`lib/mps/interpolators/`)
65
+ Interpolator classes (e.g. `Interpolators::Time`) are discovered the same way as elements — via `const_get` on the module's `constants`. Each defines `SIGNATURE_REGEX` and `get_str(**ref)`. They are loaded into `Engines::MPS` but the interpolation call-site is not yet wired up in the engine.
66
+
67
+ ### Configuration (`lib/mps/config.rb` + `lib/mps/constants.rb`)
68
+ `Config.init(path)` writes a default YAML config. `Config.new(**hash)` holds `storage_dir`, `mps_dir`, `log_file`, and a `Logger`. Two additional optional YAML keys are supported: `git_remote` (default `"origin"`) and `git_branch` (default `"master"`); both are exposed as `attr_reader`s and used by `git` and `autogit` commands. The CLI re-reads the config on every invocation via `load_config`; it auto-creates missing directories and the log file.
69
+
70
+ ## File format
71
+
72
+ ```
73
+ @task[tag1, tag2]{
74
+ Task body text
75
+ }
76
+
77
+ @note{
78
+ Free-form note
79
+ }
80
+
81
+ @reminder[at: 3pm]{
82
+ Meeting description
83
+ }
84
+
85
+ @log[start: 09:00, end: 12:30]{
86
+ Time log entry
87
+ }
88
+
89
+ @mps{
90
+ @task{ nested task }
91
+ }
92
+ ```
93
+
94
+ File names follow `YYYYMMDD.<epoch>.mps`; the epoch disambiguates multiple files per day. The regexp for valid names is `Constants::MPS_FILE_NAME_REGEXP`.
95
+
96
+ ## Testing
97
+
98
+ Tests use Minitest with `fakefs` for filesystem isolation. The test helper at `test/test_helper.rb` sets up the load path and does `include MPS`, so all constants and module methods are available directly in test classes.
99
+
100
+ `test/engine_test.rb` tests the parser directly: it uses a `parse_content(str)` helper that writes a fixture file under `FakeFS` at `/tmp/20260101.mps` and calls `Engines::MPS.parse_mps_file_to_elments_hash` on it. Covers empty files, single and multiple elements, unknown element fallback to `Struct`, nested `@mps{}`, `matched_element_class`, and `look_ahead_pos` edge cases.
101
+
102
+ `test/config_test.rb` covers `Config.init`, `Config.load_conf_hash` (including `git_remote`/`git_branch` defaults), logger formatting, and `LoadError` on missing keys.
@@ -0,0 +1,447 @@
1
+ # Getting Started with MPS
2
+
3
+ MPS is a plain-text productivity system that lives in your terminal. Your tasks, notes, reminders, and logs are just `.mps` files in a folder — readable, portable, and git-backed. No app to install, no account to create, no sync service to trust.
4
+
5
+ ---
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ gem install mps
11
+ ```
12
+
13
+ First run creates everything automatically:
14
+
15
+ ```
16
+ ~/.mps_config.yaml ← your config
17
+ ~/.mps/mps/ ← where your files live
18
+ ~/.mps/mps.log ← activity log
19
+ ```
20
+
21
+ ---
22
+
23
+ ## The file format
24
+
25
+ Before anything else, it helps to know what you're working with. Each `.mps` file is plain text. Every entry is an **element** — a type, optional arguments in `[]`, and a body in `{}`:
26
+
27
+ ```
28
+ @task[work, release]{
29
+ Ship the API refactor
30
+ }
31
+
32
+ @note{
33
+ The auth token expiry edge case needs a second look
34
+ }
35
+
36
+ @reminder[at: 10am]{
37
+ Team standup
38
+ }
39
+
40
+ @log[start: 09:00, end: 12:30]{
41
+ Debugging the auth flow
42
+ }
43
+
44
+ @mps{
45
+ @task[backend]{
46
+ Nested task inside a sub-block
47
+ }
48
+ }
49
+ ```
50
+
51
+ The brackets are optional — `@task{ body }` is perfectly valid. Elements nest freely. Files are named `YYYYMMDD.<epoch>.mps` — the epoch allows multiple files per day without collision.
52
+
53
+ ---
54
+
55
+ ## A day in the life
56
+
57
+ It's Monday morning. You open your terminal:
58
+
59
+ ```bash
60
+ mps
61
+ ```
62
+
63
+ Vim opens with today's file — `20260428.1745000000.mps`. You write your morning plan, save, and quit. That's your day started.
64
+
65
+ If you want a specific date instead:
66
+
67
+ ```bash
68
+ mps open yesterday
69
+ mps open "last monday"
70
+ mps open 20260421
71
+ mps open "2 days ago"
72
+ ```
73
+
74
+ Natural language dates work everywhere in MPS, powered by [Chronic](https://github.com/mojombo/chronic). Anything Chronic understands, MPS understands.
75
+
76
+ ---
77
+
78
+ ## Reading what you wrote
79
+
80
+ You're two hours into the day and forget whether you wrote down that reminder. Don't open Vim — just ask:
81
+
82
+ ```bash
83
+ mps list
84
+ ```
85
+
86
+ ```
87
+ [task] (open) Review the API pull request [work]
88
+ [reminder] (10am) Team standup
89
+ [note] The auth token expiry edge case needs a second look
90
+ [@mps]
91
+ [task] (open) Nested backend task [backend]
92
+ ```
93
+
94
+ The nested tree is preserved — child elements appear indented under their parent `[@mps]` group. Each type gets its own color in the terminal.
95
+
96
+ ### Filter by type
97
+
98
+ Only want tasks?
99
+
100
+ ```bash
101
+ mps list --type task
102
+ # short form:
103
+ mps list -t task
104
+ ```
105
+
106
+ ### Filter by tag
107
+
108
+ Everything tagged `work`:
109
+
110
+ ```bash
111
+ mps list --tag work
112
+ mps list -g work
113
+ ```
114
+
115
+ ### Filter by status (tasks only)
116
+
117
+ See only what's still open:
118
+
119
+ ```bash
120
+ mps list --status open
121
+ mps list -s done
122
+ ```
123
+
124
+ Status filtering only applies to tasks — notes, logs, and reminders are excluded when you use `--status`.
125
+
126
+ ### Look at a different day
127
+
128
+ ```bash
129
+ mps list yesterday
130
+ mps list "last friday"
131
+ mps list 20260421
132
+ ```
133
+
134
+ ### Date ranges with `--since`
135
+
136
+ Want everything from the last week up to today?
137
+
138
+ ```bash
139
+ mps list --since "last monday"
140
+ ```
141
+
142
+ This prints a date header for each day that has entries:
143
+
144
+ ```
145
+ ── 2026-04-25 ─────────────
146
+ [task] (done) Set up CI pipeline [devops]
147
+ ── 2026-04-28 ─────────────
148
+ [task] (open) Review the API pull request [work]
149
+ [note] Token expiry edge case
150
+ ```
151
+
152
+ Combine filters freely: `mps list --since yesterday --type task --status open` shows all open tasks from yesterday to today.
153
+
154
+ ---
155
+
156
+ ## Quick-capture without opening Vim
157
+
158
+ You're deep in a debugging session. A thought hits you. You don't want to break your flow:
159
+
160
+ ```bash
161
+ mps append note "Check if the race condition only happens under load"
162
+ ```
163
+
164
+ ```
165
+ appended [note] Check if the race condition only happens under load
166
+ ```
167
+
168
+ The note lands at the bottom of today's file.
169
+
170
+ ### Append with tags
171
+
172
+ ```bash
173
+ mps append task "Fix the token expiry bug" --tags work,backend
174
+ ```
175
+
176
+ ### Append a task with status
177
+
178
+ Already done? Mark it immediately:
179
+
180
+ ```bash
181
+ mps append task "Reviewed the PR" --tags work --status done
182
+ ```
183
+
184
+ ### Log your time
185
+
186
+ Log a focused work session with start and end times:
187
+
188
+ ```bash
189
+ mps append log "Deep work on auth refactor" --tags work --start-time 09:00 --end-time 12:30
190
+ ```
191
+
192
+ The 3h30m duration is computed automatically and shown in `list`, `stats`, and `export`.
193
+
194
+ ### Set a timed reminder
195
+
196
+ ```bash
197
+ mps append reminder "Push the hotfix before EOD" --at "5pm"
198
+ ```
199
+
200
+ All types supported by `append`: `task`, `note`, `log`, `reminder`.
201
+
202
+ ---
203
+
204
+ ## Search across all your files
205
+
206
+ End of quarter. You vaguely remember logging something about "auth" in March. You don't know which file.
207
+
208
+ ```bash
209
+ mps search "auth"
210
+ ```
211
+
212
+ ```
213
+ 2026-04-28 [log] (3h30m) Debugging the auth flow [work, backend]
214
+ 2026-04-21 [task] (done) Fix auth token expiry [backend]
215
+ (2 results)
216
+ ```
217
+
218
+ Every `.mps` file in your storage directory is searched. Results show the date, type badge, and first line of the body.
219
+
220
+ ### Narrow the search
221
+
222
+ Filter to a specific type:
223
+
224
+ ```bash
225
+ mps search "auth" --type log
226
+ mps search "auth" -t task
227
+ ```
228
+
229
+ Filter to a tag:
230
+
231
+ ```bash
232
+ mps search "auth" --tag backend
233
+ mps search "auth" -g work
234
+ ```
235
+
236
+ Limit to recent files:
237
+
238
+ ```bash
239
+ mps search "auth" --since "last month"
240
+ mps search "auth" -S "2026-04-01"
241
+ ```
242
+
243
+ All filters compose: `mps search "auth" --type task --tag backend --since "last week"`.
244
+
245
+ ---
246
+
247
+ ## Your productivity at a glance
248
+
249
+ Friday afternoon. How did your week go?
250
+
251
+ ```bash
252
+ mps stats --since monday
253
+ ```
254
+
255
+ ```
256
+ 2026-04-25 — 2 tasks (1 open, 1 done), 1 note, 1 log (2h)
257
+ 2026-04-26 — 1 task (0 open, 1 done), 2 logs (5h30m)
258
+ 2026-04-28 — 3 tasks (2 open, 1 done), 1 note, 1 reminder, 1 log (3h30m)
259
+ ────────────────────────────────────────────────
260
+ Total: 6 tasks, 3 notes, 1 reminder, 3 logs (11h total)
261
+ ```
262
+
263
+ Open vs done task counts, total logged hours, everything in one view.
264
+
265
+ For a single day:
266
+
267
+ ```bash
268
+ mps stats
269
+ mps stats yesterday
270
+ mps stats 20260421
271
+ ```
272
+
273
+ ---
274
+
275
+ ## Export your data
276
+
277
+ Need to feed your `.mps` data into a spreadsheet, script, or another tool?
278
+
279
+ ```bash
280
+ mps export --format json
281
+ ```
282
+
283
+ ```json
284
+ [
285
+ {
286
+ "date": "2026-04-28",
287
+ "ref": "1745000000.1",
288
+ "type": "task",
289
+ "tags": "work",
290
+ "body": "Review the API pull request",
291
+ "status": "open"
292
+ },
293
+ ...
294
+ ]
295
+ ```
296
+
297
+ CSV format:
298
+
299
+ ```bash
300
+ mps export --format csv
301
+ ```
302
+
303
+ ```
304
+ date,ref,type,tags,body,status,at,start,end
305
+ 2026-04-28,1745000000.1,task,work,Review the API pull request,open,,,
306
+ 2026-04-28,1745000000.2,reminder,,Team standup,,10am,,
307
+ ```
308
+
309
+ All the same filters apply:
310
+
311
+ ```bash
312
+ # Export all tasks this week
313
+ mps export --since monday --type task --format csv > this_week_tasks.csv
314
+
315
+ # Export everything from a specific day as JSON
316
+ mps export 20260421 --format json > april21.json
317
+
318
+ # Pipe into jq
319
+ mps export --since "last month" --format json | jq '[.[] | select(.status == "done")]'
320
+ ```
321
+
322
+ ---
323
+
324
+ ## Git backup — one command
325
+
326
+ Your files live in `~/.mps/mps/`. Initialize that directory as a git repo once, then let MPS handle sync:
327
+
328
+ ```bash
329
+ mps autogit
330
+ ```
331
+
332
+ This does: `git add .` → `git commit -m "$(date)"` → `git pull` → `git push`. Run it at the end of each day.
333
+
334
+ For manual control:
335
+
336
+ ```bash
337
+ mps git status
338
+ mps git log --oneline -5
339
+ mps git commit -m "end of sprint retrospective"
340
+ mps git auto # same as autogit
341
+ mps git autocommit # stage and commit only, no push
342
+ ```
343
+
344
+ Every `mps git` command runs inside your storage directory — no `cd` needed.
345
+
346
+ ### Configure your remote and branch
347
+
348
+ By default MPS pushes to `origin` on `master`. To use a different remote or branch, edit `~/.mps_config.yaml`:
349
+
350
+ ```yaml
351
+ mps_dir: /home/you/.mps
352
+ storage_dir: /home/you/.mps/mps
353
+ log_file: /home/you/.mps/mps.log
354
+ git_remote: origin
355
+ git_branch: main
356
+ ```
357
+
358
+ ---
359
+
360
+ ## Run any shell command in your storage directory
361
+
362
+ Need to see what files exist, or grep across everything raw?
363
+
364
+ ```bash
365
+ mps cmd ls -la
366
+ mps cmd grep -r "token expiry" .
367
+ mps cmd wc -l *.mps
368
+ ```
369
+
370
+ Everything runs inside `~/.mps/mps/`.
371
+
372
+ ---
373
+
374
+ ## Version
375
+
376
+ ```bash
377
+ mps version
378
+ ```
379
+
380
+ ---
381
+
382
+ ## Full reference
383
+
384
+ ### Commands
385
+
386
+ | Command | What it does |
387
+ |---------|-------------|
388
+ | `mps` / `mps open [date]` | Open a date's file in Vim (default: today) |
389
+ | `mps list [date]` | Print elements in tree order (default: today) |
390
+ | `mps append TYPE BODY` | Add one element to today's file without Vim |
391
+ | `mps search QUERY` | Full-text search across all files |
392
+ | `mps stats [date]` | Element counts and log durations for a date |
393
+ | `mps export [date]` | Export elements as JSON or CSV to stdout |
394
+ | `mps autogit` | Stage, commit, pull, push in one shot |
395
+ | `mps git ARGS` | Run any git command inside storage dir |
396
+ | `mps cmd ARGS` | Run any shell command inside storage dir |
397
+ | `mps version` | Print current version |
398
+
399
+ ### list options
400
+
401
+ | Option | Short | Description |
402
+ |--------|-------|-------------|
403
+ | `--type TYPE` | `-t` | Filter by: `task`, `note`, `log`, `reminder` |
404
+ | `--tag TAG` | `-g` | Filter by tag name |
405
+ | `--status STATUS` | `-s` | Filter tasks by: `open`, `done` |
406
+ | `--since DATESIGN` | `-S` | Show elements from SINCE up to DATESIGN |
407
+
408
+ ### append options
409
+
410
+ | Option | Description |
411
+ |--------|-------------|
412
+ | `--tags t1,t2` | Comma-separated tags |
413
+ | `--status open\|done` | Task status (default: open) |
414
+ | `--at TIME` | Time for reminders (e.g. `5pm`) |
415
+ | `--start-time HH:MM` | Start time for logs |
416
+ | `--end-time HH:MM` | End time for logs |
417
+
418
+ ### search options
419
+
420
+ | Option | Short | Description |
421
+ |--------|-------|-------------|
422
+ | `--type TYPE` | `-t` | Filter by element type |
423
+ | `--tag TAG` | `-g` | Filter by tag |
424
+ | `--since DATESIGN` | `-S` | Search from this date onward |
425
+
426
+ ### stats options
427
+
428
+ | Option | Short | Description |
429
+ |--------|-------|-------------|
430
+ | `--since DATESIGN` | `-S` | Stats from SINCE up to DATESIGN |
431
+
432
+ ### export options
433
+
434
+ | Option | Short | Description |
435
+ |--------|-------|-------------|
436
+ | `--format FORMAT` | `-f` | Output format: `json` (default), `csv` |
437
+ | `--type TYPE` | `-t` | Filter by element type |
438
+ | `--since DATESIGN` | `-S` | Export from SINCE up to DATESIGN |
439
+
440
+ ### Date formats accepted everywhere
441
+
442
+ | Input | Meaning |
443
+ |-------|---------|
444
+ | `today`, `yesterday` | Relative day |
445
+ | `monday`, `last friday` | Day of week |
446
+ | `2 days ago`, `last week` | Natural language |
447
+ | `20260421` | Explicit YYYYMMDD |
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in mps.gemspec
6
+ gemspec
data/IMPROVEMENTS.md ADDED
@@ -0,0 +1,90 @@
1
+ # MPS Improvements & Feature Roadmap
2
+
3
+ ## Bugs
4
+
5
+ | # | File | Issue | Severity |
6
+ |---|------|-------|----------|
7
+ | B1 | `lib/mps/elements/*.rb` | `# frozen string_literal: true` missing the `_` — magic comment is silently ignored | Medium |
8
+ | B2 | `lib/cli/mps.rb:61` | `git pull orign master` — typo `orign` instead of `origin` | High |
9
+ | B3 | `lib/mps/engines/mps.rb:12` | Uses `eval("::MPS::Elements::#{k}")` — unsafe; use `const_get` | Medium |
10
+ | B4 | `test/config_test.rb` | All test bodies are commented out — zero test coverage on Config | High |
11
+ | B5 | `lib/mps/interpolators/` | Interpolators are loaded into `Engines::MPS` but never invoked anywhere | Medium |
12
+
13
+ ## Code Quality
14
+
15
+ | # | Issue | Fix |
16
+ |---|-------|-----|
17
+ | Q1 | `ir()` is defined as a bare global method in `lib/mps/mps.rb` — pollutes `Object` | Move inside `MPS` module as `MPS.ir` or keep but at least document it |
18
+ | Q2 | Element classes are identical boilerplate — only `SIGNATURE_STAMP` / `SIGNATURE_REGEX` differ | Extract a `MPS::Elements.define(stamp)` factory or use a shared DSL |
19
+ | Q3 | `Engines::MPS` class name clashes with `Elements::MPS` class — confusing namespace | Rename engine to `Engines::Parser` |
20
+ | Q4 | `Exception` is rescued in every CLI command instead of `StandardError` — catches `SignalException`, `SystemExit` | Use `StandardError` |
21
+ | Q5 | Config is re-read on every CLI invocation but never cached or validated beyond key presence | Add type-checked struct |
22
+
23
+ ## New Features
24
+
25
+ ### F1 — `list` command
26
+ Display parsed elements from any `.mps` file in the terminal, with optional type filter.
27
+
28
+ ```
29
+ mps list # today's file
30
+ mps list yesterday # yesterday's file
31
+ mps list 20260226 --type task
32
+ ```
33
+
34
+ ### F2 — `search` command
35
+ Full-text search across all `.mps` files in storage, return matching elements.
36
+
37
+ ```
38
+ mps search "meeting"
39
+ mps search "deploy" --type task --since 7.days.ago
40
+ ```
41
+
42
+ ### F3 — `stats` command
43
+ Print a summary of element counts per type for a date (or range).
44
+
45
+ ```
46
+ mps stats # today
47
+ mps stats --since last.week
48
+ ```
49
+
50
+ ### F4 — `append` command (non-Vim fast entry)
51
+ Append a single element to today's file without opening Vim.
52
+
53
+ ```
54
+ mps append task "Write release notes" --tags work,release
55
+ mps append note "Idea: dark mode"
56
+ mps append reminder "Standup" --at "9am"
57
+ ```
58
+
59
+ ### F5 — Typed element attribute parsing
60
+ Currently `@log[start: 09:00, end: 12:30]` args are raw strings. Parse them into typed structs so `list`/`stats` can compute duration, countdown to reminder time, etc.
61
+
62
+ ### F6 — Export command
63
+ Serialize parsed elements to JSON or CSV.
64
+
65
+ ```
66
+ mps export --format json > today.json
67
+ mps export --format csv --since last.week > week.csv
68
+ ```
69
+
70
+ ### F7 — Configurable branch / remote for git sync
71
+ `git auto` hardcodes `master` and `origin`. Make both configurable in `~/.mps_config.yaml`.
72
+
73
+ ```yaml
74
+ git_remote: origin
75
+ git_branch: main
76
+ ```
77
+
78
+ ## Implementation Priority
79
+
80
+ 1. **B1, B2, B3** — straightforward, low-risk fixes
81
+ 2. **Q4** — safety (rescue `StandardError` not `Exception`)
82
+ 3. **B4** — restore test coverage (Config + Engine parser)
83
+ 4. **F1 `list`** — most immediately useful, builds on existing parser
84
+ 5. **F4 `append`** — second most useful daily-driver feature
85
+ 6. **F7 git config** — removes hardcoded branch/remote
86
+ 7. **Q3 rename engine** — minor breaking internal rename
87
+ 8. **F5 typed args** — enables F1/F3 to show richer output
88
+ 9. **F2 `search`** — builds on F1 infrastructure
89
+ 10. **F3 `stats`** — builds on F2
90
+ 11. **F6 `export`** — nice-to-have