name: Onyx options: bundleIdPrefix: com.scarriffleservices deploymentTarget: macOS: "26.0" createIntermediateGroups: true groupSortPosition: top settings: base: DEVELOPMENT_TEAM: PP34X97WS3 SWIFT_VERSION: "6.0" MARKETING_VERSION: "0.1.0" CURRENT_PROJECT_VERSION: "1" ENABLE_HARDENED_RUNTIME: YES # KEIN --deep. # # Es überträgt die Entitlements der App auf jede eingebettete Binary. Der # privilegierte Helfer bekam dadurch application-identifier, weatherkit und # application-groups verpasst — allesamt eingeschränkte Entitlements, die # ein Provisioning-Profil verlangen. Ein nacktes Kommandozeilenprogramm kann # aber keines einbetten, also lehnte AMFI den Start ab: # # amfid: OnyxHelper not valid: Code=-413 "No matching profile found" # taskgated-helper: Disallowing com.scarriffleservices.onyx.helper # because no eligible provisioning profiles found # # Für das ad-hoc signierte MediaRemoteAdapter.framework wird --deep nicht # gebraucht: dafür ist disable-library-validation da. SWIFT_STRICT_CONCURRENCY: complete # Xcode lagert im Debug-Build den Programmcode in eine eigene dylib aus # (für SwiftUI-Vorschauen). Das Hauptprogramm ist dann nur noch ein Rumpf — # und TCC ordnet Berechtigungsanfragen dem Rumpf zu, der weder Info.plist # noch Entitlements trägt. Ergebnis: requestFullAccessToEvents() liefert # kommentarlos false, ohne dass je ein Dialog erscheint. ENABLE_DEBUG_DYLIB: NO packages: OnyxKit: path: Packages/OnyxKit targets: # Der privilegierte Helfer. Läuft als root und tut genau eine Sache: # Lüfterdrehzahlen setzen. Kein Netzwerk, keine Oberfläche, kein # Dateizugriff — je weniger hier steht, desto kleiner die Angriffsfläche. OnyxHelper: type: tool platform: macOS sources: - path: OnyxHelper excludes: - "*.plist" dependencies: - package: OnyxKit product: OnyxHelperProtocol settings: base: PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.onyx.helper PRODUCT_NAME: OnyxHelper CODE_SIGN_STYLE: Automatic SKIP_INSTALL: YES # Kommandozeilenprogramme haben kein Bundle. Die Kennung muss deshalb # in die Binary selbst — sonst signiert codesign sie unter dem # Dateinamen und die Signaturprüfung zwischen App und Helfer scheitert. INFOPLIST_FILE: OnyxHelper/Info.plist CREATE_INFOPLIST_SECTION_IN_BINARY: YES Onyx: type: application platform: macOS sources: - path: Onyx dependencies: - target: OnyxHelper embed: false - package: OnyxKit product: OnyxCore - package: OnyxKit product: OnyxHelperProtocol - package: OnyxKit product: OnyxDesign - package: OnyxKit product: OnyxNotch - package: OnyxKit product: OnyxWidgetKit - package: OnyxKit product: OnyxMenuBar - package: OnyxKit product: CalendarProvider - package: OnyxKit product: WeatherProvider - package: OnyxKit product: MediaProvider - package: OnyxKit product: MetricsProvider - package: OnyxKit product: NetworkProvider - package: OnyxKit product: AudioProvider - package: OnyxKit product: ShelfProvider postBuildScripts: # Der Helfer und seine Plist müssen an genau diese Stellen: SMAppService # sucht die Plist unter Contents/Library/LaunchDaemons und liest von dort # den Pfad zum Programm. - name: Helfer und Launchd-Plist einbetten script: | APP="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH" mkdir -p "$APP/MacOS" "$APP/Library/LaunchDaemons" cp "$BUILT_PRODUCTS_DIR/OnyxHelper" "$APP/MacOS/OnyxHelper" cp "$SRCROOT/OnyxHelper/com.scarriffleservices.onyx.helper.plist" \ "$APP/Library/LaunchDaemons/" # Der Helfer wird eigenständig signiert — die Signatur der App deckt # ihn nicht ab, und ohne gültige eigene Signatur lehnt launchd ihn ab. # # `-i` ist Pflicht: Xcode signiert Kommandozeilenprogramme sonst mit # dem Produktnamen ("OnyxHelper") als Bezeichner. Die App prüft aber # auf com.scarriffleservices.onyx.helper und würde ihren eigenen # Helfer ablehnen. # Zeitstempel im Release, keiner im Debug. # # Die Notarisierung verlangt einen sicheren Zeitstempel; ohne ihn # lehnt Apple das Paket ab, und zwar erst nach dem Hochladen. Im # Debug wäre er nur eine Netzanfrage bei jedem Bauen. if [ "$CONFIGURATION" = "Release" ]; then TIMESTAMP="--timestamp" else TIMESTAMP="--timestamp=none" fi codesign --force --options runtime $TIMESTAMP \ -i com.scarriffleservices.onyx.helper \ --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$APP/MacOS/OnyxHelper" # Kein Neusignieren der App hier: Xcode signiert sie als letzten # Schritt, nach diesem Skript. Das repariert das Siegel von selbst # und legt im Debug-Build auch get-task-allow bei, ohne die im # Skript nachzubauen wäre — nachgemessen an der Reihenfolge im # Bauprotokoll (PhaseScriptExecution vor CodeSign Onyx.app). # Bewusst ohne outputFiles: mit ihnen überspringt Xcode den Schritt, # solange die Plist unverändert ist — auch wenn sich das Programm oder # die Signaturvorgaben geändert haben. # Der MediaRemote-Adapter wird aus dem mitgelieferten Quellcode gebaut, # nicht als fertige Binary eingecheckt: so ist nachvollziehbar, was da # läuft, und die Ad-hoc-Signatur passt zum restlichen Bundle. # # Er darf NICHT gelinkt werden. Geladen wird er von /usr/bin/perl, einem # berechtigten Systemprogramm — im eigenen Prozess greift Apples # Entitlement-Prüfung und es käme gar nichts an. - name: MediaRemote-Adapter bauen und beilegen script: | # Im Release mit der echten Identität signieren: ad-hoc signierte # Bibliotheken lehnt die Notarisierung ab. if [ "$CONFIGURATION" = "Release" ]; then export SIGN_IDENTITY="$EXPANDED_CODE_SIGN_IDENTITY" fi OUT="$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/Vendor" \ "$SRCROOT/Scripts/build-mediaremote-adapter.sh" inputFiles: - $(SRCROOT)/Scripts/build-mediaremote-adapter.sh outputFiles: - $(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Vendor/mediaremote-adapter.pl # Das Menüleistensymbol soll das Glyph aus dem App-Icon zeigen, nicht die # abgerundete Kachel mit Verlauf. actool kompiliert das .icon-Bündel zu # .icns und Assets.car und legt nichts Lesbares ins Bundle — und eine # einzelne Datei daraus lässt sich nicht als Ressource referenzieren. # Deshalb kopieren statt duplizieren: es bleibt bei einer Quelldatei. outputFiles: - $(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/quartz.svg settings: base: PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.onyx INFOPLIST_FILE: Onyx/Info.plist CODE_SIGN_ENTITLEMENTS: Onyx/Onyx.entitlements CODE_SIGN_STYLE: Automatic # Kein App-Sandbox: der privilegierte Helper, IOKit und der # MediaRemote-Adapter sind damit unvereinbar. Der App-Group-Container # bleibt trotzdem erreichbar — siehe docs/spikes/D-appgroup.md. ENABLE_APP_SANDBOX: NO ENABLE_USER_SCRIPT_SANDBOXING: NO COMBINE_HIDPI_IMAGES: YES # Icon-Composer-Bündel (Onyx/AppIcon.icon). actool übernimmt daraus # alle Größen und die Transluzenz-Darstellung von macOS 26. ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon