@tokenbooks/wt 0.2.0 → 0.2.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.
- package/README.md +7 -2
- package/dist/cli.js +18 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/new.js +2 -2
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/remove.d.ts +13 -2
- package/dist/commands/remove.js +185 -42
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/remove.spec.d.ts +1 -0
- package/dist/commands/remove.spec.js +22 -0
- package/dist/commands/remove.spec.js.map +1 -0
- package/dist/core/database.d.ts +4 -2
- package/dist/core/database.js +26 -6
- package/dist/core/database.js.map +1 -1
- package/dist/core/git.d.ts +11 -2
- package/dist/core/git.js +35 -4
- package/dist/core/git.js.map +1 -1
- package/package.json +1 -1
- package/skills/wt/SKILL.md +8 -4
package/README.md
CHANGED
|
@@ -163,7 +163,7 @@ Sets up an existing worktree that was created manually or by another tool. Usefu
|
|
|
163
163
|
|
|
164
164
|
If the worktree already has a slot allocation, it reuses it.
|
|
165
165
|
|
|
166
|
-
### `wt remove <
|
|
166
|
+
### `wt remove <targets...> [--all] [--keep-db] [--json]`
|
|
167
167
|
|
|
168
168
|
Removes a worktree and cleans up its resources:
|
|
169
169
|
|
|
@@ -171,7 +171,12 @@ Removes a worktree and cleans up its resources:
|
|
|
171
171
|
2. Runs `git worktree remove`
|
|
172
172
|
3. Removes the allocation from the registry
|
|
173
173
|
|
|
174
|
-
Accepts either
|
|
174
|
+
Accepts either paths (`.worktrees/feat-my-feature`) or slot numbers (`3`), including batch formats:
|
|
175
|
+
|
|
176
|
+
- `wt remove 1 2`
|
|
177
|
+
- `wt remove 1,2`
|
|
178
|
+
- `wt remove "1, 2"`
|
|
179
|
+
- `wt remove --all`
|
|
175
180
|
|
|
176
181
|
### `wt list [--json]`
|
|
177
182
|
|
package/dist/cli.js
CHANGED
|
@@ -56,14 +56,28 @@ program
|
|
|
56
56
|
});
|
|
57
57
|
program
|
|
58
58
|
.command('remove')
|
|
59
|
-
.description('Remove
|
|
60
|
-
.argument('
|
|
59
|
+
.description('Remove worktree(s) by target list, CSV slots, or --all')
|
|
60
|
+
.argument('[targets...]', 'Worktree path(s) or slot number(s); supports comma-separated values')
|
|
61
|
+
.option('--all', 'Remove all registered worktrees', false)
|
|
62
|
+
.option('--force', 'Remove even if worktree has uncommitted changes or unpushed commits', false)
|
|
61
63
|
.option('--keep-db', 'Keep the database (do not drop)', false)
|
|
62
64
|
.option('--json', 'Output as JSON', false)
|
|
63
|
-
.
|
|
64
|
-
|
|
65
|
+
.addHelpText('after', [
|
|
66
|
+
'',
|
|
67
|
+
'Examples:',
|
|
68
|
+
' wt remove 1',
|
|
69
|
+
' wt remove 1,2',
|
|
70
|
+
' wt remove "1, 2"',
|
|
71
|
+
' wt remove .worktrees/feat-auth',
|
|
72
|
+
' wt remove --all',
|
|
73
|
+
'',
|
|
74
|
+
].join('\n'))
|
|
75
|
+
.action(async (targets, opts) => {
|
|
76
|
+
await (0, remove_1.removeCommand)(targets ?? [], {
|
|
65
77
|
json: opts.json,
|
|
66
78
|
keepDb: opts.keepDb,
|
|
79
|
+
all: opts.all,
|
|
80
|
+
force: opts.force,
|
|
67
81
|
});
|
|
68
82
|
});
|
|
69
83
|
program
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,wCAA4C;AAC5C,4CAAgD;AAChD,8CAAkD;AAClD,0CAA8C;AAC9C,8CAAkD;AAClD,0CAA8C;AAC9C,oCAAiD;AACjD,kDAAgD;AAChD,sDAAwF;AAExF,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,IAAI,CAAC;KACV,WAAW,CAAC,wCAAwC,CAAC;KACrD,OAAO,CAAC,sBAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,iDAAiD,CAAC;KAC9D,QAAQ,CAAC,UAAU,EAAE,mCAAmC,CAAC;KACzD,MAAM,CAAC,YAAY,EAAE,8BAA8B,CAAC;KACpD,MAAM,CAAC,cAAc,EAAE,0BAA0B,CAAC;KAClD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,CAAC;KACzC,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;IACrC,MAAM,IAAA,gBAAU,EAAC,MAAM,EAAE;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,QAAQ,CAAC,QAAQ,EAAE,4CAA4C,CAAC;KAChE,MAAM,CAAC,cAAc,EAAE,0BAA0B,CAAC;KAClD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,CAAC;KACzC,MAAM,CAAC,KAAK,EAAE,UAA8B,EAAE,IAAI,EAAE,EAAE;IACrD,MAAM,IAAA,oBAAY,EAAC,UAAU,EAAE;QAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0DAA0D,CAAC;KACvE,QAAQ,CAAC,kBAAkB,EAAE,4BAA4B,CAAC;KAC1D,MAAM,CAAC,cAAc,EAAE,sCAAsC,CAAC;KAC9D,MAAM,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,CAAC;KACzC,MAAM,CAAC,KAAK,EAAE,YAAoB,EAAE,IAAI,EAAE,EAAE;IAC3C,MAAM,IAAA,kBAAW,EAAC,YAAY,EAAE;QAC9B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/new.js
CHANGED
|
@@ -84,7 +84,7 @@ async function createNewWorktree(branchName, options) {
|
|
|
84
84
|
log(`Creating worktree for '${branchName}' in slot ${slot}...`);
|
|
85
85
|
// Create worktree
|
|
86
86
|
const basePath = path.join(mainRoot, config.baseWorktreePath);
|
|
87
|
-
const worktreePath = (0, git_1.createWorktree)(basePath, branchName);
|
|
87
|
+
const worktreePath = (0, git_1.createWorktree)(basePath, branchName, (command) => log(`Running: ${command}`));
|
|
88
88
|
const actualBranch = (0, git_1.getBranchName)(worktreePath);
|
|
89
89
|
// Compute isolation params
|
|
90
90
|
const dbName = (0, slot_allocator_1.calculateDbName)(slot, config.baseDatabaseName);
|
|
@@ -94,7 +94,7 @@ async function createNewWorktree(branchName, options) {
|
|
|
94
94
|
const dbAlreadyExists = await (0, database_1.databaseExists)(databaseUrl, dbName);
|
|
95
95
|
if (!dbAlreadyExists) {
|
|
96
96
|
log(`Creating database '${dbName}'...`);
|
|
97
|
-
await (0, database_1.createDatabase)(databaseUrl, config.baseDatabaseName, dbName);
|
|
97
|
+
await (0, database_1.createDatabase)(databaseUrl, config.baseDatabaseName, dbName, (statement) => log(`Running SQL: ${statement}`));
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
100
|
log(`Database '${dbName}' already exists, reusing.`);
|
package/dist/commands/new.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,
|
|
1
|
+
{"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
interface RemoveOptions {
|
|
2
2
|
readonly json: boolean;
|
|
3
3
|
readonly keepDb: boolean;
|
|
4
|
+
readonly all: boolean;
|
|
5
|
+
readonly force: boolean;
|
|
4
6
|
}
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Parse raw CLI targets.
|
|
9
|
+
*
|
|
10
|
+
* Supports:
|
|
11
|
+
* - `wt remove 1,2`
|
|
12
|
+
* - `wt remove "1, 2"`
|
|
13
|
+
* - `wt remove 1 2`
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseRemoveTargets(rawTargets: readonly string[]): string[];
|
|
16
|
+
/** Remove one or more worktrees, their databases, and registry entries */
|
|
17
|
+
export declare function removeCommand(rawTargets: readonly string[], options: RemoveOptions): Promise<void>;
|
|
7
18
|
export {};
|
package/dist/commands/remove.js
CHANGED
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseRemoveTargets = parseRemoveTargets;
|
|
36
37
|
exports.removeCommand = removeCommand;
|
|
37
38
|
const path = __importStar(require("node:path"));
|
|
38
39
|
const fs = __importStar(require("node:fs"));
|
|
@@ -51,43 +52,92 @@ function readDatabaseUrl(mainRoot) {
|
|
|
51
52
|
}
|
|
52
53
|
return match[1];
|
|
53
54
|
}
|
|
54
|
-
/**
|
|
55
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Parse raw CLI targets.
|
|
57
|
+
*
|
|
58
|
+
* Supports:
|
|
59
|
+
* - `wt remove 1,2`
|
|
60
|
+
* - `wt remove "1, 2"`
|
|
61
|
+
* - `wt remove 1 2`
|
|
62
|
+
*/
|
|
63
|
+
function parseRemoveTargets(rawTargets) {
|
|
64
|
+
return rawTargets
|
|
65
|
+
.flatMap((rawTarget) => rawTarget.split(','))
|
|
66
|
+
.map((target) => target.trim())
|
|
67
|
+
.filter((target) => target.length > 0);
|
|
68
|
+
}
|
|
69
|
+
function parseSlotTarget(target) {
|
|
70
|
+
if (!/^\d+$/.test(target)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const slot = Number.parseInt(target, 10);
|
|
74
|
+
return Number.isSafeInteger(slot) ? slot : null;
|
|
75
|
+
}
|
|
76
|
+
function resolveTarget(registry, target) {
|
|
77
|
+
const slot = parseSlotTarget(target);
|
|
78
|
+
if (slot !== null) {
|
|
79
|
+
const allocation = registry.allocations[String(slot)];
|
|
80
|
+
if (!allocation) {
|
|
81
|
+
return { error: `No allocation found for slot ${slot}.` };
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
slot,
|
|
85
|
+
worktreePath: allocation.worktreePath,
|
|
86
|
+
dbName: allocation.dbName,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const resolvedPath = path.resolve(target);
|
|
90
|
+
const found = (0, registry_1.findByPath)(registry, resolvedPath);
|
|
91
|
+
if (!found) {
|
|
92
|
+
return { error: `No allocation found for path: ${resolvedPath}` };
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
slot: found[0],
|
|
96
|
+
worktreePath: found[1].worktreePath,
|
|
97
|
+
dbName: found[1].dbName,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** Remove one or more worktrees, their databases, and registry entries */
|
|
101
|
+
async function removeCommand(rawTargets, options) {
|
|
102
|
+
const log = options.json
|
|
103
|
+
? () => { }
|
|
104
|
+
: (message) => process.stderr.write(`${message}\n`);
|
|
56
105
|
try {
|
|
57
106
|
const mainRoot = (0, git_1.getMainWorktreePath)();
|
|
58
|
-
const config = (0, setup_1.loadConfig)(mainRoot);
|
|
59
107
|
let registry = (0, registry_1.readRegistry)(mainRoot);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
108
|
+
const parsedTargets = parseRemoveTargets(rawTargets);
|
|
109
|
+
if (options.all && parsedTargets.length > 0) {
|
|
110
|
+
const msg = 'Use either explicit targets or --all, not both.';
|
|
111
|
+
if (options.json) {
|
|
112
|
+
console.log((0, output_1.formatJson)((0, output_1.error)('INVALID_ARGS', msg)));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.error(msg);
|
|
116
|
+
}
|
|
117
|
+
process.exitCode = 1;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
let targets;
|
|
121
|
+
if (options.all) {
|
|
122
|
+
targets = Object.keys(registry.allocations).sort((a, b) => Number(a) - Number(b));
|
|
123
|
+
if (targets.length === 0) {
|
|
124
|
+
const empty = { removed: [], failed: [] };
|
|
70
125
|
if (options.json) {
|
|
71
|
-
console.log((0, output_1.formatJson)((0, output_1.
|
|
126
|
+
console.log((0, output_1.formatJson)((0, output_1.success)(empty)));
|
|
72
127
|
}
|
|
73
128
|
else {
|
|
74
|
-
console.
|
|
129
|
+
console.log('No worktree allocations found.');
|
|
75
130
|
}
|
|
76
|
-
process.exitCode = 1;
|
|
77
131
|
return;
|
|
78
132
|
}
|
|
79
|
-
|
|
80
|
-
worktreePath = allocation.worktreePath;
|
|
81
|
-
dbName = allocation.dbName;
|
|
133
|
+
log(`Removing all allocations: ${targets.join(', ')}`);
|
|
82
134
|
}
|
|
83
135
|
else {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (!found) {
|
|
88
|
-
const msg = `No allocation found for path: ${resolved}`;
|
|
136
|
+
targets = parsedTargets;
|
|
137
|
+
if (targets.length === 0) {
|
|
138
|
+
const msg = 'Provide at least one target or use --all.';
|
|
89
139
|
if (options.json) {
|
|
90
|
-
console.log((0, output_1.formatJson)((0, output_1.error)('
|
|
140
|
+
console.log((0, output_1.formatJson)((0, output_1.error)('MISSING_TARGET', msg)));
|
|
91
141
|
}
|
|
92
142
|
else {
|
|
93
143
|
console.error(msg);
|
|
@@ -95,28 +145,121 @@ async function removeCommand(pathOrSlot, options) {
|
|
|
95
145
|
process.exitCode = 1;
|
|
96
146
|
return;
|
|
97
147
|
}
|
|
98
|
-
[slot, { worktreePath, dbName }] = [found[0], found[1]];
|
|
99
148
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
149
|
+
const dbContext = options.keepDb
|
|
150
|
+
? null
|
|
151
|
+
: {
|
|
152
|
+
databaseUrl: readDatabaseUrl(mainRoot),
|
|
153
|
+
baseDatabaseName: (0, setup_1.loadConfig)(mainRoot).baseDatabaseName,
|
|
154
|
+
};
|
|
155
|
+
const seenSlots = new Set();
|
|
156
|
+
const removed = [];
|
|
157
|
+
const failed = [];
|
|
158
|
+
for (const target of targets) {
|
|
159
|
+
const resolved = resolveTarget(registry, target);
|
|
160
|
+
if ('error' in resolved) {
|
|
161
|
+
failed.push({ target, message: resolved.error });
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (seenSlots.has(resolved.slot)) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
seenSlots.add(resolved.slot);
|
|
168
|
+
if (!options.force && fs.existsSync(resolved.worktreePath)) {
|
|
169
|
+
const changes = (0, git_1.getUncommittedChanges)(resolved.worktreePath);
|
|
170
|
+
const { unpushedCommits, noUpstream } = (0, git_1.getUnsyncedStatus)(resolved.worktreePath);
|
|
171
|
+
if (changes.length > 0 || unpushedCommits.length > 0 || noUpstream) {
|
|
172
|
+
const reasons = [];
|
|
173
|
+
if (changes.length > 0) {
|
|
174
|
+
reasons.push(' Uncommitted changes:');
|
|
175
|
+
for (const line of changes) {
|
|
176
|
+
reasons.push(` ${line}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (unpushedCommits.length > 0) {
|
|
180
|
+
reasons.push(' Unpushed commits:');
|
|
181
|
+
for (const line of unpushedCommits) {
|
|
182
|
+
reasons.push(` ${line}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (noUpstream) {
|
|
186
|
+
reasons.push(' Branch has no upstream tracking branch.');
|
|
187
|
+
}
|
|
188
|
+
const detail = reasons.join('\n');
|
|
189
|
+
failed.push({
|
|
190
|
+
target,
|
|
191
|
+
message: `Worktree has unsaved changes. Use --force to override.\n${detail}`,
|
|
192
|
+
});
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
log(`Removing slot ${resolved.slot} (${resolved.worktreePath})`);
|
|
198
|
+
if (dbContext !== null) {
|
|
199
|
+
await (0, database_1.dropDatabase)(dbContext.databaseUrl, resolved.dbName, dbContext.baseDatabaseName, (statement) => log(`Running SQL: ${statement}`));
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
log(`Skipping database drop for '${resolved.dbName}' (--keep-db).`);
|
|
203
|
+
}
|
|
204
|
+
if (fs.existsSync(resolved.worktreePath)) {
|
|
205
|
+
(0, git_1.removeWorktree)(resolved.worktreePath, (command) => log(`Running: ${command}`));
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
log(`Skipping git worktree remove; path not found: ${resolved.worktreePath}`);
|
|
209
|
+
}
|
|
210
|
+
registry = (0, registry_1.removeAllocation)(registry, resolved.slot);
|
|
211
|
+
removed.push({
|
|
212
|
+
target,
|
|
213
|
+
slot: resolved.slot,
|
|
214
|
+
worktreePath: resolved.worktreePath,
|
|
215
|
+
dbName: resolved.dbName,
|
|
216
|
+
dbDropped: !options.keepDb,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
221
|
+
failed.push({ target, message });
|
|
222
|
+
}
|
|
104
223
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
(0, git_1.removeWorktree)(worktreePath);
|
|
224
|
+
if (removed.length > 0) {
|
|
225
|
+
(0, registry_1.writeRegistry)(mainRoot, registry);
|
|
108
226
|
}
|
|
109
|
-
|
|
110
|
-
registry = (0, registry_1.removeAllocation)(registry, slot);
|
|
111
|
-
(0, registry_1.writeRegistry)(mainRoot, registry);
|
|
112
|
-
const result = { slot, worktreePath, dbName, dbDropped: !options.keepDb };
|
|
227
|
+
const payload = { removed, failed };
|
|
113
228
|
if (options.json) {
|
|
114
|
-
|
|
229
|
+
if (failed.length === 0) {
|
|
230
|
+
console.log((0, output_1.formatJson)((0, output_1.success)(payload)));
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
console.log((0, output_1.formatJson)({
|
|
234
|
+
success: false,
|
|
235
|
+
data: payload,
|
|
236
|
+
error: {
|
|
237
|
+
code: 'REMOVE_PARTIAL',
|
|
238
|
+
message: `Failed to remove ${failed.length} target(s).`,
|
|
239
|
+
},
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
115
242
|
}
|
|
116
243
|
else {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
244
|
+
if (removed.length > 0) {
|
|
245
|
+
console.log(`Removed ${removed.length} worktree(s):`);
|
|
246
|
+
for (const item of removed) {
|
|
247
|
+
console.log(` Slot ${item.slot}: ${item.worktreePath}`);
|
|
248
|
+
console.log(` Database: ${item.dbName} ${item.dbDropped ? '(dropped)' : '(kept)'}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (failed.length > 0) {
|
|
252
|
+
console.error(`Failed to remove ${failed.length} target(s):`);
|
|
253
|
+
for (const item of failed) {
|
|
254
|
+
console.error(` ${item.target}: ${item.message}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (removed.length === 0 && failed.length === 0) {
|
|
258
|
+
console.log('No worktree allocations found.');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (failed.length > 0) {
|
|
262
|
+
process.exitCode = 1;
|
|
120
263
|
}
|
|
121
264
|
}
|
|
122
265
|
catch (err) {
|
|
@@ -125,7 +268,7 @@ async function removeCommand(pathOrSlot, options) {
|
|
|
125
268
|
console.log((0, output_1.formatJson)((0, output_1.error)('REMOVE_FAILED', message)));
|
|
126
269
|
}
|
|
127
270
|
else {
|
|
128
|
-
console.error(`Failed to remove worktree: ${message}`);
|
|
271
|
+
console.error(`Failed to remove worktree(s): ${message}`);
|
|
129
272
|
}
|
|
130
273
|
process.exitCode = 1;
|
|
131
274
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const globals_1 = require("@jest/globals");
|
|
4
|
+
const remove_1 = require("./remove");
|
|
5
|
+
(0, globals_1.describe)('remove command target parsing', () => {
|
|
6
|
+
(0, globals_1.it)('parses comma-separated slots', () => {
|
|
7
|
+
(0, globals_1.expect)((0, remove_1.parseRemoveTargets)(['1,2'])).toEqual(['1', '2']);
|
|
8
|
+
});
|
|
9
|
+
(0, globals_1.it)('parses comma-separated slots with spaces', () => {
|
|
10
|
+
(0, globals_1.expect)((0, remove_1.parseRemoveTargets)(['1, 2'])).toEqual(['1', '2']);
|
|
11
|
+
});
|
|
12
|
+
(0, globals_1.it)('parses mixed comma and variadic targets', () => {
|
|
13
|
+
(0, globals_1.expect)((0, remove_1.parseRemoveTargets)(['1, 2', '3'])).toEqual(['1', '2', '3']);
|
|
14
|
+
});
|
|
15
|
+
(0, globals_1.it)('keeps single path targets untouched', () => {
|
|
16
|
+
(0, globals_1.expect)((0, remove_1.parseRemoveTargets)(['.worktrees/feat-auth'])).toEqual(['.worktrees/feat-auth']);
|
|
17
|
+
});
|
|
18
|
+
(0, globals_1.it)('drops empty target fragments', () => {
|
|
19
|
+
(0, globals_1.expect)((0, remove_1.parseRemoveTargets)(['1,,2', ' , '])).toEqual(['1', '2']);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=remove.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.spec.js","sourceRoot":"","sources":["../../src/commands/remove.spec.ts"],"names":[],"mappings":";;AAAA,2CAAqD;AACrD,qCAA8C;AAE9C,IAAA,kBAAQ,EAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,IAAA,YAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,IAAA,gBAAM,EAAC,IAAA,2BAAkB,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,IAAA,YAAE,EAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,IAAA,gBAAM,EAAC,IAAA,2BAAkB,EAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,IAAA,YAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,IAAA,gBAAM,EAAC,IAAA,2BAAkB,EAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,IAAA,YAAE,EAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,IAAA,gBAAM,EAAC,IAAA,2BAAkB,EAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,IAAA,YAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,IAAA,gBAAM,EAAC,IAAA,2BAAkB,EAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/core/database.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
type SqlLogger = (statement: string) => void;
|
|
1
2
|
/**
|
|
2
3
|
* Create a new database by cloning the template database.
|
|
3
4
|
* Uses CREATE DATABASE ... TEMPLATE for fast, consistent copies.
|
|
4
5
|
*/
|
|
5
|
-
export declare function createDatabase(databaseUrl: string, templateName: string, targetName: string): Promise<void>;
|
|
6
|
+
export declare function createDatabase(databaseUrl: string, templateName: string, targetName: string, logSql?: SqlLogger): Promise<void>;
|
|
6
7
|
/** Drop a database if it exists. Refuses to drop the template database. */
|
|
7
|
-
export declare function dropDatabase(databaseUrl: string, dbName: string, templateName: string): Promise<void>;
|
|
8
|
+
export declare function dropDatabase(databaseUrl: string, dbName: string, templateName: string, logSql?: SqlLogger): Promise<void>;
|
|
8
9
|
/** Check if a database exists */
|
|
9
10
|
export declare function databaseExists(databaseUrl: string, dbName: string): Promise<boolean>;
|
|
10
11
|
/** List all databases matching a pattern (for doctor command) */
|
|
11
12
|
export declare function listDatabasesByPattern(databaseUrl: string, pattern: string): Promise<string[]>;
|
|
13
|
+
export {};
|
package/dist/core/database.js
CHANGED
|
@@ -30,26 +30,46 @@ async function withAdminClient(databaseUrl, fn) {
|
|
|
30
30
|
await client.end();
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
function quoteIdentifier(identifier) {
|
|
34
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
35
|
+
}
|
|
36
|
+
function formatQueryLog(query, params = []) {
|
|
37
|
+
if (params.length === 0) {
|
|
38
|
+
return query;
|
|
39
|
+
}
|
|
40
|
+
const bindings = params
|
|
41
|
+
.map((value, index) => `$${index + 1}=${JSON.stringify(value)}`)
|
|
42
|
+
.join(', ');
|
|
43
|
+
return `${query} -- ${bindings}`;
|
|
44
|
+
}
|
|
33
45
|
/**
|
|
34
46
|
* Create a new database by cloning the template database.
|
|
35
47
|
* Uses CREATE DATABASE ... TEMPLATE for fast, consistent copies.
|
|
36
48
|
*/
|
|
37
|
-
async function createDatabase(databaseUrl, templateName, targetName) {
|
|
49
|
+
async function createDatabase(databaseUrl, templateName, targetName, logSql) {
|
|
38
50
|
await withAdminClient(databaseUrl, async (client) => {
|
|
39
51
|
// Terminate connections to the template DB so TEMPLATE works
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
const terminateSql = 'SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()';
|
|
53
|
+
logSql?.(formatQueryLog(terminateSql, [templateName]));
|
|
54
|
+
await client.query(terminateSql, [templateName]);
|
|
55
|
+
const createSql = `CREATE DATABASE ${quoteIdentifier(targetName)} TEMPLATE ${quoteIdentifier(templateName)}`;
|
|
56
|
+
logSql?.(formatQueryLog(createSql));
|
|
57
|
+
await client.query(createSql);
|
|
42
58
|
});
|
|
43
59
|
}
|
|
44
60
|
/** Drop a database if it exists. Refuses to drop the template database. */
|
|
45
|
-
async function dropDatabase(databaseUrl, dbName, templateName) {
|
|
61
|
+
async function dropDatabase(databaseUrl, dbName, templateName, logSql) {
|
|
46
62
|
if (dbName === templateName) {
|
|
47
63
|
throw new Error(`Refusing to drop template database: ${templateName}`);
|
|
48
64
|
}
|
|
49
65
|
await withAdminClient(databaseUrl, async (client) => {
|
|
50
66
|
// Terminate active connections first
|
|
51
|
-
|
|
52
|
-
|
|
67
|
+
const terminateSql = 'SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()';
|
|
68
|
+
logSql?.(formatQueryLog(terminateSql, [dbName]));
|
|
69
|
+
await client.query(terminateSql, [dbName]);
|
|
70
|
+
const dropSql = `DROP DATABASE IF EXISTS ${quoteIdentifier(dbName)}`;
|
|
71
|
+
logSql?.(formatQueryLog(dropSql));
|
|
72
|
+
await client.query(dropSql);
|
|
53
73
|
});
|
|
54
74
|
}
|
|
55
75
|
/** Check if a database exists */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"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"}
|
package/dist/core/git.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
type CommandLogger = (command: string) => void;
|
|
1
2
|
/**
|
|
2
3
|
* Get the main (bare) worktree path from git.
|
|
3
4
|
* Parses `git worktree list --porcelain` to find the first entry.
|
|
@@ -12,8 +13,16 @@ export declare function isMainWorktree(targetPath: string): boolean;
|
|
|
12
13
|
* Create a new git worktree at the given base path for the specified branch.
|
|
13
14
|
* If the branch already exists, checks it out; otherwise creates it with -b.
|
|
14
15
|
*/
|
|
15
|
-
export declare function createWorktree(basePath: string, branchName: string): string;
|
|
16
|
+
export declare function createWorktree(basePath: string, branchName: string, logCommand?: CommandLogger): string;
|
|
16
17
|
/** Remove a git worktree by path */
|
|
17
|
-
export declare function removeWorktree(worktreePath: string): void;
|
|
18
|
+
export declare function removeWorktree(worktreePath: string, logCommand?: CommandLogger): void;
|
|
18
19
|
/** Get the current branch name for a worktree path */
|
|
19
20
|
export declare function getBranchName(worktreePath: string): string;
|
|
21
|
+
/** Get uncommitted changes in a worktree (staged, unstaged, untracked) */
|
|
22
|
+
export declare function getUncommittedChanges(worktreePath: string): string[];
|
|
23
|
+
/** Get commits not pushed to upstream tracking branch */
|
|
24
|
+
export declare function getUnsyncedStatus(worktreePath: string): {
|
|
25
|
+
unpushedCommits: string[];
|
|
26
|
+
noUpstream: boolean;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
package/dist/core/git.js
CHANGED
|
@@ -38,6 +38,8 @@ exports.isMainWorktree = isMainWorktree;
|
|
|
38
38
|
exports.createWorktree = createWorktree;
|
|
39
39
|
exports.removeWorktree = removeWorktree;
|
|
40
40
|
exports.getBranchName = getBranchName;
|
|
41
|
+
exports.getUncommittedChanges = getUncommittedChanges;
|
|
42
|
+
exports.getUnsyncedStatus = getUnsyncedStatus;
|
|
41
43
|
const node_child_process_1 = require("node:child_process");
|
|
42
44
|
const path = __importStar(require("node:path"));
|
|
43
45
|
/**
|
|
@@ -66,19 +68,23 @@ function isMainWorktree(targetPath) {
|
|
|
66
68
|
* Create a new git worktree at the given base path for the specified branch.
|
|
67
69
|
* If the branch already exists, checks it out; otherwise creates it with -b.
|
|
68
70
|
*/
|
|
69
|
-
function createWorktree(basePath, branchName) {
|
|
71
|
+
function createWorktree(basePath, branchName, logCommand) {
|
|
70
72
|
const slug = branchName.replace(/\//g, '-');
|
|
71
73
|
const worktreePath = path.resolve(basePath, slug);
|
|
72
74
|
const branchExists = branchExistsLocally(branchName);
|
|
73
75
|
const args = branchExists
|
|
74
76
|
? `"${worktreePath}" "${branchName}"`
|
|
75
77
|
: `"${worktreePath}" -b "${branchName}"`;
|
|
76
|
-
|
|
78
|
+
const command = `git worktree add ${args}`;
|
|
79
|
+
logCommand?.(command);
|
|
80
|
+
(0, node_child_process_1.execSync)(command, { stdio: 'pipe' });
|
|
77
81
|
return worktreePath;
|
|
78
82
|
}
|
|
79
83
|
/** Remove a git worktree by path */
|
|
80
|
-
function removeWorktree(worktreePath) {
|
|
81
|
-
|
|
84
|
+
function removeWorktree(worktreePath, logCommand) {
|
|
85
|
+
const command = `git worktree remove "${worktreePath}" --force`;
|
|
86
|
+
logCommand?.(command);
|
|
87
|
+
(0, node_child_process_1.execSync)(command, { stdio: 'pipe' });
|
|
82
88
|
}
|
|
83
89
|
/** Get the current branch name for a worktree path */
|
|
84
90
|
function getBranchName(worktreePath) {
|
|
@@ -87,6 +93,31 @@ function getBranchName(worktreePath) {
|
|
|
87
93
|
encoding: 'utf-8',
|
|
88
94
|
}).trim();
|
|
89
95
|
}
|
|
96
|
+
/** Get uncommitted changes in a worktree (staged, unstaged, untracked) */
|
|
97
|
+
function getUncommittedChanges(worktreePath) {
|
|
98
|
+
const output = (0, node_child_process_1.execSync)('git status --porcelain', {
|
|
99
|
+
cwd: worktreePath,
|
|
100
|
+
encoding: 'utf-8',
|
|
101
|
+
}).trim();
|
|
102
|
+
return output.length > 0 ? output.split('\n') : [];
|
|
103
|
+
}
|
|
104
|
+
/** Get commits not pushed to upstream tracking branch */
|
|
105
|
+
function getUnsyncedStatus(worktreePath) {
|
|
106
|
+
try {
|
|
107
|
+
const output = (0, node_child_process_1.execSync)('git log @{upstream}..HEAD --oneline', {
|
|
108
|
+
cwd: worktreePath,
|
|
109
|
+
encoding: 'utf-8',
|
|
110
|
+
stdio: 'pipe',
|
|
111
|
+
}).trim();
|
|
112
|
+
return {
|
|
113
|
+
unpushedCommits: output.length > 0 ? output.split('\n') : [],
|
|
114
|
+
noUpstream: false,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return { unpushedCommits: [], noUpstream: true };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
90
121
|
/** Check if a branch exists locally */
|
|
91
122
|
function branchExistsLocally(branchName) {
|
|
92
123
|
try {
|
package/dist/core/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/skills/wt/SKILL.md
CHANGED
|
@@ -171,14 +171,18 @@ wt list
|
|
|
171
171
|
|
|
172
172
|
---
|
|
173
173
|
|
|
174
|
-
### `remove
|
|
174
|
+
### `remove [targets...]|--all` — Remove one or more worktrees
|
|
175
175
|
|
|
176
176
|
Run:
|
|
177
177
|
```bash
|
|
178
|
-
wt remove
|
|
178
|
+
wt remove $@
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
Accepts
|
|
181
|
+
Accepts paths or slots, including batch slot formats:
|
|
182
|
+
- `wt remove 1 2`
|
|
183
|
+
- `wt remove 1,2`
|
|
184
|
+
- `wt remove "1, 2"`
|
|
185
|
+
- `wt remove --all`
|
|
182
186
|
|
|
183
187
|
If the user wants to keep the database, use `--keep-db`.
|
|
184
188
|
|
|
@@ -219,7 +223,7 @@ Available commands:
|
|
|
219
223
|
/wt new <branch> — Create a worktree with isolated DB, Redis, and ports
|
|
220
224
|
/wt open <slot|branch> — Open a worktree by slot or branch (creates if not found)
|
|
221
225
|
/wt list — List all worktree allocations
|
|
222
|
-
/wt remove <
|
|
226
|
+
/wt remove <targets...>|--all — Remove one or more worktrees and clean up resources
|
|
223
227
|
/wt doctor — Diagnose and fix environment issues
|
|
224
228
|
/wt setup [path] — Set up an existing worktree
|
|
225
229
|
```
|