@torus-engineering/tas-kit 1.5.0 → 1.6.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/.claude/agents/README.md +83 -0
- package/.claude/agents/architect.md +53 -0
- package/.claude/agents/aws-reviewer.md +71 -0
- package/.claude/agents/build-resolver.md +59 -0
- package/.claude/agents/code-architect.md +62 -0
- package/.claude/agents/code-explorer.md +63 -0
- package/.claude/agents/code-simplifier.md +53 -0
- package/.claude/agents/comment-analyzer.md +59 -0
- package/.claude/agents/conversation-analyzer.md +57 -0
- package/.claude/agents/csharp-reviewer.md +62 -0
- package/.claude/agents/database-reviewer.md +73 -0
- package/.claude/agents/doc-updater.md +66 -0
- package/.claude/agents/docs-lookup.md +55 -0
- package/.claude/agents/e2e-runner.md +61 -0
- package/.claude/agents/harness-optimizer.md +62 -0
- package/.claude/agents/loop-operator.md +56 -0
- package/.claude/agents/performance-optimizer.md +78 -0
- package/.claude/agents/planner.md +82 -0
- package/.claude/agents/pr-test-analyzer.md +68 -0
- package/.claude/agents/python-reviewer.md +67 -0
- package/.claude/agents/pytorch-build-resolver.md +76 -0
- package/.claude/agents/refactor-cleaner.md +70 -0
- package/.claude/agents/security-reviewer.md +79 -0
- package/.claude/agents/seo-specialist.md +75 -0
- package/.claude/agents/silent-failure-hunter.md +69 -0
- package/.claude/agents/tdd-guide.md +84 -0
- package/.claude/agents/type-design-analyzer.md +75 -0
- package/.claude/agents/typescript-reviewer.md +65 -0
- package/.claude/commands/ado-create.md +2 -1
- package/.claude/commands/ado-delete.md +3 -2
- package/.claude/commands/ado-get.md +2 -1
- package/.claude/commands/ado-status.md +2 -1
- package/.claude/commands/ado-update.md +2 -1
- package/.claude/commands/tas-adr.md +13 -12
- package/.claude/commands/tas-bug.md +97 -50
- package/.claude/commands/tas-design.md +3 -1
- package/.claude/commands/tas-dev.md +115 -0
- package/.claude/commands/tas-epic.md +4 -2
- package/.claude/commands/tas-feature.md +5 -3
- package/.claude/commands/tas-fix.md +47 -0
- package/.claude/commands/tas-plan.md +184 -0
- package/.claude/commands/tas-prd.md +3 -1
- package/.claude/commands/tas-review.md +104 -0
- package/.claude/commands/tas-sad.md +3 -1
- package/.claude/commands/tas-security.md +80 -0
- package/.claude/commands/tas-spec.md +50 -0
- package/.claude/commands/tas-story.md +77 -40
- package/.claude/commands/tas-verify.md +8 -0
- package/.claude/hooks/code-quality.js +127 -0
- package/.claude/hooks/session-end.js +116 -0
- package/.claude/rules/.gitkeep +0 -0
- package/.claude/rules/common/agents.md +65 -0
- package/.claude/rules/common/code-review.md +124 -0
- package/.claude/rules/common/coding-style.md +90 -0
- package/.claude/rules/common/development-workflow.md +44 -0
- package/.claude/rules/common/git-workflow.md +24 -0
- package/.claude/rules/common/hooks.md +30 -0
- package/.claude/rules/common/patterns.md +31 -0
- package/.claude/rules/common/performance.md +55 -0
- package/.claude/rules/common/post-review-agent.md +39 -0
- package/.claude/rules/common/project-status.md +80 -0
- package/.claude/rules/common/security.md +29 -0
- package/.claude/rules/common/stack-detection.md +29 -0
- package/.claude/rules/common/testing.md +57 -0
- package/.claude/rules/csharp/coding-style.md +72 -0
- package/.claude/rules/csharp/hooks.md +25 -0
- package/.claude/rules/csharp/patterns.md +50 -0
- package/.claude/rules/csharp/security.md +58 -0
- package/.claude/rules/csharp/testing.md +46 -0
- package/.claude/rules/python/coding-style.md +42 -0
- package/.claude/rules/python/hooks.md +19 -0
- package/.claude/rules/python/patterns.md +39 -0
- package/.claude/rules/python/security.md +30 -0
- package/.claude/rules/python/testing.md +38 -0
- package/.claude/rules/typescript/coding-style.md +199 -0
- package/.claude/rules/typescript/hooks.md +22 -0
- package/.claude/rules/typescript/patterns.md +52 -0
- package/.claude/rules/typescript/security.md +28 -0
- package/.claude/rules/typescript/testing.md +18 -0
- package/.claude/rules/web/coding-style.md +96 -0
- package/.claude/rules/web/design-quality.md +63 -0
- package/.claude/rules/web/hooks.md +120 -0
- package/.claude/rules/web/patterns.md +79 -0
- package/.claude/rules/web/performance.md +64 -0
- package/.claude/rules/web/security.md +57 -0
- package/.claude/rules/web/testing.md +55 -0
- package/.claude/settings.json +37 -0
- package/.claude/settings.local.json +38 -0
- package/.claude/skills/ado-integration/SKILL.md +44 -1
- package/.claude/skills/agent-harness-construction/SKILL.md +77 -0
- package/.claude/skills/agent-introspection-debugging/SKILL.md +157 -0
- package/.claude/skills/ai-regression-testing/SKILL.md +364 -0
- package/.claude/skills/api-design/SKILL.md +528 -0
- package/.claude/skills/architecture-decision-records/SKILL.md +184 -0
- package/.claude/skills/backend-patterns/SKILL.md +602 -0
- package/.claude/skills/benchmark/SKILL.md +98 -0
- package/.claude/skills/browser-qa/SKILL.md +92 -0
- package/.claude/skills/canary-watch/SKILL.md +104 -0
- package/.claude/skills/tas-conventions/SKILL.md +51 -3
- package/.claude/skills/tas-implementation-complete/SKILL.md +97 -0
- package/.claude/skills/tas-tdd/SKILL.md +72 -16
- package/.tas/README.md +29 -24
- package/.tas/tas-example.yaml +2 -1
- package/.tas/templates/Story.md +18 -18
- package/CLAUDE-Example.md +1 -1
- package/README.md +23 -8
- package/bin/cli.js +4 -4
- package/package.json +1 -1
- package/.claude/commands/tas-dev-story.md +0 -61
- package/.claude/commands/tas-review-code.md +0 -42
- package/.claude/commands/tas-security-check.md +0 -30
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Testing Requirements
|
|
2
|
+
|
|
3
|
+
## Minimum Test Coverage: 80%
|
|
4
|
+
|
|
5
|
+
Test Types (ALL required):
|
|
6
|
+
1. **Unit Tests** - Individual functions, utilities, components
|
|
7
|
+
2. **Integration Tests** - API endpoints, database operations
|
|
8
|
+
3. **E2E Tests** - Critical user flows (framework chosen per language)
|
|
9
|
+
|
|
10
|
+
## Test-Driven Development
|
|
11
|
+
|
|
12
|
+
MANDATORY workflow:
|
|
13
|
+
1. Write test first (RED)
|
|
14
|
+
2. Run test - it should FAIL
|
|
15
|
+
3. Write minimal implementation (GREEN)
|
|
16
|
+
4. Run test - it should PASS
|
|
17
|
+
5. Refactor (IMPROVE)
|
|
18
|
+
6. Verify coverage (80%+)
|
|
19
|
+
|
|
20
|
+
## Troubleshooting Test Failures
|
|
21
|
+
|
|
22
|
+
1. Use **tdd-guide** agent
|
|
23
|
+
2. Check test isolation
|
|
24
|
+
3. Verify mocks are correct
|
|
25
|
+
4. Fix implementation, not tests (unless tests are wrong)
|
|
26
|
+
|
|
27
|
+
## Agent Support
|
|
28
|
+
|
|
29
|
+
- **tdd-guide** - Use PROACTIVELY for new features, enforces write-tests-first
|
|
30
|
+
|
|
31
|
+
## Test Structure (AAA Pattern)
|
|
32
|
+
|
|
33
|
+
Prefer Arrange-Act-Assert structure for tests:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
test('calculates similarity correctly', () => {
|
|
37
|
+
// Arrange
|
|
38
|
+
const vector1 = [1, 0, 0]
|
|
39
|
+
const vector2 = [0, 1, 0]
|
|
40
|
+
|
|
41
|
+
// Act
|
|
42
|
+
const similarity = calculateCosineSimilarity(vector1, vector2)
|
|
43
|
+
|
|
44
|
+
// Assert
|
|
45
|
+
expect(similarity).toBe(0)
|
|
46
|
+
})
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Test Naming
|
|
50
|
+
|
|
51
|
+
Use descriptive names that explain the behavior under test:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
test('returns empty array when no markets match query', () => {})
|
|
55
|
+
test('throws error when API key is missing', () => {})
|
|
56
|
+
test('falls back to substring search when Redis is unavailable', () => {})
|
|
57
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.cs"
|
|
4
|
+
- "**/*.csx"
|
|
5
|
+
---
|
|
6
|
+
# C# Coding Style
|
|
7
|
+
|
|
8
|
+
> This file extends [common/coding-style.md](../common/coding-style.md) with C#-specific content.
|
|
9
|
+
|
|
10
|
+
## Standards
|
|
11
|
+
|
|
12
|
+
- Follow current .NET conventions and enable nullable reference types
|
|
13
|
+
- Prefer explicit access modifiers on public and internal APIs
|
|
14
|
+
- Keep files aligned with the primary type they define
|
|
15
|
+
|
|
16
|
+
## Types and Models
|
|
17
|
+
|
|
18
|
+
- Prefer `record` or `record struct` for immutable value-like models
|
|
19
|
+
- Use `class` for entities or types with identity and lifecycle
|
|
20
|
+
- Use `interface` for service boundaries and abstractions
|
|
21
|
+
- Avoid `dynamic` in application code; prefer generics or explicit models
|
|
22
|
+
|
|
23
|
+
```csharp
|
|
24
|
+
public sealed record UserDto(Guid Id, string Email);
|
|
25
|
+
|
|
26
|
+
public interface IUserRepository
|
|
27
|
+
{
|
|
28
|
+
Task<UserDto?> FindByIdAsync(Guid id, CancellationToken cancellationToken);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Immutability
|
|
33
|
+
|
|
34
|
+
- Prefer `init` setters, constructor parameters, and immutable collections for shared state
|
|
35
|
+
- Do not mutate input models in-place when producing updated state
|
|
36
|
+
|
|
37
|
+
```csharp
|
|
38
|
+
public sealed record UserProfile(string Name, string Email);
|
|
39
|
+
|
|
40
|
+
public static UserProfile Rename(UserProfile profile, string name) =>
|
|
41
|
+
profile with { Name = name };
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Async and Error Handling
|
|
45
|
+
|
|
46
|
+
- Prefer `async`/`await` over blocking calls like `.Result` or `.Wait()`
|
|
47
|
+
- Pass `CancellationToken` through public async APIs
|
|
48
|
+
- Throw specific exceptions and log with structured properties
|
|
49
|
+
|
|
50
|
+
```csharp
|
|
51
|
+
public async Task<Order> LoadOrderAsync(
|
|
52
|
+
Guid orderId,
|
|
53
|
+
CancellationToken cancellationToken)
|
|
54
|
+
{
|
|
55
|
+
try
|
|
56
|
+
{
|
|
57
|
+
return await repository.FindAsync(orderId, cancellationToken)
|
|
58
|
+
?? throw new InvalidOperationException($"Order {orderId} was not found.");
|
|
59
|
+
}
|
|
60
|
+
catch (Exception ex)
|
|
61
|
+
{
|
|
62
|
+
logger.LogError(ex, "Failed to load order {OrderId}", orderId);
|
|
63
|
+
throw;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Formatting
|
|
69
|
+
|
|
70
|
+
- Use `dotnet format` for formatting and analyzer fixes
|
|
71
|
+
- Keep `using` directives organized and remove unused imports
|
|
72
|
+
- Prefer expression-bodied members only when they stay readable
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.cs"
|
|
4
|
+
- "**/*.csx"
|
|
5
|
+
- "**/*.csproj"
|
|
6
|
+
- "**/*.sln"
|
|
7
|
+
- "**/Directory.Build.props"
|
|
8
|
+
- "**/Directory.Build.targets"
|
|
9
|
+
---
|
|
10
|
+
# C# Hooks
|
|
11
|
+
|
|
12
|
+
> This file extends [common/hooks.md](../common/hooks.md) with C#-specific content.
|
|
13
|
+
|
|
14
|
+
## PostToolUse Hooks
|
|
15
|
+
|
|
16
|
+
Configure in `~/.claude/settings.json`:
|
|
17
|
+
|
|
18
|
+
- **dotnet format**: Auto-format edited C# files and apply analyzer fixes
|
|
19
|
+
- **dotnet build**: Verify the solution or project still compiles after edits
|
|
20
|
+
- **dotnet test --no-build**: Re-run the nearest relevant test project after behavior changes
|
|
21
|
+
|
|
22
|
+
## Stop Hooks
|
|
23
|
+
|
|
24
|
+
- Run a final `dotnet build` before ending a session with broad C# changes
|
|
25
|
+
- Warn on modified `appsettings*.json` files so secrets do not get committed
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.cs"
|
|
4
|
+
- "**/*.csx"
|
|
5
|
+
---
|
|
6
|
+
# C# Patterns
|
|
7
|
+
|
|
8
|
+
> This file extends [common/patterns.md](../common/patterns.md) with C#-specific content.
|
|
9
|
+
|
|
10
|
+
## API Response Pattern
|
|
11
|
+
|
|
12
|
+
```csharp
|
|
13
|
+
public sealed record ApiResponse<T>(
|
|
14
|
+
bool Success,
|
|
15
|
+
T? Data = default,
|
|
16
|
+
string? Error = null,
|
|
17
|
+
object? Meta = null);
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Repository Pattern
|
|
21
|
+
|
|
22
|
+
```csharp
|
|
23
|
+
public interface IRepository<T>
|
|
24
|
+
{
|
|
25
|
+
Task<IReadOnlyList<T>> FindAllAsync(CancellationToken cancellationToken);
|
|
26
|
+
Task<T?> FindByIdAsync(Guid id, CancellationToken cancellationToken);
|
|
27
|
+
Task<T> CreateAsync(T entity, CancellationToken cancellationToken);
|
|
28
|
+
Task<T> UpdateAsync(T entity, CancellationToken cancellationToken);
|
|
29
|
+
Task DeleteAsync(Guid id, CancellationToken cancellationToken);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Options Pattern
|
|
34
|
+
|
|
35
|
+
Use strongly typed options for config instead of reading raw strings throughout the codebase.
|
|
36
|
+
|
|
37
|
+
```csharp
|
|
38
|
+
public sealed class PaymentsOptions
|
|
39
|
+
{
|
|
40
|
+
public const string SectionName = "Payments";
|
|
41
|
+
public required string BaseUrl { get; init; }
|
|
42
|
+
public required string ApiKeySecretName { get; init; }
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Dependency Injection
|
|
47
|
+
|
|
48
|
+
- Depend on interfaces at service boundaries
|
|
49
|
+
- Keep constructors focused; if a service needs too many dependencies, split responsibilities
|
|
50
|
+
- Register lifetimes intentionally: singleton for stateless/shared services, scoped for request data, transient for lightweight pure workers
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.cs"
|
|
4
|
+
- "**/*.csx"
|
|
5
|
+
- "**/*.csproj"
|
|
6
|
+
- "**/appsettings*.json"
|
|
7
|
+
---
|
|
8
|
+
# C# Security
|
|
9
|
+
|
|
10
|
+
> This file extends [common/security.md](../common/security.md) with C#-specific content.
|
|
11
|
+
|
|
12
|
+
## Secret Management
|
|
13
|
+
|
|
14
|
+
- Never hardcode API keys, tokens, or connection strings in source code
|
|
15
|
+
- Use environment variables, user secrets for local development, and a secret manager in production
|
|
16
|
+
- Keep `appsettings.*.json` free of real credentials
|
|
17
|
+
|
|
18
|
+
```csharp
|
|
19
|
+
// BAD
|
|
20
|
+
const string ApiKey = "sk-live-123";
|
|
21
|
+
|
|
22
|
+
// GOOD
|
|
23
|
+
var apiKey = builder.Configuration["OpenAI:ApiKey"]
|
|
24
|
+
?? throw new InvalidOperationException("OpenAI:ApiKey is not configured.");
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## SQL Injection Prevention
|
|
28
|
+
|
|
29
|
+
- Always use parameterized queries with ADO.NET, Dapper, or EF Core
|
|
30
|
+
- Never concatenate user input into SQL strings
|
|
31
|
+
- Validate sort fields and filter operators before using dynamic query composition
|
|
32
|
+
|
|
33
|
+
```csharp
|
|
34
|
+
const string sql = "SELECT * FROM Orders WHERE CustomerId = @customerId";
|
|
35
|
+
await connection.QueryAsync<Order>(sql, new { customerId });
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Input Validation
|
|
39
|
+
|
|
40
|
+
- Validate DTOs at the application boundary
|
|
41
|
+
- Use data annotations, FluentValidation, or explicit guard clauses
|
|
42
|
+
- Reject invalid model state before running business logic
|
|
43
|
+
|
|
44
|
+
## Authentication and Authorization
|
|
45
|
+
|
|
46
|
+
- Prefer framework auth handlers instead of custom token parsing
|
|
47
|
+
- Enforce authorization policies at endpoint or handler boundaries
|
|
48
|
+
- Never log raw tokens, passwords, or PII
|
|
49
|
+
|
|
50
|
+
## Error Handling
|
|
51
|
+
|
|
52
|
+
- Return safe client-facing messages
|
|
53
|
+
- Log detailed exceptions with structured context server-side
|
|
54
|
+
- Do not expose stack traces, SQL text, or filesystem paths in API responses
|
|
55
|
+
|
|
56
|
+
## References
|
|
57
|
+
|
|
58
|
+
See skill: `security-review` for broader application security review checklists.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.cs"
|
|
4
|
+
- "**/*.csx"
|
|
5
|
+
- "**/*.csproj"
|
|
6
|
+
---
|
|
7
|
+
# C# Testing
|
|
8
|
+
|
|
9
|
+
> This file extends [common/testing.md](../common/testing.md) with C#-specific content.
|
|
10
|
+
|
|
11
|
+
## Test Framework
|
|
12
|
+
|
|
13
|
+
- Prefer **xUnit** for unit and integration tests
|
|
14
|
+
- Use **FluentAssertions** for readable assertions
|
|
15
|
+
- Use **Moq** or **NSubstitute** for mocking dependencies
|
|
16
|
+
- Use **Testcontainers** when integration tests need real infrastructure
|
|
17
|
+
|
|
18
|
+
## Test Organization
|
|
19
|
+
|
|
20
|
+
- Mirror `src/` structure under `tests/`
|
|
21
|
+
- Separate unit, integration, and end-to-end coverage clearly
|
|
22
|
+
- Name tests by behavior, not implementation details
|
|
23
|
+
|
|
24
|
+
```csharp
|
|
25
|
+
public sealed class OrderServiceTests
|
|
26
|
+
{
|
|
27
|
+
[Fact]
|
|
28
|
+
public async Task FindByIdAsync_ReturnsOrder_WhenOrderExists()
|
|
29
|
+
{
|
|
30
|
+
// Arrange
|
|
31
|
+
// Act
|
|
32
|
+
// Assert
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## ASP.NET Core Integration Tests
|
|
38
|
+
|
|
39
|
+
- Use `WebApplicationFactory<TEntryPoint>` for API integration coverage
|
|
40
|
+
- Test auth, validation, and serialization through HTTP, not by bypassing middleware
|
|
41
|
+
|
|
42
|
+
## Coverage
|
|
43
|
+
|
|
44
|
+
- Target 80%+ line coverage
|
|
45
|
+
- Focus coverage on domain logic, validation, auth, and failure paths
|
|
46
|
+
- Run `dotnet test` in CI with coverage collection enabled where available
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.py"
|
|
4
|
+
- "**/*.pyi"
|
|
5
|
+
---
|
|
6
|
+
# Python Coding Style
|
|
7
|
+
|
|
8
|
+
> This file extends [common/coding-style.md](../common/coding-style.md) with Python specific content.
|
|
9
|
+
|
|
10
|
+
## Standards
|
|
11
|
+
|
|
12
|
+
- Follow **PEP 8** conventions
|
|
13
|
+
- Use **type annotations** on all function signatures
|
|
14
|
+
|
|
15
|
+
## Immutability
|
|
16
|
+
|
|
17
|
+
Prefer immutable data structures:
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from dataclasses import dataclass
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True)
|
|
23
|
+
class User:
|
|
24
|
+
name: str
|
|
25
|
+
email: str
|
|
26
|
+
|
|
27
|
+
from typing import NamedTuple
|
|
28
|
+
|
|
29
|
+
class Point(NamedTuple):
|
|
30
|
+
x: float
|
|
31
|
+
y: float
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Formatting
|
|
35
|
+
|
|
36
|
+
- **black** for code formatting
|
|
37
|
+
- **isort** for import sorting
|
|
38
|
+
- **ruff** for linting
|
|
39
|
+
|
|
40
|
+
## Reference
|
|
41
|
+
|
|
42
|
+
See skill: `python-patterns` for comprehensive Python idioms and patterns.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.py"
|
|
4
|
+
- "**/*.pyi"
|
|
5
|
+
---
|
|
6
|
+
# Python Hooks
|
|
7
|
+
|
|
8
|
+
> This file extends [common/hooks.md](../common/hooks.md) with Python specific content.
|
|
9
|
+
|
|
10
|
+
## PostToolUse Hooks
|
|
11
|
+
|
|
12
|
+
Configure in `~/.claude/settings.json`:
|
|
13
|
+
|
|
14
|
+
- **black/ruff**: Auto-format `.py` files after edit
|
|
15
|
+
- **mypy/pyright**: Run type checking after editing `.py` files
|
|
16
|
+
|
|
17
|
+
## Warnings
|
|
18
|
+
|
|
19
|
+
- Warn about `print()` statements in edited files (use `logging` module instead)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.py"
|
|
4
|
+
- "**/*.pyi"
|
|
5
|
+
---
|
|
6
|
+
# Python Patterns
|
|
7
|
+
|
|
8
|
+
> This file extends [common/patterns.md](../common/patterns.md) with Python specific content.
|
|
9
|
+
|
|
10
|
+
## Protocol (Duck Typing)
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from typing import Protocol
|
|
14
|
+
|
|
15
|
+
class Repository(Protocol):
|
|
16
|
+
def find_by_id(self, id: str) -> dict | None: ...
|
|
17
|
+
def save(self, entity: dict) -> dict: ...
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Dataclasses as DTOs
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from dataclasses import dataclass
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class CreateUserRequest:
|
|
27
|
+
name: str
|
|
28
|
+
email: str
|
|
29
|
+
age: int | None = None
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Context Managers & Generators
|
|
33
|
+
|
|
34
|
+
- Use context managers (`with` statement) for resource management
|
|
35
|
+
- Use generators for lazy evaluation and memory-efficient iteration
|
|
36
|
+
|
|
37
|
+
## Reference
|
|
38
|
+
|
|
39
|
+
See skill: `python-patterns` for comprehensive patterns including decorators, concurrency, and package organization.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.py"
|
|
4
|
+
- "**/*.pyi"
|
|
5
|
+
---
|
|
6
|
+
# Python Security
|
|
7
|
+
|
|
8
|
+
> This file extends [common/security.md](../common/security.md) with Python specific content.
|
|
9
|
+
|
|
10
|
+
## Secret Management
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
import os
|
|
14
|
+
from dotenv import load_dotenv
|
|
15
|
+
|
|
16
|
+
load_dotenv()
|
|
17
|
+
|
|
18
|
+
api_key = os.environ["OPENAI_API_KEY"] # Raises KeyError if missing
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Security Scanning
|
|
22
|
+
|
|
23
|
+
- Use **bandit** for static security analysis:
|
|
24
|
+
```bash
|
|
25
|
+
bandit -r src/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Reference
|
|
29
|
+
|
|
30
|
+
See skill: `django-security` for Django-specific security guidelines (if applicable).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.py"
|
|
4
|
+
- "**/*.pyi"
|
|
5
|
+
---
|
|
6
|
+
# Python Testing
|
|
7
|
+
|
|
8
|
+
> This file extends [common/testing.md](../common/testing.md) with Python specific content.
|
|
9
|
+
|
|
10
|
+
## Framework
|
|
11
|
+
|
|
12
|
+
Use **pytest** as the testing framework.
|
|
13
|
+
|
|
14
|
+
## Coverage
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pytest --cov=src --cov-report=term-missing
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Test Organization
|
|
21
|
+
|
|
22
|
+
Use `pytest.mark` for test categorization:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
import pytest
|
|
26
|
+
|
|
27
|
+
@pytest.mark.unit
|
|
28
|
+
def test_calculate_total():
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
@pytest.mark.integration
|
|
32
|
+
def test_database_connection():
|
|
33
|
+
...
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Reference
|
|
37
|
+
|
|
38
|
+
See skill: `python-testing` for detailed pytest patterns and fixtures.
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ts"
|
|
4
|
+
- "**/*.tsx"
|
|
5
|
+
- "**/*.js"
|
|
6
|
+
- "**/*.jsx"
|
|
7
|
+
---
|
|
8
|
+
# TypeScript/JavaScript Coding Style
|
|
9
|
+
|
|
10
|
+
> This file extends [common/coding-style.md](../common/coding-style.md) with TypeScript/JavaScript specific content.
|
|
11
|
+
|
|
12
|
+
## Types and Interfaces
|
|
13
|
+
|
|
14
|
+
Use types to make public APIs, shared models, and component props explicit, readable, and reusable.
|
|
15
|
+
|
|
16
|
+
### Public APIs
|
|
17
|
+
|
|
18
|
+
- Add parameter and return types to exported functions, shared utilities, and public class methods
|
|
19
|
+
- Let TypeScript infer obvious local variable types
|
|
20
|
+
- Extract repeated inline object shapes into named types or interfaces
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// WRONG: Exported function without explicit types
|
|
24
|
+
export function formatUser(user) {
|
|
25
|
+
return `${user.firstName} ${user.lastName}`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// CORRECT: Explicit types on public APIs
|
|
29
|
+
interface User {
|
|
30
|
+
firstName: string
|
|
31
|
+
lastName: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function formatUser(user: User): string {
|
|
35
|
+
return `${user.firstName} ${user.lastName}`
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Interfaces vs. Type Aliases
|
|
40
|
+
|
|
41
|
+
- Use `interface` for object shapes that may be extended or implemented
|
|
42
|
+
- Use `type` for unions, intersections, tuples, mapped types, and utility types
|
|
43
|
+
- Prefer string literal unions over `enum` unless an `enum` is required for interoperability
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
interface User {
|
|
47
|
+
id: string
|
|
48
|
+
email: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type UserRole = 'admin' | 'member'
|
|
52
|
+
type UserWithRole = User & {
|
|
53
|
+
role: UserRole
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Avoid `any`
|
|
58
|
+
|
|
59
|
+
- Avoid `any` in application code
|
|
60
|
+
- Use `unknown` for external or untrusted input, then narrow it safely
|
|
61
|
+
- Use generics when a value's type depends on the caller
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// WRONG: any removes type safety
|
|
65
|
+
function getErrorMessage(error: any) {
|
|
66
|
+
return error.message
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// CORRECT: unknown forces safe narrowing
|
|
70
|
+
function getErrorMessage(error: unknown): string {
|
|
71
|
+
if (error instanceof Error) {
|
|
72
|
+
return error.message
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return 'Unexpected error'
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### React Props
|
|
80
|
+
|
|
81
|
+
- Define component props with a named `interface` or `type`
|
|
82
|
+
- Type callback props explicitly
|
|
83
|
+
- Do not use `React.FC` unless there is a specific reason to do so
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
interface User {
|
|
87
|
+
id: string
|
|
88
|
+
email: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface UserCardProps {
|
|
92
|
+
user: User
|
|
93
|
+
onSelect: (id: string) => void
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function UserCard({ user, onSelect }: UserCardProps) {
|
|
97
|
+
return <button onClick={() => onSelect(user.id)}>{user.email}</button>
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### JavaScript Files
|
|
102
|
+
|
|
103
|
+
- In `.js` and `.jsx` files, use JSDoc when types improve clarity and a TypeScript migration is not practical
|
|
104
|
+
- Keep JSDoc aligned with runtime behavior
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
/**
|
|
108
|
+
* @param {{ firstName: string, lastName: string }} user
|
|
109
|
+
* @returns {string}
|
|
110
|
+
*/
|
|
111
|
+
export function formatUser(user) {
|
|
112
|
+
return `${user.firstName} ${user.lastName}`
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Immutability
|
|
117
|
+
|
|
118
|
+
Use spread operator for immutable updates:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
interface User {
|
|
122
|
+
id: string
|
|
123
|
+
name: string
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// WRONG: Mutation
|
|
127
|
+
function updateUser(user: User, name: string): User {
|
|
128
|
+
user.name = name // MUTATION!
|
|
129
|
+
return user
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// CORRECT: Immutability
|
|
133
|
+
function updateUser(user: Readonly<User>, name: string): User {
|
|
134
|
+
return {
|
|
135
|
+
...user,
|
|
136
|
+
name
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Error Handling
|
|
142
|
+
|
|
143
|
+
Use async/await with try-catch and narrow unknown errors safely:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
interface User {
|
|
147
|
+
id: string
|
|
148
|
+
email: string
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
declare function riskyOperation(userId: string): Promise<User>
|
|
152
|
+
|
|
153
|
+
function getErrorMessage(error: unknown): string {
|
|
154
|
+
if (error instanceof Error) {
|
|
155
|
+
return error.message
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return 'Unexpected error'
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const logger = {
|
|
162
|
+
error: (message: string, error: unknown) => {
|
|
163
|
+
// Replace with your production logger (for example, pino or winston).
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function loadUser(userId: string): Promise<User> {
|
|
168
|
+
try {
|
|
169
|
+
const result = await riskyOperation(userId)
|
|
170
|
+
return result
|
|
171
|
+
} catch (error: unknown) {
|
|
172
|
+
logger.error('Operation failed', error)
|
|
173
|
+
throw new Error(getErrorMessage(error))
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Input Validation
|
|
179
|
+
|
|
180
|
+
Use Zod for schema-based validation and infer types from the schema:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { z } from 'zod'
|
|
184
|
+
|
|
185
|
+
const userSchema = z.object({
|
|
186
|
+
email: z.string().email(),
|
|
187
|
+
age: z.number().int().min(0).max(150)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
type UserInput = z.infer<typeof userSchema>
|
|
191
|
+
|
|
192
|
+
const validated: UserInput = userSchema.parse(input)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Console.log
|
|
196
|
+
|
|
197
|
+
- No `console.log` statements in production code
|
|
198
|
+
- Use proper logging libraries instead
|
|
199
|
+
- See hooks for automatic detection
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ts"
|
|
4
|
+
- "**/*.tsx"
|
|
5
|
+
- "**/*.js"
|
|
6
|
+
- "**/*.jsx"
|
|
7
|
+
---
|
|
8
|
+
# TypeScript/JavaScript Hooks
|
|
9
|
+
|
|
10
|
+
> This file extends [common/hooks.md](../common/hooks.md) with TypeScript/JavaScript specific content.
|
|
11
|
+
|
|
12
|
+
## PostToolUse Hooks
|
|
13
|
+
|
|
14
|
+
Configure in `~/.claude/settings.json`:
|
|
15
|
+
|
|
16
|
+
- **Prettier**: Auto-format JS/TS files after edit
|
|
17
|
+
- **TypeScript check**: Run `tsc` after editing `.ts`/`.tsx` files
|
|
18
|
+
- **console.log warning**: Warn about `console.log` in edited files
|
|
19
|
+
|
|
20
|
+
## Stop Hooks
|
|
21
|
+
|
|
22
|
+
- **console.log audit**: Check all modified files for `console.log` before session ends
|