@devo-bmad-custom/agent-orchestration 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/bmad.js +36 -0
- package/lib/cli.js +137 -0
- package/lib/filter.js +73 -0
- package/lib/installer.js +787 -0
- package/package.json +30 -0
- package/src/.agents/skills/audit-website/README.md +20 -0
- package/src/.agents/skills/audit-website/SKILL.md +470 -0
- package/src/.agents/skills/audit-website/agents/openai.yaml +6 -0
- package/src/.agents/skills/audit-website/assets/icon-small.svg +41 -0
- package/src/.agents/skills/audit-website/references/OUTPUT-FORMAT.md +250 -0
- package/src/.agents/skills/clean-code-standards/SKILL.md +105 -0
- package/src/.agents/skills/excalidraw-dark-standard/SKILL.md +282 -0
- package/src/.agents/skills/excalidraw-diagram-generator/SKILL.md +613 -0
- package/src/.agents/skills/excalidraw-diagram-generator/references/element-types.md +497 -0
- package/src/.agents/skills/excalidraw-diagram-generator/references/excalidraw-schema.md +350 -0
- package/src/.agents/skills/excalidraw-diagram-generator/scripts/README.md +193 -0
- package/src/.agents/skills/excalidraw-diagram-generator/scripts/add-arrow.py +312 -0
- package/src/.agents/skills/excalidraw-diagram-generator/scripts/add-icon-to-diagram.py +404 -0
- package/src/.agents/skills/excalidraw-diagram-generator/scripts/split-excalidraw-library.py +183 -0
- package/src/.agents/skills/excalidraw-diagram-generator/templates/business-flow-swimlane-template.excalidraw +334 -0
- package/src/.agents/skills/excalidraw-diagram-generator/templates/class-diagram-template.excalidraw +558 -0
- package/src/.agents/skills/excalidraw-diagram-generator/templates/data-flow-diagram-template.excalidraw +279 -0
- package/src/.agents/skills/excalidraw-diagram-generator/templates/er-diagram-template.excalidraw +662 -0
- package/src/.agents/skills/excalidraw-diagram-generator/templates/flowchart-template.excalidraw +179 -0
- package/src/.agents/skills/excalidraw-diagram-generator/templates/mindmap-template.excalidraw +244 -0
- package/src/.agents/skills/excalidraw-diagram-generator/templates/relationship-template.excalidraw +145 -0
- package/src/.agents/skills/excalidraw-diagram-generator/templates/sequence-diagram-template.excalidraw +509 -0
- package/src/.agents/skills/frontend-responsive-design-standards/SKILL.md +434 -0
- package/src/.agents/skills/java-fundamentals/SKILL.md +116 -0
- package/src/.agents/skills/java-performance/SKILL.md +119 -0
- package/src/.agents/skills/next-best-practices/SKILL.md +153 -0
- package/src/.agents/skills/next-best-practices/async-patterns.md +87 -0
- package/src/.agents/skills/next-best-practices/bundling.md +180 -0
- package/src/.agents/skills/next-best-practices/data-patterns.md +297 -0
- package/src/.agents/skills/next-best-practices/debug-tricks.md +105 -0
- package/src/.agents/skills/next-best-practices/directives.md +73 -0
- package/src/.agents/skills/next-best-practices/error-handling.md +227 -0
- package/src/.agents/skills/next-best-practices/file-conventions.md +140 -0
- package/src/.agents/skills/next-best-practices/font.md +245 -0
- package/src/.agents/skills/next-best-practices/functions.md +108 -0
- package/src/.agents/skills/next-best-practices/hydration-error.md +91 -0
- package/src/.agents/skills/next-best-practices/image.md +173 -0
- package/src/.agents/skills/next-best-practices/metadata.md +301 -0
- package/src/.agents/skills/next-best-practices/parallel-routes.md +287 -0
- package/src/.agents/skills/next-best-practices/route-handlers.md +146 -0
- package/src/.agents/skills/next-best-practices/rsc-boundaries.md +159 -0
- package/src/.agents/skills/next-best-practices/runtime-selection.md +39 -0
- package/src/.agents/skills/next-best-practices/scripts.md +141 -0
- package/src/.agents/skills/next-best-practices/self-hosting.md +371 -0
- package/src/.agents/skills/next-best-practices/suspense-boundaries.md +67 -0
- package/src/.agents/skills/nextjs-app-router-patterns/SKILL.md +537 -0
- package/src/.agents/skills/postgresql-optimization/SKILL.md +404 -0
- package/src/.agents/skills/python-backend/SKILL.md +153 -0
- package/src/.agents/skills/python-fundamentals/SKILL.md +234 -0
- package/src/.agents/skills/python-performance/SKILL.md +404 -0
- package/src/.agents/skills/react-expert/SKILL.md +335 -0
- package/src/.agents/skills/redis-best-practices/SKILL.md +438 -0
- package/src/.agents/skills/security-best-practices/SKILL.md +288 -0
- package/src/.agents/skills/security-review/LICENSE +22 -0
- package/src/.agents/skills/security-review/SKILL.md +312 -0
- package/src/.agents/skills/security-review/infrastructure/docker.md +432 -0
- package/src/.agents/skills/security-review/languages/javascript.md +388 -0
- package/src/.agents/skills/security-review/languages/python.md +363 -0
- package/src/.agents/skills/security-review/references/api-security.md +519 -0
- package/src/.agents/skills/security-review/references/authentication.md +353 -0
- package/src/.agents/skills/security-review/references/authorization.md +372 -0
- package/src/.agents/skills/security-review/references/business-logic.md +443 -0
- package/src/.agents/skills/security-review/references/cryptography.md +329 -0
- package/src/.agents/skills/security-review/references/csrf.md +398 -0
- package/src/.agents/skills/security-review/references/data-protection.md +378 -0
- package/src/.agents/skills/security-review/references/deserialization.md +410 -0
- package/src/.agents/skills/security-review/references/error-handling.md +436 -0
- package/src/.agents/skills/security-review/references/file-security.md +457 -0
- package/src/.agents/skills/security-review/references/injection.md +259 -0
- package/src/.agents/skills/security-review/references/logging.md +433 -0
- package/src/.agents/skills/security-review/references/misconfiguration.md +435 -0
- package/src/.agents/skills/security-review/references/modern-threats.md +475 -0
- package/src/.agents/skills/security-review/references/ssrf.md +415 -0
- package/src/.agents/skills/security-review/references/supply-chain.md +405 -0
- package/src/.agents/skills/security-review/references/xss.md +336 -0
- package/src/.agents/skills/subagent-driven-development/SKILL.md +275 -0
- package/src/.agents/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/src/.agents/skills/subagent-driven-development/implementer-prompt.md +113 -0
- package/src/.agents/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/src/.agents/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/src/.agents/skills/systematic-debugging/SKILL.md +296 -0
- package/src/.agents/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/src/.agents/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/src/.agents/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/src/.agents/skills/systematic-debugging/find-polluter.sh +63 -0
- package/src/.agents/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/src/.agents/skills/systematic-debugging/test-academic.md +14 -0
- package/src/.agents/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/src/.agents/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/src/.agents/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/src/.agents/skills/typescript-best-practices/SKILL.md +373 -0
- package/src/.agents/skills/ui-ux-pro-custom/SKILL.md +348 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/charts.csv +26 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/colors.csv +97 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/icons.csv +101 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/SKILL.md +106 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/accessibility.md +475 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/animation.md +466 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/composition-locals.md +231 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/deprecated-patterns.md +323 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/lists-scrolling.md +400 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/modifiers.md +331 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/navigation.md +416 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/performance.md +446 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/side-effects.md +516 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/foundation-source.md +13327 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/material3-source.md +19097 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/navigation-source.md +2947 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/runtime-source.md +11316 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/ui-source.md +7896 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/state-management.md +377 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/styles-experimental.md +470 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/theming-material3.md +349 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/view-composition.md +595 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/landing.csv +31 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/mobile-ui-layout.md +654 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/products.csv +97 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/react-performance.csv +45 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/astro.csv +54 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/flutter.csv +53 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/html-tailwind.csv +56 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/jetpack-compose.csv +53 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nextjs.csv +53 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nuxt-ui.csv +51 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nuxtjs.csv +59 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/react-native.csv +56 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/react.csv +54 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/shadcn.csv +61 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/svelte.csv +54 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/swiftui.csv +51 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/vue.csv +50 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/styles.csv +68 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/alarmkit/SKILL.md +438 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/alarmkit/references/alarmkit-patterns.md +584 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-clips/SKILL.md +436 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-intents/SKILL.md +489 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-intents/references/appintents-advanced.md +1076 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/SKILL.md +340 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/references/privacy-manifest.md +90 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/references/review-checklists.md +106 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/SKILL.md +500 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/coreml-conversion.md +425 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/coreml-optimization.md +344 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/foundation-models.md +508 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/mlx-swift.md +285 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/authentication/SKILL.md +496 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/authentication/references/keychain-biometric.md +211 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/background-processing/SKILL.md +499 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/background-processing/references/background-task-patterns.md +390 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/callkit-voip/SKILL.md +461 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/callkit-voip/references/callkit-patterns.md +425 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/cloudkit-sync/SKILL.md +492 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/cloudkit-sync/references/cloudkit-patterns.md +461 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/codable-patterns/SKILL.md +467 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/contacts-framework/SKILL.md +425 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/contacts-framework/references/contacts-patterns.md +409 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-bluetooth/SKILL.md +491 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-bluetooth/references/ble-patterns.md +435 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-motion/SKILL.md +388 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-motion/references/motion-patterns.md +405 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-nfc/SKILL.md +495 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-nfc/references/nfc-patterns.md +420 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/coreml/SKILL.md +459 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/coreml/references/coreml-swift-integration.md +765 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/SKILL.md +422 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/references/instruments-guide.md +387 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/references/lldb-patterns.md +298 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/device-integrity/SKILL.md +477 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/energykit/SKILL.md +460 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/energykit/references/energykit-patterns.md +541 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/eventkit-calendar/SKILL.md +483 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/eventkit-calendar/references/eventkit-patterns.md +326 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/healthkit/SKILL.md +498 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/healthkit/references/healthkit-patterns.md +602 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/homekit-matter/SKILL.md +496 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/homekit-matter/references/matter-commissioning.md +455 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-accessibility/SKILL.md +301 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-accessibility/references/a11y-patterns.md +140 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/SKILL.md +418 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/references/formatstyle-locale.md +627 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/references/string-catalogs.md +462 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/SKILL.md +441 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/background-websocket.md +862 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/lightweight-clients.md +93 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/network-framework.md +563 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/urlsession-patterns.md +1116 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/SKILL.md +496 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/app-review-guidelines.md +174 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/cryptokit-advanced.md +297 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/file-storage-patterns.md +354 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/privacy-manifest.md +117 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/live-activities/SKILL.md +500 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/live-activities/references/live-activity-patterns.md +868 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/SKILL.md +485 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/references/corelocation-patterns.md +730 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/references/mapkit-patterns.md +748 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/metrickit-diagnostics/SKILL.md +479 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/musickit-audio/SKILL.md +395 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/musickit-audio/references/musickit-patterns.md +363 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/natural-language/SKILL.md +412 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/natural-language/references/translation-patterns.md +311 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/passkit-wallet/SKILL.md +398 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/passkit-wallet/references/wallet-passes.md +254 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/SKILL.md +387 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/references/paperkit-integration.md +376 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/references/pencilkit-patterns.md +302 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/permissionkit/SKILL.md +446 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/permissionkit/references/permissionkit-patterns.md +435 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/SKILL.md +501 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/av-playback.md +701 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/camera-capture.md +774 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/image-loading-caching.md +869 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/photospicker-patterns.md +597 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/SKILL.md +501 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/references/notification-patterns.md +677 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/references/rich-notifications.md +745 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/realitykit-ar/SKILL.md +479 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/realitykit-ar/references/realitykit-patterns.md +480 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/SKILL.md +483 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/references/shareplay-patterns.md +544 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/speech-recognition/SKILL.md +485 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/SKILL.md +478 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/references/app-review-guidelines.md +58 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/references/storekit-advanced.md +755 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-charts/SKILL.md +487 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-charts/references/charts-patterns.md +895 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/SKILL.md +408 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/approachable-concurrency.md +80 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/swift-6-2-concurrency.md +233 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/swiftui-concurrency.md +187 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/synchronization-primitives.md +341 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-language/SKILL.md +498 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-language/references/swift-patterns-extended.md +505 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-testing/SKILL.md +467 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-testing/references/testing-patterns.md +504 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/SKILL.md +334 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/core-data-coexistence.md +504 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/swiftdata-advanced.md +975 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/swiftdata-queries.md +675 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/SKILL.md +481 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/references/animation-advanced.md +804 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/references/core-animation-bridge.md +553 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-gestures/SKILL.md +450 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-gestures/references/gesture-patterns.md +425 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/SKILL.md +336 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/form.md +97 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/grids.md +69 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/list.md +99 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/scrollview.md +147 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-liquid-glass/SKILL.md +325 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-liquid-glass/references/liquid-glass.md +387 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/SKILL.md +262 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/deeplinks.md +207 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/navigationstack.md +177 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/sheets.md +169 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/tabview.md +178 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/SKILL.md +381 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/architecture-patterns.md +486 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/deprecated-migration.md +1097 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/design-polish.md +780 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/platform-and-sharing.md +696 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/SKILL.md +491 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +46 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +29 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/understanding-hangs-in-your-app.md +33 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/understanding-improving-swiftui-performance.md +52 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/SKILL.md +428 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/references/hosting-migration.md +534 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/references/representable-recipes.md +1133 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/tipkit/SKILL.md +494 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/tipkit/references/tipkit-patterns.md +782 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/SKILL.md +475 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/vision-requests.md +736 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/visionkit-scanner.md +738 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/SKILL.md +410 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/references/weatherkit-patterns.md +567 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/SKILL.md +497 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/references/widgetkit-advanced.md +871 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/typography.csv +58 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/ui-reasoning.csv +101 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/ux-guidelines.csv +100 -0
- package/src/.agents/skills/ui-ux-pro-custom/data/web-interface.csv +31 -0
- package/src/.agents/skills/ui-ux-pro-custom/scripts/core.py +253 -0
- package/src/.agents/skills/ui-ux-pro-custom/scripts/design_system.py +1067 -0
- package/src/.agents/skills/ui-ux-pro-custom/scripts/search.py +114 -0
- package/src/.agents/skills/ux-audit/SKILL.md +151 -0
- package/src/.agents/skills/websocket-engineer/SKILL.md +168 -0
- package/src/.agents/skills/websocket-engineer/references/alternatives.md +391 -0
- package/src/.agents/skills/websocket-engineer/references/patterns.md +400 -0
- package/src/.agents/skills/websocket-engineer/references/protocol.md +195 -0
- package/src/.agents/skills/websocket-engineer/references/scaling.md +333 -0
- package/src/.agents/skills/websocket-engineer/references/security.md +474 -0
- package/src/.agents/skills/writing-skills/SKILL.md +655 -0
- package/src/.agents/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/src/.agents/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/src/.agents/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/src/.agents/skills/writing-skills/persuasion-principles.md +187 -0
- package/src/.agents/skills/writing-skills/render-graphs.js +168 -0
- package/src/.agents/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/src/.claude/commands/bmad-track-compact.md +19 -0
- package/src/.claude/commands/bmad-track-extended.md +19 -0
- package/src/.claude/commands/bmad-track-large.md +19 -0
- package/src/.claude/commands/bmad-track-medium.md +19 -0
- package/src/.claude/commands/bmad-track-nano.md +19 -0
- package/src/.claude/commands/bmad-track-rv.md +18 -0
- package/src/.claude/commands/bmad-track-small.md +19 -0
- package/src/_memory/config.yaml +11 -0
- package/src/_memory/master-orchestrator-sidecar/docs-index.md +3 -0
- package/src/_memory/master-orchestrator-sidecar/instructions.md +2566 -0
- package/src/_memory/master-orchestrator-sidecar/memories.md +8 -0
- package/src/_memory/master-orchestrator-sidecar/session-state.md +15 -0
- package/src/_memory/master-orchestrator-sidecar/triage-history.md +3 -0
- package/src/_memory/master-orchestrator-sidecar/workflows-overview.html +1230 -0
- package/src/_memory/skills/excalidraw/SKILL.md +78 -0
- package/src/_memory/skills/excalidraw/diagram-patterns.md +53 -0
- package/src/_memory/skills/nimbalyst-tracking/SKILL.md +103 -0
- package/src/_memory/skills/writing-skills/SKILL.md +655 -0
- package/src/bmb/agents/agent-builder.md +59 -0
- package/src/bmb/agents/module-builder.md +60 -0
- package/src/bmb/agents/workflow-builder.md +61 -0
- package/src/bmb/config.yaml +12 -0
- package/src/bmb/module-help.csv +13 -0
- package/src/bmb/workflows/agent/data/agent-architecture.md +258 -0
- package/src/bmb/workflows/agent/data/agent-compilation.md +185 -0
- package/src/bmb/workflows/agent/data/agent-menu-patterns.md +189 -0
- package/src/bmb/workflows/agent/data/agent-metadata.md +133 -0
- package/src/bmb/workflows/agent/data/agent-validation.md +111 -0
- package/src/bmb/workflows/agent/data/brainstorm-context.md +96 -0
- package/src/bmb/workflows/agent/data/communication-presets.csv +61 -0
- package/src/bmb/workflows/agent/data/critical-actions.md +75 -0
- package/src/bmb/workflows/agent/data/persona-properties.md +252 -0
- package/src/bmb/workflows/agent/data/principles-crafting.md +142 -0
- package/src/bmb/workflows/agent/data/reference/module-examples/architect.md +68 -0
- package/src/bmb/workflows/agent/data/reference/with-sidecar/journal-keeper/journal-keeper-sidecar/entries/yy-mm-dd-entry-template.md +17 -0
- package/src/bmb/workflows/agent/data/understanding-agent-types.md +126 -0
- package/src/bmb/workflows/agent/steps-c/step-01-brainstorm.md +129 -0
- package/src/bmb/workflows/agent/steps-c/step-02-discovery.md +170 -0
- package/src/bmb/workflows/agent/steps-c/step-03-sidecar-metadata.md +309 -0
- package/src/bmb/workflows/agent/steps-c/step-04-persona.md +213 -0
- package/src/bmb/workflows/agent/steps-c/step-05-commands-menu.md +179 -0
- package/src/bmb/workflows/agent/steps-c/step-06-activation.md +278 -0
- package/src/bmb/workflows/agent/steps-c/step-07-build-agent.md +316 -0
- package/src/bmb/workflows/agent/steps-c/step-08-celebrate.md +247 -0
- package/src/bmb/workflows/agent/steps-e/e-01-load-existing.md +221 -0
- package/src/bmb/workflows/agent/steps-e/e-02-discover-edits.md +195 -0
- package/src/bmb/workflows/agent/steps-e/e-03-placeholder.md +1 -0
- package/src/bmb/workflows/agent/steps-e/e-04-sidecar-metadata.md +126 -0
- package/src/bmb/workflows/agent/steps-e/e-05-persona.md +135 -0
- package/src/bmb/workflows/agent/steps-e/e-06-commands-menu.md +123 -0
- package/src/bmb/workflows/agent/steps-e/e-07-activation.md +124 -0
- package/src/bmb/workflows/agent/steps-e/e-08-edit-agent.md +197 -0
- package/src/bmb/workflows/agent/steps-e/e-09-celebrate.md +155 -0
- package/src/bmb/workflows/agent/steps-v/v-01-load-review.md +137 -0
- package/src/bmb/workflows/agent/steps-v/v-02a-validate-metadata.md +116 -0
- package/src/bmb/workflows/agent/steps-v/v-02b-validate-persona.md +124 -0
- package/src/bmb/workflows/agent/steps-v/v-02c-validate-menu.md +127 -0
- package/src/bmb/workflows/agent/steps-v/v-02d-validate-structure.md +134 -0
- package/src/bmb/workflows/agent/steps-v/v-02e-validate-sidecar.md +134 -0
- package/src/bmb/workflows/agent/steps-v/v-03-summary.md +104 -0
- package/src/bmb/workflows/agent/templates/agent-plan.template.md +5 -0
- package/src/bmb/workflows/agent/templates/agent-template.md +89 -0
- package/src/bmb/workflows/agent/workflow-create-agent.md +72 -0
- package/src/bmb/workflows/agent/workflow-edit-agent.md +75 -0
- package/src/bmb/workflows/agent/workflow-validate-agent.md +73 -0
- package/src/bmb/workflows/module/data/agent-architecture.md +179 -0
- package/src/bmb/workflows/module/data/agent-spec-template.md +79 -0
- package/src/bmb/workflows/module/data/module-standards.md +263 -0
- package/src/bmb/workflows/module/data/module-yaml-conventions.md +392 -0
- package/src/bmb/workflows/module/module-help-generate.md +254 -0
- package/src/bmb/workflows/module/steps-b/step-01-welcome.md +148 -0
- package/src/bmb/workflows/module/steps-b/step-02-spark.md +141 -0
- package/src/bmb/workflows/module/steps-b/step-03-module-type.md +149 -0
- package/src/bmb/workflows/module/steps-b/step-04-vision.md +83 -0
- package/src/bmb/workflows/module/steps-b/step-05-identity.md +97 -0
- package/src/bmb/workflows/module/steps-b/step-06-users.md +86 -0
- package/src/bmb/workflows/module/steps-b/step-07-value.md +76 -0
- package/src/bmb/workflows/module/steps-b/step-08-agents.md +97 -0
- package/src/bmb/workflows/module/steps-b/step-09-workflows.md +83 -0
- package/src/bmb/workflows/module/steps-b/step-10-tools.md +91 -0
- package/src/bmb/workflows/module/steps-b/step-11-scenarios.md +84 -0
- package/src/bmb/workflows/module/steps-b/step-12-creative.md +95 -0
- package/src/bmb/workflows/module/steps-b/step-13-review.md +105 -0
- package/src/bmb/workflows/module/steps-b/step-14-finalize.md +117 -0
- package/src/bmb/workflows/module/steps-c/step-01-load-brief.md +179 -0
- package/src/bmb/workflows/module/steps-c/step-01b-continue.md +82 -0
- package/src/bmb/workflows/module/steps-c/step-02-structure.md +105 -0
- package/src/bmb/workflows/module/steps-c/step-03-config.md +119 -0
- package/src/bmb/workflows/module/steps-c/step-04-agents.md +168 -0
- package/src/bmb/workflows/module/steps-c/step-05-workflows.md +184 -0
- package/src/bmb/workflows/module/steps-c/step-06-docs.md +401 -0
- package/src/bmb/workflows/module/steps-c/step-07-complete.md +152 -0
- package/src/bmb/workflows/module/steps-e/step-01-load-target.md +81 -0
- package/src/bmb/workflows/module/steps-e/step-02-select-edit.md +77 -0
- package/src/bmb/workflows/module/steps-e/step-03-apply-edit.md +77 -0
- package/src/bmb/workflows/module/steps-e/step-04-review.md +80 -0
- package/src/bmb/workflows/module/steps-e/step-05-confirm.md +75 -0
- package/src/bmb/workflows/module/steps-v/step-01-load-target.md +96 -0
- package/src/bmb/workflows/module/steps-v/step-02-file-structure.md +93 -0
- package/src/bmb/workflows/module/steps-v/step-03-module-yaml.md +99 -0
- package/src/bmb/workflows/module/steps-v/step-04-agent-specs.md +152 -0
- package/src/bmb/workflows/module/steps-v/step-05-workflow-specs.md +152 -0
- package/src/bmb/workflows/module/steps-v/step-06-documentation.md +143 -0
- package/src/bmb/workflows/module/steps-v/step-07-installation.md +102 -0
- package/src/bmb/workflows/module/steps-v/step-08-report.md +197 -0
- package/src/bmb/workflows/module/templates/brief-template.md +154 -0
- package/src/bmb/workflows/module/templates/workflow-spec-template.md +96 -0
- package/src/bmb/workflows/module/workflow-create-module-brief.md +71 -0
- package/src/bmb/workflows/module/workflow-create-module.md +86 -0
- package/src/bmb/workflows/module/workflow-edit-module.md +66 -0
- package/src/bmb/workflows/module/workflow-validate-module.md +66 -0
- package/src/bmb/workflows/workflow/data/architecture.md +150 -0
- package/src/bmb/workflows/workflow/data/common-workflow-tools.csv +19 -0
- package/src/bmb/workflows/workflow/data/csv-data-file-standards.md +53 -0
- package/src/bmb/workflows/workflow/data/frontmatter-standards.md +184 -0
- package/src/bmb/workflows/workflow/data/input-discovery-standards.md +191 -0
- package/src/bmb/workflows/workflow/data/intent-vs-prescriptive-spectrum.md +44 -0
- package/src/bmb/workflows/workflow/data/menu-handling-standards.md +133 -0
- package/src/bmb/workflows/workflow/data/output-format-standards.md +135 -0
- package/src/bmb/workflows/workflow/data/step-file-rules.md +235 -0
- package/src/bmb/workflows/workflow/data/step-type-patterns.md +257 -0
- package/src/bmb/workflows/workflow/data/subprocess-optimization-patterns.md +188 -0
- package/src/bmb/workflows/workflow/data/trimodal-workflow-structure.md +164 -0
- package/src/bmb/workflows/workflow/data/workflow-chaining-standards.md +222 -0
- package/src/bmb/workflows/workflow/data/workflow-examples.md +232 -0
- package/src/bmb/workflows/workflow/data/workflow-type-criteria.md +134 -0
- package/src/bmb/workflows/workflow/steps-c/step-00-conversion.md +263 -0
- package/src/bmb/workflows/workflow/steps-c/step-01-discovery.md +194 -0
- package/src/bmb/workflows/workflow/steps-c/step-01b-continuation.md +3 -0
- package/src/bmb/workflows/workflow/steps-c/step-02-classification.md +270 -0
- package/src/bmb/workflows/workflow/steps-c/step-03-requirements.md +283 -0
- package/src/bmb/workflows/workflow/steps-c/step-04-tools.md +282 -0
- package/src/bmb/workflows/workflow/steps-c/step-05-plan-review.md +243 -0
- package/src/bmb/workflows/workflow/steps-c/step-06-design.md +330 -0
- package/src/bmb/workflows/workflow/steps-c/step-07-foundation.md +239 -0
- package/src/bmb/workflows/workflow/steps-c/step-08-build-step-01.md +379 -0
- package/src/bmb/workflows/workflow/steps-c/step-09-build-next-step.md +350 -0
- package/src/bmb/workflows/workflow/steps-c/step-10-confirmation.md +322 -0
- package/src/bmb/workflows/workflow/steps-c/step-11-completion.md +191 -0
- package/src/bmb/workflows/workflow/steps-e/step-e-01-assess-workflow.md +237 -0
- package/src/bmb/workflows/workflow/steps-e/step-e-02-discover-edits.md +251 -0
- package/src/bmb/workflows/workflow/steps-e/step-e-03-fix-validation.md +254 -0
- package/src/bmb/workflows/workflow/steps-e/step-e-04-direct-edit.md +277 -0
- package/src/bmb/workflows/workflow/steps-e/step-e-05-apply-edit.md +154 -0
- package/src/bmb/workflows/workflow/steps-e/step-e-06-validate-after.md +190 -0
- package/src/bmb/workflows/workflow/steps-e/step-e-07-complete.md +206 -0
- package/src/bmb/workflows/workflow/steps-v/step-01-validate-max-mode.md +109 -0
- package/src/bmb/workflows/workflow/steps-v/step-01-validate.md +221 -0
- package/src/bmb/workflows/workflow/steps-v/step-01b-structure.md +152 -0
- package/src/bmb/workflows/workflow/steps-v/step-02-frontmatter-validation.md +199 -0
- package/src/bmb/workflows/workflow/steps-v/step-02b-path-violations.md +265 -0
- package/src/bmb/workflows/workflow/steps-v/step-03-menu-validation.md +164 -0
- package/src/bmb/workflows/workflow/steps-v/step-04-step-type-validation.md +211 -0
- package/src/bmb/workflows/workflow/steps-v/step-05-output-format-validation.md +200 -0
- package/src/bmb/workflows/workflow/steps-v/step-06-validation-design-check.md +195 -0
- package/src/bmb/workflows/workflow/steps-v/step-07-instruction-style-check.md +209 -0
- package/src/bmb/workflows/workflow/steps-v/step-08-collaborative-experience-check.md +199 -0
- package/src/bmb/workflows/workflow/steps-v/step-08b-subprocess-optimization.md +179 -0
- package/src/bmb/workflows/workflow/steps-v/step-09-cohesive-review.md +186 -0
- package/src/bmb/workflows/workflow/steps-v/step-10-report-complete.md +154 -0
- package/src/bmb/workflows/workflow/steps-v/step-11-plan-validation.md +237 -0
- package/src/bmb/workflows/workflow/templates/minimal-output-template.md +11 -0
- package/src/bmb/workflows/workflow/templates/step-01-init-continuable-template.md +241 -0
- package/src/bmb/workflows/workflow/templates/step-1b-template.md +224 -0
- package/src/bmb/workflows/workflow/templates/step-template.md +294 -0
- package/src/bmb/workflows/workflow/templates/workflow-template.md +102 -0
- package/src/bmb/workflows/workflow/workflow-create-workflow.md +79 -0
- package/src/bmb/workflows/workflow/workflow-edit-workflow.md +65 -0
- package/src/bmb/workflows/workflow/workflow-rework-workflow.md +65 -0
- package/src/bmb/workflows/workflow/workflow-validate-max-parallel-workflow.md +66 -0
- package/src/bmb/workflows/workflow/workflow-validate-workflow.md +65 -0
- package/src/bmm/agents/analyst.md +104 -0
- package/src/bmm/agents/architect.md +85 -0
- package/src/bmm/agents/dev.md +100 -0
- package/src/bmm/agents/pm.md +98 -0
- package/src/bmm/agents/qa.md +90 -0
- package/src/bmm/agents/quick-flow-solo-dev.md +92 -0
- package/src/bmm/agents/review-agent.md +129 -0
- package/src/bmm/agents/sm.md +90 -0
- package/src/bmm/agents/tech-writer/tech-writer.md +94 -0
- package/src/bmm/agents/ux-designer.md +124 -0
- package/src/bmm/data/project-context-template.md +26 -0
- package/src/bmm/module-help.csv +31 -0
- package/src/bmm/teams/default-party.csv +20 -0
- package/src/bmm/teams/team-fullstack.yaml +12 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +115 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +107 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +141 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +144 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +147 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +161 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +99 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +57 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +87 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +156 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +165 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +140 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +152 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +345 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +92 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +164 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +174 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +184 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +105 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +360 -0
- package/src/bmm/workflows/1-analysis/research/research.template.md +29 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +87 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +165 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +174 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +141 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +159 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +387 -0
- package/src/bmm/workflows/1-analysis/research/workflow-domain-research.md +54 -0
- package/src/bmm/workflows/1-analysis/research/workflow-market-research.md +54 -0
- package/src/bmm/workflows/1-analysis/research/workflow-technical-research.md +54 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +15 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/data/project-types.csv +11 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01-init.md +139 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +100 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +160 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +88 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +99 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +169 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +156 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +136 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +176 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +184 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +174 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +175 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +189 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +162 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +79 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +183 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +149 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +187 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +192 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +108 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +166 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +131 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +150 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +118 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +155 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +170 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +158 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +147 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +182 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +202 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +148 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +201 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +179 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +164 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/templates/prd-template.md +10 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +65 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +65 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +63 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +63 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +63 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +106 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +111 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +115 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +127 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +167 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +143 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +118 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +154 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +136 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +165 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +135 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +192 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +101 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +45 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +185 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +129 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +130 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +93 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +196 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +129 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +13 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +89 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +82 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +106 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +138 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +129 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +166 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +186 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +163 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +38 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +49 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +129 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +124 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +122 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +84 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -0
- package/src/bmm/workflows/4-implementation/code-review/checklist.md +23 -0
- package/src/bmm/workflows/4-implementation/code-review/instructions.xml +227 -0
- package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +43 -0
- package/src/bmm/workflows/4-implementation/correct-course/checklist.md +288 -0
- package/src/bmm/workflows/4-implementation/correct-course/instructions.md +207 -0
- package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +53 -0
- package/src/bmm/workflows/4-implementation/create-story/checklist.md +159 -0
- package/src/bmm/workflows/4-implementation/create-story/instructions.xml +574 -0
- package/src/bmm/workflows/4-implementation/create-story/template.md +79 -0
- package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +52 -0
- package/src/bmm/workflows/4-implementation/dev-story/checklist.md +80 -0
- package/src/bmm/workflows/4-implementation/dev-story/instructions.xml +493 -0
- package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +20 -0
- package/src/bmm/workflows/4-implementation/retrospective/instructions.md +1444 -0
- package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +52 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/instructions.md +232 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +52 -0
- package/src/bmm/workflows/4-implementation/sprint-status/instructions.md +230 -0
- package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +25 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +158 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +122 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +93 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +93 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +87 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +146 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +204 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +152 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +123 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +201 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -0
- package/src/bmm/workflows/document-project/checklist.md +245 -0
- package/src/bmm/workflows/document-project/documentation-requirements.csv +12 -0
- package/src/bmm/workflows/document-project/instructions.md +130 -0
- package/src/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
- package/src/bmm/workflows/document-project/templates/index-template.md +169 -0
- package/src/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
- package/src/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
- package/src/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
- package/src/bmm/workflows/document-project/workflow.yaml +22 -0
- package/src/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
- package/src/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
- package/src/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
- package/src/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
- package/src/bmm/workflows/generate-project-context/project-context-template.md +21 -0
- package/src/bmm/workflows/generate-project-context/steps/step-01-discover.md +184 -0
- package/src/bmm/workflows/generate-project-context/steps/step-02-generate.md +322 -0
- package/src/bmm/workflows/generate-project-context/steps/step-03-complete.md +235 -0
- package/src/bmm/workflows/generate-project-context/workflow.md +49 -0
- package/src/bmm/workflows/qa/automate/workflow.yaml +233 -0
- package/src/bmm/workflows/qa-generate-e2e-tests/checklist.md +33 -0
- package/src/bmm/workflows/qa-generate-e2e-tests/instructions.md +110 -0
- package/src/bmm/workflows/qa-generate-e2e-tests/workflow.yaml +42 -0
- package/src/core/agents/bmad-master.md +56 -0
- package/src/core/agents/master-orchestrator.md +54 -0
- package/src/core/config.yaml +9 -0
- package/src/core/module-help.csv +10 -0
- package/src/core/scripts/generate-loop-report.py +72 -0
- package/src/core/skills/prepare-to-merge/SKILL.md +77 -0
- package/src/core/tasks/editorial-review-prose.xml +102 -0
- package/src/core/tasks/editorial-review-structure.xml +208 -0
- package/src/core/tasks/help.md +86 -0
- package/src/core/tasks/index-docs.xml +65 -0
- package/src/core/tasks/review-adversarial-general.xml +66 -0
- package/src/core/tasks/review-adversarial-loop.xml +46 -0
- package/src/core/tasks/review-edge-case-hunter.xml +63 -0
- package/src/core/tasks/review-party-loop.xml +46 -0
- package/src/core/tasks/shard-doc.xml +108 -0
- package/src/core/tasks/workflow.xml +236 -0
- package/src/core/templates/review-loop-report.html +88 -0
- package/src/core/templates/review-loop-report.md +5 -0
- package/src/core/workflows/advanced-elicitation/methods.csv +51 -0
- package/src/core/workflows/advanced-elicitation/workflow.xml +118 -0
- package/src/core/workflows/brainstorming/brain-methods.csv +62 -0
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +212 -0
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
- package/src/core/workflows/brainstorming/steps/step-02e-deep-dive.md +68 -0
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +403 -0
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
- package/src/core/workflows/brainstorming/template.md +15 -0
- package/src/core/workflows/brainstorming/workflow.md +60 -0
- package/src/core/workflows/extract-trackers/workflow.md +45 -0
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +142 -0
- package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
- package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +168 -0
- package/src/core/workflows/party-mode/workflow.md +194 -0
- package/src/docs/dev/tmux/actions_popup.py +291 -0
- package/src/docs/dev/tmux/actions_popup.sh +110 -0
- package/src/docs/dev/tmux/claude_usage.sh +15 -0
- package/src/docs/dev/tmux/colors.conf +34 -0
- package/src/docs/dev/tmux/cpu_usage.sh +7 -0
- package/src/docs/dev/tmux/dispatch.sh +10 -0
- package/src/docs/dev/tmux/float_init.sh +13 -0
- package/src/docs/dev/tmux/float_term.sh +23 -0
- package/src/docs/dev/tmux/open_clip.sh +14 -0
- package/src/docs/dev/tmux/paste_clipboard.sh +13 -0
- package/src/docs/dev/tmux/paste_image_wrapper.sh +83 -0
- package/src/docs/dev/tmux/ram_usage.sh +3 -0
- package/src/docs/dev/tmux/title_sync.sh +54 -0
- package/src/docs/dev/tmux/tmux-setup.md +806 -0
- package/src/docs/dev/tmux/tmux.conf +127 -0
- package/src/docs/dev/tmux/xclip +18 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# CryptoKit Advanced Patterns
|
|
2
|
+
|
|
3
|
+
Extended CryptoKit usage beyond the basics covered in the main skill. Includes
|
|
4
|
+
digital signatures, key agreement, alternative ciphers, key derivation, and
|
|
5
|
+
post-quantum cryptography.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- [ChaChaPoly (Alternative to AES-GCM)](#chachapoly-alternative-to-aes-gcm)
|
|
10
|
+
- [Digital Signatures (P256 / ECDSA)](#digital-signatures-p256-ecdsa)
|
|
11
|
+
- [Key Agreement (Diffie-Hellman)](#key-agreement-diffie-hellman)
|
|
12
|
+
- [Key Derivation with HKDF](#key-derivation-with-hkdf)
|
|
13
|
+
- [Authenticated Encryption with Associated Data (AEAD)](#authenticated-encryption-with-associated-data-aead)
|
|
14
|
+
- [AES Key Wrapping](#aes-key-wrapping)
|
|
15
|
+
- [Secure Enclave Key Agreement](#secure-enclave-key-agreement)
|
|
16
|
+
- [Post-Quantum Cryptography](#post-quantum-cryptography)
|
|
17
|
+
- [Storing CryptoKit Keys in Keychain](#storing-cryptokit-keys-in-keychain)
|
|
18
|
+
- [Jailbreak Detection](#jailbreak-detection)
|
|
19
|
+
|
|
20
|
+
## ChaChaPoly (Alternative to AES-GCM)
|
|
21
|
+
|
|
22
|
+
Same sealed-box API as AES-GCM. Use for interoperability with non-Apple systems
|
|
23
|
+
or when AES hardware acceleration is unavailable.
|
|
24
|
+
|
|
25
|
+
```swift
|
|
26
|
+
import CryptoKit
|
|
27
|
+
|
|
28
|
+
let key = SymmetricKey(size: .bits256)
|
|
29
|
+
|
|
30
|
+
// Encrypt
|
|
31
|
+
let sealed = try ChaChaPoly.seal(data, using: key)
|
|
32
|
+
let combined = sealed.combined
|
|
33
|
+
|
|
34
|
+
// Decrypt
|
|
35
|
+
let box = try ChaChaPoly.SealedBox(combined: combined)
|
|
36
|
+
let decrypted = try ChaChaPoly.open(box, using: key)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Digital Signatures (P256 / ECDSA)
|
|
40
|
+
|
|
41
|
+
```swift
|
|
42
|
+
// Generate key pair
|
|
43
|
+
let privateKey = P256.Signing.PrivateKey()
|
|
44
|
+
let publicKey = privateKey.publicKey
|
|
45
|
+
|
|
46
|
+
// Sign
|
|
47
|
+
let signature = try privateKey.signature(for: data)
|
|
48
|
+
|
|
49
|
+
// Verify
|
|
50
|
+
let isValid = publicKey.isValidSignature(signature, for: data)
|
|
51
|
+
|
|
52
|
+
// Export public key (raw, DER, or PEM)
|
|
53
|
+
let rawData = publicKey.rawRepresentation
|
|
54
|
+
let derData = publicKey.derRepresentation
|
|
55
|
+
let pemString = publicKey.pemRepresentation
|
|
56
|
+
|
|
57
|
+
// Import public key
|
|
58
|
+
let imported = try P256.Signing.PublicKey(rawRepresentation: rawData)
|
|
59
|
+
let importedDER = try P256.Signing.PublicKey(derRepresentation: derData)
|
|
60
|
+
let importedPEM = try P256.Signing.PublicKey(pemRepresentation: pemString)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Also available: `P384.Signing` and `P521.Signing` for stronger curves.
|
|
64
|
+
|
|
65
|
+
## Key Agreement (Diffie-Hellman)
|
|
66
|
+
|
|
67
|
+
### Curve25519
|
|
68
|
+
|
|
69
|
+
```swift
|
|
70
|
+
let myPrivateKey = Curve25519.KeyAgreement.PrivateKey()
|
|
71
|
+
let myPublicKey = myPrivateKey.publicKey
|
|
72
|
+
|
|
73
|
+
// After exchanging public keys...
|
|
74
|
+
let sharedSecret = try myPrivateKey.sharedSecretFromKeyAgreement(
|
|
75
|
+
with: theirPublicKey
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
// Derive symmetric key from shared secret using HKDF
|
|
79
|
+
let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
|
|
80
|
+
using: SHA256.self,
|
|
81
|
+
salt: salt,
|
|
82
|
+
sharedInfo: Data("app-encryption".utf8),
|
|
83
|
+
outputByteCount: 32
|
|
84
|
+
)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### P256 Key Agreement
|
|
88
|
+
|
|
89
|
+
```swift
|
|
90
|
+
let privateKey = P256.KeyAgreement.PrivateKey()
|
|
91
|
+
let publicKey = privateKey.publicKey
|
|
92
|
+
|
|
93
|
+
let sharedSecret = try privateKey.sharedSecretFromKeyAgreement(
|
|
94
|
+
with: theirPublicKey
|
|
95
|
+
)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Also available: `P384.KeyAgreement` and `P521.KeyAgreement`.
|
|
99
|
+
|
|
100
|
+
## Key Derivation with HKDF
|
|
101
|
+
|
|
102
|
+
Derive one or more keys from input key material:
|
|
103
|
+
|
|
104
|
+
```swift
|
|
105
|
+
// Simple derivation
|
|
106
|
+
let derived = HKDF<SHA256>.deriveKey(
|
|
107
|
+
inputKeyMaterial: inputKey,
|
|
108
|
+
salt: salt,
|
|
109
|
+
info: Data("context-string".utf8),
|
|
110
|
+
outputByteCount: 32
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
// Two-step: extract then expand (for advanced use)
|
|
114
|
+
let prk = HKDF<SHA256>.extract(inputKeyMaterial: inputKey, salt: salt)
|
|
115
|
+
let key1 = HKDF<SHA256>.expand(
|
|
116
|
+
pseudoRandomKey: prk,
|
|
117
|
+
info: Data("key-1".utf8),
|
|
118
|
+
outputByteCount: 32
|
|
119
|
+
)
|
|
120
|
+
let key2 = HKDF<SHA256>.expand(
|
|
121
|
+
pseudoRandomKey: prk,
|
|
122
|
+
info: Data("key-2".utf8),
|
|
123
|
+
outputByteCount: 32
|
|
124
|
+
)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Authenticated Encryption with Associated Data (AEAD)
|
|
128
|
+
|
|
129
|
+
Both AES-GCM and ChaChaPoly support authenticating additional data that is not
|
|
130
|
+
encrypted but is included in the authentication tag:
|
|
131
|
+
|
|
132
|
+
```swift
|
|
133
|
+
let sealed = try AES.GCM.seal(
|
|
134
|
+
plaintext,
|
|
135
|
+
using: key,
|
|
136
|
+
authenticating: associatedData // e.g., message headers
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
let decrypted = try AES.GCM.open(
|
|
140
|
+
sealed,
|
|
141
|
+
using: key,
|
|
142
|
+
authenticating: associatedData
|
|
143
|
+
)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## AES Key Wrapping
|
|
147
|
+
|
|
148
|
+
Wrap and unwrap symmetric keys for secure transport:
|
|
149
|
+
|
|
150
|
+
```swift
|
|
151
|
+
let keyToWrap = SymmetricKey(size: .bits256)
|
|
152
|
+
let wrappingKey = SymmetricKey(size: .bits256)
|
|
153
|
+
|
|
154
|
+
// Wrap
|
|
155
|
+
let wrapped = try AES.KeyWrap.wrap(keyToWrap, using: wrappingKey)
|
|
156
|
+
|
|
157
|
+
// Unwrap
|
|
158
|
+
let unwrapped = try AES.KeyWrap.unwrap(wrapped, using: wrappingKey)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Secure Enclave Key Agreement
|
|
162
|
+
|
|
163
|
+
The Secure Enclave also supports P256 key agreement:
|
|
164
|
+
|
|
165
|
+
```swift
|
|
166
|
+
let accessControl = SecAccessControlCreateWithFlags(
|
|
167
|
+
nil,
|
|
168
|
+
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
|
|
169
|
+
[.privateKeyUsage, .biometryCurrentSet],
|
|
170
|
+
nil
|
|
171
|
+
)!
|
|
172
|
+
|
|
173
|
+
let sePrivateKey = try SecureEnclave.P256.KeyAgreement.PrivateKey(
|
|
174
|
+
accessControl: accessControl
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
let sharedSecret = try sePrivateKey.sharedSecretFromKeyAgreement(
|
|
178
|
+
with: theirPublicKey
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Post-Quantum Cryptography
|
|
183
|
+
|
|
184
|
+
CryptoKit includes post-quantum algorithms for future-proofing. These are
|
|
185
|
+
available on newer OS versions.
|
|
186
|
+
|
|
187
|
+
### ML-KEM (Key Encapsulation)
|
|
188
|
+
|
|
189
|
+
```swift
|
|
190
|
+
// ML-KEM 768 (128-bit security)
|
|
191
|
+
let privateKey = try MLKEM768.PrivateKey()
|
|
192
|
+
let publicKey = privateKey.publicKey
|
|
193
|
+
|
|
194
|
+
// Encapsulate (sender side)
|
|
195
|
+
let result = try publicKey.encapsulate()
|
|
196
|
+
let sharedKey = result.sharedSecret // SymmetricKey
|
|
197
|
+
let encapsulated = result.encapsulated // Send to key owner
|
|
198
|
+
|
|
199
|
+
// Decapsulate (receiver side)
|
|
200
|
+
let decapsulatedKey = try privateKey.decapsulate(encapsulated)
|
|
201
|
+
// decapsulatedKey == sharedKey
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Also available: `MLKEM1024` for 192-bit security.
|
|
205
|
+
|
|
206
|
+
### ML-DSA (Digital Signatures)
|
|
207
|
+
|
|
208
|
+
```swift
|
|
209
|
+
// ML-DSA 65 (128-bit security)
|
|
210
|
+
let signingKey = try MLDSA65.PrivateKey()
|
|
211
|
+
let verifyingKey = signingKey.publicKey
|
|
212
|
+
|
|
213
|
+
let signature = try signingKey.signature(for: data)
|
|
214
|
+
let isValid = verifyingKey.isValidSignature(signature, for: data)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Also available: `MLDSA87` for 192-bit security.
|
|
218
|
+
|
|
219
|
+
### Hybrid Post-Quantum (HPKE)
|
|
220
|
+
|
|
221
|
+
For hybrid classical + post-quantum encryption:
|
|
222
|
+
|
|
223
|
+
```swift
|
|
224
|
+
let ciphersuite = HPKE.Ciphersuite.XWingMLKEM768X25519_SHA256_AES_GCM_256
|
|
225
|
+
|
|
226
|
+
let sender = try HPKE.Sender(
|
|
227
|
+
recipientKey: recipientPublicKey,
|
|
228
|
+
ciphersuite: ciphersuite,
|
|
229
|
+
info: Data("app-context".utf8)
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
let ciphertext = try sender.seal(plaintext)
|
|
233
|
+
// Send sender.encapsulatedKey and ciphertext to recipient
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Storing CryptoKit Keys in Keychain
|
|
237
|
+
|
|
238
|
+
For non-Secure-Enclave keys that need persistence:
|
|
239
|
+
|
|
240
|
+
```swift
|
|
241
|
+
let privateKey = P256.Signing.PrivateKey()
|
|
242
|
+
|
|
243
|
+
// Store
|
|
244
|
+
let keyData = privateKey.rawRepresentation
|
|
245
|
+
let query: [String: Any] = [
|
|
246
|
+
kSecClass as String: kSecClassKey,
|
|
247
|
+
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
|
|
248
|
+
kSecAttrKeySizeInBits as String: 256,
|
|
249
|
+
kSecAttrApplicationTag as String: "com.app.signing-key".data(using: .utf8)!,
|
|
250
|
+
kSecValueData as String: keyData,
|
|
251
|
+
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
|
|
252
|
+
]
|
|
253
|
+
SecItemAdd(query as CFDictionary, nil)
|
|
254
|
+
|
|
255
|
+
// Retrieve
|
|
256
|
+
let searchQuery: [String: Any] = [
|
|
257
|
+
kSecClass as String: kSecClassKey,
|
|
258
|
+
kSecAttrApplicationTag as String: "com.app.signing-key".data(using: .utf8)!,
|
|
259
|
+
kSecReturnData as String: true
|
|
260
|
+
]
|
|
261
|
+
var result: AnyObject?
|
|
262
|
+
SecItemCopyMatching(searchQuery as CFDictionary, &result)
|
|
263
|
+
if let data = result as? Data {
|
|
264
|
+
let restored = try P256.Signing.PrivateKey(rawRepresentation: data)
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Jailbreak Detection
|
|
269
|
+
|
|
270
|
+
Use jailbreak detection as one signal, not a security boundary. Check for known jailbreak file paths and sandbox escape:
|
|
271
|
+
|
|
272
|
+
```swift
|
|
273
|
+
func isDeviceCompromised() -> Bool {
|
|
274
|
+
let paths = [
|
|
275
|
+
"/Applications/Cydia.app",
|
|
276
|
+
"/Library/MobileSubstrate/MobileSubstrate.dylib",
|
|
277
|
+
"/usr/sbin/sshd",
|
|
278
|
+
"/etc/apt",
|
|
279
|
+
"/private/var/lib/apt/"
|
|
280
|
+
]
|
|
281
|
+
|
|
282
|
+
for path in paths {
|
|
283
|
+
if FileManager.default.fileExists(atPath: path) { return true }
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
let testPath = "/private/test_jailbreak"
|
|
287
|
+
do {
|
|
288
|
+
try "test".write(toFile: testPath, atomically: true, encoding: .utf8)
|
|
289
|
+
try FileManager.default.removeItem(atPath: testPath)
|
|
290
|
+
return true
|
|
291
|
+
} catch {
|
|
292
|
+
return false
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
This is heuristic only. Treat a positive result as higher risk, not proof.
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# File Storage Patterns
|
|
2
|
+
|
|
3
|
+
Guidance on choosing the right directory, applying file protection, managing
|
|
4
|
+
backup exclusions, and handling storage pressure on iOS.
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- [Directory Selection Guide](#directory-selection-guide)
|
|
9
|
+
- [FileProtectionType Levels](#fileprotectiontype-levels)
|
|
10
|
+
- [Backup Exclusion (isExcludedFromBackup)](#backup-exclusion-isexcludedfrombackup)
|
|
11
|
+
- [Storage Pressure Handling](#storage-pressure-handling)
|
|
12
|
+
|
|
13
|
+
## Directory Selection Guide
|
|
14
|
+
|
|
15
|
+
iOS provides four primary directories for app data. Choose based on whether
|
|
16
|
+
the data is user-generated, re-creatable, or temporary.
|
|
17
|
+
|
|
18
|
+
| Directory | Backed Up | Purged by System | Use For |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| `Documents/` | Yes | No | User-generated content (documents, exports, user files) |
|
|
21
|
+
| `Library/Application Support/` | Yes | No | App-generated supporting files (databases, config, caches that should survive updates) |
|
|
22
|
+
| `Library/Caches/` | No | Yes (low storage) | Re-creatable data (downloaded images, API responses, computed data) |
|
|
23
|
+
| `tmp/` | No | Yes (anytime) | Truly temporary files (in-progress uploads, scratch files) |
|
|
24
|
+
|
|
25
|
+
### Accessing Standard Directories
|
|
26
|
+
|
|
27
|
+
Use `FileManager.default.urls(for:in:)` to get the correct path. Never
|
|
28
|
+
hardcode paths.
|
|
29
|
+
|
|
30
|
+
```swift
|
|
31
|
+
import Foundation
|
|
32
|
+
|
|
33
|
+
// Documents/ — user-generated content, backed up by iCloud/iTunes
|
|
34
|
+
let documentsURL = FileManager.default.urls(
|
|
35
|
+
for: .documentDirectory, in: .userDomainMask
|
|
36
|
+
).first!
|
|
37
|
+
|
|
38
|
+
// Library/Application Support/ — app-generated supporting data, backed up
|
|
39
|
+
let appSupportURL = FileManager.default.urls(
|
|
40
|
+
for: .applicationSupportDirectory, in: .userDomainMask
|
|
41
|
+
).first!
|
|
42
|
+
// Create if it doesn't exist (not auto-created)
|
|
43
|
+
try FileManager.default.createDirectory(
|
|
44
|
+
at: appSupportURL, withIntermediateDirectories: true
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
// Library/Caches/ — re-creatable data, not backed up, may be purged
|
|
48
|
+
let cachesURL = FileManager.default.urls(
|
|
49
|
+
for: .cachesDirectory, in: .userDomainMask
|
|
50
|
+
).first!
|
|
51
|
+
|
|
52
|
+
// tmp/ — temporary files, purged by system periodically
|
|
53
|
+
let tmpURL = FileManager.default.temporaryDirectory
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Choosing the Right Directory
|
|
57
|
+
|
|
58
|
+
```swift
|
|
59
|
+
// User's exported PDF — Documents/
|
|
60
|
+
let exportURL = documentsURL.appendingPathComponent("Report.pdf")
|
|
61
|
+
try pdfData.write(to: exportURL)
|
|
62
|
+
|
|
63
|
+
// App's SQLite database — Library/Application Support/
|
|
64
|
+
let dbURL = appSupportURL.appendingPathComponent("AppData.sqlite")
|
|
65
|
+
|
|
66
|
+
// Downloaded thumbnail cache — Library/Caches/
|
|
67
|
+
let thumbURL = cachesURL.appendingPathComponent("thumbnails/\(imageID).jpg")
|
|
68
|
+
|
|
69
|
+
// In-progress upload — tmp/
|
|
70
|
+
let uploadURL = tmpURL.appendingPathComponent(UUID().uuidString + ".tmp")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## FileProtectionType Levels
|
|
74
|
+
|
|
75
|
+
iOS encrypts files at rest using Data Protection. The protection level
|
|
76
|
+
determines when the file is accessible relative to the device lock state.
|
|
77
|
+
|
|
78
|
+
Docs: [FileProtectionType](https://sosumi.ai/documentation/foundation/fileprotectiontype),
|
|
79
|
+
[Encrypting Your App's Files](https://sosumi.ai/documentation/uikit/encrypting-your-app-s-files)
|
|
80
|
+
|
|
81
|
+
| Level | Constant | When Accessible | Use For |
|
|
82
|
+
|---|---|---|---|
|
|
83
|
+
| Complete | `.complete` | Only when device is unlocked | Sensitive user data (health records, financial data) |
|
|
84
|
+
| Complete Unless Open | `.completeUnlessOpen` | Can finish if opened before lock | Active downloads, recordings in progress |
|
|
85
|
+
| Until First Auth | `.completeUntilFirstUserAuthentication` | After first unlock (default) | Most app data; background-accessible content |
|
|
86
|
+
| None | `.none` | Always, even before first unlock | Non-sensitive system-required data |
|
|
87
|
+
|
|
88
|
+
### Setting File Protection
|
|
89
|
+
|
|
90
|
+
```swift
|
|
91
|
+
import Foundation
|
|
92
|
+
|
|
93
|
+
// Option 1: Set protection when writing data
|
|
94
|
+
try sensitiveData.write(to: fileURL, options: .completeFileProtection)
|
|
95
|
+
|
|
96
|
+
// Option 2: Set protection via FileManager attributes
|
|
97
|
+
try FileManager.default.setAttributes(
|
|
98
|
+
[.protectionKey: FileProtectionType.complete],
|
|
99
|
+
ofItemAtPath: fileURL.path
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
// Option 3: Set protection on a directory (applies to new files within)
|
|
103
|
+
try FileManager.default.setAttributes(
|
|
104
|
+
[.protectionKey: FileProtectionType.complete],
|
|
105
|
+
ofItemAtPath: secureDirectoryURL.path
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Checking Current Protection Level
|
|
110
|
+
|
|
111
|
+
```swift
|
|
112
|
+
let attributes = try FileManager.default.attributesOfItem(atPath: fileURL.path)
|
|
113
|
+
if let protection = attributes[.protectionKey] as? FileProtectionType {
|
|
114
|
+
switch protection {
|
|
115
|
+
case .complete:
|
|
116
|
+
print("File is fully protected")
|
|
117
|
+
case .completeUnlessOpen:
|
|
118
|
+
print("Protected unless already open")
|
|
119
|
+
case .completeUntilFirstUserAuthentication:
|
|
120
|
+
print("Protected until first unlock (default)")
|
|
121
|
+
case .none:
|
|
122
|
+
print("No encryption")
|
|
123
|
+
default:
|
|
124
|
+
break
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Handling Protected Data Availability
|
|
130
|
+
|
|
131
|
+
Files with `.complete` protection are inaccessible when the device is locked.
|
|
132
|
+
Check availability before accessing:
|
|
133
|
+
|
|
134
|
+
```swift
|
|
135
|
+
import UIKit
|
|
136
|
+
|
|
137
|
+
// Check if protected data is currently available
|
|
138
|
+
if UIApplication.shared.isProtectedDataAvailable {
|
|
139
|
+
// Safe to read .complete files
|
|
140
|
+
let data = try Data(contentsOf: protectedFileURL)
|
|
141
|
+
} else {
|
|
142
|
+
// Wait for device unlock
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Observe availability changes
|
|
146
|
+
NotificationCenter.default.addObserver(
|
|
147
|
+
forName: UIApplication.protectedDataDidBecomeAvailableNotification,
|
|
148
|
+
object: nil,
|
|
149
|
+
queue: .main
|
|
150
|
+
) { _ in
|
|
151
|
+
// Protected files are now accessible
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
NotificationCenter.default.addObserver(
|
|
155
|
+
forName: UIApplication.protectedDataWillBecomeUnavailableNotification,
|
|
156
|
+
object: nil,
|
|
157
|
+
queue: .main
|
|
158
|
+
) { _ in
|
|
159
|
+
// Close file handles to .complete files
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Backup Exclusion (isExcludedFromBackup)
|
|
164
|
+
|
|
165
|
+
Exclude large re-downloadable content from iCloud/iTunes backup to avoid
|
|
166
|
+
bloating the user's backup. Apple may reject apps that back up excessive
|
|
167
|
+
re-creatable data.
|
|
168
|
+
|
|
169
|
+
Docs: [URLResourceValues](https://sosumi.ai/documentation/foundation/urlresourcevalues)
|
|
170
|
+
|
|
171
|
+
### Setting the Exclusion Flag
|
|
172
|
+
|
|
173
|
+
```swift
|
|
174
|
+
import Foundation
|
|
175
|
+
|
|
176
|
+
// Exclude a file or directory from backup
|
|
177
|
+
func excludeFromBackup(_ url: URL) throws {
|
|
178
|
+
var resourceValues = URLResourceValues()
|
|
179
|
+
resourceValues.isExcludedFromBackup = true
|
|
180
|
+
var mutableURL = url
|
|
181
|
+
try mutableURL.setResourceValues(resourceValues)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Usage
|
|
185
|
+
let largeCache = cachesURL.appendingPathComponent("video-cache")
|
|
186
|
+
try excludeFromBackup(largeCache)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Checking the Exclusion Flag
|
|
190
|
+
|
|
191
|
+
```swift
|
|
192
|
+
func isExcludedFromBackup(_ url: URL) throws -> Bool {
|
|
193
|
+
let values = try url.resourceValues(forKeys: [.isExcludedFromBackupKey])
|
|
194
|
+
return values.isExcludedFromBackup ?? false
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### When to Exclude from Backup
|
|
199
|
+
|
|
200
|
+
| Exclude | Keep in Backup |
|
|
201
|
+
|---|---|
|
|
202
|
+
| Downloaded media (images, videos, audio) | User-created documents |
|
|
203
|
+
| API response caches | User preferences and settings |
|
|
204
|
+
| Generated thumbnails or previews | App databases with user data |
|
|
205
|
+
| Offline map tiles | In-app purchase receipts |
|
|
206
|
+
| Pre-computed search indexes | User-generated content |
|
|
207
|
+
|
|
208
|
+
### Common Pattern: Application Support with Exclusion
|
|
209
|
+
|
|
210
|
+
Store re-downloadable data in Application Support but exclude from backup:
|
|
211
|
+
|
|
212
|
+
```swift
|
|
213
|
+
let offlineDataURL = appSupportURL.appendingPathComponent("OfflineData")
|
|
214
|
+
try FileManager.default.createDirectory(
|
|
215
|
+
at: offlineDataURL, withIntermediateDirectories: true
|
|
216
|
+
)
|
|
217
|
+
try excludeFromBackup(offlineDataURL)
|
|
218
|
+
|
|
219
|
+
// Files in this directory persist across app updates but don't bloat backup
|
|
220
|
+
try downloadedData.write(to: offlineDataURL.appendingPathComponent("map-tiles.db"))
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Storage Pressure Handling
|
|
224
|
+
|
|
225
|
+
When the device runs low on storage, iOS may purge files in `Library/Caches/`
|
|
226
|
+
and `tmp/`. Apps should proactively manage storage and respond to low-space
|
|
227
|
+
conditions.
|
|
228
|
+
|
|
229
|
+
### Checking Available Storage
|
|
230
|
+
|
|
231
|
+
```swift
|
|
232
|
+
import Foundation
|
|
233
|
+
|
|
234
|
+
func availableDiskSpace() throws -> Int64 {
|
|
235
|
+
let values = try URL(fileURLWithPath: NSHomeDirectory())
|
|
236
|
+
.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey])
|
|
237
|
+
return values.volumeAvailableCapacityForImportantUsage ?? 0
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Use .volumeAvailableCapacityForImportantUsageKey for important operations
|
|
241
|
+
// Use .volumeAvailableCapacityForOpportunisticUsageKey for optional operations
|
|
242
|
+
// The opportunistic value is always <= the important value
|
|
243
|
+
|
|
244
|
+
func hasSpaceForDownload(bytes: Int64) throws -> Bool {
|
|
245
|
+
let available = try availableDiskSpace()
|
|
246
|
+
return available > bytes
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Responding to Low Storage Notifications
|
|
251
|
+
|
|
252
|
+
```swift
|
|
253
|
+
import UIKit
|
|
254
|
+
|
|
255
|
+
// iOS posts this when storage is critically low (UIKit apps)
|
|
256
|
+
NotificationCenter.default.addObserver(
|
|
257
|
+
forName: UIApplication.didReceiveMemoryWarningNotification,
|
|
258
|
+
object: nil,
|
|
259
|
+
queue: .main
|
|
260
|
+
) { _ in
|
|
261
|
+
// Clear in-memory caches; consider trimming disk caches too
|
|
262
|
+
clearImageCache()
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Check storage proactively at app launch or before large operations
|
|
266
|
+
func checkStorageAndCleanup() throws {
|
|
267
|
+
let availableBytes = try availableDiskSpace()
|
|
268
|
+
let threshold: Int64 = 100 * 1024 * 1024 // 100 MB
|
|
269
|
+
|
|
270
|
+
if availableBytes < threshold {
|
|
271
|
+
try performCleanup()
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Implementing Cleanup Strategies
|
|
277
|
+
|
|
278
|
+
```swift
|
|
279
|
+
import Foundation
|
|
280
|
+
|
|
281
|
+
struct StorageCleaner {
|
|
282
|
+
let cachesURL: URL
|
|
283
|
+
let maxCacheAge: TimeInterval // e.g., 7 days
|
|
284
|
+
let maxCacheSize: Int64 // e.g., 500 MB
|
|
285
|
+
|
|
286
|
+
/// Remove files older than maxCacheAge
|
|
287
|
+
func removeExpiredFiles() throws {
|
|
288
|
+
let contents = try FileManager.default.contentsOfDirectory(
|
|
289
|
+
at: cachesURL,
|
|
290
|
+
includingPropertiesForKeys: [.contentModificationDateKey, .fileSizeKey],
|
|
291
|
+
options: .skipsHiddenFiles
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
let cutoff = Date.now.addingTimeInterval(-maxCacheAge)
|
|
295
|
+
|
|
296
|
+
for fileURL in contents {
|
|
297
|
+
let values = try fileURL.resourceValues(
|
|
298
|
+
forKeys: [.contentModificationDateKey]
|
|
299
|
+
)
|
|
300
|
+
if let modified = values.contentModificationDate, modified < cutoff {
|
|
301
|
+
try FileManager.default.removeItem(at: fileURL)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/// Trim cache to maxCacheSize using LRU eviction
|
|
307
|
+
func trimToSize() throws {
|
|
308
|
+
let contents = try FileManager.default.contentsOfDirectory(
|
|
309
|
+
at: cachesURL,
|
|
310
|
+
includingPropertiesForKeys: [.contentModificationDateKey, .fileSizeKey],
|
|
311
|
+
options: .skipsHiddenFiles
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
// Sort oldest first
|
|
315
|
+
let sorted = try contents.sorted { a, b in
|
|
316
|
+
let aDate = try a.resourceValues(forKeys: [.contentModificationDateKey])
|
|
317
|
+
.contentModificationDate ?? .distantPast
|
|
318
|
+
let bDate = try b.resourceValues(forKeys: [.contentModificationDateKey])
|
|
319
|
+
.contentModificationDate ?? .distantPast
|
|
320
|
+
return aDate < bDate
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Calculate total size
|
|
324
|
+
var totalSize: Int64 = 0
|
|
325
|
+
for fileURL in sorted {
|
|
326
|
+
let values = try fileURL.resourceValues(forKeys: [.fileSizeKey])
|
|
327
|
+
totalSize += Int64(values.fileSize ?? 0)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Delete oldest files until under budget
|
|
331
|
+
for fileURL in sorted {
|
|
332
|
+
guard totalSize > maxCacheSize else { break }
|
|
333
|
+
let values = try fileURL.resourceValues(forKeys: [.fileSizeKey])
|
|
334
|
+
let fileSize = Int64(values.fileSize ?? 0)
|
|
335
|
+
try FileManager.default.removeItem(at: fileURL)
|
|
336
|
+
totalSize -= fileSize
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/// Full cleanup: expired files first, then trim to size
|
|
341
|
+
func performCleanup() throws {
|
|
342
|
+
try removeExpiredFiles()
|
|
343
|
+
try trimToSize()
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Usage
|
|
348
|
+
let cleaner = StorageCleaner(
|
|
349
|
+
cachesURL: FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!,
|
|
350
|
+
maxCacheAge: 7 * 24 * 60 * 60, // 7 days
|
|
351
|
+
maxCacheSize: 500 * 1024 * 1024 // 500 MB
|
|
352
|
+
)
|
|
353
|
+
try cleaner.performCleanup()
|
|
354
|
+
```
|