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
21 changes: 21 additions & 0 deletions .claude/agents/winapp.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ Does the project already have an appxmanifest.xml?
│ │ └─ winapp run <build-output-dir> (registers loose layout + launches)
│ └─ Is the exe separate from your app code? (Electron, sparse package testing)
│ └─ winapp create-debug-identity <exe-path> (registers sparse package)
├─ Need production sparse packaging (ship identity for an unpackaged app)?
│ └─ winapp init --exe <exe> --sparse → winapp pack <manifest> --cert <pfx> → winapp embed-identity <exe>
│ (build a signed identity-only .msix your installer registers with Add-AppxPackage -ExternalLocation)
├─ Need to sign an existing MSIX or exe?
│ └─ winapp sign <file> <cert>
└─ Need to run a Windows SDK tool directly (makeappx, signtool, makepri)?
Expand Down Expand Up @@ -88,6 +91,7 @@ Want to inspect or interact with a running app's UI?
- `--config-dir` — directory for `winapp.yaml` (default: the selected project directory)
- `--config-only` — only create `winapp.yaml`, skip package installation
- `--no-gitignore` — don't update `.gitignore`
**Sparse mode (`--exe <exe> --sparse`):** generates an identity-only sparse `appxmanifest.xml` (with `AllowExternalContent`) plus placeholder assets for an existing executable, inferring name/publisher/version/description from the exe. Skips all SDK/package installation. `--exe` requires `--sparse`. Additional options: `--name`, `--publisher`, `--output-dir` (default: the exe's directory). This is **step 1** of the production sparse packaging workflow.
**Creates:** `winapp.yaml`, `appxmanifest.xml`, `Assets/` folder, `.winapp/` (if SDKs installed)

### `winapp restore [base-directory]`
Expand Down Expand Up @@ -127,6 +131,14 @@ Want to inspect or interact with a running app's UI?
- `--no-install` — create but don't register the package
**Requires:** `appxmanifest.xml` + path to your built `.exe`

### `winapp embed-identity <target>`
**Purpose:** Connect a desktop `.exe` to its sparse identity package by embedding the `<msix>` element into the target's side-by-side (fusion) manifest. This is **step 3** of the production sparse packaging workflow (after `winapp init --exe --sparse` and `winapp pack`).
**When to use:** After building a signed identity-only `.msix` for an unpackaged app, to make Windows associate the exe with that package at runtime.
**Modes:** `.exe` target → embeds via `mt.exe`; `.xml`/`.manifest` target → inserts/replaces the `<msix>` element in an external side-by-side manifest (rebuild the app afterward).
**Key options:**
- `--manifest <path>` — sparse `appxmanifest.xml` to read identity from (defaults to one beside the target, then `./appxmanifest.xml`)
**Requires:** a sparse `appxmanifest.xml` + the target `.exe` or `.xml`/`.manifest`

### `winapp run <input-folder>`
**Purpose:** Create a loose layout package from a build output folder, register it with Windows via `Add-AppxPackage`, and launch the app — simulating a full MSIX install for debugging.
**When to use:** The **preferred command** for iterative development and debugging with package identity. Use this whenever your exe lives inside the build output folder (most .NET, C++, Rust, Flutter, Tauri projects).
Expand Down Expand Up @@ -294,6 +306,15 @@ winapp create-debug-identity ./myapp.exe # Register sparse package for exe
# Launch your exe normally — it now has package identity
```

### Ship production sparse identity (unpackaged app + installer)
```bash
winapp init --exe ./bin/MyApp.exe --sparse # Step 1: generate identity-only manifest + assets
winapp cert generate # dev/test cert (use a trusted cert for production)
winapp pack ./appxmanifest.xml --cert dev.pfx # Step 2: build + sign the identity .msix
winapp embed-identity ./bin/MyApp.exe # Step 3: embed <msix> into the exe fusion manifest
# Your installer registers it: Add-AppxPackage -Path MyApp.identity.msix -ExternalLocation <install-dir>
```

### Clone and build existing project
```bash
winapp restore # Reinstall packages from winapp.yaml
Expand Down
36 changes: 36 additions & 0 deletions .claude/skills/winapp-identity/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,26 @@ winapp create-debug-identity .\bin\Debug\myapp.exe

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

## Production sparse packaging (`init --sparse` / `pack` / `embed-identity`)

`create-debug-identity` is for **developer-time debugging** (requires Developer Mode, registers a raw manifest). For **production** — shipping identity to an app distributed by an existing installer (Inno Setup, WiX, NSIS) — use the sparse packaging workflow, which produces a signed identity-only `.msix`:

```powershell
# 1. Create the sparse identity manifest for your exe (skips SDK install)
winapp init --exe ./bin/Release/MyApp.exe --sparse --use-defaults

# 2. Build and sign the identity-only .msix (just the manifest, no binaries)
winapp pack ./bin/Release/appxmanifest.xml --cert ./dev.pfx

# 3. Embed the <msix> identity element into the exe's fusion manifest
winapp embed-identity ./bin/Release/MyApp.exe
```

Then your installer registers the package against the install directory:
`Add-AppxPackage -Path MyApp.identity.msix -ExternalLocation <install-dir>`.

Assets are resolved from the external (install) location at runtime, **not** bundled into the `.msix`. `winapp embed-identity` also supports an XML mode (`winapp embed-identity ./app.manifest`) for updating a checked-in side-by-side manifest. See the [Sparse Packaging Guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/sparse.md) and the [sparse-app sample](https://github.com/microsoft/WinAppCli/tree/main/samples/sparse-app).

## 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
Expand Down Expand Up @@ -165,3 +185,19 @@ Enable package identity for debugging without creating full MSIX. Required for t
| `--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) |

### `winapp embed-identity`

Connect a desktop exe to its sparse identity package by embedding the <msix> element. Reads identity (packageName, publisher, applicationId) from a sparse appxmanifest.xml and writes it into the target's side-by-side (fusion) manifest. EXE targets are updated with mt.exe; .xml/.manifest targets are edited directly. Example: winapp embed-identity ./bin/MyApp.exe. This is step 3 of the sparse packaging workflow (after 'winapp init --exe --sparse' and 'winapp pack').

#### Arguments
<!-- auto-generated from cli-schema.json -->
| Argument | Required | Description |
|----------|----------|-------------|
| `<target>` | Yes | Path to the .exe (embeds identity into its side-by-side manifest via mt.exe) or an .xml/.manifest side-by-side manifest file (inserts/replaces the <msix> element; created if it doesn't exist). |

#### Options
<!-- auto-generated from cli-schema.json -->
| Option | Description | Default |
|--------|-------------|---------|
| `--manifest` | Path to the sparse appxmanifest.xml to read identity from (default: ./appxmanifest.xml) | (none) |
20 changes: 16 additions & 4 deletions .claude/skills/winapp-package/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,22 @@ Use the `microsoft/setup-winapp` action to install winapp on GitHub-hosted runne
- 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`

## Sparse identity packages

To grant identity to an app distributed by an existing installer (not as MSIX), build an **identity-only** sparse package: pass a sparse `appxmanifest.xml` (one declaring `uap10:AllowExternalContent="true"`) to `winapp pack` instead of a folder.

```powershell
# 1. Generate the sparse manifest for your exe (skips SDK install)
winapp init --exe ./bin/Release/MyApp.exe --sparse --use-defaults
# 2. Build & sign the identity-only .msix (just the manifest)
winapp pack ./bin/Release/appxmanifest.xml --cert ./dev.pfx
# 3. Embed identity into the exe, then register in your installer
winapp embed-identity ./bin/Release/MyApp.exe
```

The `.msix` contains only the manifest — binaries and assets are resolved from the external content location at runtime via `Add-AppxPackage -ExternalLocation`. If you pack a folder whose manifest declares `AllowExternalContent`, `winapp pack` warns about any assets/binaries found. See the [Sparse Packaging Guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/sparse.md).

## 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 |
Expand All @@ -201,7 +213,7 @@ Create MSIX installer from your built app. Run after building your app. A manife
<!-- 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). |
| `<input-folder>` | Yes | One or more input folders with package layout, or a single sparse appxmanifest.xml file (an identity-only package with AllowExternalContent). Pass multiple folders to create an MSIX bundle (e.g., winapp pack ./publish/x64 ./publish/arm64). |

#### Options
<!-- auto-generated from cli-schema.json -->
Expand Down
5 changes: 5 additions & 0 deletions .claude/skills/winapp-setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,14 @@ Start here for initializing a Windows app with required setup. Sets up everythin
|--------|-------------|---------|
| `--config-dir` | Directory to read/store configuration (default: the selected project directory, or current directory if no project is detected) | (none) |
| `--config-only` | Only handle configuration file operations (create if missing, validate if exists). Skip package installation and other workspace setup steps. | (none) |
| `--exe` | Path to the application executable. Requires --sparse. Generates an identity-only sparse manifest for the exe instead of a full package/SDK setup. | (none) |
| `--ignore-config` | Don't use configuration file for version management | (none) |
| `--name` | Override the package name (sparse only; default: inferred from the exe) | (none) |
| `--no-gitignore` | Don't update .gitignore file | (none) |
| `--output-dir` | Directory to write the sparse manifest and Assets/ (sparse only; default: the exe's directory) | (none) |
| `--publisher` | Override the publisher CN (sparse only; default: inferred from the exe's company name). Bare names are auto-wrapped as CN=<name>. | (none) |
| `--setup-sdks` | SDK installation mode: 'stable' (default), 'preview', 'experimental', or 'none' (skip SDK installation) | (none) |
| `--sparse` | Generate a sparse identity manifest (appxmanifest.xml) for an existing desktop exe instead of a full package manifest. Use with --exe. Skips SDK/package installation. | (none) |
| `--use-defaults` | Do not prompt; requires an explicit project directory (e.g., winapp init . --use-defaults) | (none) |

### `winapp restore`
Expand Down
21 changes: 21 additions & 0 deletions .github/plugin/agents/winapp.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ Does the project already have an appxmanifest.xml?
│ │ └─ winapp run <build-output-dir> (registers loose layout + launches)
│ └─ Is the exe separate from your app code? (Electron, sparse package testing)
│ └─ winapp create-debug-identity <exe-path> (registers sparse package)
├─ Need production sparse packaging (ship identity for an unpackaged app)?
│ └─ winapp init --exe <exe> --sparse → winapp pack <manifest> --cert <pfx> → winapp embed-identity <exe>
│ (build a signed identity-only .msix your installer registers with Add-AppxPackage -ExternalLocation)
├─ Need to sign an existing MSIX or exe?
│ └─ winapp sign <file> <cert>
└─ Need to run a Windows SDK tool directly (makeappx, signtool, makepri)?
Expand Down Expand Up @@ -89,6 +92,7 @@ Want to inspect or interact with a running app's UI?
- `--config-dir` — directory for `winapp.yaml` (default: the selected project directory)
- `--config-only` — only create `winapp.yaml`, skip package installation
- `--no-gitignore` — don't update `.gitignore`
**Sparse mode (`--exe <exe> --sparse`):** generates an identity-only sparse `appxmanifest.xml` (with `AllowExternalContent`) plus placeholder assets for an existing executable, inferring name/publisher/version/description from the exe. Skips all SDK/package installation. `--exe` requires `--sparse`. Additional options: `--name`, `--publisher`, `--output-dir` (default: the exe's directory). This is **step 1** of the production sparse packaging workflow.
**Creates:** `winapp.yaml`, `appxmanifest.xml`, `Assets/` folder, `.winapp/` (if SDKs installed)

### `winapp restore [base-directory]`
Expand Down Expand Up @@ -128,6 +132,14 @@ Want to inspect or interact with a running app's UI?
- `--no-install` — create but don't register the package
**Requires:** `appxmanifest.xml` + path to your built `.exe`

### `winapp embed-identity <target>`
**Purpose:** Connect a desktop `.exe` to its sparse identity package by embedding the `<msix>` element into the target's side-by-side (fusion) manifest. This is **step 3** of the production sparse packaging workflow (after `winapp init --exe --sparse` and `winapp pack`).
**When to use:** After building a signed identity-only `.msix` for an unpackaged app, to make Windows associate the exe with that package at runtime.
**Modes:** `.exe` target → embeds via `mt.exe`; `.xml`/`.manifest` target → inserts/replaces the `<msix>` element in an external side-by-side manifest (rebuild the app afterward).
**Key options:**
- `--manifest <path>` — sparse `appxmanifest.xml` to read identity from (defaults to one beside the target, then `./appxmanifest.xml`)
**Requires:** a sparse `appxmanifest.xml` + the target `.exe` or `.xml`/`.manifest`

### `winapp run <input-folder>`
**Purpose:** Create a loose layout package from a build output folder, register it with Windows via `Add-AppxPackage`, and launch the app — simulating a full MSIX install for debugging.
**When to use:** The **preferred command** for iterative development and debugging with package identity. Use this whenever your exe lives inside the build output folder (most .NET, C++, Rust, Flutter, Tauri projects).
Expand Down Expand Up @@ -295,6 +307,15 @@ winapp create-debug-identity ./myapp.exe # Register sparse package for exe
# Launch your exe normally — it now has package identity
```

### Ship production sparse identity (unpackaged app + installer)
```bash
winapp init --exe ./bin/MyApp.exe --sparse # Step 1: generate identity-only manifest + assets
winapp cert generate # dev/test cert (use a trusted cert for production)
winapp pack ./appxmanifest.xml --cert dev.pfx # Step 2: build + sign the identity .msix
winapp embed-identity ./bin/MyApp.exe # Step 3: embed <msix> into the exe fusion manifest
# Your installer registers it: Add-AppxPackage -Path MyApp.identity.msix -ExternalLocation <install-dir>
```

### Clone and build existing project
```bash
winapp restore # Reinstall packages from winapp.yaml
Expand Down
36 changes: 36 additions & 0 deletions .github/plugin/skills/winapp-cli/identity/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,26 @@ winapp create-debug-identity .\bin\Debug\myapp.exe

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

## Production sparse packaging (`init --sparse` / `pack` / `embed-identity`)

`create-debug-identity` is for **developer-time debugging** (requires Developer Mode, registers a raw manifest). For **production** — shipping identity to an app distributed by an existing installer (Inno Setup, WiX, NSIS) — use the sparse packaging workflow, which produces a signed identity-only `.msix`:

```powershell
# 1. Create the sparse identity manifest for your exe (skips SDK install)
winapp init --exe ./bin/Release/MyApp.exe --sparse --use-defaults

# 2. Build and sign the identity-only .msix (just the manifest, no binaries)
winapp pack ./bin/Release/appxmanifest.xml --cert ./dev.pfx

# 3. Embed the <msix> identity element into the exe's fusion manifest
winapp embed-identity ./bin/Release/MyApp.exe
```

Then your installer registers the package against the install directory:
`Add-AppxPackage -Path MyApp.identity.msix -ExternalLocation <install-dir>`.

Assets are resolved from the external (install) location at runtime, **not** bundled into the `.msix`. `winapp embed-identity` also supports an XML mode (`winapp embed-identity ./app.manifest`) for updating a checked-in side-by-side manifest. See the [Sparse Packaging Guide](https://github.com/microsoft/WinAppCli/blob/main/docs/guides/sparse.md) and the [sparse-app sample](https://github.com/microsoft/WinAppCli/tree/main/samples/sparse-app).

## 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
Expand Down Expand Up @@ -165,3 +185,19 @@ Enable package identity for debugging without creating full MSIX. Required for t
| `--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) |

### `winapp embed-identity`

Connect a desktop exe to its sparse identity package by embedding the <msix> element. Reads identity (packageName, publisher, applicationId) from a sparse appxmanifest.xml and writes it into the target's side-by-side (fusion) manifest. EXE targets are updated with mt.exe; .xml/.manifest targets are edited directly. Example: winapp embed-identity ./bin/MyApp.exe. This is step 3 of the sparse packaging workflow (after 'winapp init --exe --sparse' and 'winapp pack').

#### Arguments
<!-- auto-generated from cli-schema.json -->
| Argument | Required | Description |
|----------|----------|-------------|
| `<target>` | Yes | Path to the .exe (embeds identity into its side-by-side manifest via mt.exe) or an .xml/.manifest side-by-side manifest file (inserts/replaces the <msix> element; created if it doesn't exist). |

#### Options
<!-- auto-generated from cli-schema.json -->
| Option | Description | Default |
|--------|-------------|---------|
| `--manifest` | Path to the sparse appxmanifest.xml to read identity from (default: ./appxmanifest.xml) | (none) |
Loading
Loading