apple-reminders · git:20260730.6a0c379 · 2026-07-30 · sha256 6331557e24e3c1be
apple-reminders git:20260730.6a0c379B
Immutable. This exact content is served forever at /api/v1/blob/6331557e24e3c1be.
--- name: apple-reminders description: > Read, brief on, capture, and safely change tasks in the native Apple Reminders app through the on-device `apple-reminders` command. Use this skill whenever the user asks about their reminders, to-dos, or tasks — daily or weekly briefings, what is overdue or due today, unscheduled inbox items, adding or capturing a new task, rescheduling a due date, changing priority, moving a task to another list, marking things done, cleaning up a list, or finding a specific reminder. Trigger it even when the user never says "reminder": "what's on my plate today", "add milk to my shopping list", "push that to Friday", "what did I miss this week", "clear out the done stuff", "브리핑", "할 일", "미리알림", "오늘 뭐 해야 해", "장바구니에 추가", "마감 지난 것", "提醒事项", "待办", "今天要做什么", "リマインダー", "タスク". Also trigger when the user asks for something Reminders cannot do through this command (tags, sections, attachments, flags, subtasks, recurring reminders) so the limitation is reported accurately instead of guessed. compatibility: > iOS only. Requires the built-in `apple-reminders` native command and granted Reminders permission; the command is not registered on Android. No external dependencies, no scripts, no network. --- # Apple Reminders ## Overview `apple-reminders` is a built-in native command backed by EventKit. It exposes five verbs — `list`, `create`, `update`, `complete`, `delete` — over reminder titles, due dates, lists, priorities, notes, and completion state. Every call prints one JSON envelope to stdout. The command is small, but three of its behaviours fail *silently and successfully*: a mistyped list name, an unparseable due date, and a truncated read all return `ok: true`. Most of this skill exists to keep those three from turning into wrong answers or misplaced tasks. Read `references/cli.md` for the full contract — flags, JSON shapes, error codes, and the exact date grammar. ``` apple-reminders list [--incomplete|--completed] [--list <name>] [--limit <N>] apple-reminders create --title <t> [--due <dt>] [--list <name>] [--priority <0-9>] [--notes <text>] apple-reminders update --id <id> [--title <t>] [--due <dt>] [--list <name>] [--priority <0-9>] [--notes <text>] apple-reminders complete --id <id> [--undo] apple-reminders delete --id <id> ``` Add `--compact` to minimize JSON, `-q` to print only the `data` field. Prefer `--compact` for large reads to save context. Run `apple-reminders --help` when you are unsure whether an option still exists — the help text is authoritative for the build you are running, and this reference may lag it. The command is iOS-only. If it is not on `PATH`, say that reminder access is not available on this device. Do not reach for a workaround: there is no supported path to Reminders data outside this command, so do not try to install an adapter, script around it, or read Reminders storage directly. ## Three checks before any write These are not style preferences. Each one prevents a wrong result that the command itself reports as success. **1. Resolve the exact list title from a read. Never pass a guessed name.** `--list` matches by *case-insensitive substring*, so `--list Work` also matches `Workout`, and when several titles match, EventKit's calendar order decides which one wins — not you. Worse, on `create` an unmatched `--list` is not an error: the reminder is silently saved to the default list and the response still says `ok: true`. So read first, pick the exact title, then write, then confirm the `list` field in the response is the list you intended. Empty lists never appear in `list` output, because list titles are only observable through the reminders inside them. If the user names a list you cannot find, say it is either empty or nonexistent — do not create the task somewhere else and hope. **2. Compute due dates as absolute local datetimes yourself.** Accepted forms are `YYYY-MM-DD`, `YYYY-MM-DDTHH:MM`, `YYYY-MM-DDTHH:MM:SS` (interpreted in the device's local timezone), and full ISO 8601 with an offset or `Z`. Relative offsets are accepted *only into the past* (`-7d`, `-2h`, `-30m`); there is no `+3d` form. Anything else — `tomorrow`, `next Monday`, `+1d`, `3d`, `내일` — fails to parse, and a failed parse is **dropped without an error**: the reminder is created or updated with no due-date change and the command still exits 0. So resolve the user's wording into a concrete date and time before you build the command, and state the date you chose in your answer so a misreading is visible. Two consequences worth knowing: `YYYY-MM-DD` alone becomes 00:00 local, since this command has no all-day form; and `create` does not echo `due` back, so after any `create --due` you must read the reminder back to confirm the date actually landed. `update` does echo `due`, so its own response is the confirmation. **3. Treat a truncated read as "I have not seen the data yet".** `--limit` defaults to 100, and result order is not guaranteed — so a truncated read is an *arbitrary* subset, not the first 100 by date. When `data` contains `_warning` and `total_available`, you cannot say anything about the whole set: "nothing is overdue" may simply mean the overdue items were outside the window. Re-run with a narrower scope (`--incomplete`, `--list <exact title>`) or with `--limit` above `total_available`, then answer. Say so if you deliberately answer from a bounded scope. ## Workflow 1. **Read the real state first.** Ground every answer in actual titles, list names, due dates, and completion state. For briefings use one `--incomplete` read; `--incomplete` includes reminders with no due date, which is what you want for an inbox view. 2. **Normalize time language** into explicit dates, times, and weekdays before reasoning or writing. Use the device's local timezone. 3. **Keep reads bounded** by list, completion state, and limit — the three filters that exist. There is no date-range or text-search filter, so date grouping and keyword matching happen on your side, after the read. 4. **Target writes by `id` only.** Get `id` from a `list` read. Never write against a title you have not resolved to a single id. If several reminders share a title, disambiguate by list, due date, or notes, and name which one you chose. 5. **Verify after writing.** `update` and `complete` return post-write state — read it, don't assume. `create` returns only `id`, `title`, and `list`, so verify due date, priority, and notes with a follow-up read when they matter. Never treat a zero exit status or a bare `ok: true` as proof the change landed the way you intended: all three silent failures above exit 0 and report success. 6. **Report the exact affected set** — titles, lists, and dates — not a count. 7. **Do not retry a failed write blindly.** Check `error.code` first: `authorization_denied` needs the user to grant Reminders access in Settings, and retrying will not help; `invalid_args` means fix the command; `no_data` means the id no longer resolves — re-read before concluding the reminder is gone. ## Write safety This skill supports standing delegation — a user who has told you to act on their reminders without checking in each time has granted it, and asking again on every write makes the skill useless for the exact people who want it. So when standing delegation applies, execute high-impact writes without stopping for a separate confirmation. Delegation removes the *prompt*, not the *evidence*. Every delegated write must still be bounded to a target set you enumerated from a read, verified by read-back, and reported afterward with the exact items affected — that report is what makes the change reviewable after the fact, which is the whole basis for skipping the prompt. When standing delegation does not apply, restate the qualifying set and scope before writing. Preserve everything the user did not ask to change. `update` is a patch: flags you omit are left untouched, so pass only the fields you intend to change. Never send a field "to be safe". Match the care to how recoverable each verb is: - **`complete`** is fully reversible with `complete --id <id> --undo`. Lowest risk. Prefer completing over deleting when the user's intent is "this is done", and when they say "clear" or "clean up", ask which they mean if it is not obvious from context — the two are not equivalent and only one is undoable. - **`update`** overwrites the previous value with no undo. Capture the current value from your read before patching, and report `old → new` so the user can reverse it manually. - **`delete`** is the only irreversible verb here. This skill cannot guarantee whether a deletion made through this command is recoverable from the Reminders app's Recently Deleted, so do not tell the user it is. Before deleting, capture `title`, `list`, `due`, `priority`, and `notes`, and include them in your report so the reminder can be recreated by hand if the deletion was wrong. - **Bulk changes** need an enumerated target set before the first write, never a filter applied blindly. Keep batches small enough to report individually. If any single write returns `ok: false`, stop and report what has already been applied — do not continue through the rest of the batch, because a partially applied bulk change that is reported as complete is far harder to recover from than a stopped one. Priority is inverted and unvalidated: `1` is the highest, `5` is medium, `9` is the lowest, `0` is none. Map the user's words to that scale (high → 1, medium → 5, low → 9) and never pass a number the user gave you as if it were a 1–10 ranking. Ids from `update`, `complete`, and `delete` are resolved by scanning the whole reminder store with a 10-second cap. On a large store, a `no_data` "Reminder not found" can be that timeout rather than a missing reminder — re-read before telling the user their reminder is gone. ## Output conventions Name the list for every reminder when location matters, and use exact dates with weekdays (`Fri 2026-08-07`) rather than "in 3 days". A missing or `null` due date means unscheduled, not undated-and-fine. A due time of exactly 00:00 is most likely an all-day reminder created in the Reminders app, not a midnight deadline — all-day items surface as `T00:00:00` here and cannot be told apart from timed midnight ones. Present those as a date, and never "fix" one by writing a time onto it. **Do not surface a reminder's notes** unless the user asked for them or they are needed to tell two otherwise identical candidates apart. Notes routinely hold private detail — medical, financial, personal — that the user did not ask to have read back, and a briefing is not a reason to print it. Keep raw JSON, ids, and local file paths out of the user-facing answer too; use them, don't display them. For briefings, build the groups yourself from one `--incomplete` read, using the device's local timezone and skipping groups that are empty: - **Overdue** — due before today's local midnight, oldest first - **Due today** — due on today's local date, including times already past - **Upcoming** — "this week" means after today through the coming Sunday; "the next seven days" means a rolling seven-day window. State which basis you used - **Unscheduled** — no due date. Show at most 20, grouped by list, and report how many more were omitted, because an unscheduled inbox can be enormous - **Cleanup candidates** — long-overdue or clearly stale items, only when asked Keep it short and actionable. If your read was truncated or deliberately scoped, say so in one line rather than implying the briefing is complete. ## What this command cannot do Report these plainly when asked. Do not simulate them, do not write them into `--notes` as a silent substitute, and do not report success for something you did not do — the honest limitation is more useful than a fake feature. | Requested | Status | |---|---| | Sections within a list | Not exposed | | Tags / hashtags | Not exposed | | Flag a reminder | Not exposed | | Image or URL attachments | Not exposed | | Subtasks | Rejected with `not_available` — iOS has no public API for it | | Creating or deleting a list | Not exposed; ask the user to create it in the Reminders app first | | List emoji or color | Not exposed | | All-day due dates | Not exposed; a date-only value becomes 00:00 local | | Recurring reminders | Not exposed | | Alarms, location or messaging triggers | Not exposed; this command sets a due date, and whether a notification fires is up to the Reminders app | | Listing empty lists | Not observable — list titles only appear via reminders inside them | | Filtering by date range or search text | Not exposed; read bounded, then filter your side | When a request needs one of these, offer the closest honest alternative — a note in `--notes`, a priority instead of a flag, a separate list the user creates — and let the user decide. Do not invent a subcommand or flag to cover the gap. If the user wants the capability itself, point them at filing a feature request on the Minis repository rather than leaving them thinking it exists. ## Examples **Daily briefing.** "What's on my plate today?" ```bash apple-reminders list --incomplete --limit 200 --compact ``` Check `_warning`; if present, raise `--limit` above `total_available` and re-read. Then group into Overdue / Due today / Upcoming / Unscheduled, naming each list. **Capture into a named list.** "Add pick up prescription to my errands list, Friday 6pm" Read first to resolve the exact list title, compute the absolute datetime, create, then confirm the `list` field came back as the list you intended and read the due date back: ```bash apple-reminders list --incomplete --limit 200 --compact apple-reminders create --title "Pick up prescription" --list "Errands" --due 2026-08-07T18:00 apple-reminders list --list "Errands" --incomplete --compact ``` **Reschedule.** "Push the tax filing task to next Monday." Resolve the id from a read, patch only `--due`, and use the returned `due` as confirmation. Report `Wed 2026-08-05 → Mon 2026-08-10`. **Ambiguous list name.** The user says "work list" and the read shows both `Work` and `Workout`. Do not pass `--list work`; it would match by substring and the winner is unpredictable. Pass the exact title you determined, or name both and ask which one when the reminder's content does not settle it. **Unsupported request.** "Attach this screenshot to the visa reminder." Say the on-device command has no attachment support, so you cannot do it from here; offer to reference the file path in the reminder's notes instead, and mention that attaching it by hand in the Reminders app is the only way to get a real attachment.