# mps-rs
Production Rust rewrite of [MPS (MonoPsyches)](https://github.com/mash-97/mps) — a plain-text personal productivity CLI. Single binary, no runtime dependency, backward-compatible with all Ruby-generated `.mps` files and config.
## Install
### From local source (recommended during development)
```bash
git clone https://github.com/mash-97/mps-rs
cd mps-rs
cargo install --path .
```
> **Do not** run `cargo install mps` — there is an unrelated crate by that name on crates.io.
### Build release binary manually
```bash
cargo build --release
# binary at: target/release/mps
cp target/release/mps ~/.local/bin/mps # or any directory on $PATH
```
## Quick start
```bash
mps # open today's file in $EDITOR
mps list # print today's elements
mps list --since monday # all elements from last Monday
mps append task "Fix auth bug" --tags work,backend
mps search "auth" --since "last week"
mps stats --since monday
mps export --format csv --since "20260501" > may.csv
mps autogit # stage + commit + pull + push
```
## Commands
| `mps [open] [DATE]` | Open date's file in `$EDITOR` (default: today) |
| `mps list [DATE]` | Print elements as indented tree |
| `mps append TYPE BODY` | Append one element without opening editor |
| `mps search QUERY` | Full-text search across all `.mps` files |
| `mps stats [DATE]` | Element counts and log durations |
| `mps export [DATE]` | JSON or CSV to stdout |
| `mps autogit` | Stage, commit, pull, push |
| `mps git ARGS` | Any git command inside storage dir |
| `mps cmd ARGS` | Any shell command inside storage dir |
| `mps version` | Print version |
### list flags
| `--type TYPE` | `-t` | Filter: `task`, `note`, `log`, `reminder` |
| `--tag TAG` | `-g` | Filter by tag name |
| `--status STATUS` | `-s` | Filter tasks by `open` or `done` (excludes all other types) |
| `--since DATE` | `-S` | Show elements from DATE up to target date |
### append flags
| `--tags t1,t2` | Comma-separated tags |
| `--status open\|done` | Task status (default: open) |
| `--at TIME` | Time for reminders (e.g. `5pm`) |
| `--start-time HH:MM` | Start time for logs |
| `--end-time HH:MM` | End time for logs |
### search / stats / export flags
| `--type TYPE` | `-t` | Filter by element type |
| `--tag TAG` | `-g` | Filter by tag (search only) |
| `--since DATE` | `-S` | Date range lower bound |
| `--format json\|csv` | `-f` | Export format (default: json) |
### Date formats accepted everywhere
| `today`, `yesterday` | Relative day |
| `monday` … `sunday` | Last occurrence of weekday |
| `last friday` | Explicit "last" weekday |
| `3 days ago` | N days before today |
| `last week` | 7 days ago |
| `20260421` | Explicit YYYYMMDD |
| `2026-04-21` | Explicit YYYY-MM-DD |
## File format
Same as the Ruby gem — fully compatible:
```
@task[work, release, status: done]{
Ship the API refactor
}
@note{
The auth token expiry edge case
}
@reminder[at: 5pm]{
Team standup
}
@log[work, start: 09:00, end: 12:30]{
Debugging the auth flow
}
@mps{
@task[backend]{
Nested task inside a sub-block
}
}
```
Brackets are optional — `@task{ body }` is valid. Files are named `YYYYMMDD.<epoch>.mps`.
## Configuration
Reads `~/.mps_config.yaml` (same file the Ruby gem writes — no migration needed):
```yaml
mps_dir: /home/you/.mps
storage_dir: /home/you/.mps/mps
log_file: /home/you/.mps/mps.log
git_remote: origin
git_branch: master
```
Created automatically on first run if absent.
## Architecture
```
src/
main.rs entry point + clap dispatch
cli.rs Cli struct + Commands enum (#[derive(Parser)])
config.rs Config struct; YAML load/init; handles Ruby symbol-key YAML
constants.rs file-name regexes, new_file_name()
date_parse.rs parse_date() — natural-language dates, no external crate
error.rs MpsError enum (thiserror)
parser.rs position-based stack parser; mirrors Ruby Engines::Parser
store.rs Store — all file-system operations
elements/ Element enum (Task/Note/Log/Reminder/MpsGroup/Unknown)
commands/ one file per command + shared display helpers
```
See [DESIGN_RUST.md](../mps/DESIGN_RUST.md) in the Ruby project for the full architecture rationale.
## Development
```bash
cargo build # debug build
cargo build --release # optimized (~4MB binary)
cargo test # 36 unit tests
cargo doc --open # API docs in browser
```
## Requirements
- Rust 1.70+ (uses `std::sync::OnceLock`)
- Git (for `git` / `autogit`)
- `$EDITOR` or `vim` (for `open`)
## License
MIT