mcp-subagents-opencode 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.
- package/LICENSE +21 -0
- package/README.md +602 -0
- package/build/config/timeouts.d.ts +9 -0
- package/build/config/timeouts.d.ts.map +1 -0
- package/build/config/timeouts.js +18 -0
- package/build/config/timeouts.js.map +1 -0
- package/build/helpers.d.ts +6 -0
- package/build/helpers.d.ts.map +1 -0
- package/build/helpers.js +47 -0
- package/build/helpers.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +245 -0
- package/build/index.js.map +1 -0
- package/build/models.d.ts +32 -0
- package/build/models.d.ts.map +1 -0
- package/build/models.js +58 -0
- package/build/models.js.map +1 -0
- package/build/server/register-notifications.d.ts +3 -0
- package/build/server/register-notifications.d.ts.map +1 -0
- package/build/server/register-notifications.js +77 -0
- package/build/server/register-notifications.js.map +1 -0
- package/build/server/register-resources.d.ts +3 -0
- package/build/server/register-resources.d.ts.map +1 -0
- package/build/server/register-resources.js +210 -0
- package/build/server/register-resources.js.map +1 -0
- package/build/server/register-retry-execution.d.ts +2 -0
- package/build/server/register-retry-execution.d.ts.map +1 -0
- package/build/server/register-retry-execution.js +28 -0
- package/build/server/register-retry-execution.js.map +1 -0
- package/build/server/register-tasks.d.ts +3 -0
- package/build/server/register-tasks.d.ts.map +1 -0
- package/build/server/register-tasks.js +52 -0
- package/build/server/register-tasks.js.map +1 -0
- package/build/server/register-tools.d.ts +3 -0
- package/build/server/register-tools.d.ts.map +1 -0
- package/build/server/register-tools.js +32 -0
- package/build/server/register-tools.js.map +1 -0
- package/build/server/resource-helpers.d.ts +21 -0
- package/build/server/resource-helpers.d.ts.map +1 -0
- package/build/server/resource-helpers.js +84 -0
- package/build/server/resource-helpers.js.map +1 -0
- package/build/services/account-manager.d.ts +88 -0
- package/build/services/account-manager.d.ts.map +1 -0
- package/build/services/account-manager.js +239 -0
- package/build/services/account-manager.js.map +1 -0
- package/build/services/claude-code-runner.d.ts +15 -0
- package/build/services/claude-code-runner.d.ts.map +1 -0
- package/build/services/claude-code-runner.js +475 -0
- package/build/services/claude-code-runner.js.map +1 -0
- package/build/services/client-context.d.ts +31 -0
- package/build/services/client-context.d.ts.map +1 -0
- package/build/services/client-context.js +44 -0
- package/build/services/client-context.js.map +1 -0
- package/build/services/exhaustion-fallback.d.ts +27 -0
- package/build/services/exhaustion-fallback.d.ts.map +1 -0
- package/build/services/exhaustion-fallback.js +30 -0
- package/build/services/exhaustion-fallback.js.map +1 -0
- package/build/services/fallback-orchestrator.d.ts +16 -0
- package/build/services/fallback-orchestrator.d.ts.map +1 -0
- package/build/services/fallback-orchestrator.js +48 -0
- package/build/services/fallback-orchestrator.js.map +1 -0
- package/build/services/opencode-client.d.ts +40 -0
- package/build/services/opencode-client.d.ts.map +1 -0
- package/build/services/opencode-client.js +147 -0
- package/build/services/opencode-client.js.map +1 -0
- package/build/services/opencode-spawner.d.ts +56 -0
- package/build/services/opencode-spawner.d.ts.map +1 -0
- package/build/services/opencode-spawner.js +426 -0
- package/build/services/opencode-spawner.js.map +1 -0
- package/build/services/output-file.d.ts +24 -0
- package/build/services/output-file.d.ts.map +1 -0
- package/build/services/output-file.js +90 -0
- package/build/services/output-file.js.map +1 -0
- package/build/services/progress-registry.d.ts +12 -0
- package/build/services/progress-registry.d.ts.map +1 -0
- package/build/services/progress-registry.js +97 -0
- package/build/services/progress-registry.js.map +1 -0
- package/build/services/question-registry.d.ts +79 -0
- package/build/services/question-registry.d.ts.map +1 -0
- package/build/services/question-registry.js +249 -0
- package/build/services/question-registry.js.map +1 -0
- package/build/services/retry-queue.d.ts +41 -0
- package/build/services/retry-queue.d.ts.map +1 -0
- package/build/services/retry-queue.js +195 -0
- package/build/services/retry-queue.js.map +1 -0
- package/build/services/sdk-client-manager.d.ts +149 -0
- package/build/services/sdk-client-manager.d.ts.map +1 -0
- package/build/services/sdk-client-manager.js +632 -0
- package/build/services/sdk-client-manager.js.map +1 -0
- package/build/services/sdk-session-adapter.d.ts +203 -0
- package/build/services/sdk-session-adapter.d.ts.map +1 -0
- package/build/services/sdk-session-adapter.js +1088 -0
- package/build/services/sdk-session-adapter.js.map +1 -0
- package/build/services/sdk-spawner.d.ts +42 -0
- package/build/services/sdk-spawner.d.ts.map +1 -0
- package/build/services/sdk-spawner.js +488 -0
- package/build/services/sdk-spawner.js.map +1 -0
- package/build/services/session-hooks.d.ts +24 -0
- package/build/services/session-hooks.d.ts.map +1 -0
- package/build/services/session-hooks.js +130 -0
- package/build/services/session-hooks.js.map +1 -0
- package/build/services/session-snapshot.d.ts +19 -0
- package/build/services/session-snapshot.d.ts.map +1 -0
- package/build/services/session-snapshot.js +203 -0
- package/build/services/session-snapshot.js.map +1 -0
- package/build/services/subscription-registry.d.ts +12 -0
- package/build/services/subscription-registry.d.ts.map +1 -0
- package/build/services/subscription-registry.js +27 -0
- package/build/services/subscription-registry.js.map +1 -0
- package/build/services/task-manager.d.ts +150 -0
- package/build/services/task-manager.d.ts.map +1 -0
- package/build/services/task-manager.js +765 -0
- package/build/services/task-manager.js.map +1 -0
- package/build/services/task-persistence.d.ts +29 -0
- package/build/services/task-persistence.d.ts.map +1 -0
- package/build/services/task-persistence.js +159 -0
- package/build/services/task-persistence.js.map +1 -0
- package/build/services/task-status-mapper.d.ts +21 -0
- package/build/services/task-status-mapper.d.ts.map +1 -0
- package/build/services/task-status-mapper.js +171 -0
- package/build/services/task-status-mapper.js.map +1 -0
- package/build/templates/index.d.ts +22 -0
- package/build/templates/index.d.ts.map +1 -0
- package/build/templates/index.js +147 -0
- package/build/templates/index.js.map +1 -0
- package/build/templates/overlays/coder-csharp.mdx +58 -0
- package/build/templates/overlays/coder-go.mdx +53 -0
- package/build/templates/overlays/coder-java.mdx +54 -0
- package/build/templates/overlays/coder-kotlin.mdx +56 -0
- package/build/templates/overlays/coder-nextjs.mdx +65 -0
- package/build/templates/overlays/coder-python.mdx +53 -0
- package/build/templates/overlays/coder-react.mdx +55 -0
- package/build/templates/overlays/coder-ruby.mdx +59 -0
- package/build/templates/overlays/coder-rust.mdx +48 -0
- package/build/templates/overlays/coder-supabase.mdx +268 -0
- package/build/templates/overlays/coder-supastarter.mdx +313 -0
- package/build/templates/overlays/coder-swift.mdx +56 -0
- package/build/templates/overlays/coder-tauri.mdx +566 -0
- package/build/templates/overlays/coder-triggerdev.mdx +296 -0
- package/build/templates/overlays/coder-typescript.mdx +45 -0
- package/build/templates/overlays/coder-vue.mdx +62 -0
- package/build/templates/overlays/planner-architecture.mdx +78 -0
- package/build/templates/overlays/planner-bugfix.mdx +36 -0
- package/build/templates/overlays/planner-feature.mdx +38 -0
- package/build/templates/overlays/planner-migration.mdx +50 -0
- package/build/templates/overlays/planner-refactor.mdx +57 -0
- package/build/templates/overlays/researcher-library.mdx +59 -0
- package/build/templates/overlays/researcher-performance.mdx +68 -0
- package/build/templates/overlays/researcher-security.mdx +86 -0
- package/build/templates/overlays/tester-graphql.mdx +191 -0
- package/build/templates/overlays/tester-playwright.mdx +621 -0
- package/build/templates/overlays/tester-rest.mdx +101 -0
- package/build/templates/overlays/tester-suite.mdx +177 -0
- package/build/templates/super-coder.mdx +529 -0
- package/build/templates/super-planner.mdx +568 -0
- package/build/templates/super-researcher.mdx +406 -0
- package/build/templates/super-tester.mdx +243 -0
- package/build/tools/answer-question.d.ts +30 -0
- package/build/tools/answer-question.d.ts.map +1 -0
- package/build/tools/answer-question.js +108 -0
- package/build/tools/answer-question.js.map +1 -0
- package/build/tools/cancel-task.d.ts +44 -0
- package/build/tools/cancel-task.d.ts.map +1 -0
- package/build/tools/cancel-task.js +144 -0
- package/build/tools/cancel-task.js.map +1 -0
- package/build/tools/send-message.d.ts +39 -0
- package/build/tools/send-message.d.ts.map +1 -0
- package/build/tools/send-message.js +124 -0
- package/build/tools/send-message.js.map +1 -0
- package/build/tools/shared-spawn.d.ts +56 -0
- package/build/tools/shared-spawn.d.ts.map +1 -0
- package/build/tools/shared-spawn.js +114 -0
- package/build/tools/shared-spawn.js.map +1 -0
- package/build/tools/spawn-agent.d.ts +85 -0
- package/build/tools/spawn-agent.d.ts.map +1 -0
- package/build/tools/spawn-agent.js +133 -0
- package/build/tools/spawn-agent.js.map +1 -0
- package/build/tools/spawn-coder.d.ts +70 -0
- package/build/tools/spawn-coder.d.ts.map +1 -0
- package/build/tools/spawn-coder.js +71 -0
- package/build/tools/spawn-coder.js.map +1 -0
- package/build/tools/spawn-planner.d.ts +70 -0
- package/build/tools/spawn-planner.d.ts.map +1 -0
- package/build/tools/spawn-planner.js +71 -0
- package/build/tools/spawn-planner.js.map +1 -0
- package/build/tools/spawn-researcher.d.ts +70 -0
- package/build/tools/spawn-researcher.d.ts.map +1 -0
- package/build/tools/spawn-researcher.js +70 -0
- package/build/tools/spawn-researcher.js.map +1 -0
- package/build/tools/spawn-task.d.ts +74 -0
- package/build/tools/spawn-task.d.ts.map +1 -0
- package/build/tools/spawn-task.js +107 -0
- package/build/tools/spawn-task.js.map +1 -0
- package/build/tools/spawn-tester.d.ts +70 -0
- package/build/tools/spawn-tester.d.ts.map +1 -0
- package/build/tools/spawn-tester.js +69 -0
- package/build/tools/spawn-tester.js.map +1 -0
- package/build/types.d.ts +101 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +28 -0
- package/build/types.js.map +1 -0
- package/build/utils/brief-validator.d.ts +30 -0
- package/build/utils/brief-validator.d.ts.map +1 -0
- package/build/utils/brief-validator.js +254 -0
- package/build/utils/brief-validator.js.map +1 -0
- package/build/utils/format.d.ts +34 -0
- package/build/utils/format.d.ts.map +1 -0
- package/build/utils/format.js +55 -0
- package/build/utils/format.js.map +1 -0
- package/build/utils/sanitize.d.ts +240 -0
- package/build/utils/sanitize.d.ts.map +1 -0
- package/build/utils/sanitize.js +89 -0
- package/build/utils/sanitize.js.map +1 -0
- package/build/utils/task-id-generator.d.ts +10 -0
- package/build/utils/task-id-generator.d.ts.map +1 -0
- package/build/utils/task-id-generator.js +22 -0
- package/build/utils/task-id-generator.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
## C#-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **C#** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### LINQ — Use It Everywhere
|
|
6
|
+
- Use LINQ for collection operations — it's more readable than manual loops
|
|
7
|
+
- Prefer method syntax (`.Where().Select()`) over query syntax (`from x in ...`) — follow project convention
|
|
8
|
+
- Use `FirstOrDefault()`, `SingleOrDefault()` — know the difference (Single throws if >1)
|
|
9
|
+
- Avoid `ToList()` / `ToArray()` unless you need materialization — keep queries lazy with `IEnumerable<T>`
|
|
10
|
+
- Use `Any()` instead of `Count() > 0` for existence checks
|
|
11
|
+
|
|
12
|
+
### Async/Await — The Right Way
|
|
13
|
+
- Make async methods return `Task` or `Task<T>` — never `async void` except event handlers
|
|
14
|
+
- Use `await` all the way — never mix `.Result` or `.Wait()` with async (deadlock risk)
|
|
15
|
+
- Use `ConfigureAwait(false)` in library code (not in UI/ASP.NET controller code)
|
|
16
|
+
- Use `CancellationToken` as the last parameter on async methods — propagate it through
|
|
17
|
+
- Use `ValueTask<T>` for hot-path methods that frequently complete synchronously
|
|
18
|
+
|
|
19
|
+
### Nullable Reference Types
|
|
20
|
+
- Enable `<Nullable>enable</Nullable>` — if the project has it, respect it fully
|
|
21
|
+
- Use `?` suffix for nullable: `string?` means "might be null"
|
|
22
|
+
- Use `!` (null-forgiving) only when you've verified non-null through logic the compiler can't see — add a comment
|
|
23
|
+
- Use `[NotNull]`, `[MaybeNull]`, `[NotNullWhen]` attributes for nuanced nullability
|
|
24
|
+
- Prefer `is not null` over `!= null` in pattern matching contexts
|
|
25
|
+
|
|
26
|
+
### Record Types & Immutability
|
|
27
|
+
- Use `record` types for immutable data transfer objects: `record UserDto(string Name, string Email);`
|
|
28
|
+
- Use `record struct` for value-type records (stack-allocated, no GC pressure)
|
|
29
|
+
- Use `with` expressions for non-destructive mutation: `var updated = user with { Name = "New" };`
|
|
30
|
+
- Use `init` properties for immutable-after-construction objects
|
|
31
|
+
- Use `required` keyword (C# 11+) for mandatory init properties
|
|
32
|
+
|
|
33
|
+
### Pattern Matching
|
|
34
|
+
- Use pattern matching in `switch` expressions — cleaner than if/else chains
|
|
35
|
+
- Use `is` patterns: `if (obj is string s)`, `if (value is > 0 and < 100)`
|
|
36
|
+
- Use `switch` expressions for exhaustive matching: `var result = status switch { ... }`
|
|
37
|
+
- Use property patterns: `if (user is { Name: "admin", IsActive: true })`
|
|
38
|
+
- Use discard `_` for cases you don't handle: `_ => throw new InvalidOperationException()`
|
|
39
|
+
|
|
40
|
+
### Entity Framework Core (if applicable)
|
|
41
|
+
- Use `AsNoTracking()` for read-only queries — significant performance improvement
|
|
42
|
+
- Use `Include()` for eager loading — avoid N+1 queries
|
|
43
|
+
- Use `AsSplitQuery()` for queries with multiple includes
|
|
44
|
+
- Keep DbContext lifetime short — scoped per request in ASP.NET
|
|
45
|
+
- Use migrations — never modify the database schema manually
|
|
46
|
+
|
|
47
|
+
### Naming Conventions
|
|
48
|
+
- `PascalCase` for classes, methods, properties, events, namespaces
|
|
49
|
+
- `camelCase` for local variables, parameters
|
|
50
|
+
- `_camelCase` for private fields (with underscore prefix)
|
|
51
|
+
- `I` prefix for interfaces: `IUserRepository`
|
|
52
|
+
- `Async` suffix for async methods: `GetUserAsync()`
|
|
53
|
+
- Boolean properties: `Is*`, `Has*`, `Can*`
|
|
54
|
+
|
|
55
|
+
### Testing Considerations
|
|
56
|
+
- Use constructor injection for testability — all dependencies through constructor
|
|
57
|
+
- Use interfaces for external dependencies — mockable with Moq, NSubstitute, etc.
|
|
58
|
+
- Follow project's test framework conventions (xUnit, NUnit, MSTest)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
## GO-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **Go** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### Error Handling — The Go Way
|
|
6
|
+
- **Always check errors:** `if err != nil { return fmt.Errorf("context: %w", err) }`
|
|
7
|
+
- Use `%w` for error wrapping (enables `errors.Is()` and `errors.As()`) — not `%v`
|
|
8
|
+
- Create sentinel errors with `var ErrNotFound = errors.New("not found")` for expected conditions
|
|
9
|
+
- Create custom error types only when callers need to inspect error details
|
|
10
|
+
- Never ignore errors — if you truly don't need it, assign to `_` with a comment explaining why
|
|
11
|
+
- Return errors, don't panic — `panic` is for unrecoverable programming errors only
|
|
12
|
+
|
|
13
|
+
### Interfaces — Accept Interfaces, Return Structs
|
|
14
|
+
- Define interfaces at the **consumer** site, not the implementation site
|
|
15
|
+
- Keep interfaces small — 1-3 methods. Compose larger behaviors from small interfaces
|
|
16
|
+
- Use `io.Reader`, `io.Writer`, `fmt.Stringer`, `error` — don't reinvent standard interfaces
|
|
17
|
+
- Never export interfaces for concrete types unless multiple implementations exist
|
|
18
|
+
|
|
19
|
+
### Goroutine Lifecycle
|
|
20
|
+
- **Always ensure goroutines can be stopped** — use `context.Context` for cancellation
|
|
21
|
+
- Pass `context.Context` as the first parameter to functions that do I/O or may block
|
|
22
|
+
- Use `sync.WaitGroup` to wait for goroutine completion
|
|
23
|
+
- Use `errgroup.Group` for parallel tasks that can fail
|
|
24
|
+
- Never launch a goroutine without a clear shutdown path — leaked goroutines are resource leaks
|
|
25
|
+
- Use channels for communication, mutexes for state — prefer channels when both work
|
|
26
|
+
|
|
27
|
+
### Code Structure
|
|
28
|
+
- Follow **standard Go project layout** — respect the existing project conventions
|
|
29
|
+
- Exported names (`PascalCase`) are public API — unexported (`camelCase`) are internal
|
|
30
|
+
- One package per directory — package name matches directory name (lowercase, no underscores)
|
|
31
|
+
- Group imports: stdlib → external → internal (separated by blank lines)
|
|
32
|
+
- Use `internal/` for packages that should not be imported outside the module
|
|
33
|
+
|
|
34
|
+
### Patterns
|
|
35
|
+
- Use **functional options** for configurable constructors: `func NewServer(opts ...Option) *Server`
|
|
36
|
+
- Use **table-driven tests** as the default test pattern
|
|
37
|
+
- Use `struct embedding` for composition — not inheritance
|
|
38
|
+
- Use `defer` for cleanup — but understand it runs at function exit, not block exit
|
|
39
|
+
- Prefer `strings.Builder` for string concatenation in loops
|
|
40
|
+
- Use `context.WithValue` sparingly — prefer explicit parameters
|
|
41
|
+
|
|
42
|
+
### Naming Conventions
|
|
43
|
+
- `PascalCase` for exported, `camelCase` for unexported
|
|
44
|
+
- Receivers: short (1-2 letters), consistent within type: `func (s *Server) Start()`
|
|
45
|
+
- Acronyms are all-caps: `userID`, `httpClient`, `URL`
|
|
46
|
+
- Getters don't use `Get` prefix: `Name()` not `GetName()`
|
|
47
|
+
- Package names are lowercase, single word when possible
|
|
48
|
+
|
|
49
|
+
### Testing Considerations
|
|
50
|
+
- Use table-driven tests with `t.Run()` for subtests
|
|
51
|
+
- Use `t.Helper()` in test helper functions for better error reporting
|
|
52
|
+
- Use `t.Parallel()` when tests are independent
|
|
53
|
+
- Prefer `testify/assert` or standard `if got != want` — follow project convention
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
## JAVA-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **Java** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### Exception Handling
|
|
6
|
+
- Use **checked exceptions** for recoverable conditions, **unchecked** for programming errors
|
|
7
|
+
- Create a base application exception: `AppException extends RuntimeException`
|
|
8
|
+
- Domain exceptions extend the base: `UserNotFoundException extends AppException`
|
|
9
|
+
- Never catch `Exception` or `Throwable` broadly — catch specific types
|
|
10
|
+
- Always include the original cause: `throw new AppException("context", originalException)`
|
|
11
|
+
- Use try-with-resources for all `AutoCloseable` resources — never manual `finally` for cleanup
|
|
12
|
+
|
|
13
|
+
### Immutability — Default to Final
|
|
14
|
+
- Make fields `final` by default — mutable only when mutation is required
|
|
15
|
+
- Use `Collections.unmodifiableList()` or `List.of()` for immutable collections
|
|
16
|
+
- Prefer **record types** (Java 16+) for data carriers: `record User(String name, String email) {}`
|
|
17
|
+
- Use builder pattern for objects with many optional fields
|
|
18
|
+
|
|
19
|
+
### Modern Java Patterns
|
|
20
|
+
- Use **Stream API** for collection processing — but keep pipelines short and readable
|
|
21
|
+
- Use `Optional<T>` for return types that may not have a value — never for parameters or fields
|
|
22
|
+
- Use `var` for local variables when the type is obvious from context
|
|
23
|
+
- Use **switch expressions** (Java 14+) with pattern matching when available
|
|
24
|
+
- Use **sealed classes** (Java 17+) for restricted type hierarchies
|
|
25
|
+
- Use **text blocks** (`"""`) for multi-line strings
|
|
26
|
+
|
|
27
|
+
### Annotations
|
|
28
|
+
- `@Override` on all overridden methods — non-negotiable
|
|
29
|
+
- `@Nullable` / `@NonNull` (from JSR-305 or JetBrains) on public API parameters and return types
|
|
30
|
+
- `@Deprecated(forRemoval = true)` with `@deprecated` Javadoc tag — never deprecate without replacement guidance
|
|
31
|
+
- Use Lombok sparingly — `@Getter`, `@Builder`, `@RequiredArgsConstructor` are fine; `@Data` hides mutation
|
|
32
|
+
|
|
33
|
+
### Package Conventions
|
|
34
|
+
- Follow the project's existing package structure — don't introduce new conventions
|
|
35
|
+
- Organize by feature, not by layer (unless the project already uses layers)
|
|
36
|
+
- One public class per file — file name matches class name
|
|
37
|
+
- Keep packages focused — if a package has >15 classes, it probably needs splitting
|
|
38
|
+
|
|
39
|
+
### Dependency Injection
|
|
40
|
+
- Use constructor injection — not field injection (`@Autowired` on fields is an anti-pattern)
|
|
41
|
+
- Prefer interface types in constructor parameters for testability
|
|
42
|
+
- Keep constructors focused — if >5 parameters, the class may have too many responsibilities
|
|
43
|
+
|
|
44
|
+
### Naming Conventions
|
|
45
|
+
- `PascalCase` for classes, interfaces, enums, records
|
|
46
|
+
- `camelCase` for methods, fields, parameters, local variables
|
|
47
|
+
- `UPPER_SNAKE_CASE` for constants (`static final`)
|
|
48
|
+
- Interfaces: no `I` prefix — `UserRepository` not `IUserRepository`
|
|
49
|
+
- Boolean methods: `is*`, `has*`, `can*`, `should*`
|
|
50
|
+
|
|
51
|
+
### Testing Considerations
|
|
52
|
+
- Write code with dependency injection for testability
|
|
53
|
+
- Prefer composition over inheritance — easier to mock
|
|
54
|
+
- Use `@VisibleForTesting` (Guava) to annotate package-private methods exposed for testing
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
## KOTLIN-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **Kotlin** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### Coroutines — Structured Concurrency
|
|
6
|
+
- Use `suspend` functions for async operations — never use callbacks when coroutines are available
|
|
7
|
+
- Use `CoroutineScope` properly — never use `GlobalScope` in production code
|
|
8
|
+
- Use `viewModelScope` (Android) or `CoroutineScope(SupervisorJob())` for scoped work
|
|
9
|
+
- Use `withContext(Dispatchers.IO)` for I/O operations, `Dispatchers.Default` for CPU-intensive work
|
|
10
|
+
- Use `async/await` for parallel decomposition, `launch` for fire-and-forget
|
|
11
|
+
- Handle cancellation: check `isActive` in long-running loops, catch `CancellationException` only to rethrow
|
|
12
|
+
|
|
13
|
+
### Sealed Classes & Exhaustive When
|
|
14
|
+
- Use **sealed classes/interfaces** for restricted type hierarchies (state machines, results, events)
|
|
15
|
+
- Use `when` expressions with sealed types — the compiler enforces exhaustive matching
|
|
16
|
+
- Use sealed classes for Result types: `sealed class Result<T> { data class Success<T>(val data: T) : Result<T>(); ... }`
|
|
17
|
+
- Prefer sealed interfaces (Kotlin 1.5+) over sealed classes when state doesn't need to be stored
|
|
18
|
+
|
|
19
|
+
### Null Safety — The Kotlin Advantage
|
|
20
|
+
- Use `?` for nullable types, non-nullable is the default — respect the type system
|
|
21
|
+
- Use `?.` (safe call), `?:` (Elvis), `?.let {}` for null handling
|
|
22
|
+
- **Never use `!!`** (not-null assertion) in production code — it's a crash waiting to happen
|
|
23
|
+
- Use `requireNotNull()` or `checkNotNull()` with descriptive messages for preconditions
|
|
24
|
+
- Use `filterNotNull()` and `mapNotNull()` for collections
|
|
25
|
+
|
|
26
|
+
### Extension Functions
|
|
27
|
+
- Use extension functions for adding behavior to types you don't own
|
|
28
|
+
- Keep extensions close to their usage — don't create a giant `Extensions.kt` dump file
|
|
29
|
+
- Use extension properties for computed values: `val String.isEmail: Boolean get() = ...`
|
|
30
|
+
- Scope extensions: define them in the file/class where they're used, not globally
|
|
31
|
+
|
|
32
|
+
### Data Classes & Value Objects
|
|
33
|
+
- Use `data class` for all DTOs and value objects — automatic `equals()`, `hashCode()`, `copy()`, `toString()`
|
|
34
|
+
- Use `copy()` for non-destructive updates: `val updated = user.copy(name = "New")`
|
|
35
|
+
- Use `value class` (inline class) for type-safe wrappers: `value class UserId(val value: String)`
|
|
36
|
+
- Destructuring: `val (name, email) = user`
|
|
37
|
+
|
|
38
|
+
### Code Style
|
|
39
|
+
- Use expression bodies for simple functions: `fun double(x: Int) = x * 2`
|
|
40
|
+
- Use `apply`, `also`, `let`, `run`, `with` scope functions — but don't nest them
|
|
41
|
+
- Use `object` for singletons and companion factories
|
|
42
|
+
- Use `typealias` for complex generic types: `typealias UserMap = Map<UserId, User>`
|
|
43
|
+
- Use `require()` and `check()` for preconditions and state validation
|
|
44
|
+
|
|
45
|
+
### Naming Conventions
|
|
46
|
+
- `camelCase` for functions, properties, variables
|
|
47
|
+
- `PascalCase` for classes, interfaces, objects, enums
|
|
48
|
+
- `UPPER_SNAKE_CASE` for constants (`const val` or `@JvmField val`)
|
|
49
|
+
- Boolean properties: `is*`, `has*`, `can*`
|
|
50
|
+
- Factory functions: `PascalCase` matching the return type: `fun User(name: String) = User(name, ...)`
|
|
51
|
+
|
|
52
|
+
### Testing Considerations
|
|
53
|
+
- Use constructor injection for testability
|
|
54
|
+
- Use `runTest` (coroutine test) for testing suspend functions
|
|
55
|
+
- Use `MockK` or project's mocking framework conventions
|
|
56
|
+
- Prefer deterministic code — accept `Clock` parameter instead of `Instant.now()`
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
## NEXT.JS-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **Next.js** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### App Router — The Default (Next.js 13+)
|
|
6
|
+
- Use the **App Router** (`app/` directory) — not Pages Router, unless the project explicitly uses it
|
|
7
|
+
- Understand the file conventions: `page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx`
|
|
8
|
+
- Use `route.ts` for API routes in the App Router
|
|
9
|
+
- Layouts persist across navigations — put shared UI (nav, sidebar) in layouts
|
|
10
|
+
- Use `template.tsx` only when you need re-mounting on navigation (rare)
|
|
11
|
+
|
|
12
|
+
### Server Components — Default Rendering
|
|
13
|
+
- **All components are Server Components by default** — only add `'use client'` when you NEED client interactivity
|
|
14
|
+
- Server Components can: fetch data directly, access backend, read fs, use async/await at component level
|
|
15
|
+
- Client Components need `'use client'` directive when using: hooks, event handlers, browser APIs, state
|
|
16
|
+
- **Minimize `'use client'`** — push it as far down the tree as possible
|
|
17
|
+
- Never add `'use client'` to a layout unless absolutely necessary — it makes all children client components
|
|
18
|
+
|
|
19
|
+
### Data Fetching
|
|
20
|
+
- Use `async` Server Components for data fetching — direct `await` in the component body
|
|
21
|
+
- Use **Server Actions** (`'use server'`) for mutations — form submissions, data writes
|
|
22
|
+
- Use `fetch()` in Server Components with Next.js caching: `fetch(url, { cache: 'force-cache' })` or `{ next: { revalidate: 3600 } }`
|
|
23
|
+
- Use `unstable_cache` or `cache()` from React for caching expensive operations
|
|
24
|
+
- Never use `getServerSideProps` / `getStaticProps` in App Router — those are Pages Router patterns
|
|
25
|
+
|
|
26
|
+
### Rendering Strategies
|
|
27
|
+
- **Static (SSG):** Default for pages without dynamic data. Use `generateStaticParams()` for dynamic routes
|
|
28
|
+
- **Dynamic (SSR):** Add `export const dynamic = 'force-dynamic'` or use `cookies()`, `headers()`, `searchParams`
|
|
29
|
+
- **ISR:** Use `{ next: { revalidate: N } }` in fetch or `export const revalidate = N` in page/layout
|
|
30
|
+
- Choose the least dynamic option that works — static > ISR > SSR
|
|
31
|
+
|
|
32
|
+
### Routing & Navigation
|
|
33
|
+
- Use `next/link` for client-side navigation — never `<a>` for internal links
|
|
34
|
+
- Use `next/navigation` hooks: `useRouter()`, `usePathname()`, `useSearchParams()` — not `next/router`
|
|
35
|
+
- Use dynamic routes: `app/users/[id]/page.tsx` — access via `params` prop
|
|
36
|
+
- Use route groups `(group)` for organizing without affecting URL structure
|
|
37
|
+
- Use parallel routes `@slot` and intercepting routes `(.)` for advanced patterns
|
|
38
|
+
|
|
39
|
+
### Image & Asset Optimization
|
|
40
|
+
- Use `next/image` for all images — automatic optimization, lazy loading, responsive sizing
|
|
41
|
+
- Use `next/font` for fonts — automatic self-hosting, no layout shift
|
|
42
|
+
- Set `width` and `height` or use `fill` with a sized container — prevent layout shift
|
|
43
|
+
- Use `priority` prop for above-the-fold images (LCP optimization)
|
|
44
|
+
|
|
45
|
+
### Middleware
|
|
46
|
+
- Use `middleware.ts` at the project root for: auth guards, redirects, geolocation, A/B testing
|
|
47
|
+
- Keep middleware fast — it runs on every request. No heavy computation or database queries
|
|
48
|
+
- Use `matcher` config to limit which routes trigger middleware
|
|
49
|
+
|
|
50
|
+
### Environment Variables
|
|
51
|
+
- `NEXT_PUBLIC_*` — exposed to the browser (public). Use for: API URLs, feature flags
|
|
52
|
+
- Variables without prefix — server-only. Use for: secrets, database URLs, API keys
|
|
53
|
+
- Access in Server Components directly from `process.env`
|
|
54
|
+
- Access in Client Components only via `process.env.NEXT_PUBLIC_*`
|
|
55
|
+
|
|
56
|
+
### Naming Conventions
|
|
57
|
+
- File-based routing: `page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx`
|
|
58
|
+
- Components: `PascalCase` — `UserProfile.tsx`
|
|
59
|
+
- Server Actions: `camelCase` with descriptive names — `createUser`, `deletePost`
|
|
60
|
+
- API routes: `route.ts` with exported HTTP method handlers: `GET`, `POST`, `PUT`, `DELETE`
|
|
61
|
+
|
|
62
|
+
### Testing Considerations
|
|
63
|
+
- Separate server and client component logic for testability
|
|
64
|
+
- Use server actions as the boundary for testing mutations
|
|
65
|
+
- Mock `next/navigation` hooks in component tests
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
## PYTHON-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **Python** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### Code Style — PEP 8 Strictly
|
|
6
|
+
- Follow **PEP 8** without exception — use the project's formatter config if present (black, ruff, autopep8)
|
|
7
|
+
- **Type hints on ALL function signatures** (PEP 484) — parameters AND return types
|
|
8
|
+
- Use `from __future__ import annotations` at the top of every file for modern type hint syntax
|
|
9
|
+
- **Google-style docstrings** on all public functions — include Args, Returns, Raises sections
|
|
10
|
+
- Max line length: follow project config, default to 88 (black) or 79 (PEP 8)
|
|
11
|
+
|
|
12
|
+
### Type Safety
|
|
13
|
+
- Use `TypedDict` for structured dictionaries instead of `Dict[str, Any]`
|
|
14
|
+
- Use `Protocol` for structural typing (duck typing with type safety)
|
|
15
|
+
- Use `Optional[X]` explicitly — never rely on implicit `None` default
|
|
16
|
+
- Use `Literal` types for fixed string/int values
|
|
17
|
+
- Use `@overload` decorator for functions with multiple signatures
|
|
18
|
+
- Prefer `dataclasses` or **Pydantic** for data structures over raw dicts or tuples
|
|
19
|
+
- Use `Final` for constants: `MAX_RETRIES: Final = 3`
|
|
20
|
+
|
|
21
|
+
### Error Handling
|
|
22
|
+
- **Custom exception classes** for domain-specific errors — inherit from a base app exception
|
|
23
|
+
- Use `contextlib.contextmanager` or `contextlib.asynccontextmanager` for resource management
|
|
24
|
+
- **Never bare `except:`** — always specify the exception type
|
|
25
|
+
- Use `except Exception as e:` at minimum, prefer specific exceptions
|
|
26
|
+
- Chain exceptions with `raise NewError(...) from original_error`
|
|
27
|
+
- Use `logging` module, never `print()` for error reporting
|
|
28
|
+
|
|
29
|
+
### Imports & Structure
|
|
30
|
+
- Import grouping: **stdlib → third-party → local** (separated by blank lines)
|
|
31
|
+
- Use **absolute imports** — never relative imports unless in a package's `__init__.py`
|
|
32
|
+
- Use `__all__` to define the public API of modules
|
|
33
|
+
- Never use `from module import *` — always import specific names
|
|
34
|
+
|
|
35
|
+
### Patterns
|
|
36
|
+
- Prefer **pathlib.Path** over `os.path` for file operations
|
|
37
|
+
- Use **f-strings** over `.format()` or `%` formatting
|
|
38
|
+
- Use **generators** and `yield` for large sequences — avoid loading everything into memory
|
|
39
|
+
- Use `enumerate()` instead of manual index tracking
|
|
40
|
+
- Use `collections.defaultdict`, `collections.Counter` when appropriate
|
|
41
|
+
- Use `functools.lru_cache` or `functools.cache` for expensive pure function calls
|
|
42
|
+
- Prefer list/dict/set **comprehensions** over `map()`/`filter()` for readability
|
|
43
|
+
|
|
44
|
+
### Async Code (if applicable)
|
|
45
|
+
- Use `async/await` consistently — never mix sync and async in the same function
|
|
46
|
+
- Use `asyncio.gather()` for concurrent operations
|
|
47
|
+
- Use `aiofiles` for async file I/O if the project uses it
|
|
48
|
+
- Always handle `asyncio.CancelledError` properly
|
|
49
|
+
|
|
50
|
+
### Testing Considerations
|
|
51
|
+
- Write code that is **easily testable** — pure functions, dependency injection
|
|
52
|
+
- Use `pytest` fixtures and parametrize for clean test setup
|
|
53
|
+
- Prefer deterministic code — accept `datetime` params instead of calling `datetime.now()` directly
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
## REACT-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **React** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### Component Patterns — Functional Only
|
|
6
|
+
- **Always use functional components** — never class components for new code
|
|
7
|
+
- Keep components focused — if >150 lines, extract subcomponents
|
|
8
|
+
- Use composition over prop drilling: split into Container + Presentation components when logic is complex
|
|
9
|
+
- Export components as named exports: `export function UserCard() {}` — not default exports
|
|
10
|
+
- Co-locate related files: component, styles, tests, types in the same directory
|
|
11
|
+
|
|
12
|
+
### Hooks Rules — NON-NEGOTIABLE
|
|
13
|
+
- Hooks only at the **top level** — never inside conditions, loops, or nested functions
|
|
14
|
+
- Hooks only in **function components** or **custom hooks** — never in regular functions
|
|
15
|
+
- Custom hooks start with `use`: `useAuth()`, `useFetchUser()`
|
|
16
|
+
- Keep custom hooks focused on one responsibility — compose hooks, don't create mega-hooks
|
|
17
|
+
- Always provide proper dependency arrays for `useEffect`, `useMemo`, `useCallback`
|
|
18
|
+
|
|
19
|
+
### State Management
|
|
20
|
+
- Use `useState` for simple local state
|
|
21
|
+
- Use `useReducer` for complex state with multiple related updates
|
|
22
|
+
- Use **React Context** for truly global state (theme, auth, locale) — not for all shared state
|
|
23
|
+
- Avoid prop drilling >2 levels — extract to context or composition pattern
|
|
24
|
+
- State should live as close to where it's used as possible — lift only when necessary
|
|
25
|
+
- Never derive state from props in `useState` — compute it directly or use `useMemo`
|
|
26
|
+
|
|
27
|
+
### Performance — When to Optimize
|
|
28
|
+
- **Don't wrap everything in `memo`/`useMemo`/`useCallback`** — only optimize when there's a measured problem
|
|
29
|
+
- Use `React.memo()` when: component renders often with same props, rendering is expensive
|
|
30
|
+
- Use `useMemo()` when: computation is expensive AND dependencies change infrequently
|
|
31
|
+
- Use `useCallback()` when: passing callbacks to memoized child components
|
|
32
|
+
- Use `key` prop correctly — stable, unique IDs from data (never array index for dynamic lists)
|
|
33
|
+
|
|
34
|
+
### Error Boundaries
|
|
35
|
+
- Wrap major sections in error boundaries — prevent one component crash from taking down the page
|
|
36
|
+
- Use `react-error-boundary` or create a class-based boundary (the one exception to "no classes")
|
|
37
|
+
- Show meaningful fallback UI — not a blank page
|
|
38
|
+
|
|
39
|
+
### React 19+ Patterns (if applicable)
|
|
40
|
+
- Use `use()` hook for reading resources (promises, contexts)
|
|
41
|
+
- Use `useActionState()` for form actions with pending state
|
|
42
|
+
- Use `useOptimistic()` for optimistic UI updates
|
|
43
|
+
- Use `<form action={}>` with server actions where available
|
|
44
|
+
|
|
45
|
+
### Naming Conventions
|
|
46
|
+
- `PascalCase` for components: `UserProfile`, `LoginForm`
|
|
47
|
+
- `camelCase` for hooks: `useAuth`, `useFetchData`
|
|
48
|
+
- `camelCase` for event handlers with `handle` prefix: `handleClick`, `handleSubmit`
|
|
49
|
+
- `on` prefix for callback props: `onClick`, `onSubmit`, `onChange`
|
|
50
|
+
- Boolean props: `is*`, `has*`, `should*`: `isLoading`, `hasError`
|
|
51
|
+
|
|
52
|
+
### Testing Considerations
|
|
53
|
+
- Write components that are testable — props in, rendered output out
|
|
54
|
+
- Use data-testid attributes for test selectors (not CSS classes or element structure)
|
|
55
|
+
- Prefer composition and dependency injection over hard-coded dependencies
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
## RUBY-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **Ruby** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### Ruby Idioms
|
|
6
|
+
- Write **idiomatic Ruby** — use the language's expressiveness, not Java-in-Ruby
|
|
7
|
+
- Use `attr_reader`, `attr_writer`, `attr_accessor` — don't write manual getters/setters
|
|
8
|
+
- Use **guard clauses** for early returns: `return unless valid?` instead of wrapping in `if`
|
|
9
|
+
- Prefer `unless` for single negative conditions — but never `unless...else` (use `if` instead)
|
|
10
|
+
- Use **string interpolation** `"Hello #{name}"` over concatenation
|
|
11
|
+
- Use `freeze` on string constants: `DEFAULT_NAME = "guest".freeze`
|
|
12
|
+
|
|
13
|
+
### Blocks, Procs & Lambdas
|
|
14
|
+
- Use `&block` parameter when you need to store or pass the block
|
|
15
|
+
- Use `yield` when you just need to call the block inline
|
|
16
|
+
- Prefer **lambdas** over procs — lambdas check arity and use `return` predictably
|
|
17
|
+
- Use `Proc.new` / `proc {}` only when you need proc-specific behavior
|
|
18
|
+
- Use `.map`, `.select`, `.reject`, `.reduce` — avoid manual iteration with `each` + accumulator
|
|
19
|
+
|
|
20
|
+
### Gem Conventions
|
|
21
|
+
- Follow the project's Gemfile conventions — respect existing gem choices
|
|
22
|
+
- Use `bundler` — never install gems globally for project dependencies
|
|
23
|
+
- Pin gem versions in production: `gem 'rails', '~> 7.1'`
|
|
24
|
+
- Prefer well-maintained gems with active communities — check GitHub activity
|
|
25
|
+
|
|
26
|
+
### Duck Typing & Protocols
|
|
27
|
+
- Ruby uses **duck typing** — respond to methods, don't check types
|
|
28
|
+
- Use `respond_to?(:method)` instead of `is_a?(ClassName)` when possible
|
|
29
|
+
- Define clear method interfaces — document expected duck type in comments
|
|
30
|
+
- Use modules for shared behavior: `include Enumerable` with `each` defined
|
|
31
|
+
|
|
32
|
+
### Error Handling
|
|
33
|
+
- Rescue specific exceptions, not bare `rescue` (catches `StandardError`)
|
|
34
|
+
- Create custom exception classes inheriting from `StandardError`
|
|
35
|
+
- Use `begin/rescue/ensure` blocks — `ensure` for cleanup
|
|
36
|
+
- Use `raise` with message: `raise ArgumentError, "name cannot be blank"`
|
|
37
|
+
- Never rescue `Exception` — it catches `SystemExit`, `SignalException`, etc.
|
|
38
|
+
|
|
39
|
+
### Code Structure
|
|
40
|
+
- Follow existing project conventions (Rails, Sinatra, plain Ruby)
|
|
41
|
+
- Use modules for namespacing: `module MyApp::Services`
|
|
42
|
+
- Keep methods short — if >15 lines, consider extracting
|
|
43
|
+
- Use `frozen_string_literal: true` magic comment at top of files
|
|
44
|
+
- Follow project's Ruby version and style guide (rubocop config)
|
|
45
|
+
|
|
46
|
+
### Naming Conventions
|
|
47
|
+
- `snake_case` for methods, variables, file names
|
|
48
|
+
- `PascalCase` for classes and modules
|
|
49
|
+
- `UPPER_SNAKE_CASE` for constants
|
|
50
|
+
- Predicate methods end with `?`: `valid?`, `empty?`, `admin?`
|
|
51
|
+
- Dangerous methods end with `!`: `save!`, `destroy!`, `sort!`
|
|
52
|
+
- Setter methods end with `=`: `name=`
|
|
53
|
+
|
|
54
|
+
### RSpec Patterns (if project uses RSpec)
|
|
55
|
+
- Use `describe`/`context`/`it` hierarchy for clear test structure
|
|
56
|
+
- Use `let` (lazy) and `let!` (eager) for test data — not instance variables
|
|
57
|
+
- Use `subject` for the object under test
|
|
58
|
+
- Use `shared_examples` for reusable test patterns
|
|
59
|
+
- Prefer `expect(x).to eq(y)` over `assert_equal y, x`
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
## RUST-SPECIFIC GUIDELINES
|
|
2
|
+
|
|
3
|
+
You are working in a **Rust** codebase. Apply these principles with zero exceptions.
|
|
4
|
+
|
|
5
|
+
### Ownership & Borrowing — THE CORE RULES
|
|
6
|
+
- Prefer **borrowing** (`&T`, `&mut T`) over taking ownership when the function doesn't need to own the data
|
|
7
|
+
- Use `Clone` sparingly — it's a code smell if you're cloning to satisfy the borrow checker. Restructure instead
|
|
8
|
+
- Prefer `&str` over `String` in function parameters — accept the most general form
|
|
9
|
+
- Use `Cow<'_, str>` when a function might or might not need to allocate
|
|
10
|
+
- Understand and respect lifetimes — don't sprinkle `'static` to make errors go away
|
|
11
|
+
|
|
12
|
+
### Error Handling — Result/Option Everywhere
|
|
13
|
+
- Use `Result<T, E>` for fallible operations — **never panic** in library code
|
|
14
|
+
- Use `thiserror` for library error types, `anyhow` for application error types
|
|
15
|
+
- Use the `?` operator for error propagation — avoid manual `match` on `Result` when `?` suffices
|
|
16
|
+
- Create domain-specific error enums with `#[derive(thiserror::Error)]`
|
|
17
|
+
- Use `Option<T>` for values that may not exist — never use sentinel values
|
|
18
|
+
- Chain with `.map()`, `.and_then()`, `.unwrap_or_default()` — avoid nested `match` blocks
|
|
19
|
+
|
|
20
|
+
### Unsafe Isolation
|
|
21
|
+
- **Minimize `unsafe` blocks** — wrap unsafe operations in safe abstractions
|
|
22
|
+
- Document every `unsafe` block with a `// SAFETY:` comment explaining why it's sound
|
|
23
|
+
- Never expose raw pointers in public APIs — wrap in safe types
|
|
24
|
+
|
|
25
|
+
### Code Quality
|
|
26
|
+
- Run `cargo clippy` — treat all warnings as errors
|
|
27
|
+
- Run `cargo fmt` — never deviate from project formatting
|
|
28
|
+
- Use `#[derive(Debug, Clone, PartialEq)]` on all data types unless there's a reason not to
|
|
29
|
+
- Prefer `impl Trait` in argument position over generic constraints when there's only one trait bound
|
|
30
|
+
- Use `#[must_use]` on functions that return values that shouldn't be ignored
|
|
31
|
+
|
|
32
|
+
### Patterns
|
|
33
|
+
- Use **builder pattern** for complex struct construction
|
|
34
|
+
- Use `enum` with variants for state machines — not boolean flags
|
|
35
|
+
- Prefer iterators and combinators (`.iter().map().filter().collect()`) over manual loops
|
|
36
|
+
- Use `Default` trait for structs with sensible defaults
|
|
37
|
+
- Use `From`/`Into` traits for type conversions — avoid custom conversion functions
|
|
38
|
+
|
|
39
|
+
### Naming Conventions
|
|
40
|
+
- `snake_case` for functions, methods, variables, modules
|
|
41
|
+
- `PascalCase` for types, traits, enums
|
|
42
|
+
- `UPPER_SNAKE_CASE` for constants and statics
|
|
43
|
+
- Prefix boolean methods with `is_`, `has_`, `can_`
|
|
44
|
+
|
|
45
|
+
### Testing Considerations
|
|
46
|
+
- Write code that is testable — use trait objects or generics for dependency injection
|
|
47
|
+
- Use `#[cfg(test)]` module for unit tests within the same file
|
|
48
|
+
- Prefer deterministic code — accept timestamps/randomness as parameters
|