@jarrodmedrano/claude-skills 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/bevy/SKILL.md +406 -0
- package/.claude/skills/bevy/references/bevy_specific_tips.md +385 -0
- package/.claude/skills/bevy/references/common_pitfalls.md +217 -0
- package/.claude/skills/bevy/references/ecs_patterns.md +277 -0
- package/.claude/skills/bevy/references/project_structure.md +116 -0
- package/.claude/skills/bevy/references/ui_development.md +147 -0
- package/.claude/skills/domain-driven-design/SKILL.md +459 -0
- package/.claude/skills/domain-driven-design/references/ddd_foundations_and_patterns.md +664 -0
- package/.claude/skills/domain-driven-design/references/rich_hickey_principles.md +406 -0
- package/.claude/skills/domain-driven-design/references/visualization_examples.md +790 -0
- package/.claude/skills/domain-driven-design/references/wlaschin_patterns.md +639 -0
- package/.claude/skills/godot/SKILL.md +728 -0
- package/.claude/skills/godot/assets/templates/attribute_template.gd +109 -0
- package/.claude/skills/godot/assets/templates/component_template.gd +76 -0
- package/.claude/skills/godot/assets/templates/interaction_template.gd +108 -0
- package/.claude/skills/godot/assets/templates/item_resource.tres +11 -0
- package/.claude/skills/godot/assets/templates/spell_resource.tres +20 -0
- package/.claude/skills/godot/references/architecture-patterns.md +608 -0
- package/.claude/skills/godot/references/common-pitfalls.md +518 -0
- package/.claude/skills/godot/references/file-formats.md +491 -0
- package/.claude/skills/godot/references/godot4-physics-api.md +302 -0
- package/.claude/skills/godot/scripts/validate_tres.py +145 -0
- package/.claude/skills/godot/scripts/validate_tscn.py +170 -0
- package/.claude/skills/react-three-fiber/SKILL.md +2055 -0
- package/.claude/skills/react-three-fiber/scripts/build-scene.ts +171 -0
- package/package.json +1 -1
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# Rich Hickey's Design Principles
|
|
2
|
+
|
|
3
|
+
This reference compiles core concepts from Rich Hickey's talks and writings on software design, with focus on simplicity, data-orientation, and decomplecting.
|
|
4
|
+
|
|
5
|
+
## Simple Made Easy
|
|
6
|
+
|
|
7
|
+
**Talk:** "Simple Made Easy" (Strange Loop 2011)
|
|
8
|
+
|
|
9
|
+
### Definitions
|
|
10
|
+
|
|
11
|
+
**Simple** (opposite: Complex)
|
|
12
|
+
- From "simplex" - one fold/braid
|
|
13
|
+
- Objective measure: few interleaved concepts
|
|
14
|
+
- About lack of interleaving, not cardinality
|
|
15
|
+
- Can have many simple things (like individual strands)
|
|
16
|
+
|
|
17
|
+
**Easy** (opposite: Hard)
|
|
18
|
+
- Near at hand, familiar, within capability
|
|
19
|
+
- Subjective: varies by person, time, and context
|
|
20
|
+
- About convenience and familiarity, not inherent quality
|
|
21
|
+
|
|
22
|
+
### Key Insight: Simple != Easy
|
|
23
|
+
|
|
24
|
+
Making something familiar (easy) doesn't make it simple. Choosing familiar constructs that are complex makes systems harder to understand and change over time.
|
|
25
|
+
|
|
26
|
+
**Trade-off:** Simple may be unfamiliar (initially harder), but pays dividends in comprehension and maintainability.
|
|
27
|
+
|
|
28
|
+
### Complecting (Interleaving/Braiding)
|
|
29
|
+
|
|
30
|
+
Complecting is the act of entwining/braiding things together. Once complected:
|
|
31
|
+
- Cannot reason about parts independently
|
|
32
|
+
- Cannot change one without affecting others
|
|
33
|
+
- Cannot reuse parts separately
|
|
34
|
+
- Difficult to understand cause and effect
|
|
35
|
+
|
|
36
|
+
**Examples of Complecting:**
|
|
37
|
+
- State and identity complected in mutable objects
|
|
38
|
+
- Value and time complected in variables
|
|
39
|
+
- Syntax and semantics in many languages
|
|
40
|
+
- Policy and mechanism in frameworks
|
|
41
|
+
|
|
42
|
+
### Simple vs Complex Constructs
|
|
43
|
+
|
|
44
|
+
| Simple | Complex |
|
|
45
|
+
|--------|---------|
|
|
46
|
+
| Values | State, Objects |
|
|
47
|
+
| Functions | Methods (tied to class) |
|
|
48
|
+
| Namespaces | Hierarchical namespaces |
|
|
49
|
+
| Data | Objects with behavior |
|
|
50
|
+
| Declarative data | Imperative code |
|
|
51
|
+
| Rules | Conditional logic |
|
|
52
|
+
| Consistency | Eventual consistency |
|
|
53
|
+
| Queues | Actors (complect what and how) |
|
|
54
|
+
|
|
55
|
+
### Making Things Simple
|
|
56
|
+
|
|
57
|
+
**Strategies:**
|
|
58
|
+
1. **Choose simple constructs** - Prefer inherently simple building blocks
|
|
59
|
+
2. **Design by subtraction** - Remove, don't add
|
|
60
|
+
3. **Separate concerns** - Identify what is truly independent
|
|
61
|
+
4. **Use abstraction wisely** - Draw boundaries at natural seams
|
|
62
|
+
|
|
63
|
+
**Questions to Ask:**
|
|
64
|
+
- What is complected here?
|
|
65
|
+
- Can these concerns exist independently?
|
|
66
|
+
- Am I braiding together things that could be separate?
|
|
67
|
+
- Will I be able to change this later?
|
|
68
|
+
|
|
69
|
+
## The Value of Values
|
|
70
|
+
|
|
71
|
+
**Talk:** "The Value of Values" (JaxConf 2012)
|
|
72
|
+
|
|
73
|
+
### What is a Value?
|
|
74
|
+
|
|
75
|
+
A value is an immutable magnitude, quantity, or number:
|
|
76
|
+
- The number 42
|
|
77
|
+
- The string "hello"
|
|
78
|
+
- The date 2024-01-15
|
|
79
|
+
- A tuple/record of values
|
|
80
|
+
|
|
81
|
+
**Crucially:** Values don't change. "Changing a value" is nonsense (like "changing the number 42").
|
|
82
|
+
|
|
83
|
+
### Properties of Values
|
|
84
|
+
|
|
85
|
+
**Immutable**
|
|
86
|
+
- Never change, ever
|
|
87
|
+
- No notion of time built in
|
|
88
|
+
- Can be freely shared without concern
|
|
89
|
+
|
|
90
|
+
**Semantically Transparent**
|
|
91
|
+
- Same value everywhere, always
|
|
92
|
+
- No hidden context or identity
|
|
93
|
+
- Can be compared for equality directly
|
|
94
|
+
|
|
95
|
+
**Language Independent**
|
|
96
|
+
- 42 is 42 in any language
|
|
97
|
+
- Can be transmitted, stored, compared across boundaries
|
|
98
|
+
|
|
99
|
+
### Values Enable Local Reasoning
|
|
100
|
+
|
|
101
|
+
Because values don't change:
|
|
102
|
+
- Can reason about code by substitution
|
|
103
|
+
- No spooky action at a distance
|
|
104
|
+
- No defensive copying needed
|
|
105
|
+
- Equality is simple and meaningful
|
|
106
|
+
|
|
107
|
+
### Facts are Values
|
|
108
|
+
|
|
109
|
+
In domain modeling, facts about the world are values:
|
|
110
|
+
- "Order #123 was placed on 2024-01-15"
|
|
111
|
+
- "User's email is user@example.com as of yesterday"
|
|
112
|
+
- "The price was $42.00 when we recorded it"
|
|
113
|
+
|
|
114
|
+
**Key Insight:** Facts don't change. New facts may supersede old facts, but old facts remain true about the past.
|
|
115
|
+
|
|
116
|
+
### Identity vs State
|
|
117
|
+
|
|
118
|
+
**Identity**
|
|
119
|
+
- A stable logical entity (e.g., "User #42")
|
|
120
|
+
- Persists through time
|
|
121
|
+
|
|
122
|
+
**State**
|
|
123
|
+
- Value of an identity at a point in time
|
|
124
|
+
- "User #42's email address was X on Monday"
|
|
125
|
+
|
|
126
|
+
**Traditional OOP Problem:** Conflates identity and state in mutable objects. Changing state loses history; can't compare past and present.
|
|
127
|
+
|
|
128
|
+
**Value-Based Approach:**
|
|
129
|
+
- Identity: stable reference
|
|
130
|
+
- State: succession of immutable values over time
|
|
131
|
+
- Can compare any two states
|
|
132
|
+
- Can maintain history naturally
|
|
133
|
+
|
|
134
|
+
### Memory is Not a Place
|
|
135
|
+
|
|
136
|
+
Traditional view: Memory is a place where values live and get changed.
|
|
137
|
+
|
|
138
|
+
Value-oriented view: Memory is a storage mechanism for values. "Updating" means associating a new value with a name; old value unchanged.
|
|
139
|
+
|
|
140
|
+
**Benefits:**
|
|
141
|
+
- Retain history
|
|
142
|
+
- Compare snapshots
|
|
143
|
+
- Simpler concurrency (values never change)
|
|
144
|
+
- Undo/redo naturally
|
|
145
|
+
|
|
146
|
+
### Applying Values to Domain Modeling
|
|
147
|
+
|
|
148
|
+
**Model facts, not objects:**
|
|
149
|
+
- Don't: `user.setEmail("new@example.com")` (destroys history)
|
|
150
|
+
- Do: `events.append({type: "EmailChanged", userId: 42, newEmail: "new@example.com", timestamp: now})`
|
|
151
|
+
|
|
152
|
+
**Use persistent data structures:**
|
|
153
|
+
- Immutable collections that share structure
|
|
154
|
+
- Efficient "updates" that create new versions
|
|
155
|
+
- All versions remain accessible
|
|
156
|
+
|
|
157
|
+
**Separate identity from state:**
|
|
158
|
+
- Identity: stable reference (ID, key)
|
|
159
|
+
- State: series of immutable values
|
|
160
|
+
- Functions: transformations from state to state
|
|
161
|
+
|
|
162
|
+
## Decomplecting
|
|
163
|
+
|
|
164
|
+
### Separating Concerns
|
|
165
|
+
|
|
166
|
+
**Not just "separation of concerns" but identifying what CAN be separated:**
|
|
167
|
+
|
|
168
|
+
Real separation requires:
|
|
169
|
+
1. Components have clear, independent purpose
|
|
170
|
+
2. Components can be understood in isolation
|
|
171
|
+
3. Components can be changed without affecting others
|
|
172
|
+
4. Components can be reused in different contexts
|
|
173
|
+
|
|
174
|
+
### Common Complections to Separate
|
|
175
|
+
|
|
176
|
+
**Value and Time**
|
|
177
|
+
- Complected: Mutable variables (value changes over time)
|
|
178
|
+
- Separated: Immutable values + explicit time/version
|
|
179
|
+
|
|
180
|
+
**What and How**
|
|
181
|
+
- Complected: Imperative code (what you want mixed with how to get it)
|
|
182
|
+
- Separated: Declarative specification + separate execution strategy
|
|
183
|
+
|
|
184
|
+
**What and When**
|
|
185
|
+
- Complected: Synchronous calls (what to do tied to when it happens)
|
|
186
|
+
- Separated: Queues, streams (what is independent of when)
|
|
187
|
+
|
|
188
|
+
**What and Who**
|
|
189
|
+
- Complected: Methods (what you can do tied to who you are / what class)
|
|
190
|
+
- Separated: Functions (what you can do independent of caller)
|
|
191
|
+
|
|
192
|
+
**Mechanism and Policy**
|
|
193
|
+
- Complected: Frameworks that dictate both structure and behavior
|
|
194
|
+
- Separated: Libraries/functions (mechanism) + application code (policy)
|
|
195
|
+
|
|
196
|
+
**Domain and Infrastructure**
|
|
197
|
+
- Complected: Business logic mixed with DB access, HTTP, etc.
|
|
198
|
+
- Separated: Pure domain functions + separate persistence/transport layer
|
|
199
|
+
|
|
200
|
+
### Process for Decomplecting
|
|
201
|
+
|
|
202
|
+
1. **Identify the Complection**
|
|
203
|
+
- What seems unnecessarily tangled?
|
|
204
|
+
- What can't I change independently?
|
|
205
|
+
|
|
206
|
+
2. **Find the Seams**
|
|
207
|
+
- Where do concerns actually divide?
|
|
208
|
+
- What's essential vs. incidental?
|
|
209
|
+
|
|
210
|
+
3. **Factor Apart**
|
|
211
|
+
- Create separate constructs for separate concerns
|
|
212
|
+
- Use composition to recombine when needed
|
|
213
|
+
|
|
214
|
+
4. **Validate Independence**
|
|
215
|
+
- Can each part be understood alone?
|
|
216
|
+
- Can each part be tested alone?
|
|
217
|
+
- Can each part be reused elsewhere?
|
|
218
|
+
|
|
219
|
+
## Data Orientation
|
|
220
|
+
|
|
221
|
+
**Talks:** "The Language of the System" (Clojure/conj 2012), "Spec-ulation" (Clojure/conj 2016)
|
|
222
|
+
|
|
223
|
+
### Data > Objects
|
|
224
|
+
|
|
225
|
+
**Objects:**
|
|
226
|
+
- Complect data, behavior, and identity
|
|
227
|
+
- Hide information behind APIs
|
|
228
|
+
- Create proprietary representations
|
|
229
|
+
- Require learning specific APIs
|
|
230
|
+
|
|
231
|
+
**Data:**
|
|
232
|
+
- Open, inspectable, generic
|
|
233
|
+
- Can use common tools (map, filter, reduce)
|
|
234
|
+
- Self-describing
|
|
235
|
+
- Easier to transmit, store, and reason about
|
|
236
|
+
|
|
237
|
+
### Generic Data Structures
|
|
238
|
+
|
|
239
|
+
Prefer generic collections (maps, vectors, sets) over custom classes when:
|
|
240
|
+
- Data is primarily informational (facts, records, events)
|
|
241
|
+
- Behavior is not identity-specific
|
|
242
|
+
- Multiple systems/components will interact with the data
|
|
243
|
+
|
|
244
|
+
**Benefits:**
|
|
245
|
+
- Unified tools and functions work across all data
|
|
246
|
+
- Easy to extend with new fields
|
|
247
|
+
- Easy to serialize and transmit
|
|
248
|
+
- Easy to inspect and debug
|
|
249
|
+
|
|
250
|
+
### Information vs. Mechanism
|
|
251
|
+
|
|
252
|
+
**Information:**
|
|
253
|
+
- Facts about the domain
|
|
254
|
+
- Should be data
|
|
255
|
+
- Open and accessible
|
|
256
|
+
|
|
257
|
+
**Mechanism:**
|
|
258
|
+
- How things are computed or achieved
|
|
259
|
+
- Can be functions/code
|
|
260
|
+
- Encapsulated implementation details
|
|
261
|
+
|
|
262
|
+
**Anti-pattern:** Hiding domain information behind abstraction barriers.
|
|
263
|
+
|
|
264
|
+
### Systems are Data Flows
|
|
265
|
+
|
|
266
|
+
Model systems as data flowing through transformations:
|
|
267
|
+
1. Receive data (events, requests)
|
|
268
|
+
2. Transform data (functions)
|
|
269
|
+
3. Produce data (responses, events, state changes)
|
|
270
|
+
|
|
271
|
+
Each stage: data in → function → data out.
|
|
272
|
+
|
|
273
|
+
**Benefits:**
|
|
274
|
+
- Easy to test (data in, data out)
|
|
275
|
+
- Easy to compose (output of one = input of another)
|
|
276
|
+
- Easy to reason about (trace data flow)
|
|
277
|
+
- Easy to parallelize (data is immutable)
|
|
278
|
+
|
|
279
|
+
## Language of the System
|
|
280
|
+
|
|
281
|
+
**Talk:** "The Language of the System" (Clojure/conj 2012)
|
|
282
|
+
|
|
283
|
+
### Systems Communicate with Data
|
|
284
|
+
|
|
285
|
+
When components/services communicate, they exchange data. The format and semantics of that data IS the interface.
|
|
286
|
+
|
|
287
|
+
**Don't:**
|
|
288
|
+
- Send proprietary objects
|
|
289
|
+
- Rely on shared class definitions
|
|
290
|
+
- Use binary formats without schema
|
|
291
|
+
|
|
292
|
+
**Do:**
|
|
293
|
+
- Send data (maps, records)
|
|
294
|
+
- Use self-describing formats (JSON, EDN, Transit)
|
|
295
|
+
- Version schemas explicitly
|
|
296
|
+
|
|
297
|
+
### Accretion, Not Breaking Changes
|
|
298
|
+
|
|
299
|
+
**Growth Strategies:**
|
|
300
|
+
|
|
301
|
+
**Accretion (Good):**
|
|
302
|
+
- Add new fields (optional)
|
|
303
|
+
- Add new types/variants
|
|
304
|
+
- Extend enums with new cases
|
|
305
|
+
- Provide additional operations
|
|
306
|
+
|
|
307
|
+
**Breaking Changes (Bad):**
|
|
308
|
+
- Remove fields
|
|
309
|
+
- Rename fields
|
|
310
|
+
- Change types
|
|
311
|
+
- Remove operations
|
|
312
|
+
|
|
313
|
+
**Requiring (Neutral):**
|
|
314
|
+
- Make optional things required
|
|
315
|
+
- Add constraints
|
|
316
|
+
- Acceptable if versioned
|
|
317
|
+
|
|
318
|
+
### Versioning
|
|
319
|
+
|
|
320
|
+
When breaking changes are necessary:
|
|
321
|
+
- Create a new version (v2, v3)
|
|
322
|
+
- Support both old and new simultaneously
|
|
323
|
+
- Allow consumers to migrate at their pace
|
|
324
|
+
- Eventually deprecate old versions
|
|
325
|
+
|
|
326
|
+
**Never:** Change meaning of existing version.
|
|
327
|
+
|
|
328
|
+
## Applying to Domain Modeling
|
|
329
|
+
|
|
330
|
+
### Modeling Domain Data
|
|
331
|
+
|
|
332
|
+
**Prefer:**
|
|
333
|
+
- Plain data structures for domain entities
|
|
334
|
+
- Immutable records for domain facts
|
|
335
|
+
- Generic collections over custom containers
|
|
336
|
+
- Functions that transform domain data
|
|
337
|
+
|
|
338
|
+
**Avoid:**
|
|
339
|
+
- Mutable domain objects
|
|
340
|
+
- Behavior attached to entities
|
|
341
|
+
- Getters/setters (ceremony without benefit)
|
|
342
|
+
- Hidden state
|
|
343
|
+
|
|
344
|
+
### Example: Order Domain
|
|
345
|
+
|
|
346
|
+
**Complex (Complected):**
|
|
347
|
+
```typescript
|
|
348
|
+
class Order {
|
|
349
|
+
private lines: OrderLine[] = [];
|
|
350
|
+
private status: Status = Status.Draft;
|
|
351
|
+
|
|
352
|
+
addLine(product: Product, qty: number) {
|
|
353
|
+
this.lines.push(new OrderLine(product, qty));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
submit() {
|
|
357
|
+
if (this.lines.length === 0) throw new Error("Empty order");
|
|
358
|
+
this.status = Status.Submitted;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Simple (Decomplected):**
|
|
364
|
+
```typescript
|
|
365
|
+
type Order = {
|
|
366
|
+
id: OrderId;
|
|
367
|
+
customerId: CustomerId;
|
|
368
|
+
lines: readonly OrderLine[];
|
|
369
|
+
status: OrderStatus;
|
|
370
|
+
createdAt: Timestamp;
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
function addLine(order: Order, line: OrderLine): Order {
|
|
374
|
+
return { ...order, lines: [...order.lines, line] };
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function submitOrder(order: Order): Result<Order, ValidationError> {
|
|
378
|
+
if (order.lines.length === 0) {
|
|
379
|
+
return Err({ type: "EmptyOrder" });
|
|
380
|
+
}
|
|
381
|
+
return Ok({ ...order, status: { type: "Submitted", submittedAt: now() } });
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Why simpler:**
|
|
386
|
+
- Data and functions separate
|
|
387
|
+
- Immutable values
|
|
388
|
+
- Explicit about time (createdAt, submittedAt)
|
|
389
|
+
- No hidden state
|
|
390
|
+
- Easy to test, inspect, transmit
|
|
391
|
+
|
|
392
|
+
## Key Takeaways
|
|
393
|
+
|
|
394
|
+
1. **Simplicity is objective** - Measured by lack of interleaving, not familiarity
|
|
395
|
+
2. **Values don't change** - Model facts as immutable values; identity is separate
|
|
396
|
+
3. **Data is better than objects** - Generic, open data beats proprietary encapsulation
|
|
397
|
+
4. **Separate concerns rigorously** - Identify what can truly be independent
|
|
398
|
+
5. **Accrete, don't break** - Grow systems by adding, not changing
|
|
399
|
+
6. **Systems are data flows** - Model as transformations of immutable data
|
|
400
|
+
|
|
401
|
+
When domain modeling, constantly ask:
|
|
402
|
+
- What have I complected here?
|
|
403
|
+
- Can I use values instead of mutable state?
|
|
404
|
+
- Can I use data instead of objects?
|
|
405
|
+
- What can be separated?
|
|
406
|
+
- Am I making a breaking change, or accreting?
|