tlc-claude-code 1.1.0 → 1.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.
package/.gitattributes CHANGED
@@ -1,2 +1,3 @@
1
- # Force LF line endings for shell scripts
1
+ # Force LF line endings for shell scripts and node binaries
2
2
  *.sh text eol=lf
3
+ bin/*.js text eol=lf
package/bin/install.js CHANGED
@@ -30,6 +30,7 @@ const VERSION = require('../package.json').version;
30
30
  const COMMANDS = [
31
31
  // Core workflow
32
32
  'tlc.md',
33
+ 'sync.md',
33
34
  'new-project.md',
34
35
  'init.md',
35
36
  'import-project.md',
package/bin/rebuild.js CHANGED
@@ -1,109 +1,109 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * TLC Rebuild - Trigger full Docker rebuild
5
- * Usage: tlc rebuild
6
- */
7
-
8
- const { spawn } = require('child_process');
9
- const path = require('path');
10
- const fs = require('fs');
11
-
12
- // Find TLC installation directory
13
- function findTlcDir() {
14
- const isWSL = process.platform === 'linux' && fs.existsSync('/mnt/c');
15
-
16
- // Check common locations (adjust for WSL)
17
- const locations = [
18
- path.join(__dirname, '..'), // Where this script lives (most reliable)
19
- ];
20
-
21
- if (isWSL) {
22
- locations.push('/mnt/c/Code/TLC');
23
- locations.push(path.join(require('os').homedir(), 'Code', 'TLC'));
24
- } else {
25
- locations.push('C:\\Code\\TLC');
26
- locations.push(path.join(require('os').homedir(), 'Code', 'TLC'));
27
- }
28
-
29
- // Check npm global
30
- try {
31
- const { execSync } = require('child_process');
32
- const globalRoot = execSync('npm root -g', { encoding: 'utf-8' }).trim();
33
- locations.push(path.join(globalRoot, 'tlc-claude-code'));
34
- } catch (e) {
35
- // Ignore
36
- }
37
-
38
- for (const loc of locations) {
39
- if (fs.existsSync(path.join(loc, 'docker-compose.dev.yml'))) {
40
- return loc;
41
- }
42
- }
43
-
44
- return null;
45
- }
46
-
47
- // Get project name from current directory
48
- function getProjectName() {
49
- const projectDir = process.cwd();
50
- return path.basename(projectDir).toLowerCase().replace(/[^a-z0-9]/g, '');
51
- }
52
-
53
- async function main() {
54
- console.log('');
55
- console.log(' TLC Rebuild');
56
- console.log(' ===========');
57
- console.log('');
58
-
59
- const tlcDir = findTlcDir();
60
- if (!tlcDir) {
61
- console.error(' [ERROR] Could not find TLC installation');
62
- console.error(' Make sure docker-compose.dev.yml exists');
63
- process.exit(1);
64
- }
65
-
66
- const projectName = getProjectName();
67
- const composePath = path.join(tlcDir, 'docker-compose.dev.yml');
68
-
69
- console.log(` TLC Dir: ${tlcDir}`);
70
- console.log(` Project: ${projectName}`);
71
- console.log('');
72
-
73
- // Set environment variables
74
- process.env.PROJECT_DIR = process.cwd();
75
- process.env.COMPOSE_PROJECT_NAME = projectName;
76
-
77
- console.log(' [1/2] Stopping containers...');
78
-
79
- // Run docker-compose down
80
- const down = spawn('docker-compose', ['-f', composePath, 'down'], {
81
- stdio: 'inherit',
82
- shell: true,
83
- env: process.env
84
- });
85
-
86
- down.on('close', (code) => {
87
- if (code !== 0) {
88
- console.error(' [ERROR] Failed to stop containers');
89
- process.exit(1);
90
- }
91
-
92
- console.log('');
93
- console.log(' [2/2] Rebuilding and starting...');
94
- console.log('');
95
-
96
- // Run docker-compose up --build
97
- const up = spawn('docker-compose', ['-f', composePath, 'up', '--build'], {
98
- stdio: 'inherit',
99
- shell: true,
100
- env: process.env
101
- });
102
-
103
- up.on('close', (upCode) => {
104
- process.exit(upCode || 0);
105
- });
106
- });
107
- }
108
-
109
- main();
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * TLC Rebuild - Trigger full Docker rebuild
5
+ * Usage: tlc rebuild
6
+ */
7
+
8
+ const { spawn } = require('child_process');
9
+ const path = require('path');
10
+ const fs = require('fs');
11
+
12
+ // Find TLC installation directory
13
+ function findTlcDir() {
14
+ const isWSL = process.platform === 'linux' && fs.existsSync('/mnt/c');
15
+
16
+ // Check common locations (adjust for WSL)
17
+ const locations = [
18
+ path.join(__dirname, '..'), // Where this script lives (most reliable)
19
+ ];
20
+
21
+ if (isWSL) {
22
+ locations.push('/mnt/c/Code/TLC');
23
+ locations.push(path.join(require('os').homedir(), 'Code', 'TLC'));
24
+ } else {
25
+ locations.push('C:\\Code\\TLC');
26
+ locations.push(path.join(require('os').homedir(), 'Code', 'TLC'));
27
+ }
28
+
29
+ // Check npm global
30
+ try {
31
+ const { execSync } = require('child_process');
32
+ const globalRoot = execSync('npm root -g', { encoding: 'utf-8' }).trim();
33
+ locations.push(path.join(globalRoot, 'tlc-claude-code'));
34
+ } catch (e) {
35
+ // Ignore
36
+ }
37
+
38
+ for (const loc of locations) {
39
+ if (fs.existsSync(path.join(loc, 'docker-compose.dev.yml'))) {
40
+ return loc;
41
+ }
42
+ }
43
+
44
+ return null;
45
+ }
46
+
47
+ // Get project name from current directory
48
+ function getProjectName() {
49
+ const projectDir = process.cwd();
50
+ return path.basename(projectDir).toLowerCase().replace(/[^a-z0-9]/g, '');
51
+ }
52
+
53
+ async function main() {
54
+ console.log('');
55
+ console.log(' TLC Rebuild');
56
+ console.log(' ===========');
57
+ console.log('');
58
+
59
+ const tlcDir = findTlcDir();
60
+ if (!tlcDir) {
61
+ console.error(' [ERROR] Could not find TLC installation');
62
+ console.error(' Make sure docker-compose.dev.yml exists');
63
+ process.exit(1);
64
+ }
65
+
66
+ const projectName = getProjectName();
67
+ const composePath = path.join(tlcDir, 'docker-compose.dev.yml');
68
+
69
+ console.log(` TLC Dir: ${tlcDir}`);
70
+ console.log(` Project: ${projectName}`);
71
+ console.log('');
72
+
73
+ // Set environment variables
74
+ process.env.PROJECT_DIR = process.cwd();
75
+ process.env.COMPOSE_PROJECT_NAME = projectName;
76
+
77
+ console.log(' [1/2] Stopping containers...');
78
+
79
+ // Run docker-compose down
80
+ const down = spawn('docker-compose', ['-f', composePath, 'down'], {
81
+ stdio: 'inherit',
82
+ shell: true,
83
+ env: process.env
84
+ });
85
+
86
+ down.on('close', (code) => {
87
+ if (code !== 0) {
88
+ console.error(' [ERROR] Failed to stop containers');
89
+ process.exit(1);
90
+ }
91
+
92
+ console.log('');
93
+ console.log(' [2/2] Rebuilding and starting...');
94
+ console.log('');
95
+
96
+ // Run docker-compose up --build
97
+ const up = spawn('docker-compose', ['-f', composePath, 'up', '--build'], {
98
+ stdio: 'inherit',
99
+ shell: true,
100
+ env: process.env
101
+ });
102
+
103
+ up.on('close', (upCode) => {
104
+ process.exit(upCode || 0);
105
+ });
106
+ });
107
+ }
108
+
109
+ main();
package/bin/server.js CHANGED
@@ -1,16 +1,16 @@
1
- #!/usr/bin/env node
2
-
3
- const path = require('path');
4
- const { spawn } = require('child_process');
5
-
6
- // Run the server from the parent directory
7
- const serverPath = path.join(__dirname, '..', 'server', 'index.js');
8
-
9
- const child = spawn('node', [serverPath], {
10
- stdio: 'inherit',
11
- cwd: process.cwd()
12
- });
13
-
14
- child.on('exit', (code) => {
15
- process.exit(code || 0);
16
- });
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const { spawn } = require('child_process');
5
+
6
+ // Run the server from the parent directory
7
+ const serverPath = path.join(__dirname, '..', 'server', 'index.js');
8
+
9
+ const child = spawn('node', [serverPath], {
10
+ stdio: 'inherit',
11
+ cwd: process.cwd()
12
+ });
13
+
14
+ child.on('exit', (code) => {
15
+ process.exit(code || 0);
16
+ });
package/bin/setup.js CHANGED
@@ -1,42 +1,42 @@
1
- #!/usr/bin/env node
2
-
3
- const path = require('path');
4
- const { spawn } = require('child_process');
5
- const fs = require('fs');
6
-
7
- const setupScript = path.join(__dirname, '..', 'server', 'setup.sh');
8
-
9
- // Check if running on Windows without WSL
10
- if (process.platform === 'win32') {
11
- console.log('\n[TLC] Windows detected');
12
- console.log('[TLC] Please install Docker Desktop from: https://www.docker.com/products/docker-desktop');
13
- console.log('[TLC] After installation, TLC will automatically use Docker for databases.\n');
14
- process.exit(0);
15
- }
16
-
17
- // Check if setup script exists
18
- if (!fs.existsSync(setupScript)) {
19
- console.error('[TLC] Setup script not found:', setupScript);
20
- process.exit(1);
21
- }
22
-
23
- console.log('\n[TLC] Running TLC server setup...');
24
- console.log('[TLC] This will install Docker and other requirements.');
25
- console.log('[TLC] You may be prompted for your sudo password.\n');
26
-
27
- // Run the setup script with sudo
28
- const child = spawn('sudo', ['bash', setupScript], {
29
- stdio: 'inherit',
30
- cwd: process.cwd()
31
- });
32
-
33
- child.on('exit', (code) => {
34
- if (code === 0) {
35
- console.log('\n[TLC] Setup completed successfully!');
36
- console.log('[TLC] Please log out and log back in for Docker permissions to take effect.');
37
- console.log('[TLC] Then run: tlc-server\n');
38
- } else {
39
- console.error('\n[TLC] Setup failed with code:', code);
40
- }
41
- process.exit(code || 0);
42
- });
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const { spawn } = require('child_process');
5
+ const fs = require('fs');
6
+
7
+ const setupScript = path.join(__dirname, '..', 'server', 'setup.sh');
8
+
9
+ // Check if running on Windows without WSL
10
+ if (process.platform === 'win32') {
11
+ console.log('\n[TLC] Windows detected');
12
+ console.log('[TLC] Please install Docker Desktop from: https://www.docker.com/products/docker-desktop');
13
+ console.log('[TLC] After installation, TLC will automatically use Docker for databases.\n');
14
+ process.exit(0);
15
+ }
16
+
17
+ // Check if setup script exists
18
+ if (!fs.existsSync(setupScript)) {
19
+ console.error('[TLC] Setup script not found:', setupScript);
20
+ process.exit(1);
21
+ }
22
+
23
+ console.log('\n[TLC] Running TLC server setup...');
24
+ console.log('[TLC] This will install Docker and other requirements.');
25
+ console.log('[TLC] You may be prompted for your sudo password.\n');
26
+
27
+ // Run the setup script with sudo
28
+ const child = spawn('sudo', ['bash', setupScript], {
29
+ stdio: 'inherit',
30
+ cwd: process.cwd()
31
+ });
32
+
33
+ child.on('exit', (code) => {
34
+ if (code === 0) {
35
+ console.log('\n[TLC] Setup completed successfully!');
36
+ console.log('[TLC] Please log out and log back in for Docker permissions to take effect.');
37
+ console.log('[TLC] Then run: tlc-server\n');
38
+ } else {
39
+ console.error('\n[TLC] Setup failed with code:', code);
40
+ }
41
+ process.exit(code || 0);
42
+ });
package/bin/tlc.js CHANGED
@@ -1,49 +1,49 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * TLC CLI - Simple entry point
5
- *
6
- * Usage:
7
- * tlc - Install TLC slash commands to Claude Code
8
- * tlc init - Add Docker dev launcher (tlc-start.bat) to project
9
- */
10
-
11
- const args = process.argv.slice(2);
12
- const command = args[0];
13
-
14
- switch (command) {
15
- case 'init':
16
- require('./init.js');
17
- break;
18
- case 'rebuild':
19
- require('./rebuild.js');
20
- break;
21
- case 'help':
22
- case '--help':
23
- case '-h':
24
- console.log(`
25
- TLC - Test Led Coding
26
-
27
- Usage:
28
- tlc Install TLC slash commands to Claude Code
29
- tlc init Add Docker launcher to your project
30
- tlc rebuild Stop, rebuild, and restart Docker containers
31
-
32
- Options:
33
- --global, -g Install commands globally (~/.claude/commands)
34
- --local, -l Install commands locally (./.claude/commands)
35
-
36
- After 'tlc init':
37
- Double-click tlc-start.bat to launch Docker dev environment:
38
- - Dashboard: http://localhost:3147
39
- - App: http://localhost:5000
40
- - DB Admin: http://localhost:8080
41
- - Database: localhost:5433
42
-
43
- Requires: Docker Desktop (https://docker.com/products/docker-desktop)
44
- `);
45
- break;
46
- default:
47
- // No subcommand = run install.js (the original behavior)
48
- require('./install.js');
49
- }
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * TLC CLI - Simple entry point
5
+ *
6
+ * Usage:
7
+ * tlc - Install TLC slash commands to Claude Code
8
+ * tlc init - Add Docker dev launcher (tlc-start.bat) to project
9
+ */
10
+
11
+ const args = process.argv.slice(2);
12
+ const command = args[0];
13
+
14
+ switch (command) {
15
+ case 'init':
16
+ require('./init.js');
17
+ break;
18
+ case 'rebuild':
19
+ require('./rebuild.js');
20
+ break;
21
+ case 'help':
22
+ case '--help':
23
+ case '-h':
24
+ console.log(`
25
+ TLC - Test Led Coding
26
+
27
+ Usage:
28
+ tlc Install TLC slash commands to Claude Code
29
+ tlc init Add Docker launcher to your project
30
+ tlc rebuild Stop, rebuild, and restart Docker containers
31
+
32
+ Options:
33
+ --global, -g Install commands globally (~/.claude/commands)
34
+ --local, -l Install commands locally (./.claude/commands)
35
+
36
+ After 'tlc init':
37
+ Double-click tlc-start.bat to launch Docker dev environment:
38
+ - Dashboard: http://localhost:3147
39
+ - App: http://localhost:5000
40
+ - DB Admin: http://localhost:8080
41
+ - Database: localhost:5433
42
+
43
+ Requires: Docker Desktop (https://docker.com/products/docker-desktop)
44
+ `);
45
+ break;
46
+ default:
47
+ // No subcommand = run install.js (the original behavior)
48
+ require('./install.js');
49
+ }
package/claim.md CHANGED
@@ -24,15 +24,37 @@ else
24
24
  fi
