# stonerl/thaw architecture

> Architecture diagram of the GitHub repository stonerl/thaw, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-24). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/stonerl/thaw
- Repository: https://github.com/stonerl/thaw

## Overview

1. **What this repo is**
   Thaw is a macOS menu bar management app, split into a primary GUI app and a small helper/service target. The core product hides, shows, reorders, and restyles menu bar items, with extra features like hotkeys, search, profiles, and automation.

2. **Top-level runtime shape**
   The main executable is the `Thaw` app target. It owns app state, settings, navigation, onboarding, permissions UI, notifications, and the visible menu bar controls. A separate `MenuBarItemService` process handles low-level menu bar item discovery and monitoring so the GUI app does not do all of that work in-process.

3. **System event ingestion**
   Input comes from macOS event infrastructure: event taps, HID event monitoring, local event monitors, and hotkey handling. These feed the app’s interaction model for showing hidden items, toggling sections, invoking search, and responding to mouse/keyboard gestures. Accessibility and related permissions are first-class because the app needs to inspect and manipulate other apps’ menu bar items.

4. **Menu bar item discovery boundary**
   `MenuBarItemService` is the system-facing boundary for enumerating and tracking menu bar items. It includes a listener and PID cache, and the app connects to it through `MenuBarItemServiceConnection`. This is the most important process boundary in the architecture: the service observes the OS/menu bar space, while the main app consumes item metadata and turns it into layout decisions.

5. **Item model and layout engine**
   The `Thaw/MenuBar/MenuBarItems` subsystem contains the core layout logic. `LayoutSolver` and `LayoutReconciler` decide where each item belongs, how hidden/always-hidden sections are formed, and how changes are applied over time. Supporting pieces like `PendingLedger`, tag types, and image caches track unresolved moves, identities, and item rendering state.

6. **Menu bar presentation layer**
   Rendering is split into dedicated visual components: `LayoutBar` for arranged menu bar content, `IceBar` for the separate bar shown below or around the menu bar, and overlay/panel types for transient UI. The `ControlItem` views and icons represent the app’s own controls inside the bar. The layout UI is clearly separated from the discovery and reconciliation logic.

7. **Appearance customization subsystem**
   Appearance is handled by a dedicated set of managers, editor panels, and configuration models. This covers tint, gradients, shadows, borders, shapes, and dark/light variants. The `MenuBarAppearanceManager` and the versioned configuration types indicate persistence/migration of appearance settings over time rather than a purely ephemeral UI state.

8. **Settings and profiles**
   The settings system is broad and modular: general, advanced, automation, hotkeys, display, menu bar appearance, menu bar layout, and profile panes each map to their own model layer. `ProfileManager` and related models support applying different layouts/configurations, while `SettingsResetter`, import/export helpers, and migration utilities show that settings are treated as durable app data with compatibility concerns.

9. **Automation, hooks, and behavior policy**
   Beyond manual toggles, the app supports behavior rules such as re-hide strategies, app conflict detection, focus filtering, and hook scripts. `HookRunner` and automation settings suggest user-defined actions or scripts that run in response to menu bar state changes. This creates a policy layer above the raw layout engine.

10. **UI structure and navigation**
   The app uses SwiftUI-style window and pane structure for onboarding, permissions, settings, and specialized editors/search panels. `AppState` and `AppNavigationState` coordinate what the user sees, while custom UI components under `Thaw/UI` provide consistent macOS-style controls, tooltips, recorders, and list/panel primitives. The app is not just a single window; it is a set of coordinated windows and sheets.

11. **Lower-level platform support**
   `VirtualDisplay` and the Objective-C/bridging files indicate platform-specific support code for display-related behavior that macOS APIs alone do not fully provide. Shared utility code includes accessibility helpers, screen capture, mouse helpers, swizzling, localization, and window/space metadata extraction. These modules are the glue between macOS internals and the higher-level menu bar logic.

