Skip to content

Add recurring reminders (--repeat) and hasRecurrence/nextDueDate JSON fields - #4

Merged
udondan merged 4 commits into
mainfrom
worktree-feat-recurring-reminders
Sep 13, 2026
Merged

udondan merged 4 commits into
mainfrom
worktree-feat-recurring-reminders

Conversation

@udondan

@udondan udondan commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Summary

Ports recurring-reminder support from two still-open upstream PRs on keith/reminders-cli, and adds two additional fields to make the JSON output easier to consume from scripts.

  • Cherry-picked from keith/reminders-cli#109 by @rameshbaskaran and keith/reminders-cli#110 by @morozovpersonal (#110 reapplies #109's commit on top of newer upstream main, then adds two more commits making end-date edits safe). Original authorship is preserved via git cherry-pick; commit messages were reworded to this repo's conventional-commits style.
    • add/edit: --repeat daily|weekly|monthly|yearly, --repeat-interval N, --repeat-until <date>, --clear-repeat-end, --clear-repeat.
    • recurrence, recurrenceInterval, recurrenceEnd/recurrenceCount in JSON and plain output for show/show-all (verified end-to-end; no extra wiring was needed since both already go through the shared formatting/encoding used by add/edit).
  • New in this PR (on top of the ported work):
    • hasRecurrence: true|false — always present as a boolean in JSON, so scripts don't need to check for a missing/null field.
    • nextDueDate — EventKit doesn't advance a repeating EKReminder's dueDateComponents as occurrences pass (confirmed against real Reminders.app data; not otherwise documented by Apple), so the due date can end up arbitrarily overdue. nextDueDate computes the next actionable occurrence by stepping the rule's frequency/interval forward, honoring --repeat-until/occurrence-count ends. Only populated for the plain daily/weekly/monthly/yearly rules this CLI itself creates/edits; omitted for rules with EventKit-native complex selectors it doesn't construct.
    • README documents both the new fields and the due-date behavior.
    • Unit tests for hasRecurrence and nextOccurrence/nextDueDate (stepping, interval > 1, recurrenceEnd date/count bounds, nil for complex selectors).

Test plan

  • swift build -Xswiftc -warnings-as-errors — clean
  • swift test -Xswiftc -warnings-as-errors — 52/52 passing
  • Manual smoke test against real Reminders.app: add --repeat weekly, show/show-all in plain and JSON, confirmed hasRecurrence/nextDueDate/recurrence/recurrenceInterval appear correctly for a recurring reminder and hasRecurrence: false with no nextDueDate for a plain one; scratch reminders deleted afterward

rameshbaskaran and others added 4 commits September 13, 2026 12:45
Implements EKRecurrenceRule-backed recurrence:

- `reminders add <list> <reminder> --repeat daily|weekly|monthly|yearly`
- `--repeat-interval N` to repeat every N units instead of every 1
  (default 1), e.g. `--repeat-interval 2 --repeat weekly` for
  fortnightly.
- `--repeat-until <date>` to set a recurrence end date; omitting it
  repeats forever, matching Reminders.app's own default.
- `reminders edit <list> <index> --repeat ...` replaces an existing
  repeat rule; `--clear-repeat` removes it entirely.
- JSON output (`--format json`) now includes `recurrence`,
  `recurrenceInterval`, and `recurrenceEnd` fields when a reminder has
  a recurrence rule.

`hourly` is intentionally rejected with a clear validation error
rather than silently degrading to a daily rule: EventKit's
`EKRecurrenceFrequency` has no hourly case (Reminders.app's own UI
doesn't expose hourly repeat either), so there's no faithful way to
represent it via `EKRecurrenceRule`.

Ported from keith/reminders-cli#109, authored by Ramesh Baskaran.
Adds `edit --repeat-until <date>` and `--clear-repeat-end` so a
reminder's recurrence end condition can be changed on its own,
without needing to also respecify the frequency. An end-only edit
copies the existing EventKit recurrence rule and only changes its
end, preserving interval and any complex selectors instead of
rebuilding a plain rule from scratch. Also validates that a repeating
reminder always has a due date, and that the recurrence end can't be
earlier than it.

Ported from keith/reminders-cli#110, authored by Aleksei Morozov.
The previous end-only edit path rebuilt the recurrence rule via the
public EKRecurrenceRule initializer, which drops provider-specific
metadata such as calendarIdentifier and firstDayOfTheWeek. Copy the
existing rule instead and only mutate its recurrenceEnd, so an
end-only edit is fully transparent to everything else about the rule.

Ported from keith/reminders-cli#110, authored by Aleksei Morozov.
EventKit doesn't advance dueDateComponents on a repeating EKReminder as
occurrences pass, so a recurring reminder's due date can end up
arbitrarily overdue rather than reflecting the next actionable
occurrence (observed directly against Reminders.app; documented in the
README since Apple doesn't cover this behavior).

hasRecurrence is now always encoded as a boolean so scripts don't have
to check for a missing or null field. nextDueDate steps the recurrence
rule's frequency/interval forward from its due date, honoring
--repeat-until/occurrence-count ends, and is only populated for the
plain daily/weekly/monthly/yearly rules this CLI itself creates and
edits.

Extends the recurrence support ported from keith/reminders-cli#109 and
#110.

Co-authored-by: Ramesh Baskaran <ramesh.baskaran@gmail.com>
Co-authored-by: Aleksei Morozov <246998741+morozovpersonal@users.noreply.github.com>
@udondan
udondan merged commit ce563d9 into main Sep 13, 2026
@udondan
udondan deleted the worktree-feat-recurring-reminders branch September 13, 2026 14:32
udondan added a commit that referenced this pull request Sep 13, 2026
Add recurring reminders (--repeat) and hasRecurrence/nextDueDate JSON fields
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants