[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699N8TZXHHSBF8XJJ4W65MF":3,"skill-same:01M699N8TZXHHSBF8XJJ4W65MF":80},{"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},"01M699N8TZXHHSBF8XJJ4W65MF","add-table-to-offline-profile",null,"Internal mobile-app workflow read and executed only by mobile orchestrators to add one Dataverse table to an existing Mobile Offline Profile.","microsoft\u002Fpower-platform-skills","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M699JVYJFB75D9JM70BN4H0Q",1149,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fmobile-apps\u002Fskills\u002Fadd-table-to-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],"add table to offline profile","offline","table","add","add table","profile","Existing","workflow","true","sonnet","false","app","mobile","only","edit","write","read","grep","Bash","dataverse","2026-11-10 10:12:30",false,"---\nname: add-table-to-offline-profile\ndescription: Internal mobile-app workflow read and executed only by mobile orchestrators to add one Dataverse table to an existing 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 + §7 — POST item + PATCH selectedcolumns\n- [offline-profile-reconciliation.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Foffline-profile-reconciliation.md) — the `schemaColumns` baseline written in Step 7\n\n# Add Table to Offline Profile\n\nAdd a single table to an existing Mobile Offline Profile. Most common flow: user ran `\u002Fadd-dataverse` to add a new table to their app, now wants that table available offline too.\n\nEquivalent to running `\u002Fsetup-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.\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. Keep the selected\nenvironment ID\u002FURL\u002Ftenant, profile ID, exact table allowlist, and approved\noperations unchanged. Missing or conflicting scope returns `NEEDS_CONTEXT`;\ndo not substitute another environment, profile, or table. The marker is not\napproval: schema approval alone does not authorize offline prerequisite changes,\nprofile items, relationships, columns, publication, deletion, or membership edits.\nReuse only the same current offline approvals; otherwise retain Steps 3–4's gates.\nFor `--plan-only` or a planning-phase handoff, return a proposal after permitted\nread-only discovery, before any prerequisite update, profile mutation, publish,\nor artifact write. A gate response cannot lift proposal-only mode.\n\nApply the canonical contract to **every shell call and file tool**, including\nversion\u002Fauth checks, row counts, screen greps, 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...`. Resolve manifest location once within this root and keep\nthat absolute path; never search another app when a file is absent.\n\n## Workflow\n\n1. 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\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\nManifest path (dual-location, both within the bound root):\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nif [ -f .datamodel-manifest.json ]; then\n  printf '%s\\n' '\u003Cworking_dir>\u002F.datamodel-manifest.json'\nelif [ -f docs\u002Fplan-artifacts\u002F.datamodel-manifest.json ]; then\n  printf '%s\\n' '\u003Cworking_dir>\u002Fdocs\u002Fplan-artifacts\u002F.datamodel-manifest.json'\nelse\n  echo \"NEEDS_CONTEXT: no manifest in working_dir\" >&2\n  exit 1\nfi\n```\n\nRead the profile from `\u003Cworking_dir>\u002Foffline-profile.json` or the owner's explicit\n`--profile-id`, using `\u002Fedit-offline-profile`'s resolution rules inline. Verify it\nmatches the owner's profile and the live profile in the selected environment.\nA conflicting snapshot\u002Fargument, 404, or permission failure is not permission to\npick a different profile; return `NEEDS_CONTEXT` for conflict or `BLOCKED` for\naccess failure. Do not execute the edit workflow just to locate a profile.\n\nSTOP if no profile exists. Recommend: `Run \u002Fsetup-offline-profile first to create the profile.`\n\n### Step 2 — Resolve target table\n\n`$ARGUMENTS` parsing:\n\n| Flag | Effect |\n|---|---|\n| `--table \u003Clogical-name>` | Explicit target |\n| `--all-new` | Add missing manifest tables only within the owner's exact table allowlist (bulk mode); never widen to unrelated pending tables |\n| (no flags) | Interactive: list allowed tables in the manifest NOT yet in the selected profile via `AskUserQuestion` (max 4); if more than 4 candidates, prompt user to specify by name in next message |\n\nAn explicit `--table` must match the owner's allowlist. Conflicting selection\nreturns `NEEDS_CONTEXT`. For bulk `--all-new` mode, loop through Steps 3–7 for\neach approved missing table; each runs sequentially because Dataverse profile-item\nPOSTs serialize. Every iteration keeps the same root\u002Fenvironment\u002Fprofile context.\n\n### Step 3 — Prereq check (auto-enable if needed)\n\nQuery the target table's `EntityMetadata`:\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  \"EntityDefinitions(LogicalName='\u003Ctable>')?\\$select=IsAvailableOffline,ChangeTrackingEnabled,OwnershipType,IsCustomizable\" \\\n  --tenant-id \"\u003CtenantId>\"\n```\n\n| Flags state | Action |\n|---|---|\n| Both already `true` | Skip to Step 4 |\n| Either `false` AND IsCustomizable | Use `update-entity-offline-flags.js` only if the current offline approval covers these exact prerequisite changes and publication; otherwise show the changes and obtain owner\u002Fuser approval first |\n| `IsCustomizable.Value = false` | STOP with `BLOCKED: \u003Ctable> is system-managed and cannot be flagged for offline. Use a different table or accept this row is read-only-offline.` |\n\nAfter approval, execute the helper for this table only with the resolved tenant.\n`--tenant-id` binds both initial authentication and 401 refresh; never rely on\nambient tenant variables for this prerequisite mutation.\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fupdate-entity-offline-flags.js\" \"\u003CenvUrl>\" \\\n  --table \"\u003Ctable>\" --offline true --tracking true --tenant-id \"\u003CtenantId>\"\n```\n\nCheck the returned HTTP status, not just process exit. A 403\u002F`PrivilegeCheckFailed`\nis `BLOCKED`; do not change identity or profile to bypass permissions.\nAfter a successful change, issue the approved prerequisite publication:\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\": \"\u003Cimportexportxml>\u003Centities>\u003Centity>\u003Ctable>\u003C\u002Fentity>\u003C\u002Fentities>\u003C\u002Fimportexportxml>\"\n  }'\n```\n\nPublish only this helper's changed prerequisite table. Do not use\n`PublishAllXml` unless the owner separately approves publishing all pending\nenvironment customizations; table-only approval does not cover that fallback.\n\nNo prerequisite mutation or publication is allowed in proposal-only mode.\n\n### Step 4 — Scope picker (single question)\n\nPull from the bound absolute manifest the target table's `lookups[]` to inform\ndefaults. Run a root-bound row-count probe in the selected environment for this\ntable only to inform reference-data classification.\n\n`AskUserQuestion` with 4 options reflecting the architect's priority cascade:\n\n| Option label | Maps to |\n|---|---|\n| `Organization rows — User's rows only (Recommended for most tables)` | `recorddistributioncriteria: 2`, `recordsownedbyme: true` |\n| `All records (for small reference data)` | `recorddistributioncriteria: 1` |\n| `Related rows only (for pure child tables)` | `recorddistributioncriteria: 0` |\n| `Custom — specify exact flags in next message` | Prompt user with text |\n\nRecommendation 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.\n\nShow the proposed relationships, selected columns, and sync interval alongside\nthe scope choice. Reuse supplied answers only when they approve this exact\noffline change; otherwise wait for the choice before Step 5. Cancel stops without\ncreating a profile item. Neither invocation nor the orchestration marker answers\nthis gate.\n\n### Step 5 — POST item + associations + PATCH selectedcolumns\n\n#### Step 5a — POST profile item\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  \"mobileofflineprofileitems\" --tenant-id \"\u003CtenantId>\" \\\n  --body '{\n    \"name\": \"\u003CDisplayName>\",\n    \"regardingobjectid@odata.bind\": \"\u002Fmobileofflineprofiles(\u003CprofileId>)\",\n    \"selectedentitytypecode\": \"\u003Ctable>\",\n    \"recorddistributioncriteria\": \u003C0|1|2>,\n    \"recordsownedbyme\": \u003Cbool>,\n    \"recordsownedbymyteam\": false,\n    \"recordsownedbymybusinessunit\": false,\n    \"getrelatedentityrecords\": true,\n    \"syncintervalinminutes\": 10\n  }' \\\n  --include-headers\n```\n\nCapture `itemId` from `OData-EntityId` response header.\n\n#### Step 5b — POST associations for the new table's relationships\n\nAfter the new item is created, walk the new table's relationships (from the manifest's `lookups[]` + a `EntityDefinitions(LogicalName='\u003Ctable>')\u002FManyToOneRelationships` query) and POST one `mobileofflineprofileitemassociation` per relationship whose target is ALREADY in the profile.\n\nRecipe per [shared\u002Freferences\u002Fdataverse-offline-api.md §5–§6](${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  \"mobileofflineprofileitemassociations\" --tenant-id \"\u003CtenantId>\" \\\n  --body '{\n    \"name\": \"\u003CrelationshipSchemaName>\",\n    \"relationshipdisplayname\": \"\u003CrelationshipSchemaName>\",\n    \"relationshipid\": \"\u003CMetadataId-from-EntityDefinitions>\",\n    \"regardingobjectid@odata.bind\": \"\u002Fmobileofflineprofileitems(\u003CnewItemId>)\"\n  }' \\\n  --include-headers\n```\n\n**Critical**: do NOT include `selectedrelationshipsschema` in the body — server fills it in (empirical 2026-05-24).\n\nFor new tables that are `recorddistributioncriteria: 0` (Related rows only), at least ONE inbound relationship MUST be included or the table will sync zero rows. The skill should validate this and warn if no associations are being created for a Related-only-scoped table.\n\n#### Step 5c — PATCH selectedcolumns\n\nBuild `selectedcolumns` using the deterministic union from [offline-profile-architect.md](${PLUGIN_ROOT}\u002Fagents\u002Foffline-profile-architect.md) Step 6 (always-include ∪ lookups ∪ screen-grep'd, dedupe, sort). Scope file-tool greps to absolute `\u003Cworking_dir>\u002Fapp\u002F` and `\u003Cworking_dir>\u002Fsrc\u002F` paths and the selected table; use the same proposed columns approved in Step 4.\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 '{\"selectedcolumns\":\"{\\\"Columns\\\":[...]}\"}'\n```\n\n### Step 6 — Publish (targeted PublishXml)\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. See [shared\u002Freferences\u002Fdataverse-offline-api.md §9](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fdataverse-offline-api.md) for `0x80071141` circular-relationship handling + `PublishAllXml` fallback.\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.\nRemoving a cycle association requires the explicit user decision in that recipe.\nAn org-wide `PublishAllXml` fallback needs approval for that broader publication;\ndo not silently escalate a profile-scoped approval. Never retry on a different\nprofile or bypass a permission failure. Confirm publication before Step 7.\n\nIf a linked recovery recipe requires another offline helper, return the proposed\nchange to 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 7 — Update artifacts\n\nAppend the new table's entry to `\u003Cworking_dir>\u002Foffline-profile.json` `tables[]`.\nThe entry MUST include a `schemaColumns` array — the added table's full set of\nschema column logical names from the bound absolute manifest at this moment.\nThis is the schema-reconciliation baseline that\n`${PLUGIN_ROOT}\u002Fscripts\u002Foffline-profile-delta.js` diffs future manifest changes\nagainst; omitting it reports `columnBaselineMissing` until re-reconciled. It is\ndistinct from `selectedColumns` (the curated sync set) — see\n[offline-profile-reconciliation.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Foffline-profile-reconciliation.md).\nMatch the canonical entry shape in\n[`\u002Fsetup-offline-profile` Step 9a](${PLUGIN_ROOT}\u002Fskills\u002Fsetup-offline-profile\u002FSKILL.md)\nwithout executing that workflow. Any delta check uses\n`--project-root '\u003Cworking_dir>'` in its own guarded call.\n\nAppend to `\u003Cworking_dir>\u002Fmemory-bank.md` `## Offline profile` block:\n\n```yaml\naddedTables:\n  - { at: 2026-05-19T..., table: \u003Cname>, itemId: \u003Cguid>, scope: \u003Ccriterion> }\n```\n\n### Step 8 — Summary\n\n```\n✓ Added \u003Ctable> to profile.\n\n  Profile      : \u003Cname>\n  New item ID  : \u003Cguid>\n  Scope        : \u003Chuman-readable>\n  Sync         : \u003Cminutes> min\n  Columns      : \u003CN> selected\n  Published    : \u003CISO timestamp>\n\nTotal tables in profile now: \u003CN>\n\nUsers who already have this profile assigned will receive the new table on their\nnext sign-in sync. To force-refresh, sign out and back in on the device.\n```\n\n## Status code (final line)\n\n- `DONE` — table added, profile published, artifacts updated\n- `DONE_WITH_CONCERNS: \u003Clist>` — added with caveats (auto-enabled prereqs, publish timeout-then-success)\n- `NEEDS_CONTEXT: \u003Cmissing>` — no profile to add to, or no target table\n- `BLOCKED: \u003Creason>` — IsCustomizable=false on target, auth failure, POST\u002FPATCH failure\n\n## What this skill does NOT do\n\n- Add **N:N (ManyToMany) relationships** to a profile item — uncommon, not covered by v0.1's recipe (which assumes N:1 \u002F 1:N via the `regardingobjectid` lookup). If the user has an M:N use case, point them at the maker portal.\n- Re-architect existing tables in the profile — that's `\u002Fedit-offline-profile`.\n- Remove a table from the profile — manual `DELETE \u002Fmobileofflineprofileitems(\u003CitemId>)` (no current skill).\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 + §7 — POST item + PATCH selectedcolumns\n- [offline-profile-reconciliation.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Foffline-profile-reconciliation.md) — the `schemaColumns` baseline written in Step 7\n\n# Add Table to Offline Profile\n\nAdd a single table to an existing Mobile Offline Profile. Most common flow: user ran `\u002Fadd-dataverse` to add a new table to their app, now wants that table available offline too.\n\nEquivalent to running `\u002Fsetup-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.\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. Keep the selected\nenvironment ID\u002FURL\u002Ftenant, profile ID, exact table allowlist, and approved\noperations unchanged. Missing or conflicting scope returns `NEEDS_CONTEXT`;\ndo not substitute another environment, profile, or table. The marker is not\napproval: schema approval alone does not authorize offline prerequisite changes,\nprofile items, relationships, columns, publication, deletion, or membership edits.\nReuse only the same current offline approvals; otherwise retain Steps 3–4's gates.\nFor `--plan-only` or a planning-phase handoff, return a proposal after permitted\nread-only discovery, before any prerequisite update, profile mutation, publish,\nor artifact write. A gate response cannot lift proposal-only mode.\n\nApply the canonical contract to **every shell call and file tool**, including\nversion\u002Fauth checks, row counts, screen greps, 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...`. Resolve manifest location once within this root and keep\nthat absolute path; never search another app when a file is absent.\n\n## Workflow\n\n1. 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\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\nManifest path (dual-location, both within the bound root):\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nif [ -f .datamodel-manifest.json ]; then\n  printf '%s\\n' '\u003Cworking_dir>\u002F.datamodel-manifest.json'\nelif [ -f docs\u002Fplan-artifacts\u002F.datamodel-manifest.json ]; then\n  printf '%s\\n' '\u003Cworking_dir>\u002Fdocs\u002Fplan-artifacts\u002F.datamodel-manifest.json'\nelse\n  echo \"NEEDS_CONTEXT: no manifest in working_dir\" >&2\n  exit 1\nfi\n```\n\nRead the profile from `\u003Cworking_dir>\u002Foffline-profile.json` or the owner's explicit\n`--profile-id`, using `\u002Fedit-offline-profile`'s resolution rules inline. Verify it\nmatches the owner's profile and the live profile in the selected environment.\nA conflicting snapshot\u002Fargument, 404, or permission failure is not permission to\npick a different profile; return `NEEDS_CONTEXT` for conflict or `BLOCKED` for\naccess failure. Do not execute the edit workflow just to locate a profile.\n\nSTOP if no profile exists. Recommend: `Run \u002Fsetup-offline-profile first to create the profile.`\n\n### Step 2 — Resolve target table\n\n`$ARGUMENTS` parsing:\n\n| Flag | Effect |\n|---|---|\n| `--table \u003Clogical-name>` | Explicit target |\n| `--all-new` | Add missing manifest tables only within the owner's exact table allowlist (bulk mode); never widen to unrelated pending tables |\n| (no flags) | Interactive: list allowed tables in the manifest NOT yet in the selected profile via `AskUserQuestion` (max 4); if more than 4 candidates, prompt user to specify by name in next message |\n\nAn explicit `--table` must match the owner's allowlist. Conflicting selection\nreturns `NEEDS_CONTEXT`. For bulk `--all-new` mode, loop through Steps 3–7 for\neach approved missing table; each runs sequentially because Dataverse profile-item\nPOSTs serialize. Every iteration keeps the same root\u002Fenvironment\u002Fprofile context.\n\n### Step 3 — Prereq check (auto-enable if needed)\n\nQuery the target table's `EntityMetadata`:\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  \"EntityDefinitions(LogicalName='\u003Ctable>')?\\$select=IsAvailableOffline,ChangeTrackingEnabled,OwnershipType,IsCustomizable\" \\\n  --tenant-id \"\u003CtenantId>\"\n```\n\n| Flags state | Action |\n|---|---|\n| Both already `true` | Skip to Step 4 |\n| Either `false` AND IsCustomizable | Use `update-entity-offline-flags.js` only if the current offline approval covers these exact prerequisite changes and publication; otherwise show the changes and obtain owner\u002Fuser approval first |\n| `IsCustomizable.Value = false` | STOP with `BLOCKED: \u003Ctable> is system-managed and cannot be flagged for offline. Use a different table or accept this row is read-only-offline.` |\n\nAfter approval, execute the helper for this table only with the resolved tenant.\n`--tenant-id` binds both initial authentication and 401 refresh; never rely on\nambient tenant variables for this prerequisite mutation.\n\n```bash\ncd -- '\u003Cworking_dir>' || { echo \"BLOCKED: cannot enter working_dir\" >&2; exit 1; }\nnode \"${PLUGIN_ROOT}\u002Fscripts\u002Fupdate-entity-offline-flags.js\" \"\u003CenvUrl>\" \\\n  --table \"\u003Ctable>\" --offline true --tracking true --tenant-id \"\u003CtenantId>\"\n```\n\nCheck the returned HTTP status, not just process exit. A 403\u002F`PrivilegeCheckFailed`\nis `BLOCKED`; do not change identity or profile to bypass permissions.\nAfter a successful change, issue the approved prerequisite publication:\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\": \"\u003Cimportexportxml>\u003Centities>\u003Centity>\u003Ctable>\u003C\u002Fentity>\u003C\u002Fentities>\u003C\u002Fimportexportxml>\"\n  }'\n```\n\nPublish only this helper's changed prerequisite table. Do not use\n`PublishAllXml` unless the owner separately approves publishing all pending\nenvironment customizations; table-only approval does not cover that fallback.\n\nNo prerequisite mutation or publication is allowed in proposal-only mode.\n\n### Step 4 — Scope picker (single question)\n\nPull from the bound absolute manifest the target table's `lookups[]` to inform\ndefaults. Run a root-bound row-count probe in the selected environment for this\ntable only to inform reference-data classification.\n\n`AskUserQuestion` with 4 options reflecting the architect's priority cascade:\n\n| Option label | Maps to |\n|---|---|\n| `Organization rows — User's rows only (Recommended for most tables)` | `recorddistributioncriteria: 2`, `recordsownedbyme: true` |\n| `All records (for small reference data)` | `recorddistributioncriteria: 1` |\n| `Related rows only (for pure child tables)` | `recorddistributioncriteria: 0` |\n| `Custom — specify exact flags in next message` | Prompt user with text |\n\nRecommendation 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.\n\nShow the proposed relationships, selected columns, and sync interval alongside\nthe scope choice. Reuse supplied answers only when they approve this exact\noffline change; otherwise wait for the choice before Step 5. Cancel stops without\ncreating a profile item. Neither invocation nor the orchestration marker answers\nthis gate.\n\n### Step 5 — POST item + associations + PATCH selectedcolumns\n\n#### Step 5a — POST profile item\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  \"mobileofflineprofileitems\" --tenant-id \"\u003CtenantId>\" \\\n  --body '{\n    \"name\": \"\u003CDisplayName>\",\n    \"regardingobjectid@odata.bind\": \"\u002Fmobileofflineprofiles(\u003CprofileId>)\",\n    \"selectedentitytypecode\": \"\u003Ctable>\",\n    \"recorddistributioncriteria\": \u003C0|1|2>,\n    \"recordsownedbyme\": \u003Cbool>,\n    \"recordsownedbymyteam\": false,\n    \"recordsownedbymybusinessunit\": false,\n    \"getrelatedentityrecords\": true,\n    \"syncintervalinminutes\": 10\n  }' \\\n  --include-headers\n```\n\nCapture `itemId` from `OData-EntityId` response header.\n\n#### Step 5b — POST associations for the new table's relationships\n\nAfter the new item is created, walk the new table's relationships (from the manifest's `lookups[]` + a `EntityDefinitions(LogicalName='\u003Ctable>')\u002FManyToOneRelationships` query) and POST one `mobileofflineprofileitemassociation` per relationship whose target is ALREADY in the profile.\n\nRecipe per [shared\u002Freferences\u002Fdataverse-offline-api.md §5–§6](${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  \"mobileofflineprofileitemassociations\" --tenant-id \"\u003CtenantId>\" \\\n  --body '{\n    \"name\": \"\u003CrelationshipSchemaName>\",\n    \"relationshipdisplayname\": \"\u003CrelationshipSchemaName>\",\n    \"relationshipid\": \"\u003CMetadataId-from-EntityDefinitions>\",\n    \"regardingobjectid@odata.bind\": \"\u002Fmobileofflineprofileitems(\u003CnewItemId>)\"\n  }' \\\n  --include-headers\n```\n\n**Critical**: do NOT include `selectedrelationshipsschema` in the body — server fills it in (empirical 2026-05-24).\n\nFor new tables that are `recorddistributioncriteria: 0` (Related rows only), at least ONE inbound relationship MUST be included or the table will sync zero rows. The skill should validate this and warn if no associations are being created for a Related-only-scoped table.\n\n#### Step 5c — PATCH selectedcolumns\n\nBuild `selectedcolumns` using the deterministic union from [offline-profile-architect.md](${PLUGIN_ROOT}\u002Fagents\u002Foffline-profile-architect.md) Step 6 (always-include ∪ lookups ∪ screen-grep'd, dedupe, sort). Scope file-tool greps to absolute `\u003Cworking_dir>\u002Fapp\u002F` and `\u003Cworking_dir>\u002Fsrc\u002F` paths and the selected table; use the same proposed columns approved in Step 4.\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 '{\"selectedcolumns\":\"{\\\"Columns\\\":[...]}\"}'\n```\n\n### Step 6 — Publish (targeted PublishXml)\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. See [shared\u002Freferences\u002Fdataverse-offline-api.md §9](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Fdataverse-offline-api.md) for `0x80071141` circular-relationship handling + `PublishAllXml` fallback.\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.\nRemoving a cycle association requires the explicit user decision in that recipe.\nAn org-wide `PublishAllXml` fallback needs approval for that broader publication;\ndo not silently escalate a profile-scoped approval. Never retry on a different\nprofile or bypass a permission failure. Confirm publication before Step 7.\n\nIf a linked recovery recipe requires another offline helper, return the proposed\nchange to 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 7 — Update artifacts\n\nAppend the new table's entry to `\u003Cworking_dir>\u002Foffline-profile.json` `tables[]`.\nThe entry MUST include a `schemaColumns` array — the added table's full set of\nschema column logical names from the bound absolute manifest at this moment.\nThis is the schema-reconciliation baseline that\n`${PLUGIN_ROOT}\u002Fscripts\u002Foffline-profile-delta.js` diffs future manifest changes\nagainst; omitting it reports `columnBaselineMissing` until re-reconciled. It is\ndistinct from `selectedColumns` (the curated sync set) — see\n[offline-profile-reconciliation.md](${PLUGIN_ROOT}\u002Fshared\u002Freferences\u002Foffline-profile-reconciliation.md).\nMatch the canonical entry shape in\n[`\u002Fsetup-offline-profile` Step 9a](${PLUGIN_ROOT}\u002Fskills\u002Fsetup-offline-profile\u002FSKILL.md)\nwithout executing that workflow. Any delta check uses\n`--project-root '\u003Cworking_dir>'` in its own guarded call.\n\nAppend to `\u003Cworking_dir>\u002Fmemory-bank.md` `## Offline profile` block:\n\n```yaml\naddedTables:\n  - { at: 2026-05-19T..., table: \u003Cname>, itemId: \u003Cguid>, scope: \u003Ccriterion> }\n```\n\n### Step 8 — Summary\n\n```\n✓ Added \u003Ctable> to profile.\n\n  Profile      : \u003Cname>\n  New item ID  : \u003Cguid>\n  Scope        : \u003Chuman-readable>\n  Sync         : \u003Cminutes> min\n  Columns      : \u003CN> selected\n  Published    : \u003CISO timestamp>\n\nTotal tables in profile now: \u003CN>\n\nUsers who already have this profile assigned will receive the new table on their\nnext sign-in sync. To force-refresh, sign out and back in on the device.\n```\n\n## Status code (final line)\n\n- `DONE` — table added, profile published, artifacts updated\n- `DONE_WITH_CONCERNS: \u003Clist>` — added with caveats (auto-enabled prereqs, publish timeout-then-success)\n- `NEEDS_CONTEXT: \u003Cmissing>` — no profile to add to, or no target table\n- `BLOCKED: \u003Creason>` — IsCustomizable=false on target, auth failure, POST\u002FPATCH failure\n\n## What this skill does NOT do\n\n- Add **N:N (ManyToMany) relationships** to a profile item — uncommon, not covered by v0.1's recipe (which assumes N:1 \u002F 1:N via the `regardingobjectid` lookup). If the user has an M:N use case, point them at the maker portal.\n- Re-architect existing tables in the profile — that's `\u002Fedit-offline-profile`.\n- Remove a table from the profile — manual `DELETE \u002Fmobileofflineprofileitems(\u003CitemId>)` (no current skill).\n",{"name":5,"model":33,"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\u002Fadd-table-to-offline-profile",232,"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-14 21:46:39",{"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 add-table-to-offline-profile",{"tool":67,"command":68},"bunx","bunx skills add microsoft\u002Fpower-platform-skills --skill add-table-to-offline-profile",{"tool":70,"command":71},"pnpm","pnpm dlx skills add microsoft\u002Fpower-platform-skills --skill add-table-to-offline-profile","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fmobile-apps\u002Fskills\u002Fadd-table-to-offline-profile\u002FSKILL.md",[74],{"path":75,"resourceType":76,"resourceTypeDesc":77,"sizeBytes":78,"sourceHtmlUrl":79},"references\u002Ffix-review-format.md","REFERENCE","参考文档",7972,"https:\u002F\u002Fgithub.com\u002FSirTheOracle\u002Fforge-toolkit\u002Fblob\u002Fmain\u002Fskills\u002Ffix-plan-reviewer\u002Freferences\u002Ffix-review-format.md",[81,101,124,142,156,166],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"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",[],[83,40,88,89,90,91,92,93,94,95,96,97,98,99,100,42],"when","connection","error","sign","intelligence","configuration","use","process","diagnostics","environment","authentication","cloud","recovery",{"skillNo":102,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":112,"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",[107],{"categoryNo":108,"categoryName":109,"taxonomyType":110,"taxonomyTypeDesc":111},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[113,114,115,116,117,95,94,118,119,92,120,121,122,88,123],"report issue","report","issue","support","user","bug","summary","draft","operation","for","bug-report",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"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",[],[95,131,132,133,88,134,135,136,137,40,138,94,139,140,141],"investigate","investigate process","mining","process mining","investigation","perspectives","question","business","pattern","across","analytical",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":148,"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",[],[149,150,40,94,151,152,153,154,155,88],"metric","derive metric","formula","missing","reuse","saved","custom",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":162,"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",[],[163,164,88,94,95,165,40],"compare","compare cohorts","results",{"skillNo":167,"name":168,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":172,"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",[],[173,174,175,134,88,133,176,177,94,95,40,178,179],"analyze","variants","analyze variants","case","paths","work","common"]