@jhorst11/wt 1.0.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 +104 -0
- package/bin/wt.js +86 -0
- package/package.json +45 -0
- package/shell/wt.sh +66 -0
- package/src/commands.js +736 -0
- package/src/git.js +351 -0
- package/src/setup.js +256 -0
- package/src/ui.js +141 -0
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# 🌳 wt-cli
|
|
2
|
+
|
|
3
|
+
A beautiful, interactive CLI for managing git worktrees.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✨ **Interactive menus** - Create, list, and remove worktrees with ease
|
|
10
|
+
- 🌿 **Smart branch handling** - Create from current branch, local branches, or remote branches
|
|
11
|
+
- 🚀 **Quick navigation** - Jump between worktrees and back to home
|
|
12
|
+
- 🎨 **Beautiful UI** - Modern CLI experience with colors, emojis, and spinners
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Global Install (Recommended)
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g .
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or if you want to install from the repo:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cd /path/to/wt
|
|
26
|
+
npm install
|
|
27
|
+
npm link
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Shell Integration
|
|
31
|
+
|
|
32
|
+
To enable the `cd` functionality (jumping to worktrees), add this to your `.bashrc` or `.zshrc`:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# For wt-cli directory changing support
|
|
36
|
+
source /path/to/wt/shell/wt.sh
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Without this, the tool will show you the path to copy instead of auto-navigating.
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
### Interactive Mode (Default)
|
|
44
|
+
|
|
45
|
+
Just run `wt` with no arguments to open the interactive menu:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
wt
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Commands
|
|
52
|
+
|
|
53
|
+
| Command | Description |
|
|
54
|
+
|---------|-------------|
|
|
55
|
+
| `wt` | Open interactive menu |
|
|
56
|
+
| `wt new` | Create a new worktree |
|
|
57
|
+
| `wt list` | List all worktrees for current repo |
|
|
58
|
+
| `wt remove` | Remove a worktree |
|
|
59
|
+
| `wt go [name]` | Jump to a worktree |
|
|
60
|
+
| `wt home` | Return to the main repository |
|
|
61
|
+
|
|
62
|
+
### Creating a Worktree
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
wt new
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
You'll be prompted to:
|
|
69
|
+
1. Choose what to base your worktree on (current branch, local branch, remote branch, or new)
|
|
70
|
+
2. Enter a name for your worktree
|
|
71
|
+
3. Confirm creation
|
|
72
|
+
|
|
73
|
+
### Configuration
|
|
74
|
+
|
|
75
|
+
You can configure wt-cli via environment variables:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Directory where your projects live
|
|
79
|
+
export W_PROJECTS_DIR="$HOME/projects"
|
|
80
|
+
|
|
81
|
+
# Directory where worktrees will be created
|
|
82
|
+
export W_WORKTREES_DIR="$HOME/projects/worktrees"
|
|
83
|
+
|
|
84
|
+
# Optional prefix for branch names (e.g., "username")
|
|
85
|
+
export W_DEFAULT_BRANCH_PREFIX=""
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## How It Works
|
|
89
|
+
|
|
90
|
+
wt-cli creates worktrees in a structured directory based on your project:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
~/projects/
|
|
94
|
+
├── my-repo/ # Your main repository
|
|
95
|
+
│ └── ...
|
|
96
|
+
└── worktrees/
|
|
97
|
+
└── my-repo/ # Worktrees for my-repo
|
|
98
|
+
├── feature-a/
|
|
99
|
+
└── feature-b/
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT
|
package/bin/wt.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { program } from 'commander';
|
|
4
|
+
import {
|
|
5
|
+
mainMenu,
|
|
6
|
+
createWorktreeFlow,
|
|
7
|
+
listWorktrees,
|
|
8
|
+
removeWorktreeFlow,
|
|
9
|
+
mergeWorktreeFlow,
|
|
10
|
+
goHome,
|
|
11
|
+
goToWorktree,
|
|
12
|
+
} from '../src/commands.js';
|
|
13
|
+
import { showHelp, showLogo, spacer, colors } from '../src/ui.js';
|
|
14
|
+
import { setupCommand } from '../src/setup.js';
|
|
15
|
+
|
|
16
|
+
program
|
|
17
|
+
.name('wt')
|
|
18
|
+
.description('🌳 Beautiful interactive git worktree manager')
|
|
19
|
+
.version('1.0.0');
|
|
20
|
+
|
|
21
|
+
program
|
|
22
|
+
.command('new', { isDefault: false })
|
|
23
|
+
.description('Create a new worktree interactively')
|
|
24
|
+
.action(createWorktreeFlow);
|
|
25
|
+
|
|
26
|
+
program
|
|
27
|
+
.command('list')
|
|
28
|
+
.alias('ls')
|
|
29
|
+
.description('List all worktrees for the current repo')
|
|
30
|
+
.action(listWorktrees);
|
|
31
|
+
|
|
32
|
+
program
|
|
33
|
+
.command('remove')
|
|
34
|
+
.alias('rm')
|
|
35
|
+
.description('Remove a worktree interactively')
|
|
36
|
+
.action(removeWorktreeFlow);
|
|
37
|
+
|
|
38
|
+
program
|
|
39
|
+
.command('merge')
|
|
40
|
+
.description('Merge a worktree branch back to main')
|
|
41
|
+
.action(mergeWorktreeFlow);
|
|
42
|
+
|
|
43
|
+
program
|
|
44
|
+
.command('home')
|
|
45
|
+
.description('Return to the main repository')
|
|
46
|
+
.action(goHome);
|
|
47
|
+
|
|
48
|
+
program
|
|
49
|
+
.command('go [name]')
|
|
50
|
+
.description('Jump to a worktree (interactive if no name)')
|
|
51
|
+
.action(goToWorktree);
|
|
52
|
+
|
|
53
|
+
program
|
|
54
|
+
.command('setup')
|
|
55
|
+
.description('Configure shell integration for directory jumping')
|
|
56
|
+
.action(setupCommand);
|
|
57
|
+
|
|
58
|
+
// Default action (no command = interactive menu)
|
|
59
|
+
program.action(async () => {
|
|
60
|
+
const args = process.argv.slice(2);
|
|
61
|
+
if (args.length === 0) {
|
|
62
|
+
await mainMenu();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Custom help
|
|
67
|
+
program.on('--help', () => {
|
|
68
|
+
spacer();
|
|
69
|
+
console.log('Examples:');
|
|
70
|
+
console.log(` ${colors.muted('$')} wt ${colors.muted('# Interactive menu')}`);
|
|
71
|
+
console.log(` ${colors.muted('$')} wt new ${colors.muted('# Create new worktree')}`);
|
|
72
|
+
console.log(` ${colors.muted('$')} wt list ${colors.muted('# List all worktrees')}`);
|
|
73
|
+
console.log(` ${colors.muted('$')} wt go feature-x ${colors.muted('# Jump to worktree')}`);
|
|
74
|
+
console.log(` ${colors.muted('$')} wt merge ${colors.muted('# Merge worktree to main')}`);
|
|
75
|
+
console.log(` ${colors.muted('$')} wt home ${colors.muted('# Return to main repo')}`);
|
|
76
|
+
console.log(` ${colors.muted('$')} wt setup ${colors.muted('# Configure shell integration')}`);
|
|
77
|
+
spacer();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Handle graceful exit
|
|
81
|
+
process.on('SIGINT', () => {
|
|
82
|
+
console.log('\n');
|
|
83
|
+
process.exit(0);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jhorst11/wt",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "🌳 Beautiful interactive git worktree manager",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"wt": "./bin/wt.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"src",
|
|
12
|
+
"shell"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"start": "node bin/wt.js"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"git",
|
|
19
|
+
"worktree",
|
|
20
|
+
"cli",
|
|
21
|
+
"interactive",
|
|
22
|
+
"terminal",
|
|
23
|
+
"workflow"
|
|
24
|
+
],
|
|
25
|
+
"author": "Justin Horst",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/jhorst11/wt.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/jhorst11Ã¥/wt#readme",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@inquirer/prompts": "^7.2.1",
|
|
37
|
+
"chalk": "^5.3.0",
|
|
38
|
+
"cli-spinners": "^3.2.0",
|
|
39
|
+
"commander": "^13.0.0",
|
|
40
|
+
"figures": "^6.1.0",
|
|
41
|
+
"gradient-string": "^3.0.0",
|
|
42
|
+
"ora": "^8.1.1",
|
|
43
|
+
"simple-git": "^3.27.0"
|
|
44
|
+
}
|
|
45
|
+
}
|
package/shell/wt.sh
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Shell wrapper for wt-cli to enable directory changing
|
|
3
|
+
# Add this to your .bashrc or .zshrc:
|
|
4
|
+
# source /path/to/wt/shell/wt.sh
|
|
5
|
+
|
|
6
|
+
# Find the wt binary - works whether installed globally or locally
|
|
7
|
+
_wt_find_bin() {
|
|
8
|
+
if command -v wt &>/dev/null; then
|
|
9
|
+
echo "wt"
|
|
10
|
+
elif [[ -f "$HOME/.npm-global/bin/wt" ]]; then
|
|
11
|
+
echo "$HOME/.npm-global/bin/wt"
|
|
12
|
+
elif [[ -f "$(npm root -g 2>/dev/null)/wt-cli/bin/wt.js" ]]; then
|
|
13
|
+
echo "node $(npm root -g)/wt-cli/bin/wt.js"
|
|
14
|
+
else
|
|
15
|
+
echo "wt"
|
|
16
|
+
fi
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
wt() {
|
|
20
|
+
local wt_bin=$(_wt_find_bin)
|
|
21
|
+
local wt_cd_file="/tmp/wt_cd_$$"
|
|
22
|
+
|
|
23
|
+
# Clean up any old cd file
|
|
24
|
+
rm -f "$wt_cd_file"
|
|
25
|
+
|
|
26
|
+
# Run wt with env vars so it knows we can handle cd
|
|
27
|
+
WT_WRAPPER=1 WT_CD_FILE="$wt_cd_file" $wt_bin "$@"
|
|
28
|
+
local exit_code=$?
|
|
29
|
+
|
|
30
|
+
# Check if wt wrote a cd path
|
|
31
|
+
if [[ -f "$wt_cd_file" ]]; then
|
|
32
|
+
local dir=$(cat "$wt_cd_file")
|
|
33
|
+
rm -f "$wt_cd_file"
|
|
34
|
+
[[ -d "$dir" ]] && cd "$dir"
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
return $exit_code
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Tab completion for bash
|
|
41
|
+
if [[ -n "$BASH_VERSION" ]]; then
|
|
42
|
+
_wt_completions() {
|
|
43
|
+
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
44
|
+
local commands="new list ls remove rm home go setup"
|
|
45
|
+
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
|
|
46
|
+
}
|
|
47
|
+
complete -F _wt_completions wt
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Tab completion for zsh
|
|
51
|
+
if [[ -n "$ZSH_VERSION" ]]; then
|
|
52
|
+
_wt_completions() {
|
|
53
|
+
local commands=(
|
|
54
|
+
'new:Create a new worktree'
|
|
55
|
+
'list:List all worktrees'
|
|
56
|
+
'ls:List all worktrees'
|
|
57
|
+
'remove:Remove a worktree'
|
|
58
|
+
'rm:Remove a worktree'
|
|
59
|
+
'home:Return to main repo'
|
|
60
|
+
'go:Jump to a worktree'
|
|
61
|
+
'setup:Configure shell integration'
|
|
62
|
+
)
|
|
63
|
+
_describe 'command' commands
|
|
64
|
+
}
|
|
65
|
+
compdef _wt_completions wt
|
|
66
|
+
fi
|