@devo-bmad-custom/agent-orchestration 1.0.1 → 1.0.3
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 +44 -11
- 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/bmad-track-compact.md +1 -1
- package/src/.claude/commands/bmad-track-extended.md +1 -1
- package/src/.claude/commands/bmad-track-large.md +1 -1
- package/src/.claude/commands/bmad-track-medium.md +1 -1
- package/src/.claude/commands/bmad-track-nano.md +1 -1
- package/src/.claude/commands/bmad-track-rv.md +1 -1
- package/src/.claude/commands/bmad-track-small.md +1 -1
- package/src/.claude/commands/master-orchestrator.md +15 -0
- package/src/_memory/config.yaml +11 -11
- package/src/_memory/master-orchestrator-sidecar/instructions.md +85 -32
- 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/review-agent.md +1 -1
- 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/agents/master-orchestrator.md +3 -3
- 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/metrickit-diagnostics/SKILL.md
CHANGED
|
@@ -1,479 +1,479 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: metrickit-diagnostics
|
|
3
|
-
description: "Collect and analyze on-device performance metrics and crash diagnostics using MetricKit. Use when setting up MXMetricManager, handling MXMetricPayload or MXDiagnosticPayload, processing crash/hang/disk-write diagnostics via MXCallStackTree, adding custom signpost metrics, or uploading telemetry to an analytics backend."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# MetricKit Diagnostics
|
|
7
|
-
|
|
8
|
-
Collect aggregated performance metrics and crash diagnostics from production
|
|
9
|
-
devices using MetricKit. The framework delivers daily metric payloads (CPU,
|
|
10
|
-
memory, launch time, hang rate, animation hitches, network usage) and
|
|
11
|
-
immediate diagnostic payloads (crashes, hangs, disk-write exceptions) with
|
|
12
|
-
full call-stack trees for triage.
|
|
13
|
-
|
|
14
|
-
## Contents
|
|
15
|
-
|
|
16
|
-
- [Subscriber Setup](#subscriber-setup)
|
|
17
|
-
- [Receiving Metric Payloads](#receiving-metric-payloads)
|
|
18
|
-
- [Receiving Diagnostic Payloads](#receiving-diagnostic-payloads)
|
|
19
|
-
- [Key Metrics](#key-metrics)
|
|
20
|
-
- [Call Stack Trees](#call-stack-trees)
|
|
21
|
-
- [Custom Signpost Metrics](#custom-signpost-metrics)
|
|
22
|
-
- [Exporting and Uploading Payloads](#exporting-and-uploading-payloads)
|
|
23
|
-
- [Extended Launch Measurement](#extended-launch-measurement)
|
|
24
|
-
- [Xcode Organizer Integration](#xcode-organizer-integration)
|
|
25
|
-
- [Common Mistakes](#common-mistakes)
|
|
26
|
-
- [Review Checklist](#review-checklist)
|
|
27
|
-
- [References](#references)
|
|
28
|
-
|
|
29
|
-
## Subscriber Setup
|
|
30
|
-
|
|
31
|
-
Register a subscriber as early as possible — ideally in
|
|
32
|
-
`application(_:didFinishLaunchingWithOptions:)` or `App.init`. MetricKit
|
|
33
|
-
starts accumulating reports after the first access to `MXMetricManager.shared`.
|
|
34
|
-
|
|
35
|
-
```swift
|
|
36
|
-
import MetricKit
|
|
37
|
-
|
|
38
|
-
final class MetricsSubscriber: NSObject, MXMetricManagerSubscriber {
|
|
39
|
-
static let shared = MetricsSubscriber()
|
|
40
|
-
|
|
41
|
-
func subscribe() {
|
|
42
|
-
MXMetricManager.shared.add(self)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
func unsubscribe() {
|
|
46
|
-
MXMetricManager.shared.remove(self)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
func didReceive(_ payloads: [MXMetricPayload]) {
|
|
50
|
-
// Handle daily metrics
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
func didReceive(_ payloads: [MXDiagnosticPayload]) {
|
|
54
|
-
// Handle diagnostics (crashes, hangs, disk writes)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### UIKit Registration
|
|
60
|
-
|
|
61
|
-
```swift
|
|
62
|
-
func application(
|
|
63
|
-
_ application: UIApplication,
|
|
64
|
-
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
65
|
-
) -> Bool {
|
|
66
|
-
MetricsSubscriber.shared.subscribe()
|
|
67
|
-
return true
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### SwiftUI Registration
|
|
72
|
-
|
|
73
|
-
```swift
|
|
74
|
-
@main
|
|
75
|
-
struct MyApp: App {
|
|
76
|
-
init() {
|
|
77
|
-
MetricsSubscriber.shared.subscribe()
|
|
78
|
-
}
|
|
79
|
-
var body: some Scene {
|
|
80
|
-
WindowGroup { ContentView() }
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Receiving Metric Payloads
|
|
86
|
-
|
|
87
|
-
`MXMetricPayload` arrives approximately once per 24 hours containing
|
|
88
|
-
aggregated metrics. The array may contain multiple payloads if prior
|
|
89
|
-
deliveries were missed.
|
|
90
|
-
|
|
91
|
-
```swift
|
|
92
|
-
func didReceive(_ payloads: [MXMetricPayload]) {
|
|
93
|
-
for payload in payloads {
|
|
94
|
-
let begin = payload.timeStampBegin
|
|
95
|
-
let end = payload.timeStampEnd
|
|
96
|
-
let version = payload.latestApplicationVersion
|
|
97
|
-
|
|
98
|
-
// Persist raw JSON before processing
|
|
99
|
-
let jsonData = payload.jsonRepresentation()
|
|
100
|
-
persistPayload(jsonData, from: begin, to: end)
|
|
101
|
-
|
|
102
|
-
processMetrics(payload)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**Availability**: `MXMetricPayload` — iOS 13.0+, macOS 10.15+, visionOS 1.0+
|
|
108
|
-
|
|
109
|
-
## Receiving Diagnostic Payloads
|
|
110
|
-
|
|
111
|
-
`MXDiagnosticPayload` delivers crash, hang, CPU exception, disk-write, and
|
|
112
|
-
app-launch diagnostics. On iOS 15+ and macOS 12+, diagnostics arrive
|
|
113
|
-
immediately rather than bundled with the daily report.
|
|
114
|
-
|
|
115
|
-
```swift
|
|
116
|
-
func didReceive(_ payloads: [MXDiagnosticPayload]) {
|
|
117
|
-
for payload in payloads {
|
|
118
|
-
let jsonData = payload.jsonRepresentation()
|
|
119
|
-
persistPayload(jsonData)
|
|
120
|
-
|
|
121
|
-
if let crashes = payload.crashDiagnostics {
|
|
122
|
-
for crash in crashes {
|
|
123
|
-
handleCrash(crash)
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if let hangs = payload.hangDiagnostics {
|
|
127
|
-
for hang in hangs {
|
|
128
|
-
handleHang(hang)
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if let diskWrites = payload.diskWriteExceptionDiagnostics {
|
|
132
|
-
for diskWrite in diskWrites {
|
|
133
|
-
handleDiskWrite(diskWrite)
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if let cpuExceptions = payload.cpuExceptionDiagnostics {
|
|
137
|
-
for cpuException in cpuExceptions {
|
|
138
|
-
handleCPUException(cpuException)
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if let launchDiags = payload.appLaunchDiagnostics {
|
|
142
|
-
for launchDiag in launchDiags {
|
|
143
|
-
handleSlowLaunch(launchDiag)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**Availability**: `MXDiagnosticPayload` — iOS 14.0+, macOS 12.0+, visionOS 1.0+
|
|
151
|
-
|
|
152
|
-
## Key Metrics
|
|
153
|
-
|
|
154
|
-
### Launch Time — MXAppLaunchMetric
|
|
155
|
-
|
|
156
|
-
```swift
|
|
157
|
-
if let launch = payload.applicationLaunchMetrics {
|
|
158
|
-
let firstDraw = launch.histogrammedTimeToFirstDraw
|
|
159
|
-
let optimized = launch.histogrammedOptimizedTimeToFirstDraw
|
|
160
|
-
let resume = launch.histogrammedApplicationResumeTime
|
|
161
|
-
let extended = launch.histogrammedExtendedLaunch
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Run Time — MXAppRunTimeMetric
|
|
166
|
-
|
|
167
|
-
```swift
|
|
168
|
-
if let runTime = payload.applicationTimeMetrics {
|
|
169
|
-
let fg = runTime.cumulativeForegroundTime // Measurement<UnitDuration>
|
|
170
|
-
let bg = runTime.cumulativeBackgroundTime
|
|
171
|
-
let bgAudio = runTime.cumulativeBackgroundAudioTime
|
|
172
|
-
let bgLocation = runTime.cumulativeBackgroundLocationTime
|
|
173
|
-
}
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### CPU, Memory, and Responsiveness
|
|
177
|
-
|
|
178
|
-
```swift
|
|
179
|
-
if let cpu = payload.cpuMetrics {
|
|
180
|
-
let cpuTime = cpu.cumulativeCPUTime // Measurement<UnitDuration>
|
|
181
|
-
}
|
|
182
|
-
if let memory = payload.memoryMetrics {
|
|
183
|
-
let peakMemory = memory.peakMemoryUsage // Measurement<UnitInformationStorage>
|
|
184
|
-
}
|
|
185
|
-
if let responsiveness = payload.applicationResponsivenessMetrics {
|
|
186
|
-
let hangTime = responsiveness.histogrammedApplicationHangTime
|
|
187
|
-
}
|
|
188
|
-
if let animation = payload.animationMetrics {
|
|
189
|
-
let scrollHitchRate = animation.scrollHitchTimeRatio // Measurement<Unit>
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### Network and Cellular
|
|
194
|
-
|
|
195
|
-
```swift
|
|
196
|
-
if let network = payload.networkTransferMetrics {
|
|
197
|
-
let wifiUp = network.cumulativeWifiUpload // Measurement<UnitInformationStorage>
|
|
198
|
-
let wifiDown = network.cumulativeWifiDownload
|
|
199
|
-
let cellUp = network.cumulativeCellularUpload
|
|
200
|
-
let cellDown = network.cumulativeCellularDownload
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### App Exit Metrics
|
|
205
|
-
|
|
206
|
-
```swift
|
|
207
|
-
if let exits = payload.applicationExitMetrics {
|
|
208
|
-
let fg = exits.foregroundExitData
|
|
209
|
-
let bg = exits.backgroundExitData
|
|
210
|
-
// Inspect normal, abnormal, watchdog, memory, etc.
|
|
211
|
-
}
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Call Stack Trees
|
|
215
|
-
|
|
216
|
-
`MXCallStackTree` is attached to each diagnostic (crash, hang, CPU exception,
|
|
217
|
-
disk write, app launch). Use `jsonRepresentation()` to extract and symbolicate.
|
|
218
|
-
|
|
219
|
-
```swift
|
|
220
|
-
func handleCrash(_ crash: MXCrashDiagnostic) {
|
|
221
|
-
let tree = crash.callStackTree
|
|
222
|
-
let treeJSON = tree.jsonRepresentation()
|
|
223
|
-
|
|
224
|
-
let exceptionType = crash.exceptionType
|
|
225
|
-
let signal = crash.signal
|
|
226
|
-
let reason = crash.terminationReason
|
|
227
|
-
|
|
228
|
-
uploadDiagnostic(
|
|
229
|
-
type: "crash",
|
|
230
|
-
exceptionType: exceptionType,
|
|
231
|
-
signal: signal,
|
|
232
|
-
reason: reason,
|
|
233
|
-
callStack: treeJSON
|
|
234
|
-
)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
func handleHang(_ hang: MXHangDiagnostic) {
|
|
238
|
-
let tree = hang.callStackTree
|
|
239
|
-
let duration = hang.hangDuration // Measurement<UnitDuration>
|
|
240
|
-
uploadDiagnostic(type: "hang", duration: duration, callStack: tree.jsonRepresentation())
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
The JSON structure contains an array of call stack frames with binary name,
|
|
245
|
-
offset, and address. Symbolicate using `atos` or upload dSYMs to your
|
|
246
|
-
analytics service.
|
|
247
|
-
|
|
248
|
-
**Availability**: `MXCallStackTree` — iOS 14.0+, macOS 12.0+, visionOS 1.0+
|
|
249
|
-
|
|
250
|
-
## Custom Signpost Metrics
|
|
251
|
-
|
|
252
|
-
Use `mxSignpost` with a MetricKit log handle to capture custom performance
|
|
253
|
-
intervals. These appear in the daily `MXMetricPayload` under `signpostMetrics`.
|
|
254
|
-
|
|
255
|
-
### Creating a Log Handle
|
|
256
|
-
|
|
257
|
-
```swift
|
|
258
|
-
let metricLog = MXMetricManager.makeLogHandle(category: "Networking")
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### Emitting Signposts
|
|
262
|
-
|
|
263
|
-
```swift
|
|
264
|
-
import os
|
|
265
|
-
|
|
266
|
-
func fetchData() async throws -> Data {
|
|
267
|
-
let signpostID = MXSignpostIntervalData.makeSignpostID(log: metricLog)
|
|
268
|
-
|
|
269
|
-
mxSignpost(.begin, log: metricLog, name: "DataFetch", signpostID: signpostID)
|
|
270
|
-
let data = try await URLSession.shared.data(from: url).0
|
|
271
|
-
mxSignpost(.end, log: metricLog, name: "DataFetch", signpostID: signpostID)
|
|
272
|
-
|
|
273
|
-
return data
|
|
274
|
-
}
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### Reading Custom Metrics from Payload
|
|
278
|
-
|
|
279
|
-
```swift
|
|
280
|
-
if let signposts = payload.signpostMetrics {
|
|
281
|
-
for metric in signposts {
|
|
282
|
-
let name = metric.signpostName // "DataFetch"
|
|
283
|
-
let category = metric.signpostCategory // "Networking"
|
|
284
|
-
let count = metric.totalCount
|
|
285
|
-
if let intervalData = metric.signpostIntervalData {
|
|
286
|
-
let avgMemory = intervalData.averageMemory
|
|
287
|
-
let cumulativeCPUTime = intervalData.cumulativeCPUTime
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
> The system limits the number of custom signpost metrics per log to reduce
|
|
294
|
-
> on-device overhead. Reserve custom metrics for critical code paths.
|
|
295
|
-
|
|
296
|
-
## Exporting and Uploading Payloads
|
|
297
|
-
|
|
298
|
-
Both payload types conform to `NSSecureCoding` and provide
|
|
299
|
-
`jsonRepresentation()` for easy serialization.
|
|
300
|
-
|
|
301
|
-
```swift
|
|
302
|
-
func persistPayload(_ jsonData: Data, from: Date? = nil, to: Date? = nil) {
|
|
303
|
-
let fileName = "metrics_\(ISO8601DateFormatter().string(from: Date())).json"
|
|
304
|
-
let url = FileManager.default.temporaryDirectory.appending(path: fileName)
|
|
305
|
-
try? jsonData.write(to: url)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
func uploadPayloads(_ jsonData: Data) {
|
|
309
|
-
Task.detached(priority: .utility) {
|
|
310
|
-
var request = URLRequest(url: URL(string: "https://api.example.com/metrics")!)
|
|
311
|
-
request.httpMethod = "POST"
|
|
312
|
-
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
313
|
-
request.httpBody = jsonData
|
|
314
|
-
_ = try? await URLSession.shared.data(for: request)
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### Retrieving Past Payloads
|
|
320
|
-
|
|
321
|
-
If the subscriber was not registered when payloads arrived, retrieve them
|
|
322
|
-
using `pastPayloads` and `pastDiagnosticPayloads`. These return reports
|
|
323
|
-
generated since the last allocation of the shared manager.
|
|
324
|
-
|
|
325
|
-
```swift
|
|
326
|
-
let pastMetrics = MXMetricManager.shared.pastPayloads
|
|
327
|
-
let pastDiags = MXMetricManager.shared.pastDiagnosticPayloads
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
## Extended Launch Measurement
|
|
331
|
-
|
|
332
|
-
Track post-first-draw setup work (loading databases, restoring state) as
|
|
333
|
-
part of the launch metric using extended launch measurement.
|
|
334
|
-
|
|
335
|
-
```swift
|
|
336
|
-
let taskID = MXLaunchTaskID("com.example.app.loadDatabase")
|
|
337
|
-
|
|
338
|
-
MXMetricManager.shared.extendLaunchMeasurement(forTaskID: taskID)
|
|
339
|
-
// Perform extended launch work...
|
|
340
|
-
await database.load()
|
|
341
|
-
MXMetricManager.shared.finishExtendedLaunchMeasurement(forTaskID: taskID)
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
Extended launch times appear under `histogrammedExtendedLaunch` in
|
|
345
|
-
`MXAppLaunchMetric`.
|
|
346
|
-
|
|
347
|
-
## Xcode Organizer Integration
|
|
348
|
-
|
|
349
|
-
Xcode Organizer shows the same MetricKit data aggregated across all users
|
|
350
|
-
who have opted in to share diagnostics. Use Organizer for trend analysis:
|
|
351
|
-
|
|
352
|
-
- **Metrics tab**: Battery, performance, and disk-write metrics over time
|
|
353
|
-
- **Regressions tab**: Automatic detection of metric regressions per version
|
|
354
|
-
- **Crashes tab**: Crash logs with symbolicated stack traces
|
|
355
|
-
|
|
356
|
-
MetricKit on-device collection complements Organizer by letting you route
|
|
357
|
-
raw data to your own backend for custom dashboards, alerting, and filtering
|
|
358
|
-
by user cohort.
|
|
359
|
-
|
|
360
|
-
## Common Mistakes
|
|
361
|
-
|
|
362
|
-
### DON'T: Subscribe to MXMetricManager too late
|
|
363
|
-
|
|
364
|
-
The system may deliver pending payloads shortly after launch. Subscribing
|
|
365
|
-
late (e.g., in a view controller) risks missing them entirely.
|
|
366
|
-
|
|
367
|
-
```swift
|
|
368
|
-
// WRONG — subscribing in a view controller
|
|
369
|
-
override func viewDidLoad() {
|
|
370
|
-
super.viewDidLoad()
|
|
371
|
-
MXMetricManager.shared.add(self)
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// CORRECT — subscribe in application(_:didFinishLaunchingWithOptions:)
|
|
375
|
-
func application(
|
|
376
|
-
_ application: UIApplication,
|
|
377
|
-
didFinishLaunchingWithOptions opts: [UIApplication.LaunchOptionsKey: Any]?
|
|
378
|
-
) -> Bool {
|
|
379
|
-
MXMetricManager.shared.add(metricsSubscriber)
|
|
380
|
-
return true
|
|
381
|
-
}
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
### DON'T: Ignore MXDiagnosticPayload
|
|
385
|
-
|
|
386
|
-
Only handling `MXMetricPayload` means you miss crash, hang, and disk-write
|
|
387
|
-
diagnostics — the most actionable data MetricKit provides.
|
|
388
|
-
|
|
389
|
-
```swift
|
|
390
|
-
// WRONG — only implementing metric callback
|
|
391
|
-
func didReceive(_ payloads: [MXMetricPayload]) { /* ... */ }
|
|
392
|
-
|
|
393
|
-
// CORRECT — implement both callbacks
|
|
394
|
-
func didReceive(_ payloads: [MXMetricPayload]) { /* ... */ }
|
|
395
|
-
func didReceive(_ payloads: [MXDiagnosticPayload]) { /* ... */ }
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
### DON'T: Process payloads without persisting first
|
|
399
|
-
|
|
400
|
-
The system delivers each payload once. If your subscriber crashes during
|
|
401
|
-
processing, the data is lost permanently.
|
|
402
|
-
|
|
403
|
-
```swift
|
|
404
|
-
// WRONG — process inline, crash loses data
|
|
405
|
-
func didReceive(_ payloads: [MXDiagnosticPayload]) {
|
|
406
|
-
for p in payloads {
|
|
407
|
-
riskyProcessing(p) // If this crashes, payload is gone
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// CORRECT — persist raw JSON first, then process
|
|
412
|
-
func didReceive(_ payloads: [MXDiagnosticPayload]) {
|
|
413
|
-
for p in payloads {
|
|
414
|
-
let json = p.jsonRepresentation()
|
|
415
|
-
try? json.write(to: localCacheURL()) // Safe on disk
|
|
416
|
-
Task.detached { self.processAsync(json) }
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
### DON'T: Do heavy work synchronously in didReceive
|
|
422
|
-
|
|
423
|
-
The callback runs on an arbitrary thread. Blocking it with heavy processing
|
|
424
|
-
or synchronous network calls delays delivery of subsequent payloads.
|
|
425
|
-
|
|
426
|
-
```swift
|
|
427
|
-
// WRONG — synchronous upload in callback
|
|
428
|
-
func didReceive(_ payloads: [MXMetricPayload]) {
|
|
429
|
-
for p in payloads {
|
|
430
|
-
let data = p.jsonRepresentation()
|
|
431
|
-
URLSession.shared.uploadTask(with: request, from: data).resume() // sync wait
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// CORRECT — persist and dispatch async
|
|
436
|
-
func didReceive(_ payloads: [MXMetricPayload]) {
|
|
437
|
-
for p in payloads {
|
|
438
|
-
let json = p.jsonRepresentation()
|
|
439
|
-
persistLocally(json)
|
|
440
|
-
Task.detached(priority: .utility) {
|
|
441
|
-
await self.uploadToBackend(json)
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
### DON'T: Expect immediate data in development
|
|
448
|
-
|
|
449
|
-
MetricKit aggregates data over 24-hour windows. Payloads do not arrive
|
|
450
|
-
immediately after instrumenting. Use Xcode Organizer or simulated payloads
|
|
451
|
-
for faster iteration during development.
|
|
452
|
-
|
|
453
|
-
## Review Checklist
|
|
454
|
-
|
|
455
|
-
- [ ] `MXMetricManager.shared.add(subscriber)` called in `application(_:didFinishLaunchingWithOptions:)` or `App.init`
|
|
456
|
-
- [ ] Subscriber conforms to `MXMetricManagerSubscriber` and inherits `NSObject`
|
|
457
|
-
- [ ] Both `didReceive(_: [MXMetricPayload])` and `didReceive(_: [MXDiagnosticPayload])` implemented
|
|
458
|
-
- [ ] Raw `jsonRepresentation()` persisted to disk before processing
|
|
459
|
-
- [ ] Heavy processing dispatched asynchronously off the callback thread
|
|
460
|
-
- [ ] `MXCallStackTree` JSON uploaded with dSYMs for symbolication
|
|
461
|
-
- [ ] Custom signpost metrics limited to critical code paths
|
|
462
|
-
- [ ] `pastPayloads` and `pastDiagnosticPayloads` checked on launch for missed deliveries
|
|
463
|
-
- [ ] Extended launch tasks call both `extendLaunchMeasurement` and `finishExtendedLaunchMeasurement`
|
|
464
|
-
- [ ] Analytics backend accepts and stores MetricKit JSON format
|
|
465
|
-
- [ ] Xcode Organizer reviewed for regression trends alongside on-device data
|
|
466
|
-
|
|
467
|
-
## References
|
|
468
|
-
|
|
469
|
-
- [MetricKit framework](https://sosumi.ai/documentation/metrickit)
|
|
470
|
-
- [MXMetricManager](https://sosumi.ai/documentation/metrickit/mxmetricmanager)
|
|
471
|
-
- [MXMetricManagerSubscriber](https://sosumi.ai/documentation/metrickit/mxmetricmanagersubscriber)
|
|
472
|
-
- [MXMetricPayload](https://sosumi.ai/documentation/metrickit/mxmetricpayload)
|
|
473
|
-
- [MXDiagnosticPayload](https://sosumi.ai/documentation/metrickit/mxdiagnosticpayload)
|
|
474
|
-
- [MXCallStackTree](https://sosumi.ai/documentation/metrickit/mxcallstacktree)
|
|
475
|
-
- [MXSignpostMetric](https://sosumi.ai/documentation/metrickit/mxsignpostmetric)
|
|
476
|
-
- [MXAppLaunchMetric](https://sosumi.ai/documentation/metrickit/mxapplaunchmetric)
|
|
477
|
-
- [MXAppRunTimeMetric](https://sosumi.ai/documentation/metrickit/mxappruntimemetric)
|
|
478
|
-
- [MXCrashDiagnostic](https://sosumi.ai/documentation/metrickit/mxcrashdiagnostic)
|
|
479
|
-
- [Analyzing the performance of your shipping app](https://sosumi.ai/documentation/xcode/analyzing-the-performance-of-your-shipping-app)
|
|
1
|
+
---
|
|
2
|
+
name: metrickit-diagnostics
|
|
3
|
+
description: "Collect and analyze on-device performance metrics and crash diagnostics using MetricKit. Use when setting up MXMetricManager, handling MXMetricPayload or MXDiagnosticPayload, processing crash/hang/disk-write diagnostics via MXCallStackTree, adding custom signpost metrics, or uploading telemetry to an analytics backend."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MetricKit Diagnostics
|
|
7
|
+
|
|
8
|
+
Collect aggregated performance metrics and crash diagnostics from production
|
|
9
|
+
devices using MetricKit. The framework delivers daily metric payloads (CPU,
|
|
10
|
+
memory, launch time, hang rate, animation hitches, network usage) and
|
|
11
|
+
immediate diagnostic payloads (crashes, hangs, disk-write exceptions) with
|
|
12
|
+
full call-stack trees for triage.
|
|
13
|
+
|
|
14
|
+
## Contents
|
|
15
|
+
|
|
16
|
+
- [Subscriber Setup](#subscriber-setup)
|
|
17
|
+
- [Receiving Metric Payloads](#receiving-metric-payloads)
|
|
18
|
+
- [Receiving Diagnostic Payloads](#receiving-diagnostic-payloads)
|
|
19
|
+
- [Key Metrics](#key-metrics)
|
|
20
|
+
- [Call Stack Trees](#call-stack-trees)
|
|
21
|
+
- [Custom Signpost Metrics](#custom-signpost-metrics)
|
|
22
|
+
- [Exporting and Uploading Payloads](#exporting-and-uploading-payloads)
|
|
23
|
+
- [Extended Launch Measurement](#extended-launch-measurement)
|
|
24
|
+
- [Xcode Organizer Integration](#xcode-organizer-integration)
|
|
25
|
+
- [Common Mistakes](#common-mistakes)
|
|
26
|
+
- [Review Checklist](#review-checklist)
|
|
27
|
+
- [References](#references)
|
|
28
|
+
|
|
29
|
+
## Subscriber Setup
|
|
30
|
+
|
|
31
|
+
Register a subscriber as early as possible — ideally in
|
|
32
|
+
`application(_:didFinishLaunchingWithOptions:)` or `App.init`. MetricKit
|
|
33
|
+
starts accumulating reports after the first access to `MXMetricManager.shared`.
|
|
34
|
+
|
|
35
|
+
```swift
|
|
36
|
+
import MetricKit
|
|
37
|
+
|
|
38
|
+
final class MetricsSubscriber: NSObject, MXMetricManagerSubscriber {
|
|
39
|
+
static let shared = MetricsSubscriber()
|
|
40
|
+
|
|
41
|
+
func subscribe() {
|
|
42
|
+
MXMetricManager.shared.add(self)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func unsubscribe() {
|
|
46
|
+
MXMetricManager.shared.remove(self)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
func didReceive(_ payloads: [MXMetricPayload]) {
|
|
50
|
+
// Handle daily metrics
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func didReceive(_ payloads: [MXDiagnosticPayload]) {
|
|
54
|
+
// Handle diagnostics (crashes, hangs, disk writes)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### UIKit Registration
|
|
60
|
+
|
|
61
|
+
```swift
|
|
62
|
+
func application(
|
|
63
|
+
_ application: UIApplication,
|
|
64
|
+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
65
|
+
) -> Bool {
|
|
66
|
+
MetricsSubscriber.shared.subscribe()
|
|
67
|
+
return true
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### SwiftUI Registration
|
|
72
|
+
|
|
73
|
+
```swift
|
|
74
|
+
@main
|
|
75
|
+
struct MyApp: App {
|
|
76
|
+
init() {
|
|
77
|
+
MetricsSubscriber.shared.subscribe()
|
|
78
|
+
}
|
|
79
|
+
var body: some Scene {
|
|
80
|
+
WindowGroup { ContentView() }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Receiving Metric Payloads
|
|
86
|
+
|
|
87
|
+
`MXMetricPayload` arrives approximately once per 24 hours containing
|
|
88
|
+
aggregated metrics. The array may contain multiple payloads if prior
|
|
89
|
+
deliveries were missed.
|
|
90
|
+
|
|
91
|
+
```swift
|
|
92
|
+
func didReceive(_ payloads: [MXMetricPayload]) {
|
|
93
|
+
for payload in payloads {
|
|
94
|
+
let begin = payload.timeStampBegin
|
|
95
|
+
let end = payload.timeStampEnd
|
|
96
|
+
let version = payload.latestApplicationVersion
|
|
97
|
+
|
|
98
|
+
// Persist raw JSON before processing
|
|
99
|
+
let jsonData = payload.jsonRepresentation()
|
|
100
|
+
persistPayload(jsonData, from: begin, to: end)
|
|
101
|
+
|
|
102
|
+
processMetrics(payload)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Availability**: `MXMetricPayload` — iOS 13.0+, macOS 10.15+, visionOS 1.0+
|
|
108
|
+
|
|
109
|
+
## Receiving Diagnostic Payloads
|
|
110
|
+
|
|
111
|
+
`MXDiagnosticPayload` delivers crash, hang, CPU exception, disk-write, and
|
|
112
|
+
app-launch diagnostics. On iOS 15+ and macOS 12+, diagnostics arrive
|
|
113
|
+
immediately rather than bundled with the daily report.
|
|
114
|
+
|
|
115
|
+
```swift
|
|
116
|
+
func didReceive(_ payloads: [MXDiagnosticPayload]) {
|
|
117
|
+
for payload in payloads {
|
|
118
|
+
let jsonData = payload.jsonRepresentation()
|
|
119
|
+
persistPayload(jsonData)
|
|
120
|
+
|
|
121
|
+
if let crashes = payload.crashDiagnostics {
|
|
122
|
+
for crash in crashes {
|
|
123
|
+
handleCrash(crash)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if let hangs = payload.hangDiagnostics {
|
|
127
|
+
for hang in hangs {
|
|
128
|
+
handleHang(hang)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if let diskWrites = payload.diskWriteExceptionDiagnostics {
|
|
132
|
+
for diskWrite in diskWrites {
|
|
133
|
+
handleDiskWrite(diskWrite)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if let cpuExceptions = payload.cpuExceptionDiagnostics {
|
|
137
|
+
for cpuException in cpuExceptions {
|
|
138
|
+
handleCPUException(cpuException)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if let launchDiags = payload.appLaunchDiagnostics {
|
|
142
|
+
for launchDiag in launchDiags {
|
|
143
|
+
handleSlowLaunch(launchDiag)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Availability**: `MXDiagnosticPayload` — iOS 14.0+, macOS 12.0+, visionOS 1.0+
|
|
151
|
+
|
|
152
|
+
## Key Metrics
|
|
153
|
+
|
|
154
|
+
### Launch Time — MXAppLaunchMetric
|
|
155
|
+
|
|
156
|
+
```swift
|
|
157
|
+
if let launch = payload.applicationLaunchMetrics {
|
|
158
|
+
let firstDraw = launch.histogrammedTimeToFirstDraw
|
|
159
|
+
let optimized = launch.histogrammedOptimizedTimeToFirstDraw
|
|
160
|
+
let resume = launch.histogrammedApplicationResumeTime
|
|
161
|
+
let extended = launch.histogrammedExtendedLaunch
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Run Time — MXAppRunTimeMetric
|
|
166
|
+
|
|
167
|
+
```swift
|
|
168
|
+
if let runTime = payload.applicationTimeMetrics {
|
|
169
|
+
let fg = runTime.cumulativeForegroundTime // Measurement<UnitDuration>
|
|
170
|
+
let bg = runTime.cumulativeBackgroundTime
|
|
171
|
+
let bgAudio = runTime.cumulativeBackgroundAudioTime
|
|
172
|
+
let bgLocation = runTime.cumulativeBackgroundLocationTime
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### CPU, Memory, and Responsiveness
|
|
177
|
+
|
|
178
|
+
```swift
|
|
179
|
+
if let cpu = payload.cpuMetrics {
|
|
180
|
+
let cpuTime = cpu.cumulativeCPUTime // Measurement<UnitDuration>
|
|
181
|
+
}
|
|
182
|
+
if let memory = payload.memoryMetrics {
|
|
183
|
+
let peakMemory = memory.peakMemoryUsage // Measurement<UnitInformationStorage>
|
|
184
|
+
}
|
|
185
|
+
if let responsiveness = payload.applicationResponsivenessMetrics {
|
|
186
|
+
let hangTime = responsiveness.histogrammedApplicationHangTime
|
|
187
|
+
}
|
|
188
|
+
if let animation = payload.animationMetrics {
|
|
189
|
+
let scrollHitchRate = animation.scrollHitchTimeRatio // Measurement<Unit>
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Network and Cellular
|
|
194
|
+
|
|
195
|
+
```swift
|
|
196
|
+
if let network = payload.networkTransferMetrics {
|
|
197
|
+
let wifiUp = network.cumulativeWifiUpload // Measurement<UnitInformationStorage>
|
|
198
|
+
let wifiDown = network.cumulativeWifiDownload
|
|
199
|
+
let cellUp = network.cumulativeCellularUpload
|
|
200
|
+
let cellDown = network.cumulativeCellularDownload
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### App Exit Metrics
|
|
205
|
+
|
|
206
|
+
```swift
|
|
207
|
+
if let exits = payload.applicationExitMetrics {
|
|
208
|
+
let fg = exits.foregroundExitData
|
|
209
|
+
let bg = exits.backgroundExitData
|
|
210
|
+
// Inspect normal, abnormal, watchdog, memory, etc.
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Call Stack Trees
|
|
215
|
+
|
|
216
|
+
`MXCallStackTree` is attached to each diagnostic (crash, hang, CPU exception,
|
|
217
|
+
disk write, app launch). Use `jsonRepresentation()` to extract and symbolicate.
|
|
218
|
+
|
|
219
|
+
```swift
|
|
220
|
+
func handleCrash(_ crash: MXCrashDiagnostic) {
|
|
221
|
+
let tree = crash.callStackTree
|
|
222
|
+
let treeJSON = tree.jsonRepresentation()
|
|
223
|
+
|
|
224
|
+
let exceptionType = crash.exceptionType
|
|
225
|
+
let signal = crash.signal
|
|
226
|
+
let reason = crash.terminationReason
|
|
227
|
+
|
|
228
|
+
uploadDiagnostic(
|
|
229
|
+
type: "crash",
|
|
230
|
+
exceptionType: exceptionType,
|
|
231
|
+
signal: signal,
|
|
232
|
+
reason: reason,
|
|
233
|
+
callStack: treeJSON
|
|
234
|
+
)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
func handleHang(_ hang: MXHangDiagnostic) {
|
|
238
|
+
let tree = hang.callStackTree
|
|
239
|
+
let duration = hang.hangDuration // Measurement<UnitDuration>
|
|
240
|
+
uploadDiagnostic(type: "hang", duration: duration, callStack: tree.jsonRepresentation())
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The JSON structure contains an array of call stack frames with binary name,
|
|
245
|
+
offset, and address. Symbolicate using `atos` or upload dSYMs to your
|
|
246
|
+
analytics service.
|
|
247
|
+
|
|
248
|
+
**Availability**: `MXCallStackTree` — iOS 14.0+, macOS 12.0+, visionOS 1.0+
|
|
249
|
+
|
|
250
|
+
## Custom Signpost Metrics
|
|
251
|
+
|
|
252
|
+
Use `mxSignpost` with a MetricKit log handle to capture custom performance
|
|
253
|
+
intervals. These appear in the daily `MXMetricPayload` under `signpostMetrics`.
|
|
254
|
+
|
|
255
|
+
### Creating a Log Handle
|
|
256
|
+
|
|
257
|
+
```swift
|
|
258
|
+
let metricLog = MXMetricManager.makeLogHandle(category: "Networking")
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Emitting Signposts
|
|
262
|
+
|
|
263
|
+
```swift
|
|
264
|
+
import os
|
|
265
|
+
|
|
266
|
+
func fetchData() async throws -> Data {
|
|
267
|
+
let signpostID = MXSignpostIntervalData.makeSignpostID(log: metricLog)
|
|
268
|
+
|
|
269
|
+
mxSignpost(.begin, log: metricLog, name: "DataFetch", signpostID: signpostID)
|
|
270
|
+
let data = try await URLSession.shared.data(from: url).0
|
|
271
|
+
mxSignpost(.end, log: metricLog, name: "DataFetch", signpostID: signpostID)
|
|
272
|
+
|
|
273
|
+
return data
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Reading Custom Metrics from Payload
|
|
278
|
+
|
|
279
|
+
```swift
|
|
280
|
+
if let signposts = payload.signpostMetrics {
|
|
281
|
+
for metric in signposts {
|
|
282
|
+
let name = metric.signpostName // "DataFetch"
|
|
283
|
+
let category = metric.signpostCategory // "Networking"
|
|
284
|
+
let count = metric.totalCount
|
|
285
|
+
if let intervalData = metric.signpostIntervalData {
|
|
286
|
+
let avgMemory = intervalData.averageMemory
|
|
287
|
+
let cumulativeCPUTime = intervalData.cumulativeCPUTime
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
> The system limits the number of custom signpost metrics per log to reduce
|
|
294
|
+
> on-device overhead. Reserve custom metrics for critical code paths.
|
|
295
|
+
|
|
296
|
+
## Exporting and Uploading Payloads
|
|
297
|
+
|
|
298
|
+
Both payload types conform to `NSSecureCoding` and provide
|
|
299
|
+
`jsonRepresentation()` for easy serialization.
|
|
300
|
+
|
|
301
|
+
```swift
|
|
302
|
+
func persistPayload(_ jsonData: Data, from: Date? = nil, to: Date? = nil) {
|
|
303
|
+
let fileName = "metrics_\(ISO8601DateFormatter().string(from: Date())).json"
|
|
304
|
+
let url = FileManager.default.temporaryDirectory.appending(path: fileName)
|
|
305
|
+
try? jsonData.write(to: url)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
func uploadPayloads(_ jsonData: Data) {
|
|
309
|
+
Task.detached(priority: .utility) {
|
|
310
|
+
var request = URLRequest(url: URL(string: "https://api.example.com/metrics")!)
|
|
311
|
+
request.httpMethod = "POST"
|
|
312
|
+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
313
|
+
request.httpBody = jsonData
|
|
314
|
+
_ = try? await URLSession.shared.data(for: request)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Retrieving Past Payloads
|
|
320
|
+
|
|
321
|
+
If the subscriber was not registered when payloads arrived, retrieve them
|
|
322
|
+
using `pastPayloads` and `pastDiagnosticPayloads`. These return reports
|
|
323
|
+
generated since the last allocation of the shared manager.
|
|
324
|
+
|
|
325
|
+
```swift
|
|
326
|
+
let pastMetrics = MXMetricManager.shared.pastPayloads
|
|
327
|
+
let pastDiags = MXMetricManager.shared.pastDiagnosticPayloads
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Extended Launch Measurement
|
|
331
|
+
|
|
332
|
+
Track post-first-draw setup work (loading databases, restoring state) as
|
|
333
|
+
part of the launch metric using extended launch measurement.
|
|
334
|
+
|
|
335
|
+
```swift
|
|
336
|
+
let taskID = MXLaunchTaskID("com.example.app.loadDatabase")
|
|
337
|
+
|
|
338
|
+
MXMetricManager.shared.extendLaunchMeasurement(forTaskID: taskID)
|
|
339
|
+
// Perform extended launch work...
|
|
340
|
+
await database.load()
|
|
341
|
+
MXMetricManager.shared.finishExtendedLaunchMeasurement(forTaskID: taskID)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Extended launch times appear under `histogrammedExtendedLaunch` in
|
|
345
|
+
`MXAppLaunchMetric`.
|
|
346
|
+
|
|
347
|
+
## Xcode Organizer Integration
|
|
348
|
+
|
|
349
|
+
Xcode Organizer shows the same MetricKit data aggregated across all users
|
|
350
|
+
who have opted in to share diagnostics. Use Organizer for trend analysis:
|
|
351
|
+
|
|
352
|
+
- **Metrics tab**: Battery, performance, and disk-write metrics over time
|
|
353
|
+
- **Regressions tab**: Automatic detection of metric regressions per version
|
|
354
|
+
- **Crashes tab**: Crash logs with symbolicated stack traces
|
|
355
|
+
|
|
356
|
+
MetricKit on-device collection complements Organizer by letting you route
|
|
357
|
+
raw data to your own backend for custom dashboards, alerting, and filtering
|
|
358
|
+
by user cohort.
|
|
359
|
+
|
|
360
|
+
## Common Mistakes
|
|
361
|
+
|
|
362
|
+
### DON'T: Subscribe to MXMetricManager too late
|
|
363
|
+
|
|
364
|
+
The system may deliver pending payloads shortly after launch. Subscribing
|
|
365
|
+
late (e.g., in a view controller) risks missing them entirely.
|
|
366
|
+
|
|
367
|
+
```swift
|
|
368
|
+
// WRONG — subscribing in a view controller
|
|
369
|
+
override func viewDidLoad() {
|
|
370
|
+
super.viewDidLoad()
|
|
371
|
+
MXMetricManager.shared.add(self)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// CORRECT — subscribe in application(_:didFinishLaunchingWithOptions:)
|
|
375
|
+
func application(
|
|
376
|
+
_ application: UIApplication,
|
|
377
|
+
didFinishLaunchingWithOptions opts: [UIApplication.LaunchOptionsKey: Any]?
|
|
378
|
+
) -> Bool {
|
|
379
|
+
MXMetricManager.shared.add(metricsSubscriber)
|
|
380
|
+
return true
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### DON'T: Ignore MXDiagnosticPayload
|
|
385
|
+
|
|
386
|
+
Only handling `MXMetricPayload` means you miss crash, hang, and disk-write
|
|
387
|
+
diagnostics — the most actionable data MetricKit provides.
|
|
388
|
+
|
|
389
|
+
```swift
|
|
390
|
+
// WRONG — only implementing metric callback
|
|
391
|
+
func didReceive(_ payloads: [MXMetricPayload]) { /* ... */ }
|
|
392
|
+
|
|
393
|
+
// CORRECT — implement both callbacks
|
|
394
|
+
func didReceive(_ payloads: [MXMetricPayload]) { /* ... */ }
|
|
395
|
+
func didReceive(_ payloads: [MXDiagnosticPayload]) { /* ... */ }
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### DON'T: Process payloads without persisting first
|
|
399
|
+
|
|
400
|
+
The system delivers each payload once. If your subscriber crashes during
|
|
401
|
+
processing, the data is lost permanently.
|
|
402
|
+
|
|
403
|
+
```swift
|
|
404
|
+
// WRONG — process inline, crash loses data
|
|
405
|
+
func didReceive(_ payloads: [MXDiagnosticPayload]) {
|
|
406
|
+
for p in payloads {
|
|
407
|
+
riskyProcessing(p) // If this crashes, payload is gone
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// CORRECT — persist raw JSON first, then process
|
|
412
|
+
func didReceive(_ payloads: [MXDiagnosticPayload]) {
|
|
413
|
+
for p in payloads {
|
|
414
|
+
let json = p.jsonRepresentation()
|
|
415
|
+
try? json.write(to: localCacheURL()) // Safe on disk
|
|
416
|
+
Task.detached { self.processAsync(json) }
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### DON'T: Do heavy work synchronously in didReceive
|
|
422
|
+
|
|
423
|
+
The callback runs on an arbitrary thread. Blocking it with heavy processing
|
|
424
|
+
or synchronous network calls delays delivery of subsequent payloads.
|
|
425
|
+
|
|
426
|
+
```swift
|
|
427
|
+
// WRONG — synchronous upload in callback
|
|
428
|
+
func didReceive(_ payloads: [MXMetricPayload]) {
|
|
429
|
+
for p in payloads {
|
|
430
|
+
let data = p.jsonRepresentation()
|
|
431
|
+
URLSession.shared.uploadTask(with: request, from: data).resume() // sync wait
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// CORRECT — persist and dispatch async
|
|
436
|
+
func didReceive(_ payloads: [MXMetricPayload]) {
|
|
437
|
+
for p in payloads {
|
|
438
|
+
let json = p.jsonRepresentation()
|
|
439
|
+
persistLocally(json)
|
|
440
|
+
Task.detached(priority: .utility) {
|
|
441
|
+
await self.uploadToBackend(json)
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### DON'T: Expect immediate data in development
|
|
448
|
+
|
|
449
|
+
MetricKit aggregates data over 24-hour windows. Payloads do not arrive
|
|
450
|
+
immediately after instrumenting. Use Xcode Organizer or simulated payloads
|
|
451
|
+
for faster iteration during development.
|
|
452
|
+
|
|
453
|
+
## Review Checklist
|
|
454
|
+
|
|
455
|
+
- [ ] `MXMetricManager.shared.add(subscriber)` called in `application(_:didFinishLaunchingWithOptions:)` or `App.init`
|
|
456
|
+
- [ ] Subscriber conforms to `MXMetricManagerSubscriber` and inherits `NSObject`
|
|
457
|
+
- [ ] Both `didReceive(_: [MXMetricPayload])` and `didReceive(_: [MXDiagnosticPayload])` implemented
|
|
458
|
+
- [ ] Raw `jsonRepresentation()` persisted to disk before processing
|
|
459
|
+
- [ ] Heavy processing dispatched asynchronously off the callback thread
|
|
460
|
+
- [ ] `MXCallStackTree` JSON uploaded with dSYMs for symbolication
|
|
461
|
+
- [ ] Custom signpost metrics limited to critical code paths
|
|
462
|
+
- [ ] `pastPayloads` and `pastDiagnosticPayloads` checked on launch for missed deliveries
|
|
463
|
+
- [ ] Extended launch tasks call both `extendLaunchMeasurement` and `finishExtendedLaunchMeasurement`
|
|
464
|
+
- [ ] Analytics backend accepts and stores MetricKit JSON format
|
|
465
|
+
- [ ] Xcode Organizer reviewed for regression trends alongside on-device data
|
|
466
|
+
|
|
467
|
+
## References
|
|
468
|
+
|
|
469
|
+
- [MetricKit framework](https://sosumi.ai/documentation/metrickit)
|
|
470
|
+
- [MXMetricManager](https://sosumi.ai/documentation/metrickit/mxmetricmanager)
|
|
471
|
+
- [MXMetricManagerSubscriber](https://sosumi.ai/documentation/metrickit/mxmetricmanagersubscriber)
|
|
472
|
+
- [MXMetricPayload](https://sosumi.ai/documentation/metrickit/mxmetricpayload)
|
|
473
|
+
- [MXDiagnosticPayload](https://sosumi.ai/documentation/metrickit/mxdiagnosticpayload)
|
|
474
|
+
- [MXCallStackTree](https://sosumi.ai/documentation/metrickit/mxcallstacktree)
|
|
475
|
+
- [MXSignpostMetric](https://sosumi.ai/documentation/metrickit/mxsignpostmetric)
|
|
476
|
+
- [MXAppLaunchMetric](https://sosumi.ai/documentation/metrickit/mxapplaunchmetric)
|
|
477
|
+
- [MXAppRunTimeMetric](https://sosumi.ai/documentation/metrickit/mxappruntimemetric)
|
|
478
|
+
- [MXCrashDiagnostic](https://sosumi.ai/documentation/metrickit/mxcrashdiagnostic)
|
|
479
|
+
- [Analyzing the performance of your shipping app](https://sosumi.ai/documentation/xcode/analyzing-the-performance-of-your-shipping-app)
|