$npx -y skills add microsoft/power-platform-skills --skill edit-offline-profileUse when the user wants to change ONE aspect of an existing offline profile (row scope for a table, column list, sync frequency) without re-running the full /setup-offline-profile wizard. Mirrors the /edit-app gated edit pattern.
| 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) — refreshing the `schemaColumns` baseline after a column edit |
| 7 | |
| 8 | # Edit Offline Profile |
| 9 | |
| 10 | Re-run a single piece of an existing profile — change one table's row scope, update the column list, adjust sync frequency, or rename the profile. Avoids the cognitive cost of walking the full /setup-offline-profile wizard for a one-line change. |
| 11 | |
| 12 | Scope: existing profile (read from `offline-profile.json` or `--profile-id`); edits at the table-item granularity. To ADD a new table see `/add-table-to-offline-profile`; to delete the entire profile see [dataverse-offline-api.md §11](${CLAUDE_SKILL_DIR}/../../shared/references/dataverse-offline-api.md). |
| 13 | |
| 14 | ## Workflow |
| 15 | |
| 16 | 1. Verify project + locate profile → 2. Resolve target (which table / what to change) → 3. Show current vs proposed → Single confirm → 4. PATCH → 5. Publish → 6. Update artifacts → 7. 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 | Profile ID resolution (same priority as `/assign-offline-profile` Step 1): |
| 28 | |
| 29 | | Source | Used when | |
| 30 | |---|---| |
| 31 | | `$ARGUMENTS` `--profile-id <guid>` | Explicit override | |
| 32 | | `offline-profile.json` top-level `profileId` in cwd | Default for `/setup-offline-profile`-created projects | |
| 33 | | Otherwise | `AskUserQuestion` with list from `GET /mobileofflineprofiles` | |
| 34 | |
| 35 | STOP if no profile found: "Run `/setup-offline-profile` first." |
| 36 | |
| 37 | > **`power.config.json` is intentionally NOT consulted here.** That file is owned by `npx power-apps init`. The profile ID lives in `offline-profile.json` only. |
| 38 | |
| 39 | ### Step 2 — Resolve target (what to edit) |
| 40 | |
| 41 | Parse `$ARGUMENTS`: |
| 42 | |
| 43 | | Flag pattern | Effect | |
| 44 | |---|---| |
| 45 | | `--rename <new-name>` | Update profile `name` | |
| 46 | | `--describe <text>` | Update profile `description` | |
| 47 | | `--table <logical-name> --scope <0\|1\|2>` | Change one table's `recorddistributioncriteria`. Combine with `--me`, `--team`, `--bu` to set sub-flags when scope=2. | |
| 48 | | `--table <logical-name> --sync <minutes>` | Change one table's `syncintervalinminutes` (range 5–1440) | |
| 49 | | `--table <logical-name> --columns add:col1,col2 remove:col3` | Add or remove logical names from `selectedcolumns`. Comma-separated, both add/remove optional. | |
| 50 | | `--table <logical-name> --columns reset` | Replace selectedcolumns with union of always-include + manifest lookups + screen-grep'd (re-runs the architect's Step 6 union for this table) | |
| 51 | |
| 52 | If no flags → interactive picker. `AskUserQuestion` with up-to-4 most likely edits: |
| 53 | - "Rename profile" |
| 54 | - "Change a table's scope" → next message asks which table |
| 55 | - "Change a table's sync frequency" → next message asks which table + value |
| 56 | - "Edit a table's column list" → next message asks which table + add/remove |
| 57 | |
| 58 | ### Step 3 — Show current vs proposed (single gate) |
| 59 | |
| 60 | GET the current item state from Dataverse for any tables being edited: |
| 61 | |
| 62 | ```bash |
| 63 | node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> GET \ |
| 64 | "mobileofflineprofileitems(<itemId>)?\$select=name,recorddistributioncriteria,recordsownedbyme,recordsownedbymyteam,recordsownedbymybusinessunit,syncintervalinminutes,selectedcolumns" |
| 65 | ``` |
| 66 | |
| 67 | Render a current/proposed diff: |
| 68 | |
| 69 | ``` |
| 70 | Profile : <name> (<id>) |
| 71 | Editing : <table-logical-name> item |
| 72 | |
| 73 | Current → Proposed |
| 74 | Scope : Org+me → All records |
| 75 | Sync (min) : 10 → 30 |
| 76 | Columns : 14 → 16 (add: chnl_notes, chnl_actual_visit_date) |
| 77 | ``` |
| 78 | |
| 79 | `AskUserQuestion`: "Apply this change? [Apply / Cancel]" |
| 80 | |
| 81 | If `Apply` → continue. If `Cancel` → STOP. |
| 82 | |
| 83 | ### Step 4 — PATCH |
| 84 | |
| 85 | Build the PATCH body with only the fields that changed: |
| 86 | |
| 87 | ```bash |
| 88 | node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> PATCH \ |
| 89 | "mobileofflineprofileitems(<itemId>)" \ |
| 90 | --body '{ |
| 91 | "recorddistributioncriteria": <new>, |
| 92 | "recordsownedbyme": <new-bool>, |
| 93 | "syncintervalinminutes": <new>, |
| 94 | "selectedcolumns": "{\"Columns\":[...]}" |
| 95 | }' |
| 96 | ``` |
| 97 | |
| 98 | For profile-level edits (name / description): |
| 99 | |
| 100 | ```bash |
| 101 | node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> PATCH \ |
| 102 | "mobileofflineprofiles(<profileId>)" \ |
| 103 | --body '{"name": "...", "description": " |