Architecture overview
Magical is a native macOS menu bar and desktop client for Google Calendar. This file maps the tree
and says how the pieces fit; README.md indexes the pages that go deeper into each
subsystem.
Stack and workspace
The runtime, build tooling and workspace layout are true of both apps and live in
../developer-guidelines/coding-standards.md's Stack and workspace.
System overview
Magical runs the shared process shape: an Electron main process orchestrates, the Swift helper draws
the native UI in a child process, a C++ N-API addon reaches the window from inside Electron, and the
OS-hosted extensions are reached through files and notifications. Google Calendar itself runs in a
Chromium renderer, one per account partition. The shared mechanism is in
../shared/process-model-and-ipc.md.
flowchart TD
subgraph Main["Electron main process"]
Orchestration["Window, layout and routing"]
Pollers["Calendar and Tasks pollers"]
AddonBridge["Native addon bridge"]
end
subgraph Renderers["Chromium renderer processes"]
Views["WebContentsView per calendar account partition"]
end
subgraph Helper["Swift helper (MagicalHelper)"]
SettingsWin["Settings window"]
StatusItem["Menu bar status item and popover"]
Notify["UNUserNotificationCenter"]
end
subgraph Addon["Native N-API addon (in-process)"]
Cocoa["Cocoa window and NSToolbar"]
DockTile["NSDockTile date icon"]
end
subgraph Ext["App extensions (OS-hosted .appex)"]
Widgets["MagicalWidgets.appex"]
Intents["MagicalAppIntents.appex"]
end
Main -->|"WebContentsView API"| Views
Main <-->|"newline-delimited JSON-RPC on stdio"| Helper
Main <-->|"N-API callbacks"| Addon
Widgets -->|"App Group snapshot file"| Main
Intents -->|"distributed notification and state file"| Helper
Magical imports the shared infrastructure from @magimail/core: the Chrome
identity, the session partition configuration, the BaseWindow options and the encrypted local cache
files (secret-file.ts; see
sessions-and-security.md's Local cache files at rest).
Each account view is a WebContentsView on its own persist:magical_<id> partition, hosted by the
window in Window and views.
Window and views
Magical uses a single BaseWindow with titleBarStyle: 'hiddenInset', sidebar vibrancy, and
dimensions of 1280x820 (minWidth: 1280), hosting one WebContentsView per account. Google
Calendar's top bar carries non-collapsible navigation controls that demand at least 1211px on
Workspace accounts, so enforcing minWidth: 1280 prevents the top bar from clipping or triggering
horizontal scrolling. BrowserWindow would allocate a default renderer process (~100 MB RAM) that is
never displayed, so BaseWindow is used instead.
Titlebar insets and traffic lights
Views are offset vertically by TOOLBAR_HEIGHT (52px) so Google Calendar's web banner does not
collide with the system buttons. With hiddenInset, macOS traffic lights draw over the top-left of
the window frame. The inset area also holds the native AppKit NSToolbar (see
Native toolbar).
Lazy loading and account suspension
AccountsManager keeps memory down by creating account views late and closing them early: only the
active account's WebContentsView is instantiated at startup, and an inactive account's view is
closed rather than hidden once it has been hidden for inactiveAccountSuspendMinutes. On resume the
view is re-instantiated and navigated back to the URL it left, kept in suspendedUrls without its
query. The suspension policy, the memory it saves and why the query is dropped are in
calendar-sync.md's Suspending an inactive account
and When a view cannot load.
Single-instance lock
Only one Magical instance may run concurrently (requestSingleInstanceLock). Chromium requires an
exclusive filesystem lock on partition cookie jars and LevelDB databases. A second instance that
reads an active partition fails with silent LOCK errors.
When a view cannot load
A view whose load fails for want of a network shows Chromium's error page, which names a net:: code,
offers a reload that fails the same way, and never mentions Magical. accounts-manager.ts replaces
it on did-fail-load with the page in @magimail/core's offline-page.ts. That page names the app
and the service it cannot reach, retries the URL that actually failed rather than reloading itself,
and retries again on its own once the connection returns.
isNetworkLoadFailure decides which failures qualify. Alongside the codes that name a missing network
it counts net::ERR_FAILED, which is what a navigation a service worker handled reports when the
worker cannot answer it. net::ERR_ABORTED is excluded: a navigation superseded by another reports
it, and that happens throughout Google's sign-in redirects.
Google Calendar's own offline mode keeps working. An account with it turned on registers a service
worker that answers navigations under /calendar/u/<n>/ from its cache, so with no network the window
shows the real calendar rather than the offline page. That cache matches on the exact URL: measured,
/calendar/u/0/r is served with no network and /calendar/u/0/r?pli=1, which is the URL a cold start
leaves behind, fails. This is why suspendedUrls stores a calendar URL without its query. The date
and the view mode live in the path, so a resumed view still lands where the user left it.
Sessions and browser identity
Each account uses an isolated Chromium profile partition named persist:magical_<id>, configured via
configureGoogleSession from @magimail/core. The shared session configuration and browser identity
are in ../shared/sessions-and-security.md.
- The two apps use different partition prefixes,
persist:magical_andpersist:magimail_, so they never collide on the same SQLite profile database lock. configureGoogleSessionsets the request headers (User-Agent,Sec-CH-UA) at startup.- Headers alone are not enough, because the page also reads
navigator.userAgentData. Bare Chromium omits the brand entries, which triggers Google's "This browser or app may not be secure" block.calendar-preload.tsrunsapplyMainWorldIdentityviacontextBridge.executeInMainWorld, so the headers and the in-page JavaScript properties agree across all endpoints.
Native toolbar
The toolbar's mechanism, and the rules every native toolbar item follows, are in
../shared/native-ui.md. Magical's configured items are:
accounts: multi-account segmented switcher.navGroup: segmented control carrying<(Previous),Todayand>(Next), dispatched into the web page as semantic DOM clicks (triggerCalendarAction).invites:NSMenuToolbarItemcarrying the count of invitations awaiting a reply on the active account, opening onto a list of them with Accept, Maybe, Decline and Open per entry. Seersvp.md.addEvent: New Event button (calendar.badge.plus), which opens Google Calendar's event composer.search: optional nativeNSSearchFieldavailable via toolbar customisation, expanding Google search on submit.
The switcher segments show account colour dots, focus dimming and authentication warning icons. A filled dot means invitations have arrived on that account and not been dealt with, which is the only thing that says which account they are waiting on.
Menu bar
The status item and its popover both run in the Swift helper, not in Electron; the mechanism is in
../shared/menu-bar.md. Magical's four title modes, the countdown formatter
both surfaces share, the popover's metrics, the mini-month grid, the hero band and the day-grouped
agenda are in menu-bar.md, and how the surfaces act on an event, with every tray RPC,
is in actions.md. Hiding a calendar in the popover's filter
hides it everywhere the tray draws, including the menu bar title, and the choice is persisted as
hiddenCalendars, each entry naming its account as well as its calendar.
Styling and theming
The anti-FOUC injection mechanism, the semantic-selector rule and the theming model are shared and in
../shared/design.md. Magical's own decisions:
calendar-css.tsis injected viawebContents.insertCSS()ondid-navigate, before initial layout and first paint, so there is no flash of unstyled content.- "Hide app sidebar" matches the Google rail by
aria-label, not by the broaderrole="complementary", which would take the left drawer's calendar lists with it. - The main week and day calendar grid (
[role="grid"]) keeps a solid background for text contrast. - Turning vibrancy off removes the transparency from both the CSS and the window:
setVibrancy(null), with an opaque background of#1a1a1aor#ffffff.
Google Calendar has its own dark and light modes, and on the "Device" appearance setting the web
application tracks CSS prefers-color-scheme, so Magical only has to drive that media query through
nativeTheme.themeSource. No page reload, and no third-party CSS inversion filter.
Navigation rules
links.ts enforces strict origin allowlisting:
- Internal navigation is permitted for
calendar.google.com,accounts.google.comandmyaccount.google.com. setWindowOpenHandlerandwill-navigateintercept external links: meeting links (Zoom, Teams, Meet), Drive attachments and map coordinates all go to the macOS default handler viashell.openExternal.
Dynamic Dock tile
Magical renders today's live calendar date directly onto the macOS Dock tile using Apple's native
NSDockTile API, rather than from static image files or an SVG rasterisation package. The drawing,
the midnight rollover, the powerMonitor resume handling and the RSVP badge are in
dock-icon.md.
Calendar wire protocol decoder
Magical decodes Google Calendar's internal web client data stream, the
POST https://calendar.google.com/calendar/u/<index>/sync.prefetcheventrange endpoint, whose wire
format, XSSI guard, unauthenticated-response check and pinned-index decoding rules are all in
calendar-wire-format.md. A pinned index holding something that is not an
event date throws, because the alert engine is built on this decoder and a banner at the wrong hour is
worse than none.
Swift helper
The settings window, the menu bar status item and its popover are all built in SwiftUI and AppKit and
run in a separate native binary (apps/magical/swift/).
- The helper talks to the Electron main process over newline-delimited JSON-RPC on
stdin/stdout(SuiteRPC). - It runs under the
.accessoryactivation policy, so it adds no extra icon to the macOS Dock. - It ships inside
Magical.app/Contents/MacOS/MagicalHelperand inherits the main app's bundle identifier for notifications and preferences. - The main process pushes the state on every open (
settings.show), so a restarted helper never shows stale controls.