@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +266 -267
  5. package/package.json +2 -2
  6. package/pipeline/scripts/_notices.mjs +1 -1
  7. package/pipeline/skills/.skill-manifest.json +68 -68
  8. package/pipeline/skills/shared/README.md +70 -70
  9. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  10. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  11. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  12. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  13. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  14. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  15. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  16. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  17. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  18. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  19. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  20. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
  21. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  22. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
  23. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
  24. package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
  25. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  26. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  27. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  28. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
  29. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  30. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  31. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  32. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  34. package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
  35. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  36. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
  37. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  38. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  39. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  40. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  41. package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
  42. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  43. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
  44. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  45. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  46. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  47. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  48. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  49. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  50. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  51. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  52. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  53. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
  54. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  55. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  56. package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
  57. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  58. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  59. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  60. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  61. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  62. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  63. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  64. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  65. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  66. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  67. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  68. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  69. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  70. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  71. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  72. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  73. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  74. package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
  75. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  76. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  77. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  78. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  79. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  80. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  81. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  82. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  83. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  84. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  85. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  86. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  87. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  88. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  89. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  90. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  91. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  92. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  93. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  94. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  95. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  96. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  97. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  98. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  99. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  100. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  101. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  102. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  103. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  104. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  105. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  106. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  107. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  108. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  109. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  111. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
  112. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  113. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  114. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  115. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  116. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  117. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  118. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  119. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  120. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  121. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  122. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  123. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  124. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  125. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  126. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  127. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  128. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  129. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  130. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  131. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  132. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  133. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  134. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  135. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  136. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  137. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  138. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  139. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  140. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  141. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  142. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  143. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  144. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  145. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  146. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  147. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  148. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  149. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  150. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  151. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  152. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  153. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  154. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  155. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  156. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  157. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
  158. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  159. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  160. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  161. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  162. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  163. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  164. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  165. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  166. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  167. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  168. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  169. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  170. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  171. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  172. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
  173. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  174. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  175. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  176. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  177. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  178. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  179. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  180. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  181. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  182. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  183. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  184. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  185. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  186. package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
  187. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  188. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  189. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
  190. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  191. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  192. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  193. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  194. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  195. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  196. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
  197. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  198. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  199. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  200. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
  201. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  202. package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
  203. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  204. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
  205. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  206. package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
  207. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  208. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  209. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  210. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  211. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  212. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  213. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  214. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  215. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  216. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  217. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  218. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  219. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  220. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  221. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  222. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  223. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  224. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  225. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  226. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  227. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  228. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  229. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  230. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  231. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
  232. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  233. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
  234. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  235. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
  236. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  237. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  238. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  239. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  240. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  241. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  242. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  243. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  244. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  245. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  246. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  247. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  248. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  249. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  250. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  251. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  252. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  253. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  254. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  255. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  256. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  257. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  258. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  259. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  260. package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
  261. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  262. package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
  263. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
  264. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,499 +1,459 @@
1
1
  ---
2
2
  name: swift-language
3
- description: "Modern Swift language patterns for code outside concurrency and SwiftUI: if/switch expressions, typed throws, result builders, property wrappers, some vs any, guard patterns, Never, Regex builders, modern collection APIs and string interpolation. Use when writing core Swift with generics, protocols, enums, closures or new language features; for deep Codable use swift-codable, for formatting swift-formatstyle, for API naming swift-api-design-guidelines."
3
+ description: "Core Swift 6.3 outside concurrency and SwiftUI: if and switch expressions, typed throws, result builders, property wrappers, some vs any, guard, Never, Regex builders, collection APIs, string interpolation, @c interop, module selectors, performance attributes. Use when writing or reviewing plain Swift with generics, protocols, enums, closures or newer language features. Not for deep Codable, formatting, API naming, concurrency or SwiftUI."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
- # Swift Language Patterns
8
+ # Swift Language (Swift 6.3)
9
9
 
10
- Core Swift language features and modern syntax patterns targeting Swift 6.3. Covers language constructs, type system features, basic Codable,
11
- string and collection APIs, basic formatting, C interop (`@c`), module disambiguation (`ModuleName::symbol`), and performance attributes (`@specialized`, `@inline(always)`). For `@c` corrections, enumerate invalid Swift-only signature types: `String`, `Array`, `UnsafeBufferPointer`, closures, and generic placeholders. Route deeper Codable/API decoding to `swift-codable`, detailed formatting/localization to `swift-formatstyle`, API naming to `swift-api-design-guidelines`, concurrency to `swift-concurrency`, and SwiftUI state/view work to `swiftui-patterns`.
10
+ This skill owns the language itself: expressions, the type system, error
11
+ typing, DSL-building features, pattern matching and the standard library
12
+ surface that everyday code touches. It also carries the basics of Codable,
13
+ string and collection APIs, simple formatting, C interop through `@c`, module
14
+ disambiguation with `ModuleName::symbol`, and the performance attributes
15
+ `@specialized` and `@inline(always)`. The attribute details live in
16
+ [references/swift-attributes-interop.md](references/swift-attributes-interop.md).
12
17
 
13
- ## Contents
18
+ When a reviewer asks for a `@c` fix, list the Swift-only types that cannot
19
+ appear in the signature: `String`, `Array`, `UnsafeBufferPointer`, closures and
20
+ generic placeholders. Saying "use C types" is not enough.
14
21
 
