tdd-claude-code 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jurgen Calleja
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # TDD Workflow for Claude Code
2
+
3
+ Test-Led Development powered by [GSD](https://github.com/glittercowboy/get-shit-done).
4
+
5
+ **One interface. Tests happen automatically. You don't think about methodology.**
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npx tdd-claude-code
11
+ ```
12
+
13
+ GSD is installed automatically if missing.
14
+
15
+ Options:
16
+ ```bash
17
+ npx tdd-claude-code --global # available in all projects
18
+ npx tdd-claude-code --local # this project only
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ You use `/tdd:*` commands for everything. Never touch `/gsd:*` directly.
24
+
25
+ ```
26
+ /tdd:new-project Describe your idea, get test infrastructure
27
+
28
+ /tdd:discuss 1 Shape how phase 1 gets built
29
+ /tdd:plan 1 Create task plans
30
+ /tdd:build 1 Write tests → implement → tests pass ← TDD happens here
31
+ /tdd:verify 1 Human acceptance testing
32
+
33
+ ...repeat for each phase...
34
+
35
+ /tdd:complete Tag release
36
+ ```
37
+
38
+ ## What `/tdd:build` Does
39
+
40
+ This is where the magic happens:
41
+
42
+ 1. **Red** — Spawns agents to write failing tests for each task
43
+ 2. **Verify** — Runs tests, confirms they fail (code doesn't exist yet)
44
+ 3. **Green** — Calls GSD to implement (you walk away)
45
+ 4. **Verify** — Runs tests, confirms they pass
46
+
47
+ You run one command. Tests get written before code. Automatically.
48
+
49
+ ## Commands
50
+
51
+ | Command | What It Does |
52
+ |---------|--------------|
53
+ | `/tdd:new-project` | Start project with test infrastructure |
54
+ | `/tdd:discuss [N]` | Capture implementation preferences |
55
+ | `/tdd:plan [N]` | Create task plans |
56
+ | `/tdd:build <N>` | **Write tests → implement → verify** |
57
+ | `/tdd:verify [N]` | Human acceptance testing |
58
+ | `/tdd:status [N]` | Check test pass/fail |
59
+ | `/tdd:progress` | Where am I? |
60
+ | `/tdd:quick` | Ad-hoc task with tests |
61
+ | `/tdd:complete` | Tag release |
62
+ | `/tdd:new-milestone` | Start next version |
63
+ | `/tdd:help` | Show all commands |
64
+
65
+ ## For Vibe Coders
66
+
67
+ No existing codebase? No problem.
68
+
69
+ `/tdd:new-project` detects your stack and sets up the test framework:
70
+
71
+ | Stack | Framework |
72
+ |-------|-----------|
73
+ | Next.js / React | Vitest |
74
+ | Node.js | Vitest |
75
+ | Python | pytest |
76
+ | Go | go test |
77
+ | Ruby | RSpec |
78
+
79
+ You describe what you want. Tests and code get written. You verify it works.
80
+
81
+ ## Why TDD?
82
+
83
+ **Without TDD:**
84
+ ```
85
+ Plan → Implement → "Does it work?" → Debug → Repeat
86
+ ```
87
+
88
+ **With TDD:**
89
+ ```
90
+ Plan → Write tests (spec) → Implement (pass tests) → Verify
91
+ ```
92
+
93
+ Tests define expected behavior BEFORE code exists. Implementation has concrete pass/fail targets. Bugs surface immediately, not during manual testing.
94
+
95
+ Human verification still happens — tests catch logic errors, you catch "not what I meant" issues.
96
+
97
+ ## Safe from GSD Updates
98
+
99
+ TDD lives in `.claude/commands/tdd/`
100
+ GSD lives in `.claude/commands/gsd/`
101
+
102
+ Running `npx get-shit-done-cc@latest` only touches GSD. Your TDD commands are untouched.
103
+
104
+ ## License
105
+
106
+ MIT
package/bin/install.js ADDED
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+ const readline = require('readline');
7
+
8
+ const COMMANDS = [
9
+ 'new-project.md',
10
+ 'discuss.md',
11
+ 'plan.md',
12
+ 'build.md',
13
+ 'verify.md',
14
+ 'status.md',
15
+ 'progress.md',
16
+ 'complete.md',
17
+ 'new-milestone.md',
18
+ 'quick.md',
19
+ 'help.md'
20
+ ];
21
+
22
+ function getGlobalDir() {
23
+ const claudeConfig = process.env.CLAUDE_CONFIG_DIR || path.join(require('os').homedir(), '.claude');
24
+ return path.join(claudeConfig, 'commands');
25
+ }
26
+
27
+ function getLocalDir() {
28
+ return path.join(process.cwd(), '.claude', 'commands');
29
+ }
30
+
31
+ function checkGsd(gsdDir, installType) {
32
+ if (!fs.existsSync(gsdDir)) {
33
+ console.log('');
34
+ console.log(`GSD dependency not found at ${gsdDir}`);
35
+ console.log('TDD requires GSD to function.');
36
+ console.log('');
37
+ console.log(`Installing GSD (${installType})...`);
38
+ try {
39
+ execSync('npx --yes get-shit-done-cc@latest', { stdio: 'inherit' });
40
+ } catch (e) {
41
+ // GSD installer may exit with error but still install
42
+ }
43
+ console.log('');
44
+ if (!fs.existsSync(gsdDir)) {
45
+ console.log('GSD not found at expected location after install.');
46
+ console.log(`Ensure GSD is installed to: ${gsdDir}`);
47
+ console.log('Then re-run this installer.');
48
+ process.exit(1);
49
+ }
50
+ console.log('GSD installed');
51
+ console.log('');
52
+ }
53
+ }
54
+
55
+ function install(targetDir, installType) {
56
+ const commandsDir = path.join(targetDir, 'tdd');
57
+ const gsdDir = path.join(targetDir, 'gsd');
58
+
59
+ // Check GSD dependency
60
+ checkGsd(gsdDir, installType);
61
+
62
+ // Create directory
63
+ fs.mkdirSync(commandsDir, { recursive: true });
64
+
65
+ // Copy command files
66
+ const sourceDir = path.join(__dirname, '..');
67
+ for (const file of COMMANDS) {
68
+ const src = path.join(sourceDir, file);
69
+ const dest = path.join(commandsDir, file);
70
+ if (fs.existsSync(src)) {
71
+ fs.copyFileSync(src, dest);
72
+ }
73
+ }
74
+
75
+ console.log('');
76
+ console.log(`TDD commands installed to ${commandsDir}`);
77
+ console.log('');
78
+ console.log('Restart Claude Code to load new commands.');
79
+ console.log('');
80
+ console.log('Workflow:');
81
+ console.log(' /tdd:new-project Start project with test infrastructure');
82
+ console.log(' /tdd:discuss 1 Shape implementation preferences');
83
+ console.log(' /tdd:plan 1 Create task plans');
84
+ console.log(' /tdd:build 1 Write tests -> implement -> verify');
85
+ console.log(' /tdd:verify 1 Human acceptance testing');
86
+ console.log('');
87
+ console.log('Run /tdd:help for full command list.');
88
+ }
89
+
90
+ async function main() {
91
+ const args = process.argv.slice(2);
92
+
93
+ if (args.includes('--global') || args.includes('-g')) {
94
+ console.log(`Installing globally to ${getGlobalDir()}/tdd`);
95
+ install(getGlobalDir(), 'global');
96
+ return;
97
+ }
98
+
99
+ if (args.includes('--local') || args.includes('-l')) {
100
+ console.log(`Installing locally to ${getLocalDir()}/tdd`);
101
+ install(getLocalDir(), 'local');
102
+ return;
103
+ }
104
+
105
+ // Interactive prompt
106
+ const rl = readline.createInterface({
107
+ input: process.stdin,
108
+ output: process.stdout
109
+ });
110
+
111
+ console.log('TDD Workflow Installer');
112
+ console.log('');
113
+ console.log('Where would you like to install?');
114
+ console.log(' 1) Global (~/.claude/commands/tdd) - available in all projects');
115
+ console.log(' 2) Local (./.claude/commands/tdd) - this project only');
116
+ console.log('');
117
+
118
+ rl.question('Choice [1/2]: ', (answer) => {
119
+ rl.close();
120
+ if (answer === '2') {
121
+ install(getLocalDir(), 'local');
122
+ } else {
123
+ install(getGlobalDir(), 'global');
124
+ }
125
+ });
126
+ }
127
+
128
+ main();
package/build.md ADDED
@@ -0,0 +1,292 @@
1
+ # /tdd:build - Build a Phase (Test-First)
2
+
3
+ Write failing tests, then implement to make them pass.
4
+
5
+ ## What This Does
6
+
7
+ 1. **Write failing tests** for all tasks in the phase
8
+ 2. **Verify tests fail** (Red)
9
+ 3. **Call `/gsd:execute-phase`** to implement (Green)
10
+ 4. **Verify tests pass** after execution
11
+
12
+ This is the core TDD command. Tests before code, automatically.
13
+
14
+ ## Usage
15
+
16
+ ```
17
+ /tdd:build <phase_number>
18
+ ```
19
+
20
+ ## Process
21
+
22
+ ### Step 1: Load Plans
23
+
24
+ Read all `.planning/phases/{phase}-*-PLAN.md` files for this phase.
25
+
26
+ ### Step 2: Detect Test Framework
27
+
28
+ Check what's already set up:
29
+ - `vitest.config.*` → Vitest
30
+ - `jest.config.*` → Jest
31
+ - `pytest.ini` or `pyproject.toml` with pytest → pytest
32
+ - `spec/` directory → RSpec
33
+ - None found → Set up based on PROJECT.md stack (see framework defaults below)
34
+
35
+ ### Step 3: Write Tests (Spawn Test Writer Agents)
36
+
37
+ For each plan, spawn an agent with this prompt:
38
+
39
+ <agent_prompt>
40
+ You are a TDD Test Writer. Write failing tests that define expected behavior BEFORE implementation.
41
+
42
+ ## Context
43
+
44
+ <project>
45
+ {PROJECT.md contents}
46
+ </project>
47
+
48
+ <plan>
49
+ {Current PLAN.md contents}
50
+ </plan>
51
+
52
+ <test_framework>
53
+ {Detected or default framework}
54
+ </test_framework>
55
+
56
+ <existing_tests>
57
+ {List any existing test files for patterns, or "None - this is a new project"}
58
+ </existing_tests>
59
+
60
+ ## Your Task
61
+
62
+ For each `<task>` in the plan:
63
+
64
+ 1. **Understand the task** — What behavior is being specified?
65
+
66
+ 2. **Write test file(s)** that cover:
67
+ - Happy path (expected inputs → expected outputs)
68
+ - Edge cases mentioned in `<action>`
69
+ - Error conditions from `<verify>`
70
+
71
+ 3. **Make tests runnable NOW** — even though implementation doesn't exist:
72
+ - Import from where the code WILL be (path in `<files>`)
73
+ - Tests should FAIL, not ERROR from missing imports
74
+ - Use mocks/stubs where needed for dependencies
75
+
76
+ 4. **Use clear test names** that describe expected behavior:
77
+ ```
78
+ ✓ "user can log in with valid credentials"
79
+ ✓ "login rejects invalid password with 401"
80
+ ✓ "login returns httpOnly cookie on success"
81
+ ✗ "test login" (too vague)
82
+ ```
83
+
84
+ ## Test File Patterns
85
+
86
+ **Vitest/Jest (TypeScript):**
87
+ ```typescript
88
+ import { describe, it, expect } from 'vitest'
89
+ // Import from where code WILL exist
90
+ import { login } from '../src/auth/login'
91
+
92
+ describe('login', () => {
93
+ it('returns user object for valid credentials', async () => {
94
+ const result = await login('user@test.com', 'password123')
95
+ expect(result.user).toBeDefined()
96
+ expect(result.user.email).toBe('user@test.com')
97
+ })
98
+
99
+ it('throws AuthError for invalid password', async () => {
100
+ await expect(login('user@test.com', 'wrong'))
101
+ .rejects.toThrow('Invalid credentials')
102
+ })
103
+ })
104
+ ```
105
+
106
+ **pytest (Python):**
107
+ ```python
108
+ import pytest
109
+ # Import from where code WILL exist
110
+ from src.auth import login
111
+
112
+ def test_login_returns_user_for_valid_credentials():
113
+ result = login("user@test.com", "password123")
114
+ assert result["user"]["email"] == "user@test.com"
115
+
116
+ def test_login_raises_for_invalid_password():
117
+ with pytest.raises(AuthError, match="Invalid credentials"):
118
+ login("user@test.com", "wrong")
119
+ ```
120
+
121
+ ## Output
122
+
123
+ Create test files following the project's structure. Common locations:
124
+ - `tests/{feature}.test.ts`
125
+ - `src/{feature}/__tests__/{feature}.test.ts`
126
+ - `tests/test_{feature}.py`
127
+ - `spec/{feature}_spec.rb`
128
+
129
+ After creating each test file, run it and confirm it FAILS (not errors).
130
+
131
+ ## Critical Rules
132
+
133
+ - Tests must be **syntactically valid** and **runnable**
134
+ - Tests must **FAIL** because code doesn't exist yet
135
+ - Tests must NOT **ERROR** from import issues — mock if needed
136
+ - Do NOT write any implementation code
137
+ - Do NOT skip or stub out the actual assertions
138
+ </agent_prompt>
139
+
140
+ ### Step 4: Verify All Tests Fail (Red)
141
+
142
+ Run the test suite:
143
+ ```bash
144
+ npm test # or vitest run, pytest, etc.
145
+ ```
146
+
147
+ Check output:
148
+ - ✅ All new tests executed (no syntax errors)
149
+ - ✅ All new tests FAILED (not passed, not skipped)
150
+ - ❌ If tests error on imports, add mocks and retry
151
+ - ❌ If tests pass, something's wrong — investigate
152
+
153
+ ### Step 5: Create Test Summary
154
+
155
+ Create `.planning/phases/{phase}-TESTS.md`:
156
+
157
+ ```markdown
158
+ # Phase {N} Tests
159
+
160
+ Generated: {timestamp}
161
+ Status: ✅ All tests failing (Red)
162
+
163
+ ## Test Files
164
+
165
+ | File | Tests | Status |
166
+ |------|-------|--------|
167
+ | tests/auth.test.ts | 4 | ❌ Failing |
168
+ | tests/session.test.ts | 3 | ❌ Failing |
169
+
170
+ ## Test Output
171
+
172
+ {test runner output showing failures}
173
+
174
+ ## Coverage Map
175
+
176
+ | Test | Task |
177
+ |------|------|
178
+ | user can log in with valid credentials | 01-task-1 |
179
+ | login rejects invalid password | 01-task-1 |
180
+ | session persists across requests | 01-task-2 |
181
+ ```
182
+
183
+ ### Step 6: Execute Implementation (Green)
184
+
185
+ Call `/gsd:execute-phase {phase_number}`
186
+
187
+ GSD's executor implements the code. Tests provide concrete pass/fail targets.
188
+
189
+ ### Step 7: Verify All Tests Pass (Green)
190
+
191
+ After execution completes, run tests again:
192
+ ```bash
193
+ npm test
194
+ ```
195
+
196
+ Check output:
197
+ - ✅ All tests PASS → Continue to verify
198
+ - ❌ Some tests fail → Report which tasks need fixes
199
+
200
+ ### Step 8: Update Test Summary
201
+
202
+ Update `.planning/phases/{phase}-TESTS.md`:
203
+
204
+ ```markdown
205
+ Status: ✅ All tests passing (Green)
206
+
207
+ ## Final Test Output
208
+
209
+ {test runner output showing all pass}
210
+ ```
211
+
212
+ ## Framework Defaults (for new projects)
213
+
214
+ If no test framework detected, set up based on PROJECT.md:
215
+
216
+ | Stack in PROJECT.md | Framework | Setup |
217
+ |---------------------|-----------|-------|
218
+ | Next.js, React, Vite | Vitest | `npm install -D vitest`, create `vitest.config.ts` |
219
+ | Node.js, Express | Vitest | `npm install -D vitest`, create `vitest.config.ts` |
220
+ | Python, FastAPI, Flask | pytest | `pip install pytest`, create `pytest.ini` |
221
+ | Go | go test | Built-in, create `*_test.go` files |
222
+ | Ruby, Rails | RSpec | `gem install rspec`, `rspec --init` |
223
+
224
+ Default Vitest config:
225
+ ```typescript
226
+ import { defineConfig } from 'vitest/config'
227
+
228
+ export default defineConfig({
229
+ test: {
230
+ globals: true,
231
+ environment: 'node', // or 'jsdom' for React
232
+ },
233
+ })
234
+ ```
235
+
236
+ Default pytest.ini:
237
+ ```ini
238
+ [pytest]
239
+ testpaths = tests
240
+ python_files = test_*.py
241
+ python_functions = test_*
242
+ ```
243
+
244
+ ## Example Run
245
+
246
+ ```
247
+ User: /tdd:build 1
248
+
249
+ Claude: Loading phase 1 plans...
250
+ Found 2 plans:
251
+ - 01-01-PLAN.md: User authentication
252
+ - 01-02-PLAN.md: Session management
253
+
254
+ Checking test framework... Vitest detected.
255
+
256
+ Writing tests for 01-01-PLAN.md...
257
+ Created: tests/auth/login.test.ts (4 tests)
258
+ Created: tests/auth/logout.test.ts (2 tests)
259
+
260
+ Writing tests for 01-02-PLAN.md...
261
+ Created: tests/session/session.test.ts (5 tests)
262
+
263
+ Running tests...
264
+ ❌ 11 tests failing (expected - no implementation yet)
265
+
266
+ Created 01-TESTS.md
267
+
268
+ Executing implementation via GSD...
269
+ [GSD execute-phase output]
270
+
271
+ Running tests again...
272
+ ✅ 11 tests passing
273
+
274
+ Phase 1 complete. Ready for /tdd:verify 1
275
+ ```
276
+
277
+ ## Error Recovery
278
+
279
+ **Tests error instead of fail:**
280
+ - Missing imports → Add mocks for dependencies
281
+ - Syntax errors → Fix test code
282
+ - Framework issues → Check config
283
+
284
+ **Tests pass before implementation:**
285
+ - Code already exists? Check if reimplementing
286
+ - Tests too weak? Strengthen assertions
287
+ - Wrong file paths? Check imports
288
+
289
+ **Some tests fail after implementation:**
290
+ - Report specific failures
291
+ - Suggest running `/tdd:build {phase}` again to retry
292
+ - Or manually fix and run `/tdd:status` to verify
package/complete.md ADDED
@@ -0,0 +1,23 @@
1
+ # /tdd:complete - Complete Milestone
2
+
3
+ Archive current milestone and tag the release.
4
+
5
+ ## What This Does
6
+
7
+ 1. **Verify all tests pass** for all phases
8
+ 2. **Call `/gsd:complete-milestone`**
9
+
10
+ ## Usage
11
+
12
+ ```
13
+ /tdd:complete
14
+ ```
15
+
16
+ ## Process
17
+
18
+ Before completing:
19
+ - Runs full test suite
20
+ - If any failures → Block completion, show what needs fixing
21
+ - If all pass → Proceed with GSD milestone completion
22
+
23
+ This ensures you don't tag a release with failing tests.
package/discuss.md ADDED
@@ -0,0 +1,21 @@
1
+ # /tdd:discuss - Discuss Phase Implementation
2
+
3
+ Capture your implementation preferences before planning.
4
+
5
+ ## What This Does
6
+
7
+ Calls `/gsd:discuss-phase` — no TDD-specific logic needed here.
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ /tdd:discuss [phase_number]
13
+ ```
14
+
15
+ ## Example
16
+
17
+ ```
18
+ /tdd:discuss 1
19
+ ```
20
+
21
+ This is where you shape HOW the phase gets built — layout preferences, interaction patterns, error handling approaches, etc. The output feeds into planning and test writing.
package/help.md ADDED
@@ -0,0 +1,95 @@
1
+ # /tdd:help - Test-Led Development Commands
2
+
3
+ TDD-first workflow powered by GSD. You use `/tdd:*` for everything — tests happen automatically.
4
+
5
+ ## Commands
6
+
7
+ ### Core Workflow
8
+
9
+ | Command | What It Does |
10
+ |---------|--------------|
11
+ | `/tdd:new-project` | Start new project with test infrastructure |
12
+ | `/tdd:discuss [N]` | Capture implementation preferences for phase N |
13
+ | `/tdd:plan [N]` | Research and create task plans for phase N |
14
+ | `/tdd:build <N>` | **Write tests → implement → verify tests pass** |
15
+ | `/tdd:verify [N]` | Human acceptance testing |
16
+
17
+ ### Navigation
18
+
19
+ | Command | What It Does |
20
+ |---------|--------------|
21
+ | `/tdd:progress` | Where am I? What's next? |
22
+ | `/tdd:status [N]` | Check test pass/fail counts |
23
+ | `/tdd:help` | Show this help |
24
+
25
+ ### Milestones
26
+
27
+ | Command | What It Does |
28
+ |---------|--------------|
29
+ | `/tdd:complete` | Archive milestone, tag release |
30
+ | `/tdd:new-milestone [name]` | Start next version |
31
+
32
+ ### Quick Tasks
33
+
34
+ | Command | What It Does |
35
+ |---------|--------------|
36
+ | `/tdd:quick` | Ad-hoc task with test-first flow |
37
+
38
+ ## Workflow
39
+
40
+ ```
41
+ /tdd:new-project Describe your idea, set up project + tests
42
+
43
+ /tdd:discuss 1 Shape how phase 1 gets built
44
+ /tdd:plan 1 Create task plans
45
+ /tdd:build 1 Write tests → implement → tests pass
46
+ /tdd:verify 1 Human acceptance testing
47
+
48
+ /tdd:discuss 2 Repeat for each phase...
49
+ /tdd:plan 2
50
+ /tdd:build 2
51
+ /tdd:verify 2
52
+
53
+ /tdd:complete Tag release
54
+ /tdd:new-milestone Start v2
55
+ ```
56
+
57
+ ## What Happens in `/tdd:build`
58
+
59
+ This is where TDD happens:
60
+
61
+ 1. **Red** — Write failing tests for each task in the plan
62
+ 2. **Verify** — Run tests, confirm they fail
63
+ 3. **Green** — Implement code (via GSD execute-phase)
64
+ 4. **Verify** — Run tests, confirm they pass
65
+
66
+ You don't think about it. Just run `/tdd:build` and tests happen before code.
67
+
68
+ ## Philosophy
69
+
70
+ **Tests define behavior. Implementation makes tests pass.**
71
+
72
+ - Tests are written BEFORE code exists
73
+ - Tests are the spec, not an afterthought
74
+ - Human verification still happens at the end
75
+ - You never invoke GSD directly — TDD wraps it
76
+
77
+ ## GSD Under the Hood
78
+
79
+ TDD commands call GSD internally:
80
+
81
+ | TDD Command | Calls |
82
+ |-------------|-------|
83
+ | `/tdd:new-project` | `/gsd:new-project` + test setup |
84
+ | `/tdd:discuss` | `/gsd:discuss-phase` |
85
+ | `/tdd:plan` | `/gsd:plan-phase` |
86
+ | `/tdd:build` | write tests + `/gsd:execute-phase` |
87
+ | `/tdd:verify` | test check + `/gsd:verify-work` |
88
+
89
+ GSD does the planning and execution. TDD ensures tests come first.
90
+
91
+ ## Installation
92
+
93
+ Lives in `.claude/commands/tdd/` — separate from GSD.
94
+
95
+ GSD updates only touch `.claude/commands/gsd/`. Your TDD commands survive updates.
package/install.sh ADDED
@@ -0,0 +1,97 @@
1
+ #!/bin/bash
2
+ # Install TDD workflow for Claude Code (wraps GSD)
3
+ # Usage: ./install.sh [--global | --local]
4
+
5
+ set -e
6
+
7
+ # Check for GSD dependency and install if missing
8
+ check_gsd() {
9
+ local gsd_dir="$1"
10
+ local install_type="$2"
11
+ if [[ ! -d "$gsd_dir" ]]; then
12
+ echo ""
13
+ echo "GSD dependency not found at $gsd_dir"
14
+ echo "TDD requires GSD to function."
15
+ echo ""
16
+ echo "Installing GSD ($install_type)..."
17
+ npx --yes get-shit-done-cc@latest
18
+ echo ""
19
+ if [[ ! -d "$gsd_dir" ]]; then
20
+ echo "❌ GSD not found at expected location after install."
21
+ echo " Ensure GSD is installed to: $gsd_dir"
22
+ echo " Then re-run this installer."
23
+ exit 1
24
+ fi
25
+ echo "✅ GSD installed"
26
+ echo ""
27
+ fi
28
+ }
29
+
30
+ # Determine install location
31
+ if [[ "$1" == "--global" || "$1" == "-g" ]]; then
32
+ INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/commands/tdd"
33
+ echo "Installing globally to $INSTALL_DIR"
34
+ elif [[ "$1" == "--local" || "$1" == "-l" ]]; then
35
+ INSTALL_DIR="./.claude/commands/tdd"
36
+ echo "Installing locally to $INSTALL_DIR"
37
+ else
38
+ echo "TDD Workflow Installer"
39
+ echo ""
40
+ echo "Where would you like to install?"
41
+ echo " 1) Global (~/.claude/commands/tdd) - available in all projects"
42
+ echo " 2) Local (./.claude/commands/tdd) - this project only"
43
+ echo ""
44
+ read -p "Choice [1/2]: " choice
45
+
46
+ if [[ "$choice" == "2" ]]; then
47
+ INSTALL_DIR="./.claude/commands/tdd"
48
+ else
49
+ INSTALL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/commands/tdd"
50
+ fi
51
+ fi
52
+
53
+ # Derive GSD location (sibling to tdd directory)
54
+ GSD_DIR="${INSTALL_DIR%/tdd}/gsd"
55
+
56
+ # Determine install type for messaging
57
+ if [[ "$INSTALL_DIR" == *"$HOME"* ]] || [[ "$INSTALL_DIR" == *"${CLAUDE_CONFIG_DIR:-}"* ]]; then
58
+ INSTALL_TYPE="global"
59
+ else
60
+ INSTALL_TYPE="local"
61
+ fi
62
+
63
+ # Check and install GSD if needed
64
+ check_gsd "$GSD_DIR" "$INSTALL_TYPE"
65
+
66
+ # Create directory
67
+ mkdir -p "$INSTALL_DIR"
68
+
69
+ # Get script directory
70
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
71
+
72
+ # Copy command files
73
+ cp "$SCRIPT_DIR/new-project.md" "$INSTALL_DIR/"
74
+ cp "$SCRIPT_DIR/discuss.md" "$INSTALL_DIR/"
75
+ cp "$SCRIPT_DIR/plan.md" "$INSTALL_DIR/"
76
+ cp "$SCRIPT_DIR/build.md" "$INSTALL_DIR/"
77
+ cp "$SCRIPT_DIR/verify.md" "$INSTALL_DIR/"
78
+ cp "$SCRIPT_DIR/status.md" "$INSTALL_DIR/"
79
+ cp "$SCRIPT_DIR/progress.md" "$INSTALL_DIR/"
80
+ cp "$SCRIPT_DIR/complete.md" "$INSTALL_DIR/"
81
+ cp "$SCRIPT_DIR/new-milestone.md" "$INSTALL_DIR/"
82
+ cp "$SCRIPT_DIR/quick.md" "$INSTALL_DIR/"
83
+ cp "$SCRIPT_DIR/help.md" "$INSTALL_DIR/"
84
+
85
+ echo ""
86
+ echo "✅ TDD commands installed to $INSTALL_DIR"
87
+ echo ""
88
+ echo "Restart Claude Code to load new commands."
89
+ echo ""
90
+ echo "Workflow:"
91
+ echo " /tdd:new-project Start project with test infrastructure"
92
+ echo " /tdd:discuss 1 Shape implementation preferences"
93
+ echo " /tdd:plan 1 Create task plans"
94
+ echo " /tdd:build 1 Write tests → implement → verify"
95
+ echo " /tdd:verify 1 Human acceptance testing"
96
+ echo ""
97
+ echo "Run /tdd:help for full command list."
@@ -0,0 +1,21 @@
1
+ # /tdd:new-milestone - Start Next Version
2
+
3
+ Begin the next milestone after completing the previous one.
4
+
5
+ ## What This Does
6
+
7
+ Calls `/gsd:new-milestone` — same flow as new-project but for an existing codebase.
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ /tdd:new-milestone [name]
13
+ ```
14
+
15
+ ## Example
16
+
17
+ ```
18
+ /tdd:new-milestone v2.0
19
+ ```
20
+
21
+ Starts the question → research → requirements → roadmap flow for your next version.
package/new-project.md ADDED
@@ -0,0 +1,56 @@
1
+ # /tdd:new-project - Start a New Project
2
+
3
+ Initialize a new project with test-led development.
4
+
5
+ ## What This Does
6
+
7
+ Calls `/gsd:new-project` with TDD conventions automatically added to PROJECT.md.
8
+
9
+ ## Process
10
+
11
+ 1. **Run GSD new-project flow**
12
+ - Questions → Research → Requirements → Roadmap
13
+
14
+ 2. **After PROJECT.md is created, append TDD conventions:**
15
+
16
+ ```markdown
17
+ ## Development Methodology: Test-Led Development
18
+
19
+ This project uses TDD. All implementation follows Red → Green → Refactor:
20
+
21
+ 1. **Red**: Write failing tests that define expected behavior
22
+ 2. **Green**: Write minimum code to make tests pass
23
+ 3. **Refactor**: Clean up while keeping tests green
24
+
25
+ Tests are written BEFORE implementation, not after.
26
+ ```
27
+
28
+ 3. **Detect or set up test framework** based on stack chosen during setup:
29
+
30
+ | Stack | Framework | Config |
31
+ |-------|-----------|--------|
32
+ | Next.js / React | Vitest | `vitest.config.ts` |
33
+ | Node.js | Vitest or Jest | `vitest.config.ts` |
34
+ | Python | pytest | `pytest.ini` or `pyproject.toml` |
35
+ | Go | go test | (built-in) |
36
+ | Ruby | RSpec | `.rspec`, `spec/spec_helper.rb` |
37
+
38
+ 4. **Create test directory structure** if it doesn't exist:
39
+ - `tests/` or `__tests__/` or `spec/` depending on convention
40
+ - Example test file showing project patterns
41
+
42
+ 5. **Add test script** to package.json / pyproject.toml / Makefile:
43
+ ```json
44
+ "scripts": {
45
+ "test": "vitest run",
46
+ "test:watch": "vitest"
47
+ }
48
+ ```
49
+
50
+ ## Usage
51
+
52
+ ```
53
+ /tdd:new-project
54
+ ```
55
+
56
+ Same interactive flow as GSD, but you end up with test infrastructure ready to go.
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "tdd-claude-code",
3
+ "version": "0.1.0",
4
+ "description": "TDD workflow for Claude Code - wraps GSD",
5
+ "bin": {
6
+ "tdd-claude-code": "./bin/install.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "*.md",
11
+ "install.sh"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/jurgencalleja/tdd.git"
16
+ },
17
+ "keywords": [
18
+ "claude",
19
+ "claude-code",
20
+ "tdd",
21
+ "test-driven-development",
22
+ "gsd"
23
+ ],
24
+ "author": "Jurgen Calleja",
25
+ "license": "MIT"
26
+ }
package/plan.md ADDED
@@ -0,0 +1,23 @@
1
+ # /tdd:plan - Plan a Phase
2
+
3
+ Research and create implementation plans for a phase.
4
+
5
+ ## What This Does
6
+
7
+ Calls `/gsd:plan-phase` — no TDD-specific logic needed here.
8
+
9
+ Plans are created as usual. Tests get written when you run `/tdd:build`.
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ /tdd:plan [phase_number]
15
+ ```
16
+
17
+ ## Example
18
+
19
+ ```
20
+ /tdd:plan 1
21
+ ```
22
+
23
+ Creates `{phase}-RESEARCH.md` and `{phase}-*-PLAN.md` files with task breakdowns.
package/progress.md ADDED
@@ -0,0 +1,28 @@
1
+ # /tdd:progress - Where Am I?
2
+
3
+ Check current project status and what's next.
4
+
5
+ ## What This Does
6
+
7
+ Calls `/gsd:progress` plus shows test status.
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ /tdd:progress
13
+ ```
14
+
15
+ ## Output Example
16
+
17
+ ```
18
+ Project: My App
19
+ Milestone: v1.0
20
+
21
+ Phase 1: User Auth ✅ Complete (tests: 11/11 passing)
22
+ Phase 2: Dashboard 🔄 In Progress (tests: 6/12 passing)
23
+ Phase 3: Settings ⏳ Not Started
24
+
25
+ Current: Phase 2, implementing task 3 of 5
26
+
27
+ Next action: /tdd:build 2 (continue implementation)
28
+ ```
package/quick.md ADDED
@@ -0,0 +1,52 @@
1
+ # /tdd:quick - Quick Task with Tests
2
+
3
+ For ad-hoc tasks that don't need full phase planning, but still deserve tests.
4
+
5
+ ## What This Does
6
+
7
+ 1. **Ask what you want to do**
8
+ 2. **Write a failing test** for it
9
+ 3. **Implement** to pass the test
10
+ 4. **Verify** test passes
11
+
12
+ Lighter weight than `/tdd:build`, but still test-first.
13
+
14
+ ## Usage
15
+
16
+ ```
17
+ /tdd:quick
18
+ ```
19
+
20
+ ## Example
21
+
22
+ ```
23
+ User: /tdd:quick
24
+
25
+ Claude: What do you want to do?
26
+
27
+ User: Add a dark mode toggle to settings
28
+
29
+ Claude: Writing test...
30
+
31
+ Created: tests/settings/dark-mode.test.ts
32
+ - toggles dark mode on click
33
+ - persists preference to localStorage
34
+ - applies dark class to document
35
+
36
+ Running test... ❌ Failing (expected)
37
+
38
+ Implementing...
39
+
40
+ Running test... ✅ Passing
41
+
42
+ Done. Dark mode toggle added with test coverage.
43
+ ```
44
+
45
+ ## When to Use
46
+
47
+ - Bug fixes
48
+ - Small features
49
+ - Config changes
50
+ - One-off tasks
51
+
52
+ For anything bigger, use the full flow: `/tdd:plan` → `/tdd:build` → `/tdd:verify`
package/status.md ADDED
@@ -0,0 +1,65 @@
1
+ # /tdd:status - Check Test Status
2
+
3
+ Quick check on test status for current or specified phase.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ /tdd:status [phase_number]
9
+ ```
10
+
11
+ If no phase specified, shows overall test status.
12
+
13
+ ## Process
14
+
15
+ 1. **Detect test framework** (Vitest, Jest, pytest, etc.)
16
+ 2. **Run the test suite**
17
+ 3. **Report results** with next action
18
+
19
+ ## Output Examples
20
+
21
+ **All tests passing:**
22
+ ```
23
+ Test Status
24
+ ───────────
25
+ ✅ 18 passing, 0 failing, 0 errors
26
+
27
+ Ready for: /tdd:verify
28
+ ```
29
+
30
+ **Some failing:**
31
+ ```
32
+ Test Status
33
+ ───────────
34
+ 🔄 12 passing, 6 failing, 0 errors
35
+
36
+ Failing:
37
+ • tests/auth.test.ts: login rejects invalid password
38
+ • tests/auth.test.ts: login returns httpOnly cookie
39
+ • tests/session.test.ts: session expires after timeout
40
+ ...
41
+
42
+ Action: Fix implementation or run /tdd:build to retry
43
+ ```
44
+
45
+ **Tests erroring:**
46
+ ```
47
+ Test Status
48
+ ───────────
49
+ ⚠️ 10 passing, 0 failing, 3 errors
50
+
51
+ Errors:
52
+ • tests/auth.test.ts:45 - Cannot find module '../src/auth'
53
+ • tests/session.test.ts:12 - TypeError: x is not a function
54
+
55
+ Action: Fix test errors before continuing
56
+ ```
57
+
58
+ **No tests found:**
59
+ ```
60
+ Test Status
61
+ ───────────
62
+ No tests found.
63
+
64
+ Run /tdd:build to write tests and implement.
65
+ ```
package/verify.md ADDED
@@ -0,0 +1,65 @@
1
+ # /tdd:verify - Human Acceptance Testing
2
+
3
+ Verify the phase works as expected — with your own eyes.
4
+
5
+ ## What This Does
6
+
7
+ 1. **Check tests pass** — Quick sanity check before human testing
8
+ 2. **Call `/gsd:verify-work`** — Walk through testable deliverables
9
+
10
+ ## Usage
11
+
12
+ ```
13
+ /tdd:verify [phase_number]
14
+ ```
15
+
16
+ ## Process
17
+
18
+ ### Step 1: Run Tests
19
+
20
+ ```bash
21
+ npm test # or pytest, go test, etc.
22
+ ```
23
+
24
+ - ✅ All pass → Continue to human verification
25
+ - ❌ Some fail → Report failures, suggest `/tdd:build {N}` to fix
26
+
27
+ ### Step 2: Human Verification
28
+
29
+ Call `/gsd:verify-work {phase_number}`
30
+
31
+ GSD walks you through each deliverable:
32
+ - "Can you log in with email?" → Yes / No / Describe issue
33
+ - "Does the dashboard load?" → Yes / No / Describe issue
34
+
35
+ Issues get diagnosed and fix plans created.
36
+
37
+ ## Why Both?
38
+
39
+ **Tests verify code works.**
40
+ **You verify it works the way you wanted.**
41
+
42
+ Tests catch regressions and logic errors. Human verification catches "technically correct but not what I meant" issues — wrong layout, confusing flow, missing edge case you forgot to specify.
43
+
44
+ Both matter.
45
+
46
+ ## Example
47
+
48
+ ```
49
+ User: /tdd:verify 1
50
+
51
+ Claude: Running tests...
52
+ ✅ 11 tests passing
53
+
54
+ Starting human verification...
55
+
56
+ Phase 1 delivered:
57
+ 1. User login with email/password
58
+ 2. Session persistence
59
+ 3. Logout functionality
60
+
61
+ Let's verify each:
62
+
63
+ [1/3] Can you log in with a valid email and password?
64
+
65
+ ```