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# language/API experiments, one-file…
MANDATORY for static source-to-test pairing: find or list source files/modules without corresponding tests, or suggest test locations from repository structure. Invoke even for a tiny package; do not substitute manual globbing. Uses Roslyn for C#/.NET and tree-sitter for Python,
$ npx -y skills add dotnet/skills --skill find-untested-sources --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/find-untested-sourcesContext preview
The summary Claude sees to decide when to auto-load this skill.
MANDATORY for static source-to-test pairing: find or list source files/modules without corresponding tests, or suggest test locations from repository structure. Invoke even for a tiny package; do not substitute manual globbing. Uses Roslyn for C#/.NET and tree-sitter for Python,
name: find-untested-sources description: > MANDATORY for static source-to-test pairing: find or list source files/modules without corresponding tests, or suggest test locations from repository structure. Invoke even for a tiny package; do not substitute manual globbing. Uses Roslyn for C#/.NET and tree-sitter for Python, TS/JS, Go, Java, Rust, Ruby, Kotlin, Swift, PowerShell, and C++. DO NOT USE FOR: real line/branch/Cobertura data, coverage-backed test priorities, CRAP risk, or grading existing tests. license: MIT
Coverage tools answer "which lines were executed?" — they require a green build and a passing test run, which is minutes-to-tens-of-minutes on a real repo. The question this skill answers is different and much cheaper:
> _Which source files have no test file referencing any of their declared > types/symbols?_
That's the question an agent asks **before** writing a new test — and it can be answered statically in a few seconds by parsing source files, with **no build, no dependency resolution, and no compilation**. The output is a deterministic test-pairing map that lets the agent pick the next file to test without reading the entire codebase first.
This skill ships two interchangeable analyzers with a compatible JSON contract:
| Engine | Script | Use when | |--------|--------|----------| | **Roslyn (C#)** | `scripts/Find-UntestedSources.cs` | The repo is **.NET-only**. Parses every `.cs` file with the Roslyn syntax API and does strict **namespace disambiguation**, so it is materially more accurate on duplicated short names like `Settings` or `Context`. | | **tree-sitter (polyglot)** | `scripts/find_untested_sources.py` | The repo is **not exclusively C#**, or you want one tool across C#, Python, TypeScript/JavaScript, Go, Java, Rust, Ruby, Kotlin, Swift, PowerShell, and C++. |
For a .NET-only repository, **prefer the Roslyn engine** — its namespace-aware pairing beats the polyglot engine's identifier overlap.
1. Use the narrowest repository or package root named by the caller. Do not scan a parent workspace when the request identifies a subdirectory. 2. Execute the appropriate analyzer once. Do not replace analyzer execution with manual globbing, filename matching, or visual inspection. For polyglot analysis, pass `--include-tested` when the answer must distinguish paired sources from unpaired sources. "Static pairing only" prohibits compiling the target repository and running its tests; it does not prohibit launching this skill's parse-only analyzer. State that distinction briefly when the caller also says "do not build." Treat analyzer dependencies as environment prerequisites: do not install packages, try the wrong engine, build the repository, or fall back to a manual scan when an analyzer invocation fails. Report the prerequisite failure instead. 3. Base the result on the analyzer's JSON. Preserve its paired/unpaired classification and suggested relative path; do not guess a different path. 4. When the caller named a subdirectory, prefix analyzer-relative paths with that subdirectory so reported paths are workspace-relative. 5. Report the requested result plus the static-pairing coverage caveat. Do not append build, package-install, test-run, or coverage commands. When paired sources exist, name their covering test files so the unpaired classification is auditable.
have no tests?", "find unpaired source files", or "give me a static test gap list".
follow-up depth checks.
or `assertion-quality`.
repo's `global.json` (SDK 11 preview or later).
`Microsoft.CodeAnalysis.CSharp` on first run.
# From the skill folder dotnet run scripts/Find-UntestedSources.cs -- <repo-root> [--top N] # Save the report dotnet run scripts/Find-UntestedSources.cs -- <repo-root> > pairing.json # Iterate the untested list, highest-API-surface first $report = Get-Content pairing.json | ConvertFrom-Json $report.untested | Select-Object -First 10 source, decl_count, suggested_test_path
Diagnostics go to stderr; JSON goes to stdout.
{
"repo": "<absolute path>",
"elapsed_ms": 8883,
"counts": {
"source_files": 3036,
"test_files": 867,
"untested_files": 1852,
"paired_files": 1184
},
"untested": [
{
"source": "src/Foo/Bar.cs",
"decl_count": 8, // # of type declarations in the file
"suggested_test_path": // mirror of source under a discovered test project
"tests/Foo.Tests/Bar/BarTests.cs"
}
],
"source_to_tests": {
"src/Foo/Baz.cs": [
"tests/Foo.Tests/BazTests.cs",
"tests/Foo.IntegrationTests/Scenarios/BazScenarios.cs"
]
}
}1. **File discovery** — recursive walk pruning `bin/`, `obj/`, `node_modules/`, `.git/`, `.vs/`, `packages/`, and any dotted subdir. Skips generated files (`.g.cs`, `.Designer.cs`, `.AssemblyInfo.cs`). 2. **Test vs source classification** — walks up to the nearest `.csproj` and marks it a test project if the project name ends in `.Tests
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.
Repo: dotnet/skills
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C# language/API experiments, one-file…
Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string marshalling, memory lifetime,…
Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR: trusted publishing, NuGet…
Design, implement, optimize, and review SIMD code in .NET. USE FOR: vectorizing scalar loops with TensorPrimitives, Vector64/128/256/512, or platform hardware…
Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET, Microsoft.Extensions.AI (MEAI), Microsoft Agent…
Configure OpenTelemetry distributed tracing, metrics, and logging in ASP.NET Core using the .NET OpenTelemetry SDK. Use when adding observability, setting up…