* fix: validate native Codex plugin support
Separate Codex-compatible plugin components from GitHub Copilot custom agents, validate Codex manifest fields and MCP shapes, and document the native agent installation boundary.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* fix: strengthen Codex plugin verification
Validate Codex MCP per-tool settings and add a pinned native smoke lane that installs the marketplace, discovers skills and MCP, and calls binlog_overview.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* fix: avoid restarting Codex MCP smoke client
Use the real tool call as the app-server initialization so the Linux smoke test does not start and tear down a redundant status client first.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* fix: harden Codex validation and smoke cleanup
Constrain smoke artifacts to a dedicated child directory, validate Codex manifest field shapes and required skill paths, and document the separate Agents SDK handoff model.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* fix: align Codex smoke and hooks parsing
Use the clean Codex installation's default provider for the direct MCP call and reject heterogeneous hooks arrays like the runtime parser.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* fix: verify every Codex plugin skill
Compare native skill discovery with the full repository inventory, match Codex lexical path rejection, and allow null optional MCP tool settings.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* fix: address Codex compatibility review
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Delete msbuild-server skill
msbuild-server is now on by default since .NET 11 Preview 7. We don't want to recommend turning it on, automatically in other scenarios as critical fixes could be missing.
* Remove MSBuild Server recommendations
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* Fix Codex discovery of the dotnet-msbuild binlog MCP server
.codex-plugin/plugin.json declared "mcpServers": "./.mcp.json", but the file
was packaged at .codex-plugin/.mcp.json. Codex resolves manifest resource
paths against the plugin root, so it looked for
plugins/dotnet-msbuild/.mcp.json and never found the binlog server.
Declare the server inline in .codex-plugin/plugin.json, matching the root
plugin.json and .claude-plugin/plugin.json, and drop the unreachable file.
Add a packaging regression check to skill-validator: every companion manifest
must declare the same MCP servers as the root plugin.json, and a manifest
referencing an external .mcp.json must resolve it from the plugin root the way
hosts do. skill-check.yml already runs `skill-validator check` over plugins/*
on every PR, so this now blocks in CI. A test also loads the shipped
dotnet-msbuild manifests and asserts binlog is present in each.
Fixes#1069
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Report non-object JSON roots as validation errors
JsonElement.TryGetProperty throws InvalidOperationException when the root
value is not an object, so a manifest or referenced .mcp.json that is valid
JSON but not an object (null, array, string) crashed skill-validator instead
of producing a validation error.
Check the root kind while reading and surface it as a structured error.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Revert "Resolve binlog MCP from the dnceng dotnet-public feed"
This reverts commit 805a42a675.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3b2899e9-48f8-4a2a-a19f-1827d08cbfc4
* ci(eval): configure NuGet source explicitly
Install a repository-owned NuGet configuration at the runner user level so temporary Vally workspaces resolve packages from nuget.org without plugin-specific source arguments.
* build: use dotnet-public for repository NuGet configs
Route evaluation and version-stamping tool restores through the locked-down dotnet-public source mapping.
* fix(msbuild): enable prerelease BinlogMcp versions
Match the Roslyn LSP dnx configuration and keep all mirrored MCP manifests consistent.
---------
Co-authored-by: Jan Krivanek <jankrivanek@microsoft.com>
Copilot-Session: 3b2899e9-48f8-4a2a-a19f-1827d08cbfc4
* Resolve binlog MCP from the dnceng dotnet-public feed
The `binlog` server ran `dnx Microsoft.AITools.BinlogMcp --yes` with no feed pinned, so resolution depended on whatever ambient NuGet configuration the agent happened to run under. Pin it to the dnceng dotnet-public feed with `--source` so the server resolves deterministically.
Applied to all four manifests that embed the server definition (plugin.json, .claude-plugin/plugin.json, .codex-plugin/.mcp.json, and .claude-plugin/marketplace.json) so the mirrors stay in sync. Also corrects two stale feed names in comments/docs (dotnet-eng, dotnet-tools).
Verified: `skill-validator check` passes (exit 0, no new warnings), and `dnx --yes --source <dotnet-public> Microsoft.AITools.BinlogMcp` starts aitools-binlog-mcp 2.0.1 and completes an MCP initialize handshake.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eef3a5cc-7c9b-41b2-88e5-fbc7e786f3f2
* Keep the package ID first in the dnx args
Addresses review feedback. Both orderings resolve and start the server correctly (verified), but keeping `Microsoft.AITools.BinlogMcp` immediately after `dnx` matches the ordering already used in this repo and turns the change into a pure insertion of `--source` with no reordering noise.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eef3a5cc-7c9b-41b2-88e5-fbc7e786f3f2
---------
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Copilot-Session: eef3a5cc-7c9b-41b2-88e5-fbc7e786f3f2
* Fix dotnet-msbuild skill eval regressions and coverage gaps (#896)
Addresses the cross-family evaluation findings in #896.
P0:
- eval-performance: add diagnostic-first framing + explicit stop-conditions and
gate prescriptive fixes on measurement, to stop over-application regressions.
- msbuild-antipatterns: rewrite description with an action-verb lead and concrete
trigger phrases to fix low invocation (FIX-DISCOVERY).
P1:
- Add cross-family eval.vally.yaml for extension-points, item-management,
property-patterns, and target-authoring (previously excluded from the matrix).
- check-bin-obj-clash: trim 465 -> 315 lines, removing the redundant text-log
fallback steps, duplicate example workflow, and verbose tips (TRIM-COST).
P2:
- build-parallelism: add an opinionated 'start here' critical-path checklist.
- binlog-generation: add one-build-one-binlog rule and a verify step.
Keeps the plugin under the 15,000-char rendered skill-menu budget (14,981 -> 14,873).
* Address PR review: portable grep whitespace + per-project eval count; shell-labeled binlog verify commands (#896)
- check-bin-obj-clash: use [[:space:]] instead of non-portable \s in ERE; replace 'grep -c' note with an accurate per-project uniq -c count.
- binlog-generation: label verify commands by shell and add the Windows cmd (dir /b) equivalent instead of mislabeling ls as cmd.
* Address PR review round 2: full PowerShell -m command; match quoted project path in per-project eval count (#896)
- build-parallelism: spell out 'dotnet build -m -bl:{{}}' for PowerShell so the -m flag isn't dropped.
- check-bin-obj-clash: match the full quoted project path (not just filename) so same-named projects in different dirs stay distinct and paths with spaces work.
* Document SetTargetFramework bin/obj clash on single-targeting ProjectReferences
Setting SetTargetFramework metadata on a ProjectReference to a non-multi-targeting project injects a path-neutral TargetFramework global property, forking a redundant project instance that shares the same OutputPath/IntermediateOutputPath as the solution-rooted build. The project is built twice, causing a bin/obj clash under parallel builds.
Adds AP-23 to the msbuild-antipatterns catalog and a matching Common Causes and Fixes section plus global-properties note to the check-bin-obj-clash skill.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Clarify SetTargetFramework: same-TFM clash vs legitimate overrides
Refine AP-23 and the check-bin-obj-clash guidance to reflect two additional cases: (1) the clash only occurs when the injected TFM equals the single-targeting project's own TFM (path-neutral); injecting a DIFFERENT TFM changes the output path and is a valid override, and (2) for framework-incompatible references (e.g. .NETFramework test project -> single-targeting .NETCoreApp), SkipGetTargetFrameworkProperties=true and ReferenceOutputAssembly=false are also required.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Generalize incompatible-TFM ProjectReference guidance
SkipGetTargetFrameworkProperties=true and ReferenceOutputAssembly=false are required whenever the referencing and referenced projects target incompatible frameworks, independent of single- vs multi-targeting and independent of SetTargetFramework. Decouple that rule from the SetTargetFramework override case in both AP-23 and the check-bin-obj-clash skill.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Note TargetFramework leak when SkipGetTargetFrameworkProperties is set
When SkipGetTargetFrameworkProperties=true bypasses P2P negotiation, the referencing project's TargetFramework global property can flow into a single-targeting referenced project and build it under the wrong TFM/output path. Guard with either SetTargetFramework (pin) or UndefineProperties=TargetFramework (strip), not both.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add eval coverage for SetTargetFramework bin/obj clash (AP-23)
check-bin-obj-clash: extend ClashTest with a single-targeting ToolLib and a ConsumerApp that references it with redundant same-TFM SetTargetFramework, forking a second ToolLib instance that builds to the same bin/obj (verified: ToolLib builds twice). Adds rubric items for identifying and fixing it.
msbuild-antipatterns: LibB now references LibA with redundant same-TFM SetTargetFramework; adds a rubric item for detecting AP-23 in the static review scenario. Both eval.yaml and eval.vally.yaml updated.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Viktor Hofer <vihofer@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add copy-to-output-directory MSBuild skill
Adds a focused dotnet-msbuild skill documenting how to choose a
CopyToOutputDirectory / CopyToPublishDirectory mode, including the
`IfDifferent` mode and the `$(SkipUnchangedFilesOnCopyAlways)` property
introduced in MSBuild 17.13 / .NET SDK 9.0.2xx (dotnet/msbuild#11052).
Covers mode semantics (Never/PreserveNewest/Always/IfDifferent), why
`Always` is a per-build perf hit, the SkipUnchangedFiles timestamp+size
comparison, transitive copy through ProjectReference, and version
requirements. Registers the skill in the msbuild, msbuild-code-review,
and build-perf agent routing lists.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 881d26ad-87b7-48e3-8ec6-043163944437
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Address review feedback on copy-to-output-directory skill
- Soften the IfDifferent description to avoid overclaiming: it skips
when "unchanged per MSBuild's heuristic" (timestamp + size, not a
content hash), rather than "identical"/full Always equivalence.
- Correct the target-flow wording: the three copy targets run as
dependencies of _CopySourceItemsToOutputDirectory (invoked by
CopyFilesToOutputDirectory).
- Restore the USE FOR / DO NOT USE FOR routing pattern for the skill's
frontmatter description, matching sibling skills.
- Reclaim skill-menu budget headroom (per maintainer note) by tightening
the verbose property-patterns and target-authoring descriptions;
dotnet-msbuild rendered menu is now ~14,897/15,000 chars.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 881d26ad-87b7-48e3-8ec6-043163944437
* Fix article: 'an SQLite' per review
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 881d26ad-87b7-48e3-8ec6-043163944437
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Add automated per-plugin versioning (NBGV) with /version-bump + weekly backstop
WHY
Tools that surface skills (Copilot CLI, Claude Code, Codex, Cursor) read a
plugin's version directly from its checked-in manifest. With no versioning
discipline, a plugin's behavior can change while its advertised version stays
flat, so clients never learn to re-pull, and there is no human-readable signal
of what changed. We want correct, current versions in the repo with minimal
manual work and without bloating the marketplace clone.
WHAT
- Per-plugin semantic versioning via Nerdbank.GitVersioning (NBGV). Each plugin
owns a version.json whose pathFilters exclude the generated manifests and the
version.json itself, so version height tracks real content changes only.
- The computed version is materialized into the checked-in manifests
(plugin.json and .codex-plugin/plugin.json) so every consumer reads a current
value with no build step on their side.
- eng/version/Sync-PluginVersions.ps1 is the single workhorse. It resolves the
set of changed plugins from a git diff, computes each version with nbgv
(predicting the squash-merge height for PRs), and either reports or stamps.
AUTOMATIONS (two, low-touch by design)
- /version-bump: an admin/maintainer comments the command on a PR and the
affected plugins are stamped on the PR branch. Gated on collaborator
permission (admin/write/maintain); forks are rejected before any privileged
step. No other PRs are auto-modified.
- weekly-version-sync: a Monday backstop (and workflow_dispatch) that stamps any
drift on main, opens/updates a single bot PR, and explains the per-plugin
reason. This self-heals anything that merged without a bump.
We deliberately did NOT auto-edit contributor PRs or add a noisy advisory
comment bot; maintainers stay in control and the signal stays clean.
SECURITY (multi-model adversarial review: GPT-5.5 + Gemini 3.1 Pro)
- Supply chain (High, both models): dotnet tool restore would have honored a
nuget.config authored in the PR tree, letting an attacker remap the nbgv
package source to a malicious feed and run code in the privileged
contents:write context. Mitigated with a trusted eng/version/nuget.config
(clear + nuget.org-only + packageSourceMapping), overlaid from main and used
via --configfile so PR-supplied configs are ignored. No nuget.config is
tracked in the repo today, so this path was genuinely exploitable.
- TOCTOU (Medium): /version-bump now checks out the authorized head SHA rather
than the mutable branch name; a racing push fails non-fast-forward, which is
the safe outcome.
- Injection: Set-ManifestVersion uses a MatchEvaluator (not a replacement
string) so a "$"-bearing version cannot re-expand, plus a strict
major.minor.patch guard that throws on a malformed base, leaving manifests
untouched.
- A base-only version.json bump (0.1 -> 0.2) is correctly detected and stamped.
VERIFIED
End-to-end against a real NBGV git harness: content-scoped predict, base-only
bump -> x.y.0, docs-only -> [], weekly drift stamping, malformed-base guard,
and --configfile restore (exit 0). actionlint passes on both workflows.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address Copilot review feedback
- Add missing plugins/dotnet-test-migration/version.json so it participates
in versioning (it was the only plugin without one; manifests are at 0.1.0).
- CONTRIBUTING: the two manifests are not byte-identical; say the version is
duplicated across two manifest files instead.
- weekly-version-sync: include version.json in commit attribution so a
base-only bump is explained rather than showing 'no attributable commits'.
- Get-NbgvInfo: capture nbgv stderr and include it in the thrown error so CI
failures are diagnosable, while keeping stdout clean for JSON parsing.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Claude Code discovers MCP servers via .claude-plugin/plugin.json inside
each plugin directory. The existing .codex-plugin/ manifest only works
for Codex CLI. Add the Claude Code-specific manifest with inline
mcpServers config, and also declare mcpServers in the root marketplace
manifest entry for belt-and-suspenders coverage.
Fixes#840
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add TFM-aware buildTransitive->build forwarding guidance to msbuild skills
buildTransitive/*.props should forward through the corresponding build/*.props (ownership chain buildTransitive -> build -> shared) rather than importing buildMultiTargeting/ directly. When build/ is packed per-TFM (build/<tfm>/), the forwarder must include the TFM segment and derive it from the file own folder, not $(TargetFramework) (NuGet nearest-match can serve a different asset folder), otherwise transitive consumers hit MSB4019.
Updates extension-points (new Forwarding chain section), msbuild-antipatterns AP-13, and the msbuild-code-review agent. Lesson learned from microsoft/testfx#9431.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Clarify ambiguous props/targets glob in forwarder review check
Address review feedback on dotnet/skills#836: spell out ".props/.targets forwarders" instead of the ambiguous `buildTransitive/*.props|targets`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Tighten forwarding-chain guidance to reduce skill token overhead
Condense the new extension-points Forwarding chain section (+26 -> +11 lines) and the AP-13 note by dropping the redundant non-TFM example and self-evident derivation explanation, keeping the chain rule, MSB4019 cause, and the TFM derivation expression. Lower token footprint addresses the skill-validator weighted-score token penalty without losing substance.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review nits: AP range and forward-slash path
Update the additional anti-patterns range to AP-16 through AP-22 (the reference doc now includes AP-22), and use a forward-slash build/MyPackage.props in the forwarding-chain prose to match the build/<tfm>/ convention used in the section.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Condense AP-13 forwarding note to a cross-reference to reduce token overhead
The full TFM-forwarding guidance lives in extension-points; AP-13 only needs a concise pointer. Removes duplication and trims the msbuild-antipatterns skill footprint flagged by the skill-validator token penalty.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Address remaining review nits: targets forwarders, single-source wording, quoted MSBuildThisFileDirectory
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
The rendered skill-menu for the dotnet-msbuild plugin was 16,679 characters, exceeding the 15,000 limit. Trim two categories of content from the 18 skill descriptions that do not help agents decide when to invoke a skill:
- Remove INVOKES: clauses (which MCP tools / fallback shell commands a skill runs internally) — implementation mechanics, not routing signal.
- Remove the boilerplate 'Only activate in MSBuild/.NET build context.' repeated verbatim in all 18 skills — redundant, since every description is already MSBuild-specific and each DO NOT USE FOR still excludes non-MSBuild build systems.
USE FOR triggers and DO NOT USE FOR cross-references are preserved. Aggregate skill description size drops from 14,551 to 12,536 chars (rendered menu 16,679 -> 14,664).
Co-authored-by: Yuliia Kovalova <ykovalova@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Microsoft.AITools.BinlogMcp package is now published on nuget.org as
stable 1.0.0, so the binlog MCP server no longer needs the dnceng AzDO
dotnet-tools feed or the --prerelease flag.
Drop --prerelease and --add-source <azdo> from the binlog server args in
both plugin.json and the .codex-plugin/.mcp.json mirror.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds msbuild-antipatterns AP-22 (in references/additional-antipatterns.md): using
the <MSBuild> task to build/publish a project with an extra global property that
does not change the output path forks a distinct instance sharing the same
OutputPath/IntermediateOutputPath as the instance the graph already builds,
causing duplicate builds and parallel-write races on PDBs, *.sourcelink, and
project.assets.json. Covers both shapes:
(a) a project re-invoking itself (publish-on-build), and
(b) project A invoking Build/Publish on another project B it consumes
(e.g. a test/layout project publishing a tool) — the more common trigger.
GOOD fixes: (a) static _IsPublishing + DependsOnTargets with a cycle guard;
(b) let the producer publish in its own build and have the consumer sequence it
with a non-output ProjectReference instead of re-publishing it. Also updates the
SKILL.md pointer (AP-16 through AP-22) and the quick-reference checklist.
Extends check-bin-obj-clash with the matching cause (self or cross-project
<MSBuild> Build/Publish with a path-neutral global property), binlog-based
detection via the evaluations/global-properties/double_writes tools, the two
fixes, and an _IsPublishing row in the global-properties table.
Adds eval coverage: a publish-on-build smell in the msbuild-antipatterns review
fixture (LibA.csproj) plus a matching rubric line in eval.yaml and eval.vally.yaml.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix dotnet-msbuild Codex plugin install by externalizing mcpServers
Move the inline mcpServers configuration to a separate .mcp.json file
inside .codex-plugin/, and update .codex-plugin/plugin.json to reference
it via a relative path string. This matches the Codex plugin spec which
requires mcpServers to be a path reference to a .mcp.json file rather
than an embedded object.
The root plugin.json retains the inline mcpServers format for the
skill-validator. Both validator methods (FindPluginMcpServers and
ExternalDependencyChecker.CheckPlugin) are updated to also handle the
Codex string path format for forward compatibility.
Fixes#738
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review: validate mcpServers path and log parse errors
- Reject rooted paths and paths with '..' segments to prevent directory
traversal when resolving mcpServers string references.
- Log parse errors in ResolveMcpFile to stderr (consistent with
plugin.json parse error handling) instead of silently swallowing.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Codex CLI requires .codex-plugin/plugin.json as the plugin manifest
entry point. Without it, 'codex plugin add' fails with 'missing plugin.json'
even though the marketplace listing works.
This adds .codex-plugin/plugin.json to all 14 plugin directories, with paths
relative to the plugin root per the Codex docs. Also updates the agents
marketplace to use dotnet-aspnetcore (per #711 rename) and adds missing
dotnet-blazor and dotnet11 entries.
Fixes#578Fixes#724
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [dotnet-msbuild] Fix AP-13/AP-14 false positives and add source-vs-packed layout guidance
The msbuild-quality-review run on microsoft/testfx surfaced two confidently-stated
false positives that the maintainer rightly pushed back on:
1. The reviewer claimed unguarded `<Import>` forwarders in MSTest's NuGet
`build/<tfm>/` folders point at non-existent paths under `buildTransitive/<tfm>/`.
In reality those folders are produced at pack time by the `.nuspec` `<file
target="...">` mappings, so the forwarders resolve correctly in every restored
package.
2. The reviewer flagged backslashes in `<Import Project="...\...\...">` as a
cross-platform 🔴 error. MSBuild's evaluator normalizes `\` to `/` on
Unix-like systems via `FileUtilities.MaybeAdjustFilePath` /
`ConvertToUnixSlashes` before resolving the path, so existing backslash-style
imports work everywhere — confirmed by years of shipping MSTest to Linux/macOS
users.
This change updates the rubric so the same false positives don't recur across
every consumer of the dotnet-msbuild plugin:
* `msbuild-antipatterns/SKILL.md` AP-13 — adds an explicit "NuGet package
forwarders" exception and tells reviewers to consult `.nuspec` /
`<PackagePath>` before flagging.
* `msbuild-antipatterns/SKILL.md` AP-14 — rewritten to distinguish where
backslashes are a real bug (raw `<Exec>` shell strings, CDATA, non-MSBuild
consumers — keep 🔴) from where they're only style (`<Import>` and other
evaluator-routed paths — 🔵 with a cite to the MSBuild source).
* `extension-points/SKILL.md` — adds a "Source Tree vs Packed Layout" section
documenting the three packaging mechanisms (.nuspec `<file>` mappings, csproj
`<PackagePath>` metadata, SDK pack conventions) that legitimately reshape the
layout, with the cross-check procedure reviewers must run before flagging
"missing-file" imports.
* `agents/msbuild-code-review.agent.md` — Discovery now records the projected
packed layout; Category 4 references the new AP-13/AP-14 nuances; new
"Veracity gate" step downgrades or drops 🔴 findings that would imply
currently-shipping CI is broken.
No fixtures change: the `tests/dotnet-msbuild/msbuild-antipatterns/eval.yaml`
rubric does not enumerate AP-13/AP-14 by id, and the F#-specific scenarios are
unaffected. Markdownlint passes on all edited files.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address PR review feedback
- extension-points: rewrite .nuspec example so the source file is genuinely shared (single buildTransitive/common/MyAdapter.props fan-out instead of three already-per-TFM sources); clarify <file target=> folder-vs-rename semantics.
- extension-points: replace semicolon-list PackagePath example with the unambiguous multi-<None> form, and note in prose that semicolon syntax is also supported. Avoids reader confusion noted in review.
- msbuild-antipatterns AP-13 cross-check: align search scope with extension-points (project directory AND any parent directory) so reviewers don't miss shared mono-repo nuspecs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* AP-13: drop ../ link to extension-points to satisfy skill-validator
Skill-validator rejects file references that traverse out of the skill directory (parent-directory traversal). Replace the markdown link with a plain-text reference to the dotnet-msbuild/extension-points skill — the prose is still discoverable to humans and to the agent that loads the plugin, but no longer trips the validator.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address second round of PR review feedback
- AP-13: replace <tfm> placeholders inside XML attribute strings with concrete TFM examples (net8.0) so the snippets are valid copy-pasteable XML.
- AP-13 & extension-points: bound the .nuspec search to project directory + IMMEDIATE parent only (no unbounded walking); wording now identical in both docs.
- AP-14: add explicit text severity next to severity emoji (🔴 Error / 🔵 Style) for accessibility — screen readers and plain-text copies now convey severity without relying on color/emoji rendering.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add 4 MSBuild target authoring skills for dotnet-msbuild plugin
New skills:
- target-authoring: three-level target chain, DependsOn extension, naming conventions
- property-patterns: conditional defaults, composition, path normalization, TFM helpers
- item-management: Include/Remove/Update, batching, transforms, FileWrites registration
- extension-points: CustomBefore/After hooks, import gating, NuGet build extensions
Each skill includes eval.yaml tests with anti-pattern fixtures.
Closes#668
* Address Copilot review feedback
- target-authoring: Reword DO NOT USE clause to exclude only deep
incremental-build diagnostics, not basic Inputs/Outputs usage
- property-patterns: Close unclosed XML elements in String Functions
snippet (PropertyGroup, TargetFrameworkMoniker)
- extension-points: Add missing CustomAfterMySDK property definition
to match the import at bottom of example
* Remove accidental pr-body.md file
* Fix wildcard import placeholder path and quote NormalizePath args
- extension-points: Use full MSBuildExtensionsPath expression and
consistent Exists() casing in wildcard import example
- property-patterns: Quote property arguments in NormalizePath call
* Tune eval prompts to reduce overfitting
Rewrite all 4 eval prompts as natural developer problem descriptions
instead of skill-aligned checklists. Softens technique-prescriptive
rubric items. Result: overfitting scores drop from 0.15-0.31 to
0.06-0.08 (all green). property-patterns now passes eval.
* Fix Copilot review round 3: quote property function args, fix fixture
- property-patterns: Quote in IsPathRooted call
- extension-points: Quote in GetDirectoryNameOfFileAbove
- item-management fixture: Use literal semicolon instead of %3B in WriteLinesToFile
* Add harder multi-file eval scenarios for all 4 skills
Each skill now has a second scenario with multi-file setups containing
interacting bugs that require cross-file analysis:
- target-authoring: SDK .targets + Directory.Build.targets with 3 bugs
(target redefinition, fragile BeforeTargets, duplicate DependsOn chain)
- property-patterns: nested Directory.Build.props with 5 bugs
(import order, unconditional overwrite, unquoted condition, missing
trailing slash, NoWarn overwrite)
- item-management: csproj with 5 interacting bugs (Include vs Update,
cross-product batching, eval-time FileWrites, too-broad Remove glob)
- extension-points: Directory.Build.props/targets + NuGet package with
6 bugs (inverted guard, late ImportByWildcard, CustomBefore overwrite,
missing Exists guard, target name collision, internal target hook)
Timeouts increased to 180s for all scenarios.
* Fix review round 4: revert unintended README change, quote intrinsic call in condition
* Improve eval quality for 4 new MSBuild authoring skills
Eval improvements across target-authoring, property-patterns,
item-management, and extension-points skills:
- Rewrite prompts to describe observable symptoms without naming
MSBuild concepts, inspired by real dotnet/msbuild and dotnet/sdk
issues (msbuild#2470, #12894, #13056, #4109, sdk#43908)
- Broaden assertion regex patterns to test for diagnostic outcomes
rather than skill-specific vocabulary
- Improve rubric items to test understanding and diagnosis flow
(diagnosis -> root cause -> fix) instead of skill terminology
- Add task-completion 'fix it' scenario to each skill with
file_contains assertions that verify the agent applied correct
patterns (CompileDependsOn append, FileWrites, Exists guard, etc.)
- Remove leading 'Anti-pattern:', 'BUG N:' comments from fixture
files that were giving away answers to the baseline agent, making
scenarios more realistic and better at measuring skill value
Each skill now has 3 scenarios: basic review, hard multi-file review,
and a task-completion fix scenario. Total: 12 scenarios across 4 skills.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix review comments: quote TFM intrinsic, fix PrivateAssets example
- property-patterns SKILL.md: Quote the GetTargetFrameworkIdentifier
intrinsic call result in the Condition to match the 'always quote
both sides' guidance and avoid brittle parse when empty
- item-management SKILL.md: Replace PackageReference Update on
Microsoft.NETCore.App (not a real user-added item) with Include
on Microsoft.CodeAnalysis.NetAnalyzers (a concrete analyzer package)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix eval activation and timeouts based on eval run results
- Add MSBuild domain terms to prompts (e.g., 'MSBuild targets',
'MSBuild property patterns', 'MSBuild item groups', 'MSBuild
extension points') to improve skill activation rates — skills
were NOT ACTIVATED in plugin mode due to prompts being too
symptom-focused without domain keywords
- Increase timeouts: review scenarios 180s -> 240s, fix-it
scenarios 180s -> 300s to avoid timeout-related scoring penalties
- Keep prompts symptom-driven but include enough domain context
for the skill router to activate the correct skill
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix PR review comments and improve eval quality
Review comment fixes:
- TargetAuthoring.csproj: Replace %22/%3B URL encoding with XML
escaping ("/;) so generated C# code is valid
- target-authoring eval: Fix prompt referencing 'schema files' when
fixture has endpoint definitions — now says 'endpoint list'
- property-patterns eval: Reword LangVersion rubric — unconditional
assignment in .props IS overridable by csproj but prevents override
from earlier imports and command-line properties
- extension-points eval: Add stronger activation terms to Fix scenario
prompt (explicit mention of CustomBeforeMicrosoftCommonTargets)
Eval quality improvements based on CI results:
- Shorten target-authoring rubric items to reduce overfitting (was 0.30)
- Remove 'Focus on target authoring patterns' instruction from hard
scenario prompt (was directing agent too specifically)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Improve eval: increase timeout, add activation keywords, explicit fix instructions
- property-patterns 'Diagnose multi-level': timeout 240s -> 360s (was hitting limit at 249s)
- target-authoring 'Diagnose custom target': add CompileDependsOn/incremental build keywords for better skill activation
- property-patterns 'Fix': add 'edit ... directly' to prompt to encourage file edits
- target-authoring 'Fix': add 'edit ... directly' to prompt
- item-management 'Fix': add 'edit ... directly' to prompt
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix target-authoring skill description and eval prompts for plugin activation
The skill description said 'DO NOT USE FOR: deep incremental-build diagnostics'
which caused the plugin agent to skip it for scenarios about build regressions.
Clarified that the skill IS for diagnosing target authoring mistakes (missing
Inputs/Outputs, broken dependency chains) that cause full rebuilds.
Also updated eval prompts to use 'target authoring mistakes' framing and
increased Fix scenario timeout to 360s.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Increase eval timeouts: extension-points NuGet (240->360s), item-management cascading (240->360s)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix 3 fresh PR review comments + update eval prompts for target-authoring
- property-patterns/SKILL.md: add warning that TargetFramework-conditioned
PropertyGroups must be in .targets not .props (empty in single-target .props)
- extension-points/SKILL.md: add Exists() guard to GetPathOfFileAbove Import
to prevent build failure when no parent file is found
- target-authoring/SKILL.md: fix comment mismatch — validation target runs
via dependency chain, not BeforeTargets; update comment accordingly
- target-authoring/eval.yaml: reframe 'Diagnose' and 'Fix' prompts to use
'dependency chain' / 'authoring patterns' language (avoids routing to
incremental-build skill which also claims Inputs/Outputs diagnostics)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Improve skill descriptions for reliable plugin-mode activation
Add 'Only activate in MSBuild/.NET build context.' prefix to all 4 skills
for consistency with existing skills in the plugin.
Add explicit 'diagnosing and fixing' and 'reviewing' keywords to USE FOR
sections so the SDK selects these skills over the broader
msbuild-antipatterns skill when prompts ask to fix or review specific
item/extension/property/target patterns.
Add 'general MSBuild anti-pattern catalog (use msbuild-antipatterns)' to
DO NOT USE FOR sections to help the SDK disambiguate.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix skill descriptions: shorten to under 1024-char SDK limit
All 4 new skills had descriptions exceeding the 1024-character maximum
enforced by the skill-validator check command. The Copilot SDK silently
ignores skills with over-length descriptions, causing 0% activation in
both isolated and plugin evaluation modes.
Shortened all 4 descriptions while preserving key activation keywords
(USE FOR / DO NOT USE FOR / 'Only activate in MSBuild/.NET build context').
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address PR review comments
- target-authoring eval.yaml: fix prompt to say 'Outputs attribute' (not
'Returns') since the fixture uses Outputs on a query target, which is
the actual bug that causes MSBuild to skip re-execution
- property-patterns eval.yaml: reword prompt and rubric — the real issue
is unconditional assignment breaking parent-child Directory.Build.props
inheritance, not project files being unable to override properties
- extension-points SKILL.md: fix GetPathOfFileAbove example to factor
the path into a property so Project= and Condition= use the same value
consistently (avoiding the ..\\ vs ..\ discrepancy)
- CustomSdk.targets: add WriteLinesToFile to CoreCodeGen so it actually
creates the .g.cs output files (prevents compilation failure in fixture)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix property-patterns fixtures to match rubric claims
Scenario 1 (path merge bug):
- PropertyPatterns.csproj: add OutputPath using CustomOutputDir without a
trailing separator, making the merge bug observable
(artifacts\binPropertyPatterns\ instead of artifacts\bin\PropertyPatterns\)
Scenario 2 (multi-level hierarchy bugs):
- hard/Directory.Build.props: make LangVersion unconditional so it
overwrites the child src/Directory.Build.props LangVersion=preview,
matching the rubric claim about parent unconditional assignments
- hard/Directory.Build.props: add NoWarn=NU1702 (conditional default)
so parent suppressions are visible but lost when the child's
unconditional <NoWarn>CS1591;IDE0005</NoWarn> overwrites them after import
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The MCP package was relocated from the dotnet-eng public feed to the dotnet-tools public feed on dnceng. Update plugin.json --add-source URL and the SKILL.md fallback note accordingly.
* dotnet-msbuild: register AITools.BinlogMcp and use it from binlog-failure-analysis
Adds the AITools.BinlogMcp MCP server (pulled via dnx from the dotnet-eng public NuGet feed, prerelease, no version pin) to the dotnet-msbuild plugin and rewrites the binlog-failure-analysis SKILL.md to lead with the MCP tools (binlog_overview, binlog_errors, binlog_search, binlog_items, binlog_properties, binlog_imports, binlog_nuget). The text-log replay workflow is kept as a fallback for environments without the MCP.
* Improve skills
* Reflect PR comments
* Add fsharp-project-structure skill for .fsproj file ordering and .fsi files
Teaches agents F# compilation order rules, signature file placement,
and common FS0039/FS0010/FS0034 fixes. Includes eval with three scenarios
(add module, fix broken order, add signature file) and test fixtures.
Validated +64.6% improvement on gpt-4.1 (significant, CI [+17.2%, +63.0%]).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add fsharp-project-structure skill for .fsproj file ordering and .fsi files
Teaches agents F# compilation order rules, signature file placement,
and common FS0039/FS0010/FS0034 fixes. Includes eval with three scenarios
(add module, fix broken order, add signature file) and test fixtures.
Validated +64.6% improvement on gpt-4.1 (significant, CI [+17.2%, +63.0%]).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Update plugins/dotnet/skills/fsharp-project-structure/SKILL.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fold F# project-structure into msbuild-antipatterns AP-05
Scraps the standalone fsharp-project-structure skill and instead adds a
short F# exception to AP-05 (Manual File Listing in SDK-Style Projects):
F# compilation is order-dependent, so .fsproj files must list Compile
items in dependency order (utilities first, entry point last), and .fsi
signature files must appear immediately before their companion .fs.
The three F# eval scenarios (add module, fix broken order, add signature
file) are ported into tests/dotnet-msbuild/msbuild-antipatterns/eval.yaml
with fixtures isolated under a fsharp/ subfolder (with empty
Directory.Build.{props,targets} to prevent the existing C#-antipattern
fixture files from leaking into the F# builds).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix agents field in plugin.json to use explicit file paths
Claude Code's manifest validator rejects directory paths in the agents
field. Replace directory references with explicit .agent.md file paths
in all affected plugins (dotnet-diag, dotnet-msbuild, dotnet-template-engine).
Fixes https://github.com/dotnet/skills/issues/416
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Validate that agents paths are explicit files, not directories
Claude Code's manifest validator rejects directory paths in the agents
field. Update PluginValidator to error when an agent path resolves to a
directory, guiding authors to use explicit .agent.md file paths instead.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Initial plan
* Remove agents string field from plugin.json and handle array format in parser
Claude Code CLI validates `agents` as array-of-strings per its plugin manifest
schema. Our plugin.json files had `"agents": "./agents/"` (a string), which
caused "agents: Invalid input" validation errors on install.
Remove the field from the 3 affected plugin.json files — agents are still
discovered by convention from the `agents/` directory. Also make ParsePluginJson
resilient to both string and array formats for forward-compatibility.
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
* Remove `agents` string field from plugin.json for Claude Code CLI compatibility
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
* Change agents field to array format in plugin.json, update validator to read array-first with string fallback
Plugin.json files now declare agents as an array of file paths:
"agents": ["./agents/foo.agent.md", "./agents/bar.agent.md"]
ParsePluginJson reads the array first (preferred, Claude Code schema),
falls back to a string path (legacy). PluginInfo gains an AgentPaths
field. Validator and discovery use the array when present, else fall
back to directory-based convention.
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
* Simplify agents to directory-path array form ["./agents/"], handle directories in array entries
Per Copilot CLI spec, agents field values are "Path(s) to agent directories"
— no need to list individual files. Use ["./agents/"] to mirror how
skills uses "./skills/". Updated validator and discovery to handle both
directory and file entries in the array.
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
* Delete .nuget/nuget.exe
* Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Convert skills field to array format in plugin.json, update validator to handle both forms
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
* Align AgentPaths null checks to use { Count: > 0 } pattern for consistency
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
* Change `agents` and `skills` fields in plugin.json to array format for Claude Code CLI compatibility
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
* Delete .nuget/nuget.exe
* Consolidate SkillsPath/SkillPaths and AgentsPath/AgentPaths into single array fields
Remove dual string/array fields from PluginInfo. The parser now
normalizes legacy string values into single-element arrays, so all
downstream code uses only SkillPaths and AgentPaths (IReadOnlyList<string>).
This eliminates all array-vs-string fallback branching.
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ViktorHofer <7412651+ViktorHofer@users.noreply.github.com>
Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Enrich build-perf-diagnostics skill with MSBuild team and community insights
Additions (pure knowledge, no MCP dependency):
- RAR: dotnet/msbuild#2015 context, DisableTransitiveProjectReferences, ReferenceOutputAssembly
- Copy tasks: SkipCopyUnchangedFiles, --artifacts-path, Copy batching (dotnet/msbuild#12884)
- Dev Drive (ReFS): copy-on-write + reduced Defender scans, OrchardCore 7257 Copy tasks benchmark
- Evaluation: NuGetSdkResolver 180-400ms overhead (dotnet/msbuild#4025), EnableDefaultItems
- NuGet: RestoreUseStaticGraphEvaluation (20s+ savings in large builds)
- Project graph shape: wide vs deep (40% faster clean, 20% faster incremental)
- MSBuild Server: MSBUILDUSESERVER=1 for CLI caching
- Inline task overhead: 1s vs 3ms (RoslynCodeTaskFactory vs compiled)
- Misleading ResolveProjectReferences time (dotnet/msbuild#3135)
- Incrementality anti-patterns (dotnet/msbuild#13206)
- Impact categorization (HIGH/MEDIUM/QUICK WINS)
- Quick Wins: expanded to 15 items (from 7)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix minor issues from review comments
- Fix missing closing XML tag for CreateHardLinksForCopyFilesToOutputDirectoryIfPossible in Quick Wins checklist
- Clarify confusing Copy task batching wording per reviewer feedback
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Trim skill to reduce token overhead
Remove standalone sections (MSBuild Server, Inline Tasks,
ResolveProjectReferences, Incrementality Anti-patterns) that add
~1400 extra tokens without benefiting the evaluated scenario.
Consolidate Quick Wins checklist accordingly.
These sections can be contributed as separate skills in follow-up PRs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add separate skills for MSBuild server, inline tasks, and ResolveProjectReferences
Extract content removed from build-perf-diagnostics into standalone skills
to keep each skill focused and avoid token budget bloat:
- msbuild-server: MSBUILDUSESERVER=1 for CLI incremental caching
- inline-task-overhead: RoslynCodeTaskFactory ~1s overhead vs ~3ms compiled
- resolve-project-references: misleading Target Performance Summary time
(dotnet/msbuild#3135), guides users to Task Performance Summary instead
Incrementality anti-patterns content was not extracted as a separate skill
because the existing incremental-build skill already covers that area.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add github.com/dotnet/msbuild to known-domains.txt
Required by reference scanner for MSBuild issue links in
build-perf-diagnostics and resolve-project-references skills.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Replace full dotnet/msbuild URLs with shorthand notation
The reference scanner reads known-domains.txt from upstream main,
not from the PR branch. Use shorthand 'dotnet/msbuild#NNNN' format
(consistent with the rest of the file) instead of full URLs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review comments and fix reference scanner errors
- Remove https://aka.ms/devdrive URLs that trigger reference scanner
- Soften unsourced benchmark claims (OrchardCore Copy tasks, 20s+
restore savings, 40%/20% graph shape improvements) per reviewer
feedback to use workload-dependent language instead
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add eval tests for new skills; remove inline-task-overhead
Add eval.yaml and test fixtures for msbuild-server and
resolve-project-references skills:
- msbuild-server: tests CLI build perf scenario with developer report
- resolve-project-references: tests misleading target perf summary
with multi-project setup and perf report
Remove inline-task-overhead skill: failed 3 evaluation iterations
(avg +2.7%) because the baseline LLM already knows about
RoslynCodeTaskFactory overhead — the skill doesn't add enough
unique value to meet the 10% improvement threshold.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Address review comments
- Add caveat that DisableTransitiveProjectReferences may require
adding direct references for consumed types
- Fix escaped quotes in Quick Wins RunAnalyzers checklist item
- Add OutputType=Exe and Main entry point to msbuild-server fixture
- Change 'solution' to 'project' in resolve-project-references report
- Trim trailing spaces in developer-report.md
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Restore accidentally removed known-domains.txt
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix remaining review comments
- Quote -flp argument in resolve-project-references bash example
to handle semicolons in POSIX shells
- Format LibA/Class1.cs and LibB/Class1.cs across multiple lines
for consistency with other test fixtures
- Rename msbuild-server/Program.cs to Calculator.cs to match content
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- msbuild-antipatterns: Move AP-16 through AP-21 and checklist to
references/additional-antipatterns.md (body: 384 lines, was 583)
- directory-build-organization: Replace cross-skill reference to
../msbuild-antipatterns/SKILL.md with local reference file
references/targetframework-props-pitfall.md
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>