worktree-compose 0.1.0 → 0.1.3

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/LICENSE +21 -0
  2. package/README.md +120 -430
  3. package/package.json +9 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LevwTech
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 CHANGED
@@ -1,172 +1,139 @@
1
1
  # worktree-compose (wtc)
2
2
 
3
- Zero-config Docker Compose isolation for git worktrees.
4
-
5
- ## The Problem
6
-
7
- You're running multiple AI agents (or developers) in parallel on the same repo, each in its own [git worktree](https://git-scm.com/docs/git-worktree). Without isolation, they all share the same Docker Compose setup — same Postgres, same Redis, same backend, same frontend. This means:
3
+ [![npm](https://img.shields.io/npm/v/worktree-compose?label=npm)](https://www.npmjs.com/package/worktree-compose)
8
4
 
9
- - **Port conflicts** two stacks can't both bind to port 8000
10
- - **Shared database** — agents overwrite each other's data
11
- - **Shared cache** — one agent's Redis state leaks into another's
12
- - **Container collisions** — `docker compose up` in one worktree kills the other's containers
13
- - **No comparison** — you can't open two frontends side by side to compare agent outputs
14
-
15
- You need each worktree to have its own fully isolated stack: its own database, its own cache, its own ports, its own containers. But setting this up manually for every worktree is tedious and error-prone.
16
-
17
- ## The Solution
18
-
19
- `wtc` gives every git worktree its own Docker Compose stack automatically.
20
-
21
- It reads your `docker-compose.yml`, finds every service that exposes a port, assigns unique ports per worktree, injects them into each worktree's `.env`, and starts isolated containers. No configuration needed.
5
+ Zero-config Docker Compose isolation for git worktrees.
22
6
 
23
- Each worktree gets:
24
- - **Its own ports** — no collisions
25
- - **Its own database** — no shared state
26
- - **Its own cache** — no leaking
27
- - **Its own containers** — independent lifecycles
28
- - **Its own URL** — open them side by side and compare
7
+ Every worktree gets its own ports, database, cache, and containers — automatically.
29
8
 
30
- ## Install
9
+ https://github.com/LevwTech/worktree-compose/raw/main/wtc-explainer.mp4
31
10
 
32
11
  ```bash
33
12
  npm install -D worktree-compose
34
- # or
35
- pnpm add -D worktree-compose
36
- # or
37
- yarn add -D worktree-compose
38
13
  ```
39
14
 
40
- This gives you the `wtc` command in your project.
15
+ ```
16
+ npx wtc list
17
+
18
+ ┌───────┬───────────────┬────────┬────────────────────────┬─────────────────────────────────────────────────────────┐
19
+ │ Index │ Branch │ Status │ URL │ Ports │
20
+ ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
21
+ │ - │ main │ - │ - │ postgres:5434 redis:6380 backend:8000 frontend:5173 │
22
+ ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
23
+ │ 1 │ feature-auth │ up │ http://localhost:25174 │ postgres:25435 redis:26381 backend:28001 frontend:25174 │
24
+ ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
25
+ │ 2 │ fix-billing │ down │ http://localhost:25175 │ postgres:25436 redis:26382 backend:28002 frontend:25175 │
26
+ └───────┴───────────────┴────────┴────────────────────────┴─────────────────────────────────────────────────────────┘
27
+ ```
41
28
 
42
- ## Quick Start
29
+ ## Usage
43
30
 
44
31
  ```bash
45
- # 1. Create worktrees
46
- git worktree add ../feature-1 feature-1
47
- git worktree add ../feature-2 feature-2
48
-
49
- # 2. Start isolated stacks for all worktrees
32
+ # Start isolated stacks for all worktrees
50
33
  npx wtc start
51
34
 
52
- # 3. See what's running
35
+ # Start specific worktrees
36
+ npx wtc start 1
37
+ npx wtc start 1 2 3
38
+
39
+ # See what's running
53
40
  npx wtc list
54
41
 
55
- # 4. Open each frontend in your browser and compare
42
+ # Stop worktrees
43
+ npx wtc stop
44
+ npx wtc stop 1
56
45
 
57
- # 5. Pick the best one and pull its changes into main
46
+ # Restart (re-sync files, rebuild containers)
47
+ npx wtc restart 1
48
+
49
+ # Pull a worktree's changes into your current branch
58
50
  npx wtc promote 1
59
51
 
60
- # 6. Clean up everything
52
+ # Tear down everything (containers, worktrees, volumes)
61
53
  npx wtc clean
62
54
  ```
63
55
 
64
- ## How It Works
65
-
66
- ### 1. Auto-Detection
56
+ ## The Problem
67
57
 
68
- `wtc` finds your compose file in the repo root, checking these names in order (matching Docker Compose's own precedence):
58
+ Multiple developers or AI agents working in parallel on the same repo each in a [git worktree](https://git-scm.com/docs/git-worktree) — share the same Docker Compose setup. This means port conflicts, shared databases, shared caches, and container collisions. You can't run two stacks side by side.
69
59
 
70
- 1. `compose.yaml`
71
- 2. `compose.yml`
72
- 3. `docker-compose.yaml`
73
- 4. `docker-compose.yml`
60
+ ## The Solution
74
61
 
75
- ### 2. Port Parsing
62
+ `wtc` reads your `docker-compose.yml`, finds every service that exposes a port via `${VAR:-default}`, assigns unique ports per worktree, injects them into each worktree's `.env`, and starts isolated containers. No configuration needed.
76
63
 
77
- It parses the YAML and scans every service's `ports:` array. For each port using the `${VAR:-default}` pattern, it extracts the env var name and default value.
64
+ ## Preparing Your docker-compose.yml
78
65
 
79
- **Your compose file:**
66
+ For `wtc` to isolate a service's port, the host port must use the `${VAR:-default}` pattern:
80
67
 
81
68
  ```yaml
82
- services:
83
- postgres:
84
- image: postgres:15
85
- ports:
86
- - "${POSTGRES_PORT:-5434}:5432"
87
-
88
- redis:
89
- image: redis:7-alpine
90
- ports:
91
- - "${REDIS_PORT:-6380}:6379"
92
-
93
- backend:
94
- build:
95
- context: ./backend
96
- dockerfile: Dockerfile.dev
97
- ports:
98
- - "${BACKEND_PORT:-8000}:8000"
99
-
100
- worker:
101
- build:
102
- context: ./backend
103
- dockerfile: Dockerfile.dev
104
- # No ports — this service is ignored by wtc
105
-
106
- frontend:
107
- build:
108
- context: ./frontend
109
- dockerfile: Dockerfile.dev
110
- ports:
111
- - "${FRONTEND_PORT:-5173}:${FRONTEND_PORT:-5173}"
112
- ```
113
-
114
- `wtc` detects 4 overridable ports (postgres, redis, backend, frontend) and ignores the worker (no port mapping).
69
+ # wtc CAN isolate this
70
+ ports:
71
+ - "${BACKEND_PORT:-8000}:8000"
115
72
 
116
- ### 3. Port Allocation
73
+ # wtc CANNOT isolate this (hardcoded)
74
+ ports:
75
+ - "8080:8080"
76
+ ```
117
77
 
118
- Each worktree N gets unique ports using the formula:
78
+ If `wtc` finds hardcoded ports, it warns you and suggests the fix:
119
79
 
120
80
  ```
121
- port = 20000 + default_port + worktree_index
81
+ Service "nginx" uses a raw port mapping (8080:80).
82
+ To enable port isolation, change it to: "${NGINX_PORT:-8080}:80"
122
83
  ```
123
84
 
124
- | Service | Main (default) | Worktree 1 | Worktree 2 | Worktree 3 |
125
- |------------|---------------|------------|------------|------------|
126
- | postgres | 5434 | 25435 | 25436 | 25437 |
127
- | redis | 6380 | 26381 | 26382 | 26383 |
128
- | backend | 8000 | 28001 | 28002 | 28003 |
129
- | frontend | 5173 | 25174 | 25175 | 25176 |
85
+ ### Supported port formats
130
86
 
131
- The `20000` offset ensures worktree ports never collide with the main worktree's defaults or common system ports.
87
+ ```yaml
88
+ # Standard
89
+ - "${BACKEND_PORT:-8000}:8000"
132
90
 
133
- If a computed port exceeds 65535 (e.g. a service with a very high default port), wtc falls back to `default + 100 * N`. If even that overflows, it errors with a clear message.
91
+ # Same var for host and container
92
+ - "${FRONTEND_PORT:-5173}:${FRONTEND_PORT:-5173}"
134
93
 
135
- ### 4. Container Isolation
94
+ # IP-bound
95
+ - "127.0.0.1:${API_PORT:-3000}:3000"
136
96
 
137
- Each worktree gets its own `COMPOSE_PROJECT_NAME` following the pattern:
97
+ # With protocol
98
+ - "${BACKEND_PORT:-8000}:8000/tcp"
138
99
 
100
+ # Multiple ports per service
101
+ - "${BACKEND_PORT:-8000}:8000"
102
+ - "${DEBUG_PORT:-9229}:9229"
103
+
104
+ # Long-form syntax
105
+ - target: 8000
106
+ published: "${BACKEND_PORT:-8000}"
107
+ protocol: tcp
139
108
  ```
140
- {repo-name}-wt-{index}-{branch}
141
- ```
142
109
 
143
- For example: `myapp-wt-1-feature-auth`, `myapp-wt-2-fix-billing`.
110
+ ## How It Works
111
+
112
+ ### Port Allocation
144
113
 
145
- This means each worktree has completely separate:
146
- - **Containers** — `myapp-wt-1-feature-auth-postgres-1`, etc.
147
- - **Networks** — `myapp-wt-1-feature-auth_default`
148
- - **Volumes** — `myapp-wt-1-feature-auth_pg-data`
114
+ Each worktree N gets unique ports: `20000 + default_port + worktree_index`
149
115
 
150
- Nothing is shared between worktrees.
116
+ | Service | Main (default) | Worktree 1 | Worktree 2 | Worktree 3 |
117
+ |----------|---------------|------------|------------|------------|
118
+ | postgres | 5434 | 25435 | 25436 | 25437 |
119
+ | redis | 6380 | 26381 | 26382 | 26383 |
120
+ | backend | 8000 | 28001 | 28002 | 28003 |
121
+ | frontend | 5173 | 25174 | 25175 | 25176 |
151
122
 
152
- ### 5. File Sync
123
+ ### Container Isolation
153
124
 
154
- Before starting a worktree's stack, wtc copies infrastructure files from main into the worktree:
125
+ Each worktree gets its own `COMPOSE_PROJECT_NAME`: `{repo}-wt-{index}-{branch}`. This means separate containers, networks, and volumes. Nothing is shared.
155
126
 
156
- - The compose file itself
157
- - Every Dockerfile referenced in `build.dockerfile` fields
158
- - `.env` (or `.env.example` if `.env` doesn't exist)
127
+ ### File Sync
159
128
 
160
- This ensures the worktree always has the latest Docker setup, even if the worktree's branch doesn't have recent infrastructure changes.
129
+ Before starting, `wtc` copies infrastructure files from main into the worktree: the compose file, every Dockerfile referenced in `build.dockerfile`, and `.env`. This ensures the worktree always has the latest Docker setup.
161
130
 
162
- ### 6. Env Injection
131
+ ### Env Injection
163
132
 
164
- After copying `.env`, wtc appends a clearly delimited block with the allocated port overrides:
133
+ After copying `.env`, `wtc` appends an idempotent block with allocated port overrides:
165
134
 
166
135
  ```bash
167
136
  # existing .env content stays untouched...
168
- OPENAI_API_KEY=sk-...
169
- DATABASE_URL=...
170
137
 
171
138
  # --- wtc port overrides ---
172
139
  POSTGRES_PORT=25435
@@ -176,306 +143,89 @@ FRONTEND_PORT=25174
176
143
  # --- end wtc ---
177
144
  ```
178
145
 
179
- This is **idempotent** — running `wtc start` again strips the old block and writes a fresh one.
180
-
181
146
  ## Commands
182
147
 
183
148
  ### `wtc start [indices...]`
184
149
 
185
- Start Docker Compose stacks for worktrees.
150
+ Start Docker Compose stacks. Syncs files, injects ports, runs `docker compose up -d --build`.
186
151
 
187
152
  ```bash
188
- npx wtc start # start ALL worktrees
189
- npx wtc start 1 # start worktree 1 only
190
- npx wtc start 1 2 3 # start worktrees 1, 2, and 3
191
- ```
192
-
193
- **What it does for each worktree:**
194
-
195
- 1. Syncs the compose file and Dockerfiles from main
196
- 2. Copies `.env` and injects port overrides
197
- 3. Runs `docker compose up -d --build` with the worktree's unique project name
198
-
199
- **Output:**
200
-
201
- ```
202
- === Worktree 1: feature-auth ===
203
- ℹ Path: /Users/you/myapp-feature-auth
204
- ℹ Project: myapp-wt-1-feature-auth
205
- ℹ Ports: POSTGRES_PORT=25435 REDIS_PORT=26381 BACKEND_PORT=28001 FRONTEND_PORT=25174
206
- ✔ Synced infrastructure files
207
- ✔ Injected port overrides into .env
208
- [+] Running 5/5
209
- ✔ Container myapp-wt-1-feature-auth-postgres-1 Started
210
- ✔ Container myapp-wt-1-feature-auth-redis-1 Started
211
- ✔ Container myapp-wt-1-feature-auth-backend-1 Started
212
- ✔ Container myapp-wt-1-feature-auth-frontend-1 Started
213
- ✔ Worktree 1 started
153
+ npx wtc start # all worktrees
154
+ npx wtc start 1 # worktree 1 only
155
+ npx wtc start 1 2 3 # worktrees 1, 2, and 3
214
156
  ```
215
157
 
216
- After starting, it prints a table of all worktrees with their URLs.
217
-
218
158
  ### `wtc stop [indices...]`
219
159
 
220
- Stop Docker Compose stacks for worktrees.
160
+ Stop stacks. Runs `docker compose down`. Volumes are preserved.
221
161
 
222
162
  ```bash
223
- npx wtc stop # stop ALL worktrees
224
- npx wtc stop 1 # stop worktree 1 only
225
- npx wtc stop 1 2 # stop worktrees 1 and 2
163
+ npx wtc stop # all
164
+ npx wtc stop 1 # worktree 1 only
226
165
  ```
227
166
 
228
- Runs `docker compose down` for each target worktree. Data in named volumes is preserved — only containers and networks are removed.
229
-
230
167
  ### `wtc restart [indices...]`
231
168
 
232
- Stop and then start worktrees. This is a full restart: re-syncs files, re-injects env vars, and rebuilds containers.
169
+ Full restart: stop, re-sync files, re-inject env, rebuild, start. Use after migrations, Dockerfile changes, or config updates.
233
170
 
234
171
  ```bash
235
- npx wtc restart # restart ALL worktrees
236
- npx wtc restart 1 # restart worktree 1 only
237
- npx wtc restart 1 2 # restart worktrees 1 and 2
172
+ npx wtc restart 1
238
173
  ```
239
174
 
240
- **When to use restart:**
241
- - An agent wrote a database migration that needs to run on startup
242
- - Dockerfiles were changed and containers need rebuilding
243
- - The compose file was modified
244
- - `.env` values in main changed and need to be re-synced
245
-
246
175
  ### `wtc list` / `wtc ls`
247
176
 
248
- Show all worktrees with their branch, status (up/down), URLs, and port assignments.
177
+ Show all worktrees with branch, status, URL, and ports.
249
178
 
250
179
  ```bash
251
180
  npx wtc list
252
181
  ```
253
182
 
254
- **Output:**
255
-
256
- ```
257
- ┌───────┬───────────────┬────────┬────────────────────────┬─────────────────────────────────────────────────────────┐
258
- │ Index │ Branch │ Status │ URL │ Ports │
259
- ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
260
- │ - │ main │ - │ - │ postgres:5434 redis:6380 backend:8000 frontend:5173 │
261
- ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
262
- │ 1 │ feature-auth │ up │ http://localhost:25174 │ postgres:25435 redis:26381 backend:28001 frontend:25174 │
263
- ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
264
- │ 2 │ fix-billing │ down │ http://localhost:25175 │ postgres:25436 redis:26382 backend:28002 frontend:25175 │
265
- └───────┴───────────────┴────────┴────────────────────────┴─────────────────────────────────────────────────────────┘
266
- ```
267
-
268
- - **Index** — the number you pass to other commands (`wtc start 1`, `wtc promote 2`)
269
- - **Branch** — the git branch checked out in that worktree
270
- - **Status** — whether Docker containers are currently running
271
- - **URL** — the frontend URL (auto-detected from services named `frontend`, `web`, `app`, or `ui`)
272
- - **Ports** — all allocated ports for that worktree
273
-
274
183
  ### `wtc promote <index>`
275
184
 
276
- Copy all changed files from a worktree into your current branch as uncommitted changes.
185
+ Copy changed files from a worktree into your current branch as uncommitted changes. Automatically excludes `.env` and compose files. Aborts if it would overwrite uncommitted local changes.
277
186
 
278
187
  ```bash
279
188
  npx wtc promote 1
280
189
  ```
281
190
 
282
- **What it does:**
283
-
284
- 1. Finds the divergence point between your current branch and the worktree's branch (`git merge-base`)
285
- 2. Collects all files that changed in the worktree (committed, uncommitted, and untracked)
286
- 3. **Safety check** — aborts if any of those files have uncommitted changes in your current branch (prevents overwriting your work)
287
- 4. Copies changed files into your repo (or deletes files that were removed in the worktree)
288
- 5. Leaves everything as uncommitted changes so you can review before committing
289
-
290
- **What it excludes automatically:**
291
- - `.env` — this was injected by wtc, not authored by the agent
292
- - `docker-compose.yml` / `compose.yml` — synced from main, not a real change
293
-
294
- **Output:**
295
-
296
- ```
297
- ℹ Promoting worktree 1 (feature-auth) into main
298
- ✔ Promoted 12 file(s). Changes are uncommitted in main.
299
- src/auth/login.ts
300
- src/auth/session.ts
301
- src/middleware/auth.ts
302
- ...
303
- ```
304
-
305
- **If there's a conflict:**
306
-
307
- ```
308
- ✖ Abort: the following files have uncommitted changes and would be overwritten:
309
- src/auth/login.ts
310
-
311
- Commit or stash your local changes first, then re-run promote.
312
- ```
313
-
314
191
  ### `wtc clean`
315
192
 
316
- Stop all worktree containers, remove all worktrees (except your current one), and prune stale Docker resources.
193
+ Stop all containers, remove all worktrees, prune stale Docker resources.
317
194
 
318
195
  ```bash
319
196
  npx wtc clean
320
197
  ```
321
198
 
322
- **What it does:**
323
-
324
- 1. For each non-main worktree:
325
- - Stops its Docker Compose stack (`docker compose down`)
326
- - Removes the git worktree (`git worktree remove --force`)
327
- 2. Prunes stale git worktree references (`git worktree prune`)
328
- 3. Removes any orphaned Docker containers, networks, and volumes matching the `*-wt-*` pattern
329
-
330
- **Output:**
331
-
332
- ```
333
- ℹ Stopping containers for myapp-wt-1-feature-auth...
334
- ℹ Removing worktree: /Users/you/myapp-feature-auth
335
- ℹ Stopping containers for myapp-wt-2-fix-billing...
336
- ℹ Removing worktree: /Users/you/myapp-fix-billing
337
- ✔ Cleanup complete.
338
- ```
339
-
340
- ### `wtc mcp`
341
-
342
- Start the MCP (Model Context Protocol) server. This is not meant to be run manually — it's used by AI agents. See the [MCP Server](#mcp-server) section below.
343
-
344
- ## Preparing Your docker-compose.yml
345
-
346
- For `wtc` to isolate a service's port, the host port must use the `${VAR:-default}` pattern:
347
-
348
- ```yaml
349
- # wtc CAN isolate this (env var pattern)
350
- ports:
351
- - "${BACKEND_PORT:-8000}:8000"
352
-
353
- # wtc CANNOT isolate this (hardcoded number)
354
- ports:
355
- - "8080:8080"
356
- ```
357
-
358
- If `wtc` finds hardcoded ports, it warns you and suggests the fix:
359
-
360
- ```
361
- ⚠ Service "nginx" uses a raw port mapping (8080:80).
362
- To enable port isolation, change it to: "${NGINX_PORT:-8080}:80"
363
- ```
364
-
365
- ### Supported port formats
366
-
367
- `wtc` handles all common Docker Compose port syntaxes:
368
-
369
- ```yaml
370
- # Standard — most common
371
- - "${BACKEND_PORT:-8000}:8000"
372
-
373
- # Same var for host and container (when the app reads the port from env)
374
- - "${FRONTEND_PORT:-5173}:${FRONTEND_PORT:-5173}"
375
-
376
- # IP-bound
377
- - "127.0.0.1:${API_PORT:-3000}:3000"
378
-
379
- # With protocol
380
- - "${BACKEND_PORT:-8000}:8000/tcp"
381
-
382
- # Multiple ports per service
383
- - "${BACKEND_PORT:-8000}:8000"
384
- - "${DEBUG_PORT:-9229}:9229"
385
-
386
- # Long-form syntax
387
- - target: 8000
388
- published: "${BACKEND_PORT:-8000}"
389
- protocol: tcp
390
- ```
391
-
392
199
  ## Configuration (Optional)
393
200
 
394
- `wtc` works zero-config out of the box. For project-specific needs, create a `.wtcrc.json` in your repo root:
201
+ `wtc` works zero-config. For project-specific needs, create `.wtcrc.json` in your repo root:
395
202
 
396
203
  ```json
397
204
  {
398
- "sync": ["backend/alembic", "backend/alembic.ini"],
205
+ "sync": [".generated/prisma-client", "local-certs/"],
399
206
  "envOverrides": {
400
207
  "VITE_API_URL": "http://localhost:${BACKEND_PORT}"
401
208
  }
402
209
  }
403
210
  ```
404
211
 
405
- Or add a `"wtc"` key in your `package.json`:
406
-
407
- ```json
408
- {
409
- "wtc": {
410
- "sync": ["backend/alembic"],
411
- "envOverrides": {
412
- "VITE_API_URL": "http://localhost:${BACKEND_PORT}"
413
- }
414
- }
415
- }
416
- ```
417
-
418
- Config is looked for in this order:
419
- 1. `.wtcrc.json` in repo root
420
- 2. `"wtc"` key in `package.json`
421
- 3. No config (zero-config defaults)
212
+ Or use a `"wtc"` key in `package.json`.
422
213
 
423
214
  ### `sync`
424
215
 
425
- Extra files or directories to copy from main into each worktree on every start.
426
-
427
- **Why this exists:** Git worktrees check out a branch's files, but the branch may not have the latest infrastructure files (migration configs, seed scripts, etc.). This setting ensures every worktree gets fresh copies of these files from main.
428
-
429
- **Example:** Your backend uses Alembic for database migrations. The migration files live in `backend/alembic/` and the config in `backend/alembic.ini`. Without syncing these, a worktree on an older branch would have outdated migration files.
430
-
431
- ```json
432
- {
433
- "sync": [
434
- "backend/alembic",
435
- "backend/alembic.ini"
436
- ]
437
- }
438
- ```
439
-
440
- Both files and directories are supported. Directories are copied recursively.
216
+ Extra files/directories to copy from main into each worktree on start. Use for gitignored or generated files that Docker needs but aren't committed — like generated clients, local certificates, or build artifacts.
441
217
 
442
218
  ### `envOverrides`
443
219
 
444
- Additional environment variables to inject into each worktree's `.env`. Supports `${VAR}` interpolation with the allocated port values.
445
-
446
- **Why this exists:** Some env vars depend on allocated ports. For example, a frontend might need `VITE_API_URL` pointing to the backend's allocated port. Since `wtc` assigns different backend ports per worktree, this URL must be derived dynamically.
447
-
448
- ```json
449
- {
450
- "envOverrides": {
451
- "VITE_API_URL": "http://localhost:${BACKEND_PORT}",
452
- "VITE_WS_URL": "ws://localhost:${BACKEND_PORT}/ws"
453
- }
454
- }
455
- ```
456
-
457
- With worktree 1 getting `BACKEND_PORT=28001`, this produces:
458
-
459
- ```bash
460
- VITE_API_URL=http://localhost:28001
461
- VITE_WS_URL=ws://localhost:28001/ws
462
- ```
463
-
464
- You can reference any env var that `wtc` allocates (any `${VAR:-default}` port pattern found in your compose file).
220
+ Additional env vars injected into `.env`. Supports `${VAR}` interpolation with allocated port values. Use when env vars depend on allocated ports (e.g. `VITE_API_URL`).
465
221
 
466
222
  ## MCP Server
467
223
 
468
- `wtc` ships a built-in [MCP](https://modelcontextprotocol.io/) server so AI agents can manage their worktree's Docker stack programmatically — without shelling out to the CLI.
469
-
470
- ### Why
471
-
472
- When an AI agent is working in a worktree and makes changes that need a container restart (like adding a database migration), it needs a way to restart its stack. The MCP server exposes all `wtc` commands as tools that agents can call directly.
224
+ Built-in [MCP](https://modelcontextprotocol.io/) server so AI agents can manage their stack programmatically.
473
225
 
474
226
  ### Setup
475
227
 
476
- The MCP server uses stdio transport. Configure it in your agent's MCP settings:
477
-
478
- **Claude Code** (`.claude/settings.json` or `.claude/settings.local.json`):
228
+ **Claude Code** (`.claude/settings.json`):
479
229
 
480
230
  ```json
481
231
  {
@@ -501,117 +251,57 @@ The MCP server uses stdio transport. Configure it in your agent's MCP settings:
501
251
  }
502
252
  ```
503
253
 
504
- ### Available Tools
254
+ ### Tools
505
255
 
506
256
  | Tool | Parameters | Description |
507
257
  |------|-----------|-------------|
508
- | `wtc_start` | `indices?: number[]` | Start worktree stacks. Pass specific indices or omit for all. |
509
- | `wtc_stop` | `indices?: number[]` | Stop worktree stacks. Pass specific indices or omit for all. |
510
- | `wtc_restart` | `indices?: number[]` | Restart worktree stacks. Use after DB migrations, Dockerfile changes, or config updates that require fresh containers. |
511
- | `wtc_list` | none | List all worktrees with branch, status (up/down), ports, and URLs. Returns structured JSON. |
512
- | `wtc_promote` | `index: number` | Copy changed files from a worktree into the current branch as uncommitted changes. |
513
- | `wtc_clean` | none | Stop all containers, remove all worktrees, prune stale Docker resources. |
514
-
515
- ### Agent Workflow Example
258
+ | `wtc_start` | `indices?: number[]` | Start worktree stacks |
259
+ | `wtc_stop` | `indices?: number[]` | Stop worktree stacks |
260
+ | `wtc_restart` | `indices?: number[]` | Restart after migrations/config changes |
261
+ | `wtc_list` | none | List worktrees (returns JSON) |
262
+ | `wtc_promote` | `index: number` | Pull worktree changes into current branch |
263
+ | `wtc_clean` | none | Tear down everything |
516
264
 
517
- 1. **Human** creates worktrees and runs `npx wtc start`
518
- 2. **Agents** are spawned in separate worktrees, each with its own isolated stack
519
- 3. An agent writes a database migration, then calls `wtc_restart` with its worktree index — containers restart, the migration runs on startup
520
- 4. The agent verifies the migration worked by hitting its own backend URL
521
- 5. **Human** opens each worktree's frontend URL, compares the results side by side
522
- 6. **Human** runs `npx wtc promote 1` to pull the best agent's changes into main
523
- 7. **Human** runs `npx wtc clean` to tear everything down
524
-
525
- ## Full Example Walkthrough
526
-
527
- Here's a complete end-to-end example with a typical web app:
265
+ ## Full Example
528
266
 
529
267
  ```bash
530
- # You have a repo with docker-compose.yml containing postgres, redis, backend, frontend
531
268
  cd myapp
532
-
533
- # Install wtc
534
269
  pnpm add -D worktree-compose
535
270
 
536
- # Create branches for two AI agents to work on
537
271
  git branch agent-1-auth
538
272
  git branch agent-2-auth
539
-
540
- # Create worktrees
541
273
  git worktree add ../myapp-agent-1 agent-1-auth
542
274
  git worktree add ../myapp-agent-2 agent-2-auth
543
275
 
544
- # Start both stacks
545
276
  npx wtc start
277
+ # Worktree 1: backend:28001 frontend:25174
278
+ # Worktree 2: backend:28002 frontend:25175
546
279
 
547
- # Output shows:
548
- # Worktree 1 (agent-1-auth): backend:28001 frontend:25174
549
- # Worktree 2 (agent-2-auth): backend:28002 frontend:25175
550
-
551
- # Point each agent at its worktree directory
552
- # Agent 1 works in ../myapp-agent-1
553
- # Agent 2 works in ../myapp-agent-2
554
-
555
- # Check status anytime
556
- npx wtc list
557
-
558
- # Compare frontends side by side
280
+ # Compare side by side
559
281
  # http://localhost:25174 (agent 1)
560
282
  # http://localhost:25175 (agent 2)
561
283
 
562
- # Agent 1 did a better job — promote its changes
563
284
  npx wtc promote 1
564
-
565
- # Review the changes
566
- git diff
567
-
568
- # Commit if happy
569
- git add -A && git commit -m "feat: add auth (from agent 1)"
570
-
571
- # Clean up
285
+ git add -A && git commit -m "feat: auth from agent 1"
572
286
  npx wtc clean
573
287
  ```
574
288
 
575
289
  ## Requirements
576
290
 
577
291
  - **Node.js** >= 18
578
- - **Git** with worktree support (any modern version)
579
- - **Docker** with Compose v2 (`docker compose`, not the legacy `docker-compose`)
580
- - A `docker-compose.yml` with `${VAR:-default}` port patterns for any service you want isolated
292
+ - **Git** with worktree support
293
+ - **Docker** with Compose v2 (`docker compose`)
294
+ - `docker-compose.yml` with `${VAR:-default}` port patterns
581
295
 
582
296
  ## Troubleshooting
583
297
 
584
- ### "No compose file found"
585
-
586
- `wtc` looks for compose files in the git repo root (found via `git rev-parse --show-toplevel`), not the current directory. Make sure your compose file is in the repo root and named one of: `compose.yaml`, `compose.yml`, `docker-compose.yaml`, `docker-compose.yml`.
298
+ **"No compose file found"** — `wtc` looks in the git repo root, not the current directory.
587
299
 
588
- ### "No extra worktrees found"
300
+ **"No extra worktrees found"** — Create worktrees first: `git worktree add ../my-feature my-branch`
589
301
 
590
- You need to create git worktrees before using `wtc`. Create them with:
302
+ **Ports not changing** Use `${VAR:-default}` for host ports, not hardcoded numbers.
591
303
 
592
- ```bash
593
- git worktree add ../my-feature my-feature-branch
594
- ```
595
-
596
- ### Ports not changing
597
-
598
- Make sure your compose file uses `${VAR:-default}` for host ports, not hardcoded numbers. `wtc` can only override ports that use env var patterns.
599
-
600
- ### "Docker daemon not running"
601
-
602
- Start Docker Desktop (or the Docker daemon) before running `wtc start`.
603
-
604
- ### Promote fails with "Not a valid object name detached"
605
-
606
- This happened in older versions when a worktree was in detached HEAD state. Update to the latest version — this is now handled correctly.
607
-
608
- ### Stale containers after manual cleanup
609
-
610
- If you manually removed worktrees without running `wtc clean`, orphaned containers may remain. Run `wtc clean` to remove them, or manually:
611
-
612
- ```bash
613
- docker ps -a --filter "name=-wt-" -q | xargs docker rm -f
614
- ```
304
+ **Stale containers** — Run `wtc clean`, or manually: `docker ps -a --filter "name=-wt-" -q | xargs docker rm -f`
615
305
 
616
306
  ## License
617
307
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worktree-compose",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "Zero-config Docker Compose isolation for git worktrees",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,6 +29,14 @@
29
29
  "development",
30
30
  "mcp"
31
31
  ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/LevwTech/worktree-compose.git"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/LevwTech/worktree-compose/issues"
38
+ },
39
+ "homepage": "https://github.com/LevwTech/worktree-compose#readme",
32
40
  "license": "MIT",
33
41
  "dependencies": {
34
42
  "@modelcontextprotocol/sdk": "^1.12.1",