Skip to main content
ClaudeWave
Skill808 repo starsupdated 3d ago

add-camera

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

Install in Claude Code
Copy
git clone --depth 1 https://github.com/microsoft/power-platform-skills /tmp/add-camera && cp -r /tmp/add-camera/plugins/mobile-apps/skills/add-native/add-camera ~/.claude/skills/add-camera
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

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

**References:**

- [dataverse-reference.md](${PLUGIN_ROOT}/skills/add-dataverse/references/dataverse-reference.md) — File/image column upload patterns (Step 7–8)

# Add Camera

**Internal helper.** Users should invoke `/add-native camera`, `/add-native image-picker`, `/add-native barcode-scanner`, or `/add-native qr-scanner`; `/add-native` routes here after resolving the capability.

Generate typed camera + image-picker wrappers, an optional barcode/QR scanner control, and optional custom-upload guidance for Dataverse image/file workflows.

This skill **only writes JS files under `src/native/`**. It does not install modules and does not touch `package.json` or `app.config.js` — the underlying Expo modules (`expo-camera`, `expo-image-picker`) and their config plugins must already be shipped by the `microsoft/power-platform-skills/plugins/mobile-apps/template#main` template. If they're missing, STOP and tell the user the template doesn't ship them yet.

Why: customer binaries are built from a pre-built rewrap base, not from the customer's `package.json`. Adding a native module here would compile against modules the binary doesn't actually contain, causing runtime crashes after rewrap. See [`/add-native`](../SKILL.md) for the same hard rules.

Two modules are required (must already be in `package.json`):
- **`expo-camera`** — live viewfinder, barcode scanning
- **`expo-image-picker`** — gallery selection + quick camera capture (simpler API, no viewfinder)

**Dataverse File/Image boundary:** for normal Dataverse File/Image form fields, screens should use `FilePicker` / `ImagePicker` from `@microsoft/power-apps-native-host` (see [`/add-native` File/Image Picker Ownership](../SKILL.md#fileimage-picker-ownership)). `/add-native camera` owns custom camera/gallery/scanner workflows, such as a dedicated evidence-capture screen, barcode/QR scan gate, or gallery-selected image that is transformed before saving.

**Pen/signature boundary:** signature, sign-off, ink, drawing, or pen capture belongs to `/add-native pen-input` (which routes internally to the pen helper). Both camera photos and pen signatures can persist to Dataverse Image/File columns, but the capture wrappers are separate.

## Workflow

1. Verify project → 2. Verify modules are template-shipped → 3. Write camera wrapper → 3b. Write scanner control if requested → 4. Detect Dataverse columns → 5. Write upload helper only for custom capture flows → 6. Type-check → 7. Summary

---

### Step 1 — Verify project

```bash
test -f app.config.js && test -f power.config.json && test -f package.json
```

If any file is missing, report and STOP — this skill requires an initialized Power Apps mobile app.

### Step 2 — Verify modules are template-shipped

Both `expo-camera` and `expo-image-picker` must already be in `package.json`. Do **not** install them — if they're missing, the upstream template hasn't shipped them yet, and this skill STOPs.

```bash
node -e "const p = require('./package.json'); const need = ['expo-camera','expo-image-picker']; const missing = need.filter(m => !p.dependencies?.[m]); if (missing.length) { console.error('MISSING from package.json: ' + missing.join(', ') + '. The upstream template must ship these for /add-native camera to run. Do NOT install them yourself — file an issue at the template repo (plugins/mobile-apps/template) instead.'); process.exit(1); } console.log('OK: both modules present');"
```

If the check fails, STOP. Print the error verbatim. Do not run `npx expo install`. Do not edit `app.config.js`. Tell the user the template version they scaffolded from doesn't include the camera modules — they need to wait for a newer template release or open a request upstream.

Also check if the wrapper already exists:

```bash
test -f src/native/camera.ts && echo "exists" || echo "missing"
```

If the wrapper exists, skip Step 3 — do NOT overwrite. Continue to Step 3b / Step 4 as needed.

Detect whether barcode/QR scanning is requested by checking `$ARGUMENTS` and `native-app-plan.md` for `barcode`, `bar code`, `QR`, `scanner`, `scan gate`, `SKU scan`, or `inventory scan`. If present, set `SCANNER_NEEDED=yes`; otherwise skip Step 3b unless the user explicitly asks for scanner support.

### Step 3 — Write camera wrapper

**Print before starting:**
> "→ Writing src/native/camera.ts wrapper (takePhoto + pickImage with discriminated-union results)…"

Create `src/native/camera.ts`. If the file already exists, **do NOT overwrite** — append a comment noting "regenerated by /add-native camera" and STOP this step.

```typescript
// src/native/camera.ts
// Camera capture and image picker wrapper for Power Apps mobile apps.
// Uses expo-image-picker for both camera capture and gallery selection.
// All functions return discriminated-union results — never throw.

import * as ImagePicker from 'expo-image-picker';

// --- Result types ---

export type PhotoResult =
  | { ok: true; uri: string; width: number; height: number; mimeType?: string; fileSize?: number }
  | { ok: false; reason: 'permission-denied' | 'cancelled' | 'unsupported' | 'error'; message?: string };

// --- Permission ---

export async function requestCameraPermission(): Promise<boolean> {
  const { status } = await ImagePicker.requestCameraPermissionsAsync();
  return status === 'granted';
}

export async function requestMediaLibraryPermission(): Promise<boolean> {
  const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
  return status === 'granted';
}

// --- Capture ---

/**
 * Launch the device camera and capture a photo.
 * Returns `{ ok: false, reason: 'unsupported' }` when native camera capture is unavailable.
 */
export async function takePhoto(options?: {
  quality?: number;
  allowsEditing?: boolean;
}): Promise<PhotoResult> {
  const granted = await requestCameraPermission();
  if (!granted) return { ok: false, reason: 'perm
add-data-sourceSkill

Guide the user to add a data source, connection, or API connector to a Canvas App via Power Apps Studio, then verify and continue. USE WHEN the user asks to add a data source, add a connection, add an API, add a connector, connect to SharePoint / Dataverse / SQL / Excel / OneDrive / Teams / Office 365, or any similar request to make new data available to the app. DO NOT USE WHEN the user is asking to list or describe existing data sources — call list_data_sources or list_apis directly instead.

canvas-appSkill

Creates or edits a Power Apps Canvas App through the Canvas Authoring MCP coauthoring session. Handles new app generation, direct targeted edits, complex multi-screen changes, responsive layout, per-screen self-QA, and compile-error convergence. Trigger on requests to create, build, generate, modify, update, change, fix, or edit a Canvas App or .pa.yaml files.

configure-canvas-mcpSkill

Configure the Canvas Authoring MCP server for the current coauthoring session. USE WHEN "configure MCP", "set up MCP server", "MCP not working", "connect Canvas Apps MCP", "canvas-authoring not available", "MCP not configured", "set up canvas apps".

generate-canvas-appSkill

[DEPRECATED — use canvas-app instead] Generate a complete Power Apps canvas app.

report-issueSkill

>

add-azuredevopsSkill

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

add-connectorSkill

Use when adding a Power Platform connector to an Expo/React Native Power Apps mobile app and no dedicated mobile connector skill exists.

add-datasourceSkill

Use when adding an unspecified data source to an Expo/React Native Power Apps mobile app; routes to Dataverse, SharePoint, or another connector.