tdd-claude-code 0.1.0 → 0.3.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 CHANGED
@@ -4,6 +4,10 @@ Test-Led Development powered by [GSD](https://github.com/glittercowboy/get-shit-
4
4
 
5
5
  **One interface. Tests happen automatically. You don't think about methodology.**
6
6
 
7
+ <p align="center">
8
+ <img src="assets/terminal.svg" alt="TDD Installer" width="700">
9
+ </p>
10
+
7
11
  ## Install
8
12
 
9
13
  ```bash
@@ -23,7 +27,9 @@ npx tdd-claude-code --local # this project only
23
27
  You use `/tdd:*` commands for everything. Never touch `/gsd:*` directly.
24
28
 
25
29
  ```
26
- /tdd:new-project Describe your idea, get test infrastructure
30
+ /tdd:new-project New project from scratch
31
+ OR
32
+ /tdd:init Add TDD to existing codebase
27
33
 
28
34
  /tdd:discuss 1 Shape how phase 1 gets built
29
35
  /tdd:plan 1 Create task plans
@@ -51,6 +57,7 @@ You run one command. Tests get written before code. Automatically.
51
57
  | Command | What It Does |
52
58
  |---------|--------------|
53
59
  | `/tdd:new-project` | Start project with test infrastructure |
60
+ | `/tdd:init` | Add TDD to existing codebase |
54
61
  | `/tdd:discuss [N]` | Capture implementation preferences |
55
62
  | `/tdd:plan [N]` | Create task plans |
56
63
  | `/tdd:build <N>` | **Write tests → implement → verify** |
package/bin/install.js CHANGED
@@ -5,8 +5,32 @@ const path = require('path');
5
5
  const { execSync } = require('child_process');
6
6
  const readline = require('readline');
7
7
 
8
+ // ANSI color codes
9
+ const c = {
10
+ reset: '\x1b[0m',
11
+ bold: '\x1b[1m',
12
+ dim: '\x1b[2m',
13
+ cyan: '\x1b[36m',
14
+ green: '\x1b[32m',
15
+ yellow: '\x1b[33m',
16
+ magenta: '\x1b[35m',
17
+ white: '\x1b[37m',
18
+ };
19
+
20
+ const LOGO = `
21
+ ${c.cyan} ████████╗██████╗ ██████╗
22
+ ╚══██╔══╝██╔══██╗██╔══██╗
23
+ ██║ ██║ ██║██║ ██║
24
+ ██║ ██║ ██║██║ ██║
25
+ ██║ ██████╔╝██████╔╝
26
+ ╚═╝ ╚═════╝ ╚═════╝${c.reset}
27
+ `;
28
+
29
+ const VERSION = '0.3.0';
30
+
8
31
  const COMMANDS = [
9
32
  'new-project.md',
33
+ 'init.md',
10
34
  'discuss.md',
11
35
  'plan.md',
12
36
  'build.md',
@@ -28,27 +52,50 @@ function getLocalDir() {
28
52
  return path.join(process.cwd(), '.claude', 'commands');
29
53
  }
30
54
 
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('');
55
+ function printBanner() {
56
+ console.log(LOGO);
57
+ console.log(` ${c.bold}TDD Workflow${c.reset} ${c.dim}v${VERSION}${c.reset}`);
58
+ console.log(` ${c.white}Test-Led Development for Claude Code${c.reset}`);
59
+ console.log(` ${c.dim}Powered by GSD${c.reset}`);
60
+ console.log('');
61
+ }
62
+
63
+ function log(msg) {
64
+ console.log(` ${msg}`);
65
+ }
66
+
67
+ function success(msg) {
68
+ console.log(` ${c.green}✓${c.reset} ${msg}`);
69
+ }
70
+
71
+ function info(msg) {
72
+ console.log(` ${c.cyan}→${c.reset} ${msg}`);
73
+ }
74
+
75
+ function checkGsd(localGsdDir, installType) {
76
+ const globalGsdDir = path.join(getGlobalDir(), 'gsd');
77
+
78
+ // GSD can be in either location - check both
79
+ if (fs.existsSync(localGsdDir) || fs.existsSync(globalGsdDir)) {
80
+ return; // GSD found
81
+ }
82
+
83
+ log('');
84
+ log(`${c.yellow}GSD not found${c.reset} - installing dependency...`);
85
+ log('');
86
+ try {
87
+ execSync('npx --yes get-shit-done-cc@latest', { stdio: 'inherit' });
88
+ } catch (e) {
89
+ // GSD installer may exit with error but still install
90
+ }
91
+ console.log('');
92
+
93
+ // Check both locations again after install
94
+ if (!fs.existsSync(localGsdDir) && !fs.existsSync(globalGsdDir)) {
95
+ log(`${c.yellow}GSD not found after install.${c.reset}`);
96
+ log('Run: npx get-shit-done-cc');
97
+ log('Then re-run this installer.');
98
+ process.exit(1);
52
99
  }
53
100
  }
54
101
 
@@ -64,62 +111,79 @@ function install(targetDir, installType) {
64
111
 
65
112
  // Copy command files
66
113
  const sourceDir = path.join(__dirname, '..');
114
+ let installed = 0;
67
115
  for (const file of COMMANDS) {
68
116
  const src = path.join(sourceDir, file);
69
117
  const dest = path.join(commandsDir, file);
70
118
  if (fs.existsSync(src)) {
71
119
  fs.copyFileSync(src, dest);
120
+ installed++;
72
121
  }
73
122
  }
74
123
 
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.');
124
+ success(`Installed ${installed} commands to ${c.cyan}${commandsDir}${c.reset}`);
125
+ log('');
126
+ log(`${c.green}Done!${c.reset} Restart Claude Code to load commands.`);
127
+ log('');
128
+ log(`${c.bold}Workflow:${c.reset}`);
129
+ log(` ${c.cyan}/tdd:new-project${c.reset} Start project with test infrastructure`);
130
+ log(` ${c.cyan}/tdd:discuss${c.reset} Shape implementation preferences`);
131
+ log(` ${c.cyan}/tdd:plan${c.reset} Create task plans`);
132
+ log(` ${c.cyan}/tdd:build${c.reset} Write tests implement → verify`);
133
+ log(` ${c.cyan}/tdd:verify${c.reset} Human acceptance testing`);
134
+ log('');
135
+ log(`Run ${c.cyan}/tdd:help${c.reset} for full command list.`);
136
+ log('');
88
137
  }
89
138
 
90
139
  async function main() {
91
140
  const args = process.argv.slice(2);
92
141
 
142
+ printBanner();
143
+
93
144
  if (args.includes('--global') || args.includes('-g')) {
94
- console.log(`Installing globally to ${getGlobalDir()}/tdd`);
145
+ info(`Installing ${c.bold}globally${c.reset} to ~/.claude/commands/tdd`);
146
+ log('');
95
147
  install(getGlobalDir(), 'global');
96
148
  return;
97
149
  }
98
150
 
99
151
  if (args.includes('--local') || args.includes('-l')) {
100
- console.log(`Installing locally to ${getLocalDir()}/tdd`);
152
+ info(`Installing ${c.bold}locally${c.reset} to ./.claude/commands/tdd`);
153
+ log('');
101
154
  install(getLocalDir(), 'local');
102
155
  return;
103
156
  }
104
157
 
158
+ // Check if non-interactive
159
+ if (!process.stdin.isTTY) {
160
+ log(`${c.yellow}Non-interactive terminal detected, defaulting to global install${c.reset}`);
161
+ log('');
162
+ install(getGlobalDir(), 'global');
163
+ return;
164
+ }
165
+
105
166
  // Interactive prompt
106
167
  const rl = readline.createInterface({
107
168
  input: process.stdin,
108
169
  output: process.stdout
109
170
  });
110
171
 
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('');
172
+ log('Where would you like to install?');
173
+ log(` ${c.bold}1)${c.reset} Global ${c.dim}(~/.claude/commands/tdd)${c.reset} - available in all projects`);
174
+ log(` ${c.bold}2)${c.reset} Local ${c.dim}(./.claude/commands/tdd)${c.reset} - this project only`);
175
+ log('');
117
176
 
118
- rl.question('Choice [1/2]: ', (answer) => {
177
+ rl.question(' Choice [1/2]: ', (answer) => {
119
178
  rl.close();
179
+ console.log('');
120
180
  if (answer === '2') {
181
+ info(`Installing ${c.bold}locally${c.reset}`);
182
+ log('');
121
183
  install(getLocalDir(), 'local');
122
184
  } else {
185
+ info(`Installing ${c.bold}globally${c.reset}`);
186
+ log('');
123
187
  install(getGlobalDir(), 'global');
124
188
  }
125
189
  });
package/help.md CHANGED
@@ -4,11 +4,17 @@ TDD-first workflow powered by GSD. You use `/tdd:*` for everything — tests hap
4
4
 
5
5
  ## Commands
6
6
 
7
- ### Core Workflow
7
+ ### Getting Started
8
8
 
9
9
  | Command | What It Does |
10
10
  |---------|--------------|
11
11
  | `/tdd:new-project` | Start new project with test infrastructure |
12
+ | `/tdd:init` | Add TDD to existing codebase |
13
+
14
+ ### Core Workflow
15
+
16
+ | Command | What It Does |
17
+ |---------|--------------|
12
18
  | `/tdd:discuss [N]` | Capture implementation preferences for phase N |
13
19
  | `/tdd:plan [N]` | Research and create task plans for phase N |
14
20
  | `/tdd:build <N>` | **Write tests → implement → verify tests pass** |
@@ -38,7 +44,9 @@ TDD-first workflow powered by GSD. You use `/tdd:*` for everything — tests hap
38
44
  ## Workflow
39
45
 
40
46
  ```
41
- /tdd:new-project Describe your idea, set up project + tests
47
+ /tdd:new-project New project from scratch
48
+ OR
49
+ /tdd:init Existing codebase
42
50
 
43
51
  /tdd:discuss 1 Shape how phase 1 gets built
44
52
  /tdd:plan 1 Create task plans
@@ -81,6 +89,7 @@ TDD commands call GSD internally:
81
89
  | TDD Command | Calls |
82
90
  |-------------|-------|
83
91
  | `/tdd:new-project` | `/gsd:new-project` + test setup |
92
+ | `/tdd:init` | scan + test setup (no GSD call) |
84
93
  | `/tdd:discuss` | `/gsd:discuss-phase` |
85
94
  | `/tdd:plan` | `/gsd:plan-phase` |
86
95
  | `/tdd:build` | write tests + `/gsd:execute-phase` |
package/init.md ADDED
@@ -0,0 +1,147 @@
1
+ # /tdd:init - Initialize TDD in Existing Project
2
+
3
+ Add TDD workflow to an existing codebase.
4
+
5
+ ## When to Use
6
+
7
+ - You have existing code without tests
8
+ - You have existing code with some tests
9
+ - You're joining a project mid-development
10
+ - You want to adopt TDD on a "vibe coded" project
11
+
12
+ For brand new projects with no code, use `/tdd:new-project` instead.
13
+
14
+ ## Process
15
+
16
+ ### 1. Scan for Existing Code
17
+
18
+ Check for source files:
19
+ - `src/`, `lib/`, `app/`, `pkg/`, or root-level code files
20
+ - `package.json`, `pyproject.toml`, `go.mod`, `Gemfile`, `Cargo.toml`
21
+
22
+ If no code found, suggest running `/tdd:new-project` instead.
23
+
24
+ ### 2. Detect Stack
25
+
26
+ | Indicator | Stack |
27
+ |-----------|-------|
28
+ | `package.json` + React/Next deps | Next.js / React |
29
+ | `package.json` (no framework) | Node.js |
30
+ | `pyproject.toml` / `requirements.txt` | Python |
31
+ | `go.mod` | Go |
32
+ | `Gemfile` | Ruby |
33
+ | `Cargo.toml` | Rust |
34
+
35
+ ### 3. Scan for Existing Tests
36
+
37
+ Look for test indicators:
38
+
39
+ **Directories:**
40
+ - `tests/`, `test/`, `__tests__/`, `spec/`
41
+
42
+ **Files:**
43
+ - `*_test.py`, `test_*.py`
44
+ - `*.test.ts`, `*.test.js`, `*.spec.ts`, `*.spec.js`
45
+ - `*_test.go`
46
+ - `*_spec.rb`
47
+
48
+ **Config files:**
49
+ - `vitest.config.*`, `jest.config.*`, `pytest.ini`, `pyproject.toml` [tool.pytest]
50
+ - `.rspec`, `spec/spec_helper.rb`
51
+
52
+ ### 4. Set Up Test Framework (if missing)
53
+
54
+ If no tests found, set up based on detected stack:
55
+
56
+ | Stack | Framework | Setup |
57
+ |-------|-----------|-------|
58
+ | Next.js / React | Vitest | `npm install -D vitest @testing-library/react` |
59
+ | Node.js | Vitest | `npm install -D vitest` |
60
+ | Python | pytest | `pip install pytest` or add to pyproject.toml |
61
+ | Go | go test | Built-in, no setup needed |
62
+ | Ruby | RSpec | `gem install rspec && rspec --init` |
63
+ | Rust | cargo test | Built-in, no setup needed |
64
+
65
+ Create config file and test directory structure.
66
+
67
+ Add test scripts to package.json / pyproject.toml / Makefile:
68
+ ```json
69
+ "scripts": {
70
+ "test": "vitest run",
71
+ "test:watch": "vitest"
72
+ }
73
+ ```
74
+
75
+ ### 5. If Tests Already Exist
76
+
77
+ - Skip framework setup
78
+ - Note existing test patterns for consistency
79
+ - Report: "Found existing test framework: [vitest/jest/pytest/etc]"
80
+ - Report: "Found X existing test files"
81
+
82
+ ### 6. Analyze Existing Code Structure
83
+
84
+ Scan the codebase and generate summary:
85
+ - Main directories and their purpose
86
+ - Key modules/components identified
87
+ - Entry points (main files, API routes, etc.)
88
+ - Dependencies and their roles
89
+
90
+ ### 7. Create or Update PROJECT.md
91
+
92
+ If PROJECT.md doesn't exist, create it with:
93
+
94
+ ```markdown
95
+ # [Project Name]
96
+
97
+ ## Overview
98
+ [Inferred from code structure and README if present]
99
+
100
+ ## Tech Stack
101
+ - [Detected stack]
102
+ - [Key dependencies]
103
+
104
+ ## Project Structure
105
+ [Generated from scan]
106
+
107
+ ## Development Methodology: Test-Led Development
108
+
109
+ This project uses TDD. All new implementation follows Red -> Green -> Refactor:
110
+
111
+ 1. **Red**: Write failing tests that define expected behavior
112
+ 2. **Green**: Write minimum code to make tests pass
113
+ 3. **Refactor**: Clean up while keeping tests green
114
+
115
+ Tests are written BEFORE implementation, not after.
116
+
117
+ ## Test Framework
118
+ - Framework: [detected or installed]
119
+ - Run tests: `[test command]`
120
+ - Test directory: `[path]`
121
+ ```
122
+
123
+ If PROJECT.md exists, append the TDD section only.
124
+
125
+ ### 8. Report Summary
126
+
127
+ ```
128
+ TDD initialized for [project name]
129
+
130
+ Stack: [detected]
131
+ Test framework: [framework] (existing/newly configured)
132
+ Test directory: [path]
133
+ Existing tests: [count] files
134
+
135
+ Next steps:
136
+ - Run /tdd:status to check current test coverage
137
+ - Run /tdd:discuss to plan new features with TDD
138
+ - Run /tdd:quick for ad-hoc tasks with tests
139
+ ```
140
+
141
+ ## Usage
142
+
143
+ ```
144
+ /tdd:init
145
+ ```
146
+
147
+ No arguments needed. Auto-detects everything.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tdd-claude-code",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "TDD workflow for Claude Code - wraps GSD",
5
5
  "bin": {
6
6
  "tdd-claude-code": "./bin/install.js"