@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,264 +1,280 @@
1
1
  ---
2
2
  name: swift-testing
3
- description: "Writes and migrates Swift Testing framework tests with @Test, @Suite, #expect, #require, confirmation, traits, withKnownIssue, Attachment.record, processExitsWith exit tests and capture lists, Test.cancel, Issue.record warnings/manual failures, XCTest-to-Swift Testing migration, XCUITest UI-test boundaries, performance/snapshot boundaries, mocking, async patterns, and test organization. Use when writing tests, converting XCTest assertions such as XCTUnwrap or XCTFail, reviewing advanced Swift Testing API availability, or deciding when to keep XCTest/XCUITest."
3
+ description: "Writing, migrating and reviewing Swift Testing tests: @Test, @Suite, #expect, #require, confirmation, traits, withKnownIssue, Attachment.record, exit tests with processExitsWith and capture lists, Test.cancel, Issue.record warnings and manual failures, XCTest conversion (XCTUnwrap, XCTFail), mocking, async patterns, test organisation. Use when writing or migrating Swift tests, checking which Swift Testing APIs a toolchain supports, or deciding where XCTest and XCUITest still belong for UI, performance and snapshot tests."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
8
  # Swift Testing
9
9
 
10
- Swift Testing is the modern testing framework for Swift (Xcode 16+, Swift 6+). Prefer it over XCTest for all new unit tests. Use XCTest only for UI tests, performance benchmarks, and snapshot tests.
11
-
12
- ## Contents
13
-
14
- - [Basic Tests](#basic-tests)
15
- - [`@Test Traits`](#test-traits)
16
- - [#expect and #require](#expect-and-require)
17
- - [`@Suite and Test Organization`](#suite-and-test-organization)
18
- - [Execution Model](#execution-model)
19
- - [XCTest Migration Boundaries](#xctest-migration-boundaries)
20
- - [Known Issues](#known-issues)
21
- - [Additional Patterns](#additional-patterns)
22
- - [Common Mistakes](#common-mistakes)
23
- - [Test Attachments](#test-attachments)
24
- - [Exit Testing](#exit-testing)
25
- - [Version-Gated APIs](#version-gated-apis)
26
- - [Advanced API Review Checklist](#advanced-api-review-checklist)
27
- - [Review Checklist](#review-checklist)
28
- - [References](#references)
10
+ Swift Testing needs Xcode 16 or later and Swift 6 or later. Use it for every
11
+ new unit test. XCTest keeps UI tests (XCUITest), performance measurements and
12
+ most snapshot workflows.
29
13
 
30
- ---
14
+ More material: [patterns and migration](references/testing-patterns.md) and
15
+ [newer APIs and version gates](references/testing-advanced.md).
31
16
 
32
- ## Basic Tests
17
+ ## A First Test
33
18
 
34
19
  ```swift
35
20
  import Testing
21
+ @testable import Ledger
36
22
 
37
- @Test("User can update their display name")
38
- func updateDisplayName() {
39
- var user = User(name: "Alice")
40
- user.name = "Bob"
41
- #expect(user.name == "Bob")
23
+ @Test("A new account starts with a zero balance")
24
+ func newAccountIsEmpty() {
25
+ let account = Account(owner: "Ada")
26
+ #expect(account.balance == 0)
42
27
  }
43
28
  ```
44
29
 
45
- ## `@Test` Traits
30
+ ## Traits
46
31
 
47
32
  ```swift
48
- @Test("Validates email format") // display name
49
- @Test(.tags(.validation, .email)) // tags
50
- @Test(.disabled("Server migration in progress")) // disabled
51
- @Test(.enabled(if: ProcessInfo.processInfo.environment["CI"] != nil)) // conditional
52
- @Test(.bug("https://github.com/org/repo/issues/42")) // bug reference
53
- @Test(.timeLimit(.minutes(1))) // time limit
54
- @Test("Timeout handling", .tags(.networking), .timeLimit(.seconds(30))) // combined
55
- ```
33
+ @Test("Rejects malformed IBANs", .tags(.validation, .banking))
34
+ func rejectsMalformedIBAN() { }
56
35
 
57
- ## #expect and #require
58
-
59
- ```swift
60
- // #expect records failure but continues execution
61
- #expect(result == 42)
62
- #expect(name.isEmpty == false)
63
- #expect(items.count > 0, "Items should not be empty")
64
-
65
- // #expect with error type checking
66
- #expect(throws: ValidationError.self) {
67
- try validate(email: "not-an-email")
68
- }
36
+ @Test(.disabled("Waiting for the sandbox to come back"))
37
+ func sandboxTransfer() { }
69
38
 
70
- // #expect with specific error value
71
- #expect {
72
- try validate(email: "")
73
- } throws: { error in
74
- guard let err = error as? ValidationError else { return false }
75
- return err == .empty
76
- }
39
+ @Test(.enabled(if: ProcessInfo.processInfo.environment["CI"] == "true"))
40
+ func nightlyReconciliation() { }
77
41
 
78
- // #require records failure AND stops test (like XCTUnwrap)
79
- let user = try #require(await fetchUser(id: 1))
80
- #expect(user.name == "Alice")
42
+ @Test(.bug("https://tracker.example.com/issue/481"))
43
+ func roundingRegression() { }
81
44
 
82
- // #require for optionals -- unwraps or fails
83
- let first = try #require(items.first)
84
- #expect(first.isValid)
45
+ @Test("Imports a year of statements", .tags(.slow), .timeLimit(.minutes(2)))
46
+ func importsAYear() async throws { }
85
47
  ```
86
48
 
87
- **Rule: Use `#require` when subsequent assertions depend on the value. Use `#expect` for independent checks.**
49
+ - The first string argument is the display name.
50
+ - `.tags(...)`, `.disabled("reason")`, `.enabled(if:)`, `.bug(...)` and
51
+ `.timeLimit(...)` combine freely in one `@Test`.
52
+ - `.timeLimit` takes whole minutes only (`.minutes(_:)`). There is no
53
+ `.seconds` form.
88
54
 
89
- ## `@Suite` and Test Organization
55
+ ## `#expect` and `#require`
90
56
 
91
- See [references/testing-patterns.md](references/testing-patterns.md) for suite organization, confirmation patterns, known-issue handling, and execution-model details.
57
+ ```swift
58
+ @Test func transferValidation() async throws {
59
+ let ledger = Ledger()
92
60
 
93
- ## Execution Model
61
+ #expect(ledger.accounts.isEmpty, "A fresh ledger has no accounts")
94
62
 
95
- Swift Testing runs tests in parallel by default. Do not assume test order, shared suite instances, or exclusive access to mutable state unless you explicitly design for it.
63
+ #expect(throws: LedgerError.self) {
64
+ try ledger.transfer(amount: -5, from: "A", to: "B")
65
+ }
96
66
 
97
- ```swift
98
- @Suite(.serialized)
99
- struct KeychainTests {
100
- @Test func storesToken() throws { /* ... */ }
101
- @Test func deletesToken() throws { /* ... */ }
67
+ let error = #expect(throws: LedgerError.self) {
68
+ try ledger.transfer(amount: 10, from: "A", to: "A")
69
+ }
70
+ #expect(error == .sameAccount)
71
+
72
+ let first = try #require(await ledger.loadAccounts().first)
73
+ #expect(first.currency == "EUR")
102
74
  }
103
75
  ```
104
76
 
105
- Use `.serialized` when a test or suite must run one-at-a-time because it touches shared external state. It does not make unrelated tests outside that scope run serially.
77
+ - `#expect` records a failure and lets the test continue. An optional message
78
+ follows the condition.
79
+ - `#expect(throws: SomeError.self) { ... }` checks the error type. Since Swift
80
+ 6.1 it returns the thrown error, so you can inspect its value afterwards. The
81
+ older form with a trailing `throws: { error in ... }` predicate closure is
82
+ deprecated.
83
+ - `try #require(...)` records a failure and stops the test, like `XCTUnwrap`.
84
+ It unwraps optionals and accepts `await` expressions.
85
+ - Pick `#require` when the rest of the test needs that value to exist; pick
86
+ `#expect` for checks that stand on their own.
106
87
 
107
- **Rules:**
108
- - Each test must set up its own state.
109
- - Shared mutable globals are a bug unless protected or intentionally serialized.
110
- - `@Suite(.serialized)` is for exclusive execution, not for expressing logical ordering between tests.
111
- - If tests depend on sequence, combine them into one test or move the sequence into shared helper code.
88
+ ## How Tests Run
112
89
 
113
- ## XCTest Migration Boundaries
90
+ Unless told otherwise, Swift Testing runs tests concurrently. Never count on an
91
+ order, on one suite instance shared between tests, or on having anything to
92
+ yourself.
114
93
 
115
- Swift Testing unit tests do not inherit from `XCTestCase`. Declare `@Test` on free functions, global functions, or methods on suite types such as `struct`, `class`, or `actor`; use `static` or `class` methods when instance fixtures are not needed.
116
-
117
- When reviewing migration code or plans, do not collapse every XCTest construct into `#expect`. Include a compact assertion-mapping note or table in the answer so required unwraps and unconditional manual failures are not lost, even when the user only says "replace every XCTAssert with #expect."
118
-
119
- State coexistence explicitly: XCTest and Swift Testing can coexist during migration. Keep UI automation, performance benchmarks, and common snapshot-test flows on XCTest/XCUITest or snapshot tooling, and separate files or targets when that makes runner expectations clearer.
94
+ ```swift
95
+ @Suite(.serialized)
96
+ struct KeychainStoreTests {
97
+ @Test func savesToken() throws { }
98
+ @Test func deletesToken() throws { }
99
+ }
100
+ ```
120
101
 
121
- Migration defaults:
122
- - `XCTAssert*` -> `#expect(...)`
123
- - `XCTUnwrap` or any value required by later checks -> `try #require(...)`
124
- - `XCTFail("...")` or manual unconditional issues -> `Issue.record("...")`
125
- - UI tests, performance benchmarks, and common snapshot-test flows stay on XCTest/XCUITest or snapshot tooling.
126
- - Put `@available` on individual `@Test` functions, not on suite types or their containing types.
102
+ `.serialized` makes the tests in that suite run one at a time. It does not
103
+ affect tests outside the suite.
104
+
105
+ - Every test builds its own state.
106
+ - A shared mutable global is a bug unless it is protected or serialized.
107
+ - `.serialized` is for exclusive access, not for ordering.
108
+ - Steps that depend on each other belong in one test or a shared helper.
109
+
110
+ ## Migrating from XCTest
111
+
112
+ - Swift Testing tests do not subclass `XCTestCase`. Put `@Test` on a free
113
+ function, or on a method of a `struct`, `class` or `actor` suite. Use a
114
+ `static` or `class` method when no instance fixture is needed.
115
+ - Do not rewrite every assertion as `#expect`. Keep a mapping so required
116
+ unwraps and explicit failures keep their meaning, even when asked to "just
117
+ use #expect everywhere".
118
+ - XCTest and Swift Testing can live side by side while you migrate.
119
+ - Leave UI automation, performance measurements and common snapshot flows on
120
+ XCTest, XCUITest or the snapshot tool. Separate files or targets help when
121
+ they make it clear which runner owns what.
122
+
123
+ | XCTest | Swift Testing |
124
+ |--------|---------------|
125
+ | `XCTAssert...` | `#expect(...)` |
126
+ | `XCTUnwrap`, or a value later checks rely on | `try #require(...)` |
127
+ | `XCTFail("...")`, any unconditional failure | `Issue.record("...")` |
127
128
 
128
129
  ```swift
129
- let user = try #require(optionalUser)
130
- #expect(user.isActive)
131
-
132
- guard featureFlag.isEnabled else {
133
- Issue.record("Expected feature flag to be enabled")
134
- return
130
+ @Test func parsesHeader() throws {
131
+ guard let header = Header(raw: "v2;utf8") else {
132
+ Issue.record("Header did not parse")
133
+ return
134
+ }
135
+ #expect(header.version == 2)
135
136
  }
136
137
  ```
137
138
 
138
- See [references/testing-patterns.md](references/testing-patterns.md) for migration examples and [references/testing-advanced.md](references/testing-advanced.md) for Swift/Xcode version gates.
139
+ Put `@available` on the individual `@Test` function, never on a suite type or
140
+ the type that contains it.
139
141
 
140
142
  ## Known Issues
141
143
 
142
- Mark expected failures so they do not cause test failure:
143
-
144
144
  ```swift
145
- withKnownIssue("Propane tank is empty") {
146
- #expect(truck.grill.isHeating)
145
+ @Test func legacyExport() {
146
+ withKnownIssue("Exporter drops the BOM; fix scheduled") {
147
+ #expect(Exporter().csv().hasPrefix("\u{FEFF}"))
148
+ }
147
149
  }
148
150
 
149
- // Intermittent / flaky failures
150
- withKnownIssue(isIntermittent: true) {
151
- #expect(service.isReachable)
151
+ @Test func flakyMirror() async {
152
+ await withKnownIssue(isIntermittent: true) {
153
+ try await ReplicaSync.run()
154
+ }
152
155
  }
153
156
 
154
- // Conditional known issue
155
- withKnownIssue {
156
- #expect(foodTruck.grill.isHeating)
157
- } when: {
158
- !hasPropane
157
+ @Test func arm64OnlyBug() {
158
+ withKnownIssue {
159
+ #expect(Checksum.fast([1, 2, 3]) == Checksum.slow([1, 2, 3]))
160
+ } when: {
161
+ Platform.isARM64
162
+ }
159
163
  }
160
164
  ```
161
165
 
162
- If no known issues are recorded, Swift Testing records a distinct issue notifying you the problem may be resolved.
163
-
164
- ## Additional Patterns
165
-
166
- See [references/testing-patterns.md](references/testing-patterns.md) for parameterized tests, tags and suites, async testing, traits, and execution-model details.
167
-
168
- ## Test Attachments
166
+ A known issue does not fail the test. If the body records no issue at all,
167
+ Swift Testing reports a separate issue telling you the problem may have been
168
+ fixed, so the marker does not linger.
169
169
 
170
- Attach diagnostic data to test results for debugging failures. See [references/testing-patterns.md](references/testing-patterns.md) for full examples.
170
+ ## Attachments
171
171
 
172
172
  ```swift
173
- @Test func generateReport() async throws {
174
- let report = try generateReport()
175
- Attachment.record(report.data, named: "report.json")
176
- #expect(report.isValid)
173
+ @Test func exportsReport() throws {
174
+ let data = try ReportBuilder().json()
175
+ Attachment.record(data, named: "report.json")
176
+ #expect(!data.isEmpty)
177
177
  }
178
178
  ```
179
179
 
180
- Image attachments require Swift 6.3 / Xcode 26.4 or newer. Import `Testing` plus the relevant UI framework, then record the platform image value directly:
180
+ Images (Swift 6.3, Xcode 26.4 or later) need the UI framework imported next to
181
+ `Testing`:
181
182
 
182
183
  ```swift
183
184
  import Testing
184
185
  import UIKit
185
186
 
186
- @Test func renderedChart() async throws {
187
- let image = renderer.image { ctx in chartView.drawHierarchy(in: bounds, afterScreenUpdates: true) }
188
- Attachment.record(image, named: "chart", as: .png)
187
+ @MainActor
188
+ @Test func rendersGauge() {
189
+ let gauge = GaugeView(frame: CGRect(x: 0, y: 0, width: 160, height: 160))
190
+ let image = UIGraphicsImageRenderer(bounds: gauge.bounds).image { _ in
191
+ gauge.drawHierarchy(in: gauge.bounds, afterScreenUpdates: true)
192
+ }
193
+ Attachment.record(image, named: "gauge", as: .png)
189
194
  }
190
195
  ```
191
196
 
192
- ## Exit Testing
197
+ ## Exit Tests
193
198
 
194
- Test code that calls `exit()`, `fatalError()`, or `preconditionFailure()`. Exit testing requires Swift 6.2 / Xcode 26.0 or newer and is supported on macOS, Linux, FreeBSD, OpenBSD, and Windows runtime targets, not iOS, tvOS, or watchOS. When correcting exit-test code, name both the toolchain floor and runtime support. See [references/testing-patterns.md](references/testing-patterns.md) for details.
199
+ Exit tests check code that ends the process: `exit()`, `fatalError()`,
200
+ `preconditionFailure()`. They need Swift 6.2 (Xcode 26.0) and run on macOS,
201
+ Linux, FreeBSD, OpenBSD and Windows. They are not available on iOS, tvOS or
202
+ watchOS. When fixing exit-test code, state both limits: the toolchain floor and
203
+ the platforms it runs on.
195
204
 
196
205
  ```swift
197
- @Test func invalidInputCausesExit() async {
206
+ @Test func rejectsCorruptConfig() async {
198
207
  await #expect(processExitsWith: .failure) {
199
- processInvalidInput() // calls fatalError()
208
+ _ = Config.loadOrDie(path: "/dev/null")
200
209
  }
201
210
  }
202
211
  ```
203
212
 
204
- ## Version-Gated APIs
213
+ ## Version Gates
214
+
215
+ Check the toolchain before recommending newer APIs, and name the gate for each
216
+ API you correct.
205
217
 
206
- For advanced Swift Testing APIs, check the toolchain before recommending them. When reviewing user code that mentions one of these APIs, name the gate for each API you correct:
207
- - Exit testing requires Swift 6.2 / Xcode 26.0 and does not support iOS, tvOS, or watchOS runtime targets.
208
- - Exit-test capture lists require the Swift 6.3 compiler. If an exit-test closure reads parent-process values, use an explicit capture list and state that captured values must be `Sendable` and `Codable`.
209
- - `Test.cancel(_:)`, `Issue.record(_:severity:)`, and image attachment recording require Swift 6.3 / Xcode 26.4-era support as noted in [references/testing-advanced.md](references/testing-advanced.md).
210
- - When fixing a `Test.cancel(_:)` sample, state both shape and gate: the test must be `throws` or `async throws`, and `Test.cancel(_:)` requires Swift 6.3 / Xcode 26.4-era support.
218
+ | API | Needs |
219
+ |-----|-------|
220
+ | Exit tests (`processExitsWith:`) | Swift 6.2, Xcode 26.0; not iOS, tvOS, watchOS |
221
+ | Capture lists in exit tests | Compiles with the Swift 6.3.1 compiler (Xcode 26.4); earlier compilers not checked. Captured values must be `Sendable` and `Codable` |
222
+ | `Test.cancel(_:)`, `Issue.record(_:severity:)`, image attachments | Swift 6.3, Xcode 26.4 |
211
223
 
212
224
  ```swift
213
- @Test func exitsWithCapturedCode() async {
214
- let expectedCode: Int32 = 42
215
- await #expect(processExitsWith: .failure) { [expectedCode] in
216
- exit(expectedCode)
225
+ @Test func exitsWithConfiguredCode() async {
226
+ let status: Int32 = 42
227
+ await #expect(processExitsWith: .exitCode(status)) { [status = status as Int32] in
228
+ exit(status)
217
229
  }
218
230
  }
219
231
  ```
220
232
 
221
- ## Advanced API Review Checklist
233
+ Give each captured value an explicit type (`[name = name as Type]`). With the
234
+ Swift 6.3.1 compiler a bare `[status]` fails with "Type of captured value
235
+ 'status' is ambiguous", a captured value that is not `Codable` fails with "must
236
+ conform to 'Sendable' and 'Codable'", and a closure that reads `status` with no
237
+ capture list fails with "a C function pointer cannot be formed from a closure
238
+ that captures context".
239
+
240
+ A test that calls `Test.cancel(_:)` must be `throws` or `async throws`.
222
241
 
223
- When reviewing stale or beta-era Swift Testing samples, include the exact correction and the gate for every API the prompt mentions:
242
+ ## Correcting Advanced API Code
224
243
 
225
- | User code to correct | Current guidance |
226
- |---|---|
227
- | `#expect(exitsWith:)` | Use `await #expect(processExitsWith: .failure) { ... }`. Exit testing requires Swift 6.2 / Xcode 26.0 or newer and is supported on macOS, Linux, FreeBSD, OpenBSD, and Windows runtime targets, not iOS, tvOS, or watchOS. For an iOS app target, test fatal-path logic through a smaller non-exiting API or a supported host/tool target. |
228
- | Exit-test closure reads outer values | Add an explicit capture list, for example `{ [expectedCode] in ... }`. Exit-test capture lists require the Swift 6.3 compiler; captured values must be `Sendable` and `Codable`. |
229
- | `Test.cancel()` in a test that awaits work | Make the test `async throws` and call `try Test.cancel("reason")`. `Test.cancel(_:)` requires Swift 6.3 / Xcode 26.4-era support. |
230
- | `Issue.record(..., severity: .warning)` | Use `Issue.record("message", severity: .warning)`. Warning severity is reported but does not fail the test, and requires Swift 6.3 / Xcode 26.4-era support. |
231
- | `Attachment(image, named:).record()` | Use `Attachment.record(image, named: "name", as: .png)`. Import `Testing` plus the relevant image framework; Apple-platform image values include `UIImage`, `CGImage`, `CIImage`, and `NSImage`. Image attachment recording requires Swift 6.3 / Xcode 26.4-era support. |
244
+ | Found | Replace with |
245
+ |-------|--------------|
246
+ | `#expect(exitsWith:)` | `await #expect(processExitsWith: .failure) { ... }`. In an iOS app target, test the logic behind a smaller API that does not exit, or move the exit test to a supported host or tool target. |
247
+ | Exit-test closure reading outer values with no capture list | An explicit, typed capture list (`[code = code as Int32]`); verified with Swift 6.3.1; values `Sendable` and `Codable` |
248
+ | `Test.cancel()` in a test that is not throwing | Mark the test `async throws` and call `try Test.cancel("reason")` |
249
+ | A warning that should not fail the run | `Issue.record("message", severity: .warning)`: reported, test still passes; Swift 6.3, Xcode 26.4 |
250
+ | `Attachment(image, named:).record()` | `Attachment.record(image, named: "...", as: .png)`; accepts `UIImage`, `CGImage`, `CIImage`, `NSImage`; Swift 6.3, Xcode 26.4 |
232
251
 
233
252
  ## Common Mistakes
234
253
 
235
- 1. **Testing implementation, not behavior.** Test what the code does, not how.
236
- 2. **No error path tests.** If a function can throw, test the throw path.
237
- 3. **Flaky async tests.** Use `confirmation` with expected counts, not `sleep` calls.
238
- 4. **Shared mutable state between tests.** Each test sets up its own state via `init()` in `@Suite`.
239
- 5. **Missing accessibility identifiers in UI tests.** XCUITest queries rely on them.
240
- 6. **Using `sleep` in tests.** Use `confirmation`, clock injection, or `withKnownIssue`.
241
- 7. **Not testing cancellation.** If code supports `Task` cancellation, verify it cancels cleanly.
242
- 8. **Unclear XCTest migration boundaries.** Apple allows XCTest and Swift Testing in one file during migration; prefer separate files when it keeps imports, ownership, and runner expectations clearer.
243
- 9. **Non-Sendable test helpers shared across tests.** Ensure test helper types are Sendable when shared across concurrent test cases. Annotate MainActor-dependent test code with `@MainActor`.
244
- 10. **Assuming tests run in declaration order.** Swift Testing runs in parallel by default; use `.serialized` only when exclusive execution is required.
245
- 11. **Using `.serialized` to express workflow steps.** Serialized execution does not make one test feed another; keep dependent steps in one test.
254
+ - Testing how the code works instead of what it does.
255
+ - No tests for the error paths of throwing functions.
256
+ - Waiting with sleeps in async tests. Use `confirmation` with an expected
257
+ count, an injected clock, or `withKnownIssue` for known flakiness.
258
+ - Shared mutable state between tests. Set up in the suite's `init()`.
259
+ - UI tests without accessibility identifiers; XCUITest queries rely on them.
260
+ - Never testing that a `Task` stops when cancelled.
261
+ - Unclear migration boundaries. Both frameworks may share a file, but separate
262
+ files are usually clearer for imports, ownership and runner expectations.
263
+ - Non-`Sendable` helpers shared across concurrent tests. Mark test code that
264
+ needs the main actor `@MainActor`.
265
+ - Relying on declaration order.
266
+ - Using `.serialized` to chain the steps of a workflow. Put dependent steps in
267
+ one test.
246
268
 
247
269
  ## Review Checklist
248
270
 
249
- - [ ] All new tests use Swift Testing (`@Test`, `#expect`), not XCTest assertions
250
- - [ ] Test names describe behavior (`fetchUserReturnsNilOnNetworkError` not `testFetchUser`)
251
- - [ ] Error paths have dedicated tests
252
- - [ ] Async tests use `confirmation()`, not `Task.sleep`
253
- - [ ] Parameterized tests used for repetitive variations
254
- - [ ] Tags applied for filtering (`.critical`, `.slow`)
255
- - [ ] Mocks conform to protocols, not subclass concrete types
256
- - [ ] No shared mutable state between tests
257
- - [ ] Tests do not rely on declaration order or shared suite instances
258
- - [ ] `.serialized` used only for truly exclusive state, not to model workflow sequencing
259
- - [ ] Cancellation tested for cancellable async operations
260
-
261
- ## References
262
-
263
- - Testing patterns: [references/testing-patterns.md](references/testing-patterns.md)
264
- - Advanced testing (warnings, cancellation, image attachments): [references/testing-advanced.md](references/testing-advanced.md)
271
+ - [ ] New tests use `@Test` and `#expect`, not XCTest assertions
272
+ - [ ] Names describe behaviour (`fetchUserReturnsNilOnNetworkError`, not `testFetchUser`)
273
+ - [ ] Error paths have their own tests
274
+ - [ ] Async events verified with `confirmation()` rather than `Task.sleep`
275
+ - [ ] Repetitive variations are parameterized
276
+ - [ ] Tags such as `.critical` or `.slow` exist for filtering
277
+ - [ ] Mocks conform to protocols; no subclassing of concrete types
278
+ - [ ] No shared mutable state, no dependence on order or on a shared suite instance
279
+ - [ ] `.serialized` used only for exclusive resources
280
+ - [ ] Cancellable async work has a cancellation test
@@ -2,42 +2,44 @@
2
2
  "skill_name": "swift-testing",
3
3
  "evals": [
4
4
  {
5
- "id": 0,
6
- "prompt": "Review this migration plan from XCTest to Swift Testing: keep the XCTestCase subclass, convert setUp/tearDown into a shared singleton fixture, put @available on the whole suite type for iOS 18 APIs, replace every XCTest assertion with #expect including XCTUnwrap, keep XCTFail(\"missing user\") for guard-failure paths, and keep UI tests in the same target because Swift Testing can replace XCTest everywhere. They also want to know whether XCTest and Swift Testing can coexist during migration. Give corrected guidance with concise Swift examples where useful.",
7
- "expected_output": "A migration review that converts XCTestCase classes into Swift Testing suites or free functions, uses isolated per-test fixtures, puts availability on test functions rather than suite types, maps XCTAssert/XCTUnwrap/XCTFail to #expect/#require/Issue.record, and preserves XCTest for UI testing.",
5
+ "id": 1,
6
+ "prompt": "I'm moving our CartServiceTests from XCTest to Swift Testing. My plan: keep `final class CartServiceTests: XCTestCase` but add @Test to the methods, share one CartService through a static singleton so setUp goes away, put @available(iOS 18, *) on the class, turn every assertion including XCTUnwrap into #expect, and move the checkout UI tests into the same Swift Testing file. Review it.",
7
+ "expected_output": "A migration review that corrects each part of the plan and explains how the two frameworks coexist.",
8
8
  "files": [],
9
9
  "assertions": [
10
- "Rejects keeping XCTestCase inheritance for migrated Swift Testing unit tests and uses @Test functions or suites instead.",
11
- "Recommends per-test fixture setup using suite init or isolated fixtures rather than shared singleton mutable state.",
12
- "States that @available belongs on individual @Test functions, not on suite types or containing types.",
13
- "Explains that not every XCTest assertion should become #expect and uses #require for required values or unwraps.",
14
- "Keeps XCUITest UI tests on XCTest rather than claiming Swift Testing replaces XCTest everywhere."
10
+ "Rejects keeping XCTestCase as the parent of Swift Testing tests and proposes a struct, class or actor suite or free functions.",
11
+ "Recommends a fresh fixture per test through the suite init() instead of a shared singleton.",
12
+ "Moves @available onto the individual @Test functions, not the suite type.",
13
+ "Converts XCTUnwrap to try #require and XCTFail to Issue.record rather than turning everything into #expect.",
14
+ "Keeps the checkout UI tests on XCTest with XCUITest.",
15
+ "States that XCTest and Swift Testing can coexist during the migration."
15
16
  ]
16
17
  },
17
18
  {
18
- "id": 1,
19
- "prompt": "I'm targeting iOS 26 with Swift 6.3 and wrote Swift Testing samples using #expect(exitsWith: .failure) in an exit-test closure that reads a local expectedCode, Test.cancel() in a sync test that awaits a network check, Issue.record(severity: .warning), and Attachment(image, named:).record(). Review the samples for current API spelling, availability, platform support, which pieces are Swift 6.2/Xcode 26.0 versus Swift 6.3/Xcode 26.4-era APIs, and any code-shape fixes.",
20
- "expected_output": "An advanced Swift Testing review that uses processExitsWith for exit tests, notes exit testing availability and supported runtime targets, fixes async Test.cancel sample shape, notes Swift 6.3/Xcode 26.4 availability for warning severity and image attachments, and records images with Attachment.record(..., as:).",
19
+ "id": 2,
20
+ "prompt": "We build with Xcode 26.4 and Swift 6.3 for an iOS 26 app. Review these tests: `#expect(exitsWith: .failure) { Vault.unlock(code: badCode) }` where badCode is a local, `func skipsOffline() { Test.cancel(\"offline\") }`, `Issue.record(\"slow parse\")` that should only warn, and `Attachment(chartImage, named: \"chart\").record()`.",
21
+ "expected_output": "Each API corrected to its current spelling, with the toolchain gate and platform limits named for every change.",
21
22
  "files": [],
22
23
  "assertions": [
23
- "Replaces stale #expect(exitsWith:) with #expect(processExitsWith:).",
24
- "States that exit testing requires Swift 6.2/Xcode 26.0 or newer and is not supported on iOS/tvOS/watchOS runtime targets.",
25
- "Mentions Swift 6.3 capture-list requirements when discussing captured parent-process values in exit tests.",
26
- "Marks the Test.cancel example async when it awaits work and explains Test.cancel requires Swift 6.3/Xcode 26.4 or newer.",
27
- "Uses Issue.record(..., severity: .warning) and image Attachment.record(..., named: ..., as: .png) with Swift 6.3/Xcode 26.4 availability."
24
+ "Replaces exitsWith: with await #expect(processExitsWith: .failure).",
25
+ "States that exit tests need Swift 6.2 and Xcode 26.0 and do not run on iOS, tvOS or watchOS, and suggests testing the non-exiting logic in the app target.",
26
+ "Adds an explicit, typed capture list for badCode, notes it was verified with the Swift 6.3.1 compiler, and requires Sendable plus Codable values.",
27
+ "Makes the cancelling test async throws (or throws) and calls try Test.cancel.",
28
+ "Uses Issue.record with severity: .warning and names the Swift 6.3 and Xcode 26.4 gate.",
29
+ "Uses Attachment.record(chartImage, named:, as: .png) and names the Swift 6.3 and Xcode 26.4 gate."
28
30
  ]
29
31
  },
30
32
  {
31
- "id": 2,
32
- "prompt": "Plan tests for a SwiftUI checkout flow: unit-test a price calculator, verify async coupon events, snapshot the checkout screen in dark mode and Dynamic Type, measure parser performance, and automate the login-to-checkout UI path. Which pieces should use Swift Testing, which should stay with XCTest or snapshot tooling, and how should the test files be organized during migration?",
33
- "expected_output": "A boundary-aware test plan that uses Swift Testing for unit and async behavior tests, confirmation for callback/event checks, XCTest/XCUITest for UI automation and performance measurement, snapshot tooling for visual regression, and allows mixed files during migration while preferring clear separation for maintainability.",
33
+ "id": 3,
34
+ "prompt": "Plan the tests for our checkout feature: a price calculator with discounts, a coupon service that posts async events, the login-to-checkout flow, a launch-time benchmark, and screenshots in dark mode and at large text sizes.",
35
+ "expected_output": "A test plan that assigns each area to the right framework or tool.",
34
36
  "files": [],
35
37
  "assertions": [
36
- "Uses Swift Testing for pure unit/business logic tests such as the price calculator.",
37
- "Uses confirmation or Swift concurrency patterns for async coupon events instead of sleeps.",
38
- "Keeps UI automation with XCTest/XCUITest.",
39
- "Keeps performance measurement and common snapshot testing flows in XCTest or dedicated snapshot tooling.",
40
- "States that XCTest and Swift Testing can coexist during migration while recommending clear file or target organization when it reduces confusion."
38
+ "Uses Swift Testing (@Test, #expect, parameterized arguments) for the price calculator.",
39
+ "Uses confirmation for the async coupon events and rules out sleeps.",
40
+ "Uses XCUITest for the login-to-checkout flow.",
41
+ "Keeps the benchmark on XCTest performance APIs and the dark-mode and Dynamic Type screenshots on snapshot tooling.",
42
+ "Says both frameworks may share a target during migration but recommends clear file or target separation."
41
43
  ]
42
44
  }
43
45
  ]