[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DZ7EXHHVBPRQEPP84REZZQ":3,"skill-same:01M6DZ7EXHHVBPRQEPP84REZZQ":87},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":53,"commitSha":54,"skillDirectory":55,"forksCount":56,"repositoryHtmlUrl":57,"repositoryHomepageUrl":58,"ownerHtmlUrl":59,"ownerBlogUrl":60,"ownerDescription":61,"updatedAt":62,"install":63,"resources":76},"01M6DZ7EXHHVBPRQEPP84REZZQ","template-authoring",null,"Guides creation and validation of custom dotnet new templates from existing projects. Generates a .template.config\u002Ftemplate.json that preserves the source project's conventions. USE FOR: creating a reusable dotnet new template from an existing project, bootstrapping .template.config\u002Ftemplate.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).","managedcode\u002Fdotnet-skills","managedcode","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F78253589?v=4","01M6DYDJR3EG8KB5G4PC65XCTT","Managed Code","01M6DYDJX0ZT432N04NYJW89DN",512,"MIT","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FTools\u002FOfficial-DotNet-Template-Engine\u002Fskills\u002Ftemplate-authoring\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"template authoring","authoring","template","unrelated","new","standalone","you","guides","as","distribution","creation","project","structure","do","reusable","dotnet","publishing","only","use","packaging","projects","correct","discovery","actions","package","issues","packages","config","2026-11-10 10:12:30",false,"---\nname: template-authoring\ndescription: >\n  Guides creation and validation of custom dotnet new templates from existing projects.\n  Generates a .template.config\u002Ftemplate.json that preserves the source project's conventions.\n  USE FOR: creating a reusable dotnet new template from an existing project, bootstrapping\n  .template.config\u002Ftemplate.json with correct identity, shortName, parameters, and\n  post-actions, adding parameters or conditional content to a template you are authoring,\n  validating the template.json you are authoring before publishing,\n  packaging templates as NuGet packages for distribution.\n  DO NOT USE FOR: validating an existing template.json as a standalone task (use\n  template-validation), finding or using existing templates (use template-discovery and\n  template-instantiation), MSBuild project file issues unrelated to template authoring,\n  NuGet package publishing (only template packaging structure).\nlicense: MIT\n---\n\n# Template Authoring\n\nThis 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.\n\n## When to Use\n\n- User wants to create a reusable template from an existing .csproj\n- User wants to validate a template.json they are authoring before publishing\n- User is setting up `.template.config\u002Ftemplate.json` from scratch\n- User wants to package a template for NuGet distribution\n\n## When Not to Use\n\n- User wants to find or use existing templates — route to `template-discovery` or `template-instantiation`\n- User has MSBuild issues unrelated to template authoring — route to `dotnet-msbuild` plugin\n\n## Inputs\n\n| Input | Required | Description |\n|-------|----------|-------------|\n| Source project path | For creation | Path to the .csproj to use as template source |\n| template.json path | For validation | Path to an existing template.json to validate |\n| Template name | For creation | Human-readable name for the template |\n| Short name | Recommended | Short name for `dotnet new \u003Cshortname>` usage |\n\n## Workflow\n\n### Rules that change the answer\n\nUse these structures exactly; do not invent fields from other template features.\n\n**Deliver the requested artifact.** When the user says \"show\", \"write\", or \"give me the\ncontent\", put the complete JSON\u002FXML in the final response even if you also wrote it to disk.\nNever edit this skill's `SKILL.md` or plugin documentation as a substitute for authoring the\nuser's template. Only create or modify template files when the user requested file changes and\nthe target template\u002Fproject is present.\n\n| Need | Correct structure | Never use |\n|------|-------------------|-----------|\n| Conditional XML in a `.csproj` | XML comments such as `\u003C!--#if (database == \"SqlServer\") -->` and `\u003C!--#endif -->` around the complete element | bare `#if` lines, which make the XML invalid |\n| Restore generated projects | restore action `210D431B-A78B-4D2F-B762-4ED3E3EA9025`; use `primaryOutputs`, or `args.files` containing source-template paths\u002Fglobs | run-script fields such as `executable` on the restore action |\n| Restrict to the SDK host | a `host` constraint whose `args` is an array containing `{ \"hostname\": \"dotnetcli\" }`; its optional `version` restricts the host\u002FCLI version | using host `version` when the requirement is specifically the active SDK version, the invalid host ID `dotnet-cli`, or unrelated `pattern` \u002F `value` fields |\n| Restrict the active SDK version | an `sdk-version` constraint with a NuGet version\u002Frange string in `args` | a machine-specific exact patch unless the template truly requires it |\n| Preserve CPM | keep generated `PackageReference` items versionless and package the owning `Directory.Packages.props` when the template is self-contained | adding inline `Version` attributes |\n| Package templates | a pack project with `\u003CPackageType>Template\u003C\u002FPackageType>` and template content packed below `content\u002F` | describing a layout without showing the requested project file |\n\n### Step 1: Bootstrap from existing project\n\nAnalyze the source `.csproj` and create a `.template.config\u002Ftemplate.json`:\n\n1. Copy the source project into a dedicated template-source directory by default, preserving\n   the original project untouched. Modify the original in place only when the user explicitly\n   asks for that layout.\n2. Create `.template.config` inside the template-source directory.\n3. Generate `template.json` with `identity` (reverse-DNS), `name`, `shortName`, `sourceName` (project name for replacement), `classifications`, and `tags`\n4. Preserve from source — generic `dotnet new` templates frequently get these wrong, so verify each is carried over from the original `.csproj`:\n   1. **SDK type** — `Microsoft.NET.Sdk`, `Microsoft.NET.Sdk.Web`, `Microsoft.NET.Sdk.Worker`, etc.\n   2. **Analyzer\u002Fpackage reference metadata** — `PrivateAssets`, `IncludeAssets`, `ExcludeAssets`\n   3. **`OutputType` and other key properties** — `TreatWarningsAsErrors`, `Nullable`, `LangVersion`\n   4. **CPM participation** — no inline `Version` attributes when a `Directory.Packages.props` is present\n   5. **Custom build props\u002Ftargets** and `Directory.Build.props` conventions\n   6. **Repo conventions** — folder layout, naming, `global.json` SDK pin\n\nMinimal example:\n```json\n{\n  \"$schema\": \"http:\u002F\u002Fjson.schemastore.org\u002Ftemplate\",\n  \"author\": \"MyOrg\",\n  \"classifications\": [\"Library\"],\n  \"identity\": \"MyOrg.Templates.MyLib\",\n  \"name\": \"My Library Template\",\n  \"shortName\": \"mylib\",\n  \"sourceName\": \"MyLib\",\n  \"tags\": { \"language\": \"C#\", \"type\": \"project\" }\n}\n```\n\n**Required output — do not stop at a minimal stub.** Write the *complete* `.template.config\u002Ftemplate.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.\n\n| Source `.csproj` setting | Carried over? | How |\n|--------------------------|---------------|-----|\n| SDK (`Microsoft.NET.Sdk.*`) | ✅ | template content `.csproj` uses same SDK |\n| `TreatWarningsAsErrors` \u002F `Nullable` \u002F `LangVersion` | ✅ | preserved verbatim in template `.csproj` |\n| PackageReference `PrivateAssets` \u002F `IncludeAssets` \u002F `ExcludeAssets` | ✅ | metadata kept on each reference |\n| CPM (`Directory.Packages.props` present) | ✅ | `ManagePackageVersionsCentrally` remains enabled and no inline `Version` attributes are emitted |\n\nMark any row you intentionally omitted as ⚠️ with a reason — never leave it implicit.\n\n### Step 2: Validate template.json\n\nValidate 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).\n\nQuick summary of what gets checked:\n- **Required fields** — `identity`, `name`, and `shortName` must be present.\n- **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 \u003Cname>` 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.\n- **Parameters, post-actions, tags** — see template-validation for the complete rules, including the valid datatype list.\n\n### Step 3: Refine the template\n\nBased on validation results and user requirements:\n\n1. **Add parameters** with appropriate types (string, bool, choice), defaults, and descriptions\n2. **Add conditional content** using the file type's valid syntax. In XML use template\n   directives inside XML comments, not bare preprocessor lines:\n\n   ```xml\n   \u003C!--#if (database == \"SqlServer\") -->\n   \u003CPackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" \u002F>\n   \u003C!--#endif -->\n   \u003C!--#if (database == \"Postgres\") -->\n   \u003CPackageReference Include=\"Npgsql.EntityFrameworkCore.PostgreSQL\" \u002F>\n   \u003C!--#endif -->\n   ```\n3. **Configure post-actions** for solution add, restore, or custom scripts\n4. **Set constraints** to restrict which SDKs or workloads the template supports\n5. **Add classifications** and tags for discoverability\n\nFor a restore post-action, prefer `primaryOutputs` when the project path is known:\n\n```json\n\"primaryOutputs\": [{ \"path\": \"MyProject.csproj\" }],\n\"postActions\": [{\n  \"description\": \"Restore NuGet packages.\",\n  \"manualInstructions\": [{ \"text\": \"Run 'dotnet restore'.\" }],\n  \"actionId\": \"210D431B-A78B-4D2F-B762-4ED3E3EA9025\",\n  \"continueOnError\": true\n}]\n```\n\nIf `args.files` is needed, its paths are matched against the **source template** before\nrenames, for example `\"files\": [\"**\u002F*.csproj\"]`. Explain that distinction.\n\n### Step 4: Test the template locally\n\nFor a create-from-existing-project request, this step is required rather than optional:\ninstall the authored template, run a dry-run, instantiate it into a temporary output folder,\nand build the generated project. Report each observed result; inspecting `template.json` alone\ndoes not prove the reusable template works.\n\n```bash\ndotnet new install .\u002Fpath\u002Fto\u002Ftemplate\u002Froot\ndotnet new mylib --name TestProject --dry-run\ndotnet new mylib --name TestProject --output .\u002Ftest-output\ndotnet build .\u002Ftest-output\u002FTestProject\n```\n\nWhen packaging is requested, include the complete pack project, not only a directory tree:\n\n```xml\n\u003CProject Sdk=\"Microsoft.NET.Sdk\">\n  \u003CPropertyGroup>\n    \u003CPackageId>Contoso.ProjectTemplates\u003C\u002FPackageId>\n    \u003CPackageType>Template\u003C\u002FPackageType>\n    \u003CTargetFramework>net8.0\u003C\u002FTargetFramework>\n    \u003CIncludeBuildOutput>false\u003C\u002FIncludeBuildOutput>\n    \u003CNoWarn>$(NoWarn);NU5128\u003C\u002FNoWarn>\n  \u003C\u002FPropertyGroup>\n  \u003CItemGroup>\n    \u003CCompile Remove=\"**\\*\" \u002F>\n    \u003CContent Include=\"templates\\**\\*\" Pack=\"true\" PackagePath=\"content\\\" \u002F>\n  \u003C\u002FItemGroup>\n\u003C\u002FProject>\n```\n\nThe pack project's target framework applies only to the content-only packaging project; it\ndoes not retarget projects inside `templates\u002F`. Prefer a broadly available supported framework\nunless the packaging project itself uses newer build features.\n\nFor a self-contained CPM template, the packaged `Directory.Packages.props` must include\n`\u003CManagePackageVersionsCentrally>true\u003C\u002FManagePackageVersionsCentrally>` and every versionless\n`PackageReference` must have a matching `PackageVersion`. Keep the props file at the intended\ngenerated repository root; do not place a duplicate nearer the project where it changes lookup.\n\n## Validation\n\n- [ ] `template.json` passes manual validation with zero errors\n- [ ] Template identity and shortName are unique and meaningful\n- [ ] All parameters have descriptions and appropriate defaults\n- [ ] Template can be installed, dry-run, and instantiated successfully\n- [ ] Created projects build cleanly with `dotnet build`\n- [ ] Conditional content produces correct output for all parameter combinations\n- [ ] XML template directives are wrapped in XML comments and the generated project parses\n- [ ] Host constraints use `args[].hostname`; restore actions use `primaryOutputs` or `args.files`\n\n## Common Pitfalls\n\n| Pitfall | Solution |\n|---------|----------|\n| Identity format issues | Use reverse-DNS format (e.g., `MyOrg.Templates.WebApi`). Avoid spaces or special characters. |\n| 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`\u002F`run`\u002F`test`\u002F`publish` are fine. Run `dotnet new list` to see if the name is already taken. |\n| Missing parameter descriptions | Every parameter should have a `description` and `displayName` for discoverability. |\n| Not testing all parameter combinations | Use `dotnet new \u003Ctemplate> --dry-run` with different parameter values to verify conditional content works correctly. |\n| Hardcoded versions in template | Use `sourceName` replacement for project names and consider parameterizing framework versions. |\n| Not setting classifications | Add appropriate `classifications` (e.g., `[\"Web\", \"API\"]`) for template discovery. |\n| 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. |\n\n## More Info\n\n- [Custom templates for dotnet new](https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fcore\u002Ftools\u002Fcustom-templates) — official authoring guide\n- [template.json reference](https:\u002F\u002Fgithub.com\u002Fdotnet\u002Ftemplating\u002Fwiki\u002FReference-for-template.json) — full schema reference\n- [Template Engine Wiki](https:\u002F\u002Fgithub.com\u002Fdotnet\u002Ftemplating\u002Fwiki) — template engine internals\n","# Template Authoring\n\nThis 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.\n\n## When to Use\n\n- User wants to create a reusable template from an existing .csproj\n- User wants to validate a template.json they are authoring before publishing\n- User is setting up `.template.config\u002Ftemplate.json` from scratch\n- User wants to package a template for NuGet distribution\n\n## When Not to Use\n\n- User wants to find or use existing templates — route to `template-discovery` or `template-instantiation`\n- User has MSBuild issues unrelated to template authoring — route to `dotnet-msbuild` plugin\n\n## Inputs\n\n| Input | Required | Description |\n|-------|----------|-------------|\n| Source project path | For creation | Path to the .csproj to use as template source |\n| template.json path | For validation | Path to an existing template.json to validate |\n| Template name | For creation | Human-readable name for the template |\n| Short name | Recommended | Short name for `dotnet new \u003Cshortname>` usage |\n\n## Workflow\n\n### Rules that change the answer\n\nUse these structures exactly; do not invent fields from other template features.\n\n**Deliver the requested artifact.** When the user says \"show\", \"write\", or \"give me the\ncontent\", put the complete JSON\u002FXML in the final response even if you also wrote it to disk.\nNever edit this skill's `SKILL.md` or plugin documentation as a substitute for authoring the\nuser's template. Only create or modify template files when the user requested file changes and\nthe target template\u002Fproject is present.\n\n| Need | Correct structure | Never use |\n|------|-------------------|-----------|\n| Conditional XML in a `.csproj` | XML comments such as `\u003C!--#if (database == \"SqlServer\") -->` and `\u003C!--#endif -->` around the complete element | bare `#if` lines, which make the XML invalid |\n| Restore generated projects | restore action `210D431B-A78B-4D2F-B762-4ED3E3EA9025`; use `primaryOutputs`, or `args.files` containing source-template paths\u002Fglobs | run-script fields such as `executable` on the restore action |\n| Restrict to the SDK host | a `host` constraint whose `args` is an array containing `{ \"hostname\": \"dotnetcli\" }`; its optional `version` restricts the host\u002FCLI version | using host `version` when the requirement is specifically the active SDK version, the invalid host ID `dotnet-cli`, or unrelated `pattern` \u002F `value` fields |\n| Restrict the active SDK version | an `sdk-version` constraint with a NuGet version\u002Frange string in `args` | a machine-specific exact patch unless the template truly requires it |\n| Preserve CPM | keep generated `PackageReference` items versionless and package the owning `Directory.Packages.props` when the template is self-contained | adding inline `Version` attributes |\n| Package templates | a pack project with `\u003CPackageType>Template\u003C\u002FPackageType>` and template content packed below `content\u002F` | describing a layout without showing the requested project file |\n\n### Step 1: Bootstrap from existing project\n\nAnalyze the source `.csproj` and create a `.template.config\u002Ftemplate.json`:\n\n1. Copy the source project into a dedicated template-source directory by default, preserving\n   the original project untouched. Modify the original in place only when the user explicitly\n   asks for that layout.\n2. Create `.template.config` inside the template-source directory.\n3. Generate `template.json` with `identity` (reverse-DNS), `name`, `shortName`, `sourceName` (project name for replacement), `classifications`, and `tags`\n4. Preserve from source — generic `dotnet new` templates frequently get these wrong, so verify each is carried over from the original `.csproj`:\n   1. **SDK type** — `Microsoft.NET.Sdk`, `Microsoft.NET.Sdk.Web`, `Microsoft.NET.Sdk.Worker`, etc.\n   2. **Analyzer\u002Fpackage reference metadata** — `PrivateAssets`, `IncludeAssets`, `ExcludeAssets`\n   3. **`OutputType` and other key properties** — `TreatWarningsAsErrors`, `Nullable`, `LangVersion`\n   4. **CPM participation** — no inline `Version` attributes when a `Directory.Packages.props` is present\n   5. **Custom build props\u002Ftargets** and `Directory.Build.props` conventions\n   6. **Repo conventions** — folder layout, naming, `global.json` SDK pin\n\nMinimal example:\n```json\n{\n  \"$schema\": \"http:\u002F\u002Fjson.schemastore.org\u002Ftemplate\",\n  \"author\": \"MyOrg\",\n  \"classifications\": [\"Library\"],\n  \"identity\": \"MyOrg.Templates.MyLib\",\n  \"name\": \"My Library Template\",\n  \"shortName\": \"mylib\",\n  \"sourceName\": \"MyLib\",\n  \"tags\": { \"language\": \"C#\", \"type\": \"project\" }\n}\n```\n\n**Required output — do not stop at a minimal stub.** Write the *complete* `.template.config\u002Ftemplate.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.\n\n| Source `.csproj` setting | Carried over? | How |\n|--------------------------|---------------|-----|\n| SDK (`Microsoft.NET.Sdk.*`) | ✅ | template content `.csproj` uses same SDK |\n| `TreatWarningsAsErrors` \u002F `Nullable` \u002F `LangVersion` | ✅ | preserved verbatim in template `.csproj` |\n| PackageReference `PrivateAssets` \u002F `IncludeAssets` \u002F `ExcludeAssets` | ✅ | metadata kept on each reference |\n| CPM (`Directory.Packages.props` present) | ✅ | `ManagePackageVersionsCentrally` remains enabled and no inline `Version` attributes are emitted |\n\nMark any row you intentionally omitted as ⚠️ with a reason — never leave it implicit.\n\n### Step 2: Validate template.json\n\nValidate 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).\n\nQuick summary of what gets checked:\n- **Required fields** — `identity`, `name`, and `shortName` must be present.\n- **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 \u003Cname>` 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.\n- **Parameters, post-actions, tags** — see template-validation for the complete rules, including the valid datatype list.\n\n### Step 3: Refine the template\n\nBased on validation results and user requirements:\n\n1. **Add parameters** with appropriate types (string, bool, choice), defaults, and descriptions\n2. **Add conditional content** using the file type's valid syntax. In XML use template\n   directives inside XML comments, not bare preprocessor lines:\n\n   ```xml\n   \u003C!--#if (database == \"SqlServer\") -->\n   \u003CPackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" \u002F>\n   \u003C!--#endif -->\n   \u003C!--#if (database == \"Postgres\") -->\n   \u003CPackageReference Include=\"Npgsql.EntityFrameworkCore.PostgreSQL\" \u002F>\n   \u003C!--#endif -->\n   ```\n3. **Configure post-actions** for solution add, restore, or custom scripts\n4. **Set constraints** to restrict which SDKs or workloads the template supports\n5. **Add classifications** and tags for discoverability\n\nFor a restore post-action, prefer `primaryOutputs` when the project path is known:\n\n```json\n\"primaryOutputs\": [{ \"path\": \"MyProject.csproj\" }],\n\"postActions\": [{\n  \"description\": \"Restore NuGet packages.\",\n  \"manualInstructions\": [{ \"text\": \"Run 'dotnet restore'.\" }],\n  \"actionId\": \"210D431B-A78B-4D2F-B762-4ED3E3EA9025\",\n  \"continueOnError\": true\n}]\n```\n\nIf `args.files` is needed, its paths are matched against the **source template** before\nrenames, for example `\"files\": [\"**\u002F*.csproj\"]`. Explain that distinction.\n\n### Step 4: Test the template locally\n\nFor a create-from-existing-project request, this step is required rather than optional:\ninstall the authored template, run a dry-run, instantiate it into a temporary output folder,\nand build the generated project. Report each observed result; inspecting `template.json` alone\ndoes not prove the reusable template works.\n\n```bash\ndotnet new install .\u002Fpath\u002Fto\u002Ftemplate\u002Froot\ndotnet new mylib --name TestProject --dry-run\ndotnet new mylib --name TestProject --output .\u002Ftest-output\ndotnet build .\u002Ftest-output\u002FTestProject\n```\n\nWhen packaging is requested, include the complete pack project, not only a directory tree:\n\n```xml\n\u003CProject Sdk=\"Microsoft.NET.Sdk\">\n  \u003CPropertyGroup>\n    \u003CPackageId>Contoso.ProjectTemplates\u003C\u002FPackageId>\n    \u003CPackageType>Template\u003C\u002FPackageType>\n    \u003CTargetFramework>net8.0\u003C\u002FTargetFramework>\n    \u003CIncludeBuildOutput>false\u003C\u002FIncludeBuildOutput>\n    \u003CNoWarn>$(NoWarn);NU5128\u003C\u002FNoWarn>\n  \u003C\u002FPropertyGroup>\n  \u003CItemGroup>\n    \u003CCompile Remove=\"**\\*\" \u002F>\n    \u003CContent Include=\"templates\\**\\*\" Pack=\"true\" PackagePath=\"content\\\" \u002F>\n  \u003C\u002FItemGroup>\n\u003C\u002FProject>\n```\n\nThe pack project's target framework applies only to the content-only packaging project; it\ndoes not retarget projects inside `templates\u002F`. Prefer a broadly available supported framework\nunless the packaging project itself uses newer build features.\n\nFor a self-contained CPM template, the packaged `Directory.Packages.props` must include\n`\u003CManagePackageVersionsCentrally>true\u003C\u002FManagePackageVersionsCentrally>` and every versionless\n`PackageReference` must have a matching `PackageVersion`. Keep the props file at the intended\ngenerated repository root; do not place a duplicate nearer the project where it changes lookup.\n\n## Validation\n\n- [ ] `template.json` passes manual validation with zero errors\n- [ ] Template identity and shortName are unique and meaningful\n- [ ] All parameters have descriptions and appropriate defaults\n- [ ] Template can be installed, dry-run, and instantiated successfully\n- [ ] Created projects build cleanly with `dotnet build`\n- [ ] Conditional content produces correct output for all parameter combinations\n- [ ] XML template directives are wrapped in XML comments and the generated project parses\n- [ ] Host constraints use `args[].hostname`; restore actions use `primaryOutputs` or `args.files`\n\n## Common Pitfalls\n\n| Pitfall | Solution |\n|---------|----------|\n| Identity format issues | Use reverse-DNS format (e.g., `MyOrg.Templates.WebApi`). Avoid spaces or special characters. |\n| 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`\u002F`run`\u002F`test`\u002F`publish` are fine. Run `dotnet new list` to see if the name is already taken. |\n| Missing parameter descriptions | Every parameter should have a `description` and `displayName` for discoverability. |\n| Not testing all parameter combinations | Use `dotnet new \u003Ctemplate> --dry-run` with different parameter values to verify conditional content works correctly. |\n| Hardcoded versions in template | Use `sourceName` replacement for project names and consider parameterizing framework versions. |\n| Not setting classifications | Add appropriate `classifications` (e.g., `[\"Web\", \"API\"]`) for template discovery. |\n| 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. |\n\n## More Info\n\n- [Custom templates for dotnet new](https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fcore\u002Ftools\u002Fcustom-templates) — official authoring guide\n- [template.json reference](https:\u002F\u002Fgithub.com\u002Fdotnet\u002Ftemplating\u002Fwiki\u002FReference-for-template.json) — full schema reference\n- [Template Engine Wiki](https:\u002F\u002Fgithub.com\u002Fdotnet\u002Ftemplating\u002Fwiki) — template engine internals\n",{"name":5,"license":15,"description":52},"Guides creation and validation of custom dotnet new templates from existing projects. Generates a .template.config\u002Ftemplate.json that preserves the source project's conventions. USE FOR: creating a reusable dotnet new template from an existing project, bootstrapping .template.config\u002Ftemplate.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).\n","main","497cc9aba79a931ac6fb8d36a48cc22fe3d6d74b","catalog\u002FTools\u002FOfficial-DotNet-Template-Engine\u002Fskills\u002Ftemplate-authoring",41,"https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills","https:\u002F\u002Fskills.managed-code.com","https:\u002F\u002Fgithub.com\u002Fmanagedcode","https:\u002F\u002Fwww.managed-code.com","Open Source Community for .NET Developers: Reliable, Actively Maintained, and Community-Driven. Made in Ukraine 🇺🇦 with ❤️","2026-11-11 19:34:28",{"source":8,"skillName":5,"commands":64,"prompt":74,"zipAvailable":75},[65,68,71],{"tool":66,"command":67},"npx","npx skills add managedcode\u002Fdotnet-skills --skill template-authoring",{"tool":69,"command":70},"bunx","bunx skills add managedcode\u002Fdotnet-skills --skill template-authoring",{"tool":72,"command":73},"pnpm","pnpm dlx skills add managedcode\u002Fdotnet-skills --skill template-authoring","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FTools\u002FOfficial-DotNet-Template-Engine\u002Fskills\u002Ftemplate-authoring\u002FSKILL.md",true,[77,83],{"path":78,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":81,"sourceHtmlUrl":82},"index.json","REFERENCE","参考文档",647,"https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fsoc\u002Foperations\u002Fescalation\u002Fescalate\u002Findex.json",{"path":84,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":85,"sourceHtmlUrl":86},"manifest.json",156,"https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FTools\u002FOfficial-DotNet-Template-Engine\u002Fskills\u002Ftemplate-authoring\u002Fmanifest.json",[88,124,147,178,188,214],{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":104,"publishedAt":47},"01M6DYQE1Y9FHAQHEDTVFQ3447","xtwitter-scraper","Use XTwitterScraper when a .NET application needs typed access to Xquik's X automation REST API for tweet search, user lookup, posting workflows, extraction jobs, monitors, webhooks, or giveaway draws. USE FOR: integrating the XTwitterScraper NuGet package; reviewing Xquik API client usage; modeling API-key configuration, pagination, binary exports, raw responses, retries, and webhook\u002Fevent flows in .NET. DO NOT USE FOR: unrelated stacks; direct browser automation; generic social-media strategy; or code that does not call Xquik. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FLibraries\u002FXTwitterScraper\u002Fskills\u002Fxtwitter-scraper\u002FSKILL.md",[94,99],{"categoryNo":95,"categoryName":96,"taxonomyType":97,"taxonomyTypeDesc":98},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":100,"categoryName":101,"taxonomyType":102,"taxonomyTypeDesc":103},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[105,106,107,108,109,110,111,112,113,114,115,116,117,22,118,119,120,121,122,123],"xtwitter scraper","browser automation","workflows","run","code","browser","search","repository","api","Media","api client","access","edit","webhooks","files","social","commands","modeling","webhook",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":136,"publishedAt":47},"01M6DYQ9S4PE1H6G8MCH9T21HR","sep","Use Sep for high-performance separated-value parsing and writing in .NET, including delimiter inference, explicit parser\u002Fwriter options, and low-allocation row\u002Fcolumn workflows. USE FOR: delimited data needs are performance-sensitive and allocation-aware; project needs explicit control over separator inference, escaping, trimming, and header behavior;. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FLibraries\u002FSep\u002Fskills\u002Fsep\u002FSKILL.md",[130,133],{"categoryNo":131,"categoryName":132,"taxonomyType":97,"taxonomyTypeDesc":98},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":134,"categoryName":135,"taxonomyType":102,"taxonomyTypeDesc":103},"01JBSEEDCAT000000000000036","内容创作者",[126,137,138,107,139,108,112,140,141,142,117,143,22,119,32,144,145,30,121,146],"writing","performance","tasks","data","parsing","parser","context","writer","options","high-performance",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":47},"01M6DZS2DNEPXCGGF6SSCW6G5V","webgpu-threejs-tsl","Comprehensive guide for developing WebGPU-enabled Three.js applications using TSL (Three.js Shading Language). Covers WebGPU renderer setup, TSL syntax and node materials, compute shaders, post-processing effects, and WGSL integration. Use this skill when working with Three.js WebGPU, TSL shaders, node materials, or GPU compute in Three.js.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fexternal-sources\u002Fupstreams\u002Fwebgpu-claude-skill\u002Fskills\u002Fwebgpu-threejs-tsl\u002FSKILL.md",[],[154,155,156,157,158,159,160,161,162,163,164,165,37,166,167,168,169,170,171,172,173,174,175,176,177],"webgpu","threejs","webgpu threejs tsl","setup","shaders","gpu","integration","applications","js","node","syntax","guide","language","three","compute","post","processing","with","renderer","for","materials","wgsl","effects","when",{"skillNo":179,"name":180,"nameZh":6,"description":181,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":182,"categories":183,"keywords":184,"publishedAt":47},"01M6DZS0BQXW2B56A289XF1X76","roslynk","Use Roslynk for semantic inspection and edits of *.cs, *.razor and *.cshtml solution files.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fexternal-sources\u002Fupstreams\u002Froslynk\u002Fskills\u002Froslynk\u002FSKILL.md",[],[180,37,119,185,186,173,187],"semantic","razor","inspection",{"skillNo":189,"name":190,"nameZh":6,"description":191,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":192,"categories":193,"keywords":194,"publishedAt":47},"01M6DZRW6MEJCVW80K3S4XV60K","system-text-json-net11","Imperative guidance for the System.Text.Json APIs added in .NET 11: the built-in `JsonNamingPolicy.PascalCase` naming policy, and the strongly-typed generic `JsonSerializerOptions.GetTypeInfo` and `JsonSerializerOptions.TryGetTypeInfo` metadata accessors (generic overloads that return a typed `JsonTypeInfo`). USE ONLY when the user is targeting net11.0 or later and needs PascalCase JSON property or dictionary-key names without writing a custom naming policy, a strongly-typed generic `JsonTypeInfo` instead of the non-generic `JsonTypeInfo`, or a no-throw way to probe whether a type's serialization metadata is resolved. DO NOT USE when the target is earlier than net11.0, the requested behavior uses an established pre-net11 naming policy, or the user explicitly selected another JSON library.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fexternal-sources\u002Fupstreams\u002Fdotnet-skills\u002Fplugins\u002Fdotnet11\u002Fskills\u002Fsystem-text-json-net11\u002FSKILL.md",[],[195,196,197,198,137,199,200,201,202,203,204,37,36,205,206,207,32,208,209,210,211,173,212,213,177],"system","json","text","system text json net11","policy","metadata","library","serialization","behavior","user","probe","guidance","later","type","dictionary","naming","targeting","custom","generic",{"skillNo":215,"name":216,"nameZh":6,"description":217,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":218,"categories":219,"keywords":222,"publishedAt":47},"01M6DZRRJP3S662NFSG1RSPQQ7","process-api-net11","Provides guidance on the new System.Diagnostics.Process APIs introduced in .NET 11: Process.Run, Process.RunAndCaptureText, Process.StartAndForget, Process.ReadAllText\u002FBytes\u002FLines, KillOnParentExit, InheritedHandles, and StartDetached. USE FOR: starting, orchestrating, or capturing output from external processes in applications targeting net11.0 or later. DO NOT USE FOR: applications targeting .NET 10 or earlier, or basic pre-.NET 11 Process.Start usage without new APIs.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fexternal-sources\u002Fupstreams\u002Fdotnet-skills\u002Fplugins\u002Fdotnet11\u002Fskills\u002Fprocess-api-net11\u002FSKILL.md",[220,221],{"categoryNo":95,"categoryName":96,"taxonomyType":97,"taxonomyTypeDesc":98},{"categoryNo":100,"categoryName":101,"taxonomyType":102,"taxonomyTypeDesc":103},[113,223,224,225,108,226,161,195,37,206,207,32,227,228,229,230,211,173,23],"process","process api net11","diagnostics","start","basic","processes","output","usage"]