worktree-compose 0.1.0 → 0.1.2

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 (2) hide show
  1. package/README.md +118 -430
  2. package/package.json +9 -1
package/README.md CHANGED
@@ -1,172 +1,137 @@
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.
22
-
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
5
+ Zero-config Docker Compose isolation for git worktrees.
29
6
 
30
- ## Install
7
+ Every worktree gets its own ports, database, cache, and containers — automatically.
31
8
 
32
9
  ```bash
33
10
  npm install -D worktree-compose
34
- # or
35
- pnpm add -D worktree-compose
36
- # or
37
- yarn add -D worktree-compose
38
11
  ```
39
12
 
40
- This gives you the `wtc` command in your project.
13
+ ```
14
+ npx wtc list
15
+
16
+ ┌───────┬───────────────┬────────┬────────────────────────┬─────────────────────────────────────────────────────────┐
17
+ │ Index │ Branch │ Status │ URL │ Ports │
18
+ ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
19
+ │ - │ main │ - │ - │ postgres:5434 redis:6380 backend:8000 frontend:5173 │
20
+ ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
21
+ │ 1 │ feature-auth │ up │ http://localhost:25174 │ postgres:25435 redis:26381 backend:28001 frontend:25174 │
22
+ ├───────┼───────────────┼────────┼────────────────────────┼─────────────────────────────────────────────────────────┤
23
+ │ 2 │ fix-billing │ down │ http://localhost:25175 │ postgres:25436 redis:26382 backend:28002 frontend:25175 │
24
+ └───────┴───────────────┴────────┴────────────────────────┴─────────────────────────────────────────────────────────┘
25
+ ```
41
26
 
42
- ## Quick Start
27
+ ## Usage
43
28
 
44
29
  ```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
30
+ # Start isolated stacks for all worktrees
50
31
  npx wtc start
51
32
 
52
- # 3. See what's running
33
+ # Start specific worktrees
34
+ npx wtc start 1
35
+ npx wtc start 1 2 3
36
+
37
+ # See what's running
53
38
  npx wtc list
54
39
 
55
- # 4. Open each frontend in your browser and compare
40
+ # Stop worktrees
41
+ npx wtc stop
42
+ npx wtc stop 1
43
+
44
+ # Restart (re-sync files, rebuild containers)
45
+ npx wtc restart 1
56
46
 
57
- # 5. Pick the best one and pull its changes into main
47
+ # Pull a worktree's changes into your current branch
58
48
  npx wtc promote 1
59
49
 
60
- # 6. Clean up everything
50
+ # Tear down everything (containers, worktrees, volumes)
61
51
  npx wtc clean
62
52
  ```
63
53
 
64
- ## How It Works
65
-
66
- ### 1. Auto-Detection
54
+ ## The Problem
67
55
 
68
- `wtc` finds your compose file in the repo root, checking these names in order (matching Docker Compose's own precedence):
56
+ 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
57
 
70
- 1. `compose.yaml`
71
- 2. `compose.yml`
72
- 3. `docker-compose.yaml`
73
- 4. `docker-compose.yml`
58
+ ## The Solution
74
59
 
75
- ### 2. Port Parsing
60
+ `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
61
 
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.
62
+ ## Preparing Your docker-compose.yml
78
63
 
79
- **Your compose file:**
64
+ For `wtc` to isolate a service's port, the host port must use the `${VAR:-default}` pattern:
80
65
 
81
66
  ```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).
67
+ # wtc CAN isolate this
68
+ ports:
69
+ - "${BACKEND_PORT:-8000}:8000"
115
70
 
116
- ### 3. Port Allocation
71
+ # wtc CANNOT isolate this (hardcoded)
72
+ ports:
73
+ - "8080:8080"
74
+ ```
117
75
 
118
- Each worktree N gets unique ports using the formula:
76
+ If `wtc` finds hardcoded ports, it warns you and suggests the fix:
119
77
 
120
78
  ```
121
- port = 20000 + default_port + worktree_index
79
+ Service "nginx" uses a raw port mapping (8080:80).
80
+ To enable port isolation, change it to: "${NGINX_PORT:-8080}:80"
122
81
  ```
123
82
 
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 |
83
+ ### Supported port formats
130
84
 
131
- The `20000` offset ensures worktree ports never collide with the main worktree's defaults or common system ports.
85
+ ```yaml
86
+ # Standard
87
+ - "${BACKEND_PORT:-8000}:8000"
88
+
89
+ # Same var for host and container
90
+ - "${FRONTEND_PORT:-5173}:${FRONTEND_PORT:-5173}"
132
91
 
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.
92
+ # IP-bound
93
+ - "127.0.0.1:${API_PORT:-3000}:3000"
134
94
 
135
- ### 4. Container Isolation
95
+ # With protocol
96
+ - "${BACKEND_PORT:-8000}:8000/tcp"
136
97
 
