@pratikpsl/agent-skills 0.9.0 → 1.0.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 (93) hide show
  1. package/README.md +59 -99
  2. package/dist/bin/agent-skills.d.ts.map +1 -1
  3. package/dist/bin/agent-skills.js +0 -3
  4. package/dist/bin/agent-skills.js.map +1 -1
  5. package/dist/cli/index.js +41 -33
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/core/ide-map.d.ts +3 -9
  8. package/dist/core/ide-map.d.ts.map +1 -1
  9. package/dist/core/ide-map.js +16 -33
  10. package/dist/core/ide-map.js.map +1 -1
  11. package/dist/core/install-template.d.ts +21 -0
  12. package/dist/core/install-template.d.ts.map +1 -0
  13. package/dist/core/install-template.js +119 -0
  14. package/dist/core/install-template.js.map +1 -0
  15. package/dist/core/resolve-template.d.ts +4 -0
  16. package/dist/core/resolve-template.d.ts.map +1 -0
  17. package/dist/core/resolve-template.js +22 -0
  18. package/dist/core/resolve-template.js.map +1 -0
  19. package/package.json +2 -2
  20. package/templates/default/instructions.md +26 -28
  21. package/templates/dotnet/AgentSkills/agents/architect.agent.md +8 -54
  22. package/templates/dotnet/AgentSkills/agents/developer.agent.md +8 -83
  23. package/templates/dotnet/AgentSkills/skills/csharp-xunit/SKILL.md +32 -58
  24. package/templates/dotnet/AgentSkills/skills/dotnet-best-practices/SKILL.md +62 -153
  25. package/templates/dotnet/AgentSkills/skills/performance/SKILL.md +18 -0
  26. package/templates/react/AgentSkills/agents/developer.agent.md +23 -0
  27. package/templates/react/AgentSkills/skills/performance/SKILL.md +18 -0
  28. package/templates/react/AgentSkills/skills/react-typescript/SKILL.md +22 -0
  29. package/templates/react/AgentSkills/skills/testing/SKILL.md +17 -0
  30. package/templates/shared/AgentSkills/OPERATING.md +15 -0
  31. package/templates/shared/AgentSkills/agents/architect.agent.md +12 -0
  32. package/templates/shared/AgentSkills/agents/reviewer.agent.md +26 -0
  33. package/templates/shared/AgentSkills/skills/security/SKILL.md +18 -0
  34. package/templates/shared/AgentSkills/skills/standards/SKILL.md +27 -0
  35. package/templates/shared/entry-points/instructions.md +24 -0
  36. package/dist/cli/commands/add.d.ts +0 -3
  37. package/dist/cli/commands/add.d.ts.map +0 -1
  38. package/dist/cli/commands/add.js +0 -73
  39. package/dist/cli/commands/add.js.map +0 -1
  40. package/dist/cli/commands/dotnet-setup.d.ts +0 -5
  41. package/dist/cli/commands/dotnet-setup.d.ts.map +0 -1
  42. package/dist/cli/commands/dotnet-setup.js +0 -83
  43. package/dist/cli/commands/dotnet-setup.js.map +0 -1
  44. package/dist/cli/commands/init.d.ts +0 -3
  45. package/dist/cli/commands/init.d.ts.map +0 -1
  46. package/dist/cli/commands/init.js +0 -36
  47. package/dist/cli/commands/init.js.map +0 -1
  48. package/dist/cli/commands/list.d.ts +0 -3
  49. package/dist/cli/commands/list.d.ts.map +0 -1
  50. package/dist/cli/commands/list.js +0 -37
  51. package/dist/cli/commands/list.js.map +0 -1
  52. package/dist/cli/commands/setup.d.ts +0 -9
  53. package/dist/cli/commands/setup.d.ts.map +0 -1
  54. package/dist/cli/commands/setup.js +0 -77
  55. package/dist/cli/commands/setup.js.map +0 -1
  56. package/dist/core/copy-skills.d.ts +0 -30
  57. package/dist/core/copy-skills.d.ts.map +0 -1
  58. package/dist/core/copy-skills.js +0 -84
  59. package/dist/core/copy-skills.js.map +0 -1
  60. package/dist/core/load-pack.d.ts +0 -15
  61. package/dist/core/load-pack.d.ts.map +0 -1
  62. package/dist/core/load-pack.js +0 -35
  63. package/dist/core/load-pack.js.map +0 -1
  64. package/dist/core/manifest.d.ts +0 -21
  65. package/dist/core/manifest.d.ts.map +0 -1
  66. package/dist/core/manifest.js +0 -170
  67. package/dist/core/manifest.js.map +0 -1
  68. package/dist/core/resolve-pack.d.ts +0 -7
  69. package/dist/core/resolve-pack.d.ts.map +0 -1
  70. package/dist/core/resolve-pack.js +0 -59
  71. package/dist/core/resolve-pack.js.map +0 -1
  72. package/templates/dotnet/AgentSkills/OPERATING.md +0 -85
  73. package/templates/dotnet/AgentSkills/README.md +0 -64
  74. package/templates/dotnet/AgentSkills/agents/README.md +0 -16
  75. package/templates/dotnet/AgentSkills/entry-points/entry-point.md +0 -49
  76. package/templates/dotnet/AgentSkills/memory/index.md +0 -22
  77. package/templates/dotnet/AgentSkills/memory/lessons/api.md +0 -3
  78. package/templates/dotnet/AgentSkills/memory/lessons/auth.md +0 -3
  79. package/templates/dotnet/AgentSkills/memory/lessons/csharp.md +0 -3
  80. package/templates/dotnet/AgentSkills/memory/lessons/db.md +0 -3
  81. package/templates/dotnet/AgentSkills/memory/lessons/design.md +0 -3
  82. package/templates/dotnet/AgentSkills/memory/lessons/infra.md +0 -8
  83. package/templates/dotnet/AgentSkills/memory/lessons/mcp.md +0 -3
  84. package/templates/dotnet/AgentSkills/memory/lessons/testing.md +0 -3
  85. package/templates/dotnet/AgentSkills/memory/schema.md +0 -26
  86. package/templates/dotnet/AgentSkills/skills/INDEX.md +0 -21
  87. package/templates/dotnet/AgentSkills/skills/README.md +0 -14
  88. package/templates/dotnet/AgentSkills/skills/code-standards/SKILL.md +0 -122
  89. package/templates/dotnet/AgentSkills/skills/core/SKILL.md +0 -83
  90. package/templates/dotnet/AgentSkills/skills/design/SKILL.md +0 -108
  91. package/templates/dotnet/AgentSkills/skills/harness/SKILL.md +0 -62
  92. package/templates/dotnet/AgentSkills/skills/mcp_dotnet/SKILL.md +0 -54
  93. package/templates/shared/manifest.json +0 -57
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pratikpsl/agent-skills",
3
3
  "type": "module",