12. **Data persistence and shared domain types**
   Shared models and utilities define the common language of the app: windows, sections, modifiers, keys, commands, profiles, settings, and diagnostic logging. These types are used across the UI, layout engine, hotkey system, and helper service, which keeps the architecture cohesive even though the app is split across multiple targets.

13. **Notifications, onboarding, and updates**
   User-facing lifecycle concerns are handled separately from the menu bar engine. Onboarding introduces the app, permissions screens explain required access, notifications communicate important state, and an updates module manages version-related behavior. This keeps setup and maintenance flows distinct from the steady-state menu bar management path.

14. **Build, packaging, and automation boundary**
   The repo includes GitHub Actions for build, DMG creation, signing, notarization, release, translation checks, and CI. `ThawCtl` is a separate SwiftPM-based companion utility likely used for control/packaging workflows. Tests are extensive and cover layout planning, profiles, menu bar shapes, settings, gates, and replay fixtures, which suggests the architecture is heavily algorithmic and regression-sensitive.

15. **Overall request/response flow**
   In steady state, macOS events and hotkeys drive the main app; the app queries or receives menu bar item data from the helper service; layout/reconciliation computes the target arrangement; the UI presents bars, overlays, and settings; and persistent settings/profiles determine how the system behaves across launches. The cleanest diagram would show the helper/service, the event/input layer, the layout engine, the UI/appearance layer, and the persistence/settings layer as separate but connected subsystems.

