|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to this project will be documented in this file. |
| 4 | +Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). |
| 5 | + |
| 6 | +## [1.0.0] - 2026-02-28 |
| 7 | + |
| 8 | +Initial public release. |
| 9 | + |
| 10 | +### Sync engine |
| 11 | + |
| 12 | +- Bidirectional sync between Apple Reminders and todo.txt via a three-way |
| 13 | + diff against persisted state (`state.json`) |
| 14 | +- Last-write-wins (LWW) conflict resolution per field, with configurable |
| 15 | + timestamp tolerance (`timestamp_tolerance_secs`) to absorb iCloud rounding |
| 16 | +- Hash-based change detection on both sides (no spurious updates) |
| 17 | +- Bootstrap reconciliation by title + due date on first sync, so existing |
| 18 | + tasks and reminders are linked without duplication |
| 19 | +- EID relinking: detects iCloud external-identifier reassignment and |
| 20 | + re-links by content hash instead of treating it as delete + create |
| 21 | +- Recurrence: EventKit recurrence rules ignored on import; TTDL manages |
| 22 | + `rec:` recurrence locally and `remtodo` propagates completions |
| 23 | + |
| 24 | +### Sentinel `eid:` values |
| 25 | + |
| 26 | +Three reserved tags let tasks opt out of sync or trigger ejection: |
| 27 | + |
| 28 | +- `eid:na` — permanent local opt-out, never pushed to Reminders |
| 29 | +- `eid:na/<orig>` — eject a synced reminder and keep task local |
| 30 | +- `eid:ns/<orig>` — eject a synced reminder and resume normal rules |
| 31 | + |
| 32 | +### Configuration |
| 33 | + |
| 34 | +- Per-list sync configuration: `auto_context`, `push_filter`, `sticky_tracking` |
| 35 | +- Configurable priority mapping: Reminders integers → `context:NAME`, |
| 36 | + `priority:A`–`Z`, or `none` (default: priority 9 → `@today`) |
| 37 | +- Per-field writeback control: set `false` to make todo.txt authoritative |
| 38 | + for `title`, `due_date`, `priority`, or `is_completed` |
| 39 | +- Sticky tracking modes: `auto` (origin-aware release), `always`, `never` |
| 40 | + |
| 41 | +### Safety guards |
| 42 | + |
| 43 | +- Bulk-delete threshold: aborts if more than `max_delete_percent` (default 50%) |
| 44 | + of tracked reminders would be deleted in one cycle |
| 45 | +- First-sync protection: no deletions on the first sync for a list |
| 46 | +- Task-count coherence check: aborts if the output file shrinks unexpectedly |
| 47 | +- Post-sync consistency verification: detects duplicate EIDs and hash mismatches |
| 48 | + |
| 49 | +### Operations |
| 50 | + |
| 51 | +- `remtodo sync` — one-shot sync with optional `--dry-run` and `--config` |
| 52 | +- `remtodo restore` — reverts Reminders mutations and restores todo.txt + |
| 53 | + state.json from pre-sync backups |
| 54 | +- `remtodo install` / `status` / `uninstall` — launchd agent management |
| 55 | +- Lock file (PID-based) prevents concurrent sync runs |
| 56 | +- Graceful SIGINT/SIGTERM handling with per-list rollback |
| 57 | + |
| 58 | +### Infrastructure |
| 59 | + |
| 60 | +- Swift EventKit helper (`reminders-helper`) with batch create/update/delete |
| 61 | +- `make install` builds the Rust binary inside `nix develop` and copies both |
| 62 | + binaries to `~/.local/bin`; Swift must be pre-built outside `nix develop` |
| 63 | +- nix flake dev environment (`nix develop`) |
| 64 | +- GitHub Actions CI: `cargo fmt`, `cargo clippy`, `cargo test`, `swift build` |
| 65 | +- Dependabot for Cargo and GitHub Actions updates |
0 commit comments