Conventions, architecture, and design patterns for the boring.notch macOS Dynamic Island app. Use this skill whenever working on any feature, bugfix, or refactor in boring.notch — including adding new views, managers, settings, animations, or modifying the notch layout. Also consult this when the user asks about how the project works, how to add a new module, or when you need to understand the codebase structure before making changes.
69
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
boring.notch is a macOS app that replaces the MacBook's notch with a dynamic, interactive widget. It displays music playback, notifications, system HUDs, calendar/weather, a file shelf, and more.
Repository technical architecture (Chinese, contributor-oriented): root ARCHITECTURE.md — state layers, windowing, sizing, Liquid Glass summary, gestures, shortcuts/speech, and pointers into this skill’s references/. Build, signing, notarization, CI, and Island vs. boringNotch naming: BUILD.md.
Detailed module-specific docs live in references/. Consult them when working in the
relevant area:
| Reference | When to read |
|---|---|
references/design-conventions.md | Colors, typography, spacing, liquid glass mode, glass text modifiers |
references/animation-patterns.md | Spring values, matchedGeometryEffect IDs, transitions, gestures |
references/music-module.md | Waveform coloring rules, canonical animation params, sneak peek |
references/widget-system.md | Home layout, closed notch widgets, forbidden zone, todo/inspiration widgets |
references/window-and-input.md | NSPanel config, hover-out, canBecomeKey, keyboard shortcuts |
references/xcode-integration.md | Adding files to project.pbxproj, group IDs, dependencies |
boringNotch/
├── boringNotchApp.swift # App entry, window creation, lifecycle
├── ContentView.swift # Root view — notch shape, background, gestures, state routing
├── components/
│ ├── Notch/ # Core notch UI (BoringHeader, NotchHomeView, NotchSettingsView, etc.)
│ ├── Calendar/ # Calendar + weather widgets
│ ├── Shelf/ # Drag & drop file shelf
│ ├── Settings/ # External settings window
│ ├── Live activities/ # Download progress, HUD indicators
│ ├── Music/ # Lyrics, visualizer, slider
│ ├── Tabs/ # Tab bar (home/shelf/widgets)
│ ├── Webcam/ # Camera preview
│ ├── Onboarding/ # First-launch flow
│ └── Tips/ # TipKit tips (e.g. TipStore.swift)
├── managers/ # Singleton ObservableObject managers
├── models/ # BoringViewModel, Constants, data models
├── extensions/ # SwiftUI View extensions, helpers
├── helpers/ # Utility classes (AppleScript, AppIcons, etc.)
├── observers/ # System event observers (media keys, fullscreen, drag)
├── sizing/ # Notch dimensions and corner radii
├── enums/ # App-wide enums
├── animations/ # Animation definitions
├── private/ # CGSSpace (auto-synced in Xcode)
├── metal/ # Metal shaders (audio visualizer)
├── menu/ # Status bar menu
├── Shortcuts/ # KeyboardShortcuts definitions (e.g. ShortcutConstants.swift)
└── utils/ # LoggingBoringViewModel — Per-screen notch state. Owns notchState (.open/.closed),
notchSize, and transient UI state (hover, drop targeting, camera). Passed via
@EnvironmentObject to all views.
BoringViewCoordinator — Global singleton (BoringViewCoordinator.shared). Controls
which view is displayed (currentView: NotchViews), sneak peek / expanding view state,
first-launch flow, and screen selection. Accessed via @ObservedObject in views.
Defaults (sindresorhus/Defaults) — Persisted user preferences. All keys live in
Constants.swift under extension Defaults.Keys. Use @Default(.keyName) for reactive
bindings in views, Defaults[.keyName] for read-only access.
Constants.swift:
static let myFeature = Key<Bool>("myFeature", default: false)@Default(.myFeature) var myFeature in views that react to changes.NotchSettingsView (in-notch) and/or SettingsView (external window).Every system-level service follows this pattern:
@MainActor
class FooManager: NSObject, ObservableObject {
static let shared = FooManager()
@Published var someState: Type = defaultValue
private override init() {
super.init()
// setup observers, timers, etc.
}
func startMonitoring() { ... }
func stopMonitoring() { ... }
}Key rules:
@MainActor if the manager drives UI via @Published.static let shared — never create multiple instances.@ObservedObject var foo = FooManager.shared.NSObject base class when interfacing with system APIs (CoreAudio, CoreLocation, etc.).ContentView is the root. It builds the notch layout in layers:
ContentView (body)
└── ZStack → VStack
├── NotchLayout() # Content inside the notch shape
│ ├── [closed] state-specific views (music live activity, battery, HUD, notification, face)
│ ├── [open] BoringHeader # Top bar with tabs, notch cutout, action buttons
│ ├── [closed] ClosedNotchWidgetBar # Configurable widget indicators (market, pomodoro)
│ └── [open] switch currentView:
│ ├── .home → NotchHomeView # Music player + calendar/weather + pomodoro
│ ├── .shelf → ShelfView # File shelf
│ ├── .clip → DynaClipView # Mini file browser (pinned folders; DynaClipManager)
│ ├── .settings → NotchSettingsView
│ ├── .widgets → WidgetHubView # Widget management
│ ├── .market → MarketTickerView # Crypto/stock/gold prices
│ ├── .translation → TranslationView
│ ├── .todoList → TodoListView # Quick todo list (fn+T)
│ └── .inspiration → InspirationView # Inspiration recorder (fn+I)
└── Chin rectangle (click target below notch)When adding a new top-level view to the notch:
NotchViews enum in enums/generic.swift.case to the switch coordinator.currentView in ContentView.NotchLayout().vm.notchSize when switching to it.references/window-and-input.md for canBecomeKey setup.NotchState, NotchViews, Style)String raw values + Defaults.SerializableCaseIterable, Identifiable when used in pickersCalendarSelectionState, EventType.conditionalModifier(someCondition) { view in
view.someModifier()
}Defined in ConditionalModifier.swift. Use instead of ternary-in-modifier for complex logic.
Transient HUDs (volume, brightness, notifications) use coordinator.toggleSneakPeek().
This shows a brief overlay in the closed notch, then auto-dismisses after a timeout.
managers/ following the singleton pattern.Constants.swift.components/ subdirectory.ContentView — either in NotchLayout() for closed-state displays, or in
the switch coordinator.currentView for open-state views.project.pbxproj entries for all new files (see references/xcode-integration.md).NotchSettingsView and/or SettingsView.references/animation-patterns.md) — don't invent new springs.scrollLocked set in
handleUpGesture and to the needsTall check in onChange(of: currentView).WidgetHubView with enable toggle. Add a HomeWidget case
for home view placement. Add to homeWidgets default order in HomeWidget.defaultOrder.d1c3297
Also appears in
since Aug 28, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.