@amorydev/antigravity-kit 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.
Files changed (217) hide show
  1. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
  2. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
  3. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
  4. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
  5. package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
  6. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
  7. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
  8. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  9. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  10. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  11. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  12. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  13. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  14. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  15. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
  16. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  17. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  18. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  19. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  20. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
  21. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
  22. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  23. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  24. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
  25. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
  26. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +487 -0
  27. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +76 -0
  28. package/.agent/ARCHITECTURE.md +225 -0
  29. package/.agent/agents/backend-specialist.md +263 -0
  30. package/.agent/agents/database-architect.md +226 -0
  31. package/.agent/agents/debugger.md +225 -0
  32. package/.agent/agents/devops-engineer.md +242 -0
  33. package/.agent/agents/documentation-writer.md +104 -0
  34. package/.agent/agents/explorer-agent.md +73 -0
  35. package/.agent/agents/frontend-specialist.md +527 -0
  36. package/.agent/agents/game-developer.md +162 -0
  37. package/.agent/agents/mobile-developer.md +1126 -0
  38. package/.agent/agents/orchestrator.md +400 -0
  39. package/.agent/agents/penetration-tester.md +188 -0
  40. package/.agent/agents/performance-optimizer.md +187 -0
  41. package/.agent/agents/project-planner.md +403 -0
  42. package/.agent/agents/security-auditor.md +170 -0
  43. package/.agent/agents/seo-specialist.md +111 -0
  44. package/.agent/agents/test-engineer.md +158 -0
  45. package/.agent/rules/GEMINI.md +252 -0
  46. package/.agent/skills/api-patterns/SKILL.md +81 -0
  47. package/.agent/skills/api-patterns/api-style.md +42 -0
  48. package/.agent/skills/api-patterns/auth.md +24 -0
  49. package/.agent/skills/api-patterns/documentation.md +26 -0
  50. package/.agent/skills/api-patterns/graphql.md +41 -0
  51. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  52. package/.agent/skills/api-patterns/response.md +37 -0
  53. package/.agent/skills/api-patterns/rest.md +40 -0
  54. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  55. package/.agent/skills/api-patterns/security-testing.md +122 -0
  56. package/.agent/skills/api-patterns/trpc.md +41 -0
  57. package/.agent/skills/api-patterns/versioning.md +22 -0
  58. package/.agent/skills/app-builder/SKILL.md +75 -0
  59. package/.agent/skills/app-builder/agent-coordination.md +71 -0
  60. package/.agent/skills/app-builder/feature-building.md +53 -0
  61. package/.agent/skills/app-builder/project-detection.md +34 -0
  62. package/.agent/skills/app-builder/scaffolding.md +118 -0
  63. package/.agent/skills/app-builder/tech-stack.md +40 -0
  64. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  65. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  66. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  67. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  68. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  69. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  70. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  71. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  72. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +82 -0
  73. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +100 -0
  74. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +106 -0
  75. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +101 -0
  76. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  77. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +93 -0
  78. package/.agent/skills/architecture/SKILL.md +55 -0
  79. package/.agent/skills/architecture/context-discovery.md +43 -0
  80. package/.agent/skills/architecture/examples.md +94 -0
  81. package/.agent/skills/architecture/pattern-selection.md +68 -0
  82. package/.agent/skills/architecture/patterns-reference.md +50 -0
  83. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  84. package/.agent/skills/bash-linux/SKILL.md +199 -0
  85. package/.agent/skills/behavioral-modes/SKILL.md +242 -0
  86. package/.agent/skills/brainstorming/SKILL.md +163 -0
  87. package/.agent/skills/brainstorming/dynamic-questioning.md +350 -0
  88. package/.agent/skills/clean-code/SKILL.md +201 -0
  89. package/.agent/skills/code-review-checklist/SKILL.md +109 -0
  90. package/.agent/skills/database-design/SKILL.md +52 -0
  91. package/.agent/skills/database-design/database-selection.md +43 -0
  92. package/.agent/skills/database-design/indexing.md +39 -0
  93. package/.agent/skills/database-design/migrations.md +48 -0
  94. package/.agent/skills/database-design/optimization.md +36 -0
  95. package/.agent/skills/database-design/orm-selection.md +30 -0
  96. package/.agent/skills/database-design/schema-design.md +56 -0
  97. package/.agent/skills/database-design/scripts/schema_validator.py +172 -0
  98. package/.agent/skills/deployment-procedures/SKILL.md +241 -0
  99. package/.agent/skills/doc.md +177 -0
  100. package/.agent/skills/docker-expert/SKILL.md +409 -0
  101. package/.agent/skills/documentation-templates/SKILL.md +194 -0
  102. package/.agent/skills/frontend-design/SKILL.md +396 -0
  103. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  104. package/.agent/skills/frontend-design/color-system.md +311 -0
  105. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  106. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  107. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  108. package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
  109. package/.agent/skills/frontend-design/typography-system.md +345 -0
  110. package/.agent/skills/frontend-design/ux-psychology.md +541 -0
  111. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  112. package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
  113. package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
  114. package/.agent/skills/game-development/SKILL.md +167 -0
  115. package/.agent/skills/game-development/game-art/SKILL.md +185 -0
  116. package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
  117. package/.agent/skills/game-development/game-design/SKILL.md +129 -0
  118. package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
  119. package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
  120. package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
  121. package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
  122. package/.agent/skills/game-development/web-games/SKILL.md +150 -0
  123. package/.agent/skills/geo-fundamentals/SKILL.md +156 -0
  124. package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
  125. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  126. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  127. package/.agent/skills/lint-and-validate/SKILL.md +45 -0
  128. package/.agent/skills/lint-and-validate/scripts/lint_runner.py +172 -0
  129. package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
  130. package/.agent/skills/mcp-builder/SKILL.md +176 -0
  131. package/.agent/skills/mobile-design/SKILL.md +937 -0
  132. package/.agent/skills/mobile-design/decision-trees.md +516 -0
  133. package/.agent/skills/mobile-design/mobile-backend.md +491 -0
  134. package/.agent/skills/mobile-design/mobile-color-system.md +420 -0
  135. package/.agent/skills/mobile-design/mobile-debugging.md +122 -0
  136. package/.agent/skills/mobile-design/mobile-design-thinking.md +598 -0
  137. package/.agent/skills/mobile-design/mobile-navigation.md +458 -0
  138. package/.agent/skills/mobile-design/mobile-performance.md +1050 -0
  139. package/.agent/skills/mobile-design/mobile-testing.md +356 -0
  140. package/.agent/skills/mobile-design/mobile-typography.md +433 -0
  141. package/.agent/skills/mobile-design/platform-android.md +666 -0
  142. package/.agent/skills/mobile-design/platform-ios.md +561 -0
  143. package/.agent/skills/mobile-design/platform-kmp.md +770 -0
  144. package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
  145. package/.agent/skills/mobile-design/touch-psychology.md +537 -0
  146. package/.agent/skills/nestjs-expert/SKILL.md +552 -0
  147. package/.agent/skills/nextjs-best-practices/SKILL.md +203 -0
  148. package/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
  149. package/.agent/skills/parallel-agents/SKILL.md +175 -0
  150. package/.agent/skills/performance-profiling/SKILL.md +143 -0
  151. package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
  152. package/.agent/skills/plan-writing/SKILL.md +152 -0
  153. package/.agent/skills/powershell-windows/SKILL.md +167 -0
  154. package/.agent/skills/prisma-expert/SKILL.md +355 -0
  155. package/.agent/skills/python-patterns/SKILL.md +441 -0
  156. package/.agent/skills/react-patterns/SKILL.md +198 -0
  157. package/.agent/skills/red-team-tactics/SKILL.md +199 -0
  158. package/.agent/skills/seo-fundamentals/SKILL.md +129 -0
  159. package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
  160. package/.agent/skills/server-management/SKILL.md +161 -0
  161. package/.agent/skills/systematic-debugging/SKILL.md +109 -0
  162. package/.agent/skills/tailwind-patterns/SKILL.md +269 -0
  163. package/.agent/skills/tdd-workflow/SKILL.md +149 -0
  164. package/.agent/skills/testing-patterns/SKILL.md +178 -0
  165. package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
  166. package/.agent/skills/typescript-expert/SKILL.md +429 -0
  167. package/.agent/skills/typescript-expert/references/tsconfig-strict.json +92 -0
  168. package/.agent/skills/typescript-expert/references/typescript-cheatsheet.md +383 -0
  169. package/.agent/skills/typescript-expert/references/utility-types.ts +335 -0
  170. package/.agent/skills/typescript-expert/scripts/ts_diagnostic.py +203 -0
  171. package/.agent/skills/ui-ux-pro-max/SKILL.md +351 -0
  172. package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
  173. package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
  174. package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
  175. package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
  176. package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
  177. package/.agent/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  178. package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  179. package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  180. package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  181. package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  182. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  183. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  184. package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  185. package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  186. package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  187. package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  188. package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  189. package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  190. package/.agent/skills/ui-ux-pro-max/data/styles.csv +59 -0
  191. package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
  192. package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  193. package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  194. package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  195. package/.agent/skills/ui-ux-pro-max/scripts/core.py +257 -0
  196. package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +487 -0
  197. package/.agent/skills/ui-ux-pro-max/scripts/search.py +76 -0
  198. package/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
  199. package/.agent/skills/vulnerability-scanner/checklists.md +121 -0
  200. package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
  201. package/.agent/skills/webapp-testing/SKILL.md +187 -0
  202. package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
  203. package/.agent/workflows/brainstorm.md +113 -0
  204. package/.agent/workflows/create.md +59 -0
  205. package/.agent/workflows/debug.md +103 -0
  206. package/.agent/workflows/deploy.md +176 -0
  207. package/.agent/workflows/enhance.md +63 -0
  208. package/.agent/workflows/orchestrate.md +237 -0
  209. package/.agent/workflows/plan.md +89 -0
  210. package/.agent/workflows/preview.md +80 -0
  211. package/.agent/workflows/status.md +86 -0
  212. package/.agent/workflows/test.md +144 -0
  213. package/.agent/workflows/ui-ux-pro-max.md +231 -0
  214. package/LICENSE +21 -0
  215. package/README.md +120 -0
  216. package/bin/cli.js +81 -0
  217. package/package.json +29 -0
