本文へ移動
cccskills
無料GitHub で公開

add-geolocation

Internal implementation skill invoked by /add-native for native background GPS tracking with durable storage and Dataverse sync using @microsoft/power-apps-native-bglocation.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md9.7 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

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

Working directory: before any project read or command, execute native-artifact-compatibility.md Step 0. Inherit /add-native's resolved absolute working_dir; bind every shell call and file tool to it, even when this helper starts from another directory.

Add Geolocation

Internal helper for /add-native geolocation, /add-native location-tracking, /add-native background-location, /add-native gps-tracking, and /add-native @microsoft/power-apps-native-bglocation.

Use this only for continuous/background GPS tracking with native durable storage and inline Dataverse upload. For a single foreground coordinate read, use /add-native location (expo-location) instead.

Hard rules:

  • Auth is MSAL-only. Do not expose OneAuth or an auth selector.
  • Use geoService(dataSource, app_id) and BgLocationClient.
  • Do not use GeolocationExtension, HostingSDK, PCF, Launch URI, or CordovaV2 bridge paths.
  • Do not install packages or edit native config.
  • The control is not usable until its Dataverse target table and mapped columns are verified.

1. Verify app and package

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
test -f app.config.js && test -f power.config.json && test -f package.json && test -d src || { echo "BLOCKED: working_dir is not an initialized app" >&2; exit 1; }
node -e "const p=require('./package.json'); const m='@microsoft/power-apps-native-bglocation'; if (!p.dependencies?.[m]) { console.error('MISSING: ' + m); process.exit(1); } console.log('OK: geolocation package present');"

If either check fails, stop. The template/app must already ship the native package.

2. Verify the Dataverse target table first

This control uses the package default Dataverse entity set:

msdyn_locationrecords

Do not ask the user for a table name and do not invent a custom table. msdyn_locationrecords must already exist before the control can be used.

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
ENV_JSON=$(node "${PLUGIN_ROOT}/scripts/resolve-environment.js" "$(node -e "console.log(require('./power.config.json').environmentId)")")
ENV_URL=$(node -e "const j=JSON.parse(process.argv[1]); process.stdout.write(j.environmentUrl || '')" "$ENV_JSON")

TABLE="msdyn_locationrecords"
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "$ENV_URL" GET \
  "EntityDefinitions?\$filter=EntitySetName eq '$TABLE'&\$select=LogicalName,EntitySetName"

Required result:

  • One row returned: capture LogicalName and verify columns.
  • Empty value: []: stop. Mark BLOCKED (target table missing). Do not create the table, do not route to /add-dataverse, and do not report the control as usable. Tell the user to run the geolocation-control table provisioning/setup mechanism, then re-run /add-native geolocation.
  • Auth/environment error: stop. Mark UNVERIFIED (target table not checked). Do not report the control as usable.

When the table exists, verify every mapped column exists:

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "$ENV_URL" GET \
  "EntityDefinitions(LogicalName='<logicalName>')/Attributes?\$select=LogicalName,AttributeType"

Required default fieldMap columns from the package README:

msdyn_locationrecordid, msdyn_appid, msdyn_latitude, msdyn_longitude,
msdyn_altitude, msdyn_accuracy, msdyn_heading, msdyn_speed, msdyn_timestamp

If any active fieldMap column is missing, stop. Mark BLOCKED (target columns missing) and tell the user to fix the control table through the geolocation-control table provisioning/setup mechanism.

2a. Reconcile requested artifacts

Read and execute native-artifact-compatibility.md Steps 1–3 for the geolocation row before any writes or reuse. Inherit the current approval/mode from /add-native; do not repeat a valid scoped approval. Inspect src/native/geolocation.ts for all requested tracking/status/location exports, GeoTrackingTarget, MSAL-only geoService/BgLocationClient, required connectionUrl/trackInBackground/persistAcrossRestarts, durable storage, and Dataverse sync. Reuse Step 2's verified msdyn_locationrecords columns; one-shot location or a wrapper targeting another table is not compatible. An incompatible artifact outside approval returns NEEDS_CONTEXT to the owner, or asks standalone; missing table/columns remain BLOCKED, never a usable-control success.

3. Write src/native/geolocation.ts

Apply Step 2a's decision for src/native/geolocation.ts: create when requested and missing, reuse unchanged only if compatible, or make only the approved scoped update. Preserve custom code, exports, and callers; do not overwrite from the example. Screens import this wrapper, not the package directly.

The target config must require the README's two tracking flags:

  • trackInBackground: boolean
  • persistAcrossRestarts: boolean
// src/native/geolocation.ts
import {
  geoService,
  BgLocationClient,
  AuthMethod,
  ConnectionType,
} from '@microsoft/power-apps-native-bglocation';
import type {
  DataverseDataSource,
  LocationData,
  PermissionStatus,
} from '@microsoft/power-apps-native-bglocation';

export type { LocationData, PermissionStatus } from '@microsoft/power-apps-native-bglocation';

export type GeoTrackingTarget = Omit<DataverseDataSource, 'authMethod' | 'connectionType'>;

export type GeoResult<T> =
  | { ok: true; value: T }
  | {
      ok: false;
      reason: 'NATIVE_MODULE_MISSING' | 'PERMISSION_DENIED' | 'TRACKING_FAILED';
      message?: string;
    };

let activeClient: BgLocationClient | null = null;

function client(): BgLocationClient {
  return activeClient ?? new BgLocationClient();
}

function dataSource(target: GeoTrackingTarget): DataverseDataSource {
  return {
    ...target,
    authMethod: AuthMethod.MSAL,
    connectionType: ConnectionType.Dataverse,
  };
}