137
- Each worktree gets its own `COMPOSE_PROJECT_NAME` following the pattern:
98
+ # Multiple ports per service
99
+ - "${BACKEND_PORT:-8000}:8000"
100
+ - "${DEBUG_PORT:-9229}:9229"
138
101
 
102
+ # Long-form syntax
103
+ - target: 8000
104
+ published: "${BACKEND_PORT:-8000}"
105
+ protocol: tcp
139
106
  ```
140
- {repo-name}-wt-{index}-{branch}
141
- ```
142
107
 
143
- For example: `myapp-wt-1-feature-auth`, `myapp-wt-2-fix-billing`.
108
+ ## How It Works
109
+
110
+ ### Port Allocation
144
111
 
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`
112
+ Each worktree N gets unique ports: `20000 + default_port + worktree_index`
149
113
 
150
- Nothing is shared between worktrees.
114
+ | Service | Main (default) | Worktree 1 | Worktree 2 | Worktree 3 |
115
+ |----------|---------------|------------|------------|------------|
116
+ | postgres | 5434 | 25435 | 25436 | 25437 |
117
+ | redis | 6380 | 26381 | 26382 | 26383 |
118
+ | backend | 8000 | 28001 | 28002 | 28003 |
119
+ | frontend | 5173 | 25174 | 25175 | 25176 |
151
120
 
152
- ### 5. File Sync
121
+ ### Container Isolation
153
122
 
154
- Before starting a worktree's stack, wtc copies infrastructure files from main into the worktree:
123
+ Each worktree gets its own `COMPOSE_PROJECT_NAME`: `{repo}-wt-{index}-{branch}`. This means separate containers, networks, and volumes. Nothing is shared.
155
124
 
156
- - The compose file itself
157
- - Every Dockerfile referenced in `build.dockerfile` fields
158
- - `.env` (or `.env.example` if `.env` doesn't exist)
125
+ ### File Sync
159
126
 
160
- This ensures the worktree always has the latest Docker setup, even if the worktree's branch doesn't have recent infrastructure changes.
127
+ 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
128
 
162
- ### 6. Env Injection
129
+ ### Env Injection
163
130
 
164
- After copying `.env`, wtc appends a clearly delimited block with the allocated port overrides:
131
+ After copying `.env`, `wtc` appends an idempotent block with allocated port overrides:
165
132
 
166
133
  ```bash
167
134
  # existing .env content stays untouched...
168
- OPENAI_API_KEY=sk-...
169
- DATABASE_URL=...
170
135
 
171
136
  # --- wtc port overrides ---
172
137
  POSTGRES_PORT=25435
@@ -176,222 +141,62 @@ FRONTEND_PORT=25174
176
141
  # --- end wtc ---
177
142
  ```
178
143
 
179
- This is **idempotent** — running `wtc start` again strips the old block and writes a fresh one.
180
-
181
144
  ## Commands
182
145
 
183
146
  ### `wtc start [indices...]`
184
147
 
185
- Start Docker Compose stacks for worktrees.
148
+ Start Docker Compose stacks. Syncs files, injects ports, runs `docker compose up -d --build`.
186
149
 
187
150
  ```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
-
151
+ npx wtc start # all worktrees
152
+ npx wtc start 1 # worktree 1 only
153
+ npx wtc start 1 2 3 # worktrees 1, 2, and 3
201
154
  ```
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
214
- ```
215
-
216
- After starting, it prints a table of all worktrees with their URLs.
217
155
 
218
156
  ### `wtc stop [indices...]`
219
157
 
220
- Stop Docker Compose stacks for worktrees.
158
+ Stop stacks. Runs `docker compose down`. Volumes are preserved.
221
159
 
222
160
  ```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
161
+ npx wtc stop # all
162
+ npx wtc stop 1 # worktree 1 only
226
163
  ```
227
164
 
228
- Runs `docker compose down` for each target worktree. Data in named volumes is preserved — only containers and networks are removed.
229
-
230
165
  ### `wtc restart [indices...]`
231
166
 
232
- Stop and then start worktrees. This is a full restart: re-syncs files, re-injects env vars, and rebuilds containers.
167
+ Full restart: stop, re-sync files, re-inject env, rebuild, start. Use after migrations, Dockerfile changes, or config updates.
233
168
 
234
169
  ```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
170
+ npx wtc restart 1
238
171
  ```
239
172
 
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
173
  ### `wtc list` / `wtc ls`
247
174
 
248
- Show all worktrees with their branch, status (up/down), URLs, and port assignments.
175
+ Show all worktrees with branch, status, URL, and ports.
249
176
 
250
177
  ```bash
251
178
  npx wtc list
252
179
  ```
253
180
 
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
181
  ### `wtc promote <index>`
275
182
 
