@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,462 +1,462 @@
|
|
|
1
|
-
# String Catalogs (.xcstrings) -- Detailed Reference
|
|
2
|
-
|
|
3
|
-
## Contents
|
|
4
|
-
|
|
5
|
-
- [What is a String Catalog?](#what-is-a-string-catalog)
|
|
6
|
-
- [Creating a String Catalog](#creating-a-string-catalog)
|
|
7
|
-
- [Automatic String Extraction](#automatic-string-extraction)
|
|
8
|
-
- [Manual Key Management](#manual-key-management)
|
|
9
|
-
- [Handling Strings in Non-SwiftUI Code](#handling-strings-in-non-swiftui-code)
|
|
10
|
-
- [Bundle Access Patterns](#bundle-access-patterns)
|
|
11
|
-
- [Multi-Module / SPM Localization](#multi-module-spm-localization)
|
|
12
|
-
- [Pluralization in String Catalogs](#pluralization-in-string-catalogs)
|
|
13
|
-
- [Device Variations](#device-variations)
|
|
14
|
-
- [Exporting for Translators (XLIFF / xcloc)](#exporting-for-translators-xliff-xcloc)
|
|
15
|
-
- [String Catalog JSON Structure](#string-catalog-json-structure)
|
|
16
|
-
- [Testing Strategies](#testing-strategies)
|
|
17
|
-
- [Migration from .strings / .stringsdict](#migration-from-strings-stringsdict)
|
|
18
|
-
- [Best Practices](#best-practices)
|
|
19
|
-
|
|
20
|
-
## What is a String Catalog?
|
|
21
|
-
|
|
22
|
-
A String Catalog is a single `.xcstrings` file (JSON-based) that holds every localizable string in a target, along with all translations, plural forms, and device variations. It replaces the combination of `.strings` and `.stringsdict` files that previously required manual synchronization.
|
|
23
|
-
|
|
24
|
-
**Availability:** Xcode 15+, all Apple platforms.
|
|
25
|
-
|
|
26
|
-
## Creating a String Catalog
|
|
27
|
-
|
|
28
|
-
1. File > New > File > String Catalog
|
|
29
|
-
2. Name it `Localizable.xcstrings` (the default table name, matching the legacy `Localizable.strings`)
|
|
30
|
-
3. Place it in the target's source directory
|
|
31
|
-
4. Add target languages in Project > Info > Localizations
|
|
32
|
-
|
|
33
|
-
For a non-default table name (e.g., `Onboarding.xcstrings`), reference it explicitly:
|
|
34
|
-
|
|
35
|
-
```swift
|
|
36
|
-
String(localized: "welcome.title", table: "Onboarding")
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Automatic String Extraction
|
|
40
|
-
|
|
41
|
-
On every build, Xcode scans source files and extracts strings from known localizable initializers. Extraction is compiler-driven -- it recognizes these patterns:
|
|
42
|
-
|
|
43
|
-
### SwiftUI (LocalizedStringKey)
|
|
44
|
-
```swift
|
|
45
|
-
Text("Hello, world") // extracted
|
|
46
|
-
Label("Settings", systemImage: "gear") // extracted
|
|
47
|
-
Button("Save") { } // extracted
|
|
48
|
-
Toggle("Enable notifications", isOn: $on) // extracted
|
|
49
|
-
NavigationTitle("Home") // extracted
|
|
50
|
-
Section("Account") { } // extracted
|
|
51
|
-
|
|
52
|
-
// NOT extracted -- computed or variable strings
|
|
53
|
-
Text(viewModel.title) // not extracted (runtime value)
|
|
54
|
-
Text(verbatim: "v1.2.3") // not extracted (verbatim skips localization)
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Foundation (String(localized:))
|
|
58
|
-
```swift
|
|
59
|
-
String(localized: "No results found") // extracted
|
|
60
|
-
String(localized: "error.title",
|
|
61
|
-
defaultValue: "Something went wrong",
|
|
62
|
-
comment: "Generic error alert title") // extracted with default + comment
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### LocalizedStringResource
|
|
66
|
-
```swift
|
|
67
|
-
LocalizedStringResource("Order placed") // extracted
|
|
68
|
-
static var title: LocalizedStringResource = "Title" // extracted
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### What is NOT extracted
|
|
72
|
-
```swift
|
|
73
|
-
let x: String = "Not localized" // plain String assignment
|
|
74
|
-
print("debug info") // not user-facing
|
|
75
|
-
NSLocalizedString("legacy", comment: "") // NOT auto-extracted into .xcstrings
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
If automatic extraction misses a string, add it manually in the String Catalog editor.
|
|
79
|
-
|
|
80
|
-
## Manual Key Management
|
|
81
|
-
|
|
82
|
-
Open the `.xcstrings` file in Xcode to use the visual editor:
|
|
83
|
-
|
|
84
|
-
- **Add key**: Click + at the bottom of the key list
|
|
85
|
-
- **Remove key**: Select key, press Delete (marks as Stale, removed on next build if no code reference)
|
|
86
|
-
- **Edit comment**: Select key, edit the Comment field (provides translator context)
|
|
87
|
-
- **Mark state**: Right-click a translation to set Needs Review / Reviewed
|
|
88
|
-
- **Vary by plural**: Select a key, click Vary > Plural to add plural categories
|
|
89
|
-
- **Vary by device**: Select a key, click Vary > Device to add iPhone/iPad/Mac variants
|
|
90
|
-
|
|
91
|
-
### Key naming conventions
|
|
92
|
-
|
|
93
|
-
Use structured key names for large projects:
|
|
94
|
-
|
|
95
|
-
```text
|
|
96
|
-
onboarding.welcome.title -> "Welcome"
|
|
97
|
-
onboarding.welcome.subtitle -> "Get started in minutes"
|
|
98
|
-
settings.notifications.toggle -> "Enable Notifications"
|
|
99
|
-
error.network.title -> "Connection Error"
|
|
100
|
-
error.network.message -> "Check your internet and try again"
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
For SwiftUI, the literal text IS the key by default. Use `String(localized:defaultValue:)` when you want a structured key that differs from the English text.
|
|
104
|
-
|
|
105
|
-
## Handling Strings in Non-SwiftUI Code
|
|
106
|
-
|
|
107
|
-
### View models, services, and utilities
|
|
108
|
-
|
|
109
|
-
```swift
|
|
110
|
-
class OrderService {
|
|
111
|
-
func statusMessage(for order: Order) -> String {
|
|
112
|
-
switch order.status {
|
|
113
|
-
case .shipped:
|
|
114
|
-
return String(localized: "order.status.shipped",
|
|
115
|
-
defaultValue: "Your order has shipped!",
|
|
116
|
-
comment: "Order status when item is in transit")
|
|
117
|
-
case .delivered:
|
|
118
|
-
return String(localized: "order.status.delivered",
|
|
119
|
-
defaultValue: "Delivered on \(order.deliveryDate!, format: .dateTime.month().day())",
|
|
120
|
-
comment: "Order status with delivery date")
|
|
121
|
-
case .processing:
|
|
122
|
-
return String(localized: "order.status.processing",
|
|
123
|
-
defaultValue: "Processing your order...",
|
|
124
|
-
comment: "Order status while being prepared")
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Specifying table and bundle
|
|
131
|
-
|
|
132
|
-
```swift
|
|
133
|
-
// From a specific table
|
|
134
|
-
String(localized: "greeting",
|
|
135
|
-
table: "Onboarding",
|
|
136
|
-
comment: "First-launch greeting")
|
|
137
|
-
|
|
138
|
-
// From a specific bundle (framework or Swift package)
|
|
139
|
-
String(localized: "button.save",
|
|
140
|
-
table: "SharedUI",
|
|
141
|
-
bundle: .module,
|
|
142
|
-
comment: "Save button in shared component")
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Bundle Access Patterns
|
|
146
|
-
|
|
147
|
-
### Main app
|
|
148
|
-
```swift
|
|
149
|
-
// Uses Bundle.main by default -- no bundle argument needed
|
|
150
|
-
String(localized: "Hello")
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Swift Package (SPM)
|
|
154
|
-
```swift
|
|
155
|
-
// .module refers to the package's resource bundle
|
|
156
|
-
String(localized: "Hello", bundle: .module)
|
|
157
|
-
|
|
158
|
-
// In SwiftUI, Text uses the module's bundle automatically
|
|
159
|
-
// if the .xcstrings file is in the package's resources
|
|
160
|
-
Text("Hello") // looks up in the package's Localizable.xcstrings
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Framework
|
|
164
|
-
```swift
|
|
165
|
-
// Reference the framework's bundle
|
|
166
|
-
let frameworkBundle = Bundle(for: MyFrameworkClass.self)
|
|
167
|
-
String(localized: "Hello",
|
|
168
|
-
bundle: .init(frameworkBundle.bundleURL))
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
## Multi-Module / SPM Localization
|
|
172
|
-
|
|
173
|
-
Each Swift package target that contains user-facing strings needs its own String Catalog.
|
|
174
|
-
|
|
175
|
-
### Package.swift setup
|
|
176
|
-
```swift
|
|
177
|
-
.target(
|
|
178
|
-
name: "SharedUI",
|
|
179
|
-
dependencies: [],
|
|
180
|
-
resources: [
|
|
181
|
-
.process("Resources") // Localizable.xcstrings goes here
|
|
182
|
-
]
|
|
183
|
-
)
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Directory structure
|
|
187
|
-
```text
|
|
188
|
-
Sources/
|
|
189
|
-
SharedUI/
|
|
190
|
-
Resources/
|
|
191
|
-
Localizable.xcstrings <- String Catalog for this module
|
|
192
|
-
Views/
|
|
193
|
-
ButtonStyles.swift
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Accessing strings from the package
|
|
197
|
-
```swift
|
|
198
|
-
// Inside the package -- .module resolves automatically
|
|
199
|
-
public struct SaveButton: View {
|
|
200
|
-
public var body: some View {
|
|
201
|
-
Button(String(localized: "Save", bundle: .module)) { }
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
**Important:** SwiftUI `Text("Save")` inside an SPM target looks up in `.module` automatically only if the `.xcstrings` file is properly included in the target's resources. Verify by checking that Xcode shows the file under the target in the project navigator.
|
|
207
|
-
|
|
208
|
-
## Pluralization in String Catalogs
|
|
209
|
-
|
|
210
|
-
### Setup
|
|
211
|
-
|
|
212
|
-
1. Write code with integer interpolation:
|
|
213
|
-
```swift
|
|
214
|
-
Text("\(itemCount) items in your cart")
|
|
215
|
-
```
|
|
216
|
-
2. Build the project -- Xcode adds the key to the String Catalog
|
|
217
|
-
3. Open the String Catalog, select the key
|
|
218
|
-
4. Click "Vary by Plural" in the inspector
|
|
219
|
-
5. Fill in plural forms for each language
|
|
220
|
-
|
|
221
|
-
### English plural forms
|
|
222
|
-
```text
|
|
223
|
-
one: "%lld item in your cart"
|
|
224
|
-
other: "%lld items in your cart"
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Arabic plural forms (all six categories)
|
|
228
|
-
```text
|
|
229
|
-
zero: "لا توجد عناصر في سلتك"
|
|
230
|
-
one: "عنصر واحد في سلتك"
|
|
231
|
-
two: "عنصران في سلتك"
|
|
232
|
-
few: "%lld عناصر في سلتك" (3-10)
|
|
233
|
-
many: "%lld عنصرًا في سلتك" (11-99)
|
|
234
|
-
other: "%lld عنصر في سلتك" (100+)
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### Multiple plural variables
|
|
238
|
-
|
|
239
|
-
When a string has two integer interpolations, the String Catalog shows a matrix of plural combinations:
|
|
240
|
-
|
|
241
|
-
```swift
|
|
242
|
-
Text("\(photoCount) photos in \(albumCount) albums")
|
|
243
|
-
// English needs: one/one, one/other, other/one, other/other
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
## Device Variations
|
|
247
|
-
|
|
248
|
-
Enable "Vary by Device" for a key to provide different text on iPhone, iPad, Apple Watch, Mac, Apple TV, and Apple Vision Pro.
|
|
249
|
-
|
|
250
|
-
```swift
|
|
251
|
-
// Code is the same everywhere:
|
|
252
|
-
Text("Tap to continue")
|
|
253
|
-
|
|
254
|
-
// String Catalog provides:
|
|
255
|
-
// iPhone: "Tap to continue"
|
|
256
|
-
// iPad: "Tap or click to continue"
|
|
257
|
-
// Mac: "Click to continue"
|
|
258
|
-
// Vision: "Look and tap to continue"
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## Exporting for Translators (XLIFF / xcloc)
|
|
262
|
-
|
|
263
|
-
### Export
|
|
264
|
-
|
|
265
|
-
1. Product > Export Localizations... (or `xcodebuild -exportLocalizations`)
|
|
266
|
-
2. Select target languages
|
|
267
|
-
3. Xcode creates `.xcloc` bundles (one per language)
|
|
268
|
-
4. Send `.xcloc` files to translators (they contain XLIFF 1.2 inside)
|
|
269
|
-
|
|
270
|
-
### Command-line export
|
|
271
|
-
```bash
|
|
272
|
-
xcodebuild -exportLocalizations \
|
|
273
|
-
-project MyApp.xcodeproj \
|
|
274
|
-
-localizationPath ./Localizations \
|
|
275
|
-
-exportLanguage de -exportLanguage ja -exportLanguage ar
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Import
|
|
279
|
-
|
|
280
|
-
1. Product > Import Localizations...
|
|
281
|
-
2. Select the completed `.xcloc` file
|
|
282
|
-
3. Xcode merges translations into the String Catalog
|
|
283
|
-
4. Review changes in the diff viewer
|
|
284
|
-
|
|
285
|
-
### Command-line import
|
|
286
|
-
```bash
|
|
287
|
-
xcodebuild -importLocalizations \
|
|
288
|
-
-project MyApp.xcodeproj \
|
|
289
|
-
-localizationPath ./Localizations/de.xcloc
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
## String Catalog JSON Structure
|
|
293
|
-
|
|
294
|
-
The `.xcstrings` file is JSON. Understanding the structure enables programmatic manipulation (CI validation, batch updates, translation memory integration).
|
|
295
|
-
|
|
296
|
-
```json
|
|
297
|
-
{
|
|
298
|
-
"sourceLanguage": "en",
|
|
299
|
-
"version": "1.0",
|
|
300
|
-
"strings": {
|
|
301
|
-
"Welcome, %@!": {
|
|
302
|
-
"comment": "Greeting shown on home screen with user name",
|
|
303
|
-
"localizations": {
|
|
304
|
-
"en": {
|
|
305
|
-
"stringUnit": {
|
|
306
|
-
"state": "translated",
|
|
307
|
-
"value": "Welcome, %@!"
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
"de": {
|
|
311
|
-
"stringUnit": {
|
|
312
|
-
"state": "translated",
|
|
313
|
-
"value": "Willkommen, %@!"
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
},
|
|
318
|
-
"%lld items": {
|
|
319
|
-
"localizations": {
|
|
320
|
-
"en": {
|
|
321
|
-
"variations": {
|
|
322
|
-
"plural": {
|
|
323
|
-
"one": {
|
|
324
|
-
"stringUnit": {
|
|
325
|
-
"state": "translated",
|
|
326
|
-
"value": "%lld item"
|
|
327
|
-
}
|
|
328
|
-
},
|
|
329
|
-
"other": {
|
|
330
|
-
"stringUnit": {
|
|
331
|
-
"state": "translated",
|
|
332
|
-
"value": "%lld items"
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Translation states
|
|
345
|
-
- `"new"` -- Xcode extracted the key but no translation exists
|
|
346
|
-
- `"translated"` -- Translation provided
|
|
347
|
-
- `"needs_review"` -- Marked for review (source string changed or manual flag)
|
|
348
|
-
- `"stale"` -- Key no longer found in code (removed on next clean build)
|
|
349
|
-
|
|
350
|
-
## Testing Strategies
|
|
351
|
-
|
|
352
|
-
### Scheme language override
|
|
353
|
-
|
|
354
|
-
Edit Scheme > Run > Options > App Language. Choose any added language to launch the app in that locale without changing the device/simulator system language.
|
|
355
|
-
|
|
356
|
-
### Pseudolocalization options
|
|
357
|
-
|
|
358
|
-
Xcode provides built-in pseudolocalization modes (Edit Scheme > Run > Options > App Language):
|
|
359
|
-
|
|
360
|
-
| Option | Effect | Catches |
|
|
361
|
-
|--------|--------|---------|
|
|
362
|
-
| Accented Pseudolanguage | Adds accents: "Hello" -> "[Hellо]" | Hardcoded strings (unlocalized text is obvious) |
|
|
363
|
-
| Right-to-Left Pseudolanguage | Forces RTL layout | Layout mirroring bugs |
|
|
364
|
-
| Double-Length Pseudolanguage | Doubles all strings | Truncation and overflow |
|
|
365
|
-
| Bounded String Pseudolanguage | Wraps strings in brackets | Missing localizations |
|
|
366
|
-
|
|
367
|
-
### UI tests with locale override
|
|
368
|
-
|
|
369
|
-
```swift
|
|
370
|
-
func testGermanLayout() {
|
|
371
|
-
let app = XCUIApplication()
|
|
372
|
-
app.launchArguments += ["-AppleLanguages", "(de)"]
|
|
373
|
-
app.launchArguments += ["-AppleLocale", "de_DE"]
|
|
374
|
-
app.launch()
|
|
375
|
-
|
|
376
|
-
// Verify no truncation on key screens
|
|
377
|
-
let saveButton = app.buttons["Speichern"]
|
|
378
|
-
XCTAssertTrue(saveButton.exists)
|
|
379
|
-
XCTAssertTrue(saveButton.isHittable)
|
|
380
|
-
}
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### Snapshot testing per locale
|
|
384
|
-
|
|
385
|
-
Use a snapshot testing library to capture screenshots in multiple locales and compare them for layout regressions:
|
|
386
|
-
|
|
387
|
-
```swift
|
|
388
|
-
let locales = ["en_US", "de_DE", "ar_SA", "ja_JP"]
|
|
389
|
-
for locale in locales {
|
|
390
|
-
app.launchArguments = ["-AppleLanguages", "(\(locale.prefix(2)))"]
|
|
391
|
-
app.launch()
|
|
392
|
-
// Capture and compare snapshot
|
|
393
|
-
}
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### Translation coverage validation
|
|
397
|
-
|
|
398
|
-
Check that all keys are translated before release:
|
|
399
|
-
|
|
400
|
-
```bash
|
|
401
|
-
# Parse the .xcstrings JSON and check for "new" or empty states
|
|
402
|
-
python3 -c "
|
|
403
|
-
import json, sys
|
|
404
|
-
with open('Localizable.xcstrings') as f:
|
|
405
|
-
data = json.load(f)
|
|
406
|
-
missing = []
|
|
407
|
-
for key, info in data['strings'].items():
|
|
408
|
-
for lang, loc in info.get('localizations', {}).items():
|
|
409
|
-
unit = loc.get('stringUnit', {})
|
|
410
|
-
if unit.get('state') in ('new', None) or not unit.get('value'):
|
|
411
|
-
missing.append(f'{lang}: {key}')
|
|
412
|
-
if missing:
|
|
413
|
-
print('Missing translations:')
|
|
414
|
-
for m in missing: print(f' {m}')
|
|
415
|
-
sys.exit(1)
|
|
416
|
-
print('All translations complete.')
|
|
417
|
-
"
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
## Migration from .strings / .stringsdict
|
|
421
|
-
|
|
422
|
-
### Automatic migration
|
|
423
|
-
|
|
424
|
-
1. Select the `.strings` file in the project navigator
|
|
425
|
-
2. Right-click > Migrate to String Catalog...
|
|
426
|
-
3. Xcode creates a `.xcstrings` file with all existing keys and translations
|
|
427
|
-
4. Verify in the String Catalog editor
|
|
428
|
-
5. Remove the old `.strings` / `.stringsdict` files from the target
|
|
429
|
-
|
|
430
|
-
### Manual migration
|
|
431
|
-
|
|
432
|
-
If automatic migration fails (complex bundle setups, CocoaPods):
|
|
433
|
-
|
|
434
|
-
1. Create a new `Localizable.xcstrings`
|
|
435
|
-
2. Build to extract keys from code
|
|
436
|
-
3. Copy translations from old `.strings` files into the String Catalog editor
|
|
437
|
-
4. Copy plural rules from `.stringsdict` into plural variants
|
|
438
|
-
5. Remove old files
|
|
439
|
-
|
|
440
|
-
### Migration checklist
|
|
441
|
-
|
|
442
|
-
- [ ] All `.strings` keys present in the new String Catalog
|
|
443
|
-
- [ ] All `.stringsdict` plural rules converted to String Catalog plural variants
|
|
444
|
-
- [ ] Bundle references updated (if custom bundle was used)
|
|
445
|
-
- [ ] Build succeeds with no missing-localization warnings
|
|
446
|
-
- [ ] Test every language the app supports
|
|
447
|
-
- [ ] Remove old `.strings` and `.stringsdict` files from the target
|
|
448
|
-
- [ ] Commit the `.xcstrings` file (it is JSON, diffs well in version control)
|
|
449
|
-
|
|
450
|
-
### Coexistence
|
|
451
|
-
|
|
452
|
-
String Catalogs and `.strings` files can coexist in the same target during migration. Xcode resolves keys from the String Catalog first, then falls back to `.strings`. Remove legacy files after verifying the migration.
|
|
453
|
-
|
|
454
|
-
## Best Practices
|
|
455
|
-
|
|
456
|
-
1. **One String Catalog per target** -- keep `Localizable.xcstrings` as the single source of truth for each target.
|
|
457
|
-
2. **Use comments** -- provide context for every ambiguous key. Translators cannot see your UI.
|
|
458
|
-
3. **Review extraction on every build** -- new keys appear with state "new". Translate them promptly.
|
|
459
|
-
4. **Version control the .xcstrings file** -- it is JSON and diffs clearly. Review translation changes in PRs.
|
|
460
|
-
5. **Automate coverage checks** -- integrate translation-coverage validation in CI to catch missing translations before release.
|
|
461
|
-
6. **Export regularly** -- send updated `.xcloc` bundles to translators after each sprint or feature merge.
|
|
462
|
-
7. **Test with pseudolocalizations in CI** -- run UI tests with double-length and RTL pseudo-languages to catch layout issues early.
|
|
1
|
+
# String Catalogs (.xcstrings) -- Detailed Reference
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- [What is a String Catalog?](#what-is-a-string-catalog)
|
|
6
|
+
- [Creating a String Catalog](#creating-a-string-catalog)
|
|
7
|
+
- [Automatic String Extraction](#automatic-string-extraction)
|
|
8
|
+
- [Manual Key Management](#manual-key-management)
|
|
9
|
+
- [Handling Strings in Non-SwiftUI Code](#handling-strings-in-non-swiftui-code)
|
|
10
|
+
- [Bundle Access Patterns](#bundle-access-patterns)
|
|
11
|
+
- [Multi-Module / SPM Localization](#multi-module-spm-localization)
|
|
12
|
+
- [Pluralization in String Catalogs](#pluralization-in-string-catalogs)
|
|
13
|
+
- [Device Variations](#device-variations)
|
|
14
|
+
- [Exporting for Translators (XLIFF / xcloc)](#exporting-for-translators-xliff-xcloc)
|
|
15
|
+
- [String Catalog JSON Structure](#string-catalog-json-structure)
|
|
16
|
+
- [Testing Strategies](#testing-strategies)
|
|
17
|
+
- [Migration from .strings / .stringsdict](#migration-from-strings-stringsdict)
|
|
18
|
+
- [Best Practices](#best-practices)
|
|
19
|
+
|
|
20
|
+
## What is a String Catalog?
|
|
21
|
+
|
|
22
|
+
A String Catalog is a single `.xcstrings` file (JSON-based) that holds every localizable string in a target, along with all translations, plural forms, and device variations. It replaces the combination of `.strings` and `.stringsdict` files that previously required manual synchronization.
|
|
23
|
+
|
|
24
|
+
**Availability:** Xcode 15+, all Apple platforms.
|
|
25
|
+
|
|
26
|
+
## Creating a String Catalog
|
|
27
|
+
|
|
28
|
+
1. File > New > File > String Catalog
|
|
29
|
+
2. Name it `Localizable.xcstrings` (the default table name, matching the legacy `Localizable.strings`)
|
|
30
|
+
3. Place it in the target's source directory
|
|
31
|
+
4. Add target languages in Project > Info > Localizations
|
|
32
|
+
|
|
33
|
+
For a non-default table name (e.g., `Onboarding.xcstrings`), reference it explicitly:
|
|
34
|
+
|
|
35
|
+
```swift
|
|
36
|
+
String(localized: "welcome.title", table: "Onboarding")
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Automatic String Extraction
|
|
40
|
+
|
|
41
|
+
On every build, Xcode scans source files and extracts strings from known localizable initializers. Extraction is compiler-driven -- it recognizes these patterns:
|
|
42
|
+
|
|
43
|
+
### SwiftUI (LocalizedStringKey)
|
|
44
|
+
```swift
|
|
45
|
+
Text("Hello, world") // extracted
|
|
46
|
+
Label("Settings", systemImage: "gear") // extracted
|
|
47
|
+
Button("Save") { } // extracted
|
|
48
|
+
Toggle("Enable notifications", isOn: $on) // extracted
|
|
49
|
+
NavigationTitle("Home") // extracted
|
|
50
|
+
Section("Account") { } // extracted
|
|
51
|
+
|
|
52
|
+
// NOT extracted -- computed or variable strings
|
|
53
|
+
Text(viewModel.title) // not extracted (runtime value)
|
|
54
|
+
Text(verbatim: "v1.2.3") // not extracted (verbatim skips localization)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Foundation (String(localized:))
|
|
58
|
+
```swift
|
|
59
|
+
String(localized: "No results found") // extracted
|
|
60
|
+
String(localized: "error.title",
|
|
61
|
+
defaultValue: "Something went wrong",
|
|
62
|
+
comment: "Generic error alert title") // extracted with default + comment
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### LocalizedStringResource
|
|
66
|
+
```swift
|
|
67
|
+
LocalizedStringResource("Order placed") // extracted
|
|
68
|
+
static var title: LocalizedStringResource = "Title" // extracted
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### What is NOT extracted
|
|
72
|
+
```swift
|
|
73
|
+
let x: String = "Not localized" // plain String assignment
|
|
74
|
+
print("debug info") // not user-facing
|
|
75
|
+
NSLocalizedString("legacy", comment: "") // NOT auto-extracted into .xcstrings
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If automatic extraction misses a string, add it manually in the String Catalog editor.
|
|
79
|
+
|
|
80
|
+
## Manual Key Management
|
|
81
|
+
|
|
82
|
+
Open the `.xcstrings` file in Xcode to use the visual editor:
|
|
83
|
+
|
|
84
|
+
- **Add key**: Click + at the bottom of the key list
|
|
85
|
+
- **Remove key**: Select key, press Delete (marks as Stale, removed on next build if no code reference)
|
|
86
|
+
- **Edit comment**: Select key, edit the Comment field (provides translator context)
|
|
87
|
+
- **Mark state**: Right-click a translation to set Needs Review / Reviewed
|
|
88
|
+
- **Vary by plural**: Select a key, click Vary > Plural to add plural categories
|
|
89
|
+
- **Vary by device**: Select a key, click Vary > Device to add iPhone/iPad/Mac variants
|
|
90
|
+
|
|
91
|
+
### Key naming conventions
|
|
92
|
+
|
|
93
|
+
Use structured key names for large projects:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
onboarding.welcome.title -> "Welcome"
|
|
97
|
+
onboarding.welcome.subtitle -> "Get started in minutes"
|
|
98
|
+
settings.notifications.toggle -> "Enable Notifications"
|
|
99
|
+
error.network.title -> "Connection Error"
|
|
100
|
+
error.network.message -> "Check your internet and try again"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
For SwiftUI, the literal text IS the key by default. Use `String(localized:defaultValue:)` when you want a structured key that differs from the English text.
|
|
104
|
+
|
|
105
|
+
## Handling Strings in Non-SwiftUI Code
|
|
106
|
+
|
|
107
|
+
### View models, services, and utilities
|
|
108
|
+
|
|
109
|
+
```swift
|
|
110
|
+
class OrderService {
|
|
111
|
+
func statusMessage(for order: Order) -> String {
|
|
112
|
+
switch order.status {
|
|
113
|
+
case .shipped:
|
|
114
|
+
return String(localized: "order.status.shipped",
|
|
115
|
+
defaultValue: "Your order has shipped!",
|
|
116
|
+
comment: "Order status when item is in transit")
|
|
117
|
+
case .delivered:
|
|
118
|
+
return String(localized: "order.status.delivered",
|
|
119
|
+
defaultValue: "Delivered on \(order.deliveryDate!, format: .dateTime.month().day())",
|
|
120
|
+
comment: "Order status with delivery date")
|
|
121
|
+
case .processing:
|
|
122
|
+
return String(localized: "order.status.processing",
|
|
123
|
+
defaultValue: "Processing your order...",
|
|
124
|
+
comment: "Order status while being prepared")
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Specifying table and bundle
|
|
131
|
+
|
|
132
|
+
```swift
|
|
133
|
+
// From a specific table
|
|
134
|
+
String(localized: "greeting",
|
|
135
|
+
table: "Onboarding",
|
|
136
|
+
comment: "First-launch greeting")
|
|
137
|
+
|
|
138
|
+
// From a specific bundle (framework or Swift package)
|
|
139
|
+
String(localized: "button.save",
|
|
140
|
+
table: "SharedUI",
|
|
141
|
+
bundle: .module,
|
|
142
|
+
comment: "Save button in shared component")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Bundle Access Patterns
|
|
146
|
+
|
|
147
|
+
### Main app
|
|
148
|
+
```swift
|
|
149
|
+
// Uses Bundle.main by default -- no bundle argument needed
|
|
150
|
+
String(localized: "Hello")
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Swift Package (SPM)
|
|
154
|
+
```swift
|
|
155
|
+
// .module refers to the package's resource bundle
|
|
156
|
+
String(localized: "Hello", bundle: .module)
|
|
157
|
+
|
|
158
|
+
// In SwiftUI, Text uses the module's bundle automatically
|
|
159
|
+
// if the .xcstrings file is in the package's resources
|
|
160
|
+
Text("Hello") // looks up in the package's Localizable.xcstrings
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Framework
|
|
164
|
+
```swift
|
|
165
|
+
// Reference the framework's bundle
|
|
166
|
+
let frameworkBundle = Bundle(for: MyFrameworkClass.self)
|
|
167
|
+
String(localized: "Hello",
|
|
168
|
+
bundle: .init(frameworkBundle.bundleURL))
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Multi-Module / SPM Localization
|
|
172
|
+
|
|
173
|
+
Each Swift package target that contains user-facing strings needs its own String Catalog.
|
|
174
|
+
|
|
175
|
+
### Package.swift setup
|
|
176
|
+
```swift
|
|
177
|
+
.target(
|
|
178
|
+
name: "SharedUI",
|
|
179
|
+
dependencies: [],
|
|
180
|
+
resources: [
|
|
181
|
+
.process("Resources") // Localizable.xcstrings goes here
|
|
182
|
+
]
|
|
183
|
+
)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Directory structure
|
|
187
|
+
```text
|
|
188
|
+
Sources/
|
|
189
|
+
SharedUI/
|
|
190
|
+
Resources/
|
|
191
|
+
Localizable.xcstrings <- String Catalog for this module
|
|
192
|
+
Views/
|
|
193
|
+
ButtonStyles.swift
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Accessing strings from the package
|
|
197
|
+
```swift
|
|
198
|
+
// Inside the package -- .module resolves automatically
|
|
199
|
+
public struct SaveButton: View {
|
|
200
|
+
public var body: some View {
|
|
201
|
+
Button(String(localized: "Save", bundle: .module)) { }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Important:** SwiftUI `Text("Save")` inside an SPM target looks up in `.module` automatically only if the `.xcstrings` file is properly included in the target's resources. Verify by checking that Xcode shows the file under the target in the project navigator.
|
|
207
|
+
|
|
208
|
+
## Pluralization in String Catalogs
|
|
209
|
+
|
|
210
|
+
### Setup
|
|
211
|
+
|
|
212
|
+
1. Write code with integer interpolation:
|
|
213
|
+
```swift
|
|
214
|
+
Text("\(itemCount) items in your cart")
|
|
215
|
+
```
|
|
216
|
+
2. Build the project -- Xcode adds the key to the String Catalog
|
|
217
|
+
3. Open the String Catalog, select the key
|
|
218
|
+
4. Click "Vary by Plural" in the inspector
|
|
219
|
+
5. Fill in plural forms for each language
|
|
220
|
+
|
|
221
|
+
### English plural forms
|
|
222
|
+
```text
|
|
223
|
+
one: "%lld item in your cart"
|
|
224
|
+
other: "%lld items in your cart"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Arabic plural forms (all six categories)
|
|
228
|
+
```text
|
|
229
|
+
zero: "لا توجد عناصر في سلتك"
|
|
230
|
+
one: "عنصر واحد في سلتك"
|
|
231
|
+
two: "عنصران في سلتك"
|
|
232
|
+
few: "%lld عناصر في سلتك" (3-10)
|
|
233
|
+
many: "%lld عنصرًا في سلتك" (11-99)
|
|
234
|
+
other: "%lld عنصر في سلتك" (100+)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Multiple plural variables
|
|
238
|
+
|
|
239
|
+
When a string has two integer interpolations, the String Catalog shows a matrix of plural combinations:
|
|
240
|
+
|
|
241
|
+
```swift
|
|
242
|
+
Text("\(photoCount) photos in \(albumCount) albums")
|
|
243
|
+
// English needs: one/one, one/other, other/one, other/other
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Device Variations
|
|
247
|
+
|
|
248
|
+
Enable "Vary by Device" for a key to provide different text on iPhone, iPad, Apple Watch, Mac, Apple TV, and Apple Vision Pro.
|
|
249
|
+
|
|
250
|
+
```swift
|
|
251
|
+
// Code is the same everywhere:
|
|
252
|
+
Text("Tap to continue")
|
|
253
|
+
|
|
254
|
+
// String Catalog provides:
|
|
255
|
+
// iPhone: "Tap to continue"
|
|
256
|
+
// iPad: "Tap or click to continue"
|
|
257
|
+
// Mac: "Click to continue"
|
|
258
|
+
// Vision: "Look and tap to continue"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Exporting for Translators (XLIFF / xcloc)
|
|
262
|
+
|
|
263
|
+
### Export
|
|
264
|
+
|
|
265
|
+
1. Product > Export Localizations... (or `xcodebuild -exportLocalizations`)
|
|
266
|
+
2. Select target languages
|
|
267
|
+
3. Xcode creates `.xcloc` bundles (one per language)
|
|
268
|
+
4. Send `.xcloc` files to translators (they contain XLIFF 1.2 inside)
|
|
269
|
+
|
|
270
|
+
### Command-line export
|
|
271
|
+
```bash
|
|
272
|
+
xcodebuild -exportLocalizations \
|
|
273
|
+
-project MyApp.xcodeproj \
|
|
274
|
+
-localizationPath ./Localizations \
|
|
275
|
+
-exportLanguage de -exportLanguage ja -exportLanguage ar
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Import
|
|
279
|
+
|
|
280
|
+
1. Product > Import Localizations...
|
|
281
|
+
2. Select the completed `.xcloc` file
|
|
282
|
+
3. Xcode merges translations into the String Catalog
|
|
283
|
+
4. Review changes in the diff viewer
|
|
284
|
+
|
|
285
|
+
### Command-line import
|
|
286
|
+
```bash
|
|
287
|
+
xcodebuild -importLocalizations \
|
|
288
|
+
-project MyApp.xcodeproj \
|
|
289
|
+
-localizationPath ./Localizations/de.xcloc
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## String Catalog JSON Structure
|
|
293
|
+
|
|
294
|
+
The `.xcstrings` file is JSON. Understanding the structure enables programmatic manipulation (CI validation, batch updates, translation memory integration).
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
{
|
|
298
|
+
"sourceLanguage": "en",
|
|
299
|
+
"version": "1.0",
|
|
300
|
+
"strings": {
|
|
301
|
+
"Welcome, %@!": {
|
|
302
|
+
"comment": "Greeting shown on home screen with user name",
|
|
303
|
+
"localizations": {
|
|
304
|
+
"en": {
|
|
305
|
+
"stringUnit": {
|
|
306
|
+
"state": "translated",
|
|
307
|
+
"value": "Welcome, %@!"
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
"de": {
|
|
311
|
+
"stringUnit": {
|
|
312
|
+
"state": "translated",
|
|
313
|
+
"value": "Willkommen, %@!"
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
"%lld items": {
|
|
319
|
+
"localizations": {
|
|
320
|
+
"en": {
|
|
321
|
+
"variations": {
|
|
322
|
+
"plural": {
|
|
323
|
+
"one": {
|
|
324
|
+
"stringUnit": {
|
|
325
|
+
"state": "translated",
|
|
326
|
+
"value": "%lld item"
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
"other": {
|
|
330
|
+
"stringUnit": {
|
|
331
|
+
"state": "translated",
|
|
332
|
+
"value": "%lld items"
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Translation states
|
|
345
|
+
- `"new"` -- Xcode extracted the key but no translation exists
|
|
346
|
+
- `"translated"` -- Translation provided
|
|
347
|
+
- `"needs_review"` -- Marked for review (source string changed or manual flag)
|
|
348
|
+
- `"stale"` -- Key no longer found in code (removed on next clean build)
|
|
349
|
+
|
|
350
|
+
## Testing Strategies
|
|
351
|
+
|
|
352
|
+
### Scheme language override
|
|
353
|
+
|
|
354
|
+
Edit Scheme > Run > Options > App Language. Choose any added language to launch the app in that locale without changing the device/simulator system language.
|
|
355
|
+
|
|
356
|
+
### Pseudolocalization options
|
|
357
|
+
|
|
358
|
+
Xcode provides built-in pseudolocalization modes (Edit Scheme > Run > Options > App Language):
|
|
359
|
+
|
|
360
|
+
| Option | Effect | Catches |
|
|
361
|
+
|--------|--------|---------|
|
|
362
|
+
| Accented Pseudolanguage | Adds accents: "Hello" -> "[Hellо]" | Hardcoded strings (unlocalized text is obvious) |
|
|
363
|
+
| Right-to-Left Pseudolanguage | Forces RTL layout | Layout mirroring bugs |
|
|
364
|
+
| Double-Length Pseudolanguage | Doubles all strings | Truncation and overflow |
|
|
365
|
+
| Bounded String Pseudolanguage | Wraps strings in brackets | Missing localizations |
|
|
366
|
+
|
|
367
|
+
### UI tests with locale override
|
|
368
|
+
|
|
369
|
+
```swift
|
|
370
|
+
func testGermanLayout() {
|
|
371
|
+
let app = XCUIApplication()
|
|
372
|
+
app.launchArguments += ["-AppleLanguages", "(de)"]
|
|
373
|
+
app.launchArguments += ["-AppleLocale", "de_DE"]
|
|
374
|
+
app.launch()
|
|
375
|
+
|
|
376
|
+
// Verify no truncation on key screens
|
|
377
|
+
let saveButton = app.buttons["Speichern"]
|
|
378
|
+
XCTAssertTrue(saveButton.exists)
|
|
379
|
+
XCTAssertTrue(saveButton.isHittable)
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Snapshot testing per locale
|
|
384
|
+
|
|
385
|
+
Use a snapshot testing library to capture screenshots in multiple locales and compare them for layout regressions:
|
|
386
|
+
|
|
387
|
+
```swift
|
|
388
|
+
let locales = ["en_US", "de_DE", "ar_SA", "ja_JP"]
|
|
389
|
+
for locale in locales {
|
|
390
|
+
app.launchArguments = ["-AppleLanguages", "(\(locale.prefix(2)))"]
|
|
391
|
+
app.launch()
|
|
392
|
+
// Capture and compare snapshot
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Translation coverage validation
|
|
397
|
+
|
|
398
|
+
Check that all keys are translated before release:
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
# Parse the .xcstrings JSON and check for "new" or empty states
|
|
402
|
+
python3 -c "
|
|
403
|
+
import json, sys
|
|
404
|
+
with open('Localizable.xcstrings') as f:
|
|
405
|
+
data = json.load(f)
|
|
406
|
+
missing = []
|
|
407
|
+
for key, info in data['strings'].items():
|
|
408
|
+
for lang, loc in info.get('localizations', {}).items():
|
|
409
|
+
unit = loc.get('stringUnit', {})
|
|
410
|
+
if unit.get('state') in ('new', None) or not unit.get('value'):
|
|
411
|
+
missing.append(f'{lang}: {key}')
|
|
412
|
+
if missing:
|
|
413
|
+
print('Missing translations:')
|
|
414
|
+
for m in missing: print(f' {m}')
|
|
415
|
+
sys.exit(1)
|
|
416
|
+
print('All translations complete.')
|
|
417
|
+
"
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Migration from .strings / .stringsdict
|
|
421
|
+
|
|
422
|
+
### Automatic migration
|
|
423
|
+
|
|
424
|
+
1. Select the `.strings` file in the project navigator
|
|
425
|
+
2. Right-click > Migrate to String Catalog...
|
|
426
|
+
3. Xcode creates a `.xcstrings` file with all existing keys and translations
|
|
427
|
+
4. Verify in the String Catalog editor
|
|
428
|
+
5. Remove the old `.strings` / `.stringsdict` files from the target
|
|
429
|
+
|
|
430
|
+
### Manual migration
|
|
431
|
+
|
|
432
|
+
If automatic migration fails (complex bundle setups, CocoaPods):
|
|
433
|
+
|
|
434
|
+
1. Create a new `Localizable.xcstrings`
|
|
435
|
+
2. Build to extract keys from code
|
|
436
|
+
3. Copy translations from old `.strings` files into the String Catalog editor
|
|
437
|
+
4. Copy plural rules from `.stringsdict` into plural variants
|
|
438
|
+
5. Remove old files
|
|
439
|
+
|
|
440
|
+
### Migration checklist
|
|
441
|
+
|
|
442
|
+
- [ ] All `.strings` keys present in the new String Catalog
|
|
443
|
+
- [ ] All `.stringsdict` plural rules converted to String Catalog plural variants
|
|
444
|
+
- [ ] Bundle references updated (if custom bundle was used)
|
|
445
|
+
- [ ] Build succeeds with no missing-localization warnings
|
|
446
|
+
- [ ] Test every language the app supports
|
|
447
|
+
- [ ] Remove old `.strings` and `.stringsdict` files from the target
|
|
448
|
+
- [ ] Commit the `.xcstrings` file (it is JSON, diffs well in version control)
|
|
449
|
+
|
|
450
|
+
### Coexistence
|
|
451
|
+
|
|
452
|
+
String Catalogs and `.strings` files can coexist in the same target during migration. Xcode resolves keys from the String Catalog first, then falls back to `.strings`. Remove legacy files after verifying the migration.
|
|
453
|
+
|
|
454
|
+
## Best Practices
|
|
455
|
+
|
|
456
|
+
1. **One String Catalog per target** -- keep `Localizable.xcstrings` as the single source of truth for each target.
|
|
457
|
+
2. **Use comments** -- provide context for every ambiguous key. Translators cannot see your UI.
|
|
458
|
+
3. **Review extraction on every build** -- new keys appear with state "new". Translate them promptly.
|
|
459
|
+
4. **Version control the .xcstrings file** -- it is JSON and diffs clearly. Review translation changes in PRs.
|
|
460
|
+
5. **Automate coverage checks** -- integrate translation-coverage validation in CI to catch missing translations before release.
|
|
461
|
+
6. **Export regularly** -- send updated `.xcloc` bundles to translators after each sprint or feature merge.
|
|
462
|
+
7. **Test with pseudolocalizations in CI** -- run UI tests with double-length and RTL pseudo-languages to catch layout issues early.
|