androjack-mcp 1.3.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 (70) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +34 -0
  3. package/.github/pull_request_template.md +16 -0
  4. package/CONTRIBUTING.md +27 -0
  5. package/LICENSE +21 -0
  6. package/README.md +592 -0
  7. package/SECURITY.md +26 -0
  8. package/assets/AndroJack banner.png +0 -0
  9. package/assets/killer_argument.png +0 -0
  10. package/build/constants.js +412 -0
  11. package/build/http-server.js +163 -0
  12. package/build/http.js +151 -0
  13. package/build/index.js +553 -0
  14. package/build/install.js +379 -0
  15. package/build/logger.js +57 -0
  16. package/build/tools/api-level.js +170 -0
  17. package/build/tools/api36-compliance.js +282 -0
  18. package/build/tools/architecture.js +75 -0
  19. package/build/tools/build-publish.js +362 -0
  20. package/build/tools/component.js +90 -0
  21. package/build/tools/debugger.js +82 -0
  22. package/build/tools/gradle.js +234 -0
  23. package/build/tools/kmp.js +348 -0
  24. package/build/tools/kotlin-patterns.js +500 -0
  25. package/build/tools/large-screen.js +366 -0
  26. package/build/tools/m3-expressive.js +447 -0
  27. package/build/tools/navigation3.js +331 -0
  28. package/build/tools/ondevice-ai.js +283 -0
  29. package/build/tools/permissions.js +404 -0
  30. package/build/tools/play-policy.js +221 -0
  31. package/build/tools/scalability.js +621 -0
  32. package/build/tools/search.js +89 -0
  33. package/build/tools/testing.js +439 -0
  34. package/build/tools/wear.js +337 -0
  35. package/build/tools/xr.js +274 -0
  36. package/config/antigravity_mcp.json +32 -0
  37. package/config/claude_desktop_config.json +17 -0
  38. package/config/cursor_mcp.json +21 -0
  39. package/config/jetbrains_mcp.json +28 -0
  40. package/config/kiro_mcp.json +40 -0
  41. package/config/vscode_mcp.json +24 -0
  42. package/config/windsurf_mcp.json +18 -0
  43. package/package.json +51 -0
  44. package/src/constants.ts +436 -0
  45. package/src/http-server.ts +186 -0
  46. package/src/http.ts +190 -0
  47. package/src/index.ts +702 -0
  48. package/src/install.ts +441 -0
  49. package/src/logger.ts +67 -0
  50. package/src/tools/api-level.ts +198 -0
  51. package/src/tools/api36-compliance.ts +289 -0
  52. package/src/tools/architecture.ts +94 -0
  53. package/src/tools/build-publish.ts +379 -0
  54. package/src/tools/component.ts +106 -0
  55. package/src/tools/debugger.ts +111 -0
  56. package/src/tools/gradle.ts +288 -0
  57. package/src/tools/kmp.ts +352 -0
  58. package/src/tools/kotlin-patterns.ts +534 -0
  59. package/src/tools/large-screen.ts +391 -0
  60. package/src/tools/m3-expressive.ts +473 -0
  61. package/src/tools/navigation3.ts +338 -0
  62. package/src/tools/ondevice-ai.ts +287 -0
  63. package/src/tools/permissions.ts +445 -0
  64. package/src/tools/play-policy.ts +229 -0
  65. package/src/tools/scalability.ts +646 -0
  66. package/src/tools/search.ts +112 -0
  67. package/src/tools/testing.ts +460 -0
  68. package/src/tools/wear.ts +343 -0
  69. package/src/tools/xr.ts +278 -0
  70. package/tsconfig.json +17 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Tool 5 – gradle_dependency_checker
