devflow-kit 1.1.0 → 1.2.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 (107) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +23 -6
  3. package/dist/plugins.js +67 -3
  4. package/package.json +2 -1
  5. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +15 -0
  6. package/plugins/devflow-ambient/.claude-plugin/plugin.json +1 -1
  7. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +1 -1
  8. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +4 -0
  9. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  10. package/plugins/devflow-code-review/.claude-plugin/plugin.json +1 -4
  11. package/plugins/devflow-code-review/agents/reviewer.md +8 -0
  12. package/plugins/devflow-code-review/commands/code-review-teams.md +11 -1
  13. package/plugins/devflow-code-review/commands/code-review.md +12 -2
  14. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +2 -6
  15. package/plugins/devflow-debug/.claude-plugin/plugin.json +1 -1
  16. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +15 -0
  17. package/plugins/devflow-go/.claude-plugin/plugin.json +15 -0
  18. package/plugins/devflow-go/skills/go/SKILL.md +187 -0
  19. package/plugins/devflow-go/skills/go/references/concurrency.md +312 -0
  20. package/plugins/devflow-go/skills/go/references/detection.md +129 -0
  21. package/plugins/devflow-go/skills/go/references/patterns.md +232 -0
  22. package/plugins/devflow-go/skills/go/references/violations.md +205 -0
  23. package/plugins/devflow-implement/.claude-plugin/plugin.json +1 -3
  24. package/plugins/devflow-implement/agents/coder.md +11 -6
  25. package/plugins/devflow-java/.claude-plugin/plugin.json +15 -0
  26. package/plugins/devflow-java/skills/java/SKILL.md +183 -0
  27. package/plugins/devflow-java/skills/java/references/detection.md +120 -0
  28. package/plugins/devflow-java/skills/java/references/modern-java.md +270 -0
  29. package/plugins/devflow-java/skills/java/references/patterns.md +235 -0
  30. package/plugins/devflow-java/skills/java/references/violations.md +213 -0
  31. package/plugins/devflow-python/.claude-plugin/plugin.json +15 -0
  32. package/plugins/devflow-python/skills/python/SKILL.md +188 -0
  33. package/plugins/devflow-python/skills/python/references/async.md +220 -0
  34. package/plugins/devflow-python/skills/python/references/detection.md +128 -0
  35. package/plugins/devflow-python/skills/python/references/patterns.md +226 -0
  36. package/plugins/devflow-python/skills/python/references/violations.md +204 -0
  37. package/plugins/devflow-react/.claude-plugin/plugin.json +15 -0
  38. package/plugins/{devflow-core-skills → devflow-react}/skills/react/SKILL.md +1 -1
  39. package/plugins/{devflow-core-skills → devflow-react}/skills/react/references/patterns.md +3 -3
  40. package/plugins/devflow-resolve/.claude-plugin/plugin.json +1 -1
  41. package/plugins/devflow-rust/.claude-plugin/plugin.json +15 -0
  42. package/plugins/devflow-rust/skills/rust/SKILL.md +193 -0
  43. package/plugins/devflow-rust/skills/rust/references/detection.md +131 -0
  44. package/plugins/devflow-rust/skills/rust/references/ownership.md +242 -0
  45. package/plugins/devflow-rust/skills/rust/references/patterns.md +210 -0
  46. package/plugins/devflow-rust/skills/rust/references/violations.md +191 -0
  47. package/plugins/devflow-self-review/.claude-plugin/plugin.json +1 -1
  48. package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
  49. package/plugins/devflow-typescript/.claude-plugin/plugin.json +15 -0
  50. package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/patterns.md +3 -3
  51. package/shared/agents/coder.md +11 -6
  52. package/shared/agents/reviewer.md +8 -0
  53. package/shared/skills/ambient-router/SKILL.md +1 -1
  54. package/shared/skills/ambient-router/references/skill-catalog.md +4 -0
  55. package/shared/skills/go/SKILL.md +187 -0
  56. package/shared/skills/go/references/concurrency.md +312 -0
  57. package/shared/skills/go/references/detection.md +129 -0
  58. package/shared/skills/go/references/patterns.md +232 -0
  59. package/shared/skills/go/references/violations.md +205 -0
  60. package/shared/skills/java/SKILL.md +183 -0
  61. package/shared/skills/java/references/detection.md +120 -0
  62. package/shared/skills/java/references/modern-java.md +270 -0
  63. package/shared/skills/java/references/patterns.md +235 -0
  64. package/shared/skills/java/references/violations.md +213 -0
  65. package/shared/skills/python/SKILL.md +188 -0
  66. package/shared/skills/python/references/async.md +220 -0
  67. package/shared/skills/python/references/detection.md +128 -0
  68. package/shared/skills/python/references/patterns.md +226 -0
  69. package/shared/skills/python/references/violations.md +204 -0
  70. package/shared/skills/react/SKILL.md +1 -1
  71. package/shared/skills/react/references/patterns.md +3 -3
  72. package/shared/skills/rust/SKILL.md +193 -0
  73. package/shared/skills/rust/references/detection.md +131 -0
  74. package/shared/skills/rust/references/ownership.md +242 -0
  75. package/shared/skills/rust/references/patterns.md +210 -0
  76. package/shared/skills/rust/references/violations.md +191 -0
  77. package/shared/skills/typescript/references/patterns.md +3 -3
  78. package/plugins/devflow-code-review/skills/react/SKILL.md +0 -276
  79. package/plugins/devflow-code-review/skills/react/references/patterns.md +0 -1331
  80. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +0 -229
  81. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +0 -171
  82. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +0 -670
  83. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +0 -419
  84. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +0 -254
  85. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +0 -184
  86. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +0 -511
  87. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +0 -453
  88. package/plugins/devflow-core-skills/skills/react/references/violations.md +0 -565
  89. package/plugins/devflow-implement/skills/accessibility/SKILL.md +0 -229
  90. package/plugins/devflow-implement/skills/accessibility/references/detection.md +0 -171
  91. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +0 -670
  92. package/plugins/devflow-implement/skills/accessibility/references/violations.md +0 -419
  93. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +0 -254
  94. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +0 -184
  95. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +0 -511
  96. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +0 -453
  97. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/SKILL.md +0 -0
  98. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/detection.md +0 -0
  99. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/patterns.md +0 -0
  100. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/violations.md +0 -0
  101. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/SKILL.md +0 -0
  102. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/detection.md +0 -0
  103. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/patterns.md +0 -0
  104. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/violations.md +0 -0
  105. /package/plugins/{devflow-code-review → devflow-react}/skills/react/references/violations.md +0 -0
  106. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/SKILL.md +0 -0
  107. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/violations.md +0 -0
