Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"url": "https://github.com/microsoft/win-dev-skills"
},
"description": "Agents and skills for native Windows app development with WinUI 3 and the Windows App SDK.",
"version": "0.3.1",
"version": "0.4.0",
"plugins": [
{
"name": "winui",
"description": "Agents and skills for WinUI 3 app development. Create new WinUI 3 desktop apps, convert from other frameworks to WinUI 3, or add features to existing WinUI 3 applications.",
"version": "0.3.1",
"version": "0.4.0",
"source": "./plugins/winui",
"category": "windows-development",
"tags": [
Expand Down
16 changes: 16 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
* text=auto eol=lf

*.md text eol=lf
*.json text eol=lf
*.txt text eol=lf

*.ps1 eol=lf
*.ts eol=lf
*.cs eol=lf
*.csproj eol=lf


*.png binary
*.jpg binary
*.ico binary
*.zip binary
4 changes: 2 additions & 2 deletions .github/plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
},
"metadata": {
"description": "Agents and skills for native Windows app development with WinUI 3 and the Windows App SDK.",
"version": "0.3.1"
"version": "0.4.0"
},
"plugins": [
{
"name": "winui",
"description": "Agents and skills for WinUI 3 app development. Create new WinUI 3 desktop apps, convert from other frameworks to WinUI 3, or add features to existing WinUI 3 applications.",
"version": "0.3.1",
"version": "0.4.0",
"source": "./plugins/winui"
}
]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Dependency Review
uses: actions/dependency-review-action@v5
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v5
Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Download CI-built analyzer DLL
uses: actions/download-artifact@v8
Expand Down Expand Up @@ -109,7 +109,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v5
Expand Down Expand Up @@ -194,7 +194,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Validate plugin.json structure
shell: bash
Expand Down Expand Up @@ -231,7 +231,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Check every SKILL.md has valid YAML frontmatter
shell: bash
Expand Down Expand Up @@ -269,7 +269,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Compare duplicated analyzer .targets files
shell: bash
Expand Down
51 changes: 34 additions & 17 deletions .github/workflows/release-policy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ name: Release policy
# See CONTRIBUTING.md and RELEASING.md for the human-side flow.
#
# Job matrix:
# pr-target-policy PR → main | head_ref must be staging or hotfix/*
# version-sync PR → staging | NO version field changed
# pr-target-policy PR → main | head_ref must be staging, release/*, or hotfix/*
# version-sync PR → staging | NO version field changed (skipped for backmerge/*)
# version-bump PR → main | all 5 version fields bumped, in sync, valid semver, strictly greater
# changelog-entry PR → main | top-most CHANGELOG section matches new version, has bullets
# staging-up-to-date PR → staging | staging contains every commit on main
# staging-up-to-date PR → staging | PR head contains every commit on main
# (passes naturally for backmerge/* PRs)

on:
pull_request:
Expand Down Expand Up @@ -51,11 +52,15 @@ jobs:

version-sync:
name: No version bump in feature PR
if: github.event.pull_request.base.ref == 'staging'
# Skip on backmerge/* PRs: those legitimately carry main's version-bump
# commit forward into staging. See CONTRIBUTING.md § Back-merge path.
if: >
github.event.pull_request.base.ref == 'staging' &&
!startsWith(github.event.pull_request.head.ref, 'backmerge/')
runs-on: ubuntu-latest
steps:
- name: Checkout (full depth)
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
Expand Down Expand Up @@ -95,33 +100,45 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout (full depth)
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Verify staging contains every commit on main
- name: Verify PR head contains every commit on main
env:
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
shell: bash
run: |
set -euo pipefail
git fetch origin main staging --quiet
# Find commits on main that are not on staging.
MISSING=$(git rev-list --count origin/main ^origin/staging)
git fetch origin main --quiet
# We check the PR head (not origin/staging) so back-merge PRs — which
# bring main into staging — pass naturally: after they merge, staging
# will contain main. Any other PR that doesn't already include main
# will fail here exactly as it would have under the old "staging vs
# main" check.
MISSING=$(git rev-list --count origin/main ^"$HEAD_SHA")
if [[ "$MISSING" -gt 0 ]]; then
echo "::error::'staging' is behind 'main' by $MISSING commit(s)."
echo "::error::This usually means a hotfix landed on main and was not back-merged into staging."
echo "::error::A maintainer must run: git checkout staging && git merge origin/main && git push"
echo "::error::Then this PR can proceed. See CONTRIBUTING.md § Hotfix path."
echo "::error::PR head ('$HEAD_REF') is missing $MISSING commit(s) from 'main'."
echo "::error::This usually means a hotfix landed on main and was not back-merged into staging,"
echo "::error::and this PR was branched from a stale staging."
echo "::error::Fix: open a back-merge PR first."
echo "::error:: git checkout -b backmerge/<topic> origin/staging"
echo "::error:: git merge origin/main"
echo "::error:: git push -u origin backmerge/<topic>"
echo "::error:: gh pr create --base staging --head backmerge/<topic>"
echo "::error::Then rebase this PR on the updated staging. See CONTRIBUTING.md § Back-merge path."
exit 1
fi
echo "::notice::'staging' contains every commit on 'main' — OK."
echo "::notice::PR head contains every commit on 'main' — OK."

version-bump:
name: Version bump (5 fields in sync)
if: github.event.pull_request.base.ref == 'main'
runs-on: ubuntu-latest
steps:
- name: Checkout (full depth)
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
Expand Down Expand Up @@ -202,7 +219,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}

Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/release-post-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0

Expand Down Expand Up @@ -114,20 +114,22 @@ jobs:
BODY=$(cat <<EOF
Hotfix PR #$PR_NUMBER ('$PR_TITLE') merged into \`main\` at $MERGE_SHA.

Per [CONTRIBUTING.md § Hotfix path](../blob/main/CONTRIBUTING.md#hotfix-path),
Per [CONTRIBUTING.md § Back-merge path](../blob/main/CONTRIBUTING.md#back-merge-path),
this commit must be back-merged into \`staging\` immediately so the fix is
not lost on the next release.

To do this:

\`\`\`
git fetch origin
git checkout staging
git checkout -b backmerge/hotfix-${HEAD_REF#hotfix/} origin/staging
git merge origin/main
git push
git push -u origin backmerge/hotfix-${HEAD_REF#hotfix/}
gh pr create --base staging --head backmerge/hotfix-${HEAD_REF#hotfix/}
\`\`\`

Or open a PR from \`main\` into \`staging\` if you prefer the review trail.
The branch **must** be named \`backmerge/*\` — the \`version-sync\` CI
check skips that prefix.

The \`staging-up-to-date-with-main\` CI check will block all new feature
PRs until this back-merge happens.
Expand Down
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ The `version-bump` and `changelog-entry` CI jobs enforce this.
### Added

### Changed
## [0.4.0] — 2026-06-25

### Fixed
### Added

### Removed
- OpenClaw support: the `winui` plugin now ships a native OpenClaw manifest
(`openclaw.plugin.json`) and `package.json` entry point so all eight skills
load in OpenClaw (`Format: openclaw`). README documents the marketplace and
local-clone install routes.

### Deprecated

Comment thread
nmetulev marked this conversation as resolved.
## [0.3.1] — 2026-05-19

Expand Down Expand Up @@ -63,3 +66,4 @@ release process was introduced. Future releases will list per-PR changes here.
against source drift.
- Marketplace manifest under `.github/plugin/marketplace.json` and Claude Code
marketplace manifest under `.claude-plugin/marketplace.json`.

47 changes: 42 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ contributor flow. For the maintainer-side release process see

```
your-feature ──PR──▶ staging ──promotion PR──▶ main ──auto-tag──▶ vX.Y.Z
hotfix/* ──PR──▶ main (must back-merge to staging)
hotfix/* ──PR──▶ main ──backmerge/* ──▶ staging
release/X.Y.Z ──PR──▶ main ──backmerge/X.Y.Z ▶ staging
```

- **`main`** is the released branch. Marketplace consumers install from `main`,
Expand All @@ -26,6 +27,12 @@ hotfix/* ──PR──▶ main (must back-merge to staging)
for genuine emergencies (security, broken-on-install). They must include the
version bump + changelog entry themselves and be back-merged to `staging`
immediately after.
- **`release/X.Y.Z`** branches are the staging→main promotion PRs (opened by
`scripts/open-release-pr.ps1`). They carry the version bump + CHANGELOG
promotion for the release.
- **`backmerge/*`** branches are the only ones allowed to bring main's history
into `staging` (without tripping the `version-sync` check). Open one right
after every promotion PR or hotfix merges into `main`.

## Opening a PR

Expand Down Expand Up @@ -86,18 +93,48 @@ release:
4. PR against `main`. CI will run the same `version-bump` + `changelog-entry`
checks the promotion PR runs.
5. Once merged, immediately open a back-merge PR `main → staging` to get the
fix into the integration branch. The `back-merge-reminder` workflow opens a
tracking issue if you forget.
fix into the integration branch:

```powershell
git fetch origin
git checkout -b backmerge/hotfix-short-description origin/staging
git merge origin/main
git push -u origin backmerge/hotfix-short-description
gh pr create --base staging --head backmerge/hotfix-short-description `
--title "Back-merge hotfix into staging" `
--body "Brings #<hotfix PR> back into staging."
```

The branch **must** be named `backmerge/*` — the `version-sync` CI check
skips that prefix so the version-bump diff doesn't trip the gate. The
`back-merge-reminder` workflow opens a tracking issue if you forget.

## Back-merge path

Whenever `main` advances (promotion PR merge, hotfix merge, revert) `staging`
must be caught up before any new feature PR can merge. Open a back-merge:

```powershell
git fetch origin
git checkout -b backmerge/<topic> origin/staging
git merge origin/main
git push -u origin backmerge/<topic>
gh pr create --base staging --head backmerge/<topic>
```

Naming: use `backmerge/X.Y.Z` after a release, `backmerge/hotfix-<short>` after
a hotfix. The `backmerge/` prefix is required — without it the `version-sync`
check will (correctly) refuse to let the version-bump diff land on staging.

## CI checks you'll see

| Check | When it runs | What it wants |
|---|---|---|
| `pr-target-policy` | PR targets `main` | Your branch is `staging`, `release/*`, or `hotfix/*`, AND comes from this repo (not a fork). |
| `version-sync` | PR targets `staging` | You did NOT change any version field. |
| `version-sync` | PR targets `staging` | You did NOT change any version field. (Skipped on `backmerge/*`.) |
| `version-bump` | PR targets `main` | All 5 version fields bumped, valid semver, strictly greater, identical. |
| `changelog-entry` | PR targets `main` | Top-most `## [X.Y.Z]` section matches the bumped version, has at least one bullet. |
| `staging-up-to-date-with-main` | PR targets `staging` | `staging` contains every commit on `main` (so hotfixes aren't lost). |
| `staging-up-to-date-with-main` | PR targets `staging` | PR head contains every commit on `main` (back-merge PRs satisfy this naturally). |
| `build-tools` + provenance | Any PR | C# tools build, analyzer tests pass, committed payloads match source. |
| `validate-plugin-manifest` + `validate-skill-frontmatter` | Any PR | Manifests are well-formed, every `SKILL.md` has valid frontmatter. |

Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,28 @@ Add the `microsoft/win-dev-skills` marketplace, then enable the `winui` plugin f
> **Note:** Codex doesn't have an "agents" concept, so the orchestrator agent isn't exposed there. The skills still work - invoke them by name (e.g. `/winui-setup`, `/winui-design`) and Codex will load them on demand.
</details>

<details>
<summary><strong>OpenClaw</strong></summary>

Install straight from this repo - no marketplace pre-registration needed. The explicit `--marketplace` source clones the repo on demand, reads its marketplace manifest, and installs the `winui` plugin natively (`Format: openclaw`):

```powershell
openclaw plugins install winui --marketplace microsoft/win-dev-skills
openclaw gateway restart
```

Or from a local clone:

```powershell
git clone https://github.com/microsoft/win-dev-skills
openclaw plugins install ./win-dev-skills/plugins/winui
```

Verify the eight skills loaded with `openclaw skills list` (each shows `✓ ready`).

> **Note:** OpenClaw maps skills, not agents, so the `winui-dev` orchestrator agent isn't exposed there. The skills still work - ask the agent for a WinUI task and it loads the relevant skill on demand.
</details>

Then start a new session and run the `winui-setup` skill with `/winui-setup`.

Once setup is done, try a real task:
Expand Down
Loading
Loading