plugins/mobile-apps/skills/edit-offline-profile/SKILL.md
Use 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.
npx skillsauth add microsoft/power-platform-skills edit-offline-profileInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Shared instructions: shared-instructions.md — read first.
References:
schemaColumns baseline after a column editRe-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.
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.
test -f power.config.json
node "${CLAUDE_SKILL_DIR}/../../scripts/resolve-environment.js" "$(node -e \"console.log(require('./power.config.json').environmentId)\")"
Profile ID resolution (same priority as /assign-offline-profile Step 1):
| Source | Used when |
|---|---|
| $ARGUMENTS --profile-id <guid> | Explicit override |
| offline-profile.json top-level profileId in cwd | Default for /setup-offline-profile-created projects |
| Otherwise | AskUserQuestion with list from GET /mobileofflineprofiles |
STOP if no profile found: "Run /setup-offline-profile first."
power.config.jsonis intentionally NOT consulted here. That file is owned bynpx power-apps init. The profile ID lives inoffline-profile.jsononly.
Parse $ARGUMENTS:
| Flag pattern | Effect |
|---|---|
| --rename <new-name> | Update profile name |
| --describe <text> | Update profile description |
| --table <logical-name> --scope <0\|1\|2> | Change one table's recorddistributioncriteria. Combine with --me, --team, --bu to set sub-flags when scope=2. |
| --table <logical-name> --sync <minutes> | Change one table's syncintervalinminutes (range 5–1440) |
| --table <logical-name> --columns add:col1,col2 remove:col3 | Add or remove logical names from selectedcolumns. Comma-separated, both add/remove optional. |
| --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) |
If no flags → interactive picker. AskUserQuestion with up-to-4 most likely edits:
GET the current item state from Dataverse for any tables being edited:
node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> GET \
"mobileofflineprofileitems(<itemId>)?\$select=name,recorddistributioncriteria,recordsownedbyme,recordsownedbymyteam,recordsownedbymybusinessunit,syncintervalinminutes,selectedcolumns"
Render a current/proposed diff:
Profile : <name> (<id>)
Editing : <table-logical-name> item
Current → Proposed
Scope : Org+me → All records
Sync (min) : 10 → 30
Columns : 14 → 16 (add: chnl_notes, chnl_actual_visit_date)
AskUserQuestion: "Apply this change? [Apply / Cancel]"
If Apply → continue. If Cancel → STOP.
Build the PATCH body with only the fields that changed:
node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> PATCH \
"mobileofflineprofileitems(<itemId>)" \
--body '{
"recorddistributioncriteria": <new>,
"recordsownedbyme": <new-bool>,
"syncintervalinminutes": <new>,
"selectedcolumns": "{\"Columns\":[...]}"
}'
For profile-level edits (name / description):
node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> PATCH \
"mobileofflineprofiles(<profileId>)" \
--body '{"name": "...", "description": "..."}'
Use the targeted PublishXml recipe from shared/references/dataverse-offline-api.md §9:
node "${CLAUDE_SKILL_DIR}/../../scripts/dataverse-request.js" <envUrl> POST \
"PublishXml" --body '{
"ParameterXml": "<publish><mobileofflineprofiles><mobileofflineprofile>'"$PROFILE_ID"'</mobileofflineprofile></mobileofflineprofiles></publish>"
}'
Publishes only this profile, not the entire org's customizations. Avoids the 429 rate-limit storms on shared envs that the legacy PublishAllXml triggered.
On 400 / 0x80071141 "circular relationship" — same handling as /setup-offline-profile Step 8 (parse cycle path, prompt user to drop one association, retry). Fallback to PublishAllXml only if PublishXml returns an unexpected error other than the cycle case.
Re-read the changed item(s) and rewrite the matching entry in offline-profile.json. When the edit changed a table's columns (--columns add:/remove:/reset), also refresh that table entry's schemaColumns to the table's current full column set from .datamodel-manifest.json (root or docs/plan-artifacts/). This re-baselines the schema-reconciliation marker so a delta that was just reconciled clears on the next scripts/offline-profile-delta.js run; leave schemaColumns untouched for scope/sync/rename-only edits. See offline-profile-reconciliation.md.
Append a one-line entry to memory-bank.md ## Offline profile block:
edits:
- { at: 2026-05-19T..., field: 'chnl_storevisit.syncintervalinminutes', from: 5, to: 10 }
✓ Edited profile.
Field : chnl_storevisit.syncintervalinminutes
From : 5 min
To : 10 min
Published: 2026-05-19T...
offline-profile.json + memory-bank.md updated.
DONE — change applied and publishedDONE_WITH_CONCERNS: <list> — change applied but with caveats (publish timeout-then-success, etc.)NEEDS_CONTEXT: <missing> — couldn't resolve target table or profileBLOCKED: <reason> — auth or PATCH failure/add-table-to-offline-profileselectedrelationshipsschema work; use maker portal in the meantimeDELETE /mobileofflineprofiles(<id>) (cascade-deletes items + associations); see dataverse-offline-api.md §11CloneMobileOfflineProfile action (v0.5 work)tools
Adds Work IQ (M365 Copilot Search) to a Power Apps code app via the Work IQ Copilot MCP connector (shared_a365copilotchatmcp), then wires up a production-ready McpSession wrapper for AI-powered, knowledge-grounded search and chat. Use when integrating Microsoft 365 Copilot search/chat. The CopilotChat tool searches internal Microsoft 365 content (documents, emails, chats, sites, files) across your organization — prefer workload-specific tools (SharePoint, OneDrive, Teams, Mail) when the workload is explicit; do not use it for general knowledge, news, public web, or external information.
tools
Use when the user wants to preview generated screens in a browser without starting Metro / a simulator — for example after /create-mobile-app finishes or after /edit-app regenerates a screen.
development
Use when the user wants to iterate on an existing generated Power Apps mobile app after /create-mobile-app: update the plan, data model, native capabilities, design, screens, generated app code, and preview without restarting the full project flow.
development
Creates and manages the brand design system for a Power Apps mobile app. Generates brand/design-system.md (source of truth), brand/tokens.ts (importable Tamagui tokens), and brand/design-system.html (visual gallery). Triggered at Step 6.5 of /create-mobile-app, or standalone via /design-system.