@devo-bmad-custom/agent-orchestration 1.0.2 → 1.0.4
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/lib/installer.js +33 -0
- package/package.json +1 -1
- package/src/.agents/skills/audit-website/README.md +20 -20
- package/src/.agents/skills/audit-website/SKILL.md +470 -470
- package/src/.agents/skills/audit-website/agents/openai.yaml +6 -6
- package/src/.agents/skills/audit-website/assets/icon-small.svg +41 -41
- package/src/.agents/skills/audit-website/references/OUTPUT-FORMAT.md +250 -250
- package/src/.agents/skills/clean-code-standards/SKILL.md +104 -104
- package/src/.agents/skills/excalidraw-dark-standard/SKILL.md +281 -281
- package/src/.agents/skills/frontend-responsive-design-standards/SKILL.md +434 -434
- package/src/.agents/skills/java-fundamentals/SKILL.md +116 -116
- package/src/.agents/skills/java-performance/SKILL.md +119 -119
- package/src/.agents/skills/next-best-practices/SKILL.md +153 -153
- package/src/.agents/skills/next-best-practices/async-patterns.md +87 -87
- package/src/.agents/skills/next-best-practices/bundling.md +180 -180
- package/src/.agents/skills/next-best-practices/data-patterns.md +297 -297
- package/src/.agents/skills/next-best-practices/debug-tricks.md +105 -105
- package/src/.agents/skills/next-best-practices/directives.md +73 -73
- package/src/.agents/skills/next-best-practices/error-handling.md +227 -227
- package/src/.agents/skills/next-best-practices/file-conventions.md +140 -140
- package/src/.agents/skills/next-best-practices/font.md +245 -245
- package/src/.agents/skills/next-best-practices/functions.md +108 -108
- package/src/.agents/skills/next-best-practices/hydration-error.md +91 -91
- package/src/.agents/skills/next-best-practices/image.md +173 -173
- package/src/.agents/skills/next-best-practices/metadata.md +301 -301
- package/src/.agents/skills/next-best-practices/parallel-routes.md +287 -287
- package/src/.agents/skills/next-best-practices/route-handlers.md +146 -146
- package/src/.agents/skills/next-best-practices/rsc-boundaries.md +159 -159
- package/src/.agents/skills/next-best-practices/runtime-selection.md +39 -39
- package/src/.agents/skills/next-best-practices/scripts.md +141 -141
- package/src/.agents/skills/next-best-practices/self-hosting.md +371 -371
- package/src/.agents/skills/next-best-practices/suspense-boundaries.md +67 -67
- package/src/.agents/skills/nextjs-app-router-patterns/SKILL.md +537 -537
- package/src/.agents/skills/postgresql-optimization/SKILL.md +404 -404
- package/src/.agents/skills/python-backend/SKILL.md +153 -153
- package/src/.agents/skills/python-fundamentals/SKILL.md +234 -234
- package/src/.agents/skills/python-performance/SKILL.md +404 -404
- package/src/.agents/skills/react-expert/SKILL.md +335 -335
- package/src/.agents/skills/redis-best-practices/SKILL.md +438 -438
- package/src/.agents/skills/security-best-practices/SKILL.md +288 -288
- package/src/.agents/skills/security-review/LICENSE +22 -22
- package/src/.agents/skills/security-review/SKILL.md +312 -312
- package/src/.agents/skills/security-review/infrastructure/docker.md +432 -432
- package/src/.agents/skills/security-review/languages/javascript.md +388 -388
- package/src/.agents/skills/security-review/languages/python.md +363 -363
- package/src/.agents/skills/security-review/references/api-security.md +519 -519
- package/src/.agents/skills/security-review/references/authentication.md +353 -353
- package/src/.agents/skills/security-review/references/authorization.md +372 -372
- package/src/.agents/skills/security-review/references/business-logic.md +443 -443
- package/src/.agents/skills/security-review/references/cryptography.md +329 -329
- package/src/.agents/skills/security-review/references/csrf.md +398 -398
- package/src/.agents/skills/security-review/references/data-protection.md +378 -378
- package/src/.agents/skills/security-review/references/deserialization.md +410 -410
- package/src/.agents/skills/security-review/references/error-handling.md +436 -436
- package/src/.agents/skills/security-review/references/file-security.md +457 -457
- package/src/.agents/skills/security-review/references/injection.md +259 -259
- package/src/.agents/skills/security-review/references/logging.md +433 -433
- package/src/.agents/skills/security-review/references/misconfiguration.md +435 -435
- package/src/.agents/skills/security-review/references/modern-threats.md +475 -475
- package/src/.agents/skills/security-review/references/ssrf.md +415 -415
- package/src/.agents/skills/security-review/references/supply-chain.md +405 -405
- package/src/.agents/skills/security-review/references/xss.md +336 -336
- package/src/.agents/skills/subagent-driven-development/SKILL.md +275 -275
- package/src/.agents/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -26
- package/src/.agents/skills/subagent-driven-development/implementer-prompt.md +113 -113
- package/src/.agents/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -61
- package/src/.agents/skills/systematic-debugging/CREATION-LOG.md +119 -119
- package/src/.agents/skills/systematic-debugging/SKILL.md +296 -296
- package/src/.agents/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/src/.agents/skills/systematic-debugging/condition-based-waiting.md +115 -115
- package/src/.agents/skills/systematic-debugging/defense-in-depth.md +122 -122
- package/src/.agents/skills/systematic-debugging/root-cause-tracing.md +169 -169
- package/src/.agents/skills/systematic-debugging/test-academic.md +14 -14
- package/src/.agents/skills/systematic-debugging/test-pressure-1.md +58 -58
- package/src/.agents/skills/systematic-debugging/test-pressure-2.md +68 -68
- package/src/.agents/skills/systematic-debugging/test-pressure-3.md +69 -69
- package/src/.agents/skills/typescript-best-practices/SKILL.md +373 -373
- package/src/.agents/skills/ui-ux-pro-custom/SKILL.md +348 -348
- package/src/.agents/skills/ui-ux-pro-custom/data/charts.csv +26 -26
- package/src/.agents/skills/ui-ux-pro-custom/data/colors.csv +97 -97
- package/src/.agents/skills/ui-ux-pro-custom/data/icons.csv +101 -101
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/SKILL.md +106 -106
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/accessibility.md +475 -475
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/animation.md +466 -466
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/composition-locals.md +231 -231
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/deprecated-patterns.md +323 -323
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/lists-scrolling.md +400 -400
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/modifiers.md +331 -331
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/navigation.md +416 -416
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/performance.md +446 -446
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/side-effects.md +516 -516
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/foundation-source.md +13327 -13327
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/material3-source.md +19097 -19097
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/navigation-source.md +2947 -2947
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/runtime-source.md +11316 -11316
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/ui-source.md +7896 -7896
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/state-management.md +377 -377
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/styles-experimental.md +470 -470
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/theming-material3.md +349 -349
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/view-composition.md +595 -595
- package/src/.agents/skills/ui-ux-pro-custom/data/landing.csv +31 -31
- package/src/.agents/skills/ui-ux-pro-custom/data/mobile-ui-layout.md +654 -654
- package/src/.agents/skills/ui-ux-pro-custom/data/products.csv +96 -96
- package/src/.agents/skills/ui-ux-pro-custom/data/react-performance.csv +45 -45
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/astro.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/flutter.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/html-tailwind.csv +56 -56
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/jetpack-compose.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nextjs.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nuxt-ui.csv +51 -51
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nuxtjs.csv +59 -59
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/react-native.csv +56 -56
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/react.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/shadcn.csv +61 -61
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/svelte.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/swiftui.csv +51 -51
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/vue.csv +50 -50
- package/src/.agents/skills/ui-ux-pro-custom/data/styles.csv +68 -68
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/alarmkit/SKILL.md +438 -438
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/alarmkit/references/alarmkit-patterns.md +584 -584
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-clips/SKILL.md +436 -436
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-intents/SKILL.md +489 -489
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-intents/references/appintents-advanced.md +1076 -1076
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/SKILL.md +340 -340
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/references/privacy-manifest.md +90 -90
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/references/review-checklists.md +106 -106
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/coreml-conversion.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/coreml-optimization.md +344 -344
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/foundation-models.md +508 -508
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/mlx-swift.md +285 -285
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/authentication/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/authentication/references/keychain-biometric.md +211 -211
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/background-processing/SKILL.md +499 -499
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/background-processing/references/background-task-patterns.md +390 -390
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/callkit-voip/SKILL.md +461 -461
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/callkit-voip/references/callkit-patterns.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/cloudkit-sync/SKILL.md +492 -492
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/cloudkit-sync/references/cloudkit-patterns.md +461 -461
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/codable-patterns/SKILL.md +467 -467
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/contacts-framework/SKILL.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/contacts-framework/references/contacts-patterns.md +409 -409
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-bluetooth/SKILL.md +491 -491
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-bluetooth/references/ble-patterns.md +435 -435
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-motion/SKILL.md +388 -388
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-motion/references/motion-patterns.md +405 -405
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-nfc/SKILL.md +495 -495
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-nfc/references/nfc-patterns.md +420 -420
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/coreml/SKILL.md +459 -459
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/coreml/references/coreml-swift-integration.md +765 -765
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/SKILL.md +422 -422
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/references/instruments-guide.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/references/lldb-patterns.md +298 -298
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/device-integrity/SKILL.md +477 -477
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/energykit/SKILL.md +460 -460
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/energykit/references/energykit-patterns.md +541 -541
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/eventkit-calendar/SKILL.md +483 -483
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/eventkit-calendar/references/eventkit-patterns.md +326 -326
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/healthkit/SKILL.md +498 -498
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/healthkit/references/healthkit-patterns.md +602 -602
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/homekit-matter/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/homekit-matter/references/matter-commissioning.md +455 -455
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-accessibility/SKILL.md +301 -301
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-accessibility/references/a11y-patterns.md +140 -140
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/SKILL.md +418 -418
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/references/formatstyle-locale.md +627 -627
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/references/string-catalogs.md +462 -462
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/SKILL.md +441 -441
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/background-websocket.md +862 -862
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/lightweight-clients.md +93 -93
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/network-framework.md +563 -563
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/urlsession-patterns.md +1116 -1116
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/app-review-guidelines.md +174 -174
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/cryptokit-advanced.md +296 -296
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/file-storage-patterns.md +354 -354
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/privacy-manifest.md +117 -117
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/live-activities/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/live-activities/references/live-activity-patterns.md +868 -868
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/SKILL.md +485 -485
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/references/corelocation-patterns.md +730 -730
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/references/mapkit-patterns.md +748 -748
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/metrickit-diagnostics/SKILL.md +479 -479
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/musickit-audio/SKILL.md +395 -395
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/musickit-audio/references/musickit-patterns.md +363 -363
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/natural-language/SKILL.md +412 -412
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/natural-language/references/translation-patterns.md +311 -311
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/passkit-wallet/SKILL.md +398 -398
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/passkit-wallet/references/wallet-passes.md +254 -254
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/SKILL.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/references/paperkit-integration.md +376 -376
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/references/pencilkit-patterns.md +302 -302
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/permissionkit/SKILL.md +446 -446
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/permissionkit/references/permissionkit-patterns.md +435 -435
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/av-playback.md +701 -701
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/camera-capture.md +774 -774
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/image-loading-caching.md +869 -869
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/photospicker-patterns.md +597 -597
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/references/notification-patterns.md +677 -677
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/references/rich-notifications.md +745 -745
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/realitykit-ar/SKILL.md +479 -479
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/realitykit-ar/references/realitykit-patterns.md +480 -480
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/SKILL.md +483 -483
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/references/shareplay-patterns.md +544 -544
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/speech-recognition/SKILL.md +485 -485
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/SKILL.md +478 -478
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/references/app-review-guidelines.md +58 -58
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/references/storekit-advanced.md +755 -755
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-charts/SKILL.md +487 -487
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-charts/references/charts-patterns.md +895 -895
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/SKILL.md +408 -408
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/approachable-concurrency.md +80 -80
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/swift-6-2-concurrency.md +233 -233
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/swiftui-concurrency.md +187 -187
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/synchronization-primitives.md +341 -341
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-language/SKILL.md +498 -498
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-language/references/swift-patterns-extended.md +505 -505
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-testing/SKILL.md +467 -467
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-testing/references/testing-patterns.md +504 -504
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/SKILL.md +334 -334
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/core-data-coexistence.md +504 -504
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/swiftdata-advanced.md +975 -975
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/swiftdata-queries.md +675 -675
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/SKILL.md +481 -481
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/references/animation-advanced.md +804 -804
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/references/core-animation-bridge.md +553 -553
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-gestures/SKILL.md +450 -450
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-gestures/references/gesture-patterns.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/SKILL.md +336 -336
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/form.md +97 -97
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/grids.md +69 -69
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/list.md +99 -99
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/scrollview.md +147 -147
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-liquid-glass/SKILL.md +325 -325
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-liquid-glass/references/liquid-glass.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/SKILL.md +262 -262
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/deeplinks.md +207 -207
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/navigationstack.md +177 -177
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/sheets.md +169 -169
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/tabview.md +178 -178
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/SKILL.md +381 -381
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/architecture-patterns.md +486 -486
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/deprecated-migration.md +1097 -1097
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/design-polish.md +780 -780
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/platform-and-sharing.md +696 -696
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/SKILL.md +491 -491
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +46 -46
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +29 -29
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/understanding-hangs-in-your-app.md +33 -33
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/understanding-improving-swiftui-performance.md +52 -52
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/SKILL.md +428 -428
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/references/hosting-migration.md +534 -534
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/references/representable-recipes.md +1133 -1133
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/tipkit/SKILL.md +494 -494
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/tipkit/references/tipkit-patterns.md +782 -782
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/SKILL.md +475 -475
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/vision-requests.md +736 -736
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/visionkit-scanner.md +738 -738
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/SKILL.md +410 -410
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/references/weatherkit-patterns.md +567 -567
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/SKILL.md +497 -497
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/references/widgetkit-advanced.md +871 -871
- package/src/.agents/skills/ui-ux-pro-custom/data/typography.csv +57 -57
- package/src/.agents/skills/ui-ux-pro-custom/data/ui-reasoning.csv +101 -101
- package/src/.agents/skills/ui-ux-pro-custom/data/ux-guidelines.csv +99 -99
- package/src/.agents/skills/ui-ux-pro-custom/data/web-interface.csv +31 -31
- package/src/.agents/skills/ui-ux-pro-custom/scripts/core.py +253 -253
- package/src/.agents/skills/ui-ux-pro-custom/scripts/design_system.py +1067 -1067
- package/src/.agents/skills/ui-ux-pro-custom/scripts/search.py +114 -114
- package/src/.agents/skills/ux-audit/SKILL.md +150 -150
- package/src/.agents/skills/websocket-engineer/SKILL.md +168 -168
- package/src/.agents/skills/websocket-engineer/references/alternatives.md +391 -391
- package/src/.agents/skills/websocket-engineer/references/patterns.md +400 -400
- package/src/.agents/skills/websocket-engineer/references/protocol.md +195 -195
- package/src/.agents/skills/websocket-engineer/references/scaling.md +333 -333
- package/src/.agents/skills/websocket-engineer/references/security.md +474 -474
- package/src/.agents/skills/writing-skills/SKILL.md +655 -655
- package/src/.agents/skills/writing-skills/anthropic-best-practices.md +1150 -1150
- package/src/.agents/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -189
- package/src/.agents/skills/writing-skills/graphviz-conventions.dot +171 -171
- package/src/.agents/skills/writing-skills/persuasion-principles.md +187 -187
- package/src/.agents/skills/writing-skills/render-graphs.js +168 -168
- package/src/.agents/skills/writing-skills/testing-skills-with-subagents.md +384 -384
- package/src/.claude/commands/master-orchestrator.md +15 -0
- package/src/_memory/config.yaml +11 -11
- package/src/_memory/master-orchestrator-sidecar/instructions.md +97 -47
- package/src/_memory/skills/nimbalyst-tracking/SKILL.md +103 -103
- package/src/_memory/skills/writing-skills/SKILL.md +655 -655
- package/src/bmb/agents/agent-builder.md +59 -59
- package/src/bmb/agents/module-builder.md +60 -60
- package/src/bmb/agents/workflow-builder.md +61 -61
- package/src/bmb/config.yaml +12 -12
- package/src/bmb/module-help.csv +13 -13
- package/src/bmb/workflows/agent/data/agent-architecture.md +258 -258
- package/src/bmb/workflows/agent/data/agent-compilation.md +185 -185
- package/src/bmb/workflows/agent/data/agent-menu-patterns.md +189 -189
- package/src/bmb/workflows/agent/data/agent-metadata.md +133 -133
- package/src/bmb/workflows/agent/data/agent-validation.md +111 -111
- package/src/bmb/workflows/agent/data/brainstorm-context.md +96 -96
- package/src/bmb/workflows/agent/data/communication-presets.csv +61 -61
- package/src/bmb/workflows/agent/data/critical-actions.md +75 -75
- package/src/bmb/workflows/agent/data/persona-properties.md +252 -252
- package/src/bmb/workflows/agent/data/principles-crafting.md +142 -142
- package/src/bmb/workflows/agent/data/reference/module-examples/architect.md +68 -68
- package/src/bmb/workflows/agent/data/reference/with-sidecar/journal-keeper/journal-keeper-sidecar/entries/yy-mm-dd-entry-template.md +16 -16
- package/src/bmb/workflows/agent/data/understanding-agent-types.md +126 -126
- package/src/bmb/workflows/agent/steps-c/step-01-brainstorm.md +129 -129
- package/src/bmb/workflows/agent/steps-c/step-02-discovery.md +170 -170
- package/src/bmb/workflows/agent/steps-c/step-03-sidecar-metadata.md +309 -309
- package/src/bmb/workflows/agent/steps-c/step-04-persona.md +213 -213
- package/src/bmb/workflows/agent/steps-c/step-05-commands-menu.md +179 -179
- package/src/bmb/workflows/agent/steps-c/step-06-activation.md +278 -278
- package/src/bmb/workflows/agent/steps-c/step-07-build-agent.md +316 -316
- package/src/bmb/workflows/agent/steps-c/step-08-celebrate.md +247 -247
- package/src/bmb/workflows/agent/steps-e/e-01-load-existing.md +221 -221
- package/src/bmb/workflows/agent/steps-e/e-02-discover-edits.md +195 -195
- package/src/bmb/workflows/agent/steps-e/e-04-sidecar-metadata.md +126 -126
- package/src/bmb/workflows/agent/steps-e/e-05-persona.md +135 -135
- package/src/bmb/workflows/agent/steps-e/e-06-commands-menu.md +123 -123
- package/src/bmb/workflows/agent/steps-e/e-07-activation.md +124 -124
- package/src/bmb/workflows/agent/steps-e/e-08-edit-agent.md +197 -197
- package/src/bmb/workflows/agent/steps-e/e-09-celebrate.md +155 -155
- package/src/bmb/workflows/agent/steps-v/v-01-load-review.md +137 -137
- package/src/bmb/workflows/agent/steps-v/v-02a-validate-metadata.md +116 -116
- package/src/bmb/workflows/agent/steps-v/v-02b-validate-persona.md +124 -124
- package/src/bmb/workflows/agent/steps-v/v-02c-validate-menu.md +127 -127
- package/src/bmb/workflows/agent/steps-v/v-02d-validate-structure.md +134 -134
- package/src/bmb/workflows/agent/steps-v/v-02e-validate-sidecar.md +134 -134
- package/src/bmb/workflows/agent/steps-v/v-03-summary.md +104 -104
- package/src/bmb/workflows/agent/templates/agent-plan.template.md +5 -5
- package/src/bmb/workflows/agent/templates/agent-template.md +89 -89
- package/src/bmb/workflows/agent/workflow-create-agent.md +72 -72
- package/src/bmb/workflows/agent/workflow-edit-agent.md +75 -75
- package/src/bmb/workflows/agent/workflow-validate-agent.md +73 -73
- package/src/bmb/workflows/module/data/agent-architecture.md +179 -179
- package/src/bmb/workflows/module/data/agent-spec-template.md +79 -79
- package/src/bmb/workflows/module/data/module-standards.md +263 -263
- package/src/bmb/workflows/module/data/module-yaml-conventions.md +392 -392
- package/src/bmb/workflows/module/module-help-generate.md +254 -254
- package/src/bmb/workflows/module/steps-b/step-01-welcome.md +148 -148
- package/src/bmb/workflows/module/steps-b/step-02-spark.md +141 -141
- package/src/bmb/workflows/module/steps-b/step-03-module-type.md +149 -149
- package/src/bmb/workflows/module/steps-b/step-04-vision.md +83 -83
- package/src/bmb/workflows/module/steps-b/step-05-identity.md +97 -97
- package/src/bmb/workflows/module/steps-b/step-06-users.md +86 -86
- package/src/bmb/workflows/module/steps-b/step-07-value.md +76 -76
- package/src/bmb/workflows/module/steps-b/step-08-agents.md +97 -97
- package/src/bmb/workflows/module/steps-b/step-09-workflows.md +83 -83
- package/src/bmb/workflows/module/steps-b/step-10-tools.md +91 -91
- package/src/bmb/workflows/module/steps-b/step-11-scenarios.md +84 -84
- package/src/bmb/workflows/module/steps-b/step-12-creative.md +95 -95
- package/src/bmb/workflows/module/steps-b/step-13-review.md +105 -105
- package/src/bmb/workflows/module/steps-b/step-14-finalize.md +117 -117
- package/src/bmb/workflows/module/steps-c/step-01-load-brief.md +179 -179
- package/src/bmb/workflows/module/steps-c/step-01b-continue.md +82 -82
- package/src/bmb/workflows/module/steps-c/step-02-structure.md +105 -105
- package/src/bmb/workflows/module/steps-c/step-03-config.md +119 -119
- package/src/bmb/workflows/module/steps-c/step-04-agents.md +168 -168
- package/src/bmb/workflows/module/steps-c/step-05-workflows.md +184 -184
- package/src/bmb/workflows/module/steps-c/step-06-docs.md +401 -401
- package/src/bmb/workflows/module/steps-c/step-07-complete.md +152 -152
- package/src/bmb/workflows/module/steps-e/step-01-load-target.md +81 -81
- package/src/bmb/workflows/module/steps-e/step-02-select-edit.md +77 -77
- package/src/bmb/workflows/module/steps-e/step-03-apply-edit.md +77 -77
- package/src/bmb/workflows/module/steps-e/step-04-review.md +80 -80
- package/src/bmb/workflows/module/steps-e/step-05-confirm.md +75 -75
- package/src/bmb/workflows/module/steps-v/step-01-load-target.md +96 -96
- package/src/bmb/workflows/module/steps-v/step-02-file-structure.md +93 -93
- package/src/bmb/workflows/module/steps-v/step-03-module-yaml.md +99 -99
- package/src/bmb/workflows/module/steps-v/step-04-agent-specs.md +152 -152
- package/src/bmb/workflows/module/steps-v/step-05-workflow-specs.md +152 -152
- package/src/bmb/workflows/module/steps-v/step-06-documentation.md +143 -143
- package/src/bmb/workflows/module/steps-v/step-07-installation.md +102 -102
- package/src/bmb/workflows/module/steps-v/step-08-report.md +197 -197
- package/src/bmb/workflows/module/templates/brief-template.md +154 -154
- package/src/bmb/workflows/module/templates/workflow-spec-template.md +96 -96
- package/src/bmb/workflows/module/workflow-create-module-brief.md +71 -71
- package/src/bmb/workflows/module/workflow-create-module.md +86 -86
- package/src/bmb/workflows/module/workflow-edit-module.md +66 -66
- package/src/bmb/workflows/module/workflow-validate-module.md +66 -66
- package/src/bmb/workflows/workflow/data/architecture.md +150 -150
- package/src/bmb/workflows/workflow/data/common-workflow-tools.csv +19 -19
- package/src/bmb/workflows/workflow/data/csv-data-file-standards.md +53 -53
- package/src/bmb/workflows/workflow/data/frontmatter-standards.md +184 -184
- package/src/bmb/workflows/workflow/data/input-discovery-standards.md +191 -191
- package/src/bmb/workflows/workflow/data/intent-vs-prescriptive-spectrum.md +44 -44
- package/src/bmb/workflows/workflow/data/menu-handling-standards.md +133 -133
- package/src/bmb/workflows/workflow/data/output-format-standards.md +135 -135
- package/src/bmb/workflows/workflow/data/step-file-rules.md +235 -235
- package/src/bmb/workflows/workflow/data/step-type-patterns.md +257 -257
- package/src/bmb/workflows/workflow/data/subprocess-optimization-patterns.md +188 -188
- package/src/bmb/workflows/workflow/data/trimodal-workflow-structure.md +164 -164
- package/src/bmb/workflows/workflow/data/workflow-chaining-standards.md +222 -222
- package/src/bmb/workflows/workflow/data/workflow-examples.md +232 -232
- package/src/bmb/workflows/workflow/data/workflow-type-criteria.md +134 -134
- package/src/bmb/workflows/workflow/steps-c/step-00-conversion.md +263 -263
- package/src/bmb/workflows/workflow/steps-c/step-01-discovery.md +194 -194
- package/src/bmb/workflows/workflow/steps-c/step-01b-continuation.md +3 -3
- package/src/bmb/workflows/workflow/steps-c/step-02-classification.md +270 -270
- package/src/bmb/workflows/workflow/steps-c/step-03-requirements.md +283 -283
- package/src/bmb/workflows/workflow/steps-c/step-04-tools.md +282 -282
- package/src/bmb/workflows/workflow/steps-c/step-05-plan-review.md +243 -243
- package/src/bmb/workflows/workflow/steps-c/step-06-design.md +330 -330
- package/src/bmb/workflows/workflow/steps-c/step-07-foundation.md +239 -239
- package/src/bmb/workflows/workflow/steps-c/step-08-build-step-01.md +379 -379
- package/src/bmb/workflows/workflow/steps-c/step-09-build-next-step.md +350 -350
- package/src/bmb/workflows/workflow/steps-c/step-10-confirmation.md +322 -322
- package/src/bmb/workflows/workflow/steps-c/step-11-completion.md +191 -191
- package/src/bmb/workflows/workflow/steps-e/step-e-01-assess-workflow.md +237 -237
- package/src/bmb/workflows/workflow/steps-e/step-e-02-discover-edits.md +251 -251
- package/src/bmb/workflows/workflow/steps-e/step-e-03-fix-validation.md +254 -254
- package/src/bmb/workflows/workflow/steps-e/step-e-04-direct-edit.md +277 -277
- package/src/bmb/workflows/workflow/steps-e/step-e-05-apply-edit.md +154 -154
- package/src/bmb/workflows/workflow/steps-e/step-e-06-validate-after.md +190 -190
- package/src/bmb/workflows/workflow/steps-e/step-e-07-complete.md +206 -206
- package/src/bmb/workflows/workflow/steps-v/step-01-validate-max-mode.md +109 -109
- package/src/bmb/workflows/workflow/steps-v/step-01-validate.md +221 -221
- package/src/bmb/workflows/workflow/steps-v/step-01b-structure.md +152 -152
- package/src/bmb/workflows/workflow/steps-v/step-02-frontmatter-validation.md +199 -199
- package/src/bmb/workflows/workflow/steps-v/step-02b-path-violations.md +265 -265
- package/src/bmb/workflows/workflow/steps-v/step-03-menu-validation.md +164 -164
- package/src/bmb/workflows/workflow/steps-v/step-04-step-type-validation.md +211 -211
- package/src/bmb/workflows/workflow/steps-v/step-05-output-format-validation.md +200 -200
- package/src/bmb/workflows/workflow/steps-v/step-06-validation-design-check.md +195 -195
- package/src/bmb/workflows/workflow/steps-v/step-07-instruction-style-check.md +209 -209
- package/src/bmb/workflows/workflow/steps-v/step-08-collaborative-experience-check.md +199 -199
- package/src/bmb/workflows/workflow/steps-v/step-08b-subprocess-optimization.md +179 -179
- package/src/bmb/workflows/workflow/steps-v/step-09-cohesive-review.md +186 -186
- package/src/bmb/workflows/workflow/steps-v/step-10-report-complete.md +154 -154
- package/src/bmb/workflows/workflow/steps-v/step-11-plan-validation.md +237 -237
- package/src/bmb/workflows/workflow/templates/minimal-output-template.md +11 -11
- package/src/bmb/workflows/workflow/templates/step-01-init-continuable-template.md +241 -241
- package/src/bmb/workflows/workflow/templates/step-1b-template.md +224 -224
- package/src/bmb/workflows/workflow/templates/step-template.md +294 -294
- package/src/bmb/workflows/workflow/templates/workflow-template.md +102 -102
- package/src/bmb/workflows/workflow/workflow-create-workflow.md +79 -79
- package/src/bmb/workflows/workflow/workflow-edit-workflow.md +65 -65
- package/src/bmb/workflows/workflow/workflow-rework-workflow.md +65 -65
- package/src/bmb/workflows/workflow/workflow-validate-max-parallel-workflow.md +66 -66
- package/src/bmb/workflows/workflow/workflow-validate-workflow.md +65 -65
- package/src/bmm/agents/analyst.md +104 -104
- package/src/bmm/agents/dev.md +100 -100
- package/src/bmm/agents/qa.md +100 -90
- package/src/bmm/agents/tech-writer/tech-writer.md +94 -94
- package/src/bmm/module-help.csv +31 -31
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +115 -115
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +107 -107
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +141 -141
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +144 -144
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +147 -147
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +161 -161
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +99 -99
- package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +57 -57
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +87 -87
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +156 -156
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +165 -165
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +140 -140
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +152 -152
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +345 -345
- package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +92 -92
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +164 -164
- package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +174 -174
- package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +184 -184
- package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +105 -105
- package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +360 -360
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +87 -87
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +165 -165
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +174 -174
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +141 -141
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +159 -159
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +387 -387
- package/src/bmm/workflows/1-analysis/research/workflow-domain-research.md +54 -54
- package/src/bmm/workflows/1-analysis/research/workflow-market-research.md +54 -54
- package/src/bmm/workflows/1-analysis/research/workflow-technical-research.md +54 -54
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +100 -100
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +160 -160
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +88 -88
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +99 -99
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +169 -169
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +156 -156
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +136 -136
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +176 -176
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +184 -184
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +174 -174
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +175 -175
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +189 -189
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +162 -162
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +79 -79
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +183 -183
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +149 -149
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +187 -187
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +192 -192
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +108 -108
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +166 -166
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +131 -131
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +150 -150
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +118 -118
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +155 -155
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +170 -170
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +158 -158
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +147 -147
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +182 -182
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +202 -202
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +148 -148
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +201 -201
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +179 -179
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +164 -164
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +65 -65
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +65 -65
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +63 -63
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +63 -63
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +106 -106
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +111 -111
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +115 -115
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +127 -127
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +167 -167
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +143 -143
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +118 -118
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +154 -154
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +136 -136
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +165 -165
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +135 -135
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +192 -192
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +101 -101
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +45 -45
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +185 -185
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +129 -129
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +130 -130
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +93 -93
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +196 -196
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +129 -129
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -54
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +82 -82
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +106 -106
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +138 -138
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +129 -129
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +166 -166
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +186 -186
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +163 -163
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +38 -38
- package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +49 -49
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +124 -124
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +122 -122
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +84 -84
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -58
- package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +43 -43
- package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +53 -53
- package/src/bmm/workflows/4-implementation/create-story/checklist.md +159 -159
- package/src/bmm/workflows/4-implementation/create-story/template.md +79 -79
- package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +20 -20
- package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +25 -25
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +158 -158
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +122 -122
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +93 -93
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +93 -93
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +87 -87
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +146 -146
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -50
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +152 -152
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +123 -123
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +201 -201
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -79
- package/src/bmm/workflows/document-project/workflow.yaml +22 -22
- package/src/bmm/workflows/generate-project-context/steps/step-01-discover.md +184 -184
- package/src/bmm/workflows/generate-project-context/steps/step-02-generate.md +322 -322
- package/src/bmm/workflows/generate-project-context/steps/step-03-complete.md +235 -235
- package/src/bmm/workflows/generate-project-context/workflow.md +49 -49
- package/src/bmm/workflows/qa/automate/workflow.yaml +233 -233
- package/src/bmm/workflows/qa-generate-e2e-tests/workflow.yaml +42 -42
- package/src/core/config.yaml +9 -9
- package/src/core/module-help.csv +10 -10
- package/src/core/scripts/generate-loop-report.py +72 -72
- package/src/core/tasks/editorial-review-prose.xml +101 -101
- package/src/core/tasks/editorial-review-structure.xml +207 -207
- package/src/core/tasks/help.md +86 -86
- package/src/core/tasks/index-docs.xml +64 -64
- package/src/core/tasks/review-adversarial-general.xml +66 -66
- package/src/core/tasks/review-adversarial-loop.xml +46 -46
- package/src/core/tasks/review-edge-case-hunter.xml +63 -63
- package/src/core/tasks/review-party-loop.xml +46 -46
- package/src/core/tasks/shard-doc.xml +107 -107
- package/src/core/tasks/workflow.xml +235 -235
- package/src/core/templates/review-loop-report.html +88 -88
- package/src/core/templates/review-loop-report.md +5 -5
- package/src/core/workflows/advanced-elicitation/workflow.xml +117 -117
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +212 -212
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -122
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -225
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -237
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -209
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -264
- package/src/core/workflows/brainstorming/steps/step-02e-deep-dive.md +68 -68
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +403 -403
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -303
- package/src/core/workflows/brainstorming/workflow.md +60 -60
- package/src/core/workflows/extract-trackers/workflow.md +45 -45
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +142 -142
- package/src/core/workflows/party-mode/workflow.md +194 -194
- package/src/docs/dev/tmux/actions_popup.py +291 -291
- package/src/docs/dev/tmux/tmux-setup.md +62 -1
package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/SKILL.md
CHANGED
|
@@ -1,483 +1,483 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: shareplay-activities
|
|
3
|
-
description: "Build shared real-time experiences using GroupActivities and SharePlay. Use when implementing shared media playback, collaborative app features, synchronized game state, or any FaceTime/iMessage-integrated group activity on iOS, macOS, tvOS, or visionOS."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# GroupActivities / SharePlay
|
|
7
|
-
|
|
8
|
-
Build shared real-time experiences using the GroupActivities framework. SharePlay
|
|
9
|
-
connects people over FaceTime or iMessage, synchronizing media playback, app state,
|
|
10
|
-
or custom data. Targets Swift 6.2 / iOS 26+.
|
|
11
|
-
|
|
12
|
-
## Contents
|
|
13
|
-
|
|
14
|
-
- [Setup](#setup)
|
|
15
|
-
- [Defining a GroupActivity](#defining-a-groupactivity)
|
|
16
|
-
- [Session Lifecycle](#session-lifecycle)
|
|
17
|
-
- [Sending and Receiving Messages](#sending-and-receiving-messages)
|
|
18
|
-
- [Coordinated Media Playback](#coordinated-media-playback)
|
|
19
|
-
- [Starting SharePlay from Your App](#starting-shareplay-from-your-app)
|
|
20
|
-
- [GroupSessionJournal: File Transfer](#groupsessionjournal-file-transfer)
|
|
21
|
-
- [Common Mistakes](#common-mistakes)
|
|
22
|
-
- [Review Checklist](#review-checklist)
|
|
23
|
-
- [References](#references)
|
|
24
|
-
|
|
25
|
-
## Setup
|
|
26
|
-
|
|
27
|
-
### Entitlements
|
|
28
|
-
|
|
29
|
-
Add the Group Activities entitlement to your app:
|
|
30
|
-
|
|
31
|
-
```xml
|
|
32
|
-
<key>com.apple.developer.group-session</key>
|
|
33
|
-
<true/>
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### Info.plist
|
|
37
|
-
|
|
38
|
-
For apps that start SharePlay without a FaceTime call (iOS 17+), add:
|
|
39
|
-
|
|
40
|
-
```xml
|
|
41
|
-
<key>NSSupportsGroupActivities</key>
|
|
42
|
-
<true/>
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Checking Eligibility
|
|
46
|
-
|
|
47
|
-
```swift
|
|
48
|
-
import GroupActivities
|
|
49
|
-
|
|
50
|
-
let observer = GroupStateObserver()
|
|
51
|
-
|
|
52
|
-
// Check if a FaceTime call or iMessage group is active
|
|
53
|
-
if observer.isEligibleForGroupSession {
|
|
54
|
-
showSharePlayButton()
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Observe changes reactively:
|
|
59
|
-
|
|
60
|
-
```swift
|
|
61
|
-
for await isEligible in observer.$isEligibleForGroupSession.values {
|
|
62
|
-
showSharePlayButton(isEligible)
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Defining a GroupActivity
|
|
67
|
-
|
|
68
|
-
Conform to `GroupActivity` and provide metadata:
|
|
69
|
-
|
|
70
|
-
```swift
|
|
71
|
-
import GroupActivities
|
|
72
|
-
import CoreTransferable
|
|
73
|
-
|
|
74
|
-
struct WatchTogetherActivity: GroupActivity {
|
|
75
|
-
let movieID: String
|
|
76
|
-
let movieTitle: String
|
|
77
|
-
|
|
78
|
-
var metadata: GroupActivityMetadata {
|
|
79
|
-
var meta = GroupActivityMetadata()
|
|
80
|
-
meta.title = movieTitle
|
|
81
|
-
meta.type = .watchTogether
|
|
82
|
-
meta.fallbackURL = URL(string: "https://example.com/movie/\(movieID)")
|
|
83
|
-
return meta
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Activity Types
|
|
89
|
-
|
|
90
|
-
| Type | Use Case |
|
|
91
|
-
|---|---|
|
|
92
|
-
| `.generic` | Default for custom activities |
|
|
93
|
-
| `.watchTogether` | Video playback |
|
|
94
|
-
| `.listenTogether` | Audio playback |
|
|
95
|
-
| `.createTogether` | Collaborative creation (drawing, editing) |
|
|
96
|
-
| `.workoutTogether` | Shared fitness sessions |
|
|
97
|
-
|
|
98
|
-
The activity struct must conform to `Codable` so the system can transfer it
|
|
99
|
-
between devices.
|
|
100
|
-
|
|
101
|
-
## Session Lifecycle
|
|
102
|
-
|
|
103
|
-
### Listening for Sessions
|
|
104
|
-
|
|
105
|
-
Set up a long-lived task to receive sessions when another participant starts
|
|
106
|
-
the activity:
|
|
107
|
-
|
|
108
|
-
```swift
|
|
109
|
-
@Observable
|
|
110
|
-
@MainActor
|
|
111
|
-
final class SharePlayManager {
|
|
112
|
-
private var session: GroupSession<WatchTogetherActivity>?
|
|
113
|
-
private var messenger: GroupSessionMessenger?
|
|
114
|
-
private var tasks = TaskGroup()
|
|
115
|
-
|
|
116
|
-
func observeSessions() {
|
|
117
|
-
Task {
|
|
118
|
-
for await session in WatchTogetherActivity.sessions() {
|
|
119
|
-
self.configureSession(session)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private func configureSession(
|
|
125
|
-
_ session: GroupSession<WatchTogetherActivity>
|
|
126
|
-
) {
|
|
127
|
-
self.session = session
|
|
128
|
-
self.messenger = GroupSessionMessenger(session: session)
|
|
129
|
-
|
|
130
|
-
// Observe session state changes
|
|
131
|
-
Task {
|
|
132
|
-
for await state in session.$state.values {
|
|
133
|
-
handleState(state)
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Observe participant changes
|
|
138
|
-
Task {
|
|
139
|
-
for await participants in session.$activeParticipants.values {
|
|
140
|
-
handleParticipants(participants)
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Join the session
|
|
145
|
-
session.join()
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Session States
|
|
151
|
-
|
|
152
|
-
| State | Description |
|
|
153
|
-
|---|---|
|
|
154
|
-
| `.waiting` | Session exists but local participant has not joined |
|
|
155
|
-
| `.joined` | Local participant is actively in the session |
|
|
156
|
-
| `.invalidated(reason:)` | Session ended (check reason for details) |
|
|
157
|
-
|
|
158
|
-
### Handling State Changes
|
|
159
|
-
|
|
160
|
-
```swift
|
|
161
|
-
private func handleState(_ state: GroupSession<WatchTogetherActivity>.State) {
|
|
162
|
-
switch state {
|
|
163
|
-
case .waiting:
|
|
164
|
-
print("Waiting to join")
|
|
165
|
-
case .joined:
|
|
166
|
-
print("Joined session")
|
|
167
|
-
loadActivity(session?.activity)
|
|
168
|
-
case .invalidated(let reason):
|
|
169
|
-
print("Session ended: \(reason)")
|
|
170
|
-
cleanUp()
|
|
171
|
-
@unknown default:
|
|
172
|
-
break
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
private func handleParticipants(_ participants: Set<Participant>) {
|
|
177
|
-
print("Active participants: \(participants.count)")
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Leaving and Ending
|
|
182
|
-
|
|
183
|
-
```swift
|
|
184
|
-
// Leave the session (other participants continue)
|
|
185
|
-
session?.leave()
|
|
186
|
-
|
|
187
|
-
// End the session for all participants
|
|
188
|
-
session?.end()
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## Sending and Receiving Messages
|
|
192
|
-
|
|
193
|
-
Use `GroupSessionMessenger` to sync app state between participants.
|
|
194
|
-
|
|
195
|
-
### Defining Messages
|
|
196
|
-
|
|
197
|
-
Messages must be `Codable`:
|
|
198
|
-
|
|
199
|
-
```swift
|
|
200
|
-
struct SyncMessage: Codable {
|
|
201
|
-
let action: String
|
|
202
|
-
let timestamp: Date
|
|
203
|
-
let data: [String: String]
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Sending
|
|
208
|
-
|
|
209
|
-
```swift
|
|
210
|
-
func sendSync(_ message: SyncMessage) async throws {
|
|
211
|
-
guard let messenger else { return }
|
|
212
|
-
|
|
213
|
-
try await messenger.send(message, to: .all)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Send to specific participants
|
|
217
|
-
try await messenger.send(message, to: .only(participant))
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### Receiving
|
|
221
|
-
|
|
222
|
-
```swift
|
|
223
|
-
func observeMessages() {
|
|
224
|
-
guard let messenger else { return }
|
|
225
|
-
|
|
226
|
-
Task {
|
|
227
|
-
for await (message, context) in messenger.messages(of: SyncMessage.self) {
|
|
228
|
-
let sender = context.source
|
|
229
|
-
handleReceivedMessage(message, from: sender)
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Delivery Modes
|
|
236
|
-
|
|
237
|
-
```swift
|
|
238
|
-
// Reliable (default) -- guaranteed delivery, ordered
|
|
239
|
-
let reliableMessenger = GroupSessionMessenger(
|
|
240
|
-
session: session,
|
|
241
|
-
deliveryMode: .reliable
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
// Unreliable -- faster, no guarantees (good for frequent position updates)
|
|
245
|
-
let unreliableMessenger = GroupSessionMessenger(
|
|
246
|
-
session: session,
|
|
247
|
-
deliveryMode: .unreliable
|
|
248
|
-
)
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
Use `.reliable` for state-changing actions (play/pause, selections). Use
|
|
252
|
-
`.unreliable` for high-frequency ephemeral data (cursor positions, drawing strokes).
|
|
253
|
-
|
|
254
|
-
## Coordinated Media Playback
|
|
255
|
-
|
|
256
|
-
For video/audio, use `AVPlaybackCoordinator` with `AVPlayer`:
|
|
257
|
-
|
|
258
|
-
```swift
|
|
259
|
-
import AVFoundation
|
|
260
|
-
import GroupActivities
|
|
261
|
-
|
|
262
|
-
func configurePlayback(
|
|
263
|
-
session: GroupSession<WatchTogetherActivity>,
|
|
264
|
-
player: AVPlayer
|
|
265
|
-
) {
|
|
266
|
-
// Connect the player's coordinator to the session
|
|
267
|
-
let coordinator = player.playbackCoordinator
|
|
268
|
-
coordinator.coordinateWithSession(session)
|
|
269
|
-
}
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
Once connected, play/pause/seek actions on any participant's player are
|
|
273
|
-
automatically synchronized to all other participants. No manual message
|
|
274
|
-
passing is needed for playback controls.
|
|
275
|
-
|
|
276
|
-
### Handling Playback Events
|
|
277
|
-
|
|
278
|
-
```swift
|
|
279
|
-
// Notify participants about playback events
|
|
280
|
-
let event = GroupSessionEvent(
|
|
281
|
-
originator: session.localParticipant,
|
|
282
|
-
action: .play,
|
|
283
|
-
url: nil
|
|
284
|
-
)
|
|
285
|
-
session.showNotice(event)
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
## Starting SharePlay from Your App
|
|
289
|
-
|
|
290
|
-
### Using GroupActivitySharingController (UIKit)
|
|
291
|
-
|
|
292
|
-
```swift
|
|
293
|
-
import GroupActivities
|
|
294
|
-
import UIKit
|
|
295
|
-
|
|
296
|
-
func startSharePlay() async throws {
|
|
297
|
-
let activity = WatchTogetherActivity(
|
|
298
|
-
movieID: "123",
|
|
299
|
-
movieTitle: "Great Movie"
|
|
300
|
-
)
|
|
301
|
-
|
|
302
|
-
switch await activity.prepareForActivation() {
|
|
303
|
-
case .activationPreferred:
|
|
304
|
-
// Present the sharing controller
|
|
305
|
-
let controller = try GroupActivitySharingController(activity)
|
|
306
|
-
present(controller, animated: true)
|
|
307
|
-
|
|
308
|
-
case .activationDisabled:
|
|
309
|
-
// SharePlay is disabled or unavailable
|
|
310
|
-
print("SharePlay not available")
|
|
311
|
-
|
|
312
|
-
case .cancelled:
|
|
313
|
-
break
|
|
314
|
-
|
|
315
|
-
@unknown default:
|
|
316
|
-
break
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
For `ShareLink` (SwiftUI) and direct `activity.activate()` patterns, see
|
|
322
|
-
`references/shareplay-patterns.md`.
|
|
323
|
-
|
|
324
|
-
## GroupSessionJournal: File Transfer
|
|
325
|
-
|
|
326
|
-
For large data (images, files), use `GroupSessionJournal` instead of
|
|
327
|
-
`GroupSessionMessenger` (which has a size limit):
|
|
328
|
-
|
|
329
|
-
```swift
|
|
330
|
-
import GroupActivities
|
|
331
|
-
|
|
332
|
-
let journal = GroupSessionJournal(session: session)
|
|
333
|
-
|
|
334
|
-
// Upload a file
|
|
335
|
-
let attachment = try await journal.add(imageData)
|
|
336
|
-
|
|
337
|
-
// Observe incoming attachments
|
|
338
|
-
Task {
|
|
339
|
-
for await attachments in journal.attachments {
|
|
340
|
-
for attachment in attachments {
|
|
341
|
-
let data = try await attachment.load(Data.self)
|
|
342
|
-
handleReceivedFile(data)
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
## Common Mistakes
|
|
349
|
-
|
|
350
|
-
### DON'T: Forget to call session.join()
|
|
351
|
-
|
|
352
|
-
```swift
|
|
353
|
-
// WRONG -- session is received but never joined
|
|
354
|
-
for await session in MyActivity.sessions() {
|
|
355
|
-
self.session = session
|
|
356
|
-
// Session stays in .waiting state forever
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// CORRECT -- join after configuring
|
|
360
|
-
for await session in MyActivity.sessions() {
|
|
361
|
-
self.session = session
|
|
362
|
-
self.messenger = GroupSessionMessenger(session: session)
|
|
363
|
-
session.join()
|
|
364
|
-
}
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### DON'T: Forget to leave or end sessions
|
|
368
|
-
|
|
369
|
-
```swift
|
|
370
|
-
// WRONG -- session stays alive after the user navigates away
|
|
371
|
-
func viewDidDisappear() {
|
|
372
|
-
// Nothing -- session leaks
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// CORRECT -- leave when the view is dismissed
|
|
376
|
-
func viewDidDisappear() {
|
|
377
|
-
session?.leave()
|
|
378
|
-
session = nil
|
|
379
|
-
messenger = nil
|
|
380
|
-
}
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### DON'T: Assume all participants have the same state
|
|
384
|
-
|
|
385
|
-
```swift
|
|
386
|
-
// WRONG -- broadcasting state without handling late joiners
|
|
387
|
-
func onJoin() {
|
|
388
|
-
// New participant has no idea what the current state is
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// CORRECT -- send full state to new participants
|
|
392
|
-
func handleParticipants(_ participants: Set<Participant>) {
|
|
393
|
-
let newParticipants = participants.subtracting(knownParticipants)
|
|
394
|
-
for participant in newParticipants {
|
|
395
|
-
Task {
|
|
396
|
-
try await messenger?.send(currentState, to: .only(participant))
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
knownParticipants = participants
|
|
400
|
-
}
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
### DON'T: Use GroupSessionMessenger for large data
|
|
404
|
-
|
|
405
|
-
```swift
|
|
406
|
-
// WRONG -- messenger has a per-message size limit
|
|
407
|
-
let largeImage = try Data(contentsOf: imageURL) // 5 MB
|
|
408
|
-
try await messenger.send(largeImage, to: .all) // May fail
|
|
409
|
-
|
|
410
|
-
// CORRECT -- use GroupSessionJournal for files
|
|
411
|
-
let journal = GroupSessionJournal(session: session)
|
|
412
|
-
try await journal.add(largeImage)
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
### DON'T: Send redundant messages for media playback
|
|
416
|
-
|
|
417
|
-
```swift
|
|
418
|
-
// WRONG -- manually syncing play/pause when using AVPlayer
|
|
419
|
-
func play() {
|
|
420
|
-
player.play()
|
|
421
|
-
try await messenger.send(PlayMessage(), to: .all)
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// CORRECT -- let AVPlaybackCoordinator handle it
|
|
425
|
-
player.playbackCoordinator.coordinateWithSession(session)
|
|
426
|
-
player.play() // Automatically synced to all participants
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
### DON'T: Observe sessions in a view that gets recreated
|
|
430
|
-
|
|
431
|
-
```swift
|
|
432
|
-
// WRONG -- each time the view appears, a new listener is created
|
|
433
|
-
struct MyView: View {
|
|
434
|
-
var body: some View {
|
|
435
|
-
Text("Hello")
|
|
436
|
-
.task {
|
|
437
|
-
for await session in MyActivity.sessions() { }
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
// CORRECT -- observe sessions in a long-lived manager
|
|
443
|
-
@Observable
|
|
444
|
-
final class ActivityManager {
|
|
445
|
-
init() {
|
|
446
|
-
Task {
|
|
447
|
-
for await session in MyActivity.sessions() {
|
|
448
|
-
configureSession(session)
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
## Review Checklist
|
|
456
|
-
|
|
457
|
-
- [ ] Group Activities entitlement (`com.apple.developer.group-session`) added
|
|
458
|
-
- [ ] `GroupActivity` struct is `Codable` with meaningful metadata
|
|
459
|
-
- [ ] `sessions()` observed in a long-lived object (not a SwiftUI view body)
|
|
460
|
-
- [ ] `session.join()` called after receiving and configuring the session
|
|
461
|
-
- [ ] `session.leave()` called when the user navigates away or dismisses
|
|
462
|
-
- [ ] `GroupSessionMessenger` created with appropriate `deliveryMode`
|
|
463
|
-
- [ ] Late-joining participants receive current state on connection
|
|
464
|
-
- [ ] `$state` and `$activeParticipants` publishers observed for lifecycle changes
|
|
465
|
-
- [ ] `GroupSessionJournal` used for large file transfers instead of messenger
|
|
466
|
-
- [ ] `AVPlaybackCoordinator` used for media sync (not manual messages)
|
|
467
|
-
- [ ] `GroupStateObserver.isEligibleForGroupSession` checked before showing SharePlay UI
|
|
468
|
-
- [ ] `prepareForActivation()` called before presenting sharing controller
|
|
469
|
-
- [ ] Session invalidation handled with cleanup of messenger, journal, and tasks
|
|
470
|
-
|
|
471
|
-
## References
|
|
472
|
-
|
|
473
|
-
- Extended patterns (collaborative canvas, spatial Personas, custom templates): `references/shareplay-patterns.md`
|
|
474
|
-
- [GroupActivities framework](https://sosumi.ai/documentation/groupactivities)
|
|
475
|
-
- [GroupActivity protocol](https://sosumi.ai/documentation/groupactivities/groupactivity)
|
|
476
|
-
- [GroupSession](https://sosumi.ai/documentation/groupactivities/groupsession)
|
|
477
|
-
- [GroupSessionMessenger](https://sosumi.ai/documentation/groupactivities/groupsessionmessenger)
|
|
478
|
-
- [GroupSessionJournal](https://sosumi.ai/documentation/groupactivities/groupsessionjournal)
|
|
479
|
-
- [GroupStateObserver](https://sosumi.ai/documentation/groupactivities/groupstateobserver)
|
|
480
|
-
- [GroupActivitySharingController](https://sosumi.ai/documentation/groupactivities/groupactivitysharingcontroller-ybcy)
|
|
481
|
-
- [Defining your app's SharePlay activities](https://sosumi.ai/documentation/groupactivities/defining-your-apps-shareplay-activities)
|
|
482
|
-
- [Presenting SharePlay activities from your app's UI](https://sosumi.ai/documentation/groupactivities/promoting-shareplay-activities-from-your-apps-ui)
|
|
483
|
-
- [Synchronizing data during a SharePlay activity](https://sosumi.ai/documentation/groupactivities/synchronizing-data-during-a-shareplay-activity)
|
|
1
|
+
---
|
|
2
|
+
name: shareplay-activities
|
|
3
|
+
description: "Build shared real-time experiences using GroupActivities and SharePlay. Use when implementing shared media playback, collaborative app features, synchronized game state, or any FaceTime/iMessage-integrated group activity on iOS, macOS, tvOS, or visionOS."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GroupActivities / SharePlay
|
|
7
|
+
|
|
8
|
+
Build shared real-time experiences using the GroupActivities framework. SharePlay
|
|
9
|
+
connects people over FaceTime or iMessage, synchronizing media playback, app state,
|
|
10
|
+
or custom data. Targets Swift 6.2 / iOS 26+.
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- [Setup](#setup)
|
|
15
|
+
- [Defining a GroupActivity](#defining-a-groupactivity)
|
|
16
|
+
- [Session Lifecycle](#session-lifecycle)
|
|
17
|
+
- [Sending and Receiving Messages](#sending-and-receiving-messages)
|
|
18
|
+
- [Coordinated Media Playback](#coordinated-media-playback)
|
|
19
|
+
- [Starting SharePlay from Your App](#starting-shareplay-from-your-app)
|
|
20
|
+
- [GroupSessionJournal: File Transfer](#groupsessionjournal-file-transfer)
|
|
21
|
+
- [Common Mistakes](#common-mistakes)
|
|
22
|
+
- [Review Checklist](#review-checklist)
|
|
23
|
+
- [References](#references)
|
|
24
|
+
|
|
25
|
+
## Setup
|
|
26
|
+
|
|
27
|
+
### Entitlements
|
|
28
|
+
|
|
29
|
+
Add the Group Activities entitlement to your app:
|
|
30
|
+
|
|
31
|
+
```xml
|
|
32
|
+
<key>com.apple.developer.group-session</key>
|
|
33
|
+
<true/>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Info.plist
|
|
37
|
+
|
|
38
|
+
For apps that start SharePlay without a FaceTime call (iOS 17+), add:
|
|
39
|
+
|
|
40
|
+
```xml
|
|
41
|
+
<key>NSSupportsGroupActivities</key>
|
|
42
|
+
<true/>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Checking Eligibility
|
|
46
|
+
|
|
47
|
+
```swift
|
|
48
|
+
import GroupActivities
|
|
49
|
+
|
|
50
|
+
let observer = GroupStateObserver()
|
|
51
|
+
|
|
52
|
+
// Check if a FaceTime call or iMessage group is active
|
|
53
|
+
if observer.isEligibleForGroupSession {
|
|
54
|
+
showSharePlayButton()
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Observe changes reactively:
|
|
59
|
+
|
|
60
|
+
```swift
|
|
61
|
+
for await isEligible in observer.$isEligibleForGroupSession.values {
|
|
62
|
+
showSharePlayButton(isEligible)
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Defining a GroupActivity
|
|
67
|
+
|
|
68
|
+
Conform to `GroupActivity` and provide metadata:
|
|
69
|
+
|
|
70
|
+
```swift
|
|
71
|
+
import GroupActivities
|
|
72
|
+
import CoreTransferable
|
|
73
|
+
|
|
74
|
+
struct WatchTogetherActivity: GroupActivity {
|
|
75
|
+
let movieID: String
|
|
76
|
+
let movieTitle: String
|
|
77
|
+
|
|
78
|
+
var metadata: GroupActivityMetadata {
|
|
79
|
+
var meta = GroupActivityMetadata()
|
|
80
|
+
meta.title = movieTitle
|
|
81
|
+
meta.type = .watchTogether
|
|
82
|
+
meta.fallbackURL = URL(string: "https://example.com/movie/\(movieID)")
|
|
83
|
+
return meta
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Activity Types
|
|
89
|
+
|
|
90
|
+
| Type | Use Case |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `.generic` | Default for custom activities |
|
|
93
|
+
| `.watchTogether` | Video playback |
|
|
94
|
+
| `.listenTogether` | Audio playback |
|
|
95
|
+
| `.createTogether` | Collaborative creation (drawing, editing) |
|
|
96
|
+
| `.workoutTogether` | Shared fitness sessions |
|
|
97
|
+
|
|
98
|
+
The activity struct must conform to `Codable` so the system can transfer it
|
|
99
|
+
between devices.
|
|
100
|
+
|
|
101
|
+
## Session Lifecycle
|
|
102
|
+
|
|
103
|
+
### Listening for Sessions
|
|
104
|
+
|
|
105
|
+
Set up a long-lived task to receive sessions when another participant starts
|
|
106
|
+
the activity:
|
|
107
|
+
|
|
108
|
+
```swift
|
|
109
|
+
@Observable
|
|
110
|
+
@MainActor
|
|
111
|
+
final class SharePlayManager {
|
|
112
|
+
private var session: GroupSession<WatchTogetherActivity>?
|
|
113
|
+
private var messenger: GroupSessionMessenger?
|
|
114
|
+
private var tasks = TaskGroup()
|
|
115
|
+
|
|
116
|
+
func observeSessions() {
|
|
117
|
+
Task {
|
|
118
|
+
for await session in WatchTogetherActivity.sessions() {
|
|
119
|
+
self.configureSession(session)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private func configureSession(
|
|
125
|
+
_ session: GroupSession<WatchTogetherActivity>
|
|
126
|
+
) {
|
|
127
|
+
self.session = session
|
|
128
|
+
self.messenger = GroupSessionMessenger(session: session)
|
|
129
|
+
|
|
130
|
+
// Observe session state changes
|
|
131
|
+
Task {
|
|
132
|
+
for await state in session.$state.values {
|
|
133
|
+
handleState(state)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Observe participant changes
|
|
138
|
+
Task {
|
|
139
|
+
for await participants in session.$activeParticipants.values {
|
|
140
|
+
handleParticipants(participants)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Join the session
|
|
145
|
+
session.join()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Session States
|
|
151
|
+
|
|
152
|
+
| State | Description |
|
|
153
|
+
|---|---|
|
|
154
|
+
| `.waiting` | Session exists but local participant has not joined |
|
|
155
|
+
| `.joined` | Local participant is actively in the session |
|
|
156
|
+
| `.invalidated(reason:)` | Session ended (check reason for details) |
|
|
157
|
+
|
|
158
|
+
### Handling State Changes
|
|
159
|
+
|
|
160
|
+
```swift
|
|
161
|
+
private func handleState(_ state: GroupSession<WatchTogetherActivity>.State) {
|
|
162
|
+
switch state {
|
|
163
|
+
case .waiting:
|
|
164
|
+
print("Waiting to join")
|
|
165
|
+
case .joined:
|
|
166
|
+
print("Joined session")
|
|
167
|
+
loadActivity(session?.activity)
|
|
168
|
+
case .invalidated(let reason):
|
|
169
|
+
print("Session ended: \(reason)")
|
|
170
|
+
cleanUp()
|
|
171
|
+
@unknown default:
|
|
172
|
+
break
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private func handleParticipants(_ participants: Set<Participant>) {
|
|
177
|
+
print("Active participants: \(participants.count)")
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Leaving and Ending
|
|
182
|
+
|
|
183
|
+
```swift
|
|
184
|
+
// Leave the session (other participants continue)
|
|
185
|
+
session?.leave()
|
|
186
|
+
|
|
187
|
+
// End the session for all participants
|
|
188
|
+
session?.end()
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Sending and Receiving Messages
|
|
192
|
+
|
|
193
|
+
Use `GroupSessionMessenger` to sync app state between participants.
|
|
194
|
+
|
|
195
|
+
### Defining Messages
|
|
196
|
+
|
|
197
|
+
Messages must be `Codable`:
|
|
198
|
+
|
|
199
|
+
```swift
|
|
200
|
+
struct SyncMessage: Codable {
|
|
201
|
+
let action: String
|
|
202
|
+
let timestamp: Date
|
|
203
|
+
let data: [String: String]
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Sending
|
|
208
|
+
|
|
209
|
+
```swift
|
|
210
|
+
func sendSync(_ message: SyncMessage) async throws {
|
|
211
|
+
guard let messenger else { return }
|
|
212
|
+
|
|
213
|
+
try await messenger.send(message, to: .all)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Send to specific participants
|
|
217
|
+
try await messenger.send(message, to: .only(participant))
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Receiving
|
|
221
|
+
|
|
222
|
+
```swift
|
|
223
|
+
func observeMessages() {
|
|
224
|
+
guard let messenger else { return }
|
|
225
|
+
|
|
226
|
+
Task {
|
|
227
|
+
for await (message, context) in messenger.messages(of: SyncMessage.self) {
|
|
228
|
+
let sender = context.source
|
|
229
|
+
handleReceivedMessage(message, from: sender)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Delivery Modes
|
|
236
|
+
|
|
237
|
+
```swift
|
|
238
|
+
// Reliable (default) -- guaranteed delivery, ordered
|
|
239
|
+
let reliableMessenger = GroupSessionMessenger(
|
|
240
|
+
session: session,
|
|
241
|
+
deliveryMode: .reliable
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
// Unreliable -- faster, no guarantees (good for frequent position updates)
|
|
245
|
+
let unreliableMessenger = GroupSessionMessenger(
|
|
246
|
+
session: session,
|
|
247
|
+
deliveryMode: .unreliable
|
|
248
|
+
)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Use `.reliable` for state-changing actions (play/pause, selections). Use
|
|
252
|
+
`.unreliable` for high-frequency ephemeral data (cursor positions, drawing strokes).
|
|
253
|
+
|
|
254
|
+
## Coordinated Media Playback
|
|
255
|
+
|
|
256
|
+
For video/audio, use `AVPlaybackCoordinator` with `AVPlayer`:
|
|
257
|
+
|
|
258
|
+
```swift
|
|
259
|
+
import AVFoundation
|
|
260
|
+
import GroupActivities
|
|
261
|
+
|
|
262
|
+
func configurePlayback(
|
|
263
|
+
session: GroupSession<WatchTogetherActivity>,
|
|
264
|
+
player: AVPlayer
|
|
265
|
+
) {
|
|
266
|
+
// Connect the player's coordinator to the session
|
|
267
|
+
let coordinator = player.playbackCoordinator
|
|
268
|
+
coordinator.coordinateWithSession(session)
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Once connected, play/pause/seek actions on any participant's player are
|
|
273
|
+
automatically synchronized to all other participants. No manual message
|
|
274
|
+
passing is needed for playback controls.
|
|
275
|
+
|
|
276
|
+
### Handling Playback Events
|
|
277
|
+
|
|
278
|
+
```swift
|
|
279
|
+
// Notify participants about playback events
|
|
280
|
+
let event = GroupSessionEvent(
|
|
281
|
+
originator: session.localParticipant,
|
|
282
|
+
action: .play,
|
|
283
|
+
url: nil
|
|
284
|
+
)
|
|
285
|
+
session.showNotice(event)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Starting SharePlay from Your App
|
|
289
|
+
|
|
290
|
+
### Using GroupActivitySharingController (UIKit)
|
|
291
|
+
|
|
292
|
+
```swift
|
|
293
|
+
import GroupActivities
|
|
294
|
+
import UIKit
|
|
295
|
+
|
|
296
|
+
func startSharePlay() async throws {
|
|
297
|
+
let activity = WatchTogetherActivity(
|
|
298
|
+
movieID: "123",
|
|
299
|
+
movieTitle: "Great Movie"
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
switch await activity.prepareForActivation() {
|
|
303
|
+
case .activationPreferred:
|
|
304
|
+
// Present the sharing controller
|
|
305
|
+
let controller = try GroupActivitySharingController(activity)
|
|
306
|
+
present(controller, animated: true)
|
|
307
|
+
|
|
308
|
+
case .activationDisabled:
|
|
309
|
+
// SharePlay is disabled or unavailable
|
|
310
|
+
print("SharePlay not available")
|
|
311
|
+
|
|
312
|
+
case .cancelled:
|
|
313
|
+
break
|
|
314
|
+
|
|
315
|
+
@unknown default:
|
|
316
|
+
break
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
For `ShareLink` (SwiftUI) and direct `activity.activate()` patterns, see
|
|
322
|
+
`references/shareplay-patterns.md`.
|
|
323
|
+
|
|
324
|
+
## GroupSessionJournal: File Transfer
|
|
325
|
+
|
|
326
|
+
For large data (images, files), use `GroupSessionJournal` instead of
|
|
327
|
+
`GroupSessionMessenger` (which has a size limit):
|
|
328
|
+
|
|
329
|
+
```swift
|
|
330
|
+
import GroupActivities
|
|
331
|
+
|
|
332
|
+
let journal = GroupSessionJournal(session: session)
|
|
333
|
+
|
|
334
|
+
// Upload a file
|
|
335
|
+
let attachment = try await journal.add(imageData)
|
|
336
|
+
|
|
337
|
+
// Observe incoming attachments
|
|
338
|
+
Task {
|
|
339
|
+
for await attachments in journal.attachments {
|
|
340
|
+
for attachment in attachments {
|
|
341
|
+
let data = try await attachment.load(Data.self)
|
|
342
|
+
handleReceivedFile(data)
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Common Mistakes
|
|
349
|
+
|
|
350
|
+
### DON'T: Forget to call session.join()
|
|
351
|
+
|
|
352
|
+
```swift
|
|
353
|
+
// WRONG -- session is received but never joined
|
|
354
|
+
for await session in MyActivity.sessions() {
|
|
355
|
+
self.session = session
|
|
356
|
+
// Session stays in .waiting state forever
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// CORRECT -- join after configuring
|
|
360
|
+
for await session in MyActivity.sessions() {
|
|
361
|
+
self.session = session
|
|
362
|
+
self.messenger = GroupSessionMessenger(session: session)
|
|
363
|
+
session.join()
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### DON'T: Forget to leave or end sessions
|
|
368
|
+
|
|
369
|
+
```swift
|
|
370
|
+
// WRONG -- session stays alive after the user navigates away
|
|
371
|
+
func viewDidDisappear() {
|
|
372
|
+
// Nothing -- session leaks
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// CORRECT -- leave when the view is dismissed
|
|
376
|
+
func viewDidDisappear() {
|
|
377
|
+
session?.leave()
|
|
378
|
+
session = nil
|
|
379
|
+
messenger = nil
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### DON'T: Assume all participants have the same state
|
|
384
|
+
|
|
385
|
+
```swift
|
|
386
|
+
// WRONG -- broadcasting state without handling late joiners
|
|
387
|
+
func onJoin() {
|
|
388
|
+
// New participant has no idea what the current state is
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// CORRECT -- send full state to new participants
|
|
392
|
+
func handleParticipants(_ participants: Set<Participant>) {
|
|
393
|
+
let newParticipants = participants.subtracting(knownParticipants)
|
|
394
|
+
for participant in newParticipants {
|
|
395
|
+
Task {
|
|
396
|
+
try await messenger?.send(currentState, to: .only(participant))
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
knownParticipants = participants
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### DON'T: Use GroupSessionMessenger for large data
|
|
404
|
+
|
|
405
|
+
```swift
|
|
406
|
+
// WRONG -- messenger has a per-message size limit
|
|
407
|
+
let largeImage = try Data(contentsOf: imageURL) // 5 MB
|
|
408
|
+
try await messenger.send(largeImage, to: .all) // May fail
|
|
409
|
+
|
|
410
|
+
// CORRECT -- use GroupSessionJournal for files
|
|
411
|
+
let journal = GroupSessionJournal(session: session)
|
|
412
|
+
try await journal.add(largeImage)
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### DON'T: Send redundant messages for media playback
|
|
416
|
+
|
|
417
|
+
```swift
|
|
418
|
+
// WRONG -- manually syncing play/pause when using AVPlayer
|
|
419
|
+
func play() {
|
|
420
|
+
player.play()
|
|
421
|
+
try await messenger.send(PlayMessage(), to: .all)
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// CORRECT -- let AVPlaybackCoordinator handle it
|
|
425
|
+
player.playbackCoordinator.coordinateWithSession(session)
|
|
426
|
+
player.play() // Automatically synced to all participants
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### DON'T: Observe sessions in a view that gets recreated
|
|
430
|
+
|
|
431
|
+
```swift
|
|
432
|
+
// WRONG -- each time the view appears, a new listener is created
|
|
433
|
+
struct MyView: View {
|
|
434
|
+
var body: some View {
|
|
435
|
+
Text("Hello")
|
|
436
|
+
.task {
|
|
437
|
+
for await session in MyActivity.sessions() { }
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// CORRECT -- observe sessions in a long-lived manager
|
|
443
|
+
@Observable
|
|
444
|
+
final class ActivityManager {
|
|
445
|
+
init() {
|
|
446
|
+
Task {
|
|
447
|
+
for await session in MyActivity.sessions() {
|
|
448
|
+
configureSession(session)
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Review Checklist
|
|
456
|
+
|
|
457
|
+
- [ ] Group Activities entitlement (`com.apple.developer.group-session`) added
|
|
458
|
+
- [ ] `GroupActivity` struct is `Codable` with meaningful metadata
|
|
459
|
+
- [ ] `sessions()` observed in a long-lived object (not a SwiftUI view body)
|
|
460
|
+
- [ ] `session.join()` called after receiving and configuring the session
|
|
461
|
+
- [ ] `session.leave()` called when the user navigates away or dismisses
|
|
462
|
+
- [ ] `GroupSessionMessenger` created with appropriate `deliveryMode`
|
|
463
|
+
- [ ] Late-joining participants receive current state on connection
|
|
464
|
+
- [ ] `$state` and `$activeParticipants` publishers observed for lifecycle changes
|
|
465
|
+
- [ ] `GroupSessionJournal` used for large file transfers instead of messenger
|
|
466
|
+
- [ ] `AVPlaybackCoordinator` used for media sync (not manual messages)
|
|
467
|
+
- [ ] `GroupStateObserver.isEligibleForGroupSession` checked before showing SharePlay UI
|
|
468
|
+
- [ ] `prepareForActivation()` called before presenting sharing controller
|
|
469
|
+
- [ ] Session invalidation handled with cleanup of messenger, journal, and tasks
|
|
470
|
+
|
|
471
|
+
## References
|
|
472
|
+
|
|
473
|
+
- Extended patterns (collaborative canvas, spatial Personas, custom templates): `references/shareplay-patterns.md`
|
|
474
|
+
- [GroupActivities framework](https://sosumi.ai/documentation/groupactivities)
|
|
475
|
+
- [GroupActivity protocol](https://sosumi.ai/documentation/groupactivities/groupactivity)
|
|
476
|
+
- [GroupSession](https://sosumi.ai/documentation/groupactivities/groupsession)
|
|
477
|
+
- [GroupSessionMessenger](https://sosumi.ai/documentation/groupactivities/groupsessionmessenger)
|
|
478
|
+
- [GroupSessionJournal](https://sosumi.ai/documentation/groupactivities/groupsessionjournal)
|
|
479
|
+
- [GroupStateObserver](https://sosumi.ai/documentation/groupactivities/groupstateobserver)
|
|
480
|
+
- [GroupActivitySharingController](https://sosumi.ai/documentation/groupactivities/groupactivitysharingcontroller-ybcy)
|
|
481
|
+
- [Defining your app's SharePlay activities](https://sosumi.ai/documentation/groupactivities/defining-your-apps-shareplay-activities)
|
|
482
|
+
- [Presenting SharePlay activities from your app's UI](https://sosumi.ai/documentation/groupactivities/promoting-shareplay-activities-from-your-apps-ui)
|
|
483
|
+
- [Synchronizing data during a SharePlay activity](https://sosumi.ai/documentation/groupactivities/synchronizing-data-during-a-shareplay-activity)
|