@desplega.ai/wts 0.1.3 → 0.1.6

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/dist/index.js +57 -27
  2. 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.1.3",
1880
+ version: "0.1.6",
1881
1881
  description: "Git worktree manager with tmux integration",
1882
1882
  type: "module",
1883
1883
  bin: {
@@ -2098,6 +2098,10 @@ async function removeWorktree(path, force = false, cwd) {
2098
2098
  async function pruneWorktrees(cwd) {
2099
2099
  await Bun.$`git worktree prune`.cwd(cwd ?? process.cwd());
2100
2100
  }
2101
+ async function deleteBranch(branch, force = false, cwd) {
2102
+ const flag = force ? "-D" : "-d";
2103
+ await Bun.$`git branch ${flag} ${branch}`.cwd(cwd ?? process.cwd());
2104
+ }
2101
2105
  function generateWorktreePath(baseDir, alias) {
2102
2106
  const dirName = generateWorktreeDirName(alias);
2103
2107
  return join(baseDir, dirName);
@@ -2799,7 +2803,7 @@ async function categorizeWorktrees(worktrees, gitRoot, options) {
2799
2803
  }
2800
2804
  return { merged, unmerged, stale, active };
2801
2805
  }
2802
- var cleanupCommand = new Command2("cleanup").description("Remove merged or stale worktrees").option("--dry-run", "Show what would be removed without removing").option("-f, --force", "Force removal without confirmation").option("--older-than <days>", "Include worktrees older than N days").option("--unmerged", "Include all unmerged worktrees").action(async (options) => {
2806
+ var cleanupCommand = new Command2("cleanup").description("Remove merged or stale worktrees").option("--dry-run", "Show what would be removed without removing").option("-f, --force", "Force removal without confirmation").option("--older-than <days>", "Include worktrees older than N days").option("--unmerged", "Include all unmerged worktrees").option("--delete-branches", "Also delete the associated branches").action(async (options) => {
2803
2807
  const gitRoot = await getGitRoot();
2804
2808
  if (!gitRoot) {
2805
2809
  console.error(source_default.red("Error: Not in a git repository"));
@@ -2851,24 +2855,38 @@ var cleanupCommand = new Command2("cleanup").description("Remove merged or stale
2851
2855
  }
2852
2856
  console.log();
2853
2857
  }
2858
+ if (options.deleteBranches) {
2859
+ console.log(source_default.dim("(branches will also be deleted)"));
2860
+ }
2854
2861
  if (options.dryRun) {
2855
2862
  console.log(source_default.dim("(dry run - no changes made)"));
2856
2863
  return;
2857
2864
  }
2858
2865
  if (!options.force) {
2859
- const shouldProceed = await confirm(`Remove ${toRemove.length} worktree(s)?`, false);
2866
+ const message = options.deleteBranches ? `Remove ${toRemove.length} worktree(s) and their branches?` : `Remove ${toRemove.length} worktree(s)?`;
2867
+ const shouldProceed = await confirm(message, false);
2860
2868
  if (!shouldProceed) {
2861
2869
  console.log(source_default.dim("Cancelled"));
2862
2870
  return;
2863
2871
  }
2864
2872
  }
2865
- let removed = 0;
2873
+ let removedWorktrees = 0;
2874
+ let removedBranches = 0;
2866
2875
  let failed = 0;
2867
2876
  for (const wt of toRemove) {
2868
2877
  try {
2869
2878
  console.log(source_default.dim(`Removing ${wt.alias ?? wt.branch}...`));
2870
2879
  await removeWorktree(wt.path, true, gitRoot);
2871
- removed++;
2880
+ removedWorktrees++;
2881
+ if (options.deleteBranches && wt.branch && wt.branch !== "detached") {
2882
+ try {
2883
+ await deleteBranch(wt.branch, true, gitRoot);
2884
+ removedBranches++;
2885
+ } catch (error) {
2886
+ console.error(source_default.yellow(` Warning: Could not delete branch ${wt.branch}:`));
2887
+ console.error(source_default.dim(` ${error instanceof Error ? error.message : String(error)}`));
2888
+ }
2889
+ }
2872
2890
  } catch (error) {
2873
2891
  console.error(source_default.red(` Failed to remove ${wt.alias ?? wt.branch}:`));
2874
2892
  console.error(source_default.dim(` ${error instanceof Error ? error.message : String(error)}`));
@@ -2876,8 +2894,11 @@ var cleanupCommand = new Command2("cleanup").description("Remove merged or stale
2876
2894
  }
2877
2895
  }
2878
2896
  console.log();
2879
- if (removed > 0) {
2880
- console.log(source_default.green(`Removed ${removed} worktree(s)`));
2897
+ if (removedWorktrees > 0) {
2898
+ console.log(source_default.green(`Removed ${removedWorktrees} worktree(s)`));
2899
+ }
2900
+ if (removedBranches > 0) {
2901
+ console.log(source_default.green(`Deleted ${removedBranches} branch(es)`));
2881
2902
  }
2882
2903
  if (failed > 0) {
2883
2904
  console.log(source_default.red(`Failed to remove ${failed} worktree(s)`));
@@ -3046,14 +3067,19 @@ async function runSetupScript(worktreePath, scriptPath, gitRoot) {
3046
3067
  }
3047
3068
  const ext = scriptPath.split(".").pop()?.toLowerCase();
3048
3069
  try {
3070
+ const env2 = {
3071
+ ...process.env,
3072
+ WTS_WORKTREE_PATH: worktreePath,
3073
+ WTS_GIT_ROOT: gitRoot
3074
+ };
3049
3075
  if (ext === "ts") {
3050
- await Bun.$`bun ${fullScriptPath}`.cwd(worktreePath).env({ ...process.env, WTS_WORKTREE_PATH: worktreePath });
3076
+ await Bun.$`bun ${fullScriptPath}`.cwd(worktreePath).env(env2);
3051
3077
  } else if (ext === "sh") {
3052
- await Bun.$`bash ${fullScriptPath}`.cwd(worktreePath).env({ ...process.env, WTS_WORKTREE_PATH: worktreePath });
3078
+ await Bun.$`bash ${fullScriptPath}`.cwd(worktreePath).env(env2);
3053
3079
  } else if (ext === "js" || ext === "mjs") {
3054
- await Bun.$`bun ${fullScriptPath}`.cwd(worktreePath).env({ ...process.env, WTS_WORKTREE_PATH: worktreePath });
3080
+ await Bun.$`bun ${fullScriptPath}`.cwd(worktreePath).env(env2);
3055
3081
  } else {
3056
- await Bun.$`${fullScriptPath}`.cwd(worktreePath).env({ ...process.env, WTS_WORKTREE_PATH: worktreePath });
3082
+ await Bun.$`${fullScriptPath}`.cwd(worktreePath).env(env2);
3057
3083
  }
3058
3084
  console.log(source_default.green("Setup script completed"));
3059
3085
  } catch (error) {
@@ -3287,7 +3313,7 @@ async function listAllProjects(jsonOutput) {
3287
3313
  }
3288
3314
  function printWorktreeTable(worktrees, projectName) {
3289
3315
  console.log(source_default.bold.blue(`${projectName}`));
3290
- console.log(source_default.dim("".repeat(60)));
3316
+ console.log(source_default.dim("-".repeat(60)));
3291
3317
  if (worktrees.length === 0) {
3292
3318
  console.log(source_default.dim(" No worktrees"));
3293
3319
  return;
@@ -3413,8 +3439,13 @@ import { access as access2, chmod } from "node:fs/promises";
3413
3439
  import { join as join5 } from "node:path";
3414
3440
  var SHELL_TEMPLATE = `#!/bin/bash
3415
3441
  # wts setup script - runs after worktree creation
3416
- # Working directory: the new worktree
3417
- # Environment: WTS_WORKTREE_PATH contains the worktree path
3442
+ #
3443
+ # Environment variables:
3444
+ # WTS_WORKTREE_PATH - path to the new worktree (also the working directory)
3445
+ # WTS_GIT_ROOT - path to the main repository root
3446
+ #
3447
+ # Example: copy .env from main repo to worktree
3448
+ # cp "$WTS_GIT_ROOT/.env" "$WTS_WORKTREE_PATH/.env"
3418
3449
 
3419
3450
  set -e
3420
3451
 
@@ -3424,20 +3455,21 @@ echo "Setting up worktree..."
3424
3455
  # npm install
3425
3456
  # bun install
3426
3457
 
3427
- # Copy environment files
3428
- # cp .env.example .env
3429
-
3430
- # Run any other setup tasks
3431
- # ...
3458
+ # Copy files from main repo
3459
+ # cp "$WTS_GIT_ROOT/.env" .env
3460
+ # cp -r "$WTS_GIT_ROOT/node_modules" .
3432
3461
 
3433
3462
  echo "Setup complete!"
3434
3463
  `;
3435
3464
  var TS_TEMPLATE = `#!/usr/bin/env bun
3436
3465
  // wts setup script - runs after worktree creation
3437
- // Working directory: the new worktree
3438
- // Environment: WTS_WORKTREE_PATH contains the worktree path
3466
+ //
3467
+ // Environment variables:
3468
+ // WTS_WORKTREE_PATH - path to the new worktree (also the working directory)
3469
+ // WTS_GIT_ROOT - path to the main repository root
3439
3470
 
3440
- const worktreePath = process.env.WTS_WORKTREE_PATH;
3471
+ const worktreePath = process.env.WTS_WORKTREE_PATH!;
3472
+ const gitRoot = process.env.WTS_GIT_ROOT!;
3441
3473
 
3442
3474
  console.log("Setting up worktree...");
3443
3475
 
@@ -3445,11 +3477,9 @@ console.log("Setting up worktree...");
3445
3477
  // await Bun.$\`npm install\`;
3446
3478
  // await Bun.$\`bun install\`;
3447
3479
 
3448
- // Copy environment files
3449
- // await Bun.$\`cp .env.example .env\`;
3450
-
3451
- // Run any other setup tasks
3452
- // ...
3480
+ // Copy files from main repo
3481
+ // await Bun.$\`cp \${gitRoot}/.env .env\`;
3482
+ // await Bun.$\`cp -r \${gitRoot}/node_modules .\`;
3453
3483
 
3454
3484
  console.log("Setup complete!");
3455
3485
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@desplega.ai/wts",
3
- "version": "0.1.3",
3
+ "version": "0.1.6",
4
4
  "description": "Git worktree manager with tmux integration",
5
5
  "type": "module",
6
6
  "bin": {