Skip to content
Development
Skill

/enable-tables-offline

Internal mobile-app workflow read and executed only by /setup-offline-profile to enable Dataverse table prerequisites for a Mobile Offline Profile.

From plugin
power-platform-skills
1.1k110 skills25 agents5 MCP

Claude Code

$ npx -y skills add microsoft/power-platform-skills --skill enable-tables-offline --agent claude-code

SKILL.md

enable-tables-offline.SKILL.md
name: enable-tables-offline
description: Internal mobile-app workflow read and executed only by /setup-offline-profile to enable Dataverse table prerequisites for a Mobile Offline Profile.
user-invocable: false
disable-model-invocation: true
allowed-tools: Read, Edit, Write, Grep, Glob, Bash, AskUserQuestion, EnterPlanMode, ExitPlanMode
model: sonnet

**Shared instructions: [shared-instructions.md](${PLUGIN_ROOT}/shared/shared-instructions.md)** — read first.

**References:**

  • [offline-profile-schema.md](${PLUGIN_ROOT}/shared/references/offline-profile-schema.md) — entity field map (`IsAvailableOffline`, `ChangeTrackingEnabled`)

Enable Tables Offline

Flip `IsAvailableOffline=true` AND `ChangeTrackingEnabled=true` on the `EntityMetadata` of one or more Dataverse tables, then publish customizations. This is the prerequisite shown in Image 4 of the maker portal ("Can be taken offline" + "Track changes") — without both, a table CANNOT be added to a Mobile Offline Profile.

Sequential (Dataverse metadata lock) and idempotent: re-running on an already-enabled table is a no-op.

Invocation context and root binding

This internal helper is always a **child invocation**. Before any project read or command, execute [app-working-directory.md](${PLUGIN_ROOT}/shared/references/app-working-directory.md). Require the owner's absolute `working_dir`; `--working-dir`, when supplied, must identify that same native-canonical root. Missing, relative, or conflicting root context returns `NEEDS_CONTEXT` before project access; an inaccessible directory is `BLOCKED`. Never use the launch cwd or introduce another root resolver.

Receive `MOBILE_APP_ORCHESTRATING=1`, `orchestrator: setup-offline-profile`, `working_dir`, `phase`, `approved_scope`, and supplied answers. Preserve the selected environment ID/URL/tenant and exact table/prerequisite/publication allowlist. The marker is not approval. Reuse only matching current offline approval; a missing or changed scope returns `NEEDS_CONTEXT` to the owner. For `--plan-only` or a planning-phase handoff, return the proposed prerequisite changes after permitted read-only inspection, before PUT, publication, or artifact writes. A gate response cannot lift proposal-only mode.

Apply the canonical root contract to **every shell call and file tool**. Re-supply the absolute `PLUGIN_ROOT` and invocation context on each call; no prior `cd`, export, or shell variable persists. Missing values return `NEEDS_CONTEXT`; never execute an unresolved placeholder. All linked recovery commands, re-GET verification, and retries use the same root, environment, and explicit tenant. Read only absolute app-local paths, including `<working_dir>/power.config.json`, `<working_dir>/memory-bank.md`, and the manifest locations below.

Workflow

1. Verify project & auth → 2. Resolve table list → 3. Inspect current state → Gate → 4. PUT EntityMetadata per table → 5. Publish → 6. Verify → 7. Summary

---

Step 1 — Verify project & auth

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
if [ ! -f power.config.json ] || [ ! -f app.config.js ]; then
  echo "BLOCKED: working_dir is not an initialized app" >&2
  exit 1
fi

Require the app's `environmentId` to match the owner's selected environment before any discovery or mutation. Use this non-persisting lookup from the same root:

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
environment_id=$(node -p "require('./power.config.json').environmentId || ''") || {
  echo "BLOCKED: unreadable power.config.json" >&2; exit 1;
}
if [ -z "$environment_id" ] || [ "$environment_id" != "<selected-environment-id>" ]; then
  echo "NEEDS_CONTEXT: selected environment does not match working_dir" >&2
  exit 1
fi
node "${PLUGIN_ROOT}/scripts/resolve-environment.js" "$environment_id" --no-cache --require-tenant

Capture the **Environment URL** and **Tenant ID** from the resolver for `<envUrl>` and `<tenantId>`. Pass this tenant explicitly on every helper call and retry below; missing or conflicting tenant context is `NEEDS_CONTEXT`. Require the ID, URL, and tenant to match the owner; never switch accounts or environments to recover. STOP if not authenticated.

Step 2 — Resolve table list

Use only the exact table allowlist in the owner's `approved_scope`. The comma- or space-separated table list in `$ARGUMENTS` must match it; `--working-dir` is root context, not a table name. Missing or conflicting table selection returns `NEEDS_CONTEXT`; an explicitly empty approved list is a verified no-op.

Inspect `<working_dir>/.datamodel-manifest.json`, or `<working_dir>/docs/plan-artifacts/.datamodel-manifest.json` for newer apps, only to verify those selected tables. The manifest is not permission to enable every row. Do not discover another app's manifest or expand the allowlist silently.

Step 3 — Inspect current state

**Print before starting:** > "→ Querying current IsAvailableOffline + ChangeTrackingEnabled for <N> table(s)…"

For each table, in sequence:

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "<envUrl>" GET \
  "EntityDefinitions(LogicalName='<table>')?\$select=LogicalName,DisplayName,IsAvailableOffline,ChangeTrackingEnabled,IsCustomizable" \
  --tenant-id "<tenantId>"

Build a status table:

| Table              | IsAvailableOffline | ChangeTrackingEnabled | IsCustomizable | Needs change? |
|--------------------|--------------------|-----------------------|----------------|---------------|
| cr123_note         | false              | false                 | true           | YES (both)    |
| cr123_visit        | true               | false                 | true           | YES (track)   |
| contact            | true               | true                  | true           | NO            |

**Hard rule:** if `IsCustomizable.Value=false` on

Read more
@microsoft
Ships withpower-platform-skills

Plugins from Microsoft that teach AI assistants, such as GitHub Copilot and Claude Code, to build on Power Platform.

1.1k110 skills25 agents5 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
1.1k
Star history of microsoft/power-platform-skills on GitHub, a chart by star-history.com

Other skills on power-platform-skills.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills13d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react4d252k
@facebook@facebookInstall Skill

Questions about enable-tables-offline.

Which coding agents can use enable-tables-offline?
enable-tables-offline installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.