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.
Files changed (95) hide show
  1. package/README.md +2 -2
  2. package/dist/index.js +100 -58
  3. package/dist/template/.opencode/.env.example +1 -0
  4. package/dist/template/.opencode/AGENTS.md +13 -24
  5. package/dist/template/.opencode/README.md +8 -119
  6. package/dist/template/.opencode/agent/explore.md +2 -3
  7. package/dist/template/.opencode/agent/general.md +56 -0
  8. package/dist/template/.opencode/agent/plan.md +54 -0
  9. package/dist/template/.opencode/agent/scout.md +15 -5
  10. package/dist/template/.opencode/command/analyze-project.md +2 -2
  11. package/dist/template/.opencode/command/brainstorm.md +1 -1
  12. package/dist/template/.opencode/command/design-audit.md +4 -5
  13. package/dist/template/.opencode/command/design.md +4 -13
  14. package/dist/template/.opencode/command/generate-pattern.md +2 -9
  15. package/dist/template/.opencode/command/implement.md +4 -4
  16. package/dist/template/.opencode/command/init.md +1 -1
  17. package/dist/template/.opencode/command/new-feature.md +2 -3
  18. package/dist/template/.opencode/command/plan.md +1 -1
  19. package/dist/template/.opencode/command/pr.md +0 -1
  20. package/dist/template/.opencode/command/research.md +20 -6
  21. package/dist/template/.opencode/command/restore-image.md +1 -9
  22. package/dist/template/.opencode/command/revert-feature.md +1 -1
  23. package/dist/template/.opencode/command/review-codebase.md +4 -4
  24. package/dist/template/.opencode/command/status.md +1 -2
  25. package/dist/template/.opencode/command/summarize.md +1 -2
  26. package/dist/template/.opencode/command/triage.md +4 -32
  27. package/dist/template/.opencode/dcp.jsonc +68 -68
  28. package/dist/template/.opencode/memory/_templates/README.md +35 -0
  29. package/dist/template/.opencode/memory/_templates/project/architecture.md +60 -0
  30. package/dist/template/.opencode/memory/_templates/project/commands.md +72 -0
  31. package/dist/template/.opencode/memory/_templates/project/conventions.md +68 -0
  32. package/dist/template/.opencode/memory/_templates/project/gotchas.md +41 -0
  33. package/dist/template/.opencode/memory/beads-workflow.md +30 -29
  34. package/dist/template/.opencode/memory/project/architecture.md +31 -50
  35. package/dist/template/.opencode/memory/project/commands.md +41 -22
  36. package/dist/template/.opencode/memory/project/conventions.md +39 -177
  37. package/dist/template/.opencode/memory/project/gotchas.md +21 -177
  38. package/dist/template/.opencode/memory/user.example.md +5 -0
  39. package/dist/template/.opencode/opencode.json +644 -579
  40. package/dist/template/.opencode/package.json +18 -21
  41. package/dist/template/.opencode/plugin/compaction.ts +79 -85
  42. package/dist/template/.opencode/plugin/env-ctx.ts +19 -19
  43. package/dist/template/.opencode/plugin/lib/notify.ts +41 -45
  44. package/dist/template/.opencode/plugin/lsp.ts +197 -200
  45. package/dist/template/.opencode/plugin/memory.ts +14 -112
  46. package/dist/template/.opencode/plugin/package.json +5 -5
  47. package/dist/template/.opencode/plugin/sessions.ts +1 -1
  48. package/dist/template/.opencode/plugin/skill-mcp.ts +486 -521
  49. package/dist/template/.opencode/plugin/truncator.ts +47 -50
  50. package/dist/template/.opencode/plugin/tsconfig.json +14 -14
  51. package/dist/template/.opencode/skill/chrome-devtools/mcp.json +17 -17
  52. package/dist/template/.opencode/skill/condition-based-waiting/SKILL.md +17 -12
  53. package/dist/template/.opencode/skill/condition-based-waiting/example.ts +63 -69
  54. package/dist/template/.opencode/skill/defense-in-depth/SKILL.md +14 -8
  55. package/dist/template/.opencode/skill/dispatching-parallel-agents/SKILL.md +14 -3
  56. package/dist/template/.opencode/skill/playwright/mcp.json +14 -14
  57. package/dist/template/.opencode/skill/receiving-code-review/SKILL.md +21 -8
  58. package/dist/template/.opencode/skill/requesting-code-review/review.md +14 -0
  59. package/dist/template/.opencode/skill/root-cause-tracing/SKILL.md +18 -4
  60. package/dist/template/.opencode/skill/source-code-research/SKILL.md +9 -7
  61. package/dist/template/.opencode/skill/test-driven-development/SKILL.md +49 -32
  62. package/dist/template/.opencode/skill/testing-anti-patterns/SKILL.md +40 -22
  63. package/dist/template/.opencode/skill/testing-skills-with-subagents/SKILL.md +46 -26
  64. package/dist/template/.opencode/skill/tool-priority/SKILL.md +117 -44
  65. package/dist/template/.opencode/skill/v0/SKILL.md +1 -7
  66. package/dist/template/.opencode/skill/verification-before-completion/SKILL.md +27 -19
  67. package/dist/template/.opencode/skill/writing-skills/anthropic-best-practices.md +171 -148
  68. package/dist/template/.opencode/skill/writing-skills/persuasion-principles.md +39 -6
  69. package/dist/template/.opencode/tool/memory-read.ts +44 -56
  70. package/dist/template/.opencode/tool/memory-search.ts +8 -291
  71. package/dist/template/.opencode/tool/memory-update.ts +47 -51
  72. package/dist/template/.opencode/tool/observation.ts +6 -180
  73. package/dist/template/.opencode/tsconfig.json +19 -19
  74. package/package.json +19 -15
  75. package/dist/template/.opencode/.background-tasks.json +0 -114
  76. package/dist/template/.opencode/.ralph-state.json +0 -12
  77. package/dist/template/.opencode/agent/build.md +0 -327
  78. package/dist/template/.opencode/agent/ninja.md +0 -351
  79. package/dist/template/.opencode/agent/planner.md +0 -281
  80. package/dist/template/.opencode/agent/rush.md +0 -223
  81. package/dist/template/.opencode/memory/handoffs/README.md +0 -83
  82. package/dist/template/.opencode/memory/observations/.gitkeep +0 -0
  83. package/dist/template/.opencode/memory/observations/2026-01-09-pattern-ampcode-mcp-json-includetools-pattern.md +0 -42
  84. package/dist/template/.opencode/memory/vector_db/memories.lance/_transactions/0-0d25ba80-ba3b-4209-9046-b45d6093b4da.txn +0 -0
  85. package/dist/template/.opencode/memory/vector_db/memories.lance/_versions/1.manifest +0 -0
  86. package/dist/template/.opencode/memory/vector_db/memories.lance/data/1111100101010101011010004a9ef34df6b29f36a9a53a2892.lance +0 -0
  87. package/dist/template/.opencode/tool/ast-grep.ts +0 -245
  88. package/dist/template/.opencode/tool/background.ts +0 -509
  89. package/dist/template/.opencode/tool/bd-inbox.ts +0 -110
  90. package/dist/template/.opencode/tool/bd-msg.ts +0 -62
  91. package/dist/template/.opencode/tool/bd-release.ts +0 -71
  92. package/dist/template/.opencode/tool/bd-reserve.ts +0 -121
  93. package/dist/template/.opencode/tool/memory-embed.ts +0 -183
  94. package/dist/template/.opencode/tool/memory-index.ts +0 -769
  95. 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 | Fix |
