devflow-kit 1.1.0 → 1.3.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 (152) hide show
  1. package/CHANGELOG.md +69 -1
  2. package/README.md +23 -6
  3. package/dist/cli.js +2 -0
  4. package/dist/commands/ambient.js +5 -4
  5. package/dist/commands/init.js +4 -2
  6. package/dist/commands/memory.js +4 -4
  7. package/dist/commands/skills.d.ts +11 -0
  8. package/dist/commands/skills.js +116 -0
  9. package/dist/commands/uninstall.js +11 -1
  10. package/dist/plugins.js +67 -3
  11. package/dist/utils/installer.js +20 -2
  12. package/package.json +4 -2
  13. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +22 -0
  14. package/plugins/devflow-ambient/.claude-plugin/plugin.json +4 -2
  15. package/plugins/devflow-ambient/README.md +8 -8
  16. package/plugins/devflow-ambient/commands/ambient.md +14 -14
  17. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +16 -9
  18. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +6 -2
  19. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  20. package/plugins/devflow-code-review/.claude-plugin/plugin.json +13 -6
  21. package/plugins/devflow-code-review/agents/reviewer.md +8 -0
  22. package/plugins/devflow-code-review/commands/code-review-teams.md +11 -1
  23. package/plugins/devflow-code-review/commands/code-review.md +12 -2
  24. package/plugins/devflow-code-review/skills/architecture-patterns/SKILL.md +1 -1
  25. package/plugins/devflow-code-review/skills/complexity-patterns/SKILL.md +1 -1
  26. package/plugins/devflow-code-review/skills/consistency-patterns/SKILL.md +1 -1
  27. package/plugins/devflow-code-review/skills/database-patterns/SKILL.md +1 -1
  28. package/plugins/devflow-code-review/skills/dependencies-patterns/SKILL.md +1 -1
  29. package/plugins/devflow-code-review/skills/documentation-patterns/SKILL.md +1 -1
  30. package/plugins/devflow-code-review/skills/performance-patterns/SKILL.md +1 -1
  31. package/plugins/devflow-code-review/skills/regression-patterns/SKILL.md +1 -1
  32. package/plugins/devflow-code-review/skills/review-methodology/SKILL.md +1 -1
  33. package/plugins/devflow-code-review/skills/security-patterns/SKILL.md +1 -1
  34. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +10 -7
  35. package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +5 -8
  36. package/plugins/devflow-debug/.claude-plugin/plugin.json +10 -3
  37. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +22 -0
  38. package/plugins/devflow-go/.claude-plugin/plugin.json +22 -0
  39. package/plugins/devflow-go/skills/go/SKILL.md +187 -0
  40. package/plugins/devflow-go/skills/go/references/concurrency.md +312 -0
  41. package/plugins/devflow-go/skills/go/references/detection.md +129 -0
  42. package/plugins/devflow-go/skills/go/references/patterns.md +232 -0
  43. package/plugins/devflow-go/skills/go/references/violations.md +205 -0
  44. package/plugins/devflow-implement/.claude-plugin/plugin.json +19 -5
  45. package/plugins/devflow-implement/agents/coder.md +11 -6
  46. package/plugins/devflow-implement/skills/self-review/SKILL.md +1 -1
  47. package/plugins/devflow-java/.claude-plugin/plugin.json +22 -0
  48. package/plugins/devflow-java/skills/java/SKILL.md +183 -0
  49. package/plugins/devflow-java/skills/java/references/detection.md +120 -0
  50. package/plugins/devflow-java/skills/java/references/modern-java.md +270 -0
  51. package/plugins/devflow-java/skills/java/references/patterns.md +235 -0
  52. package/plugins/devflow-java/skills/java/references/violations.md +213 -0
  53. package/plugins/devflow-python/.claude-plugin/plugin.json +22 -0
  54. package/plugins/devflow-python/skills/python/SKILL.md +188 -0
  55. package/plugins/devflow-python/skills/python/references/async.md +220 -0
  56. package/plugins/devflow-python/skills/python/references/detection.md +128 -0
  57. package/plugins/devflow-python/skills/python/references/patterns.md +226 -0
  58. package/plugins/devflow-python/skills/python/references/violations.md +204 -0
  59. package/plugins/devflow-react/.claude-plugin/plugin.json +22 -0
  60. package/plugins/{devflow-core-skills → devflow-react}/skills/react/SKILL.md +1 -1
  61. package/plugins/{devflow-core-skills → devflow-react}/skills/react/references/patterns.md +3 -3
  62. package/plugins/devflow-resolve/.claude-plugin/plugin.json +13 -3
  63. package/plugins/devflow-resolve/skills/security-patterns/SKILL.md +1 -1
  64. package/plugins/devflow-rust/.claude-plugin/plugin.json +22 -0
  65. package/plugins/devflow-rust/skills/rust/SKILL.md +193 -0
  66. package/plugins/devflow-rust/skills/rust/references/detection.md +131 -0
  67. package/plugins/devflow-rust/skills/rust/references/ownership.md +242 -0
  68. package/plugins/devflow-rust/skills/rust/references/patterns.md +210 -0
  69. package/plugins/devflow-rust/skills/rust/references/violations.md +191 -0
  70. package/plugins/devflow-self-review/.claude-plugin/plugin.json +10 -3
  71. package/plugins/devflow-self-review/skills/self-review/SKILL.md +1 -1
  72. package/plugins/devflow-specify/.claude-plugin/plugin.json +15 -4
  73. package/plugins/devflow-typescript/.claude-plugin/plugin.json +22 -0
  74. package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/patterns.md +3 -3
  75. package/scripts/hooks/{ambient-prompt.sh → ambient-prompt} +4 -4
  76. package/scripts/hooks/{background-memory-update.sh → background-memory-update} +3 -3
  77. package/scripts/hooks/{ensure-memory-gitignore.sh → ensure-memory-gitignore} +1 -1
  78. package/scripts/hooks/{pre-compact-memory.sh → pre-compact-memory} +2 -2
  79. package/scripts/hooks/run-hook +23 -0
  80. package/scripts/hooks/session-start-memory +151 -0
  81. package/scripts/hooks/{stop-update-memory.sh → stop-update-memory} +4 -4
  82. package/shared/agents/coder.md +11 -6
  83. package/shared/agents/reviewer.md +8 -0
  84. package/shared/skills/ambient-router/SKILL.md +16 -9
  85. package/shared/skills/ambient-router/references/skill-catalog.md +6 -2
  86. package/shared/skills/architecture-patterns/SKILL.md +1 -1
  87. package/shared/skills/complexity-patterns/SKILL.md +1 -1
  88. package/shared/skills/consistency-patterns/SKILL.md +1 -1
  89. package/shared/skills/database-patterns/SKILL.md +1 -1
  90. package/shared/skills/dependencies-patterns/SKILL.md +1 -1
  91. package/shared/skills/documentation-patterns/SKILL.md +1 -1
  92. package/shared/skills/go/SKILL.md +187 -0
  93. package/shared/skills/go/references/concurrency.md +312 -0
  94. package/shared/skills/go/references/detection.md +129 -0
  95. package/shared/skills/go/references/patterns.md +232 -0
  96. package/shared/skills/go/references/violations.md +205 -0
  97. package/shared/skills/java/SKILL.md +183 -0
  98. package/shared/skills/java/references/detection.md +120 -0
  99. package/shared/skills/java/references/modern-java.md +270 -0
  100. package/shared/skills/java/references/patterns.md +235 -0
  101. package/shared/skills/java/references/violations.md +213 -0
  102. package/shared/skills/performance-patterns/SKILL.md +1 -1
  103. package/shared/skills/python/SKILL.md +188 -0
  104. package/shared/skills/python/references/async.md +220 -0
  105. package/shared/skills/python/references/detection.md +128 -0
  106. package/shared/skills/python/references/patterns.md +226 -0
  107. package/shared/skills/python/references/violations.md +204 -0
  108. package/shared/skills/react/SKILL.md +1 -1
  109. package/shared/skills/react/references/patterns.md +3 -3
  110. package/shared/skills/regression-patterns/SKILL.md +1 -1
  111. package/shared/skills/review-methodology/SKILL.md +1 -1
  112. package/shared/skills/rust/SKILL.md +193 -0
  113. package/shared/skills/rust/references/detection.md +131 -0
  114. package/shared/skills/rust/references/ownership.md +242 -0
  115. package/shared/skills/rust/references/patterns.md +210 -0
  116. package/shared/skills/rust/references/violations.md +191 -0
  117. package/shared/skills/security-patterns/SKILL.md +1 -1
  118. package/shared/skills/self-review/SKILL.md +1 -1
  119. package/shared/skills/test-driven-development/SKILL.md +5 -8
  120. package/shared/skills/typescript/references/patterns.md +3 -3
  121. package/src/templates/settings.json +3 -3
  122. package/plugins/devflow-code-review/skills/react/SKILL.md +0 -276
  123. package/plugins/devflow-code-review/skills/react/references/patterns.md +0 -1331
  124. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +0 -229
  125. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +0 -171
  126. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +0 -670
  127. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +0 -419
  128. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +0 -254
  129. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +0 -184
  130. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +0 -511
  131. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +0 -453
  132. package/plugins/devflow-core-skills/skills/react/references/violations.md +0 -565
  133. package/plugins/devflow-implement/skills/accessibility/SKILL.md +0 -229
  134. package/plugins/devflow-implement/skills/accessibility/references/detection.md +0 -171
  135. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +0 -670
  136. package/plugins/devflow-implement/skills/accessibility/references/violations.md +0 -419
  137. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +0 -254
  138. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +0 -184
  139. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +0 -511
  140. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +0 -453
  141. package/scripts/hooks/session-start-memory.sh +0 -126
  142. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/SKILL.md +0 -0
  143. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/detection.md +0 -0
  144. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/patterns.md +0 -0
  145. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/violations.md +0 -0
  146. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/SKILL.md +0 -0
  147. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/detection.md +0 -0
  148. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/patterns.md +0 -0
  149. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/violations.md +0 -0
  150. /package/plugins/{devflow-code-review → devflow-react}/skills/react/references/violations.md +0 -0
  151. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/SKILL.md +0 -0
  152. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/violations.md +0 -0