15
- - [If/Switch Expressions](#ifswitch-expressions)
16
- - [Typed Throws](#typed-throws)
17
- - [Result Builders](#result-builders)
18
- - [Property Wrappers](#property-wrappers)
19
- - [Opaque and Existential Types](#opaque-and-existential-types)
20
- - [Guard Patterns](#guard-patterns)
21
- - [Never Type](#never-type)
22
- - [Regex Builders](#regex-builders)
23
- - [Codable Best Practices](#codable-best-practices)
24
- - [Modern Collection APIs](#modern-collection-apis)
25
- - [FormatStyle](#formatstyle)
26
- - [String Interpolation](#string-interpolation)
27
- - [Common Mistakes](#common-mistakes)
28
- - [Review Checklist](#review-checklist)
29
- - [References](#references)
22
+ Hand-offs:
30
23
 
31
- ## If/Switch Expressions
24
+ | Topic | Skill |
25
+ |---|---|
26
+ | Codable models, key strategies, date decoding, API payloads | `swift-codable` |
27
+ | Format styles, locale behaviour, localized display | `swift-formatstyle` (with `ios-localization` for market QA) |
28
+ | Naming and argument labels | `swift-api-design-guidelines` |
29
+ | Actors, tasks, isolation, Sendable | `swift-concurrency` |
30
+ | SwiftUI state and view structure | `swiftui-patterns` |
31
+
32
+ ## if and switch as expressions
32
33
 
33
- Swift 5.9+ allows `if` and `switch` as expressions that return values. Use them
34
- to assign, return, or initialize directly.
34
+ Since Swift 5.9, `if` and `switch` can produce a value directly for an
35
+ assignment, a `return` or an initializer.
35
36
 
36
37
  ```swift
37
- // Assign from if expression
38
- let icon = if isComplete { "checkmark.circle.fill" } else { "circle" }
39
-
40
- // Assign from switch expression
41
- let label = switch status {
42
- case .draft: "Draft"
43
- case .published: "Published"
44
- case .archived: "Archived"
38
+ enum Tier { case free, plus, pro }
39
+
40
+ func badge(for tier: Tier, trial: Bool) -> String {
41
+ let base = if trial { "Trial" } else { "Member" }
42
+ let suffix = switch tier {
43
+ case .free: ""
44
+ case .plus: " +"
45
+ case .pro: " Pro"
46
+ }
47
+ return base + suffix
45
48
  }
46
49
 
47
- // Works in return position
48
- func color(for priority: Priority) -> Color {
49
- switch priority {
50
- case .high: .red
51
- case .medium: .orange
52
- case .low: .green
50
+ func seatLimit(_ tier: Tier) -> Int {
51
+ switch tier {
52
+ case .free: 1
53
+ case .plus: 5
54
+ case .pro: 50
53
55
  }
54
56
  }
55
57
  ```
56
58
 
57
- **Rules:**
58
- - Every branch must produce a value of the same type.
59
- - Multi-statement branches are not allowed -- each branch is a single expression.
60
- - Wrap in parentheses when used as a function argument to avoid ambiguity.
59
+ Rules to remember:
61
60
 
62
- ## Typed Throws
61
+ - All branches produce one common type.
62
+ - A branch holds exactly one expression. Several statements in a branch are not
63
+ allowed; fall back to a statement form.
64
+ - Wrap the expression in parentheses when it is passed as a function argument,
65
+ so the parser does not misread it.
63
66
 
64
- Swift 6+ allows specifying the error type a function throws.
67
+ ## Typed throws
65
68
 
66
- ```swift
67
- enum ValidationError: Error {
68
- case tooShort, invalidCharacters, alreadyTaken
69
- }
69
+ Swift 6 lets a function name its error type: `throws(ParseFailure)`. Inside,
70
+ `throw .emptyInput` works as shorthand, and a `catch` block at the call site
71
+ gets `error` already typed as `ParseFailure`, so a `switch` over it can be
72
+ exhaustive with no `as?` cast.
70
73
 
71
- func validate(username: String) throws(ValidationError) -> String {
72
- guard username.count >= 3 else { throw .tooShort }
73
- guard username.allSatisfy(\.isLetterOrDigit) else { throw .invalidCharacters }
74
- return username.lowercased()
74
+ ```swift
75
+ enum ParseFailure: Error { case emptyInput, badDigit(Character) }
76
+
77
+ func parseCode(_ text: String) throws(ParseFailure) -> Int {
78
+ guard !text.isEmpty else { throw .emptyInput }
79
+ var value = 0
80
+ for ch in text {
81
+ guard let d = ch.wholeNumberValue else { throw .badDigit(ch) }
82
+ value = value * 10 + d
83
+ }
84
+ return value
75
85
  }
76
86
 
77
- // Caller gets typed error -- no cast needed
78
- do {
79
- let name = try validate(username: input)
80
- } catch {
81
- // error is ValidationError, not any Error
82
- switch error {
83
- case .tooShort: print("Too short")
84
- case .invalidCharacters: print("Invalid characters")
85
- case .alreadyTaken: print("Taken")
87
+ func show(_ text: String) -> String {
88
+ do {
89
+ return String(try parseCode(text))
90
+ } catch {
91
+ switch error {
92
+ case .emptyInput: return "missing"
93
+ case .badDigit(let c): return "bad \(c)"
94
+ }
86
95
  }
87
96
  }
88
97
  ```
89
98
 
90
- **Rules:**
91
- - Use `throws(SomeError)` only when callers benefit from exhaustive error
92
- handling. For mixed error sources, use untyped `throws`.
93
- - `throws(Never)` marks a function that syntactically throws but never actually
94
- does -- useful in generic contexts.
95
- - Typed throws propagate: a function calling `throws(A)` and `throws(B)` must
96
- itself throw a type that covers both (or use untyped `throws`).
99
+ Guidance:
97
100
 
98
- ## Result Builders
101
+ - Reach for `throws(E)` when there is one clear error type and callers gain
102
+ from handling every case. Code that forwards errors from several unrelated
103
+ sources stays with plain `throws`.
104
+ - `throws(Never)` spells a function that is declared throwing but cannot
105
+ throw; it matters mostly in generic code that is parameterised over the
106
+ error type.
107
+ - Calling a `throws(A)` function and a `throws(B)` function from one body means
108
+ the outer function must throw a type that covers both, or be untyped.
99
109
 
100
- `@resultBuilder` enables DSL-style syntax. SwiftUI's `@ViewBuilder` is the most
101
- common example, but you can create custom builders for any domain.
110
+ ## Result builders
111
+
112
+ `@resultBuilder` turns a closure of plain statements into a built value.
113
+ `@ViewBuilder` is the one most people meet first.
102
114
 
103
115
  ```swift
104
116
  @resultBuilder
105
- struct ArrayBuilder<Element> {
106
- static func buildBlock(_ components: [Element]...) -> [Element] {
107
- components.flatMap { $0 }
108
- }
109
- static func buildExpression(_ expression: Element) -> [Element] { [expression] }
110
- static func buildOptional(_ component: [Element]?) -> [Element] { component ?? [] }
111
- static func buildEither(first component: [Element]) -> [Element] { component }
112
- static func buildEither(second component: [Element]) -> [Element] { component }
113
- static func buildArray(_ components: [[Element]]) -> [Element] { components.flatMap { $0 } }
117
+ enum LinesBuilder {
118
+ static func buildExpression(_ line: String) -> [String] { [line] }
119
+ static func buildBlock(_ parts: [String]...) -> [String] { parts.flatMap { $0 } }
120
+ static func buildOptional(_ part: [String]?) -> [String] { part ?? [] }
121
+ static func buildEither(first part: [String]) -> [String] { part }
122
+ static func buildEither(second part: [String]) -> [String] { part }
123
+ static func buildArray(_ parts: [[String]]) -> [String] { parts.flatMap { $0 } }
114
124
  }
115
125
 
116
- func makeItems(@ArrayBuilder<String> content: () -> [String]) -> [String] { content() }
126
+ func receipt(@LinesBuilder _ body: () -> [String]) -> String {
127
+ body().joined(separator: "\n")
128
+ }
117
129
 
118
- let items = makeItems {
119
- "Always included"
120
- if showExtra { "Conditional" }
121
- for name in names { name.uppercased() }
130
+ let items = ["tea", "scone"]
131
+ let printed = receipt {
132
+ "Corner Cafe"
133
+ for item in items { "- \(item)" }
134
+ if items.count > 1 { "multi-item order" } else { "single item" }
122
135
  }
123
136
  ```
124
137
 
125
- **Builder methods:** `buildBlock` (combine statements), `buildExpression` (single value), `buildOptional` (`if` without `else`), `buildEither` (`if/else`), `buildArray` (`for..in`), `buildFinalResult` (optional post-processing).
138
+ What each hook handles:
139
+
140
+ | Method | Called for |
141
+ |---|---|
142
+ | `buildBlock` | combining the statements of a block |
143
+ | `buildExpression` | lifting one expression into the component type |
144
+ | `buildOptional` | `if` with no `else` |
145
+ | `buildEither(first:)` / `buildEither(second:)` | the two arms of `if`/`else` (and `switch`) |
146
+ | `buildArray` | `for ... in` loops |
147
+ | `buildFinalResult` | optional last step that converts the result |
126
148
 
127
- ## Property Wrappers
149
+ More builders: [references/swift-patterns-extended.md](references/swift-patterns-extended.md#result-builders).
128
150
 
129
- Custom `@propertyWrapper` types encapsulate storage and access patterns.
151
+ ## Property wrappers
130
152
 
131
153
  ```swift
132
154
  @propertyWrapper
133
- struct Clamped<Value: Comparable> {
134
- private var value: Value
135
- let range: ClosedRange<Value>
155
+ struct Bounded<Value: Comparable> {
156
+ private var stored: Value
157
+ let limits: ClosedRange<Value>
136
158
 
137
- var wrappedValue: Value {
138
- get { value }
139
- set { value = min(max(newValue, range.lowerBound), range.upperBound) }
159
+ init(wrappedValue: Value, _ limits: ClosedRange<Value>) {
160
+ self.limits = limits
161
+ stored = min(max(wrappedValue, limits.lowerBound), limits.upperBound)
140
162
  }
141
163
 
142
- var projectedValue: ClosedRange<Value> { range }
143
-
144
- init(wrappedValue: Value, _ range: ClosedRange<Value>) {
145
- self.range = range
146
- self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
164
+ var wrappedValue: Value {
165
+ get { stored }
166
+ set { stored = min(max(newValue, limits.lowerBound), limits.upperBound) }
147
167
  }
148
- }
149
168
 
150
- // Usage
151
- struct Volume {
152
- @Clamped(0...100) var level: Int = 50
169
+ var projectedValue: ClosedRange<Value> { limits }
153
170
  }
154
171
 
155
- var v = Volume()
156
- v.level = 150 // clamped to 100
157
- print(v.$level) // projected value: 0...100
158
- ```
159
-
160
- **Design rules:**
161
- - `wrappedValue` is the primary getter/setter.
162
- - `projectedValue` (accessed via `$property`) provides metadata or bindings.
163
- - Property wrappers can be composed: `@A @B var x` applies outer wrapper first.
164
- - Do not use property wrappers when a simple computed property suffices.
165
-
166
- ## Opaque and Existential Types
167
-
168
- ### `some Protocol` (Opaque Type)
169
-
170
- The caller does not know the concrete type, but the compiler does. The
171
- underlying type is fixed for a given scope.
172
-
173
- ```swift
174
- func makeCollection() -> some Collection<Int> {
175
- [1, 2, 3] // Always returns Array<Int> -- compiler knows the concrete type
172
+ struct Thermostat {
173
+ @Bounded(10...30) var target: Double = 21
176
174
  }
177
- ```
178
175
 
179
- Use `some` for:
180
- - Return types when you want to hide implementation but preserve type identity.
181
- - Parameter types (Swift 5.7+): `some P` is shorthand for an unnamed generic
182
- parameter such as `<T: P>`.
183
-
184
- ### `any Protocol` (Existential Type)
185
-
186
- An existential box that can hold any conforming type at runtime. It uses dynamic
187
- dispatch and may allocate when the value does not fit in the inline buffer.
188
-
189
- ```swift
190
- func process(items: [any StringProtocol]) {
191
- for item in items {
192
- print(item.uppercased())
193
- }
194
- }
176
+ var unit = Thermostat()
177
+ unit.target = 45
178
+ let clamped = unit.target
179
+ let window = unit.$target
195
180
  ```
196
181
 
197
- ### When to choose
198
-
199
- | Use `some` | Use `any` |
182
+ - `wrappedValue` is the getter and setter the property exposes.
183
+ - `projectedValue` is what `$name` returns: metadata, a binding, a validity
184
+ flag.
185
+ - Wrappers stack. With `@Outer @Inner var x`, the outer one wraps the inner
186
+ one and is applied first.
187
+ - If a computed property would do the job, write the computed property. A
188
+ wrapper earns its place through reuse or a useful projection.
189
+
190
+ ## some and any
191
+
192
+ - `some Shape` is an opaque type: the compiler knows the concrete type, the
193
+ caller does not, and the type stays the same for every return from that
194
+ scope. `func evens() -> some Collection<Int> { [2, 4, 6] }` hides the array.
195
+ - In parameter position (Swift 5.7+), `some Shape` is shorthand for an
196
+ anonymous generic parameter `<T: Shape>`.
197
+ - `any Shape` is an existential box. It can hold any conforming value at
198
+ runtime, calls go through dynamic dispatch, and a value too large for the
199
+ box's inline storage is heap allocated.
200
+
201
+ | Pick `some` for | Pick `any` for |
200
202
  |---|---|
201
- | Return type hiding concrete type | Heterogeneous collections |
202
- | Function parameters (replaces simple generics) | Dynamic type erasure needed |
203
- | Better performance (static dispatch) | Protocol has `Self` or associated type requirements you need to erase |
203
+ | hiding a return type | mixed-type collections such as `[any Shape]` |
204
+ | simple generic parameters | erasing a type chosen at runtime |
205
+ | static dispatch and speed | working past `Self` or associated-type constraints |
204
206
 
205
- **Rule of thumb:** Default to `some`. Use `any` only when you need a
206
- heterogeneous collection or runtime type flexibility.
207
+ Start from `some`. Move to `any` only when values of different concrete types
208
+ really have to share one container or the type is decided at runtime.
207
209
 
208
- ## Guard Patterns
210
+ ## guard
209
211
 
210
- `guard` enforces preconditions and enables early exit. It keeps the happy path
211
- left-aligned and reduces nesting.
212
+ `guard` states a precondition and leaves early when it fails, so the main path
213
+ stays at the left margin.
212
214
 
213
215
  ```swift
214
- func processOrder(_ order: Order?) throws -> Receipt {
215
- // Unwrap optionals
216
- guard let order else { throw OrderError.missing }
217
-
218
- // Validate conditions
219
- guard order.items.isEmpty == false else { throw OrderError.empty }
220
- guard order.total > 0 else { throw OrderError.invalidTotal }
221
-
222
- // Boolean checks
223
- guard order.isPaid else { throw OrderError.unpaid }
224
-
225
- // Pattern matching
226
- guard case .confirmed(let date) = order.status else {
227
- throw OrderError.notConfirmed
216
+ enum Shipment { case pending, dispatched(on: Date), lost }
217
+ struct Parcel { var weight: Double; var status: Shipment }
218
+ enum ParcelError: Error { case none, tooHeavy, notDispatched }
219
+
220
+ func dispatchDate(_ parcel: Parcel?, express: Bool) throws -> Date {
221
+ guard let parcel else { throw ParcelError.none }
222
+ guard parcel.weight <= 30 else { throw ParcelError.tooHeavy }
223
+ guard express else { return .distantFuture }
224
+ guard case .dispatched(let date) = parcel.status else {
225
+ throw ParcelError.notDispatched
228
226
  }
229
-
230
- return Receipt(order: order, confirmedAt: date)
227
+ return date
231
228
  }
232
229
  ```
233
230
 
234
- **Best practices:**
235
- - Use `guard` for preconditions, `if` for branching logic.
236
- - Combine related guards: `guard let a, let b else { return }`.
237
- - The `else` block must exit scope: `return`, `throw`, `continue`, `break`, or
238
- `fatalError()`.
239
- - Use shorthand unwrap: `guard let value else { ... }` (Swift 5.7+).
231
+ - `guard` for preconditions, `if` for genuine branches.
232
+ - Several bindings fit one statement: `guard let host, let port else { return }`.
233
+ - The `else` body has to leave the scope: `return`, `throw`, `continue`,
234
+ `break`, or a `Never` call such as `fatalError()`.
235
+ - The shorthand `guard let value else` needs Swift 5.7 or later.
240
236
 
241
- ## Never Type
237
+ ## Never
242
238
 
243
- `Never` is an uninhabited type for code paths that never produce a value. It
244
- works as Swift's bottom type in expression contexts, but it does not implicitly
245
- conform to arbitrary protocols or satisfy a generic `T: SomeProtocol`
246
- constraint. When recommending `Result<T, Never>` or `throws(Never)`, explicitly
247
- state all three points: uninhabited, bottom-like, and no universal protocol
248
- conformance.
239
+ When `Never` comes up, say all three things, because each changes what code
240
+ compiles:
249
241
 
250
- ```swift
251
- // Function that terminates the program
252
- func crashWithDiagnostics(_ message: String) -> Never {
253
- let diagnostics = gatherDiagnostics()
254
- logger.critical("\(message): \(diagnostics)")
255
- fatalError(message)
256
- }
242
+ 1. It is uninhabited: no value of type `Never` can exist.
243
+ 2. It behaves like a bottom type in expressions: a call returning `Never` can
244
+ stand where any type is expected.
245
+ 3. It does not conform to arbitrary protocols, so it does not satisfy an
246
+ arbitrary `T: SomeProtocol` constraint on its own.
247
+
248
+ This applies whenever you recommend `Result<T, Never>` or `throws(Never)`.
257
249
 
258
- enum Result<Success, Failure: Error> {
259
- case success(Success)
260
- case failure(Failure)
250
+ ```swift
251
+ func halt(_ reason: String, context: [String: String]) -> Never {
252
+ let summary = context.map { "\($0.key)=\($0.value)" }.sorted().joined(separator: " ")
253
+ print("fatal: \(reason) \(summary)")
254
+ fatalError(reason)
261
255
  }
262
- // Result<String, Never> -- a result that can never fail
263
256
 
264
- // Exhaustive switch: no default needed since Never has no cases
265
- func handle(_ result: Result<String, Never>) {
266
- switch result {
267
- case .success(let value): print(value)
268
- // No .failure case needed -- compiler knows it's impossible
269
- }
257
+ let greeting: Result<String, Never> = .success("hello")
258
+ switch greeting {
259
+ case .success(let text): print(text)
270
260
  }
271
261
  ```
272
262
 
273
- ## Regex Builders
263
+ A function returning `Never` does not come back. A `Result` whose failure type
264
+ is `Never` cannot fail, so the `switch` needs only `.success` and no `default`.
265
+
266
+ ## Regex builders
274
267
 
275
- Swift 5.7+ Regex builder DSL provides compile-time checked, readable patterns.
268
+ `RegexBuilder` (Swift 5.7+, imported next to Foundation) writes patterns as
269
+ readable, compiler-checked Swift with typed captures.
276
270
 
277
271
  ```swift
278
272
  import Foundation
279
273
  import RegexBuilder
280
274
 
281
- // Parse "2024-03-15" into components
282
- let dateRegex = Regex {
283
- Capture { /\d{4}/ }; "-"; Capture { /\d{2}/ }; "-"; Capture { /\d{2}/ }
275
+ let clock = Regex {
276
+ Capture { /\d{2}/ }
277
+ ":"
278
+ Capture { /\d{2}/ }
284
279
  }
285
-
286
- if let match = "2024-03-15".firstMatch(of: dateRegex) {
287
- let (_, year, month, day) = match.output
288
- _ = (year, month, day)
280
+ if let hit = "Doors open 19:45".firstMatch(of: clock) {
281
+ let (_, hour, minute) = hit.output
282
+ print(hour, minute)
289
283
  }
290
284
 
291
- // TryCapture with transform
292
- let priceRegex = Regex {
293
- "$"
294
- TryCapture { OneOrMore(.digit); "."; Repeat(.digit, count: 2) }
295
- transform: { Decimal(string: String($0)) }
285
+ let price = Regex {
286
+ "EUR "
287
+ TryCapture {
288
+ OneOrMore(.digit)
289
+ "."
290
+ Repeat(.digit, count: 2)
291
+ } transform: { Decimal(string: String($0)) }
296
292
  }
297
293
  ```
298
294
 
299
- **When to use builder vs. literal:**
300
- - Builder: complex patterns, reusable components, strong typing on captures.
301
- - Literal (`/pattern/`): simple patterns, familiarity with regex syntax.
302
- - Both can be mixed: embed `/.../` literals inside builder blocks.
303
-
304
- ## Codable Best Practices
295
+ Use the builder when a pattern is long, reused, or needs typed captures. A
296
+ short one-off pattern reads better as a literal such as `/\d+/`, and literals
297
+ can be dropped into a builder where that helps. More in
298
+ [references/swift-patterns-extended.md](references/swift-patterns-extended.md#advanced-regex).
305
299
 
306
- ### Custom CodingKeys
307
-
308
- Rename keys without writing a custom decoder:
300
+ ## Codable basics
309
301
 
310
302
  ```swift
311
- struct User: Codable {
312
- let id: Int
313
- let displayName: String
314
- let avatarURL: URL
303
+ struct Venue: Codable {
304
+ var venueName: String
305
+ var seatCount: Int
306
+ var isOutdoor: Bool
307
+ var city: String
315
308
 
316
309
  enum CodingKeys: String, CodingKey {
317
- case id
318
- case displayName = "display_name"
319
- case avatarURL = "avatar_url"
310
+ case venueName = "venue_name", seatCount = "seat_count", isOutdoor = "is_outdoor", location
320
311
  }
321
- }
322
- ```
323
-
324
- ### Custom Decoding
325
-
326
- Handle mismatched types, defaults, and transformations:
327
-
328
- ```swift
329
- struct Item: Decodable {
330
- let name: String
331
- let quantity: Int
332
- let isActive: Bool
312
+ enum LocationKeys: String, CodingKey { case city }
333
313
 
334
314
  init(from decoder: Decoder) throws {
335
- let container = try decoder.container(keyedBy: CodingKeys.self)
336
- name = try container.decode(String.self, forKey: .name)
337
- quantity = try container.decodeIfPresent(Int.self, forKey: .quantity) ?? 0
338
- if let boolValue = try? container.decode(Bool.self, forKey: .isActive) {
339
- isActive = boolValue
315
+ let c = try decoder.container(keyedBy: CodingKeys.self)
316
+ venueName = try c.decode(String.self, forKey: .venueName)
317
+ seatCount = try c.decodeIfPresent(Int.self, forKey: .seatCount) ?? 0
318
+ if let flag = try? c.decode(Bool.self, forKey: .isOutdoor) {
319
+ isOutdoor = flag
340
320
  } else {
341
- isActive = (try container.decode(String.self, forKey: .isActive)).lowercased() == "true"
321
+ isOutdoor = (try c.decodeIfPresent(String.self, forKey: .isOutdoor)) == "true"
342
322
  }
343
- }
344
- enum CodingKeys: String, CodingKey { case name, quantity; case isActive = "is_active" }
345
- }
346
- ```
347
-
348
- ### Nested Containers
349
-
350
- Flatten nested JSON into a flat Swift struct:
351
-
352
- ```swift
353
- // JSON: { "id": 1, "metadata": { "created_at": "...", "tags": [...] } }
354
- struct Record: Decodable {
355
- let id: Int
356
- let createdAt: String
357
- let tags: [String]
358
-
359
- enum CodingKeys: String, CodingKey {
360
- case id, metadata
323
+ let place = try c.nestedContainer(keyedBy: LocationKeys.self, forKey: .location)
324
+ city = try place.decode(String.self, forKey: .city)
361
325
  }
362
326
 
363
- enum MetadataKeys: String, CodingKey {
364
- case createdAt = "created_at"
365
- case tags
366
- }
367
-
368
- init(from decoder: Decoder) throws {
369
- let container = try decoder.container(keyedBy: CodingKeys.self)
370
- id = try container.decode(Int.self, forKey: .id)
371
- let metadata = try container.nestedContainer(
372
- keyedBy: MetadataKeys.self, forKey: .metadata)
373
- createdAt = try metadata.decode(String.self, forKey: .createdAt)
374
- tags = try metadata.decode([String].self, forKey: .tags)
327
+ func encode(to encoder: Encoder) throws {
328
+ var c = encoder.container(keyedBy: CodingKeys.self)
329
+ try c.encode(venueName, forKey: .venueName)
330
+ try c.encode(seatCount, forKey: .seatCount)
331
+ try c.encode(isOutdoor, forKey: .isOutdoor)
332
+ var place = c.nestedContainer(keyedBy: LocationKeys.self, forKey: .location)
333
+ try place.encode(city, forKey: .city)
375
334
  }
376
335
  }
377
336
  ```
378
337
 
379
- See [references/swift-patterns-extended.md](references/swift-patterns-extended.md) for additional Codable patterns
380
- (enums with associated values, date strategies, unkeyed containers).
338
+ - A `CodingKeys: String, CodingKey` enum renames snake_case keys without a
339
+ custom decoder.
340
+ - A custom `init(from:)` covers defaults (`decodeIfPresent(...) ?? value`) and
341
+ type mismatches, here a flag that sometimes arrives as the string `"true"`.
342
+ - `nestedContainer(keyedBy:forKey:)` flattens a nested JSON object into flat
343
+ properties using a second key enum.
381
344
 
382
- ## Modern Collection APIs
345
+ Enums with associated values, date strategies and unkeyed containers are in
346
+ [references/swift-patterns-extended.md](references/swift-patterns-extended.md#codable).
347
+ Anything beyond this goes to `swift-codable`.
383
348
 
384
- Prefer these modern APIs over manual loops:
349
+ ## Collection APIs
385
350
 
386
351
  ```swift
387
- let numbers = [1, 2, 3, 4, 5, 6, 7, 8]
388
-
389
- // count(where:) -- use instead of .filter { }.count
390
- let evenCount = numbers.count(where: { $0.isMultiple(of: 2) })
391
-
392
- // contains(where:) -- short-circuits on first match
393
- let hasNegative = numbers.contains(where: { $0 < 0 })
394
-
395
- // first(where:) / last(where:)
396
- let firstEven = numbers.first(where: { $0.isMultiple(of: 2) })
397
-
398
- // String replacing() -- Swift 5.7+, returns new string
399
- let cleaned = rawText.replacing(/\s+/, with: " ")
400
- let snakeCase = name.replacing("_", with: " ")
401
-
402
- // compactMap -- unwrap optionals from a transform
403
- let ids = strings.compactMap { Int($0) }
404
-
405
- // flatMap -- flatten nested collections
406
- let allTags = articles.flatMap(\.tags)
407
-
408
- // Dictionary(grouping:by:)
409
- let byCategory = Dictionary(grouping: items, by: \.category)
410
-
411
- // reduce(into:) -- efficient accumulation
412
- let freq = words.reduce(into: [:]) { counts, word in
413
- counts[word, default: 0] += 1
414
- }
352
+ let scores = [72, 95, 40, 88]
353
+ let passed = scores.count(where: { $0 >= 50 })
354
+ let hasPerfect = scores.contains(where: { $0 == 100 })
355
+ let firstFail = scores.first(where: { $0 < 50 })
356
+ let lastHigh = scores.last(where: { $0 > 80 })
357
+
358
+ let slug = "Summer Sale 2026".replacing(" ", with: "-")
359
+ let digitsHidden = "PIN 4821".replacing(/\d/, with: "*")
360
+
361
+ struct Post { var tags: [String]; var author: String? }
362
+ let posts = [Post(tags: ["swift"], author: "ana"), Post(tags: ["ios", "swift"], author: nil)]
363
+ let authors = posts.compactMap(\.author)
364
+ let allTags = posts.flatMap(\.tags)
365
+ let byFirstTag = Dictionary(grouping: posts, by: { $0.tags.first ?? "" })
366
+ let tagCounts = allTags.reduce(into: [:]) { tally, tag in tally[tag, default: 0] += 1 }
415
367
  ```
416
368
 
417
- ## FormatStyle
369
+ - `count(where:)` replaces `filter { }.count` without building an array.
370
+ - `contains(where:)` stops at the first match.
371
+ - `String.replacing(_:with:)` (Swift 5.7+) returns a new string and takes a
372
+ string or a regex.
373
+ - `compactMap` drops `nil`; `flatMap(\.tags)` flattens nested arrays.
374
+ - `Dictionary(grouping:by:)` buckets values by a key.
375
+ - `reduce(into:)` mutates one accumulator instead of copying on every step.
418
376
 
419
- Use `.formatted()` instead of `DateFormatter`/`NumberFormatter`. It is
420
- type-safe, localized, and concise.
377
+ ## Formatting basics
421
378
 
422
- ```swift
423
- // Dates
424
- let now = Date.now
425
- now.formatted() // "3/15/2024, 2:30 PM"
426
- now.formatted(date: .abbreviated, time: .shortened) // "Mar 15, 2024, 2:30 PM"
427
- now.formatted(.dateTime.year().month().day()) // "Mar 15, 2024"
428
- now.formatted(.relative(presentation: .named)) // "yesterday"
429
-
430
- // Numbers
431
- let price = 42.5
432
- price.formatted(.currency(code: "USD")) // "$42.50"
433
- price.formatted(.percent) // "4,250%"
434
- (1_000_000).formatted(.number.notation(.compactName)) // "1M"
435
-
436
- // Measurements
437
- let distance = Measurement(value: 5, unit: UnitLength.kilometers)
438
- distance.formatted(.measurement(width: .abbreviated)) // "5 km"
439
-
440
- // Duration (Swift 5.7+)
441
- let duration = Duration.seconds(3661)
442
- duration.formatted(.time(pattern: .hourMinuteSecond)) // "1:01:01"
443
-
444
- // Byte counts
445
- Int64(1_500_000).formatted(.byteCount(style: .file)) // "1.5 MB"
446
-
447
- // Lists
448
- ["Alice", "Bob", "Carol"].formatted(.list(type: .and)) // "Alice, Bob, and Carol"
449
- ```
379
+ Prefer `.formatted()` to `DateFormatter` and `NumberFormatter`: it is typed,
380
+ localized and short.
450
381
 
451
- **Parsing:** `FormatStyle` also supports parsing:
452
382
  ```swift
453
- let value = try Decimal("$42.50", format: .currency(code: "USD"))
454
- let date = try Date("Mar 15, 2024", strategy: .dateTime.month().day().year())
383
+ import Foundation
384
+
385
+ let now = Date()
386
+ now.formatted()
387
+ now.formatted(date: .abbreviated, time: .shortened)
388
+ now.formatted(.dateTime.year().month().day())
389
+ now.addingTimeInterval(-3600).formatted(.relative(presentation: .named))
390
+
391
+ 19.99.formatted(.currency(code: "EUR"))
392
+ 0.425.formatted(.percent)
393
+ 42.5.formatted(.percent)
394
+ 2_400_000.formatted(.number.notation(.compactName))
395
+ Measurement(value: 12, unit: UnitLength.kilometers).formatted(.measurement(width: .abbreviated))
396
+ Duration.seconds(4000).formatted(.time(pattern: .hourMinuteSecond))
397
+ Int64(5_300_000).formatted(.byteCount(style: .file))
398
+ ["oat", "rye", "spelt"].formatted(.list(type: .and))
399
+
400
+ let cost = try Decimal("EUR 42.50", format: .currency(code: "EUR"))
401
+ let day = try Date("Mar 4, 2026", strategy: .dateTime.month().day().year())
455
402
  ```
456
403
 
457
- ## String Interpolation
458
-
459
- Extend `DefaultStringInterpolation` for domain-specific formatting. Use `"""` for multi-line strings (indentation is relative to the closing `"""`). See [references/swift-patterns-extended.md](references/swift-patterns-extended.md) for custom interpolation examples.
460
-
461
- ## Common Mistakes
462
-
463
- 1. **Using `any` when `some` works.** Default to `some` for return types and
464
- parameters. `any` has runtime overhead and loses type information.
465
- 2. **Manual loops instead of collection APIs.** Use `count(where:)`,
466
- `contains(where:)`, `compactMap`, `flatMap` instead of manual iteration.
467
- 3. **`DateFormatter` instead of FormatStyle.** `.formatted()` is simpler,
468
- type-safe, and handles localization automatically.
469
- 4. **Force-unwrapping Codable decodes.** Use `decodeIfPresent` with defaults
470
- for optional or missing keys.
471
- 5. **Nested if-let chains.** Use `guard let` for preconditions to keep the
472
- happy path at the top level.
473
- 6. **Invalid `@c` signatures.** Name valid C types and explicitly reject:
474
- `String`, `Array`, `UnsafeBufferPointer`, closures, generic placeholders.
475
- 7. **Ignoring typed throws.** When a function has a single, clear error type,
476
- typed throws give callers exhaustive switch without casting.
477
- 8. **Overusing property wrappers.** A computed property is simpler when there
478
- is no reuse or projected value needed.
479
- 9. **Underspecifying `Never`.** For `Result<T, Never>` or `throws(Never)`, say:
480
- uninhabited, bottom-like, and not arbitrary `T: P` protocol conformance.
481
- 10. **Owning deep formatting/localization.** Use `swift-formatstyle` for detailed
482
- formatting and `ios-localization` for market/localized-display QA.
483
-
484
- ## Review Checklist
485
-
486
- - [ ] `some` used for opaque returns and Swift 5.7+ generic-parameter shorthand
404
+ `.percent` multiplies by 100, so `42.5` prints as `4,250%`; pass `0.425` for
405
+ 42.5%. `.compactName` turns 2,400,000 into `2.4M`. `Duration.formatted` needs
406
+ Swift 5.7+. Everything past these basics, including locale behaviour and
407
+ custom styles in depth, belongs to `swift-formatstyle`.
408
+
409
+ ## String interpolation
410
+
411
+ Extending `DefaultStringInterpolation` gives domain-specific `\(...)` forms;
412
+ see [references/swift-patterns-extended.md](references/swift-patterns-extended.md#string-interpolation).
413
+ In a `"""` multi-line string, indentation is measured from the closing
414
+ delimiter, so align the closing quotes with the text you want flush left.
415
+
416
+ ## Common mistakes
417
+
418
+ 1. `any` where `some` would do: adds boxing and dynamic dispatch and throws
419
+ away type information.
420
+ 2. Hand-written loops where `count(where:)`, `contains(where:)`, `compactMap`
421
+ or `flatMap` say it directly.
422
+ 3. New `DateFormatter` code instead of format styles.
423
+ 4. Force-unwrapping decoded values; use `decodeIfPresent` with a default.
424
+ 5. Nested `if let` pyramids; use `guard let`.
425
+ 6. Accepting an invalid `@c` signature. Name the C-compatible types that are
426
+ allowed and reject `String`, `Array`, `UnsafeBufferPointer`, closures and
427
+ generic placeholders.
428
+ 7. Plain `throws` when a single error type exists and callers would switch on
429
+ it.
430
+ 8. A property wrapper with no reuse and no projection.
431
+ 9. Describing `Never` loosely; state uninhabited, bottom-like and no universal
432
+ conformance.
433
+ 10. Taking over deep formatting or localization work that belongs to
434
+ `swift-formatstyle` and `ios-localization`.
435
+
436
+ ## Review checklist
437
+
438
+ - [ ] `some` used for opaque returns and as parameter shorthand
487
439
  - [ ] `guard` for preconditions; collection APIs instead of manual loops
488
- - [ ] `.formatted()` used instead of `DateFormatter`/`NumberFormatter`
489
- - [ ] Codable types use `CodingKeys` for API mapping; `decodeIfPresent` with defaults for optional fields
490
- - [ ] if/switch expressions for conditional assignment; property wrappers have clear reuse justification
491
- - [ ] Regex builder used for complex patterns (literal OK for simple ones)
492
- - [ ] Typed throws used when callers benefit from exhaustive error handling
493
- - [ ] `@c` corrections enumerate rejected Swift-only types by name
494
- - [ ] `Never` guidance says uninhabited, bottom-like, and not arbitrary `T: P` protocol conformance
495
- - [ ] deep Codable, formatting/localization, naming, concurrency, and SwiftUI work routed to sibling skills
440
+ - [ ] `.formatted()` instead of formatter objects
441
+ - [ ] `CodingKeys` for renames; `decodeIfPresent` with defaults
442
+ - [ ] `if`/`switch` expressions for conditional assignment; wrappers justified
443
+ by reuse
444
+ - [ ] Regex builder for complex patterns, literals for simple ones
445
+ - [ ] typed throws where exhaustive handling helps callers
446
+ - [ ] `@c` corrections list the rejected Swift-only types
447
+ - [ ] `Never` guidance states all three properties
448
+ - [ ] deep Codable, formatting and localization, naming, concurrency and
449
+ SwiftUI work sent to the sibling skills
450
+
496
451
  ## References
497
452
 
498
- - Extended patterns and Codable examples: [references/swift-patterns-extended.md](references/swift-patterns-extended.md)
499
- - Attributes and C interop: [references/swift-attributes-interop.md](references/swift-attributes-interop.md)
453
+ - [references/swift-patterns-extended.md](references/swift-patterns-extended.md):
454
+ Codable edge cases, builders, wrappers, advanced Regex, custom format
455
+ styles, Swift Algorithms, complex `guard`, typed throws in protocols, custom
456
+ interpolation, advanced `Never`.
457
+ - [references/swift-attributes-interop.md](references/swift-attributes-interop.md):
458
+ `@c`, module selectors, `@specialized`, `@inline(always)`, `@export`,
459
+ `@section` and `@used`.