# Onyx **Notch-Erweiterung für macOS.** Beim Überfahren der Notch fährt ein Panel mit eigenen Widgets aus — Kalender, Wetter, Medien, Hardware, Netzwerk, Audio-Mixer, Ablage und AirDrop. Zielgerät: MacBook Pro mit Apple Silicon, macOS 26+. --- ## Bauen ```bash xcodegen generate # erzeugt Onyx.xcodeproj aus project.yml open Onyx.xcodeproj # dann ⌘R ``` Voraussetzungen: Xcode 26, [XcodeGen](https://github.com/yonaskolb/XcodeGen), Signierung mit Team `PP34X97WS3`. Tests laufen ohne Xcode: ```bash cd Packages/OnyxKit && swift test ``` Ein notarisiertes DMG baut `Scripts/release.sh`. Es braucht zwei Dinge, die einmalig einzurichten sind — ein „Developer ID Application“-Zertifikat und ein notarytool-Zugangsprofil; beides steht im Kopf des Skripts. Das Skript prüft beides vorweg und bricht ab, statt nach zehn Minuten Bauen zu scheitern. --- ## Aufbau Die Projektdefinition liegt als `project.yml` vor, nicht als handgepflegte `.xcodeproj` — so ist im Diff lesbar, was sich an den Build-Einstellungen ändert. ``` Onyx/ App-Target (nicht sandboxed, Hardened Runtime) Packages/OnyxKit/ Alle Module als lokales Swift-Package OnyxCore Einzelinstanz-Sicherung OnyxDesign Farben, Maße, Bewegung — einzige Quelle OnyxNotch Panel-Fenster, Geometrie, Zustandsmaschine OnyxWidgetKit Widget-Protokoll, Layout-Engine, Persistenz OnyxMenuBar Modul-Protokoll für Menüleisten-Elemente CalendarProvider EventKit (und später Calendarr) WeatherProvider WeatherKit + CoreLocation MediaProvider MediaRemote-Adapter, AppleScript, Medientasten Vendor/ Fremdcode im Quellzustand (siehe unten) Spikes/ Wegwerf-Werkzeuge zur API-Verifikation docs/spikes/ Was dabei herauskam — auch die Sackgassen ``` --- ## Entscheidungen, die man sonst für Fehler hält **Keine App-Sandbox.** Sie ist mit dem privilegierten Helper, mit IOKit und mit dem MediaRemote-Adapter unvereinbar. Der App-Group-Container für Calendarr bleibt trotzdem erreichbar — auf macOS ist er von der Sandbox unabhängig. Nachgemessen in [docs/spikes/D-appgroup.md](docs/spikes/D-appgroup.md). **TCC-Entitlements trotz fehlender Sandbox.** Bei aktivierter Hardened Runtime verlangt macOS `com.apple.security.personal-information.*` auch ohne Sandbox. Fehlt eine davon, erscheint der Berechtigungsdialog gar nicht erst — ohne Fehlermeldung. Das hat einen halben Abend gekostet: [docs/spikes/E-tcc-hardened-runtime.md](docs/spikes/E-tcc-hardened-runtime.md). **`ENABLE_DEBUG_DYLIB = NO`.** Xcode lagert im Debug-Build den Programmcode in eine eigene dylib aus. TCC ordnet Berechtigungsanfragen dann dem verbleibenden Rumpf zu, der weder Info.plist noch Entitlements trägt. **Eigenes Einstellungsfenster.** SwiftUIs `Settings`-Szene öffnet über einen privaten Selektor, der bei Apps ohne Menüleiste unzuverlässig ankommt. **Der MediaRemote-Adapter wird nicht gelinkt.** Er wird von `/usr/bin/perl` geladen, einem berechtigten Systemprogramm — im eigenen Prozess greift Apples Entitlement-Prüfung und es käme nichts an. **Signiert wird im Release anders als im Debug.** Der Helfer und der Adapter bekommen nur im Release einen sicheren Zeitstempel, und der Adapter wird dort mit der echten Identität statt ad-hoc signiert. Beides verlangt die Notarisierung, und beides fällt sonst erst nach dem Hochladen auf. Im Debug wären es nur Netzanfragen bei jedem Bauen. **Die Abdeckung eines Calendarr-Schnappschusses steht nicht in der Datei.** Sie ist zugesagtes Verhalten des Schreibers (49 Tage nach vorn) und wird von `CalendarrSnapshotReader` daraus abgeleitet. Sie aus dem frühesten Termin zu erschließen wäre naheliegend und falsch: mehrtägige Termine ragen ins Fenster hinein und werden mitgeschrieben, obwohl ihr Anfang nicht abgedeckt ist. Ein Test hält das fest. **Der Audiomixer hat keinen Schalter je Programm mehr.** Am Regler zu ziehen *ist* die Entscheidung, dieses Programm zu regeln. Ein Schalter davor wäre eine Hürde, die nichts schützt — der große Ausschalter stellt ohnehin alles zurück. --- ## Fremdcode `Vendor/mediaremote-adapter` — [ungive/mediaremote-adapter](https://github.com/ungive/mediaremote-adapter), BSD-3-Clause. Als Quellcode eingebettet und beim Bauen kompiliert, nicht als fertige Binary: so ist nachvollziehbar, was läuft. Stand siehe `ONYX-VERSION.txt`. --- © 2026 Scarriffleservices