@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.1

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 (284) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +285 -285
  5. package/package.json +3 -3
  6. package/pipeline/lib/redact.mjs +3 -2
  7. package/pipeline/scripts/_notices.mjs +1 -1
  8. package/pipeline/scripts/gen-skills-index.mjs +13 -1
  9. package/pipeline/scripts/pre-commit-check.sh +4 -0
  10. package/pipeline/skills/.skill-manifest.json +69 -69
  11. package/pipeline/skills/shared/README.md +70 -70
  12. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  13. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  14. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  15. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  16. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  17. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  18. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  19. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  20. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  21. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  22. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  23. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +345 -277
  24. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  25. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +107 -121
  26. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +145 -165
  27. package/pipeline/skills/shared/external/app-store-review/SKILL.md +306 -326
  28. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  29. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  30. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  31. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +335 -360
  32. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  34. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  35. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  36. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  37. package/pipeline/skills/shared/external/authentication/SKILL.md +277 -381
  38. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  39. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +135 -178
  40. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  41. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  42. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  43. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  44. package/pipeline/skills/shared/external/background-processing/SKILL.md +274 -384
  45. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  46. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +173 -321
  47. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  48. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  49. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  50. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  51. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  52. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  53. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  54. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  55. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  56. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +228 -376
  57. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  58. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  59. package/pipeline/skills/shared/external/core-data/SKILL.md +302 -368
  60. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  61. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  62. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  63. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  64. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  65. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  66. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  67. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  68. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  69. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  70. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  71. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  72. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  73. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  74. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  75. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  76. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  77. package/pipeline/skills/shared/external/device-integrity/SKILL.md +236 -353
  78. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  79. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  80. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  81. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  82. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  83. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  84. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  85. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  86. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  87. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  88. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  89. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  90. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  91. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  92. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  93. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  94. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  95. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  96. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  97. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  98. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  99. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  100. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  101. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  102. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  103. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  104. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  105. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  106. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  107. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  108. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  109. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  111. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  112. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  113. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  114. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +3 -3
  115. package/pipeline/skills/shared/external/localization-reuse-map/example-mapping.json +1 -1
  116. package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +8 -7
  117. package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +2 -2
  118. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +5 -2
  119. package/pipeline/skills/shared/external/localization-reuse-map/scripts/_shared.py +100 -0
  120. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +45 -26
  121. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +14 -16
  122. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +12 -5
  123. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +2 -1
  124. package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +6 -5
  125. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +44 -18
  126. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +5 -2
  127. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +10 -11
  128. package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +4 -33
  129. package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +12 -59
  130. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +297 -267
  131. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  132. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  133. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  134. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  135. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  136. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  137. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  138. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  139. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  140. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  141. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  142. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  143. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  144. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  145. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  146. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  147. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  148. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  149. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  150. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  151. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  152. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  153. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  154. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  155. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  156. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  157. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  158. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  159. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  160. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  161. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  162. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  163. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  164. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  165. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  166. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  167. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  168. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  169. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  170. package/pipeline/skills/shared/external/skill-creator/template.md +7 -1
  171. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  172. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  173. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  174. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  175. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  176. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  177. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +302 -241
  178. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  179. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  180. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  181. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  182. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  183. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  184. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  185. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  186. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  187. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  188. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  189. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  190. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  191. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  192. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +304 -351
  193. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  194. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  195. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  196. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  197. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  198. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  199. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  200. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  201. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  202. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  203. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  204. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  205. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  206. package/pipeline/skills/shared/external/swift-security/SKILL.md +183 -162
  207. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  208. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  209. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +411 -476
  210. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  211. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  212. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  213. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  214. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  215. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  216. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +375 -491
  217. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  218. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  219. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  220. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +397 -457
  221. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  222. package/pipeline/skills/shared/external/swift-testing/SKILL.md +191 -175
  223. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  224. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +81 -84
  225. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  226. package/pipeline/skills/shared/external/swiftdata/SKILL.md +394 -256
  227. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  228. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  229. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  230. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  231. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  232. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  233. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  234. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  235. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  236. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  237. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  238. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  239. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  240. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  241. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  242. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  243. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  244. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  245. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  246. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  247. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  248. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  249. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  250. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  251. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +201 -168
  252. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  253. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +134 -133
  254. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  255. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +111 -138
  256. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  257. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  258. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  259. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  260. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  261. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  262. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  263. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  264. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  265. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  266. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  267. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  268. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  269. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  270. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  271. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  272. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  273. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  274. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  275. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  276. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  277. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  278. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  279. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  280. package/pipeline/skills/shared/external/weatherkit/SKILL.md +160 -315
  281. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  282. package/pipeline/skills/shared/external/widgetkit/SKILL.md +224 -288
  283. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +416 -719
  284. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,272 +1,296 @@
1
1
  ---
2
2
  name: storekit
