@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +266 -267
  5. package/package.json +2 -2
  6. package/pipeline/scripts/_notices.mjs +1 -1
  7. package/pipeline/skills/.skill-manifest.json +68 -68
  8. package/pipeline/skills/shared/README.md +70 -70
  9. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  10. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  11. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  12. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  13. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  14. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  15. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  16. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  17. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  18. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  19. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  20. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
  21. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  22. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
  23. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
  24. package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
  25. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  26. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  27. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  28. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
  29. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  30. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  31. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  32. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  34. package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
  35. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  36. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
  37. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  38. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  39. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  40. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  41. package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
  42. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  43. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
  44. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  45. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  46. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  47. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  48. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  49. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  50. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  51. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  52. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  53. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
  54. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  55. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  56. package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
  57. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  58. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  59. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  60. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  61. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  62. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  63. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  64. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  65. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  66. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  67. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  68. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  69. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  70. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  71. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  72. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  73. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  74. package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
  75. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  76. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  77. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  78. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  79. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  80. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  81. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  82. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  83. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  84. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  85. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  86. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  87. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  88. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  89. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  90. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  91. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  92. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  93. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  94. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  95. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  96. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  97. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  98. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  99. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  100. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  101. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  102. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  103. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  104. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  105. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  106. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  107. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  108. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  109. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  111. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
  112. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  113. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  114. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  115. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  116. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  117. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  118. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  119. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  120. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  121. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  122. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  123. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  124. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  125. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  126. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  127. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  128. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  129. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  130. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  131. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  132. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  133. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  134. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  135. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  136. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  137. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  138. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  139. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  140. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  141. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  142. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  143. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  144. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  145. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  146. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  147. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  148. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  149. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  150. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  151. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  152. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  153. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  154. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  155. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  156. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  157. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
  158. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  159. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  160. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  161. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  162. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  163. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  164. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  165. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  166. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  167. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  168. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  169. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  170. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  171. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  172. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
  173. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  174. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  175. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  176. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  177. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  178. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  179. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  180. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  181. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  182. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  183. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  184. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  185. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  186. package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
  187. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  188. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  189. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
  190. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  191. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  192. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  193. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  194. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  195. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  196. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
  197. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  198. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  199. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  200. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
  201. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  202. package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
  203. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  204. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
  205. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  206. package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
  207. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  208. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  209. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  210. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  211. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  212. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  213. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  214. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  215. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  216. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  217. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  218. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  219. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  220. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  221. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  222. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  223. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  224. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  225. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  226. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  227. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  228. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  229. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  230. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  231. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
  232. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  233. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
  234. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  235. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
  236. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  237. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  238. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  239. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  240. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  241. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  242. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  243. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  244. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  245. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  246. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  247. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  248. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  249. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  250. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  251. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  252. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  253. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  254. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  255. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  256. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  257. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  258. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  259. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  260. package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
  261. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  262. package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
  263. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
  264. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,239 +1,199 @@
1
1
  ---
2
2
  name: musickit-audio
3
- description: "Integrate Apple Music playback, catalog search, and Now Playing metadata using MusicKit and MediaPlayer. Use when adding music search, Apple Music subscription flows, queue management, playback controls, remote command handling, or Now Playing info to iOS apps."
3
+ description: "MusicKit and MediaPlayer on iOS: Apple Music authorization, catalog search, subscription checks and offers, ApplicationMusicPlayer playback controls and queues, Now Playing info, remote commands. Use when adding Apple Music playback or Now Playing controls."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
- # MusicKit
8
+ # MusicKit and Now Playing
9
9
 
10
- Search the Apple Music catalog, manage playback with `ApplicationMusicPlayer`,
11
- check subscriptions, and publish Now Playing metadata via `MPNowPlayingInfoCenter`
12
- and `MPRemoteCommandCenter`. Targets Swift 6.3 / iOS 26+.
10
+ Two frameworks cover music in an iOS app. MusicKit talks to Apple Music:
11
+ permission, catalog, subscription state, library and an app-owned player.
12
+ MediaPlayer talks to the system: the Now Playing card on the Lock Screen, in
13
+ Control Center and in CarPlay, plus the remote commands that headphones and
14
+ those surfaces send. Code here targets Swift 6.3 and iOS 26.
13
15
 
