К основному содержанию
скилл CX Codex

template-authoring — скилл для Claude Code: что делает и установка

Помогает превратить существующий проект .NET в готовый шаблон dotnet new. Создаёт .template.config/template.json с параметрами и сохраняет структуру исходного файла .csproj.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add dotnet/skills --skill template-authoring -a claude-code
Открыть на GitHub

Что делает template-authoring

Агент анализирует исходный .csproj и копирует проект в отдельный каталог шаблона. Оригинальный проект остаётся целым. Скилл переносит настройки сборки: тип SDK и параметры Nullable вместе с правилами Central Package Management из Directory.Packages.props. Без этого generic-генераторы теряют метаданные зависимостей.

Для условных блоков в .csproj скилл использует XML-комментарии <!--#if ... -->, потому что обычный синтаксис директив ломает XML. В .template.config/template.json прописываются идентификатор, короткое имя и правила восстановления для dotnetcli. Здесь же готовится структура для упаковки шаблона в NuGet с тегом Template.

Инструмент не публикует пакеты в репозиторий и не ищет чужие наработки. Для проверки уже существующего template.json без пересборки проекта надёжнее вызвать скилл template-validation.

Какие задачи решает

  • Сгенерировать .template.config/template.json из рабочего проекта .NET
  • Настроить параметры и условные блоки в файле .csproj через комментарии
  • Сохранить правила Central Package Management при создании шаблона
  • Подготовить проект упаковки шаблона в NuGet-пакет

Примеры запросов агенту

  • Сделай шаблон dotnet new из проекта ./src/MyService с коротким именем myservice
  • Добавь в template.json параметр базы данных и условный блок в .csproj
  • Подготовь структуру проекта для упаковки нашего шаблона в NuGet

Как установить template-authoring

1Через Skills CLI (Vercel)

npx skills add dotnet/skills --skill template-authoring -a claude-code

2Вручную: положить файлы

~/.claude/skills/template-authoring/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/template-authoring/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Из того же набора101

maui-data-binding Скилл учит ИИ-агента связывать контролы XAML со свойствами ViewModel в .NET MAUI: компилируемые биндинги, уведомления об изменениях, конвертеры. CX Codex +1 3 200установок maui-dependency-injection Скилл обучает ассистента правилам внедрения зависимостей в .NET MAUI. Он подсказывает времена жизни сервисов в MauiProgram.cs и настраивает инъекцию в страницы и ViewModel. CX Codex +1 3 200установок migrate-mstest-v3-to-v4 Помогает перевести тестовый проект с MSTest v3 на v4: разбирает ошибки сборки, изменения поведения тестов и проблемы с обнаружением тестов в CI. CX Codex +1 3 200установок migrate-mstest-v1v2-to-v3 Скилл ведёт проект с MSTest v1 или v2 на v3: разбирает ошибки сборки, чинит DataRow и меняет .testsettings на .runsettings. CX Codex +1 3 200установок migrate-vstest-to-mtp Помогает перевести тестовые проекты .NET с VSTest на Microsoft.Testing.Platform: правит Directory.Build.props, global.json и аргументы dotnet test. CX Codex +1 3 200установок test-tagging Анализирует тесты в проекте и присваивает им стандартные метки (позитивные, граничные, критические пути, интеграционные и другие). Нужен, чтобы понять структуру тестового покрытия и выявить пробелы в основных сценариях. CX Codex +1 3 200установок migrate-xunit-to-xunit-v3 Переводит тестовые проекты .NET с xUnit v2 на xUnit v3 и чинит несовместимый код. Помогает при обновлении пакетов, переходе на исполняемый вывод и настройке раннеров. CX Codex +1 3 200установок android-tombstone-symbolication Разбирает нативные фреймы из tombstone-файла Android-приложения на .NET: достаёт имена функций, файлы и номера строк. CX Codex +1 3 300установок

Похожие

