dotnet-pilot — плагин для Claude Code: функции и установка
Плагин помогает вести разработку .NET-проектов: от проверки архитектуры и DI до миграций EF Core. Пригодится, когда агенту нужно учитывать структуру решения и существующие соглашения.
/plugin marketplace add anthropics/claude-plugins-community
/plugin install dotnet-pilot@claude-communityЧто делает dotnet-pilot
Команды dotnet-pilot запускают специализированных агентов, а те используют MCP-сервер Roslyn для анализа C#: проверяют DI, архитектурные нарушения, модели EF Core и ссылки на символы. Есть команды для инициализации проекта, создания сущностей и миграций, а также проверки готовности к релизу. Хуки реагируют на изменения файлов и события Git, но по умолчанию не блокируют работу.
Для Roslyn MCP-сервера нужна установленная .NET-утилита DotnetPilot.Mcp.Roslyn и файл .sln или .slnx в рабочей директории. Плагин автоматически запускает сервер при загрузке Claude Code. Без решения в текущей директории сервер не запустится. Инициализация записывает config.json и solution-map.json в пользовательскую .planning/, а не в репозиторий; Context7 рекомендуется для доступа агентов к актуальной документации NuGet, ASP.NET Core и EF Core.
Какие задачи решает
- проверить регистрацию зависимостей в DI
- найти нарушения чистой архитектуры
- создать сущность по свойствам проекта
- добавить миграцию EF Core через CLI
- проверить сборку и тесты перед отправкой изменений
Примеры запросов агенту
- Инициализируй решение и сохрани карту проектов:
/dotnet-pilot:project:init - Создай сущность
Categoryсо свойствамиName:stringиSortOrder:int:/dotnet-pilot:dotnet:create-entity Category --properties 'Name:string, SortOrder:int' - Проверь сборку, тесты, DI и архитектуру перед отправкой:
/dotnet-pilot:project:verify
Как установить dotnet-pilot
Через маркетплейс плагинов
/plugin marketplace add anthropics/claude-plugins-community/plugin install dotnet-pilot@claude-communityПо шагам, с командами для каждой платформы: Плагины Claude Code: маркетплейсы, установка и как собрать свой
Вопросы о dotnet-pilot
Как установить dotnet-pilot в Claude Code?
Выполните команды по порядку: /plugin marketplace add anthropics/claude-plugins-community, затем /plugin install dotnet-pilot@claude-community.
Что делает dotnet-pilot?
Плагин оркестрирует .NET-задачи через команды и специализированных агентов. Roslyn MCP-сервер анализирует код, а хуки дают обратную связь при изменениях файлов и событиях Git.
Что нужно для работы Roslyn MCP-сервера?
Установите глобальную .NET-утилиту DotnetPilot.Mcp.Roslyn; в рабочей директории должен находиться файл .sln или .slnx. Context7 рекомендуется для документации NuGet, ASP.NET Core и EF Core.
Исходный текст
SKILL.md · MIT
# 🚀 DotnetPilot
**A .NET development assistant plugin for [Claude Code](https://claude.ai/code)**
Roslyn-backed DI verification · EF Core migration safety · Clean-architecture enforcement · Convention-aware scaffolders
[](./LICENSE) [](https://dotnet.microsoft.com/) [](https://claude.ai/code) [](.)
*16 commands · 9 specialized agents · 15 skill packs · 16 Roslyn MCP tools*
---
## Quick Install
```
/plugin marketplace add zdanovichnick/dotnet-pilot
/plugin install dotnet-pilot@dotnet-pilot-marketplace
/reload-plugins
```
```
dotnet tool install -g DotnetPilot.Mcp.Roslyn # first install
dotnet tool update -g DotnetPilot.Mcp.Roslyn # update to latest
```
**Strongly recommended — enable auto-update** (one-time setup). GitHub-sourced marketplaces have auto-update disabled by default; without this step you'll have to update manually each release. Add to `~/.claude/settings.json`:
```json
{
"extraKnownMarketplaces": {
"dotnet-pilot-marketplace": { "autoUpdate": true }
}
}
```
That's it. Open Claude Code in your `.sln` / `.slnx` directory and run `/dotnet-pilot:utility:help`.
---
## Why DotnetPilot?
AI coding tools make these .NET mistakes constantly — DotnetPilot fixes them at the source:
| Without DotnetPilot | With DotnetPilot |
| --- | --- |
| Creates services, forgets DI registration | `dnp-di-wiring-checker` catches it immediately |
| Manually edits EF migration files (breaks the chain) | `add-migration` always uses `dotnet ef migrations add` |
| Puts domain models in the wrong project layer | `dnp-architect` enforces clean architecture in real time |
| Skips `dotnet build` verification | Build hook verifies after every scaffold |
| Ignores existing patterns in your codebase | Every scaffolder reads your conventions before writing code |

---
## 📦 Installation
### Step 1 — Install the plugin
```
/plugin marketplace add zdanovichnick/dotnet-pilot
/plugin install dotnet-pilot@dotnet-pilot-marketplace
/reload-plugins
```

**Verify it worked:**
```
/dotnet-pilot:utility:help → should list 16 commands
/dotnet-pilot:dotnet:health-check → validates build, tests, DI, architecture
```
**Keeping it up to date.**
**Easiest:** Open the plugin manager (`/plugin` → Installed tab → `dotnet-pilot`) and click **"Update now"**. Then `/reload-plugins` to activate.
**CLI alternative:**
```
/plugin marketplace update dotnet-pilot-marketplace
/reload-plugins
```
**Auto-update** (GitHub-sourced marketplaces disable it by default). Enable once via the `/plugin` UI (Marketplaces tab → `dotnet-pilot-marketplace` → Enable auto-update), or persist it in `.claude/settings.json`:
```json
{
"extraKnownMarketplaces": {
"dotnet-pilot-marketplace": { "autoUpdate": true }
}
}
```
> Once the plugin lands in `claude-plugins-official`, the install collapses to `/plugin install dotnet-pilot` — auto-update on by default.
**Alternative: install from a local clone**
Use this when you cloned the repo and want to run your own build, or contribute changes.
```
# Windows (type in Claude Code chat)
/plugin marketplace add C:\path\to\dotnet-pilot
# macOS / Linux
/plugin marketplace add /path/to/dotnet-pilot
```
Then activate:
```
/plugin install dotnet-pilot@dotnet-pilot-marketplace
/reload-plugins
```
Session-only (plugin active only while this Claude Code process is running):
```
# Windows
claude --plugin-dir "C:\path\to\dotnet-pilot"
# macOS / Linux
claude --plugin-dir "/path/to/dotnet-pilot"
```
> After editing plugin source (commands, agents, hooks), run `/reload-plugins` to pick up changes without restarting.
### Step 2 — Install the Roslyn MCP server
```
dotnet tool install -g DotnetPilot.Mcp.Roslyn # first install
dotnet tool update -g DotnetPilot.Mcp.Roslyn # update to the latest release
```
The plugin's `.mcp.json` auto-starts `dnp-roslyn` when Claude Code loads. It requires a `.sln` or `.slnx` file in your working directory.
### Step 3 — Enable Context7 (recommended)
In Claude Code, enable the **Context7** MCP server at the account level — agents use it for live NuGet / ASP.NET Core / EF Core documentation.
### Step 4 — Verify
```
/dotnet-pilot:utility:help → should list 16 commands
/dotnet-pilot:dotnet:health-check → validates build, tests, DI, architecture
```
---
## ⚡ Quick Start
### Initialize your project (once per solution)
```
/dotnet-pilot:project:init
```
Scans your solution, detects architecture style / test framework / EF contexts, and writes `config.json` plus `solution-map.json` into a user-scoped `.planning/` directory — nothing lands in the repo.
### Create a full entity in one command

### Or go even faster with the shorthand
```
/dotnet-pilot:dotnet:create-entity Category --properties 'Name:string, SortOrder:int'
/dotnet-pilot:dotnet:scaffold api Category
/dotnet-pilot:dotnet:add-migration AddCategoryTable
```
---
## 🗺️ Architecture

**Flow:** Developer invokes a `/dotnet-pilot:*` command → the command spawns the right agent → the agent calls the Roslyn MCP server for semantic C# analysis (DI completeness, architecture violations, EF Core models, symbol references). Hooks run automatically on file writes and git events, feeding advisory feedback back to the command layer — they never block by default.
> **v2.0.0 breaking change:** Commands were renamed for clarity. `pipeline:*` → `project:*`, `scaffold-*` → `create-*`, `audit-*` → `check-*`, and several others. See the tables below for full mapping.
>
> **v3.0.0 breaking change:** 13 commands and 6 agents were removed or folded into survivors. `/dotnet-pilot:utility:help` prints a "Did you mean" table mapping every old command name to its replacement; `CHANGELOG.md` has the full list.
---
## 📋 Commands
### Project — project lifecycle
| Command | Usage | What it does |
| --- | --- | --- |
| `project:init` | `/dotnet-pilot:project:init [--refresh]` | Initialize for a .NET solution — discover projects, write the user-scoped `.planning/` (`config.json`, `solution-map.json`) |
| `project:verify` | `/dotnet-pilot:project:verify [--quick]` | Verify readiness before shipping — build, tests, DI completeness, architecture check. `--quick` is the pre-commit form: adds the format check, downgrades DI/architecture to warnings |
| `project:ship` | `/dotnet-pilot:project:ship [--draft]` | Create a pull request for completed work — runs final checks and invokes `gh pr create` |
### Dotnet — scaffolding & solution management
| Command | Usage | What it does |
| --- | --- | --- |
| `dotnet:scaffold` | `scaffold [feature\|api\|service\|project] <Name> [--arch vsa\|clean\|ddd]` | Detect the solution's architecture via Roslyn, then scaffold a feature (default), an API surface over an entity (`--minimal` for minimal APIs), a service with interface + DI registration (`--lifetime`), or a new project (`--type`) |
| `dotnet:create-entity` | `create-entity <name> [--properties '...']` | Create a full entity stack: entity class, EF configuration, repository, service, and DI registration, then hand off to `dotnet:add-migration` for the migration |
| `dotnet:add-endpoint` | `add-endpoint <controller> <method> <route> [--with-dto]` | Add an endpoint to an existing controller or endpoint group |
| `dotnet:add-migration` | `add-migration <name> [--context <Name>]` | Generate an EF Core migration safely — checks for pending migrations, runs `migrations add` with `--context`, has `dnp-ef-migration-planner` inspect the generated `Up()` and removes the migration if it is destructive, then builds and emits an idempotent `migrations script` for review |
| `dotnet:tdd` | `tdd <task> [--complexity easy\|hard] [--existing <target>]` | Implement a feature using TDD — failing tests first, then production code. `--existing` adds tests to a class, file, or project that already exists without touching production code |
| `dotnet:run-tests` | `run-tests [project] [--coverage] [--filter ...]` | Run tests with coverage reporting and failure diagnosis |
| `dotnet:health-check` | `health-check [--fix]` | Validate full solution health — build, tests, NuGet, project references, DI completeness |
### Quality — safety checks
| Command | Usage | What it does |
| --- | --- | --- |
| `quality:review` | `review [--base <ref> \| --staged \| --last-commit \| --scope <glob>] [--depth quick\|standard\|deep]` | Sharded, Workflow-backed .NET review — haiku scouts per diff shard (shards validated in JS from the preflight manifest), opus confirmers per finding (routed to the specialist agent for security / performance / DI / architecture), one deterministic digest that names every coverage gap |
| `quality:check-architecture` | `/dotnet-pilot:quality:check-architecture` | Scan for clean architecture layer violations — forbidden project references, DI issues, package placement |
| `quality:security-scan` | `/dotnet-pilot:quality:security-scan` | Three-phase audit: `dotnet list package --vulnerable` → `dnp-security-auditor` OWASP scan → combined CRITICAL findings report |
| `quality:de-sloppify` | `de-sloppify [--scope path]` | Safe refactoring pass — dead code removal, naming normalization, duplication elimination. Requires tests passing first |
> `quality:review` is Workflow-backed. A Node preflight (`scripts/dnp-review-preflight.js`, Node ≥18, no deps) shards the selected diff and the command hands the manifest's shards to the workflow, which validates them in JS (falling back to per-file, then whole-diff units); haiku scouts read each shard, near-duplicate findings are merged, opus confirmers try to refute every finding against the source, and a fixed-format digest reports confirmed, refuted and unconfirmed findings plus every coverage gap — same change set, same report shape, every run. `--depth quick` stops after the scouts (≤6 agents), `standard` adds one confirmer per finding (≤11), `deep` adds four lens sweeps (≤20). Artifacts land in `${CLAUDE_PLUGIN_DATA}/review/<runId>/`; if Claude Code prompts on every run, allow the permission rule `Workflow(dnp-review)`.
### Utility — housekeeping
| Command | Usage | What it does |
| --- | --- | --- |
| `utility:help` | `/dotnet-pilot:utility:help` | Print the version banner, every command with its arguments, the agent / skill / hook rosters (each hook with its `hooks.*` toggle key), and a "Did you mean" table for command names removed in v3.0.0 |
| `utility:statusline` | `statusline [--manual]` | Install the .NET-aware statusline and wire it into `~/.claude/settings.json` (backs up any existing statusLine) |
---
## 🤖 Agents
Commands are thin orchestrators — all heavy work happens in one of these 9 agents, each with scoped tool access, a model tier, and a reasoning-effort level.
**Effort** is the second half of routing. Model tier sets *capability*; `effort:` sets how much reasoning is spent within that tier — so a mechanical check runs cheap on a capable model instead of being pushed onto a weaker one. Levels: `low` → `medium` → `high` → `xhigh` → `max`.
### Implementation
| Agent | Model | Effort | Role |
| --- | --- | --- | --- |
| `dnp-tdd-developer-easy` | Sonnet | low | Fast TDD for routine .NET tasks — writes both tests and production code following RED-GREEN-REFACTOR; also the worker behind `dotnet:scaffold` and `dotnet:add-endpoint` |
| `dnp-tdd-developer-hard` | Opus | medium | Deep TDD for complex .NET tasks — architectural decisions, ambiguous edge cases, cross-layer integration. Returns `[HALT: <question>]` instead of guessing when a design choice is underdetermined |
| `dnp-refactor-cleaner` | Sonnet | high | Dead code removal, naming normalization, duplication elimination — behavior preserved, verified by tests after each step |
### Architecture & data
| Agent | Model | Effort | Role |
| --- | --- | --- | --- |
| `dnp-architect` | Opus | high | Solution architecture, clean-arch layer enforcement, project-reference and package-placement validation; advises on architectural `[HALT` questions from `dotnet:tdd` and confirms architecture findings in `quality:review` (loads the `clean-architecture` skill) |
| `dnp-ef-migration-planner` | Sonnet | low | Plans safe EF Core migrations — detects breaking changes, validates chain integrity, targets correct DbContext (loads the `ef-core-patterns` skill) |
### Review confirmers (fast, focused)
| Agent | Model | Effort | Role |
| --- | --- | --- | --- |
| `dnp-security-auditor` | Sonnet | high | OWASP Top 10 for .NET APIs — injection, secrets exposure, auth config, CORS, dependencies, input validation; judges a single routed finding when given a focused brief |
| `dnp-performance-analyst` | Sonnet | high | Async hotspots, EF Core N+1 queries, missing `CancellationToken`, caching gaps, benchmark design; judges a single routed finding when given a focused brief |
| `dnp-di-wiring-checker` | Sonnet | low | Cross-references constructor injection against DI registrations — finds missing services and captive dependencies; judges a single routed finding when given a focused brief |
| `dnp-nuget-auditor` | Sonnet | low | Scans for vulnerable, outdated, and version-inconsistent NuGet packages across the solution |
> Agents never prompt the user. A decision an agent cannot make comes back as `[HALT: <question>]`, and the command that spawned it asks you, then re-briefs the agent with the answer. For an architectural question, `dotnet:tdd` first asks `dnp-architect` and lists its pick as the recommended option.
>
> Every agent runs on Sonnet or Opus with an explicit `effort:`; the mechanical ones sit at `effort: low`. The `haiku` alias resolves to Haiku 5.5 (full effort support) on the Anthropic API but to Haiku 4.5 (no effort, the field is dropped) on Bedrock, Google Cloud, Foundry and Claude Platform on AWS, so moving an agent to Haiku waits on a measured comparison.
>
> Models are tier aliases (`opus`/`sonnet`), not dated IDs, so frontmatter tracks each tier's current default and needs no bump on a model release; the consistency check rejects anything else, because Claude Code's allowlist substitution covers aliases only.
---
## 🪝 Hooks
Hooks run automatically during Claude Code sessions. Advisory hooks warn but don't block, and they respect per-project toggle settings in `.planning/config.json`. The sync hook keeps the global `CLAUDE.md` up to date with the plugin's rule set. One hook (**Git Auto-Approve**) is non-advisory by design — it speaks the PreToolUse permission protocol to skip prompts on safe git/gh commands.
| Hook | Trigger | What it does |
| --- | --- | --- |
| **Global CLAUDE.md Sync** | On session start/resume/clear/compact | Injects/updates the DotnetPilot rule block in `~/.claude/CLAUDE.md` — replaces an existing block only when the plugin version is newer, and never rewrites an unparseable `settings.json`. Toggle `hooks.sync_global_claude_md: false` to disable |
| **Git Auto-Approve** | Before `git`/`gh` commands from the Bash tool | Returns `permissionDecision: allow` for single git/gh commands that pass a per-subcommand allowlist (status/diff/log/add/commit/branch/switch/push, read-only `gh pr`/`run`/`issue`/`repo` verbs, `gh pr create`, one exact heredoc-commit shape) so commit + PR run without a prompt. Falls through to the normal prompt for chained, multi-line or redirected commands; `$`, globs, braces or backslashes anywhere; force pushes and ref deletion; `--output`, `--ext-diff`, `-c`; `reset`/`restore`/`clean`, `checkout` other than `-b`, `git config`, `gh api`, `--no-verify` commits; and anything from the PowerShell tool. Toggle `hooks.git_autoapprove: false` to disable |
| **DI Registration Check** | After writing/editing `.cs` files | New services missing DI registration |
| **Migration Guard** | Before writing/editing migration files | Warns when manually editing EF migration files |
| **Project Scope Guard** | After writing/editing any file | Warns when editing outside the current phase's focused projects (`<Project>.Tests` counts as inside); at most one advisory per project per hour |
| **Build Verify** | After `dotnet build` / `dotnet test` runs — including ones that exit non-zero | Classifies the output by text markers, so builds piped through `2>&1 \| grep` still count; records consecutive failures in the per-solution state the statusline `BUILD ✗` segment reads; warns at 3, escalates at 5; a green run resets it. Toggle `hooks.build_verify: false` to disable |
| **Stop Verify** | When Claude is about to stop after editing `.cs`/`.csproj`/`.razor` files | If the tree has uncommitted source changes and no green `dotnet build`/`dotnet test` was recorded since the last edit, nudges with the exact commands to run before reporting done. Advisory; set `hooks.stop_verify_block: true` to make it block instead. Toggle `hooks.stop_verify: false` to disable |
| **Subagent Result** | When a `dnp-*` agent finishes | Surfaces `[HALT: …]`, `[PARTIAL …]` and `[ROUTING: …]` verdicts as a system message so a halted or truncated worker is not silently absorbed. Toggle `hooks.subagent_result: false` to disable |
| **Post-Edit Format** | After Write/Edit/MultiEdit on `.cs` files (formats at Stop) | Queues the saved file; at Stop runs `dotnet format --include <files>` once per project, so the file is not rewritten mid-turn; skips `obj/`, `bin/`, `Migrations/`, generated files |
| **Commit Format** | Before `git commit` (Bash or PowerShell tool) | Enforces `type(scope): message` conventional commit format |
| **Priority Router** | Before spawning an Agent | Detects .NET projects and injects DotnetPilot agent routing priority over generic equivalents; also steers C# code inspection to `mcp__roslyn__` over `mcp__*code-analyzer__`. Toggle `hooks.dotnet_priority: false` to disable |
| **Code-Analyzer Redirect** | Before a `code-analyzer` MCP tool call | When the call targets C# (a `.cs` file, a .NET `project_path`, or a .NET cwd), nudges toward the C#-aware `mcp__roslyn__` tools — the Python/TS/JS code-analyzer has no C# support. Advisory only; never blocks. Toggle `hooks.code_analyzer_redirect: false` to disable |
| **Build-failure toasts** *(mod)* | After `dotnet build` / `dotnet test` through the Bash or PowerShell tool | Same classification as Build Verify; shows a toast at the 3rd and 5th consecutive failure. Needs a Claude Code build with mod support; additive to the Node hook. Toggle plugin option `build_status` |
| **Routing roster** *(mod)* | Each system-prompt composition | In a .NET project, adds the routing guidance once per session as a session-scoped section. Needs mod support. With it active, set `hooks.dotnet_priority: false` to drop the per-`Agent` nudge. Toggle plugin option `routing` |
| **Pressure meter** *(mod)* | After `dotnet build`/`dotnet test`, Edit calls, and prompts | Scores the session 0–100 from red runs (+25/+30), re-edits of the same file after a red run (+10), corrections in your prompt (+10) and loosening test edits (+25); a green run takes 45 off. Shows `pressure N steady/strained/high` in the status line, `/dnp-pressure` lists the events. After a red run, an Edit to a test file that adds `Skip`, removes an assertion or a `[Fact]`, or comments an assertion out gets a toast; with `pressure_test_guard_block: true` it is denied while the score is ≥ 60. While the score is ≥ 60 a short system-prompt section asks for a stated blocker or `[HALT]` instead of another retry. Toggle plugin option `pressure` |
| **Pixel band** *(mod, opt-in)* | Terminal only, above the prompt | Animated pixel-art band in four scenes: **city** (windows light with tool activity), **beach** (sea, palm, sailboat, crab), **dino** (a T-rex that jumps the cacti and runs faster while tools run; meteors in a storm) and **sunset** (a time-lapse day over mountains and a lake). The sky follows the local clock, a failed `dotnet build`/`dotnet test` brings a storm and the next green run a 30-second rainbow, and a comet crosses at the end of each turn. `/city [city\|beach\|dino\|sunset\|next\|show\|hide\|status\|dawn\|day\|dusk\|night\|auto\|storm\|rainbow\|clear\|comet]`. Needs mod support and a terminal with at least 5 free rows. Off by default — enable **Pixel city band** (`pixel_city`) in `/config`; **Pixel band scene** (`pixel_city_scene`) picks the starting scene |
| **Statusline Sync** | On session start/resume/clear/compact | Refreshes the installed statusline script at `~/.claude/dnp-statusline.js` when the plugin ships a newer version. Only wires `~/.claude/settings.json` when `statusline.auto_enable: true` (default off) — never clobbers an existing statusLine without opt-in |

*The pixel band's scenes, top to bottom: `city` at night, `beach`, `dino`, `dino` in a storm, `sunset` just after sunrise.*
---
## 📊 Statusline
A compact, .NET-aware statusline. Install it with `/dotnet-pilot:utility:statusline`:
- **Line 1 (always):** `🤖 <model> │ ⚡ EFF <effort>[ (set: <configured>)] │ 🧠 <bar> <pct>% · <tokens> │ 🌿 <branch> ✚<dirty> ↑<ahead>↓<behind> │ ⏱ <elapsed> │ 💰 $<cost>`
- **Line 2 (only inside a .NET solution):** `📦 SLN <name> │ 🎯 TFM <framework> │ ❌ BUILD <n>x`
- **Line 3 (only inside a .NET solution):** `💡 TIP <rotating DotnetPilot command hint>` — a slowly-rotating pointer to the plugin's commands, for discovery
Every segment carries an emoji icon and a saturated color on its **value** (labels stay dim), so the data reads before the scaffolding. Three segments are threshold-colored rather than fixed: the 🧠 context bar and percentage (green → yellow → red past 50 / 75 / 90%), the ⚡ effort level (dim `low` up to bold red `max`), and the 💰 cost (green → yellow → red past \$2 / \$10). Set `NO_COLOR` for plain text.
`⚡ EFF <effort>` shows the **live per-turn** reasoning-effort level (`low`/`medium`/`high`/`xhigh`/`max`) when Claude Code pipes it — it reflects mid-session `/effort` changes and the resolved level under `auto` (not a static config value), and is color-coded by level (brightest at the top of the scale) so a change is obvious at a glance; omitted when the model doesn't support effort. When the level you configured is not the one in force, a yellow `(set: <configured>)` suffix names it — e.g. `EFF high (set: xhigh)`. A top-level `effortLevel` in `~/.claude/settings.json` counts as configured only on models released before Opus 5.5 (Claude Code ignores it from Opus 5.5 and Haiku 5.5 on); for newer models only `modelSettings[<model>].effortLevel` does.
`BUILD ✗ Nx` reflects the same failure state the **Build Verify** hook records (so it also surfaces `dotnet test` failures); absence means "no recent failure recorded", not a guaranteed green build.
Claude Code plugins cannot register a `statusLine` directly, and `${CLAUDE_PLUGIN_ROOT}` is not expanded in statusLine command strings — so the command installs the script to a stable path (`~/.claude/dnp-statusline.js`) and points `settings.json` at it. It detects and backs up any existing statusLine before replacing (or run with `--manual` to print the snippet instead). To activate automatically every session, set `statusline.auto_enable: true` in `.planning/config.json`; it coexists with — never silently replaces — another statusline unless you opt in. Honors `NO_COLOR`.
---
## 📚 Skill Packs
Skills are on-demand knowledge packs loaded by agents when needed — they encode .NET conventions that would otherwise require repeated prompting. Every `SKILL.md` carries a `when_to_use:` line so the right one loads on trigger, and the five largest (`authentication`, `caching`, `ddd`, `error-handling`, `resilience`) keep their detail in `references/*.md` files loaded one at a time.
| Skill | What it teaches |
| --- | --- |
| `aspnet-api-patterns` | Minimal APIs, controller patterns, `IExceptionHandler` + `AddProblemDetails`, built-in `AddOpenApi`, Asp.Versioning |
| `ef-core-patterns` | DbContext design, migrations, query optimization, owned entities |
| `testing-dotnet` | xUnit conventions, NSubstitute, `WebApplicationFactory` over Testcontainers, test tiers, mock fidelity |
| `clean-architecture` | Layer rules, project layout, dependency direction, shared kernel |
| `dotnet-project-init` | Solution setup, NuGet config, CI scaffolding |
| `modern-csharp` | C# 12–14 gotchas: `field` keyword, extension members, null-conditional assignment, span conversions, async and cancellation |
| `error-handling` | The single `Result<TValue,TError>` definition, RFC 9457 `ProblemDetails`, `IProblemDetailsService`-backed global handler, exception boundaries |
| `resilience` | Polly v8 `ResiliencePipelineBuilder`, retry, circuit breaker, timeout, hedging, `IHttpClientFactory` |
| `caching` | `HybridCache` (.NET 9+), `IOutputCache`, cache-aside, `IMemoryCache`, typed cache keys |
| `authentication` | JWT bearer, ASP.NET Identity, OIDC, policy-based auth, `IAuthorizationHandler` |
| `vertical-slice` | Feature folders, `IEndpointGroup`, endpoint filters, no shared base classes |
| `ddd` | `AggregateRoot<TId>`, value objects (`ComplexProperty` mapping), strongly-typed IDs, domain events via `TimeProvider`, repository-placement variants |
| `convention-learner` | 6-step protocol: detect naming, folder structure, DI style, test framework, DTO style, error handling before writing any code |
| `logging` | Serilog setup, message templates (not interpolation), `LogContext`, request logging, PII rules |
| `opentelemetry` | `ActivitySource`, `IMeterFactory`, OTLP config, Aspire `AddServiceDefaults()`, Serilog correlation |
---
## 📖 Use Cases
**1. Scaffold a CRUD entity end-to-end in 30 seconds**
```
> /dotnet-pilot:dotnet:create-entity Category --properties 'Name:string, Description:string?, SortOrder:int'
Created 9 files:
src/ECommerce.Domain/Entities/Category.cs
src/ECommerce.Infrastructure/Configurations/CategoryConfiguration.cs
src/ECommerce.Infrastructure/Data/ApplicationDbContext.cs (added DbSet<Category>)
src/ECommerce.Application/Interfaces/ICategoryRepository.cs
src/ECommerce.Infrastructure/Repositories/CategoryRepository.cs
src/ECommerce.Application/Interfaces/ICategoryService.cs
src/ECommerce.Application/Services/CategoryService.cs
src/ECommerce.Api/Extensions/ServiceCollectionExtensions.cs (2 DI registrations added)
Migration: 20260420_AddCategoryTable
Build: PASS · Tests: PASS · DI: PASS
> /dotnet-pilot:dotnet:scaffold api Category
Created 4 files:
src/ECommerce.Api/DTOs/CreateCategoryRequest.cs
src/ECommerce.Api/DTOs/CategoryResponse.cs
src/ECommerce.Api/Controllers/CategoriesController.cs
src/ECommerce.Api/Validators/CreateCategoryRequestValidator.cs
Build: PASS
```
**2. Safely migrate a project with multiple DbContexts**
```
> /dotnet-pilot:dotnet:add-migration AddCompanyNameToTenant
Multiple DbContexts detected. Which one?
1. ApplicationDbContext (Infrastructure, 12 entities)
2. TenantDbContext (Infrastructure, 4 entities)
→ 2
Checking for breaking changes...
Analysis: Adding nullable column CompanyName — safe, no data loss.
Chain: 7 existing migrations, chain valid.
Running: dotnet ef migrations add AddCompanyNameToTenant
--project src/ECommerce.Infrastructure
--startup-project src/ECommerce.Api
--context TenantDbContext
Build: PASS · Dry run: PASS
Committed: feat(Infrastructure): add migration AddCompanyNameToTenant
```
**3. Catch architecture violations before they ship**
```
> /dotnet-pilot:quality:check-architecture
Architecture Audit: ECommerce.slnx
Style: clean
Violations (1):
[ERROR] ECommerce.Domain → ECommerce.Infrastructure
Domain should not reference Infrastructure.
Fix: Move the shared helper to Domain, or create an interface
in Application that Infrastructure implements.
```
**4. Find and fix missing DI registrations**
```
> /dotnet-pilot:dotnet:health-check
DI Wiring: FAIL (15 services, 2 missing)
Missing:
IPaymentGateway → consumed by OrderService (Application/Services/OrderService.cs:14)
INotificationService → consumed by OrderCompletedHandler (Application/Handlers/...:9)
> /dotnet-pilot:dotnet:health-check --fix
Fixed ServiceCollectionExtensions.cs:
+ services.AddScoped<IPaymentGateway, StripePaymentGateway>();
+ services.AddScoped<INotificationService, EmailNotificationService>();
DI Wiring: PASS (17 services, 0 missing)
```
**5. Pre-commit quality gate**
```
> /dotnet-pilot:project:verify --quick
[PASS] Build: 0 errors
[PASS] Tests: 72 passed
[WARN] Format: 2 files need formatting
[PASS] DI Wiring: all services registered
[PASS] Architecture: no violations
Ready to commit. Run `dotnet format` to fix formatting issues.
git status: 3 files modified, 1 untracked
```
**6. Deep code review before a PR merge**
```
> /dotnet-pilot:quality:review --depth deep
[HIGH] UserService.cs:45
Async method calls .Result on a Task — deadlocks under ASP.NET Core.
Fix: await the call instead.
[HIGH] UsersController.cs:28
SQL injection: string interpolation in LINQ query with user input.
Fix: use parameterized queries or LINQ expressions.
[MEDIUM] OrderRepository.cs:62
N+1 query: .Include() inside a loop. Use eager loading outside.
[LOW] OrderService.cs:15
ILogger injected but never used. Remove or add error-path logging.
4 issues found: 2 high...
© zdanovichnick · MIT · zdanovichnick/dotnet-pilot