25
25
  ```
26
26
 
27
- ### Step 2: Sync Latest State
27
+ ### Step 2: Sync with Main Branch
28
28
 
29
- Pull latest changes to get current task claims:
29
+ Get the configured trunk branch from `.tlc.json`:
30
30
 
31
31
  ```bash
32
- git pull --rebase
32
+ mainBranch=$(jq -r '.git.mainBranch // "main"' .tlc.json 2>/dev/null || echo "main")
33
33
  ```
34
34
 
35
- If pull fails due to conflicts, abort and notify user to resolve manually.
35
+ Rebase from trunk to minimize conflicts:
36
+
37
+ ```bash
38
+ git fetch origin
39
+ git rebase origin/$mainBranch
40
+ ```
41
+
42
+ Output:
43
+ ```
44
+ Syncing with main...
45
+ ↳ Rebased 2 commits from origin/main
46
+ ```
47
+
48
+ If rebase fails due to conflicts:
49
+ ```
50
+ ⚠️ Rebase conflict detected.
51
+
52
+ Your branch has diverged from main. Resolve conflicts first:
53
+ git rebase --continue (after fixing conflicts)
54
+ git rebase --abort (to cancel)
55
+
56
+ Then run /tlc:claim again.
57
+ ```
36
58
 
37
59
  ### Step 3: Find Current Phase Plan
38
60
 
package/help.md CHANGED
@@ -18,10 +18,11 @@ Launches the visual dashboard. Detects where you are, shows what's next.
18
18
  |---------|--------------|
19
19
  | `/tlc` | **Visual dashboard. Context-aware. Knows what to do next.** |
20
20
 
21
- ### Setup
21
+ ### Setup & Sync
22
22
 
23
23
  | Command | What It Does |
24
24
  |---------|--------------|
25
+ | `/tlc:sync` | **One command to rule them all.** First-time setup or post-rebase reconciliation |
25
26
  | `/tlc:new-project` | Start new project (discusses stack, creates roadmap) |
26
27
  | `/tlc:init` | Add TLC to existing code |
27
28
  | `/tlc:import-project` | Import multi-repo microservices architecture |
@@ -99,12 +100,15 @@ Launches the visual dashboard. Detects where you are, shows what's next.
99
100
 
100
101
  **Simple version:**
101
102
  ```