Main entry points: [`Thaw/Main/AppState.swift`](https://github.com/stonerl/thaw/blob/development/Thaw/Main/AppState.swift) (App State), [`Thaw/MenuBar/MenuBarItems/MenuBarItemManager.swift`](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/MenuBarItemManager.swift) (Item Manager), [`Thaw/Settings/SettingsView.swift`](https://github.com/stonerl/thaw/blob/development/Thaw/Settings/SettingsView.swift) (Settings), [`Thaw/MenuBar/MenuBarItems/LayoutReconciler.swift`](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/LayoutReconciler.swift) (Reconciler)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_main["Main App"]
  node_node_app["Thaw App<br/>macOS app<br/>[IceApp.swift]"]
  node_node_appstate(("App State<br/>[AppState.swift]"))
  node_node_nav(("Navigation<br/>ui state"))
  node_node_onboarding["Onboarding<br/>first-run UI"]
  node_node_permissions["Permissions<br/>permission UI"]
  node_node_appearance["Appearance"]
  node_node_updates(("Updates<br/>lifecycle<br/>[Updates.swift]"))
end

subgraph group_group_menubar["Menu Bar System"]
  node_node_layout{{"Layout Solver<br/>layout engine<br/>[LayoutSolver.swift]"}}
  node_node_reconcile{{"Reconciler<br/>state reconciliation"}}
  node_node_manager["Item Manager<br/>menu bar domain"]
  node_node_layoutbar["Layout Bar<br/>presentation<br/>[LayoutBar.swift]"]
  node_node_icebar["Ice Bar<br/>presentation<br/>[IceBar.swift]"]
  node_node_search["Search"]
end

subgraph group_group_settings["Settings & Policy"]
  node_node_settings["Settings<br/>configuration<br/>[SettingsView.swift]"]
  node_node_profiles["Profiles<br/>profile manager"]
  node_node_automation["Automation<br/>policy layer<br/>[HookRunner.swift]"]
end

subgraph group_group_shared["Shared & Platform"]
  node_node_events["Event Input<br/>input layer<br/>[EventMonitor.swift]"]
  node_node_hotkeys["Hotkeys<br/>keyboard actions"]
  node_node_service_conn["Service Conn<br/>ipc client"]
  node_node_shared["Shared Types<br/>domain utilities"]
  node_node_platform["Platform Glue<br/>macOS support<br/>[Helpers.swift]"]
end

subgraph group_group_service["Helper Service"]
  node_node_service["Item Service<br/>helper process<br/>[main.swift]"]
  node_node_listener["Listener<br/>OS observer<br/>[Listener.swift]"]
  node_node_pidcache(("PID Cache"))
end

node_node_app -->|"owns"| node_node_appstate
node_node_appstate -->|"coordinates"| node_node_nav
node_node_appstate -->|"presents"| node_node_onboarding
node_node_appstate -->|"requests"| node_node_permissions
node_node_appstate -->|"binds"| node_node_settings
node_node_events -->|"feeds"| node_node_hotkeys
node_node_hotkeys -->|"triggers"| node_node_appstate
node_node_events -->|"uses"| node_node_platform
node_node_appstate -->|"queries"| node_node_service_conn
node_node_service_conn -->|"connects"| node_node_service
node_node_service -->|"observes"| node_node_listener
node_node_service -->|"tracks"| node_node_pidcache
node_node_service_conn -->|"updates"| node_node_manager
node_node_manager -->|"plans"| node_node_layout
node_node_layout -->|"hands off"| node_node_reconcile
node_node_reconcile -->|"renders"| node_node_layoutbar
node_node_reconcile -->|"renders"| node_node_icebar
node_node_manager -->|"supports"| node_node_search
node_node_appstate -->|"configures"| node_node_appearance
node_node_settings -->|"contains"| node_node_profiles
node_node_settings -->|"contains"| node_node_automation
node_node_profiles -->|"applies"| node_node_manager
node_node_automation -->|"influences"| node_node_manager
node_node_settings -->|"uses"| node_node_shared
node_node_platform -->|"supports"| node_node_manager
node_node_updates -->|"signals"| node_node_appstate

click node_node_app "https://github.com/stonerl/thaw/blob/development/Thaw/Main/IceApp.swift"
click node_node_appstate "https://github.com/stonerl/thaw/blob/development/Thaw/Main/AppState.swift"
click node_node_nav "https://github.com/stonerl/thaw/blob/development/Thaw/Main/Navigation/AppNavigationState.swift"
click node_node_onboarding "https://github.com/stonerl/thaw/blob/development/Thaw/Onboarding/OnboardingSheet.swift"
click node_node_permissions "https://github.com/stonerl/thaw/blob/development/Thaw/Permissions/PermissionsView.swift"
click node_node_events "https://github.com/stonerl/thaw/blob/development/Thaw/Events/EventMonitor.swift"
click node_node_hotkeys "https://github.com/stonerl/thaw/blob/development/Thaw/Hotkeys/HotkeyRegistry.swift"
click node_node_service_conn "https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/MenuBarItemServiceConnection.swift"
click node_node_service "https://github.com/stonerl/thaw/blob/development/MenuBarItemService/main.swift"
click node_node_listener "https://github.com/stonerl/thaw/blob/development/MenuBarItemService/Listener.swift"
click node_node_pidcache "https://github.com/stonerl/thaw/blob/development/MenuBarItemService/SourcePIDCache.swift"
click node_node_layout "https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/LayoutSolver.swift"
click node_node_reconcile "https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/LayoutReconciler.swift"
click node_node_manager "https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/MenuBarItemManager.swift"
click node_node_layoutbar "https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/LayoutBar/LayoutBar.swift"
click node_node_icebar "https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/IceBar/IceBar.swift"
click node_node_search "https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/Search/MenuBarSearchPanel.swift"
click node_node_appearance "https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/Appearance/MenuBarAppearanceManager.swift"
click node_node_settings "https://github.com/stonerl/thaw/blob/development/Thaw/Settings/SettingsView.swift"
click node_node_profiles "https://github.com/stonerl/thaw/blob/development/Thaw/Settings/Models/ProfileManager.swift"
click node_node_automation "https://github.com/stonerl/thaw/blob/development/Thaw/Utilities/HookRunner.swift"
click node_node_shared "https://github.com/stonerl/thaw/blob/development/Shared/Utilities/SharedConstants.swift"
click node_node_platform "https://github.com/stonerl/thaw/blob/development/Thaw/Utilities/Helpers.swift"
click node_node_updates "https://github.com/stonerl/thaw/blob/development/Thaw/Main/Updates.swift"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_app,node_node_appstate,node_node_nav,node_node_onboarding,node_node_permissions,node_node_appearance,node_node_updates toneBlue
class node_node_layout,node_node_reconcile,node_node_manager,node_node_layoutbar,node_node_icebar,node_node_search toneAmber
class node_node_settings,node_node_profiles,node_node_automation toneMint
class node_node_events,node_node_hotkeys,node_node_service_conn,node_node_shared,node_node_platform toneRose
class node_node_service,node_node_listener,node_node_pidcache toneIndigo
```

## Components

### Main App

Primary Thaw application runtime and UI shell

- [Thaw App](https://github.com/stonerl/thaw/blob/development/Thaw/Main/IceApp.swift): macOS app · Main executable and app lifecycle · `Thaw/Main/IceApp.swift`
- [App State](https://github.com/stonerl/thaw/blob/development/Thaw/Main/AppState.swift): app state · Central application state and coordination · `Thaw/Main/AppState.swift`
- [Navigation](https://github.com/stonerl/thaw/blob/development/Thaw/Main/Navigation/AppNavigationState.swift): ui state · Window and pane navigation state · `Thaw/Main/Navigation/AppNavigationState.swift`
- [Onboarding](https://github.com/stonerl/thaw/blob/development/Thaw/Onboarding/OnboardingSheet.swift): first-run UI · Introductory setup flow · `Thaw/Onboarding/OnboardingSheet.swift`
- [Permissions](https://github.com/stonerl/thaw/blob/development/Thaw/Permissions/PermissionsView.swift): permission UI · Access prompts and status screens · `Thaw/Permissions/PermissionsView.swift`
- [Appearance](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/Appearance/MenuBarAppearanceManager.swift): appearance system · Theme, tint, shape, and overlay management · `Thaw/MenuBar/Appearance/MenuBarAppearanceManager.swift`
- [Updates](https://github.com/stonerl/thaw/blob/development/Thaw/Main/Updates.swift): lifecycle · Version-related app behavior · `Thaw/Main/Updates.swift`

### Menu Bar System

Discovery, layout, rendering, and search for menu bar items

- [Layout Solver](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/LayoutSolver.swift): layout engine · Plans positions and hidden sections · `Thaw/MenuBar/MenuBarItems/LayoutSolver.swift`
- [Reconciler](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/LayoutReconciler.swift): state reconciliation · Applies layout changes over time · `Thaw/MenuBar/MenuBarItems/LayoutReconciler.swift`
- [Item Manager](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/MenuBarItemManager.swift): menu bar domain · Coordinates item model and layout state · `Thaw/MenuBar/MenuBarItems/MenuBarItemManager.swift`
- [Layout Bar](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/LayoutBar/LayoutBar.swift): presentation · Arranged menu bar content view · `Thaw/MenuBar/LayoutBar/LayoutBar.swift`
- [Ice Bar](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/IceBar/IceBar.swift): presentation · Secondary bar and spacing presentation · `Thaw/MenuBar/IceBar/IceBar.swift`
- [Search](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/Search/MenuBarSearchPanel.swift): search panel · Search model and panel for items · `Thaw/MenuBar/Search/MenuBarSearchPanel.swift`

### Settings & Policy

Persistent configuration, profiles, automation, and permissions

- [Settings](https://github.com/stonerl/thaw/blob/development/Thaw/Settings/SettingsView.swift): configuration · Persistent settings models and panes · `Thaw/Settings/SettingsView.swift`
- [Profiles](https://github.com/stonerl/thaw/blob/development/Thaw/Settings/Models/ProfileManager.swift): profile manager · Profile application and configuration sets · `Thaw/Settings/Models/ProfileManager.swift`
- [Automation](https://github.com/stonerl/thaw/blob/development/Thaw/Utilities/HookRunner.swift): policy layer · Hooks, re-hide rules, and conflict policy · `Thaw/Utilities/HookRunner.swift`

### Shared & Platform

Cross-target services and lower-level macOS support

- [Event Input](https://github.com/stonerl/thaw/blob/development/Thaw/Events/EventMonitor.swift): input layer · Event taps, HID, and local monitors · `Thaw/Events/EventMonitor.swift`
- [Hotkeys](https://github.com/stonerl/thaw/blob/development/Thaw/Hotkeys/HotkeyRegistry.swift): keyboard actions · Global shortcut definitions and registry · `Thaw/Hotkeys/HotkeyRegistry.swift`
- [Service Conn](https://github.com/stonerl/thaw/blob/development/Thaw/MenuBar/MenuBarItems/MenuBarItemServiceConnection.swift): ipc client · App-side connection to the helper process · `Thaw/MenuBar/MenuBarItems/MenuBarItemServiceConnection.swift`
- [Shared Types](https://github.com/stonerl/thaw/blob/development/Shared/Utilities/SharedConstants.swift): domain utilities · Cross-target constants, models, and helpers · `Shared/Utilities/SharedConstants.swift`
- [Platform Glue](https://github.com/stonerl/thaw/blob/development/Thaw/Utilities/Helpers.swift): macOS support · Accessibility, display, window, and swizzling helpers · `Thaw/Utilities/Helpers.swift`

### Helper Service

Separate process that observes menu bar items

- [Item Service](https://github.com/stonerl/thaw/blob/development/MenuBarItemService/main.swift): helper process · Menu bar item discovery and monitoring service · `MenuBarItemService/main.swift`
- [Listener](https://github.com/stonerl/thaw/blob/development/MenuBarItemService/Listener.swift): OS observer · Listens to system menu bar events · `MenuBarItemService/Listener.swift`
- [PID Cache](https://github.com/stonerl/thaw/blob/development/MenuBarItemService/SourcePIDCache.swift): cache · Tracks process identifiers for menu bar items · `MenuBarItemService/SourcePIDCache.swift`

## Connections

- Thaw App → App State: owns · App lifecycle drives the shared app state
- App State → Navigation: coordinates · App state controls navigation and visible panes
- App State → Onboarding: presents · First-run flow is controlled by app state
- App State → Permissions: requests · Permission screens are surfaced from app state
- App State → Settings: binds · Settings are loaded and edited through the app
- Event Input → Hotkeys: feeds · Input events and shortcuts drive interactions
- Hotkeys → App State: triggers · Hotkey actions update app state and UI
- Event Input → Platform Glue: uses · Low-level event handling depends on platform helpers
- App State → Service Conn: queries · Main app consumes item metadata from helper process
- Service Conn → Item Service: connects · IPC boundary to the helper process
- Item Service → Listener: observes · Helper process listens to menu bar space events
- Item Service → PID Cache: tracks · Helper process maintains PID lookup state
- Service Conn → Item Manager: updates · Received item data updates the item domain model
- Item Manager → Layout Solver: plans · Item manager delegates arrangement to the solver
- Layout Solver → Reconciler: hands off · Planned layout is reconciled into incremental changes
- Reconciler → Layout Bar: renders · Reconciled state is shown in the arranged bar
- Reconciler → Ice Bar: renders · Secondary bar presentation reflects layout state
- Item Manager → Search: supports · Search operates over managed menu bar items
- App State → Appearance: configures · Appearance settings affect the visible menu bar UI
- Settings → Profiles: contains · Profiles are part of persistent settings
- Settings → Automation: contains · Automation and behavior policy live in settings
- Profiles → Item Manager: applies · Profiles reshape menu bar layout and item state
- Automation → Item Manager: influences · Hooks and policy modify layout and re-hide behavior
- Settings → Shared Types: uses · Settings reuse shared domain types and constants
- Platform Glue → Item Manager: supports · Platform helpers back item inspection and control
- Updates → App State: signals · Update lifecycle affects app state and user flow
