Magic Apps

Documentation

macmagic.app

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.

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:

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:

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:

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/).