3
- description: "Implement, review, or improve in-app purchases and subscriptions using StoreKit 2. Use when building paywalls with SubscriptionStoreView or ProductView, processing transactions with Product and Transaction APIs, verifying entitlements, handling purchase flows (consumable, non-consumable, auto-renewable), implementing offer codes or promotional/win-back/introductory offers, managing subscription status and renewal state, setting up StoreKit testing with configuration files, or integrating Family Sharing, Ask to Buy, refund handling, and billing retry logic."
3
+ description: "StoreKit 2 in-app purchases and subscriptions: SubscriptionStoreView, StoreView and ProductView paywalls, consumable, non-consumable and auto-renewable purchase flows, Product and Transaction APIs, entitlement verification, subscription status and renewal, offer codes, introductory, promotional and win-back offers, configuration file testing, Family Sharing, Ask to Buy, refunds, billing retry. Use when building or reviewing purchase, paywall, entitlement or subscription code. Not for App Store review (app-store-review) or ASO (app-store-optimization)."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
- # StoreKit 2 In-App Purchases and Subscriptions
9
-
10
- Implement in-app purchases, subscriptions, paywalls, and StoreKit testing using
11
- StoreKit 2 on iOS 26+. Use the modern Swift-based `Product`, `Transaction`,
12
- `PurchaseAction`, `StoreView`, and `SubscriptionStoreView` APIs. Avoid original
13
- In-App Purchase APIs (`SKProduct`, `SKPaymentQueue`) unless legacy OS support
14
- requires them.
15
-
16
- When reviewing StoreKit code, explicitly separate "preferred SwiftUI path" from
17
- "invalid API": `PurchaseAction` is the preferred custom SwiftUI button path, but
18
- direct `product.purchase(options:)` is still valid for lower-level custom
19
- StoreKit flows.
20
-
21
- Full, copyable code for the core flows lives in
22
- [references/core-patterns.md](references/core-patterns.md). This guide keeps the
23
- review guidance and short snippets; load the reference for a complete example.
24
-
25
- ## Contents
26
-
27
- - [Implementation Review Minimums](#implementation-review-minimums)
28
- - [Product Types](#product-types)
29
- - [Loading Products](#loading-products)
30
- - [Purchase Flow](#purchase-flow)
31
- - [Transaction.updates Listener](#transactionupdates-listener)
32
- - [Entitlement Checking](#entitlement-checking)
33
- - [Store Views (SubscriptionStoreView, StoreView, ProductView)](#store-views-subscriptionstoreview-storeview-productview)
34
- - [Subscription Status Checking](#subscription-status-checking)
35
- - [Restore Purchases](#restore-purchases)
36
- - [App Transaction](#app-transaction)
37
- - [Purchase Options](#purchase-options)
38
- - [SwiftUI Purchase Callbacks](#swiftui-purchase-callbacks)
39
- - [Common Mistakes](#common-mistakes)
40
- - [Review Checklist](#review-checklist)
41
- - [References](#references)
8
+ # StoreKit 2
9
+
10
+ StoreKit 2 is the Swift-native purchase API: `Product` describes what you
11
+ sell, `Transaction` records what the user owns, and SwiftUI supplies
12
+ `PurchaseAction`, `StoreView`, `ProductView` and `SubscriptionStoreView` to
13
+ sell it. This skill targets iOS 26 and names the release where each API
14
+ appeared, because older deployment targets change what you may call.
15
+
16
+ The original In-App Purchase API (`SKProduct`, `SKPaymentQueue`,
17
+ `SKProductsRequest`) stays out of new code. Use it only when an old OS
18
+ version forces you to.
19
+
20
+ Two review rules shape everything below:
21
+
22
+ - Separate "the preferred SwiftUI path" from "an invalid API". For a custom
23
+ SwiftUI buy button, `PurchaseAction` is preferred; calling
24
+ `product.purchase(options:)` directly is still correct for flows that need
25
+ low-level control. Never call the direct call wrong in itself.
26
+ - This file carries the rules and short snippets. Complete code for each core
27
+ flow is in [references/core-patterns.md](references/core-patterns.md).
28
+
29
+ Where neighbouring work goes:
30
+
31
+ | Topic | Skill |
32
+ |-------|-------|
33
+ | Submission readiness, privacy manifests, ATT, metadata, screenshots, rejection audits | `app-store-review` |
34
+ | Keywords, ranking, screenshot captions, conversion strategy | `app-store-optimization` |
35
+
36
+ In a file that imports SwiftUI, the bare name `Transaction` clashes with
37
+ SwiftUI's animation transaction when used as a type. Write
38
+ `StoreKit.Transaction` there.
42
39
 
43
40
  ## Implementation Review Minimums
44
41
 
45
- When reviewing a paywall, purchase manager, or entitlement gate, include these
46
- points explicitly:
47
-
48
- - Standard SwiftUI paywalls should prefer `StoreView`, `ProductView`, or
49
- `SubscriptionStoreView`; custom SwiftUI buy buttons should prefer
50
- `PurchaseAction`; direct `product.purchase(options:)` is valid for
51
- lower-level custom StoreKit flows.
52
- - `Transaction.updates` must start at app launch because it catches purchases
53
- from other devices, Family Sharing changes, renewals, Ask to Buy approvals,
54
- refunds, revocations, and unfinished transactions.
55
- - Include this entitlement-scope sentence verbatim when reviewing
56
- `Transaction.currentEntitlements`: "It covers non-consumables, active or
57
- grace-period auto-renewable subscriptions, and non-renewing subscriptions; it
58
- does not include consumable purchase or delivery history."
59
- - Verify every `VerificationResult` before granting access. Deliver or persist
60
- the entitlement first, then call `transaction.finish()`.
61
- - Pending purchases and user cancellations never unlock content; pending Ask to
62
- Buy approvals unlock only after a verified transaction arrives through the
63
- launch-time listener.
64
- - Exclude refunded or revoked transactions from active entitlement state and
65
- re-check entitlements when refunds or revocations arrive through
66
- `Transaction.updates`.
67
- - Provide a visible restore purchases path and Terms of Service / Privacy
68
- Policy links on subscription paywalls.
42
+ When you review a paywall, a purchase manager or an entitlement gate, say each
43
+ of these out loud, even when the code already gets it right:
44
+
45
+ 1. Standard SwiftUI paywalls use `StoreView`, `ProductView` or
46
+ `SubscriptionStoreView`; custom SwiftUI buy buttons use `PurchaseAction`.
47
+ 2. `Transaction.updates` is iterated from app launch. That is the only place
48
+ the app hears about purchases made on another device, Family Sharing
49
+ changes, renewals, Ask to Buy approvals, refunds, revocations and
50
+ transactions left unfinished last time.
51
+ 3. When `Transaction.currentEntitlements` comes up, include this sentence
52
+ verbatim: "`Transaction.currentEntitlements` covers non-consumables, active
53
+ or grace-period auto-renewable subscriptions, and non-renewing
54
+ subscriptions; it does not include consumable purchase or delivery
55
+ history."
56
+ 4. Every `VerificationResult` is checked before access is granted.
57
+ 5. Content is delivered or the entitlement persisted first, and only then is
58
+ `transaction.finish()` called.
59
+ 6. A pending purchase or a cancelled one never unlocks anything. A pending Ask
60
+ to Buy purchase unlocks when the approved, verified transaction arrives on
61
+ the launch-time listener.
62
+ 7. Refunded or revoked transactions are excluded from entitlement state, and
63
+ entitlements are recomputed when a refund or revocation arrives on
64
+ `Transaction.updates`.
65
+ 8. A subscription paywall shows a restore path and links to Terms of Service
66
+ and the Privacy Policy.
69
67
 
70
68
  ## Product Types
71
69
 
72
- | Type | Enum Case | Behavior |
73
- |---|---|---|
74
- | **Consumable** | `.consumable` | Used once, can be repurchased (gems, coins) |
75
- | **Non-consumable** | `.nonConsumable` | Purchased once permanently (premium unlock) |
76
- | **Auto-renewable** | `.autoRenewable` | Recurring billing with automatic renewal |
77
- | **Non-renewing** | `.nonRenewing` | Time-limited access without automatic renewal |
70
+ | Kind | `Product.ProductType` | Behaviour | Example |
71
+ |------|----------------------|-----------|---------|
72
+ | Consumable | `.consumable` | used up, can be bought again | hint packs, credits |
73
+ | Non-consumable | `.nonConsumable` | bought once, kept forever | pro unlock |
74
+ | Auto-renewable | `.autoRenewable` | billed on a schedule until cancelled | monthly plan |
75
+ | Non-renewing | `.nonRenewing` | access for a fixed period, no renewal | season pass |
78
76
 
79
77
  ## Loading Products
80
78
 
81
- Define product IDs as constants. Fetch products with `Product.products(for:)`.
79
+ Keep identifiers in one place and fetch them together:
82
80
 
83
81
  ```swift
84
- enum ProductID {
85
- static let premium = "com.myapp.premium"
86
- static let monthlyPlan = "com.myapp.monthly"
87
- static let all: [String] = [premium, monthlyPlan]
82
+ import StoreKit
83
+
84
+ enum StoreItem {
85
+ static let proUnlock = "com.example.recipes.pro"
86
+ static let monthly = "com.example.recipes.monthly"
87
+ static let annual = "com.example.recipes.annual"
88
+ static let everything = [proUnlock, monthly, annual]
88
89
  }
89
90
 
90
- let products = try await Product.products(for: ProductID.all)
91
+ func loadCatalog() async throws -> [Product] {
92
+ try await Product.products(for: StoreItem.everything)
93
+ }
91
94
  ```
92
95
 
93
96
  ## Purchase Flow
94
97
 
95
- Prefer StoreKit views for standard paywalls because they initiate purchases,
96
- restore purchases, and display policy controls. For custom SwiftUI purchase
97
- buttons, prefer `PurchaseAction` from the environment. Use direct
98
- `product.purchase(options:)` only for lower-level custom flows, and use
99
- `purchase(confirmIn:options:)` for UIKit or AppKit confirmation. Always handle
100
- every `PurchaseResult`, verify before access, deliver durably, then finish.
98
+ Pick the entry point by how much control you need:
101
99
 
102
- Review wording: do not call `product.purchase(options:)` inherently wrong. Say
103
- "prefer `PurchaseAction` for SwiftUI buttons; keep `product.purchase(options:)`
104
- for lower-level custom flows that need direct StoreKit control."
100
+ | Need | Use | Since |
101
+ |------|-----|-------|
102
+ | Standard paywall | `StoreView`, `ProductView`, `SubscriptionStoreView`; they buy, restore and show policy links | iOS 17 |
103
+ | Custom SwiftUI button | `@Environment(\.purchase)` (`PurchaseAction`) | iOS 17 |
104
+ | Low-level custom flow | `product.purchase(options:)` | iOS 15 |
105
+ | UIKit or AppKit confirmation sheet | `product.purchase(confirmIn:options:)` | iOS 17 |
105
106
 
106
- Full purchase-flow example with `checkVerified` and `.pending` handling:
107
- references/core-patterns.md#purchase-flow
107
+ Whatever the entry point, handle every `PurchaseResult` case, verify before
108
+ granting, persist the delivery, then finish. In a review, recommend
109
+ `PurchaseAction` for SwiftUI buttons and leave direct `purchase(options:)` in
110
+ place where the flow genuinely needs it; do not flag it as a bug. The full
111
+ flow with the `verified(_:)` helper and `.pending` handling is at
112
+ [core-patterns.md#buying-with-purchaseaction](references/core-patterns.md#buying-with-purchaseaction).
108
113
 
109
114
  ## Transaction.updates Listener
110
115
 
111
- Start at app launch, not when a paywall appears. Catches purchases from other
112
- devices, Family Sharing changes, renewals, Ask to Buy approvals, refunds,
113
- revocations, and unfinished transactions Apple emits once immediately after
114
- launch. Keep the task retained for the app lifetime.
116
+ - Start it when the app launches, never when a paywall appears.
117
+ - It delivers other-device purchases, Family Sharing changes, renewals, Ask
118
+ to Buy approvals, refunds and revocations.
119
+ - Right after launch it also delivers, once, every transaction that was never
120
+ finished.
121
+ - Keep the task alive for the whole life of the app.
115
122
 
116
- In implementation reviews, name the launch-time coverage explicitly: purchases
117
- made on other devices, Family Sharing changes, subscription renewals, Ask to Buy
118
- approvals, refunds, revocations, and unfinished transactions.
119
-
120
- Full launch-time listener wired into `App.init`:
121
- references/core-patterns.md#transactionupdates-listener
123
+ In a review, list those event kinds by name. The listener wired into
124
+ `App.init` is at
125
+ [core-patterns.md#launch-time-transaction-listener](references/core-patterns.md#launch-time-transaction-listener).
122
126
 
123
127
  ## Entitlement Checking
124
128
 
125
- Use `Transaction.currentEntitlements` for non-consumables, active or grace
126
- period auto-renewable subscriptions, and non-renewing subscriptions. It excludes
127
- consumables and consumable delivery history; track consumable fulfillment in
128
- your own app or server ledger. It also excludes refunded or revoked
129
- transactions. Use `Transaction.unfinished` for unfinished consumables and
130
- recovery sweeps. Always check `revocationDate` when processing transactions.
131
-
132
- In reviews, include this sentence verbatim: "Transaction.currentEntitlements
133
- covers non-consumables, active or grace-period auto-renewable subscriptions, and
134
- non-renewing subscriptions; it does not include consumable purchase or delivery
135
- history." Do not replace this with only a code sample or a revocation check.
136
-
137
- Full `StoreManager.updateEntitlements()` and the `.currentEntitlementTask`
138
- SwiftUI gate: references/core-patterns.md#entitlement-checking
139
-
140
- ## Store Views (SubscriptionStoreView, StoreView, ProductView)
141
-
142
- `SubscriptionStoreView(groupID:)` is the built-in subscription paywall; it loads
143
- products, runs the purchase UI, and can expose restore and policy controls.
144
- `StoreView(ids:)` merchandises multiple products, and `ProductView(id:)` renders
145
- a single product. All expose `.onInAppPurchaseCompletion` and
129
+ - `Transaction.currentEntitlements` covers non-consumables, active or
130
+ grace-period auto-renewable subscriptions, and non-renewing subscriptions.
131
+ - It does not contain consumables or their delivery history; record consumable
132
+ fulfilment in your own ledger, on device or on a server.
133
+ - It leaves out refunded and revoked transactions, but still check
134
+ `revocationDate` whenever you process a transaction.
135
+ - `Transaction.unfinished` is the sweep for unfinished consumables and
136
+ recovery.
137
+ - For one product, `Transaction.currentEntitlements(for:)` (iOS 18.4) replaces
138
+ `Transaction.currentEntitlement(for:)`, deprecated in iOS 18.4.
139
+
140
+ In a review the verbatim scope sentence from the minimums is required; a code
141
+ sample or a revocation check alone does not replace it. The full
142
+ `refresh()` and the `.currentEntitlementTask` gate are at
143
+ [core-patterns.md#computing-entitlements](references/core-patterns.md#computing-entitlements).
144
+
145
+ ## Store Views
146
+
147
+ `SubscriptionStoreView(groupID:)` is a complete subscription paywall: it
148
+ loads products, runs the purchase sheet and can show restore and policy
149
+ controls. `StoreView(ids:)` sells several products; `ProductView(id:)` shows
150
+ one. All three are iOS 17 and all accept `.onInAppPurchaseCompletion` and
146
151
  `.storeButton(.visible, for: .restorePurchases)`.
147
152
 
148
153
  ```swift
149
- SubscriptionStoreView(groupID: "YOUR_GROUP_ID")
150
- .storeButton(.visible, for: .restorePurchases)
151
- .subscriptionStorePolicyDestination(url: termsURL, for: .termsOfService)
152
- .subscriptionStorePolicyDestination(url: privacyURL, for: .privacyPolicy)
154
+ import StoreKit
155
+ import SwiftUI
156
+
157
+ struct PlanPicker: View {
158
+ let group: String
159
+ let terms: URL
160
+ let privacy: URL
161
+
162
+ var body: some View {
163
+ SubscriptionStoreView(groupID: group)
164
+ .storeButton(.visible, for: .restorePurchases)
165
+ .subscriptionStorePolicyDestination(url: terms, for: .termsOfService)
166
+ .subscriptionStorePolicyDestination(url: privacy, for: .privacyPolicy)
167
+ }
168
+ }
153
169
  ```
154
170
 
155
- Full paywall, custom marketing content, `StoreView`, and `ProductView` examples:
156
- references/core-patterns.md#subscriptionstoreview and
157
- references/core-patterns.md#storeview-and-productview
158
-
159
- For control styles, hierarchical option layouts, offers, and container
160
- backgrounds see [references/storekit-advanced.md](references/storekit-advanced.md).
171
+ Complete examples are at
172
+ [core-patterns.md#subscription-paywall](references/core-patterns.md#subscription-paywall)
173
+ and [core-patterns.md#product-shelves-storeview-and-productview](references/core-patterns.md#product-shelves-storeview-and-productview).
174
+ Control styles, grouped layouts, offers and backgrounds are in
175
+ [references/storekit-advanced.md](references/storekit-advanced.md).
161
176
 
162
177
  ## Subscription Status Checking
163
178
 
164
- Read status with `Product.SubscriptionInfo.status(for: groupID)`; treat
179
+ Read status with `Product.SubscriptionInfo.status(for: groupID)`. Count
165
180
  `.subscribed` and `.inGracePeriod` as active.
166
181
 
167
- | State | Meaning |
168
- |---|---|
169
- | `.subscribed` | Active subscription |
170
- | `.expired` | Subscription has expired |
171
- | `.inBillingRetryPeriod` | Payment failed, Apple is retrying |
172
- | `.inGracePeriod` | Payment failed but access continues during grace period |
173
- | `.revoked` | Apple refunded or revoked the subscription |
182
+ | `RenewalState` | Meaning |
183
+ |----------------|---------|
184
+ | `.subscribed` | active |
185
+ | `.expired` | ended |
186
+ | `.inBillingRetryPeriod` | a charge failed and Apple keeps retrying |
187
+ | `.inGracePeriod` | a charge failed, but access continues for the grace window |
188
+ | `.revoked` | refunded or revoked by Apple |
174
189
 
175
- Full status-check helper: references/core-patterns.md#subscription-status-checking.
176
- For renewal-state access decisions, expiration reasons, grace period, and billing
177
- retry see [references/storekit-advanced.md](references/storekit-advanced.md).
190
+ The helper is at
191
+ [core-patterns.md#is-a-plan-active](references/core-patterns.md#is-a-plan-active);
192
+ what to grant in each state, expiration reasons, grace period and billing retry
193
+ are in [references/storekit-advanced.md](references/storekit-advanced.md).
178
194
 
179
195
  ## Restore Purchases
180
196
 
181
- StoreKit 2 handles restoration via `Transaction.currentEntitlements`. Add a
182
- restore button or call `AppStore.sync()` explicitly.
197
+ In StoreKit 2 there is no separate restore step for data: whatever the user
198
+ owns shows up in `Transaction.currentEntitlements`. Still offer a restore
199
+ control. On a store view use `.storeButton(.visible, for: .restorePurchases)`;
200
+ in custom UI call `AppStore.sync()` and recompute:
183
201
 
184
202
  ```swift
185
- func restorePurchases() async throws {
203
+ func restoreTapped(using store: EntitlementStore) async throws {
186
204
  try await AppStore.sync()
187
- await StoreManager.shared.updateEntitlements()
205
+ await store.refresh()
188
206
  }
189
207
  ```
190
208
 
191
- On store views: `.storeButton(.visible, for: .restorePurchases)`
192
-
193
209
  ## App Transaction
194
210
 
195
- Verify the legitimacy of the app installation with `AppTransaction.shared`. Use
196
- for business model changes or detecting tampered installations (iOS 16+); read
197
- `originalAppVersion` / `originalPurchaseDate` on the verified result and restrict
198
- features on `.unverified`.
199
-
200
- Full `verifyAppPurchase()` example: references/core-patterns.md#app-transaction
211
+ `AppTransaction.shared` (iOS 16) proves the app install itself is genuine.
212
+ Use it when the business model changes, such as moving from a paid app to a
213
+ subscription while honouring earlier buyers, and to spot tampered installs.
214
+ From the verified value read `originalAppVersion` and `originalPurchaseDate`;
215
+ on `.unverified`, limit features. Full code at
216
+ [core-patterns.md#verifying-the-install-with-apptransaction](references/core-patterns.md#verifying-the-install-with-apptransaction).
201
217
 
202
218
  ## Purchase Options
203
219
 
204
- ```swift
205
- try await product.purchase(options: [.appAccountToken(UUID())]) // server reconciliation
206
- try await product.purchase(options: [.quantity(5)]) // consumable quantity
207
- try await product.purchase(options: [.simulatesAskToBuyInSandbox(true)]) // sandbox
208
- ```
220
+ | Option | Purpose |
221
+ |--------|---------|
222
+ | `.appAccountToken(uuid)` | ties the purchase to your account ID for server reconciliation |
223
+ | `.quantity(n)` | buys several of a consumable |
224
+ | `.simulatesAskToBuyInSandbox(true)` | forces the Ask to Buy flow in sandbox |
209
225
 
210
226
  ## SwiftUI Purchase Callbacks
211
227
 
212
- Store views expose `.onInAppPurchaseStart`, `.onInAppPurchaseCompletion`, and
213
- `.inAppPurchaseOptions`. In the completion handler, verify the transaction,
214
- deliver content, then `finish()`.
215
-
216
- Full callback example: references/core-patterns.md#swiftui-purchase-callbacks
228
+ Store views take `.onInAppPurchaseStart`, `.onInAppPurchaseCompletion` and
229
+ `.inAppPurchaseOptions`. In the completion handler: verify, deliver, finish.
230
+ Example at
231
+ [core-patterns.md#store-view-callbacks](references/core-patterns.md#store-view-callbacks).
217
232
 
218
233
  ## Common Mistakes
219
234
 
220
- The ten most common StoreKit 2 defects, each with a WRONG/CORRECT example, are in
221
- references/core-patterns.md#common-mistakes:
222
-
223
- 1. Not starting `Transaction.updates` at app launch
224
- 2. Forgetting `transaction.finish()`
225
- 3. Ignoring the verification result
226
- 4. Using original In-App Purchase APIs in new StoreKit 2 code
227
- 5. Not checking `revocationDate`
228
- 6. Hardcoding prices instead of `product.displayPrice`
229
- 7. Not handling the `.pending` purchase result
230
- 8. Checking entitlements only once at launch
231
- 9. Missing restore purchases button
232
- 10. Subscription views without Terms / Privacy policy links
235
+ Each has a wrong and a right version in
236
+ [core-patterns.md#ten-mistakes-fixed](references/core-patterns.md#ten-mistakes-fixed).
237
+
238
+ 1. No `Transaction.updates` listener at launch.
239
+ 2. Never calling `transaction.finish()`.
240
+ 3. Ignoring the verification result.
241
+ 4. `SKProduct` or `SKPaymentQueue` in new StoreKit 2 code.
242
+ 5. Not checking `revocationDate`.
243
+ 6. Prices typed into strings instead of `product.displayPrice`.
244
+ 7. No handling for `.pending`.
245
+ 8. Checking entitlements once at launch and never again.
246
+ 9. No restore purchases control.
247
+ 10. Subscription screens without Terms and Privacy links.
248
+
249
+ ## Old API to Current API
250
+
251
+ These replacements are regression facts; flag the left column in review.
252
+
253
+ | Stale code | Current code | Why |
254
+ |------------|--------------|-----|
255
+ | `Product.SubscriptionInfo.Status.status(for:)` | `Product.SubscriptionInfo.status(for:)` | the former does not exist |
256
+ | `transaction.offerType`, `transaction.offerID` | `transaction.offer?.type`, `transaction.offer?.id` | deprecated in iOS 17.2 |
257
+ | `.promotionalOffer(offerID:signature:)` and `.promotionalOffer(offerID:keyID:nonce:signature:timestamp:)` | `Product.PurchaseOption.promotionalOffer(_:compactJWS:)` | deprecated in iOS 26; the new call returns an array of options |
258
+ | `.subscriptionPromotionalOffer(offer:signature:)` on store views | `.subscriptionPromotionalOffer(offer:compactJWS:)` (iOS 26) | deprecated in iOS 26 |
259
+ | `Transaction.currentEntitlement(for:)` | `Transaction.currentEntitlements(for:)` | deprecated in iOS 18.4 |
260
+ | Showing every `winBackOffers` entry | only entries whose IDs are in the verified `renewalInfo.eligibleWinBackOfferIDs` | the raw list is not per user |
261
+ | `.purchaseDate(_:renewalBehavior: .default)` | `.purchaseDate(_:renewalBehavior:)` with `.renewUntilNow` or `.cancelImmediately`, from `StoreKitTest` | there is no `.default`; the option is test-only |
233
262
 
234
263
  ## Review Checklist
235
264
 
236
- - [ ] `Transaction.updates` listener starts at app launch in App init
237
- - [ ] All transactions verified before granting access
238
- - [ ] `transaction.finish()` called only after durable content delivery
239
- - [ ] Revoked/refunded transactions excluded and entitlement state updated
240
- - [ ] `.pending` result shows Ask to Buy/deferred-approval feedback
241
- - [ ] Restore purchases button visible on paywall and store views
242
- - [ ] Terms of Service and Privacy Policy links on subscription views
243
- - [ ] Prices shown using `product.displayPrice`, never hardcoded
244
- - [ ] Subscription terms (price, duration, renewal) clearly displayed
245
- - [ ] Free trial states post-trial pricing clearly
246
- - [ ] No original In-App Purchase APIs (`SKProduct`, `SKPaymentQueue`) unless legacy OS support requires them
247
- - [ ] Product IDs defined as constants, not scattered strings
248
- - [ ] StoreKit tests cover promotional offers, win-back, offer codes, Ask to Buy, renewals, refunds, and revocations
249
- - [ ] Entitlements re-checked on Transaction.updates and app foreground
250
- - [ ] Server-side validation uses `jwsRepresentation` if applicable
251
- - [ ] Consumables delivered and finished promptly
252
- - [ ] Transaction observer types and product model types are `Sendable` when shared across concurrency boundaries
265
+ - [ ] `Transaction.updates` listener starts in the `App` initializer
266
+ - [ ] Every transaction is verified before access
267
+ - [ ] `transaction.finish()` runs only after durable delivery
268
+ - [ ] Revoked and refunded transactions are excluded and entitlements refreshed
269
+ - [ ] `.pending` shows Ask to Buy or deferred-approval feedback
270
+ - [ ] Restore purchases is visible on the paywall and store views
271
+ - [ ] Subscription screens link to Terms of Service and the Privacy Policy
272
+ - [ ] Prices come from `product.displayPrice`
273
+ - [ ] Price, period and renewal terms are clear before purchase
274
+ - [ ] Free-trial copy states what is charged after the trial
275
+ - [ ] No `SKProduct` or `SKPaymentQueue` unless an old OS needs them
276
+ - [ ] Product IDs live in constants
277
+ - [ ] StoreKit tests cover promotional, win-back and code offers, Ask to Buy, renewals, refunds and revocations
278
+ - [ ] Entitlements are recomputed on `Transaction.updates` and when the app returns to the foreground
279
+ - [ ] Server validation, where used, receives `jwsRepresentation`
280
+ - [ ] Consumables are delivered and finished promptly
281
+ - [ ] Types that cross concurrency domains (observers, product models) are `Sendable`
253
282
 
254
283
  ## References
255
284
 
256
- - See [references/core-patterns.md](references/core-patterns.md) for full core
257
- code: purchase flow, launch-time transaction listener, entitlement checking,
258
- store views, subscription status, app transaction, purchase callbacks, and the
259
- ten annotated common mistakes. Load it when writing or reviewing a core flow.
260
- - See [references/storekit-advanced.md](references/storekit-advanced.md) for
261
- subscription control styles, offer management (introductory, promotional,
262
- win-back, offer codes), server-side validation, StoreKit testing, renewal
263
- states, grace period/billing retry, refunds, and Family Sharing. Load it for
264
- offers, testing setup, or advanced subscription handling.
265
- - See [references/app-review-guidelines.md](references/app-review-guidelines.md)
266
- for IAP rules (Guideline 3.1.1), subscription display requirements, and
267
- rejection prevention. Load it before a submission or when diagnosing a payment
268
- rejection.
269
- - For submission, privacy, metadata, screenshots, and rejection-risk audits use `app-store-review`.
270
- - For keyword, screenshot-caption, ranking, and conversion strategy use `app-store-optimization`.
271
- - Official Apple docs: [Choosing a StoreKit API](https://sosumi.ai/documentation/storekit/choosing-a-storekit-api-for-in-app-purchases), [Transaction.updates](https://sosumi.ai/documentation/storekit/transaction/updates), [Transaction.currentEntitlements](https://sosumi.ai/documentation/storekit/transaction/currententitlements),
272
- [SubscriptionStoreView](https://sosumi.ai/documentation/storekit/subscriptionstoreview), and [PurchaseAction](https://sosumi.ai/documentation/storekit/purchaseaction).
285
+ - [references/core-patterns.md](references/core-patterns.md): load when writing
286
+ or reviewing a core flow.
287
+ - [references/storekit-advanced.md](references/storekit-advanced.md): offers,
288
+ test setup, subscription edge cases.
289
+ - [references/app-review-guidelines.md](references/app-review-guidelines.md):
290
+ before submission or when a payment rejection needs diagnosing (Guideline
291
+ 3.1.1, subscription disclosure, avoiding rejections).
292
+ - Apple: [Choosing a StoreKit API](https://developer.apple.com/documentation/storekit/choosing-a-storekit-api-for-in-app-purchases),
293
+ [Transaction.updates](https://developer.apple.com/documentation/storekit/transaction/updates),
294
+ [Transaction.currentEntitlements](https://developer.apple.com/documentation/storekit/transaction/currententitlements),
295
+ [SubscriptionStoreView](https://developer.apple.com/documentation/storekit/subscriptionstoreview),
296
+ [PurchaseAction](https://developer.apple.com/documentation/storekit/purchaseaction).
@@ -3,41 +3,44 @@
3
3
  "evals": [
4
4
  {
5
5
  "id": 1,
6
- "prompt": "Build a SwiftUI StoreKit 2 paywall for an iOS 26 app with monthly and yearly subscriptions. Include product loading, purchase handling, entitlement checks, restore purchases, transaction updates, and what to do for Ask to Buy or refunds.",
7
- "expected_output": "A current StoreKit 2 subscription paywall plan that uses StoreKit views or PurchaseAction, verifies transactions, starts Transaction.updates at launch, handles current entitlements correctly, and exposes restore and policy links.",
6
+ "name": "ios26-subscription-paywall",
7
+ "prompt": "Write the StoreKit 2 side of an iOS 26 SwiftUI meditation app that sells a monthly and a yearly plan. I need product loading, buying, entitlement checks, restore, reacting to changes made outside the app, Ask to Buy, and refunds.",
8
+ "expected_output": "Sells through SubscriptionStoreView, StoreView or a PurchaseAction button as the preferred path instead of only calling product.purchase(options:). Iterates Transaction.updates from app launch in a task that cannot throw, and names what it brings in: renewals, refunds, approvals of Ask to Buy requests, and transactions a previous run never finished. Checks every VerificationResult before granting and finishes only after delivery. Explains the reach of Transaction.currentEntitlements: it lists permanent unlocks, auto-renewing plans that are active or in their grace period, and non-renewing passes, and it keeps no record of consumables. Handles .pending and .userCancelled, removes refunded or revoked access, offers restore, and links Terms of Service and the Privacy Policy on the paywall.",
8
9
  "files": [],
9
- "assertions": [
10
- "Uses `SubscriptionStoreView`, `StoreView`, or SwiftUI `PurchaseAction` as the preferred purchase path instead of defaulting only to `product.purchase(options:)`.",
11
- "Starts a `Transaction.updates` listener at app launch using a non-throwing task and notes that updates can deliver Ask to Buy approvals, refunds, renewals, and unfinished transactions.",
12
- "Verifies `VerificationResult` before granting access and calls `transaction.finish()` after content delivery.",
13
- "Explains that `Transaction.currentEntitlements` covers non-consumables, active or grace-period auto-renewable subscriptions, and non-renewing subscriptions, but not consumable delivery history.",
14
- "Handles `.pending`, `.userCancelled`, refunds or revocations, restore purchases, and subscription policy links."
10
+ "expectations": [
11
+ "Prefers SubscriptionStoreView, StoreView or PurchaseAction over a bare product.purchase(options:) call",
12
+ "Starts Transaction.updates at launch in a non-throwing task and says it carries renewals, refunds, Ask to Buy approvals and leftovers from earlier runs",
13
+ "Checks VerificationResult before granting and calls finish() after delivery",
14
+ "Explains that currentEntitlements holds permanent unlocks, live or grace-period auto-renewing plans and non-renewing passes, and nothing about consumables",
15
+ "Covers .pending, .userCancelled, refunds and revocations, restore, and the subscription policy links"
15
16
  ]
16
17
  },
17
18
  {
18
19
  "id": 2,
19
- "prompt": "Review this StoreKit subscription-offer code plan: use `Product.SubscriptionInfo.Status.status(for:)`, show every `winBackOffers` entry to cancelled users, use `.subscriptionPromotionalOffer(offer: signature:)`, and inspect `transaction.offerType` / `transaction.offerID` on purchase. Correct the API and eligibility mistakes.",
20
- "expected_output": "A correction-focused answer that updates stale StoreKit offer APIs, filters win-back offers through renewal eligibility, and verifies applied offers through the current transaction offer model.",
20
+ "name": "stale-offer-apis",
21
+ "prompt": "Review this offer code from an older branch: it reads Product.SubscriptionInfo.Status.status(for:) to find the plan state, shows every entry of winBackOffers to anyone who cancelled, applies .subscriptionPromotionalOffer(offer:signature:) on the store view, and logs transaction.offerType and transaction.offerID after purchase. Bring it up to date for iOS 26 and say how to test it.",
22
+ "expected_output": "Changes Product.SubscriptionInfo.Status.status(for:), which does not exist, to the static Product.SubscriptionInfo.status(for:). Explains that winBackOffers is an unfiltered list and must be narrowed to the IDs in the verified renewalInfo.eligibleWinBackOfferIDs before anything is shown or bought. Moves the store view to the iOS 26 .subscriptionPromotionalOffer(offer:compactJWS:) closures, or keeps signed promotional offers separate as purchase options built with promotionalOffer(_:compactJWS:). Swaps the deprecated offerType and offerID properties for the optional offer property and its type and id. Suggests exercising promotional, win-back and code redemptions, Ask to Buy and renewal states in a StoreKit configuration file or the sandbox.",
21
23
  "files": [],
22
- "assertions": [
23
- "Replaces `Product.SubscriptionInfo.Status.status(for:)` with `Product.SubscriptionInfo.status(for:)`.",
24
- "Explains that `product.subscription?.winBackOffers` is a raw list and must be filtered through verified `renewalInfo.eligibleWinBackOfferIDs` before display or purchase.",
25
- "Uses the iOS 26 SwiftUI `subscriptionPromotionalOffer` closure plus `compactJWS` closure for StoreKit views, or clearly separates it from lower-level signed purchase options.",
26
- "Uses `transaction.offer?.type` and `transaction.offer?.id` instead of stale `transaction.offerType` and `transaction.offerID`.",
27
- "Mentions StoreKit configuration or sandbox testing for promotional, win-back, offer code, Ask to Buy, and renewal-state flows."
24
+ "expectations": [
25
+ "Uses the static Product.SubscriptionInfo.status(for:) in place of Product.SubscriptionInfo.Status.status(for:)",
26
+ "Filters winBackOffers through verified renewalInfo.eligibleWinBackOfferIDs and calls showing all of them to every lapsed user wrong",
27
+ "Uses the iOS 26 subscriptionPromotionalOffer closures with compactJWS, or keeps the signed purchase option path visibly apart",
28
+ "Replaces offerType and offerID with the offer property (offer?.type, offer?.id)",
29
+ "Suggests a StoreKit configuration file or the sandbox to exercise promotional, win-back and code offers, Ask to Buy and renewal states"
28
30
  ]
29
31
  },
30
32
  {
31
33
  "id": 3,
32
- "prompt": "Use StoreKit guidance to review an iOS app that sells premium app features, has a reader-account sign-up link, and also wants App Store keywords and privacy manifest checks. Keep the answer scoped: what belongs in StoreKit, what belongs in App Store Review or ASO, and what IAP compliance caveats should be called out?",
33
- "expected_output": "A boundary-aware response that keeps StoreKit focused on IAP implementation, routes broader submission and metadata work to sibling skills, and states current IAP/external-link rules without overclaiming.",
34
+ "name": "scope-boundaries",
35
+ "prompt": "Before launch our subscription app needs a privacy manifest, an ATT prompt, new screenshots after a metadata rejection, a keyword refresh for search ranking, and a check that the paywall is compliant. We also link to our website for cheaper annual plans. Which parts are StoreKit work?",
36
+ "expected_output": "Keeps StoreKit to products, paywalls, purchase flows, verification, restore and entitlements, including the paywall compliance points. Hands the privacy manifest, ATT, the new screenshots, the metadata rejection and overall launch readiness to app-store-review, and keywords, search ranking, captions and conversion to app-store-optimization. Explains that digital features are normally sold through in-app purchase, with room for a present-day exception, a storefront-specific rule or an entitlement Apple has granted. Rejects the idea that any link to the website is an automatic rejection, and notes that reader-app provisions and the storefront decide whether the cheaper-plans link may stay.",
34
37
  "files": [],
35
- "assertions": [
36
- "Keeps StoreKit guidance focused on IAP products, paywalls, purchase flows, transaction verification, restore, and entitlement handling.",
37
- "Routes privacy manifests, ATT, screenshot, metadata rejection, and full submission readiness to the `app-store-review` skill.",
38
- "Routes keyword strategy, ranking, screenshot-caption optimization, and conversion work to the `app-store-optimization` skill.",
39
- "States that digital features generally require IAP unless a current guideline exception, storefront rule, or approved entitlement applies.",
40
- "Avoids a blanket claim that all external purchase links are always rejected and instead calls out reader-app and regional or storefront-sensitive rules."
38
+ "expectations": [
39
+ "Limits StoreKit to products, paywalls, purchase flows, verification, restore and entitlements",
40
+ "Hands privacy manifests, ATT, screenshots, metadata rejections and launch readiness to app-store-review",
41
+ "Hands keywords, ranking, screenshot captions and conversion to app-store-optimization",
42
+ "Says digital features are normally sold through in-app purchase, with room for a current exception, a storefront rule or a granted entitlement",
43
+ "Does not treat every external link as an automatic rejection; mentions reader-app and storefront-dependent rules"
41
44
  ]
42
45
  }
43
46
  ]