Repository navigation
Adopt Agent Plugins 1.0 for the winapp plugin - #784
Conversation
Make plugins/winapp/ conform to the Agent Plugins 1.0 specification so the plugin loads consistently across Copilot CLI, VS Code, the Copilot app, and other compatible clients without client-specific repackaging. - plugin.json: add the canonical $schema and align with the closed manifest schema. Drop the non-portable top-level fields (category, tags, agents, skills); skills/ and mcp.json are auto-discovered from fixed locations. Add homepage and repository, which the schema does permit. - Move agents/winapp.agent.md to com.github.copilot/agents/winapp.agent.md, the Copilot extension namespace for client-specific components. - Point the Claude Code manifest's agents field at the relocated file so the agent stays a single copy. Claude is not an Agent Plugins client, so .claude-plugin/plugin.json is retained. - Repo-root plugin.json stays in the legacy Copilot format (no $schema) so `copilot plugin install microsoft/WinAppCli` keeps working; only its agents path is updated. Adding $schema there would turn its nested skills/agents paths into unknown fields that clients must ignore. - No mcp.json: the plugin ships no MCP servers, and an absent fixed location is not an error under the spec. Verified plugin.json against the published 1.0.0 schema with ajv, and loaded the package via `copilot --plugin-dir`: all 10 skills are auto-discovered and the relocated agent resolves. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adopts Agent Plugins 1.0 while preserving GitHub Copilot and Claude Code compatibility.
Changes:
- Adds the portable, closed-schema manifest.
- Relocates the Copilot agent and updates host-specific references.
- Documents the new plugin layout and review guidance.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
README.md |
Documents Agent Plugins 1.0 support. |
plugins/winapp/plugin.json |
Conforms to the portable manifest schema. |
plugins/winapp/com.github.copilot/agents/winapp.agent.md |
Relocates the Copilot-specific agent. |
plugins/winapp/.claude-plugin/plugin.json |
References the relocated agent for Claude Code. |
plugin.json |
Updates the legacy Copilot agent path. |
llms.txt |
Updates the published agent link. |
AGENTS.md |
Documents layout and schema constraints. |
.github/skills/pr-review/dimensions/ship-surfaces.md |
Updates plugin review guidance. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Nothing prevented a future change from re-adding non-portable fields to plugins/winapp/plugin.json or moving the agent back out of the Copilot namespace. validate-llm-docs.ps1 only checked JSON validity and version equality, so a conformance regression would have passed CI silently. Add scripts/validate-plugin-package.ps1, which checks: - the closed manifest schema ($schema, allowed top-level fields, field types, author/keywords/extensions shapes) and the plugin name constraints - skills/ exists and every immediate child has a SKILL.md with name and description frontmatter, plus a guard for SKILL.md nested too deep to load - mcp.json conformance if one is ever added - the Copilot agent under com.github.copilot/agents/ - the Claude agents pointer resolving to a real file, so a rename cannot break Claude users silently while Copilot keeps working - the repo-root shim staying legacy, since adding $schema there would break `copilot plugin install microsoft/WinAppCli` The rules are encoded rather than fetched: the spec requires clients to validate without retrieving the schema, and it keeps CI offline-safe. validate-llm-docs.ps1 invokes it and folds the exit code into its existing drift handling, so -FailOnDrift keeps blocking PRs and warning on main. The script needs no build output and can be run standalone. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two gaps in scripts/validate-plugin-package.ps1 let non-conformant manifests pass, both confirmed against the official schema with ajv: - A scalar `keywords` string passed the "array of strings" check, because piping a scalar through Where-Object yields a single [string] and an empty filter result. Now requires [array] first. - The closed-field-set check used -notcontains, which is case-insensitive in PowerShell while JSON keys are not, so `"Name"` was accepted as a known field even though the schema requires lowercase `name`. Switched this and the three other case-insensitive comparisons (author fields, SKILL.md frontmatter keys, mcp.json top-level fields) to their case-sensitive -c forms, matching the name-pattern check that already used -cnotmatch. Verified: valid manifest still passes, single-element and multi-element keywords arrays still pass, and scalar keywords, top-level `Name`, and `author.Name` now each fail with a specific error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Build Metrics ReportBinary Sizes
Test Results✅ 4599 passed, 5 skipped out of 4604 tests in 973.3s (+376.7s vs. baseline) Test Coverage✅ 89.1% line coverage, 82.4% branch coverage · ✅ no change vs. baseline CLI Startup Time36ms median (x64, Try This BuildInstalls the MSIX for your architecture, replacing any previously installed build. Needs the GitHub CLI — the command offers to install it and sign you in if it is missing. & ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) 784Switching between builds often?Put the tool on your PATH once: & ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) -AddToPathThen this build is just: winapp-pr 784Run Updated 2026-08-25 20:16:50 UTC · commit |
Description
Makes the shipped plugin at
plugins/winapp/conform to the Agent Plugins 1.0 specification, so it can be discovered and loaded consistently across GitHub Copilot (CLI, VS Code, Copilot app), Codex, Cursor, and other compatible clients without client-specific repackaging.The plugin was already close:
plugin.jsonandskills/were at the plugin root. The remaining work was manifest conformance and moving the Copilot-specific agent into thecom.github.copilot/namespace.plugins/winapp/plugin.json— added the canonical$schemaand aligned with the spec's closed manifest schema:$schemahomepage,repositorycategory,tagsextensions["com.github.copilot"]either, so they were not relocated. Still carried in.claude-plugin/marketplace.jsonagents,skillsLayout —
agents/winapp.agent.mdmoved tocom.github.copilot/agents/winapp.agent.md, the namespace Copilot reads client-specific components from:Compatibility decisions:
.claude-plugin/plugin.jsonis retained. Rather than duplicating the agent, its optionalagentsfield now points at./com.github.copilot/agents/winapp.agent.md, keeping a single copy. Claude already discovers skills at plugin-rootskills/, so that needed no change.plugin.jsonis deliberately left in the legacy Copilot format (no$schema), with only itsagentspath updated. It is the shim that keepscopilot plugin install microsoft/WinAppCliand the awesome-copilot listing resolving the repo as a plugin. Adding$schemathere would opt it into the closed schema, turning its nestedskills/agentspaths into unknown fields that clients must ignore — which would break installation. The Agent Plugins migration guide explicitly recommends retaining a legacy manifest where a client still requires one.mcp.json— the plugin ships no MCP servers, and §6.2 states an absent fixed location is not an error.Usage Example
Unchanged for users; installation commands are the same:
Related Issue
Fixes #742
Type of Change
Checklist
Additional Notes
No CLI, npm, or NuGet code was touched — the change is JSON manifests, one file move, and docs.
Verification performed:
Schema validation. Validated
plugins/winapp/plugin.jsonagainst the publishedhttps://agent-plugins.org/schemas/1.0.0/plugin.schema.jsonwithajv --spec=draft2020→valid. Ran a negative control (re-adding"agents": "agents/") to confirm the check genuinely enforcesadditionalProperties: false→ correctly rejected.Live plugin load. Loaded the migrated package with
copilot --plugin-dir(copied to a temp dir under a unique name, since the name collides with the already-installedwinappcli):skillsdeclaration:winapp-find-ui, winapp-frameworks, winapp-identity, winapp-manifest, winapp-maui, winapp-package, winapp-setup, winapp-signing, winapp-troubleshoot, winapp-ui-automationwinappcli-migrationtest:winapp).Repo validation.
scripts/validate-llm-docs.ps1passes; the regenerateddocs/cli-schema.jsonis byte-identical.Docs updated:
README.md,AGENTS.md(new plugin-layout section documenting the closed-schema constraint),llms.txt, and.github/skills/pr-review/dimensions/ship-surfaces.md.