102
- /tlc <- just keep running this
103
+ /tlc:sync <- First time or after rebase
104
+ /tlc <- Then just keep running this
103
105
  ```
104
106
 
105
107
  **Detailed version:**
106
108
  ```
107
- /tlc:new-project New project
109
+ /tlc:sync First-time setup (all config in one go)
110
+ ↓ Or: post-rebase reconciliation
111
+ /tlc:new-project New project (or /tlc:init for existing)
108
112
 
109
113
  /tlc Guides you through each phase:
110
114
  → discuss → plan → build → verify
@@ -112,6 +116,15 @@ Launches the visual dashboard. Detects where you are, shows what's next.
112
116
  /tlc:complete Tag release
113
117
  ```
114
118
 
119
+ **After rebasing:**
120
+ ```
121
+ git rebase origin/main TLC detects changes
122
+
123
+ /tlc:sync Reconcile incoming code
124
+
125
+ /tlc Continue working
126
+ ```
127
+
115
128
  ---
116
129
 
117
130
  ## What `/tlc` Does
package/init.md CHANGED
@@ -242,7 +242,48 @@ Tests are written BEFORE implementation, not after.
242
242
 
243
243
  If PROJECT.md exists, append the TLC section only.
244
244
 
245
- ### 10. Report Summary
245
+ ### 10. Detect Main Branch
246
+
247
+ Identify the trunk branch for rebasing and merges:
248
+
249
+ ```bash
250
+ # Try to detect from git
251
+ if git rev-parse --verify main >/dev/null 2>&1; then
252
+ detected="main"
253
+ elif git rev-parse --verify master >/dev/null 2>&1; then
254
+ detected="master"
255
+ elif git rev-parse --verify develop >/dev/null 2>&1; then
256
+ detected="develop"
257
+ else
258
+ detected=$(git rev-parse --abbrev-ref HEAD)
259
+ fi
260
+ ```
261
+
262
+ Confirm with user:
263
+ ```
264
+ Detected main branch: main
265
+
266
+ Is this your trunk branch for merges? (Y/n/other):
267
+ >
268
+
269
+ If "other", prompt for branch name.
270
+ ```
271
+
272
+ Add to `.tlc.json`:
273
+ ```json
274
+ {
275
+ "git": {
276
+ "mainBranch": "main"
277
+ }
278
+ }
279
+ ```
280
+
281
+ This branch is used by:
282
+ - `/tlc:claim` - rebases from this branch before claiming
283
+ - `/tlc:build` - suggests merging back to this branch
284
+ - PR reviews - compares against this branch
285
+
286
+ ### 11. Report Summary
246
287
 
247
288
  ```
