@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.
Files changed (45) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +92 -0
  3. package/bin/agent-skills.js +7 -0
  4. package/package.json +37 -0
  5. package/src/__tests__/copySkills.test.js +161 -0
  6. package/src/__tests__/list.test.js +49 -0
  7. package/src/__tests__/manifest.test.js +72 -0
  8. package/src/commands/add.js +89 -0
  9. package/src/commands/dotnet-setup.js +67 -0
  10. package/src/commands/init.js +42 -0
  11. package/src/commands/list.js +41 -0
  12. package/src/index.js +33 -0
  13. package/src/lib/copySkills.js +84 -0
  14. package/src/lib/manifest.js +117 -0
  15. package/src/lib/resolvePack.js +44 -0
  16. package/src/templates/dotnet/AgentSkills/OPERATING.md +85 -0
  17. package/src/templates/dotnet/AgentSkills/README.md +64 -0
  18. package/src/templates/dotnet/AgentSkills/agents/README.md +16 -0
  19. package/src/templates/dotnet/AgentSkills/agents/architect.agent.md +59 -0
  20. package/src/templates/dotnet/AgentSkills/agents/developer.agent.md +88 -0
  21. package/src/templates/dotnet/AgentSkills/entry-points/AGENTS.md +16 -0
  22. package/src/templates/dotnet/AgentSkills/entry-points/CLAUDE.md +16 -0
  23. package/src/templates/dotnet/AgentSkills/entry-points/copilot-instructions.md +16 -0
  24. package/src/templates/dotnet/AgentSkills/entry-points/cursor-instructions.md +16 -0
  25. package/src/templates/dotnet/AgentSkills/memory/index.md +22 -0
  26. package/src/templates/dotnet/AgentSkills/memory/lessons/api.md +3 -0
  27. package/src/templates/dotnet/AgentSkills/memory/lessons/auth.md +3 -0
  28. package/src/templates/dotnet/AgentSkills/memory/lessons/csharp.md +3 -0
  29. package/src/templates/dotnet/AgentSkills/memory/lessons/db.md +3 -0
  30. package/src/templates/dotnet/AgentSkills/memory/lessons/design.md +3 -0
  31. package/src/templates/dotnet/AgentSkills/memory/lessons/infra.md +7 -0
  32. package/src/templates/dotnet/AgentSkills/memory/lessons/mcp.md +3 -0
  33. package/src/templates/dotnet/AgentSkills/memory/lessons/testing.md +3 -0
  34. package/src/templates/dotnet/AgentSkills/memory/schema.md +26 -0
  35. package/src/templates/dotnet/AgentSkills/skills/INDEX.md +21 -0
  36. package/src/templates/dotnet/AgentSkills/skills/README.md +14 -0
  37. package/src/templates/dotnet/AgentSkills/skills/code-standards/SKILL.md +122 -0
  38. package/src/templates/dotnet/AgentSkills/skills/core/SKILL.md +83 -0
  39. package/src/templates/dotnet/AgentSkills/skills/csharp-xunit/SKILL.md +68 -0
  40. package/src/templates/dotnet/AgentSkills/skills/design/SKILL.md +108 -0
  41. package/src/templates/dotnet/AgentSkills/skills/dotnet-api/SKILL.md +303 -0
  42. package/src/templates/dotnet/AgentSkills/skills/dotnet-best-practices/SKILL.md +170 -0
  43. package/src/templates/dotnet/AgentSkills/skills/harness/SKILL.md +62 -0
  44. package/src/templates/dotnet/AgentSkills/skills/mcp_dotnet/SKILL.md +54 -0
  45. 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,3 @@
1
+ # API Lessons
2
+
3
+ RULE: Controllers dispatch only via MediatR; all business rules belong in Domain Entities or Domain Services, never in Handlers or Controllers. #cqrs-violation 2026-05-31
@@ -0,0 +1,3 @@
1
+ # Auth Lessons
2
+
3
+ <!-- No lessons yet. Append using the format in memory/schema.md -->
@@ -0,0 +1,3 @@
1
+ # C# Lessons
2
+
3
+ <!-- No lessons yet. Append using the format in memory/schema.md -->
@@ -0,0 +1,3 @@
1
+ # DB Lessons
2
+
3
+ <!-- No lessons yet. Append using the format in memory/schema.md -->
@@ -0,0 +1,3 @@
1
+ # Design Lessons
2
+
3
+ <!-- No lessons yet. Append using the format in memory/schema.md -->
@@ -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,3 @@
1
+ # MCP Lessons
2
+
3
+ <!-- No lessons yet. Append using the format in memory/schema.md -->
@@ -0,0 +1,3 @@
1
+ # Testing Lessons
2
+
3
+ <!-- No lessons yet. Append using the format in memory/schema.md -->
@@ -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