3
+ *
4
+ * Looks up the latest stable version of any Android/Kotlin/Jetpack library
5
+ * from Google Maven and Maven Central.
6
+ *
7
+ * Correctness guarantees:
8
+ * - BOM-managed libraries (Compose, Firebase) emit platform() wrapper
9
+ * - Plugin declarations emit plugins {} block, not implementation()
10
+ * - Falls back through: Google Maven → Maven Central → Jetpack releases page
11
+ *
12
+ * Source of truth: dl.google.com/dl/android/maven2 + search.maven.org
13
+ */
14
+ import { secureFetchJson, secureFetch, extractPageText } from "../http.js";
15
+ import { MAVEN_SEARCH_URL, GOOGLE_MAVEN_URL } from "../constants.js";
16
+ const LIBRARY_CATALOGUE = {
17
+ // ── Compose ────────────────────────────────────────────────────────────────
18
+ "compose-bom": { groupId: "androidx.compose", artifactId: "compose-bom" },
19
+ "compose": { groupId: "androidx.compose.ui", artifactId: "ui", bomManaged: true },
20
+ "compose-ui": { groupId: "androidx.compose.ui", artifactId: "ui", bomManaged: true },
21
+ "compose-material3": { groupId: "androidx.compose.material3", artifactId: "material3", bomManaged: true },
22
+ "compose-foundation": { groupId: "androidx.compose.foundation", artifactId: "foundation", bomManaged: true },
23
+ "compose-runtime": { groupId: "androidx.compose.runtime", artifactId: "runtime", bomManaged: true },
24
+ "compose-animation": { groupId: "androidx.compose.animation", artifactId: "animation", bomManaged: true },
25
+ "material3": { groupId: "androidx.compose.material3", artifactId: "material3", bomManaged: true },
26
+ // ── Architecture ───────────────────────────────────────────────────────────
27
+ "lifecycle": { groupId: "androidx.lifecycle", artifactId: "lifecycle-runtime-ktx", releasePageSlug: "lifecycle" },
28
+ "viewmodel": { groupId: "androidx.lifecycle", artifactId: "lifecycle-viewmodel-ktx", releasePageSlug: "lifecycle" },
29
+ "lifecycle-compose": { groupId: "androidx.lifecycle", artifactId: "lifecycle-runtime-compose", releasePageSlug: "lifecycle" },
30
+ "navigation": { groupId: "androidx.navigation", artifactId: "navigation-compose", releasePageSlug: "navigation" },
31
+ "navigation-compose": { groupId: "androidx.navigation", artifactId: "navigation-compose", releasePageSlug: "navigation" },
32
+ "room": { groupId: "androidx.room", artifactId: "room-runtime", releasePageSlug: "room" },
33
+ "paging": { groupId: "androidx.paging", artifactId: "paging-runtime", releasePageSlug: "paging" },
34
+ "paging-compose": { groupId: "androidx.paging", artifactId: "paging-compose", releasePageSlug: "paging" },
35
+ "datastore": { groupId: "androidx.datastore", artifactId: "datastore-preferences", releasePageSlug: "datastore" },
36
+ "workmanager": { groupId: "androidx.work", artifactId: "work-runtime-ktx", releasePageSlug: "work" },
37
+ "hilt": { groupId: "com.google.dagger", artifactId: "hilt-android", releasePageSlug: "hilt" },
38
+ "hilt-compose": { groupId: "androidx.hilt", artifactId: "hilt-navigation-compose", releasePageSlug: "hilt" },
39
+ "hilt-navigation-compose": { groupId: "androidx.hilt", artifactId: "hilt-navigation-compose", releasePageSlug: "hilt" },
40
+ // ── Network ────────────────────────────────────────────────────────────────
41
+ "retrofit": { groupId: "com.squareup.retrofit2", artifactId: "retrofit" },
42
+ "retrofit-gson": { groupId: "com.squareup.retrofit2", artifactId: "converter-gson" },
43
+ "retrofit-moshi": { groupId: "com.squareup.retrofit2", artifactId: "converter-moshi" },
44
+ "okhttp": { groupId: "com.squareup.okhttp3", artifactId: "okhttp" },
45
+ "okhttp-logging": { groupId: "com.squareup.okhttp3", artifactId: "logging-interceptor" },
46
+ // Ktor — KMP HTTP client (replaces Retrofit in KMP projects)
47
+ // Note: ktor-client-android is the Android engine; use ktor-client-core in commonMain
48
+ "ktor": { groupId: "io.ktor", artifactId: "ktor-client-core" },
49
+ "ktor-core": { groupId: "io.ktor", artifactId: "ktor-client-core" },
50
+ "ktor-android": { groupId: "io.ktor", artifactId: "ktor-client-okhttp" },
51
+ "ktor-ios": { groupId: "io.ktor", artifactId: "ktor-client-darwin" },
52
+ "ktor-json": { groupId: "io.ktor", artifactId: "ktor-serialization-kotlinx-json" },
53
+ "ktor-negotiation": { groupId: "io.ktor", artifactId: "ktor-client-content-negotiation" },
54
+ // KMP — Kotlin Multiplatform core libraries
55
+ "kotlinx-serialization": { groupId: "org.jetbrains.kotlinx", artifactId: "kotlinx-serialization-json" },
56
+ "serialization": { groupId: "org.jetbrains.kotlinx", artifactId: "kotlinx-serialization-json" },
57
+ "kotlinx-datetime": { groupId: "org.jetbrains.kotlinx", artifactId: "kotlinx-datetime" },
58
+ "datetime": { groupId: "org.jetbrains.kotlinx", artifactId: "kotlinx-datetime" },
59
+ // Room KMP (stable since Room 2.7 — different from Android-only Room)
60
+ "room-kmp": { groupId: "androidx.room", artifactId: "room-runtime" },
61
+ "sqlite-bundled": { groupId: "androidx.sqlite", artifactId: "sqlite-bundled" },
62
+ // DataStore KMP (different from Android DataStore)
63
+ "datastore-kmp": { groupId: "androidx.datastore", artifactId: "datastore-preferences-core" },
64
+ // Koin — KMP-compatible DI (Hilt is Android-only, cannot be used in commonMain)
65
+ "koin": { groupId: "io.insert-koin", artifactId: "koin-core" },
66
+ "koin-android": { groupId: "io.insert-koin", artifactId: "koin-android" },
67
+ "koin-compose": { groupId: "io.insert-koin", artifactId: "koin-compose" },
68
+ // ── Image loading ──────────────────────────────────────────────────────────
69
+ // Coil 3 is the current major (io.coil-kt.coil3 group)
70
+ "coil": { groupId: "io.coil-kt.coil3", artifactId: "coil-compose" },
71
+ "coil3": { groupId: "io.coil-kt.coil3", artifactId: "coil-compose" },
72
+ "glide": { groupId: "com.github.bumptech.glide", artifactId: "glide" },
73
+ "glide-compose": { groupId: "com.github.bumptech.glide", artifactId: "compose" },
74
+ // ── Serialization ──────────────────────────────────────────────────────────
75
+ "gson": { groupId: "com.google.code.gson", artifactId: "gson" },
76
+ "moshi": { groupId: "com.squareup.moshi", artifactId: "moshi-kotlin" },
77
+ // Note: kotlinx-serialization is also listed in the KMP section above
78
+ // ── Kotlin ────────────────────────────────────────────────────────────────
79
+ "coroutines": { groupId: "org.jetbrains.kotlinx", artifactId: "kotlinx-coroutines-android" },
80
+ "kotlin-stdlib": { groupId: "org.jetbrains.kotlin", artifactId: "kotlin-stdlib" },
81
+ // ── Firebase ──────────────────────────────────────────────────────────────
82
+ "firebase-bom": { groupId: "com.google.firebase", artifactId: "firebase-bom" },
83
+ "firebase": { groupId: "com.google.firebase", artifactId: "firebase-bom" },
84
+ "firebase-analytics": { groupId: "com.google.firebase", artifactId: "firebase-analytics-ktx", bomManaged: true },
85
+ "firebase-auth": { groupId: "com.google.firebase", artifactId: "firebase-auth-ktx", bomManaged: true },
86
+ "firebase-firestore": { groupId: "com.google.firebase", artifactId: "firebase-firestore-ktx", bomManaged: true },
87
+ "firebase-crashlytics": { groupId: "com.google.firebase", artifactId: "firebase-crashlytics-ktx", bomManaged: true },
88
+ "firebase-messaging": { groupId: "com.google.firebase", artifactId: "firebase-messaging-ktx", bomManaged: true },
89
+ "firebase-storage": { groupId: "com.google.firebase", artifactId: "firebase-storage-ktx", bomManaged: true },
90
+ // ── Google Play Services ───────────────────────────────────────────────────
91
+ "play-services-auth": { groupId: "com.google.android.gms", artifactId: "play-services-auth" },
92
+ "play-services-maps": { groupId: "com.google.android.gms", artifactId: "play-services-maps" },
93
+ "credentials": { groupId: "androidx.credentials", artifactId: "credentials" },
94
+ "credentials-play": { groupId: "androidx.credentials", artifactId: "credentials-play-services-auth" },
95
+ // ── Paging / Data ─────────────────────────────────────────────────────────
96
+ "profileinstaller": { groupId: "androidx.profileinstaller", artifactId: "profileinstaller" },
97
+ "startup": { groupId: "androidx.startup", artifactId: "startup-runtime", releasePageSlug: "startup" },
98
+ "splashscreen": { groupId: "androidx.core", artifactId: "core-splashscreen", releasePageSlug: "core" },
99
+ "window": { groupId: "androidx.window", artifactId: "window", releasePageSlug: "window" },
100
+ "adaptive": { groupId: "androidx.compose.material3.adaptive", artifactId: "adaptive", releasePageSlug: "compose-material3-adaptive" },
101
+ "adaptive-compose": { groupId: "androidx.compose.material3.adaptive", artifactId: "adaptive-navigation" },
102
+ // ── Testing ───────────────────────────────────────────────────────────────
103
+ "mockk": { groupId: "io.mockk", artifactId: "mockk" },
104
+ "turbine": { groupId: "app.cash.turbine", artifactId: "turbine" },
105
+ "espresso": { groupId: "androidx.test.espresso", artifactId: "espresso-core" },
106
+ "compose-testing": { groupId: "androidx.compose.ui", artifactId: "ui-test-junit4", bomManaged: true },
107
+ // ── Plugins ───────────────────────────────────────────────────────────────
108
+ "agp": { groupId: "com.android.tools.build", artifactId: "gradle", isPlugin: true, pluginId: "com.android.application" },
109
+ "ksp": { groupId: "com.google.devtools.ksp", artifactId: "com.google.devtools.ksp.gradle.plugin", isPlugin: true, pluginId: "com.google.devtools.ksp" },
110
+ "kotlin-android": { groupId: "org.jetbrains.kotlin", artifactId: "kotlin-gradle-plugin", isPlugin: true, pluginId: "org.jetbrains.kotlin.android" },
111
+ };
112
+ // ── Maven fetchers ────────────────────────────────────────────────────────────
113
+ async function fromGoogleMaven(groupId, artifactId) {
114
+ const groupPath = groupId.replace(/\./g, "/");
115
+ const url = `${GOOGLE_MAVEN_URL}/${groupPath}/${artifactId}/maven-metadata.xml`;
116
+ try {
117
+ const xml = await secureFetch(url);
118
+ const release = xml.match(/<release>([^<]+)<\/release>/)?.[1];
119
+ const latest = xml.match(/<latest>([^<]+)<\/latest>/)?.[1];
120
+ return release ?? latest ?? null;
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ }
126
+ async function fromMavenCentral(groupId, artifactId) {
127
+ try {
128
+ const q = encodeURIComponent(`g:"${groupId}" AND a:"${artifactId}"`);
129
+ const url = `${MAVEN_SEARCH_URL}?q=${q}&rows=1&wt=json`;
130
+ const data = await secureFetchJson(url);
131
+ return data?.response?.docs?.[0]?.latestVersion ?? null;
132
+ }
133
+ catch {
134
+ return null;
135
+ }
136
+ }
137
+ async function fromJetpackReleasesPage(slug) {
138
+ const url = `https://developer.android.com/jetpack/androidx/releases/${slug}`;
139
+ try {
140
+ const html = await secureFetch(url);
141
+ return extractPageText(html, 1800);
142
+ }
143
+ catch {
144
+ return `Could not fetch release page. Check: https://developer.android.com/jetpack/androidx/versions`;
145
+ }
146
+ }
147
+ // ── Output formatters ─────────────────────────────────────────────────────────
148
+ function formatPlugin(entry, version) {
149
+ const pluginId = entry.pluginId ?? `${entry.groupId}.${entry.artifactId}`;
150
+ return (`**Plugin id:** \`${pluginId}\`\n` +
151
+ `**Latest Stable:** \`${version}\`\n\n` +
152
+ `\`\`\`kotlin\n// libs.versions.toml\n[plugins]\n${entry.artifactId.split(".")[0]} = { id = "${pluginId}", version = "${version}" }\n\n` +
153
+ `// build.gradle.kts\nplugins {\n alias(libs.plugins.${entry.artifactId.split(".")[0]})\n}\n\`\`\``);
154
+ }
155
+ function formatBom(entry, version) {
156
+ const isFirebase = entry.groupId.startsWith("com.google.firebase");
157
+ const bomCoords = isFirebase
158
+ ? `com.google.firebase:firebase-bom:${version}`
159
+ : `${entry.groupId}:${entry.artifactId}:${version}`;
160
+ return (`**BOM managed — use \`platform()\` wrapper**\n` +
161
+ `**BOM version:** \`${version}\`\n\n` +
162
+ `\`\`\`kotlin\ndependencies {\n implementation(platform("${bomCoords}"))\n implementation("${entry.groupId}:${entry.artifactId}") // no version — BOM pins it\n}\n\`\`\`\n\n` +
163
+ `> ✅ Import the BOM once; all matching artifacts pick up the pinned version automatically.`);
164
+ }
165
+ function formatLibrary(entry, version) {
166
+ const coords = `${entry.groupId}:${entry.artifactId}:${version}`;
167
+ return (`**Latest Stable:** \`${version}\`\n\n` +
168
+ `\`\`\`kotlin\n// Kotlin DSL\nimplementation("${coords}")\n\`\`\`\n\n` +
169
+ `\`\`\`groovy\n// Groovy DSL\nimplementation '${coords}'\n\`\`\`\n\n` +
170
+ `\`\`\`toml\n# libs.versions.toml\n[libraries]\n${entry.artifactId} = { group = "${entry.groupId}", name = "${entry.artifactId}", version = "${version}" }\n\`\`\``);
171
+ }
172
+ // ── Main handler ──────────────────────────────────────────────────────────────
173
+ export async function gradleDependencyChecker(libraryName) {
174
+ if (!libraryName || libraryName.trim().length < 2) {
175
+ return "ERROR: Library name must be at least 2 characters.";
176
+ }
177
+ const name = libraryName.trim().toLowerCase().replace(/\s+/g, "-").slice(0, 100);
178
+ const header = `## AndroJack Gradle Dependency Checker\n**Library:** \`${libraryName}\`\n\n`;
179
+ const entry = LIBRARY_CATALOGUE[name];
180
+ if (entry) {
181
+ // Try Google Maven first (authoritative for Jetpack + Firebase)
182
+ let version = await fromGoogleMaven(entry.groupId, entry.artifactId);
183
+ // Fallback: Maven Central (for third-party: Retrofit, OkHttp, Coil, etc.)
184
+ if (!version)
185
+ version = await fromMavenCentral(entry.groupId, entry.artifactId);
186
+ if (version) {
187
+ let body;
188
+ if (entry.isPlugin) {
189
+ body = formatPlugin(entry, version);
190
+ }
191
+ else if (entry.bomManaged && (name.endsWith("-bom") || name === "firebase" || name === "firebase-bom" || name === "compose-bom")) {
192
+ body = formatBom(entry, version);
193
+ }
194
+ else if (entry.bomManaged) {
195
+ // Individual BOM-managed artifact — show both BOM and direct approaches
196
+ body =
197
+ formatLibrary(entry, version) +
198
+ `\n\n> 💡 Prefer importing the BOM (\`compose-bom\` or \`firebase-bom\`) to keep all artifacts version-aligned.`;
199
+ }
200
+ else {
201
+ body = formatLibrary(entry, version);
202
+ }
203
+ const releaseUrl = entry.releasePageSlug
204
+ ? `https://developer.android.com/jetpack/androidx/releases/${entry.releasePageSlug}`
205
+ : `https://search.maven.org/artifact/${entry.groupId}/${entry.artifactId}`;
206
+ return (header + body +
207
+ `\n\n**Official release notes:** ${releaseUrl}\n\n` +
208
+ `> ✅ GROUNDING GATE: Use version \`${version}\` as confirmed by authoritative Maven source.`);
209
+ }
210
+ // Version not found — serve release page content
211
+ if (entry.releasePageSlug) {
212
+ const text = await fromJetpackReleasesPage(entry.releasePageSlug);
213
+ return (header +
214
+ `**Version lookup inconclusive via automated search.**\n\n` +
215
+ `**Jetpack release page:**\n${text}\n\n` +
216
+ `> Check https://developer.android.com/jetpack/androidx/versions for current stable.`);
217
+ }
218
+ }
219
+ // Unknown library — try Maven Central by name
220
+ const mcResult = await fromMavenCentral(name, name);
221
+ if (mcResult) {
222
+ return (header +
223
+ `**Not in local catalogue — Maven Central result:**\n` +
224
+ formatLibrary({ groupId: "?", artifactId: name }, mcResult) +
225
+ `\n\n> ⚠️ Verify group ID and artifact ID at https://search.maven.org`);
226
+ }
227
+ return (header +
228
+ `**Library \`${libraryName}\` not found in local catalogue or Maven search.**\n\n` +
229
+ `Try searching manually:\n` +
230
+ `- https://search.maven.org/search?q=${encodeURIComponent(name)}\n` +
231
+ `- https://developer.android.com/jetpack/androidx/versions\n` +
232
+ `- https://firebase.google.com/docs/android/setup#available-libraries\n\n` +
233
+ `Common patterns: \`compose-bom\`, \`hilt\`, \`room\`, \`firebase-bom\`, \`retrofit\`, \`coil\`, \`credentials\``);
234
+ }
@@ -0,0 +1,348 @@
1
+ // Tool 16: Kotlin Multiplatform (KMP) Guide
2
+ // 900+ new KMP libraries published in 2025. Room, DataStore, Ktor all have KMP variants.
3
+ // AI tools silently generate Android-only code for KMP projects — iOS build fails.
4
+ export async function androidKmpGuide(topic) {
5
+ const t = topic.toLowerCase().trim();
6
+ const overview = `
7
+ # Kotlin Multiplatform (KMP) — Official Reference (2025)
8
+ Source: https://kotlinlang.org/docs/multiplatform.html
9
+
10
+ ## What KMP Is — And Is Not
11
+
12
+ KMP shares **business logic and data layer** (domain, data, networking, storage) across
13
+ Android and iOS while keeping **native UIs** on each platform. It is NOT Compose Multiplatform
14
+ (CMP) — CMP shares UI as well, using Compose for iOS. They are separate, both valid.
15
+
16
+ | Approach | What's Shared | UI |
17
+ |----------|--------------|-----|
18
+ | KMP only | Domain + Data layer | Native (SwiftUI on iOS, Compose on Android) |
19
+ | KMP + CMP | Domain + Data + UI | Compose on all platforms |
20
+
21
+ ## Why AI Tools Get KMP Wrong
22
+
23
+ When you ask "add Room to my KMP project," AI tools generate Android-only Room code.
24
+ It compiles. Android works. iOS build fails. Silent correctness failure.
25
+ Every major Jetpack library now has a KMP variant — always use the KMP artifact in KMP projects.
26
+
27
+ ## Project Structure
28
+
29
+ \`\`\`
30
+ shared/
31
+ src/
32
+ commonMain/kotlin/ ← shared code (use expect/actual for platform differences)
33
+ androidMain/kotlin/ ← Android-specific implementations
34
+ iosMain/kotlin/ ← iOS-specific implementations
35
+ androidApp/ ← Android Compose UI
36
+ iosApp/ ← SwiftUI (Xcode project)
37
+ \`\`\`
38
+
39
+ ## Gradle Setup (Kotlin DSL)
40
+
41
+ \`\`\`kotlin
42
+ // shared/build.gradle.kts
43
+ plugins {
44
+ alias(libs.plugins.kotlinMultiplatform)
45
+ alias(libs.plugins.androidLibrary)
46
+ alias(libs.plugins.kotlinSerialization)
47
+ alias(libs.plugins.ksp) // For Room KMP
48
+ }
49
+
50
+ kotlin {
51
+ androidTarget {
52
+ compilations.all { kotlinOptions { jvmTarget = "11" } }
53
+ }
54
+ listOf(iosX64(), iosArm64(), iosSimulatorArm64()).forEach { iosTarget ->
55
+ iosTarget.binaries.framework {
56
+ baseName = "Shared"
57
+ isStatic = true
58
+ }
59
+ }
60
+
61
+ sourceSets {
62
+ commonMain.dependencies {
63
+ implementation(libs.kotlinx.coroutines.core)
64
+ implementation(libs.kotlinx.serialization.json)
65
+ implementation(libs.ktor.client.core) // Networking (NOT Retrofit — not KMP)
66
+ implementation(libs.ktor.client.content.negotiation)
67
+ implementation(libs.ktor.serialization.kotlinx.json)
68
+ implementation(libs.room.runtime) // Room KMP
69
+ implementation(libs.sqlite.bundled)
70
+ implementation(libs.datastore.preferences.core) // DataStore KMP
71
+ }
72
+ androidMain.dependencies {
73
+ implementation(libs.ktor.client.okhttp) // OkHttp engine on Android
74
+ implementation(libs.kotlinx.coroutines.android)
75
+ }
76
+ iosMain.dependencies {
77
+ implementation(libs.ktor.client.darwin) // Darwin engine on iOS
78
+ }
79
+ }
80
+ }
81
+ \`\`\`
82
+
83
+ Source: https://kotlinlang.org/docs/multiplatform-get-started.html
84
+ `;
85
+ const libraries = `
86
+ # KMP — Library Catalogue (2025)
87
+ Source: https://kotlinlang.org/docs/multiplatform-introduce-frameworks.html
88
+
89
+ ## ⚠️ Android vs KMP Artifact Mapping — Where AI Tools Fail
90
+
91
+ | Function | Android-Only (❌ use in KMP) | KMP Equivalent (✅ use in KMP) |
92
+ |----------|---------------------------|-------------------------------|
93
+ | Networking | Retrofit + OkHttp | **Ktor** (ktor-client-core) |
94
+ | Database | Room (Android) | **Room KMP** (room-runtime, sqlite-bundled) |
95
+ | Preferences | DataStore (Android) | **DataStore KMP** (datastore-preferences-core) |
96
+ | JSON | Gson / Moshi | **kotlinx-serialization-json** |
97
+ | DI | Hilt (Android only) | **Koin** (koin-core) or manual |
98
+ | Image loading | Coil / Glide | **Coil3** (io.coil-kt.coil3 — KMP-ready) |
99
+ | Date/Time | java.time | **kotlinx-datetime** |
100
+ | Settings | SharedPreferences | DataStore KMP |
101
+
102
+ ## libs.versions.toml — KMP Dependencies
103
+
104
+ \`\`\`toml
105
+ [versions]
106
+ kotlin = "2.1.0"
107
+ ktor = "3.1.0"
108
+ room = "2.7.0" # Room KMP stable since 2.7
109
+ kotlinxCoroutines = "1.10.1"
110
+ kotlinxSerialization = "1.8.0"
111
+ kotlinxDatetime = "0.6.2"
112
+ datastore = "1.1.2"
113
+ koin = "4.0.0"
114
+ coil3 = "3.1.0"
115
+ sqlite = "2.5.0"
116
+
117
+ [libraries]
118
+ # Ktor — Multiplatform HTTP client (replaces Retrofit in KMP)
119
+ ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }
120
+ ktor-client-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "ktor" } # Android
121
+ ktor-client-darwin = { group = "io.ktor", name = "ktor-client-darwin", version.ref = "ktor" } # iOS
122
+ ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
123
+ ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }
124
+
125
+ # Room KMP
126
+ room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
127
+ room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } # KSP
128
+ sqlite-bundled = { group = "androidx.sqlite", name = "sqlite-bundled", version.ref = "sqlite" }
129
+
130
+ # DataStore KMP
131
+ datastore-preferences-core = { group = "androidx.datastore", name = "datastore-preferences-core", version.ref = "datastore" }
132
+
133
+ # kotlinx
134
+ kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" }
135
+ kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
136
+ kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
137
+ kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" }
138
+
139
+ # Koin — KMP-compatible DI (Hilt is Android-only)
140
+ koin-core = { group = "io.insert-koin", name = "koin-core", version.ref = "koin" }
141
+ koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" }
142
+ koin-compose = { group = "io.insert-koin", name = "koin-compose", version.ref = "koin" }
143
+
144
+ # Coil3 — KMP-ready image loading
145
+ coil3-compose = { group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil3" }
146
+ coil3-network-ktor = { group = "io.coil-kt.coil3", name = "coil-network-ktor3", version.ref = "coil3" }
147
+ \`\`\`
148
+
149
+ Source: https://kotlinlang.org/docs/multiplatform-introduce-frameworks.html
150
+ `;
151
+ const roomKmp = `
152
+ # KMP — Room KMP Setup (Stable since Room 2.7)
153
+ Source: https://developer.android.com/kotlin/multiplatform/room
154
+
155
+ ## Room KMP Gradle Setup
156
+
157
+ \`\`\`kotlin
158
+ // shared/build.gradle.kts
159
+ plugins {
160
+ alias(libs.plugins.ksp)
161
+ }
162
+
163
+ kotlin {
164
+ sourceSets {
165
+ commonMain.dependencies {
166
+ implementation(libs.room.runtime)
167
+ implementation(libs.sqlite.bundled)
168
+ }
169
+ }
170
+ }
171
+
172
+ // KSP for Room compiler — apply to each target
173
+ dependencies {
174
+ add("kspAndroid", libs.room.compiler)
175
+ add("kspIosX64", libs.room.compiler)
176
+ add("kspIosArm64", libs.room.compiler)
177
+ add("kspIosSimulatorArm64", libs.room.compiler)
178
+ }
179
+ \`\`\`
180
+
181
+ ## Room KMP Database — In commonMain
182
+
183
+ \`\`\`kotlin
184
+ // shared/src/commonMain/kotlin/Database.kt
185
+ @Database(entities = [UserEntity::class], version = 1)
186
+ abstract class AppDatabase : RoomDatabase() {
187
+ abstract fun userDao(): UserDao
188
+ }
189
+
190
+ @Dao
191
+ interface UserDao {
192
+ @Query("SELECT * FROM users") fun getAllUsers(): Flow<List<UserEntity>>
193
+ @Insert suspend fun insert(user: UserEntity)
194
+ @Delete suspend fun delete(user: UserEntity)
195
+ }
196
+
197
+ @Entity(tableName = "users")
198
+ data class UserEntity(
199
+ @PrimaryKey val id: String,
200
+ val name: String,
201
+ val email: String
202
+ )
203
+ \`\`\`
204
+
205
+ ## Platform-Specific Database Builder
206
+
207
+ \`\`\`kotlin
208
+ // shared/src/androidMain/kotlin/DatabaseBuilder.kt
209
+ fun getDatabaseBuilder(ctx: Context): RoomDatabase.Builder<AppDatabase> {
210
+ val appContext = ctx.applicationContext
211
+ val dbFile = appContext.getDatabasePath("app.db")
212
+ return Room.databaseBuilder<AppDatabase>(appContext, dbFile.absolutePath)
213
+ }
214
+
215
+ // shared/src/iosMain/kotlin/DatabaseBuilder.kt
216
+ fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
217
+ val dbFilePath = NSHomeDirectory() + "/app.db"
218
+ return Room.databaseBuilder<AppDatabase>(name = dbFilePath)
219
+ }
220
+ \`\`\`
221
+
222
+ Source: https://developer.android.com/kotlin/multiplatform/room
223
+ `;
224
+ const ktor = `
225
+ # KMP — Ktor HTTP Client (Replaces Retrofit in KMP)
226
+ Source: https://ktor.io/docs/client-create-multiplatform-application.html
227
+
228
+ ## Why Retrofit Cannot Be Used in KMP
229
+ Retrofit depends on Java reflection and OkHttp — neither is available in iosMain.
230
+ Ktor is the official KMP HTTP client with platform-specific engines.
231
+
232
+ ## Ktor API Client in commonMain
233
+
234
+ \`\`\`kotlin
235
+ // shared/src/commonMain/kotlin/ApiClient.kt
236
+ import io.ktor.client.*
237
+ import io.ktor.client.call.*
238
+ import io.ktor.client.plugins.contentnegotiation.*
239
+ import io.ktor.client.request.*
240
+ import io.ktor.serialization.kotlinx.json.*
241
+ import kotlinx.serialization.json.Json
242
+
243
+ class ApiClient {
244
+ private val client = HttpClient {
245
+ install(ContentNegotiation) {
246
+ json(Json { ignoreUnknownKeys = true; isLenient = true })
247
+ }
248
+ }
249
+
250
+ suspend fun getUser(userId: String): User =
251
+ client.get("https://api.example.com/users/$userId").body()
252
+
253
+ suspend fun createPost(post: CreatePostRequest): Post =
254
+ client.post("https://api.example.com/posts") {
255
+ setBody(post)
256
+ }.body()
257
+ }
258
+
259
+ @Serializable
260
+ data class User(val id: String, val name: String, val email: String)
261
+ \`\`\`
262
+
263
+ ## Repository Pattern with Ktor
264
+
265
+ \`\`\`kotlin
266
+ // commonMain — same pattern as Android MVVM, works on all platforms
267
+ interface UserRepository {
268
+ suspend fun getUser(id: String): Result<User>
269
+ fun observeUsers(): Flow<List<User>>
270
+ }
271
+
272
+ class UserRepositoryImpl(
273
+ private val apiClient: ApiClient,
274
+ private val userDao: UserDao
275
+ ) : UserRepository {
276
+ override suspend fun getUser(id: String): Result<User> = runCatching {
277
+ val entity = userDao.getUser(id) ?: run {
278
+ val user = apiClient.getUser(id)
279
+ userDao.insert(user.toEntity())
280
+ user
281
+ }
282
+ entity.toDomain()
283
+ }
284
+
285
+ override fun observeUsers(): Flow<List<User>> =
286
+ userDao.getAllUsers().map { entities -> entities.map { it.toDomain() } }
287
+ }
288
+ \`\`\`
289
+
290
+ Source: https://ktor.io/docs/client-create-multiplatform-application.html
291
+ `;
292
+ const expectActual = `
293
+ # KMP — expect/actual Pattern
294
+ Source: https://kotlinlang.org/docs/multiplatform-expect-actual.html
295
+
296
+ ## When to Use expect/actual
297
+
298
+ Use expect/actual only for platform-specific capabilities with no KMP equivalent:
299
+ - Platform-specific APIs (GPS, biometrics, camera)
300
+ - Platform SDKs (Firebase iOS SDK vs Firebase Android SDK)
301
+ - Performance-critical native code
302
+
303
+ Do NOT use expect/actual for things that already have KMP libraries (networking, storage, etc.).
304
+
305
+ ## expect/actual Example — Platform Info
306
+
307
+ \`\`\`kotlin
308
+ // commonMain
309
+ expect fun getPlatformName(): String
310
+ expect class PlatformContext
311
+
312
+ // androidMain
313
+ actual fun getPlatformName(): String = "Android \${Build.VERSION.RELEASE}"
314
+ actual typealias PlatformContext = Context
315
+
316
+ // iosMain
317
+ actual fun getPlatformName(): String = UIDevice.currentDevice.systemName()
318
+ actual class PlatformContext
319
+ \`\`\`
320
+
321
+ ## expect/actual for Coroutines Dispatcher
322
+
323
+ \`\`\`kotlin
324
+ // commonMain
325
+ expect val backgroundDispatcher: CoroutineDispatcher
326
+
327
+ // androidMain
328
+ actual val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO
329
+
330
+ // iosMain
331
+ actual val backgroundDispatcher: CoroutineDispatcher = Dispatchers.Default
332
+ \`\`\`
333
+
334
+ Source: https://kotlinlang.org/docs/multiplatform-expect-actual.html
335
+ `;
336
+ if (t.includes("room") || t.includes("database") || t.includes("db"))
337
+ return roomKmp;
338
+ if (t.includes("ktor") || t.includes("network") || t.includes("http") || t.includes("retrofit"))
339
+ return ktor;
340
+ if (t.includes("expect") || t.includes("actual") || t.includes("platform"))
341
+ return expectActual;
342
+ if (t.includes("librar") || t.includes("depend") || t.includes("gradle") || t.includes("toml"))
343
+ return libraries;
344
+ return overview + "\n\n---\n\n" +
345
+ "**Query topics:** 'libraries' (KMP dependency catalogue), 'room' (Room KMP setup), " +
346
+ "'ktor' (networking — replaces Retrofit), 'expect actual' (platform-specific code)\n\n" +
347
+ "Source: https://kotlinlang.org/docs/multiplatform.html";
348
+ }