cluttry 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/.vwt.json +12 -0
- package/LICENSE +21 -0
- package/README.md +444 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +198 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +90 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +11 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +106 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/open.d.ts +11 -0
- package/dist/commands/open.d.ts.map +1 -0
- package/dist/commands/open.js +52 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/prune.d.ts +7 -0
- package/dist/commands/prune.d.ts.map +1 -0
- package/dist/commands/prune.js +33 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/commands/rm.d.ts +13 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +99 -0
- package/dist/commands/rm.js.map +1 -0
- package/dist/commands/spawn.d.ts +17 -0
- package/dist/commands/spawn.d.ts.map +1 -0
- package/dist/commands/spawn.js +127 -0
- package/dist/commands/spawn.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +44 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +109 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/git.d.ts +73 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +225 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/output.d.ts +33 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +83 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/paths.d.ts +36 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +84 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/secrets.d.ts +50 -0
- package/dist/lib/secrets.d.ts.map +1 -0
- package/dist/lib/secrets.js +146 -0
- package/dist/lib/secrets.js.map +1 -0
- package/dist/lib/types.d.ts +63 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +5 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +41 -0
- package/src/commands/doctor.ts +222 -0
- package/src/commands/init.ts +120 -0
- package/src/commands/list.ts +133 -0
- package/src/commands/open.ts +70 -0
- package/src/commands/prune.ts +36 -0
- package/src/commands/rm.ts +125 -0
- package/src/commands/spawn.ts +169 -0
- package/src/index.ts +112 -0
- package/src/lib/config.ts +120 -0
- package/src/lib/git.ts +243 -0
- package/src/lib/output.ts +102 -0
- package/src/lib/paths.ts +108 -0
- package/src/lib/secrets.ts +193 -0
- package/src/lib/types.ts +69 -0
- package/tests/config.test.ts +102 -0
- package/tests/paths.test.ts +155 -0
- package/tests/secrets.test.ts +150 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +15 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;GAIG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* cry - Git worktrees made painless for vibecoders
|
|
4
|
+
*
|
|
5
|
+
* A CLI tool for managing git worktrees with parallel AI-agent sessions in mind.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { init } from './commands/init.js';
|
|
9
|
+
import { spawn } from './commands/spawn.js';
|
|
10
|
+
import { list } from './commands/list.js';
|
|
11
|
+
import { open } from './commands/open.js';
|
|
12
|
+
import { rm } from './commands/rm.js';
|
|
13
|
+
import { prune } from './commands/prune.js';
|
|
14
|
+
import { doctor } from './commands/doctor.js';
|
|
15
|
+
const program = new Command();
|
|
16
|
+
program
|
|
17
|
+
.name('cry')
|
|
18
|
+
.description('Git worktrees made painless for vibecoders running parallel AI-agent sessions')
|
|
19
|
+
.version('1.0.0');
|
|
20
|
+
// cry init
|
|
21
|
+
program
|
|
22
|
+
.command('init')
|
|
23
|
+
.description('Initialize cry configuration in the current repository')
|
|
24
|
+
.option('-f, --force', 'Overwrite existing configuration')
|
|
25
|
+
.action(async (options) => {
|
|
26
|
+
await init({ force: options.force });
|
|
27
|
+
});
|
|
28
|
+
// cry spawn <branch>
|
|
29
|
+
program
|
|
30
|
+
.command('spawn <branch>')
|
|
31
|
+
.description('Create a worktree for a branch')
|
|
32
|
+
.option('-n, --new', 'Create a new branch (equivalent to git worktree add -b)')
|
|
33
|
+
.option('-p, --path <dir>', 'Explicit path for the worktree')
|
|
34
|
+
.option('-b, --base <dir>', 'Base directory for worktrees')
|
|
35
|
+
.option('-m, --mode <mode>', 'Secret handling mode: copy, symlink, or none', 'copy')
|
|
36
|
+
.option('-r, --run <cmd>', 'Command to run after creating worktree')
|
|
37
|
+
.option('-a, --agent <agent>', 'Launch agent after setup: claude or none', 'none')
|
|
38
|
+
.action(async (branch, options) => {
|
|
39
|
+
const mode = options.mode;
|
|
40
|
+
if (!['copy', 'symlink', 'none'].includes(mode)) {
|
|
41
|
+
console.error(`Invalid mode: ${mode}. Must be 'copy', 'symlink', or 'none'.`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
await spawn(branch, {
|
|
45
|
+
new: options.new,
|
|
46
|
+
path: options.path,
|
|
47
|
+
base: options.base,
|
|
48
|
+
mode,
|
|
49
|
+
run: options.run,
|
|
50
|
+
agent: options.agent,
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
// cry list
|
|
54
|
+
program
|
|
55
|
+
.command('list')
|
|
56
|
+
.alias('ls')
|
|
57
|
+
.description('List all worktrees with their status')
|
|
58
|
+
.option('-j, --json', 'Output as JSON')
|
|
59
|
+
.action(async (options) => {
|
|
60
|
+
await list({ json: options.json });
|
|
61
|
+
});
|
|
62
|
+
// cry open <branch-or-path>
|
|
63
|
+
program
|
|
64
|
+
.command('open <branch-or-path>')
|
|
65
|
+
.description('Open or navigate to a worktree by branch name or path')
|
|
66
|
+
.option('-c, --cmd <cmd>', 'Command to execute in the worktree directory')
|
|
67
|
+
.action(async (branchOrPath, options) => {
|
|
68
|
+
await open(branchOrPath, { cmd: options.cmd });
|
|
69
|
+
});
|
|
70
|
+
// cry rm <branch-or-path>
|
|
71
|
+
program
|
|
72
|
+
.command('rm <branch-or-path>')
|
|
73
|
+
.alias('remove')
|
|
74
|
+
.description('Remove a worktree safely')
|
|
75
|
+
.option('-b, --with-branch', 'Also delete the branch')
|
|
76
|
+
.option('-f, --force', 'Force removal even if dirty')
|
|
77
|
+
.option('-y, --yes', 'Skip confirmation prompts')
|
|
78
|
+
.action(async (branchOrPath, options) => {
|
|
79
|
+
await rm(branchOrPath, {
|
|
80
|
+
withBranch: options.withBranch,
|
|
81
|
+
force: options.force,
|
|
82
|
+
yes: options.yes,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
// cry prune
|
|
86
|
+
program
|
|
87
|
+
.command('prune')
|
|
88
|
+
.description('Clean up stale worktree references')
|
|
89
|
+
.action(async () => {
|
|
90
|
+
await prune();
|
|
91
|
+
});
|
|
92
|
+
// cry doctor
|
|
93
|
+
program
|
|
94
|
+
.command('doctor')
|
|
95
|
+
.description('Check and diagnose cry configuration and setup')
|
|
96
|
+
.action(async () => {
|
|
97
|
+
await doctor();
|
|
98
|
+
});
|
|
99
|
+
// Parse and execute
|
|
100
|
+
program.parse();
|
|
101
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration management for VWT
|
|
3
|
+
*/
|
|
4
|
+
import type { MergedConfig, VwtConfig, VwtLocalConfig } from './types.js';
|
|
5
|
+
export declare const CONFIG_FILE = ".vwt.json";
|
|
6
|
+
export declare const LOCAL_CONFIG_FILE = ".vwt.local.json";
|
|
7
|
+
export declare const WORKTREE_INCLUDE_FILE = ".worktreeinclude";
|
|
8
|
+
/**
|
|
9
|
+
* Load the main config file
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadConfig(repoRoot: string): VwtConfig | null;
|
|
12
|
+
/**
|
|
13
|
+
* Load the local config file
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadLocalConfig(repoRoot: string): VwtLocalConfig | null;
|
|
16
|
+
/**
|
|
17
|
+
* Merge main config with local overrides
|
|
18
|
+
*/
|
|
19
|
+
export declare function mergeConfig(config: VwtConfig | null, localConfig: VwtLocalConfig | null): MergedConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Get merged configuration
|
|
22
|
+
*/
|
|
23
|
+
export declare function getMergedConfig(repoRoot: string): MergedConfig;
|
|
24
|
+
/**
|
|
25
|
+
* Save the main config file
|
|
26
|
+
*/
|
|
27
|
+
export declare function saveConfig(repoRoot: string, config: VwtConfig): void;
|
|
28
|
+
/**
|
|
29
|
+
* Save the local config file
|
|
30
|
+
*/
|
|
31
|
+
export declare function saveLocalConfig(repoRoot: string, config: VwtLocalConfig): void;
|
|
32
|
+
/**
|
|
33
|
+
* Check if config exists
|
|
34
|
+
*/
|
|
35
|
+
export declare function configExists(repoRoot: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Get default config
|
|
38
|
+
*/
|
|
39
|
+
export declare function getDefaultConfig(): VwtConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Create default local config
|
|
42
|
+
*/
|
|
43
|
+
export declare function getDefaultLocalConfig(): VwtLocalConfig;
|
|
44
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1E,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AACnD,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAWxD;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAW7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAWvE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,WAAW,EAAE,cAAc,GAAG,IAAI,GAAG,YAAY,CAetG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAI9D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAGpE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAG9E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,SAAS,CAE5C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,CAItD"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration management for VWT
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
export const CONFIG_FILE = '.vwt.json';
|
|
7
|
+
export const LOCAL_CONFIG_FILE = '.vwt.local.json';
|
|
8
|
+
export const WORKTREE_INCLUDE_FILE = '.worktreeinclude';
|
|
9
|
+
const DEFAULT_CONFIG = {
|
|
10
|
+
defaultMode: 'copy',
|
|
11
|
+
include: ['.env', '.env.*', '.env.local'],
|
|
12
|
+
hooks: {
|
|
13
|
+
postCreate: [],
|
|
14
|
+
},
|
|
15
|
+
agentCommand: 'claude',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Load the main config file
|
|
19
|
+
*/
|
|
20
|
+
export function loadConfig(repoRoot) {
|
|
21
|
+
const configPath = path.join(repoRoot, CONFIG_FILE);
|
|
22
|
+
if (!existsSync(configPath)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
27
|
+
return JSON.parse(content);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throw new Error(`Failed to parse ${CONFIG_FILE}: ${error.message}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Load the local config file
|
|
35
|
+
*/
|
|
36
|
+
export function loadLocalConfig(repoRoot) {
|
|
37
|
+
const configPath = path.join(repoRoot, LOCAL_CONFIG_FILE);
|
|
38
|
+
if (!existsSync(configPath)) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
43
|
+
return JSON.parse(content);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
throw new Error(`Failed to parse ${LOCAL_CONFIG_FILE}: ${error.message}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Merge main config with local overrides
|
|
51
|
+
*/
|
|
52
|
+
export function mergeConfig(config, localConfig) {
|
|
53
|
+
const base = config ?? DEFAULT_CONFIG;
|
|
54
|
+
return {
|
|
55
|
+
worktreeBaseDir: localConfig?.worktreeBaseDir ?? base.worktreeBaseDir,
|
|
56
|
+
defaultMode: base.defaultMode,
|
|
57
|
+
include: [...(base.include ?? []), ...(localConfig?.include ?? [])],
|
|
58
|
+
hooks: {
|
|
59
|
+
postCreate: [
|
|
60
|
+
...(base.hooks?.postCreate ?? []),
|
|
61
|
+
...(localConfig?.hooks?.postCreate ?? []),
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
agentCommand: localConfig?.agentCommand ?? base.agentCommand ?? 'claude',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get merged configuration
|
|
69
|
+
*/
|
|
70
|
+
export function getMergedConfig(repoRoot) {
|
|
71
|
+
const config = loadConfig(repoRoot);
|
|
72
|
+
const localConfig = loadLocalConfig(repoRoot);
|
|
73
|
+
return mergeConfig(config, localConfig);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Save the main config file
|
|
77
|
+
*/
|
|
78
|
+
export function saveConfig(repoRoot, config) {
|
|
79
|
+
const configPath = path.join(repoRoot, CONFIG_FILE);
|
|
80
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Save the local config file
|
|
84
|
+
*/
|
|
85
|
+
export function saveLocalConfig(repoRoot, config) {
|
|
86
|
+
const configPath = path.join(repoRoot, LOCAL_CONFIG_FILE);
|
|
87
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check if config exists
|
|
91
|
+
*/
|
|
92
|
+
export function configExists(repoRoot) {
|
|
93
|
+
return existsSync(path.join(repoRoot, CONFIG_FILE));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get default config
|
|
97
|
+
*/
|
|
98
|
+
export function getDefaultConfig() {
|
|
99
|
+
return { ...DEFAULT_CONFIG };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create default local config
|
|
103
|
+
*/
|
|
104
|
+
export function getDefaultLocalConfig() {
|
|
105
|
+
return {
|
|
106
|
+
include: [],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git operations for VWT
|
|
3
|
+
*/
|
|
4
|
+
import type { WorktreeInfo } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Execute a git command and return stdout
|
|
7
|
+
*/
|
|
8
|
+
export declare function git(args: string[], cwd?: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Check if we're in a git repository
|
|
11
|
+
*/
|
|
12
|
+
export declare function isGitRepo(cwd?: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Get the root directory of the git repository
|
|
15
|
+
*/
|
|
16
|
+
export declare function getRepoRoot(cwd?: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Get the repository name from the root path
|
|
19
|
+
*/
|
|
20
|
+
export declare function getRepoName(cwd?: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a branch exists
|
|
23
|
+
*/
|
|
24
|
+
export declare function branchExists(branch: string, cwd?: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Get the current branch name
|
|
27
|
+
*/
|
|
28
|
+
export declare function getCurrentBranch(cwd?: string): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Check if a file is tracked by git
|
|
31
|
+
*/
|
|
32
|
+
export declare function isTracked(filePath: string, cwd?: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Check if a file is ignored by git
|
|
35
|
+
*/
|
|
36
|
+
export declare function isIgnored(filePath: string, cwd?: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* List all worktrees using porcelain format
|
|
39
|
+
*/
|
|
40
|
+
export declare function listWorktrees(cwd?: string): WorktreeInfo[];
|
|
41
|
+
/**
|
|
42
|
+
* Add a worktree
|
|
43
|
+
*/
|
|
44
|
+
export declare function addWorktree(targetPath: string, branch: string, createBranch: boolean, cwd?: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Remove a worktree
|
|
47
|
+
*/
|
|
48
|
+
export declare function removeWorktree(worktreePath: string, force: boolean, cwd?: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Prune worktrees
|
|
51
|
+
*/
|
|
52
|
+
export declare function pruneWorktrees(cwd?: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Delete a branch
|
|
55
|
+
*/
|
|
56
|
+
export declare function deleteBranch(branch: string, force: boolean, cwd?: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a worktree is dirty (has uncommitted changes)
|
|
59
|
+
*/
|
|
60
|
+
export declare function isWorktreeDirty(worktreePath: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Get short HEAD SHA for a worktree
|
|
63
|
+
*/
|
|
64
|
+
export declare function getShortHead(worktreePath: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Run a command in a directory
|
|
67
|
+
*/
|
|
68
|
+
export declare function runCommand(command: string, cwd: string): Promise<number>;
|
|
69
|
+
/**
|
|
70
|
+
* Check if a command exists
|
|
71
|
+
*/
|
|
72
|
+
export declare function commandExists(cmd: string): boolean;
|
|
73
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CASxD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOlE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOjE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOjE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAiC1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,OAAO,EACrB,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAUN;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAOvF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAG/E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAO7D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAMzD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBxE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CASlD"}
|
package/dist/lib/git.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git operations for VWT
|
|
3
|
+
*/
|
|
4
|
+
import { execSync, spawn } from 'node:child_process';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
/**
|
|
7
|
+
* Execute a git command and return stdout
|
|
8
|
+
*/
|
|
9
|
+
export function git(args, cwd) {
|
|
10
|
+
const options = cwd ? { cwd, encoding: 'utf-8' } : { encoding: 'utf-8' };
|
|
11
|
+
try {
|
|
12
|
+
return execSync(`git ${args.join(' ')}`, { ...options, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
const execError = error;
|
|
16
|
+
const stderr = execError.stderr?.toString?.() || execError.message || 'Unknown git error';
|
|
17
|
+
throw new Error(stderr.trim());
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Check if we're in a git repository
|
|
22
|
+
*/
|
|
23
|
+
export function isGitRepo(cwd) {
|
|
24
|
+
try {
|
|
25
|
+
git(['rev-parse', '--git-dir'], cwd);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the root directory of the git repository
|
|
34
|
+
*/
|
|
35
|
+
export function getRepoRoot(cwd) {
|
|
36
|
+
return git(['rev-parse', '--show-toplevel'], cwd);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the repository name from the root path
|
|
40
|
+
*/
|
|
41
|
+
export function getRepoName(cwd) {
|
|
42
|
+
const root = getRepoRoot(cwd);
|
|
43
|
+
return path.basename(root);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if a branch exists
|
|
47
|
+
*/
|
|
48
|
+
export function branchExists(branch, cwd) {
|
|
49
|
+
try {
|
|
50
|
+
git(['rev-parse', '--verify', `refs/heads/${branch}`], cwd);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the current branch name
|
|
59
|
+
*/
|
|
60
|
+
export function getCurrentBranch(cwd) {
|
|
61
|
+
try {
|
|
62
|
+
return git(['rev-parse', '--abbrev-ref', 'HEAD'], cwd);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check if a file is tracked by git
|
|
70
|
+
*/
|
|
71
|
+
export function isTracked(filePath, cwd) {
|
|
72
|
+
try {
|
|
73
|
+
git(['ls-files', '--error-unmatch', filePath], cwd);
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if a file is ignored by git
|
|
82
|
+
*/
|
|
83
|
+
export function isIgnored(filePath, cwd) {
|
|
84
|
+
try {
|
|
85
|
+
git(['check-ignore', '-q', filePath], cwd);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* List all worktrees using porcelain format
|
|
94
|
+
*/
|
|
95
|
+
export function listWorktrees(cwd) {
|
|
96
|
+
const output = git(['worktree', 'list', '--porcelain'], cwd);
|
|
97
|
+
const worktrees = [];
|
|
98
|
+
let current = {};
|
|
99
|
+
for (const line of output.split('\n')) {
|
|
100
|
+
if (line === '') {
|
|
101
|
+
if (current.worktree) {
|
|
102
|
+
worktrees.push(current);
|
|
103
|
+
}
|
|
104
|
+
current = {};
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (line.startsWith('worktree ')) {
|
|
108
|
+
current.worktree = line.substring(9);
|
|
109
|
+
}
|
|
110
|
+
else if (line.startsWith('HEAD ')) {
|
|
111
|
+
current.head = line.substring(5);
|
|
112
|
+
}
|
|
113
|
+
else if (line.startsWith('branch ')) {
|
|
114
|
+
current.branch = line.substring(7).replace('refs/heads/', '');
|
|
115
|
+
}
|
|
116
|
+
else if (line === 'bare') {
|
|
117
|
+
current.bare = true;
|
|
118
|
+
}
|
|
119
|
+
else if (line === 'detached') {
|
|
120
|
+
current.detached = true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Don't forget the last entry
|
|
124
|
+
if (current.worktree) {
|
|
125
|
+
worktrees.push(current);
|
|
126
|
+
}
|
|
127
|
+
return worktrees;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Add a worktree
|
|
131
|
+
*/
|
|
132
|
+
export function addWorktree(targetPath, branch, createBranch, cwd) {
|
|
133
|
+
const args = ['worktree', 'add'];
|
|
134
|
+
if (createBranch) {
|
|
135
|
+
args.push('-b', branch);
|
|
136
|
+
}
|
|
137
|
+
args.push(targetPath);
|
|
138
|
+
if (!createBranch) {
|
|
139
|
+
args.push(branch);
|
|
140
|
+
}
|
|
141
|
+
git(args, cwd);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Remove a worktree
|
|
145
|
+
*/
|
|
146
|
+
export function removeWorktree(worktreePath, force, cwd) {
|
|
147
|
+
const args = ['worktree', 'remove'];
|
|
148
|
+
if (force) {
|
|
149
|
+
args.push('--force');
|
|
150
|
+
}
|
|
151
|
+
args.push(worktreePath);
|
|
152
|
+
git(args, cwd);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Prune worktrees
|
|
156
|
+
*/
|
|
157
|
+
export function pruneWorktrees(cwd) {
|
|
158
|
+
return git(['worktree', 'prune', '--verbose'], cwd);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Delete a branch
|
|
162
|
+
*/
|
|
163
|
+
export function deleteBranch(branch, force, cwd) {
|
|
164
|
+
const flag = force ? '-D' : '-d';
|
|
165
|
+
git(['branch', flag, branch], cwd);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check if a worktree is dirty (has uncommitted changes)
|
|
169
|
+
*/
|
|
170
|
+
export function isWorktreeDirty(worktreePath) {
|
|
171
|
+
try {
|
|
172
|
+
const status = git(['status', '--porcelain'], worktreePath);
|
|
173
|
+
return status.length > 0;
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get short HEAD SHA for a worktree
|
|
181
|
+
*/
|
|
182
|
+
export function getShortHead(worktreePath) {
|
|
183
|
+
try {
|
|
184
|
+
return git(['rev-parse', '--short', 'HEAD'], worktreePath);
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return 'unknown';
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Run a command in a directory
|
|
192
|
+
*/
|
|
193
|
+
export function runCommand(command, cwd) {
|
|
194
|
+
return new Promise((resolve) => {
|
|
195
|
+
const isWindows = process.platform === 'win32';
|
|
196
|
+
const shell = isWindows ? 'cmd.exe' : '/bin/sh';
|
|
197
|
+
const shellArgs = isWindows ? ['/c', command] : ['-c', command];
|
|
198
|
+
const child = spawn(shell, shellArgs, {
|
|
199
|
+
cwd,
|
|
200
|
+
stdio: 'inherit',
|
|
201
|
+
env: process.env,
|
|
202
|
+
});
|
|
203
|
+
child.on('close', (code) => {
|
|
204
|
+
resolve(code ?? 1);
|
|
205
|
+
});
|
|
206
|
+
child.on('error', () => {
|
|
207
|
+
resolve(1);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Check if a command exists
|
|
213
|
+
*/
|
|
214
|
+
export function commandExists(cmd) {
|
|
215
|
+
try {
|
|
216
|
+
const isWindows = process.platform === 'win32';
|
|
217
|
+
const checkCmd = isWindows ? `where ${cmd}` : `which ${cmd}`;
|
|
218
|
+
execSync(checkCmd, { stdio: 'pipe' });
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output utilities for VWT
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent, colorful terminal output without external dependencies.
|
|
5
|
+
*/
|
|
6
|
+
export declare const fmt: {
|
|
7
|
+
bold: (text: string) => string;
|
|
8
|
+
dim: (text: string) => string;
|
|
9
|
+
red: (text: string) => string;
|
|
10
|
+
green: (text: string) => string;
|
|
11
|
+
yellow: (text: string) => string;
|
|
12
|
+
blue: (text: string) => string;
|
|
13
|
+
magenta: (text: string) => string;
|
|
14
|
+
cyan: (text: string) => string;
|
|
15
|
+
gray: (text: string) => string;
|
|
16
|
+
success: (text: string) => string;
|
|
17
|
+
error: (text: string) => string;
|
|
18
|
+
warn: (text: string) => string;
|
|
19
|
+
info: (text: string) => string;
|
|
20
|
+
path: (text: string) => string;
|
|
21
|
+
branch: (text: string) => string;
|
|
22
|
+
};
|
|
23
|
+
export declare function log(message: string): void;
|
|
24
|
+
export declare function success(message: string): void;
|
|
25
|
+
export declare function error(message: string): void;
|
|
26
|
+
export declare function warn(message: string): void;
|
|
27
|
+
export declare function info(message: string): void;
|
|
28
|
+
export declare function header(message: string): void;
|
|
29
|
+
export declare function list(items: string[], prefix?: string): void;
|
|
30
|
+
export declare function table(rows: string[][], columnWidths?: number[]): void;
|
|
31
|
+
export declare function json(data: unknown): void;
|
|
32
|
+
export declare function newline(): void;
|
|
33
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,eAAO,MAAM,GAAG;iBACD,MAAM;gBACP,MAAM;gBACN,MAAM;kBACJ,MAAM;mBACL,MAAM;iBACR,MAAM;oBACH,MAAM;iBACT,MAAM;iBACN,MAAM;oBAEH,MAAM;kBACR,MAAM;iBACP,MAAM;iBACN,MAAM;iBACN,MAAM;mBACJ,MAAM;CACtB,CAAC;AAEF,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,SAAO,GAAG,IAAI,CAIzD;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAcrE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAExC;AAED,wBAAgB,OAAO,IAAI,IAAI,CAE9B"}
|