@devo-bmad-custom/agent-orchestration 1.0.2 → 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 +33 -0
- package/package.json +1 -1
- package/src/.agents/skills/audit-website/README.md +20 -20
- package/src/.agents/skills/audit-website/SKILL.md +470 -470
- package/src/.agents/skills/audit-website/agents/openai.yaml +6 -6
- package/src/.agents/skills/audit-website/assets/icon-small.svg +41 -41
- package/src/.agents/skills/audit-website/references/OUTPUT-FORMAT.md +250 -250
- package/src/.agents/skills/clean-code-standards/SKILL.md +104 -104
- package/src/.agents/skills/excalidraw-dark-standard/SKILL.md +281 -281
- package/src/.agents/skills/frontend-responsive-design-standards/SKILL.md +434 -434
- package/src/.agents/skills/java-fundamentals/SKILL.md +116 -116
- package/src/.agents/skills/java-performance/SKILL.md +119 -119
- package/src/.agents/skills/next-best-practices/SKILL.md +153 -153
- package/src/.agents/skills/next-best-practices/async-patterns.md +87 -87
- package/src/.agents/skills/next-best-practices/bundling.md +180 -180
- package/src/.agents/skills/next-best-practices/data-patterns.md +297 -297
- package/src/.agents/skills/next-best-practices/debug-tricks.md +105 -105
- package/src/.agents/skills/next-best-practices/directives.md +73 -73
- package/src/.agents/skills/next-best-practices/error-handling.md +227 -227
- package/src/.agents/skills/next-best-practices/file-conventions.md +140 -140
- package/src/.agents/skills/next-best-practices/font.md +245 -245
- package/src/.agents/skills/next-best-practices/functions.md +108 -108
- package/src/.agents/skills/next-best-practices/hydration-error.md +91 -91
- package/src/.agents/skills/next-best-practices/image.md +173 -173
- package/src/.agents/skills/next-best-practices/metadata.md +301 -301
- package/src/.agents/skills/next-best-practices/parallel-routes.md +287 -287
- package/src/.agents/skills/next-best-practices/route-handlers.md +146 -146
- package/src/.agents/skills/next-best-practices/rsc-boundaries.md +159 -159
- package/src/.agents/skills/next-best-practices/runtime-selection.md +39 -39
- package/src/.agents/skills/next-best-practices/scripts.md +141 -141
- package/src/.agents/skills/next-best-practices/self-hosting.md +371 -371
- package/src/.agents/skills/next-best-practices/suspense-boundaries.md +67 -67
- package/src/.agents/skills/nextjs-app-router-patterns/SKILL.md +537 -537
- package/src/.agents/skills/postgresql-optimization/SKILL.md +404 -404
- package/src/.agents/skills/python-backend/SKILL.md +153 -153
- package/src/.agents/skills/python-fundamentals/SKILL.md +234 -234
- package/src/.agents/skills/python-performance/SKILL.md +404 -404
- package/src/.agents/skills/react-expert/SKILL.md +335 -335
- package/src/.agents/skills/redis-best-practices/SKILL.md +438 -438
- package/src/.agents/skills/security-best-practices/SKILL.md +288 -288
- package/src/.agents/skills/security-review/LICENSE +22 -22
- package/src/.agents/skills/security-review/SKILL.md +312 -312
- package/src/.agents/skills/security-review/infrastructure/docker.md +432 -432
- package/src/.agents/skills/security-review/languages/javascript.md +388 -388
- package/src/.agents/skills/security-review/languages/python.md +363 -363
- package/src/.agents/skills/security-review/references/api-security.md +519 -519
- package/src/.agents/skills/security-review/references/authentication.md +353 -353
- package/src/.agents/skills/security-review/references/authorization.md +372 -372
- package/src/.agents/skills/security-review/references/business-logic.md +443 -443
- package/src/.agents/skills/security-review/references/cryptography.md +329 -329
- package/src/.agents/skills/security-review/references/csrf.md +398 -398
- package/src/.agents/skills/security-review/references/data-protection.md +378 -378
- package/src/.agents/skills/security-review/references/deserialization.md +410 -410
- package/src/.agents/skills/security-review/references/error-handling.md +436 -436
- package/src/.agents/skills/security-review/references/file-security.md +457 -457
- package/src/.agents/skills/security-review/references/injection.md +259 -259
- package/src/.agents/skills/security-review/references/logging.md +433 -433
- package/src/.agents/skills/security-review/references/misconfiguration.md +435 -435
- package/src/.agents/skills/security-review/references/modern-threats.md +475 -475
- package/src/.agents/skills/security-review/references/ssrf.md +415 -415
- package/src/.agents/skills/security-review/references/supply-chain.md +405 -405
- package/src/.agents/skills/security-review/references/xss.md +336 -336
- package/src/.agents/skills/subagent-driven-development/SKILL.md +275 -275
- package/src/.agents/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -26
- package/src/.agents/skills/subagent-driven-development/implementer-prompt.md +113 -113
- package/src/.agents/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -61
- package/src/.agents/skills/systematic-debugging/CREATION-LOG.md +119 -119
- package/src/.agents/skills/systematic-debugging/SKILL.md +296 -296
- package/src/.agents/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/src/.agents/skills/systematic-debugging/condition-based-waiting.md +115 -115
- package/src/.agents/skills/systematic-debugging/defense-in-depth.md +122 -122
- package/src/.agents/skills/systematic-debugging/root-cause-tracing.md +169 -169
- package/src/.agents/skills/systematic-debugging/test-academic.md +14 -14
- package/src/.agents/skills/systematic-debugging/test-pressure-1.md +58 -58
- package/src/.agents/skills/systematic-debugging/test-pressure-2.md +68 -68
- package/src/.agents/skills/systematic-debugging/test-pressure-3.md +69 -69
- package/src/.agents/skills/typescript-best-practices/SKILL.md +373 -373
- package/src/.agents/skills/ui-ux-pro-custom/SKILL.md +348 -348
- package/src/.agents/skills/ui-ux-pro-custom/data/charts.csv +26 -26
- package/src/.agents/skills/ui-ux-pro-custom/data/colors.csv +97 -97
- package/src/.agents/skills/ui-ux-pro-custom/data/icons.csv +101 -101
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/SKILL.md +106 -106
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/accessibility.md +475 -475
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/animation.md +466 -466
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/composition-locals.md +231 -231
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/deprecated-patterns.md +323 -323
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/lists-scrolling.md +400 -400
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/modifiers.md +331 -331
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/navigation.md +416 -416
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/performance.md +446 -446
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/side-effects.md +516 -516
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/foundation-source.md +13327 -13327
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/material3-source.md +19097 -19097
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/navigation-source.md +2947 -2947
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/runtime-source.md +11316 -11316
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/ui-source.md +7896 -7896
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/state-management.md +377 -377
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/styles-experimental.md +470 -470
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/theming-material3.md +349 -349
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/view-composition.md +595 -595
- package/src/.agents/skills/ui-ux-pro-custom/data/landing.csv +31 -31
- package/src/.agents/skills/ui-ux-pro-custom/data/mobile-ui-layout.md +654 -654
- package/src/.agents/skills/ui-ux-pro-custom/data/products.csv +96 -96
- package/src/.agents/skills/ui-ux-pro-custom/data/react-performance.csv +45 -45
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/astro.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/flutter.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/html-tailwind.csv +56 -56
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/jetpack-compose.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nextjs.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nuxt-ui.csv +51 -51
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nuxtjs.csv +59 -59
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/react-native.csv +56 -56
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/react.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/shadcn.csv +61 -61
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/svelte.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/swiftui.csv +51 -51
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/vue.csv +50 -50
- package/src/.agents/skills/ui-ux-pro-custom/data/styles.csv +68 -68
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/alarmkit/SKILL.md +438 -438
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/alarmkit/references/alarmkit-patterns.md +584 -584
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-clips/SKILL.md +436 -436
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-intents/SKILL.md +489 -489
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-intents/references/appintents-advanced.md +1076 -1076
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/SKILL.md +340 -340
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/references/privacy-manifest.md +90 -90
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/references/review-checklists.md +106 -106
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/coreml-conversion.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/coreml-optimization.md +344 -344
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/foundation-models.md +508 -508
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/mlx-swift.md +285 -285
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/authentication/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/authentication/references/keychain-biometric.md +211 -211
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/background-processing/SKILL.md +499 -499
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/background-processing/references/background-task-patterns.md +390 -390
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/callkit-voip/SKILL.md +461 -461
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/callkit-voip/references/callkit-patterns.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/cloudkit-sync/SKILL.md +492 -492
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/cloudkit-sync/references/cloudkit-patterns.md +461 -461
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/codable-patterns/SKILL.md +467 -467
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/contacts-framework/SKILL.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/contacts-framework/references/contacts-patterns.md +409 -409
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-bluetooth/SKILL.md +491 -491
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-bluetooth/references/ble-patterns.md +435 -435
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-motion/SKILL.md +388 -388
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-motion/references/motion-patterns.md +405 -405
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-nfc/SKILL.md +495 -495
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-nfc/references/nfc-patterns.md +420 -420
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/coreml/SKILL.md +459 -459
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/coreml/references/coreml-swift-integration.md +765 -765
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/SKILL.md +422 -422
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/references/instruments-guide.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/references/lldb-patterns.md +298 -298
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/device-integrity/SKILL.md +477 -477
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/energykit/SKILL.md +460 -460
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/energykit/references/energykit-patterns.md +541 -541
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/eventkit-calendar/SKILL.md +483 -483
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/eventkit-calendar/references/eventkit-patterns.md +326 -326
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/healthkit/SKILL.md +498 -498
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/healthkit/references/healthkit-patterns.md +602 -602
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/homekit-matter/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/homekit-matter/references/matter-commissioning.md +455 -455
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-accessibility/SKILL.md +301 -301
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-accessibility/references/a11y-patterns.md +140 -140
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/SKILL.md +418 -418
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/references/formatstyle-locale.md +627 -627
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/references/string-catalogs.md +462 -462
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/SKILL.md +441 -441
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/background-websocket.md +862 -862
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/lightweight-clients.md +93 -93
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/network-framework.md +563 -563
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/urlsession-patterns.md +1116 -1116
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/app-review-guidelines.md +174 -174
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/cryptokit-advanced.md +296 -296
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/file-storage-patterns.md +354 -354
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/privacy-manifest.md +117 -117
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/live-activities/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/live-activities/references/live-activity-patterns.md +868 -868
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/SKILL.md +485 -485
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/references/corelocation-patterns.md +730 -730
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/references/mapkit-patterns.md +748 -748
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/metrickit-diagnostics/SKILL.md +479 -479
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/musickit-audio/SKILL.md +395 -395
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/musickit-audio/references/musickit-patterns.md +363 -363
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/natural-language/SKILL.md +412 -412
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/natural-language/references/translation-patterns.md +311 -311
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/passkit-wallet/SKILL.md +398 -398
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/passkit-wallet/references/wallet-passes.md +254 -254
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/SKILL.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/references/paperkit-integration.md +376 -376
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/references/pencilkit-patterns.md +302 -302
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/permissionkit/SKILL.md +446 -446
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/permissionkit/references/permissionkit-patterns.md +435 -435
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/av-playback.md +701 -701
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/camera-capture.md +774 -774
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/image-loading-caching.md +869 -869
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/photospicker-patterns.md +597 -597
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/references/notification-patterns.md +677 -677
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/references/rich-notifications.md +745 -745
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/realitykit-ar/SKILL.md +479 -479
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/realitykit-ar/references/realitykit-patterns.md +480 -480
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/SKILL.md +483 -483
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/references/shareplay-patterns.md +544 -544
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/speech-recognition/SKILL.md +485 -485
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/SKILL.md +478 -478
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/references/app-review-guidelines.md +58 -58
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/references/storekit-advanced.md +755 -755
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-charts/SKILL.md +487 -487
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-charts/references/charts-patterns.md +895 -895
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/SKILL.md +408 -408
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/approachable-concurrency.md +80 -80
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/swift-6-2-concurrency.md +233 -233
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/swiftui-concurrency.md +187 -187
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/synchronization-primitives.md +341 -341
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-language/SKILL.md +498 -498
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-language/references/swift-patterns-extended.md +505 -505
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-testing/SKILL.md +467 -467
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-testing/references/testing-patterns.md +504 -504
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/SKILL.md +334 -334
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/core-data-coexistence.md +504 -504
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/swiftdata-advanced.md +975 -975
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/swiftdata-queries.md +675 -675
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/SKILL.md +481 -481
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/references/animation-advanced.md +804 -804
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/references/core-animation-bridge.md +553 -553
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-gestures/SKILL.md +450 -450
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-gestures/references/gesture-patterns.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/SKILL.md +336 -336
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/form.md +97 -97
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/grids.md +69 -69
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/list.md +99 -99
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/scrollview.md +147 -147
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-liquid-glass/SKILL.md +325 -325
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-liquid-glass/references/liquid-glass.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/SKILL.md +262 -262
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/deeplinks.md +207 -207
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/navigationstack.md +177 -177
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/sheets.md +169 -169
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/tabview.md +178 -178
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/SKILL.md +381 -381
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/architecture-patterns.md +486 -486
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/deprecated-migration.md +1097 -1097
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/design-polish.md +780 -780
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/platform-and-sharing.md +696 -696
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/SKILL.md +491 -491
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +46 -46
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +29 -29
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/understanding-hangs-in-your-app.md +33 -33
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/understanding-improving-swiftui-performance.md +52 -52
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/SKILL.md +428 -428
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/references/hosting-migration.md +534 -534
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/references/representable-recipes.md +1133 -1133
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/tipkit/SKILL.md +494 -494
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/tipkit/references/tipkit-patterns.md +782 -782
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/SKILL.md +475 -475
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/vision-requests.md +736 -736
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/visionkit-scanner.md +738 -738
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/SKILL.md +410 -410
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/references/weatherkit-patterns.md +567 -567
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/SKILL.md +497 -497
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/references/widgetkit-advanced.md +871 -871
- package/src/.agents/skills/ui-ux-pro-custom/data/typography.csv +57 -57
- package/src/.agents/skills/ui-ux-pro-custom/data/ui-reasoning.csv +101 -101
- package/src/.agents/skills/ui-ux-pro-custom/data/ux-guidelines.csv +99 -99
- package/src/.agents/skills/ui-ux-pro-custom/data/web-interface.csv +31 -31
- package/src/.agents/skills/ui-ux-pro-custom/scripts/core.py +253 -253
- package/src/.agents/skills/ui-ux-pro-custom/scripts/design_system.py +1067 -1067
- package/src/.agents/skills/ui-ux-pro-custom/scripts/search.py +114 -114
- package/src/.agents/skills/ux-audit/SKILL.md +150 -150
- package/src/.agents/skills/websocket-engineer/SKILL.md +168 -168
- package/src/.agents/skills/websocket-engineer/references/alternatives.md +391 -391
- package/src/.agents/skills/websocket-engineer/references/patterns.md +400 -400
- package/src/.agents/skills/websocket-engineer/references/protocol.md +195 -195
- package/src/.agents/skills/websocket-engineer/references/scaling.md +333 -333
- package/src/.agents/skills/websocket-engineer/references/security.md +474 -474
- package/src/.agents/skills/writing-skills/SKILL.md +655 -655
- package/src/.agents/skills/writing-skills/anthropic-best-practices.md +1150 -1150
- package/src/.agents/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -189
- package/src/.agents/skills/writing-skills/graphviz-conventions.dot +171 -171
- package/src/.agents/skills/writing-skills/persuasion-principles.md +187 -187
- package/src/.agents/skills/writing-skills/render-graphs.js +168 -168
- package/src/.agents/skills/writing-skills/testing-skills-with-subagents.md +384 -384
- package/src/.claude/commands/master-orchestrator.md +15 -0
- package/src/_memory/config.yaml +11 -11
- package/src/_memory/master-orchestrator-sidecar/instructions.md +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/tech-writer/tech-writer.md +94 -94
- package/src/bmm/module-help.csv +31 -31
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +115 -115
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +107 -107
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +141 -141
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +144 -144
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +147 -147
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +161 -161
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +99 -99
- package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +57 -57
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +87 -87
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +156 -156
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +165 -165
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +140 -140
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +152 -152
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +345 -345
- package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +92 -92
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +164 -164
- package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +174 -174
- package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +184 -184
- package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +105 -105
- package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +360 -360
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +87 -87
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +165 -165
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +174 -174
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +141 -141
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +159 -159
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +387 -387
- package/src/bmm/workflows/1-analysis/research/workflow-domain-research.md +54 -54
- package/src/bmm/workflows/1-analysis/research/workflow-market-research.md +54 -54
- package/src/bmm/workflows/1-analysis/research/workflow-technical-research.md +54 -54
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +100 -100
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +160 -160
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +88 -88
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +99 -99
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +169 -169
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +156 -156
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +136 -136
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +176 -176
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +184 -184
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +174 -174
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +175 -175
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +189 -189
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +162 -162
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +79 -79
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +183 -183
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +149 -149
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +187 -187
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +192 -192
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +108 -108
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +166 -166
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +131 -131
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +150 -150
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +118 -118
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +155 -155
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +170 -170
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +158 -158
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +147 -147
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +182 -182
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +202 -202
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +148 -148
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +201 -201
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +179 -179
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +164 -164
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +65 -65
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +65 -65
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +63 -63
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +63 -63
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +106 -106
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +111 -111
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +115 -115
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +127 -127
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +167 -167
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +143 -143
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +118 -118
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +154 -154
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +136 -136
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +165 -165
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +135 -135
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +192 -192
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +101 -101
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +45 -45
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +185 -185
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +129 -129
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +130 -130
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +93 -93
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +196 -196
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +129 -129
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -54
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +82 -82
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +106 -106
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +138 -138
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +129 -129
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +166 -166
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +186 -186
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +163 -163
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +38 -38
- package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +49 -49
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +124 -124
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +122 -122
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +84 -84
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -58
- package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +43 -43
- package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +53 -53
- package/src/bmm/workflows/4-implementation/create-story/checklist.md +159 -159
- package/src/bmm/workflows/4-implementation/create-story/template.md +79 -79
- package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +20 -20
- package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +25 -25
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +158 -158
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +122 -122
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +93 -93
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +93 -93
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +87 -87
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +146 -146
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -50
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +152 -152
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +123 -123
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +201 -201
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -79
- package/src/bmm/workflows/document-project/workflow.yaml +22 -22
- package/src/bmm/workflows/generate-project-context/steps/step-01-discover.md +184 -184
- package/src/bmm/workflows/generate-project-context/steps/step-02-generate.md +322 -322
- package/src/bmm/workflows/generate-project-context/steps/step-03-complete.md +235 -235
- package/src/bmm/workflows/generate-project-context/workflow.md +49 -49
- package/src/bmm/workflows/qa/automate/workflow.yaml +233 -233
- package/src/bmm/workflows/qa-generate-e2e-tests/workflow.yaml +42 -42
- package/src/core/config.yaml +9 -9
- package/src/core/module-help.csv +10 -10
- package/src/core/scripts/generate-loop-report.py +72 -72
- package/src/core/tasks/editorial-review-prose.xml +101 -101
- package/src/core/tasks/editorial-review-structure.xml +207 -207
- package/src/core/tasks/help.md +86 -86
- package/src/core/tasks/index-docs.xml +64 -64
- package/src/core/tasks/review-adversarial-general.xml +66 -66
- package/src/core/tasks/review-adversarial-loop.xml +46 -46
- package/src/core/tasks/review-edge-case-hunter.xml +63 -63
- package/src/core/tasks/review-party-loop.xml +46 -46
- package/src/core/tasks/shard-doc.xml +107 -107
- package/src/core/tasks/workflow.xml +235 -235
- package/src/core/templates/review-loop-report.html +88 -88
- package/src/core/templates/review-loop-report.md +5 -5
- package/src/core/workflows/advanced-elicitation/workflow.xml +117 -117
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +212 -212
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -122
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -225
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -237
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -209
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -264
- package/src/core/workflows/brainstorming/steps/step-02e-deep-dive.md +68 -68
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +403 -403
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -303
- package/src/core/workflows/brainstorming/workflow.md +60 -60
- package/src/core/workflows/extract-trackers/workflow.md +45 -45
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +142 -142
- package/src/core/workflows/party-mode/workflow.md +194 -194
- package/src/docs/dev/tmux/actions_popup.py +291 -291
- package/src/docs/dev/tmux/tmux-setup.md +62 -1
|
@@ -1,377 +1,377 @@
|
|
|
1
|
-
# Jetpack Compose State Management Reference
|
|
2
|
-
|
|
3
|
-
## State Fundamentals
|
|
4
|
-
|
|
5
|
-
State in Compose is observable data that triggers recomposition when changed.
|
|
6
|
-
|
|
7
|
-
### Creating State
|
|
8
|
-
|
|
9
|
-
Use type-specific state holders for efficiency:
|
|
10
|
-
|
|
11
|
-
```kotlin
|
|
12
|
-
// General-purpose state (Any type)
|
|
13
|
-
val name = mutableStateOf("Alice")
|
|
14
|
-
|
|
15
|
-
// Primitive specializations (avoid boxing)
|
|
16
|
-
val count = mutableIntStateOf(0)
|
|
17
|
-
val progress = mutableFloatStateOf(0.5f)
|
|
18
|
-
val enabled = mutableStateOf(true) // Boolean has no specialization
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**Pitfall:** Using `mutableStateOf<Int>()` instead of `mutableIntStateOf()` causes unnecessary boxing on every read/write. Primitive specializations are located in `androidx.compose.runtime` (source: `State.kt`).
|
|
22
|
-
|
|
23
|
-
## remember vs rememberSaveable
|
|
24
|
-
|
|
25
|
-
Both associate state with a composition key, but differ in persistence scope.
|
|
26
|
-
|
|
27
|
-
### remember
|
|
28
|
-
- Lives for the composition's lifetime
|
|
29
|
-
- Lost on process death, configuration changes, back navigation
|
|
30
|
-
- Best for UI state: selection, expanded/collapsed, scroll position
|
|
31
|
-
|
|
32
|
-
```kotlin
|
|
33
|
-
@Composable
|
|
34
|
-
fun Counter() {
|
|
35
|
-
var count by remember { mutableIntStateOf(0) }
|
|
36
|
-
Button(onClick = { count++ }) {
|
|
37
|
-
Text("Count: $count")
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### rememberSaveable
|
|
43
|
-
- Survives process death and configuration changes
|
|
44
|
-
- Uses `Bundle`-compatible types by default (String, Int, Boolean, etc.)
|
|
45
|
-
- For custom types, provide a `Saver` or use `@Parcelize`
|
|
46
|
-
- Best for data that represents user input or navigation state
|
|
47
|
-
|
|
48
|
-
```kotlin
|
|
49
|
-
@Composable
|
|
50
|
-
fun SearchScreen() {
|
|
51
|
-
var query by rememberSaveable { mutableStateOf("") }
|
|
52
|
-
// survives configuration change
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Custom type requires explicit Saver
|
|
56
|
-
data class User(val id: Int, val name: String)
|
|
57
|
-
val userSaver = Saver<User, String>(
|
|
58
|
-
save = { "${it.id}:${it.name}" },
|
|
59
|
-
restore = { parts -> User(parts.split(":")[0].toInt(), parts.split(":")[1]) }
|
|
60
|
-
)
|
|
61
|
-
var user by rememberSaveable(stateSaver = userSaver) { mutableStateOf(User(1, "Alice")) }
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**Pitfall:** Assuming `rememberSaveable` works with all types. Custom classes need explicit `Saver` or `@Parcelize`. See `SaveableStateRegistry` in `androidx.compose.runtime.saveable`.
|
|
65
|
-
|
|
66
|
-
## State Hoisting
|
|
67
|
-
|
|
68
|
-
Move state up to a parent composable to enable reusability and testing.
|
|
69
|
-
|
|
70
|
-
### Stateful vs Stateless Pattern
|
|
71
|
-
|
|
72
|
-
```kotlin
|
|
73
|
-
// ❌ Stateful version (tightly coupled)
|
|
74
|
-
@Composable
|
|
75
|
-
fun Counter() {
|
|
76
|
-
var count by remember { mutableIntStateOf(0) }
|
|
77
|
-
Button(onClick = { count++ }) { Text(count.toString()) }
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// ✅ Stateless version (reusable, testable)
|
|
81
|
-
@Composable
|
|
82
|
-
fun Counter(
|
|
83
|
-
count: Int,
|
|
84
|
-
onCountChange: (Int) -> Unit
|
|
85
|
-
) {
|
|
86
|
-
Button(onClick = { onCountChange(count + 1) }) { Text(count.toString()) }
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ✅ Wrapper composable (provides state, uses stateless child)
|
|
90
|
-
@Composable
|
|
91
|
-
fun StatefulCounter() {
|
|
92
|
-
var count by remember { mutableIntStateOf(0) }
|
|
93
|
-
Counter(count = count, onCountChange = { count = it })
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**Rule:** Push state as high as needed, but no higher. If only one child needs state, keep it there. If multiple children or parents need it, hoist up.
|
|
98
|
-
|
|
99
|
-
## derivedStateOf
|
|
100
|
-
|
|
101
|
-
Computes a value from existing state, recomputing only when dependencies change.
|
|
102
|
-
|
|
103
|
-
```kotlin
|
|
104
|
-
// ❌ Wrong: recomputes on every recomposition
|
|
105
|
-
val isEven = count % 2 == 0
|
|
106
|
-
|
|
107
|
-
// ✅ Correct: recomputes only when count changes
|
|
108
|
-
val isEven = derivedStateOf { count % 2 == 0 }
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**When to use:**
|
|
112
|
-
- Expensive computations from state (e.g., filtering, sorting lists)
|
|
113
|
-
- Combining multiple state values
|
|
114
|
-
- Creating intermediate state for conditional logic
|
|
115
|
-
|
|
116
|
-
```kotlin
|
|
117
|
-
@Composable
|
|
118
|
-
fun UserList(users: List<User>, filterText: String) {
|
|
119
|
-
val filteredUsers = derivedStateOf {
|
|
120
|
-
users.filter { it.name.contains(filterText, ignoreCase = true) }
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
LazyColumn {
|
|
124
|
-
items(filteredUsers.value.size) { index ->
|
|
125
|
-
UserRow(filteredUsers.value[index])
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Pitfall:** Using `derivedStateOf` for cheap operations (String concatenation, simple conditions) adds overhead. Only use when the computation is non-trivial.
|
|
132
|
-
|
|
133
|
-
**Pitfall:** Accessing `.value` in a lambda passed to a child composable doesn't create a dependency. Use `snapshotFlow` for callbacks.
|
|
134
|
-
|
|
135
|
-
## snapshotFlow
|
|
136
|
-
|
|
137
|
-
Converts Compose state to Kotlin Flow for side effects and external APIs.
|
|
138
|
-
|
|
139
|
-
```kotlin
|
|
140
|
-
@Composable
|
|
141
|
-
fun SearchScreen(viewModel: SearchViewModel) {
|
|
142
|
-
var query by remember { mutableStateOf("") }
|
|
143
|
-
|
|
144
|
-
LaunchedEffect(Unit) {
|
|
145
|
-
snapshotFlow { query }
|
|
146
|
-
.debounce(500)
|
|
147
|
-
.distinctUntilChanged()
|
|
148
|
-
.collect { viewModel.search(it) }
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
**Key behaviors:**
|
|
154
|
-
- Emits initial value, then only on changes
|
|
155
|
-
- Works with derivedStateOf, collections, and nested state
|
|
156
|
-
- Runs in the composition's coroutine scope (launched via `LaunchedEffect`)
|
|
157
|
-
|
|
158
|
-
**Pitfall:** Accessing state directly in a `LaunchedEffect` doesn't track changes:
|
|
159
|
-
```kotlin
|
|
160
|
-
// ❌ Won't re-run when query changes
|
|
161
|
-
LaunchedEffect(Unit) {
|
|
162
|
-
viewModel.search(query) // Capture at launch time only
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// ✅ Re-runs when query changes
|
|
166
|
-
LaunchedEffect(query) {
|
|
167
|
-
viewModel.search(query)
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
## SnapshotStateList and SnapshotStateMap
|
|
172
|
-
|
|
173
|
-
Observable collections that trigger recomposition on structural changes.
|
|
174
|
-
|
|
175
|
-
```kotlin
|
|
176
|
-
val items = remember { mutableStateListOf<Item>() }
|
|
177
|
-
items.add(Item(1, "First"))
|
|
178
|
-
items[0] = Item(1, "Updated")
|
|
179
|
-
items.removeAt(0)
|
|
180
|
-
|
|
181
|
-
val map = remember { mutableStateMapOf<String, String>() }
|
|
182
|
-
map["key"] = "value" // Triggers recomposition
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
**Important:** Changes to list contents trigger recomposition, but changes to list *elements* (if they're mutable objects) do not.
|
|
186
|
-
|
|
187
|
-
```kotlin
|
|
188
|
-
data class Item(val id: Int, var name: String)
|
|
189
|
-
|
|
190
|
-
val items = remember { mutableStateListOf(Item(1, "First")) }
|
|
191
|
-
|
|
192
|
-
// ✅ Triggers recomposition (list structure changed)
|
|
193
|
-
items[0] = Item(1, "Updated")
|
|
194
|
-
|
|
195
|
-
// ❌ Does NOT trigger recomposition (object mutated in-place)
|
|
196
|
-
items[0].name = "Updated" // Mutated but list reference unchanged
|
|
197
|
-
|
|
198
|
-
// ✅ Correct: use copy() or mutableStateOf for nested state
|
|
199
|
-
items[0] = items[0].copy(name = "Updated")
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
See source: `androidx.compose.runtime.snapshots` for collection implementation.
|
|
203
|
-
|
|
204
|
-
## @Stable and @Immutable Annotations
|
|
205
|
-
|
|
206
|
-
These annotations help the compiler optimize recomposition (strong skipping mode).
|
|
207
|
-
|
|
208
|
-
### @Immutable
|
|
209
|
-
- All public fields are read-only primitives or other `@Immutable` types
|
|
210
|
-
- Instances never change after construction
|
|
211
|
-
- Compiler can skip recomposition if parameter unchanged
|
|
212
|
-
|
|
213
|
-
```kotlin
|
|
214
|
-
@Immutable
|
|
215
|
-
data class User(val id: Int, val name: String)
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### @Stable
|
|
219
|
-
- Implements structural equality (`equals`)
|
|
220
|
-
- Public properties are read-only or observable
|
|
221
|
-
- Changes are always notified to Compose (through state objects)
|
|
222
|
-
- Weaker guarantee than `@Immutable`, but suitable for types with observable state
|
|
223
|
-
|
|
224
|
-
```kotlin
|
|
225
|
-
@Stable
|
|
226
|
-
class UserViewModel {
|
|
227
|
-
val userName: State<String> = mutableStateOf("")
|
|
228
|
-
val isLoading: State<Boolean> = mutableStateOf(false)
|
|
229
|
-
|
|
230
|
-
// Observable state, not direct properties
|
|
231
|
-
}
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
**Pitfall:** Not annotating data classes used as parameters. Unannotated types are assumed unstable, triggering unnecessary recompositions.
|
|
235
|
-
|
|
236
|
-
```kotlin
|
|
237
|
-
// ❌ Treated as unstable, causes recomposition
|
|
238
|
-
class Config(val title: String, val color: Color)
|
|
239
|
-
|
|
240
|
-
// ✅ Properly annotated
|
|
241
|
-
@Immutable
|
|
242
|
-
class Config(val title: String, val color: Color)
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## Strong Skipping Mode
|
|
246
|
-
|
|
247
|
-
In Compose 1.6+, strong skipping mode applies stricter recomposition logic.
|
|
248
|
-
|
|
249
|
-
**What changed:**
|
|
250
|
-
- Composables skip recomposition if *all* parameters have unchanged identity and value
|
|
251
|
-
- Unannotated parameter types are treated as unstable (always recompose)
|
|
252
|
-
- `@Stable` and `@Immutable` annotations are now critical for performance
|
|
253
|
-
- Lambda parameters always cause recomposition (they're new instances)
|
|
254
|
-
|
|
255
|
-
**Enable strong skipping:**
|
|
256
|
-
```gradle
|
|
257
|
-
composeOptions {
|
|
258
|
-
kotlinCompilerExtensionVersion = "1.5.4+" // enables by default
|
|
259
|
-
}
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
**Practical impact:**
|
|
263
|
-
```kotlin
|
|
264
|
-
// ❌ These create new instances, always recompose child
|
|
265
|
-
@Composable
|
|
266
|
-
fun Parent() {
|
|
267
|
-
Child(title = buildString { append("Title") })
|
|
268
|
-
Child(config = Config(...)) // Unstable type
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// ✅ Cache instances
|
|
272
|
-
@Composable
|
|
273
|
-
fun Parent() {
|
|
274
|
-
val title = remember { "Title" }
|
|
275
|
-
val config = remember { Config(...) }
|
|
276
|
-
Child(title = title)
|
|
277
|
-
Child(config = config)
|
|
278
|
-
}
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
## State in ViewModels: StateFlow vs Compose State
|
|
282
|
-
|
|
283
|
-
### StateFlow (Recommended for ViewModel)
|
|
284
|
-
- Survives composition recomposition and configuration changes
|
|
285
|
-
- Works with lifecycle (`collectAsStateWithLifecycle`)
|
|
286
|
-
- Thread-safe, works across layers
|
|
287
|
-
|
|
288
|
-
```kotlin
|
|
289
|
-
class UserViewModel : ViewModel() {
|
|
290
|
-
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
|
291
|
-
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
@Composable
|
|
295
|
-
fun UserScreen(viewModel: UserViewModel) {
|
|
296
|
-
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
|
297
|
-
|
|
298
|
-
when (uiState) {
|
|
299
|
-
is UiState.Loading -> LoadingScreen()
|
|
300
|
-
is UiState.Success -> SuccessScreen((uiState as UiState.Success).data)
|
|
301
|
-
is UiState.Error -> ErrorScreen((uiState as UiState.Error).message)
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### Compose State (For UI-only state)
|
|
307
|
-
- Use for temporary, UI-local state
|
|
308
|
-
- Don't hoist to ViewModel
|
|
309
|
-
- Lost on back navigation
|
|
310
|
-
|
|
311
|
-
```kotlin
|
|
312
|
-
@Composable
|
|
313
|
-
fun SearchScreen(viewModel: SearchViewModel) {
|
|
314
|
-
var showFilters by remember { mutableStateOf(false) } // UI-only
|
|
315
|
-
val searchResults by viewModel.searchResults.collectAsStateWithLifecycle()
|
|
316
|
-
|
|
317
|
-
SearchUI(
|
|
318
|
-
results = searchResults,
|
|
319
|
-
showFilters = showFilters,
|
|
320
|
-
onToggleFilters = { showFilters = !showFilters }
|
|
321
|
-
)
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**Key difference:** `collectAsStateWithLifecycle()` (in `androidx.lifecycle:lifecycle-runtime-compose`) collects only when the composable is in a STARTED state, avoiding memory leaks.
|
|
326
|
-
|
|
327
|
-
## Common Anti-Patterns
|
|
328
|
-
|
|
329
|
-
### State in Local Variables
|
|
330
|
-
```kotlin
|
|
331
|
-
// ❌ Lost on recomposition
|
|
332
|
-
@Composable
|
|
333
|
-
fun Counter() {
|
|
334
|
-
var count = 0 // Reset to 0 on every recomposition
|
|
335
|
-
Button(onClick = { count++ }) { Text(count.toString()) }
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// ✅ Correct
|
|
339
|
-
@Composable
|
|
340
|
-
fun Counter() {
|
|
341
|
-
var count by remember { mutableIntStateOf(0) }
|
|
342
|
-
Button(onClick = { count++ }) { Text(count.toString()) }
|
|
343
|
-
}
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
### Reading State in Wrong Scope
|
|
347
|
-
```kotlin
|
|
348
|
-
// ❌ Reads happen inside lambda; changes don't re-launch effect
|
|
349
|
-
var count by remember { mutableIntStateOf(0) }
|
|
350
|
-
LaunchedEffect(Unit) {
|
|
351
|
-
while (true) {
|
|
352
|
-
delay(1000)
|
|
353
|
-
println(count) // Always prints 0
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// ✅ Pass state to LaunchedEffect key
|
|
358
|
-
LaunchedEffect(count) {
|
|
359
|
-
println("Count changed: $count")
|
|
360
|
-
}
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Creating State in Lambdas
|
|
364
|
-
```kotlin
|
|
365
|
-
// ❌ Creates new state on every call
|
|
366
|
-
val onButtonClick = {
|
|
367
|
-
val newValue = remember { mutableStateOf(0) } // ERROR: Can't call remember in lambda
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// ✅ Create state at composition level
|
|
371
|
-
var value by remember { mutableIntStateOf(0) }
|
|
372
|
-
val onButtonClick = { value++ }
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
**Source references:** `androidx.compose.runtime.State`, `androidx.compose.runtime.saveable`, `androidx.lifecycle.runtime.compose`
|
|
1
|
+
# Jetpack Compose State Management Reference
|
|
2
|
+
|
|
3
|
+
## State Fundamentals
|
|
4
|
+
|
|
5
|
+
State in Compose is observable data that triggers recomposition when changed.
|
|
6
|
+
|
|
7
|
+
### Creating State
|
|
8
|
+
|
|
9
|
+
Use type-specific state holders for efficiency:
|
|
10
|
+
|
|
11
|
+
```kotlin
|
|
12
|
+
// General-purpose state (Any type)
|
|
13
|
+
val name = mutableStateOf("Alice")
|
|
14
|
+
|
|
15
|
+
// Primitive specializations (avoid boxing)
|
|
16
|
+
val count = mutableIntStateOf(0)
|
|
17
|
+
val progress = mutableFloatStateOf(0.5f)
|
|
18
|
+
val enabled = mutableStateOf(true) // Boolean has no specialization
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Pitfall:** Using `mutableStateOf<Int>()` instead of `mutableIntStateOf()` causes unnecessary boxing on every read/write. Primitive specializations are located in `androidx.compose.runtime` (source: `State.kt`).
|
|
22
|
+
|
|
23
|
+
## remember vs rememberSaveable
|
|
24
|
+
|
|
25
|
+
Both associate state with a composition key, but differ in persistence scope.
|
|
26
|
+
|
|
27
|
+
### remember
|
|
28
|
+
- Lives for the composition's lifetime
|
|
29
|
+
- Lost on process death, configuration changes, back navigation
|
|
30
|
+
- Best for UI state: selection, expanded/collapsed, scroll position
|
|
31
|
+
|
|
32
|
+
```kotlin
|
|
33
|
+
@Composable
|
|
34
|
+
fun Counter() {
|
|
35
|
+
var count by remember { mutableIntStateOf(0) }
|
|
36
|
+
Button(onClick = { count++ }) {
|
|
37
|
+
Text("Count: $count")
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### rememberSaveable
|
|
43
|
+
- Survives process death and configuration changes
|
|
44
|
+
- Uses `Bundle`-compatible types by default (String, Int, Boolean, etc.)
|
|
45
|
+
- For custom types, provide a `Saver` or use `@Parcelize`
|
|
46
|
+
- Best for data that represents user input or navigation state
|
|
47
|
+
|
|
48
|
+
```kotlin
|
|
49
|
+
@Composable
|
|
50
|
+
fun SearchScreen() {
|
|
51
|
+
var query by rememberSaveable { mutableStateOf("") }
|
|
52
|
+
// survives configuration change
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Custom type requires explicit Saver
|
|
56
|
+
data class User(val id: Int, val name: String)
|
|
57
|
+
val userSaver = Saver<User, String>(
|
|
58
|
+
save = { "${it.id}:${it.name}" },
|
|
59
|
+
restore = { parts -> User(parts.split(":")[0].toInt(), parts.split(":")[1]) }
|
|
60
|
+
)
|
|
61
|
+
var user by rememberSaveable(stateSaver = userSaver) { mutableStateOf(User(1, "Alice")) }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Pitfall:** Assuming `rememberSaveable` works with all types. Custom classes need explicit `Saver` or `@Parcelize`. See `SaveableStateRegistry` in `androidx.compose.runtime.saveable`.
|
|
65
|
+
|
|
66
|
+
## State Hoisting
|
|
67
|
+
|
|
68
|
+
Move state up to a parent composable to enable reusability and testing.
|
|
69
|
+
|
|
70
|
+
### Stateful vs Stateless Pattern
|
|
71
|
+
|
|
72
|
+
```kotlin
|
|
73
|
+
// ❌ Stateful version (tightly coupled)
|
|
74
|
+
@Composable
|
|
75
|
+
fun Counter() {
|
|
76
|
+
var count by remember { mutableIntStateOf(0) }
|
|
77
|
+
Button(onClick = { count++ }) { Text(count.toString()) }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ✅ Stateless version (reusable, testable)
|
|
81
|
+
@Composable
|
|
82
|
+
fun Counter(
|
|
83
|
+
count: Int,
|
|
84
|
+
onCountChange: (Int) -> Unit
|
|
85
|
+
) {
|
|
86
|
+
Button(onClick = { onCountChange(count + 1) }) { Text(count.toString()) }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ✅ Wrapper composable (provides state, uses stateless child)
|
|
90
|
+
@Composable
|
|
91
|
+
fun StatefulCounter() {
|
|
92
|
+
var count by remember { mutableIntStateOf(0) }
|
|
93
|
+
Counter(count = count, onCountChange = { count = it })
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Rule:** Push state as high as needed, but no higher. If only one child needs state, keep it there. If multiple children or parents need it, hoist up.
|
|
98
|
+
|
|
99
|
+
## derivedStateOf
|
|
100
|
+
|
|
101
|
+
Computes a value from existing state, recomputing only when dependencies change.
|
|
102
|
+
|
|
103
|
+
```kotlin
|
|
104
|
+
// ❌ Wrong: recomputes on every recomposition
|
|
105
|
+
val isEven = count % 2 == 0
|
|
106
|
+
|
|
107
|
+
// ✅ Correct: recomputes only when count changes
|
|
108
|
+
val isEven = derivedStateOf { count % 2 == 0 }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**When to use:**
|
|
112
|
+
- Expensive computations from state (e.g., filtering, sorting lists)
|
|
113
|
+
- Combining multiple state values
|
|
114
|
+
- Creating intermediate state for conditional logic
|
|
115
|
+
|
|
116
|
+
```kotlin
|
|
117
|
+
@Composable
|
|
118
|
+
fun UserList(users: List<User>, filterText: String) {
|
|
119
|
+
val filteredUsers = derivedStateOf {
|
|
120
|
+
users.filter { it.name.contains(filterText, ignoreCase = true) }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
LazyColumn {
|
|
124
|
+
items(filteredUsers.value.size) { index ->
|
|
125
|
+
UserRow(filteredUsers.value[index])
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Pitfall:** Using `derivedStateOf` for cheap operations (String concatenation, simple conditions) adds overhead. Only use when the computation is non-trivial.
|
|
132
|
+
|
|
133
|
+
**Pitfall:** Accessing `.value` in a lambda passed to a child composable doesn't create a dependency. Use `snapshotFlow` for callbacks.
|
|
134
|
+
|
|
135
|
+
## snapshotFlow
|
|
136
|
+
|
|
137
|
+
Converts Compose state to Kotlin Flow for side effects and external APIs.
|
|
138
|
+
|
|
139
|
+
```kotlin
|
|
140
|
+
@Composable
|
|
141
|
+
fun SearchScreen(viewModel: SearchViewModel) {
|
|
142
|
+
var query by remember { mutableStateOf("") }
|
|
143
|
+
|
|
144
|
+
LaunchedEffect(Unit) {
|
|
145
|
+
snapshotFlow { query }
|
|
146
|
+
.debounce(500)
|
|
147
|
+
.distinctUntilChanged()
|
|
148
|
+
.collect { viewModel.search(it) }
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Key behaviors:**
|
|
154
|
+
- Emits initial value, then only on changes
|
|
155
|
+
- Works with derivedStateOf, collections, and nested state
|
|
156
|
+
- Runs in the composition's coroutine scope (launched via `LaunchedEffect`)
|
|
157
|
+
|
|
158
|
+
**Pitfall:** Accessing state directly in a `LaunchedEffect` doesn't track changes:
|
|
159
|
+
```kotlin
|
|
160
|
+
// ❌ Won't re-run when query changes
|
|
161
|
+
LaunchedEffect(Unit) {
|
|
162
|
+
viewModel.search(query) // Capture at launch time only
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ✅ Re-runs when query changes
|
|
166
|
+
LaunchedEffect(query) {
|
|
167
|
+
viewModel.search(query)
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## SnapshotStateList and SnapshotStateMap
|
|
172
|
+
|
|
173
|
+
Observable collections that trigger recomposition on structural changes.
|
|
174
|
+
|
|
175
|
+
```kotlin
|
|
176
|
+
val items = remember { mutableStateListOf<Item>() }
|
|
177
|
+
items.add(Item(1, "First"))
|
|
178
|
+
items[0] = Item(1, "Updated")
|
|
179
|
+
items.removeAt(0)
|
|
180
|
+
|
|
181
|
+
val map = remember { mutableStateMapOf<String, String>() }
|
|
182
|
+
map["key"] = "value" // Triggers recomposition
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Important:** Changes to list contents trigger recomposition, but changes to list *elements* (if they're mutable objects) do not.
|
|
186
|
+
|
|
187
|
+
```kotlin
|
|
188
|
+
data class Item(val id: Int, var name: String)
|
|
189
|
+
|
|
190
|
+
val items = remember { mutableStateListOf(Item(1, "First")) }
|
|
191
|
+
|
|
192
|
+
// ✅ Triggers recomposition (list structure changed)
|
|
193
|
+
items[0] = Item(1, "Updated")
|
|
194
|
+
|
|
195
|
+
// ❌ Does NOT trigger recomposition (object mutated in-place)
|
|
196
|
+
items[0].name = "Updated" // Mutated but list reference unchanged
|
|
197
|
+
|
|
198
|
+
// ✅ Correct: use copy() or mutableStateOf for nested state
|
|
199
|
+
items[0] = items[0].copy(name = "Updated")
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
See source: `androidx.compose.runtime.snapshots` for collection implementation.
|
|
203
|
+
|
|
204
|
+
## @Stable and @Immutable Annotations
|
|
205
|
+
|
|
206
|
+
These annotations help the compiler optimize recomposition (strong skipping mode).
|
|
207
|
+
|
|
208
|
+
### @Immutable
|
|
209
|
+
- All public fields are read-only primitives or other `@Immutable` types
|
|
210
|
+
- Instances never change after construction
|
|
211
|
+
- Compiler can skip recomposition if parameter unchanged
|
|
212
|
+
|
|
213
|
+
```kotlin
|
|
214
|
+
@Immutable
|
|
215
|
+
data class User(val id: Int, val name: String)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### @Stable
|
|
219
|
+
- Implements structural equality (`equals`)
|
|
220
|
+
- Public properties are read-only or observable
|
|
221
|
+
- Changes are always notified to Compose (through state objects)
|
|
222
|
+
- Weaker guarantee than `@Immutable`, but suitable for types with observable state
|
|
223
|
+
|
|
224
|
+
```kotlin
|
|
225
|
+
@Stable
|
|
226
|
+
class UserViewModel {
|
|
227
|
+
val userName: State<String> = mutableStateOf("")
|
|
228
|
+
val isLoading: State<Boolean> = mutableStateOf(false)
|
|
229
|
+
|
|
230
|
+
// Observable state, not direct properties
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Pitfall:** Not annotating data classes used as parameters. Unannotated types are assumed unstable, triggering unnecessary recompositions.
|
|
235
|
+
|
|
236
|
+
```kotlin
|
|
237
|
+
// ❌ Treated as unstable, causes recomposition
|
|
238
|
+
class Config(val title: String, val color: Color)
|
|
239
|
+
|
|
240
|
+
// ✅ Properly annotated
|
|
241
|
+
@Immutable
|
|
242
|
+
class Config(val title: String, val color: Color)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Strong Skipping Mode
|
|
246
|
+
|
|
247
|
+
In Compose 1.6+, strong skipping mode applies stricter recomposition logic.
|
|
248
|
+
|
|
249
|
+
**What changed:**
|
|
250
|
+
- Composables skip recomposition if *all* parameters have unchanged identity and value
|
|
251
|
+
- Unannotated parameter types are treated as unstable (always recompose)
|
|
252
|
+
- `@Stable` and `@Immutable` annotations are now critical for performance
|
|
253
|
+
- Lambda parameters always cause recomposition (they're new instances)
|
|
254
|
+
|
|
255
|
+
**Enable strong skipping:**
|
|
256
|
+
```gradle
|
|
257
|
+
composeOptions {
|
|
258
|
+
kotlinCompilerExtensionVersion = "1.5.4+" // enables by default
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Practical impact:**
|
|
263
|
+
```kotlin
|
|
264
|
+
// ❌ These create new instances, always recompose child
|
|
265
|
+
@Composable
|
|
266
|
+
fun Parent() {
|
|
267
|
+
Child(title = buildString { append("Title") })
|
|
268
|
+
Child(config = Config(...)) // Unstable type
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// ✅ Cache instances
|
|
272
|
+
@Composable
|
|
273
|
+
fun Parent() {
|
|
274
|
+
val title = remember { "Title" }
|
|
275
|
+
val config = remember { Config(...) }
|
|
276
|
+
Child(title = title)
|
|
277
|
+
Child(config = config)
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## State in ViewModels: StateFlow vs Compose State
|
|
282
|
+
|
|
283
|
+
### StateFlow (Recommended for ViewModel)
|
|
284
|
+
- Survives composition recomposition and configuration changes
|
|
285
|
+
- Works with lifecycle (`collectAsStateWithLifecycle`)
|
|
286
|
+
- Thread-safe, works across layers
|
|
287
|
+
|
|
288
|
+
```kotlin
|
|
289
|
+
class UserViewModel : ViewModel() {
|
|
290
|
+
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
|
291
|
+
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@Composable
|
|
295
|
+
fun UserScreen(viewModel: UserViewModel) {
|
|
296
|
+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
|
297
|
+
|
|
298
|
+
when (uiState) {
|
|
299
|
+
is UiState.Loading -> LoadingScreen()
|
|
300
|
+
is UiState.Success -> SuccessScreen((uiState as UiState.Success).data)
|
|
301
|
+
is UiState.Error -> ErrorScreen((uiState as UiState.Error).message)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Compose State (For UI-only state)
|
|
307
|
+
- Use for temporary, UI-local state
|
|
308
|
+
- Don't hoist to ViewModel
|
|
309
|
+
- Lost on back navigation
|
|
310
|
+
|
|
311
|
+
```kotlin
|
|
312
|
+
@Composable
|
|
313
|
+
fun SearchScreen(viewModel: SearchViewModel) {
|
|
314
|
+
var showFilters by remember { mutableStateOf(false) } // UI-only
|
|
315
|
+
val searchResults by viewModel.searchResults.collectAsStateWithLifecycle()
|
|
316
|
+
|
|
317
|
+
SearchUI(
|
|
318
|
+
results = searchResults,
|
|
319
|
+
showFilters = showFilters,
|
|
320
|
+
onToggleFilters = { showFilters = !showFilters }
|
|
321
|
+
)
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Key difference:** `collectAsStateWithLifecycle()` (in `androidx.lifecycle:lifecycle-runtime-compose`) collects only when the composable is in a STARTED state, avoiding memory leaks.
|
|
326
|
+
|
|
327
|
+
## Common Anti-Patterns
|
|
328
|
+
|
|
329
|
+
### State in Local Variables
|
|
330
|
+
```kotlin
|
|
331
|
+
// ❌ Lost on recomposition
|
|
332
|
+
@Composable
|
|
333
|
+
fun Counter() {
|
|
334
|
+
var count = 0 // Reset to 0 on every recomposition
|
|
335
|
+
Button(onClick = { count++ }) { Text(count.toString()) }
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// ✅ Correct
|
|
339
|
+
@Composable
|
|
340
|
+
fun Counter() {
|
|
341
|
+
var count by remember { mutableIntStateOf(0) }
|
|
342
|
+
Button(onClick = { count++ }) { Text(count.toString()) }
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Reading State in Wrong Scope
|
|
347
|
+
```kotlin
|
|
348
|
+
// ❌ Reads happen inside lambda; changes don't re-launch effect
|
|
349
|
+
var count by remember { mutableIntStateOf(0) }
|
|
350
|
+
LaunchedEffect(Unit) {
|
|
351
|
+
while (true) {
|
|
352
|
+
delay(1000)
|
|
353
|
+
println(count) // Always prints 0
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// ✅ Pass state to LaunchedEffect key
|
|
358
|
+
LaunchedEffect(count) {
|
|
359
|
+
println("Count changed: $count")
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Creating State in Lambdas
|
|
364
|
+
```kotlin
|
|
365
|
+
// ❌ Creates new state on every call
|
|
366
|
+
val onButtonClick = {
|
|
367
|
+
val newValue = remember { mutableStateOf(0) } // ERROR: Can't call remember in lambda
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// ✅ Create state at composition level
|
|
371
|
+
var value by remember { mutableIntStateOf(0) }
|
|
372
|
+
val onButtonClick = { value++ }
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
**Source references:** `androidx.compose.runtime.State`, `androidx.compose.runtime.saveable`, `androidx.lifecycle.runtime.compose`
|