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 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA+BD,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiE9D"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * cry init command
3
+ *
4
+ * Create or update repo-level config files for cry.
5
+ */
6
+ import { existsSync, readFileSync, appendFileSync } from 'node:fs';
7
+ import path from 'node:path';
8
+ import { isGitRepo, getRepoRoot } from '../lib/git.js';
9
+ import { CONFIG_FILE, LOCAL_CONFIG_FILE, configExists, getDefaultConfig, getDefaultLocalConfig, saveConfig, saveLocalConfig, loadConfig, } from '../lib/config.js';
10
+ import * as out from '../lib/output.js';
11
+ /**
12
+ * Ensure entries exist in .gitignore
13
+ */
14
+ function ensureGitignoreEntries(repoRoot, entries) {
15
+ const gitignorePath = path.join(repoRoot, '.gitignore');
16
+ let content = '';
17
+ if (existsSync(gitignorePath)) {
18
+ content = readFileSync(gitignorePath, 'utf-8');
19
+ }
20
+ const lines = content.split('\n').map((l) => l.trim());
21
+ const added = [];
22
+ for (const entry of entries) {
23
+ if (!lines.includes(entry)) {
24
+ added.push(entry);
25
+ }
26
+ }
27
+ if (added.length > 0) {
28
+ const suffix = content.endsWith('\n') || content === '' ? '' : '\n';
29
+ const header = content === '' ? '' : '\n# cry\n';
30
+ appendFileSync(gitignorePath, suffix + header + added.join('\n') + '\n');
31
+ }
32
+ return added;
33
+ }
34
+ export async function init(options) {
35
+ // Check if we're in a git repo
36
+ if (!isGitRepo()) {
37
+ out.error('Not a git repository. Run this command from within a git repo.');
38
+ process.exit(1);
39
+ }
40
+ const repoRoot = getRepoRoot();
41
+ const changes = [];
42
+ // Check if config already exists
43
+ if (configExists(repoRoot) && !options.force) {
44
+ out.info(`${CONFIG_FILE} already exists. Use --force to overwrite.`);
45
+ const existing = loadConfig(repoRoot);
46
+ if (existing) {
47
+ out.log('\nCurrent configuration:');
48
+ out.log(JSON.stringify(existing, null, 2));
49
+ }
50
+ return;
51
+ }
52
+ // Create main config
53
+ const config = getDefaultConfig();
54
+ saveConfig(repoRoot, config);
55
+ changes.push(`Created ${out.fmt.path(CONFIG_FILE)}`);
56
+ // Create local config if it doesn't exist
57
+ const localConfigPath = path.join(repoRoot, LOCAL_CONFIG_FILE);
58
+ if (!existsSync(localConfigPath)) {
59
+ const localConfig = getDefaultLocalConfig();
60
+ saveLocalConfig(repoRoot, localConfig);
61
+ changes.push(`Created ${out.fmt.path(LOCAL_CONFIG_FILE)} (gitignored)`);
62
+ }
63
+ // Ensure .gitignore entries
64
+ const gitignoreEntries = [
65
+ LOCAL_CONFIG_FILE,
66
+ '.worktrees/',
67
+ '.worktreeinclude',
68
+ ];
69
+ const addedEntries = ensureGitignoreEntries(repoRoot, gitignoreEntries);
70
+ if (addedEntries.length > 0) {
71
+ changes.push(`Added to .gitignore: ${addedEntries.join(', ')}`);
72
+ }
73
+ // Output summary
74
+ out.header('cry Initialized');
75
+ out.newline();
76
+ for (const change of changes) {
77
+ out.success(change);
78
+ }
79
+ out.newline();
80
+ out.log('Configuration created with defaults:');
81
+ out.log(` • Default mode: ${out.fmt.cyan(config.defaultMode)}`);
82
+ out.log(` • Include patterns: ${config.include.map((p) => out.fmt.gray(p)).join(', ')}`);
83
+ out.log(` • Agent command: ${out.fmt.cyan(config.agentCommand ?? 'claude')}`);
84
+ out.newline();
85
+ out.log('Next steps:');
86
+ out.log(` 1. Edit ${out.fmt.path(CONFIG_FILE)} to customize patterns`);
87
+ out.log(` 2. Run ${out.fmt.cyan('cry spawn <branch>')} to create a worktree`);
88
+ out.log(` 3. Run ${out.fmt.cyan('cry doctor')} to verify your setup`);
89
+ }
90
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * cry list command
3
+ *
4
+ * List all worktrees with their status.
5
+ */
6
+ interface ListOptions {
7
+ json?: boolean;
8
+ }
9
+ export declare function list(options: ListOptions): Promise<void>;
10
+ export {};
11
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA2BD,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAsF9D"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * cry list command
3
+ *
4
+ * List all worktrees with their status.
5
+ */
6
+ import { statSync } from 'node:fs';
7
+ import { isGitRepo, getRepoRoot, listWorktrees, isWorktreeDirty, getShortHead, } from '../lib/git.js';
8
+ import * as out from '../lib/output.js';
9
+ function getLastModified(worktreePath) {
10
+ try {
11
+ const stats = statSync(worktreePath);
12
+ return stats.mtime;
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ function formatRelativeTime(date) {
19
+ if (!date)
20
+ return 'unknown';
21
+ const now = new Date();
22
+ const diffMs = now.getTime() - date.getTime();
23
+ const diffMins = Math.floor(diffMs / 60000);
24
+ const diffHours = Math.floor(diffMs / 3600000);
25
+ const diffDays = Math.floor(diffMs / 86400000);
26
+ if (diffMins < 1)
27
+ return 'just now';
28
+ if (diffMins < 60)
29
+ return `${diffMins}m ago`;
30
+ if (diffHours < 24)
31
+ return `${diffHours}h ago`;
32
+ if (diffDays < 7)
33
+ return `${diffDays}d ago`;
34
+ return date.toLocaleDateString();
35
+ }
36
+ export async function list(options) {
37
+ // Check if we're in a git repo
38
+ if (!isGitRepo()) {
39
+ out.error('Not a git repository. Run this command from within a git repo.');
40
+ process.exit(1);
41
+ }
42
+ const repoRoot = getRepoRoot();
43
+ const worktrees = listWorktrees(repoRoot);
44
+ // Build list items with extra info
45
+ const items = worktrees.map((wt) => ({
46
+ branch: wt.branch ?? (wt.detached ? '(detached)' : null),
47
+ path: wt.worktree,
48
+ headShort: getShortHead(wt.worktree),
49
+ dirty: isWorktreeDirty(wt.worktree),
50
+ lastModified: getLastModified(wt.worktree),
51
+ }));
52
+ // JSON output
53
+ if (options.json) {
54
+ const jsonItems = items.map((item) => ({
55
+ ...item,
56
+ lastModified: item.lastModified?.toISOString() ?? null,
57
+ }));
58
+ out.json(jsonItems);
59
+ return;
60
+ }
61
+ // No worktrees
62
+ if (items.length === 0) {
63
+ out.info('No worktrees found.');
64
+ return;
65
+ }
66
+ // Table output
67
+ out.header('Worktrees');
68
+ out.newline();
69
+ // Calculate column widths
70
+ const branchWidth = Math.max(6, ...items.map((i) => (i.branch ?? '').length));
71
+ const pathWidth = Math.max(4, ...items.map((i) => i.path.length));
72
+ // Header row
73
+ out.log(' ' +
74
+ out.fmt.bold('Branch'.padEnd(branchWidth)) +
75
+ ' ' +
76
+ out.fmt.bold('SHA'.padEnd(7)) +
77
+ ' ' +
78
+ out.fmt.bold('Status'.padEnd(8)) +
79
+ ' ' +
80
+ out.fmt.bold('Modified'.padEnd(12)) +
81
+ ' ' +
82
+ out.fmt.bold('Path'));
83
+ out.log(' ' + '─'.repeat(branchWidth + 7 + 8 + 12 + pathWidth + 12));
84
+ // Data rows
85
+ for (const item of items) {
86
+ const branch = (item.branch ?? '(none)').padEnd(branchWidth);
87
+ const sha = item.headShort.padEnd(7);
88
+ const status = item.dirty
89
+ ? out.fmt.yellow('dirty'.padEnd(8))
90
+ : out.fmt.green('clean'.padEnd(8));
91
+ const modified = formatRelativeTime(item.lastModified).padEnd(12);
92
+ out.log(' ' +
93
+ out.fmt.branch(branch) +
94
+ ' ' +
95
+ out.fmt.dim(sha) +
96
+ ' ' +
97
+ status +
98
+ ' ' +
99
+ out.fmt.dim(modified) +
100
+ ' ' +
101
+ out.fmt.path(item.path));
102
+ }
103
+ out.newline();
104
+ out.log(` ${out.fmt.dim(`${items.length} worktree(s)`)}`);
105
+ }
106
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * cry open command
3
+ *
4
+ * Open or navigate to a worktree by branch name or path.
5
+ */
6
+ interface OpenOptions {
7
+ cmd?: string;
8
+ }
9
+ export declare function open(branchOrPath: string, options: OpenOptions): Promise<void>;
10
+ export {};
11
+ //# sourceMappingURL=open.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDpF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * cry open command
3
+ *
4
+ * Open or navigate to a worktree by branch name or path.
5
+ */
6
+ import { isGitRepo, getRepoRoot, listWorktrees, runCommand, } from '../lib/git.js';
7
+ import { resolveBranchOrPath } from '../lib/paths.js';
8
+ import * as out from '../lib/output.js';
9
+ export async function open(branchOrPath, options) {
10
+ // Check if we're in a git repo
11
+ if (!isGitRepo()) {
12
+ out.error('Not a git repository. Run this command from within a git repo.');
13
+ process.exit(1);
14
+ }
15
+ const repoRoot = getRepoRoot();
16
+ const worktrees = listWorktrees(repoRoot);
17
+ // Build lookup list
18
+ const wtList = worktrees.map((wt) => ({
19
+ branch: wt.branch ?? null,
20
+ path: wt.worktree,
21
+ }));
22
+ // Resolve the worktree
23
+ const resolved = resolveBranchOrPath(branchOrPath, wtList, repoRoot);
24
+ if (!resolved) {
25
+ out.error(`Worktree not found: ${branchOrPath}`);
26
+ out.info('Available worktrees:');
27
+ for (const wt of wtList) {
28
+ out.log(` • ${wt.branch ?? '(detached)'} → ${wt.path}`);
29
+ }
30
+ process.exit(1);
31
+ }
32
+ const { path: wtPath, branch } = resolved;
33
+ // If --cmd is provided, run it
34
+ if (options.cmd) {
35
+ out.log(`Running in ${out.fmt.path(wtPath)}:`);
36
+ out.log(` ${out.fmt.dim('$')} ${options.cmd}`);
37
+ const code = await runCommand(options.cmd, wtPath);
38
+ process.exit(code);
39
+ }
40
+ // Otherwise, print the path and helper
41
+ out.success(`Found worktree: ${branch ? out.fmt.branch(branch) : '(detached)'}`);
42
+ out.newline();
43
+ out.log(`Path: ${out.fmt.path(wtPath)}`);
44
+ out.newline();
45
+ out.log('To navigate there:');
46
+ out.log(` ${out.fmt.cyan(`cd "${wtPath}"`)}`);
47
+ // For shell integration hint
48
+ out.newline();
49
+ out.log(out.fmt.dim('Tip: Use command substitution in your shell:'));
50
+ out.log(out.fmt.dim(` cd "$(vwt open ${branchOrPath} 2>/dev/null | grep "^Path:" | cut -d' ' -f2-)"`));
51
+ }
52
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * cry prune command
3
+ *
4
+ * Clean up stale worktree references.
5
+ */
6
+ export declare function prune(): Promise<void>;
7
+ //# sourceMappingURL=prune.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prune.d.ts","sourceRoot":"","sources":["../../src/commands/prune.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA0B3C"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * cry prune command
3
+ *
4
+ * Clean up stale worktree references.
5
+ */
6
+ import { isGitRepo, getRepoRoot, pruneWorktrees } from '../lib/git.js';
7
+ import * as out from '../lib/output.js';
8
+ export async function prune() {
9
+ // Check if we're in a git repo
10
+ if (!isGitRepo()) {
11
+ out.error('Not a git repository. Run this command from within a git repo.');
12
+ process.exit(1);
13
+ }
14
+ const repoRoot = getRepoRoot();
15
+ out.log('Pruning stale worktree references...');
16
+ out.newline();
17
+ try {
18
+ const output = pruneWorktrees(repoRoot);
19
+ if (output.trim()) {
20
+ out.log(output);
21
+ out.newline();
22
+ out.success('Pruned stale worktree references');
23
+ }
24
+ else {
25
+ out.success('No stale worktree references found');
26
+ }
27
+ }
28
+ catch (error) {
29
+ out.error(`Failed to prune: ${error.message}`);
30
+ process.exit(1);
31
+ }
32
+ }
33
+ //# sourceMappingURL=prune.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prune.js","sourceRoot":"","sources":["../../src/commands/prune.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,+BAA+B;IAC/B,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACjB,GAAG,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,GAAG,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IAChD,GAAG,CAAC,OAAO,EAAE,CAAC;IAEd,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QAExC,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAClB,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChB,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,GAAG,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,oBAAqB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * cry rm command
3
+ *
4
+ * Remove a worktree safely with optional branch deletion.
5
+ */
6
+ interface RmOptions {
7
+ withBranch?: boolean;
8
+ force?: boolean;
9
+ yes?: boolean;
10
+ }
11
+ export declare function rm(branchOrPath: string, options: RmOptions): Promise<void>;
12
+ export {};
13
+ //# sourceMappingURL=rm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rm.d.ts","sourceRoot":"","sources":["../../src/commands/rm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,UAAU,SAAS;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAgBD,wBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFhF"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * cry rm command
3
+ *
4
+ * Remove a worktree safely with optional branch deletion.
5
+ */
6
+ import { createInterface } from 'node:readline';
7
+ import { isGitRepo, getRepoRoot, listWorktrees, removeWorktree, deleteBranch, isWorktreeDirty, getCurrentBranch, } from '../lib/git.js';
8
+ import { resolveBranchOrPath } from '../lib/paths.js';
9
+ import * as out from '../lib/output.js';
10
+ async function confirm(message) {
11
+ const rl = createInterface({
12
+ input: process.stdin,
13
+ output: process.stdout,
14
+ });
15
+ return new Promise((resolve) => {
16
+ rl.question(`${message} [y/N] `, (answer) => {
17
+ rl.close();
18
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
19
+ });
20
+ });
21
+ }
22
+ export async function rm(branchOrPath, options) {
23
+ // Check if we're in a git repo
24
+ if (!isGitRepo()) {
25
+ out.error('Not a git repository. Run this command from within a git repo.');
26
+ process.exit(1);
27
+ }
28
+ const repoRoot = getRepoRoot();
29
+ const worktrees = listWorktrees(repoRoot);
30
+ // Build lookup list
31
+ const wtList = worktrees.map((wt) => ({
32
+ branch: wt.branch ?? null,
33
+ path: wt.worktree,
34
+ }));
35
+ // Resolve the worktree
36
+ const resolved = resolveBranchOrPath(branchOrPath, wtList, repoRoot);
37
+ if (!resolved) {
38
+ out.error(`Worktree not found: ${branchOrPath}`);
39
+ out.info('Available worktrees:');
40
+ for (const wt of wtList) {
41
+ out.log(` • ${wt.branch ?? '(detached)'} → ${wt.path}`);
42
+ }
43
+ process.exit(1);
44
+ }
45
+ const { path: wtPath, branch } = resolved;
46
+ // Check if it's the main worktree (the original checkout)
47
+ if (wtPath === repoRoot) {
48
+ out.error('Cannot remove the main worktree.');
49
+ out.info('This is your primary repository checkout.');
50
+ process.exit(1);
51
+ }
52
+ // Check if dirty
53
+ const dirty = isWorktreeDirty(wtPath);
54
+ if (dirty && !options.force) {
55
+ out.error('Worktree has uncommitted changes.');
56
+ out.info('Use --force to remove anyway (changes will be lost).');
57
+ process.exit(1);
58
+ }
59
+ // Warn and confirm if dirty and force
60
+ if (dirty && options.force && !options.yes) {
61
+ out.warn('Worktree has uncommitted changes that will be lost!');
62
+ const confirmed = await confirm('Are you sure you want to remove it?');
63
+ if (!confirmed) {
64
+ out.log('Aborted.');
65
+ process.exit(0);
66
+ }
67
+ }
68
+ // Remove the worktree
69
+ out.log(`Removing worktree: ${out.fmt.path(wtPath)}`);
70
+ try {
71
+ removeWorktree(wtPath, options.force ?? false, repoRoot);
72
+ out.success('Worktree removed');
73
+ }
74
+ catch (error) {
75
+ out.error(`Failed to remove worktree: ${error.message}`);
76
+ process.exit(1);
77
+ }
78
+ // Optionally delete the branch
79
+ if (options.withBranch && branch) {
80
+ const currentBranch = getCurrentBranch(repoRoot);
81
+ if (branch === currentBranch) {
82
+ out.warn(`Cannot delete branch '${branch}' - it's currently checked out in main worktree.`);
83
+ }
84
+ else {
85
+ out.log(`Deleting branch: ${out.fmt.branch(branch)}`);
86
+ try {
87
+ deleteBranch(branch, options.force ?? false, repoRoot);
88
+ out.success('Branch deleted');
89
+ }
90
+ catch (error) {
91
+ out.warn(`Failed to delete branch: ${error.message}`);
92
+ out.info('You may need to use --force or delete it manually.');
93
+ }
94
+ }
95
+ }
96
+ out.newline();
97
+ out.success('Done');
98
+ }
99
+ //# sourceMappingURL=rm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rm.js","sourceRoot":"","sources":["../../src/commands/rm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * cry spawn command
3
+ *
4
+ * Create a worktree for a branch with optional secrets handling and hooks.
5
+ */
6
+ import type { SecretMode } from '../lib/types.js';
7
+ interface SpawnOptions {
8
+ new?: boolean;
9
+ path?: string;
10
+ base?: string;
11
+ mode?: SecretMode;
12
+ run?: string;
13
+ agent?: string;
14
+ }
15
+ export declare function spawn(branch: string, options: SpawnOptions): Promise<void>;
16
+ export {};
17
+ //# sourceMappingURL=spawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/commands/spawn.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,UAAU,YAAY;IACpB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuIhF"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * cry spawn command
3
+ *
4
+ * Create a worktree for a branch with optional secrets handling and hooks.
5
+ */
6
+ import { existsSync } from 'node:fs';
7
+ import { isGitRepo, getRepoRoot, getRepoName, branchExists, addWorktree, listWorktrees, runCommand, commandExists, } from '../lib/git.js';
8
+ import { getMergedConfig, configExists } from '../lib/config.js';
9
+ import { getDefaultWorktreePath } from '../lib/paths.js';
10
+ import { processSecrets } from '../lib/secrets.js';
11
+ import * as out from '../lib/output.js';
12
+ export async function spawn(branch, options) {
13
+ // Check if we're in a git repo
14
+ if (!isGitRepo()) {
15
+ out.error('Not a git repository. Run this command from within a git repo.');
16
+ process.exit(1);
17
+ }
18
+ const repoRoot = getRepoRoot();
19
+ const repoName = getRepoName();
20
+ // Load config
21
+ const config = configExists(repoRoot) ? getMergedConfig(repoRoot) : {
22
+ worktreeBaseDir: undefined,
23
+ defaultMode: 'none',
24
+ include: [],
25
+ hooks: { postCreate: [] },
26
+ agentCommand: 'claude',
27
+ };
28
+ // Determine mode
29
+ const mode = options.mode ?? config.defaultMode;
30
+ // Calculate worktree path
31
+ const worktreePath = getDefaultWorktreePath(repoRoot, branch, {
32
+ explicitPath: options.path,
33
+ baseDir: options.base ?? config.worktreeBaseDir,
34
+ repoName,
35
+ });
36
+ // Check if destination already exists
37
+ if (existsSync(worktreePath)) {
38
+ out.error(`Destination already exists: ${worktreePath}`);
39
+ out.info('Remove it first or choose a different path with --path');
40
+ process.exit(1);
41
+ }
42
+ // Check if worktree already exists for this branch
43
+ const existingWorktrees = listWorktrees(repoRoot);
44
+ const existingForBranch = existingWorktrees.find((w) => w.branch === branch);
45
+ if (existingForBranch) {
46
+ out.error(`A worktree already exists for branch '${branch}'`);
47
+ out.info(`Path: ${existingForBranch.worktree}`);
48
+ out.info('Remove it first with: cry rm ' + branch);
49
+ process.exit(1);
50
+ }
51
+ // Determine if we need to create the branch
52
+ const needsNewBranch = options.new || !branchExists(branch, repoRoot);
53
+ out.header('Creating worktree');
54
+ out.log(` Branch: ${out.fmt.branch(branch)}${needsNewBranch ? out.fmt.gray(' (new)') : ''}`);
55
+ out.log(` Path: ${out.fmt.path(worktreePath)}`);
56
+ out.log(` Mode: ${out.fmt.cyan(mode)}`);
57
+ out.newline();
58
+ // Create the worktree
59
+ try {
60
+ addWorktree(worktreePath, branch, needsNewBranch, repoRoot);
61
+ out.success('Worktree created');
62
+ }
63
+ catch (error) {
64
+ out.error(`Failed to create worktree: ${error.message}`);
65
+ process.exit(1);
66
+ }
67
+ // Handle secrets
68
+ if (mode !== 'none' && config.include.length > 0) {
69
+ out.newline();
70
+ out.log(`Processing secrets (${mode} mode)...`);
71
+ const { processed, skipped } = await processSecrets(mode, config.include, repoRoot, worktreePath);
72
+ if (processed.length > 0) {
73
+ out.success(`${mode === 'copy' ? 'Copied' : 'Symlinked'} ${processed.length} file(s):`);
74
+ for (const file of processed) {
75
+ out.log(` ${out.fmt.dim('•')} ${file}`);
76
+ }
77
+ }
78
+ if (skipped.length > 0) {
79
+ out.warn(`Skipped ${skipped.length} file(s) for safety:`);
80
+ for (const file of skipped) {
81
+ out.log(` ${out.fmt.dim('•')} ${file.path}: ${file.reason}`);
82
+ }
83
+ }
84
+ }
85
+ // Run post-create hooks from config
86
+ const hooks = config.hooks.postCreate;
87
+ if (hooks.length > 0) {
88
+ out.newline();
89
+ out.log('Running post-create hooks...');
90
+ for (const hook of hooks) {
91
+ out.log(` ${out.fmt.dim('$')} ${hook}`);
92
+ const code = await runCommand(hook, worktreePath);
93
+ if (code !== 0) {
94
+ out.warn(`Hook exited with code ${code}`);
95
+ }
96
+ }
97
+ }
98
+ // Run --run command if provided
99
+ if (options.run) {
100
+ out.newline();
101
+ out.log('Running custom command...');
102
+ out.log(` ${out.fmt.dim('$')} ${options.run}`);
103
+ const code = await runCommand(options.run, worktreePath);
104
+ if (code !== 0) {
105
+ out.warn(`Command exited with code ${code}`);
106
+ }
107
+ }
108
+ // Handle agent launch
109
+ const agentChoice = options.agent ?? 'none';
110
+ if (agentChoice === 'claude') {
111
+ const agentCmd = config.agentCommand;
112
+ out.newline();
113
+ if (commandExists(agentCmd)) {
114
+ out.log(`Launching ${agentCmd}...`);
115
+ await runCommand(agentCmd, worktreePath);
116
+ }
117
+ else {
118
+ out.warn(`Agent command '${agentCmd}' not found.`);
119
+ out.info('Install Claude Code: https://docs.anthropic.com/claude-code');
120
+ }
121
+ }
122
+ // Final summary
123
+ out.newline();
124
+ out.header('Worktree ready');
125
+ out.log(` ${out.fmt.dim('cd')} ${worktreePath}`);
126
+ }
127
+ //# sourceMappingURL=spawn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/commands/spawn.ts"],"names":[],"mappings":"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"}