{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/item-management",
  "version": "1.0.0",
  "name": "item-management",
  "description": "Patterns for managing MSBuild item groups: Include/Remove/Update semantics, item metadata, batching with %(Metadata), transforms, per-item filtering, and cross-product batching pitfalls. Only activate in MSBuild/.NET build context. USE FOR: diagnosing and fixing item group anti-patterns in .csproj files, reviewing item management for correctness, fixing CS2002 duplicate file warnings from SDK globbing, fixing targets that run more times than expected due to cross-product batching, fixing Include vs Update misuse on SDK-globbed items, fixing FileWrites registration for generated file clean support, moving generated files to IntermediateOutputPath. DO NOT USE FOR: target chain architecture (use target-authoring), property patterns (use property-patterns), incrementality (use incremental-build), general anti-patterns (use msbuild-antipatterns), non-MSBuild build systems.",
  "system_prompt_fragment": "# MSBuild Item Management Patterns\n\nCanonical patterns for working with item groups, from `Microsoft.Common.CurrentVersion.targets`.\n\n## Include / Remove / Update — Three Operations\n\n| Operation | Purpose | When to use |\n|---|---|---|\n| `Include` | Add new items to the group | Creating items with identity + metadata |\n| `Remove` | Remove items matching a pattern | Excluding files or clearing a group |\n| `Update` | Modify metadata on existing items | Adding/changing metadata without re-adding |\n\n### Include — Add Items\n\n```xml\n<ItemGroup>\n  <Compile Include=\"Generated\\*.cs\">\n    <AutoGen>true</AutoGen>\n  </Compile>\n</ItemGroup>\n```\n\n### Remove — Subtract Items\n\n```xml\n<ItemGroup>\n  <!-- Remove specific items -->\n  <Reference Remove=\"$(AdditionalExplicitAssemblyReferences)\" />\n\n  <!-- Set subtraction: prior minus current -->\n  <_CleanOrphanFileWrites Include=\"@(_CleanPriorFileWrites)\"\n      Exclude=\"@(_CleanCurrentFileWrites)\" />\n\n  <!-- Clear an entire group -->\n  <_Temporary Remove=\"@(_Temporary)\" />\n</ItemGroup>\n```\n\n### Update — Modify Existing Items\n\n```xml\n<ItemGroup>\n  <EmbeddedResource Update=\"@(EmbeddedResource)\"\n      Condition=\"'%(NuGetPackageId)' == 'Microsoft.CodeAnalysis.Collections'\">\n    <GenerateSource>true</GenerateSource>\n    <ClassName>Microsoft.CodeAnalysis.Collections.SR</ClassName>\n  </EmbeddedResource>\n</ItemGroup>\n```\n\n`Update` does not add items — it only modifies items already in the group.\n\n## Item Batching — %(Metadata)\n\nWhen `%(Metadata)` appears in target attributes or task parameters, MSBuild **batches** execution per unique metadata value.\n\n### Target-level batching (Outputs)\n\n```xml\n<Target Name=\"GenerateSatelliteAssemblies\"\n    Inputs=\"$(MSBuildAllProjects);@(_SatelliteAssemblyResourceInputs)\"\n    Outputs=\"$(IntermediateOutputPath)%(Culture)\\$(TargetName).resources.dll\">\n  <!-- Runs once per unique Culture value -->\n</Target>\n```\n\n### Task-level batching\n\n```xml\n<Copy SourceFiles=\"@(_SourceItems)\"\n    DestinationFiles=\"@(_SourceItems->'$(OutDir)%(TargetPath)')\">\n</Copy>\n```\n\n### Per-item filtering with Condition\n\n```xml\n<ItemGroup>\n  <_ResxOutput Include=\"@(EmbeddedResource->'%(OutputResource)')\"\n      Condition=\"'%(EmbeddedResource.WithCulture)' == 'false'\" />\n</ItemGroup>\n```\n\n### Batching rules\n\n- `%(Metadata)` in `Condition` or `Outputs` → target batches per unique value.\n- `%(Metadata)` in task parameters → task batches per unique value.\n- **Do not mix `%()` from different item groups** in the same expression — this causes a cross-product (see Common Pitfalls).\n\n## Item Transforms — @(Item->'expression')\n\nTransforms create new item lists by applying an expression to each item:\n\n```xml\n<!-- Transform file paths to destinations -->\n<Copy SourceFiles=\"@(IntermediateAssembly)\"\n    DestinationFiles=\"@(IntermediateAssembly->'$(OutDir)%(Filename)%(Extension)')\"/>\n\n<!-- Transform with separator for display -->\n<Message Text=\"Files: @(Compile->'%(Filename)', ', ')\" />\n```\n\n## Exclude Pattern — Set Subtraction on Include\n\n```xml\n<ItemGroup>\n  <Compile Include=\"**\\*.cs\" Exclude=\"Generated\\**;Tests\\**\" />\n</ItemGroup>\n```\n\n`Exclude` only works on `Include` — it cannot be used with `Update` or `Remove`.\n\n## Conditional Item Inclusion\n\n```xml\n<!-- Condition on ItemGroup — all or nothing -->\n<ItemGroup Condition=\"'$(NetCoreBuild)' == 'true'\">\n  <PackageReference Include=\"System.IO.Pipelines\" />\n</ItemGroup>\n\n<!-- Condition on individual items -->\n<ItemGroup>\n  <PackageReference Include=\"System.IO.Pipelines\"\n      Condition=\"'$(NetCoreBuild)' == 'true'\" />\n</ItemGroup>\n```\n\n## PrivateAssets on Tool/Analyzer Packages\n\n```xml\n<ItemGroup>\n  <PackageReference Include=\"Microsoft.CodeAnalysis.NetAnalyzers\" PrivateAssets=\"all\" />\n  <PackageReference Include=\"StyleCop.Analyzers\" PrivateAssets=\"all\" />\n</ItemGroup>\n```\n\n## Common Pitfalls\n\n### Cross-product batching\n\nReferencing `%(Metadata)` from two different item groups creates O(N×M) executions:\n\n```xml\n<!-- BAD: Cross-product of @(Source) × @(Config) -->\n<Exec Command=\"process %(Source.Identity) with %(Config.Identity)\" />\n\n<!-- GOOD: Reference one group via batching, the other via property -->\n<Exec Command=\"process %(Source.Identity) with $(ConfigFile)\" />\n```\n\n### Generated files in source tree\n\nWrite to `$(IntermediateOutputPath)` (obj/), not the source directory. Source-tree generation pollutes version control and can cause duplicate compilation via globs.\n\n### Missing FileWrites\n\nEvery file created during a target must be added to `@(FileWrites)` for `dotnet clean` support.",
  "applicable_domains": [
    "code",
    "dotnet",
    "engineering"
  ],
  "invocation": [
    "/item-management"
  ],
  "tags": [
    "dotnet-msbuild",
    "dotnet",
    "csharp",
    "microsoft"
  ],
  "authored_by": "anthropics",
  "source_url": "https://github.com/dotnet/skills/blob/main/plugins/dotnet-msbuild/skills/item-management/SKILL.md",
  "lifecycle": "stable",
  "category": "dotnet",
  "provenance": {
    "source": "dotnet/skills",
    "source_url": "https://github.com/dotnet/skills/blob/main/plugins/dotnet-msbuild/skills/item-management/SKILL.md",
    "author": "Microsoft / .NET Foundation",
    "license": "MIT",
    "notes": "Imported by scripts/import-anthropic-skills.py."
  }
}