dotnet-project-structure Aaronontheweb Скилл подсказывает агенту, как разложить .NET-решение: .slnx, Directory.Build.props, центральные версии пакетов и SourceLink. CX Codex +1 658установок project-structure codewithmukesh Скилл задаёт агенту правила раскладки .NET-решения: центральные версии пакетов, общие свойства сборки, формат .slnx и именование проектов. CX Codex +1 2 800установок migrate codewithmukesh Скилл ведёт разработчика через миграции схемы EF Core, смену версии .NET и обновление NuGet. На каждом шаге он готовит план отката и запускает тесты. CX Codex +1 2 800установок api-design Aaronontheweb Скилл для проектирования публичных API по принципу «только расширять»: помогает не ломать совместимость при выпуске новых версий. CX Codex +1 660установок dotnet-upgrade официальный github Помогает спланировать обновление проектов .NET: проверить зависимости, выбрать порядок миграции и подготовить проверки после неё. 11 475установок sentry-dotnet-sdk getsentry Скилл проводит через полную настройку Sentry в .NET-проекте: ошибки, трейсинг, логи, профилирование и кроны. Полезен, когда нужно подключить мониторинг в ASP.NET Core, MAUI, WPF или Blazor. CX Codex +1 2 300установок

Рядом в теме «Бэкенд и API»

Всё по теме «Бэкенд и API» →

Вопросы о template-authoring

Как установить template-authoring в Claude Code?

Выполните команду npx skills add dotnet/skills --skill template-authoring -a claude-code. Агент подключит скилл к вашему окружению.

Что делает скилл template-authoring?

Он помогает создавать пользовательские шаблоны dotnet new на основе готового кода C#. Скилл генерирует манифест template.json, переносит свойства проекта и оформляет условную компиляцию без повреждения XML.

Чем template-authoring отличается от template-validation?

Скилл template-authoring отвечает за генерацию файлов шаблона и перенос настроек из .csproj. Если нужно только проверить готовый template.json без изменения проекта, разработчики советуют запускать отдельный скилл template-validation.

Исходный текст

SKILL.md · MIT
---
name: template-authoring
description: >
  Guides creation and validation of custom dotnet new templates from existing projects.
  Generates a .template.config/template.json that preserves the source project's conventions.
  USE FOR: creating a reusable dotnet new template from an existing project, bootstrapping
  .template.config/template.json with correct identity, shortName, parameters, and
  post-actions, adding parameters or conditional content to a template you are authoring,
  validating the template.json you are authoring before publishing,
  packaging templates as NuGet packages for distribution.
  DO NOT USE FOR: validating an existing template.json as a standalone task (use
  template-validation), finding or using existing templates (use template-discovery and
  template-instantiation), MSBuild project file issues unrelated to template authoring,
  NuGet package publishing (only template packaging structure).
license: MIT
---

# Template Authoring

This skill helps an agent create and validate custom `dotnet new` templates. It guides bootstrapping templates from existing projects and validates `template.json` files for authoring issues before publishing.

## When to Use

- User wants to create a reusable template from an existing .csproj
- User wants to validate a template.json they are authoring before publishing
- User is setting up `.template.config/template.json` from scratch
- User wants to package a template for NuGet distribution

## When Not to Use

- User wants to find or use existing templates — route to `template-discovery` or `template-instantiation`
- User has MSBuild issues unrelated to template authoring — route to `dotnet-msbuild` plugin

## Inputs

| Input | Required | Description |
|-------|----------|-------------|
| Source project path | For creation | Path to the .csproj to use as template source |
| template.json path | For validation | Path to an existing template.json to validate |
| Template name | For creation | Human-readable name for the template |
| Short name | Recommended | Short name for `dotnet new <shortname>` usage |

## Workflow

### Rules that change the answer

Use these structures exactly; do not invent fields from other template features.

**Deliver the requested artifact.** When the user says "show", "write", or "give me the
content", put the complete JSON/XML in the final response even if you also wrote it to disk.
Never edit this skill's `SKILL.md` or plugin documentation as a substitute for authoring the
user's template. Only create or modify template files when the user requested file changes and
the target template/project is present.

| Need | Correct structure | Never use |
|------|-------------------|-----------|
| Conditional XML in a `.csproj` | XML comments such as `<!--#if (database == "SqlServer") -->` and `<!--#endif -->` around the complete element | bare `#if` lines, which make the XML invalid |
| Restore generated projects | restore action `210D431B-A78B-4D2F-B762-4ED3E3EA9025`; use `primaryOutputs`, or `args.files` containing source-template paths/globs | run-script fields such as `executable` on the restore action |
| Restrict to the SDK host | a `host` constraint whose `args` is an array containing `{ "hostname": "dotnetcli" }`; its optional `version` restricts the host/CLI version | using host `version` when the requirement is specifically the active SDK version, the invalid host ID `dotnet-cli`, or unrelated `pattern` / `value` fields |
| Restrict the active SDK version | an `sdk-version` constraint with a NuGet version/range string in `args` | a machine-specific exact patch unless the template truly requires it |
| Preserve CPM | keep generated `PackageReference` items versionless and package the owning `Directory.Packages.props` when the template is self-contained | adding inline `Version` attributes |
| Package templates | a pack project with `<PackageType>Template</PackageType>` and template content packed below `content/` | describing a layout without showing the requested project file |

