Releases: 83noit/remtodo
v1.3.0
See CHANGELOG.md for details.
What's new
time: tag ↔ Apple Reminders due-time sync
The TTDL agenda tag time:HHMM is now synced with the dueDateComponents.hour/minute field on Apple Reminders.
- Accepts both 4-digit (
time:0930) and TTDL's 3-digit shorthand (time:900); normalises to 4-digit HHMM - Preserves end-time duration when start time changes:
time:0900-1030+ new start1000→time:1000-1130 - Follows the same
writeback.due_dateconfig flag as due date
v1.2.0
See CHANGELOG.md for details.
v1.1.2
v1.1.1
What's new
Added
remtodo --version/-V/version— print the version string and exit.
Fixed
-
Orphan
eid:tags after Triage release: whensticky_tracking = "triage"released a task, the state entry was removed but theeid:tag was left on the task in todo.txt, producing averify_post_sync"no state entry" warning on every subsequent sync. The fix stripseid:at release time; a one-time cleanup pass also heals tasks left in this state by the v1.1.0 run. -
Hash mismatch warnings for untracked field changes: editing an untracked field — adding/removing a context, project,
rec:tag, or any other custom tag — produced averify_post_sync"hash mismatch" warning every cycle, and could cause an incorrectResurrectReminderinstead ofDeleteTaskin Case B. A hash-reconciliation pass now keeps the stored hash accurate.
See CHANGELOG.md for full details.
v1.1.0
What's changed
Changed — sticky tracking mode "auto" → "triage"
The old auto mode distinguished between push-origin and pull-origin tasks. Pull-origin tasks (created in Reminders, pulled into todo.txt) would only be released from Reminders if another configured list admitted them after an edit — which meant reminders persisted indefinitely for the common inbox workflow:
Reminders → todo.txt → prioritise/edit in todo.txt → filter governs
The new triage mode uses a simpler rule: any edit to a task in todo.txt is the triage signal. Once edited, the push filter is authoritative. Unedited tasks retain inbox protection regardless of origin.
Migration: replace sticky_tracking = "auto" with sticky_tracking = "triage" in your config.toml. The value "auto" is now a parse error.
Fixed — recurring tasks no longer inherit parent eid:
The spawned next instance of a recurring task was silently inheriting the parent task's eid: tag because todo_lib's cleanup_cloned_task() does not strip it. This caused the completed parent and the new instance to share the same EID, which verify_post_sync reported as a duplicate-EID warning on every subsequent sync cycle.
Full changelog
See CHANGELOG.md.
v1.0.1
v1.0.0 — initial public release
Changelog
All notable changes to this project will be documented in this file.
Format follows Keep a Changelog.
[1.0.0] - 2026-02-28
Initial public release.
Sync engine
- Bidirectional sync between Apple Reminders and todo.txt via a three-way
diff against persisted state (state.json) - Last-write-wins (LWW) conflict resolution per field, with configurable
timestamp tolerance (timestamp_tolerance_secs) to absorb iCloud rounding - Hash-based change detection on both sides (no spurious updates)
- Bootstrap reconciliation by title + due date on first sync, so existing
tasks and reminders are linked without duplication - EID relinking: detects iCloud external-identifier reassignment and
re-links by content hash instead of treating it as delete + create - Recurrence: EventKit recurrence rules ignored on import; TTDL manages
rec:recurrence locally andremtodopropagates completions
Sentinel eid: values
Three reserved tags let tasks opt out of sync or trigger ejection:
eid:na— permanent local opt-out, never pushed to Reminderseid:na/<orig>— eject a synced reminder and keep task localeid:ns/<orig>— eject a synced reminder and resume normal rules
Configuration
- Per-list sync configuration:
auto_context,push_filter,sticky_tracking - Configurable priority mapping: Reminders integers →
context:NAME,
priority:A–Z, ornone(default: priority 9 →@today) - Per-field writeback control: set
falseto make todo.txt authoritative
fortitle,due_date,priority, oris_completed - Sticky tracking modes:
auto(origin-aware release),always,never
Safety guards
- Bulk-delete threshold: aborts if more than
max_delete_percent(default 50%)
of tracked reminders would be deleted in one cycle - First-sync protection: no deletions on the first sync for a list
- Task-count coherence check: aborts if the output file shrinks unexpectedly
- Post-sync consistency verification: detects duplicate EIDs and hash mismatches
Operations
remtodo sync— one-shot sync with optional--dry-runand--configremtodo restore— reverts Reminders mutations and restores todo.txt +
state.json from pre-sync backupsremtodo install/status/uninstall— launchd agent management- Lock file (PID-based) prevents concurrent sync runs
- Graceful SIGINT/SIGTERM handling with per-list rollback
Infrastructure
- Swift EventKit helper (
reminders-helper) with batch create/update/delete make installbuilds the Rust binary insidenix developand copies both
binaries to~/.local/bin; Swift must be pre-built outsidenix develop- nix flake dev environment (
nix develop) - GitHub Actions CI:
cargo fmt,cargo clippy,cargo test,swift build - Dependabot for Cargo and GitHub Actions updates