reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
{
"name": "win-dev-skills",
"interface": {
"displayName": "Windows development and debugging"
},
"plugins": [
{
"name": "windbg",
"source": {
"source": "local",
"path": "./plugins/windbg"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Developer Tools"
},
{
"name": "winui",
"source": {
"source": "git-subdir",
"url": "https://github.com/microsoft/winappCli.git",
"path": "plugins/winui",
"sha": "5a064a427f1e056822a939b13ddce43b798090fa"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Developer Tools"
},
{
"name": "winappcli",
"source": {
"source": "git-subdir",
"url": "https://github.com/microsoft/winappCli.git",
"path": "plugins/winapp",
"ref": "v0.7.1",
"sha": "e3cd0b94f3e7b776ac51ba0564f4908094e979b5"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Developer Tools"
}
]
}

View File

@@ -0,0 +1,84 @@
{
"name": "win-dev-skills",
"owner": {
"name": "Microsoft",
"url": "https://github.com/microsoft/win-dev-skills"
},
"description": "Agents and skills for Windows development and debugging.",
"version": "0.7.1",
"plugins": [
{
"name": "windbg",
"description": "WinDbg diagnosis workflows and report validation for applications, services, UMDF/user-mode drivers, and kernel-mode drivers.",
"version": "1.0.0",
"source": "./plugins/windbg",
"author": {
"name": "Microsoft",
"url": "https://github.com/microsoft/WinDbg-Feedback"
},
"homepage": "https://github.com/microsoft/WinDbg-Feedback",
"repository": "https://github.com/microsoft/win-dev-skills"
},
{
"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.7.1",
"source": {
"source": "git-subdir",
"url": "https://github.com/microsoft/winappCli.git",
"path": "plugins/winui",
"sha": "5a064a427f1e056822a939b13ddce43b798090fa"
},
"category": "windows-development",
"tags": [
"windows",
"winui",
"winui3",
"xaml",
"msix",
"packaging",
"desktop",
"wpf-migration"
],
"author": {
"name": "Microsoft",
"url": "https://github.com/microsoft/win-dev-skills"
},
"homepage": "https://github.com/microsoft/win-dev-skills",
"repository": "https://github.com/microsoft/winappCli",
"license": "MIT"
},
{
"name": "winappcli",
"description": "Windows app development, packaging, and distribution. Helps with creating Windows installers (MSIX), code signing, certificates, Windows SDK and Windows App SDK setup, package identity for Windows APIs (push notifications, background tasks, share target), appxmanifest authoring, and Microsoft Store distribution. Supports Electron, .NET, C++, Rust, Flutter, and Tauri apps.",
"version": "0.7.1",
"source": {
"source": "git-subdir",
"url": "https://github.com/microsoft/winappCli.git",
"path": "plugins/winapp",
"ref": "v0.7.1",
"sha": "e3cd0b94f3e7b776ac51ba0564f4908094e979b5"
},
"category": "windows-development",
"tags": [
"windows",
"msix",
"packaging",
"installer",
"desktop",
"notifications",
"sdk",
"signing",
"certificate",
"distribution"
],
"author": {
"name": "Microsoft",
"url": "https://github.com/microsoft/winappCli"
},
"homepage": "https://github.com/microsoft/winappCli",
"repository": "https://github.com/microsoft/winappCli",
"license": "MIT"
}
]
}

View File

@@ -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

View File

@@ -0,0 +1,20 @@
# Catalog maintainers review everything by default. They're the repo
# maintainers who have been landing changes here.
* @nmetulev @azchohfi @niels9001
# Catalog files: adding, removing, or re-pinning a plugin.
/.github/plugin/marketplace.json @nmetulev @azchohfi @niels9001
/.claude-plugin/marketplace.json @nmetulev @azchohfi @niels9001
/.agents/plugins/marketplace.json @nmetulev @azchohfi @niels9001
# CI and catalog tooling
/.github/workflows/ @nmetulev @azchohfi @niels9001
/scripts/ @nmetulev @azchohfi @niels9001
# Plugins stored in this repo: one entry per plugin, owned by two or more
# people or a team. Template:
# /plugins/<name>/ @owner1 @owner2
#
# winui and winappcli are maintained in microsoft/winappCli and reviewed
# there; their catalog entries are covered above.
/plugins/windbg/ @nmetulev @azchohfi @niels9001 @rtrimceski-MS

View File

@@ -0,0 +1,89 @@
name: Bug report
description: Report a catalog or plugin install problem
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to file a bug report!
**Problem with a `winui` or `winappcli` skill or agent, WinApp CLI, or the analyzer?** Please [open an issue in microsoft/winappCli](https://github.com/microsoft/winappCli/issues/new/choose), where those plugins are authored. Use this form for catalog and install problems (e.g. `plugin marketplace add`, `plugin install`, or `plugin update` fails).
- type: textarea
id: description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is.
validations:
required: true
- type: dropdown
id: area
attributes:
label: Affected host
description: Which agent host shows the problem?
options:
- Not sure
- GitHub Copilot
- Claude Code
- OpenAI Codex
- OpenClaw
- OpenCode
- Other
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. Run `copilot plugin marketplace add microsoft/win-dev-skills`
2. Run `copilot plugin install winui@win-dev-skills`
3. See error
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Command output
description: Paste the full output of the failing command.
render: shell
validations:
required: false
- type: input
id: copilot-version
attributes:
label: Host version
description: e.g. output of `copilot --version`, `claude --version`, or `codex --version`
placeholder: e.g. 1.0.87
validations:
required: false
- type: input
id: plugin-version
attributes:
label: Plugin version
description: From your host's plugin list (e.g. `copilot plugin list`)
placeholder: e.g. 0.7.1
validations:
required: false
- type: input
id: os
attributes:
label: OS version
description: e.g. Windows 11 23H2 (build 22631.4317)
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional context
description: Anything else that might help us reproduce or understand the issue.
validations:
required: false

View File

@@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: winui or winappcli plugin issue
url: https://github.com/microsoft/winappCli/issues/new/choose
about: The winui and winappcli plugins are authored in microsoft/winappCli. File their skill and agent issues, and WinApp CLI and analyzer issues, there.
- name: Question / discussion
url: https://github.com/microsoft/win-dev-skills/discussions
about: Have a question about how to use a skill, or want to discuss an idea? Start a Discussion.
- name: Microsoft Open Source Code of Conduct
url: https://opensource.microsoft.com/codeofconduct/
about: Read the Microsoft Open Source Code of Conduct.
- name: Security vulnerability
url: https://aka.ms/SECURITY.md
about: Please do NOT file public issues for security vulnerabilities. Use the Microsoft Security Response Center instead.

View File

@@ -0,0 +1,38 @@
name: Documentation
description: Report a problem with a SKILL.md, README, or other documentation
title: "[Docs]: "
labels: ["documentation"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to flag a documentation issue! **Problem in a `winui` or `winappcli` skill or agent?** Please [open it in microsoft/winappCli](https://github.com/microsoft/winappCli/issues/new/choose), where those plugins are authored. Use this form for this repo's README and docs.
- type: textarea
id: location
attributes:
label: Where is the issue?
description: Link to the specific page, file, or section.
placeholder: e.g. README.md, "Install" section
validations:
required: true
- type: textarea
id: problem
attributes:
label: What's wrong?
description: Describe the documentation problem — broken link, wrong path, outdated example, missing step, unclear wording, etc.
validations:
required: true
- type: textarea
id: suggestion
attributes:
label: Suggested fix
description: If you have a concrete suggestion for how to fix it, share it here.
validations:
required: false
- type: textarea
id: context
attributes:
label: Additional context
description: Anything else we should know.
validations:
required: false

View File

@@ -0,0 +1,40 @@
name: Feature request
description: Suggest a new skill, capability, or improvement
title: "[Feature]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to suggest a new feature!
**Idea for the `winui` or `winappcli` skills or agents?** Please [open it in microsoft/winappCli](https://github.com/microsoft/winappCli/issues/new/choose). Use this form to propose a new plugin for this catalog or a catalog improvement.
- type: textarea
id: problem
attributes:
label: What problem are you trying to solve?
description: Describe the developer scenario you're trying to support and why the current skills/tools fall short.
placeholder: e.g. When asking the agent to scaffold a charting page, it has no guidance on which charting library to use...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Proposed solution
description: Describe what you'd like to see — a new skill, an extension to an existing skill, a new tool, etc.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: What other approaches did you consider, and why is the proposed solution better?
validations:
required: false
- type: textarea
id: context
attributes:
label: Additional context
description: Links to upstream docs, related issues, prior art, screenshots, or anything else that helps frame the request.
validations:
required: false

View File

@@ -0,0 +1,39 @@
<!--
Changing winui or winappcli skills, agents, or manifests? Open the PR in microsoft/winappCli
instead: https://github.com/microsoft/winappCli
This repo holds the plugin catalog. See CONTRIBUTING.md.
-->
## Description
<!-- Briefly describe what this PR does and why -->
## Related Issue
<!-- Link to any related issues: Fixes #123, Closes #456, Related to #789 -->
## Type of Change
<!-- Keep the applicable line(s), delete the rest -->
- 📦 Catalog entry added, moved to a new pin, or removed
- 📝 Documentation
- 🔧 Config / CI
## Checklist
<!-- Delete the ones that do not apply -->
- [ ] All three catalogs (`.github/plugin`, `.claude-plugin`, `.agents/plugins`) list the same plugins at the same pin
- [ ] Installed the plugin from this branch on each host and confirmed its skills load
- [ ] If user-facing: added a bullet to `## [Unreleased]` in `CHANGELOG.md`
## Additional Notes
<!-- Any additional information that reviewers should know -->
## AI Description
<!-- ai-description-start -->
_This section is auto-generated by AI when the PR is opened or updated. To opt out, delete this entire section including the marker comments._
<!-- ai-description-end -->

View File

@@ -0,0 +1,2 @@
paths:
- .github/workflows

View File

@@ -0,0 +1,32 @@
version: 2
updates:
# GitHub Actions used by our workflows
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "github-actions"
commit-message:
prefix: "ci"
include: "scope"
cooldown:
default-days: 7
# vally skill linter (pinned to match github/awesome-copilot's marketplace gate)
- package-ecosystem: "npm"
directory: "/scripts/vally"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 2
labels:
- "dependencies"
commit-message:
prefix: "ci"
include: "scope"

View File

@@ -0,0 +1,42 @@
{
"name": "win-dev-skills",
"owner": {
"name": "Microsoft",
"url": "https://github.com/microsoft/win-dev-skills"
},
"metadata": {
"description": "Agents and skills for Windows development and debugging.",
"version": "0.7.1"
},
"plugins": [
{
"name": "windbg",
"description": "WinDbg diagnosis workflows and report validation for applications, services, UMDF/user-mode drivers, and kernel-mode drivers.",
"version": "1.0.0",
"source": "./plugins/windbg"
},
{
"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.7.1",
"source": {
"source": "github",
"repo": "microsoft/winappCli",
"path": "plugins/winui/agent-plugin",
"sha": "5a064a427f1e056822a939b13ddce43b798090fa"
}
},
{
"name": "winappcli",
"description": "Windows app development, packaging, and distribution. Helps with creating Windows installers (MSIX), code signing, certificates, Windows SDK and Windows App SDK setup, package identity for Windows APIs (push notifications, background tasks, share target), appxmanifest authoring, and Microsoft Store distribution. Supports Electron, .NET, C++, Rust, Flutter, and Tauri apps.",
"version": "0.7.1",
"source": {
"source": "github",
"repo": "microsoft/winappCli",
"path": "plugins/winapp",
"ref": "v0.7.1",
"sha": "e3cd0b94f3e7b776ac51ba0564f4908094e979b5"
}
}
]
}

View File

@@ -0,0 +1,46 @@
name: "CodeQL Advanced"
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '35 20 * * 0'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Initialize CodeQL
uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
config-file: ./.github/codeql/codeql-config.yml
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
with:
category: "/language:${{matrix.language}}"

View File

@@ -0,0 +1,22 @@
name: Dependency Review
on:
pull_request:
branches: [ "main" ]
permissions:
contents: read
pull-requests: write
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Dependency Review
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
with:
fail-on-severity: high
comment-summary-in-pr: on-failure

View File

@@ -0,0 +1,62 @@
name: PR validation
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
permissions:
contents: read
jobs:
catalog-check:
name: Catalog check
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
# Every entry resolves (repo, commit, path, manifest, name, version) and
# the Copilot, Claude, and Codex catalogs list the same plugins at the same pin.
- name: Check catalogs
env:
GITHUB_TOKEN: ${{ github.token }}
run: node scripts/check-catalogs.mjs
vally-lint:
name: Local plugin lint (vally)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
# Same linter and version github/awesome-copilot runs on external plugins.
# Only plugins stored in this repo are linted; remote plugins are linted
# in their own repositories.
- name: Install local plugin lint dependencies
run: npm ci --prefix scripts/vally --no-audit --no-fund
- name: Check WinDbg package
run: node scripts/validate-windbg.mjs
- name: Test WinDbg diagnosis validator
run: node scripts/tests/test-windbg-validator.mjs
- name: Lint local plugin skills
run: node scripts/vally/lint-skills.mjs
# Fixture-based self-test: a plugin stored in this repo is checked and linted.
- name: Test catalog tooling
run: node scripts/tests/test-catalog-tools.mjs

View File

@@ -0,0 +1,88 @@
name: Release post-merge
# On every push to main: if the catalog version changed, tag main HEAD as
# vX.Y.Z. The catalog version is metadata.version in
# .github/plugin/marketplace.json (the Catalog check keeps the Claude catalog
# in sync). Pushes that don't change it are skipped.
on:
push:
branches: [main]
permissions:
contents: write # push tags
# Serialize tag-creation across overlapping pushes to main so two workflow runs
# can't race on the same tag.
concurrency:
group: release-post-merge-${{ github.ref }}
cancel-in-progress: false
jobs:
auto-tag:
name: Tag main HEAD as vX.Y.Z
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Read catalog version
id: ver
env:
BEFORE: ${{ github.event.before }}
shell: bash
run: |
set -euo pipefail
CATALOG=.github/plugin/marketplace.json
VERSION=$(jq -r '.metadata.version' "$CATALOG")
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::$CATALOG metadata.version '$VERSION' is not valid semver. Refusing to tag."
exit 1
fi
PREVIOUS=""
if [[ -n "$BEFORE" && ! "$BEFORE" =~ ^0+$ ]] && git cat-file -e "$BEFORE:$CATALOG" 2>/dev/null; then
PREVIOUS=$(git show "$BEFORE:$CATALOG" | jq -r '.metadata.version // empty')
elif git cat-file -e "HEAD^1:$CATALOG" 2>/dev/null; then
PREVIOUS=$(git show "HEAD^1:$CATALOG" | jq -r '.metadata.version // empty')
fi
if [[ "$PREVIOUS" == "$VERSION" ]]; then
echo "::notice::Catalog version unchanged ($VERSION) — no tag."
echo "tag=" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
- name: Create and push tag (idempotent, SHA-checked)
if: steps.ver.outputs.tag != ''
env:
TAG: ${{ steps.ver.outputs.tag }}
shell: bash
run: |
set -euo pipefail
git fetch --tags origin --quiet
# Same SHA = idempotent success. A tag on an earlier main commit (e.g.
# after reverting a bump) is left alone. Anything else fails loudly;
# never overwrite or accept a misplaced tag.
if git rev-parse --verify --quiet "refs/tags/$TAG^{}" >/dev/null; then
EXISTING_SHA=$(git rev-parse "refs/tags/$TAG^{}")
if [[ "$EXISTING_SHA" == "$GITHUB_SHA" ]]; then
echo "::notice::Tag $TAG already points at $GITHUB_SHA — nothing to do."
exit 0
fi
if git merge-base --is-ancestor "$EXISTING_SHA" "$GITHUB_SHA"; then
echo "::notice::Tag $TAG already exists at earlier commit $EXISTING_SHA — not moving it."
exit 0
fi
echo "::error::Tag $TAG already exists at $EXISTING_SHA but main HEAD is $GITHUB_SHA. Bump the catalog version instead of reusing one."
exit 1
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"
echo "::notice::Tagged $GITHUB_SHA as $TAG."

View File

@@ -0,0 +1,54 @@
name: Close stale issues
on:
schedule:
- cron: '0 0 * * *' # Run daily at midnight UTC
workflow_dispatch: # Allow manual trigger for testing
permissions:
issues: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0
with:
# Only process issues with this label
only-issue-labels: 'needs-author-response'
# Mark stale after 14 days of no activity
days-before-issue-stale: 14
# Close 7 days after being marked stale
days-before-issue-close: 7
# Label to add when marking stale
stale-issue-label: 'stale'
# Warning message when marking as stale
stale-issue-message: >
This issue has been automatically marked as stale because it has not had
recent activity after requesting information from the author. It will be
closed in 7 days if no further activity occurs.
# Message when closing
close-issue-message: >
This issue was closed because it has been stale for 7 days with no activity.
Feel free to reopen if you have the requested information.
# Remove these labels when issue becomes unstale (any comment/activity)
labels-to-remove-when-unstale: 'needs-author-response,stale'
# Add this label when issue becomes unstale (author responded)
labels-to-add-when-unstale: 'needs-maintainer-response'
# Exempt issues with these labels from stale processing
exempt-issue-labels: 'exempt-from-stale'
# Don't process PRs
days-before-pr-stale: -1
days-before-pr-close: -1
# Enable for testing - remove this line after verifying behavior
# debug-only: true

423
vendor-new/win-dev-skills/.gitignore vendored Normal file
View File

@@ -0,0 +1,423 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
*.env
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
[Aa][Rr][Mm]64[Ee][Cc]/
bld/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Build results on 'Bin' directories
**/[Bb]in/*
# Uncomment if you have tasks that rely on *.refresh files to move binaries
# (https://github.com/github/gitignore/pull/3736)
#!**/[Bb]in/*.refresh
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*.trx
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Approval Tests result files
*.received.*
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.idb
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
# but not Directory.Build.rsp, as it configures directory-level build defaults
!Directory.Build.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
**/.paket/paket.exe
paket-files/
# FAKE - F# Make
**/.fake/
# CodeRush personal settings
**/.cr/personal
# Python Tools for Visual Studio (PTVS)
**/__pycache__/
*.pyc
# Cake - Uncomment if you are using it
#tools/**
#!tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
MSBuild_Logs/
# AWS SAM Build and Temporary Artifacts folder
.aws-sam
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
**/.mfractor/
# Local History for Visual Studio
**/.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
**/.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# Release build artifacts
staging/
*.zip
# Local launch-prep scratchpad (uncommitted notes / trackers)
.launch/

View File

@@ -0,0 +1,40 @@
trigger:
branches:
include:
- main
- dev/**
tags:
exclude:
- '*'
pr: none
resources:
repositories:
- repository: 1esPipelines
type: git
name: 1ESPipelineTemplates/1ESPipelineTemplates
ref: refs/tags/release
extends:
template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines
parameters:
# Keep source compliance scanning for the content plugin. Native tooling
# builds and binary analysis belong to microsoft/winappCli.
sdl:
policheck:
enabled: true
sourceAnalysisPool:
name: Azure-Pipelines-1ESPT-ExDShared
image: windows-latest
os: windows
stages:
- stage: Compliance
jobs:
- job: SourceChecks
pool:
name: Azure-Pipelines-1ESPT-ExDShared
image: windows-latest
os: windows
hostArchitecture: amd64
steps:
- checkout: self

View File

@@ -0,0 +1,228 @@
# Changelog
All notable changes to this project are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
<!--
Add user-facing catalog changes below. A catalog release renames this section
to `## [X.Y.Z] — YYYY-MM-DD` (see RELEASING.md).
-->
### Added
- **`windbg` plugin**: focused WinDbg diagnosis workflows,
deterministic output validation, contrarian review, and public
WinDbg-Feedback guidance.
- **`winappcli` plugin** (WinApp CLI 0.7.1: MSIX packaging, signing, package
identity, appxmanifest, Windows SDK setup, Store distribution) for Copilot,
Claude Code, and Codex, pinned to microsoft/winappCli `v0.7.1`. Install with
`copilot plugin install winappcli@win-dev-skills` (or the Claude/Codex
equivalent). OpenClaw users install it as a skills-only bundle with
`openclaw plugins install winappcli --marketplace microsoft/winappCli`.
- Contribution guide for new plugins: add one here under `plugins/<name>/`,
or pin one maintained in another repo.
### Changed
- Broadened the README and contribution guide to Windows development and
debugging, including apps, services, and kernel-mode drivers. Existing plugin
listings and functionality are unchanged.
- **The `winui` plugin now installs from
[microsoft/winappCli](https://github.com/microsoft/winappCli)**, pinned to
commit `5a064a42`. Its content is unchanged (still 0.7.1: same name, agent,
and eight skills). File WinUI issues and PRs in microsoft/winappCli.
- This repo now hosts and lists agent plugins for Windows development and
debugging ("Agents and skills for Windows development and debugging").
Copilot and Claude Code install commands are unchanged.
- **The Codex catalog is renamed from `microsoft-winui` to `win-dev-skills`**,
so Codex commands now match the other hosts (`<plugin>@win-dev-skills`).
### Removed
- The local copy of the `winui` plugin (`plugins/winui/`) and its tests, and
the `staging` release flow. PRs now target `main`.
### Migration
- **Codex:** `codex plugin marketplace upgrade` now fails with "upgraded
marketplace name `win-dev-skills` does not match configured marketplace
`microsoft-winui`". Installed plugins keep working but stop updating. Move
them over once, removing plugins before the marketplace:
`codex plugin remove <plugin>@microsoft-winui` (for each installed plugin),
`codex plugin marketplace remove microsoft-winui`,
`codex plugin marketplace add microsoft/win-dev-skills`, then
`codex plugin add <plugin>@win-dev-skills`.
- **OpenClaw:** reinstall `winui` once with
`openclaw plugins install winui --marketplace microsoft/winappCli`.
`--marketplace microsoft/win-dev-skills` and `openclaw plugins update` no
longer work for this plugin.
- **OpenCode:** link the skills from a microsoft/winappCli clone
(`plugins/winui/agent-plugin/skills` and `plugins/winapp/skills`).
## [0.7.1] — 2026-09-30
### Fixed
- Replace cross-skill markdown links with plain-text skill names so each skill
is self-contained and passes marketplace link validation (vally `valid-refs`),
which blocked the awesome-copilot listing update. CI now enforces this.
## [0.7.0] — 2026-09-30
### Added
- Explicit Native AOT run/publish guidance, source-generated WinRT binding
patterns, and native toolchain prerequisites.
- UI testing that prefers Windows Sandbox when available so synthetic input
stays off your desktop, otherwise runs locally; explicit Windows Sandbox
requests never fall back. Normal build-and-run launches locally.
### Changed
- Require WinApp CLI 0.7+ and recommend the latest
`Microsoft.Windows.SDK.BuildTools.WinUIAnalyzer` for app, IDE, and CI builds.
If unavailable, continue with a notice that analyzer checks were not run.
- Route analyzer and WinApp CLI tool bugs to `microsoft/winappCli`; keep skill
and plugin guidance issues here.
- Install or upgrade WinApp CLI automatically when missing (no admin needed)
instead of asking the user to run setup; still ask before the .NET SDK,
Developer Mode, or anything else that needs admin rights or a reboot.
- Use direct `winapp run`, project-scoped `winapp find-api`, and native
project-mode MSIX packaging, including multi-architecture bundles.
- Treat `microsoft/winappCli` as the owner of analyzer and CLI implementation,
tests, and package publication. Keep this repository's validation focused on
plugin content and PowerShell workflows.
### Fixed
### Removed
- `BuildAndRun.ps1`, bundled analyzer DLL/targets, and their provenance jobs.
- The local `winmd-cli` source and build/dependency wiring; API discovery is
provided by `winapp find-api`.
- The remaining analyzer source/tests, `build-tools.ps1`, C# build/CodeQL jobs,
and NuGet restore/dependency wiring; there is no local native-tool build.
### Deprecated
## [0.6.1] — 2026-09-09
### Fixed
- Synced `plugins/winui/.claude-plugin/plugin.json` and
`plugins/winui/.codex-plugin/plugin.json` versions (previously stuck at
`0.3.0` since the Agent Plugins 1.0 package migration) to the current
release version. Both files are now written by the release helper and
checked by CI alongside the other version fields.
## [0.6.0] — 2026-08-26
### Added
- WinApp CLI 0.6 integration: new projects use `winapp new`, and WinUI
control/sample discovery uses `winapp find-ui`.
- Added reusable SVG and 512 px PNG WinUI artwork for marketplace listings.
### Changed
- Adopted the [Agent Plugins 1.0 specification](https://agent-plugins.org/specification) and [Agent Skills specification](https://agentskills.io/specification) for portable skill packaging. The conforming package now has its own `plugins/winui/agent-plugin` root, while Claude Code, OpenAI Codex, and OpenClaw retain a containing compatibility package because their required legacy root files are not valid Agent Plugins extension namespaces.
- The skills now require WinApp CLI 0.6 or later. `BuildAndRun.ps1` is a thin
wrapper over project-mode `winapp run`; it keeps only the bundled analyzer
injection and default crash diagnostics while WinApp CLI handles restore,
build, output discovery, runtime setup, registration, and launch.
- `winui-setup` no longer installs the WinUI template pack separately because
`winapp new` manages templates on demand.
- `winui-setup` now gives harness-neutral post-setup guidance while preserving the
GitHub Copilot CLI invocation example.
### Fixed
### Removed
- The in-repo `winui-search` source, unsigned executable payload, dependency
metadata, and CI provenance job; WinApp CLI 0.6's `winapp find-ui` is now the
single supported search surface.
### Deprecated
## [0.5.0] — 2026-07-21
### Added
- `winui-search` now indexes a third source, **Reactor**
(`microsoft/microsoft-ui-reactor`): 93 C#-only declarative WinUI controls from the
ReactorGallery, surfaced alongside Gallery and Toolkit results. Searchable via
`--source reactor`; ships an embedded offline snapshot plus on-demand `update`
refresh.
- `winui-ui-testing`: documents the new `winapp ui` input and capture verbs —
`send-keys` (synthetic keyboard, accelerators, per-character `KeyDown`),
`hover`, `drag`, `touch`, `pen`, and `record` (H.264 MP4 capture) — with usage
examples plus new rows in the "what to test" and assertion tables, and a
`RichEditBox`→`send-keys` gotcha.
- `winui-dev-workflow`: documents WinUI crash diagnosis in `winapp run` — the
`--debug-output` stowed-exception triage pass (first-run debugger-component
download, `WINAPP_DBGTOOLS_DIR`) and the new `--symbols` flag for Microsoft
Symbol Server-backed native crash analysis; `BuildAndRun.ps1` gains an opt-in
`-Symbols` switch.
### Changed
- `winui-ui-testing` now targets **any Windows desktop app** (Win32, WPF, WinForms, WinUI 3, packaged or unpackaged) — the `winapp ui` UI Automation harness is framework-agnostic, not WinUI-only.
- `BuildAndRun.ps1` defaults to `dotnet build` (was Visual Studio MSBuild) now that the Windows App SDK XAML-compiler bug is fixed; pass `-UseMSBuild` to opt back in.
### Fixed
- `winui-search`: restored the WinUI Gallery data refresh, which broke when upstream
`microsoft/WinUI-Gallery` reorganized and reformatted its samples — `ControlInfoData.json`
moved to `SampleSupport/Data/`, sample pages moved to per-control `Samples/{UniqueId}/`
folders, and the `ControlExample` schema was replaced with `--- header/xaml/c#`
`SampleDefinition` `.txt` bundles. `GalleryFetcher` now parses the new format (keeping a
fallback for the few legacy inline Accessibility pages) and the embedded gallery snapshot
was regenerated. Fixes #120.
## [0.4.0] — 2026-06-25
### Added
- 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.
## [0.3.1] — 2026-05-19
### Added
- `winui-dev` agent: window sizing rubric, screenshot validation step, and
anti-self-delegation guardrails (#84).
- `winui-search`: batched CLI mode, background cache refresh, BM25-based
ranking, and upgraded WinUI Gallery + Community Toolkit data fetchers (#83).
### Changed
- CI: `pr-validation` workflow now also runs on PRs targeting `staging`.
- Bumped `coverlet.collector` from 10.0.0 to 10.0.1 (#87).
## [0.3.0] — 2026-05-13
Baseline entry covering everything currently shipped on `main` at the time the
release process was introduced. Future releases will list per-PR changes here.
### Added
- Initial public preview of the `winui` plugin: `winui-dev` agent and the eight
skills (`winui-dev-workflow`, `winui-design`, `winui-code-review`,
`winui-ui-testing`, `winui-packaging`, `winui-wpf-migration`,
`winui-session-report`, `winui-setup`).
- In-repo tools: `Microsoft.WindowsAppSDK.Analyzers` (Roslyn analyzer),
`winui-search` (Native AOT search over WinUI Gallery + Community Toolkit),
`winmd-cli` (Native AOT WinRT/.NET metadata indexer).
- CI provenance jobs guarding the committed analyzer DLL and `winui-search.exe`
against source drift.
- Marketplace manifest under `.github/plugin/marketplace.json` and Claude Code
marketplace manifest under `.claude-plugin/marketplace.json`.

View File

@@ -0,0 +1,10 @@
# Microsoft Open Source Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
Resources:
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
- Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support)

View File

@@ -0,0 +1,113 @@
# Contributing to `win-dev-skills`
This repo hosts agent plugins for Windows development and debugging under
`plugins/<name>/`, and also lists plugins maintained in other repos, pinned to a
release. You can contribute:
- **A new plugin.** Add it here (Option A), or pin a plugin from its own repo
(Option B).
- **Skills for an existing plugin.** Send them to wherever that plugin is
maintained (see the [README](README.md) table). `winui` and `winappcli` are
maintained in [microsoft/winappCli](https://github.com/microsoft/winappCli);
file their issues and PRs there.
## Bar for inclusion
- **Windows development and debugging.** Building, designing, testing,
debugging, packaging, or shipping Windows apps, services, or kernel-mode
drivers.
- **Small and curated.** A focused plugin with a few skills that each do one
job well, not a dump of prompts.
- **Clear descriptions.** Each skill `description` is 300 characters or fewer
and says when to use it and when not to: "Use when… Not for…".
- **No overlap.** Check existing plugins first: `winappcli` and `winui` in
this catalog, and [dotnet/skills](https://github.com/dotnet/skills)' `dotnet-diag`,
`dotnet-winforms`, and `dotnet-maui`. Extend one of those instead of
duplicating it.
- **Owned.** Two or more maintainers who review its PRs.
Open an issue first if you're unsure whether a plugin fits.
## Option A: add a plugin here
Use the [Agent Plugins](https://agent-plugins.org/specification) layout, plus
the manifests each host needs:
```text
plugins/<name>/
plugin.json Agent Plugins manifest with "$schema" (Copilot, Codex)
.claude-plugin/plugin.json Claude Code manifest (same name and version)
skills/<skill>/SKILL.md one folder per skill
com.github.copilot/agents/ optional Copilot agents
```
Then:
1. Add the plugin to all three catalogs. Use `"source": "./plugins/<name>"` in
`.github/plugin/marketplace.json` and `.claude-plugin/marketplace.json`, and
`"source": { "source": "local", "path": "./plugins/<name>" }` in
`.agents/plugins/marketplace.json`. Use the same `name`, and the same
`version` as the manifests.
2. Add a `/plugins/<name>/` entry to [`.github/CODEOWNERS`](.github/CODEOWNERS).
3. Add a row to the README plugin table (the only place plugins are listed; list the hosts it supports) and a `CHANGELOG.md` entry.
## Option B: pin a plugin from another repo
Use this when the plugin ships with a product in its own repo. Pin a
**release tag and its commit sha** in all three catalogs:
```jsonc
// .github/plugin/marketplace.json
"source": { "source": "github", "repo": "owner/repo", "path": "plugins/<name>", "ref": "v1.2.3", "sha": "<40-char sha>" }
// .claude-plugin/marketplace.json and .agents/plugins/marketplace.json
"source": { "source": "git-subdir", "url": "https://github.com/owner/repo.git", "path": "plugins/<name>", "ref": "v1.2.3", "sha": "<40-char sha>" }
```
Resolve the sha with `gh api repos/<owner>/<repo>/commits/<tag> --jq .sha`.
Add the README table row and a `CHANGELOG.md` entry. The source repo owns the
plugin's content, issues, and PRs.
## Bumping a pin
Open a PR that updates `ref`, `sha`, and the plugin `version` in all three
catalogs. Hosts only pick up new content when the version changes. CI checks
that the tag still points at the sha, and that the version matches the
plugin's manifests at that commit.
## Review
[`.github/CODEOWNERS`](.github/CODEOWNERS) routes catalog, CI, and tooling
changes to the catalog maintainers, and `plugins/<name>/` changes to that
plugin's owners. PRs target `main`.
## CI checks
| Check | What it wants |
|---|---|
| `Catalog check` | Every entry resolves: repo, commit, path, and the host's plugin manifest exist, and its name and version match. A `ref` must resolve to the pinned `sha`. All three catalogs list the same plugins at the same pin. |
| `Local plugin lint (vally)` | Plugins in this repo pass the [vally](https://github.com/microsoft/vally) lint that awesome-copilot runs. A fixture test proves the check and lint handle a local plugin. |
Run them locally (Node 22+; set `GITHUB_TOKEN` to avoid API rate limits):
```powershell
node scripts/check-catalogs.mjs
npm ci --prefix scripts/vally
node scripts/vally/lint-skills.mjs
node scripts/tests/test-catalog-tools.mjs
```
The checks read files only. Before merging, install from your branch on each
host (for example
`copilot plugin marketplace add microsoft/win-dev-skills#<branch>`) and confirm
the skills load.
## Code of Conduct
This project follows the
[Microsoft Open Source Code of Conduct](CODE_OF_CONDUCT.md).
## CLA
Contributions of non-trivial size require signing the
[Microsoft CLA](https://opensource.microsoft.com/cla/). The CLA bot will
prompt you on your first PR.

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation and Contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

View File

@@ -0,0 +1,135 @@
# Agents and skills for Windows development and debugging
Agent plugins for Windows development and debugging—from apps and services to kernel-mode drivers—with GitHub Copilot, Claude Code, OpenAI Codex, and more. Add this repo as a marketplace once, then install the plugins you need.
| Plugin | What it's for | Maintained in | Hosts |
|---|---|---|---|
| **`winappcli`** | Packaging, signing, and distributing Windows apps with [WinApp CLI](https://github.com/microsoft/winappCli): MSIX, certificates, package identity, appxmanifest, Windows SDK setup, and the Microsoft Store. Works with Electron, .NET, C++, Rust, Flutter, and Tauri. | [microsoft/winappCli](https://github.com/microsoft/winappCli/tree/main/plugins/winapp) | Copilot, Claude Code, Codex, OpenClaw, OpenCode |
| **`winui`** | Native Windows apps with **WinUI 3** and the **Windows App SDK**: scaffold, design, build, run, test, package, and ship. | [microsoft/winappCli](https://github.com/microsoft/winappCli/tree/main/plugins/winui) | Copilot, Claude Code, Codex, OpenClaw, OpenCode |
| **`windbg`** | WinDbg diagnosis workflows and report validation for applications, services, UMDF/user-mode drivers, and kernel-mode drivers. [Feedback](https://github.com/microsoft/WinDbg-Feedback/issues). | [This repo](plugins/windbg/README.md) | Copilot, Claude Code, Codex, OpenCode |
On Codex, OpenClaw, and OpenCode, skills load; agents aren't available.
Plugins are either hosted here under `plugins/<name>/` or maintained in another repo and pinned to a release; both are first-class. `winappcli` and `winui` are maintained in [microsoft/winappCli](https://github.com/microsoft/winappCli); file their issues and PRs there.
## Install
You need **Git** (`winget install Git.Git`) and one of the hosts below. Replace `<plugin>` with a name from the table.
> [!NOTE]
> Install each plugin from **one** catalog. microsoft/winappCli's own catalog (`<plugin>@winappcli`) and awesome-copilot ship the same plugins; installing a second copy gives you duplicate skills.
### GitHub Copilot CLI
```powershell
copilot plugin marketplace add microsoft/win-dev-skills
copilot plugin install <plugin>@win-dev-skills
```
<details>
<summary>Or let Copilot install <code>winui</code> and its prerequisites</summary>
Paste this prompt into a Copilot CLI session:
```
Install the Copilot CLI plugin "winui" from microsoft/win-dev-skills, then set up my machine for WinUI 3 development. Specifically:
1. Run: copilot plugin marketplace add microsoft/win-dev-skills
2. Run: copilot plugin install winui@win-dev-skills
3. Make sure these prerequisites are present (check first and change only what is missing or too old):
- .NET SDK >= 8.0.100 (run `dotnet --list-sdks`; if none qualifies, `winget install --id Microsoft.DotNet.SDK.10 --exact --silent --accept-package-agreements --accept-source-agreements`)
- WinApp CLI: must be >= 0.7.0 (parse the standalone version line from `winapp --version`); if missing, `winget install --id Microsoft.WinAppCli`; if older, `winget upgrade --id Microsoft.WinAppCli`.
- Do not install WinUI templates separately — WinApp CLI installs and updates them on demand through `winapp new`.
- Developer Mode (DWORD HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowDevelopmentWithoutDevLicense == 1) — ASK ME first before triggering UAC; if I decline, just print the elevated command for me to run later.
- Report whether Windows Sandbox is available for UI testing. If it isn't and I want it, tell me how to enable it myself (Pro, Enterprise, or Education, not Home); don't change Windows features or reboot. Report native C++ toolchain requirements separately if I request AOT.
4. Print a short summary of what was installed vs already present, then tell me to start a new Copilot CLI, activate the "winui-dev" agent, and to ask it to build an app.
```
</details>
### Claude Code
```powershell
claude plugin marketplace add microsoft/win-dev-skills
claude plugin install <plugin>@win-dev-skills
```
### OpenAI Codex
```powershell
codex plugin marketplace add microsoft/win-dev-skills
codex plugin add <plugin>@win-dev-skills
```
Codex loads skills, not agents. Invoke skills by name (e.g. `/winui-setup`).
> [!IMPORTANT]
> **Added this catalog to Codex before as `microsoft-winui`?** It's now named `win-dev-skills`, and `codex plugin marketplace upgrade` fails with "upgraded marketplace name `win-dev-skills` does not match configured marketplace `microsoft-winui`". Your installed plugins keep working but stop updating. Move them over once, removing plugins before the marketplace:
>
> ```powershell
> codex plugin remove <plugin>@microsoft-winui # for each installed plugin
> codex plugin marketplace remove microsoft-winui
> codex plugin marketplace add microsoft/win-dev-skills
> codex plugin add <plugin>@win-dev-skills # for each plugin
> ```
### OpenClaw
OpenClaw only reads catalogs whose plugins all live in the same repo, so it can't use this catalog today. Install from the catalog of the repo that maintains the plugin. For `winappcli` and `winui`, that's microsoft/winappCli:
```powershell
openclaw plugins install <plugin> --marketplace microsoft/winappCli
openclaw gateway restart
```
OpenClaw loads skills, not agents. Check them with `openclaw skills list`.
> [!IMPORTANT]
> **Installed `winui` from `--marketplace microsoft/win-dev-skills` before?** That route no longer works, and `openclaw plugins update` fails for it. Reinstall once with the command above.
### OpenCode
OpenCode loads Agent Skills from `<name>/SKILL.md` folders. Clone the repo that maintains the plugin, then link its skills folder (the one containing `<skill>/SKILL.md` directories) into OpenCode's global skills directory, or a project's `.opencode/skills/`:
```powershell
git clone <repo from the "Maintained in" column>
$src = "<path to the plugin's skills folder in that clone>"
$dst = "$env:USERPROFILE\.config\opencode\skills"
New-Item -ItemType Directory -Force $dst | Out-Null
Get-ChildItem $src -Directory | ForEach-Object {
$link = Join-Path $dst $_.Name
if (-not (Test-Path $link)) { New-Item -ItemType Junction -Path $link -Target $_.FullName | Out-Null }
}
```
The links are junctions, so `git pull` in the clone picks up skill updates. OpenCode loads skills, not agents.
### Next steps
Start a new session and ask for a real task, for example:
> "Build me a WinUI 3 markdown editor with live preview and a custom title bar"
## Updates
When a catalog entry moves to a new version, update with your host's usual commands:
```powershell
copilot plugin marketplace update win-dev-skills; copilot plugin update <plugin>@win-dev-skills
claude plugin marketplace update win-dev-skills; claude plugin update <plugin>@win-dev-skills
codex plugin marketplace upgrade win-dev-skills
```
Tags up to `v0.7.1` of this repo contain the `winui` plugin itself, so `https://github.com/microsoft/win-dev-skills.git#v0.7.1` still installs that version.
## Contributing
New plugins and skills for Windows development and debugging are welcome, either as a plugin in this repo under `plugins/<name>/` or as a pinned entry for a plugin maintained in another repo. See [`CONTRIBUTING.md`](CONTRIBUTING.md). For catalog or install problems, [open an issue here](https://github.com/microsoft/win-dev-skills/issues).
Most contributions require you to agree to a Contributor License Agreement (CLA); see [opensource.microsoft.com/cla](https://opensource.microsoft.com/cla) for details. This project has adopted the [Microsoft Open Source Code of Conduct](CODE_OF_CONDUCT.md). For support channels see [SUPPORT.md](SUPPORT.md), and for responsible disclosure of security issues see [SECURITY.md](SECURITY.md).
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos is subject to those third parties' policies.
## License
This project is licensed under the [MIT License](LICENSE). Third-party components and their licenses are listed in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).

View File

@@ -0,0 +1,48 @@
# Releasing `win-dev-skills`
A plugin hosted here under `plugins/<name>/` ships from `main`. A plugin
maintained in another repo is released there, and the catalog then moves its
pin to that release.
## Release a plugin hosted here
In one PR, bump the plugin's `version` in its manifests and in its entries in
the Copilot and Claude catalogs, bump the catalog version, and add a
`CHANGELOG.md` section. `Catalog check` verifies that the versions match.
## Move a pinned plugin to a new version
1. Release the plugin in its source repo (for `winui` and `winappcli`: a
microsoft/winappCli release). Note the release tag, its commit sha
(`gh api repos/<owner>/<repo>/commits/<tag> --jq .sha`), and the plugin
version.
2. On a branch from `main`, update the plugin entry in all three catalogs:
- `.github/plugin/marketplace.json`: `source.ref`, `source.sha`, `version`
- `.claude-plugin/marketplace.json`: `source.ref`, `source.sha`, `version`
- `.agents/plugins/marketplace.json`: `source.ref`, `source.sha`
3. Bump the catalog version (`metadata.version` in the Copilot catalog and
`version` in the Claude catalog) and add a `## [X.Y.Z] — YYYY-MM-DD`
section to `CHANGELOG.md`.
4. Open a PR to `main`. `Catalog check` verifies the new pin resolves and the
versions match.
5. Merge. If the catalog version changed, `auto-tag` tags the merge commit
`vX.Y.Z`.
Hosts pick up a plugin change when its **version** changes. Copilot and Codex
also re-fetch when only the source changes; Claude Code keeps the installed
copy until the version changes. So always ship new plugin content with a new
plugin version.
## Tags
`release-post-merge.yml` reads `metadata.version` from
`.github/plugin/marketplace.json` on every push to `main`. If it changed, it
tags the commit `vX.Y.Z`. It never moves an existing tag.
Tags up to `v0.7.1` contain the `winui` plugin itself.
## Rolling back
Ship a fixed version with a higher version number: for a pinned plugin,
release it in the source repo and move the pin. Don't point the catalog back at
an older version.

View File

@@ -0,0 +1,14 @@
<!-- BEGIN MICROSOFT SECURITY.MD V1.0.0 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which
includes all source code repositories in our GitHub organizations.
**Please do not report security vulnerabilities through public GitHub issues.**
For security reporting information, locations, contact information, and policies,
please review the latest guidance for Microsoft repositories at
[https://aka.ms/SECURITY.md](https://aka.ms/SECURITY.md).
<!-- END MICROSOFT SECURITY.MD BLOCK -->

View File

@@ -0,0 +1,69 @@
# Support
> **The `winui` and `winappcli` plugins are authored in [microsoft/winappCli](https://github.com/microsoft/winappCli); file their issues and PRs there.**
## How to file issues and get help
This project uses GitHub Issues to track bugs and feature requests. Please search the existing issues before filing new issues to avoid duplicates.
### Filing Issues
We have specific issue templates to help you provide the right information:
- **[Bug Report](https://github.com/microsoft/win-dev-skills/issues/new?template=bug-report.yml)** - Report something that isn't working correctly
- **[Feature Request](https://github.com/microsoft/win-dev-skills/issues/new?template=feature_request.yml)** - Suggest a new feature, skill, or enhancement
- **[Documentation Issue](https://github.com/microsoft/win-dev-skills/issues/new?template=documentation.yml)** - Report a problem with a `SKILL.md`, README, or other docs
- **[General Issues](https://github.com/microsoft/win-dev-skills/issues)** - File any other type of issue or browse existing issues
Please ensure that you are not filing a duplicate issue by searching existing issues first.
For WinUI agent-run problems, file the issue in microsoft/winappCli and attach a `session-report.md` from the **`winui-session-report`** skill.
### Getting Help
For help and questions about using this project:
1. Read the [README](./README.md) for setup and quick-start instructions.
2. For skill guidance, see the `winui` and `winappcli` skills in [`microsoft/winappCli`](https://github.com/microsoft/winappCli/tree/main/plugins).
3. Browse existing [GitHub Issues](https://github.com/microsoft/win-dev-skills/issues) for similar questions.
4. File a new issue with the `question` label if you need additional help.
## Issue Triage
Our team actively monitors and manages issues in this repository.
- **Bug Reports and questions**: Critical bugs are prioritized and addressed as quickly as possible. Questions will be monitored.
- **Feature Requests**: Evaluated during regular planning cycles. Feature requests for new skills are tracked separately and may be picked up by the community.
### When a New Issue is Created
All new issues are automatically reviewed and tagged with appropriate labels:
- **Type**: `bug`, `enhancement`, `question`, `documentation`
- **Area**: per-skill labels (e.g., `skill: winui-dev-workflow`, `skill: winui-design`) or `area: agent`, `area: tools`, `area: plugin`
- **Priority**: `good first issue`, `help wanted` (for community contribution opportunities)
### Investigation
As we investigate and work on issues, additional labels are applied:
- **`known-issue`** - Applied to issues the team has identified and is tracking
- **`needs-author-response`** - Waiting on the issue author for clarification or additional information (used by the [stale-issues workflow](./.github/workflows/stale-issues.yml))
- **`needs:docs`** - Issues that require documentation updates or clarification
- **`dependencies`** - Issues related to external dependency updates
### Closing Issues
When closing issues, we apply final classification labels:
- **`duplicate`** - Issue already reported elsewhere (includes link to original)
- **`invalid`** - Issue doesn't seem right or cannot be reproduced
- **`wontfix`** - Issue will not be addressed (with explanation in comments)
## Contributing
Contributions are welcome. See the [README](./README.md) for an overview of the plugin layout and how skills are structured, and the [PR template](./.github/PULL_REQUEST_TEMPLATE.md) for the checklist your PR should satisfy.
## Microsoft Support Policy
Support for **win-dev-skills** is limited to the resources listed above. This is an open-source project maintained by Microsoft, and community contributions are welcome.

View File

@@ -0,0 +1,20 @@
# Third-Party Notices
This repository is licensed under the [MIT License](LICENSE). Any third-party
material added to the plugin must retain its original copyright notices and
licenses.
This file is informational and is updated whenever vendored content,
embedded data snapshots, or significant runtime dependencies change. For
machine-readable component governance metadata, see
[`cgmanifest.json`](cgmanifest.json).
## External development tools
The plugin does not vendor the WinUI analyzer, its NuGet dependencies, or the
metadata CLI. WinApp CLI and `Microsoft.Windows.SDK.BuildTools.WinUIAnalyzer`
are installed separately and used under their respective licenses.
The removed C# source and test dependencies are no longer registrations in
`cgmanifest.json`; their build and dependency governance belong upstream in
[`microsoft/winappCli`](https://github.com/microsoft/winappCli).

View File

@@ -0,0 +1,5 @@
{
"$schema": "https://json.schemastore.org/component-detection-manifest.json",
"version": 1,
"registrations": []
}

View File

@@ -0,0 +1,21 @@
{
"name": "windbg",
"version": "1.0.0",
"description": "WinDbg diagnosis workflows and report validation for applications, services, UMDF/user-mode drivers, and kernel-mode drivers.",
"author": {
"name": "Microsoft",
"url": "https://github.com/microsoft/WinDbg-Feedback"
},
"homepage": "https://github.com/microsoft/WinDbg-Feedback",
"repository": "https://github.com/microsoft/win-dev-skills",
"keywords": [
"windows",
"windbg",
"debugging",
"crash",
"hang",
"memory",
"umdf",
"drivers"
]
}

View File

@@ -0,0 +1,12 @@
# Changelog
## 1.0.0 - Initial contribution
- Included the curated debugging skill inventory in `skills.json`.
- Added the shared `windbg-diagnostic-method` skill with deterministic report
validation and the contrarian agent required for the complete workflow.
- Kept the runtime package limited to the inventory in `skills.json`.
- Removed owner and metadata fields from every skill header.
- Added public WinDbg-Feedback guidance.
- Added explicit diagnosis/fix confidence separation and fix-path coverage
calibration for the contrarian review gate.

View File

@@ -0,0 +1,66 @@
# Public feedback
Feedback destination:
[microsoft/WinDbg-Feedback issues](https://github.com/microsoft/WinDbg-Feedback/issues).
Use this procedure for feedback about these debugging skills or WinDbg. For
general application-debugging help, consult that repository's
[support guidance](https://github.com/microsoft/WinDbg-Feedback/blob/master/SUPPORT.md).
## Procedure for assistants
1. Collect the skill ID, public package version, the user's own verdict, and
what was confusing, incorrect, or missing. Do not invent the user's verdict
or claim a diagnosis is confirmed when it is not.
2. Check for an existing relevant issue before drafting a new one, when search
is available. Do not add labels or choose assignees without authorization.
3. Prepare a minimal sanitized title and body using the template below. Exclude
secrets, customer data, usernames, private paths, hostnames, proprietary source,
internal links, memory contents, and complete diagnostic transcripts.
4. Show the exact draft and state that it will be publicly visible in
`microsoft/WinDbg-Feedback`. Obtain explicit approval before posting. Re-review
material changes to the approved draft. Declining or cancelling creates no
issue.
5. Use the host's supported GitHub issue-creation tool when available and
authorized. Otherwise provide the approved text and
[new-issue page](https://github.com/microsoft/WinDbg-Feedback/issues/new)
for manual submission. Tool/authentication failure is an explicit failure,
not a successful submission or an excuse to silently use another destination.
6. Return a confirmed issue URL only after creation succeeds. Never fabricate a
receipt. For manual submission, say that the issue has not been submitted yet.
Do not automatically attach or upload dumps, CABs, ETLs, TTD recordings, source
code, or diagnosis files. Permission to share an artifact privately does not
authorize public disclosure. Do not put unreviewed diagnostic text into
issue-URL query parameters. Report sensitive vulnerabilities through the approved
private security reporting channel, not this public feedback flow.
## Suggested issue template
Title: `[Debugging skills][<skill-id>] <short feedback summary>`
```markdown
### Skill and version
Plugin: windbg
Package version: <public version from plugin.json>
Skill: <skill-id>
### Category and verdict
Category: <incorrect guidance / missing coverage / unclear instructions / packaging / positive feedback>
My verdict: <helpful / partly helpful / incorrect / unclear>
### Expected behavior
<What the guidance should help me do>
### Observed behavior
<Relevant step and minimal sanitized evidence; label uncertain conclusions>
### Environment
<Relevant WinDbg version, Windows version, architecture; omit identifying information>
### Suggested improvement
<Optional correction, missing explanation, or synthetic repro>
```
Only include information the user approves for public disclosure. There is no
bundled uploader, credential store, private share, or notification service.

View File

@@ -0,0 +1,371 @@
# Debugging Diagnostician
A WinDbg-centric crash, hang, memory, and driver diagnosis playbook for
developers who build software **for Windows**: native applications, services,
third-party user-mode drivers (including UMDF), and kernel-mode drivers.
This public edition combines focused user-mode and kernel-mode debugging skills,
a shared `windbg-diagnostic-method` skill with deterministic report validation,
and a contrarian reviewer. It does not require private Windows source, symbols,
portals, or feedback services. The goal is to shorten the path from a dump,
trace, or stack to a supported root cause and candidate fix without forcing a
pattern match.
## Install
Install from the catalog:
```powershell
copilot plugin marketplace add microsoft/win-dev-skills
copilot plugin install windbg@win-dev-skills
```
Claude Code and Codex use their normal marketplace install commands described in
the repository README. Skills work independently on skill-capable hosts. The
optional `diagnostician` agent is provided for GitHub Copilot only; it is not
required to use the skills on other hosts.
### Claude Code with the WinDbg MCP server
For Claude Code to use the WinDbg MCP server without its debugger operations
being blocked, open **WinDbg > Settings > MCP** and clear both of these options:
- **Enable Cross Prompt Injection Mitigation**
- **Enable Secure Mode for MCP Server**
If secure mode was already activated, restart WinDbg after clearing it. WinDbg
keeps secure mode active until restart.
> [!WARNING]
> These settings are security protections. Disable them only for a trusted
> debugging session with dumps, command output, source, and prompts you are
> authorized to expose to Claude Code. Re-enable the protections when the
> unrestricted MCP operations are no longer required.
The plugin does not bundle an MCP server; this configuration applies to the
separately installed WinDbg MCP integration.
For a pre-merge local review, use your host's supported local plugin loading
mechanism on this directory. Do not assume the catalog commands can fetch an
unmerged contribution.
## Quick Start
Invoke the optional Copilot agent with a dump, stack, trace, or failure summary:
```text
Use the diagnostician agent to analyze this crash stack, bugcheck, hang
symptom, or debugger output: <paste the evidence here>
```
You can also invoke a skill directly on a skill-capable host:
```text
Use windbg-user-heap-corruption-investigation on the dump open in WinDbg.
Establish what evidence is available, distinguish competing explanations, and
state what remains unproven.
```
The plugin supplies diagnostic guidance, not a debugger connection. Use an
existing, approved WinDbg integration if available, or inspect the suggested
commands yourself and provide their output. The assistant must never claim to
have executed commands or accessed source/dumps that it cannot actually use.
## Short prompt — root cause a dump in the debugger
Use this when an authorized debugger integration is connected to a dump and you
want the diagnostician to drive the investigation:
```text
Root cause the dump in the debugger. Let the diagnostician orchestrate the
debugging session, use the available source tools for my own code, and follow
the standard five-phase protocol. Treat pattern matches as hypotheses, test
alternatives, and state missing evidence.
```
This prompt does three things:
1. Names the diagnostician as the investigation orchestrator while preserving
user approval for state-changing operations.
2. Grounds source lookups in tools and repositories the user is authorized to
access, rather than assuming private operating-system source.
3. Invokes the full observe-hypothesize-test-evaluate-conclude/pivot protocol.
## Full investigation prompt
Use this prompt when you want a durable diagnosis with explicit structure:
````text
Use the diagnostician agent to run the full investigation workflow on the dump,
trace, stack, or debugger session in this conversation.
1. Apply the five-phase diagnostic method. Treat matching skills as hypothesis
generators, not proof.
2. If filesystem access is available, write the complete diagnosis to
./.diagnoses/<short-id>/<yyyyMMdd-HHmmss>.md. Otherwise return the same
structure in the response and state that no file was written.
3. Include these H2 sections in order:
Analysis, Root Cause, Fix, Reasoning Chain, Alternatives Considered,
Trigger Verification, Mermaid, Contrarian Verdict, and JSON Output Contract Summary.
4. Trigger Verification must be a table separating observed evidence,
contradictory evidence, missing evidence, and the validation needed for the
proposed fix.
5. Mermaid must be a VS Code-renderable sequenceDiagram with at least two
participants when a sequence/ownership flow is relevant. If a sequence
diagram would misrepresent the failure, explain why and use the closest
evidence-preserving Mermaid diagram.
6. Do not finalize a root cause while a plausible alternative remains untested.
If evidence is insufficient, use diagnosis_status
"candidate-pending-verification" and name the next evidence required.
````
The package includes a public contrarian sub-agent and the shared
`windbg-diagnostic-method` skill. The full prompt invokes both gates; when a
host cannot run a separate sub-agent, the agent must state that limitation
rather than substitute inline self-review.
## How It Works
Every diagnosis follows a five-phase **hypothesis-test-pivot** cycle:
1. **OBSERVE** — Parse dump/trace type, architecture, stack, code, registers,
resource state, and evidence limitations.
2. **HYPOTHESIZE** — Form a specific, testable primary theory and plausible
alternatives.
3. **TEST** — Identify and collect evidence that would confirm or deny each
hypothesis.
4. **EVALUATE** — Separate what is supported, contradicted, inferred, or still
missing.
5. **CONCLUDE or PIVOT** — State the supported cause and verification plan, or
revise the hypothesis when evidence does not support it.
The agent may choose one of three reasoning paths:
| Path | Indicative confidence | Behavior |
|---|---:|---|
| **Fast** | ≥80% | A strong known pattern is treated as a hypothesis, required evidence is verified, and alternatives are checked before conclusion. |
| **Validate** | 40–79% | The leading pattern and at least one plausible alternative go through the full cycle. |
| **Full-reasoning** | <40% or no match | Start from observations, construct alternatives, and preserve explicit uncertainty. |
Confidence is an explanation aid, not measured probability. A high initial
match does not bypass evidence or permit blaming a module solely because it
appears on the stack.
## Invocation Modes
### Mode 1: Interactive Debugging
Use the diagnostician agent with a dump, trace, stack, or live debugger context.
The agent drives the five-phase investigation and produces a structured
diagnosis.
State-changing actions—enabling Verifier/Page Heap, changing configuration,
capturing traces, or forcing a crash—require explicit user authorization.
### Mode 2: Triage Enrichment
Provide failure metadata, stack text, or a partial investigation without a live
debugger. The diagnostician identifies likely skill routes, missing evidence,
and concrete next commands. It must not imply that proposed commands were
executed or that a routing match proves the root cause.
### Mode 3: Public Feedback
When the user asks to submit WinDbg or debugging-skill feedback, follow
`FEEDBACK.md`. Draft a minimal sanitized public issue for
[microsoft/WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues),
show the exact title/body and public destination, and obtain explicit approval
before posting with a supported GitHub issue tool. Without such a tool, provide
the approved text and new-issue page for manual submission.
This public mode does not collect an eval corpus and never automatically uploads
dumps, TTD recordings, ETLs, CABs, private source, or full transcripts.
## Input
The agent accepts natural language. A structured handoff can use this shape:
```json
{
"case_id": "optional public or local identifier",
"bug_type": "crash|hang|leak|bugcheck|unknown",
"stack_frames": ["frame1", "frame2"],
"error_code": "0xC0000005",
"exception_type": "ACCESS_VIOLATION",
"target": "application|service|user-mode-driver|kernel-mode-driver",
"additional_context": "authorized, sanitized context and evidence limits"
}
```
Do not put secrets, customer data, private paths, or memory contents into a
public feedback issue. Diagnostic input can remain local to the approved session.
## Output
```json
{
"diagnosis_status": "final|candidate-pending-verification",
"routing_path": "fast|validate|full-reasoning",
"analysis": {
"summary": "what the evidence shows",
"evidence": ["direct evidence with command/source"],
"reasoning": ["why evidence supports or contradicts each hypothesis"],
"uncertainty": ["what remains unproven"]
},
"reasoning_chain": [
"OBSERVE: ...",
"HYPOTHESIZE: ...",
"TEST: ...",
"EVALUATE: ...",
"CONCLUDE or PIVOT: ..."
],
"root_cause": "supported cause, or null while pending verification",
"fix": "candidate change and verification plan, or null",
"confidence": 0.82,
"fix_confidence": 0.68,
"fix_code_path_coverage": "read-this-session|read-prior-session|symbol-or-disassembly|pattern-only|not-read",
"matched_skill": "a skill name, or null",
"alternatives_considered": ["alternative and evidence"],
"trigger_verification": "verified|partially-verified|not-verified",
"contrarian_review": "ACCEPTED|CHALLENGED with notes",
"contrarian_loopback": false
}
```
## Knowledge Base
### Debugging Skills (`skills/`)
The authoritative skill inventory is `skills.json`.
#### User-mode: applications, services, and user-mode drivers (including UMDF)
| Skill | Use it for |
|---|---|
| `windbg-user-exception-triage` | Establish exception context and classify native process crashes, including user-mode driver host failures. |
| `windbg-user-heap-corruption-investigation` | Investigate use-after-free, double-free, and overruns in applications, services, or user-mode driver hosts. |
| `windbg-user-wait-chain-analysis` | Follow application, service, user-mode driver, COM/RPC, and process waits to a supported blocker or cycle. |
| `windbg-user-ttd-reverse-debugging-triage` | Find earlier writes, frees, and calls in a recorded user-mode process, including a user-mode driver host. |
| `windbg-user-virtual-memory-exhaustion` | Separate address-space pressure, fragmentation, commit pressure, and applicable limits. |
| `windbg-user-mutex-held-across-co-await` | Investigate thread-affine locks held across coroutine suspension in user-mode components. |
#### Kernel-mode: external kernel-mode driver developers
| Skill | Use it for |
|---|---|
| `windbg-kernel-bugcheck-triage` | Decode bugchecks and recover original exception or trap context. |
| `windbg-kernel-verifier-triage` | Interpret Driver Verifier violations and available I/O verification evidence. |
| `windbg-kernel-irp-lifecycle-triage` | Investigate outstanding I/O, completion/cancel ownership, and power IRPs. |
| `windbg-kernel-lock-deadlock-triage` | Build supported kernel owner/waiter graphs and investigate lock-order inversions. |
Trap-frame and exception-context recovery are included in
`windbg-kernel-bugcheck-triage`, not additional skills. Feedback guidance and
the optional agent are support content rather than bug-family skills.
No specialized C++ thrown-object or XAML stowed-exception decoder is included. `windbg-user-exception-triage` documents the boundary and continues evidence-led reasoning instead of dispatching to absent skills. This is native debugging guidance, not a managed .NET diagnostics package.
### Eight Hypothesis Templates
These are starting hypotheses, never automatic diagnoses:
| Template | Signal | Required discipline |
|---|---|---|
| Race Condition | Race, TOCTOU, concurrent access | Identify shared state, competing paths, ordering, and a reproducible interleaving. |
| Lock Ordering | Deadlock, inversion, ABBA | Establish every owner/waiter edge and the conflicting acquisition order. |
| RPC Under Lock | Cross-process call while holding a lock | Prove the held resource and callback/server dependency; a synchronous COM call alone is not a deadlock. |
| Timer/Callback Race | Callback during teardown | Prove registration, cancellation/rundown, object lifetime, and which path can still execute. |
| Cross-Apartment Dependency | Wrong-thread/apartment failure or STA hang | Establish apartment contracts, marshaling, pumping/reentrancy, and object agility. |
| Reentrant Lock Acquisition | Re-entry while state/lock is held | Identify the reentrant edge and whether the primitive or invariant permits it. |
| Regression | Failure after a version/build change | Compare evidence and code/config changes; correlation with a build is not causation. |
| Platform/Instruction | Architecture, alignment, or illegal instruction | Verify target architecture, decoded bytes, CPU/ABI requirement, and binary identity. |
### Shared method skill
| Skill | Purpose |
|---|---|
| `windbg-diagnostic-method` | Applies the shared evidence, reasoning, confidence, review, reporting, and deterministic validation method. |
## File Inventory
| File | Purpose |
|---|---|
| `plugin.json` | Portable Agent Plugins manifest for Copilot and Codex. |
| `.claude-plugin/plugin.json` | Claude Code plugin manifest with matching name/version. |
| `com.github.copilot/agents/diagnostician.agent.md` | Main Copilot diagnostician agent. |
| `com.github.copilot/agents/contrarian.agent.md` | Independent adversarial review agent. |
| `skills/<skill-name>/SKILL.md` | Bug-family skills and the shared diagnostic method. |
| `skills.json` | Exact public skill inventory and user-mode/kernel-mode grouping. |
| `FEEDBACK.md` | Public, reviewed WinDbg-Feedback issue procedure and issue template. |
| `CHANGELOG.md` | Public package changes. |
| `README.md` | Package usage, methodology, scope, and support contract. |
There is no bundled MCP server, uploader, credential store, notification
service, or feedback automation. The shared method is explicitly inventoried
and is not a bug-family-specific skill.
### Authoring and calibration material not bundled
The runtime package contains only the files listed above. Case data, test
artifacts, evaluation datasets, source links, and authoring records are not
distributed with the plugin. The published skills retain actionable workflows
and public references.
## Requirements and Limits
- WinDbg and an appropriate process, user-mode driver host, or kernel dump (or
an authorized live debugging session).
- Public Windows symbols and matching binaries/PDBs for your own modules.
Missing dump pages or symbols limit conclusions and must be reported.
- TTD requires an actual authorized user-mode recording; it cannot replay
kernel execution or reconstruct history from an ordinary dump.
- Application Verifier/Page Heap and Driver Verifier are optional repro tools.
Use them on suitable test systems; their overhead or deliberate failures can
disrupt workloads. Record settings and restore them after the investigation.
- Commands and data-model features vary across WinDbg/extension versions. Check
installed help and public documentation rather than inventing unsupported
syntax or private structure layouts.
## Constraints
- **Diagnosis is read-only by default:** Produce a diagnosis; do not modify code,
bug state, machine settings, or uploaded artifacts unless the user explicitly
authorizes that action.
- **Feedback submission is explicit and public:** Show the exact sanitized
issue payload and destination before posting. No submission occurs on decline,
cancellation, missing tooling, or authentication failure.
- **Reasoning-first:** Investigate and test; do not conclude from keyword or
stack-pattern matching alone.
- **Conservative:** Unknown or candidate-pending-verification is valid. State
missing pages, symbols, histories, or cross-process evidence.
- **Evidence provenance:** Cite debugger output, the user's authorized source,
a controlled reproduction, or public documentation. Do not require private
Windows source or portals.
- **Windows-scoped:** Native Windows application/service debugging, user-mode
drivers including UMDF, and kernel-mode drivers.
## Contact, Support, and Feedback
| | |
|---|---|
| **Issue and feedback tracking** | [microsoft/WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues) |
| **Public feedback procedure** | [`FEEDBACK.md`](FEEDBACK.md) |
| **General debugging support guidance** | [WinDbg-Feedback SUPPORT.md](https://github.com/microsoft/WinDbg-Feedback/blob/master/SUPPORT.md) |
| **Sensitive security reports** | Follow the repository SECURITY policy; do not post vulnerabilities publicly. |
The package uses the public WinDbg-Feedback repository rather than personal
contacts or non-public destinations. WinDbg-Feedback is for feedback, not a
guarantee of individual application-debugging support. Publication reviewers
should confirm ongoing skill-feedback triage with that repository's maintainers.
Never automatically upload dumps, TTD traces, ETLs, CABs, private source, or
full diagnostic transcripts. Review and approve a minimal sanitized issue
before posting.
## Versioning and Contribution
The public inventory is `skills.json`. Change the package version in both plugin
manifests and all three catalog entries when publishing changed content. Update
the plugin CHANGELOG and keep exactly the intended skill inventory.
Do not mark an update as shipped until its public contribution or release is
confirmed. Future changes must be reviewed in this repository and preserve
independent improvements made to the published plugin.

View File

@@ -0,0 +1,153 @@
---
name: contrarian
description: Independently challenges a proposed Diagnostician root cause, trigger evidence, alternatives, confidence, fix strength, and diagram consistency.
tools: []
user-invocable: false
---
# Contrarian
You are the **Contrarian** in an adversarial root-cause pipeline for Windows crash, hang, and leak diagnoses. You are invoked by the diagnostician agent AFTER it has completed Phase 5 (Conclude) and produced a candidate root cause + fix + mermaid diagram.
## Input
You receive **the diagnostician's complete output**, including:
- The reasoning chain (all 5 phases verbatim)
- The list of alternative hypotheses considered and the evidence cited to rule each one out
- The trigger-verification record (which trigger was suspected, what evidence verifies it, or UNVERIFIED)
- The proposed fix, `fix_confidence`, and `fix_code_path_coverage` declaration
- The diagnosis confidence value and its calibration rationale
- The mermaid sequence diagram
You do **NOT** see:
- The original dump file or live debug session
- The ability to run any debugger commands or read any source
You work ONLY from the diagnostician's output text.
## Mission
Argue the **OPPOSITE** of the diagnostician's primary root cause. Find what is **WRONG** with the reasoning, the trigger verification, or the fix. You are not here to be agreeable — you are here to prevent false confidence from reaching the bug fix or the customer.
## Attack Vectors
Systematically evaluate the diagnostician's output for these failure modes:
### 1. Symptom-vs-Cause Confusion
The diagnostician may have anchored on the **observable symptom** rather than the **root invariant violation**. Common patterns:
- "The pointer was stack-allocated" — but is that actually possible given the lifetime of the structure on this code path? Did the diagnostician verify it, or assume it because the address looked stack-shaped?
- "The structure was freed" — but freed by whom, and was free actually reachable on this code path?
- "The lock was not held" — but did the diagnostician verify the locking discipline by reading the producer/consumer code, or only the faulting frame?
If the root cause restates the crash mode in mechanism terms but does not name the **invariant the code violates**, flag it.
### 2. Trigger Not Verified by Direct Evidence
The diagnostician's `trigger_verification` field claims either VERIFIED (with cited evidence) or UNVERIFIED. Audit this:
- If VERIFIED: Did the diagnostician actually read the source/disassembly cited, or paraphrase a structure they expect to exist? Look for suspiciously round line numbers, code that "must" have a certain shape, or quotes that read like model knowledge rather than file content.
- If the trigger is "the producer's wait has a timeout escape" — was the wait actually inspected, or was it assumed because the symptom requires it?
- If the trigger is "callback fires after the producer signals" — was the signal-then-callback ordering proven, or inferred from the crash being in that callback?
A diagnosis whose entire fix matrix depends on an unverified trigger is a diagnosis without a fix. Call it out.
### 3. Single-Stack Reasoning / Missing Threads
Many Windows crashes are cross-thread races. Did the diagnostician examine ONLY the faulting thread's stack, or did they reason about the producer/owner thread as well?
- If the bug is a UAF, who freed the memory? Did the diagnostician identify the freeing thread and prove its sequencing?
- If the bug is a hang, who holds the lock/signal/handle that the faulting thread is waiting on? Was that thread's state inspected?
- If the bug is a corruption, who wrote the bad bytes? Was the writer identified, or assumed?
A complete diagnosis names BOTH parties to the race. A partial diagnosis names only the victim.
### 4. Fix Targets Reproducer, Not Invariant
The proposed fix may eliminate the **specific repro path** without restoring the **broken invariant**. Common patterns:
- "Add a null check" — does this fix the use-after-free, or does it just prevent the crash on the dereference while leaving the lifetime bug intact?
- "Increase the timeout" — does this fix the synchronization bug, or just hide it?
- "Initialize the field to zero" — does this fix the missing initialization, or just prevent the assertion on this code path?
- "Hold the lock longer" — does this restore the locking invariant, or just narrow the race window?
Ask: if a different caller hits the same invariant violation through a different code path, does the proposed fix protect them? If not, the fix is reproducer-targeted, not invariant-restoring.
### 5. Fix-Confidence Calibration Violation
The diagnostician's fix confidence must comply with this calibration:
- ≥0.9 requires `fix_code_path_coverage = read-this-session`
- 0.7–0.89 allows `read-prior-session` or `symbol-or-disassembly`
- 0.5–0.69 covers incomplete symbol/disassembly evidence or `pattern-only`
- <0.5 uses `not-read` and is candidate-only
Audit: does the declared `fix_confidence` match the declared coverage? If the diagnostician claims 0.9 but admits the fix was inferred from a related skill rather than read in this session, the calibration is wrong.
### 6. Mermaid Diagram Lies
The mermaid diagram should match the reasoning chain. Common drift:
- The diagram shows actors that are not named in the reasoning chain
- The diagram skips the trigger condition in favor of the symptom
- The diagram uses prose that contradicts the verified evidence
- The diagram glosses over an unverified step with `Note over` instead of an explicit message
If the diagram is more confident than the prose, the diagram is wrong.
## Counter-Hypothesis Requirement
You **must** produce a counter-hypothesis: an alternative root cause that does NOT rely on the diagnostician's primary mechanism. The counter-hypothesis should:
- Be plausible given the symptoms described in the diagnostician's OBSERVE phase
- Use a fundamentally different mechanism than the diagnostician's primary hypothesis
- Identify what direct evidence (from the dump or source) would distinguish it from the primary hypothesis
- Include a probability and confidence estimate
## Honesty Clause
If the diagnostician's analysis is genuinely strong — trigger verified, alternatives ruled out with cited evidence, fix targets the invariant, confidence calibrated — say so explicitly. Forced contrarianism without substance is worse than useless. A real ACCEPTED verdict is more valuable than a manufactured CHALLENGE.
## Isolation Constraints
- You have **NO tools**. Do not attempt to call any tools.
- You work ONLY from the diagnostician's output text.
- Do NOT fabricate source code references, function names, or technical details. If the diagnostician didn't cite it, you don't know it.
- Your value comes from logical and structural analysis of the diagnosis, not from inventing alternative evidence.
## Output Format
Structure your response with these exact sections:
```
## Verdict: ACCEPTED | CHALLENGED
[One-sentence summary]
## Counter-Hypothesis (probability: X.XX, confidence: X.XX)
[An alternative root cause that does NOT use the diagnostician's primary mechanism. Include the distinguishing evidence that would resolve it.]
## Critique of Diagnostician
### Symptom-vs-Cause Assessment
[Does the root cause name the invariant, or restate the symptom?]
### Trigger Verification Audit
[Was the trigger verified by cited evidence, or assumed? Quote the claim being audited.]
### Cross-Thread Completeness
[Did the diagnosis name both parties to the race / both ends of the lifetime?]
### Fix-Targets-Invariant Assessment
[Does the fix restore the invariant, or close the reproducer?]
### Confidence Calibration Audit
[Does the declared confidence match the declared code-path coverage per the calibration table?]
### Mermaid Diagram Consistency
[Does the diagram match the reasoning chain and verified evidence?]
## Fabrication Check
[List each specific technical claim from the diagnostician and grade as VERIFIED (cited evidence in this session), PLAUSIBLE (consistent but uncited), or SUSPECT (no supporting evidence and reads like model knowledge)]
## Strength Assessment
[What the diagnostician got RIGHT, and what makes those conclusions reliable. Required even when verdict is CHALLENGED.]
```

View File

@@ -0,0 +1,126 @@
---
name: diagnostician
description: Diagnose native Windows application, service, user-mode driver (including UMDF), and kernel-mode driver failures with public WinDbg workflows.
---
# Debugging Diagnostician
Apply `windbg-diagnostic-method` throughout every investigation, then use the
most relevant bug-family skill for detailed commands and evidence requirements.
Use the available debugger integration only when authorized. If none is
available, explain which commands to run and reason from supplied output; never
claim execution or access you do not have. Use the user's approved source tools
for their own code, not private operating-system repositories.
## Investigation contract
1. Observe dump type, architecture, symbols, exception/bugcheck or hang symptoms,
and the actual evidence available.
2. Form a primary hypothesis and plausible alternatives. Pattern matches are
hypotheses, not conclusions.
3. Test with specific commands, source inspection, or a controlled reproduction.
Record direct evidence and missing information.
4. Evaluate contradictions and distinguish the original defect from downstream
symptoms. Do not blame a module solely because the crash appears there.
5. Conclude with the supported cause, candidate fix, and verification plan, or
pivot when evidence is insufficient.
## Routing paths
- **Fast (indicative confidence ≥80%)**: validate required evidence and plausible
alternatives before concluding; never skip the five phases.
- **Validate (40–79%)**: test the leading pattern and at least one plausible
alternative through the full cycle.
- **Full-reasoning (<40% or no match)**: reason from observations, preserve
uncertainty, and state the next evidence required.
Confidence is explanatory judgment, not measured probability.
## Available routes
| Evidence | Skill |
|---|---|
| Application, service, or user-mode driver host structured exception | `windbg-user-exception-triage` |
| Application, service, or user-mode driver host heap corruption/history | `windbg-user-heap-corruption-investigation` |
| Blocked UI, service, user-mode driver host, COM/RPC, or thread/process wait | `windbg-user-wait-chain-analysis` |
| A recorded application, service, or user-mode driver host execution with a history question | `windbg-user-ttd-reverse-debugging-triage` |
| User-mode allocation failure, VA fragmentation, or commit pressure | `windbg-user-virtual-memory-exhaustion` |
| Thread-affine lock surviving coroutine suspension in a user-mode component | `windbg-user-mutex-held-across-co-await` |
| Kernel bugcheck, trap frame, or saved exception context | `windbg-kernel-bugcheck-triage` |
| Driver Verifier violation | `windbg-kernel-verifier-triage` |
| Outstanding/power IRP, cancellation, or completion | `windbg-kernel-irp-lifecycle-triage` |
| Kernel lock owner/waiter chain | `windbg-kernel-lock-deadlock-triage` |
The user-mode skills apply to native applications, services, and user-mode
drivers such as UMDF drivers running in a user-mode host process. The
kernel-mode skills apply to kernel-mode drivers. `skills.json` is the complete
inventory. No specialized C++ thrown-object
or XAML stowed-exception decoder is supplied. For unsupported families continue
evidence-led reasoning, state the coverage gap, and do not dispatch to absent
skills. Kernel trap and context recovery are part of the bugcheck skill.
## Hypothesis templates
Use these only to generate testable alternatives:
| Template | Evidence required |
|---|---|
| Race condition | Shared state, competing paths, ordering, and a reproducible interleaving |
| Lock ordering | Owners/waiters and the conflicting acquisition order |
| RPC under lock | Held resource plus callback/server dependency |
| Timer/callback race | Registration, cancellation/rundown, lifetime, and still-runnable path |
| Cross-apartment dependency | Apartment contracts, marshaling, pumping/reentrancy, and agility |
| Reentrant lock acquisition | Reentrant edge and violated lock/state invariant |
| Regression | Before/after evidence and the relevant code/configuration change |
| Platform/instruction | Architecture, decoded bytes, ABI/CPU requirement, and binary identity |
## Independent review and completion gate
Before finalizing a full diagnosis:
1. Invoke the bundled `contrarian` agent by name as an independent sub-agent
when the host supports sub-agents. Give it the complete proposed diagnosis.
2. If the host cannot run sub-agents, state that the independent contrarian gate
could not run; do not silently substitute inline self-review.
3. If the contrarian challenges the diagnosis, test its counter-hypothesis with
direct evidence, then downgrade confidence or use
`candidate-pending-verification`. Stop after one loopback.
4. Write the diagnosis report when filesystem access is available, then run the
validator bundled with `windbg-diagnostic-method`. Correct structural
failures and re-run the script before finalizing.
## Output
Provide a diagnosis with: observations, hypothesis, evidence, alternatives,
supported/candidate cause, proposed fix, and verification needs. Distinguish
observed facts from inference; report insufficient symbols/dump pages explicitly.
Report diagnosis confidence separately from `fix_confidence`, and include
`fix_code_path_coverage` using one of: `read-this-session`,
`read-prior-session`, `symbol-or-disassembly`, `pattern-only`, or `not-read`.
Write a local diagnosis artifact only when requested or required by the user's
workflow. Do not automatically turn the analysis into public feedback.
When the user requests the full durable workflow and filesystem access is
available, write `./.diagnoses/<short-id>/<yyyyMMdd-HHmmss>.md` with these H2
sections in order: Analysis, Root Cause, Fix, Reasoning Chain, Alternatives
Considered, Trigger Verification, Mermaid, Contrarian Verdict, and JSON Output
Contract Summary. Trigger Verification must separate observed, contradictory,
and missing evidence plus fix validation. Record `contrarian_loopback` as the
Boolean `true` or `false`. Run the validator bundled with
`windbg-diagnostic-method` against the report. If a file cannot be written,
return the same structure and state that the validator could not run.
## Safety and feedback
Do not enable Verifier/Page Heap, change system configuration, capture a trace,
or upload an artifact without user authorization. Explain repro-tool impact and
restoration steps. Never force a crash or alter a production machine merely to
collect evidence.
For requested feedback follow the plugin's `FEEDBACK.md`: draft a minimal
sanitized issue for https://github.com/microsoft/WinDbg-Feedback/issues, show
the exact public payload, and ask for approval before posting with a supported
GitHub issue tool. Without a tool, provide approved text for manual submission.
Never attach dumps/traces/transcripts automatically or claim submission without
a confirmed issue URL.

View File

@@ -0,0 +1,27 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "windbg",
"version": "1.0.0",
"description": "WinDbg diagnosis workflows and report validation for applications, services, UMDF/user-mode drivers, and kernel-mode drivers.",
"author": {
"name": "Microsoft",
"url": "https://github.com/microsoft/WinDbg-Feedback"
},
"homepage": "https://github.com/microsoft/WinDbg-Feedback",
"repository": "https://github.com/microsoft/win-dev-skills",
"keywords": [
"windows",
"windbg",
"debugging",
"crash",
"hang",
"memory",
"umdf",
"drivers"
],
"extensions": {
"com.github.copilot": {
"agents": "./com.github.copilot/agents"
}
}
}

View File

@@ -0,0 +1,19 @@
{
"name": "windbg",
"version": "1.0.0",
"diagnosticSkills": [
"windbg-user-exception-triage",
"windbg-user-heap-corruption-investigation",
"windbg-user-wait-chain-analysis",
"windbg-user-ttd-reverse-debugging-triage",
"windbg-user-virtual-memory-exhaustion",
"windbg-user-mutex-held-across-co-await",
"windbg-kernel-bugcheck-triage",
"windbg-kernel-verifier-triage",
"windbg-kernel-irp-lifecycle-triage",
"windbg-kernel-lock-deadlock-triage"
],
"methodSkills": [
"windbg-diagnostic-method"
]
}

View File

@@ -0,0 +1,179 @@
---
name: windbg-diagnostic-method
description: Use with every WinDbg plugin investigation to apply evidence-first reasoning, confidence calibration, contrarian review, structured reporting, and deterministic validation. Not a bug-family-specific triage skill.
user-invocable: false
---
# WinDbg Diagnostic Method
Apply this method alongside the bug-family-specific skill selected for an
investigation. Pattern matches route the investigation; they do not prove the
root cause.
## Evidence ladder
Prefer direct evidence in this order:
1. Faulting instruction/context, bugcheck or exception parameters, and resource
owners/waiters from the actual dump or trace.
2. Matching symbols and the user's authorized source for the involved build.
3. Allocation/free, Verifier, IRP, lock, ETW, WCT, or TTD history captured for
the same failure.
4. Controlled reproduction and instrumentation.
5. Pattern guidance as a hypothesis only.
Never claim commands, source access, or artifacts that are unavailable in the
session.
## First-pass normalization
- Confirm process dump versus kernel dump and target architecture/build.
- Load public Windows symbols and matching symbols for user/vendor modules.
- Record missing pages, symbols, related-process dumps, trace scope, and tool
availability.
- User-mode exception: `.exr -1`, `.ecxr`, stack, and registers.
- Kernel bugcheck: `.bugcheck`, `!analyze -v`, then documented context/trap
recovery for that code.
- Hang: identify the affected operation, wait type, owner/server, and deepest
supported blocker.
- Memory: distinguish corruption, address-space pressure, and commit/limit
failures before choosing a fix.
## Five-phase investigation
1. **OBSERVE**: establish dump/trace type, architecture, symbols, code, stack,
registers, thread/resource state, and missing evidence.
2. **HYPOTHESIZE**: form a specific primary mechanism and at least two plausible
alternatives when the evidence permits.
3. **TEST**: identify direct debugger, source, trace, or reproduction evidence
that distinguishes the hypotheses. Absence of evidence is not evidence of
absence.
4. **EVALUATE**: record supporting, contradictory, and missing evidence.
5. **CONCLUDE or PIVOT**: name the violated invariant and verification plan, or
remain `candidate-pending-verification`.
## Routing index
| Evidence | Skill |
|---|---|
| Native user-mode exception in an app, service, or UMDF/user-mode driver host | `windbg-user-exception-triage` |
| User-mode heap corruption or allocation/free history | `windbg-user-heap-corruption-investigation` |
| Cross-thread/process, COM/RPC, or service wait | `windbg-user-wait-chain-analysis` |
| User-mode TTD history question | `windbg-user-ttd-reverse-debugging-triage` |
| User-mode VA fragmentation, allocation failure, or commit pressure | `windbg-user-virtual-memory-exhaustion` |
| Thread-affine lock across coroutine suspension | `windbg-user-mutex-held-across-co-await` |
| Kernel bugcheck, trap frame, or saved context | `windbg-kernel-bugcheck-triage` |
| Driver Verifier violation | `windbg-kernel-verifier-triage` |
| Outstanding/power IRP, completion, or cancellation | `windbg-kernel-irp-lifecycle-triage` |
| Kernel lock owner/waiter chain | `windbg-kernel-lock-deadlock-triage` |
These are the complete bug-family routes. Continue evidence-led reasoning for
unsupported families; never dispatch to an absent skill.
## Routing depth
- **Fast (indicative diagnosis confidence >=0.80)**: validate the apparent
pattern, its required evidence, and plausible alternatives.
- **Validate (0.40-0.79)**: test the leading pattern and at least one plausible
alternative through the full cycle.
- **Full reasoning (<0.40 or no match)**: reason from observations and preserve
explicit uncertainty.
Confidence is explanatory judgment, not measured probability.
## Trigger and fix gates
- Verify the trigger in the dump, disassembly, source, trace, or controlled
reproduction before declaring a final fix.
- Name the violated invariant and the parties or path that violate it.
- Separate the detector or victim from the original writer, freeing actor, or
resource holder.
- A fix must restore the violated invariant, not merely suppress the reproducer.
- If the trigger is unverified, use `candidate-pending-verification`, set the
fix to null or a verification plan, and name the evidence/fix matrix needed.
- Do not blame a module solely from a bucket or `MODULE_NAME`.
## Fix-confidence calibration
Diagnosis confidence and fix confidence are separate. Every proposed fix must
declare `fix_confidence` and one `fix_code_path_coverage` value:
| Fix confidence | Required coverage |
|---|---|
| `>=0.90` | `read-this-session`: the actual fix path was read in this investigation. |
| `0.70-0.89` | `read-prior-session` or `symbol-or-disassembly`: direct coverage exists, but the complete source path was not read in this investigation. |
| `0.50-0.69` | `pattern-only`, or incomplete symbol/disassembly evidence. Treat the fix as a candidate. |
| `<0.50` | `not-read`: no direct fix-path coverage. Keep the diagnosis candidate-pending-verification and set the fix to null or a verification plan. |
Lower confidence is always allowed when evidence quality, path coverage, or
alternatives warrant it. Never raise confidence to fit the table.
## Independent review
Before finalizing a full diagnosis:
1. When the host supports the bundled Copilot agents, invoke the `contrarian`
agent once with the complete proposed diagnosis.
2. When the host cannot run that agent, state that the independent review did
not run; do not silently substitute inline self-review.
3. If the verdict is `CHALLENGED`, test the counter-hypothesis with direct
evidence, then downgrade confidence or remain pending verification.
4. Stop after one loopback. A second challenge remains pending verification.
Record `contrarian_loopback` as the Boolean `true` or `false`.
## Report contract
A full report contains these H2 sections in order:
1. Analysis
2. Root Cause
3. Fix
4. Reasoning Chain
5. Alternatives Considered
6. Trigger Verification
7. Mermaid
8. Contrarian Verdict
9. JSON Output Contract Summary
The Trigger Verification section must distinguish observed, contradictory, and
missing evidence plus fix validation. Mermaid must reflect verified evidence.
The JSON summary must include:
- `diagnosis_status`
- `routing_path`
- `root_cause`
- `confidence`
- `fix_confidence`
- `fix_code_path_coverage`
- `contrarian_review`
- `contrarian_loopback`
## Deterministic report validation
After writing the report, run the bundled validator with PowerShell 7:
```powershell
pwsh -NoProfile -File <skill-directory>\scripts\validate-diagnosis-output.ps1 `
-Path <diagnosis-markdown-path>
```
Use the installed `windbg-diagnostic-method` directory for
`<skill-directory>`. The script checks each section body independently,
requires at least two alternatives, accepts explicit or implicit Mermaid
participants, parses the JSON summary, and exits nonzero on failure.
Correct failed checks and rerun the script before presenting the report as
structurally complete. Structural validation does not replace technical review.
## Safety and privacy
Dumps, traces, ETLs, CABs, source, paths, tokens, and memory contents can be
sensitive. Obtain authorization before capture, configuration changes, or
sharing. Verifier and Page Heap can disrupt workloads and require a recoverable
test plan plus restoration steps. Public feedback follows `FEEDBACK.md` and
defaults to a minimal reviewed summary with no automatic attachments.
## Feedback
For feedback about this method or validator, follow the package `FEEDBACK.md`.
Do not attach private diagnosis files automatically.

View File

@@ -0,0 +1,169 @@
param(
[Parameter(Mandatory = $true)]
[string]$Path
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
throw "Diagnosis file not found: $Path"
}
$resolvedPath = (Resolve-Path -LiteralPath $Path).Path
$content = Get-Content -LiteralPath $resolvedPath -Raw
function Get-SectionMatch {
param([Parameter(Mandatory = $true)][string]$HeadingPattern)
$pattern = "(?ims)^##\s+(?:$HeadingPattern)\b[^\r\n]*\r?\n(?<body>.*?)(?=^##\s+|\z)"
return [regex]::Match($content, $pattern)
}
function Test-MermaidDiagram {
$blocks = [regex]::Matches($content, '(?ims)^```mermaid\s*\r?\n(?<body>.*?)^```\s*$')
foreach ($block in $blocks) {
$body = $block.Groups["body"].Value
if ($body -match '(?im)^\s*sequenceDiagram\s*$') {
$actors = [System.Collections.Generic.HashSet[string]]::new(
[System.StringComparer]::OrdinalIgnoreCase
)
foreach ($match in [regex]::Matches(
$body,
'(?im)^\s*(?:participant|actor)\s+([A-Za-z0-9_.-]+)'
)) {
[void]$actors.Add($match.Groups[1].Value)
}
foreach ($match in [regex]::Matches(
$body,
'(?im)^\s*([A-Za-z0-9_.-]+)\s*(?:--?>>|->>|--?>|--x|-x|--\)|-\))\s*([A-Za-z0-9_.-]+)\s*:'
)) {
[void]$actors.Add($match.Groups[1].Value)
[void]$actors.Add($match.Groups[2].Value)
}
if ($actors.Count -ge 2) {
return $true
}
}
if ($body -match '(?im)^\s*(?:flowchart|graph)\b') {
$nodes = [System.Collections.Generic.HashSet[string]]::new(
[System.StringComparer]::OrdinalIgnoreCase
)
foreach ($match in [regex]::Matches(
$body,
'(?im)^\s*([A-Za-z0-9_]+).*?(?:-->|---|-.->|==>)\s*([A-Za-z0-9_]+)'
)) {
[void]$nodes.Add($match.Groups[1].Value)
[void]$nodes.Add($match.Groups[2].Value)
}
if ($nodes.Count -ge 2) {
return $true
}
}
}
return $false
}
$analysis = Get-SectionMatch "Analysis"
$rootCause = Get-SectionMatch "Root Cause"
$fix = Get-SectionMatch "Fix"
$reasoning = Get-SectionMatch "Reasoning Chain"
$alternatives = Get-SectionMatch "Alternatives(?: Considered)?"
$trigger = Get-SectionMatch "Trigger Verification"
$contrarian = Get-SectionMatch "Contrarian Verdict"
$alternativeCount = 0
if ($alternatives.Success) {
$alternativeCount = [regex]::Matches(
$alternatives.Groups["body"].Value,
'(?m)^\s*(?:[-*+]\s+|\d+[.)]\s+)'
).Count
}
$triggerBody = if ($trigger.Success) { $trigger.Groups["body"].Value } else { "" }
$triggerTableRows = [regex]::Matches($triggerBody, '(?m)^\s*\|.*\|\s*$').Count
$contrarianBody = if ($contrarian.Success) {
$contrarian.Groups["body"].Value
} else {
""
}
$results = [ordered]@{
AnalysisHeading = $analysis.Success
RootCauseHeading = $rootCause.Success
FixHeading = $fix.Success
ReasoningChain = (
$reasoning.Success -and
$reasoning.Groups["body"].Value -match 'OBSERVE|HYPOTHESIZE|TEST|EVALUATE|CONCLUDE'
)
Alternatives = ($alternatives.Success -and $alternativeCount -ge 2)
TriggerVerification = (
$trigger.Success -and
$triggerTableRows -ge 3 -and
$triggerBody -match '(?i)\bVERIFIED\b|\bUNVERIFIED\b|verified by'
)
MermaidDiagram = Test-MermaidDiagram
ContrarianVerdict = (
$contrarian.Success -and
$contrarianBody -match '\bACCEPTED\b|\bCHALLENGED\b' -and
$contrarianBody -match '(?i)contrarian_loopback[^:\r\n]*:\s*(?:true|false)\b'
)
JsonSummary = $false
}
$requiredJsonProperties = @(
"diagnosis_status",
"routing_path",
"root_cause",
"confidence",
"fix_confidence",
"fix_code_path_coverage",
"contrarian_review",
"contrarian_loopback"
)
foreach ($block in [regex]::Matches($content, '(?is)```json\s*(?<body>.*?)```')) {
try {
$json = $block.Groups["body"].Value | ConvertFrom-Json
} catch {
continue
}
$propertyNames = @($json.PSObject.Properties.Name)
$hasRequiredProperties = $true
foreach ($property in $requiredJsonProperties) {
if ($propertyNames -notcontains $property) {
$hasRequiredProperties = $false
break
}
}
if (
$hasRequiredProperties -and
$json.contrarian_loopback -is [bool]
) {
$results.JsonSummary = $true
break
}
}
$pass = @($results.Values | Where-Object { $_ -eq $false }).Count -eq 0
$output = [pscustomobject]@{
Pass = $pass
File = $resolvedPath
Checks = [pscustomobject]$results
}
$output | ConvertTo-Json -Depth 5
if (-not $pass) {
exit 1
}

View File

@@ -0,0 +1,129 @@
---
name: windbg-kernel-bugcheck-triage
description: 'Use when a kernel dump reports a Windows bugcheck; decode parameters and recover exception or trap context before investigating your driver. Not for user-mode process crashes or blaming a module from its name alone.'
---
# Kernel Bugcheck Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Scope
Use a kernel crash dump or authorized live kernel session. A process dump
captured after a reboot does not contain the earlier kernel fault. Confirm
the dump type with the debugger, not a filename or the user's visible symptom.
This skill includes exception-context and trap-frame recovery.
## Workflow
### 1. Establish symbols and bugcheck evidence
```text
.symfix
.sympath+ <your-vendor-symbol-directory>
.reload
!analyze -v
.bugcheck
k
```
Replace the placeholder with the approved symbol location for your own binaries.
Record dump type, target architecture/build, bugcheck code and parameters,
faulting instruction, and available memory. Public Windows symbols suffice
for many investigations; do not require private Windows source or PDBs.
### 2. Decode parameters for the specific code
| Code | Parameter meaning / next step |
|---|---|
| `0x1E` | P1 exception code; P2 exception address; P3/P4 exception-specific information. These are not generically a CONTEXT pair. |
| `0x7E` | P1 exception code; P2 exception address; P3 EXCEPTION_RECORD; P4 CONTEXT. |
| `0x3B` | P1 exception code; P2 instruction address; P3 CONTEXT; P4 unused. |
| `0x0A` / `0xD1` | Referenced address, IRQL, access information, instruction address. Decode the access field for that code; these parameters are not generally a trap-frame pointer. |
| `0x50` | Invalid memory reference; parameter interpretation varies with target version. Consult the code reference. |
| `0x9F` | P1 selects the power-failure subtype; use its specific parameter table and `windbg-kernel-irp-lifecycle-triage` where applicable. |
| Verifier-class stop | Use `windbg-kernel-verifier-triage` and the exact code/subcode definition. |
Do not reuse a parameter layout across different bugchecks.
### 3. Recover the original faulting context
For `0x7E`:
```text
.exr <P3>
.cxr <P4>
kb
r
```
For `0x3B`:
```text
.cxr <P3>
kb
r
```
For other exception-style bugchecks, locate a valid saved exception/context
using the documented code procedure and available analysis output. Do not
guess `.cxr` arguments from arbitrary P1..P4 values.
When `!analyze -v` or verified stack evidence identifies a `TRAP_FRAME`:
```text
.trap <trap-frame-address>
kb
r
```
Trap frames can be partial: some registers may be missing or reconstructed
incorrectly. Note the debugger's warnings and do not treat unsaved registers as
reliable evidence. If a frame is missing, malformed, or absent from the dump,
report the limitation rather than scanning arbitrary pointers and claiming a
recovered context.
### 4. Investigate the driver, not just the detector
```text
!thread
lmvm <driver-module>
.frame /r <frame-number>
```
Inspect the recovered instruction, register/object used, IRQL, ownership,
and nearby driver frames. A crash in an operating-system routine may result
from prior driver corruption. Conversely, a third-party name in
`MODULE_NAME` does not establish that the named driver caused the failure.
Verify vendor build identity against the matching binary/PDB.
For concurrency or blocked requests use `windbg-kernel-lock-deadlock-triage` or
`windbg-kernel-irp-lifecycle-triage`. Kernel `~` commands select processors, not the
application thread list; use documented thread/process inspection such as
`!thread` and `!process 0 7`.
## Validation
Record the decoded parameters, recovered context and its limitations, and the
evidence connecting the driver's operation to the violated invariant. Test
competing lifetime, bounds, IRQL, and synchronization explanations. Recommend
an instrumented test/repro only with approval; route Verifier evidence to
`windbg-kernel-verifier-triage`. Do not call a guessed module assignment a proven cause.
## References
- [Bugcheck reference](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-code-reference2)
- [0x3B SYSTEM_SERVICE_EXCEPTION](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-0x3b--system-service-exception)
- [0x7E SYSTEM_THREAD_EXCEPTION_NOT_HANDLED](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-0x7e--system-thread-exception-not-handled)
- [Context record](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-cxr--display-context-record-)
- [Trap frame](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-trap--display-trap-frame-)
## Feedback
Follow `FEEDBACK.md` and submit only reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-kernel-bugcheck-triage` and the package version from `plugin.json`; no
automatic kernel dump, private-symbol, or source upload.

View File

@@ -0,0 +1,101 @@
---
name: windbg-kernel-irp-lifecycle-triage
description: 'Use when kernel evidence shows stalled I/O, a power IRP, or completion/cancellation misuse; inspect request state and driver ownership. Not for interpreting an empty IRP search in a limited dump as proof of healthy I/O.'
---
# IRP Lifecycle Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Scope
Investigate I/O Request Packets in a kernel dump or authorized live kernel
session. Examples include `0x9F` power failures and hangs where progress
depends on a driver request. Apply the parameter table for the specific
bugcheck subtype rather than assuming every `0x9F` identifies the same object.
For `0x9F` with P1 equal to `3`, P4 is the blocked IRP. Inspect that directly
before running a system-wide search.
## Workflow
### 1. Decode the known request
```text
!analyze -v
!irp <irp-address>
```
When no request address is known and the dump has the required pool data:
```text
!irpfind
```
`!irpfind` can be expensive in a live session and incomplete in a limited dump.
Use supported filters where appropriate. No result does not prove there are
no outstanding requests.
### 2. Follow the stack and ownership
Record the major/minor operation, current stack location, device/driver stack,
completion routine, pending flags, cancellation state, and any relevant thread.
Use the available device stack and driver source to establish which component
is expected to advance or complete the request.
Do not identify an offending driver solely by the last name printed in the IRP
stack. A completion routine, downstream dependency, or framework-owned request
may change the responsible path.
### 3. Correlate dependencies
| Evidence | Next investigation |
|---|---|
| I/O verifier violation or available shadow history | `windbg-kernel-verifier-triage` |
| Owner/waiter kernel lock chain | `windbg-kernel-lock-deadlock-triage` |
| Exception or trap during request handling | `windbg-kernel-bugcheck-triage` |
Preserve evidence between skills; avoid repeatedly handing the same unchanged
IRP back and forth.
### 4. Test the request protocol
- **Power request:** inspect the subtype's objects and power/PnP state,
current stack location, and completion dependency.
- **Cancellation race:** establish which routine owns completion, how
cancellation synchronizes with normal completion, and whether the request
can be completed twice or retained after cancellation.
- **Double completion:** trace competing terminal paths; a single live IRP
snapshot may not contain enough history.
- **Pending request:** verify API/framework-specific pending and completion
rules, remove/shutdown paths, and who promises eventual progress.
WDM and WDF have different ownership APIs. Do not transplant a raw WDM
completion/cancel pattern into a framework-owned request without checking its
contract. This skill establishes evidence; it is not a complete I/O protocol
reference or a decoder for every power subtype.
## Validation
Name the operation, current owner/dependency, and supported protocol violation
or stalled path. Test normal completion, concurrent cancellation, removal,
power transitions, and shutdown where relevant. If history is missing, propose
an approved instrumented test using the verifier skill rather than inventing
which driver lost the completion.
## References
- [IRP inspection](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-irp)
- [IRP search](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-irpfind)
- [0x9F power-state failure](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-0x9f--driver-power-state-failure)
- [Canceling IRPs](https://learn.microsoft.com/windows-hardware/drivers/kernel/canceling-irps)
## Feedback
Follow `FEEDBACK.md` and report only reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-kernel-irp-lifecycle-triage` and the package version from `plugin.json`; no
automatic kernel dump or request-content upload.

View File

@@ -0,0 +1,105 @@
---
name: windbg-kernel-lock-deadlock-triage
description: 'Use when kernel threads block on driver synchronization or Verifier reports a lock-order violation; build an owner/waiter graph. Not for treating every watchdog stop as a deadlock or listing every lock type with !locks.'
---
# Kernel Lock and Deadlock Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection
Use kernel thread stacks, synchronization-object evidence, and Driver Verifier
deadlock records. A watchdog bugcheck can indicate CPU/DPC progress failures,
not necessarily a lock cycle. Establish the actual waits before choosing this
workflow.
## Workflow
### 1. Gather owners and waiters
```text
!locks
!thread <ethread-address>
!process 0 7
```
`!locks` enumerates ERESOURCE information. It is not an inventory of all
pushlocks, fast mutexes, and spinlocks. For other primitives use documented
primitive-specific inspection when available, matching symbols for your
driver, its source, and recorded acquisition evidence. State missing owners
explicitly.
### 2. Inspect recorded lock-order evidence
If Driver Verifier deadlock detection was enabled and the dump contains its
records:
```text
!deadlock 1
```
Inspect the reported resources, acquisition sequence, and threads. Verifier
can detect an unsafe ordering before a persistent deadlock actually forms.
An empty result without the required verification/history is not proof that
the lock order is safe. For Verifier setup/safety use `windbg-kernel-verifier-triage`.
### 3. Build and test the graph
```text
thread A holds resource X -> waits for Y owned by B
thread B holds resource Y -> waits for X owned by A
```
Show evidence for every edge. Check recursive acquisition, callbacks under
locks, I/O completion dependencies, and destruction/rundown paths.
Distinguish:
- A demonstrated cycle or Verifier-reported order inversion.
- Contention where a runnable owner can progress.
- Starvation or an owner blocked on a separate request.
- Spin/IRQL problems, which are not necessarily blocking-lock deadlocks.
If blocked on an IRP use `windbg-kernel-irp-lifecycle-triage`; if a chain crosses into a
user-mode COM/RPC operation use `windbg-user-wait-chain-analysis`. Carry the proven graph
edges into the next skill rather than starting the same investigation again.
### 4. Localize the driver path
Identify which call path held one resource while acquiring/waiting for another.
Check the required IRQL, permitted waits, lock hierarchy, and object lifetime.
Private Windows implementation layouts are not prerequisites; if public
symbols and captured state cannot recover an edge, request appropriate
authorized evidence and keep the conclusion provisional.
## Fix patterns
Use a consistent acquisition hierarchy, reduce lock scope, avoid unbounded
waits/cross-component callbacks while holding resources, and move potentially
blocking destruction outside locks where the ownership design permits.
Do not replace a lock or add a timeout without preserving invariants and
completion/cancellation semantics.
## Validation
Record the graph, supported cycle/inversion, and offending driver path.
Test concurrency, callbacks, teardown, and the same applicable Verifier checks.
Separate a demonstrated fix from an unproven contention hypothesis.
## References
- [ERESOURCE locks extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-locks)
- [Deadlock extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-deadlock)
- [Driver Verifier deadlock detection](https://learn.microsoft.com/windows-hardware/drivers/devtest/deadlock-detection)
- [Thread inspection](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-thread)
## Feedback
Follow `FEEDBACK.md` and report reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-kernel-lock-deadlock-triage` and the package version from `plugin.json`; no
automatic dump, lock-history transcript, or driver-source upload.

View File

@@ -0,0 +1,107 @@
---
name: windbg-kernel-verifier-triage
description: 'Use when a kernel dump contains Driver Verifier violations; inspect flags, bugcheck subcodes, and available I/O shadow state. Not for Application Verifier user-mode stops or inferring a violation from enabled flags alone.'
---
# Driver Verifier Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Scope
Driver Verifier checks kernel driver contracts. Application Verifier is a
different user-mode facility; use `windbg-user-heap-corruption-investigation` for its heap
stops. Enabled Driver Verifier flags alone do not prove a contract violation.
Use this skill when a verifier-class bugcheck or analysis identifies an actual
violation. Examples include `0xC4`, `0xC9`, and `0xE6`; inspect the exact code
and parameters rather than treating every stop as the same family.
## Workflow
### 1. Preserve code, subcode, and active configuration
```text
!analyze -v
.bugcheck
!verifier
k
```
Record the bugcheck, subtype/subcode, offending operation and driver when
reported, enabled checks, target build, and evidence availability. Decode each
subcode against its documented contract. Existing output may be incomplete in
a small dump; do not discard captured evidence merely because live
configuration is now different.
### 2. Decode available I/O history
When the violation supplies an appropriate IRP address and I/O verification
state is available:
```text
!iovirp <irp-address>
!irp <irp-address>
```
Shadow state may preserve information lost from the live request. Correlate it
with the decoded contract and use `windbg-kernel-irp-lifecycle-triage` for completion,
cancellation, pending state, and ownership.
### 3. Recover context or follow dependencies
- Saved exception/trap context: `windbg-kernel-bugcheck-triage`.
- Lock-order evidence: `windbg-kernel-lock-deadlock-triage`.
- Outstanding or power request: `windbg-kernel-irp-lifecycle-triage`.
Avoid cyclic dispatch. Carry the evidence already collected to the next skill;
re-enter only when a distinct evidence requirement exists.
### 4. Investigate uncovered violations
For a generic DDI violation, identify the exact precondition (IRQL, lifetime,
parameters, or ownership) and the driver call that broke it. For a DMA violation,
inspect supported adapter/map/unmap and buffer-lifetime evidence for that
subcode. This package does not provide a specialized decoder for every DDI or
DMA case; state the gap and continue from documentation and driver source.
## Controlled repro
Do not enable Driver Verifier without approval. It can deliberately crash the
system and expose boot-critical defects. Use a recoverable test machine, save
the current configuration, select relevant vendor drivers/checks, and agree on
rollback before restarting. Do not verify every installed driver by default.
Read-only configuration inspection on a test machine:
```text
verifier /querysettings
```
`verifier /reset` clears settings and normally requires a restart to stop
verification; it is a configuration change, not a harmless query. Restore
previous intentional settings rather than unconditionally clearing them.
## Validation
Name the exact violated contract, link the recorded operation to driver source,
and test that the remedy satisfies it under the same checks and workload.
Record dump/verification limitations and unverified assumptions. Passing a
single repro is not proof that every driver path is safe.
## References
- [Driver Verifier](https://learn.microsoft.com/windows-hardware/drivers/devtest/driver-verifier)
- [Verifier extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-verifier)
- [I/O verifier IRP extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-iovirp)
- [0xC4 verifier violation](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-0xc4--driver-verifier-detected-violation)
## Feedback
Follow `FEEDBACK.md` and submit reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-kernel-verifier-triage` and the package version from `plugin.json`; do not
automatically upload dumps or proprietary driver source.

View File

@@ -0,0 +1,98 @@
---
name: windbg-user-exception-triage
description: 'Use when a native C/C++ app, service, or user-mode driver host (including UMDF) crashes with a structured exception in a dump or WinDbg session, including native faults inside managed processes. Not for managed .NET exceptions, WinUI/XAML app errors, or kernel bugchecks.'
---
# User-Mode Exception Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## When to use
Start here for access violations, heap corruption, stack overflow, fail-fast,
breakpoints, and other structured exceptions in a native application, service,
or user-mode driver host process dump. This includes UMDF driver failures that
occur in their user-mode host. Confirm
the dump type from WinDbg; the filename extension alone does not distinguish
user-mode from kernel-mode dumps.
## Workflow
### 1. Establish the exception context
```text
.exr -1
.ecxr
k
!analyze -v
```
Record the exception code, address, parameters, access type, registers, module,
and stack. `.ecxr` selects the saved exception context when available. If no
exception context was captured, report that limitation rather than treating the
currently selected thread as the faulting thread.
Use matching binaries and PDBs for your modules and public Windows symbols.
Investigate mismatches or truncated stacks before naming a failing source line.
### 2. Classify and choose an available investigation
| Evidence | Next step |
|---|---|
| `0xC0000005` with allocation/free or overrun evidence | `windbg-user-heap-corruption-investigation` |
| `0xC0000374` heap corruption | `windbg-user-heap-corruption-investigation` |
| `0xC0000017`, `0x8007000E`, or an allocation-failure path | `windbg-user-virtual-memory-exhaustion` |
| Lock/unlock failure following coroutine suspension | `windbg-user-mutex-held-across-co-await` |
| A TTD recording is available and earlier mutation is in question | `windbg-user-ttd-reverse-debugging-triage` |
| No crash exception and evidence of blocked work | `windbg-user-wait-chain-analysis` |
| A kernel dump reports a bugcheck | `windbg-kernel-bugcheck-triage` |
Do not classify every address in a heap range as a lifetime bug. Check access
type, faulting instruction, object layout, and valid allocation boundaries.
### 3. Investigate families without a dedicated skill
- **Access violation without a match:** identify the read/write/execute target,
object/register used, and whether bounds, ownership, or synchronization was
violated. Distinguish a null pointer from stale or corrupted state.
- **`0xC0000409` / fail-fast:** inspect exception parameters and the documented
fast-fail subcode, then the failing condition and call path. The historical
status name alone does not prove a buffer overrun or rule one out. Not every
fast-fail carries an HRESULT.
- **`0xC00000FD` / stack overflow:** inspect stack bounds and frame sizes; test
recursion, reentrancy, large frames, and inability to commit stack growth.
Use the memory-exhaustion skill when commit evidence supports that branch.
- **`0xE06D7363` / MSVC C++ exception:** establish whether it was handled,
identify the throw/catch path with available symbols, and inspect the
exception information supported by the runtime/version. A first-chance throw
is not automatically a defect. This package does not decode thrown-object
layouts or fully diagnose `noexcept`/termination behavior.
- **Stowed/WinRT exceptions:** preserved error information can precede the
final failure. Correlate its originating stack and nested errors with the
application; this package does not include a XAML extension workflow.
- **Illegal instruction or breakpoint:** distinguish CPU/architecture or
code-corruption hypotheses from intentional assertions/debug breaks.
## Validation
- Exception context and code are established, or their absence is stated.
- Faulting instruction and relevant object/register agree with the hypothesis.
- Alternatives are tested against evidence, not just stack names.
- Missing memory, symbols, and specialized exception coverage are explicit.
- The proposed fix addresses a demonstrated invariant and has a repro/test plan.
## References
- [Exception context](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-ecxr--display-exception-context-record-)
- [Exception record](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-exr--display-exception-record-)
- [Controlling exceptions and events](https://learn.microsoft.com/windows-hardware/drivers/debugger/controlling-exceptions-and-events)
## Feedback
For this skill, follow the plugin's `FEEDBACK.md` and report a reviewed, sanitized
issue to [WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-exception-triage` and the package version from `plugin.json`; do not
upload dumps or private source automatically.

View File

@@ -0,0 +1,124 @@
---
name: windbg-user-heap-corruption-investigation
description: 'Use when an app, service, or user-mode driver host heap fails or Application Verifier detects corruption; inspect history and bounds. Not for kernel pool corruption or ordinary OOM.'
---
# Heap Corruption Investigation
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection and limits
Look for `STATUS_HEAP_CORRUPTION` (`0xC0000374`), Application Verifier stops,
or failures in heap allocate/free/reallocate paths in an application, service,
or user-mode driver host such as an UMDF host process. A crash inside the allocator
may be the first detection of an earlier bad write, not the faulty operation.
Distinguish corruption from allocation failure; for the latter use
`windbg-user-virtual-memory-exhaustion`.
Allocation/free history depends on how the process was instrumented and which
pages were captured. A missing history is a limitation, not proof of a leak or
use-after-free.
## Workflow
### 1. Decode the stop
```text
.exr -1
.ecxr
!analyze -v
k
```
Record the stop reason, corrupted block, corruption address, and the operation
that detected the damage. If a verifier stop frame has parameter/local symbols,
select it with `.frame /r <frame>` and inspect `dv`; otherwise use the captured
stop output and the documented stop definition. Do not assume one fixed
parameter layout or a stop code shared by all verifier versions.
### 2. Recover available block history
```text
!heap -p -a <address>
!avrf -hp -a <address>
```
The first command inspects a Page Heap allocation; the second searches available
Application Verifier heap-operation history. Use `!heap -?` and `!avrf -?` to
confirm support in the installed extension. On an uninstrumented dump these
commands may not recover the history needed to identify the writer.
Capture allocation and free stacks when present. Check the address is inside
the user allocation rather than a header or neighboring block.
### 3. Test competing explanations
| Hypothesis | Evidence to seek |
|---|---|
| Use-after-free | Confirmed free before a later access through a retained reference |
| Double-free | Two ownership/completion paths freeing the same allocation |
| Overrun/underrun | A write outside the allocated user bounds |
| Wild write | Corrupted header or payload and a writer with an invalid target |
| Allocation/free contract mismatch | Different allocator/deallocator or incorrect owning heap |
Inspect bytes with `db <address> L<size>` and disassembly around the access.
Fill patterns and plausible pointers are clues, not causal proof. Correlate with
source, history, or a repro and trace the ownership transition.
### 4. Obtain stronger evidence if necessary
With user approval, enable full Page Heap for a named test executable:
```text
gflags /p /enable target.exe /full
```
Restart that process and reproduce under the debugger. Application Verifier
heap checks can also be configured for that test executable. Explain memory
overhead, timing changes, and potential deliberate stops before doing this.
Record the previous settings and restore them when finished; if Page Heap was
newly enabled for this test, disable it with:
```text
gflags /p /disable target.exe
```
Do not change an existing application's verification policy without approval.
If a user-mode TTD trace is available, use `windbg-user-ttd-reverse-debugging-triage` to
find the relevant mutation or free.
## Fix patterns
- Enforce the actual lifetime contract with ownership types or explicit
acquire/release rules. Shared ownership is appropriate only when the design
genuinely has multiple owners.
- Synchronize shared state separately: `shared_ptr` ownership does not make a
concurrently modified cache or pointed-to object thread-safe.
- Size buffers and check arithmetic, lengths, and terminators; use bounds-aware
containers where appropriate.
- Keep allocation and deallocation compatible across DLL/API boundaries.
## Validation
Establish the affected block and supported corruption class, name the path that
violated bounds or ownership, and distinguish the detector from the writer.
Exercise the fix with the same instrumentation and relevant concurrency/load.
Report unresolved writer history rather than presenting a guessed fix as proven.
## References
- [Application Verifier stop definitions](https://learn.microsoft.com/windows-hardware/drivers/devtest/application-verifier-stop-codes-and-definitions)
- [Heap extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-heap)
- [Application Verifier extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-avrf)
- [GFlags and Page Heap](https://learn.microsoft.com/windows-hardware/drivers/debugger/gflags-and-pageheap)
## Feedback
Follow `FEEDBACK.md` and report reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-heap-corruption-investigation` and the package version from
`plugin.json`; no automatic dump, source, or transcript upload.

View File

@@ -0,0 +1,86 @@
---
name: windbg-user-mutex-held-across-co-await
description: 'Use when app, service, or user-mode driver C++ coroutine code holds a thread-affine lock across suspension and later hangs or fails. Not for all coroutine crashes or choosing lock performance.'
---
# Mutex Held Across co_await
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection
This pattern can occur in native application, service, or user-mode driver
code, including UMDF components that use C++ coroutines. Look for a lock
acquired before `co_await` and released after resumption or
coroutine destruction. Mutex ownership belongs to the acquiring thread, not
the coroutine frame. A resumption on another thread can violate that contract.
Even same-thread resumption can create reentrancy or progress problems when
the awaited operation needs a lock the coroutine still holds.
## Workflow
1. Identify the exact lock primitive and acquisition/release scope in source.
Audit every suspension point while the RAII guard or ownership is alive.
2. Establish the acquire and resume threads using trace/source evidence.
Standard mutexes and SRW locks do not provide a universally queryable owner
field; do not fabricate an owning TID from undocumented layouts.
3. Verify the awaiter's resumption contract. C++/WinRT can preserve apartment
context for particular awaitables; `resume_background` intentionally switches.
Do not assume every WinRT awaitable always resumes on a worker or always on
the originating thread.
4. Distinguish wrong-thread release, a dependency cycle, state changed during
suspension, lifetime failure, and unrelated memory corruption.
5. Move the thread-affine lock into synchronous scopes. Revalidate relevant
state after the await rather than treating the pre-await snapshot as current.
If the symptom is general blocking use `windbg-user-wait-chain-analysis`. For damaged
heap objects use `windbg-user-heap-corruption-investigation`. If a recording is available,
`windbg-user-ttd-reverse-debugging-triage` can help establish the ownership timeline.
## Fix pattern
Conceptual sequence, not a promise about any particular scheduler:
```text
under lock:
take a snapshot and its generation
release lock
await work using that snapshot
under lock on the resumed thread:
revalidate generation, lifetime, and assumptions
apply result or explicitly handle a stale/cancelled operation
release lock
```
Use RAII for each synchronous scope. If invariants cannot tolerate unlocking,
redesign the operation or use a specifically designed asynchronous coordination
primitive with cancellation/lifetime rules. Switching to a recursive mutex or
`shared_mutex` does not make a thread-affine lock coroutine-safe.
Do not recommend a blanket mutex-type replacement. Shared locking is a separate
design decision; changing the primitive does not repair suspension ownership.
Keep the object and any captured interfaces alive across asynchronous work.
## Validation
- No thread-affine lock ownership survives a suspension in the corrected path.
- Each awaiter's thread/apartment contract is understood.
- State invariants are revalidated after suspension.
- Cancellation, concurrent mutation, shutdown, and failed awaited work are tested.
- The remedy removes the demonstrated cause, not just an observed exception.
## References
- [Holding a lock across coroutine suspension](https://devblogs.microsoft.com/oldnewthing/20210707-00/?p=105417)
- [C++/WinRT concurrency and asynchronous operations](https://learn.microsoft.com/windows/uwp/cpp-and-winrt-apis/concurrency)
- [Slim reader/writer locks](https://learn.microsoft.com/windows/win32/sync/slim-reader-writer--srw--locks)
## Feedback
Follow `FEEDBACK.md` and report reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-mutex-held-across-co-await` and the package version from `plugin.json`;
no automatic source, dump, or transcript upload.

View File

@@ -0,0 +1,105 @@
---
name: windbg-user-ttd-reverse-debugging-triage
description: 'Use when an app, service, or user-mode driver host TTD recording is available and earlier calls, writes, or lifetimes matter. Not for kernel replay or history from a normal dump.'
---
# TTD Reverse Debugging Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Requirements and scope
Time Travel Debugging records a user-mode process for replay, including an
authorized application, service, or user-mode driver host process. A dump alone
contains no execution timeline. Confirm a valid recording and matching module
symbols before attempting timeline queries. It does not record kernel execution
or automatically include another process's server-side activity.
Recording can change timing, require substantial storage, and capture sensitive
memory. Obtain authorization before capture. Check the installed recorder's help
for supported target, architecture, and options. WinDbg's **Launch executable
(advanced)** / **Record with Time Travel Debugging** flow can record a named
test application without guessing a recorder command.
## Workflow
### 1. Open and index the recording
Open the recorded `.run` file in WinDbg and load public Windows symbols and
matching PDBs for your own binaries.
```text
!tt.index
dx @$cursession.TTD
```
Confirm the timeline range. Indexing and data-model availability depend on
WinDbg/TTD versions; consult the installed help if the command is unavailable.
### 2. Ask a bounded history question
```text
dx @$cursession.TTD.Calls("MyModule!MyFunction")
dx @$cursession.TTD.Memory(<start-address>, <end-address>, "w")
```
Query the known function or exact memory range, then inspect relevant results
and their timeline positions. An empty result can mean unmatched symbols,
uninstrumented execution, or an out-of-range query, not proof of absence.
Use the call query to find allocation/free or module lifetime transitions and
the memory query to locate candidate writes. Account for allocator reuse: the
same virtual address may represent different objects over the recording.
### 3. Seek and inspect state
```text
!tt <position>
k
r
g-
```
Seek to an actual position returned by the query. `g-` continues backward;
use the installed reverse-step controls to refine the search. Capture the
last-good and first-bad states, writer/caller stack, and ownership transition.
Do not equate the last write with the bug until you establish the object's
identity, valid lifetime, intended invariant, and relevant cross-thread order.
### 4. Continue with a shipped investigation
| Evidence | Skill |
|---|---|
| Bad free/write or allocation-boundary violation | `windbg-user-heap-corruption-investigation` |
| Growing allocation/reservation usage | `windbg-user-virtual-memory-exhaustion` |
| Lock survives coroutine suspension | `windbg-user-mutex-held-across-co-await` |
| Blocker or cross-process dependency at the selected moment | `windbg-user-wait-chain-analysis` |
For other user-mode families continue reasoning from the timeline rather than
dispatching to absent skills. For a kernel crash use `windbg-kernel-bugcheck-triage`;
TTD is not a kernel-history substitute.
## Validation
Record the question, trace identity, timeline positions, relevant object
lifetime, and source/stack evidence. Test alternatives and state recording
boundaries. A reproducible timeline proves what occurred in that recording;
it does not establish that instrumentation preserved all production timing.
## References
- [Time Travel Debugging overview](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/time-travel-debugging-overview)
- [TTD data-model queries](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/time-travel-debugging-object-model)
- [TTD extension commands](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/time-travel-debugging-extension-commands)
## Feedback
Follow `FEEDBACK.md` and report a reviewed summary to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-ttd-reverse-debugging-triage` and the package version from
`plugin.json`; never automatically upload a recording or its memory/query
contents.

View File

@@ -0,0 +1,113 @@
---
name: windbg-user-virtual-memory-exhaustion
description: 'Use when a native app, service, or user-mode driver host allocation fails; distinguish VA exhaustion, fragmentation, and commit pressure. Not for managed .NET heap growth, proving a leak from one snapshot, or corruption.'
---
# Virtual Memory Exhaustion
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection
Investigate `E_OUTOFMEMORY` (`0x8007000E`), `STATUS_NO_MEMORY` (`0xC0000017`),
`bad_alloc`, or failed heap/virtual allocations in an application, service, or
user-mode driver host (including UMDF). Record the actual API, requested
size/alignment, architecture, flags, and error. Free physical RAM does not rule
out insufficient virtual address space, commit pressure, or applicable limits.
## Workflow
### 1. Examine the process VA map
```text
!address -summary
!address
!heap -s
```
Compare available regions with the attempted allocation's contiguous range and
alignment requirements. Distinguish reserved, committed, free, image, mapped,
stack, and heap ranges. A large reservation consumes VA without committing its
entire range. Heap internals may require more than the user's requested bytes.
Report unavailable pages/map data rather than inferring completeness from a
limited dump.
### 2. Separate pressure mechanisms
| Mechanism | Evidence needed |
|---|---|
| VA exhaustion | Process address range/architecture and little usable free VA |
| Fragmentation | Free space exists, but no suitable contiguous/aligned region |
| System commit pressure | Commit usage/limit near the failure, not just free RAM |
| Process/job memory limit | Actual configured limit and relevant usage/accounting |
| Allocation policy/API failure | API-specific constraints, flags, or allocator policy |
Use contemporaneous system memory counters or an appropriate live/kernel
session for system commit data. A process PEB is not a documented
`MaximumCommit` source. A process's committed bytes alone do not establish a
system-wide or job limit.
For 32-bit targets inspect `/LARGEADDRESSAWARE` and the host architecture;
2 GB versus up to 4 GB depends on those settings. Verify current documented
limits for the target Windows version and architecture instead of applying
one 64-bit limit to every system.
### 3. Identify dominant consumers
```text
!address -f:Heap
!address -f:Stack
!heap -stat -h <heap-address>
```
Use `!address -?` and `!heap -?` for allocator/version-specific support.
Classify dominant heaps, stacks, mappings, images, and reserved arenas.
Large or numerous allocations are not automatically leaks: map them to cache
policy, owners, workload, and expected lifetimes.
### 4. Establish growth with history
Collect authorized time-series counters, repeated comparable snapshots, or
allocation/free tracing across the workload. Compare warm-up with steady-state
behavior and verify whether memory is reclaimed when work finishes.
One snapshot plus process uptime cannot prove a leak rate. For a suitable
user-mode recording use `windbg-user-ttd-reverse-debugging-triage`; for damaged allocations
use `windbg-user-heap-corruption-investigation` instead.
## Fix patterns
- Bound caches by an appropriate size/cost policy and verify eviction.
Define the lifetime of any references returned before eviction.
- Match `VirtualAlloc` reservations with the correct `VirtualFree` release
contract; distinguish decommit from release.
- Use RAII to release resources on all supported exit/error paths.
- Reduce large contiguous allocation requirements where the design permits.
- Do not blindly increase limits or stack reservations before finding the
pressure source, and do not convert a failed allocation into a silent success.
## Validation
Name the failing allocation and pressure mechanism, identify the consumer with
evidence, and exercise the remedy through warm-up, sustained load, and cleanup.
Verify memory remains bounded or the intended allocation succeeds under the
required constraints. Document configured system/job limits separately.
## References
- [Address extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-address)
- [Heap extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-heap)
- [Windows memory limits](https://learn.microsoft.com/windows/win32/memory/memory-limits-for-windows-releases)
- [Large-address-aware linker option](https://learn.microsoft.com/cpp/build/reference/largeaddressaware-handle-large-addresses)
- [VirtualFree](https://learn.microsoft.com/windows/win32/api/memoryapi/nf-memoryapi-virtualfree)
## Feedback
Follow `FEEDBACK.md` and submit reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-virtual-memory-exhaustion` and the package version from `plugin.json`;
no automatic dump or memory-content upload.

View File

@@ -0,0 +1,116 @@
---
name: windbg-user-wait-chain-analysis
description: 'Use when an app, service, or user-mode driver host is unresponsive on locks, COM/RPC, I/O, or another process; follow the blocker chain. Not for a crash solely from an exception stack.'
---
# Cross-Process Wait Chain Analysis
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection
Look for blocked work in an application, service, or user-mode driver host
(including UMDF), and threads in wait, COM, RPC, or I/O paths.
The process displaying the symptom may not own the underlying defect.
Idle worker threads waiting normally are not evidence of a hang.
## Workflow
### 1. Identify the affected operation and its thread
```text
.lastevent
~*kb
!runaway
```
Confirm why the dump was collected. A dump is a snapshot; `.lastevent` does not
by itself certify "hang" or "no crash." Identify the UI/serving thread from
application evidence instead of assuming thread zero is always the UI thread.
If work is spinning rather than blocked, collect appropriate CPU evidence.
### 2. Identify each wait and its owner
Inspect frames around `WaitForSingleObject`, `WaitForMultipleObjects`, COM
send/receive, and RPC calls. Use matching symbols/source for your own proxy,
interface, and server registration to determine what was requested.
For each edge record:
```text
process / thread -> waited resource or request -> owner / serving thread
```
Do not guess a server PID from undocumented private COM layouts. Use available
Wait Chain Traversal, RPC/COM tracing, application correlation IDs, or
registration/process information, and explicitly mark unresolved edges.
### 3. Gather corresponding server evidence
Obtain authorized dumps or live state of the relevant server processes close
enough in time to represent the same operation. Inspect their serving threads.
For kernel context use documented commands such as:
```text
!process 0 7
!thread <ethread>
```
Available user pages and symbol/context support vary by dump type. If the chain
ends in a kernel lock use `windbg-kernel-lock-deadlock-triage`; if blocked I/O is supported
by IRP evidence use `windbg-kernel-irp-lifecycle-triage`. Do not promise process heaps or
user stacks absent from the dump.
### 4. Distinguish a cycle from a slow or missing responder
- **Cycle:** show every required wait/owner edge back to the starting actor.
- **Contention:** a runnable owner may eventually release the resource.
- **Starvation:** queued work cannot obtain execution capacity.
- **Lost completion:** the actor/event expected to unblock the waiter no
longer exists or no path signals it.
- **Slow server:** the endpoint is doing work, blocked on another dependency,
or looping; gather its evidence before blaming the client.
Multiple snapshots or tracing may be needed to distinguish transient waits
from persistent blocking.
## Fix patterns and COM boundaries
A synchronous COM call from an STA can pump messages and permit reentrancy.
It is not automatically a deadlock. Investigate locks held across calls,
callbacks, apartment access, and any non-pumping waits that form an actual
dependency cycle.
Possible remedies include asynchronous APIs, shorter lock scopes, moving
destruction/cross-process calls outside critical sections, and bounded
wait/cancellation protocols where the API supports them. A timeout on the
caller does not cancel server work by itself.
If work moves to another apartment, marshal apartment-bound interfaces, keep
captured state alive, and dispatch UI updates to the correct thread. Merely
capturing a COM pointer and `this` in a worker lambda is not a safe fix.
## Validation
Identify the affected thread, relevant resources and owners, and demonstrated
cycle or deepest supported blocker. Test the proposed remedy under concurrency,
reentrancy, shutdown, and timeout/cancellation. Do not stop at "waiting in RPC."
If the server dump or an owner edge is missing, state the unresolved hypothesis.
## References
- [Wait Chain Traversal](https://learn.microsoft.com/windows/win32/debug/wait-chain-traversal)
- [Processes, threads, and COM apartments](https://learn.microsoft.com/windows/win32/com/processes--threads--and-apartments)
- [Process inspection](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-process)
- [Thread inspection](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-thread)
## Feedback
Follow `FEEDBACK.md` and submit only reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-wait-chain-analysis` and the package version from `plugin.json`; no
automatic capture or public upload of process dumps or full diagnostic
transcripts.

View File

@@ -0,0 +1,271 @@
// Validates the three host catalogs:
// .github/plugin/marketplace.json (GitHub Copilot)
// .claude-plugin/marketplace.json (Claude Code)
// .agents/plugins/marketplace.json (OpenAI Codex)
//
// - All three list the same plugins, from the same repo at the same pinned commit.
// - Every entry resolves: the repo, commit, path, and the host's plugin manifest
// exist, and the manifest's name and version match the catalog.
// Local entries (./path in this repo) are checked against the working tree.
// Set GITHUB_TOKEN to avoid API rate limits. CATALOG_ROOT points the check at
// another tree (used by scripts/tests/test-catalog-tools.mjs).
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const repoRoot = process.env.CATALOG_ROOT
? path.resolve(process.env.CATALOG_ROOT)
: path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
const errors = [];
const fail = (msg) => errors.push(msg);
const SEMVER = /^\d+\.\d+\.\d+$/;
const SHA = /^[0-9a-f]{40}$/;
const AGENT_PLUGINS_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json";
// Manifest lookup order per host. `portable` entries only count when the file
// declares the Agent Plugins schema.
const hosts = {
copilot: {
file: ".github/plugin/marketplace.json",
// Copilot accepts a manifest at the plugin root or in a host folder.
manifests: ["plugin.json", ".github/plugin/plugin.json", ".claude-plugin/plugin.json"],
catalogVersion: (c) => c.metadata?.version,
},
claude: {
file: ".claude-plugin/marketplace.json",
manifests: [".claude-plugin/plugin.json"],
catalogVersion: (c) => c.version,
},
codex: {
file: ".agents/plugins/marketplace.json",
// openai/codex utils/plugins/src/plugin_namespace.rs: a portable root
// plugin.json first, then the legacy host folders.
manifests: [{ file: "plugin.json", portable: true }, ".codex-plugin/plugin.json", ".claude-plugin/plugin.json"],
catalogVersion: () => undefined,
},
};
function readJson(file) {
try {
return JSON.parse(fs.readFileSync(path.join(repoRoot, file), "utf8"));
} catch (e) {
fail(`${file}: cannot read JSON (${e.message})`);
return {};
}
}
const trimSlashes = (p) => (p ?? "").replace(/^\.?\/+/, "").replace(/\/+$/, "");
function repoFromUrl(url) {
const m = /^https:\/\/github\.com\/([^/]+\/[^/]+?)(?:\.git)?\/?$/i.exec(url ?? "");
return m ? m[1] : undefined;
}
// Normalize a host-specific source into { kind: "local", path } or
// { kind: "remote", repo, path, sha, ref }.
function normalizeSource(src) {
if (typeof src === "string") {
return src.startsWith("./") ? { kind: "local", path: trimSlashes(src) } : { kind: "unknown", raw: src };
}
if (!src || typeof src !== "object") return { kind: "unknown", raw: src };
switch (src.source) {
case "local":
return { kind: "local", path: trimSlashes(src.path) };
case "github":
return { kind: "remote", repo: src.repo, path: trimSlashes(src.path), sha: src.sha, ref: src.ref };
case "url":
case "git-subdir":
return { kind: "remote", repo: repoFromUrl(src.url), path: trimSlashes(src.path), sha: src.sha ?? src.rev, ref: src.ref };
default:
return { kind: "unknown", raw: src };
}
}
async function gh(url) {
const headers = { "User-Agent": "win-dev-skills-catalog-check", Accept: "application/vnd.github+json" };
if (token) headers.Authorization = `Bearer ${token}`;
for (let attempt = 1; ; attempt++) {
const res = await fetch(url, { headers });
if (res.status < 500 || attempt === 3) return res;
await new Promise((r) => setTimeout(r, 1000 * attempt));
}
}
const commitCache = new Map();
async function commitExists(repo, sha) {
const key = `${repo}@${sha}`;
if (!commitCache.has(key)) {
commitCache.set(key, gh(`https://api.github.com/repos/${repo}/commits/${sha}`).then((r) => r.status));
}
return commitCache.get(key);
}
async function readRemoteFile(repo, sha, file) {
const res = await gh(`https://api.github.com/repos/${repo}/contents/${file}?ref=${sha}`);
if (res.status === 404) return undefined;
if (!res.ok) throw new Error(`GET ${repo}/${file}@${sha}: HTTP ${res.status}`);
const body = await res.json();
if (Array.isArray(body)) return { dir: true };
return { text: Buffer.from(body.content, "base64").toString("utf8") };
}
function readLocalFile(file) {
const full = path.join(repoRoot, file);
if (!fs.existsSync(full)) return undefined;
if (fs.statSync(full).isDirectory()) return { dir: true };
return { text: fs.readFileSync(full, "utf8") };
}
async function checkEntry(host, entry, src, expectedVersion) {
const where = `${hosts[host].file} → ${entry.name}`;
const read = src.kind === "local"
? async (f) => readLocalFile(f)
: async (f) => readRemoteFile(src.repo, src.sha, f);
const label = src.kind === "local" ? `./${src.path}` : `${src.repo}/${src.path}@${src.sha.slice(0, 12)}`;
const root = src.path ? await read(src.path) : { dir: true };
if (!root?.dir) return fail(`${where}: path '${src.path}' not found in ${label}`);
let manifest;
let manifestFile;
for (const candidate of hosts[host].manifests) {
const rel = typeof candidate === "string" ? candidate : candidate.file;
manifestFile = src.path ? `${src.path}/${rel}` : rel;
const file = await read(manifestFile);
if (file?.text) {
let parsed;
try {
parsed = JSON.parse(file.text);
} catch (e) {
return fail(`${where}: ${manifestFile} is not valid JSON (${e.message})`);
}
if (candidate.portable && parsed.$schema !== AGENT_PLUGINS_SCHEMA) continue;
manifest = parsed;
break;
}
}
if (!manifest) {
const names = hosts[host].manifests.map((c) => (typeof c === "string" ? c : c.file));
return fail(`${where}: no plugin manifest (${names.join(", ")}) under ${label}`);
}
let ok = true;
if (manifest.name !== entry.name) {
ok = false;
fail(`${where}: manifest ${manifestFile} has name '${manifest.name}', catalog says '${entry.name}'`);
}
if (manifest.version !== expectedVersion) {
ok = false;
fail(`${where}: manifest ${manifestFile} has version '${manifest.version}', catalog says '${expectedVersion}'`);
}
if (ok) console.log(`ok ${host.padEnd(7)} ${entry.name}@${manifest.version} ← ${label} (${manifestFile})`);
}
const catalogs = Object.fromEntries(Object.entries(hosts).map(([h, cfg]) => [h, readJson(cfg.file)]));
// One catalog name everywhere, so `<plugin>@<catalog>` works on every host.
const catalogNames = new Set(Object.values(catalogs).map((c) => c.name));
if (catalogNames.size !== 1) {
fail(`Catalog names differ across hosts: ${Object.entries(catalogs).map(([h, c]) => `${h}=${c.name}`).join(", ")}`);
}
// Catalog-level version: Copilot and Claude carry one; keep them in sync.
const catalogVersions = ["copilot", "claude"].map((h) => hosts[h].catalogVersion(catalogs[h]));
if (!catalogVersions.every((v) => typeof v === "string" && SEMVER.test(v))) {
fail(`Catalog version must be X.Y.Z in ${hosts.copilot.file} (metadata.version) and ${hosts.claude.file} (version); got ${catalogVersions.join(", ")}`);
} else if (catalogVersions[0] !== catalogVersions[1]) {
fail(`Catalog versions differ: Copilot ${catalogVersions[0]}, Claude ${catalogVersions[1]}`);
}
// Index entries by name per host.
const byHost = {};
for (const host of Object.keys(hosts)) {
const plugins = catalogs[host].plugins;
if (!Array.isArray(plugins)) {
fail(`${hosts[host].file}: plugins must be an array`);
byHost[host] = new Map();
continue;
}
byHost[host] = new Map();
for (const entry of plugins) {
if (byHost[host].has(entry.name)) fail(`${hosts[host].file}: duplicate plugin '${entry.name}'`);
byHost[host].set(entry.name, entry);
}
}
const allNames = new Set(Object.values(byHost).flatMap((m) => [...m.keys()]));
const checks = [];
for (const name of [...allNames].sort()) {
const missing = Object.keys(hosts).filter((h) => !byHost[h].has(name));
if (missing.length) {
fail(`Plugin '${name}' is missing from: ${missing.map((h) => hosts[h].file).join(", ")}`);
continue;
}
const errorsBefore = errors.length;
const version = byHost.copilot.get(name).version;
if (typeof version !== "string" || !SEMVER.test(version)) {
fail(`${hosts.copilot.file} → ${name}: version must be X.Y.Z, got '${version}'`);
}
if (byHost.claude.get(name).version !== version) {
fail(`Plugin '${name}': Claude catalog version '${byHost.claude.get(name).version}' != Copilot catalog version '${version}'`);
}
const sources = Object.fromEntries(Object.keys(hosts).map((h) => [h, normalizeSource(byHost[h].get(name).source)]));
for (const [h, s] of Object.entries(sources)) {
if (s.kind === "unknown") fail(`${hosts[h].file} → ${name}: unsupported source ${JSON.stringify(s.raw)}`);
if (s.kind === "remote") {
if (!s.repo) fail(`${hosts[h].file} → ${name}: remote source must be a github.com repository`);
if (!SHA.test(s.sha ?? "")) fail(`${hosts[h].file} → ${name}: remote source must pin a full 40-character commit sha`);
}
}
const kinds = new Set(Object.values(sources).map((s) => s.kind));
if (kinds.size > 1) {
fail(`Plugin '${name}': hosts disagree on local vs remote source`);
continue;
}
if (kinds.has("remote")) {
const pins = new Set(Object.values(sources).map((s) => `${(s.repo ?? "").toLowerCase()}@${s.sha}`));
if (pins.size > 1) {
fail(`Plugin '${name}': hosts pin different repos/commits: ${[...pins].join(", ")}`);
continue;
}
const refs = new Set(Object.values(sources).map((s) => s.ref ?? ""));
if (refs.size > 1) {
fail(`Plugin '${name}': hosts use different refs: ${[...refs].map((r) => r || "(none)").join(", ")}`);
continue;
}
}
if (errors.length > errorsBefore) continue;
if (kinds.has("remote")) {
const { repo, sha, ref } = sources.copilot;
checks.push((async () => {
const status = await commitExists(repo, sha);
if (status !== 200) return fail(`Plugin '${name}': commit ${repo}@${sha} not found (HTTP ${status})`);
if (ref) {
// A ref (normally a release tag) must still point at the pinned commit.
const res = await gh(`https://api.github.com/repos/${repo}/commits/${encodeURIComponent(ref)}`);
const resolved = res.ok ? (await res.json()).sha : undefined;
if (resolved !== sha) {
return fail(`Plugin '${name}': ref '${ref}' in ${repo} resolves to ${resolved ?? `nothing (HTTP ${res.status})`}, but the catalogs pin ${sha}`);
}
}
await Promise.all(Object.entries(sources).map(([h, s]) =>
checkEntry(h, byHost[h].get(name), s, version).catch((e) => fail(`${hosts[h].file} → ${name}: ${e.message}`))));
})().catch((e) => fail(`Plugin '${name}': ${e.message}`)));
} else {
for (const [h, s] of Object.entries(sources)) {
checks.push(checkEntry(h, byHost[h].get(name), s, version).catch((e) => fail(`${hosts[h].file} → ${name}: ${e.message}`)));
}
}
}
await Promise.all(checks);
if (errors.length) {
for (const e of errors) console.log(`::error::${e}`);
process.exitCode = 1;
} else {
console.log(`All ${allNames.size} plugin(s) resolve and match across the three catalogs.`);
}

View File

@@ -0,0 +1,6 @@
{
"name": "fixture",
"plugins": [
{ "name": "sample", "source": { "source": "local", "path": "./plugins/sample" } }
]
}

View File

@@ -0,0 +1,9 @@
{
"name": "fixture",
"owner": { "name": "Fixture" },
"description": "Local plugin fixture.",
"version": "1.0.0",
"plugins": [
{ "name": "sample", "description": "Sample local plugin.", "version": "1.2.3", "source": "./plugins/sample" }
]
}

View File

@@ -0,0 +1,8 @@
{
"name": "fixture",
"owner": { "name": "Fixture" },
"metadata": { "description": "Local plugin fixture.", "version": "1.0.0" },
"plugins": [
{ "name": "sample", "description": "Sample local plugin.", "version": "1.2.3", "source": "./plugins/sample" }
]
}

View File

@@ -0,0 +1,5 @@
{
"name": "sample",
"version": "1.2.3",
"description": "Sample local plugin."
}

View File

@@ -0,0 +1,6 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "sample",
"version": "1.2.3",
"description": "Sample local plugin."
}

View File

@@ -0,0 +1,8 @@
---
name: sample-skill
description: Sample skill used to test the catalog tooling. Use when testing CI. Not for real work.
---
# Sample skill
This skill exists only to exercise the catalog check and lint.

View File

@@ -0,0 +1,47 @@
// Proves the catalog tooling handles a plugin stored in this repo, using the
// fixture in scripts/tests/fixtures/local-plugin. Needs `npm ci --prefix scripts/vally`.
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";
const here = path.dirname(fileURLToPath(import.meta.url));
const fixture = path.join(here, "fixtures", "local-plugin");
const checkScript = path.join(here, "..", "check-catalogs.mjs");
const lintScript = path.join(here, "..", "vally", "lint-skills.mjs");
let failed = 0;
function expect(label, script, root, wantExit, wantText) {
const r = spawnSync(process.execPath, [script], { env: { ...process.env, CATALOG_ROOT: root }, encoding: "utf8" });
const out = `${r.stdout}${r.stderr}`;
const ok = r.status === wantExit && (!wantText || out.includes(wantText));
console.log(`${ok ? "pass" : "FAIL"} ${label} (exit ${r.status})`);
if (!ok) {
failed++;
console.log(out);
}
}
function mutatedCopy(file, from, to) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "catalog-fixture-"));
fs.cpSync(fixture, dir, { recursive: true });
const target = path.join(dir, file);
fs.writeFileSync(target, fs.readFileSync(target, "utf8").replace(from, to));
return dir;
}
expect("catalog check accepts a local plugin", checkScript, fixture, 0, "ok codex sample@1.2.3 ← ./plugins/sample (plugins/sample/plugin.json)");
expect("vally lints the local plugin", lintScript, fixture, 0, "sample-skill");
const badVersion = mutatedCopy("plugins/sample/.claude-plugin/plugin.json", '"1.2.3"', '"1.2.4"');
expect("catalog check rejects a manifest version mismatch", checkScript, badVersion, 1, "has version '1.2.4'");
const missingCodex = mutatedCopy(".agents/plugins/marketplace.json", '"name": "sample"', '"name": "other"');
expect("catalog check rejects catalogs that disagree", checkScript, missingCodex, 1, "is missing from");
const badSkill = mutatedCopy("plugins/sample/skills/sample-skill/SKILL.md", "name: sample-skill", "name: Not A Valid Name");
expect("vally rejects an invalid skill", lintScript, badSkill, 1);
for (const dir of [badVersion, missingCodex, badSkill]) fs.rmSync(dir, { recursive: true, force: true });
process.exitCode = failed ? 1 : 0;

View File

@@ -0,0 +1,134 @@
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
const repositoryRoot = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
"..",
"..",
);
const validator = path.join(
repositoryRoot,
"plugins",
"windbg",
"skills",
"windbg-diagnostic-method",
"scripts",
"validate-diagnosis-output.ps1",
);
const temporaryDirectory = fs.mkdtempSync(
path.join(os.tmpdir(), "diagnosis-validator-"),
);
const validReport = `## Analysis
Observed evidence.
## Root Cause
Candidate cause.
## Fix
Candidate fix.
## Reasoning Chain
OBSERVE: evidence.
## Alternatives Considered
- Alternative one
- Alternative two
## Trigger Verification
| Evidence | Status |
|---|---|
| Trigger | VERIFIED |
## Mermaid
\`\`\`mermaid
sequenceDiagram
A->>B: request
B-->>A: response
\`\`\`
## Contrarian Verdict
ACCEPTED
contrarian_loopback: false
## JSON Output Contract Summary
\`\`\`json
{"diagnosis_status":"final","routing_path":"validate","root_cause":"cause","confidence":0.8,"fix_confidence":0.7,"fix_code_path_coverage":"symbol-or-disassembly","contrarian_review":"ACCEPTED","contrarian_loopback":false}
\`\`\`
`;
const invalidReport = `## Analysis
The words OBSERVE and VERIFIED appear outside their required sections.
## Root Cause
Candidate cause.
## Fix
Candidate fix.
## Reasoning Chain
No phase marker appears here.
## Alternatives Considered
- Only one alternative
## Trigger Verification
No table appears here.
## Mermaid
\`\`\`mermaid
sequenceDiagram
participant A
\`\`\`
## Contrarian Verdict
ACCEPTED
contrarian_loopback: 1
## JSON Output Contract Summary
\`\`\`json
{"diagnosis_status":"final","routing_path":"validate","root_cause":"cause","confidence":0.8,"fix_confidence":0.7,"fix_code_path_coverage":"symbol-or-disassembly","contrarian_review":"ACCEPTED","contrarian_loopback":1}
\`\`\`
`;
function runValidator(file) {
return spawnSync(
"pwsh",
["-NoProfile", "-File", validator, "-Path", file],
{ encoding: "utf8" },
);
}
try {
const validPath = path.join(temporaryDirectory, "valid.md");
const invalidPath = path.join(temporaryDirectory, "invalid.md");
fs.writeFileSync(validPath, validReport);
fs.writeFileSync(invalidPath, invalidReport);
const validResult = runValidator(validPath);
assert.equal(validResult.status, 0, validResult.stderr || validResult.stdout);
const validOutput = JSON.parse(validResult.stdout);
assert.equal(validOutput.Pass, true);
assert.equal(validOutput.Checks.MermaidDiagram, true);
const invalidResult = runValidator(invalidPath);
assert.equal(invalidResult.status, 1, invalidResult.stderr);
const invalidOutput = JSON.parse(invalidResult.stdout);
assert.equal(invalidOutput.Pass, false);
assert.equal(invalidOutput.Checks.ReasoningChain, false);
assert.equal(invalidOutput.Checks.Alternatives, false);
assert.equal(invalidOutput.Checks.TriggerVerification, false);
assert.equal(invalidOutput.Checks.MermaidDiagram, false);
assert.equal(invalidOutput.Checks.ContrarianVerdict, false);
assert.equal(invalidOutput.Checks.JsonSummary, false);
console.log("Diagnosis validator accepts valid reports and rejects malformed sections.");
} finally {
fs.rmSync(temporaryDirectory, { recursive: true, force: true });
}

View File

@@ -0,0 +1,128 @@
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import { createRequire } from "node:module";
import { fileURLToPath } from "node:url";
const repositoryRoot = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
"..",
);
const pluginRoot = path.join(
repositoryRoot,
"plugins",
"windbg",
);
const require = createRequire(
path.join(repositoryRoot, "scripts", "vally", "package.json"),
);
const { parseDocument } = require("yaml");
const inventory = JSON.parse(
fs.readFileSync(path.join(pluginRoot, "skills.json"), "utf8"),
);
assert.deepEqual(inventory.methodSkills, ["windbg-diagnostic-method"]);
const allowedSkills = [
...inventory.diagnosticSkills,
...inventory.methodSkills,
].sort();
const skillDirectories = fs
.readdirSync(path.join(pluginRoot, "skills"), { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)
.sort();
assert.deepEqual(skillDirectories, allowedSkills);
const allowedUrlHosts = new Set([
"agent-plugins.org",
"devblogs.microsoft.com",
"github.com",
"learn.microsoft.com",
]);
function assertPublicText(text, label) {
for (const match of text.matchAll(/https?:\/\/[^\s<>"'`]+/g)) {
const value = match[0].replace(/[),.;:]+$/, "");
const host = new URL(value).hostname.toLowerCase();
assert.ok(
allowedUrlHosts.has(host),
`${label} references unapproved URL host ${host}`,
);
}
assert.doesNotMatch(
text,
/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i,
`${label} contains an email address`,
);
}
for (const skill of skillDirectories) {
const relativePath = path.join("skills", skill, "SKILL.md");
const text = fs.readFileSync(path.join(pluginRoot, relativePath), "utf8");
const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---/.exec(text);
assert.ok(frontmatter, relativePath);
const document = parseDocument(frontmatter[1], { uniqueKeys: true });
assert.equal(document.errors.length, 0, relativePath);
const header = document.toJS();
assert.equal(header.name, skill);
assert.ok(!("owner" in header));
assert.ok(!("metadata" in header));
assert.ok(!("version" in header));
assertPublicText(text, relativePath);
}
assert.ok(!fs.existsSync(path.join(pluginRoot, ".mcp.json")));
assert.ok(!fs.existsSync(path.join(pluginRoot, "mcp")));
const workflowFiles = [
"README.md",
"FEEDBACK.md",
"com.github.copilot/agents/diagnostician.agent.md",
"com.github.copilot/agents/contrarian.agent.md",
"skills/windbg-diagnostic-method/SKILL.md",
];
for (const relativePath of workflowFiles) {
const text = fs.readFileSync(path.join(pluginRoot, relativePath), "utf8");
assertPublicText(text, relativePath);
}
const confidenceContractFiles = [
"README.md",
"com.github.copilot/agents/diagnostician.agent.md",
"com.github.copilot/agents/contrarian.agent.md",
"skills/windbg-diagnostic-method/SKILL.md",
"skills/windbg-diagnostic-method/scripts/validate-diagnosis-output.ps1",
];
for (const relativePath of confidenceContractFiles) {
const text = fs.readFileSync(path.join(pluginRoot, relativePath), "utf8");
assert.match(text, /fix_confidence/, `${relativePath} omits fix_confidence`);
assert.match(
text,
/fix_code_path_coverage/,
`${relativePath} omits fix_code_path_coverage`,
);
}
assert.ok(
fs.existsSync(
path.join(
pluginRoot,
"skills",
"windbg-diagnostic-method",
"scripts",
"validate-diagnosis-output.ps1",
),
),
);
console.log(
`Validated ${inventory.diagnosticSkills.length} diagnostic skills, ` +
`${inventory.methodSkills.length} method skill, agent workflow, ` +
"validator script, and public-only links.",
);

View File

@@ -0,0 +1,40 @@
// Runs the same vally lint that marketplaces such as github/awesome-copilot
// apply to external plugins, on every LOCAL plugin in the Copilot catalog
// (entries whose source is a ./path in this repo). Plugins hosted in other
// repositories are linted there.
// Mirrors awesome-copilot's eng/external-plugin-quality-gates.mjs: lint each
// skills path declared in plugin.json, or the plugin root when none is declared.
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { runLint, LintConsoleReporter } from "@microsoft/vally";
const repoRoot = process.env.CATALOG_ROOT
? path.resolve(process.env.CATALOG_ROOT)
: path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
const catalog = JSON.parse(fs.readFileSync(path.join(repoRoot, ".github", "plugin", "marketplace.json"), "utf8"));
const localRoots = (catalog.plugins ?? [])
.map((p) => (typeof p.source === "string" ? p.source : p.source?.source === "local" ? p.source.path : undefined))
.filter((s) => typeof s === "string" && s.startsWith("./"))
.map((s) => path.resolve(repoRoot, s));
if (localRoots.length === 0) {
console.log("No local plugins in the catalog; nothing to lint.");
process.exit(0);
}
let passed = true;
for (const pluginRoot of localRoots) {
const manifestPath = path.join(pluginRoot, "plugin.json");
const manifest = fs.existsSync(manifestPath) ? JSON.parse(fs.readFileSync(manifestPath, "utf8")) : {};
const skillPaths = [].concat(manifest.skills ?? [])
.map((p) => path.resolve(pluginRoot, p))
.filter((p) => fs.existsSync(p) && fs.statSync(p).isDirectory());
for (const target of skillPaths.length > 0 ? skillPaths : [pluginRoot]) {
const result = await runLint({ rootPath: target });
await new LintConsoleReporter({ verbose: true, stream: process.stdout }).report(result);
passed &&= result.passed;
}
}
process.exit(passed ? 0 : 1);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
{
"name": "win-dev-skills-vally-lint",
"private": true,
"type": "module",
"description": "Marketplace skill lint (vally), pinned to the version github/awesome-copilot uses.",
"scripts": {
"lint": "node lint-skills.mjs"
},
"dependencies": {
"@microsoft/vally": "0.12.0"
},
"engines": {
"node": ">=22"
}
}