[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-ionic-build-actions-generator":3,"mdc--uv6r5s-key":40,"related-repo-ionic-build-actions-generator":2678,"related-org-ionic-build-actions-generator":2716},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":30,"repoUrl":31,"updatedAt":32,"license":33,"forks":34,"topics":35,"repo":36,"sourceUrl":38,"mdContent":39},"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},"ionic","Ionic","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fionic.png","ionic-team",[13,17,20,23,26,29],{"name":14,"slug":15,"type":16},"Android","android","tag",{"name":18,"slug":19,"type":16},"iOS","ios",{"name":21,"slug":22,"type":16},"Mobile","mobile",{"name":24,"slug":25,"type":16},"Capacitor","capacitor",{"name":27,"slug":28,"type":16},"Deployment","deployment",{"name":9,"slug":8,"type":16},14,"https:\u002F\u002Fgithub.com\u002Fionic-team\u002Fcapacitor-skills","2026-07-12T07:37:41.801053",null,1,[],{"repoUrl":31,"stars":30,"forks":34,"topics":37,"description":33},[],"https:\u002F\u002Fgithub.com\u002Fionic-team\u002Fcapacitor-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fbuild-actions-generator","---\nname: build-actions-generator\ndescription: >-\n  Generates OutSystems Developer Cloud (ODC) build action JSON files that\n  configure Capacitor mobile plugin builds for Android and iOS. Produces\n  correct JSON with platform-specific actions, input variables, and conditional\n  logic. Use when a developer says \"create a build action for my ODC plugin\",\n  \"generate a buildAction.json file\", \"set up Gradle or plist build actions for\n  a Capacitor or Cordova plugin\", \"configure AndroidManifest for ODC build\", or\n  \"scaffold ODC native build configuration\". If the target platform is\n  ambiguous, still generate and note that build actions only apply to ODC —\n  they have no effect in standalone Capacitor apps. Do not use when the\n  developer explicitly mentions Cordova apps, O11, Cordova extensibility\n  configurations, MABS versions prior to 12, or uploading and registering the\n  JSON in ODC Studio.\nmetadata:\n  author: ionic\n  source: https:\u002F\u002Fgithub.com\u002Fionic-team\u002Fcapacitor-skills\n---\n\n# ODC Build Actions Generator\n\nGenerates `buildAction.json` for ODC Mobile Libraries (Capacitor and Cordova plugins) and ODC apps targeting Android and iOS via MABS 12+.\n\n\n## When to Use\n\n✅ **Use this skill when:**\n\n- Generating a `buildAction.json` file for an ODC Mobile Library (Capacitor or Cordova plugin).\n- Generating a `buildAction.json` file for an ODC app that requires native build configuration.\n- Generating build actions for a Cordova plugin being adapted for ODC (Capacitor-based) deployment.\n- Configuring `AndroidManifest.xml`, Gradle files, or XML resources for Android.\n- Configuring `Info.plist`, entitlements, or display name for iOS.\n- Defining input variables (string, number, boolean) and conditional logic.\n- Scaffolding build actions for both platforms from a plugin's native requirements.\n- Invoked with a plugin path argument or from within a Capacitor or Cordova plugin directory.\n\n❌ **Do NOT use this skill for:**\n\n- Uploading or referencing the JSON in ODC Studio\u002FPortal (Steps 2–3 — see manual guidance).\n- Cordova extensibility configurations or O11 extensibility JSON.\n- Cordova app builds, O11 builds, or MABS versions prior to 12 — build actions only apply to Capacitor apps on ODC (MABS 12+).\n- App-level build configuration that lives outside the build action JSON.\n- Publishing or testing the plugin (Step 4 — developer responsibility).\n\n---\n\n## End-to-End Process\n\nThis skill handles **Step 1 only**. Steps 2–4 require manual action.\n\n| Step | Owner | What |\n|------|-------|------|\n| **1. Generate JSON** | This skill | Create `buildAction.json` with all required platform actions |\n| **2. Upload JSON** | Developer | Add the file to the plugin\u002Flibrary in ODC Studio → Resources, and then reference it Extensibility tab, creating Extensibility Settings for any variables. |\n| **3. Link in Portal** | Developer | If the build action has parameters, provide values in ODC Portal → Mobile Distribution tab → Extensibility settings |\n| **4. Publish & test** | Developer | Test a mobile build using MABS 12 (Capacitor) or later |\n\n---\n\n## JSON File Structure\n\n**Output location:** Two files are written to the `build-actions\u002F` folder at\nthe plugin root:\n- `build-actions\u002FbuildAction.json` — the build action configuration\n- `build-actions\u002FREADME.md` — human-readable documentation (see Generation Guidelines step 5)\n\n**Always create `build-actions\u002F` at the top level of the directory provided\n(or the current working directory if no path argument was given).** Never\ncreate it inside a subdirectory such as `plugin\u002F`, `android\u002F`, or `ios\u002F`,\neven when scanning source files that live in those subdirectories. If the\nplugin repo has a nested structure (e.g. `plugin\u002Fandroid\u002F`, `plugin\u002Fios\u002F`),\nthe output still goes at the repo root: `build-actions\u002FbuildAction.json`.\n\n```json\n{\n  \"variables\": { },       \u002F\u002F optional — input parameters for the build action\n  \"platforms\": {\n    \"android\": { },       \u002F\u002F optional — Android-specific actions\n    \"ios\": { }            \u002F\u002F optional — iOS-specific actions\n  }\n}\n```\n\n**File naming:** Use camelCase without spaces.\n\n✅ `buildAction.json`, `pushNotifications.json`, `cameraPlugin.json`\n❌ `build action.json`, `Build_Action.json`\n\nAt least one of `android` or `ios` must be present under `platforms`.\n\n---\n\n## Variables & Conditions\n\nIf the build action uses variables or conditions, read **`references\u002Fvariables-and-conditions.md`** for full syntax and examples.\n\n- **Variables** (`\"variables\"` key) — typed inputs (`string`, `number`, `boolean`) declared by the plugin developer; consuming apps supply values via the extensibility configuration `parameters` block. Always include a `default` unless the value is genuinely required; without one the build fails if unset.\n- **Platform-specific variants** — if the same logical value (e.g. an App ID, API key) is used on both Android and iOS but is typically distinct per platform, expose **separate variables** with `_ANDROID` and `_IOS` suffixes (e.g. `ADMOB_APP_ID_ANDROID`, `ADMOB_APP_ID_IOS`). Do not merge them into a single shared variable — the developer must be able to configure each platform independently.\n- **Conditions** — add a `condition` field to any action entry (except `displayName`, `productName`, and `appName`) to conditionally skip it; for syntax and operators, see the reference file.\n\n> If variables are defined, read **`references\u002Fextensibility-configuration.md`** for how `parameters` in the extensibility configuration supplies values for variables declared in `buildAction.json`. When a library and its consuming app both define build actions, the library's runs first.\n\n---\n\n## Android Actions\n\nIf targeting Android, read **`references\u002Fandroid-build-actions.md`** for full action schemas and examples.\n\nAvailable actions:\n\n- `appName` — Set the Android app name (string, no condition support)\n- `manifest` — Modify `AndroidManifest.xml` (set attributes, merge or inject XML)\n- `gradle` — Patch Gradle build files (insert or replace at target DSL path)\n- `res` — Create resource files under the `res\u002F` folder\n- `json` — Modify JSON files (`set` or `merge`)\n- `xml` — Modify arbitrary XML resource files\n- `copy` — Copy files, directories, or URLs into the project\n- `code` — Add or patch native Android (Java\u002FKotlin) source files (`source`+`targetDir`, `file`+`target`+`replace`, or `file`+`patchFile`)\n- `tar` — Apply tar operations on project files\n\n---\n\n## iOS Actions\n\nIf targeting iOS, read **`references\u002Fios-build-actions.md`** for full action schemas and examples.\n\nAvailable actions:\n\n- `displayName` — Set app display name shown on the home screen (no condition support)\n- `productName` — Set product name shown in App Store (no condition support)\n- `buildSettings` — Set Xcode build settings as key-value pairs\n- `buildPhases` — Add or replace custom shell script build phases\n- `plist` — Modify `Info.plist` or other plist files (replace or merge entries)\n- `xcprivacy` — Update `PrivacyInfo.xcprivacy`\n- `entitlements` — Add or modify entitlements (**object**, not array)\n- `frameworks` — Add system or custom frameworks to the Xcode project\n- `json` — Modify JSON files (`set` or `merge`)\n- `xml` — Modify arbitrary XML files\n- `copy` — Copy files, directories, or URLs into the project\n- `strings` — Update `.strings` localization files\n- `xcconfig` — Update `.xcconfig` build configuration files\n- `code` — Add or patch native iOS (Swift\u002FObjective-C) source files (`source`+`compilerFlags`, `file`+`target`+`replace`, or `file`+`patchFile`)\n- `tar` — Apply tar operations on project files\n\n---\n\n## Generation Guidelines\n\n### 1. Read plugin input signals\n\nPlugin root is the path argument if one was given, otherwise the current directory. Before asking the developer any questions, check for existing signals in the plugin:\n\n- If `input-contract.yaml` exists at the plugin root, read it against the full\n  `capacitor-plugin-generator\u002Freferences\u002Finput-contract.md` schema and extract\n  the following relevant sections:\n  - `migration.hooks` (`tier_1` \u002F `tier_2` \u002F `tier_3`) — hook classification\n    for build-action derivation.\n  - `dependencies.android.gradle` and\n    `dependencies.ios.{cocoapods,spm,system_frameworks}` — dependency-based\n    actions (Gradle patches, framework entries).\n  - `permissions.android` and `permissions.ios` — permission actions\n    (manifest `\u003Cuses-permission>`, plist usage descriptions).\n  - `plugin.name` — for the README title.\n  - All other fields (`api.methods`, `api.types`, `api.events`, etc.) are\n    irrelevant — ignore silently.\n- **Always also scan plugin source directly**, even when the contract is\n  present. The contract is a starting point; source scanning catches signals\n  the contract may not capture or may be stale on:\n  - **Cordova plugins:** parse `plugin.xml` — read **`references\u002Fcordova-plugin-scanning.md`** for the full element-to-action mapping and hook classification guide.\n  - **Capacitor plugins:** scan plugin documentation, `package.json`, and native source files (Java\u002FKotlin and Swift\u002FObjective-C) — read **`references\u002Fcapacitor-plugin-scanning.md`** for the full scanning guide.\n- When invoked as part of the `cordova-plugin-migrator` ODC flow (Phase 11a),\n  the output (`build-actions\u002F`) is written to the **Capacitor plugin\n  directory**, not the Cordova source tree. The `cordova-plugin-migrator`\n  supplies the Capacitor plugin path as the working directory or argument.\n\n### 2. Gather requirements\n\nAsk the developer (or infer from context):\n\n- What native capabilities does the plugin need? (camera, location, push, Bluetooth, etc.)\n- Which platforms are targeted: Android only, iOS only, or both?\n- Are there runtime configuration values the developer should control? (→ variables)\n- Are any actions conditional on those values?\n\n### 3. Map requirements to actions\n\n| Native requirement | Android action | iOS action |\n|--------------------|----------------|------------|\n| Runtime permission | `manifest` inject `\u003Cuses-permission>` | `plist` usage description key |\n| Custom URL scheme | `manifest` merge intent-filter | `plist` `CFBundleURLTypes` |\n| Custom app attribute | `manifest` attrs | — |\n| Native dependency | `gradle` replace | — |\n| Push notifications | `manifest` merge + `gradle` | `entitlements` `aps-environment` |\n| App groups | — | `entitlements` `com.apple.security.application-groups` |\n| Custom display name | — | `displayName` |\n| Custom native code | `code` inject\u002Freplace | `code` inject\u002Freplace |\n\n> If a hook or element does not map clearly to any action listed above, read **`references\u002Fcommon-scenarios.md`** for patterns that appear unmappable but have correct build action equivalents.\n\n### 4. Generate the JSON\n\n- Filename: camelCase, no spaces (e.g., `buildAction.json`)\n- Only include platforms that have actual actions\n- Use `$VAR_NAME` substitution for developer-controlled values\n- Include a `default` on variables unless the value is genuinely required — without one, the build fails if neither the plugin library nor the consuming app supplies the variable value in the extensibility configuration `parameters`\n- Add `condition` only when an action should be conditionally skipped\n- Prefer `merge` over `inject` in `manifest` to avoid duplicate entries\n- Output valid, well-formatted JSON\n- The `code` action has **platform-specific file path conventions** — iOS targets\n  Swift\u002FObjective-C files (e.g., `App\u002FAppDelegate.swift`); Android targets\n  Java\u002FKotlin files (e.g., `app\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fexample\u002FApp.java`). Do not\n  mix conventions between platforms.\n- **Prefer config-level actions over `code`** — `manifest`, `gradle`, `plist`,\n  `xml`, and `entitlements` cover most native requirements without touching\n  source files. Only generate a `code` action when no config-level alternative\n  exists. If you do, use `file`+`target`+`replace`; never use `patchFile` — it\n  is unreliable in ODC builds. If the change cannot be expressed as a simple\n  string replacement, briefly tell the user the approach is not reliable in ODC\n  and suggest a Capacitor hook as the alternative (out of scope for this skill).\n  Do not explain ODC internals.\n- **Avoid `tar` and `copy` when the source file is user-supplied at runtime** —\n  these actions are only reliable with hardcoded paths inside the plugin bundle\n  or external URLs. If the use case requires user-provided files, briefly tell\n  the user to consider a Capacitor hook instead. Do not explain ODC internals.\n\nAfter writing the JSON file, validate its syntax before proceeding:\n\n1. Tell the user: *\"Validating JSON syntax...\"*\n2. Try `python3 -m json.tool build-actions\u002FbuildAction.json > \u002Fdev\u002Fnull` — use\n   this if `python3` is available.\n3. If `python3` is not available, try `jq empty build-actions\u002FbuildAction.json`.\n4. If neither tool is available, self-inspect the file carefully: check for\n   balanced braces and brackets, no trailing commas, and correct escaping in\n   string values (pay special attention to XML content inside `manifest`\u002F`plist`\n   entries where quotes must be escaped as `\\\"`).\n5. If an error is found (by tool or self-inspection), fix the file and repeat\n   from step 2 until the JSON is valid.\n6. Only proceed to the generation guideline 5 (README) once validation passes.\n\n### 5. Generate the README and wrap up\n\nGenerate `build-actions\u002FREADME.md` alongside the JSON. It serves as\nsource-control documentation for the plugin and as the primary reference for\nthe developer setting up ODC. Read **`references\u002Freadme-template.md`** for\nthe required structure, then follow the authoring rules below.\n\n**README authoring rules:**\n- Omit the `### Android` or `### iOS` section if that platform has no actions.\n- Omit `## What requires additional setup` entirely if all input signals were\n  mapped to build actions. Include it only when hooks or elements were found\n  that could not be mapped.\n- Omit the `## Variables` section entirely if there are no variables.\n- Omit the extensibility settings instructions (the paragraph below the JSON block in step 2 of `## ODC Setup`) if the plugin has no variables — the `parameters` key is absent in that case and the instructions have no context.\n- In the `## Variables` table, set Required to `yes` if there is no default,\n  `no` if a default exists. Leave Default as `—` when Required is `yes`.\n- The extensibility JSON in `## ODC Setup` should reflect actual variable names\n  from the generated JSON, not placeholder `VAR_NAME`.\n- In `## What requires additional setup`, set Recommended approach to:\n  - `Capacitor hook` for script-type hooks — describe concretely what the hook must do\n  - `ODC resource` for user-supplied files — tell the developer to add the file as an ODC resource in ODC Studio (Deploy Action: Deploy to Target Directory)\n  - `Not supported in ODC` for blockers — ODC developers have no access to the native project, so there is no manual fallback; briefly state why rework would be needed\n- **Extensibility config permissions alternative**: Only mention `pluginConfigurations.permissions` in the README if (a) the developer explicitly asked about extensibility configurations, or (b) every generated build action is exclusively a `manifest` `\u003Cuses-permission>` entry and\u002For a `plist` iOS usage description entry — meaning the entire `buildAction.json` could be replaced by the `permissions` block in the library extensibility configuration. In all other cases omit it; the reference is in [references\u002Fextensibility-configuration.md](references\u002Fextensibility-configuration.md).\n\n**Terminal output after generating both files:**\n- Do not output the `buildAction.json` contents — the file write already\n  displays them.\n- Do not show analysis tables, scanning decisions, or per-element reasoning in\n  the terminal. Internal reasoning stays internal; noteworthy decisions that did\n  not map cleanly belong in the README, not the terminal.\n- Output a single short note: *\"Build actions written to `build-actions\u002F`. This is a candidate — review `build-actions\u002FbuildAction.json` before use, then validate with a MABS 12+ build and functional tests against a real mobile app. See `build-actions\u002FREADME.md` for a summary of what this configures and ODC setup instructions.\"*\n- If `## What requires additional setup` was written to the README, add one\n  additional line: *\"Some hooks or elements could not be mapped to build\n  actions — see `build-actions\u002FREADME.md` for details.\"*\n- If the developer did not explicitly mention ODC as the target platform, add\n  one sentence noting that build actions only take effect in ODC builds, not in\n  standalone Capacitor apps.\n- Do not repeat the ODC setup steps in the terminal.\n\n",{"data":41,"body":43},{"name":4,"description":6,"metadata":42},{"author":8,"source":31},{"type":44,"children":45},"root",[46,55,70,77,88,161,171,199,203,209,221,343,346,352,370,395,458,634,644,682,707,710,716,732,880,914,917,923,939,944,1122,1125,1131,1146,1150,1396,1399,1405,1412,1417,1665,1671,1676,1699,1705,1956,1975,1981,2212,2217,2308,2314,2337,2345,2580,2588,2672],{"type":47,"tag":48,"props":49,"children":51},"element","h1",{"id":50},"odc-build-actions-generator",[52],{"type":53,"value":54},"text","ODC Build Actions Generator",{"type":47,"tag":56,"props":57,"children":58},"p",{},[59,61,68],{"type":53,"value":60},"Generates ",{"type":47,"tag":62,"props":63,"children":65},"code",{"className":64},[],[66],{"type":53,"value":67},"buildAction.json",{"type":53,"value":69}," for ODC Mobile Libraries (Capacitor and Cordova plugins) and ODC apps targeting Android and iOS via MABS 12+.",{"type":47,"tag":71,"props":72,"children":74},"h2",{"id":73},"when-to-use",[75],{"type":53,"value":76},"When to Use",{"type":47,"tag":56,"props":78,"children":79},{},[80,82],{"type":53,"value":81},"✅ ",{"type":47,"tag":83,"props":84,"children":85},"strong",{},[86],{"type":53,"value":87},"Use this skill when:",{"type":47,"tag":89,"props":90,"children":91},"ul",{},[92,105,116,121,134,146,151,156],{"type":47,"tag":93,"props":94,"children":95},"li",{},[96,98,103],{"type":53,"value":97},"Generating a ",{"type":47,"tag":62,"props":99,"children":101},{"className":100},[],[102],{"type":53,"value":67},{"type":53,"value":104}," file for an ODC Mobile Library (Capacitor or Cordova plugin).",{"type":47,"tag":93,"props":106,"children":107},{},[108,109,114],{"type":53,"value":97},{"type":47,"tag":62,"props":110,"children":112},{"className":111},[],[113],{"type":53,"value":67},{"type":53,"value":115}," file for an ODC app that requires native build configuration.",{"type":47,"tag":93,"props":117,"children":118},{},[119],{"type":53,"value":120},"Generating build actions for a Cordova plugin being adapted for ODC (Capacitor-based) deployment.",{"type":47,"tag":93,"props":122,"children":123},{},[124,126,132],{"type":53,"value":125},"Configuring ",{"type":47,"tag":62,"props":127,"children":129},{"className":128},[],[130],{"type":53,"value":131},"AndroidManifest.xml",{"type":53,"value":133},", Gradle files, or XML resources for Android.",{"type":47,"tag":93,"props":135,"children":136},{},[137,138,144],{"type":53,"value":125},{"type":47,"tag":62,"props":139,"children":141},{"className":140},[],[142],{"type":53,"value":143},"Info.plist",{"type":53,"value":145},", entitlements, or display name for iOS.",{"type":47,"tag":93,"props":147,"children":148},{},[149],{"type":53,"value":150},"Defining input variables (string, number, boolean) and conditional logic.",{"type":47,"tag":93,"props":152,"children":153},{},[154],{"type":53,"value":155},"Scaffolding build actions for both platforms from a plugin's native requirements.",{"type":47,"tag":93,"props":157,"children":158},{},[159],{"type":53,"value":160},"Invoked with a plugin path argument or from within a Capacitor or Cordova plugin directory.",{"type":47,"tag":56,"props":162,"children":163},{},[164,166],{"type":53,"value":165},"❌ ",{"type":47,"tag":83,"props":167,"children":168},{},[169],{"type":53,"value":170},"Do NOT use this skill for:",{"type":47,"tag":89,"props":172,"children":173},{},[174,179,184,189,194],{"type":47,"tag":93,"props":175,"children":176},{},[177],{"type":53,"value":178},"Uploading or referencing the JSON in ODC Studio\u002FPortal (Steps 2–3 — see manual guidance).",{"type":47,"tag":93,"props":180,"children":181},{},[182],{"type":53,"value":183},"Cordova extensibility configurations or O11 extensibility JSON.",{"type":47,"tag":93,"props":185,"children":186},{},[187],{"type":53,"value":188},"Cordova app builds, O11 builds, or MABS versions prior to 12 — build actions only apply to Capacitor apps on ODC (MABS 12+).",{"type":47,"tag":93,"props":190,"children":191},{},[192],{"type":53,"value":193},"App-level build configuration that lives outside the build action JSON.",{"type":47,"tag":93,"props":195,"children":196},{},[197],{"type":53,"value":198},"Publishing or testing the plugin (Step 4 — developer responsibility).",{"type":47,"tag":200,"props":201,"children":202},"hr",{},[],{"type":47,"tag":71,"props":204,"children":206},{"id":205},"end-to-end-process",[207],{"type":53,"value":208},"End-to-End Process",{"type":47,"tag":56,"props":210,"children":211},{},[212,214,219],{"type":53,"value":213},"This skill handles ",{"type":47,"tag":83,"props":215,"children":216},{},[217],{"type":53,"value":218},"Step 1 only",{"type":53,"value":220},". Steps 2–4 require manual action.",{"type":47,"tag":222,"props":223,"children":224},"table",{},[225,249],{"type":47,"tag":226,"props":227,"children":228},"thead",{},[229],{"type":47,"tag":230,"props":231,"children":232},"tr",{},[233,239,244],{"type":47,"tag":234,"props":235,"children":236},"th",{},[237],{"type":53,"value":238},"Step",{"type":47,"tag":234,"props":240,"children":241},{},[242],{"type":53,"value":243},"Owner",{"type":47,"tag":234,"props":245,"children":246},{},[247],{"type":53,"value":248},"What",{"type":47,"tag":250,"props":251,"children":252},"tbody",{},[253,282,303,323],{"type":47,"tag":230,"props":254,"children":255},{},[256,265,270],{"type":47,"tag":257,"props":258,"children":259},"td",{},[260],{"type":47,"tag":83,"props":261,"children":262},{},[263],{"type":53,"value":264},"1. Generate JSON",{"type":47,"tag":257,"props":266,"children":267},{},[268],{"type":53,"value":269},"This skill",{"type":47,"tag":257,"props":271,"children":272},{},[273,275,280],{"type":53,"value":274},"Create ",{"type":47,"tag":62,"props":276,"children":278},{"className":277},[],[279],{"type":53,"value":67},{"type":53,"value":281}," with all required platform actions",{"type":47,"tag":230,"props":283,"children":284},{},[285,293,298],{"type":47,"tag":257,"props":286,"children":287},{},[288],{"type":47,"tag":83,"props":289,"children":290},{},[291],{"type":53,"value":292},"2. Upload JSON",{"type":47,"tag":257,"props":294,"children":295},{},[296],{"type":53,"value":297},"Developer",{"type":47,"tag":257,"props":299,"children":300},{},[301],{"type":53,"value":302},"Add the file to the plugin\u002Flibrary in ODC Studio → Resources, and then reference it Extensibility tab, creating Extensibility Settings for any variables.",{"type":47,"tag":230,"props":304,"children":305},{},[306,314,318],{"type":47,"tag":257,"props":307,"children":308},{},[309],{"type":47,"tag":83,"props":310,"children":311},{},[312],{"type":53,"value":313},"3. Link in Portal",{"type":47,"tag":257,"props":315,"children":316},{},[317],{"type":53,"value":297},{"type":47,"tag":257,"props":319,"children":320},{},[321],{"type":53,"value":322},"If the build action has parameters, provide values in ODC Portal → Mobile Distribution tab → Extensibility settings",{"type":47,"tag":230,"props":324,"children":325},{},[326,334,338],{"type":47,"tag":257,"props":327,"children":328},{},[329],{"type":47,"tag":83,"props":330,"children":331},{},[332],{"type":53,"value":333},"4. Publish & test",{"type":47,"tag":257,"props":335,"children":336},{},[337],{"type":53,"value":297},{"type":47,"tag":257,"props":339,"children":340},{},[341],{"type":53,"value":342},"Test a mobile build using MABS 12 (Capacitor) or later",{"type":47,"tag":200,"props":344,"children":345},{},[],{"type":47,"tag":71,"props":347,"children":349},{"id":348},"json-file-structure",[350],{"type":53,"value":351},"JSON File Structure",{"type":47,"tag":56,"props":353,"children":354},{},[355,360,362,368],{"type":47,"tag":83,"props":356,"children":357},{},[358],{"type":53,"value":359},"Output location:",{"type":53,"value":361}," Two files are written to the ",{"type":47,"tag":62,"props":363,"children":365},{"className":364},[],[366],{"type":53,"value":367},"build-actions\u002F",{"type":53,"value":369}," folder at\nthe plugin root:",{"type":47,"tag":89,"props":371,"children":372},{},[373,384],{"type":47,"tag":93,"props":374,"children":375},{},[376,382],{"type":47,"tag":62,"props":377,"children":379},{"className":378},[],[380],{"type":53,"value":381},"build-actions\u002FbuildAction.json",{"type":53,"value":383}," — the build action configuration",{"type":47,"tag":93,"props":385,"children":386},{},[387,393],{"type":47,"tag":62,"props":388,"children":390},{"className":389},[],[391],{"type":53,"value":392},"build-actions\u002FREADME.md",{"type":53,"value":394}," — human-readable documentation (see Generation Guidelines step 5)",{"type":47,"tag":56,"props":396,"children":397},{},[398,410,412,418,420,426,428,434,436,442,443,449,451,456],{"type":47,"tag":83,"props":399,"children":400},{},[401,403,408],{"type":53,"value":402},"Always create ",{"type":47,"tag":62,"props":404,"children":406},{"className":405},[],[407],{"type":53,"value":367},{"type":53,"value":409}," at the top level of the directory provided\n(or the current working directory if no path argument was given).",{"type":53,"value":411}," Never\ncreate it inside a subdirectory such as ",{"type":47,"tag":62,"props":413,"children":415},{"className":414},[],[416],{"type":53,"value":417},"plugin\u002F",{"type":53,"value":419},", ",{"type":47,"tag":62,"props":421,"children":423},{"className":422},[],[424],{"type":53,"value":425},"android\u002F",{"type":53,"value":427},", or ",{"type":47,"tag":62,"props":429,"children":431},{"className":430},[],[432],{"type":53,"value":433},"ios\u002F",{"type":53,"value":435},",\neven when scanning source files that live in those subdirectories. If the\nplugin repo has a nested structure (e.g. ",{"type":47,"tag":62,"props":437,"children":439},{"className":438},[],[440],{"type":53,"value":441},"plugin\u002Fandroid\u002F",{"type":53,"value":419},{"type":47,"tag":62,"props":444,"children":446},{"className":445},[],[447],{"type":53,"value":448},"plugin\u002Fios\u002F",{"type":53,"value":450},"),\nthe output still goes at the repo root: ",{"type":47,"tag":62,"props":452,"children":454},{"className":453},[],[455],{"type":53,"value":381},{"type":53,"value":457},".",{"type":47,"tag":459,"props":460,"children":465},"pre",{"className":461,"code":462,"language":463,"meta":464,"style":464},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"variables\": { },       \u002F\u002F optional — input parameters for the build action\n  \"platforms\": {\n    \"android\": { },       \u002F\u002F optional — Android-specific actions\n    \"ios\": { }            \u002F\u002F optional — iOS-specific actions\n  }\n}\n","json","",[466],{"type":47,"tag":62,"props":467,"children":468},{"__ignoreMap":464},[469,480,521,547,582,616,625],{"type":47,"tag":470,"props":471,"children":473},"span",{"class":472,"line":34},"line",[474],{"type":47,"tag":470,"props":475,"children":477},{"style":476},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[478],{"type":53,"value":479},"{\n",{"type":47,"tag":470,"props":481,"children":483},{"class":472,"line":482},2,[484,489,495,500,505,510,515],{"type":47,"tag":470,"props":485,"children":486},{"style":476},[487],{"type":53,"value":488},"  \"",{"type":47,"tag":470,"props":490,"children":492},{"style":491},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[493],{"type":53,"value":494},"variables",{"type":47,"tag":470,"props":496,"children":497},{"style":476},[498],{"type":53,"value":499},"\"",{"type":47,"tag":470,"props":501,"children":502},{"style":476},[503],{"type":53,"value":504},":",{"type":47,"tag":470,"props":506,"children":507},{"style":476},[508],{"type":53,"value":509}," {",{"type":47,"tag":470,"props":511,"children":512},{"style":476},[513],{"type":53,"value":514}," },",{"type":47,"tag":470,"props":516,"children":518},{"style":517},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[519],{"type":53,"value":520},"       \u002F\u002F optional — input parameters for the build action\n",{"type":47,"tag":470,"props":522,"children":524},{"class":472,"line":523},3,[525,529,534,538,542],{"type":47,"tag":470,"props":526,"children":527},{"style":476},[528],{"type":53,"value":488},{"type":47,"tag":470,"props":530,"children":531},{"style":491},[532],{"type":53,"value":533},"platforms",{"type":47,"tag":470,"props":535,"children":536},{"style":476},[537],{"type":53,"value":499},{"type":47,"tag":470,"props":539,"children":540},{"style":476},[541],{"type":53,"value":504},{"type":47,"tag":470,"props":543,"children":544},{"style":476},[545],{"type":53,"value":546}," {\n",{"type":47,"tag":470,"props":548,"children":550},{"class":472,"line":549},4,[551,556,561,565,569,573,577],{"type":47,"tag":470,"props":552,"children":553},{"style":476},[554],{"type":53,"value":555},"    \"",{"type":47,"tag":470,"props":557,"children":559},{"style":558},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[560],{"type":53,"value":15},{"type":47,"tag":470,"props":562,"children":563},{"style":476},[564],{"type":53,"value":499},{"type":47,"tag":470,"props":566,"children":567},{"style":476},[568],{"type":53,"value":504},{"type":47,"tag":470,"props":570,"children":571},{"style":476},[572],{"type":53,"value":509},{"type":47,"tag":470,"props":574,"children":575},{"style":476},[576],{"type":53,"value":514},{"type":47,"tag":470,"props":578,"children":579},{"style":517},[580],{"type":53,"value":581},"       \u002F\u002F optional — Android-specific actions\n",{"type":47,"tag":470,"props":583,"children":585},{"class":472,"line":584},5,[586,590,594,598,602,606,611],{"type":47,"tag":470,"props":587,"children":588},{"style":476},[589],{"type":53,"value":555},{"type":47,"tag":470,"props":591,"children":592},{"style":558},[593],{"type":53,"value":19},{"type":47,"tag":470,"props":595,"children":596},{"style":476},[597],{"type":53,"value":499},{"type":47,"tag":470,"props":599,"children":600},{"style":476},[601],{"type":53,"value":504},{"type":47,"tag":470,"props":603,"children":604},{"style":476},[605],{"type":53,"value":509},{"type":47,"tag":470,"props":607,"children":608},{"style":476},[609],{"type":53,"value":610}," }",{"type":47,"tag":470,"props":612,"children":613},{"style":517},[614],{"type":53,"value":615},"            \u002F\u002F optional — iOS-specific actions\n",{"type":47,"tag":470,"props":617,"children":619},{"class":472,"line":618},6,[620],{"type":47,"tag":470,"props":621,"children":622},{"style":476},[623],{"type":53,"value":624},"  }\n",{"type":47,"tag":470,"props":626,"children":628},{"class":472,"line":627},7,[629],{"type":47,"tag":470,"props":630,"children":631},{"style":476},[632],{"type":53,"value":633},"}\n",{"type":47,"tag":56,"props":635,"children":636},{},[637,642],{"type":47,"tag":83,"props":638,"children":639},{},[640],{"type":53,"value":641},"File naming:",{"type":53,"value":643}," Use camelCase without spaces.",{"type":47,"tag":56,"props":645,"children":646},{},[647,648,653,654,660,661,667,669,675,676],{"type":53,"value":81},{"type":47,"tag":62,"props":649,"children":651},{"className":650},[],[652],{"type":53,"value":67},{"type":53,"value":419},{"type":47,"tag":62,"props":655,"children":657},{"className":656},[],[658],{"type":53,"value":659},"pushNotifications.json",{"type":53,"value":419},{"type":47,"tag":62,"props":662,"children":664},{"className":663},[],[665],{"type":53,"value":666},"cameraPlugin.json",{"type":53,"value":668},"\n❌ ",{"type":47,"tag":62,"props":670,"children":672},{"className":671},[],[673],{"type":53,"value":674},"build action.json",{"type":53,"value":419},{"type":47,"tag":62,"props":677,"children":679},{"className":678},[],[680],{"type":53,"value":681},"Build_Action.json",{"type":47,"tag":56,"props":683,"children":684},{},[685,687,692,694,699,701,706],{"type":53,"value":686},"At least one of ",{"type":47,"tag":62,"props":688,"children":690},{"className":689},[],[691],{"type":53,"value":15},{"type":53,"value":693}," or ",{"type":47,"tag":62,"props":695,"children":697},{"className":696},[],[698],{"type":53,"value":19},{"type":53,"value":700}," must be present under ",{"type":47,"tag":62,"props":702,"children":704},{"className":703},[],[705],{"type":53,"value":533},{"type":53,"value":457},{"type":47,"tag":200,"props":708,"children":709},{},[],{"type":47,"tag":71,"props":711,"children":713},{"id":712},"variables-conditions",[714],{"type":53,"value":715},"Variables & Conditions",{"type":47,"tag":56,"props":717,"children":718},{},[719,721,730],{"type":53,"value":720},"If the build action uses variables or conditions, read ",{"type":47,"tag":83,"props":722,"children":723},{},[724],{"type":47,"tag":62,"props":725,"children":727},{"className":726},[],[728],{"type":53,"value":729},"references\u002Fvariables-and-conditions.md",{"type":53,"value":731}," for full syntax and examples.",{"type":47,"tag":89,"props":733,"children":734},{},[735,791,839],{"type":47,"tag":93,"props":736,"children":737},{},[738,743,745,751,753,759,760,766,767,773,775,781,783,789],{"type":47,"tag":83,"props":739,"children":740},{},[741],{"type":53,"value":742},"Variables",{"type":53,"value":744}," (",{"type":47,"tag":62,"props":746,"children":748},{"className":747},[],[749],{"type":53,"value":750},"\"variables\"",{"type":53,"value":752}," key) — typed inputs (",{"type":47,"tag":62,"props":754,"children":756},{"className":755},[],[757],{"type":53,"value":758},"string",{"type":53,"value":419},{"type":47,"tag":62,"props":761,"children":763},{"className":762},[],[764],{"type":53,"value":765},"number",{"type":53,"value":419},{"type":47,"tag":62,"props":768,"children":770},{"className":769},[],[771],{"type":53,"value":772},"boolean",{"type":53,"value":774},") declared by the plugin developer; consuming apps supply values via the extensibility configuration ",{"type":47,"tag":62,"props":776,"children":778},{"className":777},[],[779],{"type":53,"value":780},"parameters",{"type":53,"value":782}," block. Always include a ",{"type":47,"tag":62,"props":784,"children":786},{"className":785},[],[787],{"type":53,"value":788},"default",{"type":53,"value":790}," unless the value is genuinely required; without one the build fails if unset.",{"type":47,"tag":93,"props":792,"children":793},{},[794,799,801,806,808,814,816,822,824,830,831,837],{"type":47,"tag":83,"props":795,"children":796},{},[797],{"type":53,"value":798},"Platform-specific variants",{"type":53,"value":800}," — if the same logical value (e.g. an App ID, API key) is used on both Android and iOS but is typically distinct per platform, expose ",{"type":47,"tag":83,"props":802,"children":803},{},[804],{"type":53,"value":805},"separate variables",{"type":53,"value":807}," with ",{"type":47,"tag":62,"props":809,"children":811},{"className":810},[],[812],{"type":53,"value":813},"_ANDROID",{"type":53,"value":815}," and ",{"type":47,"tag":62,"props":817,"children":819},{"className":818},[],[820],{"type":53,"value":821},"_IOS",{"type":53,"value":823}," suffixes (e.g. ",{"type":47,"tag":62,"props":825,"children":827},{"className":826},[],[828],{"type":53,"value":829},"ADMOB_APP_ID_ANDROID",{"type":53,"value":419},{"type":47,"tag":62,"props":832,"children":834},{"className":833},[],[835],{"type":53,"value":836},"ADMOB_APP_ID_IOS",{"type":53,"value":838},"). Do not merge them into a single shared variable — the developer must be able to configure each platform independently.",{"type":47,"tag":93,"props":840,"children":841},{},[842,847,849,855,857,863,864,870,872,878],{"type":47,"tag":83,"props":843,"children":844},{},[845],{"type":53,"value":846},"Conditions",{"type":53,"value":848}," — add a ",{"type":47,"tag":62,"props":850,"children":852},{"className":851},[],[853],{"type":53,"value":854},"condition",{"type":53,"value":856}," field to any action entry (except ",{"type":47,"tag":62,"props":858,"children":860},{"className":859},[],[861],{"type":53,"value":862},"displayName",{"type":53,"value":419},{"type":47,"tag":62,"props":865,"children":867},{"className":866},[],[868],{"type":53,"value":869},"productName",{"type":53,"value":871},", and ",{"type":47,"tag":62,"props":873,"children":875},{"className":874},[],[876],{"type":53,"value":877},"appName",{"type":53,"value":879},") to conditionally skip it; for syntax and operators, see the reference file.",{"type":47,"tag":881,"props":882,"children":883},"blockquote",{},[884],{"type":47,"tag":56,"props":885,"children":886},{},[887,889,898,900,905,907,912],{"type":53,"value":888},"If variables are defined, read ",{"type":47,"tag":83,"props":890,"children":891},{},[892],{"type":47,"tag":62,"props":893,"children":895},{"className":894},[],[896],{"type":53,"value":897},"references\u002Fextensibility-configuration.md",{"type":53,"value":899}," for how ",{"type":47,"tag":62,"props":901,"children":903},{"className":902},[],[904],{"type":53,"value":780},{"type":53,"value":906}," in the extensibility configuration supplies values for variables declared in ",{"type":47,"tag":62,"props":908,"children":910},{"className":909},[],[911],{"type":53,"value":67},{"type":53,"value":913},". When a library and its consuming app both define build actions, the library's runs first.",{"type":47,"tag":200,"props":915,"children":916},{},[],{"type":47,"tag":71,"props":918,"children":920},{"id":919},"android-actions",[921],{"type":53,"value":922},"Android Actions",{"type":47,"tag":56,"props":924,"children":925},{},[926,928,937],{"type":53,"value":927},"If targeting Android, read ",{"type":47,"tag":83,"props":929,"children":930},{},[931],{"type":47,"tag":62,"props":932,"children":934},{"className":933},[],[935],{"type":53,"value":936},"references\u002Fandroid-build-actions.md",{"type":53,"value":938}," for full action schemas and examples.",{"type":47,"tag":56,"props":940,"children":941},{},[942],{"type":53,"value":943},"Available actions:",{"type":47,"tag":89,"props":945,"children":946},{},[947,957,975,986,1005,1030,1041,1052,1111],{"type":47,"tag":93,"props":948,"children":949},{},[950,955],{"type":47,"tag":62,"props":951,"children":953},{"className":952},[],[954],{"type":53,"value":877},{"type":53,"value":956}," — Set the Android app name (string, no condition support)",{"type":47,"tag":93,"props":958,"children":959},{},[960,966,968,973],{"type":47,"tag":62,"props":961,"children":963},{"className":962},[],[964],{"type":53,"value":965},"manifest",{"type":53,"value":967}," — Modify ",{"type":47,"tag":62,"props":969,"children":971},{"className":970},[],[972],{"type":53,"value":131},{"type":53,"value":974}," (set attributes, merge or inject XML)",{"type":47,"tag":93,"props":976,"children":977},{},[978,984],{"type":47,"tag":62,"props":979,"children":981},{"className":980},[],[982],{"type":53,"value":983},"gradle",{"type":53,"value":985}," — Patch Gradle build files (insert or replace at target DSL path)",{"type":47,"tag":93,"props":987,"children":988},{},[989,995,997,1003],{"type":47,"tag":62,"props":990,"children":992},{"className":991},[],[993],{"type":53,"value":994},"res",{"type":53,"value":996}," — Create resource files under the ",{"type":47,"tag":62,"props":998,"children":1000},{"className":999},[],[1001],{"type":53,"value":1002},"res\u002F",{"type":53,"value":1004}," folder",{"type":47,"tag":93,"props":1006,"children":1007},{},[1008,1013,1015,1021,1022,1028],{"type":47,"tag":62,"props":1009,"children":1011},{"className":1010},[],[1012],{"type":53,"value":463},{"type":53,"value":1014}," — Modify JSON files (",{"type":47,"tag":62,"props":1016,"children":1018},{"className":1017},[],[1019],{"type":53,"value":1020},"set",{"type":53,"value":693},{"type":47,"tag":62,"props":1023,"children":1025},{"className":1024},[],[1026],{"type":53,"value":1027},"merge",{"type":53,"value":1029},")",{"type":47,"tag":93,"props":1031,"children":1032},{},[1033,1039],{"type":47,"tag":62,"props":1034,"children":1036},{"className":1035},[],[1037],{"type":53,"value":1038},"xml",{"type":53,"value":1040}," — Modify arbitrary XML resource files",{"type":47,"tag":93,"props":1042,"children":1043},{},[1044,1050],{"type":47,"tag":62,"props":1045,"children":1047},{"className":1046},[],[1048],{"type":53,"value":1049},"copy",{"type":53,"value":1051}," — Copy files, directories, or URLs into the project",{"type":47,"tag":93,"props":1053,"children":1054},{},[1055,1060,1062,1068,1070,1076,1077,1083,1084,1090,1091,1097,1098,1103,1104,1110],{"type":47,"tag":62,"props":1056,"children":1058},{"className":1057},[],[1059],{"type":53,"value":62},{"type":53,"value":1061}," — Add or patch native Android (Java\u002FKotlin) source files (",{"type":47,"tag":62,"props":1063,"children":1065},{"className":1064},[],[1066],{"type":53,"value":1067},"source",{"type":53,"value":1069},"+",{"type":47,"tag":62,"props":1071,"children":1073},{"className":1072},[],[1074],{"type":53,"value":1075},"targetDir",{"type":53,"value":419},{"type":47,"tag":62,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":53,"value":1082},"file",{"type":53,"value":1069},{"type":47,"tag":62,"props":1085,"children":1087},{"className":1086},[],[1088],{"type":53,"value":1089},"target",{"type":53,"value":1069},{"type":47,"tag":62,"props":1092,"children":1094},{"className":1093},[],[1095],{"type":53,"value":1096},"replace",{"type":53,"value":427},{"type":47,"tag":62,"props":1099,"children":1101},{"className":1100},[],[1102],{"type":53,"value":1082},{"type":53,"value":1069},{"type":47,"tag":62,"props":1105,"children":1107},{"className":1106},[],[1108],{"type":53,"value":1109},"patchFile",{"type":53,"value":1029},{"type":47,"tag":93,"props":1112,"children":1113},{},[1114,1120],{"type":47,"tag":62,"props":1115,"children":1117},{"className":1116},[],[1118],{"type":53,"value":1119},"tar",{"type":53,"value":1121}," — Apply tar operations on project files",{"type":47,"tag":200,"props":1123,"children":1124},{},[],{"type":47,"tag":71,"props":1126,"children":1128},{"id":1127},"ios-actions",[1129],{"type":53,"value":1130},"iOS Actions",{"type":47,"tag":56,"props":1132,"children":1133},{},[1134,1136,1145],{"type":53,"value":1135},"If targeting iOS, read ",{"type":47,"tag":83,"props":1137,"children":1138},{},[1139],{"type":47,"tag":62,"props":1140,"children":1142},{"className":1141},[],[1143],{"type":53,"value":1144},"references\u002Fios-build-actions.md",{"type":53,"value":938},{"type":47,"tag":56,"props":1147,"children":1148},{},[1149],{"type":53,"value":943},{"type":47,"tag":89,"props":1151,"children":1152},{},[1153,1163,1173,1184,1195,1212,1229,1247,1258,1279,1289,1298,1316,1334,1387],{"type":47,"tag":93,"props":1154,"children":1155},{},[1156,1161],{"type":47,"tag":62,"props":1157,"children":1159},{"className":1158},[],[1160],{"type":53,"value":862},{"type":53,"value":1162}," — Set app display name shown on the home screen (no condition support)",{"type":47,"tag":93,"props":1164,"children":1165},{},[1166,1171],{"type":47,"tag":62,"props":1167,"children":1169},{"className":1168},[],[1170],{"type":53,"value":869},{"type":53,"value":1172}," — Set product name shown in App Store (no condition support)",{"type":47,"tag":93,"props":1174,"children":1175},{},[1176,1182],{"type":47,"tag":62,"props":1177,"children":1179},{"className":1178},[],[1180],{"type":53,"value":1181},"buildSettings",{"type":53,"value":1183}," — Set Xcode build settings as key-value pairs",{"type":47,"tag":93,"props":1185,"children":1186},{},[1187,1193],{"type":47,"tag":62,"props":1188,"children":1190},{"className":1189},[],[1191],{"type":53,"value":1192},"buildPhases",{"type":53,"value":1194}," — Add or replace custom shell script build phases",{"type":47,"tag":93,"props":1196,"children":1197},{},[1198,1204,1205,1210],{"type":47,"tag":62,"props":1199,"children":1201},{"className":1200},[],[1202],{"type":53,"value":1203},"plist",{"type":53,"value":967},{"type":47,"tag":62,"props":1206,"children":1208},{"className":1207},[],[1209],{"type":53,"value":143},{"type":53,"value":1211}," or other plist files (replace or merge entries)",{"type":47,"tag":93,"props":1213,"children":1214},{},[1215,1221,1223],{"type":47,"tag":62,"props":1216,"children":1218},{"className":1217},[],[1219],{"type":53,"value":1220},"xcprivacy",{"type":53,"value":1222}," — Update ",{"type":47,"tag":62,"props":1224,"children":1226},{"className":1225},[],[1227],{"type":53,"value":1228},"PrivacyInfo.xcprivacy",{"type":47,"tag":93,"props":1230,"children":1231},{},[1232,1238,1240,1245],{"type":47,"tag":62,"props":1233,"children":1235},{"className":1234},[],[1236],{"type":53,"value":1237},"entitlements",{"type":53,"value":1239}," — Add or modify entitlements (",{"type":47,"tag":83,"props":1241,"children":1242},{},[1243],{"type":53,"value":1244},"object",{"type":53,"value":1246},", not array)",{"type":47,"tag":93,"props":1248,"children":1249},{},[1250,1256],{"type":47,"tag":62,"props":1251,"children":1253},{"className":1252},[],[1254],{"type":53,"value":1255},"frameworks",{"type":53,"value":1257}," — Add system or custom frameworks to the Xcode project",{"type":47,"tag":93,"props":1259,"children":1260},{},[1261,1266,1267,1272,1273,1278],{"type":47,"tag":62,"props":1262,"children":1264},{"className":1263},[],[1265],{"type":53,"value":463},{"type":53,"value":1014},{"type":47,"tag":62,"props":1268,"children":1270},{"className":1269},[],[1271],{"type":53,"value":1020},{"type":53,"value":693},{"type":47,"tag":62,"props":1274,"children":1276},{"className":1275},[],[1277],{"type":53,"value":1027},{"type":53,"value":1029},{"type":47,"tag":93,"props":1280,"children":1281},{},[1282,1287],{"type":47,"tag":62,"props":1283,"children":1285},{"className":1284},[],[1286],{"type":53,"value":1038},{"type":53,"value":1288}," — Modify arbitrary XML files",{"type":47,"tag":93,"props":1290,"children":1291},{},[1292,1297],{"type":47,"tag":62,"props":1293,"children":1295},{"className":1294},[],[1296],{"type":53,"value":1049},{"type":53,"value":1051},{"type":47,"tag":93,"props":1299,"children":1300},{},[1301,1307,1308,1314],{"type":47,"tag":62,"props":1302,"children":1304},{"className":1303},[],[1305],{"type":53,"value":1306},"strings",{"type":53,"value":1222},{"type":47,"tag":62,"props":1309,"children":1311},{"className":1310},[],[1312],{"type":53,"value":1313},".strings",{"type":53,"value":1315}," localization files",{"type":47,"tag":93,"props":1317,"children":1318},{},[1319,1325,1326,1332],{"type":47,"tag":62,"props":1320,"children":1322},{"className":1321},[],[1323],{"type":53,"value":1324},"xcconfig",{"type":53,"value":1222},{"type":47,"tag":62,"props":1327,"children":1329},{"className":1328},[],[1330],{"type":53,"value":1331},".xcconfig",{"type":53,"value":1333}," build configuration files",{"type":47,"tag":93,"props":1335,"children":1336},{},[1337,1342,1344,1349,1350,1356,1357,1362,1363,1368,1369,1374,1375,1380,1381,1386],{"type":47,"tag":62,"props":1338,"children":1340},{"className":1339},[],[1341],{"type":53,"value":62},{"type":53,"value":1343}," — Add or patch native iOS (Swift\u002FObjective-C) source files (",{"type":47,"tag":62,"props":1345,"children":1347},{"className":1346},[],[1348],{"type":53,"value":1067},{"type":53,"value":1069},{"type":47,"tag":62,"props":1351,"children":1353},{"className":1352},[],[1354],{"type":53,"value":1355},"compilerFlags",{"type":53,"value":419},{"type":47,"tag":62,"props":1358,"children":1360},{"className":1359},[],[1361],{"type":53,"value":1082},{"type":53,"value":1069},{"type":47,"tag":62,"props":1364,"children":1366},{"className":1365},[],[1367],{"type":53,"value":1089},{"type":53,"value":1069},{"type":47,"tag":62,"props":1370,"children":1372},{"className":1371},[],[1373],{"type":53,"value":1096},{"type":53,"value":427},{"type":47,"tag":62,"props":1376,"children":1378},{"className":1377},[],[1379],{"type":53,"value":1082},{"type":53,"value":1069},{"type":47,"tag":62,"props":1382,"children":1384},{"className":1383},[],[1385],{"type":53,"value":1109},{"type":53,"value":1029},{"type":47,"tag":93,"props":1388,"children":1389},{},[1390,1395],{"type":47,"tag":62,"props":1391,"children":1393},{"className":1392},[],[1394],{"type":53,"value":1119},{"type":53,"value":1121},{"type":47,"tag":200,"props":1397,"children":1398},{},[],{"type":47,"tag":71,"props":1400,"children":1402},{"id":1401},"generation-guidelines",[1403],{"type":53,"value":1404},"Generation Guidelines",{"type":47,"tag":1406,"props":1407,"children":1409},"h3",{"id":1408},"_1-read-plugin-input-signals",[1410],{"type":53,"value":1411},"1. Read plugin input signals",{"type":47,"tag":56,"props":1413,"children":1414},{},[1415],{"type":53,"value":1416},"Plugin root is the path argument if one was given, otherwise the current directory. Before asking the developer any questions, check for existing signals in the plugin:",{"type":47,"tag":89,"props":1418,"children":1419},{},[1420,1560,1631],{"type":47,"tag":93,"props":1421,"children":1422},{},[1423,1425,1431,1433,1439,1441],{"type":53,"value":1424},"If ",{"type":47,"tag":62,"props":1426,"children":1428},{"className":1427},[],[1429],{"type":53,"value":1430},"input-contract.yaml",{"type":53,"value":1432}," exists at the plugin root, read it against the full\n",{"type":47,"tag":62,"props":1434,"children":1436},{"className":1435},[],[1437],{"type":53,"value":1438},"capacitor-plugin-generator\u002Freferences\u002Finput-contract.md",{"type":53,"value":1440}," schema and extract\nthe following relevant sections:\n",{"type":47,"tag":89,"props":1442,"children":1443},{},[1444,1477,1496,1522,1533],{"type":47,"tag":93,"props":1445,"children":1446},{},[1447,1453,1454,1460,1462,1468,1469,1475],{"type":47,"tag":62,"props":1448,"children":1450},{"className":1449},[],[1451],{"type":53,"value":1452},"migration.hooks",{"type":53,"value":744},{"type":47,"tag":62,"props":1455,"children":1457},{"className":1456},[],[1458],{"type":53,"value":1459},"tier_1",{"type":53,"value":1461}," \u002F ",{"type":47,"tag":62,"props":1463,"children":1465},{"className":1464},[],[1466],{"type":53,"value":1467},"tier_2",{"type":53,"value":1461},{"type":47,"tag":62,"props":1470,"children":1472},{"className":1471},[],[1473],{"type":53,"value":1474},"tier_3",{"type":53,"value":1476},") — hook classification\nfor build-action derivation.",{"type":47,"tag":93,"props":1478,"children":1479},{},[1480,1486,1488,1494],{"type":47,"tag":62,"props":1481,"children":1483},{"className":1482},[],[1484],{"type":53,"value":1485},"dependencies.android.gradle",{"type":53,"value":1487}," and\n",{"type":47,"tag":62,"props":1489,"children":1491},{"className":1490},[],[1492],{"type":53,"value":1493},"dependencies.ios.{cocoapods,spm,system_frameworks}",{"type":53,"value":1495}," — dependency-based\nactions (Gradle patches, framework entries).",{"type":47,"tag":93,"props":1497,"children":1498},{},[1499,1505,1506,1512,1514,1520],{"type":47,"tag":62,"props":1500,"children":1502},{"className":1501},[],[1503],{"type":53,"value":1504},"permissions.android",{"type":53,"value":815},{"type":47,"tag":62,"props":1507,"children":1509},{"className":1508},[],[1510],{"type":53,"value":1511},"permissions.ios",{"type":53,"value":1513}," — permission actions\n(manifest ",{"type":47,"tag":62,"props":1515,"children":1517},{"className":1516},[],[1518],{"type":53,"value":1519},"\u003Cuses-permission>",{"type":53,"value":1521},", plist usage descriptions).",{"type":47,"tag":93,"props":1523,"children":1524},{},[1525,1531],{"type":47,"tag":62,"props":1526,"children":1528},{"className":1527},[],[1529],{"type":53,"value":1530},"plugin.name",{"type":53,"value":1532}," — for the README title.",{"type":47,"tag":93,"props":1534,"children":1535},{},[1536,1538,1544,1545,1551,1552,1558],{"type":53,"value":1537},"All other fields (",{"type":47,"tag":62,"props":1539,"children":1541},{"className":1540},[],[1542],{"type":53,"value":1543},"api.methods",{"type":53,"value":419},{"type":47,"tag":62,"props":1546,"children":1548},{"className":1547},[],[1549],{"type":53,"value":1550},"api.types",{"type":53,"value":419},{"type":47,"tag":62,"props":1553,"children":1555},{"className":1554},[],[1556],{"type":53,"value":1557},"api.events",{"type":53,"value":1559},", etc.) are\nirrelevant — ignore silently.",{"type":47,"tag":93,"props":1561,"children":1562},{},[1563,1568,1570],{"type":47,"tag":83,"props":1564,"children":1565},{},[1566],{"type":53,"value":1567},"Always also scan plugin source directly",{"type":53,"value":1569},", even when the contract is\npresent. The contract is a starting point; source scanning catches signals\nthe contract may not capture or may be stale on:\n",{"type":47,"tag":89,"props":1571,"children":1572},{},[1573,1602],{"type":47,"tag":93,"props":1574,"children":1575},{},[1576,1581,1583,1589,1591,1600],{"type":47,"tag":83,"props":1577,"children":1578},{},[1579],{"type":53,"value":1580},"Cordova plugins:",{"type":53,"value":1582}," parse ",{"type":47,"tag":62,"props":1584,"children":1586},{"className":1585},[],[1587],{"type":53,"value":1588},"plugin.xml",{"type":53,"value":1590}," — read ",{"type":47,"tag":83,"props":1592,"children":1593},{},[1594],{"type":47,"tag":62,"props":1595,"children":1597},{"className":1596},[],[1598],{"type":53,"value":1599},"references\u002Fcordova-plugin-scanning.md",{"type":53,"value":1601}," for the full element-to-action mapping and hook classification guide.",{"type":47,"tag":93,"props":1603,"children":1604},{},[1605,1610,1612,1618,1620,1629],{"type":47,"tag":83,"props":1606,"children":1607},{},[1608],{"type":53,"value":1609},"Capacitor plugins:",{"type":53,"value":1611}," scan plugin documentation, ",{"type":47,"tag":62,"props":1613,"children":1615},{"className":1614},[],[1616],{"type":53,"value":1617},"package.json",{"type":53,"value":1619},", and native source files (Java\u002FKotlin and Swift\u002FObjective-C) — read ",{"type":47,"tag":83,"props":1621,"children":1622},{},[1623],{"type":47,"tag":62,"props":1624,"children":1626},{"className":1625},[],[1627],{"type":53,"value":1628},"references\u002Fcapacitor-plugin-scanning.md",{"type":53,"value":1630}," for the full scanning guide.",{"type":47,"tag":93,"props":1632,"children":1633},{},[1634,1636,1642,1644,1649,1651,1656,1658,1663],{"type":53,"value":1635},"When invoked as part of the ",{"type":47,"tag":62,"props":1637,"children":1639},{"className":1638},[],[1640],{"type":53,"value":1641},"cordova-plugin-migrator",{"type":53,"value":1643}," ODC flow (Phase 11a),\nthe output (",{"type":47,"tag":62,"props":1645,"children":1647},{"className":1646},[],[1648],{"type":53,"value":367},{"type":53,"value":1650},") is written to the ",{"type":47,"tag":83,"props":1652,"children":1653},{},[1654],{"type":53,"value":1655},"Capacitor plugin\ndirectory",{"type":53,"value":1657},", not the Cordova source tree. The ",{"type":47,"tag":62,"props":1659,"children":1661},{"className":1660},[],[1662],{"type":53,"value":1641},{"type":53,"value":1664},"\nsupplies the Capacitor plugin path as the working directory or argument.",{"type":47,"tag":1406,"props":1666,"children":1668},{"id":1667},"_2-gather-requirements",[1669],{"type":53,"value":1670},"2. Gather requirements",{"type":47,"tag":56,"props":1672,"children":1673},{},[1674],{"type":53,"value":1675},"Ask the developer (or infer from context):",{"type":47,"tag":89,"props":1677,"children":1678},{},[1679,1684,1689,1694],{"type":47,"tag":93,"props":1680,"children":1681},{},[1682],{"type":53,"value":1683},"What native capabilities does the plugin need? (camera, location, push, Bluetooth, etc.)",{"type":47,"tag":93,"props":1685,"children":1686},{},[1687],{"type":53,"value":1688},"Which platforms are targeted: Android only, iOS only, or both?",{"type":47,"tag":93,"props":1690,"children":1691},{},[1692],{"type":53,"value":1693},"Are there runtime configuration values the developer should control? (→ variables)",{"type":47,"tag":93,"props":1695,"children":1696},{},[1697],{"type":53,"value":1698},"Are any actions conditional on those values?",{"type":47,"tag":1406,"props":1700,"children":1702},{"id":1701},"_3-map-requirements-to-actions",[1703],{"type":53,"value":1704},"3. Map requirements to actions",{"type":47,"tag":222,"props":1706,"children":1707},{},[1708,1729],{"type":47,"tag":226,"props":1709,"children":1710},{},[1711],{"type":47,"tag":230,"props":1712,"children":1713},{},[1714,1719,1724],{"type":47,"tag":234,"props":1715,"children":1716},{},[1717],{"type":53,"value":1718},"Native requirement",{"type":47,"tag":234,"props":1720,"children":1721},{},[1722],{"type":53,"value":1723},"Android action",{"type":47,"tag":234,"props":1725,"children":1726},{},[1727],{"type":53,"value":1728},"iOS action",{"type":47,"tag":250,"props":1730,"children":1731},{},[1732,1765,1799,1822,1844,1882,1909,1929],{"type":47,"tag":230,"props":1733,"children":1734},{},[1735,1740,1755],{"type":47,"tag":257,"props":1736,"children":1737},{},[1738],{"type":53,"value":1739},"Runtime permission",{"type":47,"tag":257,"props":1741,"children":1742},{},[1743,1748,1750],{"type":47,"tag":62,"props":1744,"children":1746},{"className":1745},[],[1747],{"type":53,"value":965},{"type":53,"value":1749}," inject ",{"type":47,"tag":62,"props":1751,"children":1753},{"className":1752},[],[1754],{"type":53,"value":1519},{"type":47,"tag":257,"props":1756,"children":1757},{},[1758,1763],{"type":47,"tag":62,"props":1759,"children":1761},{"className":1760},[],[1762],{"type":53,"value":1203},{"type":53,"value":1764}," usage description key",{"type":47,"tag":230,"props":1766,"children":1767},{},[1768,1773,1783],{"type":47,"tag":257,"props":1769,"children":1770},{},[1771],{"type":53,"value":1772},"Custom URL scheme",{"type":47,"tag":257,"props":1774,"children":1775},{},[1776,1781],{"type":47,"tag":62,"props":1777,"children":1779},{"className":1778},[],[1780],{"type":53,"value":965},{"type":53,"value":1782}," merge intent-filter",{"type":47,"tag":257,"props":1784,"children":1785},{},[1786,1791,1793],{"type":47,"tag":62,"props":1787,"children":1789},{"className":1788},[],[1790],{"type":53,"value":1203},{"type":53,"value":1792}," ",{"type":47,"tag":62,"props":1794,"children":1796},{"className":1795},[],[1797],{"type":53,"value":1798},"CFBundleURLTypes",{"type":47,"tag":230,"props":1800,"children":1801},{},[1802,1807,1817],{"type":47,"tag":257,"props":1803,"children":1804},{},[1805],{"type":53,"value":1806},"Custom app attribute",{"type":47,"tag":257,"props":1808,"children":1809},{},[1810,1815],{"type":47,"tag":62,"props":1811,"children":1813},{"className":1812},[],[1814],{"type":53,"value":965},{"type":53,"value":1816}," attrs",{"type":47,"tag":257,"props":1818,"children":1819},{},[1820],{"type":53,"value":1821},"—",{"type":47,"tag":230,"props":1823,"children":1824},{},[1825,1830,1840],{"type":47,"tag":257,"props":1826,"children":1827},{},[1828],{"type":53,"value":1829},"Native dependency",{"type":47,"tag":257,"props":1831,"children":1832},{},[1833,1838],{"type":47,"tag":62,"props":1834,"children":1836},{"className":1835},[],[1837],{"type":53,"value":983},{"type":53,"value":1839}," replace",{"type":47,"tag":257,"props":1841,"children":1842},{},[1843],{"type":53,"value":1821},{"type":47,"tag":230,"props":1845,"children":1846},{},[1847,1852,1867],{"type":47,"tag":257,"props":1848,"children":1849},{},[1850],{"type":53,"value":1851},"Push notifications",{"type":47,"tag":257,"props":1853,"children":1854},{},[1855,1860,1862],{"type":47,"tag":62,"props":1856,"children":1858},{"className":1857},[],[1859],{"type":53,"value":965},{"type":53,"value":1861}," merge + ",{"type":47,"tag":62,"props":1863,"children":1865},{"className":1864},[],[1866],{"type":53,"value":983},{"type":47,"tag":257,"props":1868,"children":1869},{},[1870,1875,1876],{"type":47,"tag":62,"props":1871,"children":1873},{"className":1872},[],[1874],{"type":53,"value":1237},{"type":53,"value":1792},{"type":47,"tag":62,"props":1877,"children":1879},{"className":1878},[],[1880],{"type":53,"value":1881},"aps-environment",{"type":47,"tag":230,"props":1883,"children":1884},{},[1885,1890,1894],{"type":47,"tag":257,"props":1886,"children":1887},{},[1888],{"type":53,"value":1889},"App groups",{"type":47,"tag":257,"props":1891,"children":1892},{},[1893],{"type":53,"value":1821},{"type":47,"tag":257,"props":1895,"children":1896},{},[1897,1902,1903],{"type":47,"tag":62,"props":1898,"children":1900},{"className":1899},[],[1901],{"type":53,"value":1237},{"type":53,"value":1792},{"type":47,"tag":62,"props":1904,"children":1906},{"className":1905},[],[1907],{"type":53,"value":1908},"com.apple.security.application-groups",{"type":47,"tag":230,"props":1910,"children":1911},{},[1912,1917,1921],{"type":47,"tag":257,"props":1913,"children":1914},{},[1915],{"type":53,"value":1916},"Custom display name",{"type":47,"tag":257,"props":1918,"children":1919},{},[1920],{"type":53,"value":1821},{"type":47,"tag":257,"props":1922,"children":1923},{},[1924],{"type":47,"tag":62,"props":1925,"children":1927},{"className":1926},[],[1928],{"type":53,"value":862},{"type":47,"tag":230,"props":1930,"children":1931},{},[1932,1937,1947],{"type":47,"tag":257,"props":1933,"children":1934},{},[1935],{"type":53,"value":1936},"Custom native code",{"type":47,"tag":257,"props":1938,"children":1939},{},[1940,1945],{"type":47,"tag":62,"props":1941,"children":1943},{"className":1942},[],[1944],{"type":53,"value":62},{"type":53,"value":1946}," inject\u002Freplace",{"type":47,"tag":257,"props":1948,"children":1949},{},[1950,1955],{"type":47,"tag":62,"props":1951,"children":1953},{"className":1952},[],[1954],{"type":53,"value":62},{"type":53,"value":1946},{"type":47,"tag":881,"props":1957,"children":1958},{},[1959],{"type":47,"tag":56,"props":1960,"children":1961},{},[1962,1964,1973],{"type":53,"value":1963},"If a hook or element does not map clearly to any action listed above, read ",{"type":47,"tag":83,"props":1965,"children":1966},{},[1967],{"type":47,"tag":62,"props":1968,"children":1970},{"className":1969},[],[1971],{"type":53,"value":1972},"references\u002Fcommon-scenarios.md",{"type":53,"value":1974}," for patterns that appear unmappable but have correct build action equivalents.",{"type":47,"tag":1406,"props":1976,"children":1978},{"id":1977},"_4-generate-the-json",[1979],{"type":53,"value":1980},"4. Generate the JSON",{"type":47,"tag":89,"props":1982,"children":1983},{},[1984,1995,2000,2013,2030,2042,2069,2074,2109,2189],{"type":47,"tag":93,"props":1985,"children":1986},{},[1987,1989,1994],{"type":53,"value":1988},"Filename: camelCase, no spaces (e.g., ",{"type":47,"tag":62,"props":1990,"children":1992},{"className":1991},[],[1993],{"type":53,"value":67},{"type":53,"value":1029},{"type":47,"tag":93,"props":1996,"children":1997},{},[1998],{"type":53,"value":1999},"Only include platforms that have actual actions",{"type":47,"tag":93,"props":2001,"children":2002},{},[2003,2005,2011],{"type":53,"value":2004},"Use ",{"type":47,"tag":62,"props":2006,"children":2008},{"className":2007},[],[2009],{"type":53,"value":2010},"$VAR_NAME",{"type":53,"value":2012}," substitution for developer-controlled values",{"type":47,"tag":93,"props":2014,"children":2015},{},[2016,2018,2023,2025],{"type":53,"value":2017},"Include a ",{"type":47,"tag":62,"props":2019,"children":2021},{"className":2020},[],[2022],{"type":53,"value":788},{"type":53,"value":2024}," on variables unless the value is genuinely required — without one, the build fails if neither the plugin library nor the consuming app supplies the variable value in the extensibility configuration ",{"type":47,"tag":62,"props":2026,"children":2028},{"className":2027},[],[2029],{"type":53,"value":780},{"type":47,"tag":93,"props":2031,"children":2032},{},[2033,2035,2040],{"type":53,"value":2034},"Add ",{"type":47,"tag":62,"props":2036,"children":2038},{"className":2037},[],[2039],{"type":53,"value":854},{"type":53,"value":2041}," only when an action should be conditionally skipped",{"type":47,"tag":93,"props":2043,"children":2044},{},[2045,2047,2052,2054,2060,2062,2067],{"type":53,"value":2046},"Prefer ",{"type":47,"tag":62,"props":2048,"children":2050},{"className":2049},[],[2051],{"type":53,"value":1027},{"type":53,"value":2053}," over ",{"type":47,"tag":62,"props":2055,"children":2057},{"className":2056},[],[2058],{"type":53,"value":2059},"inject",{"type":53,"value":2061}," in ",{"type":47,"tag":62,"props":2063,"children":2065},{"className":2064},[],[2066],{"type":53,"value":965},{"type":53,"value":2068}," to avoid duplicate entries",{"type":47,"tag":93,"props":2070,"children":2071},{},[2072],{"type":53,"value":2073},"Output valid, well-formatted JSON",{"type":47,"tag":93,"props":2075,"children":2076},{},[2077,2079,2084,2086,2091,2093,2099,2101,2107],{"type":53,"value":2078},"The ",{"type":47,"tag":62,"props":2080,"children":2082},{"className":2081},[],[2083],{"type":53,"value":62},{"type":53,"value":2085}," action has ",{"type":47,"tag":83,"props":2087,"children":2088},{},[2089],{"type":53,"value":2090},"platform-specific file path conventions",{"type":53,"value":2092}," — iOS targets\nSwift\u002FObjective-C files (e.g., ",{"type":47,"tag":62,"props":2094,"children":2096},{"className":2095},[],[2097],{"type":53,"value":2098},"App\u002FAppDelegate.swift",{"type":53,"value":2100},"); Android targets\nJava\u002FKotlin files (e.g., ",{"type":47,"tag":62,"props":2102,"children":2104},{"className":2103},[],[2105],{"type":53,"value":2106},"app\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fexample\u002FApp.java",{"type":53,"value":2108},"). Do not\nmix conventions between platforms.",{"type":47,"tag":93,"props":2110,"children":2111},{},[2112,2122,2124,2129,2130,2135,2136,2141,2143,2148,2149,2154,2156,2161,2163,2168,2169,2174,2175,2180,2182,2187],{"type":47,"tag":83,"props":2113,"children":2114},{},[2115,2117],{"type":53,"value":2116},"Prefer config-level actions over ",{"type":47,"tag":62,"props":2118,"children":2120},{"className":2119},[],[2121],{"type":53,"value":62},{"type":53,"value":2123}," — ",{"type":47,"tag":62,"props":2125,"children":2127},{"className":2126},[],[2128],{"type":53,"value":965},{"type":53,"value":419},{"type":47,"tag":62,"props":2131,"children":2133},{"className":2132},[],[2134],{"type":53,"value":983},{"type":53,"value":419},{"type":47,"tag":62,"props":2137,"children":2139},{"className":2138},[],[2140],{"type":53,"value":1203},{"type":53,"value":2142},",\n",{"type":47,"tag":62,"props":2144,"children":2146},{"className":2145},[],[2147],{"type":53,"value":1038},{"type":53,"value":871},{"type":47,"tag":62,"props":2150,"children":2152},{"className":2151},[],[2153],{"type":53,"value":1237},{"type":53,"value":2155}," cover most native requirements without touching\nsource files. Only generate a ",{"type":47,"tag":62,"props":2157,"children":2159},{"className":2158},[],[2160],{"type":53,"value":62},{"type":53,"value":2162}," action when no config-level alternative\nexists. If you do, use ",{"type":47,"tag":62,"props":2164,"children":2166},{"className":2165},[],[2167],{"type":53,"value":1082},{"type":53,"value":1069},{"type":47,"tag":62,"props":2170,"children":2172},{"className":2171},[],[2173],{"type":53,"value":1089},{"type":53,"value":1069},{"type":47,"tag":62,"props":2176,"children":2178},{"className":2177},[],[2179],{"type":53,"value":1096},{"type":53,"value":2181},"; never use ",{"type":47,"tag":62,"props":2183,"children":2185},{"className":2184},[],[2186],{"type":53,"value":1109},{"type":53,"value":2188}," — it\nis unreliable in ODC builds. If the change cannot be expressed as a simple\nstring replacement, briefly tell the user the approach is not reliable in ODC\nand suggest a Capacitor hook as the alternative (out of scope for this skill).\nDo not explain ODC internals.",{"type":47,"tag":93,"props":2190,"children":2191},{},[2192,2210],{"type":47,"tag":83,"props":2193,"children":2194},{},[2195,2197,2202,2203,2208],{"type":53,"value":2196},"Avoid ",{"type":47,"tag":62,"props":2198,"children":2200},{"className":2199},[],[2201],{"type":53,"value":1119},{"type":53,"value":815},{"type":47,"tag":62,"props":2204,"children":2206},{"className":2205},[],[2207],{"type":53,"value":1049},{"type":53,"value":2209}," when the source file is user-supplied at runtime",{"type":53,"value":2211}," —\nthese actions are only reliable with hardcoded paths inside the plugin bundle\nor external URLs. If the use case requires user-provided files, briefly tell\nthe user to consider a Capacitor hook instead. Do not explain ODC internals.",{"type":47,"tag":56,"props":2213,"children":2214},{},[2215],{"type":53,"value":2216},"After writing the JSON file, validate its syntax before proceeding:",{"type":47,"tag":2218,"props":2219,"children":2220},"ol",{},[2221,2232,2253,2271,2298,2303],{"type":47,"tag":93,"props":2222,"children":2223},{},[2224,2226],{"type":53,"value":2225},"Tell the user: ",{"type":47,"tag":2227,"props":2228,"children":2229},"em",{},[2230],{"type":53,"value":2231},"\"Validating JSON syntax...\"",{"type":47,"tag":93,"props":2233,"children":2234},{},[2235,2237,2243,2245,2251],{"type":53,"value":2236},"Try ",{"type":47,"tag":62,"props":2238,"children":2240},{"className":2239},[],[2241],{"type":53,"value":2242},"python3 -m json.tool build-actions\u002FbuildAction.json > \u002Fdev\u002Fnull",{"type":53,"value":2244}," — use\nthis if ",{"type":47,"tag":62,"props":2246,"children":2248},{"className":2247},[],[2249],{"type":53,"value":2250},"python3",{"type":53,"value":2252}," is available.",{"type":47,"tag":93,"props":2254,"children":2255},{},[2256,2257,2262,2264,2270],{"type":53,"value":1424},{"type":47,"tag":62,"props":2258,"children":2260},{"className":2259},[],[2261],{"type":53,"value":2250},{"type":53,"value":2263}," is not available, try ",{"type":47,"tag":62,"props":2265,"children":2267},{"className":2266},[],[2268],{"type":53,"value":2269},"jq empty build-actions\u002FbuildAction.json",{"type":53,"value":457},{"type":47,"tag":93,"props":2272,"children":2273},{},[2274,2276,2281,2283,2288,2290,2296],{"type":53,"value":2275},"If neither tool is available, self-inspect the file carefully: check for\nbalanced braces and brackets, no trailing commas, and correct escaping in\nstring values (pay special attention to XML content inside ",{"type":47,"tag":62,"props":2277,"children":2279},{"className":2278},[],[2280],{"type":53,"value":965},{"type":53,"value":2282},"\u002F",{"type":47,"tag":62,"props":2284,"children":2286},{"className":2285},[],[2287],{"type":53,"value":1203},{"type":53,"value":2289},"\nentries where quotes must be escaped as ",{"type":47,"tag":62,"props":2291,"children":2293},{"className":2292},[],[2294],{"type":53,"value":2295},"\\\"",{"type":53,"value":2297},").",{"type":47,"tag":93,"props":2299,"children":2300},{},[2301],{"type":53,"value":2302},"If an error is found (by tool or self-inspection), fix the file and repeat\nfrom step 2 until the JSON is valid.",{"type":47,"tag":93,"props":2304,"children":2305},{},[2306],{"type":53,"value":2307},"Only proceed to the generation guideline 5 (README) once validation passes.",{"type":47,"tag":1406,"props":2309,"children":2311},{"id":2310},"_5-generate-the-readme-and-wrap-up",[2312],{"type":53,"value":2313},"5. Generate the README and wrap up",{"type":47,"tag":56,"props":2315,"children":2316},{},[2317,2319,2324,2326,2335],{"type":53,"value":2318},"Generate ",{"type":47,"tag":62,"props":2320,"children":2322},{"className":2321},[],[2323],{"type":53,"value":392},{"type":53,"value":2325}," alongside the JSON. It serves as\nsource-control documentation for the plugin and as the primary reference for\nthe developer setting up ODC. Read ",{"type":47,"tag":83,"props":2327,"children":2328},{},[2329],{"type":47,"tag":62,"props":2330,"children":2332},{"className":2331},[],[2333],{"type":53,"value":2334},"references\u002Freadme-template.md",{"type":53,"value":2336}," for\nthe required structure, then follow the authoring rules below.",{"type":47,"tag":56,"props":2338,"children":2339},{},[2340],{"type":47,"tag":83,"props":2341,"children":2342},{},[2343],{"type":53,"value":2344},"README authoring rules:",{"type":47,"tag":89,"props":2346,"children":2347},{},[2348,2368,2381,2393,2413,2454,2473,2521],{"type":47,"tag":93,"props":2349,"children":2350},{},[2351,2353,2359,2360,2366],{"type":53,"value":2352},"Omit the ",{"type":47,"tag":62,"props":2354,"children":2356},{"className":2355},[],[2357],{"type":53,"value":2358},"### Android",{"type":53,"value":693},{"type":47,"tag":62,"props":2361,"children":2363},{"className":2362},[],[2364],{"type":53,"value":2365},"### iOS",{"type":53,"value":2367}," section if that platform has no actions.",{"type":47,"tag":93,"props":2369,"children":2370},{},[2371,2373,2379],{"type":53,"value":2372},"Omit ",{"type":47,"tag":62,"props":2374,"children":2376},{"className":2375},[],[2377],{"type":53,"value":2378},"## What requires additional setup",{"type":53,"value":2380}," entirely if all input signals were\nmapped to build actions. Include it only when hooks or elements were found\nthat could not be mapped.",{"type":47,"tag":93,"props":2382,"children":2383},{},[2384,2385,2391],{"type":53,"value":2352},{"type":47,"tag":62,"props":2386,"children":2388},{"className":2387},[],[2389],{"type":53,"value":2390},"## Variables",{"type":53,"value":2392}," section entirely if there are no variables.",{"type":47,"tag":93,"props":2394,"children":2395},{},[2396,2398,2404,2406,2411],{"type":53,"value":2397},"Omit the extensibility settings instructions (the paragraph below the JSON block in step 2 of ",{"type":47,"tag":62,"props":2399,"children":2401},{"className":2400},[],[2402],{"type":53,"value":2403},"## ODC Setup",{"type":53,"value":2405},") if the plugin has no variables — the ",{"type":47,"tag":62,"props":2407,"children":2409},{"className":2408},[],[2410],{"type":53,"value":780},{"type":53,"value":2412}," key is absent in that case and the instructions have no context.",{"type":47,"tag":93,"props":2414,"children":2415},{},[2416,2418,2423,2425,2431,2433,2439,2441,2446,2448,2453],{"type":53,"value":2417},"In the ",{"type":47,"tag":62,"props":2419,"children":2421},{"className":2420},[],[2422],{"type":53,"value":2390},{"type":53,"value":2424}," table, set Required to ",{"type":47,"tag":62,"props":2426,"children":2428},{"className":2427},[],[2429],{"type":53,"value":2430},"yes",{"type":53,"value":2432}," if there is no default,\n",{"type":47,"tag":62,"props":2434,"children":2436},{"className":2435},[],[2437],{"type":53,"value":2438},"no",{"type":53,"value":2440}," if a default exists. Leave Default as ",{"type":47,"tag":62,"props":2442,"children":2444},{"className":2443},[],[2445],{"type":53,"value":1821},{"type":53,"value":2447}," when Required is ",{"type":47,"tag":62,"props":2449,"children":2451},{"className":2450},[],[2452],{"type":53,"value":2430},{"type":53,"value":457},{"type":47,"tag":93,"props":2455,"children":2456},{},[2457,2459,2464,2466,2472],{"type":53,"value":2458},"The extensibility JSON in ",{"type":47,"tag":62,"props":2460,"children":2462},{"className":2461},[],[2463],{"type":53,"value":2403},{"type":53,"value":2465}," should reflect actual variable names\nfrom the generated JSON, not placeholder ",{"type":47,"tag":62,"props":2467,"children":2469},{"className":2468},[],[2470],{"type":53,"value":2471},"VAR_NAME",{"type":53,"value":457},{"type":47,"tag":93,"props":2474,"children":2475},{},[2476,2478,2483,2485],{"type":53,"value":2477},"In ",{"type":47,"tag":62,"props":2479,"children":2481},{"className":2480},[],[2482],{"type":53,"value":2378},{"type":53,"value":2484},", set Recommended approach to:\n",{"type":47,"tag":89,"props":2486,"children":2487},{},[2488,2499,2510],{"type":47,"tag":93,"props":2489,"children":2490},{},[2491,2497],{"type":47,"tag":62,"props":2492,"children":2494},{"className":2493},[],[2495],{"type":53,"value":2496},"Capacitor hook",{"type":53,"value":2498}," for script-type hooks — describe concretely what the hook must do",{"type":47,"tag":93,"props":2500,"children":2501},{},[2502,2508],{"type":47,"tag":62,"props":2503,"children":2505},{"className":2504},[],[2506],{"type":53,"value":2507},"ODC resource",{"type":53,"value":2509}," for user-supplied files — tell the developer to add the file as an ODC resource in ODC Studio (Deploy Action: Deploy to Target Directory)",{"type":47,"tag":93,"props":2511,"children":2512},{},[2513,2519],{"type":47,"tag":62,"props":2514,"children":2516},{"className":2515},[],[2517],{"type":53,"value":2518},"Not supported in ODC",{"type":53,"value":2520}," for blockers — ODC developers have no access to the native project, so there is no manual fallback; briefly state why rework would be needed",{"type":47,"tag":93,"props":2522,"children":2523},{},[2524,2529,2531,2537,2539,2544,2545,2550,2552,2557,2559,2564,2566,2572,2574,2579],{"type":47,"tag":83,"props":2525,"children":2526},{},[2527],{"type":53,"value":2528},"Extensibility config permissions alternative",{"type":53,"value":2530},": Only mention ",{"type":47,"tag":62,"props":2532,"children":2534},{"className":2533},[],[2535],{"type":53,"value":2536},"pluginConfigurations.permissions",{"type":53,"value":2538}," in the README if (a) the developer explicitly asked about extensibility configurations, or (b) every generated build action is exclusively a ",{"type":47,"tag":62,"props":2540,"children":2542},{"className":2541},[],[2543],{"type":53,"value":965},{"type":53,"value":1792},{"type":47,"tag":62,"props":2546,"children":2548},{"className":2547},[],[2549],{"type":53,"value":1519},{"type":53,"value":2551}," entry and\u002For a ",{"type":47,"tag":62,"props":2553,"children":2555},{"className":2554},[],[2556],{"type":53,"value":1203},{"type":53,"value":2558}," iOS usage description entry — meaning the entire ",{"type":47,"tag":62,"props":2560,"children":2562},{"className":2561},[],[2563],{"type":53,"value":67},{"type":53,"value":2565}," could be replaced by the ",{"type":47,"tag":62,"props":2567,"children":2569},{"className":2568},[],[2570],{"type":53,"value":2571},"permissions",{"type":53,"value":2573}," block in the library extensibility configuration. In all other cases omit it; the reference is in ",{"type":47,"tag":2575,"props":2576,"children":2577},"a",{"href":897},[2578],{"type":53,"value":897},{"type":53,"value":457},{"type":47,"tag":56,"props":2581,"children":2582},{},[2583],{"type":47,"tag":83,"props":2584,"children":2585},{},[2586],{"type":53,"value":2587},"Terminal output after generating both files:",{"type":47,"tag":89,"props":2589,"children":2590},{},[2591,2603,2608,2639,2662,2667],{"type":47,"tag":93,"props":2592,"children":2593},{},[2594,2596,2601],{"type":53,"value":2595},"Do not output the ",{"type":47,"tag":62,"props":2597,"children":2599},{"className":2598},[],[2600],{"type":53,"value":67},{"type":53,"value":2602}," contents — the file write already\ndisplays them.",{"type":47,"tag":93,"props":2604,"children":2605},{},[2606],{"type":53,"value":2607},"Do not show analysis tables, scanning decisions, or per-element reasoning in\nthe terminal. Internal reasoning stays internal; noteworthy decisions that did\nnot map cleanly belong in the README, not the terminal.",{"type":47,"tag":93,"props":2609,"children":2610},{},[2611,2613],{"type":53,"value":2612},"Output a single short note: ",{"type":47,"tag":2227,"props":2614,"children":2615},{},[2616,2618,2623,2625,2630,2632,2637],{"type":53,"value":2617},"\"Build actions written to ",{"type":47,"tag":62,"props":2619,"children":2621},{"className":2620},[],[2622],{"type":53,"value":367},{"type":53,"value":2624},". This is a candidate — review ",{"type":47,"tag":62,"props":2626,"children":2628},{"className":2627},[],[2629],{"type":53,"value":381},{"type":53,"value":2631}," before use, then validate with a MABS 12+ build and functional tests against a real mobile app. See ",{"type":47,"tag":62,"props":2633,"children":2635},{"className":2634},[],[2636],{"type":53,"value":392},{"type":53,"value":2638}," for a summary of what this configures and ODC setup instructions.\"",{"type":47,"tag":93,"props":2640,"children":2641},{},[2642,2643,2648,2650],{"type":53,"value":1424},{"type":47,"tag":62,"props":2644,"children":2646},{"className":2645},[],[2647],{"type":53,"value":2378},{"type":53,"value":2649}," was written to the README, add one\nadditional line: ",{"type":47,"tag":2227,"props":2651,"children":2652},{},[2653,2655,2660],{"type":53,"value":2654},"\"Some hooks or elements could not be mapped to build\nactions — see ",{"type":47,"tag":62,"props":2656,"children":2658},{"className":2657},[],[2659],{"type":53,"value":392},{"type":53,"value":2661}," for details.\"",{"type":47,"tag":93,"props":2663,"children":2664},{},[2665],{"type":53,"value":2666},"If the developer did not explicitly mention ODC as the target platform, add\none sentence noting that build actions only take effect in ODC builds, not in\nstandalone Capacitor apps.",{"type":47,"tag":93,"props":2668,"children":2669},{},[2670],{"type":53,"value":2671},"Do not repeat the ODC setup steps in the terminal.",{"type":47,"tag":2673,"props":2674,"children":2675},"style",{},[2676],{"type":53,"value":2677},"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":2679,"total":523},[2680,2689,2702],{"slug":4,"name":4,"fn":5,"description":6,"org":2681,"tags":2682,"stars":30,"repoUrl":31,"updatedAt":32},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2683,2684,2685,2686,2687,2688],{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":27,"slug":28,"type":16},{"name":9,"slug":8,"type":16},{"name":18,"slug":19,"type":16},{"name":21,"slug":22,"type":16},{"slug":2690,"name":2690,"fn":2691,"description":2692,"org":2693,"tags":2694,"stars":30,"repoUrl":31,"updatedAt":2701},"capacitor-plugin-generator","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},[2695,2696,2699,2700],{"name":24,"slug":25,"type":16},{"name":2697,"slug":2698,"type":16},"Engineering","engineering",{"name":9,"slug":8,"type":16},{"name":21,"slug":22,"type":16},"2026-07-12T07:37:44.39093",{"slug":1641,"name":1641,"fn":2703,"description":2704,"org":2705,"tags":2706,"stars":30,"repoUrl":31,"updatedAt":2715},"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},[2707,2708,2709,2710,2711,2714],{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":9,"slug":8,"type":16},{"name":18,"slug":19,"type":16},{"name":2712,"slug":2713,"type":16},"Migration","migration",{"name":21,"slug":22,"type":16},"2026-07-12T07:37:43.055071",{"items":2717,"total":523},[2718,2727,2734],{"slug":4,"name":4,"fn":5,"description":6,"org":2719,"tags":2720,"stars":30,"repoUrl":31,"updatedAt":32},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2721,2722,2723,2724,2725,2726],{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":27,"slug":28,"type":16},{"name":9,"slug":8,"type":16},{"name":18,"slug":19,"type":16},{"name":21,"slug":22,"type":16},{"slug":2690,"name":2690,"fn":2691,"description":2692,"org":2728,"tags":2729,"stars":30,"repoUrl":31,"updatedAt":2701},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2730,2731,2732,2733],{"name":24,"slug":25,"type":16},{"name":2697,"slug":2698,"type":16},{"name":9,"slug":8,"type":16},{"name":21,"slug":22,"type":16},{"slug":1641,"name":1641,"fn":2703,"description":2704,"org":2735,"tags":2736,"stars":30,"repoUrl":31,"updatedAt":2715},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2737,2738,2739,2740,2741,2742],{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":9,"slug":8,"type":16},{"name":18,"slug":19,"type":16},{"name":2712,"slug":2713,"type":16},{"name":21,"slug":22,"type":16}]