agentleFS
MicrosoftKnown publishermicrosoft/power-platform-skills/plugins/mobile-apps/skills/preview-offline-scope/SKILL.md

preview-offline-scope

Skill1.1k starsChanged 10 days agoMITView on GitHub

Use when the user wants to estimate the download size + sync frequency cost of an offline profile BEFORE pushing to users. Read-only. Wraps verify-offline-profile.js with per-table row-count estimates.

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read-only diagnostic. Tells you "if you pushed this profile to users right now, here's what their devices would download and how often it …

    line 13
  2. Very specific:

    Before any project read or command, apply app-working-directory.md.

    line 20
  3. Distinctive:

    Verify project + locate profile → 2.

    line 30
  4. Very specific:

    If status: drift, surface the drift list verbatim.

    line 62

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Shared instructions: shared-instructions.md — read first.

Preview Offline Scope

Read-only diagnostic. Tells you "if you pushed this profile to users right now, here's what their devices would download and how often it would re-sync." No mutations.

Useful before:

  • /setup-offline-profile for a final sanity check
  • /assign-offline-profile (so users don't get surprised by data caps)
  • /edit-offline-profile to gauge impact of a column-list change

Before any project read or command, apply app-working-directory.md. Resolve one absolute working_dir for this direct invocation, or require the owner's root for a child. Keep all shell calls, file reads, and retries on that root and the same resolved environment/tenant. Read <working_dir>/offline-profile.json; a supplied profile ID must match the snapshot before verification. Missing or conflicting context is NEEDS_CONTEXT.

Workflow

  1. Verify project + locate profile → 2. Run verify (drift check) → 3. Per-table row counts → 4. Cache-size estimate → 5. Report

Step 1 — Verify project + locate profile

Same as /edit-offline-profile Step 1. Read profileId from offline-profile.json or $ARGUMENTS --profile-id. Do not read profile metadata from power.config.json; it is owned by pa app init.

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" ]; then
  echo "NEEDS_CONTEXT: selected app has no environmentId" >&2; exit 1;
fi
node "${PLUGIN_ROOT}/scripts/resolve-environment.js" "$environment_id" --no-cache --require-tenant

Capture <envUrl> and <tenantId> and require them to match any owner identity. Pass that tenant explicitly on verification, row counts, identity reads, and retries.

Step 2 — Run verify

Telemetry checkpoint: verify_offline_profile_snapshot

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/verify-offline-profile.js" <envUrl> \
  --project-root '<working_dir>' --tenant-id "<tenantId>"

If status: drift, surface the drift list verbatim. The estimate that follows is still meaningful but flag that the live profile diverges from offline-profile.json — recommend re-running /setup-offline-profile or /edit-offline-profile to reconcile.

Step 3 — Per-table row counts (with scope-applied filter)

Telemetry checkpoint: count_offline_profile_rows

For each table in the profile, run a count query that applies the same filter the runtime would use:

recorddistributioncriteriarecordsownedby* flagEffective filter
1 (All records)n/a?$count=true&$top=0 (whole table)
2 + merecordsownedbyme=true?$count=true&$top=0&$filter=_ownerid_value eq <current-user-id>
2 + teamrecordsownedbymyteam=trueApprox: _ownerid_value in (current user's team-owned IDs); for estimate, use team count from teamroles_association
2 + burecordsownedbymybusinessunit=true?$count=true&$top=0&$filter=_owningbusinessunit_value eq <current-bu-id>
0 (Related only)n/aCan't estimate independently — depends on parents. Report ~depends on parent counts.

For current-user/current-BU filters, resolve identity only inside this skill by calling Dataverse WhoAmI through scripts/dataverse-request.js against the resolved <envUrl> with --tenant-id "<tenantId>" from the same guarded root. If that call fails, report the affected scope as unknown — current user/BU unavailable instead of blocking the whole preview. Do not expect scripts/resolve-environment.js or auth.config.json.environment to provide UserId / BusinessUnitId.

For each table:

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" <envUrl> GET \
  "<entitysetname>?\$count=true&\$top=0&<scope-filter>" --tenant-id "<tenantId>"

Cap at 5000 (Dataverse non-aggregate count cap). When the result is exactly 5000, prefix with ≥ in the report.

Step 4 — Cache-size estimate

Telemetry checkpoint: estimate_offline_cache_size

Rough byte-per-row heuristics (configurable; replace with measured values once we have a real sync benchmark):

Column typeBytes
Uniqueidentifier40
String (avg 80 chars)100
Integer / Decimal12
DateTime28
Boolean / State / Status4
Picklist (option value only)8
Memo (avg 500 chars)600
Lookup (FK only)40
Image (URL + thumbnail metadata only — see note below for full-image bytes)200
File (URL + name metadata)200

For each table, compute: estimatedBytesPerRow = sum(bytesForEach column in selectedcolumns). Then tableTotalBytes = rows × estimatedBytesPerRow.

Per-table sync overhead: each syncintervalinminutes interval triggers a delta query → assume ~20% of total rows touched on a typical day. dailyTransferBytes = (totalBytes × 0.20 × intervalsPerDay).

Step 5 — Report

═════════════════════════════════════════════════════════════
  Offline Scope Preview — <profileName>
═════════════════════════════════════════════════════════════

Drift status: ok | drift (see verify output)

Per-table breakdown:

| Table              | Scope          | Rows     | Cols | Est. bytes | Sync (min) |
|--------------------|----------------|----------|------|------------|------------|
| chnl_region        | All records    | 12       | 7    | 4 KB       | 60         |
| chnl_product       | All records    | 312      | 13   | 280 KB     | 60         |
| chnl_rmprofile     | Org+me         | 1        | 10   | 1 KB       | 10         |
| chnl_store         | Org+me         | 84       | 17   | 112 KB     | 10         |
| chnl_storevisit    | Org+me         | 412      | 13   | 220 KB     | 5          |
| chnl_order         | Org+me         | 156      | 14   | 95 KB      | 10         |
| chnl_orderline     | Related only   | ~depends | 11   | ~150 KB    | 10         |

Total initial download : ~860 KB (5000-rows cap not hit)
Daily transfer estimate: ~12 MB / device / day (assuming 20% delta rate)

Sync intervals per day:
  chnl_storevisit (5 min)  → 288 syncs/day  ⚠ high
  chnl_store      (10 min) → 144 syncs/day
  chnl_order      (10 min) → 144 syncs/day
  chnl_rmprofile  (10 min) → 144 syncs/day
  chnl_region     (60 min) → 24  syncs/day
  chnl_product    (60 min) → 24  syncs/day

Concerns:
  - chnl_storevisit at 5 min could exceed mobile data caps in low-signal areas
    (battery drain too). Consider 10 min unless 5 min is mission-critical.

Image / File bytes NOT counted by these heuristics. The metadata (URL +
thumbnail size) IS counted at 200 bytes/row, but the JPEG/file payload
itself transfers separately at runtime sync time. To estimate image
storage, multiply expected non-empty image rows × average JPEG size
(typically 10–500 KB per thumbnail).

Status code (final line)

  • DONE — estimate produced, no concerns
  • DONE_WITH_CONCERNS: <list> — estimate produced but flagged items (high sync rates, near-cap row counts, drift detected, etc.)
  • NEEDS_CONTEXT: <missing> — no profile to estimate against
  • BLOCKED: <reason> — auth or query failures

Notes

This skill is intentionally estimate-grade, not precise. The byte heuristics are rule-of-thumb; real cache size depends on Dataverse's storage layout + JSON serialization + per-device cache compression. The numbers are useful for comparative decisions (one scope vs another, one column list vs another), not for absolute capacity planning.

For precise figures, the only source of truth is the runtime sync log itself — only available once the app is deployed and an RM has signed in.

Download now (ZIP)

Trending

Steady: 0 new projects took it in the last 4 weeks, none the 4 weeks before.thin data

Week of Aug 30: 0 new projectsWeek of Sep 6: 0 new projectsWeek of Sep 13: 0 new projectsWeek of Sep 20: 0 new projectsWeek of Sep 27: 0 new projectsWeek of Oct 4: 0 new projectsWeek of Oct 11: 0 new projectsWeek of Oct 18: 0 new projects
Aug 2026Sep 2026Oct 2026
New projects taking a version of this file each week, over the 8 weeks our latest run read: only 0 in all, so this is a hint, not a trend.

Who's talking about microsoft/power-platform-skills

The biggest 5 of 50 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 50

Talked about on GitHub (50 times).

On GitHub · 50

45 more on GitHub

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.