Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
327 changes: 327 additions & 0 deletions .claude/agents/winapp.md

Large diffs are not rendered by default.

116 changes: 116 additions & 0 deletions .claude/skills/winapp-frameworks/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
name: winapp-frameworks
description: Framework-specific Windows development guidance for Electron, .NET (WPF, WinForms), C++, Rust, Flutter, and Tauri. Use when packaging or adding Windows features to an Electron app, .NET desktop app, Flutter app, Tauri app, Rust app, or C++ app.
version: 0.3.3
---
## When to use

Use this skill when:
- **Working with a specific app framework** and need to know the right winapp workflow
- **Choosing the correct install method** (npm package vs. standalone CLI)
- **Looking for framework-specific guides** for step-by-step setup, build, and packaging

Each framework has a detailed guide — refer to the links below rather than trying to guess commands.

## Framework guides

| Framework | Install method | Guide |
|-----------|---------------|-------|
| **Electron** | `npm install --save-dev @microsoft/winappcli` | [Electron setup guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/electron/setup.md) |
| **.NET** (WPF, WinForms, Console) | `winget install Microsoft.winappcli` | [.NET guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/dotnet.md) |
| **C++** (CMake, MSBuild) | `winget install Microsoft.winappcli` | [C++ guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/cpp.md) |
| **Rust** | `winget install Microsoft.winappcli` | [Rust guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/rust.md) |
| **Flutter** | `winget install Microsoft.winappcli` | [Flutter guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/flutter.md) |
| **Tauri** | `winget install Microsoft.winappcli` | [Tauri guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/tauri.md) |

## Key differences by framework

### Electron (npm package)
Use the **npm package** (`@Microsoft/WinAppCli`), **not** the standalone CLI. The npm package includes:
- The native winapp CLI binary bundled inside `node_modules`
- A Node.js SDK with helpers for creating native C#/C++ addons
Comment on lines +28 to +31
- Electron-specific commands under `npx winapp node`

Quick start:
```powershell
npm install --save-dev @microsoft/winappcli
npx winapp init . --use-defaults
npx winapp node create-addon --template cs # create a C# native addon
npx winapp node add-electron-debug-identity # register identity for debugging
```

Additional Electron guides:
- [Packaging guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/electron/packaging.md)
- [C++ notification addon guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/electron/cpp-notification-addon.md)
- [WinML addon guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/electron/winml-addon.md)
- [Phi Silica addon guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/electron/phi-silica-addon.md)

### .NET (WPF, WinForms, Console)
.NET projects have direct access to Windows APIs. Key differences:
- Projects with NuGet references to `Microsoft.Windows.SDK.BuildTools` or `Microsoft.WindowsAppSDK` **don't need `winapp.yaml`** — winapp auto-detects SDK versions from the `.csproj`
- The key prerequisite is `Package.appxmanifest`, not `winapp.yaml`
- No native addon step needed — unlike Electron, .NET can call Windows APIs directly
- `winapp init` automatically adds the `Microsoft.Windows.SDK.BuildTools.WinApp` NuGet package, enabling `dotnet run` with automatic identity registration

**If you already have a `Package.appxmanifest`** (e.g., WinUI 3 apps or projects with an existing packaging setup), you likely **don't need `winapp init`** — your project is already configured for packaged builds. Just make sure:
- Your `.csproj` references the `Microsoft.WindowsAppSDK` NuGet package (WinUI 3 apps already have this)
- The project properties are set up for packaged builds (e.g., `<WindowsPackageType>MSIX</WindowsPackageType>` or equivalent)
- WinUI 3 apps created from Visual Studio templates are typically already fully configured

Quick start:
```powershell
winapp init . --use-defaults
dotnet build <path-to-project.csproj> -c Debug -p:Platform=x64
winapp run bin\x64\Debug\<tfm>\win-x64\
```

Replace `<tfm>` with your target framework (e.g., `net10.0-windows10.0.26100.0`), and adjust `x64` to match your target architecture.

