$npx -y skills add microsoft/power-platform-skills --skill add-cameraInternal implementation skill invoked by /add-native for camera, image picker, barcode scanner, QR scanner, and camera/gallery Dataverse artifact workflows.
| 1 | **Shared instructions: [shared-instructions.md](${CLAUDE_SKILL_DIR}/../../../shared/shared-instructions.md)** — read first. |
| 2 | |
| 3 | **References:** |
| 4 | |
| 5 | - [dataverse-reference.md](${CLAUDE_SKILL_DIR}/../../add-dataverse/references/dataverse-reference.md) — File/image column upload patterns (Step 7–8) |
| 6 | |
| 7 | # Add Camera |
| 8 | |
| 9 | **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. |
| 10 | |
| 11 | Generate typed camera + image-picker wrappers, an optional barcode/QR scanner control, and optional custom-upload guidance for Dataverse image/file workflows. |
| 12 | |
| 13 | 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 upstream `pa-wrap-tools/templates/expo-app-standalone` template. If they're missing, STOP and tell the user the template doesn't ship them yet. |
| 14 | |
| 15 | 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. |
| 16 | |
| 17 | Two modules are required (must already be in `package.json`): |
| 18 | - **`expo-camera`** — live viewfinder, barcode scanning |
| 19 | - **`expo-image-picker`** — gallery selection + quick camera capture (simpler API, no viewfinder) |
| 20 | |
| 21 | **Dataverse File/Image boundary:** for normal Dataverse File/Image form fields, screens should use `FilePicker` / `ImagePicker` from `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. |
| 22 | |
| 23 | **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. |
| 24 | |
| 25 | ## Workflow |
| 26 | |
| 27 | 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 |
| 28 | |
| 29 | --- |
| 30 | |
| 31 | ### Step 1 — Verify project |
| 32 | |
| 33 | ```bash |
| 34 | test -f app.config.js && test -f power.config.json && test -f package.json |
| 35 | ``` |
| 36 | |
| 37 | If any file is missing, report and STOP — this skill requires an initialized Power Apps mobile app. |
| 38 | |
| 39 | ### Step 2 — Verify modules are template-shipped |
| 40 | |
| 41 | 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. |
| 42 | |
| 43 | ```bash |
| 44 | 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 (pa-wrap-tools/templates/expo-app-standalone) instead.'); process.exit(1); } console.log('OK: both modules present');" |
| 45 | ``` |
| 46 | |
| 47 | 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. |
| 48 | |
| 49 | Also check if the wrapper already exists: |
| 50 | |
| 51 | ```bash |
| 52 | test -f src/native/camera.ts && echo "exists" || echo "missing" |
| 53 | ``` |
| 54 | |
| 55 | If the wrapper exists, skip Step 3 — do NOT overwrite. Continue to Step 3b / Step 4 as needed. |
| 56 | |
| 57 | 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. |
| 58 | |
| 59 | ### Step 3 — Write camera wrapper |
| 60 | |
| 61 | **Print before starting:** |
| 62 | > "→ Writing src/native/camera.ts wrapper (takePhoto + pickImage with discriminated-union results)…" |
| 63 | |
| 64 | 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. |
| 65 | |
| 66 | ```typescript |
| 67 | // src/ |