### Step 1: Bootstrap from existing project

Analyze the source `.csproj` and create a `.template.config/template.json`:

1. Copy the source project into a dedicated template-source directory by default, preserving
   the original project untouched. Modify the original in place only when the user explicitly
   asks for that layout.
2. Create `.template.config` inside the template-source directory.
3. Generate `template.json` with `identity` (reverse-DNS), `name`, `shortName`, `sourceName` (project name for replacement), `classifications`, and `tags`
4. Preserve from source — generic `dotnet new` templates frequently get these wrong, so verify each is carried over from the original `.csproj`:
   1. **SDK type** — `Microsoft.NET.Sdk`, `Microsoft.NET.Sdk.Web`, `Microsoft.NET.Sdk.Worker`, etc.
   2. **Analyzer/package reference metadata** — `PrivateAssets`, `IncludeAssets`, `ExcludeAssets`
   3. **`OutputType` and other key properties** — `TreatWarningsAsErrors`, `Nullable`, `LangVersion`
   4. **CPM participation** — no inline `Version` attributes when a `Directory.Packages.props` is present
   5. **Custom build props/targets** and `Directory.Build.props` conventions
   6. **Repo conventions** — folder layout, naming, `global.json` SDK pin

Minimal example:
```json
{
  "$schema": "http://json.schemastore.org/template",
  "author": "MyOrg",
  "classifications": ["Library"],
  "identity": "MyOrg.Templates.MyLib",
  "name": "My Library Template",
  "shortName": "mylib",
  "sourceName": "MyLib",
  "tags": { "language": "C#", "type": "project" }
}
```

**Required output — do not stop at a minimal stub.** Write the *complete* `.template.config/template.json` for the actual source project, then emit a short **conventions-preserved** confirmation so the user can see nothing was silently dropped. This carry-over is the whole value of the skill; a generic `dotnet new` template that loses these is why authoring ties with a hand-written stub.

| Source `.csproj` setting | Carried over? | How |
|--------------------------|---------------|-----|
| SDK (`Microsoft.NET.Sdk.*`) | ✅ | template content `.csproj` uses same SDK |
| `TreatWarningsAsErrors` / `Nullable` / `LangVersion` | ✅ | preserved verbatim in template `.csproj` |
| PackageReference `PrivateAssets` / `IncludeAssets` / `ExcludeAssets` | ✅ | metadata kept on each reference |
| CPM (`Directory.Packages.props` present) | ✅ | `ManagePackageVersionsCentrally` remains enabled and no inline `Version` attributes are emitted |

Mark any row you intentionally omitted as ⚠️ with a reason — never leave it implicit.

### Step 2: Validate template.json

Validate the generated `template.json` using the **template-validation** skill (it owns the full rule set — required fields, identity format, reserved shortName conflicts, parameter datatypes, post-actions, constraints, and tags).

Quick summary of what gets checked:
- **Required fields** — `identity`, `name`, and `shortName` must be present.
- **ShortName conflicts** — avoid names that collide with `dotnet new` subcommands. Read the authoritative set from the `Commands:` section of `dotnet new --help` for the installed SDK and do not hardcode it (it can change between versions); illustrative examples from current SDKs are `install`, `uninstall`, `update`, `list`, `search`, `details`, `create`. A conflict happens because `dotnet new <name>` would be parsed as the subcommand of the same name. Top-level `dotnet` verbs like `build`, `run`, `test`, and `publish` do NOT conflict. Run `dotnet new list` to confirm the name is not already taken.
- **Parameters, post-actions, tags** — see template-validation for the complete rules, including the valid datatype list.

### Step 3: Refine the template

Based on validation results and user requirements:

1. **Add parameters** with appropriate types (string, bool, choice), defaults, and descriptions
2. **Add conditional content** using the file type's valid syntax. In XML use template
   directives inside XML comments, not bare preprocessor lines:

   ```xml
   <!--#if (database == "SqlServer") -->
   <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
   <!--#endif -->
   <!--#if (database == "Postgres") -->
   <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
   <!--#endif -->
   ```