### C++ (CMake, MSBuild)
C++ projects use winapp primarily for SDK projections (CppWinRT headers) and packaging:
- `winapp init --setup-sdks stable` downloads Windows SDK + App SDK and generates CppWinRT headers
- Headers generated in `.winapp/generated/include`
- Response file at `.cppwinrt.rsp` for build system integration
- Add `.winapp/packages` to include/lib paths in your build system

### Rust
- Use the `windows` crate for Windows API bindings
- winapp handles manifest, identity, packaging, and certificate management
- Typical build output: `target/release/myapp.exe`

### Flutter
- Flutter handles the build (`flutter build windows`)
- winapp handles manifest, identity, packaging
- Build output: `build\windows\x64\runner\Release\`

### Tauri
- Tauri has its own bundler for `.msi` installers
- Use winapp specifically for **MSIX distribution** and package identity features
- winapp adds capabilities beyond what Tauri's built-in bundler provides (identity, sparse packages, Windows API access)

## Debugging by framework

| Framework | Recommended command | Notes |
|-----------|-------------------|-------|
| **.NET** | `winapp run .\bin\x64\Debug\<tfm>\win-x64\` | Build with `dotnet build -c Debug -p:Platform=x64` first; GUI apps launch directly; console apps need `--with-alias` |
| **C++** | `winapp run .\build\Debug --with-alias` | Console apps need `--with-alias` + `uap5:ExecutionAlias` in manifest |
| **Rust** | `winapp run .\target\debug --with-alias` | Console apps need `--with-alias` + `uap5:ExecutionAlias` in manifest |
| **Flutter** | `winapp run .\build\windows\x64\runner\Debug` | GUI app — plain `winapp run` works |
| **Tauri** | `winapp run .\dist` | Stage exe to `dist/` first (avoids copying entire `target/` tree); GUI app |
| **Electron** | `npx winapp node add-electron-debug-identity` | Uses Electron-specific identity registration; `winapp run` is **not** recommended for Electron |

**Key rules:**
- **GUI apps** (Flutter, Tauri, WPF): use `winapp run <build-output>` — launches via AUMID activation
- **Console apps** (C++, Rust, .NET console): use `winapp run <build-output> --with-alias` — launches via execution alias to preserve stdin/stdout. Requires `uap5:ExecutionAlias` in `Package.appxmanifest`
- **Electron**: different mechanism — uses `npx winapp node add-electron-debug-identity` because `electron.exe` is in `node_modules/`, not your build output
- **Startup debugging (any framework)**: use `winapp create-debug-identity <exe>` so your IDE can F5-launch the exe with identity from the first instruction

For full debugging scenarios and IDE setup, see the [Debugging Guide](https://github.com/microsoft/WinAppCli/blob/main/docs/debugging.md).

## Related skills
- **Setup**: `winapp-setup` — initial project setup with `winapp init`
- **Manifest**: `winapp-manifest` — creating and customizing `Package.appxmanifest`
- **Signing**: `winapp-signing` — certificate generation and management
- **Packaging**: `winapp-package` — creating MSIX installers from build output
- **Identity**: `winapp-identity` — enabling package identity for Windows APIs during development
- Not sure which command to use? See `winapp-troubleshoot` for a command selection flowchart
167 changes: 167 additions & 0 deletions .claude/skills/winapp-identity/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
---
name: winapp-identity
description: Enable Windows package identity for desktop apps to access Windows APIs like push notifications, background tasks, share target, and startup tasks. Use when adding Windows notifications, background tasks, or other identity-requiring Windows features to a desktop app.
version: 0.3.3
---
## When to use

Use this skill when:
- **The exe is separate from your app code** — e.g., Electron apps where `electron.exe` is in `node_modules`, not your build output
- **Testing sparse package behavior** specifically — `AllowExternalContent`, `TrustedLaunch`, etc.
- **Registering identity without copying files** — `create-debug-identity` leaves the exe in place

> **Prefer `winapp run` for most frameworks.** If your exe is inside your build output folder (.NET, C++, Rust, Flutter, Tauri), use `winapp run <build-output>` instead — it registers a full loose layout package and launches the app, simulating an MSIX install. Use `create-debug-identity` only when `winapp run` doesn't fit your scenario.

## Prerequisites

1. **`Package.appxmanifest`** in your project — from `winapp init` or `winapp manifest generate`
2. **Built executable** — the `.exe` your app runs from

## What is package identity?

Windows package identity enables your app to use restricted APIs and OS integration features:
- **Push notifications** (WNS)
- **Background tasks**
- **Share target** / share source
- **App startup tasks**
- **Taskbar pinning**
- **Windows AI APIs** (Phi Silica, OCR, etc.)
- **File type associations** registered properly in Settings

A standard `.exe` (from `dotnet build`, `cmake`, etc.) does **not** have identity. `create-debug-identity` registers a *sparse package* with Windows — the exe stays in its original location and Windows associates identity with it via `Add-AppxPackage -ExternalLocation`. This is different from `winapp run`, which copies files into a loose layout package.

## Usage

### Basic usage

```powershell
# Register sparse package for your exe (manifest auto-detected from current dir)
winapp create-debug-identity ./bin/Release/myapp.exe

# Specify manifest location
winapp create-debug-identity ./bin/Release/myapp.exe --manifest ./Package.appxmanifest
```

### Keep the original package identity

```powershell
# By default, '.debug' is appended to the package name to avoid conflicts with
# an installed MSIX version. Use --keep-identity to keep the manifest identity as-is.
winapp create-debug-identity ./myapp.exe --keep-identity
```

### Generate without installing

```powershell
# Create the sparse package layout but don't register it with Windows
winapp create-debug-identity ./myapp.exe --no-install
```

## What the command does

1. **Reads `Package.appxmanifest`** — extracts identity, capabilities, and assets
2. **Creates a sparse package layout** in a temp directory
3. **Appends `.debug`** to the package name (unless `--keep-identity`) to avoid conflicts
4. **Registers with Windows** via `Add-AppxPackage -ExternalLocation` — makes your exe "identity-aware"

After running, launch your exe normally — Windows will recognize it as having package identity.

## Recommended workflow

1. **Setup** — `winapp init . --use-defaults` (creates `Package.appxmanifest`)
2. **Generate development certificate** — `winapp cert generate`
3. **Build** your app
4. **Register identity** — `winapp create-debug-identity ./bin/myapp.exe`
5. **Run** your app — identity-requiring APIs now work
6. **Re-run step 4** whenever you change `Package.appxmanifest` or `Assets/`

## Tips

- You must re-run `create-debug-identity` after any changes to `Package.appxmanifest` or image assets
- The debug identity persists across reboots until explicitly removed
- To remove: `Get-AppxPackage *yourapp.debug* | Remove-AppxPackage`
- If you have both a debug identity and an installed MSIX, they may conflict — use `--keep-identity` carefully
- For Electron apps, use `npx winapp node add-electron-debug-identity` instead (handles Electron-specific paths)

## Debugging: `winapp run` vs `create-debug-identity`

| | `winapp run` | `create-debug-identity` |
|---|---|---|
| **What it registers** | Full loose layout package (entire folder) | Sparse package (single exe) |
| **How the app launches** | Launched by winapp (AUMID activation or execution alias) | You launch the exe yourself (command line, IDE, etc.) |
| **Simulates MSIX install** | Yes — closest to production behavior | No — sparse identity only |
| **Files stay in place** | Copied to an AppX layout directory | Yes — exe stays at its original path |
| **Debugger-friendly** | Attach to PID after launch, or use `--no-launch` then launch via alias | Launch directly from your IDE's debugger — the exe has identity regardless |
| **Console app support** | `--with-alias` keeps stdin/stdout in terminal | Run exe directly in terminal |
| **Best for** | Most frameworks (.NET, C++, Rust, Flutter, Tauri) | Electron, or when you need full IDE debugger control (F5 startup debugging) |

### When to use which

**Default to `winapp run`** for most development — it simulates a real MSIX install with full identity, capabilities, and file associations:

```powershell
winapp run .\build\output # GUI apps
winapp run .\build\output --with-alias # console apps (preserves stdin/stdout)
```

**Use `create-debug-identity` when:**
- **Debugging startup code** — your IDE launches + debugs the exe directly; identity is attached from the first instruction
- **Exe is separate from build output** — e.g., Electron where `electron.exe` is in `node_modules/`
- **Testing sparse package behavior** — `AllowExternalContent`, `TrustedLaunch`

```powershell
winapp create-debug-identity .\bin\Debug\myapp.exe
# Now launch any way you like — F5, terminal, script — the exe has identity
```

### Common debugging scenarios

| Scenario | Command | Notes |
|----------|---------|-------|
| **Just run with identity** | `winapp run .\build\Debug` | Simplest workflow; add `--with-alias` for console apps |
| **Attach debugger to running app** | `winapp run .\build\Debug`, then attach to PID | Misses startup code |
| **Register identity, launch via AUMID** | `winapp run .\build\Debug --no-launch` | Launch with `start shell:AppsFolder\<AUMID>` or the execution alias (not the exe directly) |
| **F5 startup debugging** | `winapp create-debug-identity .\bin\myapp.exe` | IDE controls process from first instruction; best for debugging activation/startup code |
| **Capture debug output** | `winapp run .\build\Debug --debug-output` | Captures `OutputDebugString`; on crash, writes minidump and analyzes managed exceptions automatically. **Blocks other debuggers** (one debugger per process) |
| **Run and auto-clean** | `winapp run .\build\Debug --unregister-on-exit` | Unregisters the dev package after the app exits |
| **Launch and detach (CI)** | `winapp run .\build\Debug --detach` | Returns immediately after launch; use `--json` to get PID for scripting |
| **Clean up stale registration** | `winapp unregister` | Removes dev packages for the current project (auto-detects from manifest) |

> **Using Visual Studio with a packaging project?** VS already handles identity, AUMID activation, and debugger attachment from F5. These workflows are most useful for VS Code, terminal-based development, and frameworks VS doesn't natively package (Rust, Flutter, Tauri, Electron, C++).

For full details including IDE setup examples, see the [Debugging Guide](https://github.com/microsoft/WinAppCli/blob/main/docs/debugging.md).

## Related skills
- Need a manifest? See `winapp-manifest` to generate `Package.appxmanifest`
- Need a certificate? See `winapp-signing` — a trusted cert is required for identity registration
- Ready for full MSIX distribution? See `winapp-package` to create an installer
- Having issues? See `winapp-troubleshoot` for common error solutions

## Troubleshooting
| Error | Cause | Solution |
|-------|-------|----------|
| "Package.appxmanifest not found" | No manifest in current directory | Run `winapp init` or `winapp manifest generate`, or pass `--manifest` |
| "Failed to add package identity" | Previous registration stale or cert untrusted | Run `winapp unregister` to remove stale packages, then `winapp cert install ./devcert.pfx` (admin) |
| "Access denied" | Cert not trusted or permission issue | Run `winapp cert install ./devcert.pfx` as admin |
| APIs still fail after registration | App launched before registration completed | Close app, re-run `create-debug-identity`, then relaunch |


## Command Reference

### `winapp create-debug-identity`

Enable package identity for debugging without creating full MSIX. Required for testing Windows APIs (push notifications, share target, etc.) during development. Example: winapp create-debug-identity ./myapp.exe. Requires Package.appxmanifest or appxmanifest.xml in current directory or passed via --manifest. Re-run after changing the manifest or Assets/.

#### Arguments
<!-- auto-generated from cli-schema.json -->
| Argument | Required | Description |
|----------|----------|-------------|
| `<entrypoint>` | No | Path to the .exe that will need to run with identity, or entrypoint script. |

#### Options
<!-- auto-generated from cli-schema.json -->
| Option | Description | Default |
|--------|-------------|---------|
| `--keep-identity` | Keep the package identity from the manifest as-is, without appending '.debug' to the package name and application ID. | (none) |
| `--manifest` | Path to the Package.appxmanifest or appxmanifest.xml | (none) |
| `--no-install` | Do not install the package after creation. | (none) |
Loading
Loading