[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-ionic-capacitor-uiscene-migrator":3,"mdc--yim04s-key":36,"related-org-ionic-capacitor-uiscene-migrator":1678,"related-repo-ionic-capacitor-uiscene-migrator":1729},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":32,"sourceUrl":34,"mdContent":35},"capacitor-uiscene-migrator","migrate Capacitor apps to UIScene lifecycle","Assists Capacitor developers migrating an iOS app or plugin from 8.4 to the 8.5 UIScene lifecycle, covering what `npx cap migrate` skips or only warns about: partially migrated projects, hand-rolled scene delegates, and custom application(_:open:) bodies that must move by hand. Audits first, reports findings, asks the developer at judgement points, merges surgically instead of overwriting, and hands off to `npx cap migrate` when the project matches the template shape. Branches for Capacitor plugin repos, auditing Swift for lifecycle assumptions without touching app-level files. Use when the user says \"migrate my Capacitor app to UIScene\", \"add SceneDelegate support\", \"Capacitor 8.5 migration\", \"update to Capacitor 8.5\", \"adopt the scene lifecycle\", \"Xcode 27 Capacitor build failing\", or mentions the \"CLIENT OF UIKIT REQUIRES UPDATE\" warning. Do not use for Cordova-to-Capacitor migration (use cordova-plugin-migrator), generating new plugins (use capacitor-plugin-generator), or Capacitor 9 migrations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"ionic","Ionic","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fionic.png","ionic-team",[13,17,20,23],{"name":14,"slug":15,"type":16},"iOS","ios","tag",{"name":18,"slug":19,"type":16},"Mobile","mobile",{"name":21,"slug":22,"type":16},"Capacitor","capacitor",{"name":24,"slug":25,"type":16},"Migration","migration",14,"https:\u002F\u002Fgithub.com\u002Fionic-team\u002Fcapacitor-skills","2026-08-03T06:27:21.216153",null,1,[],{"repoUrl":27,"stars":26,"forks":30,"topics":33,"description":29},[],"https:\u002F\u002Fgithub.com\u002Fionic-team\u002Fcapacitor-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fcapacitor-uiscene-migrator","---\nname: capacitor-uiscene-migrator\ndescription: >-\n  Assists Capacitor developers migrating an iOS app or plugin from 8.4 to\n  the 8.5 UIScene lifecycle, covering what `npx cap migrate` skips or only\n  warns about: partially migrated projects, hand-rolled scene delegates,\n  and custom application(_:open:) bodies that must move by hand. Audits\n  first, reports findings, asks the developer at judgement points, merges\n  surgically instead of overwriting, and hands off to `npx cap migrate`\n  when the project matches the template shape. Branches for Capacitor\n  plugin repos, auditing Swift for lifecycle assumptions without touching\n  app-level files. Use when the user says \"migrate my Capacitor app to\n  UIScene\", \"add SceneDelegate support\", \"Capacitor 8.5 migration\",\n  \"update to Capacitor 8.5\", \"adopt the scene lifecycle\", \"Xcode 27\n  Capacitor build failing\", or mentions the \"CLIENT OF UIKIT REQUIRES\n  UPDATE\" warning. Do not use for Cordova-to-Capacitor migration (use\n  cordova-plugin-migrator), generating new plugins\n  (use capacitor-plugin-generator), or Capacitor 9 migrations.\nmetadata:\n  author: ionic\n  source: https:\u002F\u002Fgithub.com\u002Fionic-team\u002Fcapacitor-skills\n---\n\n# Capacitor UIScene Migrator\n\nGuides a Capacitor 8.4 → 8.5 iOS migration to the UIScene lifecycle. The\nCLI migrator (`npx cap migrate`) handles projects that still match the\nCapacitor templates; this skill exists for everything else. It audits\nbefore editing, asks the developer where judgement is required, merges\ninto existing files rather than replacing them, and delegates the\nmechanical work to the CLI whenever the project shape allows.\n\nThe canonical migration reference is the\n[8.4 → 8.5 migration guide](https:\u002F\u002Fcapacitorjs.com\u002Fdocs\u002Fupdating\u002F8-5).\nLink it whenever a step is left for the developer to do manually.\n\n## When to Use This Skill\n\n- Migrating a Capacitor 8.x iOS app to the UIScene lifecycle\n- A project where `npx cap migrate` reported a partial state and skipped\n- An app with a hand-rolled `SceneDelegate.swift` or a customized\n  `AppDelegate.swift` (deep-link routing, third-party SDK forwarding)\n- Auditing a Capacitor plugin repo for UIScene compatibility\n- Diagnosing the Xcode \"CLIENT OF UIKIT REQUIRES UPDATE: This process\n  does not adopt UIScene lifecycle\" warning in a Capacitor app\n\n## When NOT to Use This Skill\n\n- Cordova-to-Capacitor plugin migration → `cordova-plugin-migrator`\n- Generating a new Capacitor plugin → `capacitor-plugin-generator`\n- Capacitor 9 or later migrations (this skill is 8.4 → 8.5 only)\n- Android lifecycle work (UIScene is iOS only)\n- General Capacitor debugging unrelated to the scene lifecycle\n\n## Prerequisites\n\n- A Capacitor 8.x project (app or plugin) with an `ios\u002F` platform or\n  iOS sources\n- `@capacitor\u002Fcli` 8.5+ available for the `npx cap migrate` handoff\n- Xcode installed if the developer wants build verification\n\n## What Changed in 8.5 (facts the audit relies on)\n\nThese determine what breaks and what does not. Do not soften them.\n\n- Scene adoption is opt-in. An app with no `UIApplicationSceneManifest`\n  keeps the AppDelegate path, which still works on the 8.5 core. iOS\n  posts `UIScene.*` notifications even for legacy apps (compatibility\n  scene), so the bridge's JS `resume`\u002F`pause` events fire in both modes.\n- Once the scene manifest exists, iOS stops calling\n  `application(_:open:options:)`, `application(_:continue:)`, and the\n  four foreground\u002Fbackground AppDelegate methods\n  (`applicationDidBecomeActive`, `applicationWillResignActive`,\n  `applicationDidEnterBackground`, `applicationWillEnterForeground`).\n  Custom code in any of those silently stops running. The\n  `UIApplication` notifications still fire; `didFinishLaunching`,\n  `applicationWillTerminate`, push token registration, and the\n  remote-notification callbacks stay on the AppDelegate.\n- `SceneDelegateProxy` re-posts the legacy `.capacitorOpenURL`,\n  `.capacitorOpenUniversalLink`, and `CDVPluginHandleOpenURL`\n  notifications with the same payload shape, so existing observers keep\n  working. Cold-start URLs are delivered after the bridge view appears,\n  so both `appUrlOpen` and `getLaunchUrl()` work on cold launch.\n- New `.capacitorSceneWillConnect`, `.capacitorSceneOpenURL`, and\n  `.capacitorSceneOpenUniversalLink` notifications carry the `UIScene`\n  as the object. They are only posted on 8.5+; plugins that also support\n  8.4 must keep using the legacy names.\n- `TmpViewController` and `CapacitorBridge.tmpWindow` were removed. Any\n  reference is a build error on 8.5.\n- The 8.5 templates create the window in code in\n  `scene(_:willConnectTo:)`; `Main.storyboard` no longer provides the\n  root view controller. Custom `CAPBridgeViewController` subclasses are\n  instantiated in the SceneDelegate, not set in the storyboard.\n\n## Agent Behavior\n\n- Audit first, report second, edit last. Never modify a file before the\n  developer has seen the findings and confirmed.\n- Never overwrite an existing `SceneDelegate.swift`, `AppDelegate.swift`,\n  or `Info.plist` structure. Merge surgically per\n  [references\u002Fsurgical-merges.md](references\u002Fsurgical-merges.md).\n- Prefer the CLI. If the project classifies as eligible (Phase 3), run\n  `npx cap migrate` instead of editing files by hand.\n- Ask, do not assume, at the decision points in Phase 6. Use\n  `AskUserQuestion` where available; otherwise ask in plain text and\n  wait.\n- Do not commit, stage, or push. Leave version control to the developer.\n- On a plugin repo, never touch `Info.plist`, `AppDelegate.swift`, or\n  project files. The plugin branch is audit and advice only.\n\n## Procedures\n\n### Phase 1: Detect Repo Type\n\nDecide app vs. plugin before anything else.\n\n- **App**: has `ios\u002FApp\u002FApp.xcodeproj` (or `capacitor.config.*` with an\n  `ios\u002F` platform directory).\n- **Plugin**: has a `Package.swift` or `.podspec` depending on\n  Capacitor, `CAPPlugin`\u002F`CapacitorPlugin` subclasses in `ios\u002FSources`\n  or `ios\u002FPlugin`, and no `App\u002FApp.xcodeproj`.\n\nPlugin repo → skip to Phase 10\n([references\u002Fplugin-repo-audit.md](references\u002Fplugin-repo-audit.md)).\n\n### Phase 2: Detect Package Manager and Versions\n\n- Pods vs. SPM: `ios\u002FApp\u002FPodfile` → CocoaPods; `Package.swift` or an SPM\n  reference inside the Xcode project → SPM. This affects how `npx cap\n  sync ios` behaves, not the SceneDelegate content: the 8.5 templates\n  ship one SceneDelegate for both.\n- Check `@capacitor\u002Fios` version in `package.json`. If below 8.5, the\n  dependency update is part of the migration; the CLI migrator handles\n  it, or update manually per the guide.\n\n### Phase 3: Classify the Project State\n\nRead the same three signals the CLI migrator uses:\n\n1. `Info.plist` contains `UIApplicationSceneManifest`\n2. `SceneDelegate.swift` exists on disk in the app target directory\n   (pbxproj registration is a separate concern, handled in Phase 7)\n3. `AppDelegate.swift` contains `UISceneConfiguration(name:`\n\n| Signals present | State | Route |\n|---|---|---|\n| 0 of 3 | eligible | Phases 4-6, then Phase 7a: hand off to `npx cap migrate` |\n| 3 of 3 | already migrated | Audit only (Phase 4), then verify (Phase 9) |\n| 1-2 of 3 | partial | Phases 4-6, then Phase 7b: surgical merges |\n\nEvery route audits before anything runs or changes; the routes differ\nonly in who applies the changes.\n\nThe CLI warns and skips on partial states by design. Partial is exactly\nwhere this skill does its own editing.\n\n### Phase 4: Audit the Codebase\n\nRun the scans in\n[references\u002Faudit-patterns.md](references\u002Faudit-patterns.md) across the\napp's iOS sources and installed plugins (`node_modules\u002F@capacitor*`,\nplus any local plugin paths). Collect findings for:\n\n- `UIApplication.shared.applicationState` usage\n- Custom `application(_:open:)` \u002F `application(_:continue:)` bodies\n  beyond the `ApplicationDelegateProxy` forwarder\n- Custom code in AppDelegate lifecycle methods\n- Existing `SceneDelegate.swift` implementations and what they contain\n- References to `tmpWindow` \u002F `TmpViewController` (build errors on 8.5)\n- Existing or partial `UIApplicationSceneManifest` entries\n- `.capacitorOpenURL` \u002F `.capacitorOpenUniversalLink` observers\n  (informational: they keep working)\n\n### Phase 5: Present Findings and Confirm\n\nReport every finding with file and line before touching anything.\nGroup as: blocks the build (tmpWindow\u002FTmpViewController), needs a\ndecision (custom delegate bodies, existing SceneDelegate), informational\n(observers, applicationState in plugins the developer does not own).\nAsk the developer to confirm proceeding.\n\n### Phase 6: Decision Points\n\nAsk, at minimum:\n\n1. **Legacy URL handlers**: keep or remove\n   `application(_:open:options:)` \u002F `application(_:continue:)` in\n   `AppDelegate.swift`? They become dead code under scenes. Keeping them\n   is harmless; removing them is cleaner. If the body contains custom\n   logic, it must move to the SceneDelegate either way. On the eligible\n   route, apply the answer after the CLI has run.\n2. **Custom `application(_:open:)` body**: migrate it manually (the\n   developer moves the logic) or have the skill move it into\n   `scene(_:openURLContexts:)` alongside the proxy forwarder? Show the\n   body before asking. Skip this question when the body is\n   forwarder-only per the audit test.\n3. **Existing SceneDelegate**: confirm each proposed insertion\n   (missing forwarders, window setup) as a diff before applying.\n\n### Phase 7a: Eligible → CLI Handoff\n\nVerify the resolved CLI first: run `npm install` if `node_modules` is\nmissing, then `npx cap --version`; the UIScene migrator needs 8.5 or\nnewer. Then run `npx cap migrate` and interpret its output. It writes\n`SceneDelegate.swift`, patches `Info.plist` and `AppDelegate.swift`,\nregisters the file in `project.pbxproj`, warns on the scan patterns from\nPhase 4, and links the migration guide. Confirm each step's log line;\nif the CLI skipped a step (file existed, partial state raced in),\nfall through to Phase 7b for that step only.\n\n### Phase 7b: Partial or Hand-Rolled → Surgical Merges\n\nApply only the missing pieces, per\n[references\u002Fsurgical-merges.md](references\u002Fsurgical-merges.md):\n\n- Missing manifest → merge `UIApplicationSceneManifest` into\n  `Info.plist`, preserving existing keys\n- Missing `configurationForConnecting` → insert into the existing\n  `AppDelegate.swift` before the class's closing brace, displacing\n  nothing\n- Missing or incomplete `SceneDelegate.swift` → create from\n  [references\u002Fscene-delegate-template.md](references\u002Fscene-delegate-template.md),\n  or add the missing `SceneDelegateProxy.shared` forwarders to the\n  existing one, preserving all custom logic\n- New file → register in `project.pbxproj` (Xcode does this when the\n  file is added through the IDE; otherwise follow the reference)\n\n### Phase 8: Sync and Build\n\nRun `npx cap sync ios`. If Xcode is available, build the app target and\nsurface any errors (most commonly leftover `tmpWindow` references).\n\n### Phase 9: Verification Checklist\n\nWalk the developer through, linking the guide for detail:\n\n- App launches to the web view\n- Background and foreground the app: JS `resume`\u002F`pause` fire (they are\n  scoped to the app's scene now)\n- Custom URL scheme: cold launch and warm open both deliver the URL\n  (`appUrlOpen` listener and `App.getLaunchUrl()`)\n- Universal link, if the app uses them (requires an associated domain)\n\n### Phase 10: Plugin Repo Branch\n\nNo app-level files to patch. Audit the plugin's Swift per\n[references\u002Fplugin-repo-audit.md](references\u002Fplugin-repo-audit.md) and\nreport: lifecycle assumptions that break under scenes, APIs removed in\n8.5, and the compatibility rules for supporting 8.4 and 8.5 with one\nplugin version. Apply code changes only if the developer asks, and only\nin the plugin's own sources.\n\n## Best Practices\n\n### DO\n\n- Show diffs before applying them\n- Keep every finding tied to a file and line\n- Re-run the Phase 3 classification after edits to confirm the project\n  reads as fully migrated\n- Tell plugin authors to keep the legacy notification names while they\n  support 8.4\n\n### DON'T\n\n- Overwrite user code, ever\n- Rewrite third-party plugin code under `node_modules` (report it;\n  the fix belongs upstream)\n- Duplicate the CLI's work by hand-editing an eligible project\n- Promise universal-link behavior without an associated domain to test\n\n## Error Handling\n\n- `npx cap migrate` warns \"partial state\" → expected; this skill's\n  Phase 7b exists for that. Do not reset the project without asking.\n- `project.pbxproj` edits fail or the project no longer opens → revert\n  the pbxproj change and register the file through Xcode instead.\n- Build fails on `tmpWindow` \u002F `TmpViewController` → the references\n  must be deleted; there is no 8.5 replacement (the bridge's\n  `viewController` is the presentation anchor).\n- `SceneDelegate` exists but the app shows a black screen → the\n  delegate neither creates a window nor lets a storyboard do it; add\n  the window setup from the template.\n\n## Related Skills\n\n- `cordova-plugin-migrator`: Cordova plugin to Capacitor migration\n- `capacitor-plugin-generator`: new Capacitor plugin scaffolds\n\n## References\n\n| File | Purpose |\n|---|---|\n| [references\u002Fscene-delegate-template.md](references\u002Fscene-delegate-template.md) | The 8.5 SceneDelegate template and custom-subclass variant |\n| [references\u002Faudit-patterns.md](references\u002Faudit-patterns.md) | Exact scan patterns with commands |\n| [references\u002Fsurgical-merges.md](references\u002Fsurgical-merges.md) | Merge recipes for partial and hand-rolled projects |\n| [references\u002Fplugin-repo-audit.md](references\u002Fplugin-repo-audit.md) | Plugin-author branch: audit and compatibility rules |\n",{"data":37,"body":39},{"name":4,"description":6,"metadata":38},{"author":8,"source":27},{"type":40,"children":41},"root",[42,50,65,81,88,141,147,187,193,232,238,243,490,496,585,591,598,603,704,716,722,774,780,785,829,921,926,931,937,957,1063,1069,1074,1080,1085,1152,1158,1222,1228,1239,1320,1326,1345,1351,1356,1407,1413,1424,1430,1436,1459,1465,1495,1501,1561,1567,1590,1596],{"type":43,"tag":44,"props":45,"children":46},"element","h1",{"id":4},[47],{"type":48,"value":49},"text","Capacitor UIScene Migrator",{"type":43,"tag":51,"props":52,"children":53},"p",{},[54,56,63],{"type":48,"value":55},"Guides a Capacitor 8.4 → 8.5 iOS migration to the UIScene lifecycle. The\nCLI migrator (",{"type":43,"tag":57,"props":58,"children":60},"code",{"className":59},[],[61],{"type":48,"value":62},"npx cap migrate",{"type":48,"value":64},") handles projects that still match the\nCapacitor templates; this skill exists for everything else. It audits\nbefore editing, asks the developer where judgement is required, merges\ninto existing files rather than replacing them, and delegates the\nmechanical work to the CLI whenever the project shape allows.",{"type":43,"tag":51,"props":66,"children":67},{},[68,70,79],{"type":48,"value":69},"The canonical migration reference is the\n",{"type":43,"tag":71,"props":72,"children":76},"a",{"href":73,"rel":74},"https:\u002F\u002Fcapacitorjs.com\u002Fdocs\u002Fupdating\u002F8-5",[75],"nofollow",[77],{"type":48,"value":78},"8.4 → 8.5 migration guide",{"type":48,"value":80},".\nLink it whenever a step is left for the developer to do manually.",{"type":43,"tag":82,"props":83,"children":85},"h2",{"id":84},"when-to-use-this-skill",[86],{"type":48,"value":87},"When to Use This Skill",{"type":43,"tag":89,"props":90,"children":91},"ul",{},[92,98,110,131,136],{"type":43,"tag":93,"props":94,"children":95},"li",{},[96],{"type":48,"value":97},"Migrating a Capacitor 8.x iOS app to the UIScene lifecycle",{"type":43,"tag":93,"props":99,"children":100},{},[101,103,108],{"type":48,"value":102},"A project where ",{"type":43,"tag":57,"props":104,"children":106},{"className":105},[],[107],{"type":48,"value":62},{"type":48,"value":109}," reported a partial state and skipped",{"type":43,"tag":93,"props":111,"children":112},{},[113,115,121,123,129],{"type":48,"value":114},"An app with a hand-rolled ",{"type":43,"tag":57,"props":116,"children":118},{"className":117},[],[119],{"type":48,"value":120},"SceneDelegate.swift",{"type":48,"value":122}," or a customized\n",{"type":43,"tag":57,"props":124,"children":126},{"className":125},[],[127],{"type":48,"value":128},"AppDelegate.swift",{"type":48,"value":130}," (deep-link routing, third-party SDK forwarding)",{"type":43,"tag":93,"props":132,"children":133},{},[134],{"type":48,"value":135},"Auditing a Capacitor plugin repo for UIScene compatibility",{"type":43,"tag":93,"props":137,"children":138},{},[139],{"type":48,"value":140},"Diagnosing the Xcode \"CLIENT OF UIKIT REQUIRES UPDATE: This process\ndoes not adopt UIScene lifecycle\" warning in a Capacitor app",{"type":43,"tag":82,"props":142,"children":144},{"id":143},"when-not-to-use-this-skill",[145],{"type":48,"value":146},"When NOT to Use This Skill",{"type":43,"tag":89,"props":148,"children":149},{},[150,161,172,177,182],{"type":43,"tag":93,"props":151,"children":152},{},[153,155],{"type":48,"value":154},"Cordova-to-Capacitor plugin migration → ",{"type":43,"tag":57,"props":156,"children":158},{"className":157},[],[159],{"type":48,"value":160},"cordova-plugin-migrator",{"type":43,"tag":93,"props":162,"children":163},{},[164,166],{"type":48,"value":165},"Generating a new Capacitor plugin → ",{"type":43,"tag":57,"props":167,"children":169},{"className":168},[],[170],{"type":48,"value":171},"capacitor-plugin-generator",{"type":43,"tag":93,"props":173,"children":174},{},[175],{"type":48,"value":176},"Capacitor 9 or later migrations (this skill is 8.4 → 8.5 only)",{"type":43,"tag":93,"props":178,"children":179},{},[180],{"type":48,"value":181},"Android lifecycle work (UIScene is iOS only)",{"type":43,"tag":93,"props":183,"children":184},{},[185],{"type":48,"value":186},"General Capacitor debugging unrelated to the scene lifecycle",{"type":43,"tag":82,"props":188,"children":190},{"id":189},"prerequisites",[191],{"type":48,"value":192},"Prerequisites",{"type":43,"tag":89,"props":194,"children":195},{},[196,209,227],{"type":43,"tag":93,"props":197,"children":198},{},[199,201,207],{"type":48,"value":200},"A Capacitor 8.x project (app or plugin) with an ",{"type":43,"tag":57,"props":202,"children":204},{"className":203},[],[205],{"type":48,"value":206},"ios\u002F",{"type":48,"value":208}," platform or\niOS sources",{"type":43,"tag":93,"props":210,"children":211},{},[212,218,220,225],{"type":43,"tag":57,"props":213,"children":215},{"className":214},[],[216],{"type":48,"value":217},"@capacitor\u002Fcli",{"type":48,"value":219}," 8.5+ available for the ",{"type":43,"tag":57,"props":221,"children":223},{"className":222},[],[224],{"type":48,"value":62},{"type":48,"value":226}," handoff",{"type":43,"tag":93,"props":228,"children":229},{},[230],{"type":48,"value":231},"Xcode installed if the developer wants build verification",{"type":43,"tag":82,"props":233,"children":235},{"id":234},"what-changed-in-85-facts-the-audit-relies-on",[236],{"type":48,"value":237},"What Changed in 8.5 (facts the audit relies on)",{"type":43,"tag":51,"props":239,"children":240},{},[241],{"type":48,"value":242},"These determine what breaks and what does not. Do not soften them.",{"type":43,"tag":89,"props":244,"children":245},{},[246,283,357,407,443,461],{"type":43,"tag":93,"props":247,"children":248},{},[249,251,257,259,265,267,273,275,281],{"type":48,"value":250},"Scene adoption is opt-in. An app with no ",{"type":43,"tag":57,"props":252,"children":254},{"className":253},[],[255],{"type":48,"value":256},"UIApplicationSceneManifest",{"type":48,"value":258},"\nkeeps the AppDelegate path, which still works on the 8.5 core. iOS\nposts ",{"type":43,"tag":57,"props":260,"children":262},{"className":261},[],[263],{"type":48,"value":264},"UIScene.*",{"type":48,"value":266}," notifications even for legacy apps (compatibility\nscene), so the bridge's JS ",{"type":43,"tag":57,"props":268,"children":270},{"className":269},[],[271],{"type":48,"value":272},"resume",{"type":48,"value":274},"\u002F",{"type":43,"tag":57,"props":276,"children":278},{"className":277},[],[279],{"type":48,"value":280},"pause",{"type":48,"value":282}," events fire in both modes.",{"type":43,"tag":93,"props":284,"children":285},{},[286,288,294,296,302,304,310,311,317,319,325,326,332,334,340,342,348,349,355],{"type":48,"value":287},"Once the scene manifest exists, iOS stops calling\n",{"type":43,"tag":57,"props":289,"children":291},{"className":290},[],[292],{"type":48,"value":293},"application(_:open:options:)",{"type":48,"value":295},", ",{"type":43,"tag":57,"props":297,"children":299},{"className":298},[],[300],{"type":48,"value":301},"application(_:continue:)",{"type":48,"value":303},", and the\nfour foreground\u002Fbackground AppDelegate methods\n(",{"type":43,"tag":57,"props":305,"children":307},{"className":306},[],[308],{"type":48,"value":309},"applicationDidBecomeActive",{"type":48,"value":295},{"type":43,"tag":57,"props":312,"children":314},{"className":313},[],[315],{"type":48,"value":316},"applicationWillResignActive",{"type":48,"value":318},",\n",{"type":43,"tag":57,"props":320,"children":322},{"className":321},[],[323],{"type":48,"value":324},"applicationDidEnterBackground",{"type":48,"value":295},{"type":43,"tag":57,"props":327,"children":329},{"className":328},[],[330],{"type":48,"value":331},"applicationWillEnterForeground",{"type":48,"value":333},").\nCustom code in any of those silently stops running. The\n",{"type":43,"tag":57,"props":335,"children":337},{"className":336},[],[338],{"type":48,"value":339},"UIApplication",{"type":48,"value":341}," notifications still fire; ",{"type":43,"tag":57,"props":343,"children":345},{"className":344},[],[346],{"type":48,"value":347},"didFinishLaunching",{"type":48,"value":318},{"type":43,"tag":57,"props":350,"children":352},{"className":351},[],[353],{"type":48,"value":354},"applicationWillTerminate",{"type":48,"value":356},", push token registration, and the\nremote-notification callbacks stay on the AppDelegate.",{"type":43,"tag":93,"props":358,"children":359},{},[360,366,368,374,375,381,383,389,391,397,399,405],{"type":43,"tag":57,"props":361,"children":363},{"className":362},[],[364],{"type":48,"value":365},"SceneDelegateProxy",{"type":48,"value":367}," re-posts the legacy ",{"type":43,"tag":57,"props":369,"children":371},{"className":370},[],[372],{"type":48,"value":373},".capacitorOpenURL",{"type":48,"value":318},{"type":43,"tag":57,"props":376,"children":378},{"className":377},[],[379],{"type":48,"value":380},".capacitorOpenUniversalLink",{"type":48,"value":382},", and ",{"type":43,"tag":57,"props":384,"children":386},{"className":385},[],[387],{"type":48,"value":388},"CDVPluginHandleOpenURL",{"type":48,"value":390},"\nnotifications with the same payload shape, so existing observers keep\nworking. Cold-start URLs are delivered after the bridge view appears,\nso both ",{"type":43,"tag":57,"props":392,"children":394},{"className":393},[],[395],{"type":48,"value":396},"appUrlOpen",{"type":48,"value":398}," and ",{"type":43,"tag":57,"props":400,"children":402},{"className":401},[],[403],{"type":48,"value":404},"getLaunchUrl()",{"type":48,"value":406}," work on cold launch.",{"type":43,"tag":93,"props":408,"children":409},{},[410,412,418,419,425,427,433,435,441],{"type":48,"value":411},"New ",{"type":43,"tag":57,"props":413,"children":415},{"className":414},[],[416],{"type":48,"value":417},".capacitorSceneWillConnect",{"type":48,"value":295},{"type":43,"tag":57,"props":420,"children":422},{"className":421},[],[423],{"type":48,"value":424},".capacitorSceneOpenURL",{"type":48,"value":426},", and\n",{"type":43,"tag":57,"props":428,"children":430},{"className":429},[],[431],{"type":48,"value":432},".capacitorSceneOpenUniversalLink",{"type":48,"value":434}," notifications carry the ",{"type":43,"tag":57,"props":436,"children":438},{"className":437},[],[439],{"type":48,"value":440},"UIScene",{"type":48,"value":442},"\nas the object. They are only posted on 8.5+; plugins that also support\n8.4 must keep using the legacy names.",{"type":43,"tag":93,"props":444,"children":445},{},[446,452,453,459],{"type":43,"tag":57,"props":447,"children":449},{"className":448},[],[450],{"type":48,"value":451},"TmpViewController",{"type":48,"value":398},{"type":43,"tag":57,"props":454,"children":456},{"className":455},[],[457],{"type":48,"value":458},"CapacitorBridge.tmpWindow",{"type":48,"value":460}," were removed. Any\nreference is a build error on 8.5.",{"type":43,"tag":93,"props":462,"children":463},{},[464,466,472,474,480,482,488],{"type":48,"value":465},"The 8.5 templates create the window in code in\n",{"type":43,"tag":57,"props":467,"children":469},{"className":468},[],[470],{"type":48,"value":471},"scene(_:willConnectTo:)",{"type":48,"value":473},"; ",{"type":43,"tag":57,"props":475,"children":477},{"className":476},[],[478],{"type":48,"value":479},"Main.storyboard",{"type":48,"value":481}," no longer provides the\nroot view controller. Custom ",{"type":43,"tag":57,"props":483,"children":485},{"className":484},[],[486],{"type":48,"value":487},"CAPBridgeViewController",{"type":48,"value":489}," subclasses are\ninstantiated in the SceneDelegate, not set in the storyboard.",{"type":43,"tag":82,"props":491,"children":493},{"id":492},"agent-behavior",[494],{"type":48,"value":495},"Agent Behavior",{"type":43,"tag":89,"props":497,"children":498},{},[499,504,537,549,562,567],{"type":43,"tag":93,"props":500,"children":501},{},[502],{"type":48,"value":503},"Audit first, report second, edit last. Never modify a file before the\ndeveloper has seen the findings and confirmed.",{"type":43,"tag":93,"props":505,"children":506},{},[507,509,514,515,520,522,528,530,535],{"type":48,"value":508},"Never overwrite an existing ",{"type":43,"tag":57,"props":510,"children":512},{"className":511},[],[513],{"type":48,"value":120},{"type":48,"value":295},{"type":43,"tag":57,"props":516,"children":518},{"className":517},[],[519],{"type":48,"value":128},{"type":48,"value":521},",\nor ",{"type":43,"tag":57,"props":523,"children":525},{"className":524},[],[526],{"type":48,"value":527},"Info.plist",{"type":48,"value":529}," structure. Merge surgically per\n",{"type":43,"tag":71,"props":531,"children":533},{"href":532},"references\u002Fsurgical-merges.md",[534],{"type":48,"value":532},{"type":48,"value":536},".",{"type":43,"tag":93,"props":538,"children":539},{},[540,542,547],{"type":48,"value":541},"Prefer the CLI. If the project classifies as eligible (Phase 3), run\n",{"type":43,"tag":57,"props":543,"children":545},{"className":544},[],[546],{"type":48,"value":62},{"type":48,"value":548}," instead of editing files by hand.",{"type":43,"tag":93,"props":550,"children":551},{},[552,554,560],{"type":48,"value":553},"Ask, do not assume, at the decision points in Phase 6. Use\n",{"type":43,"tag":57,"props":555,"children":557},{"className":556},[],[558],{"type":48,"value":559},"AskUserQuestion",{"type":48,"value":561}," where available; otherwise ask in plain text and\nwait.",{"type":43,"tag":93,"props":563,"children":564},{},[565],{"type":48,"value":566},"Do not commit, stage, or push. Leave version control to the developer.",{"type":43,"tag":93,"props":568,"children":569},{},[570,572,577,578,583],{"type":48,"value":571},"On a plugin repo, never touch ",{"type":43,"tag":57,"props":573,"children":575},{"className":574},[],[576],{"type":48,"value":527},{"type":48,"value":295},{"type":43,"tag":57,"props":579,"children":581},{"className":580},[],[582],{"type":48,"value":128},{"type":48,"value":584},", or\nproject files. The plugin branch is audit and advice only.",{"type":43,"tag":82,"props":586,"children":588},{"id":587},"procedures",[589],{"type":48,"value":590},"Procedures",{"type":43,"tag":592,"props":593,"children":595},"h3",{"id":594},"phase-1-detect-repo-type",[596],{"type":48,"value":597},"Phase 1: Detect Repo Type",{"type":43,"tag":51,"props":599,"children":600},{},[601],{"type":48,"value":602},"Decide app vs. plugin before anything else.",{"type":43,"tag":89,"props":604,"children":605},{},[606,640],{"type":43,"tag":93,"props":607,"children":608},{},[609,615,617,623,625,631,633,638],{"type":43,"tag":610,"props":611,"children":612},"strong",{},[613],{"type":48,"value":614},"App",{"type":48,"value":616},": has ",{"type":43,"tag":57,"props":618,"children":620},{"className":619},[],[621],{"type":48,"value":622},"ios\u002FApp\u002FApp.xcodeproj",{"type":48,"value":624}," (or ",{"type":43,"tag":57,"props":626,"children":628},{"className":627},[],[629],{"type":48,"value":630},"capacitor.config.*",{"type":48,"value":632}," with an\n",{"type":43,"tag":57,"props":634,"children":636},{"className":635},[],[637],{"type":48,"value":206},{"type":48,"value":639}," platform directory).",{"type":43,"tag":93,"props":641,"children":642},{},[643,648,650,656,658,664,666,672,673,679,681,687,689,695,697,703],{"type":43,"tag":610,"props":644,"children":645},{},[646],{"type":48,"value":647},"Plugin",{"type":48,"value":649},": has a ",{"type":43,"tag":57,"props":651,"children":653},{"className":652},[],[654],{"type":48,"value":655},"Package.swift",{"type":48,"value":657}," or ",{"type":43,"tag":57,"props":659,"children":661},{"className":660},[],[662],{"type":48,"value":663},".podspec",{"type":48,"value":665}," depending on\nCapacitor, ",{"type":43,"tag":57,"props":667,"children":669},{"className":668},[],[670],{"type":48,"value":671},"CAPPlugin",{"type":48,"value":274},{"type":43,"tag":57,"props":674,"children":676},{"className":675},[],[677],{"type":48,"value":678},"CapacitorPlugin",{"type":48,"value":680}," subclasses in ",{"type":43,"tag":57,"props":682,"children":684},{"className":683},[],[685],{"type":48,"value":686},"ios\u002FSources",{"type":48,"value":688},"\nor ",{"type":43,"tag":57,"props":690,"children":692},{"className":691},[],[693],{"type":48,"value":694},"ios\u002FPlugin",{"type":48,"value":696},", and no ",{"type":43,"tag":57,"props":698,"children":700},{"className":699},[],[701],{"type":48,"value":702},"App\u002FApp.xcodeproj",{"type":48,"value":536},{"type":43,"tag":51,"props":705,"children":706},{},[707,709,714],{"type":48,"value":708},"Plugin repo → skip to Phase 10\n(",{"type":43,"tag":71,"props":710,"children":712},{"href":711},"references\u002Fplugin-repo-audit.md",[713],{"type":48,"value":711},{"type":48,"value":715},").",{"type":43,"tag":592,"props":717,"children":719},{"id":718},"phase-2-detect-package-manager-and-versions",[720],{"type":48,"value":721},"Phase 2: Detect Package Manager and Versions",{"type":43,"tag":89,"props":723,"children":724},{},[725,753],{"type":43,"tag":93,"props":726,"children":727},{},[728,730,736,738,743,745,751],{"type":48,"value":729},"Pods vs. SPM: ",{"type":43,"tag":57,"props":731,"children":733},{"className":732},[],[734],{"type":48,"value":735},"ios\u002FApp\u002FPodfile",{"type":48,"value":737}," → CocoaPods; ",{"type":43,"tag":57,"props":739,"children":741},{"className":740},[],[742],{"type":48,"value":655},{"type":48,"value":744}," or an SPM\nreference inside the Xcode project → SPM. This affects how ",{"type":43,"tag":57,"props":746,"children":748},{"className":747},[],[749],{"type":48,"value":750},"npx cap sync ios",{"type":48,"value":752}," behaves, not the SceneDelegate content: the 8.5 templates\nship one SceneDelegate for both.",{"type":43,"tag":93,"props":754,"children":755},{},[756,758,764,766,772],{"type":48,"value":757},"Check ",{"type":43,"tag":57,"props":759,"children":761},{"className":760},[],[762],{"type":48,"value":763},"@capacitor\u002Fios",{"type":48,"value":765}," version in ",{"type":43,"tag":57,"props":767,"children":769},{"className":768},[],[770],{"type":48,"value":771},"package.json",{"type":48,"value":773},". If below 8.5, the\ndependency update is part of the migration; the CLI migrator handles\nit, or update manually per the guide.",{"type":43,"tag":592,"props":775,"children":777},{"id":776},"phase-3-classify-the-project-state",[778],{"type":48,"value":779},"Phase 3: Classify the Project State",{"type":43,"tag":51,"props":781,"children":782},{},[783],{"type":48,"value":784},"Read the same three signals the CLI migrator uses:",{"type":43,"tag":786,"props":787,"children":788},"ol",{},[789,804,814],{"type":43,"tag":93,"props":790,"children":791},{},[792,797,799],{"type":43,"tag":57,"props":793,"children":795},{"className":794},[],[796],{"type":48,"value":527},{"type":48,"value":798}," contains ",{"type":43,"tag":57,"props":800,"children":802},{"className":801},[],[803],{"type":48,"value":256},{"type":43,"tag":93,"props":805,"children":806},{},[807,812],{"type":43,"tag":57,"props":808,"children":810},{"className":809},[],[811],{"type":48,"value":120},{"type":48,"value":813}," exists on disk in the app target directory\n(pbxproj registration is a separate concern, handled in Phase 7)",{"type":43,"tag":93,"props":815,"children":816},{},[817,822,823],{"type":43,"tag":57,"props":818,"children":820},{"className":819},[],[821],{"type":48,"value":128},{"type":48,"value":798},{"type":43,"tag":57,"props":824,"children":826},{"className":825},[],[827],{"type":48,"value":828},"UISceneConfiguration(name:",{"type":43,"tag":830,"props":831,"children":832},"table",{},[833,857],{"type":43,"tag":834,"props":835,"children":836},"thead",{},[837],{"type":43,"tag":838,"props":839,"children":840},"tr",{},[841,847,852],{"type":43,"tag":842,"props":843,"children":844},"th",{},[845],{"type":48,"value":846},"Signals present",{"type":43,"tag":842,"props":848,"children":849},{},[850],{"type":48,"value":851},"State",{"type":43,"tag":842,"props":853,"children":854},{},[855],{"type":48,"value":856},"Route",{"type":43,"tag":858,"props":859,"children":860},"tbody",{},[861,885,903],{"type":43,"tag":838,"props":862,"children":863},{},[864,870,875],{"type":43,"tag":865,"props":866,"children":867},"td",{},[868],{"type":48,"value":869},"0 of 3",{"type":43,"tag":865,"props":871,"children":872},{},[873],{"type":48,"value":874},"eligible",{"type":43,"tag":865,"props":876,"children":877},{},[878,880],{"type":48,"value":879},"Phases 4-6, then Phase 7a: hand off to ",{"type":43,"tag":57,"props":881,"children":883},{"className":882},[],[884],{"type":48,"value":62},{"type":43,"tag":838,"props":886,"children":887},{},[888,893,898],{"type":43,"tag":865,"props":889,"children":890},{},[891],{"type":48,"value":892},"3 of 3",{"type":43,"tag":865,"props":894,"children":895},{},[896],{"type":48,"value":897},"already migrated",{"type":43,"tag":865,"props":899,"children":900},{},[901],{"type":48,"value":902},"Audit only (Phase 4), then verify (Phase 9)",{"type":43,"tag":838,"props":904,"children":905},{},[906,911,916],{"type":43,"tag":865,"props":907,"children":908},{},[909],{"type":48,"value":910},"1-2 of 3",{"type":43,"tag":865,"props":912,"children":913},{},[914],{"type":48,"value":915},"partial",{"type":43,"tag":865,"props":917,"children":918},{},[919],{"type":48,"value":920},"Phases 4-6, then Phase 7b: surgical merges",{"type":43,"tag":51,"props":922,"children":923},{},[924],{"type":48,"value":925},"Every route audits before anything runs or changes; the routes differ\nonly in who applies the changes.",{"type":43,"tag":51,"props":927,"children":928},{},[929],{"type":48,"value":930},"The CLI warns and skips on partial states by design. Partial is exactly\nwhere this skill does its own editing.",{"type":43,"tag":592,"props":932,"children":934},{"id":933},"phase-4-audit-the-codebase",[935],{"type":48,"value":936},"Phase 4: Audit the Codebase",{"type":43,"tag":51,"props":938,"children":939},{},[940,942,947,949,955],{"type":48,"value":941},"Run the scans in\n",{"type":43,"tag":71,"props":943,"children":945},{"href":944},"references\u002Faudit-patterns.md",[946],{"type":48,"value":944},{"type":48,"value":948}," across the\napp's iOS sources and installed plugins (",{"type":43,"tag":57,"props":950,"children":952},{"className":951},[],[953],{"type":48,"value":954},"node_modules\u002F@capacitor*",{"type":48,"value":956},",\nplus any local plugin paths). Collect findings for:",{"type":43,"tag":89,"props":958,"children":959},{},[960,971,999,1004,1016,1035,1047],{"type":43,"tag":93,"props":961,"children":962},{},[963,969],{"type":43,"tag":57,"props":964,"children":966},{"className":965},[],[967],{"type":48,"value":968},"UIApplication.shared.applicationState",{"type":48,"value":970}," usage",{"type":43,"tag":93,"props":972,"children":973},{},[974,976,982,984,989,991,997],{"type":48,"value":975},"Custom ",{"type":43,"tag":57,"props":977,"children":979},{"className":978},[],[980],{"type":48,"value":981},"application(_:open:)",{"type":48,"value":983}," \u002F ",{"type":43,"tag":57,"props":985,"children":987},{"className":986},[],[988],{"type":48,"value":301},{"type":48,"value":990}," bodies\nbeyond the ",{"type":43,"tag":57,"props":992,"children":994},{"className":993},[],[995],{"type":48,"value":996},"ApplicationDelegateProxy",{"type":48,"value":998}," forwarder",{"type":43,"tag":93,"props":1000,"children":1001},{},[1002],{"type":48,"value":1003},"Custom code in AppDelegate lifecycle methods",{"type":43,"tag":93,"props":1005,"children":1006},{},[1007,1009,1014],{"type":48,"value":1008},"Existing ",{"type":43,"tag":57,"props":1010,"children":1012},{"className":1011},[],[1013],{"type":48,"value":120},{"type":48,"value":1015}," implementations and what they contain",{"type":43,"tag":93,"props":1017,"children":1018},{},[1019,1021,1027,1028,1033],{"type":48,"value":1020},"References to ",{"type":43,"tag":57,"props":1022,"children":1024},{"className":1023},[],[1025],{"type":48,"value":1026},"tmpWindow",{"type":48,"value":983},{"type":43,"tag":57,"props":1029,"children":1031},{"className":1030},[],[1032],{"type":48,"value":451},{"type":48,"value":1034}," (build errors on 8.5)",{"type":43,"tag":93,"props":1036,"children":1037},{},[1038,1040,1045],{"type":48,"value":1039},"Existing or partial ",{"type":43,"tag":57,"props":1041,"children":1043},{"className":1042},[],[1044],{"type":48,"value":256},{"type":48,"value":1046}," entries",{"type":43,"tag":93,"props":1048,"children":1049},{},[1050,1055,1056,1061],{"type":43,"tag":57,"props":1051,"children":1053},{"className":1052},[],[1054],{"type":48,"value":373},{"type":48,"value":983},{"type":43,"tag":57,"props":1057,"children":1059},{"className":1058},[],[1060],{"type":48,"value":380},{"type":48,"value":1062}," observers\n(informational: they keep working)",{"type":43,"tag":592,"props":1064,"children":1066},{"id":1065},"phase-5-present-findings-and-confirm",[1067],{"type":48,"value":1068},"Phase 5: Present Findings and Confirm",{"type":43,"tag":51,"props":1070,"children":1071},{},[1072],{"type":48,"value":1073},"Report every finding with file and line before touching anything.\nGroup as: blocks the build (tmpWindow\u002FTmpViewController), needs a\ndecision (custom delegate bodies, existing SceneDelegate), informational\n(observers, applicationState in plugins the developer does not own).\nAsk the developer to confirm proceeding.",{"type":43,"tag":592,"props":1075,"children":1077},{"id":1076},"phase-6-decision-points",[1078],{"type":48,"value":1079},"Phase 6: Decision Points",{"type":43,"tag":51,"props":1081,"children":1082},{},[1083],{"type":48,"value":1084},"Ask, at minimum:",{"type":43,"tag":786,"props":1086,"children":1087},{},[1088,1118,1142],{"type":43,"tag":93,"props":1089,"children":1090},{},[1091,1096,1098,1103,1104,1109,1111,1116],{"type":43,"tag":610,"props":1092,"children":1093},{},[1094],{"type":48,"value":1095},"Legacy URL handlers",{"type":48,"value":1097},": keep or remove\n",{"type":43,"tag":57,"props":1099,"children":1101},{"className":1100},[],[1102],{"type":48,"value":293},{"type":48,"value":983},{"type":43,"tag":57,"props":1105,"children":1107},{"className":1106},[],[1108],{"type":48,"value":301},{"type":48,"value":1110}," in\n",{"type":43,"tag":57,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":48,"value":128},{"type":48,"value":1117},"? They become dead code under scenes. Keeping them\nis harmless; removing them is cleaner. If the body contains custom\nlogic, it must move to the SceneDelegate either way. On the eligible\nroute, apply the answer after the CLI has run.",{"type":43,"tag":93,"props":1119,"children":1120},{},[1121,1132,1134,1140],{"type":43,"tag":610,"props":1122,"children":1123},{},[1124,1125,1130],{"type":48,"value":975},{"type":43,"tag":57,"props":1126,"children":1128},{"className":1127},[],[1129],{"type":48,"value":981},{"type":48,"value":1131}," body",{"type":48,"value":1133},": migrate it manually (the\ndeveloper moves the logic) or have the skill move it into\n",{"type":43,"tag":57,"props":1135,"children":1137},{"className":1136},[],[1138],{"type":48,"value":1139},"scene(_:openURLContexts:)",{"type":48,"value":1141}," alongside the proxy forwarder? Show the\nbody before asking. Skip this question when the body is\nforwarder-only per the audit test.",{"type":43,"tag":93,"props":1143,"children":1144},{},[1145,1150],{"type":43,"tag":610,"props":1146,"children":1147},{},[1148],{"type":48,"value":1149},"Existing SceneDelegate",{"type":48,"value":1151},": confirm each proposed insertion\n(missing forwarders, window setup) as a diff before applying.",{"type":43,"tag":592,"props":1153,"children":1155},{"id":1154},"phase-7a-eligible-cli-handoff",[1156],{"type":48,"value":1157},"Phase 7a: Eligible → CLI Handoff",{"type":43,"tag":51,"props":1159,"children":1160},{},[1161,1163,1169,1171,1177,1179,1185,1187,1192,1194,1199,1201,1206,1207,1212,1214,1220],{"type":48,"value":1162},"Verify the resolved CLI first: run ",{"type":43,"tag":57,"props":1164,"children":1166},{"className":1165},[],[1167],{"type":48,"value":1168},"npm install",{"type":48,"value":1170}," if ",{"type":43,"tag":57,"props":1172,"children":1174},{"className":1173},[],[1175],{"type":48,"value":1176},"node_modules",{"type":48,"value":1178}," is\nmissing, then ",{"type":43,"tag":57,"props":1180,"children":1182},{"className":1181},[],[1183],{"type":48,"value":1184},"npx cap --version",{"type":48,"value":1186},"; the UIScene migrator needs 8.5 or\nnewer. Then run ",{"type":43,"tag":57,"props":1188,"children":1190},{"className":1189},[],[1191],{"type":48,"value":62},{"type":48,"value":1193}," and interpret its output. It writes\n",{"type":43,"tag":57,"props":1195,"children":1197},{"className":1196},[],[1198],{"type":48,"value":120},{"type":48,"value":1200},", patches ",{"type":43,"tag":57,"props":1202,"children":1204},{"className":1203},[],[1205],{"type":48,"value":527},{"type":48,"value":398},{"type":43,"tag":57,"props":1208,"children":1210},{"className":1209},[],[1211],{"type":48,"value":128},{"type":48,"value":1213},",\nregisters the file in ",{"type":43,"tag":57,"props":1215,"children":1217},{"className":1216},[],[1218],{"type":48,"value":1219},"project.pbxproj",{"type":48,"value":1221},", warns on the scan patterns from\nPhase 4, and links the migration guide. Confirm each step's log line;\nif the CLI skipped a step (file existed, partial state raced in),\nfall through to Phase 7b for that step only.",{"type":43,"tag":592,"props":1223,"children":1225},{"id":1224},"phase-7b-partial-or-hand-rolled-surgical-merges",[1226],{"type":48,"value":1227},"Phase 7b: Partial or Hand-Rolled → Surgical Merges",{"type":43,"tag":51,"props":1229,"children":1230},{},[1231,1233,1237],{"type":48,"value":1232},"Apply only the missing pieces, per\n",{"type":43,"tag":71,"props":1234,"children":1235},{"href":532},[1236],{"type":48,"value":532},{"type":48,"value":1238},":",{"type":43,"tag":89,"props":1240,"children":1241},{},[1242,1261,1281,1308],{"type":43,"tag":93,"props":1243,"children":1244},{},[1245,1247,1252,1254,1259],{"type":48,"value":1246},"Missing manifest → merge ",{"type":43,"tag":57,"props":1248,"children":1250},{"className":1249},[],[1251],{"type":48,"value":256},{"type":48,"value":1253}," into\n",{"type":43,"tag":57,"props":1255,"children":1257},{"className":1256},[],[1258],{"type":48,"value":527},{"type":48,"value":1260},", preserving existing keys",{"type":43,"tag":93,"props":1262,"children":1263},{},[1264,1266,1272,1274,1279],{"type":48,"value":1265},"Missing ",{"type":43,"tag":57,"props":1267,"children":1269},{"className":1268},[],[1270],{"type":48,"value":1271},"configurationForConnecting",{"type":48,"value":1273}," → insert into the existing\n",{"type":43,"tag":57,"props":1275,"children":1277},{"className":1276},[],[1278],{"type":48,"value":128},{"type":48,"value":1280}," before the class's closing brace, displacing\nnothing",{"type":43,"tag":93,"props":1282,"children":1283},{},[1284,1286,1291,1293,1298,1300,1306],{"type":48,"value":1285},"Missing or incomplete ",{"type":43,"tag":57,"props":1287,"children":1289},{"className":1288},[],[1290],{"type":48,"value":120},{"type":48,"value":1292}," → create from\n",{"type":43,"tag":71,"props":1294,"children":1296},{"href":1295},"references\u002Fscene-delegate-template.md",[1297],{"type":48,"value":1295},{"type":48,"value":1299},",\nor add the missing ",{"type":43,"tag":57,"props":1301,"children":1303},{"className":1302},[],[1304],{"type":48,"value":1305},"SceneDelegateProxy.shared",{"type":48,"value":1307}," forwarders to the\nexisting one, preserving all custom logic",{"type":43,"tag":93,"props":1309,"children":1310},{},[1311,1313,1318],{"type":48,"value":1312},"New file → register in ",{"type":43,"tag":57,"props":1314,"children":1316},{"className":1315},[],[1317],{"type":48,"value":1219},{"type":48,"value":1319}," (Xcode does this when the\nfile is added through the IDE; otherwise follow the reference)",{"type":43,"tag":592,"props":1321,"children":1323},{"id":1322},"phase-8-sync-and-build",[1324],{"type":48,"value":1325},"Phase 8: Sync and Build",{"type":43,"tag":51,"props":1327,"children":1328},{},[1329,1331,1336,1338,1343],{"type":48,"value":1330},"Run ",{"type":43,"tag":57,"props":1332,"children":1334},{"className":1333},[],[1335],{"type":48,"value":750},{"type":48,"value":1337},". If Xcode is available, build the app target and\nsurface any errors (most commonly leftover ",{"type":43,"tag":57,"props":1339,"children":1341},{"className":1340},[],[1342],{"type":48,"value":1026},{"type":48,"value":1344}," references).",{"type":43,"tag":592,"props":1346,"children":1348},{"id":1347},"phase-9-verification-checklist",[1349],{"type":48,"value":1350},"Phase 9: Verification Checklist",{"type":43,"tag":51,"props":1352,"children":1353},{},[1354],{"type":48,"value":1355},"Walk the developer through, linking the guide for detail:",{"type":43,"tag":89,"props":1357,"children":1358},{},[1359,1364,1382,1402],{"type":43,"tag":93,"props":1360,"children":1361},{},[1362],{"type":48,"value":1363},"App launches to the web view",{"type":43,"tag":93,"props":1365,"children":1366},{},[1367,1369,1374,1375,1380],{"type":48,"value":1368},"Background and foreground the app: JS ",{"type":43,"tag":57,"props":1370,"children":1372},{"className":1371},[],[1373],{"type":48,"value":272},{"type":48,"value":274},{"type":43,"tag":57,"props":1376,"children":1378},{"className":1377},[],[1379],{"type":48,"value":280},{"type":48,"value":1381}," fire (they are\nscoped to the app's scene now)",{"type":43,"tag":93,"props":1383,"children":1384},{},[1385,1387,1392,1394,1400],{"type":48,"value":1386},"Custom URL scheme: cold launch and warm open both deliver the URL\n(",{"type":43,"tag":57,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":48,"value":396},{"type":48,"value":1393}," listener and ",{"type":43,"tag":57,"props":1395,"children":1397},{"className":1396},[],[1398],{"type":48,"value":1399},"App.getLaunchUrl()",{"type":48,"value":1401},")",{"type":43,"tag":93,"props":1403,"children":1404},{},[1405],{"type":48,"value":1406},"Universal link, if the app uses them (requires an associated domain)",{"type":43,"tag":592,"props":1408,"children":1410},{"id":1409},"phase-10-plugin-repo-branch",[1411],{"type":48,"value":1412},"Phase 10: Plugin Repo Branch",{"type":43,"tag":51,"props":1414,"children":1415},{},[1416,1418,1422],{"type":48,"value":1417},"No app-level files to patch. Audit the plugin's Swift per\n",{"type":43,"tag":71,"props":1419,"children":1420},{"href":711},[1421],{"type":48,"value":711},{"type":48,"value":1423}," and\nreport: lifecycle assumptions that break under scenes, APIs removed in\n8.5, and the compatibility rules for supporting 8.4 and 8.5 with one\nplugin version. Apply code changes only if the developer asks, and only\nin the plugin's own sources.",{"type":43,"tag":82,"props":1425,"children":1427},{"id":1426},"best-practices",[1428],{"type":48,"value":1429},"Best Practices",{"type":43,"tag":592,"props":1431,"children":1433},{"id":1432},"do",[1434],{"type":48,"value":1435},"DO",{"type":43,"tag":89,"props":1437,"children":1438},{},[1439,1444,1449,1454],{"type":43,"tag":93,"props":1440,"children":1441},{},[1442],{"type":48,"value":1443},"Show diffs before applying them",{"type":43,"tag":93,"props":1445,"children":1446},{},[1447],{"type":48,"value":1448},"Keep every finding tied to a file and line",{"type":43,"tag":93,"props":1450,"children":1451},{},[1452],{"type":48,"value":1453},"Re-run the Phase 3 classification after edits to confirm the project\nreads as fully migrated",{"type":43,"tag":93,"props":1455,"children":1456},{},[1457],{"type":48,"value":1458},"Tell plugin authors to keep the legacy notification names while they\nsupport 8.4",{"type":43,"tag":592,"props":1460,"children":1462},{"id":1461},"dont",[1463],{"type":48,"value":1464},"DON'T",{"type":43,"tag":89,"props":1466,"children":1467},{},[1468,1473,1485,1490],{"type":43,"tag":93,"props":1469,"children":1470},{},[1471],{"type":48,"value":1472},"Overwrite user code, ever",{"type":43,"tag":93,"props":1474,"children":1475},{},[1476,1478,1483],{"type":48,"value":1477},"Rewrite third-party plugin code under ",{"type":43,"tag":57,"props":1479,"children":1481},{"className":1480},[],[1482],{"type":48,"value":1176},{"type":48,"value":1484}," (report it;\nthe fix belongs upstream)",{"type":43,"tag":93,"props":1486,"children":1487},{},[1488],{"type":48,"value":1489},"Duplicate the CLI's work by hand-editing an eligible project",{"type":43,"tag":93,"props":1491,"children":1492},{},[1493],{"type":48,"value":1494},"Promise universal-link behavior without an associated domain to test",{"type":43,"tag":82,"props":1496,"children":1498},{"id":1497},"error-handling",[1499],{"type":48,"value":1500},"Error Handling",{"type":43,"tag":89,"props":1502,"children":1503},{},[1504,1514,1524,1550],{"type":43,"tag":93,"props":1505,"children":1506},{},[1507,1512],{"type":43,"tag":57,"props":1508,"children":1510},{"className":1509},[],[1511],{"type":48,"value":62},{"type":48,"value":1513}," warns \"partial state\" → expected; this skill's\nPhase 7b exists for that. Do not reset the project without asking.",{"type":43,"tag":93,"props":1515,"children":1516},{},[1517,1522],{"type":43,"tag":57,"props":1518,"children":1520},{"className":1519},[],[1521],{"type":48,"value":1219},{"type":48,"value":1523}," edits fail or the project no longer opens → revert\nthe pbxproj change and register the file through Xcode instead.",{"type":43,"tag":93,"props":1525,"children":1526},{},[1527,1529,1534,1535,1540,1542,1548],{"type":48,"value":1528},"Build fails on ",{"type":43,"tag":57,"props":1530,"children":1532},{"className":1531},[],[1533],{"type":48,"value":1026},{"type":48,"value":983},{"type":43,"tag":57,"props":1536,"children":1538},{"className":1537},[],[1539],{"type":48,"value":451},{"type":48,"value":1541}," → the references\nmust be deleted; there is no 8.5 replacement (the bridge's\n",{"type":43,"tag":57,"props":1543,"children":1545},{"className":1544},[],[1546],{"type":48,"value":1547},"viewController",{"type":48,"value":1549}," is the presentation anchor).",{"type":43,"tag":93,"props":1551,"children":1552},{},[1553,1559],{"type":43,"tag":57,"props":1554,"children":1556},{"className":1555},[],[1557],{"type":48,"value":1558},"SceneDelegate",{"type":48,"value":1560}," exists but the app shows a black screen → the\ndelegate neither creates a window nor lets a storyboard do it; add\nthe window setup from the template.",{"type":43,"tag":82,"props":1562,"children":1564},{"id":1563},"related-skills",[1565],{"type":48,"value":1566},"Related Skills",{"type":43,"tag":89,"props":1568,"children":1569},{},[1570,1580],{"type":43,"tag":93,"props":1571,"children":1572},{},[1573,1578],{"type":43,"tag":57,"props":1574,"children":1576},{"className":1575},[],[1577],{"type":48,"value":160},{"type":48,"value":1579},": Cordova plugin to Capacitor migration",{"type":43,"tag":93,"props":1581,"children":1582},{},[1583,1588],{"type":43,"tag":57,"props":1584,"children":1586},{"className":1585},[],[1587],{"type":48,"value":171},{"type":48,"value":1589},": new Capacitor plugin scaffolds",{"type":43,"tag":82,"props":1591,"children":1593},{"id":1592},"references",[1594],{"type":48,"value":1595},"References",{"type":43,"tag":830,"props":1597,"children":1598},{},[1599,1615],{"type":43,"tag":834,"props":1600,"children":1601},{},[1602],{"type":43,"tag":838,"props":1603,"children":1604},{},[1605,1610],{"type":43,"tag":842,"props":1606,"children":1607},{},[1608],{"type":48,"value":1609},"File",{"type":43,"tag":842,"props":1611,"children":1612},{},[1613],{"type":48,"value":1614},"Purpose",{"type":43,"tag":858,"props":1616,"children":1617},{},[1618,1633,1648,1663],{"type":43,"tag":838,"props":1619,"children":1620},{},[1621,1628],{"type":43,"tag":865,"props":1622,"children":1623},{},[1624],{"type":43,"tag":71,"props":1625,"children":1626},{"href":1295},[1627],{"type":48,"value":1295},{"type":43,"tag":865,"props":1629,"children":1630},{},[1631],{"type":48,"value":1632},"The 8.5 SceneDelegate template and custom-subclass variant",{"type":43,"tag":838,"props":1634,"children":1635},{},[1636,1643],{"type":43,"tag":865,"props":1637,"children":1638},{},[1639],{"type":43,"tag":71,"props":1640,"children":1641},{"href":944},[1642],{"type":48,"value":944},{"type":43,"tag":865,"props":1644,"children":1645},{},[1646],{"type":48,"value":1647},"Exact scan patterns with commands",{"type":43,"tag":838,"props":1649,"children":1650},{},[1651,1658],{"type":43,"tag":865,"props":1652,"children":1653},{},[1654],{"type":43,"tag":71,"props":1655,"children":1656},{"href":532},[1657],{"type":48,"value":532},{"type":43,"tag":865,"props":1659,"children":1660},{},[1661],{"type":48,"value":1662},"Merge recipes for partial and hand-rolled projects",{"type":43,"tag":838,"props":1664,"children":1665},{},[1666,1673],{"type":43,"tag":865,"props":1667,"children":1668},{},[1669],{"type":43,"tag":71,"props":1670,"children":1671},{"href":711},[1672],{"type":48,"value":711},{"type":43,"tag":865,"props":1674,"children":1675},{},[1676],{"type":48,"value":1677},"Plugin-author branch: audit and compatibility rules",{"items":1679,"total":1728},[1680,1697,1709,1716],{"slug":1681,"name":1681,"fn":1682,"description":1683,"org":1684,"tags":1685,"stars":26,"repoUrl":27,"updatedAt":1696},"build-actions-generator","configure OutSystems ODC Capacitor builds","Generates OutSystems Developer Cloud (ODC) build action JSON files that configure Capacitor mobile plugin builds for Android and iOS. Produces correct JSON with platform-specific actions, input variables, and conditional logic. Use when a developer says \"create a build action for my ODC plugin\", \"generate a buildAction.json file\", \"set up Gradle or plist build actions for a Capacitor or Cordova plugin\", \"configure AndroidManifest for ODC build\", or \"scaffold ODC native build configuration\". If the target platform is ambiguous, still generate and note that build actions only apply to ODC — they have no effect in standalone Capacitor apps. Do not use when the developer explicitly mentions Cordova apps, O11, Cordova extensibility configurations, MABS versions prior to 12, or uploading and registering the JSON in ODC Studio.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1686,1689,1690,1693,1694,1695],{"name":1687,"slug":1688,"type":16},"Android","android",{"name":21,"slug":22,"type":16},{"name":1691,"slug":1692,"type":16},"Deployment","deployment",{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":18,"slug":19,"type":16},"2026-07-12T07:37:41.801053",{"slug":171,"name":171,"fn":1698,"description":1699,"org":1700,"tags":1701,"stars":26,"repoUrl":27,"updatedAt":1708},"generate Capacitor plugin scaffolds","Generates new Capacitor plugin scaffolds and first-pass implementations from conversational requirements or a structured YAML input contract. Use when a user says \"generate a Capacitor plugin\", \"create a Capacitor plugin scaffold\", \"build a native plugin for iOS and Android\", \"turn this plugin plan into Capacitor code\", or \"use this YAML contract to generate a plugin\". Do not use for analyzing Cordova source, migrating whole apps, installing existing plugins, upgrading Capacitor versions, or publishing production-ready code without human review.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1702,1703,1706,1707],{"name":21,"slug":22,"type":16},{"name":1704,"slug":1705,"type":16},"Engineering","engineering",{"name":9,"slug":8,"type":16},{"name":18,"slug":19,"type":16},"2026-07-12T07:37:44.39093",{"slug":4,"name":4,"fn":5,"description":6,"org":1710,"tags":1711,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1712,1713,1714,1715],{"name":21,"slug":22,"type":16},{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":18,"slug":19,"type":16},{"slug":160,"name":160,"fn":1717,"description":1718,"org":1719,"tags":1720,"stars":26,"repoUrl":27,"updatedAt":1727},"migrate Cordova projects to Capacitor","End-to-end Cordova-to-Capacitor migration orchestrator. Analyzes the Cordova plugin (plugin.xml, native iOS\u002FAndroid source, JS bridge, hooks, third-party dependencies), produces a structured migration plan as YAML conforming to capacitor-plugin-generator's input contract, invokes the generator skill in structured mode at a user checkpoint, then consolidates intermediate notes into a single MIGRATION.md. Use when the user says \"migrate this cordova plugin\", \"convert cordova to capacitor\", \"assess migration feasibility\", \"what blocks this migration\", \"port this cordova plugin to capacitor\", or \"estimate the effort to migrate\". Do not use for generating new Capacitor plugins from scratch (use capacitor-plugin-generator instead), debugging runtime issues in an already-migrated plugin, or migrating an entire Cordova application; scope is plugin-level only.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1721,1722,1723,1724,1725,1726],{"name":1687,"slug":1688,"type":16},{"name":21,"slug":22,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":18,"slug":19,"type":16},"2026-07-12T07:37:43.055071",4,{"items":1730,"total":1728},[1731,1740,1747,1754],{"slug":1681,"name":1681,"fn":1682,"description":1683,"org":1732,"tags":1733,"stars":26,"repoUrl":27,"updatedAt":1696},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1734,1735,1736,1737,1738,1739],{"name":1687,"slug":1688,"type":16},{"name":21,"slug":22,"type":16},{"name":1691,"slug":1692,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":18,"slug":19,"type":16},{"slug":171,"name":171,"fn":1698,"description":1699,"org":1741,"tags":1742,"stars":26,"repoUrl":27,"updatedAt":1708},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1743,1744,1745,1746],{"name":21,"slug":22,"type":16},{"name":1704,"slug":1705,"type":16},{"name":9,"slug":8,"type":16},{"name":18,"slug":19,"type":16},{"slug":4,"name":4,"fn":5,"description":6,"org":1748,"tags":1749,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1750,1751,1752,1753],{"name":21,"slug":22,"type":16},{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":18,"slug":19,"type":16},{"slug":160,"name":160,"fn":1717,"description":1718,"org":1755,"tags":1756,"stars":26,"repoUrl":27,"updatedAt":1727},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1757,1758,1759,1760,1761,1762],{"name":1687,"slug":1688,"type":16},{"name":21,"slug":22,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":18,"slug":19,"type":16}]