@mmerterden/multi-agent-pipeline 20.6.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.
- package/CHANGELOG.md +27 -0
- package/LICENSE +0 -10
- package/docs/facts.json +1 -1
- package/manifest.json +328 -329
- package/package.json +2 -2
- package/pipeline/multi-agent-refs/features/design-conformance.md +62 -64
- package/pipeline/scripts/_notices.mjs +12 -1
- package/pipeline/scripts/gen-skills-index.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +106 -106
- package/pipeline/skills/shared/README.md +71 -71
- package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +1 -0
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
- package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
- package/pipeline/skills/shared/external/android-architecture/SKILL.md +2 -0
- package/pipeline/skills/shared/external/android-performance/SKILL.md +2 -0
- package/pipeline/skills/shared/external/android-security/SKILL.md +2 -0
- package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
- package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
- package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
- package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
- package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
- package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
- package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
- package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
- package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
- package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
- package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
- package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
- package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
- package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
- package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
- package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
- package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
- package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
- package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
- package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
- package/pipeline/skills/shared/external/backlog/SKILL.md +56 -33
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
- package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -0
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
- package/pipeline/skills/shared/external/compose-components/SKILL.md +2 -0
- package/pipeline/skills/shared/external/compose-navigation/SKILL.md +3 -2
- package/pipeline/skills/shared/external/compose-testing/SKILL.md +2 -0
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
- package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
- package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
- package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
- package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
- package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
- package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
- package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
- package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
- package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
- package/pipeline/skills/shared/external/council/SKILL.md +1 -0
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
- package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
- package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
- package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -0
- package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
- package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
- package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
- package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
- package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
- package/pipeline/skills/shared/external/evidence-github/SKILL.md +2 -0
- package/pipeline/skills/shared/external/evidence-registry/SKILL.md +2 -0
- package/pipeline/skills/shared/external/gradle-kotlin-dsl/SKILL.md +2 -0
- package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
- package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
- package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -0
- package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
- package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
- package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
- package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
- package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
- package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
- package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
- package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
- package/pipeline/skills/shared/external/ios-security/SKILL.md +2 -0
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
- package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
- package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
- package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +91 -283
- package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +119 -151
- package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +60 -90
- package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +119 -156
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +726 -787
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +253 -288
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +243 -304
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +88 -104
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +181 -235
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-key-shots.py +198 -263
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +461 -466
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +145 -151
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +123 -141
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +146 -157
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/snapshot-resources.sh +22 -19
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +156 -140
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
- package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
- package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
- package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
- package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -0
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
- package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
- package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
- package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
- package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
- package/pipeline/skills/shared/external/play-store-review/SKILL.md +2 -0
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
- package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
- package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -0
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
- package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -0
- package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +2 -0
- package/pipeline/skills/shared/external/room-database/SKILL.md +2 -0
- package/pipeline/skills/shared/external/search-first/SKILL.md +1 -0
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
- package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
- package/pipeline/skills/shared/external/signal-community/SKILL.md +2 -0
- package/pipeline/skills/shared/external/skill-creator/SKILL.md +80 -41
- package/pipeline/skills/shared/external/skill-creator/audit.md +63 -59
- package/pipeline/skills/shared/external/skill-creator/checklist.md +28 -20
- package/pipeline/skills/shared/external/skill-creator/examples.md +40 -40
- package/pipeline/skills/shared/external/skill-creator/label-check.md +48 -36
- package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +91 -100
- package/pipeline/skills/shared/external/skill-creator/template.md +51 -39
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
- package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
- package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
- package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
- package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
- package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
- package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
- package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
- package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
- package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
- package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
- package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
- package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
- package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
- package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
- package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
- package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
- package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
- package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
- package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
- package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
- package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
- package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
- package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
- package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
- package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
- package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
- package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
- package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
- package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
- package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
- package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
- package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
- package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
- package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
- package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
- package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
- package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
- package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
- package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
- package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
- package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -0
- package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -0
- package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
- package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
- package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -0
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
- package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -0
- package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -0
- package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -0
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
|
@@ -3,42 +3,45 @@
|
|
|
3
3
|
"evals": [
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
|
-
"
|
|
7
|
-
"
|
|
6
|
+
"name": "calendar-access-levels",
|
|
7
|
+
"prompt": "Our event-ticket app targets iOS 16 and later. It calls requestAccess(to: .event) on every launch, only has NSCalendarsUsageDescription in Info.plist, asks for write-only access so it can add concerts, and then checks the user's calendar for clashes. Some people just want to add a concert through the system editor. What should change?",
|
|
8
|
+
"expected_output": "Adds the iOS 17 full-access and write-only keys alongside the legacy key, uses the granular request methods with requestAccess(to:) only in a pre-17 availability branch, explains write-only cannot read or fetch so the clash check needs full access, and notes EKEventEditViewController needs no permission on iOS 17+ but its saved result cannot be inspected.",
|
|
8
9
|
"files": [],
|
|
9
10
|
"assertions": [
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"Requires full
|
|
14
|
-
"
|
|
11
|
+
"Adds NSCalendarsFullAccessUsageDescription and NSCalendarsWriteOnlyAccessUsageDescription, not only the legacy key",
|
|
12
|
+
"Uses requestFullAccessToEvents or requestWriteOnlyAccessToEvents on iOS 17+, with requestAccess(to:) only as an availability-guarded fallback",
|
|
13
|
+
"States write-only access cannot read calendars or fetch events",
|
|
14
|
+
"Requires full access for the conflict check",
|
|
15
|
+
"Says EKEventEditViewController works without authorization on iOS 17+ and the app cannot inspect what was saved"
|
|
15
16
|
]
|
|
16
17
|
},
|
|
17
18
|
{
|
|
18
19
|
"id": 2,
|
|
19
|
-
"
|
|
20
|
-
"
|
|
20
|
+
"name": "location-reminder",
|
|
21
|
+
"prompt": "Build a 'remind me when I get to the hardware store' feature. We have the store's coordinates from our own database. Our draft saves an EKReminder straight away without a calendar, puts the coordinate in the notes field, and asks for Always location permission at launch.",
|
|
22
|
+
"expected_output": "Requests full reminders access, checks the default reminder list is not nil and sets title and calendar before saving, builds an EKStructuredLocation with geoLocation and a radius in meters, attaches it to an EKAlarm with proximity .enter, and adds a location usage key only if the app uses the person's current location.",
|
|
21
23
|
"files": [],
|
|
22
24
|
"assertions": [
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
25
|
+
"Calls requestFullAccessToReminders before creating the reminder",
|
|
26
|
+
"Guards defaultCalendarForNewReminders against nil and sets title and calendar before saving",
|
|
27
|
+
"Creates an EKStructuredLocation with geoLocation and a radius in meters",
|
|
28
|
+
"Adds an EKAlarm with the structured location and a proximity of .enter or .leave",
|
|
29
|
+
"Adds a location usage description and Core Location request only when the person's current location is used"
|
|
28
30
|
]
|
|
29
31
|
},
|
|
30
32
|
{
|
|
31
33
|
"id": 3,
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
+
"name": "alarms-vs-app-notifications",
|
|
35
|
+
"prompt": "Our study planner adds exam events to the user's calendar and wants alerts 1 day and 1 hour before. We also want the app itself to send a motivational notification each morning. Do we need notification permission for the calendar alerts, and how should both parts be built?",
|
|
36
|
+
"expected_output": "Uses EKAlarm with relative offsets (or absolute dates) added through addAlarm(_:) for the calendar alerts, mentions structured-location alarms for reminders, routes the app's own morning notification to UNUserNotificationCenter and the push-notifications skill, and does not claim EventKit alarms need notification authorization.",
|
|
34
37
|
"files": [],
|
|
35
38
|
"assertions": [
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"Mentions
|
|
39
|
-
"
|
|
40
|
-
"Does not
|
|
39
|
+
"Uses EKAlarm for the exam alerts",
|
|
40
|
+
"Shows relative or absolute alarms added with addAlarm(_:)",
|
|
41
|
+
"Mentions location-based alarms on reminders through EKStructuredLocation",
|
|
42
|
+
"Sends the app-owned morning notification through UNUserNotificationCenter or the push-notifications skill",
|
|
43
|
+
"Does not say EventKit alarms require notification permission"
|
|
41
44
|
]
|
|
42
45
|
}
|
|
43
46
|
]
|
|
44
|
-
}
|
|
47
|
+
}
|
|
@@ -1,376 +1,273 @@
|
|
|
1
|
-
# EventKit
|
|
1
|
+
# EventKit Patterns
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Extended recipes for the `eventkit-calendar` skill.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## A SwiftUI week view
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- [Calendar Management](#calendar-management)
|
|
11
|
-
- [Reminder Workflows](#reminder-workflows)
|
|
12
|
-
- [EventKitUI in SwiftUI](#eventkitui-in-swiftui)
|
|
13
|
-
- [Typed Change Notifications](#typed-change-notifications)
|
|
14
|
-
|
|
15
|
-
## SwiftUI Calendar Integration
|
|
16
|
-
|
|
17
|
-
Read event data only after full calendar access. Write-only access can create
|
|
18
|
-
events but cannot read calendars or events, including events the app created.
|
|
19
|
-
When supporting iOS 16 or earlier, availability-guard iOS 17+ access requests
|
|
20
|
-
and use `requestAccess(to:)` only on the older path.
|
|
21
|
-
|
|
22
|
-
### Observable Event Manager
|
|
7
|
+
Reading events needs full access. Write-only access cannot read anything,
|
|
8
|
+
including events the app saved itself. If the app still supports iOS 16 or
|
|
9
|
+
earlier, put the iOS 17 request methods behind availability checks.
|
|
23
10
|
|
|
24
11
|
```swift
|
|
25
|
-
import EventKit
|
|
26
12
|
import SwiftUI
|
|
13
|
+
import EventKit
|
|
27
14
|
|
|
28
|
-
@Observable
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
15
|
+
@MainActor @Observable
|
|
16
|
+
final class WeekAgenda {
|
|
17
|
+
private(set) var items: [EKEvent] = []
|
|
18
|
+
private(set) var status = EKEventStore.authorizationStatus(for: .event)
|
|
19
|
+
|
|
20
|
+
@ObservationIgnored private let store = EKEventStore()
|
|
21
|
+
@ObservationIgnored private var changeToken: (any NSObjectProtocol)?
|
|
22
|
+
|
|
23
|
+
func connect() async {
|
|
24
|
+
let granted = (try? await store.requestFullAccessToEvents()) ?? false
|
|
25
|
+
status = granted ? .fullAccess : .denied
|
|
26
|
+
guard granted else { return }
|
|
27
|
+
reload()
|
|
28
|
+
let center = NotificationCenter.default
|
|
29
|
+
changeToken = center.addObserver(forName: .EKEventStoreChanged, object: store, queue: .main) { [weak self] _ in
|
|
30
|
+
Task { @MainActor in self?.reload() }
|
|
42
31
|
}
|
|
43
32
|
}
|
|
44
33
|
|
|
45
|
-
func
|
|
46
|
-
let
|
|
47
|
-
let
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let predicate = eventStore.predicateForEvents(
|
|
51
|
-
withStart: start,
|
|
52
|
-
end: end,
|
|
34
|
+
func reload() {
|
|
35
|
+
let monday = Calendar.current.startOfDay(for: .now)
|
|
36
|
+
let week = store.predicateForEvents(
|
|
37
|
+
withStart: monday,
|
|
38
|
+
end: monday.addingTimeInterval(7 * 86_400),
|
|
53
39
|
calendars: nil
|
|
54
40
|
)
|
|
55
|
-
|
|
56
|
-
.sorted { $0.startDate < $1.startDate }
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
func observeChanges() {
|
|
60
|
-
NotificationCenter.default.addObserver(
|
|
61
|
-
forName: .EKEventStoreChanged,
|
|
62
|
-
object: eventStore,
|
|
63
|
-
queue: .main
|
|
64
|
-
) { [weak self] _ in
|
|
65
|
-
self?.fetchThisWeekEvents()
|
|
66
|
-
}
|
|
41
|
+
items = store.events(matching: week).sorted { $0.startDate < $1.startDate }
|
|
67
42
|
}
|
|
68
43
|
}
|
|
69
|
-
```
|
|
70
44
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
```swift
|
|
74
|
-
struct CalendarEventsView: View {
|
|
75
|
-
@State private var manager = CalendarManager()
|
|
45
|
+
struct WeekAgendaView: View {
|
|
46
|
+
@State private var agenda = WeekAgenda()
|
|
76
47
|
|
|
77
48
|
var body: some View {
|
|
78
|
-
List(
|
|
79
|
-
|
|
80
|
-
Text(event.title)
|
|
81
|
-
.font(.headline)
|
|
49
|
+
List(agenda.items, id: \.eventIdentifier) { event in
|
|
50
|
+
LabeledContent {
|
|
82
51
|
Text(event.startDate, style: .date)
|
|
83
|
-
|
|
84
|
-
|
|
52
|
+
} label: {
|
|
53
|
+
Text(event.title)
|
|
85
54
|
}
|
|
86
55
|
}
|
|
87
|
-
.task {
|
|
88
|
-
await manager.requestAccess()
|
|
89
|
-
manager.observeChanges()
|
|
90
|
-
}
|
|
91
56
|
.overlay {
|
|
92
|
-
if
|
|
93
|
-
ContentUnavailableView(
|
|
94
|
-
"No Events",
|
|
95
|
-
systemImage: "calendar",
|
|
96
|
-
description: Text("No events this week.")
|
|
97
|
-
)
|
|
57
|
+
if agenda.items.isEmpty {
|
|
58
|
+
ContentUnavailableView("Nothing This Week", systemImage: "calendar")
|
|
98
59
|
}
|
|
99
60
|
}
|
|
61
|
+
.task { await agenda.connect() }
|
|
100
62
|
}
|
|
101
63
|
}
|
|
102
64
|
```
|
|
103
65
|
|
|
104
|
-
##
|
|
66
|
+
## Queries
|
|
105
67
|
|
|
106
|
-
|
|
107
|
-
`enumerateEvents(matching:using:)` are synchronous and include only committed
|
|
108
|
-
events, so commit batched changes before querying and move large reads off the
|
|
109
|
-
main actor when needed.
|
|
68
|
+
Keep these limits in mind:
|
|
110
69
|
|
|
111
|
-
|
|
70
|
+
- A predicate covers at most four years.
|
|
71
|
+
- Fetches are synchronous and see only committed data, so commit a batch
|
|
72
|
+
before querying it.
|
|
73
|
+
- Large reads block the caller; run them away from the main actor.
|
|
74
|
+
|
|
75
|
+
### One calendar, one interval
|
|
112
76
|
|
|
113
77
|
```swift
|
|
114
|
-
func
|
|
115
|
-
let
|
|
116
|
-
|
|
117
|
-
end: range.end,
|
|
118
|
-
calendars: [calendar]
|
|
119
|
-
)
|
|
120
|
-
return eventStore.events(matching: predicate)
|
|
78
|
+
func events(in calendar: EKCalendar, during span: DateInterval) -> [EKEvent] {
|
|
79
|
+
let query = store.predicateForEvents(withStart: span.start, end: span.end, calendars: [calendar])
|
|
80
|
+
return store.events(matching: query)
|
|
121
81
|
}
|
|
122
82
|
```
|
|
123
83
|
|
|
124
|
-
### Completed
|
|
84
|
+
### Completed reminders
|
|
85
|
+
|
|
86
|
+
As in the main skill, only `Sendable` values leave the callback; here that is
|
|
87
|
+
the identifiers.
|
|
125
88
|
|
|
126
89
|
```swift
|
|
127
|
-
func
|
|
128
|
-
let
|
|
129
|
-
withCompletionDateStarting: start,
|
|
130
|
-
ending: end,
|
|
131
|
-
calendars: nil
|
|
90
|
+
func finishedReminders(since start: Date) async -> [String] {
|
|
91
|
+
let query = store.predicateForCompletedReminders(
|
|
92
|
+
withCompletionDateStarting: start, ending: .now, calendars: nil
|
|
132
93
|
)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
continuation.resume(returning: reminders ?? [])
|
|
94
|
+
return await withCheckedContinuation { resume in
|
|
95
|
+
store.fetchReminders(matching: query) { found in
|
|
96
|
+
resume.resume(returning: (found ?? []).map(\.calendarItemIdentifier))
|
|
137
97
|
}
|
|
138
98
|
}
|
|
139
99
|
}
|
|
140
100
|
```
|
|
141
101
|
|
|
142
|
-
###
|
|
143
|
-
|
|
144
|
-
For large date ranges, use `enumerateEvents` to process events one at a time
|
|
145
|
-
without loading all into memory.
|
|
102
|
+
### Walking a long range
|
|
146
103
|
|
|
147
104
|
```swift
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
eventStore.enumerateEvents(matching: predicate) { event, stop in
|
|
156
|
-
// Process each event
|
|
157
|
-
if event.title.contains("Cancel") {
|
|
158
|
-
stop.pointee = true // Stop enumeration early
|
|
159
|
-
}
|
|
105
|
+
var firstClash: EKEvent?
|
|
106
|
+
store.enumerateEvents(matching: query) { event, stop in
|
|
107
|
+
if event.availability == .busy, event.startDate < proposedEnd, event.endDate > proposedStart {
|
|
108
|
+
firstClash = event
|
|
109
|
+
stop.pointee = true
|
|
160
110
|
}
|
|
161
111
|
}
|
|
162
112
|
```
|
|
163
113
|
|
|
164
|
-
|
|
114
|
+
`enumerateEvents` hands over one event at a time instead of building an array,
|
|
115
|
+
and setting `stop.pointee = true` ends the walk early.
|
|
165
116
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
Use `commit: false` for individual saves, then commit once at the end.
|
|
117
|
+
## Batches
|
|
169
118
|
|
|
170
119
|
```swift
|
|
171
|
-
func
|
|
172
|
-
for
|
|
173
|
-
let event = EKEvent(eventStore:
|
|
174
|
-
event.title = title
|
|
175
|
-
event.startDate = start
|
|
176
|
-
event.endDate = end
|
|
177
|
-
event.calendar =
|
|
178
|
-
try
|
|
120
|
+
func importSessions(_ sessions: [ConferenceSession], into calendar: EKCalendar) throws {
|
|
121
|
+
for session in sessions {
|
|
122
|
+
let event = EKEvent(eventStore: store)
|
|
123
|
+
event.title = session.title
|
|
124
|
+
event.startDate = session.start
|
|
125
|
+
event.endDate = session.end
|
|
126
|
+
event.calendar = calendar
|
|
127
|
+
try store.save(event, span: .thisEvent, commit: false)
|
|
179
128
|
}
|
|
180
|
-
try
|
|
129
|
+
try store.commit()
|
|
181
130
|
}
|
|
182
|
-
```
|
|
183
131
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
func deleteEvents(_ events: [EKEvent]) throws {
|
|
188
|
-
for event in events {
|
|
189
|
-
try eventStore.remove(event, span: .thisEvent, commit: false)
|
|
132
|
+
func cancelAll(_ doomed: [EKEvent]) throws {
|
|
133
|
+
for item in doomed {
|
|
134
|
+
try store.remove(item, span: .thisEvent, commit: false)
|
|
190
135
|
}
|
|
191
|
-
try
|
|
136
|
+
try store.commit()
|
|
192
137
|
}
|
|
193
138
|
```
|
|
194
139
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
```swift
|
|
198
|
-
// Discard all uncommitted changes
|
|
199
|
-
eventStore.reset()
|
|
200
|
-
```
|
|
140
|
+
One `commit()` at the end writes the whole batch. `store.reset()` throws away
|
|
141
|
+
everything not yet committed.
|
|
201
142
|
|
|
202
|
-
##
|
|
203
|
-
|
|
204
|
-
### Creating a Custom Calendar
|
|
143
|
+
## Managing calendars
|
|
205
144
|
|
|
206
145
|
```swift
|
|
207
|
-
func
|
|
208
|
-
let
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}) {
|
|
216
|
-
calendar.source = localSource
|
|
217
|
-
} else if let defaultSource = eventStore.defaultCalendarForNewEvents?.source {
|
|
218
|
-
calendar.source = defaultSource
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
try eventStore.saveCalendar(calendar, commit: true)
|
|
222
|
-
return calendar
|
|
146
|
+
func makeTripCalendar() throws -> EKCalendar {
|
|
147
|
+
let trips = EKCalendar(for: .event, eventStore: store)
|
|
148
|
+
trips.title = "Trips"
|
|
149
|
+
trips.cgColor = UIColor.systemTeal.cgColor
|
|
150
|
+
trips.source = store.sources.first { $0.sourceType == .local }
|
|
151
|
+
?? store.defaultCalendarForNewEvents?.source
|
|
152
|
+
try store.saveCalendar(trips, commit: true)
|
|
153
|
+
return trips
|
|
223
154
|
}
|
|
224
155
|
```
|
|
225
156
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
let eventCalendars = eventStore.calendars(for: .event)
|
|
231
|
-
|
|
232
|
-
// All reminder calendars
|
|
233
|
-
let reminderCalendars = eventStore.calendars(for: .reminder)
|
|
234
|
-
|
|
235
|
-
// Only writable calendars
|
|
236
|
-
let writableCalendars = eventCalendars.filter { $0.allowsContentModifications }
|
|
237
|
-
```
|
|
157
|
+
A local source is preferred; otherwise the new calendar joins the default
|
|
158
|
+
calendar's source. List calendars with `store.calendars(for: .event)` or
|
|
159
|
+
`.reminder`, and keep only those with `allowsContentModifications` when you
|
|
160
|
+
need a writable one.
|
|
238
161
|
|
|
239
|
-
## Reminder
|
|
162
|
+
## Reminder recipes
|
|
240
163
|
|
|
241
|
-
###
|
|
164
|
+
### Location-triggered reminder
|
|
242
165
|
|
|
243
166
|
```swift
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
case missingDefaultReminderList
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
func createLocationReminder(
|
|
253
|
-
title: String,
|
|
254
|
-
latitude: Double,
|
|
255
|
-
longitude: Double
|
|
256
|
-
) throws {
|
|
257
|
-
guard EKEventStore.authorizationStatus(for: .reminder) == .fullAccess else {
|
|
258
|
-
throw CalendarError.remindersAccessRequired
|
|
167
|
+
func remindOnArrival(at place: CLLocation, named title: String) throws {
|
|
168
|
+
let access = EKEventStore.authorizationStatus(for: .reminder)
|
|
169
|
+
guard access == .fullAccess else { throw PlannerError.remindersNotAllowed }
|
|
170
|
+
guard let list = store.defaultCalendarForNewReminders() else {
|
|
171
|
+
throw PlannerError.noReminderList
|
|
259
172
|
}
|
|
260
|
-
|
|
261
|
-
throw CalendarError.missingDefaultReminderList
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
let reminder = EKReminder(eventStore: eventStore)
|
|
173
|
+
let reminder = EKReminder(eventStore: store)
|
|
265
174
|
reminder.title = title
|
|
266
|
-
reminder.calendar =
|
|
175
|
+
reminder.calendar = list
|
|
267
176
|
|
|
268
|
-
let
|
|
269
|
-
|
|
270
|
-
|
|
177
|
+
let spot = EKStructuredLocation(title: "Garden Centre")
|
|
178
|
+
spot.geoLocation = place
|
|
179
|
+
spot.radius = 150
|
|
271
180
|
|
|
272
|
-
let
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
reminder.addAlarm(
|
|
181
|
+
let trigger = EKAlarm(relativeOffset: 0)
|
|
182
|
+
trigger.structuredLocation = spot
|
|
183
|
+
trigger.proximity = .enter
|
|
184
|
+
reminder.addAlarm(trigger)
|
|
276
185
|
|
|
277
|
-
try
|
|
186
|
+
try store.save(reminder, commit: true)
|
|
278
187
|
}
|
|
279
188
|
```
|
|
280
189
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
190
|
+
`radius` is in meters. Use `.leave` instead of `.enter` for departure alerts.
|
|
191
|
+
The reminder needs a title and a calendar before it is saved. Coordinates from your own data need no
|
|
192
|
+
location permission. Only when `place` comes from where the person is right
|
|
193
|
+
now does the app add `NSLocationWhenInUseUsageDescription` and ask Core
|
|
194
|
+
Location.
|
|
284
195
|
|
|
285
|
-
###
|
|
196
|
+
### Priority
|
|
286
197
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
## EventKitUI in SwiftUI
|
|
198
|
+
| `priority` | Meaning |
|
|
199
|
+
|------------|---------|
|
|
200
|
+
| 0 | None |
|
|
201
|
+
| 1 to 4 | High |
|
|
202
|
+
| 5 | Medium |
|
|
203
|
+
| 6 to 9 | Low |
|
|
295
204
|
|
|
296
|
-
|
|
205
|
+
## The event editor in SwiftUI
|
|
297
206
|
|
|
298
207
|
```swift
|
|
299
|
-
import SwiftUI
|
|
300
208
|
import EventKitUI
|
|
301
209
|
|
|
302
|
-
struct
|
|
303
|
-
let
|
|
210
|
+
struct EventEditorSheet: UIViewControllerRepresentable {
|
|
211
|
+
let store: EKEventStore
|
|
304
212
|
@Binding var isPresented: Bool
|
|
305
213
|
|
|
214
|
+
func makeCoordinator() -> Coordinator { Coordinator(isPresented: $isPresented) }
|
|
215
|
+
|
|
306
216
|
func makeUIViewController(context: Context) -> EKEventEditViewController {
|
|
307
|
-
let
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
return
|
|
217
|
+
let sheet = EKEventEditViewController()
|
|
218
|
+
sheet.editViewDelegate = context.coordinator
|
|
219
|
+
sheet.eventStore = store
|
|
220
|
+
return sheet
|
|
311
221
|
}
|
|
312
222
|
|
|
313
|
-
func updateUIViewController(
|
|
314
|
-
_ uiViewController: EKEventEditViewController,
|
|
315
|
-
context: Context
|
|
316
|
-
) {}
|
|
223
|
+
func updateUIViewController(_ sheet: EKEventEditViewController, context: Context) {}
|
|
317
224
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
class Coordinator: NSObject, EKEventEditViewDelegate {
|
|
323
|
-
let parent: EventEditView
|
|
225
|
+
final class Coordinator: NSObject, EKEventEditViewDelegate {
|
|
226
|
+
@Binding var isPresented: Bool
|
|
324
227
|
|
|
325
|
-
init(
|
|
326
|
-
self.parent = parent
|
|
327
|
-
}
|
|
228
|
+
init(isPresented: Binding<Bool>) { _isPresented = isPresented }
|
|
328
229
|
|
|
329
|
-
func eventEditViewController(
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
) {
|
|
333
|
-
parent.isPresented = false
|
|
230
|
+
func eventEditViewController(_ sheet: EKEventEditViewController,
|
|
231
|
+
didCompleteWith outcome: EKEventEditViewAction) {
|
|
232
|
+
isPresented = false
|
|
334
233
|
}
|
|
335
234
|
}
|
|
336
235
|
}
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
On iOS 17+, the editor can create events without app calendar authorization. It
|
|
340
|
-
runs out of process, so the app cannot inspect the dismissed controller to learn
|
|
341
|
-
what the person saved unless the app separately has full access and refetches.
|
|
342
236
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
struct CalendarView: View {
|
|
347
|
-
@State private var showEditor = false
|
|
348
|
-
let eventStore = EKEventStore()
|
|
237
|
+
struct AddToCalendarButton: View {
|
|
238
|
+
let store: EKEventStore
|
|
239
|
+
@State private var editing = false
|
|
349
240
|
|
|
350
241
|
var body: some View {
|
|
351
|
-
Button("Add
|
|
352
|
-
.sheet(isPresented: $
|
|
353
|
-
|
|
354
|
-
eventStore: eventStore,
|
|
355
|
-
isPresented: $showEditor
|
|
356
|
-
)
|
|
242
|
+
Button("Add to Calendar", systemImage: "calendar.badge.plus") { editing = true }
|
|
243
|
+
.sheet(isPresented: $editing) {
|
|
244
|
+
EventEditorSheet(store: store, isPresented: $editing)
|
|
357
245
|
}
|
|
358
246
|
}
|
|
359
247
|
}
|
|
360
248
|
```
|
|
361
249
|
|
|
362
|
-
|
|
250
|
+
From iOS 17 this needs no calendar permission at all: the editor lives in
|
|
251
|
+
another process. The app does not learn what was saved; it can see
|
|
252
|
+
the result only with full access and a fresh fetch.
|
|
363
253
|
|
|
364
|
-
|
|
365
|
-
|
|
254
|
+
## Change notifications, old and new
|
|
255
|
+
|
|
256
|
+
`.EKEventStoreChanged` works on every supported version. On iOS 26 the typed
|
|
257
|
+
message can be used through Foundation's message-based observer API:
|
|
366
258
|
|
|
367
259
|
```swift
|
|
368
|
-
if #available(iOS 26
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
260
|
+
if #available(iOS 26, *) {
|
|
261
|
+
storeObservation = NotificationCenter.default.addObserver(of: store, for: .changed) { _ in
|
|
262
|
+
agenda.reload()
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
let center = NotificationCenter.default
|
|
266
|
+
storeObservation = center.addObserver(forName: .EKEventStoreChanged, object: store, queue: nil) { _ in
|
|
267
|
+
Task { @MainActor in agenda.reload() }
|
|
374
268
|
}
|
|
375
269
|
}
|
|
376
270
|
```
|
|
271
|
+
|
|
272
|
+
Keep the returned token alive for as long as updates are wanted. The two APIs
|
|
273
|
+
return different token types, so `storeObservation` is declared as `Any?`.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: evidence-github
|
|
3
3
|
description: Search GitHub for facts an analysis can cite - a known issue in a dependency, the PR that fixed it, what a release actually changed, prior art for a pattern. Use when a spec, review or triage needs to know whether a problem is already known upstream.
|
|
4
|
+
metadata:
|
|
5
|
+
source: multi-agent-pipeline
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# GitHub as evidence
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: evidence-registry
|
|
3
3
|
description: Check a package's real version, deprecation status and release notes on npm, PyPI, Maven Central or Swift Package Index. Use when a spec or review depends on what a dependency currently is rather than what a lockfile said months ago. Keyless HTTP, works on every platform.
|
|
4
|
+
metadata:
|
|
5
|
+
source: multi-agent-pipeline
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Package registries as evidence
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gradle-kotlin-dsl
|
|
3
3
|
description: "Configure Android builds with Gradle Kotlin DSL, version catalogs (libs.versions.toml), convention plugins (build-logic module), common configurations for android library/compose/testing, build variants, flavors, signing configs, R8/ProGuard rules, and build performance optimization including configuration cache and parallel execution. Use when setting up Gradle builds, adding dependencies, creating convention plugins, or optimizing build times."
|
|
4
|
+
metadata:
|
|
5
|
+
source: multi-agent-pipeline
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Gradle Kotlin DSL
|