167
- |---------|-----|
168
- | Performative agreement | State requirement or just act |
169
- | Blind implementation | Verify against codebase first |
170
- | Batch without testing | One at a time, test each |
171
- | Assuming reviewer is right | Check if breaks things |
172
- | Avoiding pushback | Technical correctness > comfort |
173
- | Partial implementation | Clarify all items first |
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('git', ['init'], { cwd: projectDir });
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('name', context.tempDir); // Accessed before beforeEach!
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('DEBUG git init:', {
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('git', ['init'], { cwd: directory });
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 the code you need:
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
- // Use AST search for precise patterns
103
- ast_grep({
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
- ast_grep({
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/ast-grep to find relevant code first, then read.
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
- const result = await retryOperation(operation);
88
+ const result = await retryOperation(operation);
86
89
 
87
- expect(result).toBe('success');
88
- expect(attempts).toBe(3);
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 | Good | Bad |
201
- |---------|------|-----|
202
- | **Minimal** | One thing. "and" in name? Split it. | `test('validates email and domain and whitespace')` |
203
- | **Clear** | Name describes behavior | `test('test1')` |
204
- | **Shows intent** | Demonstrates desired API | Obscures what code should do |
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 | Reality |
259
- |--------|---------|
260
- | "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
261
- | "I'll test after" | Tests passing immediately prove nothing. |
262
- | "Tests after achieve same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" |
263
- | "Already manually tested" | Ad-hoc ≠ systematic. No record, can't re-run. |
264
- | "Deleting X hours is wasteful" | Sunk cost fallacy. Keeping unverified code is technical debt. |
265
- | "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete. |
266
- | "Need to explore first" | Fine. Throw away exploration, start with TDD. |
267
- | "Test hard = design unclear" | Listen to test. Hard to test = hard to use. |
268
- | "TDD will slow me down" | TDD faster than debugging. Pragmatic = test-first. |
269
- | "Manual test faster" | Manual doesn't prove edge cases. You'll re-test every change. |
270
- | "Existing code has no tests" | You're improving it. Add tests for existing code. |
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('rejects empty email', async () => {
297
- const result = await submitForm({ email: '' });
298
- expect(result.error).toBe('Email required');
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: 'Email required' };
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 | Solution |
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 | Design too complicated. Simplify interface. |
348
- | Must mock everything | Code too coupled. Use dependency injection. |
349
- | Test setup huge | Extract helpers. Still complex? Simplify design. |
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