winapp-package
Package a Windows app as an MSIX installer for distribution or testing. Use when creating a Windows installer, packaging an Electron/Flutter/.NET/Rust/C++/Tauri app for Windows, building an MSIX, distributing a desktop app, packaging a console app or CLI tool, or adding MSIX packaging to a build script or CI/CD pipeline.
Works with
---
name: winapp-package
description: Package a Windows app as an MSIX installer for distribution or testing. Use when creating a Windows installer, packaging an Electron/Flutter/.NET/Rust/C++/Tauri app for Windows, building an MSIX, distributing a desktop app, packaging a console app or CLI tool, or adding MSIX packaging to a build script or CI/CD pipeline.
license: MIT
---
## When to use
Use this skill when:
- **Creating an MSIX installer** from a built app for distribution or testing
- **Packaging any Windows app** — GUI apps, console apps, CLI tools, services, or background processes
- **Signing a package** with a development or production certificate
- **Bundling the Windows App SDK runtime** for self-contained deployment
## Prerequisites
Before packaging, you need:
1. **Built app output** in a folder (e.g., `bin/Release/`, `dist/`, `build/`)
2. **`Package.appxmanifest`** — from `winapp init` or `winapp manifest generate`
3. **Certificate** (optional) — `devcert.pfx` from `winapp cert generate` for signing
## Usage
### Basic packaging (unsigned)
```powershell
# Package from build output — manifest auto-detected from current dir or input folder
winapp package ./bin/Release
# Specify manifest location explicitly
winapp package ./dist --manifest ./Package.appxmanifest
```
### Package and sign in one step
```powershell
# Sign with existing certificate
winapp package ./bin/Release --cert ./devcert.pfx
# Custom certificate password
winapp package ./bin/Release --cert ./devcert.pfx --cert-password MyP@ssw0rd
```
### Generate certificate + package in one step
```powershell
# Auto-generate cert, sign, and package
winapp package ./bin/Release --generate-cert
# Also install the cert to trust it on this machine (requires admin)
winapp package ./bin/Release --generate-cert --install-cert
```
### Self-contained deployment
```powershell
# Bundle Windows App SDK runtime so users don't need it installed (must have winappsdk reference in the winapp.yaml or *.csproj)
winapp package ./bin/Release --cert ./devcert.pfx --self-contained
```
### Custom output path and name
```powershell
# Specify output file
winapp package ./dist --output ./releases/myapp-v1.0.msix --cert ./devcert.pfx
# Custom package name
winapp package ./dist --name "MyApp_1.0.0_x64" --cert ./devcert.pfx
```
## What the command does
1. **Locates `Package.appxmanifest`** — looks in input folder, then current directory (or uses `--manifest`)
2. **Copies manifest + assets** into a staging layout alongside your app files
3. **Discovers manifest-referenced files** — any non-image file referenced in the manifest (e.g., AppExtension payloads like `manifest.json`, config files) is automatically copied from the manifest directory or input folder if missing from staging
4. **Generates `resources.pri`** — Package Resource Index for UWP-style resource lookup (skip with `--skip-pri`)
5. **Runs `makeappx pack`** — creates the `.msix` package file
6. **Signs the package** (if `--cert` provided) — calls `signtool` with your certificate
Output: a `.msix` file that can be installed on Windows via double-click or `Add-AppxPackage`.
## Installing the MSIX for testing
```powershell
# Trust the dev certificate first (one-time, requires admin)
winapp cert install ./devcert.pfx
# Install the MSIX
Add-AppxPackage ./myapp.msix
# Uninstall if needed
Get-AppxPackage *myapp* | Remove-AppxPackage
```
## Recommended workflow
1. **Build** your app (`dotnet build`, `cmake --build`, `npm run make`, etc.)
2. **Package** — `winapp package <build-output> --cert ./devcert.pfx`
3. **Trust cert** (first time) — `winapp cert install ./devcert.pfx` (admin)
4. **Install** — double-click the `.msix` or `Add-AppxPackage ./myapp.msix`
5. **Test** the installed app from the Start menu
### Advanced: External content catalog
For sparse packages with `AllowExternalContent`, you may need a code integrity catalog:
```powershell
# Generate CodeIntegrityExternal.cat for external executables
winapp create-external-catalog "./bin/Release"
# Include subdirectories and specify output path
winapp create-external-catalog "./bin/Release" --recursive --output ./catalog/CodeIntegrityExternal.cat
```
### Bundling multiple architectures
Create an MSIX bundle from multiple per-architecture build outputs:
```powershell
# Create unsigned bundle for Store submission (x64 + arm64)
winapp package ./publish/x64 ./publish/arm64
# Create signed bundle for sideloading
winapp package ./publish/x64 ./publish/arm64 --cert ./devcert.pfx
# Self-contained bundle with Windows App SDK runtime per arch
winapp package ./publish/x64 ./publish/arm64 --self-contained --generate-cert
```
**How it works:** When multiple input folders are passed, `winapp package`:
1. Detects the architecture of each folder's primary executable from its PE header
2. Resolves a manifest for each slice (see below)
3. Validates that all slices share the same Identity, Capabilities, and Dependencies
4. Packs each folder into an intermediate unsigned `.msix`
5. Bundles them into a single `.msixbundle` using `makeappx bundle`
6. Signs only the bundle (not individual slices) — the signature covers all packages inside
**Manifest resolution:** Each slice needs a manifest. Resolution order:
- `--manifest <path>` uses one manifest for all slices (architecture auto-stamped per folder)
- Per-folder `Package.appxmanifest` if present in the input folder
- Fallback to `Package.appxmanifest` in the current working directory
The `ProcessorArchitecture` is always force-set to the detected architecture per-slice. All other Identity fields must be consistent across slices.
**Output:** `<Name>_<Version>_<arch1>_<arch2>.msixbundle` (architectures sorted alphabetically).
**Store submission:** An unsigned bundle is valid for Store upload — Partner Center signs it with your reserved identity certificate. For sideloading, pass `--cert` or `--generate-cert`.
This hashes executables in the specified directories so Windows trusts them when running with sparse package identity.
## CI/CD
### GitHub Actions
Use the `microsoft/setup-winapp` action to install winapp on GitHub-hosted runners:
```yaml
- uses: microsoft/setup-winapp@v1
- name: Package
run: winapp package ./dist --cert ${{ secrets.CERT_PATH }} --cert-password ${{ secrets.CERT_PASSWORD }} --quiet
```
**Tips for CI/CD pipelines:**
- Use `--quiet` (or `-q`) to suppress progress output
- Use `--if-exists skip` with `winapp cert generate` to avoid regenerating existing certificates
- Store your PFX certificate as a repository secret and decode it in CI
- Use `--use-defaults` (or `--no-prompt`) with `winapp init` to avoid interactive prompts
## Tips
- The `package` command aliases to `pack` — both work identically
- `Package.appxmanifest` Publisher must match the certificate publisher — use `winapp cert generate --manifest` to ensure they match
- Use `--skip-pri` if your app doesn't use Windows resource loading (e.g., most Electron/Rust/C++ apps without UWP resources)
- For framework-specific packaging paths (Electron, .NET, Rust, etc.), see the `winapp-frameworks` skill
- The `--executable` flag overrides the entry point in the manifest — useful when your exe name differs from what's in `Package.appxmanifest`
- For production distribution, use a certificate from a trusted CA and add `--timestamp` when signing with `winapp sign`
## Related skills
- Need a manifest first? See `winapp-manifest` to generate `Package.appxmanifest`
- Need a certificate? See `winapp-signing` for certificate generation and management
- Having issues? See `winapp-troubleshoot` for a command selection flowchart and error solutions
## Troubleshooting
| Error | Cause | Solution |
|-------|-------|----------|
| "Package.appxmanifest not found" | No manifest in input folder or current dir | Run `winapp init` or `winapp manifest generate` first |
| "Publisher mismatch" | Cert publisher ≠ manifest publisher | Regenerate cert with `winapp cert generate --manifest`, or edit manifest |
| "Package installation failed" | Cert not trusted or stale package | Run `winapp cert install ./devcert.pfx` (admin), then `Get-AppxPackage <name> \| Remove-AppxPackage` |
| "makeappx not found" | Build tools not downloaded | Run `winapp update` or `winapp tool makeappx --help` to trigger download |
## Command Reference
### `winapp package`
Create MSIX installer from your built app. Run after building your app. A manifest (Package.appxmanifest or appxmanifest.xml) is required for packaging - it must be in current working directory, passed as --manifest or be in the input folder. Use --cert devcert.pfx to sign for testing. Example: winapp package ./dist --manifest Package.appxmanifest --cert ./devcert.pfx
**Aliases:** `pack`
#### Arguments
<!-- auto-generated from cli-schema.json -->
| Argument | Required | Description |
|----------|----------|-------------|
| `<input-folder>` | Yes | One or more input folders with package layout. Pass multiple folders to create an MSIX bundle (e.g., winapp pack ./publish/x64 ./publish/arm64). |
#### Options
<!-- auto-generated from cli-schema.json -->
| Option | Description | Default |
|--------|-------------|---------|
| `--cert` | Path to signing certificate (will auto-sign if provided) | (none) |
| `--cert-password` | Certificate password (default: password) | `password` |
| `--executable` | Path to the executable relative to the input folder. | (none) |
| `--generate-cert` | Generate a new development certificate | (none) |
| `--install-cert` | Install certificate to machine | (none) |
| `--manifest` | Path to AppX manifest file (default: auto-detect from input folder or current directory) | (none) |
| `--name` | Package name (default: from manifest) | (none) |
| `--output` | Output file name for the generated package (.msix) or bundle (.msixbundle). Defaults to <name>_<version>_<arch>.msix for single packages, or <name>_<version>_<arch1>_<arch2>.msixbundle for bundles. | (none) |
| `--publisher` | Publisher distinguished name (DN) for certificate generation (e.g., CN=MyCompany). Bare names are auto-wrapped as CN=<name>. | (none) |
| `--self-contained` | Bundle Windows App SDK runtime for self-contained deployment | (none) |
| `--skip-pri` | Skip PRI file generation | (none) |
### `winapp create-external-catalog`
Generates a CodeIntegrityExternal.cat catalog file with hashes of executable files from specified directories. Used with the TrustedLaunch flag in MSIX sparse package manifests (AllowExternalContent) to allow execution of external files not included in the package.
#### Arguments
<!-- auto-generated from cli-schema.json -->
| Argument | Required | Description |
|----------|----------|-------------|
| `<input-folder>` | Yes | List of input folders with executable files to process (separated by semicolons) |
#### Options
<!-- auto-generated from cli-schema.json -->
| Option | Description | Default |
|--------|-------------|---------|
| `--compute-flat-hashes` | Include flat hashes when generating the catalog | (none) |
| `--if-exists` | Behavior when output file already exists | `Error` |
| `--output` | Output catalog file path. If not specified, the default CodeIntegrityExternal.cat name is used. | (none) |
| `--recursive` | Include files from subdirectories | (none) |
| `--use-page-hashes` | Include page hashes when generating the catalog | (none) |More Testing skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
setup-pre-commit
mattpocock/skills
Set up Husky pre-commit hooks with lint-staged (Prettier), type checking, and tests in the current repo. Use when user wants to add pre-commit hooks, set up Husky, configure lint-staged, or add commit-time formatting/typechecking/testing.
agent-browser
vercel-labs/agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.

