csharp-scripts
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C#…
Remove repeated NuGet restores from multi-step .NET builds safely. USE FOR: build/test/publish steps that each restore, Directory.Build.rsp with -restore, safe restore suppression, NETSDK1004/NETSDK1047 after --no-restore. DO NOT USE FOR: slow first restore, only one restore,
$ npx -y skills add dotnet/skills --skill eliminate-redundant-restores --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/eliminate-redundant-restoresContext preview
The summary Claude sees to decide when to auto-load this skill.
Remove repeated NuGet restores from multi-step .NET builds safely. USE FOR: build/test/publish steps that each restore, Directory.Build.rsp with -restore, safe restore suppression, NETSDK1004/NETSDK1047 after --no-restore. DO NOT USE FOR: slow first restore, only one restore,
name: eliminate-redundant-restores description: "Remove repeated NuGet restores from multi-step .NET builds safely. USE FOR: build/test/publish steps that each restore, Directory.Build.rsp with -restore, safe restore suppression, NETSDK1004/NETSDK1047 after --no-restore. DO NOT USE FOR: slow first restore, only one restore, version or lock errors, unranked build slowness (use build-perf-baseline)." license: MIT
A no-op restore still evaluates every project and checks restore state, so each extra restore in a multi-step build costs seconds to tens of seconds in a large repo. The cure is easy to get wrong: `--no-restore` on a step that no earlier restore actually covered turns a slow build into a failed one. This skill finds which invocations restore, proves which are already covered, and changes only those.
Discover repository inputs in the working directory; do not ask the user for paths.
| Invocation | Restores? | |---|---| | `dotnet build`, `test`, `publish`, `pack` | Implicitly, unless `--no-restore`; also check inherited rsp flags | | `dotnet run` | Implicitly before building; `--no-restore` can still inherit rsp restore on older SDKs. With `--no-build`, no build or restore runs | | `dotnet test`, `publish`, `pack` with `--no-build` | No implicit restore, but an rsp `-restore` can still enable restore; add `--no-restore -restore:false` | | `dotnet msbuild`, `msbuild.exe`, CI MSBuild tasks | With `-restore` or `-t:Restore`, including flags inherited from repository `Directory.Build.rsp` or installation-level `MSBuild.rsp`, even when a step looks build-only | | `dotnet restore`, `nuget restore`, `msbuild -t:Restore` | Explicit restore | | CI build task with a "restore packages" option | Check its default |
Starting with .NET SDK 9.0.1xx, `--no-restore` forwards `-restore:false` to override rsp flags; older SDKs can still inherit `-restore` despite skipping the CLI's implicit restore. Whenever an rsp enables restore, use the version-independent `--no-restore -restore:false` with `dotnet build`, `test`, `publish` or `pack`, even with `--no-build`. `dotnet msbuild` and `msbuild.exe` take `-restore:false`, not `--no-restore`.
`dotnet run` does not expose the MSBuild `-restore:false` override. With an rsp on older SDKs, first build using `dotnet build --no-restore -restore:false`, then run using `dotnet run --no-build` with the same project, configuration, framework and runtime inputs (or execute the built DLL directly). Passing `-restore:false` to `dotnet run` is not a restore-suppression strategy.
Keep the first restore. Skip a later one only when all four checks pass:
| Check | If it fails | |---|---| | **Same project set.** A restore covers its entry project or solution and that project's ProjectReference closure. It does not cover a project in another solution or `.slnf`, a tool built from another path, or a project an orchestrating `.proj` builds through the `MSBuild` task (`-restore` on the orchestrator leaves those unrestored and they fail with NETSDK1004) | Keep restore on that step, or add the project to the explicit restore step | | **Same restore inputs.** `-r`/`--runtime`, RID-producing `-a`/`--arch`, `--os`, `--ucr`/`--use-current-runtime`, `TargetFramework(s)`, `RuntimeIdentifier(s)`, `PublishAot`, package sources (`--source`, `--configfile`, `RestoreSources`), `RestorePackagesPath`, and any `-p:` value a PackageReference condition reads. Architecture/OS options combine with the SDK's current RID; `--use-current-runtime` selects it. Missing RID targets fail with NETSDK1047 (`Assets file ... doesn't have a target for 'net10.0/linux-x64'`) | Match the effective RID in the explicit restore (for example `publish --os linux --arch x64` requires `restore -r linux-x64`), or keep restore on the later step. A generic restore does not cover these aliases merely because there is no `-r`. Do not require `SelfContained=true` on restore solely because publish is self-contained: RID-only restore covers ordinary SDK projects. M
This repository contains the .NET team's curated set of portable skills and host-specific custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io.
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C#…
Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string…
Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR:…
Design, implement, optimize, and review SIMD code in .NET. USE FOR: vectorizing scalar loops with TensorPrimitives,…
Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET,…
Guides conversion of a pre-.NET 8 Blazor Server app into a .NET 8+ Blazor Web App. USE FOR: migrating apps that use…