4
- "version": "0.9.0",
4
+ "version": "1.0.0",
5
5
  "description": "CLI to scaffold and manage AI agent skills across projects — like shadcn/ui, but for Cursor, Claude, Codex, Copilot, Antigravity, and more",
6
6
  "bin": {
7
7
  "agent-skills": "dist/bin/agent-skills.js"
@@ -47,7 +47,7 @@
47
47
  "build": "tsc",
48
48
  "test": "vitest run",
49
49
  "test:watch": "vitest",
50
- "dry-run": "bun run build && npm publish --dry-run"
50
+ "dry-run": "npm run build && npm pack --dry-run"
51
51
  },
52
52
  "dependencies": {
53
53
  "commander": "^15.0.0"
@@ -2,37 +2,35 @@
2
2
 
3
3
  ## Goal
4
4
  Implement the requested change with production-quality code, preserving existing behavior and
5
- minimizing the diff, following the project's own architecture and conventions - unless explicitly
6
- told otherwise.
5
+ minimizing the diff, following the project's own architecture and conventions.
7
6
 
8
7
  ## Principles
9
- - Match existing code style, patterns, naming, architecture, and folder structure.
10
- - Prefer simple, clean, clear, efficient, maintainable, manageable code over clever or complex solutions.
11
- - Make the smallest change that satisfies the request; don't touch unrelated code.
12
- - Favor deletion over addition - don't grow the codebase for changes that don't need it.
13
- - Reuse existing utilities/helpers/components before writing new ones.
14
- - No new dependencies unless necessary. If one is needed: popular, actively maintained,
15
- permissively licensed (MIT/Apache-2.0), no known security issues.
16
- - Apply SOLID, DRY, KISS. Single-responsibility functions/classes, Separation of concern. No duplicated logic.
17
- - No magic numbers/strings - use named constants/enums.
18
- - Each function must be a maximum of 50 lines.
19
- - Use meaningful names for classes, methods, variables, and all other code.
20
- - Handle errors the way the codebase already does.
21
- - Never hardcode secrets, keys, or credentials; follow the project's existing security practices.
22
- - Use idiomatic async/non-blocking I/O and ensure the code is free of race conditions and deadlocks.
23
- - Avoid deprecated APIs and patterns.
24
- - Comment only where intent isn't obvious from the code itself.
25
- - Don't change public APIs/interfaces, formatting, or file layout unless the task requires it.
26
- - Don't add features, abstractions, or "improvements" that weren't asked for.
27
- - If a requirement is ambiguous or missing critical detail, ask before guessing.
8
+
9
+ ### Scope & Intent
10
+ - Make the smallest change that satisfies the request; touch only what is explicitly required.
11
+ - Do not add unrequested features, speculative abstractions, or unsolicited refactoring (YAGNI).
12
+ - Favor deletion over addition; reuse existing utilities and helpers before creating new ones.
13
+ - If requirements are ambiguous or missing critical details, ask before guessing.
14
+
15
+ ### Code Quality & Design
16
+ - Match existing code style, patterns, naming, error handling, and folder structure.
17
+ - Apply SOLID, DRY, and KISS: single-responsibility functions, separation of concerns, no duplicated logic.
18
+ - Keep functions under 50 lines, nesting depth at most 2 levels (prefer early returns), and signatures under 4 parameters.
19
+ - Use meaningful names and named constants/enums (no magic numbers or strings).
20
+ - Design self-describing APIs, structured schemas, and human-/machine-readable contracts.
21
+ - Comment only where non-obvious rationale is required, not what the code already says.
22
+
23
+ ### Reliability & Security
24
+ - Never hardcode, commit, or log secrets, credentials, tokens, or sensitive user data.
25
+ - Validate and sanitize external input; use parameterized queries to prevent injection.
26
+ - Use idiomatic non-blocking `async`/`await`; ensure code is free of race conditions and deadlocks.
27
+ - Avoid deprecated APIs and patterns; introduce new dependencies only when strictly necessary (permissive license, actively maintained).
28
28
 
29
29
  ## Definition of Done
30
- - Builds and runs without errors.
31
- - No debug code, dead code, unused imports, or temp files left behind.
32
- - Tests pass; add/update tests for the change if the project has a test suite.
33
- - The change is minimal, focused, and easy to review.
30
+ - Builds cleanly and all tests pass without errors or warnings.
31
+ - No debug code, dead code, unused imports, or temporary files left behind.
32
+ - Changes are minimal, focused, covered by tests, and easy to review.
34
33
 
35
34
  ## Agent Memory
36
- Read `AgentSkills/memory/index.md` at the start of every task (create it if missing); load only the relevant domain file(s) to avoid repeating past mistakes.
37
- When a mistake is made and corrected, record a clear, actionable lesson in the matching domain file `AgentSkills/memory/lessons/<domain>.md` (create if missing) for future reference.
38
- Keep lessons clear and understandable for both humans and agents, and maintain `index.md` by registering new domains and keeping lesson counts accurate.
35
+ - Read `AgentSkills/memory/index.md` at the start of every task (create if missing); load only relevant domain lessons.
36
+ - When a mistake is corrected or a durable rule discovered, record an actionable lesson in `AgentSkills/memory/lessons/<domain>.md` (create if missing) and update `index.md`.
@@ -1,59 +1,13 @@
1
1
  ---
2
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.
3
+ description: .NET architectural design, Clean Architecture, CQRS, and API boundaries.
7
4
  ---
8
5
 
9
- # Architect Agent
6
+ # .NET Architect
10
7
 
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
- ```
8
+ ## Architectural Principles
9
+ - **Separation of Concerns**: Enforce clean boundaries (Domain, Application, Infrastructure, API).
10
+ - **CQRS Pattern**: Separate commands (mutating state) from queries (read-only projections).
11
+ - **Domain Encapsulation**: Place core business rules in domain entities or domain services; keep API controllers and minimal endpoints thin.
12
+ - **Contract-First Design**: Define relational schemas, entity relationships, indexes, and immutable DTO contracts before implementation.
13
+ - **Protocol Neutrality**: Design application handlers (e.g. MediatR) to serve REST, gRPC, and MCP tools without coupling to transport logic.
@@ -1,88 +1,13 @@
1
1
  ---
2
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.
3
+ description: .NET C# feature implementation, ASP.NET Core APIs, MediatR, and EF Core.
7
4
  ---
8
5
 
9
- # Developer Agent
6
+ # .NET Developer
10
7
 
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
- ```
8
+ ## Implementation Principles
9
+ - **Modern C# Idioms**: Use `record` for immutable DTOs/commands/queries, `sealed` classes by default, and primary constructors where appropriate.
10
+ - **Clean Endpoints**: Keep controllers thin; handle validation and dispatch requests through mediator handlers.
11
+ - **Async & Cancellation**: Use non-blocking `async`/`await` throughout; propagate `CancellationToken` to all EF Core, HTTP, and async calls.
12
+ - **Query Efficiency**: Always use `.AsNoTracking()` for read-only queries, project explicitly to DTOs, and prevent N+1 query patterns.
13
+ - **Complexity Limits**: Keep methods under 50 lines, avoid blocking calls (`.Result`, `.Wait()`), and eliminate magic numbers/strings.
@@ -1,68 +1,42 @@
1
1
  ---
2
2
  name: csharp-xunit
3
- description: 'Get best practices for XUnit unit testing, including data-driven tests'
3
+ description: Best practices for xUnit testing, data-driven theories, mocking, fixtures, and assertions.
4
4
  ---
5
5
 
6
- # XUnit Best Practices
6
+ # xUnit Best Practices
7
7
 
8
- Your goal is to help me write effective unit tests with XUnit, covering both standard and data-driven testing approaches.
8
+ Guidelines for writing effective, isolated, and maintainable unit and integration tests with xUnit.
9
9
 
10
- ## Project Setup
10
+ ## Project Setup & Conventions
11
+ - Place tests in a dedicated test project named `[ProjectName].Tests`.
12
+ - Reference `Microsoft.NET.Test.Sdk`, `xunit`, and `xunit.runner.visualstudio`.
13
+ - Match test class names to the class under test (e.g., `OrderServiceTests` for `OrderService`).
14
+ - Execute tests via standard CLI: `dotnet test`.
11
15
 
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
+ ## Test Structure & Naming
17
+ - Follow the **Arrange-Act-Assert (AAA)** pattern.
18
+ - Use the standard naming convention: `MethodName_Scenario_ExpectedBehavior`.
19
+ - Use constructors for test initialization and `IDisposable.Dispose()` for teardown.
20
+ - Use `IClassFixture<T>` for shared context across tests in a single class.
21
+ - Use `ICollectionFixture<T>` for shared context across multiple test classes.
16
22
 
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
23
+ ## Fact vs. Theory Tests
24
+ - **`[Fact]`**: For single-condition tests verifying one specific behavior.
25
+ - **`[Theory]`**: For data-driven tests testing multiple inputs and edge cases.
26
+ - `[InlineData(arg1, arg2)]`: For simple scalar test cases.
27
+ - `[MemberData(nameof(TestDataMethod))]`: For complex or generated test objects.
28
+ - `[ClassData(typeof(CustomTestDataClass))]`: For reusable external test datasets.
44
29
 
45
30
  ## 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
31
+ - Use specific assertions expressing intent:
32
+ - Values: `Assert.Equal(expected, actual)`, `Assert.NotEqual(...)`
33
+ - References: `Assert.Same(expected, actual)`
34
+ - Conditions: `Assert.True(condition)`, `Assert.False(condition)`
35
+ - Collections: `Assert.Contains(item, list)`, `Assert.DoesNotContain(...)`
36
+ - Exceptions: `Assert.Throws<T>(() => ...)` or `await Assert.ThrowsAsync<T>(() => ...)`
37
+ - Alternatively, use `FluentAssertions` where it improves assertion readability.
38
+
39
+ ## Isolation & Mocking
40
+ - Mock external dependencies and I/O boundaries using Moq or NSubstitute.
41
+ - Code against interfaces to enable clean mock substitution.
42
+ - Keep tests isolated, independent, and idempotent (no reliance on execution order or external state).
@@ -8,163 +8,72 @@ description: >
8
8
 
9
9
  # .NET/C# Best Practices
10
10
 
11
- Use this skill to keep .NET/C# changes simple, maintainable, testable, and aligned with this repository.
12
-
13
- ## Repository Defaults
14
-
15
- - Follow the target framework and language version declared in `Directory.Build.props`.
16
- - Current defaults are `net10.0` and `LangVersion` set to `latest`.
17
- - Use modern C# features only when they improve readability or correctness.
18
- - Prefer clear, boring code over clever code.
19
- - Keep changes scoped to the current feature or bug.
20
-
21
- ## Documentation and Structure
22
-
23
- - Add XML documentation comments for public APIs when they are part of the external or shared surface.
24
- - Include meaningful parameter and return descriptions when they add information beyond the name.
25
- - Organize code by feature/domain when the project already follows that structure.
26
- - Keep controllers, endpoints, handlers, validators, repositories, and DTOs in predictable folders.
27
- - Use namespaces that match the project and feature structure.
28
-
29
- ## CQRS and Architecture
30
-
31
- - Commands mutate state and should return nothing, an ID, or a small result.
32
- - Queries read state and must not mutate data.
33
- - Keep controllers and minimal API endpoints thin; they should validate transport concerns and dispatch through MediatR.
34
- - Put business rules in domain/application services or entities, not controllers.
35
- - Use one handler per command or query.
36
- - Prefer records for commands, queries, and DTOs when immutability is appropriate.
37
- - Mark classes `sealed` unless inheritance is intentionally supported.
38
- - Use interfaces for boundaries that need substitution, testing, or multiple implementations.
39
-
40
- ## Dependency Injection and Services
41
-
11
+ Use this skill to keep .NET/C# changes simple, maintainable, testable, and aligned with repository conventions.
12
+
13
+ ## Repository Defaults & Structure
14
+ - Follow target framework and language versions in `Directory.Build.props` (default `net10.0`, `LangVersion` `latest`).
15
+ - Add XML documentation comments for public/shared API surfaces.
16
+ - Organize code by feature or domain slices; place controllers, handlers, validators, repositories, and DTOs predictably.
17
+ - Prefer clear, direct code over complex or speculative patterns (YAGNI).
18
+
19
+ ## CQRS & Architecture
20
+ - **Commands**: Mutate state; return void, an identifier, or a minimal result.
21
+ - **Queries**: Read state only; never mutate data.
22
+ - **Thin Endpoints**: Keep controllers and minimal API endpoints thin; validate transport concerns and dispatch via mediator handlers.
23
+ - **Domain Logic**: Encapsulate domain rules in domain entities or domain services, never in transport handlers.
24
+ - **Immutability**: Use `record` for commands, queries, and DTOs; mark classes `sealed` unless inheritance is intentionally designed.
25
+ - **Interfaces**: Define interfaces for boundaries requiring testing, multiple implementations, or out-of-process integration.
26
+
27
+ ## Dependency Injection & Lifetimes
42
28
  - Use constructor injection or primary constructors for required dependencies.
43
- - Validate required dependencies when nullable flow does not already prove safety.
44
- - Register services with the narrowest correct lifetime:
45
- - `Singleton` for stateless, thread-safe services.
46
- - `Scoped` for request-bound services and EF Core `DbContext`.
47
- - `Transient` for lightweight stateless services.
48
- - Do not resolve services manually from `IServiceProvider` unless there is a clear framework boundary.
49
- - Avoid hidden global state.
50
-
51
- ## Async/Await
52
-
53
- - Use async/await for I/O, database, network, and long-running operations.
54
- - Do not block async work with `.Result`, `.Wait()`, or `.GetAwaiter().GetResult()`.
55
- - Prefer async all the way through the call chain.
56
- - Accept and pass `CancellationToken` on request, handler, EF Core, and HTTP calls.
57
- - Use `ConfigureAwait(false)` in reusable library code when appropriate; it is usually unnecessary in ASP.NET Core request code.
58
- - Avoid `async void` except for event handlers.
59
-
60
- ## EF Core and Database Performance
61
-
62
- - Avoid N+1 queries. Use projections, `Include`, explicit joins, or separate optimized queries.
63
- - Use `.AsNoTracking()` for read-only queries.
64
- - Select only required columns into DTOs instead of loading full entities.
65
- - Add pagination for list endpoints; avoid returning unbounded result sets.
66
- - Filter in the database, not in memory.
67
- - Use indexes for frequent filters, joins, and ordering paths.
68
- - Prefer `AnyAsync` over `CountAsync` when checking existence.
69
- - Avoid lazy loading in APIs unless there is a specific measured reason.
70
- - Use `SplitQuery` only when it avoids cartesian explosion from large includes.
71
- - Batch writes where possible and call `SaveChangesAsync` once per unit of work.
72
- - Consider `ExecuteUpdateAsync` and `ExecuteDeleteAsync` for bulk updates/deletes.
73
- - Consider compiled queries only for measured hot paths.
74
- - Always parameterize raw SQL if raw SQL is truly needed.
75
-
76
- ## Memory and Allocation Performance
77
-
78
- - Avoid unnecessary object creation in hot paths.
79
- - Use `StringBuilder` for repeated string concatenation in loops or large text generation.
80
- - Be careful with LINQ in hot paths; simple loops can reduce allocations and improve clarity.
81
- - Avoid exceptions for normal control flow.
82
- - Prefer `Array.Empty<T>()` over new empty arrays.
83
- - Reuse static readonly immutable data when safe.
84
- - Use pooling, `Span<T>`, `Memory<T>`, or `ValueTask` only when measurement shows a real benefit.
85
-
86
- ## Caching
87
-
88
- - Cache frequently used, slow-changing data to reduce database and network load.
89
- - Use in-memory caching for single-instance or per-node data.
90
- - Use distributed caching such as Redis for multi-instance deployments or shared cache state.
91
- - Define clear cache keys, expiration, invalidation, and size limits.
92
- - Avoid caching sensitive user data unless encryption, isolation, and expiry are correct.
93
- - Prevent cache stampedes for expensive entries with locking or single-flight behavior.
94
- - Do not cache data that must be strongly consistent unless the domain explicitly allows staleness.
95
-
96
- ## API Payload and Response Performance
97
-
98
- - Return DTOs that contain only the fields the caller needs.
99
- - Use pagination, filtering, and sorting parameters for collection endpoints.
100
- - Avoid sending large object graphs.
101
- - Enable response compression for compressible text responses such as JSON, HTML, CSS, and JavaScript.
102
- - Do not compress already compressed content such as images, videos, zip files, or PDFs.
103
- - Use ETags, `Last-Modified`, or cache headers where HTTP caching is safe.
104
- - Prefer streaming for large downloads instead of buffering the full payload in memory.
105
-
106
- ## Logging and Observability
107
-
108
- - Use structured logging with message templates and named properties.
109
- - Avoid excessive logging in hot paths, especially per-item logs in loops.
110
- - Do not use string interpolation for expensive log messages unless guarded by `logger.IsEnabled(...)`.
111
- - Log enough context to diagnose failures without logging secrets or personal data.
112
- - Use correlation IDs, request IDs, or tracing context across request boundaries.
113
- - Use metrics/tracing for performance-critical paths instead of relying only on logs.
114
-
115
- ## Efficient Data Structures
116
-
117
- - Use `Dictionary<TKey, TValue>` for fast key lookups.
118
- - Use `HashSet<T>` for uniqueness checks and membership tests.
119
- - Avoid repeated linear searches over large collections.
120
- - Use `List<T>` when order matters and append/read operations dominate.
121
- - Choose immutable or read-only collections when shared state should not change.
122
-
123
- ## HTTP and External Calls
124
-
29
+ - Register services with the narrowest appropriate lifetime:
30
+ - `Singleton`: Stateless, thread-safe services.
31
+ - `Scoped`: Request-bound services and EF Core `DbContext`.
32
+ - `Transient`: Lightweight, stateless operations.
33
+ - Avoid resolving services manually via `IServiceProvider` or introducing static global state.
34
+
35
+ ## Async & I/O
36
+ - Use `async`/`await` for all I/O, database, network, and file operations.
37
+ - Never block async code using `.Result`, `.Wait()`, or `.GetAwaiter().GetResult()`.
38
+ - Accept and propagate `CancellationToken` through all handler, EF Core, and outbound HTTP calls.
39
+ - Avoid `async void` except for top-level event handlers.
40
+
41
+ ## EF Core & Data Access
42
+ - Avoid N+1 queries by using explicit projections, `.Include()`, or separate optimized queries.
43
+ - Use `.AsNoTracking()` for all read-only queries.
44
+ - Select only needed columns into DTOs instead of loading full tracked entities.
45
+ - Implement server-side pagination, filtering, and sorting; never filter unbounded sets in memory.
46
+ - Prefer `AnyAsync()` over `CountAsync()` when testing for existence.
47
+ - Use `ExecuteUpdateAsync` and `ExecuteDeleteAsync` for bulk operations where appropriate.
48
+
49
+ ## Logging & Observability
50
+ - Use structured logging with message templates and named properties (`LogInformation("Order {OrderId} processed", id)`).
51
+ - Avoid logging inside tight loops or hot execution paths.
52
+ - Propagate correlation/request IDs across service and HTTP boundaries.
53
+ - Never log secrets, passwords, connection strings, or sensitive personal data (PII).
54
+
55
+ ## HTTP & Resilient Integration
125
56
  - Use `IHttpClientFactory` for outbound HTTP calls.
126
- - Set timeouts and pass cancellation tokens.
127
- - Avoid retry storms; use bounded retries with backoff for transient failures.
128
- - Do not make external calls inside tight loops when batching is possible.
129
- - Prefer resilient integration patterns for unreliable dependencies.
57
+ - Set explicit timeouts and pass cancellation tokens to all HTTP calls.
58
+ - Use bounded retries with exponential backoff for transient failures; avoid unbounded retry storms.
59
+ - Batch outbound requests rather than making external calls inside tight loops.
130
60
 
131
- ## Security
132
-
133
- - Validate and sanitize external input.
134
- - Use FluentValidation or existing validation patterns for request validation.
135
- - Never concatenate user input into SQL, file paths, shell commands, or logs.
136
- - Do not log secrets, tokens, passwords, connection strings, or sensitive personal data.
137
- - Use least-privilege configuration for database and external services.
61
+ ## Security & Validation
62
+ - Validate all incoming request payloads using FluentValidation or Data Annotations.
63
+ - Never concatenate raw user input into SQL queries, shell commands, or file paths.
64
+ - Follow the principle of least privilege for database connections and external service credentials.
138
65
 
139
66
  ## Testing Standards
140
-
141
- - Use xUnit for unit tests.
142
- - Use FluentAssertions where it improves readability.
143
- - Use Moq or the existing repository mocking style for dependencies.
144
- - Follow Arrange, Act, Assert.
145
- - Test success, failure, validation, null/empty input, and cancellation paths when relevant.
146
- - Keep tests deterministic and independent.
147
-
148
- ## Performance Workflow
149
-
150
- - Measure before optimizing unless the issue is obvious and local.
151
- - Prefer simple fixes before complex optimizations.
152
- - Use realistic data sizes when validating performance.
153
- - Consider tools such as logs, metrics, traces, `dotnet-counters`, `dotnet-trace`, BenchmarkDotNet, or database query plans.
154
- - Document any non-obvious optimization with the measured reason.
155
- - Do not trade correctness, security, or maintainability for small unmeasured gains.
67
+ - Use xUnit for unit and integration testing.
68
+ - Structure tests using Arrange-Act-Assert (AAA).
69
+ - Test happy paths, edge cases, validation failures, and cancellation flows.
70
+ - Keep tests isolated, deterministic, and idempotent.
156
71
 
157
72
  ## Review Checklist
158
-
159
- - [ ] No avoidable N+1 queries.
160
- - [ ] Read-only EF Core queries use `.AsNoTracking()`.
161
- - [ ] Queries project only required columns.
162
- - [ ] Async code does not block on tasks.
163
- - [ ] Cancellation tokens flow through I/O boundaries.
164
- - [ ] No excessive allocations in hot paths.
165
- - [ ] Caching has clear expiration and invalidation.
166
- - [ ] Logs are structured and not excessive.
167
- - [ ] API responses avoid unnecessary payload size.
168
- - [ ] Compression and HTTP caching are used only where appropriate.
169
- - [ ] Data structures match access patterns.
170
- - [ ] Tests cover the changed behavior.
73
+ - [ ] No N+1 queries; read-only EF Core queries use `.AsNoTracking()`.
74
+ - [ ] DTO projections used; no full entity graphs exposed to callers.
75
+ - [ ] Async methods propagate `CancellationToken` without blocking.
76
+ - [ ] DI lifetimes correctly configured (`Scoped` for DbContext).
77
+ - [ ] Structured logging used without leaking sensitive data or secrets.
78
+ - [ ] Input validation applied at boundaries.
79
+ - [ ] Tests pass and cover edge cases.
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: performance
3
+ description: .NET memory allocation reduction, Span/ReadOnlySpan, EF Core query tuning, and async efficiency.
4
+ ---
5
+
6
+ # .NET Performance
7
+
8
+ ## Memory & Allocation Optimization
9
+ - Minimize heap allocations in hot paths using `ReadOnlySpan<T>`, `Span<T>`, and `Memory<T>`.
10
+ - Use `ValueTask<T>` for asynchronous methods that frequently complete synchronously.
11
+ - Avoid boxing value types and eliminate unnecessary LINQ allocations inside tight loops.
12
+ - Use `ArrayPool<T>` or `StringBuilder` for buffer reuse in repetitive or large text/byte operations.
13
+
14
+ ## Database & I/O Efficiency
15
+ - Always use `.AsNoTracking()` for read-only EF Core queries to eliminate change tracking overhead.
16
+ - Use explicit projection (`.Select(x => new ... )`) to fetch only necessary database columns into DTOs.
17
+ - Stream large result sets using `IAsyncEnumerable<T>` instead of buffering entire collections in memory.
18
+ - Avoid N+1 queries by using explicit joins, `.Include()`, or split queries where cartesian explosion is a risk.
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: developer
3
+ description: React feature implementation, custom hooks, and state architecture.
4
+ ---
5
+
6
+ # React Developer
7
+
8
+ ## Component & State Principles
9
+ - Keep components focused on a single UI responsibility; decompose complex trees.
10
+ - Type props and state strictly using TypeScript discriminated unions for variant states.
11
+ - Colocate state with the closest consuming component; compute derived values during render.
12
+ - Use `useEffect` strictly for external synchronization and always return a cleanup function.
13
+ - Avoid speculative memoization (`useMemo`/`useCallback`) unless measured performance profiling justifies it.
14
+
15
+ ## User Interface & Accessibility
16
+ - Build with semantic HTML elements (`<button>`, `<dialog>`, `<form>`, `<nav>`) by default.
17
+ - Use `useId` for unique, accessible form controls and ARIA associations.
18
+ - Ensure all interactive elements have accessible names and visible focus states.
19
+ - Handle loading, empty, and error boundary states explicitly at the feature level.
20
+
21
+ ## Async & Resource Safety
22
+ - Use non-blocking `async`/`await` with `AbortController` signal propagation for cancellable data fetching.
23
+ - Clean up active subscriptions, intervals/timers, and abort controllers on component unmount.