3. **Configure post-actions** for solution add, restore, or custom scripts
4. **Set constraints** to restrict which SDKs or workloads the template supports
5. **Add classifications** and tags for discoverability

For a restore post-action, prefer `primaryOutputs` when the project path is known:

```json
"primaryOutputs": [{ "path": "MyProject.csproj" }],
"postActions": [{
  "description": "Restore NuGet packages.",
  "manualInstructions": [{ "text": "Run 'dotnet restore'." }],
  "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
  "continueOnError": true
}]
```

If `args.files` is needed, its paths are matched against the **source template** before
renames, for example `"files": ["**/*.csproj"]`. Explain that distinction.

### Step 4: Test the template locally

For a create-from-existing-project request, this step is required rather than optional:
install the authored template, run a dry-run, instantiate it into a temporary output folder,
and build the generated project. Report each observed result; inspecting `template.json` alone
does not prove the reusable template works.

```bash
dotnet new install ./path/to/template/root
dotnet new mylib --name TestProject --dry-run
dotnet new mylib --name TestProject --output ./test-output
dotnet build ./test-output/TestProject
```

When packaging is requested, include the complete pack project, not only a directory tree:

```xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <PackageId>Contoso.ProjectTemplates</PackageId>
    <PackageType>Template</PackageType>
    <TargetFramework>net8.0</TargetFramework>
    <IncludeBuildOutput>false</IncludeBuildOutput>
    <NoWarn>$(NoWarn);NU5128</NoWarn>
  </PropertyGroup>
  <ItemGroup>
    <Compile Remove="**\*" />
    <Content Include="templates\**\*" Pack="true" PackagePath="content\" />
  </ItemGroup>
</Project>
```

The pack project's target framework applies only to the content-only packaging project; it
does not retarget projects inside `templates/`. Prefer a broadly available supported framework
unless the packaging project itself uses newer build features.

For a self-contained CPM template, the packaged `Directory.Packages.props` must include
`<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>` and every versionless
`PackageReference` must have a matching `PackageVersion`. Keep the props file at the intended
generated repository root; do not place a duplicate nearer the project where it changes lookup.

## Validation

- [ ] `template.json` passes manual validation with zero errors
- [ ] Template identity and shortName are unique and meaningful
- [ ] All parameters have descriptions and appropriate defaults
- [ ] Template can be installed, dry-run, and instantiated successfully
- [ ] Created projects build cleanly with `dotnet build`
- [ ] Conditional content produces correct output for all parameter combinations
- [ ] XML template directives are wrapped in XML comments and the generated project parses
- [ ] Host constraints use `args[].hostname`; restore actions use `primaryOutputs` or `args.files`

## Common Pitfalls

| Pitfall | Solution |
|---------|----------|
| Identity format issues | Use reverse-DNS format (e.g., `MyOrg.Templates.WebApi`). Avoid spaces or special characters. |
| ShortName conflicts with CLI commands | Avoid names that match a `dotnet new` subcommand; read the live set from `dotnet new --help` and don't hardcode it (illustrative examples: `install`, `uninstall`, `update`, `list`, `search`, `details`, `create`). Top-level verbs like `build`/`run`/`test`/`publish` are fine. Run `dotnet new list` to see if the name is already taken. |
| Missing parameter descriptions | Every parameter should have a `description` and `displayName` for discoverability. |
| Not testing all parameter combinations | Use `dotnet new <template> --dry-run` with different parameter values to verify conditional content works correctly. |
| Hardcoded versions in template | Use `sourceName` replacement for project names and consider parameterizing framework versions. |
| Not setting classifications | Add appropriate `classifications` (e.g., `["Web", "API"]`) for template discovery. |
| Reusing fields from a different constraint or post-action | Follow the exact schema: `host.args[].hostname`, and restore `args.files` rather than run-script fields. |

## More Info

- [Custom templates for dotnet new](https://learn.microsoft.com/dotnet/core/tools/custom-templates) — official authoring guide
- [template.json reference](https://github.com/dotnet/templating/wiki/Reference-for-template.json) — full schema reference
- [Template Engine Wiki](https://github.com/dotnet/templating/wiki) — template engine internals

© dotnet · MIT · dotnet/skills

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой