Recurring Special Events
Add birthdays, anniversaries and holidays once, and Omniscio creates the Google Calendar entries and lead-time reminders for them every year, automatically. It is a third tab inside the Google Calendar panel that replaces the old reminder spreadsheet, and it can do what a spreadsheet cannot — like ten days before a holiday that moves each year.
What it is
A tab inside the Google Calendar panel where you add a yearly "special event" — a person's birthday, an anniversary, or a holiday — and Omniscio turns it into a set of Google Calendar entries: the day itself, plus whichever advance reminders you pick (on the day, a day before, a week before, a month before, or any custom number of days before). It replaces the manual "Birthday/Anniversary Reminder Creation Tool" spreadsheet: instead of copying formulas and pasting dates, you fill a short form and the calendar events are created for you.
It writes to the same Google Calendar that Omniscio's Calendar integration already connects to (one OAuth grant covers Gmail, Calendar, Drive, Sheets). If Google isn't connected yet, the panel shows a "Connect Google Calendar in Settings" prompt instead of the form.
Add birthdays, anniversaries, and holidays once — Omniscio creates the Google Calendar events and lead-time reminders for them, every year, automatically.
Status: shipped — on by default for anyone with Google Calendar enabled
(calendarEnabled), desktop-only. It surfaces as a third tab ("Recurring
Events") inside the Google Calendar panel — open Google Calendar in the sidebar,
then switch to the Recurring Events tab (the calendar grid stays visible in the
main pane for context). The tab appears whenever Calendar is enabled; if Google
isn't connected yet it shows a "Connect Google Calendar" prompt.
Where to find it
Open Google Calendar from the sidebar, then switch to its third tab, Recurring Events. The calendar grid stays visible beside the form so you keep your context, and everything you save there appears on the same calendar Omniscio already connects to.
The tab is there whenever Google Calendar is enabled. If Google has not been connected yet, it shows a prompt to connect it instead of the form.
How it behaves
The three kinds of event
- Fixed date — the same calendar date every year (e.g. June 13). Best for birthdays and anniversaries.
- Nth weekday of a month — a date that moves but follows a rule (e.g. the 3rd Sunday of May). "Last" is supported (e.g. the last Monday of May).
- Holiday — pick from a built-in catalog whose recurrence rules are baked into the software: New Year's, MLK Day, Valentine's, Presidents' Day, St. Patrick's, Good Friday, Easter, Mother's Day, Memorial Day, Father's Day, Juneteenth, Independence Day, Labor Day, Halloween, Veterans Day, Thanksgiving, Christmas Eve/Day, New Year's Eve. Easter (and Good Friday) are computed with the Gregorian Computus algorithm; the rest are fixed dates or Nth-weekday rules.
For each event you also choose all-day (default) or a specific time, and the time zone the reminders are anchored in.
Lead-time reminders
Tick any combination of: On the day, 1 day before, 1 week before, 1 month before, and a custom "N days before". Each one becomes its own visible calendar entry titled like "Mom's Birthday — 1 week before", so you see the heads-up on your calendar (not just a silent popup). At least one reminder is required.
Why "N days before a holiday" is now reliable
This is the feature's whole reason for existing. In a spreadsheet you can't reliably say "10 days before Mother's Day", because Mother's Day moves every year (2nd Sunday of May) and a fixed cell can't track it. Omniscio resolves the holiday's exact date in software for each year and then subtracts your offset, so the reminder lands on the correct day every year.
How the calendar events are created (behind the scenes)
- Fixed-date events (and their lead reminders) always land on the same
month/day each year, so each is created as a single yearly-recurring Google
Calendar event using an
RRULE:FREQ=YEARLYrule. One event, recurs forever, no maintenance. - Floating events (Nth-weekday and holidays): the day-of entry of an
Nth-weekday or fixed holiday is also a single recurring event
(
BYDAY=3SU,BYMONTHDAY=…). But a lead reminder on a floating date (e.g. 10 days before Mother's Day) can't be expressed as a clean recurring rule, so Omniscio materializes it: it computes the exact date for each of the next several years and creates one calendar entry per year. Computed holidays like Easter are materialized the same way. - The materialized horizon is topped up each time you open the panel, so the reminders never quietly run out. Creation is idempotent (a stable id is derived per event+reminder+year), so topping up never double-books.
- Editing an event removes its old calendar entries and recreates them; deleting an event removes them from Google Calendar too.
Drive it from the CLI
Special events are also reachable over the AMC control server (127.0.0.1:19519,
bearer-auth) so an agent or a curl script can manage them headlessly — the same
five operations the panel exposes:
| Method | Path | Does |
|---|---|---|
GET |
/special-events |
List active special events |
GET |
/special-events/status |
Is Google Calendar connected (and which account) |
POST |
/special-events |
Create one (+ its calendar events) → 201 { event, calendarEventsCreated } |
PATCH |
/special-events/:id |
Replace an event's calendar events from a new spec |
DELETE |
/special-events/:id |
Remove an event + every calendar event it created |
- Calendar-gated. Every route returns 403
{ disabled: true }until Google Calendar is enabled (calendarEnabled) — the same gate as the panel, so once you can see the tab, the CLI works. - Google must be connected. Create/update return 409 with a plain message when it isn't — connect Google Calendar in Settings first.
- Apply immediately (bearer + the shared 10/min mutation budget) — a special
event is a personal-account Google Calendar write, like
/google/calendar/*. - Create is not idempotent — a blind retry re-books a duplicate. If you didn't
see the response,
GET /special-eventsand delete the extra rather than retrying.
The request body matches the panel's form (title, kind, month/day or
nthWeek/weekday or holidayId, allDay + timeLocal, timeZone, leadReminders, …). Full
per-route detail + curl recipes live in the omniscio-control skill's
special-events.md spoke.
Limits / notes
- Desktop-only for now (creating events from a phone is gated off).
- Writes to your primary Google Calendar.
- A Feb 29 birthday recurs on Feb 29 only in leap years (Google's own behavior).
- The holiday catalog is US-centric in this first release; more can be added to
holiday-catalog.tswithout touching anything else.
For agents
Where it lives in the code
- Shared, pure recurrence logic (no runtime deps, fully unit-tested):
src/shared/special-events/—types.ts,date-math.ts(Nth-weekday, month subtraction, Easter/Computus),holiday-catalog.ts, andoccurrences.ts(buildCalendarEventSpecs, which decides recurring-vs-materialized). - Backend service:
src/main/services/special-events/special-events-service.ts(orchestrates the DB + Google Calendar via the existingcalendar-api-service), DB insrc/main/db/queries-special-events.ts(special_eventstable), IPC insrc/main/ipc/special-events-handlers.ts. - Renderer view:
src/renderer/src/features/recurring-events/(RecurringEventsView), mounted as the "Recurring Events" tab of the Google Calendar panel insrc/renderer/src/features/calendar/CalendarPanelTabs.tsx(shown whencalendarEnabledis on + Electron). The main-pane calendar grid stays visible viacalendarAgendaTabinDashboard.tsx. - IPC channels
special-events:list | create | update | delete | status+ thespecial-events/changedrefetch push. - CLI control-server routes:
src/main/services/cli/cli-server-special-events-routes.ts(registerSpecialEventsRoutes), wired inregister-cli-routes.ts; the three mutations areCLI_PARITY_ROUTESentries (promoted fromdeferred-no-route).
Related
Google integrations covers the Google connection these events are written through, and Calendar quick add with its follow-up covers putting an event straight onto the calendar. INDEX.md is the library index.
Last verified 2026-09-23