248
289
  TLC initialized for [project name]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tlc-claude-code",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "TLC - Test Led Coding for Claude Code",
5
5
  "bin": {
6
6
  "tlc": "./bin/tlc.js",
package/plan.md CHANGED
@@ -124,7 +124,55 @@ Create `.planning/phases/{N}-PLAN.md`:
124
124
  - Tests: ~{N} (estimated)
125
125
  ```
126
126
 
127
- ### Step 5: Review Plan
127
+ ### Step 5: Detect File Overlaps (Parallel Safety)
128
+
129
+ Analyze tasks for file conflicts to prevent merge issues:
130
+
131
+ ```
132
+ Analyzing task dependencies...
133
+
134
+ Files by task:
135
+ Task 1: src/db/schema.ts, src/db/migrations/001.sql
136
+ Task 2: src/api/users.ts, src/db/schema.ts ← overlap!
137
+ Task 3: src/api/auth.ts
138
+ Task 4: src/api/users.ts ← overlap with Task 2!
139
+ ```
140
+
141
+ When overlaps detected, auto-sequence:
142
+
143
+ ```
144
+ ⚠️ File overlaps detected:
145
+
146
+ src/db/schema.ts → Task 1, Task 2
147
+ src/api/users.ts → Task 2, Task 4
148
+
149
+ Restructuring for parallel safety:
150
+ Task 1: Create schema [independent]
151
+ Task 2: Add user endpoints [after: 1] ← must wait for schema
152
+ Task 3: Add auth middleware [independent]
153
+ Task 4: Add user validation [after: 2] ← must wait for endpoints
154
+
155
+ Tasks 1 and 3 can be worked in parallel.
156
+ Tasks 2 and 4 are sequential.
157
+ ```
158
+
159
+ Add dependencies to PLAN.md:
160
+
161
+ ```markdown
162
+ ## Dependencies
163
+
164
+ | Task | Depends On | Reason |
165
+ |------|------------|--------|
166
+ | 2 | 1 | Both modify src/db/schema.ts |
167
+ | 4 | 2 | Both modify src/api/users.ts |
168
+
169
+ **Parallel groups:**
170
+ - Group A: Tasks 1, 3 (can work simultaneously)
171
+ - Group B: Task 2 (after Group A)
172
+ - Group C: Task 4 (after Task 2)
173
+ ```
174
+
175
+ ### Step 6: Review Plan
128
176
 
129
177
  Present plan summary:
130
178
 
@@ -144,7 +192,7 @@ Proceed with this plan? (Y/n)
144
192
 
145
193
  Allow refinement if needed.
146
194
 
147
- ### Step 6: Save and Continue
195
+ ### Step 7: Save and Continue
148
196
 
149
197
  ```
150
198
  Plan saved to .planning/phases/{N}-PLAN.md