@@ -0,0 +1,205 @@
1
+ # Go Violation Examples
2
+
3
+ Extended violation patterns for Go reviews. Reference from main SKILL.md.
4
+
5
+ ## Error Handling Violations
6
+
7
+ ### Ignored Errors
8
+
9
+ ```go
10
+ // VIOLATION: Silently discarding error
11
+ data, _ := json.Marshal(user)
12
+ w.Write(data)
13
+
14
+ // VIOLATION: Error ignored in deferred call
15
+ defer file.Close() // Close() returns error
16
+
17
+ // VIOLATION: Swallowing error with log
18
+ if err != nil {
19
+ log.Println("something failed") // Error details lost
20
+ return nil
21
+ }
22
+ ```
23
+
24
+ ### Unwrapped Errors
25
+
26
+ ```go
27
+ // VIOLATION: No context on error
28
+ func LoadConfig(path string) (*Config, error) {
29
+ data, err := os.ReadFile(path)
30
+ if err != nil {
31
+ return nil, err // Caller has no idea what failed
32
+ }
33
+ var cfg Config
34
+ if err := json.Unmarshal(data, &cfg); err != nil {
35
+ return nil, err // Which unmarshal? What file?
36
+ }
37
+ return &cfg, nil
38
+ }
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Goroutine Leak Violations
44
+
45
+ ### Fire-and-Forget Goroutine
46
+
47
+ ```go
48
+ // VIOLATION: No way to stop or wait for this goroutine
49
+ func StartPoller() {
50
+ go func() {
51
+ for {
52
+ poll()
53
+ time.Sleep(10 * time.Second)
54
+ }
55
+ }()
56
+ }
57
+
58
+ // VIOLATION: Goroutine blocks forever on channel nobody reads
59
+ func process(items []Item) {
60
+ ch := make(chan Result)
61
+ for _, item := range items {
62
+ go func(i Item) {
63
+ ch <- compute(i) // Blocks if nobody reads
64
+ }(item)
65
+ }
66
+ // Only reads first result - rest leak
67
+ result := <-ch
68
+ _ = result
69
+ }
70
+ ```
71
+
72
+ ### Missing Context Cancellation
73
+
74
+ ```go
75
+ // VIOLATION: Goroutine ignores context
76
+ func Fetch(ctx context.Context, url string) ([]byte, error) {
77
+ ch := make(chan []byte, 1)
78
+ go func() {
79
+ resp, _ := http.Get(url) // Ignores ctx cancellation
80
+ body, _ := io.ReadAll(resp.Body)
81
+ ch <- body
82
+ }()
83
+ return <-ch, nil
84
+ }
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Interface Pollution Violations
90
+
91
+ ### Premature Interface Definition
92
+
93
+ ```go
94
+ // VIOLATION: Interface defined at producer, not consumer
95
+ package user
96
+
97
+ type UserStore interface { // Only one implementation exists
98
+ Get(id string) (*User, error)
99
+ Save(u *User) error
100
+ Delete(id string) error
101
+ List() ([]*User, error)
102
+ Count() (int, error)
103
+ }
104
+
105
+ type PostgresStore struct{ db *sql.DB }
106
+
107
+ func (s *PostgresStore) Get(id string) (*User, error) { ... }
108
+ // ... implements all 5 methods
109
+ ```
110
+
111
+ ### God Interface
112
+
113
+ ```go
114
+ // VIOLATION: Interface too large - impossible to mock cleanly
115
+ type Service interface {
116
+ CreateUser(ctx context.Context, u *User) error
117
+ GetUser(ctx context.Context, id string) (*User, error)
118
+ UpdateUser(ctx context.Context, u *User) error
119
+ DeleteUser(ctx context.Context, id string) error
120
+ ListUsers(ctx context.Context) ([]*User, error)
121
+ SendEmail(ctx context.Context, to string, body string) error
122
+ GenerateReport(ctx context.Context) ([]byte, error)
123
+ ProcessPayment(ctx context.Context, amt int) error
124
+ }
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Naked Return Violations
130
+
131
+ ```go
132
+ // VIOLATION: Naked returns obscure what's being returned
133
+ func divide(a, b float64) (result float64, err error) {
134
+ if b == 0 {
135
+ err = errors.New("division by zero")
136
+ return // What is result here? Zero - but not obvious
137
+ }
138
+ result = a / b
139
+ return // Have to trace back to find return values
140
+ }
141
+ ```
142
+
143
+ ---
144
+
145
+ ## init() Abuse Violations
146
+
147
+ ```go
148
+ // VIOLATION: Side effects in init - runs on import
149
+ func init() {
150
+ db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
151
+ if err != nil {
152
+ log.Fatal(err) // Crashes on import
153
+ }
154
+ globalDB = db
155
+ }
156
+
157
+ // VIOLATION: Registration magic in init
158
+ func init() {
159
+ http.HandleFunc("/health", healthCheck) // Hidden route registration
160
+ prometheus.MustRegister(requestCounter) // Panics if called twice
161
+ }
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Mutex Violations
167
+
168
+ ```go
169
+ // VIOLATION: Copying mutex (passes by value)
170
+ type Cache struct {
171
+ mu sync.Mutex
172
+ data map[string]string
173
+ }
174
+
175
+ func process(c Cache) { // c is a COPY - mutex is copied too
176
+ c.mu.Lock()
177
+ defer c.mu.Unlock()
178
+ c.data["key"] = "val"
179
+ }
180
+
181
+ // VIOLATION: Forgetting to unlock
182
+ func (c *Cache) Get(key string) string {
183
+ c.mu.Lock()
184
+ if val, ok := c.data[key]; ok {
185
+ return val // Mutex never unlocked!
186
+ }
187
+ c.mu.Unlock()
188
+ return ""
189
+ }
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Slice and Map Violations
195
+
196
+ ```go
197
+ // VIOLATION: Nil map write (runtime panic)
198
+ var m map[string]int
199
+ m["key"] = 1 // panic: assignment to entry in nil map
200
+
201
+ // VIOLATION: Sharing slice backing array
202
+ func getFirstThree(s []int) []int {
203
+ return s[:3] // Shares backing array - mutations leak
204
+ }
205
+ ```
@@ -5,16 +5,14 @@
5
5
  "name": "DevFlow Contributors",
6
6
  "email": "dean@keren.dev"
7
7
  },
8
- "version": "1.1.0",
8
+ "version": "1.2.0",
9
9
  "homepage": "https://github.com/dean0x/devflow",
10
10
  "repository": "https://github.com/dean0x/devflow",
11
11
  "license": "MIT",
12
12
  "keywords": ["implementation", "coding", "workflow", "agents", "agentic", "pr"],
13
13
  "agents": ["git", "skimmer", "synthesizer", "coder", "simplifier", "scrutinizer", "shepherd", "validator"],
14
14
  "skills": [
15
- "accessibility",
16
15
  "agent-teams",
17
- "frontend-design",
18
16
  "implementation-patterns",
19
17
  "self-review"
20
18
  ]
@@ -2,7 +2,7 @@
2
2
  name: Coder
3
3
  description: Autonomous task implementation on feature branch. Implements, tests, and commits.
4
4
  model: inherit
5
- skills: core-patterns, git-safety, implementation-patterns, git-workflow, typescript, react, test-patterns, input-validation, accessibility, frontend-design
5
+ skills: core-patterns, git-safety, implementation-patterns, git-workflow, test-patterns, input-validation
6
6
  ---
7
7
 
8
8
  # Coder Agent
@@ -33,11 +33,16 @@ You receive from orchestrator:
33
33
 
34
34
  2. **Reference handoff** (if PRIOR_PHASE_SUMMARY provided): Use summary to validate your understanding of prior work, not as the sole source of truth. The actual code is authoritative.
35
35
 
36
- 3. **Load domain skills**: Based on DOMAIN hint, apply relevant patterns:
37
- - `backend`: typescript, implementation-patterns, input-validation
38
- - `frontend`: react, typescript, accessibility, frontend-design
39
- - `tests`: test-patterns, typescript
40
- - `fullstack`: all of the above
36
+ 3. **Load domain skills**: Based on DOMAIN hint and files in scope, dynamically load relevant language/ecosystem skills by reading their SKILL.md. Only load skills that are installed:
37
+ - `backend` (TypeScript): Read `~/.claude/skills/typescript/SKILL.md`, `~/.claude/skills/input-validation/SKILL.md`
38
+ - `backend` (Go): Read `~/.claude/skills/go/SKILL.md`
39
+ - `backend` (Java): Read `~/.claude/skills/java/SKILL.md`
40
+ - `backend` (Python): Read `~/.claude/skills/python/SKILL.md`
41
+ - `backend` (Rust): Read `~/.claude/skills/rust/SKILL.md`
42
+ - `frontend`: Read `~/.claude/skills/react/SKILL.md`, `~/.claude/skills/typescript/SKILL.md`, `~/.claude/skills/accessibility/SKILL.md`, `~/.claude/skills/frontend-design/SKILL.md`
43
+ - `tests`: Read `~/.claude/skills/test-patterns/SKILL.md`, `~/.claude/skills/typescript/SKILL.md`
44
+ - `fullstack`: Combine backend + frontend skills
45
+ - If a Read fails (skill not installed), skip it silently and continue.
41
46
 
42
47
  4. **Implement the plan**: Work through execution steps systematically, creating and modifying files. Follow existing patterns. Type everything. Use Result types if codebase uses them.
43
48
 
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "devflow-java",
3
+ "description": "Java language patterns - records, sealed classes, composition, modern Java features",
4
+ "author": {
5
+ "name": "DevFlow Contributors",
6
+ "email": "dean@keren.dev"
7
+ },
8
+ "version": "1.2.0",
9
+ "homepage": "https://github.com/dean0x/devflow",
10
+ "repository": "https://github.com/dean0x/devflow",
11
+ "license": "MIT",
12
+ "keywords": ["java", "records", "sealed-classes", "composition"],
13
+ "agents": [],
14
+ "skills": ["java"]
15
+ }
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: java
3
+ description: This skill should be used when the user works with Java files (.java), asks about "records", "sealed classes", "Optional", "streams", "composition over inheritance", or discusses modern Java patterns and API design. Provides patterns for type system usage, error handling, immutability, and concurrency.
4
+ user-invocable: false
5
+ allowed-tools: Read, Grep, Glob
6
+ activation:
7
+ file-patterns:
8
+ - "**/*.java"
9
+ exclude:
10
+ - "**/build/**"
11
+ - "**/target/**"
12
+ ---
13
+
14
+ # Java Patterns
15
+
16
+ Reference for modern Java patterns, type system, and best practices.
17
+
18
+ ## Iron Law
19
+
20
+ > **FAVOR COMPOSITION OVER INHERITANCE**
21
+ >
22
+ > Delegation and interfaces over class hierarchies. Inheritance creates tight coupling,
23
+ > breaks encapsulation, and makes refactoring dangerous. Use interfaces for polymorphism,
24
+ > records for data, and sealed classes for restricted hierarchies. Extend only when the
25
+ > "is-a" relationship is genuinely invariant.
26
+
27
+ ## When This Skill Activates
28
+
29
+ - Working with Java codebases
30
+ - Designing APIs with modern Java features
31
+ - Using records, sealed classes, Optional
32
+ - Implementing concurrent code
33
+ - Structuring Java packages
34
+
35
+ ---
36
+
37
+ ## Type System (Modern Java)
38
+
39
+ ### Records for Data
40
+
41
+ ```java
42
+ // BAD: Mutable POJO with getters/setters
43
+ // GOOD: Immutable record
44
+ public record User(String name, String email, Instant createdAt) {
45
+ public User {
46
+ Objects.requireNonNull(name, "name must not be null");
47
+ Objects.requireNonNull(email, "email must not be null");
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Sealed Classes for Restricted Hierarchies
53
+
54
+ ```java
55
+ public sealed interface Result<T> permits Success, Failure {
56
+ record Success<T>(T value) implements Result<T> {}
57
+ record Failure<T>(String error) implements Result<T> {}
58
+ }
59
+
60
+ // Exhaustive pattern matching (Java 21+)
61
+ switch (result) {
62
+ case Success<User> s -> handleSuccess(s.value());
63
+ case Failure<User> f -> handleError(f.error());
64
+ }
65
+ ```
66
+
67
+ ### Optional for Absent Values
68
+
69
+ ```java
70
+ // BAD: return null;
71
+ // GOOD:
72
+ public Optional<User> findById(String id) {
73
+ return Optional.ofNullable(userMap.get(id));
74
+ }
75
+
76
+ // BAD: if (optional.isPresent()) optional.get()
77
+ // GOOD:
78
+ optional.map(User::name).orElse("Anonymous");
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Error Handling
84
+
85
+ ### Custom Exceptions with Context
86
+
87
+ ```java
88
+ public class EntityNotFoundException extends RuntimeException {
89
+ private final String entityType;
90
+ private final String entityId;
91
+
92
+ public EntityNotFoundException(String entityType, String entityId) {
93
+ super("%s with id %s not found".formatted(entityType, entityId));
94
+ this.entityType = entityType;
95
+ this.entityId = entityId;
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### Try-with-Resources
101
+
102
+ ```java
103
+ // Always use try-with-resources for AutoCloseable
104
+ try (var conn = dataSource.getConnection();
105
+ var stmt = conn.prepareStatement(sql)) {
106
+ stmt.setString(1, id);
107
+ return mapResult(stmt.executeQuery());
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Immutability
114
+
115
+ ```java
116
+ // Prefer unmodifiable collections
117
+ List<String> names = List.of("Alice", "Bob");
118
+ Map<String, Integer> scores = Map.of("Alice", 100, "Bob", 95);
119
+
120
+ // Defensive copies in constructors
121
+ public final class Team {
122
+ private final List<String> members;
123
+ public Team(List<String> members) {
124
+ this.members = List.copyOf(members);
125
+ }
126
+ public List<String> members() { return members; }
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Composition Over Inheritance
133
+
134
+ ```java
135
+ // BAD: class UserService extends BaseService extends AbstractDAO
136
+ // GOOD: compose via constructor injection
137
+ public class UserService {
138
+ private final UserRepository repository;
139
+ private final EventPublisher events;
140
+
141
+ public UserService(UserRepository repository, EventPublisher events) {
142
+ this.repository = repository;
143
+ this.events = events;
144
+ }
145
+ }
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Anti-Patterns
151
+
152
+ | Pattern | Bad | Good |
153
+ |---------|-----|------|
154
+ | Returning null | `return null` | `return Optional.empty()` |
155
+ | Checked exception abuse | `throws Exception` | Specific exceptions or unchecked |
156
+ | Raw types | `List list` | `List<User> list` |
157
+ | Deep inheritance | 4+ level hierarchy | Interfaces + composition |
158
+ | Mutable data objects | `setName()/getName()` | Records or immutable classes |
159
+
160
+ ---
161
+
162
+ ## Extended References
163
+
164
+ For additional patterns and examples:
165
+ - `references/violations.md` - Common Java violations
166
+ - `references/patterns.md` - Extended Java patterns
167
+ - `references/detection.md` - Detection patterns for Java issues
168
+ - `references/modern-java.md` - Modern Java features (17-21+)
169
+
170
+ ---
171
+
172
+ ## Checklist
173
+
174
+ - [ ] Records for pure data types
175
+ - [ ] Sealed interfaces for type hierarchies
176
+ - [ ] Optional instead of null returns
177
+ - [ ] Composition over inheritance
178
+ - [ ] Try-with-resources for all AutoCloseable
179
+ - [ ] Immutable collections (List.of, Map.of)
180
+ - [ ] No raw generic types
181
+ - [ ] Custom exceptions with context
182
+ - [ ] Streams for collection transforms
183
+ - [ ] Constructor injection for dependencies
@@ -0,0 +1,120 @@
1
+ # Detection Patterns for Java Issues
2
+
3
+ Grep and regex patterns for automated detection of Java violations. Reference from main SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Null Returns
8
+
9
+ ```bash
10
+ # Methods returning null instead of Optional
11
+ rg 'return\s+null\s*;' --type java
12
+
13
+ # Nullable method parameters without validation
14
+ rg 'public\s+\w+\s+\w+\((?!.*@NonNull).*\)' --type java
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Raw Types
20
+
21
+ ```bash
22
+ # Raw List, Map, Set, Collection usage
23
+ rg '\b(List|Map|Set|Collection|Iterator|Iterable)\b(?!\s*<)' --type java
24
+
25
+ # Raw Comparable implementation
26
+ rg 'implements\s+Comparable\b(?!\s*<)' --type java
27
+
28
+ # Unsafe casts from Object
29
+ rg '\(\s*(String|Integer|Long|Double)\s*\)\s*\w+\.get' --type java
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Deep Inheritance
35
+
36
+ ```bash
37
+ # Classes extending non-Object/non-interface classes (potential deep hierarchy)
38
+ rg 'class\s+\w+\s+extends\s+(?!Object\b)\w+' --type java
39
+
40
+ # Abstract class chains (look for multiple levels)
41
+ rg 'abstract\s+class\s+\w+\s+extends\s+Abstract' --type java
42
+
43
+ # Count inheritance depth per file
44
+ rg 'extends\s+\w+' --type java --count
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Missing Try-with-Resources
50
+
51
+ ```bash
52
+ # Manual close() calls (should use try-with-resources)
53
+ rg '\.close\(\)\s*;' --type java
54
+
55
+ # InputStream/OutputStream/Connection created outside try-with-resources
56
+ rg 'new\s+(FileInputStream|FileOutputStream|BufferedReader|BufferedWriter|Socket)\(' --type java
57
+
58
+ # getConnection() without try-with-resources context
59
+ rg '\.getConnection\(\)' --type java
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Checked Exception Abuse
65
+
66
+ ```bash
67
+ # Broad throws declarations
68
+ rg 'throws\s+Exception\b' --type java
69
+
70
+ # Empty catch blocks
71
+ rg -U 'catch\s*\([^)]+\)\s*\{\s*\}' --type java --multiline
72
+
73
+ # Catch-and-ignore (catch with only a comment or log)
74
+ rg -U 'catch\s*\([^)]+\)\s*\{\s*(//|/\*|logger\.(debug|trace))' --type java --multiline
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Mutable Data Objects
80
+
81
+ ```bash
82
+ # Setter methods (JavaBean anti-pattern for data objects)
83
+ rg 'public\s+void\s+set[A-Z]\w*\(' --type java
84
+
85
+ # Mutable collections returned from getters
86
+ rg 'return\s+(this\.)?(list|map|set|collection)\s*;' --type java -i
87
+
88
+ # Missing defensive copies in constructors
89
+ rg 'this\.\w+\s*=\s*\w+\s*;' --type java
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Concurrency Issues
95
+
96
+ ```bash
97
+ # HashMap in concurrent context (should be ConcurrentHashMap)
98
+ rg 'new\s+HashMap\b' --type java
99
+
100
+ # Missing volatile on shared fields
101
+ rg 'private\s+(?!volatile\s)(?!final\s)\w+\s+\w+\s*=' --type java
102
+
103
+ # Synchronized on non-private lock object
104
+ rg 'synchronized\s*\(\s*this\s*\)' --type java
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Streams Anti-Patterns
110
+
111
+ ```bash
112
+ # Stream.forEach with side effects (should use for-loop or collect)
113
+ rg '\.stream\(\).*\.forEach\(' --type java
114
+
115
+ # Nested streams (performance concern)
116
+ rg '\.stream\(\).*\.stream\(\)' --type java
117
+
118
+ # collect(Collectors.toList()) instead of .toList() (Java 16+)
119
+ rg 'collect\(Collectors\.toList\(\)\)' --type java
120
+ ```