tdd-claude-code 0.1.0 → 0.2.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 (3) hide show
  1. package/README.md +4 -0
  2. package/bin/install.js +106 -43
  3. package/package.json +1 -1
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
package/bin/install.js CHANGED
@@ -5,6 +5,29 @@ 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.2.0';
30
+
8
31
  const COMMANDS = [
9
32
  'new-project.md',
10
33
  'discuss.md',
@@ -28,27 +51,50 @@ function getLocalDir() {
28
51
  return path.join(process.cwd(), '.claude', 'commands');
29
52
  }
30
53
 
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('');
54
+ function printBanner() {
55
+ console.log(LOGO);
56
+ console.log(` ${c.bold}TDD Workflow${c.reset} ${c.dim}v${VERSION}${c.reset}`);
57
+ console.log(` ${c.white}Test-Led Development for Claude Code${c.reset}`);
58
+ console.log(` ${c.dim}Powered by GSD${c.reset}`);
59
+ console.log('');
60
+ }
61
+
62
+ function log(msg) {
63
+ console.log(` ${msg}`);
64
+ }
65
+
66
+ function success(msg) {
67
+ console.log(` ${c.green}✓${c.reset} ${msg}`);
68
+ }
69
+
70
+ function info(msg) {
71
+ console.log(` ${c.cyan}→${c.reset} ${msg}`);
72
+ }
73
+
74
+ function checkGsd(localGsdDir, installType) {
75
+ const globalGsdDir = path.join(getGlobalDir(), 'gsd');
76
+
77
+ // GSD can be in either location - check both
78
+ if (fs.existsSync(localGsdDir) || fs.existsSync(globalGsdDir)) {
79
+ return; // GSD found
80
+ }
81
+
82
+ log('');
83
+ log(`${c.yellow}GSD not found${c.reset} - installing dependency...`);
84
+ log('');
85
+ try {
86
+ execSync('npx --yes get-shit-done-cc@latest', { stdio: 'inherit' });
87
+ } catch (e) {
88
+ // GSD installer may exit with error but still install
89
+ }
90
+ console.log('');
91
+
92
+ // Check both locations again after install
93
+ if (!fs.existsSync(localGsdDir) && !fs.existsSync(globalGsdDir)) {
94
+ log(`${c.yellow}GSD not found after install.${c.reset}`);
95
+ log('Run: npx get-shit-done-cc');
96
+ log('Then re-run this installer.');
97
+ process.exit(1);
52
98
  }
53
99
  }
54
100
 
@@ -64,62 +110,79 @@ function install(targetDir, installType) {
64
110
 
65
111
  // Copy command files
66
112
  const sourceDir = path.join(__dirname, '..');
113
+ let installed = 0;
67
114
  for (const file of COMMANDS) {
68
115
  const src = path.join(sourceDir, file);
69
116
  const dest = path.join(commandsDir, file);
70
117
  if (fs.existsSync(src)) {
71
118
  fs.copyFileSync(src, dest);
119
+ installed++;
72
120
  }
73
121
  }
74
122
 
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.');
123
+ success(`Installed ${installed} commands to ${c.cyan}${commandsDir}${c.reset}`);
124
+ log('');
125
+ log(`${c.green}Done!${c.reset} Restart Claude Code to load commands.`);
126
+ log('');
127
+ log(`${c.bold}Workflow:${c.reset}`);
128
+ log(` ${c.cyan}/tdd:new-project${c.reset} Start project with test infrastructure`);
129
+ log(` ${c.cyan}/tdd:discuss${c.reset} Shape implementation preferences`);
130
+ log(` ${c.cyan}/tdd:plan${c.reset} Create task plans`);
131
+ log(` ${c.cyan}/tdd:build${c.reset} Write tests implement → verify`);
132
+ log(` ${c.cyan}/tdd:verify${c.reset} Human acceptance testing`);
133
+ log('');
134
+ log(`Run ${c.cyan}/tdd:help${c.reset} for full command list.`);
135
+ log('');
88
136
  }
89
137
 
90
138
  async function main() {
91
139
  const args = process.argv.slice(2);
92
140
 
141
+ printBanner();
142
+
93
143
  if (args.includes('--global') || args.includes('-g')) {
94
- console.log(`Installing globally to ${getGlobalDir()}/tdd`);
144
+ info(`Installing ${c.bold}globally${c.reset} to ~/.claude/commands/tdd`);
145
+ log('');
95
146
  install(getGlobalDir(), 'global');
96
147
  return;
97
148
  }
98
149
 
99
150
  if (args.includes('--local') || args.includes('-l')) {
100
- console.log(`Installing locally to ${getLocalDir()}/tdd`);
151
+ info(`Installing ${c.bold}locally${c.reset} to ./.claude/commands/tdd`);
152
+ log('');
101
153
  install(getLocalDir(), 'local');
102
154
  return;
103
155
  }
104
156
 
157
+ // Check if non-interactive
158
+ if (!process.stdin.isTTY) {
159
+ log(`${c.yellow}Non-interactive terminal detected, defaulting to global install${c.reset}`);
160
+ log('');
161
+ install(getGlobalDir(), 'global');
162
+ return;
163
+ }
164
+
105
165
  // Interactive prompt
106
166
  const rl = readline.createInterface({
107
167
  input: process.stdin,
108
168
  output: process.stdout
109
169
  });
110
170
 
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('');
171
+ log('Where would you like to install?');
172
+ log(` ${c.bold}1)${c.reset} Global ${c.dim}(~/.claude/commands/tdd)${c.reset} - available in all projects`);
173
+ log(` ${c.bold}2)${c.reset} Local ${c.dim}(./.claude/commands/tdd)${c.reset} - this project only`);
174
+ log('');
117
175
 
118
- rl.question('Choice [1/2]: ', (answer) => {
176
+ rl.question(' Choice [1/2]: ', (answer) => {
119
177
  rl.close();
178
+ console.log('');
120
179
  if (answer === '2') {
180
+ info(`Installing ${c.bold}locally${c.reset}`);
181
+ log('');
121
182
  install(getLocalDir(), 'local');
122
183
  } else {
184
+ info(`Installing ${c.bold}globally${c.reset}`);
185
+ log('');
123
186
  install(getGlobalDir(), 'global');
124
187
  }
125
188
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tdd-claude-code",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "TDD workflow for Claude Code - wraps GSD",
5
5
  "bin": {
6
6
  "tdd-claude-code": "./bin/install.js"