function fail(error: unknown): Extract<GeoResult<never>, { ok: false }> {
  const message = error instanceof Error ? error.message : String(error);
  if (/native|module|not.*link|undefined is not an object|null is not an object/i.test(message)) {
    return { ok: false, reason: 'NATIVE_MODULE_MISSING', message };
  }
  if (/permission|denied|authoriz|not granted/i.test(message)) {
    return { ok: false, reason: 'PERMISSION_DENIED', message };
  }
  return { ok: false, reason: 'TRACKING_FAILED', message };
}

export async function startTracking(
  app_id: string,
  target: GeoTrackingTarget,
): Promise<GeoResult<void>> {
  try {
    activeClient = geoService(dataSource(target), app_id);
    await activeClient.startTracking();
    return { ok: true, value: undefined };
  } catch (error) {
    activeClient = null;
    return fail(error);
  }
}

export async function stopTracking(): Promise<GeoResult<void>> {
  try {
    await client().stopTracking();
    activeClient = null;
    return { ok: true, value: undefined };
  } catch (error) {
    return fail(error);
  }
}

export async function isTracking(): Promise<GeoResult<boolean>> {
  try {
    return { ok: true, value: await client().isTracking() };
  } catch (error) {
    return fail(error);
  }
}

export async function getPermissionStatus(): Promise<GeoResult<PermissionStatus>> {
  try {
    return { ok: true, value: await client().getPermissionStatus() };
  } catch (error) {
    return fail(error);
  }
}

export async function getCurrentLocation(): Promise<GeoResult<LocationData>> {
  try {
    return { ok: true, value: await client().getCurrentLocation() };
  } catch (error) {
    return fail(error);
  }
}

4. Usage shape

Integration guidance for the owner; do not edit screens in this helper.

Screens must pass connectionUrl, trackInBackground, and persistAcrossRestarts. Do not pass tableName or fieldMap; the control uses the default msdyn_locationrecords table and default msdyn_* field map. intervalMs, distanceFilterMeters, and notification are optional.

const target: GeoTrackingTarget = {
  connectionUrl: 'https://org.crm.dynamics.com',
  trackInBackground: true,
  persistAcrossRestarts: false,
};

await startTracking('my-wrap-app', target);

5. Type-check and summary

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
npx --no-install tsc --noEmit

Execute the shared compatibility contract's Step 4 after type-checking. Recheck all requested tracking APIs/flags, MSAL auth, durable storage/sync, and failure paths. Type-check success alone is insufficient; do not fix screen/generated files. Only after the requested artifact contract, table + columns, and TypeScript all pass, return the shared compatibility result and actual created/updated/reused paths before reporting:

Geolocation status : READY
Package present    : @microsoft/power-apps-native-bglocation
Wrapper            : src/native/geolocation.ts
Required config    : connectionUrl, trackInBackground, persistAcrossRestarts
Auth               : MSAL only
Target table       : <TABLE> verified
Native config      : not changed

If table verification failed, report BLOCKED or UNVERIFIED instead and do not update memory-bank.md as if the control is ready.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Activates and provisions a Power Pages website in a Power Platform environment via the Power Platform REST API. Use when the user wants to activate, provision, turn on, or enable a Power Pages website or portal.

日本語の概要は準備中です。原文の説明を表示しています。

microsoft/power-platform-skills9922026年10月11日 更新

Integrates Power Pages generative-AI summarization APIs (PREVIEW) into a Single Page Application (SPA) site — the Search Summary API and the Data Summarization API — on any record-detail or list page. Generates per-target service code (CSRF-handled) and AI site settings; delegates Web API settings, table permissions, and web roles to `/integrate-webapi` and `/create-webroles`. Use whenever a user wants AI/Copilot output that condenses Dataverse content on a Power Pages site — an AI summary, AI-generated overview or "key insights" across a record or list, a search-results summary, a case/incident summary, or recommendation-chip refinement — even when phrased as "AI-generated paragraph", "insights", or "overview". Do NOT use for: generative pages in model-driven apps (use the model-apps `genpage` skill), Copilot Studio agents/chatbots, summarizing documents or PDFs, Power BI dashboards, plain keyword search with no AI summary, or plain Dataverse CRUD (use `/integrate-webapi`).

日本語の概要は準備中です。原文の説明を表示しています。

microsoft/power-platform-skills9922026年10月11日 更新

Adds Azure DevOps connector to a Power Apps code app. Use when querying work items, creating bugs, managing pipelines, or making ADO API calls.

日本語の概要は準備中です。原文の説明を表示しています。

microsoft/power-platform-skills9922026年10月11日 更新

Internal implementation skill invoked by /add-native for camera, image picker, barcode scanner, QR scanner, and camera/gallery Dataverse artifact workflows.

日本語の概要は準備中です。原文の説明を表示しています。

microsoft/power-platform-skills9922026年10月11日 更新

Integrates Power Automate cloud flows into a Power Pages site. Lists available flows, suggests relevant ones based on intent, identifies scenarios and web roles, creates metadata files, and generates client-side code to call flows. Handles both new flow registration and adding already-registered flows to additional pages without re-creating metadata. Use when the user wants to add, connect, register, or link a Power Automate cloud flow to their site.

日本語の概要は準備中です。原文の説明を表示しています。

microsoft/power-platform-skills9922026年10月11日 更新

Adds any Power Platform connector to a Power Apps code app. Generic fallback for connectors not covered by a specific skill.

日本語の概要は準備中です。原文の説明を表示しています。

microsoft/power-platform-skills9922026年10月11日 更新

microsoft のスキルをすべて見る

このスキルの問題を報告する