opencodekit 0.14.6 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.js +100 -58
- package/dist/template/.opencode/.env.example +1 -0
- package/dist/template/.opencode/AGENTS.md +13 -24
- package/dist/template/.opencode/README.md +8 -119
- package/dist/template/.opencode/agent/explore.md +2 -3
- package/dist/template/.opencode/agent/general.md +56 -0
- package/dist/template/.opencode/agent/plan.md +54 -0
- package/dist/template/.opencode/agent/scout.md +15 -5
- package/dist/template/.opencode/command/analyze-project.md +2 -2
- package/dist/template/.opencode/command/brainstorm.md +1 -1
- package/dist/template/.opencode/command/design-audit.md +4 -5
- package/dist/template/.opencode/command/design.md +4 -13
- package/dist/template/.opencode/command/generate-pattern.md +2 -9
- package/dist/template/.opencode/command/implement.md +4 -4
- package/dist/template/.opencode/command/init.md +1 -1
- package/dist/template/.opencode/command/new-feature.md +2 -3
- package/dist/template/.opencode/command/plan.md +1 -1
- package/dist/template/.opencode/command/pr.md +0 -1
- package/dist/template/.opencode/command/research.md +20 -6
- package/dist/template/.opencode/command/restore-image.md +1 -9
- package/dist/template/.opencode/command/revert-feature.md +1 -1
- package/dist/template/.opencode/command/review-codebase.md +4 -4
- package/dist/template/.opencode/command/status.md +1 -2
- package/dist/template/.opencode/command/summarize.md +1 -2
- package/dist/template/.opencode/command/triage.md +4 -32
- package/dist/template/.opencode/dcp.jsonc +68 -68
- package/dist/template/.opencode/memory/_templates/README.md +35 -0
- package/dist/template/.opencode/memory/_templates/project/architecture.md +60 -0
- package/dist/template/.opencode/memory/_templates/project/commands.md +72 -0
- package/dist/template/.opencode/memory/_templates/project/conventions.md +68 -0
- package/dist/template/.opencode/memory/_templates/project/gotchas.md +41 -0
- package/dist/template/.opencode/memory/beads-workflow.md +30 -29
- package/dist/template/.opencode/memory/project/architecture.md +31 -50
- package/dist/template/.opencode/memory/project/commands.md +41 -22
- package/dist/template/.opencode/memory/project/conventions.md +39 -177
- package/dist/template/.opencode/memory/project/gotchas.md +21 -177
- package/dist/template/.opencode/memory/user.example.md +5 -0
- package/dist/template/.opencode/opencode.json +644 -579
- package/dist/template/.opencode/package.json +18 -21
- package/dist/template/.opencode/plugin/compaction.ts +79 -85
- package/dist/template/.opencode/plugin/env-ctx.ts +19 -19
- package/dist/template/.opencode/plugin/lib/notify.ts +41 -45
- package/dist/template/.opencode/plugin/lsp.ts +197 -200
- package/dist/template/.opencode/plugin/memory.ts +14 -112
- package/dist/template/.opencode/plugin/package.json +5 -5
- package/dist/template/.opencode/plugin/sessions.ts +1 -1
- package/dist/template/.opencode/plugin/skill-mcp.ts +486 -521
- package/dist/template/.opencode/plugin/truncator.ts +47 -50
- package/dist/template/.opencode/plugin/tsconfig.json +14 -14
- package/dist/template/.opencode/skill/chrome-devtools/mcp.json +17 -17
- package/dist/template/.opencode/skill/condition-based-waiting/SKILL.md +17 -12
- package/dist/template/.opencode/skill/condition-based-waiting/example.ts +63 -69
- package/dist/template/.opencode/skill/defense-in-depth/SKILL.md +14 -8
- package/dist/template/.opencode/skill/dispatching-parallel-agents/SKILL.md +14 -3
- package/dist/template/.opencode/skill/playwright/mcp.json +14 -14
- package/dist/template/.opencode/skill/receiving-code-review/SKILL.md +21 -8
- package/dist/template/.opencode/skill/requesting-code-review/review.md +14 -0
- package/dist/template/.opencode/skill/root-cause-tracing/SKILL.md +18 -4
- package/dist/template/.opencode/skill/source-code-research/SKILL.md +9 -7
- package/dist/template/.opencode/skill/test-driven-development/SKILL.md +49 -32
- package/dist/template/.opencode/skill/testing-anti-patterns/SKILL.md +40 -22
- package/dist/template/.opencode/skill/testing-skills-with-subagents/SKILL.md +46 -26
- package/dist/template/.opencode/skill/tool-priority/SKILL.md +117 -44
- package/dist/template/.opencode/skill/v0/SKILL.md +1 -7
- package/dist/template/.opencode/skill/verification-before-completion/SKILL.md +27 -19
- package/dist/template/.opencode/skill/writing-skills/anthropic-best-practices.md +171 -148
- package/dist/template/.opencode/skill/writing-skills/persuasion-principles.md +39 -6
- package/dist/template/.opencode/tool/memory-read.ts +44 -56
- package/dist/template/.opencode/tool/memory-search.ts +8 -291
- package/dist/template/.opencode/tool/memory-update.ts +47 -51
- package/dist/template/.opencode/tool/observation.ts +6 -180
- package/dist/template/.opencode/tsconfig.json +19 -19
- package/package.json +19 -15
- package/dist/template/.opencode/.background-tasks.json +0 -114
- package/dist/template/.opencode/.ralph-state.json +0 -12
- package/dist/template/.opencode/agent/build.md +0 -327
- package/dist/template/.opencode/agent/ninja.md +0 -351
- package/dist/template/.opencode/agent/planner.md +0 -281
- package/dist/template/.opencode/agent/rush.md +0 -223
- package/dist/template/.opencode/memory/handoffs/README.md +0 -83
- package/dist/template/.opencode/memory/observations/.gitkeep +0 -0
- package/dist/template/.opencode/memory/observations/2026-01-09-pattern-ampcode-mcp-json-includetools-pattern.md +0 -42
- package/dist/template/.opencode/memory/vector_db/memories.lance/_transactions/0-0d25ba80-ba3b-4209-9046-b45d6093b4da.txn +0 -0
- package/dist/template/.opencode/memory/vector_db/memories.lance/_versions/1.manifest +0 -0
- package/dist/template/.opencode/memory/vector_db/memories.lance/data/1111100101010101011010004a9ef34df6b29f36a9a53a2892.lance +0 -0
- package/dist/template/.opencode/tool/ast-grep.ts +0 -245
- package/dist/template/.opencode/tool/background.ts +0 -509
- package/dist/template/.opencode/tool/bd-inbox.ts +0 -110
- package/dist/template/.opencode/tool/bd-msg.ts +0 -62
- package/dist/template/.opencode/tool/bd-release.ts +0 -71
- package/dist/template/.opencode/tool/bd-reserve.ts +0 -121
- package/dist/template/.opencode/tool/memory-embed.ts +0 -183
- package/dist/template/.opencode/tool/memory-index.ts +0 -769
- package/dist/template/.opencode/tool/repo-map.ts +0 -451
|
@@ -27,11 +27,13 @@ WHEN receiving code review feedback:
|
|
|
27
27
|
## Forbidden Responses
|
|
28
28
|
|
|
29
29
|
**NEVER:**
|
|
30
|
+
|
|
30
31
|
- "You're absolutely right!" (explicit CLAUDE.md violation)
|
|
31
32
|
- "Great point!" / "Excellent feedback!" (performative)
|
|
32
33
|
- "Let me implement that now" (before verification)
|
|
33
34
|
|
|
34
35
|
**INSTEAD:**
|
|
36
|
+
|
|
35
37
|
- Restate the technical requirement
|
|
36
38
|
- Ask clarifying questions
|
|
37
39
|
- Push back with technical reasoning if wrong
|
|
@@ -48,6 +50,7 @@ WHY: Items may be related. Partial understanding = wrong implementation.
|
|
|
48
50
|
```
|
|
49
51
|
|
|
50
52
|
**Example:**
|
|
53
|
+
|
|
51
54
|
```
|
|
52
55
|
your human partner: "Fix 1-6"
|
|
53
56
|
You understand 1,2,3,6. Unclear on 4,5.
|
|
@@ -59,12 +62,14 @@ You understand 1,2,3,6. Unclear on 4,5.
|
|
|
59
62
|
## Source-Specific Handling
|
|
60
63
|
|
|
61
64
|
### From your human partner
|
|
65
|
+
|
|
62
66
|
- **Trusted** - implement after understanding
|
|
63
67
|
- **Still ask** if scope unclear
|
|
64
68
|
- **No performative agreement**
|
|
65
69
|
- **Skip to action** or technical acknowledgment
|
|
66
70
|
|
|
67
71
|
### From External Reviewers
|
|
72
|
+
|
|
68
73
|
```
|
|
69
74
|
BEFORE implementing:
|
|
70
75
|
1. Check: Technically correct for THIS codebase?
|
|
@@ -113,6 +118,7 @@ FOR multi-item feedback:
|
|
|
113
118
|
## When To Push Back
|
|
114
119
|
|
|
115
120
|
Push back when:
|
|
121
|
+
|
|
116
122
|
- Suggestion breaks existing functionality
|
|
117
123
|
- Reviewer lacks full context
|
|
118
124
|
- Violates YAGNI (unused feature)
|
|
@@ -121,6 +127,7 @@ Push back when:
|
|
|
121
127
|
- Conflicts with your human partner's architectural decisions
|
|
122
128
|
|
|
123
129
|
**How to push back:**
|
|
130
|
+
|
|
124
131
|
- Use technical reasoning, not defensiveness
|
|
125
132
|
- Ask specific questions
|
|
126
133
|
- Reference working tests/code
|
|
@@ -131,6 +138,7 @@ Push back when:
|
|
|
131
138
|
## Acknowledging Correct Feedback
|
|
132
139
|
|
|
133
140
|
When feedback IS correct:
|
|
141
|
+
|
|
134
142
|
```
|
|
135
143
|
✅ "Fixed. [Brief description of what changed]"
|
|
136
144
|
✅ "Good catch - [specific issue]. Fixed in [location]."
|
|
@@ -150,6 +158,7 @@ When feedback IS correct:
|
|
|
150
158
|
## Gracefully Correcting Your Pushback
|
|
151
159
|
|
|
152
160
|
If you pushed back and were wrong:
|
|
161
|
+
|
|
153
162
|
```
|
|
154
163
|
✅ "You were right - I checked [X] and it does [Y]. Implementing now."
|
|
155
164
|
✅ "Verified this and you're correct. My initial understanding was wrong because [reason]. Fixing."
|
|
@@ -163,37 +172,41 @@ State the correction factually and move on.
|
|
|
163
172
|
|
|
164
173
|
## Common Mistakes
|
|
165
174
|
|
|
166
|
-
| Mistake
|
|
167
|
-
|
|
168
|
-
| Performative agreement
|
|
169
|
-
| Blind implementation
|
|
170
|
-
| Batch without testing
|
|
171
|
-
| Assuming reviewer is right
|
|
172
|
-
| Avoiding pushback
|
|
173
|
-
| Partial implementation
|
|
175
|
+
| Mistake | Fix |
|
|
176
|
+
| ---------------------------- | ----------------------------------- |
|
|
177
|
+
| Performative agreement | State requirement or just act |
|
|
178
|
+
| Blind implementation | Verify against codebase first |
|
|
179
|
+
| Batch without testing | One at a time, test each |
|
|
180
|
+
| Assuming reviewer is right | Check if breaks things |
|
|
181
|
+
| Avoiding pushback | Technical correctness > comfort |
|
|
182
|
+
| Partial implementation | Clarify all items first |
|
|
174
183
|
| Can't verify, proceed anyway | State limitation, ask for direction |
|
|
175
184
|
|
|
176
185
|
## Real Examples
|
|
177
186
|
|
|
178
187
|
**Performative Agreement (Bad):**
|
|
188
|
+
|
|
179
189
|
```
|
|
180
190
|
Reviewer: "Remove legacy code"
|
|
181
191
|
❌ "You're absolutely right! Let me remove that..."
|
|
182
192
|
```
|
|
183
193
|
|
|
184
194
|
**Technical Verification (Good):**
|
|
195
|
+
|
|
185
196
|
```
|
|
186
197
|
Reviewer: "Remove legacy code"
|
|
187
198
|
✅ "Checking... build target is 10.15+, this API needs 13+. Need legacy for backward compat. Current impl has wrong bundle ID - fix it or drop pre-13 support?"
|
|
188
199
|
```
|
|
189
200
|
|
|
190
201
|
**YAGNI (Good):**
|
|
202
|
+
|
|
191
203
|
```
|
|
192
204
|
Reviewer: "Implement proper metrics tracking with database, date filters, CSV export"
|
|
193
205
|
✅ "Grepped codebase - nothing calls this endpoint. Remove it (YAGNI)? Or is there usage I'm missing?"
|
|
194
206
|
```
|
|
195
207
|
|
|
196
208
|
**Unclear Item (Good):**
|
|
209
|
+
|
|
197
210
|
```
|
|
198
211
|
your human partner: "Fix items 1-6"
|
|
199
212
|
You understand 1,2,3,6. Unclear on 4,5.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
You are reviewing code changes for production readiness.
|
|
4
4
|
|
|
5
5
|
**Your task:**
|
|
6
|
+
|
|
6
7
|
1. Review {WHAT_WAS_IMPLEMENTED}
|
|
7
8
|
2. Compare against {PLAN_OR_REQUIREMENTS}
|
|
8
9
|
3. Check code quality, architecture, testing
|
|
@@ -30,6 +31,7 @@ git diff {BASE_SHA}..{HEAD_SHA}
|
|
|
30
31
|
## Review Checklist
|
|
31
32
|
|
|
32
33
|
**Code Quality:**
|
|
34
|
+
|
|
33
35
|
- Clean separation of concerns?
|
|
34
36
|
- Proper error handling?
|
|
35
37
|
- Type safety (if applicable)?
|
|
@@ -37,24 +39,28 @@ git diff {BASE_SHA}..{HEAD_SHA}
|
|
|
37
39
|
- Edge cases handled?
|
|
38
40
|
|
|
39
41
|
**Architecture:**
|
|
42
|
+
|
|
40
43
|
- Sound design decisions?
|
|
41
44
|
- Scalability considerations?
|
|
42
45
|
- Performance implications?
|
|
43
46
|
- Security concerns?
|
|
44
47
|
|
|
45
48
|
**Testing:**
|
|
49
|
+
|
|
46
50
|
- Tests actually test logic (not mocks)?
|
|
47
51
|
- Edge cases covered?
|
|
48
52
|
- Integration tests where needed?
|
|
49
53
|
- All tests passing?
|
|
50
54
|
|
|
51
55
|
**Requirements:**
|
|
56
|
+
|
|
52
57
|
- All plan requirements met?
|
|
53
58
|
- Implementation matches spec?
|
|
54
59
|
- No scope creep?
|
|
55
60
|
- Breaking changes documented?
|
|
56
61
|
|
|
57
62
|
**Production Readiness:**
|
|
63
|
+
|
|
58
64
|
- Migration strategy (if schema changes)?
|
|
59
65
|
- Backward compatibility considered?
|
|
60
66
|
- Documentation complete?
|
|
@@ -63,26 +69,32 @@ git diff {BASE_SHA}..{HEAD_SHA}
|
|
|
63
69
|
## Output Format
|
|
64
70
|
|
|
65
71
|
### Strengths
|
|
72
|
+
|
|
66
73
|
[What's well done? Be specific.]
|
|
67
74
|
|
|
68
75
|
### Issues
|
|
69
76
|
|
|
70
77
|
#### Critical (Must Fix)
|
|
78
|
+
|
|
71
79
|
[Bugs, security issues, data loss risks, broken functionality]
|
|
72
80
|
|
|
73
81
|
#### Important (Should Fix)
|
|
82
|
+
|
|
74
83
|
[Architecture problems, missing features, poor error handling, test gaps]
|
|
75
84
|
|
|
76
85
|
#### Minor (Nice to Have)
|
|
86
|
+
|
|
77
87
|
[Code style, optimization opportunities, documentation improvements]
|
|
78
88
|
|
|
79
89
|
**For each issue:**
|
|
90
|
+
|
|
80
91
|
- File:line reference
|
|
81
92
|
- What's wrong
|
|
82
93
|
- Why it matters
|
|
83
94
|
- How to fix (if not obvious)
|
|
84
95
|
|
|
85
96
|
### Recommendations
|
|
97
|
+
|
|
86
98
|
[Improvements for code quality, architecture, or process]
|
|
87
99
|
|
|
88
100
|
### Assessment
|
|
@@ -94,6 +106,7 @@ git diff {BASE_SHA}..{HEAD_SHA}
|
|
|
94
106
|
## Critical Rules
|
|
95
107
|
|
|
96
108
|
**DO:**
|
|
109
|
+
|
|
97
110
|
- Categorize by actual severity (not everything is Critical)
|
|
98
111
|
- Be specific (file:line, not vague)
|
|
99
112
|
- Explain WHY issues matter
|
|
@@ -101,6 +114,7 @@ git diff {BASE_SHA}..{HEAD_SHA}
|
|
|
101
114
|
- Give clear verdict
|
|
102
115
|
|
|
103
116
|
**DON'T:**
|
|
117
|
+
|
|
104
118
|
- Say "looks good" without checking
|
|
105
119
|
- Mark nitpicks as Critical
|
|
106
120
|
- Give feedback on code you didn't review
|
|
@@ -29,6 +29,7 @@ digraph when_to_use {
|
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
**Use when:**
|
|
32
|
+
|
|
32
33
|
- Error happens deep in execution (not at entry point)
|
|
33
34
|
- Stack trace shows long call chain
|
|
34
35
|
- Unclear where invalid data originated
|
|
@@ -37,17 +38,21 @@ digraph when_to_use {
|
|
|
37
38
|
## The Tracing Process
|
|
38
39
|
|
|
39
40
|
### 1. Observe the Symptom
|
|
41
|
+
|
|
40
42
|
```
|
|
41
43
|
Error: git init failed in /Users/jesse/project/packages/core
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
### 2. Find Immediate Cause
|
|
47
|
+
|
|
45
48
|
**What code directly causes this?**
|
|
49
|
+
|
|
46
50
|
```typescript
|
|
47
|
-
await execFileAsync(
|
|
51
|
+
await execFileAsync("git", ["init"], { cwd: projectDir });
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
### 3. Ask: What Called This?
|
|
55
|
+
|
|
51
56
|
```typescript
|
|
52
57
|
WorktreeManager.createSessionWorktree(projectDir, sessionId)
|
|
53
58
|
→ called by Session.initializeWorkspace()
|
|
@@ -56,16 +61,20 @@ WorktreeManager.createSessionWorktree(projectDir, sessionId)
|
|
|
56
61
|
```
|
|
57
62
|
|
|
58
63
|
### 4. Keep Tracing Up
|
|
64
|
+
|
|
59
65
|
**What value was passed?**
|
|
66
|
+
|
|
60
67
|
- `projectDir = ''` (empty string!)
|
|
61
68
|
- Empty string as `cwd` resolves to `process.cwd()`
|
|
62
69
|
- That's the source code directory!
|
|
63
70
|
|
|
64
71
|
### 5. Find Original Trigger
|
|
72
|
+
|
|
65
73
|
**Where did empty string come from?**
|
|
74
|
+
|
|
66
75
|
```typescript
|
|
67
76
|
const context = setupCoreTest(); // Returns { tempDir: '' }
|
|
68
|
-
Project.create(
|
|
77
|
+
Project.create("name", context.tempDir); // Accessed before beforeEach!
|
|
69
78
|
```
|
|
70
79
|
|
|
71
80
|
## Adding Stack Traces
|
|
@@ -76,25 +85,27 @@ When you can't trace manually, add instrumentation:
|
|
|
76
85
|
// Before the problematic operation
|
|
77
86
|
async function gitInit(directory: string) {
|
|
78
87
|
const stack = new Error().stack;
|
|
79
|
-
console.error(
|
|
88
|
+
console.error("DEBUG git init:", {
|
|
80
89
|
directory,
|
|
81
90
|
cwd: process.cwd(),
|
|
82
91
|
nodeEnv: process.env.NODE_ENV,
|
|
83
92
|
stack,
|
|
84
93
|
});
|
|
85
94
|
|
|
86
|
-
await execFileAsync(
|
|
95
|
+
await execFileAsync("git", ["init"], { cwd: directory });
|
|
87
96
|
}
|
|
88
97
|
```
|
|
89
98
|
|
|
90
99
|
**Critical:** Use `console.error()` in tests (not logger - may not show)
|
|
91
100
|
|
|
92
101
|
**Run and capture:**
|
|
102
|
+
|
|
93
103
|
```bash
|
|
94
104
|
npm test 2>&1 | grep 'DEBUG git init'
|
|
95
105
|
```
|
|
96
106
|
|
|
97
107
|
**Analyze stack traces:**
|
|
108
|
+
|
|
98
109
|
- Look for test file names
|
|
99
110
|
- Find the line number triggering the call
|
|
100
111
|
- Identify the pattern (same test? same parameter?)
|
|
@@ -116,6 +127,7 @@ Runs tests one-by-one, stops at first polluter. See script for usage.
|
|
|
116
127
|
**Symptom:** `.git` created in `packages/core/` (source code)
|
|
117
128
|
|
|
118
129
|
**Trace chain:**
|
|
130
|
+
|
|
119
131
|
1. `git init` runs in `process.cwd()` ← empty cwd parameter
|
|
120
132
|
2. WorktreeManager called with empty projectDir
|
|
121
133
|
3. Session.create() passed empty string
|
|
@@ -127,6 +139,7 @@ Runs tests one-by-one, stops at first polluter. See script for usage.
|
|
|
127
139
|
**Fix:** Made tempDir a getter that throws if accessed before beforeEach
|
|
128
140
|
|
|
129
141
|
**Also added defense-in-depth:**
|
|
142
|
+
|
|
130
143
|
- Layer 1: Project.create() validates directory
|
|
131
144
|
- Layer 2: WorkspaceManager validates not empty
|
|
132
145
|
- Layer 3: NODE_ENV guard refuses git init outside tmpdir
|
|
@@ -168,6 +181,7 @@ digraph principle {
|
|
|
168
181
|
## Real-World Impact
|
|
169
182
|
|
|
170
183
|
From debugging session (2025-10-03):
|
|
184
|
+
|
|
171
185
|
- Found root cause through 5-level trace
|
|
172
186
|
- Fixed at source (getter validation)
|
|
173
187
|
- Added 4 layers of defense
|
|
@@ -86,7 +86,7 @@ npx opensrc vercel/ai@v3.0.0 # Fetch specific tag
|
|
|
86
86
|
|
|
87
87
|
### Step 3: Locate Relevant Code
|
|
88
88
|
|
|
89
|
-
Use search tools to find
|
|
89
|
+
Use search tools to find code you need:
|
|
90
90
|
|
|
91
91
|
```typescript
|
|
92
92
|
// Find all TypeScript source files
|
|
@@ -99,10 +99,11 @@ grep({
|
|
|
99
99
|
include: "*.ts",
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
pattern: "export function parse
|
|
102
|
+
// Search for function pattern
|
|
103
|
+
grep({
|
|
104
|
+
pattern: "export function parse",
|
|
105
105
|
path: "opensrc/",
|
|
106
|
+
include: "*.ts",
|
|
106
107
|
});
|
|
107
108
|
```
|
|
108
109
|
|
|
@@ -216,9 +217,10 @@ grep({ pattern: "throw new", path: "opensrc/", include: "*.ts" });
|
|
|
216
217
|
// bash: npx opensrc react-hook-form
|
|
217
218
|
|
|
218
219
|
// 2. Find function definition
|
|
219
|
-
|
|
220
|
-
pattern: "export function useForm
|
|
220
|
+
grep({
|
|
221
|
+
pattern: "export function useForm",
|
|
221
222
|
path: "opensrc/",
|
|
223
|
+
include: "*.ts",
|
|
222
224
|
});
|
|
223
225
|
|
|
224
226
|
// 3. Read implementation
|
|
@@ -491,7 +493,7 @@ read({ filePath: "opensrc/.../helpers.ts" });
|
|
|
491
493
|
// ... (unfocused exploration)
|
|
492
494
|
```
|
|
493
495
|
|
|
494
|
-
**Do:** Use grep
|
|
496
|
+
**Do:** Use grep to find relevant code first, then read.
|
|
495
497
|
|
|
496
498
|
### ❌ Don't: Ignore Version Mismatch
|
|
497
499
|
|
|
@@ -16,12 +16,14 @@ Write the test first. Watch it fail. Write minimal code to pass.
|
|
|
16
16
|
## When to Use
|
|
17
17
|
|
|
18
18
|
**Always:**
|
|
19
|
+
|
|
19
20
|
- New features
|
|
20
21
|
- Bug fixes
|
|
21
22
|
- Refactoring
|
|
22
23
|
- Behavior changes
|
|
23
24
|
|
|
24
25
|
**Exceptions (ask your human partner):**
|
|
26
|
+
|
|
25
27
|
- Throwaway prototypes
|
|
26
28
|
- Generated code
|
|
27
29
|
- Configuration files
|
|
@@ -37,6 +39,7 @@ NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
|
|
|
37
39
|
Write code before the test? Delete it. Start over.
|
|
38
40
|
|
|
39
41
|
**No exceptions:**
|
|
42
|
+
|
|
40
43
|
- Don't keep it as "reference"
|
|
41
44
|
- Don't "adapt" it while writing tests
|
|
42
45
|
- Don't look at it
|
|
@@ -82,12 +85,13 @@ test('retries failed operations 3 times', async () => {
|
|
|
82
85
|
return 'success';
|
|
83
86
|
};
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
const result = await retryOperation(operation);
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
expect(result).toBe('success');
|
|
91
|
+
expect(attempts).toBe(3);
|
|
89
92
|
});
|
|
90
|
-
|
|
93
|
+
|
|
94
|
+
````
|
|
91
95
|
Clear name, tests real behavior, one thing
|
|
92
96
|
</Good>
|
|
93
97
|
|
|
@@ -101,11 +105,13 @@ test('retry works', async () => {
|
|
|
101
105
|
await retryOperation(mock);
|
|
102
106
|
expect(mock).toHaveBeenCalledTimes(3);
|
|
103
107
|
});
|
|
104
|
-
|
|
108
|
+
````
|
|
109
|
+
|
|
105
110
|
Vague name, tests mock not code
|
|
106
111
|
</Bad>
|
|
107
112
|
|
|
108
113
|
**Requirements:**
|
|
114
|
+
|
|
109
115
|
- One behavior
|
|
110
116
|
- Clear name
|
|
111
117
|
- Real code (no mocks unless unavoidable)
|
|
@@ -119,6 +125,7 @@ npm test path/to/test.test.ts
|
|
|
119
125
|
```
|
|
120
126
|
|
|
121
127
|
Confirm:
|
|
128
|
+
|
|
122
129
|
- Test fails (not errors)
|
|
123
130
|
- Failure message is expected
|
|
124
131
|
- Fails because feature missing (not typos)
|
|
@@ -174,6 +181,7 @@ npm test path/to/test.test.ts
|
|
|
174
181
|
```
|
|
175
182
|
|
|
176
183
|
Confirm:
|
|
184
|
+
|
|
177
185
|
- Test passes
|
|
178
186
|
- Other tests still pass
|
|
179
187
|
- Output pristine (no errors, warnings)
|
|
@@ -185,6 +193,7 @@ Confirm:
|
|
|
185
193
|
### REFACTOR - Clean Up
|
|
186
194
|
|
|
187
195
|
After green only:
|
|
196
|
+
|
|
188
197
|
- Remove duplication
|
|
189
198
|
- Improve names
|
|
190
199
|
- Extract helpers
|
|
@@ -197,17 +206,18 @@ Next failing test for next feature.
|
|
|
197
206
|
|
|
198
207
|
## Good Tests
|
|
199
208
|
|
|
200
|
-
| Quality
|
|
201
|
-
|
|
202
|
-
| **Minimal**
|
|
203
|
-
| **Clear**
|
|
204
|
-
| **Shows intent** | Demonstrates desired API
|
|
209
|
+
| Quality | Good | Bad |
|
|
210
|
+
| ---------------- | ----------------------------------- | --------------------------------------------------- |
|
|
211
|
+
| **Minimal** | One thing. "and" in name? Split it. | `test('validates email and domain and whitespace')` |
|
|
212
|
+
| **Clear** | Name describes behavior | `test('test1')` |
|
|
213
|
+
| **Shows intent** | Demonstrates desired API | Obscures what code should do |
|
|
205
214
|
|
|
206
215
|
## Why Order Matters
|
|
207
216
|
|
|
208
217
|
**"I'll write tests after to verify it works"**
|
|
209
218
|
|
|
210
219
|
Tests written after code pass immediately. Passing immediately proves nothing:
|
|
220
|
+
|
|
211
221
|
- Might test wrong thing
|
|
212
222
|
- Might test implementation, not behavior
|
|
213
223
|
- Might miss edge cases you forgot
|
|
@@ -218,6 +228,7 @@ Test-first forces you to see the test fail, proving it actually tests something.
|
|
|
218
228
|
**"I already manually tested all the edge cases"**
|
|
219
229
|
|
|
220
230
|
Manual testing is ad-hoc. You think you tested everything but:
|
|
231
|
+
|
|
221
232
|
- No record of what you tested
|
|
222
233
|
- Can't re-run when code changes
|
|
223
234
|
- Easy to forget cases under pressure
|
|
@@ -228,6 +239,7 @@ Automated tests are systematic. They run the same way every time.
|
|
|
228
239
|
**"Deleting X hours of work is wasteful"**
|
|
229
240
|
|
|
230
241
|
Sunk cost fallacy. The time is already gone. Your choice now:
|
|
242
|
+
|
|
231
243
|
- Delete and rewrite with TDD (X more hours, high confidence)
|
|
232
244
|
- Keep it and add tests after (30 min, low confidence, likely bugs)
|
|
233
245
|
|
|
@@ -236,6 +248,7 @@ The "waste" is keeping code you can't trust. Working code without real tests is
|
|
|
236
248
|
**"TDD is dogmatic, being pragmatic means adapting"**
|
|
237
249
|
|
|
238
250
|
TDD IS pragmatic:
|
|
251
|
+
|
|
239
252
|
- Finds bugs before commit (faster than debugging after)
|
|
240
253
|
- Prevents regressions (tests catch breaks immediately)
|
|
241
254
|
- Documents behavior (tests show how to use code)
|
|
@@ -255,19 +268,19 @@ Tests-first force edge case discovery before implementing. Tests-after verify yo
|
|
|
255
268
|
|
|
256
269
|
## Common Rationalizations
|
|
257
270
|
|
|
258
|
-
| Excuse
|
|
259
|
-
|
|
260
|
-
| "Too simple to test"
|
|
261
|
-
| "I'll test after"
|
|
262
|
-
| "Tests after achieve same goals"
|
|
263
|
-
| "Already manually tested"
|
|
264
|
-
| "Deleting X hours is wasteful"
|
|
265
|
-
| "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete.
|
|
266
|
-
| "Need to explore first"
|
|
267
|
-
| "Test hard = design unclear"
|
|
268
|
-
| "TDD will slow me down"
|
|
269
|
-
| "Manual test faster"
|
|
270
|
-
| "Existing code has no tests"
|
|
271
|
+
| Excuse | Reality |
|
|
272
|
+
| -------------------------------------- | ----------------------------------------------------------------------- |
|
|
273
|
+
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
|
|
274
|
+
| "I'll test after" | Tests passing immediately prove nothing. |
|
|
275
|
+
| "Tests after achieve same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" |
|
|
276
|
+
| "Already manually tested" | Ad-hoc ≠ systematic. No record, can't re-run. |
|
|
277
|
+
| "Deleting X hours is wasteful" | Sunk cost fallacy. Keeping unverified code is technical debt. |
|
|
278
|
+
| "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete. |
|
|
279
|
+
| "Need to explore first" | Fine. Throw away exploration, start with TDD. |
|
|
280
|
+
| "Test hard = design unclear" | Listen to test. Hard to test = hard to use. |
|
|
281
|
+
| "TDD will slow me down" | TDD faster than debugging. Pragmatic = test-first. |
|
|
282
|
+
| "Manual test faster" | Manual doesn't prove edge cases. You'll re-test every change. |
|
|
283
|
+
| "Existing code has no tests" | You're improving it. Add tests for existing code. |
|
|
271
284
|
|
|
272
285
|
## Red Flags - STOP and Start Over
|
|
273
286
|
|
|
@@ -292,30 +305,34 @@ Tests-first force edge case discovery before implementing. Tests-after verify yo
|
|
|
292
305
|
**Bug:** Empty email accepted
|
|
293
306
|
|
|
294
307
|
**RED**
|
|
308
|
+
|
|
295
309
|
```typescript
|
|
296
|
-
test(
|
|
297
|
-
const result = await submitForm({ email:
|
|
298
|
-
expect(result.error).toBe(
|
|
310
|
+
test("rejects empty email", async () => {
|
|
311
|
+
const result = await submitForm({ email: "" });
|
|
312
|
+
expect(result.error).toBe("Email required");
|
|
299
313
|
});
|
|
300
314
|
```
|
|
301
315
|
|
|
302
316
|
**Verify RED**
|
|
317
|
+
|
|
303
318
|
```bash
|
|
304
319
|
$ npm test
|
|
305
320
|
FAIL: expected 'Email required', got undefined
|
|
306
321
|
```
|
|
307
322
|
|
|
308
323
|
**GREEN**
|
|
324
|
+
|
|
309
325
|
```typescript
|
|
310
326
|
function submitForm(data: FormData) {
|
|
311
327
|
if (!data.email?.trim()) {
|
|
312
|
-
return { error:
|
|
328
|
+
return { error: "Email required" };
|
|
313
329
|
}
|
|
314
330
|
// ...
|
|
315
331
|
}
|
|
316
332
|
```
|
|
317
333
|
|
|
318
334
|
**Verify GREEN**
|
|
335
|
+
|
|
319
336
|
```bash
|
|
320
337
|
$ npm test
|
|
321
338
|
PASS
|
|
@@ -341,12 +358,12 @@ Can't check all boxes? You skipped TDD. Start over.
|
|
|
341
358
|
|
|
342
359
|
## When Stuck
|
|
343
360
|
|
|
344
|
-
| Problem
|
|
345
|
-
|
|
361
|
+
| Problem | Solution |
|
|
362
|
+
| ---------------------- | -------------------------------------------------------------------- |
|
|
346
363
|
| Don't know how to test | Write wished-for API. Write assertion first. Ask your human partner. |
|
|
347
|
-
| Test too complicated
|
|
348
|
-
| Must mock everything
|
|
349
|
-
| Test setup huge
|
|
364
|
+
| Test too complicated | Design too complicated. Simplify interface. |
|
|
365
|
+
| Must mock everything | Code too coupled. Use dependency injection. |
|
|
366
|
+
| Test setup huge | Extract helpers. Still complex? Simplify design. |
|
|
350
367
|
|
|
351
368
|
## Debugging Integration
|
|
352
369
|
|