[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699NXTQZBWH81FXSAXSN4S3":3,"skill-same:01M699NXTQZBWH81FXSAXSN4S3":74},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":51,"commitSha":52,"skillDirectory":53,"forksCount":54,"repositoryHtmlUrl":55,"repositoryHomepageUrl":56,"ownerHtmlUrl":57,"ownerBlogUrl":58,"ownerDescription":59,"updatedAt":60,"install":61,"resources":73},"01M699NXTQZBWH81FXSAXSN4S3","edit-offline-profile",null,"Internal mobile-app workflow read and executed only by mobile orchestrators to change one table's scope, columns, or sync settings in a Mobile Offline Profile.","microsoft\u002Fpower-platform-skills","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M699JVYJFB75D9JM70BN4H0Q",1134,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fmobile-apps\u002Fskills\u002Fedit-offline-profile\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"edit offline profile","offline","edit","profile","settings","true","sonnet","columns","scope","false","app","mobile","only","workflow","write","read","table","Bash","sync","change","2026-11-10 10:12:30",false,"---\nname: edit-offline-profile\ndescription: Internal mobile-app workflow read and executed only by mobile orchestrators to change one table's scope, columns, or sync settings in a Mobile Offline Profile.\nuser-invocable: false\ndisable-model-invocation: true\nallowed-tools: Read, Edit, Write, Grep, Glob, Bash, AskUserQuestion\nmodel: sonnet\n---\n\n**Shared instructions: [shared-instructions.md](${PLUGIN_ROOT}\u002Fshared\u002Fshared-instructions.md)** — read first.\n\n**References:**\n\n- [dataverse-offline-api.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fdataverse-offline-api.md) §4 \u002F §7 — POST item + PATCH selectedcolumns\n- [offline-profile-reconciliation.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Foffline-profile-reconciliation.md) — refreshing the `schemaColumns` baseline after a column edit\n\n# Edit Offline Profile\n\nRe-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 \u002Fsetup-offline-profile wizard for a one-line change.\n\nScope: existing profile (read from `\u003Cworking_dir>\u002Foffline-profile.json` or\n`--profile-id`); edits at the table-item granularity. To ADD a new table return to\nthe owner for `\u002Fadd-table-to-offline-profile`; deleting an entire profile is\noutside this helper's scope, not an automatic recovery.\n\n## Invocation context and root binding\n\nThis internal helper is always a **child invocation**. Before any project read or\ncommand, execute [app-working-directory.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fapp-working-directory.md).\nRequire the owner's absolute `working_dir`; `--working-dir`, when supplied, must\nidentify that same native-canonical root. Missing, relative, or conflicting root\ncontext returns `NEEDS_CONTEXT` before project access; an inaccessible directory\nis `BLOCKED`. Never use the launch cwd or introduce another root resolver.\n\nReceive `MOBILE_APP_ORCHESTRATING=1`, `orchestrator`, `working_dir`, `phase`,\n`approved_scope`, and supplied answers from the owner. Preserve the selected\nenvironment ID\u002FURL\u002Ftenant, profile ID, table allowlist, item IDs, and exact\nscope\u002Fcolumn\u002Fsync\u002Fname\u002Fdescription changes. Missing or conflicting scope returns\n`NEEDS_CONTEXT`, not another environment\u002Fprofile\u002Ftable selection. The marker is\nnot approval: schema approval alone does not authorize profile edits, publication,\ndeletion, or membership edits. Retain Step 3's single confirm unless supplied\nanswers already approve that same current offline change.\nFor `--plan-only` or a planning-phase handoff, return the current\u002Fproposed diff\nafter read-only discovery and STOP before Apply, PATCH, publication, or artifact\nwrites. A gate response cannot lift proposal-only mode.\n\nApply the canonical contract to **every shell call and file tool**, including\nversion\u002Fauth checks, manifest\u002Fscreen reads, commands copied from references,\nverification, recovery, and retries. Re-supply the absolute `PLUGIN_ROOT` and\nrequired context on each call; no prior `cd`, export, or shell variable persists.\nUse the canonical Bash guard below or its PowerShell equivalent. Replace\nplaceholders with validated, shell-quoted invocation values; missing values\nreturn `NEEDS_CONTEXT`, never execute an unresolved placeholder.\nFile tools use absolute `\u003Cworking_dir>\u002F...` paths; plugin reads\u002Fscripts use\n`${PLUGIN_ROOT}\u002F...`. Never search another app when a file is absent.\n\n## Workflow\n\n1. Verify project + locate profile → 2. Resolve target (which table \u002F what to change) → 3. Show current vs proposed → Single confirm → 4. PATCH → 5. Publish → 6. Update artifacts → 7. Summary\n\n---\n\n### Step 1 — Verify project + locate profile\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nif [ ! -f power.config.json ] || [ ! -f app.config.js ]; then\n  echo \"BLOCKED: working_dir is not an initialized app\" >&2\n  exit 1\nfi\n```\n\nRead `\u003Cworking_dir>\u002Fpower.config.json` and require a nonempty `environmentId`\nmatching the owner's selected environment. Reuse matching complete environment\ncontext, or perform this non-persisting lookup from the bound root:\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nenvironment_id=$(node -p \"require('.\u002Fpower.config.json').environmentId || ''\") || {\n  echo \"BLOCKED: unreadable power.config.json\" >&2; exit 1;\n}\nif [ -z \"$environment_id\" ] || [ \"$environment_id\" != \"\u003Cselected-environment-id>\" ]; then\n  echo \"NEEDS_CONTEXT: selected environment does not match working_dir\" >&2\n  exit 1\nfi\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fresolve-environment.js\" \"$environment_id\" --no-cache --require-tenant\n```\n\nRequire the returned environment ID, HTTPS URL, and tenant to match the owner;\nincomplete or conflicting context returns `NEEDS_CONTEXT`. Never drop\n`--no-cache --require-tenant`, change configuration, or switch auth\u002Fenvironment\nto recover a failure. Use that exact `\u003CenvUrl>` and `\u003CtenantId>` for every request.\n\nProfile ID resolution (same priority as `\u002Fassign-offline-profile` Step 1):\n\n| Source | Used when |\n|---|---|\n| `$ARGUMENTS` `--profile-id \u003Cguid>` | Explicit selection matching the owner's profile context |\n| `\u003Cworking_dir>\u002Foffline-profile.json` top-level `profileId` | Default for `\u002Fsetup-offline-profile`-created projects, matching the owner's profile context |\n| Otherwise | Return `NEEDS_CONTEXT` to the owner to select the intended profile; never pick another profile silently |\n\nSTOP if no profile found: \"Run `\u002Fsetup-offline-profile` first.\"\n\nVerify the selected live profile belongs to the selected environment. A conflicting\nsnapshot\u002Fargument returns `NEEDS_CONTEXT`; a 404 or permission failure is\n`BLOCKED`, not permission to discover a substitute. Resolve each `\u003CitemId>` only\nwithin this profile and verify its table matches the exact requested logical name.\n\n> **`\u003Cworking_dir>\u002Fpower.config.json` is intentionally NOT consulted for the profile ID.**\n> That file is owned by `pa app init`. The local profile ID lives in\n> `\u003Cworking_dir>\u002Foffline-profile.json` only.\n\n### Step 2 — Resolve target (what to edit)\n\nParse `$ARGUMENTS`:\n\n| Flag pattern | Effect |\n|---|---|\n| `--rename \u003Cnew-name>` | Update profile `name` |\n| `--describe \u003Ctext>` | Update profile `description` |\n| `--table \u003Clogical-name> --scope \u003C0\\|1\\|2>` | Change one table's `recorddistributioncriteria`. Combine with `--me`, `--team`, `--bu` to set sub-flags when scope=2. |\n| `--table \u003Clogical-name> --sync \u003Cminutes>` | Change one table's `syncintervalinminutes` (range 5–1440) |\n| `--table \u003Clogical-name> --columns add:col1,col2 remove:col3` | Add or remove logical names from `selectedcolumns`. Comma-separated, both add\u002Fremove optional. |\n| `--table \u003Clogical-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) |\n\nIf no flags → interactive picker. `AskUserQuestion` with up-to-4 most likely edits:\n- \"Rename profile\"\n- \"Change a table's scope\" → next message asks which table\n- \"Change a table's sync frequency\" → next message asks which table + value\n- \"Edit a table's column list\" → next message asks which table + add\u002Fremove\n\nRestrict the picker and explicit flags to the owner's exact current scope.\n`--columns reset` reads the selected table from\n`\u003Cworking_dir>\u002F.datamodel-manifest.json` or\n`\u003Cworking_dir>\u002Fdocs\u002Fplan-artifacts\u002F.datamodel-manifest.json` and greps only\nabsolute `\u003Cworking_dir>\u002Fapp\u002F` and `\u003Cworking_dir>\u002Fsrc\u002F` paths. Keep the chosen\nabsolute manifest path for the whole invocation; no other-app fallback.\nChanging the table, profile, or operation requires returning `NEEDS_CONTEXT`\nto the owner, not expanding an existing approval.\n\n### Step 3 — Show current vs proposed (single gate)\n\nGET the current item state from Dataverse for any tables being edited:\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fdataverse-request.js\" \"\u003CenvUrl>\" GET \\\n  \"mobileofflineprofileitems(\u003CitemId>)?\\$select=name,recorddistributioncriteria,recordsownedbyme,recordsownedbymyteam,recordsownedbymybusinessunit,syncintervalinminutes,selectedcolumns\" \\\n  --tenant-id \"\u003CtenantId>\"\n```\n\nRender a current\u002Fproposed diff:\n\n```\nProfile  : \u003Cname> (\u003Cid>)\nEditing  : \u003Ctable-logical-name> item\n\n                Current     →    Proposed\nScope         : Org+me     →    All records\nSync (min)    : 10         →    30\nColumns       : 14         →    16  (add: chnl_notes, chnl_actual_visit_date)\n```\n\n`AskUserQuestion`: \"Apply this change? [Apply \u002F Cancel]\"\n\nIf `Apply` → continue. If `Cancel` → STOP.\n\n### Step 4 — PATCH\n\nBuild the PATCH body with only the fields that changed:\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fdataverse-request.js\" \"\u003CenvUrl>\" PATCH \\\n  \"mobileofflineprofileitems(\u003CitemId>)\" --tenant-id \"\u003CtenantId>\" \\\n  --body '{\n    \"recorddistributioncriteria\": \u003Cnew>,\n    \"recordsownedbyme\": \u003Cnew-bool>,\n    \"syncintervalinminutes\": \u003Cnew>,\n    \"selectedcolumns\": \"{\\\"Columns\\\":[...]}\"\n  }'\n```\n\nFor profile-level edits (name \u002F description):\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fdataverse-request.js\" \"\u003CenvUrl>\" PATCH \\\n  \"mobileofflineprofiles(\u003CprofileId>)\" --tenant-id \"\u003CtenantId>\" \\\n  --body '{\"name\": \"...\", \"description\": \"...\"}'\n```\n\nCheck returned HTTP statuses as well as process exit. A\n403\u002F`PrivilegeCheckFailed` is `BLOCKED`; do not change identity or profile to\nbypass permissions. Preserve every field and table outside the approved delta.\n\n### Step 5 — Publish\n\nUse the **targeted `PublishXml`** recipe from [shared\u002Freferences\u002Fdataverse-offline-api.md §9](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fdataverse-offline-api.md):\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fdataverse-request.js\" \"\u003CenvUrl>\" POST \\\n  \"PublishXml\" --tenant-id \"\u003CtenantId>\" --body '{\n    \"ParameterXml\": \"\u003Cpublish>\u003Cmobileofflineprofiles>\u003Cmobileofflineprofile>\u003CprofileId>\u003C\u002Fmobileofflineprofile>\u003C\u002Fmobileofflineprofiles>\u003C\u002Fpublish>\"\n  }'\n```\n\nPublishes only this profile, not the entire org's customizations. Avoids the 429 rate-limit storms on shared envs that the legacy `PublishAllXml` triggered.\n\nOn `400 \u002F 0x80071141` \"circular relationship\" — same handling as\n`\u002Fsetup-offline-profile` Step 8 (parse cycle path, prompt user to drop one\nassociation, retry). Fallback to `PublishAllXml` only if `PublishXml` returns an\nunexpected error other than the cycle case **and** the owner\u002Fuser approves that\nbroader publication; a profile-scoped approval does not cover it.\n\nAll linked recovery commands, re-GET verification, and retries must bind the\nsame root and pass the same environment\u002Ftenant\u002Fprofile\u002Ftable\u002Fitem context.\nNever retry on a different profile or bypass a permission failure. Confirm\npublication before Step 6.\n\nIf a linked recipe requires another offline helper, return the proposed change\nto the owner for approval first, then read the helper at its absolute\n`${PLUGIN_ROOT}\u002Fskills\u002F\u003Chelper>\u002FSKILL.md` path. Forward:\n\n```text\nArguments: --working-dir '\u003Cworking_dir>' --profile-id \"\u003CprofileId>\" --table \"\u003Ctable>\" \u003Cexact-approved-change-flags>\nContext: MOBILE_APP_ORCHESTRATING=1, orchestrator, working_dir, phase, approved_scope,\n         selected environment ID\u002FURL\u002Ftenant, profile ID, table allowlist, item ID,\n         supplied answers, --plan-only (if present)\n```\n\nThe recipient must enforce the same canonical root contract. Missing context\nreturns `NEEDS_CONTEXT`; do not fall back to direct invocation or rediscovery.\n\n### Step 6 — Update artifacts\n\nRe-read the changed item(s) in the same profile\u002Fenvironment and rewrite the\nmatching entry in `\u003Cworking_dir>\u002Foffline-profile.json`. When the edit changed a\ntable's **columns** (`--columns add:\u002Fremove:\u002Freset`), also refresh that entry's\n`schemaColumns` to the table's current full column set from the bound absolute\nmanifest. This re-baselines the schema-reconciliation marker for the next\n`${PLUGIN_ROOT}\u002Fscripts\u002Foffline-profile-delta.js` run; leave `schemaColumns`\nuntouched for scope\u002Fsync\u002Frename-only edits. Any delta check uses\n`--project-root '\u003Cworking_dir>'` in its own guarded call. See\n[offline-profile-reconciliation.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Foffline-profile-reconciliation.md).\n\nAppend a one-line entry to `\u003Cworking_dir>\u002Fmemory-bank.md` `## Offline profile` block:\n\n```yaml\nedits:\n  - { at: 2026-05-19T..., field: 'chnl_storevisit.syncintervalinminutes', from: 5, to: 10 }\n```\n\n### Step 7 — Summary\n\n```\n✓ Edited profile.\n\n  Field : chnl_storevisit.syncintervalinminutes\n  From  : 5 min\n  To    : 10 min\n  Published: 2026-05-19T...\n\noffline-profile.json + memory-bank.md updated.\n```\n\n## Status code (final line)\n\n- `DONE` — change applied and published\n- `DONE_WITH_CONCERNS: \u003Clist>` — change applied but with caveats (publish timeout-then-success, etc.)\n- `NEEDS_CONTEXT: \u003Cmissing>` — couldn't resolve target table or profile\n- `BLOCKED: \u003Creason>` — auth or PATCH failure\n\n## What this skill does NOT do\n\n- Add a NEW table to the profile → use `\u002Fadd-table-to-offline-profile`\n- Add a new association (relationship inclusion) → blocked on v0.2 `selectedrelationshipsschema` work; use maker portal in the meantime\n- Delete the whole profile → manual `DELETE \u002Fmobileofflineprofiles(\u003Cid>)` (cascade-deletes items + associations); see [dataverse-offline-api.md §11](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fdataverse-offline-api.md)\n- Migrate the profile between environments → use `CloneMobileOfflineProfile` action (v0.5 work)\n","**Shared instructions: [shared-instructions.md](${PLUGIN_ROOT}\u002Fshared\u002Fshared-instructions.md)** — read first.\n\n**References:**\n\n- [dataverse-offline-api.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fdataverse-offline-api.md) §4 \u002F §7 — POST item + PATCH selectedcolumns\n- [offline-profile-reconciliation.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Foffline-profile-reconciliation.md) — refreshing the `schemaColumns` baseline after a column edit\n\n# Edit Offline Profile\n\nRe-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 \u002Fsetup-offline-profile wizard for a one-line change.\n\nScope: existing profile (read from `\u003Cworking_dir>\u002Foffline-profile.json` or\n`--profile-id`); edits at the table-item granularity. To ADD a new table return to\nthe owner for `\u002Fadd-table-to-offline-profile`; deleting an entire profile is\noutside this helper's scope, not an automatic recovery.\n\n## Invocation context and root binding\n\nThis internal helper is always a **child invocation**. Before any project read or\ncommand, execute [app-working-directory.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fapp-working-directory.md).\nRequire the owner's absolute `working_dir`; `--working-dir`, when supplied, must\nidentify that same native-canonical root. Missing, relative, or conflicting root\ncontext returns `NEEDS_CONTEXT` before project access; an inaccessible directory\nis `BLOCKED`. Never use the launch cwd or introduce another root resolver.\n\nReceive `MOBILE_APP_ORCHESTRATING=1`, `orchestrator`, `working_dir`, `phase`,\n`approved_scope`, and supplied answers from the owner. Preserve the selected\nenvironment ID\u002FURL\u002Ftenant, profile ID, table allowlist, item IDs, and exact\nscope\u002Fcolumn\u002Fsync\u002Fname\u002Fdescription changes. Missing or conflicting scope returns\n`NEEDS_CONTEXT`, not another environment\u002Fprofile\u002Ftable selection. The marker is\nnot approval: schema approval alone does not authorize profile edits, publication,\ndeletion, or membership edits. Retain Step 3's single confirm unless supplied\nanswers already approve that same current offline change.\nFor `--plan-only` or a planning-phase handoff, return the current\u002Fproposed diff\nafter read-only discovery and STOP before Apply, PATCH, publication, or artifact\nwrites. A gate response cannot lift proposal-only mode.\n\nApply the canonical contract to **every shell call and file tool**, including\nversion\u002Fauth checks, manifest\u002Fscreen reads, commands copied from references,\nverification, recovery, and retries. Re-supply the absolute `PLUGIN_ROOT` and\nrequired context on each call; no prior `cd`, export, or shell variable persists.\nUse the canonical Bash guard below or its PowerShell equivalent. Replace\nplaceholders with validated, shell-quoted invocation values; missing values\nreturn `NEEDS_CONTEXT`, never execute an unresolved placeholder.\nFile tools use absolute `\u003Cworking_dir>\u002F...` paths; plugin reads\u002Fscripts use\n`${PLUGIN_ROOT}\u002F...`. Never search another app when a file is absent.\n\n## Workflow\n\n1. Verify project + locate profile → 2. Resolve target (which table \u002F what to change) → 3. Show current vs proposed → Single confirm → 4. PATCH → 5. Publish → 6. Update artifacts → 7. Summary\n\n---\n\n### Step 1 — Verify project + locate profile\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nif [ ! -f power.config.json ] || [ ! -f app.config.js ]; then\n  echo \"BLOCKED: working_dir is not an initialized app\" >&2\n  exit 1\nfi\n```\n\nRead `\u003Cworking_dir>\u002Fpower.config.json` and require a nonempty `environmentId`\nmatching the owner's selected environment. Reuse matching complete environment\ncontext, or perform this non-persisting lookup from the bound root:\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nenvironment_id=$(node -p \"require('.\u002Fpower.config.json').environmentId || ''\") || {\n  echo \"BLOCKED: unreadable power.config.json\" >&2; exit 1;\n}\nif [ -z \"$environment_id\" ] || [ \"$environment_id\" != \"\u003Cselected-environment-id>\" ]; then\n  echo \"NEEDS_CONTEXT: selected environment does not match working_dir\" >&2\n  exit 1\nfi\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fresolve-environment.js\" \"$environment_id\" --no-cache --require-tenant\n```\n\nRequire the returned environment ID, HTTPS URL, and tenant to match the owner;\nincomplete or conflicting context returns `NEEDS_CONTEXT`. Never drop\n`--no-cache --require-tenant`, change configuration, or switch auth\u002Fenvironment\nto recover a failure. Use that exact `\u003CenvUrl>` and `\u003CtenantId>` for every request.\n\nProfile ID resolution (same priority as `\u002Fassign-offline-profile` Step 1):\n\n| Source | Used when |\n|---|---|\n| `$ARGUMENTS` `--profile-id \u003Cguid>` | Explicit selection matching the owner's profile context |\n| `\u003Cworking_dir>\u002Foffline-profile.json` top-level `profileId` | Default for `\u002Fsetup-offline-profile`-created projects, matching the owner's profile context |\n| Otherwise | Return `NEEDS_CONTEXT` to the owner to select the intended profile; never pick another profile silently |\n\nSTOP if no profile found: \"Run `\u002Fsetup-offline-profile` first.\"\n\nVerify the selected live profile belongs to the selected environment. A conflicting\nsnapshot\u002Fargument returns `NEEDS_CONTEXT`; a 404 or permission failure is\n`BLOCKED`, not permission to discover a substitute. Resolve each `\u003CitemId>` only\nwithin this profile and verify its table matches the exact requested logical name.\n\n> **`\u003Cworking_dir>\u002Fpower.config.json` is intentionally NOT consulted for the profile ID.**\n> That file is owned by `pa app init`. The local profile ID lives in\n> `\u003Cworking_dir>\u002Foffline-profile.json` only.\n\n### Step 2 — Resolve target (what to edit)\n\nParse `$ARGUMENTS`:\n\n| Flag pattern | Effect |\n|---|---|\n| `--rename \u003Cnew-name>` | Update profile `name` |\n| `--describe \u003Ctext>` | Update profile `description` |\n| `--table \u003Clogical-name> --scope \u003C0\\|1\\|2>` | Change one table's `recorddistributioncriteria`. Combine with `--me`, `--team`, `--bu` to set sub-flags when scope=2. |\n| `--table \u003Clogical-name> --sync \u003Cminutes>` | Change one table's `syncintervalinminutes` (range 5–1440) |\n| `--table \u003Clogical-name> --columns add:col1,col2 remove:col3` | Add or remove logical names from `selectedcolumns`. Comma-separated, both add\u002Fremove optional. |\n| `--table \u003Clogical-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) |\n\nIf no flags → interactive picker. `AskUserQuestion` with up-to-4 most likely edits:\n- \"Rename profile\"\n- \"Change a table's scope\" → next message asks which table\n- \"Change a table's sync frequency\" → next message asks which table + value\n- \"Edit a table's column list\" → next message asks which table + add\u002Fremove\n\nRestrict the picker and explicit flags to the owner's exact current scope.\n`--columns reset` reads the selected table from\n`\u003Cworking_dir>\u002F.datamodel-manifest.json` or\n`\u003Cworking_dir>\u002Fdocs\u002Fplan-artifacts\u002F.datamodel-manifest.json` and greps only\nabsolute `\u003Cworking_dir>\u002Fapp\u002F` and `\u003Cworking_dir>\u002Fsrc\u002F` paths. Keep the chosen\nabsolute manifest path for the whole invocation; no other-app fallback.\nChanging the table, profile, or operation requires returning `NEEDS_CONTEXT`\nto the owner, not expanding an existing approval.\n\n### Step 3 — Show current vs proposed (single gate)\n\nGET the current item state from Dataverse for any tables being edited:\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fdataverse-request.js\" \"\u003CenvUrl>\" GET \\\n  \"mobileofflineprofileitems(\u003CitemId>)?\\$select=name,recorddistributioncriteria,recordsownedbyme,recordsownedbymyteam,recordsownedbymybusinessunit,syncintervalinminutes,selectedcolumns\" \\\n  --tenant-id \"\u003CtenantId>\"\n```\n\nRender a current\u002Fproposed diff:\n\n```\nProfile  : \u003Cname> (\u003Cid>)\nEditing  : \u003Ctable-logical-name> item\n\n                Current     →    Proposed\nScope         : Org+me     →    All records\nSync (min)    : 10         →    30\nColumns       : 14         →    16  (add: chnl_notes, chnl_actual_visit_date)\n```\n\n`AskUserQuestion`: \"Apply this change? [Apply \u002F Cancel]\"\n\nIf `Apply` → continue. If `Cancel` → STOP.\n\n### Step 4 — PATCH\n\nBuild the PATCH body with only the fields that changed:\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fdataverse-request.js\" \"\u003CenvUrl>\" PATCH \\\n  \"mobileofflineprofileitems(\u003CitemId>)\" --tenant-id \"\u003CtenantId>\" \\\n  --body '{\n    \"recorddistributioncriteria\": \u003Cnew>,\n    \"recordsownedbyme\": \u003Cnew-bool>,\n    \"syncintervalinminutes\": \u003Cnew>,\n    \"selectedcolumns\": \"{\\\"Columns\\\":[...]}\"\n  }'\n```\n\nFor profile-level edits (name \u002F description):\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fdataverse-request.js\" \"\u003CenvUrl>\" PATCH \\\n  \"mobileofflineprofiles(\u003CprofileId>)\" --tenant-id \"\u003CtenantId>\" \\\n  --body '{\"name\": \"...\", \"description\": \"...\"}'\n```\n\nCheck returned HTTP statuses as well as process exit. A\n403\u002F`PrivilegeCheckFailed` is `BLOCKED`; do not change identity or profile to\nbypass permissions. Preserve every field and table outside the approved delta.\n\n### Step 5 — Publish\n\nUse the **targeted `PublishXml`** recipe from [shared\u002Freferences\u002Fdataverse-offline-api.md §9](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fdataverse-offline-api.md):\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fdataverse-request.js\" \"\u003CenvUrl>\" POST \\\n  \"PublishXml\" --tenant-id \"\u003CtenantId>\" --body '{\n    \"ParameterXml\": \"\u003Cpublish>\u003Cmobileofflineprofiles>\u003Cmobileofflineprofile>\u003CprofileId>\u003C\u002Fmobileofflineprofile>\u003C\u002Fmobileofflineprofiles>\u003C\u002Fpublish>\"\n  }'\n```\n\nPublishes only this profile, not the entire org's customizations. Avoids the 429 rate-limit storms on shared envs that the legacy `PublishAllXml` triggered.\n\nOn `400 \u002F 0x80071141` \"circular relationship\" — same handling as\n`\u002Fsetup-offline-profile` Step 8 (parse cycle path, prompt user to drop one\nassociation, retry). Fallback to `PublishAllXml` only if `PublishXml` returns an\nunexpected error other than the cycle case **and** the owner\u002Fuser approves that\nbroader publication; a profile-scoped approval does not cover it.\n\nAll linked recovery commands, re-GET verification, and retries must bind the\nsame root and pass the same environment\u002Ftenant\u002Fprofile\u002Ftable\u002Fitem context.\nNever retry on a different profile or bypass a permission failure. Confirm\npublication before Step 6.\n\nIf a linked recipe requires another offline helper, return the proposed change\nto the owner for approval first, then read the helper at its absolute\n`${PLUGIN_ROOT}\u002Fskills\u002F\u003Chelper>\u002FSKILL.md` path. Forward:\n\n```text\nArguments: --working-dir '\u003Cworking_dir>' --profile-id \"\u003CprofileId>\" --table \"\u003Ctable>\" \u003Cexact-approved-change-flags>\nContext: MOBILE_APP_ORCHESTRATING=1, orchestrator, working_dir, phase, approved_scope,\n         selected environment ID\u002FURL\u002Ftenant, profile ID, table allowlist, item ID,\n         supplied answers, --plan-only (if present)\n```\n\nThe recipient must enforce the same canonical root contract. Missing context\nreturns `NEEDS_CONTEXT`; do not fall back to direct invocation or rediscovery.\n\n### Step 6 — Update artifacts\n\nRe-read the changed item(s) in the same profile\u002Fenvironment and rewrite the\nmatching entry in `\u003Cworking_dir>\u002Foffline-profile.json`. When the edit changed a\ntable's **columns** (`--columns add:\u002Fremove:\u002Freset`), also refresh that entry's\n`schemaColumns` to the table's current full column set from the bound absolute\nmanifest. This re-baselines the schema-reconciliation marker for the next\n`${PLUGIN_ROOT}\u002Fscripts\u002Foffline-profile-delta.js` run; leave `schemaColumns`\nuntouched for scope\u002Fsync\u002Frename-only edits. Any delta check uses\n`--project-root '\u003Cworking_dir>'` in its own guarded call. See\n[offline-profile-reconciliation.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Foffline-profile-reconciliation.md).\n\nAppend a one-line entry to `\u003Cworking_dir>\u002Fmemory-bank.md` `## Offline profile` block:\n\n```yaml\nedits:\n  - { at: 2026-05-19T..., field: 'chnl_storevisit.syncintervalinminutes', from: 5, to: 10 }\n```\n\n### Step 7 — Summary\n\n```\n✓ Edited profile.\n\n  Field : chnl_storevisit.syncintervalinminutes\n  From  : 5 min\n  To    : 10 min\n  Published: 2026-05-19T...\n\noffline-profile.json + memory-bank.md updated.\n```\n\n## Status code (final line)\n\n- `DONE` — change applied and published\n- `DONE_WITH_CONCERNS: \u003Clist>` — change applied but with caveats (publish timeout-then-success, etc.)\n- `NEEDS_CONTEXT: \u003Cmissing>` — couldn't resolve target table or profile\n- `BLOCKED: \u003Creason>` — auth or PATCH failure\n\n## What this skill does NOT do\n\n- Add a NEW table to the profile → use `\u002Fadd-table-to-offline-profile`\n- Add a new association (relationship inclusion) → blocked on v0.2 `selectedrelationshipsschema` work; use maker portal in the meantime\n- Delete the whole profile → manual `DELETE \u002Fmobileofflineprofiles(\u003Cid>)` (cascade-deletes items + associations); see [dataverse-offline-api.md §11](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fdataverse-offline-api.md)\n- Migrate the profile between environments → use `CloneMobileOfflineProfile` action (v0.5 work)\n",{"name":5,"model":30,"description":7,"allowed-tools":49,"user-invocable":45,"disable-model-invocation":50},"Read, Edit, Write, Grep, Glob, Bash, AskUserQuestion",true,"main","0a55a88fa2855404029d1e5450faf92878baf763","plugins\u002Fmobile-apps\u002Fskills\u002Fedit-offline-profile",228,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills","https:\u002F\u002Fmicrosoft.github.io\u002Fpower-platform-skills\u002F","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-12 02:16:25",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":50},[63,66,69],{"tool":64,"command":65},"npx","npx skills add microsoft\u002Fpower-platform-skills --skill edit-offline-profile",{"tool":67,"command":68},"bunx","bunx skills add microsoft\u002Fpower-platform-skills --skill edit-offline-profile",{"tool":70,"command":71},"pnpm","pnpm dlx skills add microsoft\u002Fpower-platform-skills --skill edit-offline-profile","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fmobile-apps\u002Fskills\u002Fedit-offline-profile\u002FSKILL.md",[],[75,95,118,136,150,160],{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":44},"01M699WVHX0XN59EPBTTPEKYPG","setup","Use when Process Intelligence needs building, explicit cloud\u002Faccount\u002Fenvironment configuration, sign-in, connection diagnostics, or recovery from an authentication error.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Fsetup\u002FSKILL.md",[],[77,39,82,83,84,85,86,87,88,89,90,91,92,93,94,41],"when","connection","error","sign","intelligence","configuration","use","process","diagnostics","environment","authentication","cloud","recovery",{"skillNo":96,"name":97,"nameZh":6,"description":98,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":106,"publishedAt":44},"01M699WSR9EX55YY1WD9J22FEG","report-issue","Use when the user wants a Process Intelligence bug-report draft or support summary for a failed operation.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Freport-issue\u002FSKILL.md",[101],{"categoryNo":102,"categoryName":103,"taxonomyType":104,"taxonomyTypeDesc":105},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[107,108,109,110,111,89,88,112,113,86,114,115,116,82,117],"report issue","report","issue","support","user","bug","summary","draft","operation","for","bug-report",{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":44},"01M699WR26YQ9Q21KE6MJF5B2G","investigate-process","Use when a broad Process Mining business question, observed pattern or competing explanation needs investigation across analytical perspectives.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Finvestigate-process\u002FSKILL.md",[],[89,125,126,127,82,128,129,130,131,39,132,88,133,134,135],"investigate","investigate process","mining","process mining","investigation","perspectives","question","business","pattern","across","analytical",{"skillNo":137,"name":138,"nameZh":6,"description":139,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":140,"categories":141,"keywords":142,"publishedAt":44},"01M699WP9SDG5ZR12P8VYNXKTN","derive-metric","Use when a requested measure is missing, a saved custom metric needs reuse, or an ephemeral formula or derived scalar is needed.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Fderive-metric\u002FSKILL.md",[],[143,144,39,88,145,146,147,148,149,82],"metric","derive metric","formula","missing","reuse","saved","custom",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":156,"publishedAt":44},"01M699WMG5R8P6SMTDAS1TKF9E","compare-cohorts","Use when comparing process cohorts, departments, periods or before-and-after results under matched definitions.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Fcompare-cohorts\u002FSKILL.md",[],[157,158,82,88,89,159,39],"compare","compare cohorts","results",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":164,"categories":165,"keywords":166,"publishedAt":44},"01M699WJWNVTMP9XK3NCJHV14D","analyze-variants","Use when investigating common or slow variants, repeated work, unusual paths, or a specific Process Mining case.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Fanalyze-variants\u002FSKILL.md",[],[167,168,169,128,82,127,170,171,88,89,39,172,173],"analyze","variants","analyze variants","case","paths","work","common"]