$npx -y skills add microsoft/power-platform-skills --skill setup-offline-profileUse when the user wants to enable offline mode for a Power Apps mobile app and create a Mobile Offline Profile in Dataverse — designs per-table row scope, relationships, columns, and sync frequency through a 3-gate approval flow.
| 1 | **Shared instructions: [shared-instructions.md](${CLAUDE_SKILL_DIR}/../../shared/shared-instructions.md)** — read first. |
| 2 | |
| 3 | **References:** |
| 4 | |
| 5 | - [offline-profile-schema.md](${CLAUDE_SKILL_DIR}/../../shared/references/offline-profile-schema.md) — Dataverse entity field map |
| 6 | - [dataverse-offline-api.md](${CLAUDE_SKILL_DIR}/../../shared/references/dataverse-offline-api.md) — Web API recipes for profile / item / association POSTs |
| 7 | - [offline-profile-reconciliation.md](${CLAUDE_SKILL_DIR}/../../shared/references/offline-profile-reconciliation.md) — the `schemaColumns` baseline this skill writes + the lifecycle delta check that consumes it |
| 8 | |
| 9 | # Setup Offline Profile |
| 10 | |
| 11 | End-to-end wizard for creating a Dataverse Mobile Offline Profile that the app (and any other compatible Power Apps client) can use to download data for offline access. |
| 12 | |
| 13 | **Scope of v0**: authoring only. This skill creates the Dataverse entities (`mobileofflineprofile`, `mobileofflineprofileitem`, `mobileofflineprofileitemassociation`) and writes the full app-level offline config — profile metadata, per-table scope, and the temporary SDK-workaround fields — to `offline-profile.json`. **This skill does NOT modify `power.config.json`** (that file is owned by `npx power-apps init` and its schema is controlled upstream). It also does NOT scaffold an offline runtime (SQLite store, sync engine, write queue) in the generated app — that's gated on upstream `@microsoft/power-apps-native-host` runtime support. |
| 14 | |
| 15 | **Out of scope for v0**: |
| 16 | - Custom filter mode (`recorddistributioncriteria=3`, savedquery picker) — defer to v0.5 |
| 17 | - User/team membership assignment — split into `/assign-offline-profile` |
| 18 | - Row-count download estimation — split into `/preview-offline-scope` |
| 19 | |
| 20 | ## Workflow |
| 21 | |
| 22 | 1. Verify project & auth → 2. Resolve mode (create vs extend) → 3. Spawn architect agent → **Gate 1** (table prerequisites) → 4. Run `/enable-tables-offline` if needed → 5. POST profile shell → **Gate 2** (per-table row scope) → 6. POST profile items → **Gate 3** (relationships + columns + sync) → 7. POST associations → 8. Validate + publish → 9. Persist artifacts → 10. Summary |
| 23 | |
| 24 | --- |
| 25 | |
| 26 | ### Step 1 — Verify project & auth |
| 27 | |
| 28 | ```bash |
| 29 | test -f power.config.json && test -f app.config.js |
| 30 | # Manifest lives at either root (legacy) or docs/plan-artifacts/ (newer scaffolds) |
| 31 | MANIFEST=$(test -f .datamodel-manifest.json && echo ".datamodel-manifest.json" || \ |
| 32 | (test -f docs/plan-artifacts/.datamodel-manifest.json && echo "docs/plan-artifacts/.datamodel-manifest.json")) |
| 33 | test -n "$MANIFEST" && echo "✓ manifest at $MANIFEST" |
| 34 | node "${CLAUDE_SKILL_DIR}/../../scripts/resolve-environment.js" "$(node -e \"console.log(require('./power.config.json').environmentId)\")" |
| 35 | ``` |
| 36 | |
| 37 | Capture **Environment URL** for `<envUrl>` and **manifest path** for the architect spawn (Step 3) and the artifacts write (Step 9). |
| 38 | |
| 39 | **Web-only target detection** — Mobile Offline Profiles only apply to native targets (iOS/Android). If the project is web-only, the profile will be created in Dataverse but **the generated app will never use it**: |
| 40 | |
| 41 | ```bash |
| 42 | # Inspect platforms declared in app.config.js |
| 43 | node -e " |
| 44 | const c = require('$(pwd)/app.config.js'); |
| 45 | const platforms = c?.expo?.platforms ?? []; |
| 46 | const hasNative = platforms.includes('ios') || platforms.includes('android'); |
| 47 | console.log(JSON.stringify({ platforms, hasNative })); |
| 48 | " 2>/dev/null |
| 49 | ``` |
| 50 | |
| 51 | | `hasNative` | Action | |
| 52 | |---|---| |
| 53 | | `true` (has `ios` and/or `android`) | Continue normally | |
| 54 | | `false` (web-only or no platforms) | Print: `⚠ This project only targets web — Mobile Offline Profiles don't apply (they require iOS/Android). Continuing will create the profile in Dataverse but no app will use it.` Ask via `AskUserQuestion`: "Continue anyway?" Default No. | |
| 55 | | Parse error / app.config.js missing key | Warn, but assume native (don't block on a parser quirk) | |
| 56 | |
| 57 | STOP conditions: |
| 58 | - No `power.config.json` → "Run `/create-mobile-app` first." |
| 59 | - Neither `.datamodel-manifest.json` nor `docs/plan-artifacts/.datamodel-manifest.json` → "Run `/add-dataverse` first — offline profiles require a data model." |
| 60 | - Environment resolution failure → standard auth recovery (`az login --tenant <env-tenant>` or provide environment URL directly; see [shared-instructions.md](${CLAUDE_SKILL_DIR}/../../shared/shared-instructions.md)). |
| 61 | - Web-only + user declines override → STOP. Print: `Offline profile creation skipped — no native target.` |
| 62 | |
| 63 | #### Step 1a — Environment consistency check |
| 64 | |
| 65 | Same as `/add-dataverse` Step 3a — verify `power.config.json` resolves and `az` can token for the target tenant. STOP if it cannot; use |