@pratikpsl/agent-skills 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +92 -0
- package/bin/agent-skills.js +7 -0
- package/package.json +37 -0
- package/src/__tests__/copySkills.test.js +161 -0
- package/src/__tests__/list.test.js +49 -0
- package/src/__tests__/manifest.test.js +72 -0
- package/src/commands/add.js +89 -0
- package/src/commands/dotnet-setup.js +67 -0
- package/src/commands/init.js +42 -0
- package/src/commands/list.js +41 -0
- package/src/index.js +33 -0
- package/src/lib/copySkills.js +84 -0
- package/src/lib/manifest.js +117 -0
- package/src/lib/resolvePack.js +44 -0
- package/src/templates/dotnet/AgentSkills/OPERATING.md +85 -0
- package/src/templates/dotnet/AgentSkills/README.md +64 -0
- package/src/templates/dotnet/AgentSkills/agents/README.md +16 -0
- package/src/templates/dotnet/AgentSkills/agents/architect.agent.md +59 -0
- package/src/templates/dotnet/AgentSkills/agents/developer.agent.md +88 -0
- package/src/templates/dotnet/AgentSkills/entry-points/AGENTS.md +16 -0
- package/src/templates/dotnet/AgentSkills/entry-points/CLAUDE.md +16 -0
- package/src/templates/dotnet/AgentSkills/entry-points/copilot-instructions.md +16 -0
- package/src/templates/dotnet/AgentSkills/entry-points/cursor-instructions.md +16 -0
- package/src/templates/dotnet/AgentSkills/memory/index.md +22 -0
- package/src/templates/dotnet/AgentSkills/memory/lessons/api.md +3 -0
- package/src/templates/dotnet/AgentSkills/memory/lessons/auth.md +3 -0
- package/src/templates/dotnet/AgentSkills/memory/lessons/csharp.md +3 -0
- package/src/templates/dotnet/AgentSkills/memory/lessons/db.md +3 -0
- package/src/templates/dotnet/AgentSkills/memory/lessons/design.md +3 -0
- package/src/templates/dotnet/AgentSkills/memory/lessons/infra.md +7 -0
- package/src/templates/dotnet/AgentSkills/memory/lessons/mcp.md +3 -0
- package/src/templates/dotnet/AgentSkills/memory/lessons/testing.md +3 -0
- package/src/templates/dotnet/AgentSkills/memory/schema.md +26 -0
- package/src/templates/dotnet/AgentSkills/skills/INDEX.md +21 -0
- package/src/templates/dotnet/AgentSkills/skills/README.md +14 -0
- package/src/templates/dotnet/AgentSkills/skills/code-standards/SKILL.md +122 -0
- package/src/templates/dotnet/AgentSkills/skills/core/SKILL.md +83 -0
- package/src/templates/dotnet/AgentSkills/skills/csharp-xunit/SKILL.md +68 -0
- package/src/templates/dotnet/AgentSkills/skills/design/SKILL.md +108 -0
- package/src/templates/dotnet/AgentSkills/skills/dotnet-api/SKILL.md +303 -0
- package/src/templates/dotnet/AgentSkills/skills/dotnet-best-practices/SKILL.md +170 -0
- package/src/templates/dotnet/AgentSkills/skills/harness/SKILL.md +62 -0
- package/src/templates/dotnet/AgentSkills/skills/mcp_dotnet/SKILL.md +54 -0
- package/src/templates/dotnet/manifest.json +86 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Agents
|
|
2
|
+
|
|
3
|
+
This folder is the canonical source of truth for agent definitions used by all AI tools and IDEs in this repository.
|
|
4
|
+
|
|
5
|
+
Do not duplicate agent content under `.github/`, `.copilot/`, `.codex/`, or other tool-specific folders.
|
|
6
|
+
Those tools should load agent definitions from this folder.
|
|
7
|
+
Complete `AgentSkills/OPERATING.md` before loading a task-specific agent definition.
|
|
8
|
+
|
|
9
|
+
## Agent Locations (canonical paths)
|
|
10
|
+
|
|
11
|
+
| Agent | Canonical Path |
|
|
12
|
+
|---|---|
|
|
13
|
+
| architect | `AgentSkills/agents/architect.agent.md` |
|
|
14
|
+
| developer | `AgentSkills/agents/developer.agent.md` |
|
|
15
|
+
|
|
16
|
+
All agents and tools (Copilot, Codex, Claude, Cursor, Antigravity) load agents from `AgentSkills/agents/`.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architect
|
|
3
|
+
description: >
|
|
4
|
+
Load when designing features, planning CQRS structure,
|
|
5
|
+
designing SQL schema, or planning MCP server contracts.
|
|
6
|
+
Do not write implementation code; output structure only.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Architect Agent
|
|
10
|
+
|
|
11
|
+
## Responsibilities
|
|
12
|
+
|
|
13
|
+
- Design CQRS command/query split before any code is written.
|
|
14
|
+
- Define SQL schema and relationships.
|
|
15
|
+
- Define MCP tool contracts including name, input, and output.
|
|
16
|
+
- Identify performance-sensitive read/write paths and expected data volume.
|
|
17
|
+
- Reject designs that violate SOLID, KISS, or YAGNI.
|
|
18
|
+
- Prefer simple, small designs that are easy to delete.
|
|
19
|
+
|
|
20
|
+
## CQRS Rules
|
|
21
|
+
|
|
22
|
+
- Commands mutate state and return nothing, an ID, or a small result.
|
|
23
|
+
- Queries read state and never mutate.
|
|
24
|
+
- Controllers dispatch only; no business logic belongs in controllers.
|
|
25
|
+
- Use one handler per command or query.
|
|
26
|
+
- Query designs returning collections must specify projection, pagination, and tracking behavior.
|
|
27
|
+
|
|
28
|
+
## Output Format
|
|
29
|
+
|
|
30
|
+
Before implementation, produce:
|
|
31
|
+
|
|
32
|
+
1. Command/query split with input and output.
|
|
33
|
+
2. SQL schema if new tables are needed.
|
|
34
|
+
3. MCP tool contract if the MCP surface changes.
|
|
35
|
+
4. Proposed folder structure.
|
|
36
|
+
|
|
37
|
+
## Example Command / Query Split
|
|
38
|
+
|
|
39
|
+
| Type | Name | Input | Output |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| Command | CreateOrderCommand | CreateOrderRequest | OrderId |
|
|
42
|
+
| Query | GetOrderByIdQuery | OrderId | OrderDto |
|
|
43
|
+
|
|
44
|
+
## Example Folder Structure
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
Features/
|
|
48
|
+
└── Orders/
|
|
49
|
+
├── Commands/
|
|
50
|
+
│ └── CreateOrder/
|
|
51
|
+
│ ├── CreateOrderCommand.cs
|
|
52
|
+
│ ├── CreateOrderHandler.cs
|
|
53
|
+
│ └── CreateOrderValidator.cs
|
|
54
|
+
└── Queries/
|
|
55
|
+
└── GetOrderById/
|
|
56
|
+
├── GetOrderByIdQuery.cs
|
|
57
|
+
├── GetOrderByIdHandler.cs
|
|
58
|
+
└── OrderDto.cs
|
|
59
|
+
```
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: developer
|
|
3
|
+
description: >
|
|
4
|
+
Load when implementing features in .NET C# API.
|
|
5
|
+
Always load architect guidance first if structure is not defined.
|
|
6
|
+
Always follows CQRS and loads code-standards plus dotnet-best-practices.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Developer Agent
|
|
10
|
+
|
|
11
|
+
## Stack
|
|
12
|
+
|
|
13
|
+
- .NET 10 and modern C#.
|
|
14
|
+
- ASP.NET Core Minimal APIs or controllers.
|
|
15
|
+
- MediatR for CQRS dispatch.
|
|
16
|
+
- FluentValidation for input validation.
|
|
17
|
+
- EF Core for persistence.
|
|
18
|
+
- MCP Server SDK for AI tool surface.
|
|
19
|
+
|
|
20
|
+
## Implementation Rules
|
|
21
|
+
|
|
22
|
+
- Use records for commands, queries, and DTOs when immutability is appropriate.
|
|
23
|
+
- Mark classes `sealed` unless inheritance is intentionally supported.
|
|
24
|
+
- Keep controllers thin; they should validate transport concerns and dispatch through MediatR.
|
|
25
|
+
- Keep business rules in domain entities or domain/application services, not controllers or handlers.
|
|
26
|
+
- Use repositories or data access abstractions where the project already follows that convention.
|
|
27
|
+
- Use async all the way; never block with `.Result`, `.Wait()`, or `.GetAwaiter().GetResult()`.
|
|
28
|
+
- Pass `CancellationToken` through request, handler, EF Core, HTTP, and MCP boundaries.
|
|
29
|
+
- Optimize read queries with `.AsNoTracking()`, DTO projection, pagination, and no N+1 queries.
|
|
30
|
+
- Keep API payloads small and avoid excessive logging in hot paths.
|
|
31
|
+
|
|
32
|
+
## CQRS Pattern
|
|
33
|
+
|
|
34
|
+
```csharp
|
|
35
|
+
public sealed record CreateOrderCommand(Guid CustomerId, IReadOnlyList<OrderItem> Items)
|
|
36
|
+
: IRequest<Guid>;
|
|
37
|
+
|
|
38
|
+
public sealed class CreateOrderHandler(IOrderRepository repository)
|
|
39
|
+
: IRequestHandler<CreateOrderCommand, Guid>
|
|
40
|
+
{
|
|
41
|
+
public async Task<Guid> Handle(
|
|
42
|
+
CreateOrderCommand command,
|
|
43
|
+
CancellationToken cancellationToken)
|
|
44
|
+
{
|
|
45
|
+
var order = Order.Create(command.CustomerId, command.Items);
|
|
46
|
+
await repository.AddAsync(order, cancellationToken);
|
|
47
|
+
return order.Id;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Controller Rule
|
|
53
|
+
|
|
54
|
+
Controllers dispatch only.
|
|
55
|
+
|
|
56
|
+
```csharp
|
|
57
|
+
[HttpPost]
|
|
58
|
+
public async Task<IActionResult> Create(
|
|
59
|
+
CreateOrderRequest request,
|
|
60
|
+
CancellationToken cancellationToken)
|
|
61
|
+
{
|
|
62
|
+
var orderId = await mediator.Send(
|
|
63
|
+
new CreateOrderCommand(request.CustomerId, request.Items),
|
|
64
|
+
cancellationToken);
|
|
65
|
+
|
|
66
|
+
return CreatedAtAction(nameof(GetById), new { orderId }, null);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## MCP Tool Rule
|
|
71
|
+
|
|
72
|
+
MCP tools should reuse the same command/query handlers as REST endpoints.
|
|
73
|
+
|
|
74
|
+
```csharp
|
|
75
|
+
[McpTool("create_order", "Creates a new order")]
|
|
76
|
+
public static async Task<CreateOrderResult> CreateOrderAsync(
|
|
77
|
+
Guid customerId,
|
|
78
|
+
IReadOnlyList<OrderItem> items,
|
|
79
|
+
IMediator mediator,
|
|
80
|
+
CancellationToken cancellationToken)
|
|
81
|
+
{
|
|
82
|
+
var orderId = await mediator.Send(
|
|
83
|
+
new CreateOrderCommand(customerId, items),
|
|
84
|
+
cancellationToken);
|
|
85
|
+
|
|
86
|
+
return new CreateOrderResult(orderId);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Codex / OpenAI Entry Point
|
|
2
|
+
|
|
3
|
+
This file is a lightweight entry point for Codex and OpenAI agents.
|
|
4
|
+
|
|
5
|
+
`AgentSkills/` is the single source of truth for skills, agents, memory,
|
|
6
|
+
prerequisites, checklists, and project rules used by all coding agents and
|
|
7
|
+
AI-enabled IDEs in this repository.
|
|
8
|
+
|
|
9
|
+
## Start Here
|
|
10
|
+
|
|
11
|
+
1. Read `AgentSkills/OPERATING.md`.
|
|
12
|
+
2. Follow skill routing in `AgentSkills/skills/INDEX.md`.
|
|
13
|
+
3. Load role definitions from `AgentSkills/agents/` only when the task requires them.
|
|
14
|
+
|
|
15
|
+
Do not duplicate canonical instructions in this file. Edit shared guidance in
|
|
16
|
+
`AgentSkills/`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Claude Entry Point
|
|
2
|
+
|
|
3
|
+
This file is a lightweight entry point for Claude (Anthropic).
|
|
4
|
+
|
|
5
|
+
`AgentSkills/` is the single source of truth for skills, agents, memory,
|
|
6
|
+
prerequisites, checklists, and project rules used by all coding agents and
|
|
7
|
+
AI-enabled IDEs in this repository.
|
|
8
|
+
|
|
9
|
+
## Start Here
|
|
10
|
+
|
|
11
|
+
1. Read `AgentSkills/OPERATING.md`.
|
|
12
|
+
2. Follow skill routing in `AgentSkills/skills/INDEX.md`.
|
|
13
|
+
3. Load role definitions from `AgentSkills/agents/` only when the task requires them.
|
|
14
|
+
|
|
15
|
+
Do not duplicate canonical instructions in this file. Edit shared guidance in
|
|
16
|
+
`AgentSkills/`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Copilot Entry Point
|
|
2
|
+
|
|
3
|
+
This file is a lightweight entry point for GitHub Copilot.
|
|
4
|
+
|
|
5
|
+
`AgentSkills/` is the single source of truth for skills, agents, memory,
|
|
6
|
+
prerequisites, checklists, and project rules used by all coding agents and
|
|
7
|
+
AI-enabled IDEs in this repository.
|
|
8
|
+
|
|
9
|
+
## Start Here
|
|
10
|
+
|
|
11
|
+
1. Read `AgentSkills/OPERATING.md`.
|
|
12
|
+
2. Follow skill routing in `AgentSkills/skills/INDEX.md`.
|
|
13
|
+
3. Load role definitions from `AgentSkills/agents/` only when the task requires them.
|
|
14
|
+
|
|
15
|
+
Do not duplicate canonical instructions in this file. Edit shared guidance in
|
|
16
|
+
`AgentSkills/`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Cursor / Antigravity Entry Point
|
|
2
|
+
|
|
3
|
+
This file is a lightweight entry point for Cursor and Antigravity IDEs.
|
|
4
|
+
|
|
5
|
+
`AgentSkills/` is the single source of truth for skills, agents, memory,
|
|
6
|
+
prerequisites, checklists, and project rules used by all coding agents and
|
|
7
|
+
AI-enabled IDEs in this repository.
|
|
8
|
+
|
|
9
|
+
## Start Here
|
|
10
|
+
|
|
11
|
+
1. Read `AgentSkills/OPERATING.md`.
|
|
12
|
+
2. Follow skill routing in `AgentSkills/skills/INDEX.md`.
|
|
13
|
+
3. Load role definitions from `AgentSkills/agents/` only when the task requires them.
|
|
14
|
+
|
|
15
|
+
Do not duplicate canonical instructions in this file. Edit shared guidance in
|
|
16
|
+
`AgentSkills/`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Memory Index
|
|
2
|
+
|
|
3
|
+
Always load this file first. Then load **only** the domain file(s) that match your task.
|
|
4
|
+
Do NOT load domain files you do not need. Never load all files at once.
|
|
5
|
+
|
|
6
|
+
## Domain Map
|
|
7
|
+
|
|
8
|
+
| Domain | Load when | File | Lessons |
|
|
9
|
+
|--------|-----------|------|---------|
|
|
10
|
+
| api | CQRS, MediatR, commands, queries, controllers, endpoints | [lessons/api.md](lessons/api.md) | 1 |
|
|
11
|
+
| db | EF Core, migrations, schema, seeding, repositories | [lessons/db.md](lessons/db.md) | 0 |
|
|
12
|
+
| infra | Build, paths, CI, tooling, portability, AgentSkills setup | [lessons/infra.md](lessons/infra.md) | 5 |
|
|
13
|
+
| auth | Authentication, authorisation, JWT, policies, claims | [lessons/auth.md](lessons/auth.md) | 0 |
|
|
14
|
+
| testing | xUnit, test data, mocking, coverage, assertions | [lessons/testing.md](lessons/testing.md) | 0 |
|
|
15
|
+
| csharp | C# language features, async/await, naming, code style | [lessons/csharp.md](lessons/csharp.md) | 0 |
|
|
16
|
+
| design | SOLID, CQRS, Repository, patterns, architecture decisions | [lessons/design.md](lessons/design.md) | 0 |
|
|
17
|
+
| mcp | MCP server tools, transports, contracts, .NET MCP integration | [lessons/mcp.md](lessons/mcp.md) | 0 |
|
|
18
|
+
|
|
19
|
+
## Writing a lesson?
|
|
20
|
+
|
|
21
|
+
Load `memory/schema.md` for the one-line format. Do not inline logging instructions here.
|
|
22
|
+
Update the lesson count in this table after appending to the domain file.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Infra Lessons
|
|
2
|
+
|
|
3
|
+
RULE: Never overwrite files in AgentSkills/ without verifying they are backed up; it is the single source of truth and tool-specific entry points must point to it, never duplicate it. #circular-redirect 2026-05-31
|
|
4
|
+
RULE: Use repo-relative paths in all agent and IDE instruction files; never write absolute local drive paths in shared documentation. #wrong-path 2026-06-06
|
|
5
|
+
RULE: When splitting a monolithic memory file into domain files, grep the whole repo for the old path and update every reference before deleting the original. #stale-reference 2026-06-07
|
|
6
|
+
RULE: Always check native command exit codes explicitly in PowerShell harness scripts. #native-exit-code 2026-06-21
|
|
7
|
+
RULE: Run dotnet format after patching C# files; this repo enforces CRLF and no final newline. #format-fail 2026-07-01
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Lesson Logging Schema
|
|
2
|
+
|
|
3
|
+
Load this file **only when writing a new lesson** at the end of a task.
|
|
4
|
+
Never load at task start — it adds no value during execution.
|
|
5
|
+
|
|
6
|
+
## Format
|
|
7
|
+
|
|
8
|
+
Append one line per lesson to the correct domain file in `memory/lessons/`:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
RULE: <imperative sentence — what to always do or never do> #tag YYYY-MM-DD
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Rules for a good entry
|
|
15
|
+
|
|
16
|
+
- Start with **Always**, **Never**, or an action verb.
|
|
17
|
+
- Keep it under 20 words. The rule only — no symptom narrative, no root cause prose.
|
|
18
|
+
- Add one `#tag` describing the symptom class (e.g. `#build-fail`, `#wrong-path`, `#cqrs-violation`).
|
|
19
|
+
- Pick the correct domain from `memory/index.md`. If unsure, use `infra.md`.
|
|
20
|
+
- After appending, **increment the lesson count** for that domain in `memory/index.md`.
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
RULE: Never place business logic in MediatR Handlers; delegate to domain entities or services. #cqrs-violation 2026-05-31
|
|
26
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Skills Index
|
|
2
|
+
|
|
3
|
+
Load the relevant skill from `AgentSkills/skills/` before starting any task.
|
|
4
|
+
Start with `AgentSkills/OPERATING.md` for the shared prerequisite and completion workflow.
|
|
5
|
+
|
|
6
|
+
`AgentSkills/` is the single source of truth for all skills and agents.
|
|
7
|
+
Do not duplicate skill content under `.github/`, `.copilot/`, `.codex/`, or other tool-specific folders.
|
|
8
|
+
All AI tools and IDEs should load skills from this folder.
|
|
9
|
+
|
|
10
|
+
## Skills
|
|
11
|
+
|
|
12
|
+
| Skill | Load when | Path |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| **core** | Every task | [SKILL.md](core/SKILL.md) |
|
|
15
|
+
| **code-standards** | Writing, reviewing, or refactoring C# code | [SKILL.md](code-standards/SKILL.md) |
|
|
16
|
+
| **design** | Designing, architecting, or implementing patterns | [SKILL.md](design/SKILL.md) |
|
|
17
|
+
| **dotnet-best-practices** | Writing, reviewing, refactoring, or optimizing .NET/C# code | [SKILL.md](dotnet-best-practices/SKILL.md) |
|
|
18
|
+
| **csharp-xunit** | Get best practices for XUnit unit testing, including data-driven tests | [SKILL.md](csharp-xunit/SKILL.md) |
|
|
19
|
+
| **mcp_dotnet** | Building, reviewing, or extending .NET MCP server tools, transports, and integration points | [SKILL.md](mcp_dotnet/SKILL.md) |
|
|
20
|
+
| **dotnet-api** | Creating, structuring, or reviewing .NET 10 Web API projects with Swagger/OpenAPI, CORS, compression, auth, versioning, and error handling | [SKILL.md](dotnet-api/SKILL.md) |
|
|
21
|
+
| **harness** | Changing agent instructions, validation scripts, CI workflows, hooks, or operational guardrails | [SKILL.md](harness/SKILL.md) |
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Skills
|
|
2
|
+
|
|
3
|
+
This folder is the canonical source of truth for reusable skills used by all AI tools and IDEs in this repository.
|
|
4
|
+
|
|
5
|
+
Do not duplicate skill content under `.github/`, `.copilot/`, `.codex/`, or other tool-specific folders.
|
|
6
|
+
Those tools should load skill definitions from this folder.
|
|
7
|
+
|
|
8
|
+
## Skill Index
|
|
9
|
+
|
|
10
|
+
Start with `AgentSkills/skills/INDEX.md`, then load only the skills that match the task.
|
|
11
|
+
|
|
12
|
+
## Harness Skill
|
|
13
|
+
|
|
14
|
+
Use `AgentSkills/skills/harness/SKILL.md` when changing guides, sensors, hooks, CI, validation, or operational guardrails.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-standards
|
|
3
|
+
description: >
|
|
4
|
+
Load when writing, reviewing, or refactoring C# code.
|
|
5
|
+
Covers naming, structure, comments, and commit hygiene.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Code Standards
|
|
9
|
+
|
|
10
|
+
Language: C#. Every example is production code, not pseudocode.
|
|
11
|
+
|
|
12
|
+
## 1. No Magic Values
|
|
13
|
+
|
|
14
|
+
```csharp
|
|
15
|
+
// Bad
|
|
16
|
+
if (role == 3) { }
|
|
17
|
+
|
|
18
|
+
// Good
|
|
19
|
+
private const int AdminRoleId = 3;
|
|
20
|
+
if (role == AdminRoleId) { }
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 2. Meaningful Names
|
|
24
|
+
|
|
25
|
+
Names explain what a value represents and why it matters. If a comment is needed to explain a variable, rename it.
|
|
26
|
+
|
|
27
|
+
```csharp
|
|
28
|
+
// Bad
|
|
29
|
+
int d = 86400;
|
|
30
|
+
bool flag = true;
|
|
31
|
+
|
|
32
|
+
// Good
|
|
33
|
+
const int SecondsPerDay = 86400;
|
|
34
|
+
bool isUserVerified = true;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 3. One Function, One Responsibility
|
|
38
|
+
|
|
39
|
+
One function should do one thing. If you cannot summarize it in one sentence, split it.
|
|
40
|
+
|
|
41
|
+
## 4. Descriptive Booleans
|
|
42
|
+
|
|
43
|
+
```csharp
|
|
44
|
+
// Bad
|
|
45
|
+
bool check = true;
|
|
46
|
+
|
|
47
|
+
// Good
|
|
48
|
+
bool hasPermission = true;
|
|
49
|
+
bool isSessionExpired = false;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 5. DRY
|
|
53
|
+
|
|
54
|
+
Keep one source of truth per piece of logic. Apply judgment: premature abstraction is also harmful.
|
|
55
|
+
|
|
56
|
+
## 6. Early Returns Over Deep Nesting
|
|
57
|
+
|
|
58
|
+
```csharp
|
|
59
|
+
// Bad
|
|
60
|
+
void Process(User user)
|
|
61
|
+
{
|
|
62
|
+
if (user != null)
|
|
63
|
+
{
|
|
64
|
+
if (user.IsActive)
|
|
65
|
+
{
|
|
66
|
+
// Main logic
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Good
|
|
72
|
+
void Process(User user)
|
|
73
|
+
{
|
|
74
|
+
if (user is null) return;
|
|
75
|
+
if (!user.IsActive) return;
|
|
76
|
+
|
|
77
|
+
// Main logic
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 7. Comment Why, Not What
|
|
82
|
+
|
|
83
|
+
```csharp
|
|
84
|
+
// Bad
|
|
85
|
+
// Increment counter.
|
|
86
|
+
count++;
|
|
87
|
+
|
|
88
|
+
// Good
|
|
89
|
+
// Back off before HTTP 429; this API caps requests at 100 per minute.
|
|
90
|
+
if (requestCount >= RateLimitBackoffThreshold) { }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 8. Limit Function Arguments
|
|
94
|
+
|
|
95
|
+
More than 3 arguments should usually become a config object, command object, or record.
|
|
96
|
+
|
|
97
|
+
```csharp
|
|
98
|
+
// Bad
|
|
99
|
+
CreateUser("Alice", "alice@example.com", true, "admin", "UTC");
|
|
100
|
+
|
|
101
|
+
// Good
|
|
102
|
+
CreateUser(new UserConfig
|
|
103
|
+
{
|
|
104
|
+
Name = "Alice",
|
|
105
|
+
Email = "alice@example.com",
|
|
106
|
+
IsVerified = true,
|
|
107
|
+
Role = Role.Admin,
|
|
108
|
+
Timezone = "UTC"
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 9. Meaningful Commits
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
Bad:
|
|
116
|
+
fix bug
|
|
117
|
+
update stuff
|
|
118
|
+
|
|
119
|
+
Good:
|
|
120
|
+
fix: prevent double-submit on payment
|
|
121
|
+
refactor: extract shared email validation
|
|
122
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: core
|
|
3
|
+
description: >
|
|
4
|
+
Load on every task. Non-negotiable principles that govern
|
|
5
|
+
all work: how to think, what to change, and how to verify.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Core Principles
|
|
9
|
+
|
|
10
|
+
> Simplification is the ultimate sophistication.
|
|
11
|
+
> Write code that is simple, small, easy to delete, and adds nothing unnecessary.
|
|
12
|
+
|
|
13
|
+
1. **Think Before Coding** – Understand the goal before writing a line. If requirements are ambiguous, **stop and ask** — assumptions compound. Surface tradeoffs to the caller, not just in comments.
|
|
14
|
+
2. **Simplicity First** - Write the minimum code that correctly solves the problem. Avoid speculative features.
|
|
15
|
+
3. **Surgical Changes** – Touch only what the task requires. Avoid "while I'm here" changes. Refactoring is a separate, explicit task — never bundled into a feature or fix.
|
|
16
|
+
4. **Goal-Driven Testing** – Define success before writing code. Tests are the contract. Cover the failure path — a test suite that only passes on happy inputs is not a contract, it's a wish.
|
|
17
|
+
5. **No Race Conditions** - Treat shared mutable state as dangerous. Prefer immutability.
|
|
18
|
+
6. **Agent Memory** – Every task is a learning loop. Read `AgentSkills/memory/index.md` at task start, then load only the domain file(s) matching your task. Before closing, check if a new lesson is warranted — if so, read `AgentSkills/memory/schema.md`, append one line to the correct domain file, and update the count in `index.md`.
|
|
19
|
+
|
|
20
|
+
7. **Fail Loudly, Recover Gracefully** – Errors are a first-class output. When something goes wrong, fail loudly with context (what, where, relevant IDs). Never swallow exceptions silently. Recovery paths must be as deliberate as the happy path.
|
|
21
|
+
|
|
22
|
+
8. **Prefer Reversible Moves** – When two approaches solve the problem equally well, choose the one that can be undone. Flag irreversible changes (schema drops, destructive migrations, hard deletes) explicitly before executing them.
|
|
23
|
+
|
|
24
|
+
## Prerequisite Gate
|
|
25
|
+
|
|
26
|
+
Every task starts with the shared operating contract in
|
|
27
|
+
`AgentSkills/OPERATING.md`.
|
|
28
|
+
|
|
29
|
+
Before editing, confirm that you have:
|
|
30
|
+
|
|
31
|
+
- [ ] Read `AgentSkills/memory/index.md` and loaded only the relevant domain
|
|
32
|
+
lesson file(s).
|
|
33
|
+
- [ ] Read `AgentSkills/skills/INDEX.md`.
|
|
34
|
+
- [ ] Loaded this core skill.
|
|
35
|
+
- [ ] Loaded task-specific skills and agent definitions only when they apply.
|
|
36
|
+
- [ ] Identified the expected verification command(s).
|
|
37
|
+
- [ ] Checked the worktree context so existing user changes are preserved.
|
|
38
|
+
|
|
39
|
+
## Pre-submit Checklist
|
|
40
|
+
|
|
41
|
+
### Scope
|
|
42
|
+
|
|
43
|
+
- [ ] Only required files changed; no unrelated refactors or metadata churn.
|
|
44
|
+
- [ ] Public documentation changed only when behavior, setup, commands, or usage changed.
|
|
45
|
+
- [ ] Commit message states what changed and why, when a commit is made.
|
|
46
|
+
- [ ] Memory was updated only if a mistake or durable project-specific rule was discovered.
|
|
47
|
+
|
|
48
|
+
### Design and Maintainability
|
|
49
|
+
|
|
50
|
+
- [ ] Code is as simple as possible, but no simpler.
|
|
51
|
+
- [ ] No speculative generality or unused extension points.
|
|
52
|
+
- [ ] Each function does one thing.
|
|
53
|
+
- [ ] No argument list longer than 4; use an object, options type, or record.
|
|
54
|
+
- [ ] No nesting deeper than 2 levels; prefer early returns.
|
|
55
|
+
- [ ] No duplicated logic; shared behavior is extracted only when it is real reuse.
|
|
56
|
+
- [ ] SOLID respected, especially Single Responsibility.
|
|
57
|
+
- [ ] Important values are named; no magic literals.
|
|
58
|
+
- [ ] Comments explain why, not what the code already says.
|
|
59
|
+
|
|
60
|
+
### Reliability and Security
|
|
61
|
+
|
|
62
|
+
- [ ] No race condition on shared mutable state.
|
|
63
|
+
- [ ] All async operations have a cancellation path.
|
|
64
|
+
- [ ] No sensitive data such as keys, PII, or tokens appears in logs, errors, commits, or responses.
|
|
65
|
+
- [ ] External inputs are validated before use.
|
|
66
|
+
- [ ] Rendered outputs are sanitized where applicable.
|
|
67
|
+
- [ ] Errors include useful context: what failed, where, and relevant IDs.
|
|
68
|
+
- [ ] Structured log entries are used; no raw string concatenation in logs.
|
|
69
|
+
- [ ] Correlation or trace IDs are propagated on cross-service calls.
|
|
70
|
+
|
|
71
|
+
### API and Contract Behavior
|
|
72
|
+
|
|
73
|
+
- [ ] API responses use correct HTTP status codes; errors are not returned as `200`.
|
|
74
|
+
- [ ] Collection endpoints include pagination and filtering where applicable.
|
|
75
|
+
- [ ] Existing API contracts are preserved unless a versioned breaking change is intentional.
|
|
76
|
+
- [ ] MCP, REST, and application contracts stay aligned when they expose the same behavior.
|
|
77
|
+
|
|
78
|
+
### Tests and Verification
|
|
79
|
+
|
|
80
|
+
- [ ] Tests cover failure paths, not just happy paths.
|
|
81
|
+
- [ ] Test names describe behavior, not implementation.
|
|
82
|
+
- [ ] Tests do not depend on external state or execution order.
|
|
83
|
+
- [ ] Relevant build, test, format, and harness commands were run, or skipped with a clear reason.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: csharp-xunit
|
|
3
|
+
description: 'Get best practices for XUnit unit testing, including data-driven tests'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# XUnit Best Practices
|
|
7
|
+
|
|
8
|
+
Your goal is to help me write effective unit tests with XUnit, covering both standard and data-driven testing approaches.
|
|
9
|
+
|
|
10
|
+
## Project Setup
|
|
11
|
+
|
|
12
|
+
- Use a separate test project with naming convention `[ProjectName].Tests`
|
|
13
|
+
- Reference Microsoft.NET.Test.Sdk, xunit, and xunit.runner.visualstudio packages
|
|
14
|
+
- Create test classes that match the classes being tested (e.g., `CalculatorTests` for `Calculator`)
|
|
15
|
+
- Use .NET SDK test commands: `dotnet test` for running tests
|
|
16
|
+
|
|
17
|
+
## Test Structure
|
|
18
|
+
|
|
19
|
+
- No test class attributes required (unlike MSTest/NUnit)
|
|
20
|
+
- Use fact-based tests with `[Fact]` attribute for simple tests
|
|
21
|
+
- Follow the Arrange-Act-Assert (AAA) pattern
|
|
22
|
+
- Name tests using the pattern `MethodName_Scenario_ExpectedBehavior`
|
|
23
|
+
- Use constructor for setup and `IDisposable.Dispose()` for teardown
|
|
24
|
+
- Use `IClassFixture<T>` for shared context between tests in a class
|
|
25
|
+
- Use `ICollectionFixture<T>` for shared context between multiple test classes
|
|
26
|
+
|
|
27
|
+
## Standard Tests
|
|
28
|
+
|
|
29
|
+
- Keep tests focused on a single behavior
|
|
30
|
+
- Avoid testing multiple behaviors in one test method
|
|
31
|
+
- Use clear assertions that express intent
|
|
32
|
+
- Include only the assertions needed to verify the test case
|
|
33
|
+
- Make tests independent and idempotent (can run in any order)
|
|
34
|
+
- Avoid test interdependencies
|
|
35
|
+
|
|
36
|
+
## Data-Driven Tests
|
|
37
|
+
|
|
38
|
+
- Use `[Theory]` combined with data source attributes
|
|
39
|
+
- Use `[InlineData]` for inline test data
|
|
40
|
+
- Use `[MemberData]` for method-based test data
|
|
41
|
+
- Use `[ClassData]` for class-based test data
|
|
42
|
+
- Create custom data attributes by implementing `DataAttribute`
|
|
43
|
+
- Use meaningful parameter names in data-driven tests
|
|
44
|
+
|
|
45
|
+
## Assertions
|
|
46
|
+
|
|
47
|
+
- Use `Assert.Equal` for value equality
|
|
48
|
+
- Use `Assert.Same` for reference equality
|
|
49
|
+
- Use `Assert.True`/`Assert.False` for boolean conditions
|
|
50
|
+
- Use `Assert.Contains`/`Assert.DoesNotContain` for collections
|
|
51
|
+
- Use `Assert.Matches`/`Assert.DoesNotMatch` for regex pattern matching
|
|
52
|
+
- Use `Assert.Throws<T>` or `await Assert.ThrowsAsync<T>` to test exceptions
|
|
53
|
+
- Use fluent assertions library for more readable assertions
|
|
54
|
+
|
|
55
|
+
## Mocking and Isolation
|
|
56
|
+
|
|
57
|
+
- Consider using Moq or NSubstitute alongside XUnit
|
|
58
|
+
- Mock dependencies to isolate units under test
|
|
59
|
+
- Use interfaces to facilitate mocking
|
|
60
|
+
- Consider using a DI container for complex test setups
|
|
61
|
+
|
|
62
|
+
## Test Organization
|
|
63
|
+
|
|
64
|
+
- Group tests by feature or component
|
|
65
|
+
- Use `[Trait("Category", "CategoryName")]` for categorization
|
|
66
|
+
- Use collection fixtures to group tests with shared dependencies
|
|
67
|
+
- Consider output helpers (`ITestOutputHelper`) for test diagnostics
|
|
68
|
+
- Skip tests conditionally with `Skip = "reason"` in fact/theory attributes
|