@jhorst11/wt 2.0.1 â 2.1.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 +39 -3
- package/dist/bin/wt.d.ts +3 -0
- package/dist/bin/wt.d.ts.map +1 -0
- package/dist/bin/wt.js +83 -0
- package/dist/bin/wt.js.map +1 -0
- package/dist/src/commands.d.ts +9 -0
- package/dist/src/commands.d.ts.map +1 -0
- package/dist/src/commands.js +924 -0
- package/dist/src/commands.js.map +1 -0
- package/dist/src/config.d.ts +51 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +384 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/git.d.ts +55 -0
- package/dist/src/git.d.ts.map +1 -0
- package/dist/src/git.js +387 -0
- package/dist/src/git.js.map +1 -0
- package/dist/src/setup.d.ts +8 -0
- package/dist/src/setup.d.ts.map +1 -0
- package/dist/src/setup.js +245 -0
- package/dist/src/setup.js.map +1 -0
- package/dist/src/types.d.ts +64 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/ui.d.ts +93 -0
- package/dist/src/ui.d.ts.map +1 -0
- package/dist/src/ui.js +273 -0
- package/dist/src/ui.js.map +1 -0
- package/package.json +20 -6
- package/bin/wt.js +0 -87
- package/shell/wt.sh +0 -66
- package/src/commands.js +0 -883
- package/src/config.js +0 -257
- package/src/git.js +0 -397
- package/src/setup.js +0 -267
- package/src/ui.js +0 -147
package/src/setup.js
DELETED
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import { select, confirm } from '@inquirer/prompts';
|
|
2
|
-
import { ExitPromptError } from '@inquirer/core';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
import { existsSync, readFileSync, appendFileSync, writeFileSync } from 'fs';
|
|
5
|
-
import { join } from 'path';
|
|
6
|
-
import {
|
|
7
|
-
showMiniLogo,
|
|
8
|
-
success,
|
|
9
|
-
error,
|
|
10
|
-
warning,
|
|
11
|
-
info,
|
|
12
|
-
heading,
|
|
13
|
-
spacer,
|
|
14
|
-
colors,
|
|
15
|
-
icons,
|
|
16
|
-
divider,
|
|
17
|
-
} from './ui.js';
|
|
18
|
-
|
|
19
|
-
// Shell detection
|
|
20
|
-
export function detectShell() {
|
|
21
|
-
const shell = process.env.SHELL || '';
|
|
22
|
-
|
|
23
|
-
if (shell.includes('zsh')) return 'zsh';
|
|
24
|
-
if (shell.includes('bash')) return 'bash';
|
|
25
|
-
if (shell.includes('fish')) return 'fish';
|
|
26
|
-
if (process.env.FISH_VERSION) return 'fish';
|
|
27
|
-
if (process.env.ZSH_VERSION) return 'zsh';
|
|
28
|
-
if (process.env.BASH_VERSION) return 'bash';
|
|
29
|
-
|
|
30
|
-
return 'unknown';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function getShellConfig() {
|
|
34
|
-
const shell = detectShell();
|
|
35
|
-
const home = homedir();
|
|
36
|
-
|
|
37
|
-
const configs = {
|
|
38
|
-
zsh: {
|
|
39
|
-
name: 'Zsh',
|
|
40
|
-
rcFile: join(home, '.zshrc'),
|
|
41
|
-
wrapper: `
|
|
42
|
-
# wt-cli: Git worktree manager shell integration
|
|
43
|
-
wt() {
|
|
44
|
-
local wt_cd_file="/tmp/wt_cd_$$"
|
|
45
|
-
rm -f "$wt_cd_file"
|
|
46
|
-
WT_WRAPPER=1 WT_CD_FILE="$wt_cd_file" command wt "$@"
|
|
47
|
-
local exit_code=$?
|
|
48
|
-
if [[ -f "$wt_cd_file" ]]; then
|
|
49
|
-
local dir=$(cat "$wt_cd_file")
|
|
50
|
-
rm -f "$wt_cd_file"
|
|
51
|
-
[[ -d "$dir" ]] && cd "$dir"
|
|
52
|
-
fi
|
|
53
|
-
return $exit_code
|
|
54
|
-
}`,
|
|
55
|
-
},
|
|
56
|
-
bash: {
|
|
57
|
-
name: 'Bash',
|
|
58
|
-
rcFile: join(home, '.bashrc'),
|
|
59
|
-
wrapper: `
|
|
60
|
-
# wt-cli: Git worktree manager shell integration
|
|
61
|
-
wt() {
|
|
62
|
-
local wt_cd_file="/tmp/wt_cd_$$"
|
|
63
|
-
rm -f "$wt_cd_file"
|
|
64
|
-
WT_WRAPPER=1 WT_CD_FILE="$wt_cd_file" command wt "$@"
|
|
65
|
-
local exit_code=$?
|
|
66
|
-
if [[ -f "$wt_cd_file" ]]; then
|
|
67
|
-
local dir=$(cat "$wt_cd_file")
|
|
68
|
-
rm -f "$wt_cd_file"
|
|
69
|
-
[[ -d "$dir" ]] && cd "$dir"
|
|
70
|
-
fi
|
|
71
|
-
return $exit_code
|
|
72
|
-
}`,
|
|
73
|
-
},
|
|
74
|
-
fish: {
|
|
75
|
-
name: 'Fish',
|
|
76
|
-
rcFile: join(home, '.config/fish/config.fish'),
|
|
77
|
-
wrapper: `
|
|
78
|
-
# wt-cli: Git worktree manager shell integration
|
|
79
|
-
function wt
|
|
80
|
-
set -l wt_cd_file "/tmp/wt_cd_fish_$fish_pid"
|
|
81
|
-
rm -f "$wt_cd_file"
|
|
82
|
-
env WT_WRAPPER=1 WT_CD_FILE="$wt_cd_file" command wt $argv
|
|
83
|
-
set -l exit_code $status
|
|
84
|
-
if test -f "$wt_cd_file"
|
|
85
|
-
set -l dir (cat "$wt_cd_file")
|
|
86
|
-
rm -f "$wt_cd_file"
|
|
87
|
-
test -d "$dir"; and cd "$dir"
|
|
88
|
-
end
|
|
89
|
-
return $exit_code
|
|
90
|
-
end`,
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
return configs[shell] || null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function isWrapperInstalled() {
|
|
98
|
-
// Check if we're running through the wrapper
|
|
99
|
-
// The wrapper would need to set this env var
|
|
100
|
-
return process.env.WT_WRAPPER === '1';
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function checkWrapperInRcFile() {
|
|
104
|
-
const config = getShellConfig();
|
|
105
|
-
if (!config) return { installed: false, reason: 'unknown-shell' };
|
|
106
|
-
|
|
107
|
-
if (!existsSync(config.rcFile)) {
|
|
108
|
-
return { installed: false, reason: 'no-rc-file', rcFile: config.rcFile };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
const content = readFileSync(config.rcFile, 'utf-8');
|
|
113
|
-
if (content.includes('wt-cli') || content.includes('__WT_CD__')) {
|
|
114
|
-
return { installed: true, rcFile: config.rcFile };
|
|
115
|
-
}
|
|
116
|
-
return { installed: false, reason: 'not-configured', rcFile: config.rcFile };
|
|
117
|
-
} catch {
|
|
118
|
-
return { installed: false, reason: 'read-error', rcFile: config.rcFile };
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export async function setupCommand() {
|
|
123
|
-
showMiniLogo();
|
|
124
|
-
heading(`${icons.sparkles} Shell Setup`);
|
|
125
|
-
|
|
126
|
-
const shell = detectShell();
|
|
127
|
-
const config = getShellConfig();
|
|
128
|
-
|
|
129
|
-
if (shell === 'unknown' || !config) {
|
|
130
|
-
warning(`Could not detect your shell type`);
|
|
131
|
-
info(`SHELL environment variable: ${process.env.SHELL || 'not set'}`);
|
|
132
|
-
spacer();
|
|
133
|
-
console.log(` ${colors.muted('Please manually add the shell wrapper to your shell config.')}`);
|
|
134
|
-
console.log(` ${colors.muted('See:')} ${colors.path('https://github.com/jhorst11/wt#shell-integration')}`);
|
|
135
|
-
spacer();
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
success(`Detected shell: ${colors.primary(config.name)}`);
|
|
140
|
-
info(`Config file: ${colors.path(config.rcFile)}`);
|
|
141
|
-
spacer();
|
|
142
|
-
|
|
143
|
-
const status = checkWrapperInRcFile();
|
|
144
|
-
|
|
145
|
-
if (status.installed) {
|
|
146
|
-
success(`Shell integration is already installed! ${icons.check}`);
|
|
147
|
-
spacer();
|
|
148
|
-
info(`If directory jumping isn't working, try restarting your terminal`);
|
|
149
|
-
info(`or run: ${colors.primary(`source ${config.rcFile}`)}`);
|
|
150
|
-
spacer();
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Not installed - offer to install
|
|
155
|
-
divider();
|
|
156
|
-
spacer();
|
|
157
|
-
|
|
158
|
-
console.log(` ${colors.muted('To enable directory jumping (wt go, wt home), we need to')}`);
|
|
159
|
-
console.log(` ${colors.muted('add a small shell function to your')} ${colors.path(config.rcFile)}`);
|
|
160
|
-
spacer();
|
|
161
|
-
|
|
162
|
-
try {
|
|
163
|
-
const action = await select({
|
|
164
|
-
message: 'How would you like to proceed?',
|
|
165
|
-
choices: [
|
|
166
|
-
{
|
|
167
|
-
name: `${icons.sparkles} Auto-install (append to ${config.rcFile})`,
|
|
168
|
-
value: 'auto',
|
|
169
|
-
description: 'Recommended - automatically adds the integration',
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
name: `${icons.info} Show me the code to copy`,
|
|
173
|
-
value: 'show',
|
|
174
|
-
description: 'Display the code so you can add it manually',
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
name: `${colors.muted(icons.cross + ' Skip for now')}`,
|
|
178
|
-
value: 'skip',
|
|
179
|
-
},
|
|
180
|
-
],
|
|
181
|
-
theme: { prefix: icons.tree },
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
if (action === 'auto') {
|
|
185
|
-
await autoInstall(config);
|
|
186
|
-
} else if (action === 'show') {
|
|
187
|
-
showManualInstructions(config);
|
|
188
|
-
} else {
|
|
189
|
-
info('Skipped. You can run `wt setup` anytime to configure shell integration.');
|
|
190
|
-
spacer();
|
|
191
|
-
}
|
|
192
|
-
} catch (err) {
|
|
193
|
-
if (err instanceof ExitPromptError) {
|
|
194
|
-
spacer();
|
|
195
|
-
info('Cancelled');
|
|
196
|
-
spacer();
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
throw err;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
async function autoInstall(config) {
|
|
204
|
-
spacer();
|
|
205
|
-
|
|
206
|
-
try {
|
|
207
|
-
appendFileSync(config.rcFile, '\n' + config.wrapper + '\n');
|
|
208
|
-
success(`Added shell integration to ${colors.path(config.rcFile)}`);
|
|
209
|
-
spacer();
|
|
210
|
-
|
|
211
|
-
console.log(` ${icons.rocket} ${colors.primary('Almost done!')} Run this to activate:`);
|
|
212
|
-
spacer();
|
|
213
|
-
console.log(` ${colors.secondary(`source ${config.rcFile}`)}`);
|
|
214
|
-
spacer();
|
|
215
|
-
console.log(` ${colors.muted('Or just restart your terminal.')}`);
|
|
216
|
-
spacer();
|
|
217
|
-
} catch (err) {
|
|
218
|
-
error(`Failed to write to ${config.rcFile}`);
|
|
219
|
-
error(err.message);
|
|
220
|
-
spacer();
|
|
221
|
-
showManualInstructions(config);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function showManualInstructions(config) {
|
|
226
|
-
spacer();
|
|
227
|
-
console.log(` ${colors.muted('Add this to')} ${colors.path(config.rcFile)}${colors.muted(':')}`);
|
|
228
|
-
spacer();
|
|
229
|
-
divider();
|
|
230
|
-
console.log(colors.secondary(config.wrapper));
|
|
231
|
-
divider();
|
|
232
|
-
spacer();
|
|
233
|
-
console.log(` ${colors.muted('Then run:')} ${colors.primary(`source ${config.rcFile}`)}`);
|
|
234
|
-
spacer();
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Helper to show a gentle nudge if wrapper isn't set up
|
|
238
|
-
export function showCdHint(path) {
|
|
239
|
-
// Check if we're running through the shell wrapper with a cd file
|
|
240
|
-
const cdFile = process.env.WT_CD_FILE;
|
|
241
|
-
if (cdFile && isWrapperInstalled()) {
|
|
242
|
-
// Write path to temp file for shell wrapper to read
|
|
243
|
-
try {
|
|
244
|
-
writeFileSync(cdFile, path);
|
|
245
|
-
} catch {
|
|
246
|
-
// Fall through to show manual instructions
|
|
247
|
-
}
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Fall back to checking rc file
|
|
252
|
-
const status = checkWrapperInRcFile();
|
|
253
|
-
|
|
254
|
-
if (status.installed) {
|
|
255
|
-
// Wrapper is in rc file but not active - show path
|
|
256
|
-
spacer();
|
|
257
|
-
console.log(` ${icons.rocket} ${colors.muted('Switching to:')} ${colors.path(path)}`);
|
|
258
|
-
spacer();
|
|
259
|
-
} else {
|
|
260
|
-
// No wrapper - show a friendly message instead
|
|
261
|
-
spacer();
|
|
262
|
-
console.log(` ${icons.rocket} ${colors.muted('Run:')} ${colors.primary(`cd "${path}"`)}`);
|
|
263
|
-
spacer();
|
|
264
|
-
console.log(` ${colors.muted(`Tip: Run`)} ${colors.secondary('wt setup')} ${colors.muted('to enable auto-navigation')}`);
|
|
265
|
-
spacer();
|
|
266
|
-
}
|
|
267
|
-
}
|
package/src/ui.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import gradient from 'gradient-string';
|
|
3
|
-
import figures from 'figures';
|
|
4
|
-
import { createRequire } from 'module';
|
|
5
|
-
|
|
6
|
-
const require = createRequire(import.meta.url);
|
|
7
|
-
const { version } = require('../package.json');
|
|
8
|
-
|
|
9
|
-
// Custom gradient for the logo
|
|
10
|
-
const wtGradient = gradient(['#00d4ff', '#7c3aed', '#f472b6']);
|
|
11
|
-
const successGradient = gradient(['#10b981', '#34d399']);
|
|
12
|
-
const warningGradient = gradient(['#f59e0b', '#fbbf24']);
|
|
13
|
-
|
|
14
|
-
export const icons = {
|
|
15
|
-
tree: 'đŗ',
|
|
16
|
-
branch: 'đŋ',
|
|
17
|
-
rocket: 'đ',
|
|
18
|
-
sparkles: 'â¨',
|
|
19
|
-
folder: 'đ',
|
|
20
|
-
trash: 'đī¸',
|
|
21
|
-
home: 'đ ',
|
|
22
|
-
check: figures.tick,
|
|
23
|
-
cross: figures.cross,
|
|
24
|
-
pointer: figures.pointer,
|
|
25
|
-
arrowRight: figures.arrowRight,
|
|
26
|
-
bullet: figures.bullet,
|
|
27
|
-
star: 'â',
|
|
28
|
-
git: 'ķ°ĸ',
|
|
29
|
-
plus: 'â',
|
|
30
|
-
warning: 'â ī¸',
|
|
31
|
-
info: 'âšī¸',
|
|
32
|
-
remote: 'âī¸',
|
|
33
|
-
local: 'đģ',
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const colors = {
|
|
37
|
-
primary: chalk.hex('#7c3aed'),
|
|
38
|
-
secondary: chalk.hex('#00d4ff'),
|
|
39
|
-
success: chalk.hex('#10b981'),
|
|
40
|
-
warning: chalk.hex('#f59e0b'),
|
|
41
|
-
error: chalk.hex('#ef4444'),
|
|
42
|
-
muted: chalk.gray,
|
|
43
|
-
highlight: chalk.hex('#f472b6'),
|
|
44
|
-
branch: chalk.hex('#34d399'),
|
|
45
|
-
path: chalk.hex('#60a5fa'),
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export function showLogo() {
|
|
49
|
-
const logo = `
|
|
50
|
-
${wtGradient('âĻ âĻââââĻâââĻââââĻââĻââââââââ')}
|
|
51
|
-
${wtGradient('ââââ ââ âĻââ âŠâ â â âĻâââŖ ââŖ ')}
|
|
52
|
-
${wtGradient('ââŠâââââŠââ⊠⊠⊠âŠââââââââ')}
|
|
53
|
-
${chalk.gray(' Git Worktree Manager')}
|
|
54
|
-
`;
|
|
55
|
-
console.log(logo);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function showMiniLogo() {
|
|
59
|
-
console.log(`\n ${icons.tree} ${wtGradient('worktree')} ${colors.muted(`v${version}`)}\n`);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function success(message) {
|
|
63
|
-
console.log(` ${colors.success(icons.check)} ${message}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function error(message) {
|
|
67
|
-
console.log(` ${colors.error(icons.cross)} ${message}`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function warning(message) {
|
|
71
|
-
console.log(` ${colors.warning(icons.warning)} ${message}`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function info(message) {
|
|
75
|
-
console.log(` ${colors.secondary(icons.info)} ${message}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function heading(text) {
|
|
79
|
-
console.log(`\n ${colors.primary.bold(text)}\n`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function subheading(text) {
|
|
83
|
-
console.log(` ${colors.muted(text)}`);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function listItem(text, indent = 2) {
|
|
87
|
-
const spaces = ' '.repeat(indent);
|
|
88
|
-
console.log(`${spaces}${colors.secondary(icons.bullet)} ${text}`);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function branchItem(name, isCurrent = false, isRemote = false) {
|
|
92
|
-
const icon = isRemote ? icons.remote : icons.local;
|
|
93
|
-
const prefix = isCurrent ? colors.success(icons.pointer) : ' ';
|
|
94
|
-
const branchName = isCurrent ? colors.success.bold(name) : colors.branch(name);
|
|
95
|
-
const typeLabel = isRemote ? colors.muted(' (remote)') : '';
|
|
96
|
-
console.log(` ${prefix} ${icon} ${branchName}${typeLabel}`);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function worktreeItem(name, path, isCurrent = false) {
|
|
100
|
-
const prefix = isCurrent ? colors.success(icons.pointer) : ' ';
|
|
101
|
-
const nameDisplay = isCurrent ? colors.success.bold(name) : colors.highlight(name);
|
|
102
|
-
console.log(` ${prefix} ${icons.folder} ${nameDisplay}`);
|
|
103
|
-
console.log(` ${colors.muted(path)}`);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function divider() {
|
|
107
|
-
console.log(colors.muted(' â'.repeat(20)));
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export function spacer() {
|
|
111
|
-
console.log('');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export function formatBranchChoice(branch, type = 'local') {
|
|
115
|
-
const icon = type === 'remote' ? icons.remote : icons.local;
|
|
116
|
-
const typeLabel = type === 'remote' ? chalk.dim(' (remote)') : '';
|
|
117
|
-
return `${icon} ${branch}${typeLabel}`;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function formatWorktreeChoice(wt) {
|
|
121
|
-
return `${icons.folder} ${colors.highlight(wt.name)} ${colors.muted(`â ${wt.branch}`)}`;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export function showHelp() {
|
|
125
|
-
showLogo();
|
|
126
|
-
|
|
127
|
-
console.log(colors.primary.bold(' Commands:\n'));
|
|
128
|
-
|
|
129
|
-
const commands = [
|
|
130
|
-
['wt', 'Interactive menu to manage worktrees'],
|
|
131
|
-
['wt new', 'Create a new worktree interactively'],
|
|
132
|
-
['wt list|ls', 'List all worktrees for current repo'],
|
|
133
|
-
['wt go [name]', 'Jump to a worktree (interactive if no name)'],
|
|
134
|
-
['wt merge', 'Merge a worktree branch into another branch'],
|
|
135
|
-
['wt remove|rm', 'Remove a worktree interactively'],
|
|
136
|
-
['wt home', 'Jump back to the main repository'],
|
|
137
|
-
['wt setup', 'Configure shell integration for auto-navigation'],
|
|
138
|
-
];
|
|
139
|
-
|
|
140
|
-
commands.forEach(([cmd, desc]) => {
|
|
141
|
-
console.log(` ${colors.secondary(cmd.padEnd(18))} ${colors.muted(desc)}`);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
spacer();
|
|
145
|
-
console.log(colors.muted(' Run any command without arguments for interactive mode'));
|
|
146
|
-
spacer();
|
|
147
|
-
}
|