@@ -0,0 +1,235 @@
1
+ # Extended Java Patterns
2
+
3
+ Correct patterns for Java development. Reference from main SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Builder Pattern (Type-Safe)
8
+
9
+ ```java
10
+ // Compile-time enforcement of required fields
11
+ public record EmailMessage(String to, String subject, String body, List<String> cc) {
12
+
13
+ public static Builder builder() { return new Builder(); }
14
+
15
+ public static class Builder {
16
+ private String to;
17
+ private String subject;
18
+ private String body;
19
+ private List<String> cc = List.of();
20
+
21
+ public Builder to(String to) { this.to = Objects.requireNonNull(to); return this; }
22
+ public Builder subject(String subject) { this.subject = Objects.requireNonNull(subject); return this; }
23
+ public Builder body(String body) { this.body = Objects.requireNonNull(body); return this; }
24
+ public Builder cc(List<String> cc) { this.cc = List.copyOf(cc); return this; }
25
+
26
+ public EmailMessage build() {
27
+ Objects.requireNonNull(to, "to is required");
28
+ Objects.requireNonNull(subject, "subject is required");
29
+ Objects.requireNonNull(body, "body is required");
30
+ return new EmailMessage(to, subject, body, cc);
31
+ }
32
+ }
33
+ }
34
+
35
+ // Usage
36
+ var email = EmailMessage.builder()
37
+ .to("user@example.com")
38
+ .subject("Welcome")
39
+ .body("Hello!")
40
+ .build();
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Strategy via Interfaces
46
+
47
+ ```java
48
+ // Define strategy as functional interface
49
+ @FunctionalInterface
50
+ public interface PricingStrategy {
51
+ Money calculatePrice(Order order);
52
+ }
53
+
54
+ // Implementations as lambdas or classes
55
+ PricingStrategy standard = order -> order.subtotal();
56
+ PricingStrategy discounted = order -> order.subtotal().multiply(0.9);
57
+ PricingStrategy tiered = order -> {
58
+ if (order.itemCount() > 10) return order.subtotal().multiply(0.8);
59
+ if (order.itemCount() > 5) return order.subtotal().multiply(0.9);
60
+ return order.subtotal();
61
+ };
62
+
63
+ // Inject strategy
64
+ public class OrderService {
65
+ private final PricingStrategy pricing;
66
+
67
+ public OrderService(PricingStrategy pricing) {
68
+ this.pricing = pricing;
69
+ }
70
+
71
+ public Money calculateTotal(Order order) {
72
+ return pricing.calculatePrice(order);
73
+ }
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Repository Pattern
80
+
81
+ ```java
82
+ public interface UserRepository {
83
+ Optional<User> findById(String id);
84
+ List<User> findByEmail(String email);
85
+ User save(User user);
86
+ void deleteById(String id);
87
+ boolean existsById(String id);
88
+ }
89
+
90
+ // Implementation with constructor injection
91
+ public class JpaUserRepository implements UserRepository {
92
+ private final EntityManager em;
93
+
94
+ public JpaUserRepository(EntityManager em) {
95
+ this.em = em;
96
+ }
97
+
98
+ @Override
99
+ public Optional<User> findById(String id) {
100
+ return Optional.ofNullable(em.find(User.class, id));
101
+ }
102
+
103
+ @Override
104
+ public User save(User user) {
105
+ return em.merge(user);
106
+ }
107
+ }
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Value Objects
113
+
114
+ ```java
115
+ // Immutable value object with validation
116
+ public record Money(BigDecimal amount, Currency currency) {
117
+ public Money {
118
+ Objects.requireNonNull(amount, "amount must not be null");
119
+ Objects.requireNonNull(currency, "currency must not be null");
120
+ if (amount.scale() > currency.getDefaultFractionDigits()) {
121
+ throw new IllegalArgumentException("Scale exceeds currency precision");
122
+ }
123
+ }
124
+
125
+ public Money add(Money other) {
126
+ requireSameCurrency(other);
127
+ return new Money(amount.add(other.amount), currency);
128
+ }
129
+
130
+ public Money multiply(double factor) {
131
+ return new Money(
132
+ amount.multiply(BigDecimal.valueOf(factor))
133
+ .setScale(currency.getDefaultFractionDigits(), RoundingMode.HALF_UP),
134
+ currency
135
+ );
136
+ }
137
+
138
+ private void requireSameCurrency(Money other) {
139
+ if (!currency.equals(other.currency)) {
140
+ throw new IllegalArgumentException(
141
+ "Cannot combine %s and %s".formatted(currency, other.currency)
142
+ );
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Event-Driven Pattern
151
+
152
+ ```java
153
+ // Domain event as sealed interface
154
+ public sealed interface OrderEvent permits OrderCreated, OrderShipped, OrderCancelled {
155
+ String orderId();
156
+ Instant occurredAt();
157
+ }
158
+
159
+ public record OrderCreated(String orderId, Instant occurredAt, List<LineItem> items)
160
+ implements OrderEvent {}
161
+
162
+ public record OrderShipped(String orderId, Instant occurredAt, String trackingNumber)
163
+ implements OrderEvent {}
164
+
165
+ public record OrderCancelled(String orderId, Instant occurredAt, String reason)
166
+ implements OrderEvent {}
167
+
168
+ // Event handler with exhaustive matching
169
+ public class OrderEventHandler {
170
+ public void handle(OrderEvent event) {
171
+ switch (event) {
172
+ case OrderCreated e -> notifyWarehouse(e.items());
173
+ case OrderShipped e -> sendTrackingEmail(e.trackingNumber());
174
+ case OrderCancelled e -> processRefund(e.orderId(), e.reason());
175
+ }
176
+ }
177
+ }
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Stream Pipelines
183
+
184
+ ```java
185
+ // Declarative collection processing
186
+ public List<String> getActiveUserEmails(List<User> users) {
187
+ return users.stream()
188
+ .filter(User::isActive)
189
+ .map(User::email)
190
+ .filter(email -> email.contains("@"))
191
+ .sorted()
192
+ .toList(); // Unmodifiable list (Java 16+)
193
+ }
194
+
195
+ // Grouping and aggregation
196
+ public Map<Department, Long> countByDepartment(List<Employee> employees) {
197
+ return employees.stream()
198
+ .collect(Collectors.groupingBy(Employee::department, Collectors.counting()));
199
+ }
200
+
201
+ // Reducing to summary
202
+ public record OrderSummary(int count, Money total) {}
203
+
204
+ public OrderSummary summarize(List<Order> orders) {
205
+ return orders.stream()
206
+ .reduce(
207
+ new OrderSummary(0, Money.ZERO),
208
+ (summary, order) -> new OrderSummary(
209
+ summary.count() + 1,
210
+ summary.total().add(order.total())
211
+ ),
212
+ (a, b) -> new OrderSummary(a.count() + b.count(), a.total().add(b.total()))
213
+ );
214
+ }
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Dependency Injection (Manual)
220
+
221
+ ```java
222
+ // Composition root wires everything together
223
+ public class Application {
224
+ public static void main(String[] args) {
225
+ var config = Config.load();
226
+ var dataSource = createDataSource(config);
227
+ var userRepo = new JpaUserRepository(dataSource);
228
+ var eventBus = new InMemoryEventBus();
229
+ var userService = new UserService(userRepo, eventBus);
230
+ var userController = new UserController(userService);
231
+
232
+ startServer(config.port(), userController);
233
+ }
234
+ }
235
+ ```
@@ -0,0 +1,213 @@
1
+ # Common Java Violations
2
+
3
+ Extended violation patterns for Java reviews. Reference from main SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Null Returns
8
+
9
+ ### Returning null Instead of Optional
10
+
11
+ ```java
12
+ // VIOLATION: Null return forces callers to null-check
13
+ public User findById(String id) {
14
+ return userMap.get(id); // Returns null if absent
15
+ }
16
+
17
+ // Callers must remember to check:
18
+ User user = findById(id);
19
+ user.getName(); // NullPointerException if not found
20
+ ```
21
+
22
+ ### Nullable Collections
23
+
24
+ ```java
25
+ // VIOLATION: Returning null instead of empty collection
26
+ public List<Order> getOrders(String userId) {
27
+ List<Order> orders = orderMap.get(userId);
28
+ return orders; // null if user has no orders
29
+ }
30
+
31
+ // Callers iterate without checking:
32
+ for (Order o : getOrders(userId)) { // NullPointerException
33
+ process(o);
34
+ }
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Raw Types
40
+
41
+ ### Unparameterized Generics
42
+
43
+ ```java
44
+ // VIOLATION: Raw List - no type safety
45
+ List users = new ArrayList();
46
+ users.add("not a user"); // No compile error
47
+ users.add(42); // No compile error
48
+ User first = (User) users.get(0); // ClassCastException at runtime
49
+
50
+ // VIOLATION: Raw Map
51
+ Map cache = new HashMap();
52
+ cache.put(123, "value");
53
+ String val = (String) cache.get(123); // Unsafe cast
54
+ ```
55
+
56
+ ### Raw Type in Method Signatures
57
+
58
+ ```java
59
+ // VIOLATION: Raw Comparable
60
+ public class Price implements Comparable {
61
+ public int compareTo(Object other) {
62
+ return Double.compare(this.amount, ((Price) other).amount); // Unsafe cast
63
+ }
64
+ }
65
+
66
+ // VIOLATION: Raw Iterator
67
+ Iterator it = collection.iterator();
68
+ while (it.hasNext()) {
69
+ String s = (String) it.next(); // Unsafe cast
70
+ }
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Checked Exception Abuse
76
+
77
+ ### Broad Throws Declarations
78
+
79
+ ```java
80
+ // VIOLATION: throws Exception - hides what can actually go wrong
81
+ public User createUser(String name) throws Exception {
82
+ // Callers must catch Exception, can't handle specific failures
83
+ }
84
+
85
+ // VIOLATION: Wrapping everything in checked exceptions
86
+ public void process(String data) throws ProcessingException {
87
+ try {
88
+ Integer.parseInt(data);
89
+ } catch (NumberFormatException e) {
90
+ throw new ProcessingException("Failed", e); // Unnecessary wrapping
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### Swallowed Exceptions
96
+
97
+ ```java
98
+ // VIOLATION: Empty catch block
99
+ try {
100
+ connection.close();
101
+ } catch (SQLException e) {
102
+ // silently ignored - resource leak hidden
103
+ }
104
+
105
+ // VIOLATION: Catching and logging only
106
+ try {
107
+ processPayment(order);
108
+ } catch (PaymentException e) {
109
+ logger.error("Payment failed", e);
110
+ // Continues as if nothing happened - order in inconsistent state
111
+ }
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Mutable Data Objects
117
+
118
+ ### JavaBean-Style Mutability
119
+
120
+ ```java
121
+ // VIOLATION: Mutable DTO with setters
122
+ public class UserDTO {
123
+ private String name;
124
+ private String email;
125
+
126
+ public void setName(String name) { this.name = name; }
127
+ public void setEmail(String email) { this.email = email; }
128
+ public String getName() { return name; }
129
+ public String getEmail() { return email; }
130
+ }
131
+
132
+ // Anyone can modify at any time:
133
+ dto.setName("changed"); // No control over when/where mutation happens
134
+ ```
135
+
136
+ ### Exposing Internal Mutable State
137
+
138
+ ```java
139
+ // VIOLATION: Getter returns mutable internal list
140
+ public class Team {
141
+ private List<String> members = new ArrayList<>();
142
+
143
+ public List<String> getMembers() {
144
+ return members; // Caller can modify internal state
145
+ }
146
+ }
147
+
148
+ // External code breaks encapsulation:
149
+ team.getMembers().clear(); // Empties the team's internal list
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Deep Inheritance
155
+
156
+ ### Fragile Base Class
157
+
158
+ ```java
159
+ // VIOLATION: Deep hierarchy creates tight coupling
160
+ public abstract class AbstractEntity { ... }
161
+ public abstract class AbstractAuditableEntity extends AbstractEntity { ... }
162
+ public abstract class AbstractVersionedEntity extends AbstractAuditableEntity { ... }
163
+ public class User extends AbstractVersionedEntity { ... }
164
+
165
+ // Changing any base class ripples through all descendants
166
+ // Testing requires understanding 4 levels of behavior
167
+ ```
168
+
169
+ ### Inheritance for Code Reuse
170
+
171
+ ```java
172
+ // VIOLATION: Extending just to reuse utility methods
173
+ public class OrderService extends BaseService {
174
+ // Only extends BaseService to get logAndAudit() method
175
+ public void processOrder(Order order) {
176
+ logAndAudit("processing", order.getId()); // Inherited utility
177
+ }
178
+ }
179
+ // Should be: inject a LogAuditService instead
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Concurrency Violations
185
+
186
+ ### Shared Mutable State Without Synchronization
187
+
188
+ ```java
189
+ // VIOLATION: HashMap accessed from multiple threads
190
+ private Map<String, Session> sessions = new HashMap<>();
191
+
192
+ public void addSession(String id, Session s) {
193
+ sessions.put(id, s); // Not thread-safe
194
+ }
195
+ ```
196
+
197
+ ### Double-Checked Locking Done Wrong
198
+
199
+ ```java
200
+ // VIOLATION: Missing volatile on lazily-initialized field
201
+ private ExpensiveObject instance;
202
+
203
+ public ExpensiveObject getInstance() {
204
+ if (instance == null) {
205
+ synchronized (this) {
206
+ if (instance == null) {
207
+ instance = new ExpensiveObject(); // Partially constructed object visible
208
+ }
209
+ }
210
+ }
211
+ return instance;
212
+ }
213
+ ```
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "devflow-python",
3
+ "description": "Python language patterns - type hints, protocols, dataclasses, async programming",
4
+ "author": {
5
+ "name": "DevFlow Contributors",
6
+ "email": "dean@keren.dev"
7
+ },
8
+ "version": "1.3.0",
9
+ "homepage": "https://github.com/dean0x/devflow",
10
+ "repository": "https://github.com/dean0x/devflow",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "python",
14
+ "type-hints",
15
+ "dataclasses",
16
+ "async"
17
+ ],
18
+ "agents": [],
19
+ "skills": [
20
+ "python"
21
+ ]
22
+ }
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: python
3
+ description: This skill should be used when the user works with Python files (.py), asks about "type hints", "protocols", "dataclasses", "async/await", "decorators", or discusses Pythonic patterns and data modeling. Provides patterns for type safety, error handling, data modeling, and async programming.
4
+ user-invocable: false
5
+ allowed-tools: Read, Grep, Glob
6
+ activation:
7
+ file-patterns:
8
+ - "**/*.py"
9
+ exclude:
10
+ - "venv/**"
11
+ - ".venv/**"
12
+ - "**/__pycache__/**"
13
+ ---
14
+
15
+ # Python Patterns
16
+
17
+ Reference for Python-specific patterns, type safety, and idioms.
18
+
19
+ ## Iron Law
20
+
21
+ > **EXPLICIT IS BETTER THAN IMPLICIT**
22
+ >
23
+ > Type-hint every function signature. Name every exception. Use dataclasses over raw dicts.
24
+ > Python's flexibility is a strength only when boundaries are explicit. Implicit behavior
25
+ > causes debugging nightmares and makes codebases hostile to newcomers.
26
+
27
+ ## When This Skill Activates
28
+
29
+ - Working with Python codebases
30
+ - Designing typed APIs with type hints
31
+ - Modeling data with dataclasses or Pydantic
32
+ - Implementing async code
33
+ - Structuring Python packages
34
+
35
+ ---
36
+
37
+ ## Type Safety
38
+
39
+ ### Type Hint Everything
40
+
41
+ ```python
42
+ # BAD: def process(data, config): ...
43
+ # GOOD:
44
+ def process(data: list[dict[str, Any]], config: AppConfig) -> ProcessResult:
45
+ ...
46
+ ```
47
+
48
+ ### Use Protocols for Structural Typing
49
+
50
+ ```python
51
+ from typing import Protocol
52
+
53
+ class Repository(Protocol):
54
+ def find_by_id(self, id: str) -> User | None: ...
55
+ def save(self, entity: User) -> User: ...
56
+
57
+ # Any class with these methods satisfies Repository — no inheritance needed
58
+ ```
59
+
60
+ ### Strict Optional Handling
61
+
62
+ ```python
63
+ # BAD: def get_name(user): return user.name
64
+ # GOOD:
65
+ def get_name(user: User | None) -> str:
66
+ if user is None:
67
+ return "Anonymous"
68
+ return user.name
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Error Handling
74
+
75
+ ### Custom Exception Hierarchies
76
+
77
+ ```python
78
+ class AppError(Exception):
79
+ """Base application error."""
80
+
81
+ class NotFoundError(AppError):
82
+ def __init__(self, entity: str, id: str) -> None:
83
+ super().__init__(f"{entity} {id} not found")
84
+ self.entity = entity
85
+ self.id = id
86
+
87
+ class ValidationError(AppError):
88
+ def __init__(self, field: str, message: str) -> None:
89
+ super().__init__(f"Validation failed for {field}: {message}")
90
+ ```
91
+
92
+ ### Context Managers for Resources
93
+
94
+ ```python
95
+ from contextlib import contextmanager
96
+
97
+ @contextmanager
98
+ def database_transaction(conn: Connection):
99
+ try:
100
+ yield conn
101
+ conn.commit()
102
+ except Exception:
103
+ conn.rollback()
104
+ raise
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Data Modeling
110
+
111
+ ### Dataclasses Over Raw Dicts
112
+
113
+ ```python
114
+ # BAD: user = {"name": "Alice", "email": "alice@example.com"}
115
+ # GOOD:
116
+ @dataclass(frozen=True)
117
+ class User:
118
+ name: str
119
+ email: str
120
+ created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
121
+ ```
122
+
123
+ ### Pydantic for Validation at Boundaries
124
+
125
+ ```python
126
+ from pydantic import BaseModel, EmailStr
127
+
128
+ class CreateUserRequest(BaseModel):
129
+ name: str
130
+ email: EmailStr
131
+ age: int = Field(ge=0, le=150)
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Pythonic Patterns
137
+
138
+ ```python
139
+ # Comprehensions over loops for transforms
140
+ names = [user.name for user in users if user.active]
141
+
142
+ # Enumerate over manual index tracking
143
+ for i, item in enumerate(items):
144
+ process(i, item)
145
+
146
+ # EAFP: Easier to Ask Forgiveness than Permission
147
+ try:
148
+ value = mapping[key]
149
+ except KeyError:
150
+ value = default
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Anti-Patterns
156
+
157
+ | Pattern | Bad | Good |
158
+ |---------|-----|------|
159
+ | Bare except | `except:` | `except (ValueError, KeyError):` |
160
+ | Mutable default | `def fn(items=[])` | `def fn(items: list | None = None)` |
161
+ | No type hints | `def process(data)` | `def process(data: DataFrame) -> Result` |
162
+ | String typing | `x: "MyClass"` (without reason) | `from __future__ import annotations` |
163
+ | God class | `class App` with 50 methods | Compose smaller focused classes |
164
+
165
+ ---
166
+
167
+ ## Extended References
168
+
169
+ For additional patterns and examples:
170
+ - `references/violations.md` - Common Python violations
171
+ - `references/patterns.md` - Extended Python patterns
172
+ - `references/detection.md` - Detection patterns for Python issues
173
+ - `references/async.md` - Async Python patterns
174
+
175
+ ---
176
+
177
+ ## Checklist
178
+
179
+ - [ ] All functions have type hints (params + return)
180
+ - [ ] Custom exceptions with meaningful messages
181
+ - [ ] Dataclasses or Pydantic for structured data
182
+ - [ ] No bare `except:` clauses
183
+ - [ ] No mutable default arguments
184
+ - [ ] Context managers for resource management
185
+ - [ ] `from __future__ import annotations` for forward refs
186
+ - [ ] Protocols for structural typing (not ABC unless needed)
187
+ - [ ] Comprehensions for simple transforms
188
+ - [ ] Tests use pytest with fixtures