14
- ## Contents
15
-
16
- - [Setup](#setup)
17
- - [Authorization](#authorization)
18
- - [Catalog Search](#catalog-search)
19
- - [Subscription Checks](#subscription-checks)
20
- - [Playback with ApplicationMusicPlayer](#playback-with-applicationmusicplayer)
21
- - [Queue Management](#queue-management)
22
- - [Now Playing Info](#now-playing-info)
23
- - [Remote Command Center](#remote-command-center)
24
- - [Common Mistakes](#common-mistakes)
25
- - [Review Checklist](#review-checklist)
26
- - [References](#references)
16
+ Longer building blocks (an observable player model, mini player, search screen,
17
+ charts, library and playlist work, `MPNowPlayingSession`, audio session setup,
18
+ interruptions and route changes) live in
19
+ [references/musickit-patterns.md](references/musickit-patterns.md).
27
20
 
28
21
  ## Setup
29
22
 
30
- ### Project Configuration
23
+ ### Portal and Info.plist
24
+
25
+ 1. In the developer portal, open the app's explicit App ID and turn on the
26
+ **MusicKit** App Service. That is what lets the system mint developer tokens
27
+ for the app automatically; there is no token code to write.
28
+ 2. Add `NSAppleMusicUsageDescription` to Info.plist. Without it, access to the
29
+ user's media library fails wherever the system requires the string.
30
+ 3. Only if audio must keep playing in the background: add `audio` to the
31
+ `UIBackgroundModes` array.
31
32
 
32
- 1. Enable the **MusicKit App Service** for the app's explicit bundle ID in the Apple Developer portal so MusicKit can generate developer tokens automatically.
33
- 2. Add `NSAppleMusicUsageDescription` to Info.plist explaining why the app accesses the user's media library.
34
- 3. For background playback, add the `audio` background mode to `UIBackgroundModes`.
33
+ There is no `com.apple.developer.musickit` entitlement to add on iOS, and a
34
+ missing entitlement is not what makes authorization fail. The App Service and
35
+ the usage string are the two requirements.
35
36
 
36
37
  ### Imports
37
38
 
38
39
  ```swift
39
- import MusicKit // Catalog, auth, playback
40
- import MediaPlayer // MPRemoteCommandCenter, MPNowPlayingInfoCenter
40
+ import MusicKit // authorization, catalog, subscription, ApplicationMusicPlayer
41
+ import MediaPlayer // MPNowPlayingInfoCenter, MPRemoteCommandCenter
41
42
  ```
42
43
 
43
44
  ## Authorization
44
45
 
45
- Request permission before accessing the user's music data or playing Apple Music
46
- content. `request()` presents Apple's consent dialog when necessary; use
47
- `currentStatus` to read the current setting without prompting.
46
+ Ask before touching the user's music data or starting Apple Music playback.
48
47
 
49
48
  ```swift
50
- func requestMusicAccess() async -> MusicAuthorization.Status {
51
- let status = await MusicAuthorization.request()
52
- switch status {
49
+ func ensureMusicAccess() async -> Bool {
50
+ switch await MusicAuthorization.request() {
53
51
  case .authorized:
54
- // Full access to MusicKit APIs
55
- break
52
+ return true
56
53
  case .denied, .restricted:
57
- // Show guidance to enable in Settings
58
- break
54
+ // Explain the limitation and point the user at Settings.
55
+ return false
59
56
  case .notDetermined:
60
- break
57
+ return false
61
58
  @unknown default:
62
- break
59
+ return false
63
60
  }
64
- return status
65
61
  }
66
-
67
- // Check current status without prompting
68
- let current = MusicAuthorization.currentStatus
69
62
  ```
70
63
 
71
- ## Catalog Search
64
+ `request()` shows the consent prompt only when the user has not answered yet;
65
+ otherwise it returns the stored answer. To read the state without any chance of
66
+ a prompt, use `MusicAuthorization.currentStatus`.
72
67
 
73
- Use `MusicCatalogSearchRequest` to search the Apple Music catalog. Catalog lookup
74
- can fetch Apple Music resources, but playback of subscription catalog content
75
- must still be gated on `MusicSubscription.current.canPlayCatalogContent`.
68
+ ## Catalog search
76
69
 
77
- ```swift
78
- func searchCatalog(term: String) async throws -> MusicItemCollection<Song> {
79
- var request = MusicCatalogSearchRequest(term: term, types: [Song.self])
80
- request.limit = 25
70
+ Searching the catalog works for anyone who granted access. Playing what you
71
+ found is a separate question, answered by the subscription check below.
81
72
 
82
- let response = try await request.response()
83
- return response.songs
73
+ ```swift
74
+ func findTracks(matching phrase: String) async throws -> MusicItemCollection<Song> {
75
+ var search = MusicCatalogSearchRequest(term: phrase, types: [Song.self])
76
+ search.limit = 25
77
+ let result = try await search.response()
78
+ return result.songs
84
79
  }
85
80
  ```
86
81
 
87
- ### Displaying Results
82
+ For a row, read `song.title`, `song.artistName` and
83
+ `song.artwork?.url(width: 120, height: 120)`.
84
+
85
+ ## Subscription state
88
86
 
89
87
  ```swift
90
- for song in songs {
91
- print("\(song.title) by \(song.artistName)")
92
- if let artwork = song.artwork {
93
- let url = artwork.url(width: 300, height: 300)
94
- // Load artwork from url
95
- }
96
- }
88
+ let membership = try await MusicSubscription.current
89
+ let mayPlay = membership.canPlayCatalogContent
97
90
  ```
98
91
 
99
- ## Subscription Checks
100
-
101
- Check whether the user has an active Apple Music subscription before offering playback features.
92
+ Subscription state changes while the app runs. Keep the UI in step:
102
93
 
103
94
  ```swift
104
- func checkSubscription() async throws -> Bool {
105
- let subscription = try await MusicSubscription.current
106
- return subscription.canPlayCatalogContent
107
- }
108
-
109
- // Observe subscription changes
110
- func observeSubscription() async {
111
- for await subscription in MusicSubscription.subscriptionUpdates {
112
- if subscription.canPlayCatalogContent {
113
- // Enable full playback UI
114
- } else {
115
- // Show subscription offer
116
- }
95
+ .task {
96
+ for await membership in MusicSubscription.subscriptionUpdates {
97
+ showsPlayControls = membership.canPlayCatalogContent
98
+ showsJoinButton = !membership.canPlayCatalogContent && membership.canBecomeSubscriber
117
99
  }
118
100
  }
119
101
  ```
120
102
 
121
- ### Offering Apple Music
103
+ ### Presenting the Apple Music offer
122
104
 
123
- Present the Apple Music subscription offer sheet when the user is not subscribed.
124
- Check `canBecomeSubscriber` first, and pass `MusicSubscriptionOffer.Options` or
125
- `onLoadCompletion` when the sheet needs contextual metadata or load-error handling.
105
+ Only offer when `canBecomeSubscriber` is true. The sheet comes from a view
106
+ modifier:
126
107
 
127
108
  ```swift
128
- import MusicKit
129
- import SwiftUI
130
-
131
- struct MusicOfferView: View {
132
- @State private var showOffer = false
109
+ struct JoinAppleMusicButton: View {
110
+ @State private var offerVisible = false
111
+ @State private var offerOptions = MusicSubscriptionOffer.Options.default
112
+ @State private var offerError: (any Error)?
133
113
 
134
114
  var body: some View {
135
- Button("Subscribe to Apple Music") {
136
- Task {
137
- let subscription = try? await MusicSubscription.current
138
- showOffer = subscription?.canBecomeSubscriber == true
139
- }
140
- }
141
- .musicSubscriptionOffer(
142
- isPresented: $showOffer,
143
- options: .default,
144
- onLoadCompletion: { error in
145
- if let error {
146
- // Surface loading errors in app UI or diagnostics.
147
- print(error)
148
- }
149
- }
150
- )
115
+ Button("Try Apple Music") { offerVisible = true }
116
+ .musicSubscriptionOffer(
117
+ isPresented: $offerVisible,
118
+ options: offerOptions,
119
+ onLoadCompletion: { failure in offerError = failure }
120
+ )
151
121
  }
152
122
  }
153
123
  ```
154
124
 
155
- ## Playback with ApplicationMusicPlayer
125
+ When `offerError` is non-nil the sheet did not load; show a fallback message.
156
126
 
157
- `ApplicationMusicPlayer` plays Apple Music content independently from the Music app. It does not affect the system player's state.
127
+ ## ApplicationMusicPlayer
158
128
 
159
- ```swift
160
- let player = ApplicationMusicPlayer.shared
129
+ `ApplicationMusicPlayer.shared` is the app's own player. It plays alongside the
130
+ Music app without touching the Music app's queue or state.
161
131
 
162
- func playSong(_ song: Song) async throws {
163
- player.queue = [song]
132
+ ```swift
133
+ func start(_ track: Song) async throws {
134
+ let player = ApplicationMusicPlayer.shared
135
+ player.queue = [track]
164
136
  try await player.play()
165
137
  }
166
138
 
167
- func pause() {
168
- player.pause()
169
- }
139
+ func halt() { ApplicationMusicPlayer.shared.pause() }
170
140
 
171
- func skipToNext() async throws {
172
- try await player.skipToNextEntry()
173
- }
141
+ func forward() async throws { try await ApplicationMusicPlayer.shared.skipToNextEntry() }
174
142
  ```
175
143
 
176
- ### Observing Playback State
144
+ The player is not `Sendable`. Read `.shared` where it is used; a global
145
+ `let player`, or a property on a main-actor type, fails Swift 6 checking once
146
+ an async method is called on it. The snippets below use `player` for
147
+ `ApplicationMusicPlayer.shared`.
148
+
149
+ `player.state` is observable, so SwiftUI redraws when it changes. Branch on
150
+ `playbackStatus`:
177
151
 
178
152
  ```swift
179
- func observePlayback() {
180
- // player.state is an @Observable property
181
- let state = player.state
182
- switch state.playbackStatus {
183
- case .playing:
184
- break
185
- case .paused:
186
- break
187
- case .stopped, .interrupted, .seekingForward, .seekingBackward:
188
- break
189
- @unknown default:
190
- break
191
- }
153
+ switch player.state.playbackStatus {
154
+ case .playing: label = "Playing"
155
+ case .paused: label = "Paused"
156
+ case .stopped: label = "Stopped"
157
+ case .interrupted: label = "Interrupted"
158
+ case .seekingForward,
159
+ .seekingBackward: label = "Seeking"
160
+ @unknown default: label = ""
192
161
  }
193
162
  ```
194
163
 
195
- ## Queue Management
164
+ ## Queue management
196
165
 
197
- Build and manipulate the playback queue using `ApplicationMusicPlayer.Queue`.
166
+ `player.queue` is an `ApplicationMusicPlayer.Queue`. Assigning a collection
167
+ replaces it, and an album or playlist works as well as songs:
198
168
 
199
169
  ```swift
200
- // Initialize with multiple items
201
- func playAlbum(_ album: Album) async throws {
202
- player.queue = [album]
203
- try await player.play()
204
- }
170
+ player.queue = [albumToPlay]
171
+ ```
205
172
 
206
- // Append songs to the existing queue
207
- func appendToQueue(_ songs: [Song]) async throws {
208
- try await player.queue.insert(songs, position: .tail)
209
- }
173
+ To add without replacing:
210
174
 
211
- // Insert song to play next
212
- func playNext(_ song: Song) async throws {
213
- try await player.queue.insert(song, position: .afterCurrentEntry)
214
- }
175
+ ```swift
176
+ try await player.queue.insert(extraTracks, position: .tail) // at the end
177
+ try await player.queue.insert(nextUp, position: .afterCurrentEntry) // play next
215
178
  ```
216
179
 
217
- ## Now Playing Info
180
+ ## Now Playing info
218
181
 
219
- Update `MPNowPlayingInfoCenter` so the Lock Screen, Control Center, and CarPlay
220
- display current track metadata. This is essential when playing custom audio
221
- (non-MusicKit sources). `ApplicationMusicPlayer` handles this automatically for
222
- Apple Music content.
182
+ `MPNowPlayingInfoCenter` feeds the Lock Screen, Control Center and CarPlay.
183
+ When `ApplicationMusicPlayer` plays Apple Music content, the system fills this
184
+ in for you. Write it yourself only for audio the app plays some other way, such
185
+ as an `AVPlayer` streaming podcasts.
223
186
 
224
187
  ```swift
225
- import MediaPlayer
226
-
227
- func updateNowPlaying(title: String, artist: String, duration: TimeInterval, elapsed: TimeInterval) {
228
- var info = [String: Any]()
229
- info[MPMediaItemPropertyTitle] = title
230
- info[MPMediaItemPropertyArtist] = artist
231
- info[MPMediaItemPropertyPlaybackDuration] = duration
232
- info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = elapsed
233
- info[MPNowPlayingInfoPropertyPlaybackRate] = 1.0
234
- info[MPNowPlayingInfoPropertyMediaType] = MPNowPlayingInfoMediaType.audio.rawValue
235
-
236
- MPNowPlayingInfoCenter.default().nowPlayingInfo = info
188
+ func publishNowPlaying(for episode: Episode, position: TimeInterval) {
189
+ MPNowPlayingInfoCenter.default().nowPlayingInfo = [
190
+ MPMediaItemPropertyTitle: episode.title,
191
+ MPMediaItemPropertyArtist: episode.showName,
192
+ MPMediaItemPropertyPlaybackDuration: episode.length,
193
+ MPNowPlayingInfoPropertyElapsedPlaybackTime: position,
194
+ MPNowPlayingInfoPropertyPlaybackRate: 1.0,
195
+ MPNowPlayingInfoPropertyMediaType: MPNowPlayingInfoMediaType.audio.rawValue
196
+ ]
237
197
  }
238
198
 
239
199
  func clearNowPlaying() {
@@ -241,184 +201,98 @@ func clearNowPlaying() {
241
201
  }
242
202
  ```
243
203
 
244
- ### Adding Artwork
204
+ Artwork goes in under `MPMediaItemPropertyArtwork`. Merge it into the existing
205
+ dictionary rather than replacing the whole thing:
245
206
 
246
207
  ```swift
247
- func setArtwork(_ image: UIImage) {
248
- let artwork = MPMediaItemArtwork(boundsSize: image.size) { _ in image }
208
+ func attachCover(_ cover: UIImage) {
209
+ let art = MPMediaItemArtwork(boundsSize: cover.size) { _ in cover }
249
210
  var info = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:]
250
- info[MPMediaItemPropertyArtwork] = artwork
211
+ info[MPMediaItemPropertyArtwork] = art
251
212
  MPNowPlayingInfoCenter.default().nowPlayingInfo = info
252
213
  }
253
214
  ```
254
215
 
255
- ## Remote Command Center
256
-
257
- Register handlers for `MPRemoteCommandCenter` to respond to Lock Screen controls,
258
- AirPods tap gestures, and CarPlay buttons.
216
+ Refresh the elapsed time on a timer or at each seek, so the Lock Screen
217
+ scrubber stays accurate.
259
218
 
260
- ```swift
261
- func setupRemoteCommands() {
262
- let center = MPRemoteCommandCenter.shared()
263
-
264
- center.playCommand.addTarget { _ in
265
- resumePlayback()
266
- return .success
267
- }
268
-
269
- center.pauseCommand.addTarget { _ in
270
- pausePlayback()
271
- return .success
272
- }
219
+ ## Remote commands
273
220
 
274
- center.nextTrackCommand.addTarget { _ in
275
- skipToNext()
276
- return .success
277
- }
221
+ `MPRemoteCommandCenter.shared()` receives Lock Screen buttons, AirPods taps and
222
+ CarPlay controls. Register the handlers from the main actor so they can call a
223
+ main-actor engine directly; `EpisodeEngine` stands for that type.
278
224
 
279
- center.previousTrackCommand.addTarget { _ in
280
- skipToPrevious()
281
- return .success
282
- }
225
+ ```swift
226
+ @MainActor
227
+ func wireRemoteControls(to engine: EpisodeEngine) {
228
+ let commands = MPRemoteCommandCenter.shared()
283
229
 
284
- // Disable commands you do not support
285
- center.seekForwardCommand.isEnabled = false
286
- center.seekBackwardCommand.isEnabled = false
287
- }
288
- ```
230
+ commands.playCommand.addTarget { _ in engine.resume(); return .success }
231
+ commands.pauseCommand.addTarget { _ in engine.suspend(); return .success }
232
+ commands.nextTrackCommand.addTarget { _ in engine.advance(); return .success }
233
+ commands.previousTrackCommand.addTarget { _ in engine.rewind(); return .success }
289
234
 
290
- ### Scrubbing Support
235
+ commands.seekForwardCommand.isEnabled = false
236
+ commands.seekBackwardCommand.isEnabled = false
291
237
 
292
- ```swift
293
- func enableScrubbing() {
294
- let center = MPRemoteCommandCenter.shared()
295
- center.changePlaybackPositionCommand.addTarget { event in
296
- guard let positionEvent = event as? MPChangePlaybackPositionCommandEvent else {
238
+ commands.changePlaybackPositionCommand.addTarget { event in
239
+ guard let jump = event as? MPChangePlaybackPositionCommandEvent else {
297
240
  return .commandFailed
298
241
  }
299
- seek(to: positionEvent.positionTime)
242
+ engine.move(to: jump.positionTime)
300
243
  return .success
301
244
  }
302
245
  }
303
246
  ```
304
247
 
305
- ## Common Mistakes
306
-
307
- ### DON'T: Skip MusicKit App Service setup or usage description
308
-
309
- Without the MusicKit App Service on the app's explicit bundle ID, automatic
310
- developer token generation for Apple Music API requests is not configured.
311
- Without `NSAppleMusicUsageDescription`, the app cannot access the user's media
312
- library on Apple platforms that require the purpose string.
313
-
314
- ```swift
315
- // WRONG: MusicKit App Service not enabled for this bundle ID
316
-
317
- // CORRECT: Enable MusicKit App Service in the developer portal,
318
- // set the matching bundle ID, then add NSAppleMusicUsageDescription.
319
- let status = await MusicAuthorization.request()
320
- ```
321
-
322
- ### DON'T: Forget to check subscription before playback
323
-
324
- Attempting to play catalog content without a subscription silently fails or throws.
325
-
326
- ```swift
327
- // WRONG
328
- func play(_ song: Song) async throws {
329
- player.queue = [song]
330
- try await player.play() // Fails if no subscription
331
- }
332
-
333
- // CORRECT
334
- func play(_ song: Song) async throws {
335
- let sub = try await MusicSubscription.current
336
- guard sub.canPlayCatalogContent else {
337
- showSubscriptionOffer()
338
- return
339
- }
340
- player.queue = [song]
341
- try await player.play()
342
- }
343
- ```
344
-
345
- ### DON'T: Use SystemMusicPlayer when you mean ApplicationMusicPlayer
346
-
347
- `SystemMusicPlayer` controls the global Music app queue. Changes affect the user's
348
- Music app state. Use `ApplicationMusicPlayer` for app-scoped playback.
349
-
350
- ```swift
351
- // WRONG: Modifies the user's Music app queue
352
- let player = SystemMusicPlayer.shared
353
-
354
- // CORRECT: App-scoped playback
355
- let player = ApplicationMusicPlayer.shared
356
- ```
357
-
358
- ### DON'T: Forget to update Now Playing info when track changes
359
-
360
- Stale metadata on the Lock Screen confuses users. Update Now Playing info
361
- every time the current track changes.
362
-
363
- ```swift
364
- // WRONG: Set once and forget
365
- updateNowPlaying(title: firstSong.title, ...)
366
-
367
- // CORRECT: Update on every track change
368
- func onTrackChanged(_ song: Song) {
369
- updateNowPlaying(
370
- title: song.title,
371
- artist: song.artistName,
372
- duration: song.duration ?? 0,
373
- elapsed: 0
374
- )
375
- }
376
- ```
377
-
378
- ### DON'T: Register remote commands without handling them
379
-
380
- Registering a command but returning `.commandFailed` breaks Lock Screen controls.
381
- Disable commands you do not support instead.
382
-
383
- ```swift
384
- // WRONG
385
- center.skipForwardCommand.addTarget { _ in .commandFailed }
386
-
387
- // CORRECT
388
- center.skipForwardCommand.isEnabled = false
389
- ```
390
-
391
- ## Review Checklist
392
-
393
- - [ ] MusicKit App Service enabled for the app's explicit bundle ID
394
- - [ ] `NSAppleMusicUsageDescription` added to Info.plist
395
- - [ ] `MusicAuthorization.request()` called before any MusicKit access
396
- - [ ] Subscription checked before attempting catalog playback
397
- - [ ] `canBecomeSubscriber` checked before presenting a subscription offer
248
+ ## Common mistakes
249
+
250
+ - **Skipping portal or plist setup.** Without the MusicKit App Service there is
251
+ no automatic developer token; without `NSAppleMusicUsageDescription`, library
252
+ access fails where it is required.
253
+ - **Playing catalog items without a subscription.** Playback fails quietly or
254
+ throws. Check `canPlayCatalogContent` first and show the offer when it is
255
+ false.
256
+ - **Reaching for `SystemMusicPlayer`.** It drives the Music app's global queue
257
+ and changes the user's own listening state. App-scoped playback belongs in
258
+ `ApplicationMusicPlayer`.
259
+ - **Stale Now Playing data.** For custom audio, rewrite the dictionary on every
260
+ track change: title, artist, duration (use `track.duration ?? 0` when it is
261
+ optional) and an elapsed time reset to 0.
262
+ - **Registering commands you cannot honor.** A handler that returns
263
+ `.commandFailed` leaves a dead button on the Lock Screen. Turn the command off
264
+ instead, for example `MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = false`.
265
+
266
+ ## Review checklist
267
+
268
+ - [ ] MusicKit App Service enabled on the explicit App ID
269
+ - [ ] `NSAppleMusicUsageDescription` present
270
+ - [ ] `MusicAuthorization.request()` runs before any MusicKit access
271
+ - [ ] Subscription checked before catalog playback
272
+ - [ ] `canBecomeSubscriber` checked before the offer is shown
273
+ - [ ] Offer shown when the user is not subscribed
398
274
  - [ ] `hasCloudLibraryEnabled` checked before library writes
399
- - [ ] `ApplicationMusicPlayer` used (not `SystemMusicPlayer`) for app-scoped playback
400
- - [ ] Background audio mode enabled if music plays in background
401
- - [ ] Now Playing info updated on every track change (for custom audio)
402
- - [ ] Remote command handlers return `.success` for supported commands
403
- - [ ] Unsupported remote commands disabled with `isEnabled = false`
404
- - [ ] Artwork provided in Now Playing info for Lock Screen display
405
- - [ ] Elapsed playback time updated periodically for scrubber accuracy
406
- - [ ] Subscription offer presented when user lacks Apple Music subscription
275
+ - [ ] `ApplicationMusicPlayer` used, not `SystemMusicPlayer`
276
+ - [ ] `audio` background mode set if playback continues in the background
277
+ - [ ] Now Playing updated on each track change (custom audio)
278
+ - [ ] Artwork supplied for the Lock Screen
279
+ - [ ] Elapsed time refreshed so the scrubber is accurate
280
+ - [ ] Supported remote commands return `.success`; unsupported ones are disabled
407
281
 
408
282
  ## References
409
283
 
410
- - Extended patterns (SwiftUI integration, genre browsing, playlist management): [references/musickit-patterns.md](references/musickit-patterns.md)
411
- - [MusicKit framework](https://sosumi.ai/documentation/musickit)
412
- - [Using automatic developer token generation for Apple Music API](https://sosumi.ai/documentation/musickit/using-automatic-token-generation-for-apple-music-api)
413
- - [MusicAuthorization](https://sosumi.ai/documentation/musickit/musicauthorization)
414
- - [ApplicationMusicPlayer](https://sosumi.ai/documentation/musickit/applicationmusicplayer)
415
- - [MusicCatalogSearchRequest](https://sosumi.ai/documentation/musickit/musiccatalogsearchrequest)
416
- - [MusicSubscription](https://sosumi.ai/documentation/musickit/musicsubscription)
417
- - [canPlayCatalogContent](https://sosumi.ai/documentation/musickit/musicsubscription/canplaycatalogcontent)
418
- - [canBecomeSubscriber](https://sosumi.ai/documentation/musickit/musicsubscription/canbecomesubscriber)
419
- - [hasCloudLibraryEnabled](https://sosumi.ai/documentation/musickit/musicsubscription/hascloudlibraryenabled)
420
- - [MusicCatalogChartsRequest initializer](https://sosumi.ai/documentation/musickit/musiccatalogchartsrequest/init(genre:kinds:types:))
421
- - [musicSubscriptionOffer(isPresented:options:onLoadCompletion:)](https://sosumi.ai/documentation/swiftui/view/musicsubscriptionoffer(ispresented:options:onloadcompletion:))
422
- - [MPRemoteCommandCenter](https://sosumi.ai/documentation/mediaplayer/mpremotecommandcenter)
423
- - [MPNowPlayingInfoCenter](https://sosumi.ai/documentation/mediaplayer/mpnowplayinginfocenter)
424
- - [NSAppleMusicUsageDescription](https://sosumi.ai/documentation/bundleresources/information-property-list/nsapplemusicusagedescription)
284
+ - [references/musickit-patterns.md](references/musickit-patterns.md)
285
+ - [MusicKit](https://developer.apple.com/documentation/musickit)
286
+ - [Using automatic developer token generation](https://developer.apple.com/documentation/musickit/using-automatic-developer-token-generation-for-apple-music-api)
287
+ - [MusicAuthorization](https://developer.apple.com/documentation/musickit/musicauthorization)
288
+ - [ApplicationMusicPlayer](https://developer.apple.com/documentation/musickit/applicationmusicplayer)
289
+ - [MusicCatalogSearchRequest](https://developer.apple.com/documentation/musickit/musiccatalogsearchrequest)
290
+ - [MusicSubscription](https://developer.apple.com/documentation/musickit/musicsubscription)
291
+ - [canPlayCatalogContent](https://developer.apple.com/documentation/musickit/musicsubscription/canplaycatalogcontent)
292
+ - [canBecomeSubscriber](https://developer.apple.com/documentation/musickit/musicsubscription/canbecomesubscriber)
293
+ - [hasCloudLibraryEnabled](https://developer.apple.com/documentation/musickit/musicsubscription/hascloudlibraryenabled)
294
+ - [MusicCatalogChartsRequest init(genre:kinds:types:)](https://developer.apple.com/documentation/musickit/musiccatalogchartsrequest/init(genre:kinds:types:))
295
+ - [musicSubscriptionOffer(isPresented:options:onLoadCompletion:)](https://developer.apple.com/documentation/swiftui/view/musicsubscriptionoffer(ispresented:options:onloadcompletion:))
296
+ - [MPRemoteCommandCenter](https://developer.apple.com/documentation/mediaplayer/mpremotecommandcenter)
297
+ - [MPNowPlayingInfoCenter](https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter)
298
+ - [NSAppleMusicUsageDescription](https://developer.apple.com/documentation/bundleresources/information-property-list/nsapplemusicusagedescription)