$npx -y skills add microsoft/power-platform-skills --skill add-table-to-offline-profileUse when the user wants to add ONE table (typically a newly-added Dataverse table) to an existing offline profile without re-running the full /setup-offline-profile wizard. Parallel to /add-dataverse — same single-table flow.
| 1 | **Shared instructions: [shared-instructions.md](${CLAUDE_SKILL_DIR}/../../shared/shared-instructions.md)** — read first. |
| 2 | |
| 3 | **References:** |
| 4 | |
| 5 | - [dataverse-offline-api.md](${CLAUDE_SKILL_DIR}/../../shared/references/dataverse-offline-api.md) §4 + §7 — POST item + PATCH selectedcolumns |
| 6 | - [offline-profile-reconciliation.md](${CLAUDE_SKILL_DIR}/../../shared/references/offline-profile-reconciliation.md) — the `schemaColumns` baseline written in Step 7 |
| 7 | |
| 8 | # Add Table to Offline Profile |
| 9 | |
| 10 | Add a single table to an existing Mobile Offline Profile. Most common flow: user ran `/add-dataverse` to add a new table to their app, now wants that table available offline too. |
| 11 | |
| 12 | Equivalent to running `/setup-offline-profile` and seeing the existing profile (extend-mode), but skips the per-table questionnaire for the tables already in the profile — only configures the new one. |
| 13 | |
| 14 | ## Workflow |
| 15 | |
| 16 | 1. Verify project + locate profile → 2. Resolve target table → 3. Prereq check (auto-enable if needed) → 4. Scope picker (single question) → 5. POST item + PATCH selectedcolumns → 6. Publish → 7. Update artifacts → 8. Summary |
| 17 | |
| 18 | --- |
| 19 | |
| 20 | ### Step 1 — Verify project + locate profile |
| 21 | |
| 22 | ```bash |
| 23 | test -f power.config.json |
| 24 | node "${CLAUDE_SKILL_DIR}/../../scripts/resolve-environment.js" "$(node -e \"console.log(require('./power.config.json').environmentId)\")" |
| 25 | ``` |
| 26 | |
| 27 | Manifest path (dual-location): |
| 28 | |
| 29 | ```bash |
| 30 | MANIFEST=$(test -f .datamodel-manifest.json && echo ".datamodel-manifest.json" || \ |
| 31 | (test -f docs/plan-artifacts/.datamodel-manifest.json && echo "docs/plan-artifacts/.datamodel-manifest.json")) |
| 32 | test -n "$MANIFEST" && echo "✓ manifest at $MANIFEST" |
| 33 | ``` |
| 34 | |
| 35 | Profile ID resolution (same as `/edit-offline-profile`). |
| 36 | |
| 37 | STOP if no profile exists. Recommend: `Run /setup-offline-profile first to create the profile.` |
| 38 | |
| 39 | ### Step 2 — Resolve target table |
| 40 | |
| 41 | `$ARGUMENTS` parsing: |
| 42 | |
| 43 | | Flag | Effect | |
| 44 | |---|---| |
| 45 | | `--table <logical-name>` | Explicit target | |
| 46 | | `--all-new` | Add ALL tables in the manifest that aren't already in the profile (bulk mode) | |
| 47 | | (no flags) | Interactive: list tables in manifest NOT yet in profile via `AskUserQuestion` (max 4); if more than 4 candidates, prompt user to specify by name in next message | |
| 48 | |
| 49 | For bulk `--all-new` mode, loop through Steps 3-6 for each missing table; each runs sequentially because Dataverse profile-item POSTs serialize. |
| 50 | |
| 51 | ### Step 3 — Prereq check (auto-enable if needed) |
| 52 | |
| 53 | Query the target table's `EntityMetadata`: |
| 54 | |
| 55 | ```bash |
| 56 | node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> GET \ |
| 57 | "EntityDefinitions(LogicalName='<table>')?\$select=IsAvailableOffline,ChangeTrackingEnabled,OwnershipType,IsCustomizable" |
| 58 | ``` |
| 59 | |
| 60 | | Flags state | Action | |
| 61 | |---|---| |
| 62 | | Both already `true` | Skip to Step 4 | |
| 63 | | Either `false` AND IsCustomizable | Auto-enable via `update-entity-offline-flags.js` (no prompt — the user already opted into "offline this table" by invoking this skill) | |
| 64 | | `IsCustomizable.Value = false` | STOP with `BLOCKED: <table> is system-managed and cannot be flagged for offline. Use a different table or accept this row is read-only-offline.` | |
| 65 | |
| 66 | After auto-enable, single `POST PublishAllXml`. |
| 67 | |
| 68 | ### Step 4 — Scope picker (single question) |
| 69 | |
| 70 | Pull from manifest the target table's `lookups[]` to inform defaults. Run a quick row-count probe to inform reference-data classification. |
| 71 | |
| 72 | `AskUserQuestion` with 4 options reflecting the architect's priority cascade: |
| 73 | |
| 74 | | Option label | Maps to | |
| 75 | |---|---| |
| 76 | | `Organization rows — User's rows only (Recommended for most tables)` | `recorddistributioncriteria: 2`, `recordsownedbyme: true` | |
| 77 | | `All records (for small reference data)` | `recorddistributioncriteria: 1` | |
| 78 | | `Related rows only (for pure child tables)` | `recorddistributioncriteria: 0` | |
| 79 | | `Custom — specify exact flags in next message` | Prompt user with text | |
| 80 | |
| 81 | Recommendation in the question body should be derived from the architect's heuristics for the table being added (use the same priority cascade from `offline-profile-architect.md` Step 4 inline). The user can override. |
| 82 | |
| 83 | ### Step 5 — POST item + associations + PATCH selectedcolumns |
| 84 | |
| 85 | #### Step 5a — POST profile item |
| 86 | |
| 87 | ```bash |
| 88 | node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> POST \ |
| 89 | "mobileofflineprofileitems" \ |
| 90 | --body '{ |
| 91 | "name": "<DisplayName>", |
| 92 | "regardingobjectid@odata.bind": "/mobileofflineprofiles(<profileId>)", |
| 93 | "selectedentitytypecode": "<table>", |
| 94 | "recorddistributioncriteria": <0|1|2>, |
| 95 | "recordsownedbyme": <bool>, |
| 96 | "recordsownedbymyteam": false, |
| 97 | "recordsownedbymybusinessunit": false, |
| 98 | "getrelatedentityrecords": true, |
| 99 | "syncintervalinminu |