@desplega.ai/wts 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +106 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1877,7 +1877,7 @@ var {
|
|
|
1877
1877
|
// package.json
|
|
1878
1878
|
var package_default = {
|
|
1879
1879
|
name: "@desplega.ai/wts",
|
|
1880
|
-
version: "0.
|
|
1880
|
+
version: "0.2.0",
|
|
1881
1881
|
description: "Git worktree manager with tmux integration",
|
|
1882
1882
|
type: "module",
|
|
1883
1883
|
bin: {
|
|
@@ -2614,7 +2614,8 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
2614
2614
|
var source_default = chalk;
|
|
2615
2615
|
|
|
2616
2616
|
// src/config/local.ts
|
|
2617
|
-
import {
|
|
2617
|
+
import { homedir as homedir3 } from "node:os";
|
|
2618
|
+
import { isAbsolute, join as join3 } from "node:path";
|
|
2618
2619
|
|
|
2619
2620
|
// src/config/global.ts
|
|
2620
2621
|
import { homedir as homedir2 } from "node:os";
|
|
@@ -2624,7 +2625,7 @@ import { join as join2 } from "node:path";
|
|
|
2624
2625
|
var DEFAULT_GLOBAL_CONFIG = {
|
|
2625
2626
|
projects: {},
|
|
2626
2627
|
defaults: {
|
|
2627
|
-
worktreeDir: "
|
|
2628
|
+
worktreeDir: "~/.worktrees",
|
|
2628
2629
|
tmuxWindowTemplate: "{project}-{alias}",
|
|
2629
2630
|
autoTmux: false,
|
|
2630
2631
|
autoClaude: false
|
|
@@ -2708,7 +2709,14 @@ async function resolveConfig(gitRoot) {
|
|
|
2708
2709
|
};
|
|
2709
2710
|
}
|
|
2710
2711
|
function getWorktreeBaseDir(config) {
|
|
2711
|
-
|
|
2712
|
+
let baseDir = config.worktreeDir;
|
|
2713
|
+
if (baseDir.startsWith("~")) {
|
|
2714
|
+
baseDir = join3(homedir3(), baseDir.slice(1));
|
|
2715
|
+
}
|
|
2716
|
+
if (isAbsolute(baseDir)) {
|
|
2717
|
+
return join3(baseDir, config.projectName);
|
|
2718
|
+
}
|
|
2719
|
+
return join3(config.gitRoot, baseDir, config.projectName);
|
|
2712
2720
|
}
|
|
2713
2721
|
|
|
2714
2722
|
// src/utils/prompts.ts
|
|
@@ -3234,8 +3242,8 @@ Next steps:`));
|
|
|
3234
3242
|
});
|
|
3235
3243
|
async function promptForConfig(existing) {
|
|
3236
3244
|
const config = {};
|
|
3237
|
-
const worktreeDir = await prompt("Worktree directory", existing?.worktreeDir ?? "
|
|
3238
|
-
if (worktreeDir !== "
|
|
3245
|
+
const worktreeDir = await prompt("Worktree directory", existing?.worktreeDir ?? "~/.worktrees");
|
|
3246
|
+
if (worktreeDir !== "~/.worktrees") {
|
|
3239
3247
|
config.worktreeDir = worktreeDir;
|
|
3240
3248
|
}
|
|
3241
3249
|
const autoTmux = await confirm("Auto-open tmux window on create?", existing?.autoTmux ?? false);
|
|
@@ -3328,6 +3336,97 @@ function printWorktreeTable(worktrees, projectName) {
|
|
|
3328
3336
|
}
|
|
3329
3337
|
}
|
|
3330
3338
|
|
|
3339
|
+
// src/commands/merge.ts
|
|
3340
|
+
var mergeCommand = new Command2("merge").description("Merge a worktree branch into main").argument("[alias]", "Alias of the worktree to merge").option("--no-cleanup", "Skip cleanup prompt").option("-f, --force", "Skip confirmations (except cleanup)").action(async (alias, options) => {
|
|
3341
|
+
const gitRoot = await getGitRoot();
|
|
3342
|
+
if (!gitRoot) {
|
|
3343
|
+
console.error(source_default.red("Error: Not in a git repository"));
|
|
3344
|
+
process.exit(1);
|
|
3345
|
+
}
|
|
3346
|
+
const config = await resolveConfig(gitRoot);
|
|
3347
|
+
const worktrees = await listWorktrees(gitRoot, config.projectName);
|
|
3348
|
+
let worktree;
|
|
3349
|
+
if (alias) {
|
|
3350
|
+
worktree = await findWorktreeByAlias(alias, gitRoot);
|
|
3351
|
+
if (!worktree) {
|
|
3352
|
+
console.error(source_default.red(`Error: No worktree found with alias "${alias}"`));
|
|
3353
|
+
process.exit(1);
|
|
3354
|
+
}
|
|
3355
|
+
} else {
|
|
3356
|
+
const nonMain = worktrees.filter((wt) => !wt.isMain);
|
|
3357
|
+
if (nonMain.length === 0) {
|
|
3358
|
+
console.error(source_default.yellow("No worktrees to merge"));
|
|
3359
|
+
process.exit(1);
|
|
3360
|
+
}
|
|
3361
|
+
worktree = await selectWorktree(worktrees, { excludeMain: true });
|
|
3362
|
+
if (!worktree) {
|
|
3363
|
+
console.log(source_default.dim("Cancelled"));
|
|
3364
|
+
return;
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
if (worktree.isMain) {
|
|
3368
|
+
console.error(source_default.red("Error: Cannot merge the main worktree"));
|
|
3369
|
+
process.exit(1);
|
|
3370
|
+
}
|
|
3371
|
+
const defaultBranch = await getDefaultBranch(gitRoot);
|
|
3372
|
+
const branchToMerge = worktree.branch;
|
|
3373
|
+
console.log(source_default.bold(`
|
|
3374
|
+
Merging ${source_default.cyan(branchToMerge)} into ${source_default.cyan(defaultBranch)}
|
|
3375
|
+
`));
|
|
3376
|
+
if (!options.force) {
|
|
3377
|
+
const proceed = await confirm(`Switch to ${defaultBranch}?`, true);
|
|
3378
|
+
if (!proceed) {
|
|
3379
|
+
console.log(source_default.dim("Cancelled"));
|
|
3380
|
+
return;
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
console.log(source_default.dim(`Switching to ${defaultBranch}...`));
|
|
3384
|
+
await Bun.$`git checkout ${defaultBranch}`.cwd(gitRoot);
|
|
3385
|
+
if (!options.force) {
|
|
3386
|
+
const proceed = await confirm(`Pull latest ${defaultBranch}?`, true);
|
|
3387
|
+
if (!proceed) {
|
|
3388
|
+
console.log(source_default.dim("Cancelled"));
|
|
3389
|
+
return;
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
console.log(source_default.dim(`Pulling latest...`));
|
|
3393
|
+
await Bun.$`git pull`.cwd(gitRoot);
|
|
3394
|
+
if (!options.force) {
|
|
3395
|
+
const proceed = await confirm(`Merge ${branchToMerge}?`, true);
|
|
3396
|
+
if (!proceed) {
|
|
3397
|
+
console.log(source_default.dim("Cancelled"));
|
|
3398
|
+
return;
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
console.log(source_default.dim(`Merging ${branchToMerge}...`));
|
|
3402
|
+
await Bun.$`git merge ${branchToMerge}`.cwd(gitRoot);
|
|
3403
|
+
if (!options.force) {
|
|
3404
|
+
const proceed = await confirm(`Push to origin?`, true);
|
|
3405
|
+
if (!proceed) {
|
|
3406
|
+
console.log(source_default.dim("Skipped push"));
|
|
3407
|
+
} else {
|
|
3408
|
+
console.log(source_default.dim(`Pushing...`));
|
|
3409
|
+
await Bun.$`git push`.cwd(gitRoot);
|
|
3410
|
+
}
|
|
3411
|
+
} else {
|
|
3412
|
+
console.log(source_default.dim(`Pushing...`));
|
|
3413
|
+
await Bun.$`git push`.cwd(gitRoot);
|
|
3414
|
+
}
|
|
3415
|
+
console.log(source_default.green(`
|
|
3416
|
+
✓ Merged ${branchToMerge} into ${defaultBranch}`));
|
|
3417
|
+
if (options.cleanup !== false) {
|
|
3418
|
+
const cleanup = await confirm(`
|
|
3419
|
+
Clean up worktree and branch?`, false);
|
|
3420
|
+
if (cleanup) {
|
|
3421
|
+
console.log(source_default.dim(`Removing worktree...`));
|
|
3422
|
+
await removeWorktree(worktree.path, true, gitRoot);
|
|
3423
|
+
console.log(source_default.dim(`Deleting branch ${branchToMerge}...`));
|
|
3424
|
+
await deleteBranch(branchToMerge, true, gitRoot);
|
|
3425
|
+
console.log(source_default.green(`✓ Cleaned up`));
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3428
|
+
});
|
|
3429
|
+
|
|
3331
3430
|
// src/commands/pr.ts
|
|
3332
3431
|
async function isGhAvailable() {
|
|
3333
3432
|
try {
|
|
@@ -3606,6 +3705,7 @@ program3.addCommand(initCommand);
|
|
|
3606
3705
|
program3.addCommand(listCommand);
|
|
3607
3706
|
program3.addCommand(createCommand3);
|
|
3608
3707
|
program3.addCommand(deleteCommand);
|
|
3708
|
+
program3.addCommand(mergeCommand);
|
|
3609
3709
|
program3.addCommand(cdCommand);
|
|
3610
3710
|
program3.addCommand(switchCommand);
|
|
3611
3711
|
program3.addCommand(prCommand);
|