[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-jetbrains-kotlin-tooling-cocoapods-spm-migration":3,"mdc--m3fwt0-key":39,"related-org-jetbrains-kotlin-tooling-cocoapods-spm-migration":4385,"related-repo-jetbrains-kotlin-tooling-cocoapods-spm-migration":4516},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":28,"repoUrl":29,"updatedAt":30,"license":31,"forks":32,"topics":33,"repo":34,"sourceUrl":37,"mdContent":38},"kotlin-tooling-cocoapods-spm-migration","migrate KMP projects to Swift Package Manager","Migrate KMP projects from CocoaPods (kotlin(\"native.cocoapods\")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(), transforms cocoapods.* imports to swiftPMImport.*, and reconfigures the Xcode project.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"jetbrains","JetBrains","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fjetbrains.png",[12,16,19,22,25],{"name":13,"slug":14,"type":15},"Kotlin","kotlin","tag",{"name":17,"slug":18,"type":15},"iOS","ios",{"name":20,"slug":21,"type":15},"Mobile","mobile",{"name":23,"slug":24,"type":15},"Migration","migration",{"name":26,"slug":27,"type":15},"Xcode","xcode",252,"https:\u002F\u002Fgithub.com\u002FJetBrains\u002Fskills","2026-07-17T06:04:39.367114","Apache-2.0",17,[],{"repoUrl":29,"stars":28,"forks":32,"topics":35,"description":36},[],"Curated agent skills collection verified by JetBrains","https:\u002F\u002Fgithub.com\u002FJetBrains\u002Fskills\u002Ftree\u002FHEAD\u002Fkotlin-tooling-cocoapods-spm-migration","---\nname: kotlin-tooling-cocoapods-spm-migration\ndescription: Migrate KMP projects from CocoaPods (kotlin(\"native.cocoapods\")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(), transforms cocoapods.* imports to swiftPMImport.*, and reconfigures the Xcode project.\nlicense: Apache-2.0\nmetadata:\n  short-description: \"Migrate KMP from CocoaPods to SPM\"\n  author: JetBrains\n  version: \"1.0.0\"\n  source: https:\u002F\u002Fgithub.com\u002FKotlin\u002Fkotlin-agent-skills\u002Ftree\u002Fmain\u002Fskills\u002Fkotlin-tooling-cocoapods-spm-migration\n---\n\n# CocoaPods to SwiftPM Migration for KMP\n\nMigrate Kotlin Multiplatform projects from `kotlin(\"native.cocoapods\")` to `swiftPMDependencies {}` DSL.\n\n## Requirements\n\n- **Kotlin**: Version with Swift Import support (e.g., 2.4.0-Beta1 or later)\n- **Xcode**: 16.4 or 26.0+\n- **iOS Deployment Target**: 16.0+ recommended\n\n## Migration Overview\n\n**IMPORTANT**: Keep the `cocoapods {}` block and plugin active until Phase 6. The migration adds `swiftPMDependencies {}` alongside the existing CocoaPods setup first, reconfigures Xcode, and only then removes CocoaPods.\n\n| Phase | Action |\n|-------|--------|\n| 1 | Analyze existing CocoaPods configuration |\n| 2 | Update Gradle configuration (repos, Kotlin version) |\n| 3 | Add `swiftPMDependencies {}` alongside existing `cocoapods {}` |\n| 4 | Transform Kotlin imports |\n| 5 | Reconfigure iOS project and deintegrate CocoaPods |\n| 6 | Remove CocoaPods plugin from Gradle |\n| 7 | Verify Gradle build and Xcode project build |\n| 8 | Write MIGRATION_REPORT.md |\n\n---\n\n## Phase 1: Pre-Migration Analysis\n\n### 1.0 Verify the project builds\n\nBefore starting migration, identify the module to migrate and confirm it compiles successfully.\n\n1. **Find the module that uses CocoaPods** — look for `build.gradle.kts` files containing `cocoapods`:\n   ```bash\n   grep -rl \"cocoapods\" --include=\"build.gradle.kts\" .\n   ```\n   Extract the module name from the path (e.g., `.\u002Fshared\u002Fbuild.gradle.kts` → module name is `shared`).\n\n2. **Build only that module** (avoids building the entire multi-module project):\n   ```bash\n   .\u002Fgradlew :moduleName:build\n   ```\n   Replace `moduleName` with the directory name of the module (e.g., `:shared:build`).\n\n3. **If the targeted build fails**, ask the user to either:\n   - Provide the correct Gradle command to verify the module builds, or\n   - Confirm the module is in a working state and it's safe to proceed\n\n   If the user confirms without providing a build command, **record that the pre-migration build could not be verified** and warn about this at the end of migration (Phase 7).\n\n### 1.0a Confirm Kotlin version with Swift Import support\n\nAsk the user:\n\n> Does your project already use a Kotlin version with Swift Import support (swiftPMDependencies DSL)?\n\n**If yes** → read their current Kotlin version from `gradle\u002Flibs.versions.toml` (or `build.gradle.kts`), record it, and skip Phase 2.2 (no version change needed).\n\n**If no** → ask:\n\n> Please provide the Kotlin version to use (e.g., \"2.4.0\", \"2.4.0-Beta1\", \"2.4.0-dev-123\").\n\nRecord the user-provided version. Then ask:\n\n> Does this Kotlin version require a custom Maven repository (e.g., JetBrains dev repo)?\n\n- **Yes** → ask for the repo URL (suggest `https:\u002F\u002Fpackages.jetbrains.team\u002Fmaven\u002Fp\u002Fkt\u002Fdev` as default). Phase 2.1 will add it.\n- **No** → Phase 2.1 is skipped (no custom repo needed).\n\nFinally, check the project's current Kotlin version. Compare **major.minor** against the target. If it differs significantly (e.g., `2.1.0` → `2.4.0`), warn: \"⚠️ Kotlin version jump — upgrading across minor versions can introduce breaking changes unrelated to this migration. Recommended: update first, verify it builds, then re-run.\" If the user confirms despite the mismatch, proceed.\n\n### 1.1 Check for deprecated CocoaPods workaround property\n\nSearch `gradle.properties` for the deprecated property:\n\n```properties\nkotlin.apple.deprecated.allowUsingEmbedAndSignWithCocoaPodsDependencies=true\n```\n\nThis property was a workaround (see [KT-64096](https:\u002F\u002Fyoutrack.jetbrains.com\u002Fissue\u002FKT-64096)) for projects using `embedAndSign` alongside CocoaPods dependencies. It suppresses an error about unsupported configurations that can cause runtime crashes or symbol duplication. After migrating to SwiftPM import, this property is no longer needed and **must be removed** in Phase 6. Record its presence if found.\n\n### 1.2 Check for EmbedAndSign disablers\n\nSearch all `build.gradle.kts` files for code that disables `EmbedAndSign` tasks (e.g., `TaskGraph.whenReady` filters, `tasks.matching` blocks). This is a CocoaPods-era workaround that **breaks the migration** because `integrateEmbedAndSign` (needed in Phase 5) gets disabled too. Record any such code — it **must be removed** in Phase 6, and may need to be removed earlier. See [troubleshooting.md](references\u002Ftroubleshooting.md) § \"`integrateEmbedAndSign` Skipped\" for patterns.\n\n### 1.3 Check for third-party KMP libraries with bundled cinterop klibs\n\nSome KMP libraries ship pre-built cinterop klibs with `cocoapods.*` package namespaces. After migration, the swiftPMDependencies cinterop generator detects these existing bindings and **skips generating new bindings** for those Clang modules to avoid duplicates. This means `cocoapods.*` imports for those modules must be **kept as-is** — they resolve to the third-party library's bundled klib, not to actual CocoaPods.\n\n**Known libraries with bundled `cocoapods.*` klibs:**\n\n| Library | Maven artifact | Bundled klib namespace | Classes provided |\n|---------|---------------|----------------------|-----------------|\n| [KMPNotifier](https:\u002F\u002Fgithub.com\u002Fmirzemehdi\u002FKMPNotifier) | `io.github.mirzemehdi:kmpnotifier` | `cocoapods.FirebaseMessaging` | `FIRMessaging`, `FIRMessagingAPNSTokenType`, etc. |\n\n**How to detect:** Search Gradle dependency declarations for known libraries, then cross-reference their bundled namespaces against the `import cocoapods.*` statements found in step 4. Mark any matches — these imports will NOT be transformed in Phase 4.\n\nIf unsure whether a third-party KMP library bundles cinterop klibs, check if it has a `linkOnly = true` pod dependency in the project — this is a strong indicator that the library provides its own klib for those classes.\n\nTo inspect klib contents and verify bundled bindings, see [troubleshooting.md](references\u002Ftroubleshooting.md) § \"Third-Party KMP Libraries with Bundled Klibs\".\n\n**Find and record:**\n\n1. **CocoaPods configuration** - Search for `cocoapods` in `build.gradle.kts` files\n2. **Pod dependencies** - Extract pod names, versions from `cocoapods {}` blocks\n3. **Framework configuration** - Record `baseName`, `isStatic`, deployment target from `cocoapods.framework {}`\n4. **linkOnly pods** - Record pods declared with `linkOnly = true`. These pods provide native linking only — cinterop bindings come from a KMP wrapper library (e.g., `dev.gitlive:firebase-*`). See [common-pods-mapping.md](references\u002Fcommon-pods-mapping.md) for implications.\n5. **Kotlin imports** - Find all `import cocoapods.*` statements. Cross-reference with step 1.3 to identify which imports come from bundled klibs (and must be preserved) vs. which come from direct pod cinterop (and must be transformed).\n6. **Map pods to SPM** - See [common-pods-mapping.md](references\u002Fcommon-pods-mapping.md)\n7. **Locate iOS project directory** - Find the directory containing `Podfile` and `.xcworkspace`:\n   ```bash\n   find . -name \"Podfile\" -type f\n   ```\n   Record this path (e.g., `iosApp\u002F`, `ios\u002F`, or project root) - needed for Phase 5\n8. **Check for non-KMP CocoaPods** - Determine if the project uses CocoaPods for dependencies other than KMP. This affects cleanup strategy in Phase 5.\n9. **Check Xcode build phases** - Open the `.xcodeproj`'s `project.pbxproj` and search for the Gradle build phase script. Check if `embedAndSignAppleFrameworkForXcode` is present but **commented out** (prefixed with `#`). If commented out, it must be uncommented during Phase 5 — the `integrateEmbedAndSign` task may or may not handle this automatically.\n10. **Check for existing Crashlytics dSYM upload script** - If using FirebaseCrashlytics, search `project.pbxproj` for a dSYM upload shell script phase. Record its current path (CocoaPods-era scripts reference `${PODS_ROOT}\u002FFirebaseCrashlytics\u002Fupload-symbols`). This must be updated to the SPM path in Phase 5.\n11. **Identify CocoaPods-related extras in build scripts** - Search all `build.gradle.kts` files for CocoaPods workarounds beyond the standard `cocoapods {}` block (custom tasks hooking into `podInstall`, `Pods.xcodeproj` patching, podspec metadata, `extraSpecAttributes`, `noPodspec()`, etc.). See [cocoapods-extras-patterns.md](references\u002Fcocoapods-extras-patterns.md) for the full pattern list. Record all findings — these will be handled in Phase 6.\n\n---\n\n## Phase 2: Gradle Configuration\n\n**Important scope note:** Do NOT upgrade the Gradle wrapper version, update KSP, or update any other dependencies during this migration. Those are separate concerns and out of scope. Only change what is listed below.\n\n### 2.1 Add custom Maven repository (if needed)\n\n**Skip this step** if the user indicated in Phase 1.0a that their Kotlin version does not require a custom Maven repository (i.e., it is an official release, Beta, or RC available from Maven Central).\n\nFor dev\u002Fcustom builds, add the custom Maven repository (URL from Phase 1.0a) to `settings.gradle.kts`:\n\n```kotlin\npluginManagement {\n    repositories {\n        gradlePluginPortal()\n        mavenCentral()\n        maven(\"\u003Ccustom-repo-url>\")  \u002F\u002F ADD\n    }\n}\n\ndependencyResolutionManagement {\n    repositories {\n        mavenCentral()\n        maven(\"\u003Ccustom-repo-url>\")  \u002F\u002F ADD\n    }\n}\n```\n\n### 2.2 Update Kotlin version\n\n**Skip this step** if the user's project already uses a Kotlin version with Swift Import support (recorded in Phase 1.0a).\n\nUpdate to the version recorded in Phase 1.0a:\n\n```toml\n# gradle\u002Flibs.versions.toml\n[versions]\nkotlin = \"\u003Ckotlin-version>\"\n```\n\n### 2.3 Add buildscript constraint (if swiftPMDependencies not recognized)\n\n```kotlin\n\u002F\u002F root build.gradle.kts\nbuildscript {\n    dependencies.constraints {\n        \"classpath\"(\"org.jetbrains.kotlin:kotlin-gradle-plugin:\u003Ckotlin-version>!!\")\n    }\n}\n```\n\nReplace `\u003Ckotlin-version>` with the version recorded in Phase 1.0a. The `!!` suffix forces strict version resolution, ensuring no other dependency pulls in a different Kotlin Gradle plugin version.\n\n---\n\n## Phase 3: Add swiftPMDependencies (Keep CocoaPods)\n\n**Do NOT remove the `cocoapods {}` block or `kotlin(\"native.cocoapods\")` plugin yet.** Add `swiftPMDependencies {}` alongside the existing CocoaPods configuration.\n\n### 3.1 Add group property\n\n```kotlin\ngroup = \"org.example.myproject\"  \u002F\u002F Required for import namespace\n```\n\n### 3.2 Add swiftPMDependencies block alongside cocoapods\n\nFor each pod dependency, add the equivalent SwiftPM package declaration. Use [common-pods-mapping.md](references\u002Fcommon-pods-mapping.md) to map each pod to its SPM package URL, product name, and `importedModules`.\n\n**Key concepts:** `products` = SPM product names (controls linking). `importedModules` = Clang module names for cinterop bindings (only when `discoverModulesImplicitly = false`). `discoverModulesImplicitly` defaults to `true` (bindings for all Clang modules); set `false` when transitive C\u002FC++ modules fail cinterop (Firebase, gRPC), then list needed modules explicitly.\n\n**Important:** SPM product names and Clang module names don't always match. Always consult [common-pods-mapping.md](references\u002Fcommon-pods-mapping.md) for correct values.\n\n**Do not mix the same library suite across CocoaPods and SPM.** Libraries that share a common repository (e.g., all Firebase products) share transitive dependencies. Having some products linked via CocoaPods and others via SPM causes duplicate\u002Fconflicting symbols and dyld crashes at runtime. When migrating such a suite, move **all** pods from that suite to SPM at once — including Swift-only pods that Kotlin doesn't use directly. Add Swift-only pods as `products` entries (no `importedModules` needed). After adding new products, re-run `integrateLinkagePackage` to regenerate the linkage Swift package.\n\n```kotlin\nkotlin {\n    \u002F\u002F Keep existing targets\n    iosArm64()\n    iosSimulatorArm64()\n    iosX64()\n\n    swiftPMDependencies {\n        iosDeploymentVersion.set(\"16.0\")\n\n        \u002F\u002F If using KMP IntelliJ plugin, specify the .xcodeproj path:\n        \u002F\u002F xcodeProjectPathForKmpIJPlugin.set(\n        \u002F\u002F     layout.projectDirectory.file(\"..\u002FiosApp\u002FiosApp.xcodeproj\")\n        \u002F\u002F )\n\n        swiftPackage(\n            url = url(\"https:\u002F\u002Fgithub.com\u002Fowner\u002Frepo.git\"),\n            version = from(\"1.0.0\"),\n            products = listOf(product(\"ProductName\")),\n        )\n    }\n\n    cocoapods {\n        \u002F\u002F ... keep existing cocoapods block for now\n    }\n}\n```\n\n### 3.3 Move framework configuration out of cocoapods block\n\nIf the `cocoapods` block contains a `framework {}` configuration, move it to the `binaries` API on each target. **`isStatic = true` is recommended** — dynamic frameworks have known edge cases with SwiftPM import that can cause linker errors, dyld crashes, or duplicate class warnings:\n\n```kotlin\nlistOf(iosArm64(), iosSimulatorArm64(), iosX64()).forEach { iosTarget ->\n    iosTarget.binaries.framework { baseName = \"Shared\"; isStatic = true }\n}\n```\n\n### 3.4 Handle dev.gitlive\u002Ffirebase-kotlin-sdk and similar CocoaPods-era KMP wrappers\n\nIf the project uses `dev.gitlive:firebase-*` or similar KMP wrapper libraries, two additional steps are required:\n\n**A. Switch to `isStatic = true`** — dynamic frameworks + Firebase SPM = runtime `dyld` crash. After switching: re-run `integrateLinkagePackage`, remove any \"Embed Frameworks\" copy phase, move linker flags to `OTHER_LDFLAGS`.\n\n**B. Add framework search paths** — add conditional `-F` linkerOpts in `build.gradle.kts` and matching `FRAMEWORK_SEARCH_PATHS` in the Xcode project.\n\nSee [common-pods-mapping.md](references\u002Fcommon-pods-mapping.md) § dev.gitlive and [troubleshooting.md](references\u002Ftroubleshooting.md) for code snippets and the full product list.\n\n### 3.5 Add opt-in for cinterop API\n\n```kotlin\nkotlin.compilerOptions {\n    optIn.add(\"kotlinx.cinterop.ExperimentalForeignApi\")\n}\n```\n\nFor full DSL reference, see [dsl-reference.md](references\u002Fdsl-reference.md).\n\n---\n\n## Phase 4: Kotlin Source Updates\n\n### Import Namespace Formula\n\n```\nswiftPMImport.\u003Cgroup>.\u003Cmodule>.\u003CClassName>\n\nWhere:\n- group: build.gradle.kts `group` property, dashes (-) → dots (.)\n- module: Gradle module name, dashes (-) → dots (.)\n- ClassName: Objective-C class name (FIR* for Firebase, GMS* for Google Maps)\n```\n\n### Example Transformation\n\n```kotlin\n\u002F\u002F group = \"org.jetbrains.kotlin.firebase.sample\", module = \"kotlin-library\"\n\n\u002F\u002F BEFORE:\nimport cocoapods.FirebaseAnalytics.FIRAnalytics\n\n\u002F\u002F AFTER:\nimport swiftPMImport.org.jetbrains.kotlin.firebase.sample.kotlin.library.FIRAnalytics\n```\n\n**Import flattening:** The Clang module name (e.g., `FirebaseFirestoreInternal`, `FirebaseAuth`) disappears from the import path — all classes are flattened under the same `swiftPMImport.\u003Cgroup>.\u003Cmodule>` prefix regardless of which library they come from. For example, both `cocoapods.FirebaseAuth.FIRAuth` and `cocoapods.FirebaseFirestoreInternal.FIRFirestore` become `swiftPMImport.\u003Cgroup>.\u003Cmodule>.FIRAuth` and `swiftPMImport.\u003Cgroup>.\u003Cmodule>.FIRFirestore`.\n\n### Preserving Bundled Klib Imports\n\n> **CRITICAL:** Do NOT replace `cocoapods.*` imports that resolve to third-party KMP libraries' bundled cinterop klibs (identified in Phase 1 step 1.3). These imports must remain as-is — the `cocoapods` prefix is the package namespace in the library's published klib, not an actual CocoaPods dependency. The swiftPMDependencies cinterop generator skips modules already provided by a dependency's klib, so `swiftPMImport.*` for those classes will fail with \"Unresolved reference\".\n\n**Example** (project using [KMPNotifier](https:\u002F\u002Fgithub.com\u002Fmirzemehdi\u002FKMPNotifier)):\n```kotlin\n\u002F\u002F KEEP — resolves to kmpnotifier's bundled cinterop klib\nimport cocoapods.FirebaseMessaging.FIRMessaging\n```\n\n### Bulk Replacement\n\nUse a regex find-and-replace across all Kotlin source files, **excluding imports identified in Phase 1 step 1.3**:\n\n```\nFind:    cocoapods\\.\\w+\\.\nReplace: swiftPMImport.\u003Cyour.group>.\u003Cyour.module>.\n```\n\nAfter bulk replacement, **manually restore** any `cocoapods.*` imports that should be preserved (from bundled klibs).\n\n**Finding correct import path:** Run `.\u002Fgradlew :moduleName:build` - errors show available classes.\n\n---\n\n## Phase 5: iOS Project Reconfiguration\n\n### 5.1 Get migration command\n\nBuild the CocoaPods workspace to obtain the migration command:\n\n```bash\ncd \u002Fpath\u002Fto\u002FiosApp\n\nxcodebuild -scheme \"$(echo -n *.xcworkspace | python3 -c 'import sys, json; from subprocess import check_output; print(list(set(json.loads(check_output([\"xcodebuild\", \"-workspace\", sys.stdin.readline(), \"-list\", \"-json\"]))[\"workspace\"][\"schemes\"]) - set(json.loads(check_output([\"xcodebuild\", \"-project\", \"Pods\u002FPods.xcodeproj\", \"-list\", \"-json\"]))[\"project\"][\"schemes\"]))[0])')\" -workspace *.xcworkspace -destination 'generic\u002Fplatform=iOS Simulator' ARCHS=arm64 | grep -A5 'What went wrong'\n```\n\nThe build output will contain a command like:\n```bash\nXCODEPROJ_PATH='\u002Fpath\u002Fto\u002Fproject\u002FiosApp.xcodeproj' GRADLE_PROJECT_PATH=':shared' '\u002Fpath\u002Fto\u002Fproject\u002Fgradlew' -p '\u002Fpath\u002Fto\u002Fproject' ':shared:integrateEmbedAndSign' ':shared:integrateLinkagePackage'\n```\n\nRun this command. It modifies the `.xcodeproj` to trigger `embedAndSignAppleFrameworkForXcode` during the build. `integrateLinkagePackage` is a one-time setup — it does not need to be added as a build phase. If `integrateEmbedAndSign` is skipped, check for EmbedAndSign disablers (Phase 1 step 1.2) — remove them first, then re-run.\n\n**Verify `embedAndSignAppleFrameworkForXcode` is active:** After running integration, check the build phase script in `project.pbxproj`. If `embedAndSignAppleFrameworkForXcode` is commented out (prefixed with `#`), uncomment it.\n\nThe `integrateLinkagePackage` task generates `_internal_linkage_SwiftPMImport\u002F` at `\u003CiosDir>\u002F` — a local Swift package that mirrors your `products` list and ensures SPM libraries are linked into the final binary.\n\nAfter running the integration tasks, **disable User Script Sandboxing** (`ENABLE_USER_SCRIPT_SANDBOXING = NO`) in the `.xcodeproj`. Xcode 16+ enables it by default, which prevents the Gradle build phase from writing to the project directory:\n\n```bash\nsed -i '' 's\u002FENABLE_USER_SCRIPT_SANDBOXING = YES\u002FENABLE_USER_SCRIPT_SANDBOXING = NO\u002Fg' \"$XCODEPROJ_PATH\u002Fproject.pbxproj\"\n```\n\nIf the setting is absent (Xcode defaults to YES), add `ENABLE_USER_SCRIPT_SANDBOXING = NO;` to the app target's `buildSettings` sections. Then restart the Gradle daemon: `.\u002Fgradlew --stop`\n\n**Alternative (if xcodebuild approach fails):** See [troubleshooting.md](references\u002Ftroubleshooting.md) § \"Manual Integration Command Discovery\" for a fallback script to discover paths and run integration tasks directly.\n\n### 5.2 Update Crashlytics dSYM upload script (if applicable)\n\nIf the project uses FirebaseCrashlytics and has a dSYM upload run script phase (identified in Phase 1 step 10), update the script path from `${PODS_ROOT}\u002FFirebaseCrashlytics\u002Fupload-symbols` to `\"${BUILD_DIR%\u002FBuild\u002F*}\u002FSourcePackages\u002Fcheckouts\u002Ffirebase-ios-sdk\u002FCrashlytics\u002Frun\"`. See [troubleshooting.md](references\u002Ftroubleshooting.md) § \"Firebase Crashlytics: dSYM Upload Script\" and [common-pods-mapping.md](references\u002Fcommon-pods-mapping.md) for the full script and input files list.\n\n### 5.3 Deintegrate CocoaPods\n\n**Option A: Full deintegration** (if CocoaPods was used ONLY for KMP dependencies):\n\nBefore deleting files, run `git status --short` and verify the paths. If unsure, move files to a backup location instead of deleting immediately.\n\n```bash\ncd \u002Fpath\u002Fto\u002FiosApp\npod deintegrate\nrm -rf Podfile Podfile.lock Pods\u002F\n# Remove the workspace that matches your app xcodeproj name\nXCODEPROJ_NAME=$(basename \"$(find . -maxdepth 1 -name \"*.xcodeproj\" -type d | grep -v Pods | head -1)\" .xcodeproj)\nrm -rf \"${XCODEPROJ_NAME}.xcworkspace\"\n# Return to project root\ncd ..\n# Remove the migrated module podspec only (for example, shared.podspec)\n# If unknown, list candidates and remove the matching one explicitly:\nls -1 *.podspec\n# rm -f shared.podspec\n```\n\nThis cleanup snippet is self-contained and does not assume `XCODEPROJ_PATH` or `GRADLE_PROJECT_PATH` from the earlier one-off migration command are still available in your shell.\n\nIf `pod deintegrate` is not available, see [troubleshooting.md](references\u002Ftroubleshooting.md) § \"Manual CocoaPods Deintegration from pbxproj\" for the full list of references to remove. Also remove `Pods\u002F` from `.gitignore` and delete the `.xcworkspace` directory.\n\n**Option B: Partial removal** (if other non-KMP CocoaPods dependencies remain):\n\nRemove only the KMP pod line from the `Podfile` and re-run pod install:\n\n```ruby\ntarget 'iosApp' do\n  # Remove this line:\n  pod 'shared', :path => '..\u002Fshared'\n  # Keep other non-KMP pods\nend\n```\n\n```bash\ncd \u002Fpath\u002Fto\u002FiosApp && pod install\n```\n\n> **Tip:** Consider migrating remaining pods to SPM too — most popular iOS libraries support it natively. Add them in Xcode via File → Add Package Dependencies, then fully deintegrate CocoaPods once all pods are replaced.\n\n### 5.4 Manual integration (if automatic fails)\n\nSee [troubleshooting.md](references\u002Ftroubleshooting.md) § \"Manual Xcode Integration Steps\" for the 5-step manual setup (build phase, sandboxing, linkage package).\n\n---\n\n## Phase 6: Remove CocoaPods from Gradle\n\nNow that the iOS project is reconfigured, remove the CocoaPods plugin and block:\n\n### 6.1 Remove CocoaPods plugin\n\n```kotlin\nplugins {\n    \u002F\u002F REMOVE: kotlin(\"native.cocoapods\")\n    alias(libs.plugins.kotlinMultiplatform)  \u002F\u002F Keep\n}\n```\n\n### 6.2 Remove cocoapods block\n\nDelete the entire `cocoapods { ... }` block from `build.gradle.kts`. The `swiftPMDependencies {}` block and `binaries.framework {}` configuration added in Phase 3 replace it.\n\n### 6.3 Remove deprecated gradle.properties entries\n\nIf found in Phase 1.1, remove from `gradle.properties`:\n\n```properties\n# REMOVE — no longer needed after migrating away from CocoaPods (KT-64096)\nkotlin.apple.deprecated.allowUsingEmbedAndSignWithCocoaPodsDependencies=true\n```\n\n### 6.4 Clean up CocoaPods-related extras\n\nReview the extras identified in Phase 1 step 11. Podspec metadata, `noPodspec()`, CocoaPods task hooks, and `Pods.xcodeproj` patching code are **safe to remove** without user consultation. Non-standard pod configurations (`extraOpts`, `moduleName`), custom cinterop `defFile` setups, and CocoaPods-specific compiler\u002Flinker flags **require analysis** — consult the user if unsure whether SPM handles them automatically.\n\nSee [cocoapods-extras-patterns.md](references\u002Fcocoapods-extras-patterns.md) for the full categorized list with examples.\n\n---\n\n## Phase 7: Verification\n\n### 7.1 Build Gradle project\n\nBuild the migrated module to verify the migration succeeded:\n\n```bash\n.\u002Fgradlew :moduleName:build\n```\n\n### 7.2 Link framework\n\n```bash\n.\u002Fgradlew :moduleName:linkDebugFrameworkIosSimulatorArm64\n```\n\n### 7.3 Build iOS\u002FmacOS Xcode project\n\nAfter the Gradle build succeeds, build the Xcode project. Use `-project *.xcodeproj` if all CocoaPods were removed (Option A), or `-workspace *.xcworkspace` if non-KMP CocoaPods remain (Option B):\n\n```bash\ncd \u002Fpath\u002Fto\u002FiosApp\n# Discover schemes and build (replace -project\u002F-workspace as needed; for macOS use -destination 'platform=macOS'):\nxcodebuild -project *.xcodeproj -list -json 2>\u002Fdev\u002Fnull | python3 -c \"import sys,json; schemes=json.load(sys.stdin)['project']['schemes']; [print(s) for s in schemes]\"\nxcodebuild -project *.xcodeproj -scheme \"\u003CAppScheme>\" -destination 'generic\u002Fplatform=iOS Simulator' ARCHS=arm64 build\n```\n\n**If `checkSandboxAndWriteProtection` fails** — sandboxing was not disabled in Phase 5.1. Go back and apply the sandboxing fix from Phase 5.1, then retry.\n\n**If the pre-migration build was not verified** (Phase 1.0 fallback was used), warn the user:\n> Note: The pre-migration build could not be fully verified. If build errors appear now, some may be pre-existing issues unrelated to the migration. Compare errors against the pre-migration build output to distinguish migration issues from prior problems.\n\n### If the build fails\n\n**Do NOT revert the migration.** Read the error log, re-check Phases 2-6, and consult [troubleshooting.md](references\u002Ftroubleshooting.md). If unsure, present options to the user — do not silently undo migration work.\n\n---\n\n## Phase 8: Migration Report\n\nAfter migration (whether successful or not), write a comprehensive `MIGRATION_REPORT.md` in the project root. Use the template in [migration-report-template.md](references\u002Fmigration-report-template.md).\n\nThe report must include:\n1. **Pre-Migration State** — CocoaPods dependencies (name, version, `linkOnly`), framework config, `cocoapods.*` imports, non-KMP pods, atypical configuration\n2. **Migration Steps** — exact changes per phase with before\u002Fafter snippets for non-trivial changes\n3. **Import Transformations** — table of every import change, clearly marking preserved `cocoapods.*` imports and which bundled klib provides them\n4. **Errors Encountered** — structured `Error #N` entries: phase, exact symptom, root cause, fix, generalizable flag\n5. **Non-Trivial Decisions** — `isStatic` changes, preserved imports, framework search paths, trade-offs\n6. **Files Changed** — complete list grouped by type (Gradle, Kotlin, Xcode, created, deleted)\n\n---\n\n## Additional Resources\n\n- [DSL Reference](references\u002Fdsl-reference.md) - Full swiftPMDependencies syntax\n- [Common Pods Mapping](references\u002Fcommon-pods-mapping.md) - Pod to SPM mapping table\n- [CocoaPods Extras Patterns](references\u002Fcocoapods-extras-patterns.md) - Detection and cleanup patterns for CocoaPods workarounds\n- [Troubleshooting](references\u002Ftroubleshooting.md) - Issues, solutions, rollback\n- [Migration Report Template](references\u002Fmigration-report-template.md) - Post-migration report template\n",{"data":40,"body":45},{"name":4,"description":6,"license":31,"metadata":41},{"short-description":42,"author":9,"version":43,"source":44},"Migrate KMP from CocoaPods to SPM","1.0.0","https:\u002F\u002Fgithub.com\u002FKotlin\u002Fkotlin-agent-skills\u002Ftree\u002Fmain\u002Fskills\u002Fkotlin-tooling-cocoapods-spm-migration",{"type":46,"children":47},"root",[48,57,80,87,121,127,152,296,300,306,313,318,521,527,532,541,566,576,584,589,597,628,656,662,675,691,722,728,800,806,840,855,937,955,968,979,987,1369,1372,1378,1388,1394,1404,1416,1545,1551,1560,1565,1598,1604,1657,1677,1680,1686,1717,1723,1737,1743,1762,1819,1835,1874,2084,2090,2131,2161,2167,2179,2216,2249,2266,2272,2302,2314,2317,2323,2329,2339,2345,2406,2468,2474,2509,2526,2549,2555,2566,2575,2594,2612,2615,2621,2627,2632,2796,2801,2913,2946,2984,3019,3046,3103,3130,3146,3152,3183,3189,3199,3212,3479,3499,3541,3551,3563,3612,3646,3659,3665,3675,3678,3684,3689,3695,3733,3739,3774,3780,3791,3813,3819,3874,3884,3887,3893,3899,3904,3921,3927,3946,3952,3973,4126,4143,4153,4161,4167,4183,4186,4192,4212,4217,4317,4320,4326,4379],{"type":49,"tag":50,"props":51,"children":53},"element","h1",{"id":52},"cocoapods-to-swiftpm-migration-for-kmp",[54],{"type":55,"value":56},"text","CocoaPods to SwiftPM Migration for KMP",{"type":49,"tag":58,"props":59,"children":60},"p",{},[61,63,70,72,78],{"type":55,"value":62},"Migrate Kotlin Multiplatform projects from ",{"type":49,"tag":64,"props":65,"children":67},"code",{"className":66},[],[68],{"type":55,"value":69},"kotlin(\"native.cocoapods\")",{"type":55,"value":71}," to ",{"type":49,"tag":64,"props":73,"children":75},{"className":74},[],[76],{"type":55,"value":77},"swiftPMDependencies {}",{"type":55,"value":79}," DSL.",{"type":49,"tag":81,"props":82,"children":84},"h2",{"id":83},"requirements",[85],{"type":55,"value":86},"Requirements",{"type":49,"tag":88,"props":89,"children":90},"ul",{},[91,102,111],{"type":49,"tag":92,"props":93,"children":94},"li",{},[95,100],{"type":49,"tag":96,"props":97,"children":98},"strong",{},[99],{"type":55,"value":13},{"type":55,"value":101},": Version with Swift Import support (e.g., 2.4.0-Beta1 or later)",{"type":49,"tag":92,"props":103,"children":104},{},[105,109],{"type":49,"tag":96,"props":106,"children":107},{},[108],{"type":55,"value":26},{"type":55,"value":110},": 16.4 or 26.0+",{"type":49,"tag":92,"props":112,"children":113},{},[114,119],{"type":49,"tag":96,"props":115,"children":116},{},[117],{"type":55,"value":118},"iOS Deployment Target",{"type":55,"value":120},": 16.0+ recommended",{"type":49,"tag":81,"props":122,"children":124},{"id":123},"migration-overview",[125],{"type":55,"value":126},"Migration Overview",{"type":49,"tag":58,"props":128,"children":129},{},[130,135,137,143,145,150],{"type":49,"tag":96,"props":131,"children":132},{},[133],{"type":55,"value":134},"IMPORTANT",{"type":55,"value":136},": Keep the ",{"type":49,"tag":64,"props":138,"children":140},{"className":139},[],[141],{"type":55,"value":142},"cocoapods {}",{"type":55,"value":144}," block and plugin active until Phase 6. The migration adds ",{"type":49,"tag":64,"props":146,"children":148},{"className":147},[],[149],{"type":55,"value":77},{"type":55,"value":151}," alongside the existing CocoaPods setup first, reconfigures Xcode, and only then removes CocoaPods.",{"type":49,"tag":153,"props":154,"children":155},"table",{},[156,175],{"type":49,"tag":157,"props":158,"children":159},"thead",{},[160],{"type":49,"tag":161,"props":162,"children":163},"tr",{},[164,170],{"type":49,"tag":165,"props":166,"children":167},"th",{},[168],{"type":55,"value":169},"Phase",{"type":49,"tag":165,"props":171,"children":172},{},[173],{"type":55,"value":174},"Action",{"type":49,"tag":176,"props":177,"children":178},"tbody",{},[179,193,206,231,244,257,270,283],{"type":49,"tag":161,"props":180,"children":181},{},[182,188],{"type":49,"tag":183,"props":184,"children":185},"td",{},[186],{"type":55,"value":187},"1",{"type":49,"tag":183,"props":189,"children":190},{},[191],{"type":55,"value":192},"Analyze existing CocoaPods configuration",{"type":49,"tag":161,"props":194,"children":195},{},[196,201],{"type":49,"tag":183,"props":197,"children":198},{},[199],{"type":55,"value":200},"2",{"type":49,"tag":183,"props":202,"children":203},{},[204],{"type":55,"value":205},"Update Gradle configuration (repos, Kotlin version)",{"type":49,"tag":161,"props":207,"children":208},{},[209,214],{"type":49,"tag":183,"props":210,"children":211},{},[212],{"type":55,"value":213},"3",{"type":49,"tag":183,"props":215,"children":216},{},[217,219,224,226],{"type":55,"value":218},"Add ",{"type":49,"tag":64,"props":220,"children":222},{"className":221},[],[223],{"type":55,"value":77},{"type":55,"value":225}," alongside existing ",{"type":49,"tag":64,"props":227,"children":229},{"className":228},[],[230],{"type":55,"value":142},{"type":49,"tag":161,"props":232,"children":233},{},[234,239],{"type":49,"tag":183,"props":235,"children":236},{},[237],{"type":55,"value":238},"4",{"type":49,"tag":183,"props":240,"children":241},{},[242],{"type":55,"value":243},"Transform Kotlin imports",{"type":49,"tag":161,"props":245,"children":246},{},[247,252],{"type":49,"tag":183,"props":248,"children":249},{},[250],{"type":55,"value":251},"5",{"type":49,"tag":183,"props":253,"children":254},{},[255],{"type":55,"value":256},"Reconfigure iOS project and deintegrate CocoaPods",{"type":49,"tag":161,"props":258,"children":259},{},[260,265],{"type":49,"tag":183,"props":261,"children":262},{},[263],{"type":55,"value":264},"6",{"type":49,"tag":183,"props":266,"children":267},{},[268],{"type":55,"value":269},"Remove CocoaPods plugin from Gradle",{"type":49,"tag":161,"props":271,"children":272},{},[273,278],{"type":49,"tag":183,"props":274,"children":275},{},[276],{"type":55,"value":277},"7",{"type":49,"tag":183,"props":279,"children":280},{},[281],{"type":55,"value":282},"Verify Gradle build and Xcode project build",{"type":49,"tag":161,"props":284,"children":285},{},[286,291],{"type":49,"tag":183,"props":287,"children":288},{},[289],{"type":55,"value":290},"8",{"type":49,"tag":183,"props":292,"children":293},{},[294],{"type":55,"value":295},"Write MIGRATION_REPORT.md",{"type":49,"tag":297,"props":298,"children":299},"hr",{},[],{"type":49,"tag":81,"props":301,"children":303},{"id":302},"phase-1-pre-migration-analysis",[304],{"type":55,"value":305},"Phase 1: Pre-Migration Analysis",{"type":49,"tag":307,"props":308,"children":310},"h3",{"id":309},"_10-verify-the-project-builds",[311],{"type":55,"value":312},"1.0 Verify the project builds",{"type":49,"tag":58,"props":314,"children":315},{},[316],{"type":55,"value":317},"Before starting migration, identify the module to migrate and confirm it compiles successfully.",{"type":49,"tag":319,"props":320,"children":321},"ol",{},[322,436,486],{"type":49,"tag":92,"props":323,"children":324},{},[325,330,332,338,340,346,348,414,418,420,426,428,434],{"type":49,"tag":96,"props":326,"children":327},{},[328],{"type":55,"value":329},"Find the module that uses CocoaPods",{"type":55,"value":331}," — look for ",{"type":49,"tag":64,"props":333,"children":335},{"className":334},[],[336],{"type":55,"value":337},"build.gradle.kts",{"type":55,"value":339}," files containing ",{"type":49,"tag":64,"props":341,"children":343},{"className":342},[],[344],{"type":55,"value":345},"cocoapods",{"type":55,"value":347},":",{"type":49,"tag":349,"props":350,"children":355},"pre",{"className":351,"code":352,"language":353,"meta":354,"style":354},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","grep -rl \"cocoapods\" --include=\"build.gradle.kts\" .\n","bash","",[356],{"type":49,"tag":64,"props":357,"children":358},{"__ignoreMap":354},[359],{"type":49,"tag":360,"props":361,"children":364},"span",{"class":362,"line":363},"line",1,[365,371,377,383,387,392,397,401,405,409],{"type":49,"tag":360,"props":366,"children":368},{"style":367},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[369],{"type":55,"value":370},"grep",{"type":49,"tag":360,"props":372,"children":374},{"style":373},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[375],{"type":55,"value":376}," -rl",{"type":49,"tag":360,"props":378,"children":380},{"style":379},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[381],{"type":55,"value":382}," \"",{"type":49,"tag":360,"props":384,"children":385},{"style":373},[386],{"type":55,"value":345},{"type":49,"tag":360,"props":388,"children":389},{"style":379},[390],{"type":55,"value":391},"\"",{"type":49,"tag":360,"props":393,"children":394},{"style":373},[395],{"type":55,"value":396}," --include=",{"type":49,"tag":360,"props":398,"children":399},{"style":379},[400],{"type":55,"value":391},{"type":49,"tag":360,"props":402,"children":403},{"style":373},[404],{"type":55,"value":337},{"type":49,"tag":360,"props":406,"children":407},{"style":379},[408],{"type":55,"value":391},{"type":49,"tag":360,"props":410,"children":411},{"style":373},[412],{"type":55,"value":413}," .\n",{"type":49,"tag":415,"props":416,"children":417},"br",{},[],{"type":55,"value":419},"Extract the module name from the path (e.g., ",{"type":49,"tag":64,"props":421,"children":423},{"className":422},[],[424],{"type":55,"value":425},".\u002Fshared\u002Fbuild.gradle.kts",{"type":55,"value":427}," → module name is ",{"type":49,"tag":64,"props":429,"children":431},{"className":430},[],[432],{"type":55,"value":433},"shared",{"type":55,"value":435},").",{"type":49,"tag":92,"props":437,"children":438},{},[439,444,446,466,469,471,477,479,485],{"type":49,"tag":96,"props":440,"children":441},{},[442],{"type":55,"value":443},"Build only that module",{"type":55,"value":445}," (avoids building the entire multi-module project):",{"type":49,"tag":349,"props":447,"children":449},{"className":351,"code":448,"language":353,"meta":354,"style":354},".\u002Fgradlew :moduleName:build\n",[450],{"type":49,"tag":64,"props":451,"children":452},{"__ignoreMap":354},[453],{"type":49,"tag":360,"props":454,"children":455},{"class":362,"line":363},[456,461],{"type":49,"tag":360,"props":457,"children":458},{"style":367},[459],{"type":55,"value":460},".\u002Fgradlew",{"type":49,"tag":360,"props":462,"children":463},{"style":373},[464],{"type":55,"value":465}," :moduleName:build\n",{"type":49,"tag":415,"props":467,"children":468},{},[],{"type":55,"value":470},"Replace ",{"type":49,"tag":64,"props":472,"children":474},{"className":473},[],[475],{"type":55,"value":476},"moduleName",{"type":55,"value":478}," with the directory name of the module (e.g., ",{"type":49,"tag":64,"props":480,"children":482},{"className":481},[],[483],{"type":55,"value":484},":shared:build",{"type":55,"value":435},{"type":49,"tag":92,"props":487,"children":488},{},[489,494,496,509,512,514,519],{"type":49,"tag":96,"props":490,"children":491},{},[492],{"type":55,"value":493},"If the targeted build fails",{"type":55,"value":495},", ask the user to either:",{"type":49,"tag":88,"props":497,"children":498},{},[499,504],{"type":49,"tag":92,"props":500,"children":501},{},[502],{"type":55,"value":503},"Provide the correct Gradle command to verify the module builds, or",{"type":49,"tag":92,"props":505,"children":506},{},[507],{"type":55,"value":508},"Confirm the module is in a working state and it's safe to proceed",{"type":49,"tag":415,"props":510,"children":511},{},[],{"type":55,"value":513},"If the user confirms without providing a build command, ",{"type":49,"tag":96,"props":515,"children":516},{},[517],{"type":55,"value":518},"record that the pre-migration build could not be verified",{"type":55,"value":520}," and warn about this at the end of migration (Phase 7).",{"type":49,"tag":307,"props":522,"children":524},{"id":523},"_10a-confirm-kotlin-version-with-swift-import-support",[525],{"type":55,"value":526},"1.0a Confirm Kotlin version with Swift Import support",{"type":49,"tag":58,"props":528,"children":529},{},[530],{"type":55,"value":531},"Ask the user:",{"type":49,"tag":533,"props":534,"children":535},"blockquote",{},[536],{"type":49,"tag":58,"props":537,"children":538},{},[539],{"type":55,"value":540},"Does your project already use a Kotlin version with Swift Import support (swiftPMDependencies DSL)?",{"type":49,"tag":58,"props":542,"children":543},{},[544,549,551,557,559,564],{"type":49,"tag":96,"props":545,"children":546},{},[547],{"type":55,"value":548},"If yes",{"type":55,"value":550}," → read their current Kotlin version from ",{"type":49,"tag":64,"props":552,"children":554},{"className":553},[],[555],{"type":55,"value":556},"gradle\u002Flibs.versions.toml",{"type":55,"value":558}," (or ",{"type":49,"tag":64,"props":560,"children":562},{"className":561},[],[563],{"type":55,"value":337},{"type":55,"value":565},"), record it, and skip Phase 2.2 (no version change needed).",{"type":49,"tag":58,"props":567,"children":568},{},[569,574],{"type":49,"tag":96,"props":570,"children":571},{},[572],{"type":55,"value":573},"If no",{"type":55,"value":575}," → ask:",{"type":49,"tag":533,"props":577,"children":578},{},[579],{"type":49,"tag":58,"props":580,"children":581},{},[582],{"type":55,"value":583},"Please provide the Kotlin version to use (e.g., \"2.4.0\", \"2.4.0-Beta1\", \"2.4.0-dev-123\").",{"type":49,"tag":58,"props":585,"children":586},{},[587],{"type":55,"value":588},"Record the user-provided version. Then ask:",{"type":49,"tag":533,"props":590,"children":591},{},[592],{"type":49,"tag":58,"props":593,"children":594},{},[595],{"type":55,"value":596},"Does this Kotlin version require a custom Maven repository (e.g., JetBrains dev repo)?",{"type":49,"tag":88,"props":598,"children":599},{},[600,618],{"type":49,"tag":92,"props":601,"children":602},{},[603,608,610,616],{"type":49,"tag":96,"props":604,"children":605},{},[606],{"type":55,"value":607},"Yes",{"type":55,"value":609}," → ask for the repo URL (suggest ",{"type":49,"tag":64,"props":611,"children":613},{"className":612},[],[614],{"type":55,"value":615},"https:\u002F\u002Fpackages.jetbrains.team\u002Fmaven\u002Fp\u002Fkt\u002Fdev",{"type":55,"value":617}," as default). Phase 2.1 will add it.",{"type":49,"tag":92,"props":619,"children":620},{},[621,626],{"type":49,"tag":96,"props":622,"children":623},{},[624],{"type":55,"value":625},"No",{"type":55,"value":627}," → Phase 2.1 is skipped (no custom repo needed).",{"type":49,"tag":58,"props":629,"children":630},{},[631,633,638,640,646,648,654],{"type":55,"value":632},"Finally, check the project's current Kotlin version. Compare ",{"type":49,"tag":96,"props":634,"children":635},{},[636],{"type":55,"value":637},"major.minor",{"type":55,"value":639}," against the target. If it differs significantly (e.g., ",{"type":49,"tag":64,"props":641,"children":643},{"className":642},[],[644],{"type":55,"value":645},"2.1.0",{"type":55,"value":647}," → ",{"type":49,"tag":64,"props":649,"children":651},{"className":650},[],[652],{"type":55,"value":653},"2.4.0",{"type":55,"value":655},"), warn: \"⚠️ Kotlin version jump — upgrading across minor versions can introduce breaking changes unrelated to this migration. Recommended: update first, verify it builds, then re-run.\" If the user confirms despite the mismatch, proceed.",{"type":49,"tag":307,"props":657,"children":659},{"id":658},"_11-check-for-deprecated-cocoapods-workaround-property",[660],{"type":55,"value":661},"1.1 Check for deprecated CocoaPods workaround property",{"type":49,"tag":58,"props":663,"children":664},{},[665,667,673],{"type":55,"value":666},"Search ",{"type":49,"tag":64,"props":668,"children":670},{"className":669},[],[671],{"type":55,"value":672},"gradle.properties",{"type":55,"value":674}," for the deprecated property:",{"type":49,"tag":349,"props":676,"children":680},{"className":677,"code":678,"language":679,"meta":354,"style":354},"language-properties shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","kotlin.apple.deprecated.allowUsingEmbedAndSignWithCocoaPodsDependencies=true\n","properties",[681],{"type":49,"tag":64,"props":682,"children":683},{"__ignoreMap":354},[684],{"type":49,"tag":360,"props":685,"children":686},{"class":362,"line":363},[687],{"type":49,"tag":360,"props":688,"children":689},{},[690],{"type":55,"value":678},{"type":49,"tag":58,"props":692,"children":693},{},[694,696,705,707,713,715,720],{"type":55,"value":695},"This property was a workaround (see ",{"type":49,"tag":697,"props":698,"children":702},"a",{"href":699,"rel":700},"https:\u002F\u002Fyoutrack.jetbrains.com\u002Fissue\u002FKT-64096",[701],"nofollow",[703],{"type":55,"value":704},"KT-64096",{"type":55,"value":706},") for projects using ",{"type":49,"tag":64,"props":708,"children":710},{"className":709},[],[711],{"type":55,"value":712},"embedAndSign",{"type":55,"value":714}," alongside CocoaPods dependencies. It suppresses an error about unsupported configurations that can cause runtime crashes or symbol duplication. After migrating to SwiftPM import, this property is no longer needed and ",{"type":49,"tag":96,"props":716,"children":717},{},[718],{"type":55,"value":719},"must be removed",{"type":55,"value":721}," in Phase 6. Record its presence if found.",{"type":49,"tag":307,"props":723,"children":725},{"id":724},"_12-check-for-embedandsign-disablers",[726],{"type":55,"value":727},"1.2 Check for EmbedAndSign disablers",{"type":49,"tag":58,"props":729,"children":730},{},[731,733,738,740,746,748,754,756,762,764,769,771,777,779,783,785,791,793,798],{"type":55,"value":732},"Search all ",{"type":49,"tag":64,"props":734,"children":736},{"className":735},[],[737],{"type":55,"value":337},{"type":55,"value":739}," files for code that disables ",{"type":49,"tag":64,"props":741,"children":743},{"className":742},[],[744],{"type":55,"value":745},"EmbedAndSign",{"type":55,"value":747}," tasks (e.g., ",{"type":49,"tag":64,"props":749,"children":751},{"className":750},[],[752],{"type":55,"value":753},"TaskGraph.whenReady",{"type":55,"value":755}," filters, ",{"type":49,"tag":64,"props":757,"children":759},{"className":758},[],[760],{"type":55,"value":761},"tasks.matching",{"type":55,"value":763}," blocks). This is a CocoaPods-era workaround that ",{"type":49,"tag":96,"props":765,"children":766},{},[767],{"type":55,"value":768},"breaks the migration",{"type":55,"value":770}," because ",{"type":49,"tag":64,"props":772,"children":774},{"className":773},[],[775],{"type":55,"value":776},"integrateEmbedAndSign",{"type":55,"value":778}," (needed in Phase 5) gets disabled too. Record any such code — it ",{"type":49,"tag":96,"props":780,"children":781},{},[782],{"type":55,"value":719},{"type":55,"value":784}," in Phase 6, and may need to be removed earlier. See ",{"type":49,"tag":697,"props":786,"children":788},{"href":787},"references\u002Ftroubleshooting.md",[789],{"type":55,"value":790},"troubleshooting.md",{"type":55,"value":792}," § \"",{"type":49,"tag":64,"props":794,"children":796},{"className":795},[],[797],{"type":55,"value":776},{"type":55,"value":799}," Skipped\" for patterns.",{"type":49,"tag":307,"props":801,"children":803},{"id":802},"_13-check-for-third-party-kmp-libraries-with-bundled-cinterop-klibs",[804],{"type":55,"value":805},"1.3 Check for third-party KMP libraries with bundled cinterop klibs",{"type":49,"tag":58,"props":807,"children":808},{},[809,811,817,819,824,826,831,833,838],{"type":55,"value":810},"Some KMP libraries ship pre-built cinterop klibs with ",{"type":49,"tag":64,"props":812,"children":814},{"className":813},[],[815],{"type":55,"value":816},"cocoapods.*",{"type":55,"value":818}," package namespaces. After migration, the swiftPMDependencies cinterop generator detects these existing bindings and ",{"type":49,"tag":96,"props":820,"children":821},{},[822],{"type":55,"value":823},"skips generating new bindings",{"type":55,"value":825}," for those Clang modules to avoid duplicates. This means ",{"type":49,"tag":64,"props":827,"children":829},{"className":828},[],[830],{"type":55,"value":816},{"type":55,"value":832}," imports for those modules must be ",{"type":49,"tag":96,"props":834,"children":835},{},[836],{"type":55,"value":837},"kept as-is",{"type":55,"value":839}," — they resolve to the third-party library's bundled klib, not to actual CocoaPods.",{"type":49,"tag":58,"props":841,"children":842},{},[843],{"type":49,"tag":96,"props":844,"children":845},{},[846,848,853],{"type":55,"value":847},"Known libraries with bundled ",{"type":49,"tag":64,"props":849,"children":851},{"className":850},[],[852],{"type":55,"value":816},{"type":55,"value":854}," klibs:",{"type":49,"tag":153,"props":856,"children":857},{},[858,884],{"type":49,"tag":157,"props":859,"children":860},{},[861],{"type":49,"tag":161,"props":862,"children":863},{},[864,869,874,879],{"type":49,"tag":165,"props":865,"children":866},{},[867],{"type":55,"value":868},"Library",{"type":49,"tag":165,"props":870,"children":871},{},[872],{"type":55,"value":873},"Maven artifact",{"type":49,"tag":165,"props":875,"children":876},{},[877],{"type":55,"value":878},"Bundled klib namespace",{"type":49,"tag":165,"props":880,"children":881},{},[882],{"type":55,"value":883},"Classes provided",{"type":49,"tag":176,"props":885,"children":886},{},[887],{"type":49,"tag":161,"props":888,"children":889},{},[890,900,909,918],{"type":49,"tag":183,"props":891,"children":892},{},[893],{"type":49,"tag":697,"props":894,"children":897},{"href":895,"rel":896},"https:\u002F\u002Fgithub.com\u002Fmirzemehdi\u002FKMPNotifier",[701],[898],{"type":55,"value":899},"KMPNotifier",{"type":49,"tag":183,"props":901,"children":902},{},[903],{"type":49,"tag":64,"props":904,"children":906},{"className":905},[],[907],{"type":55,"value":908},"io.github.mirzemehdi:kmpnotifier",{"type":49,"tag":183,"props":910,"children":911},{},[912],{"type":49,"tag":64,"props":913,"children":915},{"className":914},[],[916],{"type":55,"value":917},"cocoapods.FirebaseMessaging",{"type":49,"tag":183,"props":919,"children":920},{},[921,927,929,935],{"type":49,"tag":64,"props":922,"children":924},{"className":923},[],[925],{"type":55,"value":926},"FIRMessaging",{"type":55,"value":928},", ",{"type":49,"tag":64,"props":930,"children":932},{"className":931},[],[933],{"type":55,"value":934},"FIRMessagingAPNSTokenType",{"type":55,"value":936},", etc.",{"type":49,"tag":58,"props":938,"children":939},{},[940,945,947,953],{"type":49,"tag":96,"props":941,"children":942},{},[943],{"type":55,"value":944},"How to detect:",{"type":55,"value":946}," Search Gradle dependency declarations for known libraries, then cross-reference their bundled namespaces against the ",{"type":49,"tag":64,"props":948,"children":950},{"className":949},[],[951],{"type":55,"value":952},"import cocoapods.*",{"type":55,"value":954}," statements found in step 4. Mark any matches — these imports will NOT be transformed in Phase 4.",{"type":49,"tag":58,"props":956,"children":957},{},[958,960,966],{"type":55,"value":959},"If unsure whether a third-party KMP library bundles cinterop klibs, check if it has a ",{"type":49,"tag":64,"props":961,"children":963},{"className":962},[],[964],{"type":55,"value":965},"linkOnly = true",{"type":55,"value":967}," pod dependency in the project — this is a strong indicator that the library provides its own klib for those classes.",{"type":49,"tag":58,"props":969,"children":970},{},[971,973,977],{"type":55,"value":972},"To inspect klib contents and verify bundled bindings, see ",{"type":49,"tag":697,"props":974,"children":975},{"href":787},[976],{"type":55,"value":790},{"type":55,"value":978}," § \"Third-Party KMP Libraries with Bundled Klibs\".",{"type":49,"tag":58,"props":980,"children":981},{},[982],{"type":49,"tag":96,"props":983,"children":984},{},[985],{"type":55,"value":986},"Find and record:",{"type":49,"tag":319,"props":988,"children":989},{},[990,1014,1031,1062,1095,1112,1126,1216,1226,1282,1307],{"type":49,"tag":92,"props":991,"children":992},{},[993,998,1000,1005,1007,1012],{"type":49,"tag":96,"props":994,"children":995},{},[996],{"type":55,"value":997},"CocoaPods configuration",{"type":55,"value":999}," - Search for ",{"type":49,"tag":64,"props":1001,"children":1003},{"className":1002},[],[1004],{"type":55,"value":345},{"type":55,"value":1006}," in ",{"type":49,"tag":64,"props":1008,"children":1010},{"className":1009},[],[1011],{"type":55,"value":337},{"type":55,"value":1013}," files",{"type":49,"tag":92,"props":1015,"children":1016},{},[1017,1022,1024,1029],{"type":49,"tag":96,"props":1018,"children":1019},{},[1020],{"type":55,"value":1021},"Pod dependencies",{"type":55,"value":1023}," - Extract pod names, versions from ",{"type":49,"tag":64,"props":1025,"children":1027},{"className":1026},[],[1028],{"type":55,"value":142},{"type":55,"value":1030}," blocks",{"type":49,"tag":92,"props":1032,"children":1033},{},[1034,1039,1041,1047,1048,1054,1056],{"type":49,"tag":96,"props":1035,"children":1036},{},[1037],{"type":55,"value":1038},"Framework configuration",{"type":55,"value":1040}," - Record ",{"type":49,"tag":64,"props":1042,"children":1044},{"className":1043},[],[1045],{"type":55,"value":1046},"baseName",{"type":55,"value":928},{"type":49,"tag":64,"props":1049,"children":1051},{"className":1050},[],[1052],{"type":55,"value":1053},"isStatic",{"type":55,"value":1055},", deployment target from ",{"type":49,"tag":64,"props":1057,"children":1059},{"className":1058},[],[1060],{"type":55,"value":1061},"cocoapods.framework {}",{"type":49,"tag":92,"props":1063,"children":1064},{},[1065,1070,1072,1077,1079,1085,1087,1093],{"type":49,"tag":96,"props":1066,"children":1067},{},[1068],{"type":55,"value":1069},"linkOnly pods",{"type":55,"value":1071}," - Record pods declared with ",{"type":49,"tag":64,"props":1073,"children":1075},{"className":1074},[],[1076],{"type":55,"value":965},{"type":55,"value":1078},". These pods provide native linking only — cinterop bindings come from a KMP wrapper library (e.g., ",{"type":49,"tag":64,"props":1080,"children":1082},{"className":1081},[],[1083],{"type":55,"value":1084},"dev.gitlive:firebase-*",{"type":55,"value":1086},"). See ",{"type":49,"tag":697,"props":1088,"children":1090},{"href":1089},"references\u002Fcommon-pods-mapping.md",[1091],{"type":55,"value":1092},"common-pods-mapping.md",{"type":55,"value":1094}," for implications.",{"type":49,"tag":92,"props":1096,"children":1097},{},[1098,1103,1105,1110],{"type":49,"tag":96,"props":1099,"children":1100},{},[1101],{"type":55,"value":1102},"Kotlin imports",{"type":55,"value":1104}," - Find all ",{"type":49,"tag":64,"props":1106,"children":1108},{"className":1107},[],[1109],{"type":55,"value":952},{"type":55,"value":1111}," statements. Cross-reference with step 1.3 to identify which imports come from bundled klibs (and must be preserved) vs. which come from direct pod cinterop (and must be transformed).",{"type":49,"tag":92,"props":1113,"children":1114},{},[1115,1120,1122],{"type":49,"tag":96,"props":1116,"children":1117},{},[1118],{"type":55,"value":1119},"Map pods to SPM",{"type":55,"value":1121}," - See ",{"type":49,"tag":697,"props":1123,"children":1124},{"href":1089},[1125],{"type":55,"value":1092},{"type":49,"tag":92,"props":1127,"children":1128},{},[1129,1134,1136,1142,1144,1150,1152,1199,1201,1207,1208,1214],{"type":49,"tag":96,"props":1130,"children":1131},{},[1132],{"type":55,"value":1133},"Locate iOS project directory",{"type":55,"value":1135}," - Find the directory containing ",{"type":49,"tag":64,"props":1137,"children":1139},{"className":1138},[],[1140],{"type":55,"value":1141},"Podfile",{"type":55,"value":1143}," and ",{"type":49,"tag":64,"props":1145,"children":1147},{"className":1146},[],[1148],{"type":55,"value":1149},".xcworkspace",{"type":55,"value":1151},":\n",{"type":49,"tag":349,"props":1153,"children":1155},{"className":351,"code":1154,"language":353,"meta":354,"style":354},"find . -name \"Podfile\" -type f\n",[1156],{"type":49,"tag":64,"props":1157,"children":1158},{"__ignoreMap":354},[1159],{"type":49,"tag":360,"props":1160,"children":1161},{"class":362,"line":363},[1162,1167,1172,1177,1181,1185,1189,1194],{"type":49,"tag":360,"props":1163,"children":1164},{"style":367},[1165],{"type":55,"value":1166},"find",{"type":49,"tag":360,"props":1168,"children":1169},{"style":373},[1170],{"type":55,"value":1171}," .",{"type":49,"tag":360,"props":1173,"children":1174},{"style":373},[1175],{"type":55,"value":1176}," -name",{"type":49,"tag":360,"props":1178,"children":1179},{"style":379},[1180],{"type":55,"value":382},{"type":49,"tag":360,"props":1182,"children":1183},{"style":373},[1184],{"type":55,"value":1141},{"type":49,"tag":360,"props":1186,"children":1187},{"style":379},[1188],{"type":55,"value":391},{"type":49,"tag":360,"props":1190,"children":1191},{"style":373},[1192],{"type":55,"value":1193}," -type",{"type":49,"tag":360,"props":1195,"children":1196},{"style":373},[1197],{"type":55,"value":1198}," f\n",{"type":55,"value":1200},"\nRecord this path (e.g., ",{"type":49,"tag":64,"props":1202,"children":1204},{"className":1203},[],[1205],{"type":55,"value":1206},"iosApp\u002F",{"type":55,"value":928},{"type":49,"tag":64,"props":1209,"children":1211},{"className":1210},[],[1212],{"type":55,"value":1213},"ios\u002F",{"type":55,"value":1215},", or project root) - needed for Phase 5",{"type":49,"tag":92,"props":1217,"children":1218},{},[1219,1224],{"type":49,"tag":96,"props":1220,"children":1221},{},[1222],{"type":55,"value":1223},"Check for non-KMP CocoaPods",{"type":55,"value":1225}," - Determine if the project uses CocoaPods for dependencies other than KMP. This affects cleanup strategy in Phase 5.",{"type":49,"tag":92,"props":1227,"children":1228},{},[1229,1234,1236,1242,1244,1250,1252,1258,1260,1265,1267,1273,1275,1280],{"type":49,"tag":96,"props":1230,"children":1231},{},[1232],{"type":55,"value":1233},"Check Xcode build phases",{"type":55,"value":1235}," - Open the ",{"type":49,"tag":64,"props":1237,"children":1239},{"className":1238},[],[1240],{"type":55,"value":1241},".xcodeproj",{"type":55,"value":1243},"'s ",{"type":49,"tag":64,"props":1245,"children":1247},{"className":1246},[],[1248],{"type":55,"value":1249},"project.pbxproj",{"type":55,"value":1251}," and search for the Gradle build phase script. Check if ",{"type":49,"tag":64,"props":1253,"children":1255},{"className":1254},[],[1256],{"type":55,"value":1257},"embedAndSignAppleFrameworkForXcode",{"type":55,"value":1259}," is present but ",{"type":49,"tag":96,"props":1261,"children":1262},{},[1263],{"type":55,"value":1264},"commented out",{"type":55,"value":1266}," (prefixed with ",{"type":49,"tag":64,"props":1268,"children":1270},{"className":1269},[],[1271],{"type":55,"value":1272},"#",{"type":55,"value":1274},"). If commented out, it must be uncommented during Phase 5 — the ",{"type":49,"tag":64,"props":1276,"children":1278},{"className":1277},[],[1279],{"type":55,"value":776},{"type":55,"value":1281}," task may or may not handle this automatically.",{"type":49,"tag":92,"props":1283,"children":1284},{},[1285,1290,1292,1297,1299,1305],{"type":49,"tag":96,"props":1286,"children":1287},{},[1288],{"type":55,"value":1289},"Check for existing Crashlytics dSYM upload script",{"type":55,"value":1291}," - If using FirebaseCrashlytics, search ",{"type":49,"tag":64,"props":1293,"children":1295},{"className":1294},[],[1296],{"type":55,"value":1249},{"type":55,"value":1298}," for a dSYM upload shell script phase. Record its current path (CocoaPods-era scripts reference ",{"type":49,"tag":64,"props":1300,"children":1302},{"className":1301},[],[1303],{"type":55,"value":1304},"${PODS_ROOT}\u002FFirebaseCrashlytics\u002Fupload-symbols",{"type":55,"value":1306},"). This must be updated to the SPM path in Phase 5.",{"type":49,"tag":92,"props":1308,"children":1309},{},[1310,1315,1317,1322,1324,1329,1331,1337,1338,1344,1346,1352,1353,1359,1361,1367],{"type":49,"tag":96,"props":1311,"children":1312},{},[1313],{"type":55,"value":1314},"Identify CocoaPods-related extras in build scripts",{"type":55,"value":1316}," - Search all ",{"type":49,"tag":64,"props":1318,"children":1320},{"className":1319},[],[1321],{"type":55,"value":337},{"type":55,"value":1323}," files for CocoaPods workarounds beyond the standard ",{"type":49,"tag":64,"props":1325,"children":1327},{"className":1326},[],[1328],{"type":55,"value":142},{"type":55,"value":1330}," block (custom tasks hooking into ",{"type":49,"tag":64,"props":1332,"children":1334},{"className":1333},[],[1335],{"type":55,"value":1336},"podInstall",{"type":55,"value":928},{"type":49,"tag":64,"props":1339,"children":1341},{"className":1340},[],[1342],{"type":55,"value":1343},"Pods.xcodeproj",{"type":55,"value":1345}," patching, podspec metadata, ",{"type":49,"tag":64,"props":1347,"children":1349},{"className":1348},[],[1350],{"type":55,"value":1351},"extraSpecAttributes",{"type":55,"value":928},{"type":49,"tag":64,"props":1354,"children":1356},{"className":1355},[],[1357],{"type":55,"value":1358},"noPodspec()",{"type":55,"value":1360},", etc.). See ",{"type":49,"tag":697,"props":1362,"children":1364},{"href":1363},"references\u002Fcocoapods-extras-patterns.md",[1365],{"type":55,"value":1366},"cocoapods-extras-patterns.md",{"type":55,"value":1368}," for the full pattern list. Record all findings — these will be handled in Phase 6.",{"type":49,"tag":297,"props":1370,"children":1371},{},[],{"type":49,"tag":81,"props":1373,"children":1375},{"id":1374},"phase-2-gradle-configuration",[1376],{"type":55,"value":1377},"Phase 2: Gradle Configuration",{"type":49,"tag":58,"props":1379,"children":1380},{},[1381,1386],{"type":49,"tag":96,"props":1382,"children":1383},{},[1384],{"type":55,"value":1385},"Important scope note:",{"type":55,"value":1387}," Do NOT upgrade the Gradle wrapper version, update KSP, or update any other dependencies during this migration. Those are separate concerns and out of scope. Only change what is listed below.",{"type":49,"tag":307,"props":1389,"children":1391},{"id":1390},"_21-add-custom-maven-repository-if-needed",[1392],{"type":55,"value":1393},"2.1 Add custom Maven repository (if needed)",{"type":49,"tag":58,"props":1395,"children":1396},{},[1397,1402],{"type":49,"tag":96,"props":1398,"children":1399},{},[1400],{"type":55,"value":1401},"Skip this step",{"type":55,"value":1403}," if the user indicated in Phase 1.0a that their Kotlin version does not require a custom Maven repository (i.e., it is an official release, Beta, or RC available from Maven Central).",{"type":49,"tag":58,"props":1405,"children":1406},{},[1407,1409,1415],{"type":55,"value":1408},"For dev\u002Fcustom builds, add the custom Maven repository (URL from Phase 1.0a) to ",{"type":49,"tag":64,"props":1410,"children":1412},{"className":1411},[],[1413],{"type":55,"value":1414},"settings.gradle.kts",{"type":55,"value":347},{"type":49,"tag":349,"props":1417,"children":1420},{"className":1418,"code":1419,"language":14,"meta":354,"style":354},"language-kotlin shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pluginManagement {\n    repositories {\n        gradlePluginPortal()\n        mavenCentral()\n        maven(\"\u003Ccustom-repo-url>\")  \u002F\u002F ADD\n    }\n}\n\ndependencyResolutionManagement {\n    repositories {\n        mavenCentral()\n        maven(\"\u003Ccustom-repo-url>\")  \u002F\u002F ADD\n    }\n}\n",[1421],{"type":49,"tag":64,"props":1422,"children":1423},{"__ignoreMap":354},[1424,1432,1441,1450,1459,1468,1477,1486,1496,1505,1513,1521,1529,1537],{"type":49,"tag":360,"props":1425,"children":1426},{"class":362,"line":363},[1427],{"type":49,"tag":360,"props":1428,"children":1429},{},[1430],{"type":55,"value":1431},"pluginManagement {\n",{"type":49,"tag":360,"props":1433,"children":1435},{"class":362,"line":1434},2,[1436],{"type":49,"tag":360,"props":1437,"children":1438},{},[1439],{"type":55,"value":1440},"    repositories {\n",{"type":49,"tag":360,"props":1442,"children":1444},{"class":362,"line":1443},3,[1445],{"type":49,"tag":360,"props":1446,"children":1447},{},[1448],{"type":55,"value":1449},"        gradlePluginPortal()\n",{"type":49,"tag":360,"props":1451,"children":1453},{"class":362,"line":1452},4,[1454],{"type":49,"tag":360,"props":1455,"children":1456},{},[1457],{"type":55,"value":1458},"        mavenCentral()\n",{"type":49,"tag":360,"props":1460,"children":1462},{"class":362,"line":1461},5,[1463],{"type":49,"tag":360,"props":1464,"children":1465},{},[1466],{"type":55,"value":1467},"        maven(\"\u003Ccustom-repo-url>\")  \u002F\u002F ADD\n",{"type":49,"tag":360,"props":1469,"children":1471},{"class":362,"line":1470},6,[1472],{"type":49,"tag":360,"props":1473,"children":1474},{},[1475],{"type":55,"value":1476},"    }\n",{"type":49,"tag":360,"props":1478,"children":1480},{"class":362,"line":1479},7,[1481],{"type":49,"tag":360,"props":1482,"children":1483},{},[1484],{"type":55,"value":1485},"}\n",{"type":49,"tag":360,"props":1487,"children":1489},{"class":362,"line":1488},8,[1490],{"type":49,"tag":360,"props":1491,"children":1493},{"emptyLinePlaceholder":1492},true,[1494],{"type":55,"value":1495},"\n",{"type":49,"tag":360,"props":1497,"children":1499},{"class":362,"line":1498},9,[1500],{"type":49,"tag":360,"props":1501,"children":1502},{},[1503],{"type":55,"value":1504},"dependencyResolutionManagement {\n",{"type":49,"tag":360,"props":1506,"children":1508},{"class":362,"line":1507},10,[1509],{"type":49,"tag":360,"props":1510,"children":1511},{},[1512],{"type":55,"value":1440},{"type":49,"tag":360,"props":1514,"children":1516},{"class":362,"line":1515},11,[1517],{"type":49,"tag":360,"props":1518,"children":1519},{},[1520],{"type":55,"value":1458},{"type":49,"tag":360,"props":1522,"children":1524},{"class":362,"line":1523},12,[1525],{"type":49,"tag":360,"props":1526,"children":1527},{},[1528],{"type":55,"value":1467},{"type":49,"tag":360,"props":1530,"children":1532},{"class":362,"line":1531},13,[1533],{"type":49,"tag":360,"props":1534,"children":1535},{},[1536],{"type":55,"value":1476},{"type":49,"tag":360,"props":1538,"children":1540},{"class":362,"line":1539},14,[1541],{"type":49,"tag":360,"props":1542,"children":1543},{},[1544],{"type":55,"value":1485},{"type":49,"tag":307,"props":1546,"children":1548},{"id":1547},"_22-update-kotlin-version",[1549],{"type":55,"value":1550},"2.2 Update Kotlin version",{"type":49,"tag":58,"props":1552,"children":1553},{},[1554,1558],{"type":49,"tag":96,"props":1555,"children":1556},{},[1557],{"type":55,"value":1401},{"type":55,"value":1559}," if the user's project already uses a Kotlin version with Swift Import support (recorded in Phase 1.0a).",{"type":49,"tag":58,"props":1561,"children":1562},{},[1563],{"type":55,"value":1564},"Update to the version recorded in Phase 1.0a:",{"type":49,"tag":349,"props":1566,"children":1570},{"className":1567,"code":1568,"language":1569,"meta":354,"style":354},"language-toml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# gradle\u002Flibs.versions.toml\n[versions]\nkotlin = \"\u003Ckotlin-version>\"\n","toml",[1571],{"type":49,"tag":64,"props":1572,"children":1573},{"__ignoreMap":354},[1574,1582,1590],{"type":49,"tag":360,"props":1575,"children":1576},{"class":362,"line":363},[1577],{"type":49,"tag":360,"props":1578,"children":1579},{},[1580],{"type":55,"value":1581},"# gradle\u002Flibs.versions.toml\n",{"type":49,"tag":360,"props":1583,"children":1584},{"class":362,"line":1434},[1585],{"type":49,"tag":360,"props":1586,"children":1587},{},[1588],{"type":55,"value":1589},"[versions]\n",{"type":49,"tag":360,"props":1591,"children":1592},{"class":362,"line":1443},[1593],{"type":49,"tag":360,"props":1594,"children":1595},{},[1596],{"type":55,"value":1597},"kotlin = \"\u003Ckotlin-version>\"\n",{"type":49,"tag":307,"props":1599,"children":1601},{"id":1600},"_23-add-buildscript-constraint-if-swiftpmdependencies-not-recognized",[1602],{"type":55,"value":1603},"2.3 Add buildscript constraint (if swiftPMDependencies not recognized)",{"type":49,"tag":349,"props":1605,"children":1607},{"className":1418,"code":1606,"language":14,"meta":354,"style":354},"\u002F\u002F root build.gradle.kts\nbuildscript {\n    dependencies.constraints {\n        \"classpath\"(\"org.jetbrains.kotlin:kotlin-gradle-plugin:\u003Ckotlin-version>!!\")\n    }\n}\n",[1608],{"type":49,"tag":64,"props":1609,"children":1610},{"__ignoreMap":354},[1611,1619,1627,1635,1643,1650],{"type":49,"tag":360,"props":1612,"children":1613},{"class":362,"line":363},[1614],{"type":49,"tag":360,"props":1615,"children":1616},{},[1617],{"type":55,"value":1618},"\u002F\u002F root build.gradle.kts\n",{"type":49,"tag":360,"props":1620,"children":1621},{"class":362,"line":1434},[1622],{"type":49,"tag":360,"props":1623,"children":1624},{},[1625],{"type":55,"value":1626},"buildscript {\n",{"type":49,"tag":360,"props":1628,"children":1629},{"class":362,"line":1443},[1630],{"type":49,"tag":360,"props":1631,"children":1632},{},[1633],{"type":55,"value":1634},"    dependencies.constraints {\n",{"type":49,"tag":360,"props":1636,"children":1637},{"class":362,"line":1452},[1638],{"type":49,"tag":360,"props":1639,"children":1640},{},[1641],{"type":55,"value":1642},"        \"classpath\"(\"org.jetbrains.kotlin:kotlin-gradle-plugin:\u003Ckotlin-version>!!\")\n",{"type":49,"tag":360,"props":1644,"children":1645},{"class":362,"line":1461},[1646],{"type":49,"tag":360,"props":1647,"children":1648},{},[1649],{"type":55,"value":1476},{"type":49,"tag":360,"props":1651,"children":1652},{"class":362,"line":1470},[1653],{"type":49,"tag":360,"props":1654,"children":1655},{},[1656],{"type":55,"value":1485},{"type":49,"tag":58,"props":1658,"children":1659},{},[1660,1661,1667,1669,1675],{"type":55,"value":470},{"type":49,"tag":64,"props":1662,"children":1664},{"className":1663},[],[1665],{"type":55,"value":1666},"\u003Ckotlin-version>",{"type":55,"value":1668}," with the version recorded in Phase 1.0a. The ",{"type":49,"tag":64,"props":1670,"children":1672},{"className":1671},[],[1673],{"type":55,"value":1674},"!!",{"type":55,"value":1676}," suffix forces strict version resolution, ensuring no other dependency pulls in a different Kotlin Gradle plugin version.",{"type":49,"tag":297,"props":1678,"children":1679},{},[],{"type":49,"tag":81,"props":1681,"children":1683},{"id":1682},"phase-3-add-swiftpmdependencies-keep-cocoapods",[1684],{"type":55,"value":1685},"Phase 3: Add swiftPMDependencies (Keep CocoaPods)",{"type":49,"tag":58,"props":1687,"children":1688},{},[1689,1708,1710,1715],{"type":49,"tag":96,"props":1690,"children":1691},{},[1692,1694,1699,1701,1706],{"type":55,"value":1693},"Do NOT remove the ",{"type":49,"tag":64,"props":1695,"children":1697},{"className":1696},[],[1698],{"type":55,"value":142},{"type":55,"value":1700}," block or ",{"type":49,"tag":64,"props":1702,"children":1704},{"className":1703},[],[1705],{"type":55,"value":69},{"type":55,"value":1707}," plugin yet.",{"type":55,"value":1709}," Add ",{"type":49,"tag":64,"props":1711,"children":1713},{"className":1712},[],[1714],{"type":55,"value":77},{"type":55,"value":1716}," alongside the existing CocoaPods configuration.",{"type":49,"tag":307,"props":1718,"children":1720},{"id":1719},"_31-add-group-property",[1721],{"type":55,"value":1722},"3.1 Add group property",{"type":49,"tag":349,"props":1724,"children":1726},{"className":1418,"code":1725,"language":14,"meta":354,"style":354},"group = \"org.example.myproject\"  \u002F\u002F Required for import namespace\n",[1727],{"type":49,"tag":64,"props":1728,"children":1729},{"__ignoreMap":354},[1730],{"type":49,"tag":360,"props":1731,"children":1732},{"class":362,"line":363},[1733],{"type":49,"tag":360,"props":1734,"children":1735},{},[1736],{"type":55,"value":1725},{"type":49,"tag":307,"props":1738,"children":1740},{"id":1739},"_32-add-swiftpmdependencies-block-alongside-cocoapods",[1741],{"type":55,"value":1742},"3.2 Add swiftPMDependencies block alongside cocoapods",{"type":49,"tag":58,"props":1744,"children":1745},{},[1746,1748,1752,1754,1760],{"type":55,"value":1747},"For each pod dependency, add the equivalent SwiftPM package declaration. Use ",{"type":49,"tag":697,"props":1749,"children":1750},{"href":1089},[1751],{"type":55,"value":1092},{"type":55,"value":1753}," to map each pod to its SPM package URL, product name, and ",{"type":49,"tag":64,"props":1755,"children":1757},{"className":1756},[],[1758],{"type":55,"value":1759},"importedModules",{"type":55,"value":1761},".",{"type":49,"tag":58,"props":1763,"children":1764},{},[1765,1770,1772,1778,1780,1785,1787,1793,1795,1801,1803,1809,1811,1817],{"type":49,"tag":96,"props":1766,"children":1767},{},[1768],{"type":55,"value":1769},"Key concepts:",{"type":55,"value":1771}," ",{"type":49,"tag":64,"props":1773,"children":1775},{"className":1774},[],[1776],{"type":55,"value":1777},"products",{"type":55,"value":1779}," = SPM product names (controls linking). ",{"type":49,"tag":64,"props":1781,"children":1783},{"className":1782},[],[1784],{"type":55,"value":1759},{"type":55,"value":1786}," = Clang module names for cinterop bindings (only when ",{"type":49,"tag":64,"props":1788,"children":1790},{"className":1789},[],[1791],{"type":55,"value":1792},"discoverModulesImplicitly = false",{"type":55,"value":1794},"). ",{"type":49,"tag":64,"props":1796,"children":1798},{"className":1797},[],[1799],{"type":55,"value":1800},"discoverModulesImplicitly",{"type":55,"value":1802}," defaults to ",{"type":49,"tag":64,"props":1804,"children":1806},{"className":1805},[],[1807],{"type":55,"value":1808},"true",{"type":55,"value":1810}," (bindings for all Clang modules); set ",{"type":49,"tag":64,"props":1812,"children":1814},{"className":1813},[],[1815],{"type":55,"value":1816},"false",{"type":55,"value":1818}," when transitive C\u002FC++ modules fail cinterop (Firebase, gRPC), then list needed modules explicitly.",{"type":49,"tag":58,"props":1820,"children":1821},{},[1822,1827,1829,1833],{"type":49,"tag":96,"props":1823,"children":1824},{},[1825],{"type":55,"value":1826},"Important:",{"type":55,"value":1828}," SPM product names and Clang module names don't always match. Always consult ",{"type":49,"tag":697,"props":1830,"children":1831},{"href":1089},[1832],{"type":55,"value":1092},{"type":55,"value":1834}," for correct values.",{"type":49,"tag":58,"props":1836,"children":1837},{},[1838,1843,1845,1850,1852,1857,1859,1864,1866,1872],{"type":49,"tag":96,"props":1839,"children":1840},{},[1841],{"type":55,"value":1842},"Do not mix the same library suite across CocoaPods and SPM.",{"type":55,"value":1844}," Libraries that share a common repository (e.g., all Firebase products) share transitive dependencies. Having some products linked via CocoaPods and others via SPM causes duplicate\u002Fconflicting symbols and dyld crashes at runtime. When migrating such a suite, move ",{"type":49,"tag":96,"props":1846,"children":1847},{},[1848],{"type":55,"value":1849},"all",{"type":55,"value":1851}," pods from that suite to SPM at once — including Swift-only pods that Kotlin doesn't use directly. Add Swift-only pods as ",{"type":49,"tag":64,"props":1853,"children":1855},{"className":1854},[],[1856],{"type":55,"value":1777},{"type":55,"value":1858}," entries (no ",{"type":49,"tag":64,"props":1860,"children":1862},{"className":1861},[],[1863],{"type":55,"value":1759},{"type":55,"value":1865}," needed). After adding new products, re-run ",{"type":49,"tag":64,"props":1867,"children":1869},{"className":1868},[],[1870],{"type":55,"value":1871},"integrateLinkagePackage",{"type":55,"value":1873}," to regenerate the linkage Swift package.",{"type":49,"tag":349,"props":1875,"children":1877},{"className":1418,"code":1876,"language":14,"meta":354,"style":354},"kotlin {\n    \u002F\u002F Keep existing targets\n    iosArm64()\n    iosSimulatorArm64()\n    iosX64()\n\n    swiftPMDependencies {\n        iosDeploymentVersion.set(\"16.0\")\n\n        \u002F\u002F If using KMP IntelliJ plugin, specify the .xcodeproj path:\n        \u002F\u002F xcodeProjectPathForKmpIJPlugin.set(\n        \u002F\u002F     layout.projectDirectory.file(\"..\u002FiosApp\u002FiosApp.xcodeproj\")\n        \u002F\u002F )\n\n        swiftPackage(\n            url = url(\"https:\u002F\u002Fgithub.com\u002Fowner\u002Frepo.git\"),\n            version = from(\"1.0.0\"),\n            products = listOf(product(\"ProductName\")),\n        )\n    }\n\n    cocoapods {\n        \u002F\u002F ... keep existing cocoapods block for now\n    }\n}\n",[1878],{"type":49,"tag":64,"props":1879,"children":1880},{"__ignoreMap":354},[1881,1889,1897,1905,1913,1921,1928,1936,1944,1951,1959,1967,1975,1983,1990,1999,2008,2016,2025,2034,2042,2050,2059,2068,2076],{"type":49,"tag":360,"props":1882,"children":1883},{"class":362,"line":363},[1884],{"type":49,"tag":360,"props":1885,"children":1886},{},[1887],{"type":55,"value":1888},"kotlin {\n",{"type":49,"tag":360,"props":1890,"children":1891},{"class":362,"line":1434},[1892],{"type":49,"tag":360,"props":1893,"children":1894},{},[1895],{"type":55,"value":1896},"    \u002F\u002F Keep existing targets\n",{"type":49,"tag":360,"props":1898,"children":1899},{"class":362,"line":1443},[1900],{"type":49,"tag":360,"props":1901,"children":1902},{},[1903],{"type":55,"value":1904},"    iosArm64()\n",{"type":49,"tag":360,"props":1906,"children":1907},{"class":362,"line":1452},[1908],{"type":49,"tag":360,"props":1909,"children":1910},{},[1911],{"type":55,"value":1912},"    iosSimulatorArm64()\n",{"type":49,"tag":360,"props":1914,"children":1915},{"class":362,"line":1461},[1916],{"type":49,"tag":360,"props":1917,"children":1918},{},[1919],{"type":55,"value":1920},"    iosX64()\n",{"type":49,"tag":360,"props":1922,"children":1923},{"class":362,"line":1470},[1924],{"type":49,"tag":360,"props":1925,"children":1926},{"emptyLinePlaceholder":1492},[1927],{"type":55,"value":1495},{"type":49,"tag":360,"props":1929,"children":1930},{"class":362,"line":1479},[1931],{"type":49,"tag":360,"props":1932,"children":1933},{},[1934],{"type":55,"value":1935},"    swiftPMDependencies {\n",{"type":49,"tag":360,"props":1937,"children":1938},{"class":362,"line":1488},[1939],{"type":49,"tag":360,"props":1940,"children":1941},{},[1942],{"type":55,"value":1943},"        iosDeploymentVersion.set(\"16.0\")\n",{"type":49,"tag":360,"props":1945,"children":1946},{"class":362,"line":1498},[1947],{"type":49,"tag":360,"props":1948,"children":1949},{"emptyLinePlaceholder":1492},[1950],{"type":55,"value":1495},{"type":49,"tag":360,"props":1952,"children":1953},{"class":362,"line":1507},[1954],{"type":49,"tag":360,"props":1955,"children":1956},{},[1957],{"type":55,"value":1958},"        \u002F\u002F If using KMP IntelliJ plugin, specify the .xcodeproj path:\n",{"type":49,"tag":360,"props":1960,"children":1961},{"class":362,"line":1515},[1962],{"type":49,"tag":360,"props":1963,"children":1964},{},[1965],{"type":55,"value":1966},"        \u002F\u002F xcodeProjectPathForKmpIJPlugin.set(\n",{"type":49,"tag":360,"props":1968,"children":1969},{"class":362,"line":1523},[1970],{"type":49,"tag":360,"props":1971,"children":1972},{},[1973],{"type":55,"value":1974},"        \u002F\u002F     layout.projectDirectory.file(\"..\u002FiosApp\u002FiosApp.xcodeproj\")\n",{"type":49,"tag":360,"props":1976,"children":1977},{"class":362,"line":1531},[1978],{"type":49,"tag":360,"props":1979,"children":1980},{},[1981],{"type":55,"value":1982},"        \u002F\u002F )\n",{"type":49,"tag":360,"props":1984,"children":1985},{"class":362,"line":1539},[1986],{"type":49,"tag":360,"props":1987,"children":1988},{"emptyLinePlaceholder":1492},[1989],{"type":55,"value":1495},{"type":49,"tag":360,"props":1991,"children":1993},{"class":362,"line":1992},15,[1994],{"type":49,"tag":360,"props":1995,"children":1996},{},[1997],{"type":55,"value":1998},"        swiftPackage(\n",{"type":49,"tag":360,"props":2000,"children":2002},{"class":362,"line":2001},16,[2003],{"type":49,"tag":360,"props":2004,"children":2005},{},[2006],{"type":55,"value":2007},"            url = url(\"https:\u002F\u002Fgithub.com\u002Fowner\u002Frepo.git\"),\n",{"type":49,"tag":360,"props":2009,"children":2010},{"class":362,"line":32},[2011],{"type":49,"tag":360,"props":2012,"children":2013},{},[2014],{"type":55,"value":2015},"            version = from(\"1.0.0\"),\n",{"type":49,"tag":360,"props":2017,"children":2019},{"class":362,"line":2018},18,[2020],{"type":49,"tag":360,"props":2021,"children":2022},{},[2023],{"type":55,"value":2024},"            products = listOf(product(\"ProductName\")),\n",{"type":49,"tag":360,"props":2026,"children":2028},{"class":362,"line":2027},19,[2029],{"type":49,"tag":360,"props":2030,"children":2031},{},[2032],{"type":55,"value":2033},"        )\n",{"type":49,"tag":360,"props":2035,"children":2037},{"class":362,"line":2036},20,[2038],{"type":49,"tag":360,"props":2039,"children":2040},{},[2041],{"type":55,"value":1476},{"type":49,"tag":360,"props":2043,"children":2045},{"class":362,"line":2044},21,[2046],{"type":49,"tag":360,"props":2047,"children":2048},{"emptyLinePlaceholder":1492},[2049],{"type":55,"value":1495},{"type":49,"tag":360,"props":2051,"children":2053},{"class":362,"line":2052},22,[2054],{"type":49,"tag":360,"props":2055,"children":2056},{},[2057],{"type":55,"value":2058},"    cocoapods {\n",{"type":49,"tag":360,"props":2060,"children":2062},{"class":362,"line":2061},23,[2063],{"type":49,"tag":360,"props":2064,"children":2065},{},[2066],{"type":55,"value":2067},"        \u002F\u002F ... keep existing cocoapods block for now\n",{"type":49,"tag":360,"props":2069,"children":2071},{"class":362,"line":2070},24,[2072],{"type":49,"tag":360,"props":2073,"children":2074},{},[2075],{"type":55,"value":1476},{"type":49,"tag":360,"props":2077,"children":2079},{"class":362,"line":2078},25,[2080],{"type":49,"tag":360,"props":2081,"children":2082},{},[2083],{"type":55,"value":1485},{"type":49,"tag":307,"props":2085,"children":2087},{"id":2086},"_33-move-framework-configuration-out-of-cocoapods-block",[2088],{"type":55,"value":2089},"3.3 Move framework configuration out of cocoapods block",{"type":49,"tag":58,"props":2091,"children":2092},{},[2093,2095,2100,2102,2108,2110,2116,2118,2129],{"type":55,"value":2094},"If the ",{"type":49,"tag":64,"props":2096,"children":2098},{"className":2097},[],[2099],{"type":55,"value":345},{"type":55,"value":2101}," block contains a ",{"type":49,"tag":64,"props":2103,"children":2105},{"className":2104},[],[2106],{"type":55,"value":2107},"framework {}",{"type":55,"value":2109}," configuration, move it to the ",{"type":49,"tag":64,"props":2111,"children":2113},{"className":2112},[],[2114],{"type":55,"value":2115},"binaries",{"type":55,"value":2117}," API on each target. ",{"type":49,"tag":96,"props":2119,"children":2120},{},[2121,2127],{"type":49,"tag":64,"props":2122,"children":2124},{"className":2123},[],[2125],{"type":55,"value":2126},"isStatic = true",{"type":55,"value":2128}," is recommended",{"type":55,"value":2130}," — dynamic frameworks have known edge cases with SwiftPM import that can cause linker errors, dyld crashes, or duplicate class warnings:",{"type":49,"tag":349,"props":2132,"children":2134},{"className":1418,"code":2133,"language":14,"meta":354,"style":354},"listOf(iosArm64(), iosSimulatorArm64(), iosX64()).forEach { iosTarget ->\n    iosTarget.binaries.framework { baseName = \"Shared\"; isStatic = true }\n}\n",[2135],{"type":49,"tag":64,"props":2136,"children":2137},{"__ignoreMap":354},[2138,2146,2154],{"type":49,"tag":360,"props":2139,"children":2140},{"class":362,"line":363},[2141],{"type":49,"tag":360,"props":2142,"children":2143},{},[2144],{"type":55,"value":2145},"listOf(iosArm64(), iosSimulatorArm64(), iosX64()).forEach { iosTarget ->\n",{"type":49,"tag":360,"props":2147,"children":2148},{"class":362,"line":1434},[2149],{"type":49,"tag":360,"props":2150,"children":2151},{},[2152],{"type":55,"value":2153},"    iosTarget.binaries.framework { baseName = \"Shared\"; isStatic = true }\n",{"type":49,"tag":360,"props":2155,"children":2156},{"class":362,"line":1443},[2157],{"type":49,"tag":360,"props":2158,"children":2159},{},[2160],{"type":55,"value":1485},{"type":49,"tag":307,"props":2162,"children":2164},{"id":2163},"_34-handle-devgitlivefirebase-kotlin-sdk-and-similar-cocoapods-era-kmp-wrappers",[2165],{"type":55,"value":2166},"3.4 Handle dev.gitlive\u002Ffirebase-kotlin-sdk and similar CocoaPods-era KMP wrappers",{"type":49,"tag":58,"props":2168,"children":2169},{},[2170,2172,2177],{"type":55,"value":2171},"If the project uses ",{"type":49,"tag":64,"props":2173,"children":2175},{"className":2174},[],[2176],{"type":55,"value":1084},{"type":55,"value":2178}," or similar KMP wrapper libraries, two additional steps are required:",{"type":49,"tag":58,"props":2180,"children":2181},{},[2182,2192,2194,2200,2202,2207,2209,2215],{"type":49,"tag":96,"props":2183,"children":2184},{},[2185,2187],{"type":55,"value":2186},"A. Switch to ",{"type":49,"tag":64,"props":2188,"children":2190},{"className":2189},[],[2191],{"type":55,"value":2126},{"type":55,"value":2193}," — dynamic frameworks + Firebase SPM = runtime ",{"type":49,"tag":64,"props":2195,"children":2197},{"className":2196},[],[2198],{"type":55,"value":2199},"dyld",{"type":55,"value":2201}," crash. After switching: re-run ",{"type":49,"tag":64,"props":2203,"children":2205},{"className":2204},[],[2206],{"type":55,"value":1871},{"type":55,"value":2208},", remove any \"Embed Frameworks\" copy phase, move linker flags to ",{"type":49,"tag":64,"props":2210,"children":2212},{"className":2211},[],[2213],{"type":55,"value":2214},"OTHER_LDFLAGS",{"type":55,"value":1761},{"type":49,"tag":58,"props":2217,"children":2218},{},[2219,2224,2226,2232,2234,2239,2241,2247],{"type":49,"tag":96,"props":2220,"children":2221},{},[2222],{"type":55,"value":2223},"B. Add framework search paths",{"type":55,"value":2225}," — add conditional ",{"type":49,"tag":64,"props":2227,"children":2229},{"className":2228},[],[2230],{"type":55,"value":2231},"-F",{"type":55,"value":2233}," linkerOpts in ",{"type":49,"tag":64,"props":2235,"children":2237},{"className":2236},[],[2238],{"type":55,"value":337},{"type":55,"value":2240}," and matching ",{"type":49,"tag":64,"props":2242,"children":2244},{"className":2243},[],[2245],{"type":55,"value":2246},"FRAMEWORK_SEARCH_PATHS",{"type":55,"value":2248}," in the Xcode project.",{"type":49,"tag":58,"props":2250,"children":2251},{},[2252,2254,2258,2260,2264],{"type":55,"value":2253},"See ",{"type":49,"tag":697,"props":2255,"children":2256},{"href":1089},[2257],{"type":55,"value":1092},{"type":55,"value":2259}," § dev.gitlive and ",{"type":49,"tag":697,"props":2261,"children":2262},{"href":787},[2263],{"type":55,"value":790},{"type":55,"value":2265}," for code snippets and the full product list.",{"type":49,"tag":307,"props":2267,"children":2269},{"id":2268},"_35-add-opt-in-for-cinterop-api",[2270],{"type":55,"value":2271},"3.5 Add opt-in for cinterop API",{"type":49,"tag":349,"props":2273,"children":2275},{"className":1418,"code":2274,"language":14,"meta":354,"style":354},"kotlin.compilerOptions {\n    optIn.add(\"kotlinx.cinterop.ExperimentalForeignApi\")\n}\n",[2276],{"type":49,"tag":64,"props":2277,"children":2278},{"__ignoreMap":354},[2279,2287,2295],{"type":49,"tag":360,"props":2280,"children":2281},{"class":362,"line":363},[2282],{"type":49,"tag":360,"props":2283,"children":2284},{},[2285],{"type":55,"value":2286},"kotlin.compilerOptions {\n",{"type":49,"tag":360,"props":2288,"children":2289},{"class":362,"line":1434},[2290],{"type":49,"tag":360,"props":2291,"children":2292},{},[2293],{"type":55,"value":2294},"    optIn.add(\"kotlinx.cinterop.ExperimentalForeignApi\")\n",{"type":49,"tag":360,"props":2296,"children":2297},{"class":362,"line":1443},[2298],{"type":49,"tag":360,"props":2299,"children":2300},{},[2301],{"type":55,"value":1485},{"type":49,"tag":58,"props":2303,"children":2304},{},[2305,2307,2313],{"type":55,"value":2306},"For full DSL reference, see ",{"type":49,"tag":697,"props":2308,"children":2310},{"href":2309},"references\u002Fdsl-reference.md",[2311],{"type":55,"value":2312},"dsl-reference.md",{"type":55,"value":1761},{"type":49,"tag":297,"props":2315,"children":2316},{},[],{"type":49,"tag":81,"props":2318,"children":2320},{"id":2319},"phase-4-kotlin-source-updates",[2321],{"type":55,"value":2322},"Phase 4: Kotlin Source Updates",{"type":49,"tag":307,"props":2324,"children":2326},{"id":2325},"import-namespace-formula",[2327],{"type":55,"value":2328},"Import Namespace Formula",{"type":49,"tag":349,"props":2330,"children":2334},{"className":2331,"code":2333,"language":55},[2332],"language-text","swiftPMImport.\u003Cgroup>.\u003Cmodule>.\u003CClassName>\n\nWhere:\n- group: build.gradle.kts `group` property, dashes (-) → dots (.)\n- module: Gradle module name, dashes (-) → dots (.)\n- ClassName: Objective-C class name (FIR* for Firebase, GMS* for Google Maps)\n",[2335],{"type":49,"tag":64,"props":2336,"children":2337},{"__ignoreMap":354},[2338],{"type":55,"value":2333},{"type":49,"tag":307,"props":2340,"children":2342},{"id":2341},"example-transformation",[2343],{"type":55,"value":2344},"Example Transformation",{"type":49,"tag":349,"props":2346,"children":2348},{"className":1418,"code":2347,"language":14,"meta":354,"style":354},"\u002F\u002F group = \"org.jetbrains.kotlin.firebase.sample\", module = \"kotlin-library\"\n\n\u002F\u002F BEFORE:\nimport cocoapods.FirebaseAnalytics.FIRAnalytics\n\n\u002F\u002F AFTER:\nimport swiftPMImport.org.jetbrains.kotlin.firebase.sample.kotlin.library.FIRAnalytics\n",[2349],{"type":49,"tag":64,"props":2350,"children":2351},{"__ignoreMap":354},[2352,2360,2367,2375,2383,2390,2398],{"type":49,"tag":360,"props":2353,"children":2354},{"class":362,"line":363},[2355],{"type":49,"tag":360,"props":2356,"children":2357},{},[2358],{"type":55,"value":2359},"\u002F\u002F group = \"org.jetbrains.kotlin.firebase.sample\", module = \"kotlin-library\"\n",{"type":49,"tag":360,"props":2361,"children":2362},{"class":362,"line":1434},[2363],{"type":49,"tag":360,"props":2364,"children":2365},{"emptyLinePlaceholder":1492},[2366],{"type":55,"value":1495},{"type":49,"tag":360,"props":2368,"children":2369},{"class":362,"line":1443},[2370],{"type":49,"tag":360,"props":2371,"children":2372},{},[2373],{"type":55,"value":2374},"\u002F\u002F BEFORE:\n",{"type":49,"tag":360,"props":2376,"children":2377},{"class":362,"line":1452},[2378],{"type":49,"tag":360,"props":2379,"children":2380},{},[2381],{"type":55,"value":2382},"import cocoapods.FirebaseAnalytics.FIRAnalytics\n",{"type":49,"tag":360,"props":2384,"children":2385},{"class":362,"line":1461},[2386],{"type":49,"tag":360,"props":2387,"children":2388},{"emptyLinePlaceholder":1492},[2389],{"type":55,"value":1495},{"type":49,"tag":360,"props":2391,"children":2392},{"class":362,"line":1470},[2393],{"type":49,"tag":360,"props":2394,"children":2395},{},[2396],{"type":55,"value":2397},"\u002F\u002F AFTER:\n",{"type":49,"tag":360,"props":2399,"children":2400},{"class":362,"line":1479},[2401],{"type":49,"tag":360,"props":2402,"children":2403},{},[2404],{"type":55,"value":2405},"import swiftPMImport.org.jetbrains.kotlin.firebase.sample.kotlin.library.FIRAnalytics\n",{"type":49,"tag":58,"props":2407,"children":2408},{},[2409,2414,2416,2422,2423,2429,2431,2437,2439,2445,2446,2452,2454,2460,2461,2467],{"type":49,"tag":96,"props":2410,"children":2411},{},[2412],{"type":55,"value":2413},"Import flattening:",{"type":55,"value":2415}," The Clang module name (e.g., ",{"type":49,"tag":64,"props":2417,"children":2419},{"className":2418},[],[2420],{"type":55,"value":2421},"FirebaseFirestoreInternal",{"type":55,"value":928},{"type":49,"tag":64,"props":2424,"children":2426},{"className":2425},[],[2427],{"type":55,"value":2428},"FirebaseAuth",{"type":55,"value":2430},") disappears from the import path — all classes are flattened under the same ",{"type":49,"tag":64,"props":2432,"children":2434},{"className":2433},[],[2435],{"type":55,"value":2436},"swiftPMImport.\u003Cgroup>.\u003Cmodule>",{"type":55,"value":2438}," prefix regardless of which library they come from. For example, both ",{"type":49,"tag":64,"props":2440,"children":2442},{"className":2441},[],[2443],{"type":55,"value":2444},"cocoapods.FirebaseAuth.FIRAuth",{"type":55,"value":1143},{"type":49,"tag":64,"props":2447,"children":2449},{"className":2448},[],[2450],{"type":55,"value":2451},"cocoapods.FirebaseFirestoreInternal.FIRFirestore",{"type":55,"value":2453}," become ",{"type":49,"tag":64,"props":2455,"children":2457},{"className":2456},[],[2458],{"type":55,"value":2459},"swiftPMImport.\u003Cgroup>.\u003Cmodule>.FIRAuth",{"type":55,"value":1143},{"type":49,"tag":64,"props":2462,"children":2464},{"className":2463},[],[2465],{"type":55,"value":2466},"swiftPMImport.\u003Cgroup>.\u003Cmodule>.FIRFirestore",{"type":55,"value":1761},{"type":49,"tag":307,"props":2469,"children":2471},{"id":2470},"preserving-bundled-klib-imports",[2472],{"type":55,"value":2473},"Preserving Bundled Klib Imports",{"type":49,"tag":533,"props":2475,"children":2476},{},[2477],{"type":49,"tag":58,"props":2478,"children":2479},{},[2480,2485,2487,2492,2494,2499,2501,2507],{"type":49,"tag":96,"props":2481,"children":2482},{},[2483],{"type":55,"value":2484},"CRITICAL:",{"type":55,"value":2486}," Do NOT replace ",{"type":49,"tag":64,"props":2488,"children":2490},{"className":2489},[],[2491],{"type":55,"value":816},{"type":55,"value":2493}," imports that resolve to third-party KMP libraries' bundled cinterop klibs (identified in Phase 1 step 1.3). These imports must remain as-is — the ",{"type":49,"tag":64,"props":2495,"children":2497},{"className":2496},[],[2498],{"type":55,"value":345},{"type":55,"value":2500}," prefix is the package namespace in the library's published klib, not an actual CocoaPods dependency. The swiftPMDependencies cinterop generator skips modules already provided by a dependency's klib, so ",{"type":49,"tag":64,"props":2502,"children":2504},{"className":2503},[],[2505],{"type":55,"value":2506},"swiftPMImport.*",{"type":55,"value":2508}," for those classes will fail with \"Unresolved reference\".",{"type":49,"tag":58,"props":2510,"children":2511},{},[2512,2517,2519,2524],{"type":49,"tag":96,"props":2513,"children":2514},{},[2515],{"type":55,"value":2516},"Example",{"type":55,"value":2518}," (project using ",{"type":49,"tag":697,"props":2520,"children":2522},{"href":895,"rel":2521},[701],[2523],{"type":55,"value":899},{"type":55,"value":2525},"):",{"type":49,"tag":349,"props":2527,"children":2529},{"className":1418,"code":2528,"language":14,"meta":354,"style":354},"\u002F\u002F KEEP — resolves to kmpnotifier's bundled cinterop klib\nimport cocoapods.FirebaseMessaging.FIRMessaging\n",[2530],{"type":49,"tag":64,"props":2531,"children":2532},{"__ignoreMap":354},[2533,2541],{"type":49,"tag":360,"props":2534,"children":2535},{"class":362,"line":363},[2536],{"type":49,"tag":360,"props":2537,"children":2538},{},[2539],{"type":55,"value":2540},"\u002F\u002F KEEP — resolves to kmpnotifier's bundled cinterop klib\n",{"type":49,"tag":360,"props":2542,"children":2543},{"class":362,"line":1434},[2544],{"type":49,"tag":360,"props":2545,"children":2546},{},[2547],{"type":55,"value":2548},"import cocoapods.FirebaseMessaging.FIRMessaging\n",{"type":49,"tag":307,"props":2550,"children":2552},{"id":2551},"bulk-replacement",[2553],{"type":55,"value":2554},"Bulk Replacement",{"type":49,"tag":58,"props":2556,"children":2557},{},[2558,2560,2565],{"type":55,"value":2559},"Use a regex find-and-replace across all Kotlin source files, ",{"type":49,"tag":96,"props":2561,"children":2562},{},[2563],{"type":55,"value":2564},"excluding imports identified in Phase 1 step 1.3",{"type":55,"value":347},{"type":49,"tag":349,"props":2567,"children":2570},{"className":2568,"code":2569,"language":55},[2332],"Find:    cocoapods\\.\\w+\\.\nReplace: swiftPMImport.\u003Cyour.group>.\u003Cyour.module>.\n",[2571],{"type":49,"tag":64,"props":2572,"children":2573},{"__ignoreMap":354},[2574],{"type":55,"value":2569},{"type":49,"tag":58,"props":2576,"children":2577},{},[2578,2580,2585,2587,2592],{"type":55,"value":2579},"After bulk replacement, ",{"type":49,"tag":96,"props":2581,"children":2582},{},[2583],{"type":55,"value":2584},"manually restore",{"type":55,"value":2586}," any ",{"type":49,"tag":64,"props":2588,"children":2590},{"className":2589},[],[2591],{"type":55,"value":816},{"type":55,"value":2593}," imports that should be preserved (from bundled klibs).",{"type":49,"tag":58,"props":2595,"children":2596},{},[2597,2602,2604,2610],{"type":49,"tag":96,"props":2598,"children":2599},{},[2600],{"type":55,"value":2601},"Finding correct import path:",{"type":55,"value":2603}," Run ",{"type":49,"tag":64,"props":2605,"children":2607},{"className":2606},[],[2608],{"type":55,"value":2609},".\u002Fgradlew :moduleName:build",{"type":55,"value":2611}," - errors show available classes.",{"type":49,"tag":297,"props":2613,"children":2614},{},[],{"type":49,"tag":81,"props":2616,"children":2618},{"id":2617},"phase-5-ios-project-reconfiguration",[2619],{"type":55,"value":2620},"Phase 5: iOS Project Reconfiguration",{"type":49,"tag":307,"props":2622,"children":2624},{"id":2623},"_51-get-migration-command",[2625],{"type":55,"value":2626},"5.1 Get migration command",{"type":49,"tag":58,"props":2628,"children":2629},{},[2630],{"type":55,"value":2631},"Build the CocoaPods workspace to obtain the migration command:",{"type":49,"tag":349,"props":2633,"children":2635},{"className":351,"code":2634,"language":353,"meta":354,"style":354},"cd \u002Fpath\u002Fto\u002FiosApp\n\nxcodebuild -scheme \"$(echo -n *.xcworkspace | python3 -c 'import sys, json; from subprocess import check_output; print(list(set(json.loads(check_output([\"xcodebuild\", \"-workspace\", sys.stdin.readline(), \"-list\", \"-json\"]))[\"workspace\"][\"schemes\"]) - set(json.loads(check_output([\"xcodebuild\", \"-project\", \"Pods\u002FPods.xcodeproj\", \"-list\", \"-json\"]))[\"project\"][\"schemes\"]))[0])')\" -workspace *.xcworkspace -destination 'generic\u002Fplatform=iOS Simulator' ARCHS=arm64 | grep -A5 'What went wrong'\n",[2636],{"type":49,"tag":64,"props":2637,"children":2638},{"__ignoreMap":354},[2639,2653,2660],{"type":49,"tag":360,"props":2640,"children":2641},{"class":362,"line":363},[2642,2648],{"type":49,"tag":360,"props":2643,"children":2645},{"style":2644},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[2646],{"type":55,"value":2647},"cd",{"type":49,"tag":360,"props":2649,"children":2650},{"style":373},[2651],{"type":55,"value":2652}," \u002Fpath\u002Fto\u002FiosApp\n",{"type":49,"tag":360,"props":2654,"children":2655},{"class":362,"line":1434},[2656],{"type":49,"tag":360,"props":2657,"children":2658},{"emptyLinePlaceholder":1492},[2659],{"type":55,"value":1495},{"type":49,"tag":360,"props":2661,"children":2662},{"class":362,"line":1443},[2663,2668,2673,2678,2683,2688,2694,2699,2704,2709,2714,2719,2724,2729,2734,2739,2743,2748,2753,2758,2762,2767,2772,2777,2782,2786,2791],{"type":49,"tag":360,"props":2664,"children":2665},{"style":367},[2666],{"type":55,"value":2667},"xcodebuild",{"type":49,"tag":360,"props":2669,"children":2670},{"style":373},[2671],{"type":55,"value":2672}," -scheme",{"type":49,"tag":360,"props":2674,"children":2675},{"style":379},[2676],{"type":55,"value":2677}," \"$(",{"type":49,"tag":360,"props":2679,"children":2680},{"style":2644},[2681],{"type":55,"value":2682},"echo",{"type":49,"tag":360,"props":2684,"children":2685},{"style":373},[2686],{"type":55,"value":2687}," -n ",{"type":49,"tag":360,"props":2689,"children":2691},{"style":2690},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[2692],{"type":55,"value":2693},"*",{"type":49,"tag":360,"props":2695,"children":2696},{"style":373},[2697],{"type":55,"value":2698},".xcworkspace ",{"type":49,"tag":360,"props":2700,"children":2701},{"style":379},[2702],{"type":55,"value":2703},"|",{"type":49,"tag":360,"props":2705,"children":2706},{"style":367},[2707],{"type":55,"value":2708}," python3",{"type":49,"tag":360,"props":2710,"children":2711},{"style":373},[2712],{"type":55,"value":2713}," -c ",{"type":49,"tag":360,"props":2715,"children":2716},{"style":379},[2717],{"type":55,"value":2718},"'",{"type":49,"tag":360,"props":2720,"children":2721},{"style":373},[2722],{"type":55,"value":2723},"import sys, json; from subprocess import check_output; print(list(set(json.loads(check_output([\"xcodebuild\", \"-workspace\", sys.stdin.readline(), \"-list\", \"-json\"]))[\"workspace\"][\"schemes\"]) - set(json.loads(check_output([\"xcodebuild\", \"-project\", \"Pods\u002FPods.xcodeproj\", \"-list\", \"-json\"]))[\"project\"][\"schemes\"]))[0])",{"type":49,"tag":360,"props":2725,"children":2726},{"style":379},[2727],{"type":55,"value":2728},"')\"",{"type":49,"tag":360,"props":2730,"children":2731},{"style":373},[2732],{"type":55,"value":2733}," -workspace",{"type":49,"tag":360,"props":2735,"children":2736},{"style":2690},[2737],{"type":55,"value":2738}," *",{"type":49,"tag":360,"props":2740,"children":2741},{"style":373},[2742],{"type":55,"value":1149},{"type":49,"tag":360,"props":2744,"children":2745},{"style":373},[2746],{"type":55,"value":2747}," -destination",{"type":49,"tag":360,"props":2749,"children":2750},{"style":379},[2751],{"type":55,"value":2752}," '",{"type":49,"tag":360,"props":2754,"children":2755},{"style":373},[2756],{"type":55,"value":2757},"generic\u002Fplatform=iOS Simulator",{"type":49,"tag":360,"props":2759,"children":2760},{"style":379},[2761],{"type":55,"value":2718},{"type":49,"tag":360,"props":2763,"children":2764},{"style":373},[2765],{"type":55,"value":2766}," ARCHS=arm64",{"type":49,"tag":360,"props":2768,"children":2769},{"style":379},[2770],{"type":55,"value":2771}," |",{"type":49,"tag":360,"props":2773,"children":2774},{"style":367},[2775],{"type":55,"value":2776}," grep",{"type":49,"tag":360,"props":2778,"children":2779},{"style":373},[2780],{"type":55,"value":2781}," -A5",{"type":49,"tag":360,"props":2783,"children":2784},{"style":379},[2785],{"type":55,"value":2752},{"type":49,"tag":360,"props":2787,"children":2788},{"style":373},[2789],{"type":55,"value":2790},"What went wrong",{"type":49,"tag":360,"props":2792,"children":2793},{"style":379},[2794],{"type":55,"value":2795},"'\n",{"type":49,"tag":58,"props":2797,"children":2798},{},[2799],{"type":55,"value":2800},"The build output will contain a command like:",{"type":49,"tag":349,"props":2802,"children":2804},{"className":351,"code":2803,"language":353,"meta":354,"style":354},"XCODEPROJ_PATH='\u002Fpath\u002Fto\u002Fproject\u002FiosApp.xcodeproj' GRADLE_PROJECT_PATH=':shared' '\u002Fpath\u002Fto\u002Fproject\u002Fgradlew' -p '\u002Fpath\u002Fto\u002Fproject' ':shared:integrateEmbedAndSign' ':shared:integrateLinkagePackage'\n",[2805],{"type":49,"tag":64,"props":2806,"children":2807},{"__ignoreMap":354},[2808],{"type":49,"tag":360,"props":2809,"children":2810},{"class":362,"line":363},[2811,2816,2821,2825,2830,2834,2839,2843,2847,2852,2856,2860,2865,2869,2874,2878,2883,2887,2891,2896,2900,2904,2909],{"type":49,"tag":360,"props":2812,"children":2813},{"style":2690},[2814],{"type":55,"value":2815},"XCODEPROJ_PATH",{"type":49,"tag":360,"props":2817,"children":2818},{"style":379},[2819],{"type":55,"value":2820},"=",{"type":49,"tag":360,"props":2822,"children":2823},{"style":379},[2824],{"type":55,"value":2718},{"type":49,"tag":360,"props":2826,"children":2827},{"style":373},[2828],{"type":55,"value":2829},"\u002Fpath\u002Fto\u002Fproject\u002FiosApp.xcodeproj",{"type":49,"tag":360,"props":2831,"children":2832},{"style":379},[2833],{"type":55,"value":2718},{"type":49,"tag":360,"props":2835,"children":2836},{"style":2690},[2837],{"type":55,"value":2838}," GRADLE_PROJECT_PATH",{"type":49,"tag":360,"props":2840,"children":2841},{"style":379},[2842],{"type":55,"value":2820},{"type":49,"tag":360,"props":2844,"children":2845},{"style":379},[2846],{"type":55,"value":2718},{"type":49,"tag":360,"props":2848,"children":2849},{"style":373},[2850],{"type":55,"value":2851},":shared",{"type":49,"tag":360,"props":2853,"children":2854},{"style":379},[2855],{"type":55,"value":2718},{"type":49,"tag":360,"props":2857,"children":2858},{"style":379},[2859],{"type":55,"value":2752},{"type":49,"tag":360,"props":2861,"children":2862},{"style":373},[2863],{"type":55,"value":2864},"\u002Fpath\u002Fto\u002Fproject\u002Fgradlew",{"type":49,"tag":360,"props":2866,"children":2867},{"style":379},[2868],{"type":55,"value":2718},{"type":49,"tag":360,"props":2870,"children":2871},{"style":367},[2872],{"type":55,"value":2873}," -p",{"type":49,"tag":360,"props":2875,"children":2876},{"style":379},[2877],{"type":55,"value":2752},{"type":49,"tag":360,"props":2879,"children":2880},{"style":373},[2881],{"type":55,"value":2882},"\u002Fpath\u002Fto\u002Fproject",{"type":49,"tag":360,"props":2884,"children":2885},{"style":379},[2886],{"type":55,"value":2718},{"type":49,"tag":360,"props":2888,"children":2889},{"style":379},[2890],{"type":55,"value":2752},{"type":49,"tag":360,"props":2892,"children":2893},{"style":373},[2894],{"type":55,"value":2895},":shared:integrateEmbedAndSign",{"type":49,"tag":360,"props":2897,"children":2898},{"style":379},[2899],{"type":55,"value":2718},{"type":49,"tag":360,"props":2901,"children":2902},{"style":379},[2903],{"type":55,"value":2752},{"type":49,"tag":360,"props":2905,"children":2906},{"style":373},[2907],{"type":55,"value":2908},":shared:integrateLinkagePackage",{"type":49,"tag":360,"props":2910,"children":2911},{"style":379},[2912],{"type":55,"value":2795},{"type":49,"tag":58,"props":2914,"children":2915},{},[2916,2918,2923,2925,2930,2932,2937,2939,2944],{"type":55,"value":2917},"Run this command. It modifies the ",{"type":49,"tag":64,"props":2919,"children":2921},{"className":2920},[],[2922],{"type":55,"value":1241},{"type":55,"value":2924}," to trigger ",{"type":49,"tag":64,"props":2926,"children":2928},{"className":2927},[],[2929],{"type":55,"value":1257},{"type":55,"value":2931}," during the build. ",{"type":49,"tag":64,"props":2933,"children":2935},{"className":2934},[],[2936],{"type":55,"value":1871},{"type":55,"value":2938}," is a one-time setup — it does not need to be added as a build phase. If ",{"type":49,"tag":64,"props":2940,"children":2942},{"className":2941},[],[2943],{"type":55,"value":776},{"type":55,"value":2945}," is skipped, check for EmbedAndSign disablers (Phase 1 step 1.2) — remove them first, then re-run.",{"type":49,"tag":58,"props":2947,"children":2948},{},[2949,2961,2963,2968,2970,2975,2977,2982],{"type":49,"tag":96,"props":2950,"children":2951},{},[2952,2954,2959],{"type":55,"value":2953},"Verify ",{"type":49,"tag":64,"props":2955,"children":2957},{"className":2956},[],[2958],{"type":55,"value":1257},{"type":55,"value":2960}," is active:",{"type":55,"value":2962}," After running integration, check the build phase script in ",{"type":49,"tag":64,"props":2964,"children":2966},{"className":2965},[],[2967],{"type":55,"value":1249},{"type":55,"value":2969},". If ",{"type":49,"tag":64,"props":2971,"children":2973},{"className":2972},[],[2974],{"type":55,"value":1257},{"type":55,"value":2976}," is commented out (prefixed with ",{"type":49,"tag":64,"props":2978,"children":2980},{"className":2979},[],[2981],{"type":55,"value":1272},{"type":55,"value":2983},"), uncomment it.",{"type":49,"tag":58,"props":2985,"children":2986},{},[2987,2989,2994,2996,3002,3004,3010,3012,3017],{"type":55,"value":2988},"The ",{"type":49,"tag":64,"props":2990,"children":2992},{"className":2991},[],[2993],{"type":55,"value":1871},{"type":55,"value":2995}," task generates ",{"type":49,"tag":64,"props":2997,"children":2999},{"className":2998},[],[3000],{"type":55,"value":3001},"_internal_linkage_SwiftPMImport\u002F",{"type":55,"value":3003}," at ",{"type":49,"tag":64,"props":3005,"children":3007},{"className":3006},[],[3008],{"type":55,"value":3009},"\u003CiosDir>\u002F",{"type":55,"value":3011}," — a local Swift package that mirrors your ",{"type":49,"tag":64,"props":3013,"children":3015},{"className":3014},[],[3016],{"type":55,"value":1777},{"type":55,"value":3018}," list and ensures SPM libraries are linked into the final binary.",{"type":49,"tag":58,"props":3020,"children":3021},{},[3022,3024,3029,3031,3037,3039,3044],{"type":55,"value":3023},"After running the integration tasks, ",{"type":49,"tag":96,"props":3025,"children":3026},{},[3027],{"type":55,"value":3028},"disable User Script Sandboxing",{"type":55,"value":3030}," (",{"type":49,"tag":64,"props":3032,"children":3034},{"className":3033},[],[3035],{"type":55,"value":3036},"ENABLE_USER_SCRIPT_SANDBOXING = NO",{"type":55,"value":3038},") in the ",{"type":49,"tag":64,"props":3040,"children":3042},{"className":3041},[],[3043],{"type":55,"value":1241},{"type":55,"value":3045},". Xcode 16+ enables it by default, which prevents the Gradle build phase from writing to the project directory:",{"type":49,"tag":349,"props":3047,"children":3049},{"className":351,"code":3048,"language":353,"meta":354,"style":354},"sed -i '' 's\u002FENABLE_USER_SCRIPT_SANDBOXING = YES\u002FENABLE_USER_SCRIPT_SANDBOXING = NO\u002Fg' \"$XCODEPROJ_PATH\u002Fproject.pbxproj\"\n",[3050],{"type":49,"tag":64,"props":3051,"children":3052},{"__ignoreMap":354},[3053],{"type":49,"tag":360,"props":3054,"children":3055},{"class":362,"line":363},[3056,3061,3066,3071,3075,3080,3084,3088,3093,3098],{"type":49,"tag":360,"props":3057,"children":3058},{"style":367},[3059],{"type":55,"value":3060},"sed",{"type":49,"tag":360,"props":3062,"children":3063},{"style":373},[3064],{"type":55,"value":3065}," -i",{"type":49,"tag":360,"props":3067,"children":3068},{"style":379},[3069],{"type":55,"value":3070}," ''",{"type":49,"tag":360,"props":3072,"children":3073},{"style":379},[3074],{"type":55,"value":2752},{"type":49,"tag":360,"props":3076,"children":3077},{"style":373},[3078],{"type":55,"value":3079},"s\u002FENABLE_USER_SCRIPT_SANDBOXING = YES\u002FENABLE_USER_SCRIPT_SANDBOXING = NO\u002Fg",{"type":49,"tag":360,"props":3081,"children":3082},{"style":379},[3083],{"type":55,"value":2718},{"type":49,"tag":360,"props":3085,"children":3086},{"style":379},[3087],{"type":55,"value":382},{"type":49,"tag":360,"props":3089,"children":3090},{"style":2690},[3091],{"type":55,"value":3092},"$XCODEPROJ_PATH",{"type":49,"tag":360,"props":3094,"children":3095},{"style":373},[3096],{"type":55,"value":3097},"\u002Fproject.pbxproj",{"type":49,"tag":360,"props":3099,"children":3100},{"style":379},[3101],{"type":55,"value":3102},"\"\n",{"type":49,"tag":58,"props":3104,"children":3105},{},[3106,3108,3114,3116,3122,3124],{"type":55,"value":3107},"If the setting is absent (Xcode defaults to YES), add ",{"type":49,"tag":64,"props":3109,"children":3111},{"className":3110},[],[3112],{"type":55,"value":3113},"ENABLE_USER_SCRIPT_SANDBOXING = NO;",{"type":55,"value":3115}," to the app target's ",{"type":49,"tag":64,"props":3117,"children":3119},{"className":3118},[],[3120],{"type":55,"value":3121},"buildSettings",{"type":55,"value":3123}," sections. Then restart the Gradle daemon: ",{"type":49,"tag":64,"props":3125,"children":3127},{"className":3126},[],[3128],{"type":55,"value":3129},".\u002Fgradlew --stop",{"type":49,"tag":58,"props":3131,"children":3132},{},[3133,3138,3140,3144],{"type":49,"tag":96,"props":3134,"children":3135},{},[3136],{"type":55,"value":3137},"Alternative (if xcodebuild approach fails):",{"type":55,"value":3139}," See ",{"type":49,"tag":697,"props":3141,"children":3142},{"href":787},[3143],{"type":55,"value":790},{"type":55,"value":3145}," § \"Manual Integration Command Discovery\" for a fallback script to discover paths and run integration tasks directly.",{"type":49,"tag":307,"props":3147,"children":3149},{"id":3148},"_52-update-crashlytics-dsym-upload-script-if-applicable",[3150],{"type":55,"value":3151},"5.2 Update Crashlytics dSYM upload script (if applicable)",{"type":49,"tag":58,"props":3153,"children":3154},{},[3155,3157,3162,3163,3169,3171,3175,3177,3181],{"type":55,"value":3156},"If the project uses FirebaseCrashlytics and has a dSYM upload run script phase (identified in Phase 1 step 10), update the script path from ",{"type":49,"tag":64,"props":3158,"children":3160},{"className":3159},[],[3161],{"type":55,"value":1304},{"type":55,"value":71},{"type":49,"tag":64,"props":3164,"children":3166},{"className":3165},[],[3167],{"type":55,"value":3168},"\"${BUILD_DIR%\u002FBuild\u002F*}\u002FSourcePackages\u002Fcheckouts\u002Ffirebase-ios-sdk\u002FCrashlytics\u002Frun\"",{"type":55,"value":3170},". See ",{"type":49,"tag":697,"props":3172,"children":3173},{"href":787},[3174],{"type":55,"value":790},{"type":55,"value":3176}," § \"Firebase Crashlytics: dSYM Upload Script\" and ",{"type":49,"tag":697,"props":3178,"children":3179},{"href":1089},[3180],{"type":55,"value":1092},{"type":55,"value":3182}," for the full script and input files list.",{"type":49,"tag":307,"props":3184,"children":3186},{"id":3185},"_53-deintegrate-cocoapods",[3187],{"type":55,"value":3188},"5.3 Deintegrate CocoaPods",{"type":49,"tag":58,"props":3190,"children":3191},{},[3192,3197],{"type":49,"tag":96,"props":3193,"children":3194},{},[3195],{"type":55,"value":3196},"Option A: Full deintegration",{"type":55,"value":3198}," (if CocoaPods was used ONLY for KMP dependencies):",{"type":49,"tag":58,"props":3200,"children":3201},{},[3202,3204,3210],{"type":55,"value":3203},"Before deleting files, run ",{"type":49,"tag":64,"props":3205,"children":3207},{"className":3206},[],[3208],{"type":55,"value":3209},"git status --short",{"type":55,"value":3211}," and verify the paths. If unsure, move files to a backup location instead of deleting immediately.",{"type":49,"tag":349,"props":3213,"children":3215},{"className":351,"code":3214,"language":353,"meta":354,"style":354},"cd \u002Fpath\u002Fto\u002FiosApp\npod deintegrate\nrm -rf Podfile Podfile.lock Pods\u002F\n# Remove the workspace that matches your app xcodeproj name\nXCODEPROJ_NAME=$(basename \"$(find . -maxdepth 1 -name \"*.xcodeproj\" -type d | grep -v Pods | head -1)\" .xcodeproj)\nrm -rf \"${XCODEPROJ_NAME}.xcworkspace\"\n# Return to project root\ncd ..\n# Remove the migrated module podspec only (for example, shared.podspec)\n# If unknown, list candidates and remove the matching one explicitly:\nls -1 *.podspec\n# rm -f shared.podspec\n",[3216],{"type":49,"tag":64,"props":3217,"children":3218},{"__ignoreMap":354},[3219,3230,3243,3271,3280,3381,3414,3422,3434,3442,3450,3471],{"type":49,"tag":360,"props":3220,"children":3221},{"class":362,"line":363},[3222,3226],{"type":49,"tag":360,"props":3223,"children":3224},{"style":2644},[3225],{"type":55,"value":2647},{"type":49,"tag":360,"props":3227,"children":3228},{"style":373},[3229],{"type":55,"value":2652},{"type":49,"tag":360,"props":3231,"children":3232},{"class":362,"line":1434},[3233,3238],{"type":49,"tag":360,"props":3234,"children":3235},{"style":367},[3236],{"type":55,"value":3237},"pod",{"type":49,"tag":360,"props":3239,"children":3240},{"style":373},[3241],{"type":55,"value":3242}," deintegrate\n",{"type":49,"tag":360,"props":3244,"children":3245},{"class":362,"line":1443},[3246,3251,3256,3261,3266],{"type":49,"tag":360,"props":3247,"children":3248},{"style":367},[3249],{"type":55,"value":3250},"rm",{"type":49,"tag":360,"props":3252,"children":3253},{"style":373},[3254],{"type":55,"value":3255}," -rf",{"type":49,"tag":360,"props":3257,"children":3258},{"style":373},[3259],{"type":55,"value":3260}," Podfile",{"type":49,"tag":360,"props":3262,"children":3263},{"style":373},[3264],{"type":55,"value":3265}," Podfile.lock",{"type":49,"tag":360,"props":3267,"children":3268},{"style":373},[3269],{"type":55,"value":3270}," Pods\u002F\n",{"type":49,"tag":360,"props":3272,"children":3273},{"class":362,"line":1452},[3274],{"type":49,"tag":360,"props":3275,"children":3277},{"style":3276},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[3278],{"type":55,"value":3279},"# Remove the workspace that matches your app xcodeproj name\n",{"type":49,"tag":360,"props":3281,"children":3282},{"class":362,"line":1461},[3283,3288,3293,3298,3302,3306,3311,3316,3321,3325,3330,3334,3339,3343,3347,3352,3356,3361,3366,3371,3376],{"type":49,"tag":360,"props":3284,"children":3285},{"style":2690},[3286],{"type":55,"value":3287},"XCODEPROJ_NAME",{"type":49,"tag":360,"props":3289,"children":3290},{"style":379},[3291],{"type":55,"value":3292},"=$(",{"type":49,"tag":360,"props":3294,"children":3295},{"style":367},[3296],{"type":55,"value":3297},"basename",{"type":49,"tag":360,"props":3299,"children":3300},{"style":379},[3301],{"type":55,"value":2677},{"type":49,"tag":360,"props":3303,"children":3304},{"style":367},[3305],{"type":55,"value":1166},{"type":49,"tag":360,"props":3307,"children":3308},{"style":373},[3309],{"type":55,"value":3310}," . -maxdepth ",{"type":49,"tag":360,"props":3312,"children":3314},{"style":3313},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[3315],{"type":55,"value":187},{"type":49,"tag":360,"props":3317,"children":3318},{"style":373},[3319],{"type":55,"value":3320}," -name ",{"type":49,"tag":360,"props":3322,"children":3323},{"style":379},[3324],{"type":55,"value":391},{"type":49,"tag":360,"props":3326,"children":3327},{"style":373},[3328],{"type":55,"value":3329},"*.xcodeproj",{"type":49,"tag":360,"props":3331,"children":3332},{"style":379},[3333],{"type":55,"value":391},{"type":49,"tag":360,"props":3335,"children":3336},{"style":373},[3337],{"type":55,"value":3338}," -type d ",{"type":49,"tag":360,"props":3340,"children":3341},{"style":379},[3342],{"type":55,"value":2703},{"type":49,"tag":360,"props":3344,"children":3345},{"style":367},[3346],{"type":55,"value":2776},{"type":49,"tag":360,"props":3348,"children":3349},{"style":373},[3350],{"type":55,"value":3351}," -v Pods ",{"type":49,"tag":360,"props":3353,"children":3354},{"style":379},[3355],{"type":55,"value":2703},{"type":49,"tag":360,"props":3357,"children":3358},{"style":367},[3359],{"type":55,"value":3360}," head",{"type":49,"tag":360,"props":3362,"children":3363},{"style":373},[3364],{"type":55,"value":3365}," -1",{"type":49,"tag":360,"props":3367,"children":3368},{"style":379},[3369],{"type":55,"value":3370},")\"",{"type":49,"tag":360,"props":3372,"children":3373},{"style":373},[3374],{"type":55,"value":3375}," .xcodeproj",{"type":49,"tag":360,"props":3377,"children":3378},{"style":379},[3379],{"type":55,"value":3380},")\n",{"type":49,"tag":360,"props":3382,"children":3383},{"class":362,"line":1470},[3384,3388,3392,3397,3401,3406,3410],{"type":49,"tag":360,"props":3385,"children":3386},{"style":367},[3387],{"type":55,"value":3250},{"type":49,"tag":360,"props":3389,"children":3390},{"style":373},[3391],{"type":55,"value":3255},{"type":49,"tag":360,"props":3393,"children":3394},{"style":379},[3395],{"type":55,"value":3396}," \"${",{"type":49,"tag":360,"props":3398,"children":3399},{"style":2690},[3400],{"type":55,"value":3287},{"type":49,"tag":360,"props":3402,"children":3403},{"style":379},[3404],{"type":55,"value":3405},"}",{"type":49,"tag":360,"props":3407,"children":3408},{"style":373},[3409],{"type":55,"value":1149},{"type":49,"tag":360,"props":3411,"children":3412},{"style":379},[3413],{"type":55,"value":3102},{"type":49,"tag":360,"props":3415,"children":3416},{"class":362,"line":1479},[3417],{"type":49,"tag":360,"props":3418,"children":3419},{"style":3276},[3420],{"type":55,"value":3421},"# Return to project root\n",{"type":49,"tag":360,"props":3423,"children":3424},{"class":362,"line":1488},[3425,3429],{"type":49,"tag":360,"props":3426,"children":3427},{"style":2644},[3428],{"type":55,"value":2647},{"type":49,"tag":360,"props":3430,"children":3431},{"style":373},[3432],{"type":55,"value":3433}," ..\n",{"type":49,"tag":360,"props":3435,"children":3436},{"class":362,"line":1498},[3437],{"type":49,"tag":360,"props":3438,"children":3439},{"style":3276},[3440],{"type":55,"value":3441},"# Remove the migrated module podspec only (for example, shared.podspec)\n",{"type":49,"tag":360,"props":3443,"children":3444},{"class":362,"line":1507},[3445],{"type":49,"tag":360,"props":3446,"children":3447},{"style":3276},[3448],{"type":55,"value":3449},"# If unknown, list candidates and remove the matching one explicitly:\n",{"type":49,"tag":360,"props":3451,"children":3452},{"class":362,"line":1515},[3453,3458,3462,3466],{"type":49,"tag":360,"props":3454,"children":3455},{"style":367},[3456],{"type":55,"value":3457},"ls",{"type":49,"tag":360,"props":3459,"children":3460},{"style":373},[3461],{"type":55,"value":3365},{"type":49,"tag":360,"props":3463,"children":3464},{"style":2690},[3465],{"type":55,"value":2738},{"type":49,"tag":360,"props":3467,"children":3468},{"style":373},[3469],{"type":55,"value":3470},".podspec\n",{"type":49,"tag":360,"props":3472,"children":3473},{"class":362,"line":1523},[3474],{"type":49,"tag":360,"props":3475,"children":3476},{"style":3276},[3477],{"type":55,"value":3478},"# rm -f shared.podspec\n",{"type":49,"tag":58,"props":3480,"children":3481},{},[3482,3484,3489,3491,3497],{"type":55,"value":3483},"This cleanup snippet is self-contained and does not assume ",{"type":49,"tag":64,"props":3485,"children":3487},{"className":3486},[],[3488],{"type":55,"value":2815},{"type":55,"value":3490}," or ",{"type":49,"tag":64,"props":3492,"children":3494},{"className":3493},[],[3495],{"type":55,"value":3496},"GRADLE_PROJECT_PATH",{"type":55,"value":3498}," from the earlier one-off migration command are still available in your shell.",{"type":49,"tag":58,"props":3500,"children":3501},{},[3502,3504,3510,3512,3516,3518,3524,3526,3532,3534,3539],{"type":55,"value":3503},"If ",{"type":49,"tag":64,"props":3505,"children":3507},{"className":3506},[],[3508],{"type":55,"value":3509},"pod deintegrate",{"type":55,"value":3511}," is not available, see ",{"type":49,"tag":697,"props":3513,"children":3514},{"href":787},[3515],{"type":55,"value":790},{"type":55,"value":3517}," § \"Manual CocoaPods Deintegration from pbxproj\" for the full list of references to remove. Also remove ",{"type":49,"tag":64,"props":3519,"children":3521},{"className":3520},[],[3522],{"type":55,"value":3523},"Pods\u002F",{"type":55,"value":3525}," from ",{"type":49,"tag":64,"props":3527,"children":3529},{"className":3528},[],[3530],{"type":55,"value":3531},".gitignore",{"type":55,"value":3533}," and delete the ",{"type":49,"tag":64,"props":3535,"children":3537},{"className":3536},[],[3538],{"type":55,"value":1149},{"type":55,"value":3540}," directory.",{"type":49,"tag":58,"props":3542,"children":3543},{},[3544,3549],{"type":49,"tag":96,"props":3545,"children":3546},{},[3547],{"type":55,"value":3548},"Option B: Partial removal",{"type":55,"value":3550}," (if other non-KMP CocoaPods dependencies remain):",{"type":49,"tag":58,"props":3552,"children":3553},{},[3554,3556,3561],{"type":55,"value":3555},"Remove only the KMP pod line from the ",{"type":49,"tag":64,"props":3557,"children":3559},{"className":3558},[],[3560],{"type":55,"value":1141},{"type":55,"value":3562}," and re-run pod install:",{"type":49,"tag":349,"props":3564,"children":3568},{"className":3565,"code":3566,"language":3567,"meta":354,"style":354},"language-ruby shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","target 'iosApp' do\n  # Remove this line:\n  pod 'shared', :path => '..\u002Fshared'\n  # Keep other non-KMP pods\nend\n","ruby",[3569],{"type":49,"tag":64,"props":3570,"children":3571},{"__ignoreMap":354},[3572,3580,3588,3596,3604],{"type":49,"tag":360,"props":3573,"children":3574},{"class":362,"line":363},[3575],{"type":49,"tag":360,"props":3576,"children":3577},{},[3578],{"type":55,"value":3579},"target 'iosApp' do\n",{"type":49,"tag":360,"props":3581,"children":3582},{"class":362,"line":1434},[3583],{"type":49,"tag":360,"props":3584,"children":3585},{},[3586],{"type":55,"value":3587},"  # Remove this line:\n",{"type":49,"tag":360,"props":3589,"children":3590},{"class":362,"line":1443},[3591],{"type":49,"tag":360,"props":3592,"children":3593},{},[3594],{"type":55,"value":3595},"  pod 'shared', :path => '..\u002Fshared'\n",{"type":49,"tag":360,"props":3597,"children":3598},{"class":362,"line":1452},[3599],{"type":49,"tag":360,"props":3600,"children":3601},{},[3602],{"type":55,"value":3603},"  # Keep other non-KMP pods\n",{"type":49,"tag":360,"props":3605,"children":3606},{"class":362,"line":1461},[3607],{"type":49,"tag":360,"props":3608,"children":3609},{},[3610],{"type":55,"value":3611},"end\n",{"type":49,"tag":349,"props":3613,"children":3615},{"className":351,"code":3614,"language":353,"meta":354,"style":354},"cd \u002Fpath\u002Fto\u002FiosApp && pod install\n",[3616],{"type":49,"tag":64,"props":3617,"children":3618},{"__ignoreMap":354},[3619],{"type":49,"tag":360,"props":3620,"children":3621},{"class":362,"line":363},[3622,3626,3631,3636,3641],{"type":49,"tag":360,"props":3623,"children":3624},{"style":2644},[3625],{"type":55,"value":2647},{"type":49,"tag":360,"props":3627,"children":3628},{"style":373},[3629],{"type":55,"value":3630}," \u002Fpath\u002Fto\u002FiosApp",{"type":49,"tag":360,"props":3632,"children":3633},{"style":379},[3634],{"type":55,"value":3635}," &&",{"type":49,"tag":360,"props":3637,"children":3638},{"style":367},[3639],{"type":55,"value":3640}," pod",{"type":49,"tag":360,"props":3642,"children":3643},{"style":373},[3644],{"type":55,"value":3645}," install\n",{"type":49,"tag":533,"props":3647,"children":3648},{},[3649],{"type":49,"tag":58,"props":3650,"children":3651},{},[3652,3657],{"type":49,"tag":96,"props":3653,"children":3654},{},[3655],{"type":55,"value":3656},"Tip:",{"type":55,"value":3658}," Consider migrating remaining pods to SPM too — most popular iOS libraries support it natively. Add them in Xcode via File → Add Package Dependencies, then fully deintegrate CocoaPods once all pods are replaced.",{"type":49,"tag":307,"props":3660,"children":3662},{"id":3661},"_54-manual-integration-if-automatic-fails",[3663],{"type":55,"value":3664},"5.4 Manual integration (if automatic fails)",{"type":49,"tag":58,"props":3666,"children":3667},{},[3668,3669,3673],{"type":55,"value":2253},{"type":49,"tag":697,"props":3670,"children":3671},{"href":787},[3672],{"type":55,"value":790},{"type":55,"value":3674}," § \"Manual Xcode Integration Steps\" for the 5-step manual setup (build phase, sandboxing, linkage package).",{"type":49,"tag":297,"props":3676,"children":3677},{},[],{"type":49,"tag":81,"props":3679,"children":3681},{"id":3680},"phase-6-remove-cocoapods-from-gradle",[3682],{"type":55,"value":3683},"Phase 6: Remove CocoaPods from Gradle",{"type":49,"tag":58,"props":3685,"children":3686},{},[3687],{"type":55,"value":3688},"Now that the iOS project is reconfigured, remove the CocoaPods plugin and block:",{"type":49,"tag":307,"props":3690,"children":3692},{"id":3691},"_61-remove-cocoapods-plugin",[3693],{"type":55,"value":3694},"6.1 Remove CocoaPods plugin",{"type":49,"tag":349,"props":3696,"children":3698},{"className":1418,"code":3697,"language":14,"meta":354,"style":354},"plugins {\n    \u002F\u002F REMOVE: kotlin(\"native.cocoapods\")\n    alias(libs.plugins.kotlinMultiplatform)  \u002F\u002F Keep\n}\n",[3699],{"type":49,"tag":64,"props":3700,"children":3701},{"__ignoreMap":354},[3702,3710,3718,3726],{"type":49,"tag":360,"props":3703,"children":3704},{"class":362,"line":363},[3705],{"type":49,"tag":360,"props":3706,"children":3707},{},[3708],{"type":55,"value":3709},"plugins {\n",{"type":49,"tag":360,"props":3711,"children":3712},{"class":362,"line":1434},[3713],{"type":49,"tag":360,"props":3714,"children":3715},{},[3716],{"type":55,"value":3717},"    \u002F\u002F REMOVE: kotlin(\"native.cocoapods\")\n",{"type":49,"tag":360,"props":3719,"children":3720},{"class":362,"line":1443},[3721],{"type":49,"tag":360,"props":3722,"children":3723},{},[3724],{"type":55,"value":3725},"    alias(libs.plugins.kotlinMultiplatform)  \u002F\u002F Keep\n",{"type":49,"tag":360,"props":3727,"children":3728},{"class":362,"line":1452},[3729],{"type":49,"tag":360,"props":3730,"children":3731},{},[3732],{"type":55,"value":1485},{"type":49,"tag":307,"props":3734,"children":3736},{"id":3735},"_62-remove-cocoapods-block",[3737],{"type":55,"value":3738},"6.2 Remove cocoapods block",{"type":49,"tag":58,"props":3740,"children":3741},{},[3742,3744,3750,3752,3757,3759,3764,3766,3772],{"type":55,"value":3743},"Delete the entire ",{"type":49,"tag":64,"props":3745,"children":3747},{"className":3746},[],[3748],{"type":55,"value":3749},"cocoapods { ... }",{"type":55,"value":3751}," block from ",{"type":49,"tag":64,"props":3753,"children":3755},{"className":3754},[],[3756],{"type":55,"value":337},{"type":55,"value":3758},". The ",{"type":49,"tag":64,"props":3760,"children":3762},{"className":3761},[],[3763],{"type":55,"value":77},{"type":55,"value":3765}," block and ",{"type":49,"tag":64,"props":3767,"children":3769},{"className":3768},[],[3770],{"type":55,"value":3771},"binaries.framework {}",{"type":55,"value":3773}," configuration added in Phase 3 replace it.",{"type":49,"tag":307,"props":3775,"children":3777},{"id":3776},"_63-remove-deprecated-gradleproperties-entries",[3778],{"type":55,"value":3779},"6.3 Remove deprecated gradle.properties entries",{"type":49,"tag":58,"props":3781,"children":3782},{},[3783,3785,3790],{"type":55,"value":3784},"If found in Phase 1.1, remove from ",{"type":49,"tag":64,"props":3786,"children":3788},{"className":3787},[],[3789],{"type":55,"value":672},{"type":55,"value":347},{"type":49,"tag":349,"props":3792,"children":3794},{"className":677,"code":3793,"language":679,"meta":354,"style":354},"# REMOVE — no longer needed after migrating away from CocoaPods (KT-64096)\nkotlin.apple.deprecated.allowUsingEmbedAndSignWithCocoaPodsDependencies=true\n",[3795],{"type":49,"tag":64,"props":3796,"children":3797},{"__ignoreMap":354},[3798,3806],{"type":49,"tag":360,"props":3799,"children":3800},{"class":362,"line":363},[3801],{"type":49,"tag":360,"props":3802,"children":3803},{},[3804],{"type":55,"value":3805},"# REMOVE — no longer needed after migrating away from CocoaPods (KT-64096)\n",{"type":49,"tag":360,"props":3807,"children":3808},{"class":362,"line":1434},[3809],{"type":49,"tag":360,"props":3810,"children":3811},{},[3812],{"type":55,"value":678},{"type":49,"tag":307,"props":3814,"children":3816},{"id":3815},"_64-clean-up-cocoapods-related-extras",[3817],{"type":55,"value":3818},"6.4 Clean up CocoaPods-related extras",{"type":49,"tag":58,"props":3820,"children":3821},{},[3822,3824,3829,3831,3836,3838,3843,3845,3851,3852,3857,3859,3865,3867,3872],{"type":55,"value":3823},"Review the extras identified in Phase 1 step 11. Podspec metadata, ",{"type":49,"tag":64,"props":3825,"children":3827},{"className":3826},[],[3828],{"type":55,"value":1358},{"type":55,"value":3830},", CocoaPods task hooks, and ",{"type":49,"tag":64,"props":3832,"children":3834},{"className":3833},[],[3835],{"type":55,"value":1343},{"type":55,"value":3837}," patching code are ",{"type":49,"tag":96,"props":3839,"children":3840},{},[3841],{"type":55,"value":3842},"safe to remove",{"type":55,"value":3844}," without user consultation. Non-standard pod configurations (",{"type":49,"tag":64,"props":3846,"children":3848},{"className":3847},[],[3849],{"type":55,"value":3850},"extraOpts",{"type":55,"value":928},{"type":49,"tag":64,"props":3853,"children":3855},{"className":3854},[],[3856],{"type":55,"value":476},{"type":55,"value":3858},"), custom cinterop ",{"type":49,"tag":64,"props":3860,"children":3862},{"className":3861},[],[3863],{"type":55,"value":3864},"defFile",{"type":55,"value":3866}," setups, and CocoaPods-specific compiler\u002Flinker flags ",{"type":49,"tag":96,"props":3868,"children":3869},{},[3870],{"type":55,"value":3871},"require analysis",{"type":55,"value":3873}," — consult the user if unsure whether SPM handles them automatically.",{"type":49,"tag":58,"props":3875,"children":3876},{},[3877,3878,3882],{"type":55,"value":2253},{"type":49,"tag":697,"props":3879,"children":3880},{"href":1363},[3881],{"type":55,"value":1366},{"type":55,"value":3883}," for the full categorized list with examples.",{"type":49,"tag":297,"props":3885,"children":3886},{},[],{"type":49,"tag":81,"props":3888,"children":3890},{"id":3889},"phase-7-verification",[3891],{"type":55,"value":3892},"Phase 7: Verification",{"type":49,"tag":307,"props":3894,"children":3896},{"id":3895},"_71-build-gradle-project",[3897],{"type":55,"value":3898},"7.1 Build Gradle project",{"type":49,"tag":58,"props":3900,"children":3901},{},[3902],{"type":55,"value":3903},"Build the migrated module to verify the migration succeeded:",{"type":49,"tag":349,"props":3905,"children":3906},{"className":351,"code":448,"language":353,"meta":354,"style":354},[3907],{"type":49,"tag":64,"props":3908,"children":3909},{"__ignoreMap":354},[3910],{"type":49,"tag":360,"props":3911,"children":3912},{"class":362,"line":363},[3913,3917],{"type":49,"tag":360,"props":3914,"children":3915},{"style":367},[3916],{"type":55,"value":460},{"type":49,"tag":360,"props":3918,"children":3919},{"style":373},[3920],{"type":55,"value":465},{"type":49,"tag":307,"props":3922,"children":3924},{"id":3923},"_72-link-framework",[3925],{"type":55,"value":3926},"7.2 Link framework",{"type":49,"tag":349,"props":3928,"children":3930},{"className":351,"code":3929,"language":353,"meta":354,"style":354},".\u002Fgradlew :moduleName:linkDebugFrameworkIosSimulatorArm64\n",[3931],{"type":49,"tag":64,"props":3932,"children":3933},{"__ignoreMap":354},[3934],{"type":49,"tag":360,"props":3935,"children":3936},{"class":362,"line":363},[3937,3941],{"type":49,"tag":360,"props":3938,"children":3939},{"style":367},[3940],{"type":55,"value":460},{"type":49,"tag":360,"props":3942,"children":3943},{"style":373},[3944],{"type":55,"value":3945}," :moduleName:linkDebugFrameworkIosSimulatorArm64\n",{"type":49,"tag":307,"props":3947,"children":3949},{"id":3948},"_73-build-iosmacos-xcode-project",[3950],{"type":55,"value":3951},"7.3 Build iOS\u002FmacOS Xcode project",{"type":49,"tag":58,"props":3953,"children":3954},{},[3955,3957,3963,3965,3971],{"type":55,"value":3956},"After the Gradle build succeeds, build the Xcode project. Use ",{"type":49,"tag":64,"props":3958,"children":3960},{"className":3959},[],[3961],{"type":55,"value":3962},"-project *.xcodeproj",{"type":55,"value":3964}," if all CocoaPods were removed (Option A), or ",{"type":49,"tag":64,"props":3966,"children":3968},{"className":3967},[],[3969],{"type":55,"value":3970},"-workspace *.xcworkspace",{"type":55,"value":3972}," if non-KMP CocoaPods remain (Option B):",{"type":49,"tag":349,"props":3974,"children":3976},{"className":351,"code":3975,"language":353,"meta":354,"style":354},"cd \u002Fpath\u002Fto\u002FiosApp\n# Discover schemes and build (replace -project\u002F-workspace as needed; for macOS use -destination 'platform=macOS'):\nxcodebuild -project *.xcodeproj -list -json 2>\u002Fdev\u002Fnull | python3 -c \"import sys,json; schemes=json.load(sys.stdin)['project']['schemes']; [print(s) for s in schemes]\"\nxcodebuild -project *.xcodeproj -scheme \"\u003CAppScheme>\" -destination 'generic\u002Fplatform=iOS Simulator' ARCHS=arm64 build\n",[3977],{"type":49,"tag":64,"props":3978,"children":3979},{"__ignoreMap":354},[3980,3991,3999,4065],{"type":49,"tag":360,"props":3981,"children":3982},{"class":362,"line":363},[3983,3987],{"type":49,"tag":360,"props":3984,"children":3985},{"style":2644},[3986],{"type":55,"value":2647},{"type":49,"tag":360,"props":3988,"children":3989},{"style":373},[3990],{"type":55,"value":2652},{"type":49,"tag":360,"props":3992,"children":3993},{"class":362,"line":1434},[3994],{"type":49,"tag":360,"props":3995,"children":3996},{"style":3276},[3997],{"type":55,"value":3998},"# Discover schemes and build (replace -project\u002F-workspace as needed; for macOS use -destination 'platform=macOS'):\n",{"type":49,"tag":360,"props":4000,"children":4001},{"class":362,"line":1443},[4002,4006,4011,4015,4019,4024,4029,4034,4039,4043,4047,4052,4056,4061],{"type":49,"tag":360,"props":4003,"children":4004},{"style":367},[4005],{"type":55,"value":2667},{"type":49,"tag":360,"props":4007,"children":4008},{"style":373},[4009],{"type":55,"value":4010}," -project",{"type":49,"tag":360,"props":4012,"children":4013},{"style":2690},[4014],{"type":55,"value":2738},{"type":49,"tag":360,"props":4016,"children":4017},{"style":373},[4018],{"type":55,"value":1241},{"type":49,"tag":360,"props":4020,"children":4021},{"style":373},[4022],{"type":55,"value":4023}," -list",{"type":49,"tag":360,"props":4025,"children":4026},{"style":373},[4027],{"type":55,"value":4028}," -json",{"type":49,"tag":360,"props":4030,"children":4031},{"style":379},[4032],{"type":55,"value":4033}," 2>",{"type":49,"tag":360,"props":4035,"children":4036},{"style":373},[4037],{"type":55,"value":4038},"\u002Fdev\u002Fnull",{"type":49,"tag":360,"props":4040,"children":4041},{"style":379},[4042],{"type":55,"value":2771},{"type":49,"tag":360,"props":4044,"children":4045},{"style":367},[4046],{"type":55,"value":2708},{"type":49,"tag":360,"props":4048,"children":4049},{"style":373},[4050],{"type":55,"value":4051}," -c",{"type":49,"tag":360,"props":4053,"children":4054},{"style":379},[4055],{"type":55,"value":382},{"type":49,"tag":360,"props":4057,"children":4058},{"style":373},[4059],{"type":55,"value":4060},"import sys,json; schemes=json.load(sys.stdin)['project']['schemes']; [print(s) for s in schemes]",{"type":49,"tag":360,"props":4062,"children":4063},{"style":379},[4064],{"type":55,"value":3102},{"type":49,"tag":360,"props":4066,"children":4067},{"class":362,"line":1452},[4068,4072,4076,4080,4084,4088,4092,4097,4101,4105,4109,4113,4117,4121],{"type":49,"tag":360,"props":4069,"children":4070},{"style":367},[4071],{"type":55,"value":2667},{"type":49,"tag":360,"props":4073,"children":4074},{"style":373},[4075],{"type":55,"value":4010},{"type":49,"tag":360,"props":4077,"children":4078},{"style":2690},[4079],{"type":55,"value":2738},{"type":49,"tag":360,"props":4081,"children":4082},{"style":373},[4083],{"type":55,"value":1241},{"type":49,"tag":360,"props":4085,"children":4086},{"style":373},[4087],{"type":55,"value":2672},{"type":49,"tag":360,"props":4089,"children":4090},{"style":379},[4091],{"type":55,"value":382},{"type":49,"tag":360,"props":4093,"children":4094},{"style":373},[4095],{"type":55,"value":4096},"\u003CAppScheme>",{"type":49,"tag":360,"props":4098,"children":4099},{"style":379},[4100],{"type":55,"value":391},{"type":49,"tag":360,"props":4102,"children":4103},{"style":373},[4104],{"type":55,"value":2747},{"type":49,"tag":360,"props":4106,"children":4107},{"style":379},[4108],{"type":55,"value":2752},{"type":49,"tag":360,"props":4110,"children":4111},{"style":373},[4112],{"type":55,"value":2757},{"type":49,"tag":360,"props":4114,"children":4115},{"style":379},[4116],{"type":55,"value":2718},{"type":49,"tag":360,"props":4118,"children":4119},{"style":373},[4120],{"type":55,"value":2766},{"type":49,"tag":360,"props":4122,"children":4123},{"style":373},[4124],{"type":55,"value":4125}," build\n",{"type":49,"tag":58,"props":4127,"children":4128},{},[4129,4141],{"type":49,"tag":96,"props":4130,"children":4131},{},[4132,4133,4139],{"type":55,"value":3503},{"type":49,"tag":64,"props":4134,"children":4136},{"className":4135},[],[4137],{"type":55,"value":4138},"checkSandboxAndWriteProtection",{"type":55,"value":4140}," fails",{"type":55,"value":4142}," — sandboxing was not disabled in Phase 5.1. Go back and apply the sandboxing fix from Phase 5.1, then retry.",{"type":49,"tag":58,"props":4144,"children":4145},{},[4146,4151],{"type":49,"tag":96,"props":4147,"children":4148},{},[4149],{"type":55,"value":4150},"If the pre-migration build was not verified",{"type":55,"value":4152}," (Phase 1.0 fallback was used), warn the user:",{"type":49,"tag":533,"props":4154,"children":4155},{},[4156],{"type":49,"tag":58,"props":4157,"children":4158},{},[4159],{"type":55,"value":4160},"Note: The pre-migration build could not be fully verified. If build errors appear now, some may be pre-existing issues unrelated to the migration. Compare errors against the pre-migration build output to distinguish migration issues from prior problems.",{"type":49,"tag":307,"props":4162,"children":4164},{"id":4163},"if-the-build-fails",[4165],{"type":55,"value":4166},"If the build fails",{"type":49,"tag":58,"props":4168,"children":4169},{},[4170,4175,4177,4181],{"type":49,"tag":96,"props":4171,"children":4172},{},[4173],{"type":55,"value":4174},"Do NOT revert the migration.",{"type":55,"value":4176}," Read the error log, re-check Phases 2-6, and consult ",{"type":49,"tag":697,"props":4178,"children":4179},{"href":787},[4180],{"type":55,"value":790},{"type":55,"value":4182},". If unsure, present options to the user — do not silently undo migration work.",{"type":49,"tag":297,"props":4184,"children":4185},{},[],{"type":49,"tag":81,"props":4187,"children":4189},{"id":4188},"phase-8-migration-report",[4190],{"type":55,"value":4191},"Phase 8: Migration Report",{"type":49,"tag":58,"props":4193,"children":4194},{},[4195,4197,4203,4205,4211],{"type":55,"value":4196},"After migration (whether successful or not), write a comprehensive ",{"type":49,"tag":64,"props":4198,"children":4200},{"className":4199},[],[4201],{"type":55,"value":4202},"MIGRATION_REPORT.md",{"type":55,"value":4204}," in the project root. Use the template in ",{"type":49,"tag":697,"props":4206,"children":4208},{"href":4207},"references\u002Fmigration-report-template.md",[4209],{"type":55,"value":4210},"migration-report-template.md",{"type":55,"value":1761},{"type":49,"tag":58,"props":4213,"children":4214},{},[4215],{"type":55,"value":4216},"The report must include:",{"type":49,"tag":319,"props":4218,"children":4219},{},[4220,4245,4255,4272,4290,4307],{"type":49,"tag":92,"props":4221,"children":4222},{},[4223,4228,4230,4236,4238,4243],{"type":49,"tag":96,"props":4224,"children":4225},{},[4226],{"type":55,"value":4227},"Pre-Migration State",{"type":55,"value":4229}," — CocoaPods dependencies (name, version, ",{"type":49,"tag":64,"props":4231,"children":4233},{"className":4232},[],[4234],{"type":55,"value":4235},"linkOnly",{"type":55,"value":4237},"), framework config, ",{"type":49,"tag":64,"props":4239,"children":4241},{"className":4240},[],[4242],{"type":55,"value":816},{"type":55,"value":4244}," imports, non-KMP pods, atypical configuration",{"type":49,"tag":92,"props":4246,"children":4247},{},[4248,4253],{"type":49,"tag":96,"props":4249,"children":4250},{},[4251],{"type":55,"value":4252},"Migration Steps",{"type":55,"value":4254}," — exact changes per phase with before\u002Fafter snippets for non-trivial changes",{"type":49,"tag":92,"props":4256,"children":4257},{},[4258,4263,4265,4270],{"type":49,"tag":96,"props":4259,"children":4260},{},[4261],{"type":55,"value":4262},"Import Transformations",{"type":55,"value":4264}," — table of every import change, clearly marking preserved ",{"type":49,"tag":64,"props":4266,"children":4268},{"className":4267},[],[4269],{"type":55,"value":816},{"type":55,"value":4271}," imports and which bundled klib provides them",{"type":49,"tag":92,"props":4273,"children":4274},{},[4275,4280,4282,4288],{"type":49,"tag":96,"props":4276,"children":4277},{},[4278],{"type":55,"value":4279},"Errors Encountered",{"type":55,"value":4281}," — structured ",{"type":49,"tag":64,"props":4283,"children":4285},{"className":4284},[],[4286],{"type":55,"value":4287},"Error #N",{"type":55,"value":4289}," entries: phase, exact symptom, root cause, fix, generalizable flag",{"type":49,"tag":92,"props":4291,"children":4292},{},[4293,4298,4300,4305],{"type":49,"tag":96,"props":4294,"children":4295},{},[4296],{"type":55,"value":4297},"Non-Trivial Decisions",{"type":55,"value":4299}," — ",{"type":49,"tag":64,"props":4301,"children":4303},{"className":4302},[],[4304],{"type":55,"value":1053},{"type":55,"value":4306}," changes, preserved imports, framework search paths, trade-offs",{"type":49,"tag":92,"props":4308,"children":4309},{},[4310,4315],{"type":49,"tag":96,"props":4311,"children":4312},{},[4313],{"type":55,"value":4314},"Files Changed",{"type":55,"value":4316}," — complete list grouped by type (Gradle, Kotlin, Xcode, created, deleted)",{"type":49,"tag":297,"props":4318,"children":4319},{},[],{"type":49,"tag":81,"props":4321,"children":4323},{"id":4322},"additional-resources",[4324],{"type":55,"value":4325},"Additional Resources",{"type":49,"tag":88,"props":4327,"children":4328},{},[4329,4339,4349,4359,4369],{"type":49,"tag":92,"props":4330,"children":4331},{},[4332,4337],{"type":49,"tag":697,"props":4333,"children":4334},{"href":2309},[4335],{"type":55,"value":4336},"DSL Reference",{"type":55,"value":4338}," - Full swiftPMDependencies syntax",{"type":49,"tag":92,"props":4340,"children":4341},{},[4342,4347],{"type":49,"tag":697,"props":4343,"children":4344},{"href":1089},[4345],{"type":55,"value":4346},"Common Pods Mapping",{"type":55,"value":4348}," - Pod to SPM mapping table",{"type":49,"tag":92,"props":4350,"children":4351},{},[4352,4357],{"type":49,"tag":697,"props":4353,"children":4354},{"href":1363},[4355],{"type":55,"value":4356},"CocoaPods Extras Patterns",{"type":55,"value":4358}," - Detection and cleanup patterns for CocoaPods workarounds",{"type":49,"tag":92,"props":4360,"children":4361},{},[4362,4367],{"type":49,"tag":697,"props":4363,"children":4364},{"href":787},[4365],{"type":55,"value":4366},"Troubleshooting",{"type":55,"value":4368}," - Issues, solutions, rollback",{"type":49,"tag":92,"props":4370,"children":4371},{},[4372,4377],{"type":49,"tag":697,"props":4373,"children":4374},{"href":4207},[4375],{"type":55,"value":4376},"Migration Report Template",{"type":55,"value":4378}," - Post-migration report template",{"type":49,"tag":4380,"props":4381,"children":4382},"style",{},[4383],{"type":55,"value":4384},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":4386,"total":4515},[4387,4405,4414,4423,4434,4444,4457,4466,4475,4485,4494,4505],{"slug":4388,"name":4388,"fn":4389,"description":4390,"org":4391,"tags":4392,"stars":4402,"repoUrl":4403,"updatedAt":4404},"mps-aspect-accessories","configure JetBrains MPS module dependencies","Wire MPS module and model dependencies, used languages, used devkits, extended languages, runtime solutions, accessory models, and language\u002Fdependency versions. Use when adding\u002Fremoving module dependencies, importing languages or devkits into a model, declaring runtime solutions, or shipping accessory content visible to consumers without explicit import.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4393,4396,4399],{"name":4394,"slug":4395,"type":15},"Architecture","architecture",{"name":4397,"slug":4398,"type":15},"Configuration","configuration",{"name":4400,"slug":4401,"type":15},"Engineering","engineering",1650,"https:\u002F\u002Fgithub.com\u002FJetBrains\u002FMPS","2026-07-17T06:06:57.311661",{"slug":4406,"name":4406,"fn":4407,"description":4408,"org":4409,"tags":4410,"stars":4402,"repoUrl":4403,"updatedAt":4413},"mps-aspect-actions","define and edit MPS node factories","Use when defining or editing MPS node factories (the \"actions\" aspect) — `NodeFactories` roots, per-concept `NodeFactory` setup functions that initialize a freshly created node and optionally copy data from a replaced `sampleNode`, plus the actions aspect's `CopyPasteHandlers` and `PasteWrappers` roots. Reach for this skill when a substitution, side transform, completion replacement, or `add new initialized(...)` should preserve fields from the node it is replacing, or when defaults set in a constructor are not enough.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4411,4412],{"name":4394,"slug":4395,"type":15},{"name":4400,"slug":4401,"type":15},"2026-07-17T06:04:48.066901",{"slug":4415,"name":4415,"fn":4416,"description":4417,"org":4418,"tags":4419,"stars":4402,"repoUrl":4403,"updatedAt":4422},"mps-aspect-behavior","define and edit MPS concept behavior","Use when defining or editing MPS `ConceptBehavior` — per-concept methods (non-virtual \u002F virtual \u002F abstract \u002F static \u002F virtual static), constructors, virtual dispatch (MRO), super and interface-default calls (`super\u003CInterface>.method`), overriding methods from `lang.core.behavior` interfaces such as `ScopeProvider.getScope` \u002F `INamedConcept.getName` \u002F `BaseConcept.getPresentation`, calling sibling methods (`LocalBehaviorMethodCall`) and behavior methods from other aspects via `node.method(...)`. Reach for this skill whenever the task involves authoring or modifying `\u003Clang>\u002FlanguageModels\u002Fbehavior.mps`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4420,4421],{"name":4394,"slug":4395,"type":15},{"name":4400,"slug":4401,"type":15},"2026-07-13T06:45:21.757084",{"slug":4424,"name":4424,"fn":4425,"description":4426,"org":4427,"tags":4428,"stars":4402,"repoUrl":4403,"updatedAt":4433},"mps-aspect-constraints","define JetBrains MPS language constraints","Use when defining or editing MPS language constraints — property validators \u002F setters \u002F getters, referent search scopes (imperative or inherited via `ScopeProvider.getScope`), `referentSetHandler` side effects, default-scope blocks, `canBeChild` \u002F `canBeParent` \u002F `canBeAncestor` \u002F `canBeRoot` placement rules, `defaultConcreteConcept` for abstract concepts, `set \u003Cread-only>` and `{name}` aliasing, and scope helpers (`SimpleRoleScope`, `ListScope`, `CompositeScope`, `HidingByNameScope`). Reach for this skill whenever the task involves authoring or modifying `\u003Clang>\u002FlanguageModels\u002Fconstraints.mps`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4429,4430],{"name":4394,"slug":4395,"type":15},{"name":4431,"slug":4432,"type":15},"Code Analysis","code-analysis","2026-07-23T05:41:33.639365",{"slug":4435,"name":4435,"fn":4436,"description":4437,"org":4438,"tags":4439,"stars":4402,"repoUrl":4403,"updatedAt":4443},"mps-aspect-dataflow","define and debug MPS dataflow builders","Use when defining or debugging MPS dataflow builders for a concept — control\u002Fdata flow declarations that drive reachability analysis and variable-use checking. Covers DataFlowBuilderDeclaration, BuilderBlock, emit instructions (code for, jump, ifjump, label, read, write, ret, mayBeUnreachable), positions (AfterPosition, BeforePosition, LabelPosition), the jetbrains.mps.lang.dataFlow language, the NodeParameter implicit, BL+smodel usage inside builder bodies, and IBuilderMode for advanced analyses such as nullable\u002Fnon-null tracking.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4440],{"name":4441,"slug":4442,"type":15},"Data Analysis","data-analysis","2026-07-13T06:45:19.114674",{"slug":4445,"name":4445,"fn":4446,"description":4447,"org":4448,"tags":4449,"stars":4402,"repoUrl":4403,"updatedAt":4456},"mps-aspect-editor","define MPS editor layouts","Use when creating or changing MPS editor definitions — the overall workflow from scaffolding a `ConceptEditorDeclaration` through componentizing reusable `EditorComponentDeclaration`s, refining cell models and cell layouts, applying style sheets and indent-layout style items, wiring smart references, leveraging inheritance via super-concepts and interfaces, inspecting (`print_node_json`, `show_node_representation`) and validating (`check_root_node_problems`). Covers `jetbrains.mps.lang.editor` cell models (`CellModel_RefNode`\u002F`CellModel_RefNodeList`\u002F`CellModel_RefCell`\u002F`CellModel_Property`\u002F`CellModel_Constant`), layout choices, and JSON blueprints for common editor shapes. For the non-layout side (action maps, keymaps, transformation\u002Fsubstitute menus) use `mps-aspect-editor-menus-and-keymaps`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4450,4453],{"name":4451,"slug":4452,"type":15},"Design","design",{"name":4454,"slug":4455,"type":15},"UI Components","ui-components","2026-07-23T05:41:56.638151",{"slug":4458,"name":4458,"fn":4459,"description":4460,"org":4461,"tags":4462,"stars":4402,"repoUrl":4403,"updatedAt":4465},"mps-aspect-editor-menus-and-keymaps","author MPS editor menus and keymaps","Use when authoring the **non-layout** parts of the MPS editor aspect — what happens when the user types, presses a key, triggers completion, pastes, or invokes a context action. Covers action maps (`CellActionMapDeclaration`), cell keymaps (`CellKeyMapDeclaration`), transformation menus (`TransformationMenu_Default` \u002F `_Named` \u002F `_Contribution`), substitute menus (`SubstituteMenu_Default` \u002F `SubstituteMenu` \u002F contributions), side transforms (LEFT\u002FRIGHT), legacy cell menus, paste wrappers and copy-paste handlers (in the actions language), completion styling, reference presentation, two-step deletion, and the editor selection API. Trigger terms: `actionMap`, `keyMap`, `delete_action_id`, `transformationMenu`, `substituteMenu`, `Ctrl+Space`, `Ctrl+Alt+B`, side transform, paste wrapper, completion styling, `PasteWrappers`, `CopyPasteHandlers`. For the **layout** side (cells, layouts, style sheets) use `mps-aspect-editor` instead.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4463,4464],{"name":4400,"slug":4401,"type":15},{"name":4454,"slug":4455,"type":15},"2026-07-23T05:41:49.666535",{"slug":4467,"name":4467,"fn":4468,"description":4469,"org":4470,"tags":4471,"stars":4402,"repoUrl":4403,"updatedAt":4474},"mps-aspect-generation-plan","modify MPS generation plans","Use when defining or modifying an MPS generation plan — explicit ordering of generators, checkpoints for cross-model reference resolution, forks for parallel branches, IncludePlan composition, conditional PlanContribution activation, ParameterEquals\u002FConceptListSelector fork selectors, and InitModelAttributes for targetFacet routing. Apply when working with @genplan models, the jetbrains.mps.lang.generator.plan language, attaching plans via DevKits or the Custom generation facet, or debugging cross-model mapping label resolution.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4472,4473],{"name":4394,"slug":4395,"type":15},{"name":4400,"slug":4401,"type":15},"2026-07-13T06:44:59.507855",{"slug":4476,"name":4476,"fn":4477,"description":4478,"org":4479,"tags":4480,"stars":4402,"repoUrl":4403,"updatedAt":4484},"mps-aspect-generator","define JetBrains MPS generator rules","Use when defining or modifying MPS generators — author a generator module, add or edit root\u002Freduction\u002Fweaving\u002Fpattern mapping rules, attach template macros ($COPY_SRC, $LOOP, $IF, $PROPERTY, $REF, $SWITCH, $MAP_SRC, $WEAVE, $INSERT, $LABEL, $TRACE, $VAR), wire mapping labels, build template switches, write pre\u002Fpost mapping scripts, navigate `genContext`, or debug \"rule didn't fire\", missing references, empty output, infinite reduction loops, and generated-Java compile failures.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4481,4482,4483],{"name":4394,"slug":4395,"type":15},{"name":4431,"slug":4432,"type":15},{"name":4400,"slug":4401,"type":15},"2026-07-17T06:06:58.042999",{"slug":4486,"name":4486,"fn":4487,"description":4488,"org":4489,"tags":4490,"stars":4402,"repoUrl":4403,"updatedAt":4493},"mps-aspect-intentions","define and edit MPS intentions","Use when defining or editing MPS intentions (the Alt+Enter context-action aspect) — adding `IntentionDeclaration` roots, parameterized or surround-with variants, description\u002FisApplicable\u002Fexecute blocks, child-filter functions, factory-initialized AST splicing, or debugging why an intention is not offered. Lives in the language's `intentions` model and uses `jetbrains.mps.lang.intentions`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4491,4492],{"name":4394,"slug":4395,"type":15},{"name":4400,"slug":4401,"type":15},"2026-07-23T05:41:48.692899",{"slug":4495,"name":4495,"fn":4496,"description":4497,"org":4498,"tags":4499,"stars":4402,"repoUrl":4403,"updatedAt":4504},"mps-aspect-migrations","author and debug MPS migration scripts","Use when authoring or debugging MPS migration scripts that upgrade user models after a language definition changes — covers jetbrains.mps.lang.migration (MigrationScript class-based, PureMigrationScript declarative, MoveConcept\u002FMoveContainmentLink\u002FMoveReferenceLink\u002FMoveProperty, ordering via OrderDependency, data exchange via putData\u002FgetData, RefactoringLog, ConceptMigrationReference) and jetbrains.mps.lang.script Enhancement Scripts (MigrationScript with MigrationScriptPart_Instance, ExtractInterfaceMigration, FactoryMigrationScriptPart, CommentMigrationScriptPart) — when a model needs version-gated upgrade, concept rename or removal, link or property rename, instance-level transformation, or composition of migration steps.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4500,4503],{"name":4501,"slug":4502,"type":15},"Debugging","debugging",{"name":23,"slug":24,"type":15},"2026-07-13T06:45:20.372122",{"slug":4506,"name":4506,"fn":4507,"description":4508,"org":4509,"tags":4510,"stars":4402,"repoUrl":4403,"updatedAt":4514},"mps-aspect-structure-concepts","define concepts in MPS structure aspect","Define concepts, interface concepts, enumerations, and constrained data types in an MPS language's `structure` aspect. Covers smart-reference detection, alias rules, cardinality, INamedConcept usage, bulk creation, and the full `mps_mcp_alter_structure` \u002F `mps_mcp_query_structure` reference. Use when authoring or modifying a language's structure model.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4511],{"name":4512,"slug":4513,"type":15},"Data Modeling","data-modeling","2026-07-23T05:41:30.705975",188,{"items":4517,"total":4633},[4518,4537,4552,4566,4581,4602,4619],{"slug":4519,"name":4519,"fn":4520,"description":4521,"org":4522,"tags":4523,"stars":28,"repoUrl":29,"updatedAt":4536},"algorithmic-art","create generative art with p5.js","Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4524,4527,4530,4533],{"name":4525,"slug":4526,"type":15},"Creative","creative",{"name":4528,"slug":4529,"type":15},"Generative Art","generative-art",{"name":4531,"slug":4532,"type":15},"Graphics","graphics",{"name":4534,"slug":4535,"type":15},"JavaScript","javascript","2026-07-13T06:41:35.540127",{"slug":4538,"name":4538,"fn":4539,"description":4540,"org":4541,"tags":4542,"stars":28,"repoUrl":29,"updatedAt":4551},"antfu","configure JavaScript projects with Anthony Fu's tools","Anthony Fu's opinionated tooling and conventions for JavaScript\u002FTypeScript projects. Use when setting up new projects, configuring ESLint\u002FPrettier alternatives, monorepos, library publishing, or when the user mentions Anthony Fu's preferences.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4543,4546,4547,4548],{"name":4544,"slug":4545,"type":15},"Best Practices","best-practices",{"name":4400,"slug":4401,"type":15},{"name":4534,"slug":4535,"type":15},{"name":4549,"slug":4550,"type":15},"TypeScript","typescript","2026-07-13T06:43:13.153309",{"slug":4553,"name":4553,"fn":4554,"description":4555,"org":4556,"tags":4557,"stars":28,"repoUrl":29,"updatedAt":4565},"brand-guidelines","apply Anthropic brand guidelines","Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4558,4561,4562],{"name":4559,"slug":4560,"type":15},"Branding","branding",{"name":4451,"slug":4452,"type":15},{"name":4563,"slug":4564,"type":15},"Typography","typography","2026-07-13T06:43:06.077629",{"slug":4567,"name":4567,"fn":4568,"description":4569,"org":4570,"tags":4571,"stars":28,"repoUrl":29,"updatedAt":4580},"canvas-design","create visual art and design assets","Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4572,4573,4574,4577],{"name":4525,"slug":4526,"type":15},{"name":4451,"slug":4452,"type":15},{"name":4575,"slug":4576,"type":15},"Images","images",{"name":4578,"slug":4579,"type":15},"PDF","pdf","2026-07-13T06:39:58.803113",{"slug":4582,"name":4582,"fn":4583,"description":4584,"org":4585,"tags":4586,"stars":28,"repoUrl":29,"updatedAt":4601},"ci-cd-containerization-advisor","design CI\u002FCD pipelines for Kotlin applications","Design reproducible build, image, and deployment pipelines for Kotlin plus Spring applications, including CI verification, layered containers, rollout safety, and deployment-time migration coordination. Use when creating or improving Dockerfiles, CI workflows, image hardening, Kubernetes manifests, release gates, or deployment strategies for Spring Boot services, especially where build reproducibility and operational safety matter.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4587,4590,4593,4596,4597,4598],{"name":4588,"slug":4589,"type":15},"CI\u002FCD","ci-cd",{"name":4591,"slug":4592,"type":15},"Containers","containers",{"name":4594,"slug":4595,"type":15},"Deployment","deployment",{"name":4400,"slug":4401,"type":15},{"name":13,"slug":14,"type":15},{"name":4599,"slug":4600,"type":15},"Spring","spring","2026-07-13T06:41:47.83899",{"slug":4603,"name":4603,"fn":4604,"description":4605,"org":4606,"tags":4607,"stars":28,"repoUrl":29,"updatedAt":4618},"cloudflare-deploy","deploy applications to Cloudflare","Deploy applications and infrastructure to Cloudflare using Workers, Pages, and related platform services. Use when the user asks to deploy, host, publish, or set up a project on Cloudflare.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4608,4611,4614,4617],{"name":4609,"slug":4610,"type":15},"Cloudflare","cloudflare",{"name":4612,"slug":4613,"type":15},"Cloudflare Pages","cloudflare-pages",{"name":4615,"slug":4616,"type":15},"Cloudflare Workers","cloudflare-workers",{"name":4594,"slug":4595,"type":15},"2026-07-17T06:04:42.853896",{"slug":4620,"name":4620,"fn":4621,"description":4622,"org":4623,"tags":4624,"stars":28,"repoUrl":29,"updatedAt":4632},"compose-ui-control","interact with Compose Desktop applications","Control a running Compose Desktop application via HTTP. Use when you need to interact with UI elements, click buttons, enter text, wait for elements to appear, or capture screenshots in a Compose Desktop app that has compose-ui-test-server enabled.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[4625,4628,4631],{"name":4626,"slug":4627,"type":15},"Automation","automation",{"name":4629,"slug":4630,"type":15},"Desktop","desktop",{"name":4454,"slug":4455,"type":15},"2026-07-13T06:40:38.798626",128]