@tokenbooks/wt 0.2.2 → 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 +59 -28
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/new.js +30 -5
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/prune.d.ts +8 -0
- package/dist/commands/prune.js +210 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/commands/prune.spec.d.ts +1 -0
- package/dist/commands/prune.spec.js +173 -0
- package/dist/commands/prune.spec.js.map +1 -0
- package/dist/commands/remove.js +11 -1
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/setup.js +144 -7
- package/dist/commands/setup.js.map +1 -1
- package/dist/core/env-patcher.js +8 -8
- package/dist/core/env-patcher.js.map +1 -1
- package/dist/core/git.d.ts +8 -0
- package/dist/core/git.js +32 -0
- package/dist/core/git.js.map +1 -1
- package/dist/core/managed-redis.d.ts +19 -0
- package/dist/core/managed-redis.js +266 -0
- package/dist/core/managed-redis.js.map +1 -0
- package/dist/core/slot-allocator.d.ts +10 -0
- package/dist/core/slot-allocator.js +98 -0
- package/dist/core/slot-allocator.js.map +1 -1
- package/dist/output.js +14 -3
- package/dist/output.js.map +1 -1
- package/dist/schemas/config.schema.d.ts +45 -27
- package/dist/schemas/config.schema.js +22 -6
- package/dist/schemas/config.schema.js.map +1 -1
- package/dist/schemas/registry.schema.d.ts +4 -2
- package/dist/schemas/registry.schema.js +2 -1
- package/dist/schemas/registry.schema.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +2 -1
- package/skills/wt/SKILL.md +31 -12
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# wt — Git Worktree Environment Isolation
|
|
2
2
|
|
|
3
|
-
A CLI tool that gives each git worktree its own Postgres database, Redis
|
|
3
|
+
A CLI tool that gives each git worktree its own Postgres database, managed Redis container, ports, and `.env` files. Prevents worktrees from corrupting each other's data.
|
|
4
4
|
|
|
5
5
|
## The Problem
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ When you use `git worktree add` for parallel development, all worktrees share th
|
|
|
11
11
|
- Two dev servers can't run simultaneously on the same port
|
|
12
12
|
- `.env` files point to the same resources everywhere
|
|
13
13
|
|
|
14
|
-
`wt` solves this by assigning each worktree an isolated **slot**
|
|
14
|
+
`wt` solves this by assigning each worktree an isolated **slot** that determines its database name, Redis container, and port range.
|
|
15
15
|
|
|
16
16
|
## How It Works
|
|
17
17
|
|
|
@@ -20,11 +20,11 @@ Each worktree gets a numbered slot. The slot determines everything:
|
|
|
20
20
|
| Resource | Formula | Slot 0 (main) | Slot 1 | Slot 2 | Slot 3 |
|
|
21
21
|
|----------|---------|:-:|:-:|:-:|:-:|
|
|
22
22
|
| Database | `{baseName}_wt{slot}` | `mydb` | `mydb_wt1` | `mydb_wt2` | `mydb_wt3` |
|
|
23
|
-
| Redis
|
|
23
|
+
| Redis | `wt-<repo>-<hash>-slot-<slot>-redis` on `6379 + slot * stride` | shared/local | `6479` | `6579` | `6679` |
|
|
24
24
|
| Ports | `slot * stride + defaultPort` | 3000, 3001 | 3100, 3101 | 3200, 3201 | 3300, 3301 |
|
|
25
25
|
|
|
26
26
|
- **Database**: Created via `CREATE DATABASE ... TEMPLATE` (fast filesystem copy, not dump/restore)
|
|
27
|
-
- **Redis**:
|
|
27
|
+
- **Redis**: Runs in a dedicated Docker container per worktree, visible in Docker Desktop
|
|
28
28
|
- **Ports**: Offset by `portStride` (default 100) per slot
|
|
29
29
|
- **Env files**: Copied from main worktree and patched with the slot's values
|
|
30
30
|
|
|
@@ -53,10 +53,11 @@ Create this file in your repository root and commit it. See [Configuration Refer
|
|
|
53
53
|
"baseDatabaseName": "myapp",
|
|
54
54
|
"baseWorktreePath": ".worktrees",
|
|
55
55
|
"portStride": 100,
|
|
56
|
-
"maxSlots":
|
|
56
|
+
"maxSlots": 50,
|
|
57
57
|
"services": [
|
|
58
58
|
{ "name": "web", "defaultPort": 3000 },
|
|
59
|
-
{ "name": "api", "defaultPort": 4000 }
|
|
59
|
+
{ "name": "api", "defaultPort": 4000 },
|
|
60
|
+
{ "name": "redis", "defaultPort": 6379 }
|
|
60
61
|
],
|
|
61
62
|
"envFiles": [
|
|
62
63
|
{
|
|
@@ -69,7 +70,7 @@ Create this file in your repository root and commit it. See [Configuration Refer
|
|
|
69
70
|
"source": "backend/.env",
|
|
70
71
|
"patches": [
|
|
71
72
|
{ "var": "DATABASE_URL", "type": "database" },
|
|
72
|
-
{ "var": "REDIS_URL", "type": "redis" },
|
|
73
|
+
{ "var": "REDIS_URL", "type": "redis", "service": "redis" },
|
|
73
74
|
{ "var": "PORT", "type": "port", "service": "api" }
|
|
74
75
|
]
|
|
75
76
|
},
|
|
@@ -108,8 +109,11 @@ wt list
|
|
|
108
109
|
# Check health
|
|
109
110
|
wt doctor
|
|
110
111
|
|
|
111
|
-
# Clean up
|
|
112
|
-
wt remove feat-my-feature
|
|
112
|
+
# Clean up by path or slot
|
|
113
|
+
wt remove .worktrees/feat-my-feature
|
|
114
|
+
|
|
115
|
+
# Prune worktrees Git already considers stale
|
|
116
|
+
wt prune
|
|
113
117
|
```
|
|
114
118
|
|
|
115
119
|
### 5. Claude Code skill (optional)
|
|
@@ -133,7 +137,8 @@ Creates a new git worktree and sets up its isolated environment:
|
|
|
133
137
|
2. Runs `git worktree add .worktrees/<slug> -b <branch>`
|
|
134
138
|
3. Creates a new Postgres database from the main DB as template
|
|
135
139
|
4. Copies all configured `.env` files, patching each with slot-specific values
|
|
136
|
-
5.
|
|
140
|
+
5. Starts a managed Redis Docker container if Redis patching is configured
|
|
141
|
+
6. Runs `postSetup` commands (unless `--no-install`)
|
|
137
142
|
|
|
138
143
|
### `wt open <slot-or-branch> [--no-install] [--json]`
|
|
139
144
|
|
|
@@ -168,19 +173,33 @@ If the worktree already has a slot allocation, it reuses it.
|
|
|
168
173
|
Removes a worktree and cleans up its resources:
|
|
169
174
|
|
|
170
175
|
1. Drops the worktree's Postgres database (unless `--keep-db`)
|
|
171
|
-
2.
|
|
172
|
-
3.
|
|
176
|
+
2. Removes the managed Redis Docker container for that slot
|
|
177
|
+
3. Runs `git worktree remove`
|
|
178
|
+
4. Removes the allocation from the registry
|
|
173
179
|
|
|
174
|
-
Accepts either paths (`.worktrees/feat-my-feature`) or slot numbers (`3`), including batch formats:
|
|
180
|
+
Accepts either paths (`.worktrees/feat-my-feature`) or slot numbers (`3`), not branch names, including batch formats:
|
|
175
181
|
|
|
176
182
|
- `wt remove 1 2`
|
|
177
183
|
- `wt remove 1,2`
|
|
178
184
|
- `wt remove "1, 2"`
|
|
179
185
|
- `wt remove --all`
|
|
180
186
|
|
|
187
|
+
### `wt prune [--dry-run] [--keep-db] [--json]`
|
|
188
|
+
|
|
189
|
+
Finds worktrees that Git already marks as prunable, then:
|
|
190
|
+
|
|
191
|
+
1. Cleans up `wt`-managed resources for matching registry entries
|
|
192
|
+
2. Drops their databases unless `--keep-db` is set
|
|
193
|
+
3. Removes managed Redis containers if present
|
|
194
|
+
4. Runs `git worktree prune`
|
|
195
|
+
|
|
196
|
+
This is mainly for worktrees that were deleted manually from disk instead of through `wt remove`.
|
|
197
|
+
|
|
198
|
+
Use `--dry-run` to preview what would be pruned.
|
|
199
|
+
|
|
181
200
|
### `wt list [--json]`
|
|
182
201
|
|
|
183
|
-
Shows all worktree allocations with their slot, branch, database, Redis
|
|
202
|
+
Shows all worktree allocations with their slot, branch, database, Redis info, ports, and status (ok/stale).
|
|
184
203
|
|
|
185
204
|
### `wt doctor [--fix] [--json]`
|
|
186
205
|
|
|
@@ -209,7 +228,10 @@ Or on error:
|
|
|
209
228
|
```json
|
|
210
229
|
{
|
|
211
230
|
"success": false,
|
|
212
|
-
"error": {
|
|
231
|
+
"error": {
|
|
232
|
+
"code": "NO_SLOTS",
|
|
233
|
+
"message": "All 50 slots are occupied or blocked by ports already in use."
|
|
234
|
+
}
|
|
213
235
|
}
|
|
214
236
|
```
|
|
215
237
|
|
|
@@ -230,10 +252,12 @@ This file lives in your repository root and is committed to version control.
|
|
|
230
252
|
// Port offset per slot (default: 100)
|
|
231
253
|
"portStride": number,
|
|
232
254
|
|
|
233
|
-
// Maximum number of concurrent worktrees (default:
|
|
255
|
+
// Maximum number of concurrent worktrees (default: 50)
|
|
234
256
|
"maxSlots": number,
|
|
235
257
|
|
|
236
|
-
// Services that need port allocation
|
|
258
|
+
// Services that need port allocation.
|
|
259
|
+
// If you use a `redis` patch and omit a redis service,
|
|
260
|
+
// wt assumes { name: "redis", defaultPort: 6379 }.
|
|
237
261
|
"services": [
|
|
238
262
|
{ "name": string, "defaultPort": number }
|
|
239
263
|
],
|
|
@@ -246,7 +270,7 @@ This file lives in your repository root and is committed to version control.
|
|
|
246
270
|
{
|
|
247
271
|
"var": string, // Env var name to patch
|
|
248
272
|
"type": string, // "database" | "redis" | "port" | "url"
|
|
249
|
-
"service": string // Required for "port" and "url" types
|
|
273
|
+
"service": string // Required for "redis", "port", and "url" types
|
|
250
274
|
}
|
|
251
275
|
]
|
|
252
276
|
}
|
|
@@ -260,16 +284,18 @@ This file lives in your repository root and is committed to version control.
|
|
|
260
284
|
}
|
|
261
285
|
```
|
|
262
286
|
|
|
287
|
+
Legacy configs that used a `redis` patch without an explicit `redis` service are auto-migrated on first run.
|
|
288
|
+
|
|
263
289
|
### Patch Types
|
|
264
290
|
|
|
265
291
|
| Type | What it patches | Input | Output (slot 3) |
|
|
266
292
|
|------|----------------|-------|------------------|
|
|
267
293
|
| `database` | Replaces DB name in a Postgres URL | `postgresql://u:p@host:5432/myapp?schema=public` | `postgresql://u:p@host:5432/myapp_wt3?schema=public` |
|
|
268
|
-
| `redis` |
|
|
294
|
+
| `redis` | Rewrites a Redis URL to the managed local Redis container on DB 0 | `redis://:pass@host:6379/0` | `redis://:pass@127.0.0.1:6679/0` |
|
|
269
295
|
| `port` | Replaces the entire value with the allocated port | `4000` | `4300` |
|
|
270
296
|
| `url` | Replaces the port number inside a URL | `http://localhost:4000/api` | `http://localhost:4300/api` |
|
|
271
297
|
|
|
272
|
-
The `port
|
|
298
|
+
The `redis`, `port`, and `url` types require a `service` field that matches a name in `services`.
|
|
273
299
|
|
|
274
300
|
### `.worktree-registry.json`
|
|
275
301
|
|
|
@@ -283,8 +309,8 @@ Auto-managed file at the repo root. **Add to `.gitignore`** — it's machine-loc
|
|
|
283
309
|
"worktreePath": "/absolute/path/to/.worktrees/feat-auth",
|
|
284
310
|
"branchName": "feat/auth",
|
|
285
311
|
"dbName": "myapp_wt1",
|
|
286
|
-
"
|
|
287
|
-
"ports": { "web": 3100, "api": 4100 },
|
|
312
|
+
"redisContainerName": "wt-myapp-a1b2c3d4-slot-1-redis",
|
|
313
|
+
"ports": { "web": 3100, "api": 4100, "redis": 6479 },
|
|
288
314
|
"createdAt": "2026-02-17T14:30:00Z"
|
|
289
315
|
}
|
|
290
316
|
}
|
|
@@ -344,7 +370,7 @@ If you are an LLM agent setting up `wt` for a repository, follow these steps:
|
|
|
344
370
|
Identify these from the repository:
|
|
345
371
|
|
|
346
372
|
- **Database URL format**: Search `.env` files for `DATABASE_URL`. Extract the database name (the path segment after the port, before `?`).
|
|
347
|
-
- **Redis URL format**: Search for `REDIS_URL`.
|
|
373
|
+
- **Redis URL format**: Search for `REDIS_URL`. `wt` will rewrite it to a local Docker-managed Redis URL on DB 0.
|
|
348
374
|
- **Services and ports**: Find all dev server commands and their default ports. Check `package.json` scripts, `docker-compose.yml`, and framework configs.
|
|
349
375
|
- **Env files**: List all `.env` files (not `.env.example`). These are the files that need patching.
|
|
350
376
|
|
|
@@ -355,7 +381,7 @@ For each `.env` file, identify which variables need patching:
|
|
|
355
381
|
| If the variable contains... | Use patch type |
|
|
356
382
|
|----------------------------|----------------|
|
|
357
383
|
| A Postgres connection URL (`postgresql://...`) | `database` |
|
|
358
|
-
| A Redis connection URL (`redis://...`) | `redis` |
|
|
384
|
+
| A Redis connection URL (`redis://...`) | `redis` + service name (`redis`) |
|
|
359
385
|
| Just a port number (`3000`) | `port` + service name |
|
|
360
386
|
| A URL with a port (`http://localhost:3000/...`) | `url` + service name |
|
|
361
387
|
|
|
@@ -368,12 +394,14 @@ Using the discovered information, construct the config:
|
|
|
368
394
|
```
|
|
369
395
|
1. baseDatabaseName = the DB name from the main DATABASE_URL
|
|
370
396
|
2. services = each dev server as { name, defaultPort }
|
|
371
|
-
3.
|
|
372
|
-
4.
|
|
397
|
+
3. if using a `redis` patch, include { name: "redis", defaultPort: 6379 } unless you want a custom base port
|
|
398
|
+
4. envFiles = each .env file with its patches
|
|
399
|
+
5. postSetup = the install command for the package manager (npm install, pnpm install, etc.)
|
|
373
400
|
```
|
|
374
401
|
|
|
375
402
|
Validate that:
|
|
376
403
|
- Every `port` and `url` patch has a `service` that exists in `services`
|
|
404
|
+
- If using a `redis` patch, Docker is available locally and the Redis service port is included or left to the default `6379`
|
|
377
405
|
- The `portStride` (default 100) doesn't cause port collisions with other local services
|
|
378
406
|
- `maxSlots * portStride` doesn't push ports into reserved ranges (e.g., above 65535)
|
|
379
407
|
|
|
@@ -393,8 +421,11 @@ wt doctor # Should show "All checks passed."
|
|
|
393
421
|
# Smoke test (creates a real worktree + database)
|
|
394
422
|
wt new test/wt-smoke --no-install
|
|
395
423
|
wt list # Should show the new allocation
|
|
396
|
-
wt remove test-wt-smoke
|
|
424
|
+
wt remove .worktrees/test-wt-smoke
|
|
397
425
|
wt list # Should be empty again
|
|
426
|
+
|
|
427
|
+
# Opt-in Docker integration test for managed Redis
|
|
428
|
+
pnpm test:docker
|
|
398
429
|
```
|
|
399
430
|
|
|
400
431
|
### Step 5: Add convenience scripts (optional)
|
|
@@ -414,7 +445,7 @@ wt list # Should be empty again
|
|
|
414
445
|
|
|
415
446
|
- Node.js >= 20.19.0
|
|
416
447
|
- PostgreSQL (running, accessible via `DATABASE_URL` in root `.env`)
|
|
417
|
-
-
|
|
448
|
+
- Docker (if using `redis` patch type)
|
|
418
449
|
- Git (for worktree operations)
|
|
419
450
|
|
|
420
451
|
## License
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ const commander_1 = require("commander");
|
|
|
5
5
|
const new_1 = require("./commands/new");
|
|
6
6
|
const setup_1 = require("./commands/setup");
|
|
7
7
|
const remove_1 = require("./commands/remove");
|
|
8
|
+
const prune_1 = require("./commands/prune");
|
|
8
9
|
const list_1 = require("./commands/list");
|
|
9
10
|
const doctor_1 = require("./commands/doctor");
|
|
10
11
|
const open_1 = require("./commands/open");
|
|
@@ -80,6 +81,19 @@ program
|
|
|
80
81
|
force: opts.force,
|
|
81
82
|
});
|
|
82
83
|
});
|
|
84
|
+
program
|
|
85
|
+
.command('prune')
|
|
86
|
+
.description('Prune Git-prunable worktrees and clean up managed resources')
|
|
87
|
+
.option('--dry-run', 'Show what would be pruned without changing anything', false)
|
|
88
|
+
.option('--keep-db', 'Keep databases for managed worktrees (do not drop)', false)
|
|
89
|
+
.option('--json', 'Output as JSON', false)
|
|
90
|
+
.action(async (opts) => {
|
|
91
|
+
await (0, prune_1.pruneCommand)({
|
|
92
|
+
json: opts.json,
|
|
93
|
+
keepDb: opts.keepDb,
|
|
94
|
+
dryRun: opts.dryRun,
|
|
95
|
+
});
|
|
96
|
+
});
|
|
83
97
|
program
|
|
84
98
|
.command('list')
|
|
85
99
|
.description('List all worktree allocations')
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/new.js
CHANGED
|
@@ -40,6 +40,7 @@ const registry_1 = require("../core/registry");
|
|
|
40
40
|
const slot_allocator_1 = require("../core/slot-allocator");
|
|
41
41
|
const env_patcher_1 = require("../core/env-patcher");
|
|
42
42
|
const database_1 = require("../core/database");
|
|
43
|
+
const managed_redis_1 = require("../core/managed-redis");
|
|
43
44
|
const git_1 = require("../core/git");
|
|
44
45
|
const output_1 = require("../output");
|
|
45
46
|
const setup_1 = require("./setup");
|
|
@@ -62,6 +63,7 @@ async function createNewWorktree(branchName, options) {
|
|
|
62
63
|
: (msg) => process.stderr.write(`${msg}\n`);
|
|
63
64
|
const mainRoot = (0, git_1.getMainWorktreePath)();
|
|
64
65
|
const config = (0, setup_1.loadConfig)(mainRoot);
|
|
66
|
+
const services = (0, managed_redis_1.getAllocationServices)(config);
|
|
65
67
|
let registry = (0, registry_1.readRegistry)(mainRoot);
|
|
66
68
|
// Determine slot
|
|
67
69
|
let slot;
|
|
@@ -73,11 +75,20 @@ async function createNewWorktree(branchName, options) {
|
|
|
73
75
|
if (String(slot) in registry.allocations) {
|
|
74
76
|
throw new Error(`Slot ${slot} is already occupied.`);
|
|
75
77
|
}
|
|
78
|
+
const requestedPorts = (0, slot_allocator_1.calculatePorts)(slot, services, config.portStride);
|
|
79
|
+
const unavailablePorts = await (0, slot_allocator_1.findUnavailableServicePorts)(requestedPorts);
|
|
80
|
+
if (unavailablePorts.length > 0) {
|
|
81
|
+
const detail = unavailablePorts
|
|
82
|
+
.map(({ service, port }) => `${service}:${port}`)
|
|
83
|
+
.join(', ');
|
|
84
|
+
throw new Error(`Slot ${slot} has ports already in use: ${detail}`);
|
|
85
|
+
}
|
|
76
86
|
}
|
|
77
87
|
else {
|
|
78
|
-
const available = (0, slot_allocator_1.
|
|
88
|
+
const available = await (0, slot_allocator_1.findAvailablePortSafeSlot)(registry, config.maxSlots, services, config.portStride);
|
|
79
89
|
if (available === null) {
|
|
80
|
-
throw new Error(`All ${config.maxSlots} slots are occupied
|
|
90
|
+
throw new Error(`All ${config.maxSlots} slots are occupied or blocked by ports already in use. ` +
|
|
91
|
+
'Remove a worktree, stop conflicting services, or increase maxSlots.');
|
|
81
92
|
}
|
|
82
93
|
slot = available;
|
|
83
94
|
}
|
|
@@ -88,7 +99,21 @@ async function createNewWorktree(branchName, options) {
|
|
|
88
99
|
const actualBranch = (0, git_1.getBranchName)(worktreePath);
|
|
89
100
|
// Compute isolation params
|
|
90
101
|
const dbName = (0, slot_allocator_1.calculateDbName)(slot, config.baseDatabaseName);
|
|
91
|
-
const ports = (0, slot_allocator_1.calculatePorts)(slot,
|
|
102
|
+
const ports = (0, slot_allocator_1.calculatePorts)(slot, services, config.portStride);
|
|
103
|
+
const redisSourceUrl = (0, managed_redis_1.usesManagedRedis)(config)
|
|
104
|
+
? (0, managed_redis_1.readManagedRedisSourceUrl)(mainRoot, config)
|
|
105
|
+
: null;
|
|
106
|
+
const redisContainerName = (0, managed_redis_1.usesManagedRedis)(config)
|
|
107
|
+
? (0, managed_redis_1.ensureManagedRedisContainer)({
|
|
108
|
+
mainRoot,
|
|
109
|
+
slot,
|
|
110
|
+
branchName: actualBranch,
|
|
111
|
+
worktreePath,
|
|
112
|
+
port: ports.redis,
|
|
113
|
+
sourceUrl: redisSourceUrl,
|
|
114
|
+
log,
|
|
115
|
+
})
|
|
116
|
+
: undefined;
|
|
92
117
|
// Create database
|
|
93
118
|
const databaseUrl = readDatabaseUrl(mainRoot);
|
|
94
119
|
const dbAlreadyExists = await (0, database_1.databaseExists)(databaseUrl, dbName);
|
|
@@ -103,7 +128,7 @@ async function createNewWorktree(branchName, options) {
|
|
|
103
128
|
log(`Patching ${config.envFiles.length} env file(s)...`);
|
|
104
129
|
(0, env_patcher_1.copyAndPatchAllEnvFiles)(config, mainRoot, worktreePath, {
|
|
105
130
|
dbName,
|
|
106
|
-
|
|
131
|
+
redisPort: ports.redis,
|
|
107
132
|
ports,
|
|
108
133
|
});
|
|
109
134
|
// Update registry
|
|
@@ -111,7 +136,7 @@ async function createNewWorktree(branchName, options) {
|
|
|
111
136
|
worktreePath,
|
|
112
137
|
branchName: actualBranch,
|
|
113
138
|
dbName,
|
|
114
|
-
|
|
139
|
+
redisContainerName,
|
|
115
140
|
ports,
|
|
116
141
|
createdAt: new Date().toISOString(),
|
|
117
142
|
};
|
package/dist/commands/new.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface PruneOptions {
|
|
2
|
+
readonly json: boolean;
|
|
3
|
+
readonly keepDb: boolean;
|
|
4
|
+
readonly dryRun: boolean;
|
|
5
|
+
}
|
|
6
|
+
/** Prune Git-prunable worktrees and clean up wt-managed resources for matching slots. */
|
|
7
|
+
export declare function pruneCommand(options: PruneOptions): Promise<void>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.pruneCommand = pruneCommand;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const registry_1 = require("../core/registry");
|
|
40
|
+
const database_1 = require("../core/database");
|
|
41
|
+
const git_1 = require("../core/git");
|
|
42
|
+
const managed_redis_1 = require("../core/managed-redis");
|
|
43
|
+
const setup_1 = require("./setup");
|
|
44
|
+
const output_1 = require("../output");
|
|
45
|
+
/** Read DATABASE_URL from the main worktree's .env file */
|
|
46
|
+
function readDatabaseUrl(mainRoot) {
|
|
47
|
+
const envPath = path.join(mainRoot, '.env');
|
|
48
|
+
const content = fs.readFileSync(envPath, 'utf-8');
|
|
49
|
+
const match = content.match(/^DATABASE_URL=["']?([^"'\n]+)/m);
|
|
50
|
+
if (!match?.[1]) {
|
|
51
|
+
throw new Error('DATABASE_URL not found in .env');
|
|
52
|
+
}
|
|
53
|
+
return match[1];
|
|
54
|
+
}
|
|
55
|
+
/** Prune Git-prunable worktrees and clean up wt-managed resources for matching slots. */
|
|
56
|
+
async function pruneCommand(options) {
|
|
57
|
+
const log = options.json
|
|
58
|
+
? () => { }
|
|
59
|
+
: (message) => process.stderr.write(`${message}\n`);
|
|
60
|
+
try {
|
|
61
|
+
const mainRoot = (0, git_1.getMainWorktreePath)();
|
|
62
|
+
let registry = (0, registry_1.readRegistry)(mainRoot);
|
|
63
|
+
const prunable = (0, git_1.listPrunableWorktrees)();
|
|
64
|
+
const managed = [];
|
|
65
|
+
const unmanaged = [];
|
|
66
|
+
for (const entry of prunable) {
|
|
67
|
+
const found = (0, registry_1.findByPath)(registry, entry.path);
|
|
68
|
+
if (!found) {
|
|
69
|
+
unmanaged.push({ worktreePath: entry.path, reason: entry.reason });
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
managed.push({
|
|
73
|
+
slot: found[0],
|
|
74
|
+
allocation: found[1],
|
|
75
|
+
reason: entry.reason,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const payloadBase = {
|
|
79
|
+
prunableCount: prunable.length,
|
|
80
|
+
managed,
|
|
81
|
+
unmanaged,
|
|
82
|
+
};
|
|
83
|
+
if (options.dryRun) {
|
|
84
|
+
if (options.json) {
|
|
85
|
+
console.log((0, output_1.formatJson)((0, output_1.success)(payloadBase)));
|
|
86
|
+
}
|
|
87
|
+
else if (prunable.length === 0) {
|
|
88
|
+
console.log('No Git-prunable worktrees found.');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.log(`Would prune ${prunable.length} worktree entr${prunable.length === 1 ? 'y' : 'ies'}:`);
|
|
92
|
+
for (const item of managed) {
|
|
93
|
+
console.log(` Slot ${item.slot}: ${item.allocation.worktreePath}`);
|
|
94
|
+
console.log(` Reason: ${item.reason}`);
|
|
95
|
+
console.log(` Database: ${item.allocation.dbName}${options.keepDb ? ' (kept)' : ' (dropped)'}`);
|
|
96
|
+
if (item.allocation.redisContainerName) {
|
|
97
|
+
console.log(` Redis: ${item.allocation.redisContainerName} (removed)`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const item of unmanaged) {
|
|
101
|
+
console.log(` Unmanaged: ${item.worktreePath}`);
|
|
102
|
+
console.log(` Reason: ${item.reason}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (prunable.length === 0) {
|
|
108
|
+
if (options.json) {
|
|
109
|
+
console.log((0, output_1.formatJson)((0, output_1.success)({
|
|
110
|
+
prunedManaged: [],
|
|
111
|
+
prunedUnmanaged: [],
|
|
112
|
+
failed: [],
|
|
113
|
+
})));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
console.log('No Git-prunable worktrees found.');
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const config = !options.keepDb && managed.length > 0 ? (0, setup_1.loadConfig)(mainRoot) : null;
|
|
121
|
+
const dbContext = options.keepDb || managed.length === 0 || config === null
|
|
122
|
+
? null
|
|
123
|
+
: {
|
|
124
|
+
databaseUrl: readDatabaseUrl(mainRoot),
|
|
125
|
+
baseDatabaseName: config.baseDatabaseName,
|
|
126
|
+
};
|
|
127
|
+
const prunedManaged = [];
|
|
128
|
+
const failed = [];
|
|
129
|
+
for (const item of managed) {
|
|
130
|
+
try {
|
|
131
|
+
if (dbContext !== null) {
|
|
132
|
+
await (0, database_1.dropDatabase)(dbContext.databaseUrl, item.allocation.dbName, dbContext.baseDatabaseName, (statement) => log(`Running SQL: ${statement}`));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
log(`Skipping database drop for '${item.allocation.dbName}' (${options.keepDb ? '--keep-db' : 'no config'}).`);
|
|
136
|
+
}
|
|
137
|
+
const redisContainerRemoved = item.allocation.redisContainerName !== undefined
|
|
138
|
+
? (0, managed_redis_1.removeManagedRedisContainer)(mainRoot, item.slot, log)
|
|
139
|
+
: false;
|
|
140
|
+
registry = (0, registry_1.removeAllocation)(registry, item.slot);
|
|
141
|
+
prunedManaged.push({
|
|
142
|
+
slot: item.slot,
|
|
143
|
+
worktreePath: item.allocation.worktreePath,
|
|
144
|
+
dbName: item.allocation.dbName,
|
|
145
|
+
dbDropped: dbContext !== null,
|
|
146
|
+
redisContainerRemoved,
|
|
147
|
+
reason: item.reason,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
152
|
+
failed.push({ worktreePath: item.allocation.worktreePath, message });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (prunedManaged.length > 0) {
|
|
156
|
+
(0, registry_1.writeRegistry)(mainRoot, registry);
|
|
157
|
+
}
|
|
158
|
+
(0, git_1.pruneWorktrees)((command) => log(`Running: ${command}`));
|
|
159
|
+
const payload = {
|
|
160
|
+
prunedManaged,
|
|
161
|
+
prunedUnmanaged: unmanaged,
|
|
162
|
+
failed,
|
|
163
|
+
};
|
|
164
|
+
if (options.json) {
|
|
165
|
+
if (failed.length === 0) {
|
|
166
|
+
console.log((0, output_1.formatJson)((0, output_1.success)(payload)));
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
console.log((0, output_1.formatJson)({
|
|
170
|
+
success: false,
|
|
171
|
+
data: payload,
|
|
172
|
+
error: {
|
|
173
|
+
code: 'PRUNE_PARTIAL',
|
|
174
|
+
message: `Failed to clean up ${failed.length} managed worktree entr${failed.length === 1 ? 'y' : 'ies'}.`,
|
|
175
|
+
},
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
console.log(`Pruned ${prunable.length} Git worktree entr${prunable.length === 1 ? 'y' : 'ies'}.`);
|
|
181
|
+
for (const item of prunedManaged) {
|
|
182
|
+
console.log(` Slot ${item.slot}: ${item.worktreePath}`);
|
|
183
|
+
console.log(` Reason: ${item.reason}`);
|
|
184
|
+
console.log(` Database: ${item.dbName} ${item.dbDropped ? '(dropped)' : '(kept)'}`);
|
|
185
|
+
console.log(` Redis: ${item.redisContainerRemoved ? '(removed)' : '(not found)'}`);
|
|
186
|
+
}
|
|
187
|
+
for (const item of unmanaged) {
|
|
188
|
+
console.log(` Unmanaged: ${item.worktreePath}`);
|
|
189
|
+
console.log(` Reason: ${item.reason}`);
|
|
190
|
+
}
|
|
191
|
+
if (failed.length > 0) {
|
|
192
|
+
console.error(`Failed to clean up ${failed.length} managed worktree entr${failed.length === 1 ? 'y' : 'ies'}:`);
|
|
193
|
+
for (const item of failed) {
|
|
194
|
+
console.error(` ${item.worktreePath}: ${item.message}`);
|
|
195
|
+
}
|
|
196
|
+
process.exitCode = 1;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
201
|
+
if (options.json) {
|
|
202
|
+
console.log((0, output_1.formatJson)((0, output_1.error)('PRUNE_FAILED', message)));
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
console.error(`Prune failed: ${message}`);
|
|
206
|
+
}
|
|
207
|
+
process.exitCode = 1;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=prune.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune.js","sourceRoot":"","sources":["../../src/commands/prune.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|