@sylphx/flow 1.4.6 → 1.4.7
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/CHANGELOG.md +28 -0
- package/assets/agents/coder.md +91 -98
- package/assets/agents/orchestrator.md +73 -339
- package/assets/agents/reviewer.md +68 -101
- package/assets/agents/writer.md +80 -272
- package/assets/output-styles/silent.md +8 -4
- package/assets/rules/code-standards.md +78 -137
- package/assets/rules/core.md +57 -25
- package/assets/rules/workspace.md +485 -0
- package/assets/slash-commands/cleanup.md +60 -0
- package/assets/slash-commands/improve.md +154 -0
- package/assets/slash-commands/polish.md +88 -0
- package/assets/slash-commands/quality.md +182 -0
- package/assets/slash-commands/release.md +104 -0
- package/package.json +1 -1
- package/src/commands/init-core.ts +0 -10
- package/src/core/installers/file-installer.ts +0 -27
- package/src/utils/sync-utils.ts +3 -16
- package/assets/slash-commands/commit.md +0 -23
- package/assets/slash-commands/context.md +0 -112
- package/assets/slash-commands/explain.md +0 -35
- package/assets/slash-commands/review.md +0 -39
- package/assets/slash-commands/test.md +0 -30
|
@@ -35,47 +35,33 @@ description: Shared coding standards for Coder and Reviewer agents
|
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
**File size limits**:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- If larger → split by feature or responsibility
|
|
38
|
+
Component <250 lines, Module <300 lines.
|
|
39
|
+
Larger → split by feature or responsibility.
|
|
41
40
|
|
|
42
41
|
---
|
|
43
42
|
|
|
44
43
|
## Programming Patterns
|
|
45
44
|
|
|
46
|
-
**
|
|
45
|
+
**3+ params → named args**:
|
|
47
46
|
```typescript
|
|
48
|
-
|
|
49
|
-
updateUser(
|
|
50
|
-
|
|
51
|
-
// ❌ Positional
|
|
52
|
-
updateUser(id, email, role)
|
|
47
|
+
✅ updateUser({ id, email, role })
|
|
48
|
+
❌ updateUser(id, email, role)
|
|
53
49
|
```
|
|
54
50
|
|
|
55
51
|
**Functional composition**:
|
|
56
|
-
|
|
57
|
-
- Immutable data structures
|
|
58
|
-
- Explicit side effects (mark with comments or types)
|
|
52
|
+
Pure functions where possible. Immutable data. Explicit side effects.
|
|
59
53
|
|
|
60
54
|
**Composition over inheritance**:
|
|
61
|
-
|
|
62
|
-
- Dependency injection > tight coupling
|
|
55
|
+
Prefer mixins, HOCs, hooks. Dependency injection > tight coupling.
|
|
63
56
|
|
|
64
57
|
**Declarative over imperative**:
|
|
65
58
|
```typescript
|
|
66
|
-
|
|
67
|
-
const active =
|
|
68
|
-
|
|
69
|
-
// ❌ Imperative
|
|
70
|
-
const active = []
|
|
71
|
-
for (let i = 0; i < users.length; i++) {
|
|
72
|
-
if (users[i].isActive) active.push(users[i])
|
|
73
|
-
}
|
|
59
|
+
✅ const active = users.filter(u => u.isActive)
|
|
60
|
+
❌ const active = []; for (let i = 0; i < users.length; i++) { ... }
|
|
74
61
|
```
|
|
75
62
|
|
|
76
63
|
**Event-driven when appropriate**:
|
|
77
|
-
|
|
78
|
-
- Pub/sub for cross-cutting concerns
|
|
64
|
+
Decouple components through events/messages. Pub/sub for cross-cutting concerns.
|
|
79
65
|
|
|
80
66
|
---
|
|
81
67
|
|
|
@@ -83,9 +69,9 @@ for (let i = 0; i < users.length; i++) {
|
|
|
83
69
|
|
|
84
70
|
**YAGNI**: Build what's needed now, not hypothetical futures.
|
|
85
71
|
|
|
86
|
-
**KISS**:
|
|
72
|
+
**KISS**: Simple > complex.
|
|
87
73
|
|
|
88
|
-
**DRY**: Extract
|
|
74
|
+
**DRY**: Extract on 3rd duplication. Balance with readability.
|
|
89
75
|
|
|
90
76
|
**Single Responsibility**: One reason to change per module.
|
|
91
77
|
|
|
@@ -100,7 +86,7 @@ for (let i = 0; i < users.length; i++) {
|
|
|
100
86
|
- [ ] Booleans: is/has/can (isActive, hasPermission)
|
|
101
87
|
- [ ] Classes: nouns (UserService, AuthManager)
|
|
102
88
|
- [ ] Constants: UPPER_SNAKE_CASE
|
|
103
|
-
- [ ] No abbreviations unless
|
|
89
|
+
- [ ] No abbreviations unless universal (req/res ok, usr/calc not ok)
|
|
104
90
|
|
|
105
91
|
**Testing**:
|
|
106
92
|
- [ ] Critical paths: 100% coverage
|
|
@@ -126,27 +112,21 @@ for (let i = 0; i < users.length; i++) {
|
|
|
126
112
|
## Security Standards
|
|
127
113
|
|
|
128
114
|
**Input Validation**:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
- Sanitize before storage/display
|
|
132
|
-
- Use schema validation (Zod, Yup)
|
|
115
|
+
Validate at boundaries (API, forms, file uploads). Whitelist > blacklist.
|
|
116
|
+
Sanitize before storage/display. Use schema validation (Zod, Yup).
|
|
133
117
|
|
|
134
118
|
**Authentication/Authorization**:
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
- Check permissions at every entry point
|
|
138
|
-
- Never trust client-side validation
|
|
119
|
+
Auth required by default (opt-in to public). Deny by default.
|
|
120
|
+
Check permissions at every entry point. Never trust client-side validation.
|
|
139
121
|
|
|
140
122
|
**Data Protection**:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
- Secure cookie flags (httpOnly, secure, sameSite)
|
|
123
|
+
Never log: passwords, tokens, API keys, PII.
|
|
124
|
+
Encrypt sensitive data at rest. HTTPS only.
|
|
125
|
+
Secure cookie flags (httpOnly, secure, sameSite).
|
|
145
126
|
|
|
146
127
|
**Risk Mitigation**:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
- Circuit breakers for external services
|
|
128
|
+
Rollback plan for risky changes. Feature flags for gradual rollout.
|
|
129
|
+
Circuit breakers for external services.
|
|
150
130
|
|
|
151
131
|
---
|
|
152
132
|
|
|
@@ -154,34 +134,21 @@ for (let i = 0; i < users.length; i++) {
|
|
|
154
134
|
|
|
155
135
|
**At Boundaries**:
|
|
156
136
|
```typescript
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const data = await fetchUser(id)
|
|
160
|
-
return Ok(data)
|
|
161
|
-
} catch (error) {
|
|
162
|
-
logger.error('Failed to fetch user', { id, error })
|
|
163
|
-
return Err(new UserNotFoundError(id))
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// ❌ Let it bubble silently
|
|
167
|
-
const data = await fetchUser(id)
|
|
137
|
+
✅ try { return Ok(data) } catch { return Err(error) }
|
|
138
|
+
❌ const data = await fetchUser(id) // let it bubble
|
|
168
139
|
```
|
|
169
140
|
|
|
170
141
|
**Expected Failures**:
|
|
171
|
-
|
|
172
|
-
- Never use exceptions for control flow
|
|
173
|
-
- Return errors as values
|
|
142
|
+
Use Result/Either types. Never exceptions for control flow. Return errors as values.
|
|
174
143
|
|
|
175
144
|
**Logging**:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
- Appropriate severity (debug, info, warn, error)
|
|
179
|
-
- Never mask failures
|
|
145
|
+
Include context (user id, request id). Actionable messages.
|
|
146
|
+
Appropriate severity. Never mask failures.
|
|
180
147
|
|
|
181
148
|
**Retry Logic**:
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
149
|
+
Transient failures (network, rate limits) → retry with exponential backoff.
|
|
150
|
+
Permanent failures (validation, auth) → fail fast.
|
|
151
|
+
Max retries: 3-5 with jitter.
|
|
185
152
|
|
|
186
153
|
---
|
|
187
154
|
|
|
@@ -189,31 +156,23 @@ const data = await fetchUser(id)
|
|
|
189
156
|
|
|
190
157
|
**Query Optimization**:
|
|
191
158
|
```typescript
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
user.posts = await db.posts.findByUserId(user.id)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// ✅ Batch/Join
|
|
198
|
-
const userIds = users.map(u => u.id)
|
|
199
|
-
const posts = await db.posts.findByUserIds(userIds)
|
|
159
|
+
❌ for (const user of users) { user.posts = await db.posts.find(user.id) }
|
|
160
|
+
✅ const posts = await db.posts.findByUserIds(users.map(u => u.id))
|
|
200
161
|
```
|
|
201
162
|
|
|
202
163
|
**Algorithm Complexity**:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
164
|
+
O(n²) in hot paths → reconsider algorithm.
|
|
165
|
+
Nested loops on large datasets → use hash maps.
|
|
166
|
+
Repeated calculations → memoize.
|
|
206
167
|
|
|
207
168
|
**Data Transfer**:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
169
|
+
Large payloads → pagination or streaming.
|
|
170
|
+
API responses → only return needed fields.
|
|
171
|
+
Images/assets → lazy load, CDN.
|
|
211
172
|
|
|
212
173
|
**When to Optimize**:
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
- Measure impact after changes
|
|
216
|
-
- No premature optimization
|
|
174
|
+
Only with data showing bottleneck. Profile before optimizing.
|
|
175
|
+
Measure impact. No premature optimization.
|
|
217
176
|
|
|
218
177
|
---
|
|
219
178
|
|
|
@@ -222,85 +181,76 @@ const posts = await db.posts.findByUserIds(userIds)
|
|
|
222
181
|
**Extract function when**:
|
|
223
182
|
- 3rd duplication appears
|
|
224
183
|
- Function >20 lines
|
|
225
|
-
-
|
|
226
|
-
- Cognitive load high
|
|
184
|
+
- >3 levels of nesting
|
|
185
|
+
- Cognitive load high
|
|
227
186
|
|
|
228
187
|
**Extract module when**:
|
|
229
188
|
- File >300 lines
|
|
230
189
|
- Multiple unrelated responsibilities
|
|
231
190
|
- Difficult to name clearly
|
|
232
191
|
|
|
233
|
-
**Immediate refactor
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
192
|
+
**Immediate refactor**:
|
|
193
|
+
Thinking "I'll clean later" → Clean NOW.
|
|
194
|
+
Adding TODO → Implement NOW.
|
|
195
|
+
Copy-pasting → Extract NOW.
|
|
237
196
|
|
|
238
197
|
---
|
|
239
198
|
|
|
240
199
|
## Anti-Patterns
|
|
241
200
|
|
|
242
|
-
**Technical Debt
|
|
201
|
+
**Technical Debt**:
|
|
243
202
|
- ❌ "I'll clean this later" → You won't
|
|
244
203
|
- ❌ "Just one more TODO" → Compounds
|
|
245
204
|
- ❌ "Tests slow me down" → Bugs slow more
|
|
246
|
-
- ✅ Refactor AS you
|
|
205
|
+
- ✅ Refactor AS you work, not after
|
|
247
206
|
|
|
248
207
|
**Reinventing the Wheel**:
|
|
249
208
|
Before ANY feature: research best practices + search codebase + check package registry + check framework built-ins.
|
|
250
209
|
|
|
251
210
|
```typescript
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
// ❌ Don't: Custom validation
|
|
256
|
-
// ✅ Do: import { z } from 'zod'
|
|
257
|
-
|
|
258
|
-
// ❌ Don't: Custom date formatting
|
|
259
|
-
// ✅ Do: import { format } from 'date-fns'
|
|
211
|
+
❌ Custom Result type → ✅ import { Result } from 'neverthrow'
|
|
212
|
+
❌ Custom validation → ✅ import { z } from 'zod'
|
|
213
|
+
❌ Custom date formatting → ✅ import { format } from 'date-fns'
|
|
260
214
|
```
|
|
261
215
|
|
|
262
216
|
**Premature Abstraction**:
|
|
263
|
-
- ❌
|
|
217
|
+
- ❌ Interfaces before 2nd use case
|
|
264
218
|
- ❌ Generic solutions for specific problems
|
|
265
|
-
- ✅ Solve specific
|
|
219
|
+
- ✅ Solve specific first, extract when pattern emerges
|
|
266
220
|
|
|
267
221
|
**Copy-Paste Without Understanding**:
|
|
268
|
-
- ❌ Stack Overflow → paste → hope
|
|
269
|
-
- ✅ Stack Overflow → understand → adapt
|
|
222
|
+
- ❌ Stack Overflow → paste → hope
|
|
223
|
+
- ✅ Stack Overflow → understand → adapt
|
|
270
224
|
|
|
271
225
|
**Working Around Errors**:
|
|
272
226
|
- ❌ Suppress error, add fallback
|
|
273
227
|
- ✅ Fix root cause
|
|
274
228
|
|
|
275
|
-
**God Objects**:
|
|
276
|
-
- ❌ One class/module does everything
|
|
277
|
-
- ✅ Small, focused modules with clear responsibilities
|
|
278
|
-
|
|
279
229
|
---
|
|
280
230
|
|
|
281
|
-
## Code Smells
|
|
231
|
+
## Code Smells
|
|
282
232
|
|
|
283
|
-
**Complexity
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
233
|
+
**Complexity**:
|
|
234
|
+
Function >20 lines → extract.
|
|
235
|
+
>3 nesting levels → flatten or extract.
|
|
236
|
+
>5 parameters → use object or split.
|
|
237
|
+
Deeply nested ternaries → use if/else or early returns.
|
|
288
238
|
|
|
289
|
-
**Coupling
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
239
|
+
**Coupling**:
|
|
240
|
+
Circular dependencies → redesign.
|
|
241
|
+
Import chains >3 levels → reconsider architecture.
|
|
242
|
+
Tight coupling to external APIs → add adapter layer.
|
|
293
243
|
|
|
294
|
-
**Data
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
244
|
+
**Data**:
|
|
245
|
+
Mutable shared state → make immutable or encapsulate.
|
|
246
|
+
Global variables → dependency injection.
|
|
247
|
+
Magic numbers → named constants.
|
|
248
|
+
Stringly typed → use enums/types.
|
|
299
249
|
|
|
300
|
-
**Naming
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
250
|
+
**Naming**:
|
|
251
|
+
Generic names (data, info, manager, utils) → be specific.
|
|
252
|
+
Misleading names → rename immediately.
|
|
253
|
+
Inconsistent naming → align with conventions.
|
|
304
254
|
|
|
305
255
|
---
|
|
306
256
|
|
|
@@ -309,10 +259,7 @@ Before ANY feature: research best practices + search codebase + check package re
|
|
|
309
259
|
**Self-Healing at Read**:
|
|
310
260
|
```typescript
|
|
311
261
|
function loadConfig(raw: unknown): Config {
|
|
312
|
-
// 1. Validate
|
|
313
262
|
const parsed = ConfigSchema.safeParse(raw)
|
|
314
|
-
|
|
315
|
-
// 2. Fix common issues
|
|
316
263
|
if (!parsed.success) {
|
|
317
264
|
const fixed = applyDefaults(raw)
|
|
318
265
|
const retry = ConfigSchema.safeParse(fixed)
|
|
@@ -321,21 +268,15 @@ function loadConfig(raw: unknown): Config {
|
|
|
321
268
|
return retry.data
|
|
322
269
|
}
|
|
323
270
|
}
|
|
324
|
-
|
|
325
|
-
// 3. Fail hard if unfixable
|
|
326
|
-
if (!parsed.success) {
|
|
327
|
-
throw new ConfigError('Invalid config', parsed.error)
|
|
328
|
-
}
|
|
329
|
-
|
|
271
|
+
if (!parsed.success) throw new ConfigError(parsed.error)
|
|
330
272
|
return parsed.data
|
|
331
273
|
}
|
|
332
274
|
```
|
|
333
275
|
|
|
334
276
|
**Single Source of Truth**:
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
- Use references, not copies
|
|
277
|
+
Configuration → Environment + config files.
|
|
278
|
+
State → Single store (Redux, Zustand, Context).
|
|
279
|
+
Derived data → Compute from source, don't duplicate.
|
|
339
280
|
|
|
340
281
|
**Data Flow**:
|
|
341
282
|
```
|
package/assets/rules/core.md
CHANGED
|
@@ -18,6 +18,12 @@ Only act on verified data or logic.
|
|
|
18
18
|
|
|
19
19
|
## Execution
|
|
20
20
|
|
|
21
|
+
**Research First**: Before implementing, research current best practices. Assume knowledge may be outdated.
|
|
22
|
+
|
|
23
|
+
Check latest docs, review codebase patterns, verify current practices. Document sources in code.
|
|
24
|
+
|
|
25
|
+
Skip research → outdated implementation → rework.
|
|
26
|
+
|
|
21
27
|
**Parallel Execution**: Multiple tool calls in ONE message = parallel. Multiple messages = sequential.
|
|
22
28
|
Use parallel whenever tools are independent.
|
|
23
29
|
|
|
@@ -30,29 +36,24 @@ Document assumptions:
|
|
|
30
36
|
// ALTERNATIVE: Session-based
|
|
31
37
|
```
|
|
32
38
|
|
|
33
|
-
**Decision hierarchy**: existing patterns > simplicity > maintainability
|
|
39
|
+
**Decision hierarchy**: existing patterns > current best practices > simplicity > maintainability
|
|
34
40
|
|
|
35
41
|
**Thoroughness**:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- Surface all findings at once (not piecemeal)
|
|
42
|
+
Finish tasks completely before reporting. Don't stop halfway to ask permission.
|
|
43
|
+
Unclear → make reasonable assumption + document + proceed.
|
|
44
|
+
Surface all findings at once (not piecemeal).
|
|
40
45
|
|
|
41
46
|
**Problem Solving**:
|
|
42
|
-
|
|
43
|
-
1. State the blocker clearly
|
|
44
|
-
2. List what you've tried
|
|
45
|
-
3. Propose 2+ alternative approaches
|
|
46
|
-
4. Pick best option and proceed (or ask if genuinely ambiguous)
|
|
47
|
+
Stuck → state blocker + what tried + 2+ alternatives + pick best and proceed (or ask if genuinely ambiguous).
|
|
47
48
|
|
|
48
49
|
---
|
|
49
50
|
|
|
50
51
|
## Communication
|
|
51
52
|
|
|
52
53
|
**Output Style**:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
Concise and direct. No fluff, no apologies, no hedging.
|
|
55
|
+
Show, don't tell. Code examples over explanations.
|
|
56
|
+
One clear statement over three cautious ones.
|
|
56
57
|
|
|
57
58
|
**Minimal Effective Prompt**: All docs, comments, delegation messages.
|
|
58
59
|
|
|
@@ -99,18 +100,31 @@ Benefits: Encapsulation, easy deletion, focused work, team collaboration.
|
|
|
99
100
|
## Principles
|
|
100
101
|
|
|
101
102
|
### Programming
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
|
|
104
|
+
**Pure functions default**: No mutations, no global state, no I/O.
|
|
105
|
+
Side effects isolated: `// SIDE EFFECT: writes to disk`
|
|
106
|
+
|
|
107
|
+
**3+ params → named args**: `fn({ a, b, c })` not `fn(a, b, c)`
|
|
108
|
+
|
|
109
|
+
**Composition over inheritance**: Max 1 inheritance level.
|
|
110
|
+
|
|
111
|
+
**Declarative over imperative**: Express what you want, not how.
|
|
112
|
+
|
|
113
|
+
**Event-driven when appropriate**: Decouple components through events/messages.
|
|
107
114
|
|
|
108
115
|
### Quality
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
|
|
117
|
+
**YAGNI**: Build what's needed now, not hypothetical futures.
|
|
118
|
+
|
|
119
|
+
**KISS**: Simple > complex.
|
|
120
|
+
Solution needs >3 sentences to explain → find simpler approach.
|
|
121
|
+
|
|
122
|
+
**DRY**: Copying 2nd time → mark for extraction. 3rd time → extract immediately.
|
|
123
|
+
|
|
124
|
+
**Single Responsibility**: One reason to change per module.
|
|
125
|
+
File does multiple things → split.
|
|
126
|
+
|
|
127
|
+
**Dependency inversion**: Depend on abstractions, not implementations.
|
|
114
128
|
|
|
115
129
|
---
|
|
116
130
|
|
|
@@ -118,19 +132,37 @@ Benefits: Encapsulation, easy deletion, focused work, team collaboration.
|
|
|
118
132
|
|
|
119
133
|
**Code Quality**: Self-documenting names, test critical paths (100%) and business logic (80%+), comments explain WHY not WHAT, make illegal states unrepresentable.
|
|
120
134
|
|
|
135
|
+
**Testing**: Every module needs `.test.ts` and `.bench.ts`.
|
|
136
|
+
Write tests with implementation. Run after every change. Coverage ≥80%.
|
|
137
|
+
Skip tests → bugs in production.
|
|
138
|
+
|
|
121
139
|
**Security**: Validate inputs at boundaries, never log sensitive data, secure defaults (auth required, deny by default), follow OWASP API Security, rollback plan for risky changes.
|
|
122
140
|
|
|
123
141
|
**API Design**: On-demand data, field selection, cursor pagination.
|
|
124
142
|
|
|
125
143
|
**Error Handling**: Handle explicitly at boundaries, use Result/Either for expected failures, never mask failures, log with context, actionable messages.
|
|
126
144
|
|
|
127
|
-
**Refactoring**: Extract on 3rd duplication, when function >20 lines or cognitive load high.
|
|
145
|
+
**Refactoring**: Extract on 3rd duplication, when function >20 lines or cognitive load high. Thinking "I'll clean later" → Clean NOW. Adding TODO → Implement NOW.
|
|
146
|
+
|
|
147
|
+
**Proactive Cleanup**: Before every commit:
|
|
148
|
+
|
|
149
|
+
Organize imports, remove unused code/imports/commented code/debug statements.
|
|
150
|
+
Update or delete outdated docs/comments/configs. Fix discovered tech debt.
|
|
151
|
+
|
|
152
|
+
**Prime directive: Never accumulate misleading artifacts.**
|
|
153
|
+
Unsure whether to delete → delete it. Git remembers everything.
|
|
128
154
|
|
|
129
155
|
---
|
|
130
156
|
|
|
131
157
|
## Documentation
|
|
132
158
|
|
|
133
|
-
|
|
159
|
+
**Code-Level**: Comments explain WHY, not WHAT.
|
|
160
|
+
Non-obvious decision → `// WHY: [reason]`
|
|
161
|
+
|
|
162
|
+
**Project-Level**: Every project needs a docs site.
|
|
163
|
+
|
|
164
|
+
First feature completion: Create docs with `@sylphx/leaf` + Vercel (unless specified otherwise).
|
|
165
|
+
Deploy with `vercel` CLI. Add docs URL to README.
|
|
134
166
|
|
|
135
167
|
Separate documentation files only when explicitly requested.
|
|
136
168
|
|