Calendar Quick Add
Calendar Quick Add is the Calendar tab inside the Quick Launch box: type one natural-language line describing an event and it creates it on Google Calendar, honouring typed time zones and offering a repeat fallback and a calendar picker.
What it is
A tab inside the Quick Launch floating composer (Ctrl+Space → Calendar tab) for creating Google Calendar events from a single natural-language line. Type something like "Lunch with Sarah tomorrow at noon for 90 minutes" into the Item field, press Ctrl+Enter, and Omniscio creates the event on your Google Calendar — your primary by default, or another calendar you pick (see "Pick a calendar" below). Type a time zone with the time ("3pm EST") and it's honored, not ignored (see "Time zones" below).
The tab is pinned by default alongside Session / Alarm / Task / Scratchpad / Drip / Bookmark. Existing installs get the new tab automatically via a one-shot startup migration that appends calendar to quickLaunchPinnedActionIds. The tab is gated on calendarEnabled — if Google Calendar isn't connected yet, the tab is hidden from the strip until you authorize at Settings → Google Integrations.
What it looks like:
- An Event text input in the Quick Launch body — inline recurrence is extracted from the same line (the legacy free-text Repeat field was retired 2026-05-24). It even understands a dangling "every" typed after the day ("Kathleen Tuesday 10am every" → repeats weekly on Tuesday) rather than leaving the stray word in the title.
- Below the preview, a small Repeat checkbox + Daily/Weekly/Monthly/Yearly picker — a manual fallback to force (or remove) recurrence when the typed text alone didn't imply one (added 2026-07-06). It mirrors any repeat the text already implied, so you only reach for it when you need to.
- Below the input, a SnoozePalette-style preview list of 1–2 plausible interpretations:
- If you gave an exact time ("Birthday tomorrow at 2pm"), the preview is a single timed row — no all-day alternative on the same date and no shorter-duration look-alike row, both of which would have rendered identically to the 1-hour default and read as duplicates.
- If you gave a date only ("Friday birthday"), the preview shows two rows — the all-day interpretation and a 9 AM timed alternative — so you can disambiguate between "the whole day" and "a morning event on that day".
- If you gave a "…of the month" phrase without "every" ("Team meeting first Monday of the month"), the preview shows two rows — a repeating monthly interpretation and a one-time interpretation — both on the upcoming occurrence, so you pick whether you meant a recurring meeting or a single event. (Add "every" — "first Monday of every month" — to get just the repeating row.)
- If you gave a weekday and a date that disagree ("Mon the 21st" when the 21st is actually a Sunday), the preview shows two rows — the 21st and the next Monday — so you pick which you meant. When they agree, it's a single date.
- Each row reads as Title — date and time spelled out in full (e.g. Monday, June 29 at 12:00 PM; an all-day event shows the date with no time), with the date/time hugging the title rather than pinned to the right edge (the legacy left-right-spread layout was retired 2026-05-25). The recurrence summary, when present, sits on a second line beneath.
- When the content needs more room — several interpretations, and/or the Repeat row and Calendar picker being shown — everything renders inside the Control Space's one fixed-size window: content taller than the window scrolls, with the Cancel/Create buttons pinned below the scroll area so they are never pushed off. (The window itself never grows or shrinks — resizing it live used to flash a white strip for a frame on Windows, so the resize was removed; entrance-animation contract I21.) The suggestion list can't be squeezed, so a row is never cut off — it scrolls instead.
- A small sparkle pill at the top of the preview reads "AI is thinking…" only while the Haiku fallback is actually running, and "AI fallback used" on rows produced by the LLM. With the regex layer extensions from Phase 2 you should rarely see this pill — the goal is <1% of inputs.
- Click any row to pick the interpretation and submit. Ctrl+Enter picks the selected row. Esc dismisses the whole Quick Launch window.
- The microphone button feeds the Event field. Inline recurrence in the transcript ("every Tuesday at 3pm") flows through the same parser path and shows up on the preview row's recurrence summary.
After a successful create, the floating composer closes immediately and a small toast appears in the bottom-left of the main Omniscio window (where Omniscio's other notifications live) — "Added to Google Calendar: <event title>" — with two compact links:
- Open — opens the event in your browser.
- Undo — deletes the event you just created (one-click, no re-prompt), then confirms it was removed.
The toast auto-dismisses after a few seconds. (Changed 2026-06-23 — previously the composer showed a larger in-window pane that lingered for 4 seconds.) Note: if you've turned off the Other notifications toast category in Settings → Notifications, this confirmation won't appear.
Where to find it
The tab lives inside Quick Launch, the floating composer you open with Ctrl+Space; if the tab is pinned and Google is connected, Calendar is one of the entries in the strip along its top, and clicking it swaps the body for the Event field. The tab itself is switched on by connecting Google in Settings → Google Integrations, is pinned or unpinned in the Quick Launch card in Settings, and has no settings card of its own.
There is no dedicated settings card for Calendar Quick Add. A few things you might look for and where they actually live:
- The tab pinning — Settings → Quick Launch (the tabs card every tab uses). Calendar is pinned by default; uncheck to hide it.
- The default calendar — no card; it's set automatically to whatever you last picked in the tab's calendar dropdown (stored as
calendarQuickAddDefaultCalendarId). Change it just by picking a different calendar next time. - The $0.10/day LLM cap — not user-configurable. Tracked in the shared
api_cost_logtable under the source labelcalendar-quick-add. - The Google connection — Settings → Google Integrations. Same OAuth as Calendar / Drive / Sheets / Gmail. If revoked, the Calendar tab is hidden from the Quick Launch strip until reconnected.
How it behaves
Open the tab
Press Ctrl+Space (or your rebind) to open Quick Launch. If you have the Calendar tab pinned and Google is connected, the Calendar tab is one of the entries in the top strip. Click it or press Ctrl+Tab to cycle.
Type a prompt
Drop a natural-language description of the event into the Event field. The parser understands:
- Relative date phrases — today, tomorrow, tonight, yesterday, next Friday, in 3 weeks, plus slang anchors tonite, tmrw, tmr, 2morrow, etc.
- Explicit dates in just about any common form — month names (June 5, Dec 25, 21 June, 21st of June), numeric (6/5, 6/21/2026), dashed / dotted with a year (6-21-2026, 6.21.2026), ISO (2026-06-21), a bare day-of-month (the 21st, on the 1st), and a weekday paired with a date (Sun 21st, Sunday the 21st).
- The date and time can sit anywhere in the line, in any order — the parser finds them wherever they are and uses the leftover text as the title, so "6/21 12pm vr event", "dentist June 5", "meeting at 3 today", "birthday tomorrow at 10am", and time-before-day phrasings like "John 1pm tomorrow", "call mom 9am friday", and "mon 10am standup" all parse cleanly — the date never has to come last, and neither the date nor the time ever leaks into the title.
- "next <weekday>" skips to next week — "next Sunday" means the Sunday of next week, not the one that may be only a day or two away. (Plain "Sunday" or "this Sunday" still means the nearest upcoming Sunday.)
- When a weekday and a date disagree, you choose — type "Mon the 21st" when the 21st is actually a Sunday and you get two rows — the 21st and the next Monday — so you pick which you meant. When they agree ("Sun 21st", the 21st is a Sunday) it's a single date.
- A lone number is never a date — "invoice 4521", "room 1530", and "sprint 2-3 planning" won't accidentally book an event; an explicit date needs a month, a slash/ISO form, an ordinal (the 21st), or a weekday to be recognized.
- Times — at 3pm, 3:30 PM, 15:00, noon, midnight, plus compact / shorthand entry: 805p (8:05 PM), 8p, 1230a, 12p, 845a, and sloppy variants where the separator is fat-fingered (8.05p, 8;05pm) or a minute digit is dropped (8:5pm). A compact time with no separator must carry its am/pm letter, so a bare room or extension number ("room 1530") is never silently read as a time.
- Time ranges — 8-9p, 8:05-9:30pm, 8 to 9pm set the event's start and end in one line; a meridiem on either side carries to the other (8-9pm → both PM), and this still works with a day-of-week trailing the range ("block 2-4pm thursday" → Thursday 2 PM–4 PM, fixed 2026-07-04 — the bare "2" used to drop out of the range and strand in the title).
- Everything the Snooze box understands, this box understands too — Calendar Quick Add's date/time parsing shares one engine with session snooze (see Snooze a session), so business days ("3 business days"), ordinal days ("the 15th", "25th of march"), bare months ("june", "early august"), week-part phrases ("next week friday", "monday week"), "same time" phrases, and end-of-period phrases ("eom", "eoy", "cob") all resolve here as well — any grammar the shared engine learns, Calendar Quick Add inherits automatically, no separate work needed.
- Inline duration — for 90 minutes, for 1 hour, for 2h.
- Inline recurrence — every Tuesday, every weekday, every other week, yearly. A dangling "every" typed after the day also works: "Kathleen Tuesday 10am every" or "standup Friday 9am every other" read as every Tuesday / every other Friday (weekly / biweekly on that day). With no weekday to anchor it, the stray "every" is simply cleaned out of the title — use the Repeat box (below) to force a repeat in that case.
- "…of the month" recurrence — first Monday of the month, last Friday of the month (a specific weekday each month), and first of the month, the 15th of the month, last day of the month (a specific date each month). These also accept "of every month". Typed without "every" the phrase is ambiguous, so the preview offers a repeating row and a one-time row on the upcoming occurrence — pick which you meant (see below).
- Approximate / named / spelled times — around 1, 3ish, early morning, late afternoon, after lunch, first thing, half past three, quarter to five, two pm, plus meal context (dinner at 7 → 7 PM) and in an hour / in 15.
- Typos, shorthand & reschedules — common day misspellings (fryday, tomorow, tuseday) resolve to the right day; friday's deadline, all day friday, and move dentist from tue to fri read cleanly.
- Time zones are honored — write a zone with the time (3pm EST, 9am PST, noon eastern time, 14:00 UTC) and Omniscio books the event at that clock in that zone and labels it accordingly, so "9am EST" lands at 9:00 Eastern even when your computer is on Pacific time. It's daylight-saving-aware — a summer "EST" resolves to Eastern Daylight Time, exactly as Google shows it. Recognized zones are the US zones (ET/CT/MT/PT, standard or daylight) plus UTC/GMT; leave the zone off and the event uses your computer's local zone as before, and an unrecognized/exotic zone falls through to the AI parser.
- Holidays — Christmas, Thanksgiving, Memorial Day, Halloween, New Year's, July 4th … resolve to the right date (rolling to next year once it has passed). Easter and other moving/lunar holidays use the AI fallback.
- Relative dates — two weeks from friday, a week from today, end of the month, end of next week.
- Multi-day repeats & ordinals — mon wed fri 6am, tue and thu, mwf, every other tuesday become recurring schedules; an ordinal that names a thing (10th anniversary june 1) keeps the ordinal in the title and uses the real date.
Anything left over after stripping date/time/duration/recurrence becomes the event title.
Examples:
| You type | Parses to |
|---|---|
Lunch tomorrow at noon |
One row: 1-hour timed event tomorrow at 12:00 (time given → no all-day alternative) |
Birthday tomorrow at 2pm |
One row: 1-hour timed event tomorrow at 14:00 |
John 1pm tomorrow |
One row: 1-hour timed event tomorrow at 13:00, title "John" (time before the day still parses) |
call mom 9am friday |
One row: timed event Friday at 09:00, title "Call mom" |
Dinner 805p |
One row: 1-hour timed event today at 20:05 (compact time → timed, never an all-day row) |
Thursday 7p Holly |
One row: timed event next Thursday at 19:00, title "Holly" (single-letter time parses even with the title last) |
Meeting 8-9p |
One row: timed event today 20:00–21:00 (range sets both start and end) |
block 2-4pm thursday |
One row: timed event Thursday 14:00–16:00, title "Block" (range + trailing day-of-week) |
Friday birthday |
Two rows: all-day on Friday or a 9 AM timed alternative (no time given → pick which one you meant) |
Standup every weekday at 9 |
Recurring weekly Mo-Fr, 1-hour event at 09:00 |
Kathleen Tuesday 10am every |
One row: repeats weekly on Tuesday at 10:00, title "Kathleen" (dangling "every" + a weekday → weekly) |
Standup Friday 9am every other |
One row: repeats every other Friday at 09:00, title "Standup" ("every other" → biweekly) |
Dentist June 5 |
All-day event on June 5 (no time given) |
6/21 12pm vr event |
One row: timed event on June 21 at 12:00, title "Vr event" (date found mid-line, stripped from title) |
dinner at 7 friday |
One row: Friday at 19:00 (evening context → PM), title "Dinner" |
christmas dinner |
All-day event on Dec 25, title "Dinner" |
gym mon wed fri 6am |
Recurring Mon/Wed/Fri at 06:00, title "Gym" |
10th anniversary june 1 |
All-day on June 1, title "10th anniversary" (the ordinal isn't read as the date) |
Dentist 2026-06-21 |
All-day event on June 21 (ISO date) |
Pay rent the 1st |
All-day event on the next 1st of the month |
Mon the 21st (21st is a Sunday) |
Two rows: the 21st or the next Monday — pick which you meant |
next Sunday |
All-day on the Sunday of next week (skips the imminent one) |
Gym in 3 weeks for 1 hour at 6pm |
Single 1-hour timed event 3 weeks from today at 18:00 |
Standup for 3 weeks every Monday at 9am |
Recurring weekly Monday at 09:00, COUNT=3 |
Team meeting first Monday of the month |
Two rows: repeating monthly on the first Monday or a one-time event — both on the next first-Monday |
Rent first of the month |
Two rows: repeating on the 1st or a one-time event on the next 1st |
Standup first Monday of every month |
One row: repeating monthly on the first Monday ("every" → unambiguously recurring) |
Standup 9am EST (on a Pacific computer) |
One row: timed event at 9:00 Eastern, tagged Eastern Time — the typed zone is honored, not shifted to your local time |
Pick from the preview
When the parser produces multiple plausible interpretations, the preview list shows them as clickable rows. Each row shows the event title, the date/time, and (when applicable) a one-line recurrence summary like "Every Mon/Wed/Fri, 10 times".
- Click a row to select + submit immediately.
- Ctrl+Enter submits the first (top-ranked) row.
- The selected row gets a left-accent stripe so you can tell which one Ctrl+Enter will fire.
If nothing parses (typed too much prose, or just typed nonsense), Omniscio silently falls back to a Haiku LLM call to try again — capped at $0.10/day across all your Quick Add usage. While the Haiku call is in flight the small "AI is thinking…" pill is visible above the preview; you'll know that this particular parse took longer because the regex missed, not because the feature is slow. If the daily cap is hit, you'll see "AI fallback unavailable (daily cap reached). Try simpler date phrasing…" instead of the LLM trying.
Make it repeat (the Repeat box)
Most of the time you just type the repeat into the line — "every Tuesday", "yearly", "every other week", or even a dangling "…every" after the day. When the text alone didn't capture it (say you typed an exact date, or a phrase the parser didn't read as recurring), use the Repeat checkbox that sits below the preview once an event is parsed:
- Tick Repeat and choose Daily / Weekly / Monthly / Yearly. Weekly repeats on the event's own weekday.
- If the text already implied a repeat, the box is already ticked and shows that frequency — so the control and the preview never disagree. Change the frequency to override it, or untick to drop the repeat entirely.
- Leave it untouched and nothing changes — the event repeats exactly as the text implied (or not at all).
The Repeat box only forces the recurrence rule; the date, time, title, and calendar all still come from what you typed.
Pick a calendar
By default a Quick Add event lands on your primary Google Calendar. If your Google account has more than one calendar you can write to, a small calendar dropdown appears below the preview list — choose the one you want and press Create. Two conveniences:
- Your pick is remembered. The calendar you choose becomes the default for the next Quick Add, so a one-time switch sticks until you change it again (including switching back to primary).
- Only writable calendars are offered. Calendars you can only view — a shared holidays feed, a coworker's calendar shared read-only — are filtered out, because creating an event on one would just be rejected by Google.
If you have exactly one writable calendar (the common case), there's no dropdown — it just uses it, no extra click.
Time zones
Write a time zone right in the line — "Standup 9am EST", "call 2pm PST", "sync at noon eastern time", "deploy 14:00 UTC" — and Omniscio creates the event at that clock in that zone, then tags the event with it so Google shows it correctly. So "9am EST" is 9:00 AM Eastern no matter what time zone your own computer is set to.
- It's daylight-saving-aware: a "9am EST" in July resolves to 9:00 Eastern Daylight Time (summer Eastern), which is how Google itself labels it — you don't have to remember EST-vs-EDT.
- Recognized zones are the US zones (Eastern / Central / Mountain / Pacific, written as ET/CT/MT/PT or the full "eastern time" etc.) plus UTC/GMT.
- No zone typed? The event uses your computer's own time zone, exactly as before — nothing changes for the common case.
- A zone Omniscio doesn't recognize (something outside the set above) falls through to the AI parser rather than guessing.
Defaults
- All-day vs timed: If you didn't give a time, Omniscio creates an all-day event. If you gave a time but no duration, the event is 1 hour long.
- Calendar: Your primary Google Calendar by default. If you have more than one calendar you can write to, a calendar picker appears below the preview — pick any writable calendar and your choice is remembered as the new default next time. (Read-only calendars — a shared holidays feed, someone else's calendar you can only view — are never offered, since a create there would just fail.)
- Time zone: If you type a zone (EST, PST, eastern time, UTC…), the event is booked at that clock in that zone. If you don't, it uses your computer's local zone (whatever your OS reports).
Validation
- An empty Item field rejects with a red border + tooltip "Type something to create an event."
- An Item field that produces zero parseable interpretations rejects similarly — but tells you the LLM fallback was tried (or that the daily cap blocked it).
What happens if Google Calendar disconnects?
Your Google sign-in can lapse — desktop OAuth refresh tokens expire after about six months idle, or sooner if you change your Google password or manually revoke access — or the stored connection can go missing entirely (for example after a system or credential reset). Either way, when you click Create, Omniscio does not dump the raw error. Instead the preview area swaps to a plain-language message — "Google session has expired" when the sign-in lapsed, or "Not connected to Google" when it's gone — each with a hint to reconnect, and a Reconnect Google button right there in the pane. Click it, finish the standard Google sign-in in your web browser (the same one Drive / Sheets / Gmail use — all four share one connection), and Omniscio automatically re-creates the event you already described — no re-typing the prompt, no clicking Create again. If the reconnect itself is cancelled or fails, the button stays so you can try again. Non-auth failures (e.g. a network blip) show the friendly message without the reconnect button, since reconnecting wouldn't fix them.
Related
- quick-launch-modal.md — the parent feature. Calendar is one tab inside Quick Launch; everything about the hotkey, voice mic, project chip suppression, and tab strip behavior lives there.
- google-integrations.md — the OAuth connection that gates this tab. If
calendarEnabledis false, the tab is hidden. - alarms.md — the closest sibling tab in shape: natural-language input, regex-first parser, Haiku fallback, daily cap. Calendar Quick Add reuses the same orchestration pattern.
The reasoning behind the parser, the preview and the calendar picker, plus the code map underneath the tab, is on part 2.
Last verified 2026-10-06