276
- Copy all changed files from a worktree into your current branch as uncommitted changes.
183
+ 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
184
 
278
185
  ```bash
279
186
  npx wtc promote 1
280
187
  ```
281
188
 
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
189
  ### `wtc clean`
315
190
 
316
- Stop all worktree containers, remove all worktrees (except your current one), and prune stale Docker resources.
191
+ Stop all containers, remove all worktrees, prune stale Docker resources.
317
192
 
318
193
  ```bash
319
194
  npx wtc clean
320
195
  ```
321
196
 
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
197
  ## Configuration (Optional)
393
198
 
394
- `wtc` works zero-config out of the box. For project-specific needs, create a `.wtcrc.json` in your repo root:
199
+ `wtc` works zero-config. For project-specific needs, create `.wtcrc.json` in your repo root:
395
200
 
396
201
  ```json
397
202
  {
@@ -402,80 +207,23 @@ If `wtc` finds hardcoded ports, it warns you and suggests the fix:
402
207
  }
403
208
  ```
404
209
 
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)
210
+ Or use a `"wtc"` key in `package.json`.
422
211
 
423
212
  ### `sync`
424
213
 
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.
214
+ Extra files/directories to copy from main into each worktree on start. Use for migration configs, seed scripts, or anything not on the worktree's branch.
441
215
 
442
216
  ### `envOverrides`
443
217
 
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).
218
+ 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
219
 
466
220
  ## MCP Server
467
221
 
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.
222
+ Built-in [MCP](https://modelcontextprotocol.io/) server so AI agents can manage their stack programmatically.
473
223
 
474
224
  ### Setup
475
225
 
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`):
226
+ **Claude Code** (`.claude/settings.json`):
479
227
 
480
228
  ```json
481
229
  {
@@ -501,117 +249,57 @@ The MCP server uses stdio transport. Configure it in your agent's MCP settings:
501
249
  }
502
250
  ```
503
251
 
504
- ### Available Tools
252
+ ### Tools
505
253
 
506
254
  | Tool | Parameters | Description |
507
255
  |------|-----------|-------------|
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. |
256
+ | `wtc_start` | `indices?: number[]` | Start worktree stacks |
257
+ | `wtc_stop` | `indices?: number[]` | Stop worktree stacks |
258
+ | `wtc_restart` | `indices?: number[]` | Restart after migrations/config changes |
259
+ | `wtc_list` | none | List worktrees (returns JSON) |
260
+ | `wtc_promote` | `index: number` | Pull worktree changes into current branch |
261
+ | `wtc_clean` | none | Tear down everything |
514
262
 
515
- ### Agent Workflow Example
516
-
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:
263
+ ## Full Example
528
264
 
529
265
  ```bash
530
- # You have a repo with docker-compose.yml containing postgres, redis, backend, frontend
531
266
  cd myapp
532
-
533
- # Install wtc
534
267
  pnpm add -D worktree-compose
535
268
 
536
- # Create branches for two AI agents to work on
537
269
  git branch agent-1-auth
538
270
  git branch agent-2-auth
539
-
540
- # Create worktrees
541
271
  git worktree add ../myapp-agent-1 agent-1-auth
542
272
  git worktree add ../myapp-agent-2 agent-2-auth
543
273
 
544
- # Start both stacks
545
274
  npx wtc start
275
+ # Worktree 1: backend:28001 frontend:25174
276
+ # Worktree 2: backend:28002 frontend:25175
546
277
 
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
278
+ # Compare side by side
559
279
  # http://localhost:25174 (agent 1)
560
280
  # http://localhost:25175 (agent 2)
561
281
 
562
- # Agent 1 did a better job — promote its changes
563
282
  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
283
+ git add -A && git commit -m "feat: auth from agent 1"
572
284
  npx wtc clean
573
285
  ```
574
286
 
575
287
  ## Requirements
576
288
 
577
289
  - **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
290
+ - **Git** with worktree support
291
+ - **Docker** with Compose v2 (`docker compose`)
292
+ - `docker-compose.yml` with `${VAR:-default}` port patterns
581
293
 
582
294
  ## Troubleshooting
583
295
 
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`.
296
+ **"No compose file found"** — `wtc` looks in the git repo root, not the current directory.
587
297
 
588
- ### "No extra worktrees found"
298
+ **"No extra worktrees found"** — Create worktrees first: `git worktree add ../my-feature my-branch`
589
299
 
590
- You need to create git worktrees before using `wtc`. Create them with:
300
+ **Ports not changing** Use `${VAR:-default}` for host ports, not hardcoded numbers.
591
301
 
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
- ```
302
+ **Stale containers** — Run `wtc clean`, or manually: `docker ps -a --filter "name=-wt-" -q | xargs docker rm -f`
615
303
 
616
304
  ## License
617
305
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worktree-compose",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
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",