Skip to content
Development
Skill

/add-pdf-report

Internal implementation skill invoked by /add-native for app-generated PDF report workflows using expo-print and, when present, expo-sharing.

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

Claude Code

$ npx -y skills add microsoft/power-platform-skills --skill add-pdf-report --agent claude-code

SKILL.md

add-pdf-report.SKILL.md
name: add-pdf-report
description: Internal implementation skill invoked by /add-native for app-generated PDF report workflows using expo-print and, when present, expo-sharing.
user-invocable: false
disable-model-invocation: true
allowed-tools: Read, Edit, Write, Grep, Glob, Bash, AskUserQuestion
model: sonnet

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

**Working directory:** before any project read or command, execute [native-artifact-compatibility.md Step 0](${PLUGIN_ROOT}/shared/references/native-artifact-compatibility.md#0-bind-every-operation-to-the-app-root). 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 PDF Report

**Internal helper.** Users should invoke `/add-native pdf-report`, `/add-native generate-pdf`, or `/add-native pdf-export`; `/add-native` routes here after resolving the capability.

Generate or verify a local PDF report wrapper for app-owned PDFs created from records, evidence, certificates, receipts, or summaries. This helper uses `expo-print` to create a local PDF file URI. It may use `expo-sharing` only when that package is already present. It never installs packages or imports the native PDF viewer directly.

Capability boundaries

| User need | Correct path | |---|---| | Generate/export/print a report from app data | This helper: `expo-print` -> local PDF URI | | Share the generated local PDF from the device | Add share method only if `expo-sharing` is already in `package.json` | | Retain the generated PDF in Dataverse | Create/update parent row first, then upload to a Dataverse File column with generated services | | Open an existing HTTPS or local file PDF in the Power Apps native viewer | `/add-native pdf-viewer`, only if `@microsoft/power-apps-native-pdf-viewer` 0.2.9+ is already present | | Pick/import/upload a user-selected PDF | `/add-native document-picker` or host `<FilePicker>` for Dataverse File columns |

Local generated PDFs are usually `file://` URIs and can be passed to `openHttpsPdf(...)` with `@microsoft/power-apps-native-pdf-viewer` 0.2.9+.

Steps

1. Verify app

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; }

If this fails, tell the user to run `/create-mobile-app` first and STOP.

2. Verify packages are already present

`expo-print` is required. `expo-sharing` is optional unless the plan specifically needs sharing behavior.

cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node -e "const p=require('./package.json'); const deps={...p.dependencies,...p.devDependencies}; const required='expo-print'; if (!deps[required]) { console.error('MISSING: expo-print is not in package.json. The template/app must already ship it for /add-native pdf-report. This skill will not install it or edit native config. Capability not added.'); process.exit(1); } console.log('OK: expo-print package present'); console.log(deps['expo-sharing'] ? 'OK: expo-sharing package present' : 'OPTIONAL_MISSING: expo-sharing is not in package.json; generated PDFs can be created/viewed/uploaded, but sharing helpers must not be generated.');"

If `expo-print` is missing, STOP. Do not run `npm install`, `npx expo install`, `pod install`, or edit `app.config.js`. Do not add `pdf-report` to the plan or generated wrappers for this app.

If `expo-sharing` is missing:

  • Continue for generate-only, native-viewer preview, or Dataverse-upload flows.
  • Do not import `expo-sharing`.
  • Do not generate `sharePdfReport(...)`.
  • If the user's requirement specifically includes sharing, STOP and say sharing is not supported by this template.

2a. Reconcile requested artifacts

Read and execute [native-artifact-compatibility.md](${PLUGIN_ROOT}/shared/references/native-artifact-compatibility.md) Steps 1–3 for the PDF report row before any writes or reuse. Inherit the current approval/mode from `/add-native`; do not repeat a valid scoped approval. Inspect `src/native/pdfReport.ts` for the full requested API: `createPdfReport`, `wrapPdfDocument`, `escapePdfHtml`, requested `includeBase64` output for retention, and `sharePdfReport`/`PdfShareResult` when sharing is approved. Generate-only compatibility does not satisfy a share/upload request. Verify local-file and generated File-service payload requirements; missing required storage or an incompatible artifact outside approval returns `NEEDS_CONTEXT` to the owner, or asks standalone.

3. Write or verify `src/native/pdfReport.ts`

Apply Step 2a's decision for `src/native/pdfReport.ts`: create when requested and missing, reuse unchanged only if compatible, or make only the approved scoped update. Preserve custom HTML logic and existing exports; the example is not an overwrite template.

The wrapper MUST:

  • Import `expo-print` only after Step 2 confirms it is present.
  • Import `expo-sharing` only when Step 2 confirms it is present.
  • Return discriminated unions and never throw.
  • Treat generated local PDFs as local files for view/share/upload flows.
  • Never import `@microsoft/power-apps-native-pdf-viewer` directly from this wrapper.
  • Keep HTML generation deterministic and app-owned; do not fetch remote HTML inside the wrapper.

Base wrapper when sharing is requested and `expo-sharing` is present:

// src/native/pdfReport.ts
import * as Print from 'expo-print';
import * as Sharing from 'expo-sharing';

export type PdfReportResult =
  | { ok: true; uri: string; numberOfPages?: number; base64?: string }
  | { ok: false; reason: 'EMPTY_HTML' | 'PRINT_FAILED'; message?: string };

export type PdfShareResult =
  | { ok: true }
  | { ok: false; reason: 'INVALID_URI' | 'SHARING_UNAVAILABLE' | 'SHARE_
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 add-pdf-report.

Which coding agents can use add-pdf-report?
add-pdf-report 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.