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.
Files changed (79) hide show
  1. package/.vwt.json +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +444 -0
  4. package/dist/commands/doctor.d.ts +7 -0
  5. package/dist/commands/doctor.d.ts.map +1 -0
  6. package/dist/commands/doctor.js +198 -0
  7. package/dist/commands/doctor.js.map +1 -0
  8. package/dist/commands/init.d.ts +11 -0
  9. package/dist/commands/init.d.ts.map +1 -0
  10. package/dist/commands/init.js +90 -0
  11. package/dist/commands/init.js.map +1 -0
  12. package/dist/commands/list.d.ts +11 -0
  13. package/dist/commands/list.d.ts.map +1 -0
  14. package/dist/commands/list.js +106 -0
  15. package/dist/commands/list.js.map +1 -0
  16. package/dist/commands/open.d.ts +11 -0
  17. package/dist/commands/open.d.ts.map +1 -0
  18. package/dist/commands/open.js +52 -0
  19. package/dist/commands/open.js.map +1 -0
  20. package/dist/commands/prune.d.ts +7 -0
  21. package/dist/commands/prune.d.ts.map +1 -0
  22. package/dist/commands/prune.js +33 -0
  23. package/dist/commands/prune.js.map +1 -0
  24. package/dist/commands/rm.d.ts +13 -0
  25. package/dist/commands/rm.d.ts.map +1 -0
  26. package/dist/commands/rm.js +99 -0
  27. package/dist/commands/rm.js.map +1 -0
  28. package/dist/commands/spawn.d.ts +17 -0
  29. package/dist/commands/spawn.d.ts.map +1 -0
  30. package/dist/commands/spawn.js +127 -0
  31. package/dist/commands/spawn.js.map +1 -0
  32. package/dist/index.d.ts +8 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +101 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/lib/config.d.ts +44 -0
  37. package/dist/lib/config.d.ts.map +1 -0
  38. package/dist/lib/config.js +109 -0
  39. package/dist/lib/config.js.map +1 -0
  40. package/dist/lib/git.d.ts +73 -0
  41. package/dist/lib/git.d.ts.map +1 -0
  42. package/dist/lib/git.js +225 -0
  43. package/dist/lib/git.js.map +1 -0
  44. package/dist/lib/output.d.ts +33 -0
  45. package/dist/lib/output.d.ts.map +1 -0
  46. package/dist/lib/output.js +83 -0
  47. package/dist/lib/output.js.map +1 -0
  48. package/dist/lib/paths.d.ts +36 -0
  49. package/dist/lib/paths.d.ts.map +1 -0
  50. package/dist/lib/paths.js +84 -0
  51. package/dist/lib/paths.js.map +1 -0
  52. package/dist/lib/secrets.d.ts +50 -0
  53. package/dist/lib/secrets.d.ts.map +1 -0
  54. package/dist/lib/secrets.js +146 -0
  55. package/dist/lib/secrets.js.map +1 -0
  56. package/dist/lib/types.d.ts +63 -0
  57. package/dist/lib/types.d.ts.map +1 -0
  58. package/dist/lib/types.js +5 -0
  59. package/dist/lib/types.js.map +1 -0
  60. package/package.json +41 -0
  61. package/src/commands/doctor.ts +222 -0
  62. package/src/commands/init.ts +120 -0
  63. package/src/commands/list.ts +133 -0
  64. package/src/commands/open.ts +70 -0
  65. package/src/commands/prune.ts +36 -0
  66. package/src/commands/rm.ts +125 -0
  67. package/src/commands/spawn.ts +169 -0
  68. package/src/index.ts +112 -0
  69. package/src/lib/config.ts +120 -0
  70. package/src/lib/git.ts +243 -0
  71. package/src/lib/output.ts +102 -0
  72. package/src/lib/paths.ts +108 -0
  73. package/src/lib/secrets.ts +193 -0
  74. package/src/lib/types.ts +69 -0
  75. package/tests/config.test.ts +102 -0
  76. package/tests/paths.test.ts +155 -0
  77. package/tests/secrets.test.ts +150 -0
  78. package/tsconfig.json +20 -0
  79. package/vitest.config.ts +15 -0
@@ -0,0 +1,8 @@
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
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -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"}