Calendar and scheduling
Control Center connects to Google Calendar so your day sits alongside your fleet. It syncs your events, shows them in month, week, day and agenda views, warns you before a meeting starts and turns any event into a recorded, summarized meeting.
What it changes on Google
Section titled “What it changes on Google”Almost nothing. The integration pulls events in and renders them; it never creates, edits, or deletes calendar entries. The one write it can make is your own attendance response and even that is constrained by the scope the connect flow requests.
Events are synced into the workspace’s own database on the server
(<dataDir>/<workspaceId>/workspace.db) and rendered by every client over RPC.
No client holds a Google credential.
Per-workspace accounts
Section titled “Per-workspace accounts”Calendar accounts are workspace-scoped, like everything else in Control Center. Each workspace connects its own Google account (or several) and one workspace’s events and tokens are never visible from another. Switching workspaces switches which calendars you see.
A workspace can connect multiple Google accounts, such as a work account and a personal one and their events are merged into the same views.
Why sign-in is a device code
Section titled “Why sign-in is a device code”The headless cc_server has no browser to catch an OAuth redirect. So it does
not use one: it authorizes with the device-code grant (RFC 8628). The server
shows a short user code and a Google URL, you approve on any device that has a
browser and the server polls until you do. A headless install can connect an
account precisely because there is no redirect endpoint to host.
The consequence to know before you bring your own credentials: the client type
must be Google’s “TV and Limited Input devices”. Google only grants an
allow-listed set of scopes to that client type and a project where Calendar is
not permitted for it fails with invalid_scope — you would need a loopback or
web client instead.
Tokens never leave the server. They are written to the server’s secrets.json
in its data directory, keyed google_google:<workspaceId>:<email>, alongside
the databases and under the same host-filesystem trust boundary. The server refreshes
access automatically and, when Google permanently invalidates an account (a
revoked or long-expired session), publishes CalendarAuthExpired and surfaces a
reconnect banner instead of failing silently.
A build from source ships no Google credentials at all — you supply your own
client id and secret. Official release builds bake in a non-confidential
device-code client so the connect flow works out of the box; the server stores
only a marker referencing it, never a copy and a --google-client-id you
supply always takes precedence.
For running your own Google project, see Connect a Google Calendar.
The server pulls a rolling window of each connected account’s events — every calendar on the account, not just the primary — every two minutes, plus on demand (start, connect, manual refresh). The short cadence is affordable because the sweep is incremental: each calendar carries its own sync token, so an unchanged calendar costs one near-empty response rather than re-fetching a five-month window.
Recurring events are expanded server-side, so no client ever parses a recurrence rule. Navigating to a month outside the current window lazily loads that range. Deleted or moved-out-of-range events are reconciled away on the next sync.
| View | What it shows |
|---|---|
| Month | A full month grid (powered by the kalender package) |
| Week | A week’s timed events in a time-grid |
| Day | A single day’s timed events in a time-grid |
| Agenda | A scrollable list of upcoming events |
Open the calendar at /calendar; selecting an event opens its detail at
/calendar/:eventId. The view you pick is stored in that client’s own
preferences, so it does not follow you to another device.
Meeting alerts
Section titled “Meeting alerts”A per-minute scheduler scans for events starting within a configurable lead
window and fires a “meeting starting soon” notification (a
MeetingStartingSoon domain event). The
notification carries the join URL when one is present and clicking it opens the
event detail. Alerts are de-duplicated against the event’s alertedAt, so the
same meeting never alerts twice, even across restarts and an event whose start
passed while the app was closed never replays.
Two limits are easy to trip over. The scheduler runs client-side on the desktop and only for the workspace you currently have open — a workspace you are not in raises no alert. And the web build has no OS-notification pipeline at all, so it raises none either.
Record and link
Section titled “Record and link”From a calendar event you can start a meeting recording seeded with the event’s title. Control Center stores a one-to-one link between the recording and the event, so the meeting’s notes and the calendar entry stay connected without either feature depending on the other.
Start recording & link is desktop-only. On the web client the action reports that recording is unavailable — even though the meetings screen’s own record flow does work in the browser.
See also
Section titled “See also”- Meetings and transcription: what happens after you start a recording
- Workspaces and isolation: why calendar accounts are per-workspace
- Domain events:
MeetingStartingSoonandCalendarAuthExpired - Connect a Google Calendar
- Record and summarize a meeting