@@ -0,0 +1,770 @@
1
+ ---
2
+ name: platform-kmp
3
+ description: Kotlin Multiplatform (KMP) architecture, shared logic patterns, expect/actual mechanism, iOS framework integration, and Compose Multiplatform UI.
4
+ ---
5
+
6
+ # Kotlin Multiplatform (KMP) Guide
7
+
8
+ > **Philosophy:** Share business logic, not UI (unless using Compose Multiplatform).
9
+ > **Core Principle:** Write once in Kotlin, compile to native iOS/Android.
10
+
11
+ ---
12
+
13
+ ## 🎯 When to Use KMP
14
+
15
+ ### ✅ GOOD Use Cases:
16
+ - **Business Logic Sharing**: Networking, data models, repositories, use cases
17
+ - **Type-Safe APIs**: Generate shared API clients from OpenAPI/GraphQL
18
+ - **Database Logic**: SQLDelight for shared database code
19
+ - **Validation Logic**: Form validation, business rules
20
+ - **Utilities**: Date formatting, crypto, parsing
21
+ - **Analytics/Logging**: Shared tracking logic
22
+
23
+ ### ❌ NOT Recommended For:
24
+ - **UI Code** (unless Compose Multiplatform)
25
+ - **Platform-Specific Features**: Camera, contacts, biometrics (use expect/actual)
26
+ - **Simple Apps**: Overhead not worth it for CRUD apps
27
+ - **Teams Without Kotlin Expertise**: Steep learning curve
28
+
29
+ ---
30
+
31
+ ## 🏗️ KMP Architecture Layers
32
+ ```
33
+ ┌─────────────────────────────────────────────────────────────┐
34
+ │ PLATFORM LAYER │
35
+ │ ┌──────────────────────┐ ┌──────────────────────┐ │
36
+ │ │ iOS (SwiftUI) │ │ Android (Compose) │ │
37
+ │ │ - Views │ │ - Composables │ │
38
+ │ │ - ViewModels │ │ - ViewModels │ │
39
+ │ │ - Navigation │ │ - Navigation │ │
40
+ │ └──────────────────────┘ └──────────────────────┘ │
41
+ ├─────────────────────────────────────────────────────────────┤
42
+ │ SHARED KOTLIN CODE │
43
+ │ ┌─────────────────────────────────────────────────────┐ │
44
+ │ │ PRESENTATION LAYER │ │
45
+ │ │ - ViewModels (if sharing) │ │
46
+ │ │ - State classes │ │
47
+ │ │ - UI Events │ │
48
+ │ └─────────────────────────────────────────────────────┘ │
49
+ │ ┌─────────────────────────────────────────────────────┐ │
50
+ │ │ DOMAIN LAYER │ │
51
+ │ │ - Use Cases │ │
52
+ │ │ - Business Logic │ │
53
+ │ │ - Domain Models │ │
54
+ │ └─────────────────────────────────────────────────────┘ │
55
+ │ ┌─────────────────────────────────────────────────────┐ │
56
+ │ │ DATA LAYER │ │
57
+ │ │ - Repositories │ │
58
+ │ │ - API Clients (Ktor) │ │
59
+ │ │ - Database (SQLDelight) │ │
60
+ │ │ - Data Models / DTOs │ │
61
+ │ └─────────────────────────────────────────────────────┘ │
62
+ │ ┌─────────────────────────────────────────────────────┐ │
63
+ │ │ PLATFORM-SPECIFIC (expect/actual) │ │
64
+ │ │ - File I/O │ │
65
+ │ │ - Platform APIs │ │
66
+ │ │ - Native Features │ │
67
+ │ └─────────────────────────────────────────────────────┘ │
68
+ └─────────────────────────────────────────────────────────────┘
69
+ ```
70
+
71
+ ---
72
+
73
+ ## 🔧 Project Structure
74
+ ```
75
+ my-kmp-app/
76
+ ├── shared/
77
+ │ ├── src/
78
+ │ │ ├── commonMain/kotlin/
79
+ │ │ │ ├── data/
80
+ │ │ │ │ ├── api/
81
+ │ │ │ │ │ └── ApiClient.kt
82
+ │ │ │ │ ├── database/
83
+ │ │ │ │ │ └── Database.kt (SQLDelight)
84
+ │ │ │ │ └── repository/
85
+ │ │ │ │ └── UserRepository.kt
86
+ │ │ │ ├── domain/
87
+ │ │ │ │ ├── model/
88
+ │ │ │ │ │ └── User.kt
89
+ │ │ │ │ └── usecase/
90
+ │ │ │ │ └── GetUserUseCase.kt
91
+ │ │ │ └── Platform.kt (expect declaration)
92
+ │ │ │
93
+ │ │ ├── androidMain/kotlin/
94
+ │ │ │ └── Platform.android.kt (actual implementation)
95
+ │ │ │
96
+ │ │ └── iosMain/kotlin/
97
+ │ │ └── Platform.ios.kt (actual implementation)
98
+ │ │
99
+ │ └── build.gradle.kts
100
+
101
+ ├── androidApp/
102
+ │ ├── src/main/
103
+ │ │ ├── java/
104
+ │ │ │ └── com/myapp/
105
+ │ │ │ ├── ui/
106
+ │ │ │ │ └── MainActivity.kt
107
+ │ │ │ └── viewmodel/
108
+ │ │ │ └── UserViewModel.kt
109
+ │ │ └── AndroidManifest.xml
110
+ │ └── build.gradle.kts
111
+
112
+ └── iosApp/
113
+ ├── iosApp/
114
+ │ ├── ContentView.swift
115
+ │ └── UserViewModel.swift
116
+ └── iosApp.xcodeproj
117
+ ```
118
+
119
+ ---
120
+
121
+ ## 📦 Core Libraries
122
+
123
+ ### Essential KMP Libraries
124
+ ```kotlin
125
+ // shared/build.gradle.kts
126
+
127
+ kotlin {
128
+ // Ktor for networking
129
+ sourceSets {
130
+ val commonMain by getting {
131
+ dependencies {
132
+ // Networking
133
+ implementation("io.ktor:ktor-client-core:2.3.7")
134
+ implementation("io.ktor:ktor-client-content-negotiation:2.3.7")
135
+ implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")
136
+
137
+ // Serialization
138
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
139
+
140
+ // Coroutines
141
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
142
+
143
+ // DateTime
144
+ implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0")
145
+
146
+ // DI (optional)
147
+ implementation("io.insert-koin:koin-core:3.5.3")
148
+ }
149
+ }
150
+
151
+ val androidMain by getting {
152
+ dependencies {
153
+ implementation("io.ktor:ktor-client-okhttp:2.3.7")
154
+ }
155
+ }
156
+
157
+ val iosMain by getting {
158
+ dependencies {
159
+ implementation("io.ktor:ktor-client-darwin:2.3.7")
160
+ }
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ ### SQLDelight Setup
167
+ ```kotlin
168
+ // shared/build.gradle.kts
169
+
170
+ plugins {
171
+ id("app.cash.sqldelight") version "2.0.1"
172
+ }
173
+
174
+ sqldelight {
175
+ databases {
176
+ create("AppDatabase") {
177
+ packageName.set("com.myapp.database")
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ---
184
+
185
+ ## 🎭 expect/actual Mechanism
186
+
187
+ ### Pattern 1: Platform-Specific Implementation
188
+ ```kotlin
189
+ // commonMain/Platform.kt
190
+ expect class Platform() {
191
+ val name: String
192
+ }
193
+
194
+ expect fun getPlatform(): Platform
195
+
196
+ // androidMain/Platform.android.kt
197
+ actual class Platform actual constructor() {
198
+ actual val name: String = "Android ${android.os.Build.VERSION.SDK_INT}"
199
+ }
200
+
201
+ actual fun getPlatform(): Platform = Platform()
202
+
203
+ // iosMain/Platform.ios.kt
204
+ import platform.UIKit.UIDevice
205
+
206
+ actual class Platform actual constructor() {
207
+ actual val name: String =
208
+ UIDevice.currentDevice.systemName() + " " +
209
+ UIDevice.currentDevice.systemVersion
210
+ }
211
+
212
+ actual fun getPlatform(): Platform = Platform()
213
+ ```
214
+
215
+ ### Pattern 2: Platform-Specific API Access
216
+ ```kotlin
217
+ // commonMain/storage/SecureStorage.kt
218
+ expect class SecureStorage {
219
+ suspend fun save(key: String, value: String)
220
+ suspend fun get(key: String): String?
221
+ suspend fun delete(key: String)
222
+ }
223
+
224
+ // androidMain/storage/SecureStorage.android.kt
225
+ import androidx.security.crypto.EncryptedSharedPreferences
226
+ import androidx.security.crypto.MasterKey
227
+
228
+ actual class SecureStorage(private val context: Context) {
229
+ private val masterKey = MasterKey.Builder(context)
230
+ .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
231
+ .build()
232
+
233
+ private val prefs = EncryptedSharedPreferences.create(
234
+ context,
235
+ "secure_prefs",
236
+ masterKey,
237
+ EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
238
+ EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
239
+ )
240
+
241
+ actual suspend fun save(key: String, value: String) {
242
+ prefs.edit().putString(key, value).apply()
243
+ }
244
+
245
+ actual suspend fun get(key: String): String? {
246
+ return prefs.getString(key, null)
247
+ }
248
+
249
+ actual suspend fun delete(key: String) {
250
+ prefs.edit().remove(key).apply()
251
+ }
252
+ }
253
+
254
+ // iosMain/storage/SecureStorage.ios.kt
255
+ import platform.Security.*
256
+ import platform.Foundation.*
257
+
258
+ actual class SecureStorage {
259
+ actual suspend fun save(key: String, value: String) {
260
+ val query = mapOf<Any?, Any?>(
261
+ kSecClass to kSecClassGenericPassword,
262
+ kSecAttrAccount to key,
263
+ kSecValueData to value.encodeToByteArray().toNSData()
264
+ )
265
+ SecItemDelete(query as CFDictionaryRef)
266
+ SecItemAdd(query as CFDictionaryRef, null)
267
+ }
268
+
269
+ actual suspend fun get(key: String): String? {
270
+ val query = mapOf<Any?, Any?>(
271
+ kSecClass to kSecClassGenericPassword,
272
+ kSecAttrAccount to key,
273
+ kSecReturnData to kCFBooleanTrue,
274
+ kSecMatchLimit to kSecMatchLimitOne
275
+ )
276
+
277
+ val result = memScoped {
278
+ val resultPtr = alloc<CFTypeRefVar>()
279
+ val status = SecItemCopyMatching(query as CFDictionaryRef, resultPtr.ptr)
280
+
281
+ if (status == errSecSuccess) {
282
+ val data = resultPtr.value as NSData
283
+ NSString.create(data, NSUTF8StringEncoding) as String
284
+ } else null
285
+ }
286
+
287
+ return result
288
+ }
289
+
290
+ actual suspend fun delete(key: String) {
291
+ val query = mapOf<Any?, Any?>(
292
+ kSecClass to kSecClassGenericPassword,
293
+ kSecAttrAccount to key
294
+ )
295
+ SecItemDelete(query as CFDictionaryRef)
296
+ }
297
+ }
298
+ ```
299
+
300
+ ---
301
+
302
+ ## 🌐 Networking with Ktor
303
+ ```kotlin
304
+ // commonMain/api/ApiClient.kt
305
+
306
+ import io.ktor.client.*
307
+ import io.ktor.client.call.*
308
+ import io.ktor.client.plugins.contentnegotiation.*
309
+ import io.ktor.client.request.*
310
+ import io.ktor.serialization.kotlinx.json.*
311
+ import kotlinx.serialization.json.Json
312
+
313
+ class ApiClient {
314
+ private val client = HttpClient {
315
+ install(ContentNegotiation) {
316
+ json(Json {
317
+ ignoreUnknownKeys = true
318
+ isLenient = true
319
+ })
320
+ }
321
+ }
322
+
323
+ suspend fun getUsers(): List<User> {
324
+ return client.get("https://api.example.com/users").body()
325
+ }
326
+
327
+ suspend fun createUser(user: User): User {
328
+ return client.post("https://api.example.com/users") {
329
+ setBody(user)
330
+ }.body()
331
+ }
332
+ }
333
+
334
+ @Serializable
335
+ data class User(
336
+ val id: String,
337
+ val name: String,
338
+ val email: String
339
+ )
340
+ ```
341
+
342
+ ---
343
+
344
+ ## 💾 Database with SQLDelight
345
+ ```sql
346
+ -- shared/src/commonMain/sqldelight/com/myapp/User.sq
347
+
348
+ CREATE TABLE User (
349
+ id TEXT PRIMARY KEY NOT NULL,
350
+ name TEXT NOT NULL,
351
+ email TEXT NOT NULL,
352
+ createdAt INTEGER NOT NULL
353
+ );
354
+
355
+ selectAll:
356
+ SELECT * FROM User;
357
+
358
+ selectById:
359
+ SELECT * FROM User WHERE id = ?;
360
+
361
+ insert:
362
+ INSERT OR REPLACE INTO User(id, name, email, createdAt)
363
+ VALUES (?, ?, ?, ?);
364
+
365
+ deleteById:
366
+ DELETE FROM User WHERE id = ?;
367
+ ```
368
+ ```kotlin
369
+ // commonMain/database/UserDatabase.kt
370
+
371
+ class UserDatabase(driver: SqlDriver) {
372
+ private val database = AppDatabase(driver)
373
+ private val queries = database.userQueries
374
+
375
+ fun getAllUsers(): List<User> {
376
+ return queries.selectAll().executeAsList().map { it.toDomain() }
377
+ }
378
+
379
+ fun getUserById(id: String): User? {
380
+ return queries.selectById(id).executeAsOneOrNull()?.toDomain()
381
+ }
382
+
383
+ fun insertUser(user: User) {
384
+ queries.insert(
385
+ id = user.id,
386
+ name = user.name,
387
+ email = user.email,
388
+ createdAt = Clock.System.now().toEpochMilliseconds()
389
+ )
390
+ }
391
+
392
+ fun deleteUser(id: String) {
393
+ queries.deleteById(id)
394
+ }
395
+ }
396
+
397
+ // Mapper
398
+ private fun com.myapp.User.toDomain(): User {
399
+ return User(
400
+ id = this.id,
401
+ name = this.name,
402
+ email = this.email
403
+ )
404
+ }
405
+ ```
406
+
407
+ ### Platform-Specific Drivers
408
+ ```kotlin
409
+ // androidMain/database/DriverFactory.android.kt
410
+ import app.cash.sqldelight.db.SqlDriver
411
+ import app.cash.sqldelight.driver.android.AndroidSqliteDriver
412
+ import com.myapp.database.AppDatabase
413
+
414
+ actual class DriverFactory(private val context: Context) {
415
+ actual fun createDriver(): SqlDriver {
416
+ return AndroidSqliteDriver(
417
+ AppDatabase.Schema,
418
+ context,
419
+ "app.db"
420
+ )
421
+ }
422
+ }
423
+
424
+ // iosMain/database/DriverFactory.ios.kt
425
+ import app.cash.sqldelight.db.SqlDriver
426
+ import app.cash.sqldelight.driver.native.NativeSqliteDriver
427
+ import com.myapp.database.AppDatabase
428
+
429
+ actual class DriverFactory {
430
+ actual fun createDriver(): SqlDriver {
431
+ return NativeSqliteDriver(
432
+ AppDatabase.Schema,
433
+ "app.db"
434
+ )
435
+ }
436
+ }
437
+ ```
438
+
439
+ ---
440
+
441
+ ## 🎨 Compose Multiplatform (Optional UI Sharing)
442
+
443
+ ### Setup
444
+ ```kotlin
445
+ // shared/build.gradle.kts
446
+
447
+ kotlin {
448
+ androidTarget()
449
+
450
+ listOf(
451
+ iosX64(),
452
+ iosArm64(),
453
+ iosSimulatorArm64()
454
+ ).forEach {
455
+ it.binaries.framework {
456
+ baseName = "shared"
457
+ isStatic = true
458
+ }
459
+ }
460
+
461
+ sourceSets {
462
+ val commonMain by getting {
463
+ dependencies {
464
+ implementation(compose.runtime)
465
+ implementation(compose.foundation)
466
+ implementation(compose.material3)
467
+ implementation(compose.ui)
468
+ implementation(compose.components.resources)
469
+ implementation(compose.components.uiToolingPreview)
470
+ }
471
+ }
472
+ }
473
+ }
474
+
475
+ compose.experimental {
476
+ web.application {}
477
+ }
478
+ ```
479
+
480
+ ### Shared UI Example
481
+ ```kotlin
482
+ // commonMain/ui/UserListScreen.kt
483
+
484
+ @Composable
485
+ fun UserListScreen(
486
+ viewModel: UserViewModel
487
+ ) {
488
+ val users by viewModel.users.collectAsState()
489
+ val isLoading by viewModel.isLoading.collectAsState()
490
+
491
+ if (isLoading) {
492
+ Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
493
+ CircularProgressIndicator()
494
+ }
495
+ } else {
496
+ LazyColumn {
497
+ items(users) { user ->
498
+ UserItem(user = user)
499
+ }
500
+ }
501
+ }
502
+ }
503
+
504
+ @Composable
505
+ fun UserItem(user: User) {
506
+ Card(
507
+ modifier = Modifier
508
+ .fillMaxWidth()
509
+ .padding(16.dp)
510
+ ) {
511
+ Column(Modifier.padding(16.dp)) {
512
+ Text(
513
+ text = user.name,
514
+ style = MaterialTheme.typography.titleMedium
515
+ )
516
+ Text(
517
+ text = user.email,
518
+ style = MaterialTheme.typography.bodyMedium
519
+ )
520
+ }
521
+ }
522
+ }
523
+ ```
524
+
525
+ ---
526
+
527
+ ## 🍎 iOS Integration
528
+
529
+ ### Creating Framework for iOS
530
+ ```kotlin
531
+ // shared/build.gradle.kts
532
+
533
+ kotlin {
534
+ listOf(
535
+ iosX64(),
536
+ iosArm64(),
537
+ iosSimulatorArm64()
538
+ ).forEach { iosTarget ->
539
+ iosTarget.binaries.framework {
540
+ baseName = "shared"
541
+ isStatic = true // or false for dynamic
542
+
543
+ // Export dependencies for iOS
544
+ export("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
545
+ }
546
+ }
547
+ }
548
+ ```
549
+
550
+ ### Swift Integration
551
+ ```swift
552
+ // iosApp/UserViewModel.swift
553
+
554
+ import shared
555
+ import Combine
556
+
557
+ @MainActor
558
+ class UserViewModel: ObservableObject {
559
+ @Published var users: [User] = []
560
+ @Published var isLoading = false
561
+ @Published var error: String?
562
+
563
+ private let repository = UserRepository()
564
+
565
+ func loadUsers() {
566
+ isLoading = true
567
+
568
+ repository.getUsers { result, error in
569
+ DispatchQueue.main.async {
570
+ self.isLoading = false
571
+
572
+ if let users = result {
573
+ self.users = users
574
+ } else if let error = error {
575
+ self.error = error.localizedDescription
576
+ }
577
+ }
578
+ }
579
+ }
580
+ }
581
+ ```
582
+
583
+ ### Handling Kotlin Coroutines in Swift
584
+ ```kotlin
585
+ // shared/src/iosMain/kotlin/util/CoroutineHelper.kt
586
+
587
+ // Wrapper for iOS to convert suspend functions to callbacks
588
+ class IOSCoroutineHelper {
589
+ fun <T> execute(
590
+ block: suspend () -> T,
591
+ onSuccess: (T) -> Unit,
592
+ onError: (Throwable) -> Unit
593
+ ) {
594
+ MainScope().launch {
595
+ try {
596
+ val result = block()
597
+ onSuccess(result)
598
+ } catch (e: Throwable) {
599
+ onError(e)
600
+ }
601
+ }
602
+ }
603
+ }
604
+ ```
605
+ ```swift
606
+ // Usage in Swift
607
+ let helper = IOSCoroutineHelper()
608
+
609
+ helper.execute(
610
+ block: { try await repository.getUsers() },
611
+ onSuccess: { users in
612
+ self.users = users
613
+ },
614
+ onError: { error in
615
+ self.error = error.localizedDescription
616
+ }
617
+ )
618
+ ```
619
+
620
+ ---
621
+
622
+ ## 🔄 State Management in KMP
623
+
624
+ ### ViewModel Sharing (Optional)
625
+ ```kotlin
626
+ // commonMain/viewmodel/UserViewModel.kt
627
+
628
+ class UserViewModel(
629
+ private val getUsersUseCase: GetUsersUseCase
630
+ ) {
631
+ private val _state = MutableStateFlow<UiState>(UiState.Loading)
632
+ val state: StateFlow<UiState> = _state.asStateFlow()
633
+
634
+ fun loadUsers() {
635
+ viewModelScope.launch {
636
+ _state.value = UiState.Loading
637
+ try {
638
+ val users = getUsersUseCase()
639
+ _state.value = UiState.Success(users)
640
+ } catch (e: Exception) {
641
+ _state.value = UiState.Error(e.message ?: "Unknown error")
642
+ }
643
+ }
644
+ }
645
+
646
+ sealed class UiState {
647
+ object Loading : UiState()
648
+ data class Success(val users: List<User>) : UiState()
649
+ data class Error(val message: String) : UiState()
650
+ }
651
+ }
652
+ ```
653
+
654
+ ---
655
+
656
+ ## ⚡ Performance Considerations
657
+
658
+ ### iOS Framework Size
659
+ ```bash
660
+ # Check framework size
661
+ du -sh iosApp/Pods/shared/shared.framework
662
+
663
+ # Optimize:
664
+ # 1. Use static framework (smaller)
665
+ # 2. Enable code stripping
666
+ # 3. Use ProGuard/R8 for Android
667
+ ```
668
+
669
+ ### Memory Management
670
+ ```kotlin
671
+ // iOS: Be careful with cycles
672
+ class MyClass {
673
+ private var callback: (() -> Unit)? = null
674
+
675
+ fun setCallback(cb: @escaping () -> Void) {
676
+ // Weak reference to avoid retain cycles
677
+ callback = { [weak self] in
678
+ cb()
679
+ }
680
+ }
681
+ }
682
+ ```
683
+
684
+ ---
685
+
686
+ ## 🚫 KMP Anti-Patterns
687
+
688
+ | ❌ NEVER | ✅ ALWAYS | Why |
689
+ |----------|----------|-----|
690
+ | Share UI code (without Compose MP) | Share logic only | Platform UI feels native |
691
+ | Use Android APIs in commonMain | Use expect/actual | Won't compile for iOS |
692
+ | Block main thread | Use coroutines | Freezing on iOS |
693
+ | Ignore iOS memory model | Understand freezing/thawing | Crashes on iOS |
694
+ | Skip platform testing | Test on both platforms | Subtle bugs per platform |
695
+ | Use mutable shared state carelessly | Immutable data or StateFlow | Thread safety issues |
696
+
697
+ ---
698
+
699
+ ## 📋 KMP Checklist
700
+
701
+ ### Before Starting KMP Project
702
+
703
+ - [ ] **Team has Kotlin expertise?**
704
+ - [ ] **Business logic complex enough to justify KMP?**
705
+ - [ ] **Both iOS and Android targets needed?**
706
+ - [ ] **UI will be platform-specific or Compose MP?**
707
+ - [ ] **CI/CD supports iOS + Android builds?**
708
+
709
+ ### Project Setup
710
+
711
+ - [ ] **Gradle configured for multiplatform?**
712
+ - [ ] **expect/actual declarations planned?**
713
+ - [ ] **SQLDelight or other DB set up?**
714
+ - [ ] **Ktor configured with platform engines?**
715
+ - [ ] **iOS framework exported correctly?**
716
+ - [ ] **CocoaPods or SPM integration working?**
717
+
718
+ ### Development
719
+
720
+ - [ ] **Shared code in commonMain only?**
721
+ - [ ] **Platform-specific code in androidMain/iosMain?**
722
+ - [ ] **Coroutines used correctly (MainScope for iOS)?**
723
+ - [ ] **Serialization working on both platforms?**
724
+ - [ ] **Database migrations planned?**
725
+
726
+ ### iOS Integration
727
+
728
+ - [ ] **Framework builds successfully?**
729
+ - [ ] **Swift can import and use shared code?**
730
+ - [ ] **Memory leaks checked (Xcode Instruments)?**
731
+ - [ ] **Callback-based APIs for iOS (if needed)?**
732
+ - [ ] **iOS-specific permissions handled?**
733
+
734
+ ---
735
+
736
+ ## 🎯 Decision: KMP vs React Native vs Flutter
737
+ ```
738
+ USE KMP IF:
739
+ ├── Existing native iOS/Android apps
740
+ ├── Team has strong Kotlin expertise
741
+ ├── Need native UI feel on both platforms
742
+ ├── Complex business logic to share
743
+ └── Performance critical (games, heavy computation)
744
+
745
+ USE REACT NATIVE IF:
746
+ ├── Team has JavaScript/React expertise
747
+ ├── Need OTA updates
748
+ ├── Rapid iteration important
749
+ └── Large ecosystem of libraries needed
750
+
751
+ USE FLUTTER IF:
752
+ ├── Need pixel-perfect custom UI
753
+ ├── Team comfortable with Dart
754
+ ├── Strong animation requirements
755
+ └── Greenfield project
756
+ ```
757
+
758
+ ---
759
+
760
+ ## 📚 Resources
761
+
762
+ - [Official KMP Docs](https://kotlinlang.org/docs/multiplatform.html)
763
+ - [KMP Samples](https://github.com/Kotlin/kmm-samples)
764
+ - [Ktor Documentation](https://ktor.io/)
765
+ - [SQLDelight](https://cashapp.github.io/sqldelight/)
766
+ - [Compose Multiplatform](https://www.jetbrains.com/lp/compose-multiplatform/)
767
+
768
+ ---
769
+
770
+ > **Remember:** KMP is about sharing logic, not UI (unless you choose Compose Multiplatform). Keep platform UI native for best user experience.