@camaradesuk/git-worktree-tools 1.0.4 → 1.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.
Files changed (168) hide show
  1. package/README.md +4 -0
  2. package/dist/cli/cleanpr.d.ts +1 -6
  3. package/dist/cli/cleanpr.d.ts.map +1 -1
  4. package/dist/cli/cleanpr.js +110 -302
  5. package/dist/cli/cleanpr.js.map +1 -1
  6. package/dist/cli/cleanpr.test.d.ts +2 -0
  7. package/dist/cli/cleanpr.test.d.ts.map +1 -0
  8. package/dist/cli/cleanpr.test.js +225 -0
  9. package/dist/cli/cleanpr.test.js.map +1 -0
  10. package/dist/cli/lswt.d.ts +1 -4
  11. package/dist/cli/lswt.d.ts.map +1 -1
  12. package/dist/cli/lswt.js +32 -251
  13. package/dist/cli/lswt.js.map +1 -1
  14. package/dist/cli/lswt.test.d.ts +2 -0
  15. package/dist/cli/lswt.test.d.ts.map +1 -0
  16. package/dist/cli/lswt.test.js +165 -0
  17. package/dist/cli/lswt.test.js.map +1 -0
  18. package/dist/cli/newpr.d.ts +1 -4
  19. package/dist/cli/newpr.d.ts.map +1 -1
  20. package/dist/cli/newpr.js +98 -493
  21. package/dist/cli/newpr.js.map +1 -1
  22. package/dist/cli/newpr.test.d.ts +2 -0
  23. package/dist/cli/newpr.test.d.ts.map +1 -0
  24. package/dist/cli/newpr.test.js +329 -0
  25. package/dist/cli/newpr.test.js.map +1 -0
  26. package/dist/cli/wtlink.test.d.ts +2 -0
  27. package/dist/cli/wtlink.test.d.ts.map +1 -0
  28. package/dist/cli/wtlink.test.js +148 -0
  29. package/dist/cli/wtlink.test.js.map +1 -0
  30. package/dist/e2e/cli.e2e.test.js +44 -1
  31. package/dist/e2e/cli.e2e.test.js.map +1 -1
  32. package/dist/integration/git.integration.test.js.map +1 -1
  33. package/dist/lib/cleanpr/args.d.ts +14 -0
  34. package/dist/lib/cleanpr/args.d.ts.map +1 -0
  35. package/dist/lib/cleanpr/args.js +82 -0
  36. package/dist/lib/cleanpr/args.js.map +1 -0
  37. package/dist/lib/cleanpr/args.test.d.ts +2 -0
  38. package/dist/lib/cleanpr/args.test.d.ts.map +1 -0
  39. package/dist/lib/cleanpr/args.test.js +192 -0
  40. package/dist/lib/cleanpr/args.test.js.map +1 -0
  41. package/dist/lib/cleanpr/cleanup.d.ts +61 -0
  42. package/dist/lib/cleanpr/cleanup.d.ts.map +1 -0
  43. package/dist/lib/cleanpr/cleanup.js +97 -0
  44. package/dist/lib/cleanpr/cleanup.js.map +1 -0
  45. package/dist/lib/cleanpr/cleanup.test.d.ts +2 -0
  46. package/dist/lib/cleanpr/cleanup.test.d.ts.map +1 -0
  47. package/dist/lib/cleanpr/cleanup.test.js +264 -0
  48. package/dist/lib/cleanpr/cleanup.test.js.map +1 -0
  49. package/dist/lib/cleanpr/index.d.ts +10 -0
  50. package/dist/lib/cleanpr/index.d.ts.map +1 -0
  51. package/dist/lib/cleanpr/index.js +8 -0
  52. package/dist/lib/cleanpr/index.js.map +1 -0
  53. package/dist/lib/cleanpr/types.d.ts +49 -0
  54. package/dist/lib/cleanpr/types.d.ts.map +1 -0
  55. package/dist/lib/cleanpr/types.js +5 -0
  56. package/dist/lib/cleanpr/types.js.map +1 -0
  57. package/dist/lib/cleanpr/worktree-info.d.ts +27 -0
  58. package/dist/lib/cleanpr/worktree-info.d.ts.map +1 -0
  59. package/dist/lib/cleanpr/worktree-info.js +95 -0
  60. package/dist/lib/cleanpr/worktree-info.js.map +1 -0
  61. package/dist/lib/cleanpr/worktree-info.test.d.ts +2 -0
  62. package/dist/lib/cleanpr/worktree-info.test.d.ts.map +1 -0
  63. package/dist/lib/cleanpr/worktree-info.test.js +160 -0
  64. package/dist/lib/cleanpr/worktree-info.test.js.map +1 -0
  65. package/dist/lib/colors.test.js +73 -0
  66. package/dist/lib/colors.test.js.map +1 -1
  67. package/dist/lib/config.test.js +79 -2
  68. package/dist/lib/config.test.js.map +1 -1
  69. package/dist/lib/git.d.ts.map +1 -1
  70. package/dist/lib/git.js +4 -3
  71. package/dist/lib/git.js.map +1 -1
  72. package/dist/lib/git.test.js +7 -7
  73. package/dist/lib/git.test.js.map +1 -1
  74. package/dist/lib/github.d.ts.map +1 -1
  75. package/dist/lib/github.js +4 -3
  76. package/dist/lib/github.js.map +1 -1
  77. package/dist/lib/github.test.js +2 -2
  78. package/dist/lib/github.test.js.map +1 -1
  79. package/dist/lib/lswt/args.d.ts +14 -0
  80. package/dist/lib/lswt/args.d.ts.map +1 -0
  81. package/dist/lib/lswt/args.js +67 -0
  82. package/dist/lib/lswt/args.js.map +1 -0
  83. package/dist/lib/lswt/args.test.d.ts +2 -0
  84. package/dist/lib/lswt/args.test.d.ts.map +1 -0
  85. package/dist/lib/lswt/args.test.js +135 -0
  86. package/dist/lib/lswt/args.test.js.map +1 -0
  87. package/dist/lib/lswt/formatters.d.ts +29 -0
  88. package/dist/lib/lswt/formatters.d.ts.map +1 -0
  89. package/dist/lib/lswt/formatters.js +113 -0
  90. package/dist/lib/lswt/formatters.js.map +1 -0
  91. package/dist/lib/lswt/formatters.test.d.ts +2 -0
  92. package/dist/lib/lswt/formatters.test.d.ts.map +1 -0
  93. package/dist/lib/lswt/formatters.test.js +233 -0
  94. package/dist/lib/lswt/formatters.test.js.map +1 -0
  95. package/dist/lib/lswt/index.d.ts +9 -0
  96. package/dist/lib/lswt/index.d.ts.map +1 -0
  97. package/dist/lib/lswt/index.js +9 -0
  98. package/dist/lib/lswt/index.js.map +1 -0
  99. package/dist/lib/lswt/types.d.ts +44 -0
  100. package/dist/lib/lswt/types.d.ts.map +1 -0
  101. package/dist/lib/lswt/types.js +5 -0
  102. package/dist/lib/lswt/types.js.map +1 -0
  103. package/dist/lib/lswt/worktree-info.d.ts +23 -0
  104. package/dist/lib/lswt/worktree-info.d.ts.map +1 -0
  105. package/dist/lib/lswt/worktree-info.js +81 -0
  106. package/dist/lib/lswt/worktree-info.js.map +1 -0
  107. package/dist/lib/lswt/worktree-info.test.d.ts +2 -0
  108. package/dist/lib/lswt/worktree-info.test.d.ts.map +1 -0
  109. package/dist/lib/lswt/worktree-info.test.js +190 -0
  110. package/dist/lib/lswt/worktree-info.test.js.map +1 -0
  111. package/dist/lib/newpr/actions.d.ts +56 -0
  112. package/dist/lib/newpr/actions.d.ts.map +1 -0
  113. package/dist/lib/newpr/actions.js +130 -0
  114. package/dist/lib/newpr/actions.js.map +1 -0
  115. package/dist/lib/newpr/actions.test.d.ts +2 -0
  116. package/dist/lib/newpr/actions.test.d.ts.map +1 -0
  117. package/dist/lib/newpr/actions.test.js +254 -0
  118. package/dist/lib/newpr/actions.test.js.map +1 -0
  119. package/dist/lib/newpr/args.d.ts +17 -0
  120. package/dist/lib/newpr/args.d.ts.map +1 -0
  121. package/dist/lib/newpr/args.js +123 -0
  122. package/dist/lib/newpr/args.js.map +1 -0
  123. package/dist/lib/newpr/args.test.d.ts +2 -0
  124. package/dist/lib/newpr/args.test.d.ts.map +1 -0
  125. package/dist/lib/newpr/args.test.js +271 -0
  126. package/dist/lib/newpr/args.test.js.map +1 -0
  127. package/dist/lib/newpr/index.d.ts +10 -0
  128. package/dist/lib/newpr/index.d.ts.map +1 -0
  129. package/dist/lib/newpr/index.js +8 -0
  130. package/dist/lib/newpr/index.js.map +1 -0
  131. package/dist/lib/newpr/scenario-handler.d.ts +40 -0
  132. package/dist/lib/newpr/scenario-handler.d.ts.map +1 -0
  133. package/dist/lib/newpr/scenario-handler.js +261 -0
  134. package/dist/lib/newpr/scenario-handler.js.map +1 -0
  135. package/dist/lib/newpr/scenario-handler.test.d.ts +2 -0
  136. package/dist/lib/newpr/scenario-handler.test.d.ts.map +1 -0
  137. package/dist/lib/newpr/scenario-handler.test.js +250 -0
  138. package/dist/lib/newpr/scenario-handler.test.js.map +1 -0
  139. package/dist/lib/newpr/types.d.ts +76 -0
  140. package/dist/lib/newpr/types.d.ts.map +1 -0
  141. package/dist/lib/newpr/types.js +5 -0
  142. package/dist/lib/newpr/types.js.map +1 -0
  143. package/dist/lib/state-detection.d.ts.map +1 -1
  144. package/dist/lib/state-detection.js +12 -3
  145. package/dist/lib/state-detection.js.map +1 -1
  146. package/dist/lib/state-detection.test.js +253 -2
  147. package/dist/lib/state-detection.test.js.map +1 -1
  148. package/dist/lib/wtlink/link-configs.d.ts +40 -0
  149. package/dist/lib/wtlink/link-configs.d.ts.map +1 -1
  150. package/dist/lib/wtlink/link-configs.js +126 -11
  151. package/dist/lib/wtlink/link-configs.js.map +1 -1
  152. package/dist/lib/wtlink/link-configs.test.js +237 -84
  153. package/dist/lib/wtlink/link-configs.test.js.map +1 -1
  154. package/dist/lib/wtlink/manage-manifest.d.ts +86 -0
  155. package/dist/lib/wtlink/manage-manifest.d.ts.map +1 -1
  156. package/dist/lib/wtlink/manage-manifest.js +18 -15
  157. package/dist/lib/wtlink/manage-manifest.js.map +1 -1
  158. package/dist/lib/wtlink/manage-manifest.test.d.ts +2 -0
  159. package/dist/lib/wtlink/manage-manifest.test.d.ts.map +1 -0
  160. package/dist/lib/wtlink/manage-manifest.test.js +383 -0
  161. package/dist/lib/wtlink/manage-manifest.test.js.map +1 -0
  162. package/dist/lib/wtlink/validate-manifest.d.ts +27 -0
  163. package/dist/lib/wtlink/validate-manifest.d.ts.map +1 -1
  164. package/dist/lib/wtlink/validate-manifest.js +103 -28
  165. package/dist/lib/wtlink/validate-manifest.js.map +1 -1
  166. package/dist/lib/wtlink/validate-manifest.test.js +170 -65
  167. package/dist/lib/wtlink/validate-manifest.test.js.map +1 -1
  168. package/package.json +1 -1
@@ -0,0 +1,97 @@
1
+ /**
2
+ * cleanpr cleanup - core cleanup logic with dependency injection
3
+ */
4
+ /**
5
+ * Group worktrees by PR state - pure function
6
+ */
7
+ export function groupWorktreesByState(worktrees) {
8
+ return {
9
+ merged: worktrees.filter((w) => w.prState === 'MERGED'),
10
+ closed: worktrees.filter((w) => w.prState === 'CLOSED'),
11
+ open: worktrees.filter((w) => w.prState === 'OPEN'),
12
+ unknown: worktrees.filter((w) => w.prState === 'UNKNOWN'),
13
+ };
14
+ }
15
+ /**
16
+ * Get worktrees that are cleanable (merged or closed)
17
+ */
18
+ export function getCleanableWorktrees(worktrees) {
19
+ return worktrees.filter((w) => w.prState === 'MERGED' || w.prState === 'CLOSED');
20
+ }
21
+ /**
22
+ * Find a specific worktree by PR number
23
+ */
24
+ export function findWorktreeByPrNumber(worktrees, prNumber) {
25
+ return worktrees.find((w) => w.prNumber === prNumber);
26
+ }
27
+ /**
28
+ * Check if a worktree can be cleaned based on options
29
+ */
30
+ export function canCleanWorktree(info, options) {
31
+ if (info.hasChanges && !options.force) {
32
+ return false;
33
+ }
34
+ return true;
35
+ }
36
+ /**
37
+ * Clean a single worktree - returns result object
38
+ * Uses dependency injection for git operations
39
+ */
40
+ export function cleanWorktree(info, options, deps) {
41
+ const prLabel = `PR #${info.prNumber}`;
42
+ // Check for uncommitted changes
43
+ if (!canCleanWorktree(info, options)) {
44
+ return {
45
+ success: false,
46
+ prNumber: info.prNumber,
47
+ message: `${prLabel}: Has uncommitted changes (use --force to override)`,
48
+ };
49
+ }
50
+ try {
51
+ // Remove worktree
52
+ deps.removeWorktree(info.path, options.force);
53
+ // Delete local branch
54
+ if (info.branch) {
55
+ deps.deleteLocalBranch(info.branch);
56
+ // Delete remote branch if requested
57
+ if (options.deleteRemote) {
58
+ deps.deleteRemoteBranch(info.branch);
59
+ }
60
+ }
61
+ // Prune worktrees
62
+ deps.pruneWorktrees();
63
+ return {
64
+ success: true,
65
+ prNumber: info.prNumber,
66
+ message: `${prLabel}: Cleaned successfully`,
67
+ };
68
+ }
69
+ catch (err) {
70
+ const message = err instanceof Error ? err.message : String(err);
71
+ return {
72
+ success: false,
73
+ prNumber: info.prNumber,
74
+ message: `${prLabel}: Failed to clean - ${message}`,
75
+ };
76
+ }
77
+ }
78
+ /**
79
+ * Clean multiple worktrees - returns array of results
80
+ */
81
+ export function cleanWorktrees(worktrees, options, deps) {
82
+ return worktrees.map((w) => cleanWorktree(w, options, deps));
83
+ }
84
+ /**
85
+ * Format PR state for display - pure function
86
+ */
87
+ export function formatPrState(state) {
88
+ return state.toLowerCase();
89
+ }
90
+ export function summarizeResults(results) {
91
+ return {
92
+ total: results.length,
93
+ cleaned: results.filter((r) => r.success).length,
94
+ failed: results.filter((r) => !r.success).length,
95
+ };
96
+ }
97
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../../src/lib/cleanpr/cleanup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cleanup.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.test.d.ts","sourceRoot":"","sources":["../../../src/lib/cleanpr/cleanup.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,264 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { groupWorktreesByState, getCleanableWorktrees, findWorktreeByPrNumber, canCleanWorktree, cleanWorktree, cleanWorktrees, formatPrState, summarizeResults, } from './cleanup.js';
3
+ describe('cleanpr/cleanup', () => {
4
+ const makeWorktreeInfo = (overrides = {}) => ({
5
+ path: '/home/user/repo.pr1',
6
+ branch: 'feature',
7
+ commit: 'abc123',
8
+ prNumber: 1,
9
+ prState: 'OPEN',
10
+ hasChanges: false,
11
+ ...overrides,
12
+ });
13
+ const makeOptions = (overrides = {}) => ({
14
+ deleteRemote: false,
15
+ force: false,
16
+ all: false,
17
+ interactive: true,
18
+ ...overrides,
19
+ });
20
+ const makeDeps = (overrides = {}) => ({
21
+ removeWorktree: vi.fn(),
22
+ deleteLocalBranch: vi.fn().mockReturnValue(true),
23
+ deleteRemoteBranch: vi.fn().mockReturnValue(true),
24
+ pruneWorktrees: vi.fn(),
25
+ ...overrides,
26
+ });
27
+ describe('groupWorktreesByState', () => {
28
+ it('groups worktrees by state', () => {
29
+ const worktrees = [
30
+ makeWorktreeInfo({ prNumber: 1, prState: 'MERGED' }),
31
+ makeWorktreeInfo({ prNumber: 2, prState: 'CLOSED' }),
32
+ makeWorktreeInfo({ prNumber: 3, prState: 'OPEN' }),
33
+ makeWorktreeInfo({ prNumber: 4, prState: 'UNKNOWN' }),
34
+ makeWorktreeInfo({ prNumber: 5, prState: 'MERGED' }),
35
+ ];
36
+ const groups = groupWorktreesByState(worktrees);
37
+ expect(groups.merged).toHaveLength(2);
38
+ expect(groups.closed).toHaveLength(1);
39
+ expect(groups.open).toHaveLength(1);
40
+ expect(groups.unknown).toHaveLength(1);
41
+ });
42
+ it('returns empty arrays for missing states', () => {
43
+ const worktrees = [makeWorktreeInfo({ prState: 'OPEN' })];
44
+ const groups = groupWorktreesByState(worktrees);
45
+ expect(groups.merged).toHaveLength(0);
46
+ expect(groups.closed).toHaveLength(0);
47
+ expect(groups.open).toHaveLength(1);
48
+ expect(groups.unknown).toHaveLength(0);
49
+ });
50
+ it('handles empty array', () => {
51
+ const groups = groupWorktreesByState([]);
52
+ expect(groups.merged).toHaveLength(0);
53
+ expect(groups.closed).toHaveLength(0);
54
+ expect(groups.open).toHaveLength(0);
55
+ expect(groups.unknown).toHaveLength(0);
56
+ });
57
+ });
58
+ describe('getCleanableWorktrees', () => {
59
+ it('returns merged and closed worktrees', () => {
60
+ const worktrees = [
61
+ makeWorktreeInfo({ prNumber: 1, prState: 'MERGED' }),
62
+ makeWorktreeInfo({ prNumber: 2, prState: 'CLOSED' }),
63
+ makeWorktreeInfo({ prNumber: 3, prState: 'OPEN' }),
64
+ makeWorktreeInfo({ prNumber: 4, prState: 'UNKNOWN' }),
65
+ ];
66
+ const cleanable = getCleanableWorktrees(worktrees);
67
+ expect(cleanable).toHaveLength(2);
68
+ expect(cleanable.map((w) => w.prNumber)).toEqual([1, 2]);
69
+ });
70
+ it('returns empty array when no cleanable worktrees', () => {
71
+ const worktrees = [
72
+ makeWorktreeInfo({ prState: 'OPEN' }),
73
+ makeWorktreeInfo({ prState: 'UNKNOWN' }),
74
+ ];
75
+ const cleanable = getCleanableWorktrees(worktrees);
76
+ expect(cleanable).toHaveLength(0);
77
+ });
78
+ });
79
+ describe('findWorktreeByPrNumber', () => {
80
+ it('finds worktree by PR number', () => {
81
+ const worktrees = [
82
+ makeWorktreeInfo({ prNumber: 1 }),
83
+ makeWorktreeInfo({ prNumber: 42 }),
84
+ makeWorktreeInfo({ prNumber: 99 }),
85
+ ];
86
+ const found = findWorktreeByPrNumber(worktrees, 42);
87
+ expect(found).toBeDefined();
88
+ expect(found?.prNumber).toBe(42);
89
+ });
90
+ it('returns undefined when not found', () => {
91
+ const worktrees = [makeWorktreeInfo({ prNumber: 1 })];
92
+ const found = findWorktreeByPrNumber(worktrees, 999);
93
+ expect(found).toBeUndefined();
94
+ });
95
+ });
96
+ describe('canCleanWorktree', () => {
97
+ it('returns true when no changes', () => {
98
+ const info = makeWorktreeInfo({ hasChanges: false });
99
+ const options = makeOptions({ force: false });
100
+ expect(canCleanWorktree(info, options)).toBe(true);
101
+ });
102
+ it('returns false when has changes and not forced', () => {
103
+ const info = makeWorktreeInfo({ hasChanges: true });
104
+ const options = makeOptions({ force: false });
105
+ expect(canCleanWorktree(info, options)).toBe(false);
106
+ });
107
+ it('returns true when has changes but forced', () => {
108
+ const info = makeWorktreeInfo({ hasChanges: true });
109
+ const options = makeOptions({ force: true });
110
+ expect(canCleanWorktree(info, options)).toBe(true);
111
+ });
112
+ });
113
+ describe('cleanWorktree', () => {
114
+ it('returns failure when has uncommitted changes and not forced', () => {
115
+ const info = makeWorktreeInfo({ prNumber: 42, hasChanges: true });
116
+ const options = makeOptions({ force: false });
117
+ const deps = makeDeps();
118
+ const result = cleanWorktree(info, options, deps);
119
+ expect(result.success).toBe(false);
120
+ expect(result.prNumber).toBe(42);
121
+ expect(result.message).toContain('uncommitted changes');
122
+ });
123
+ it('removes worktree', () => {
124
+ const info = makeWorktreeInfo({ path: '/path/to/wt' });
125
+ const options = makeOptions();
126
+ const deps = makeDeps();
127
+ cleanWorktree(info, options, deps);
128
+ expect(deps.removeWorktree).toHaveBeenCalledWith('/path/to/wt', false);
129
+ });
130
+ it('removes worktree with force when option set', () => {
131
+ const info = makeWorktreeInfo({ path: '/path/to/wt' });
132
+ const options = makeOptions({ force: true });
133
+ const deps = makeDeps();
134
+ cleanWorktree(info, options, deps);
135
+ expect(deps.removeWorktree).toHaveBeenCalledWith('/path/to/wt', true);
136
+ });
137
+ it('deletes local branch', () => {
138
+ const info = makeWorktreeInfo({ branch: 'feature-branch' });
139
+ const options = makeOptions();
140
+ const deps = makeDeps();
141
+ cleanWorktree(info, options, deps);
142
+ expect(deps.deleteLocalBranch).toHaveBeenCalledWith('feature-branch');
143
+ });
144
+ it('does not delete local branch when null', () => {
145
+ const info = makeWorktreeInfo({ branch: null });
146
+ const options = makeOptions();
147
+ const deps = makeDeps();
148
+ cleanWorktree(info, options, deps);
149
+ expect(deps.deleteLocalBranch).not.toHaveBeenCalled();
150
+ });
151
+ it('deletes remote branch when option set', () => {
152
+ const info = makeWorktreeInfo({ branch: 'feature-branch' });
153
+ const options = makeOptions({ deleteRemote: true });
154
+ const deps = makeDeps();
155
+ cleanWorktree(info, options, deps);
156
+ expect(deps.deleteRemoteBranch).toHaveBeenCalledWith('feature-branch');
157
+ });
158
+ it('does not delete remote branch when option not set', () => {
159
+ const info = makeWorktreeInfo({ branch: 'feature-branch' });
160
+ const options = makeOptions({ deleteRemote: false });
161
+ const deps = makeDeps();
162
+ cleanWorktree(info, options, deps);
163
+ expect(deps.deleteRemoteBranch).not.toHaveBeenCalled();
164
+ });
165
+ it('prunes worktrees after cleanup', () => {
166
+ const info = makeWorktreeInfo();
167
+ const options = makeOptions();
168
+ const deps = makeDeps();
169
+ cleanWorktree(info, options, deps);
170
+ expect(deps.pruneWorktrees).toHaveBeenCalled();
171
+ });
172
+ it('returns success result on successful cleanup', () => {
173
+ const info = makeWorktreeInfo({ prNumber: 42 });
174
+ const options = makeOptions();
175
+ const deps = makeDeps();
176
+ const result = cleanWorktree(info, options, deps);
177
+ expect(result.success).toBe(true);
178
+ expect(result.prNumber).toBe(42);
179
+ expect(result.message).toContain('Cleaned successfully');
180
+ });
181
+ it('returns failure result when removeWorktree throws', () => {
182
+ const info = makeWorktreeInfo({ prNumber: 42 });
183
+ const options = makeOptions();
184
+ const deps = makeDeps({
185
+ removeWorktree: vi.fn().mockImplementation(() => {
186
+ throw new Error('Permission denied');
187
+ }),
188
+ });
189
+ const result = cleanWorktree(info, options, deps);
190
+ expect(result.success).toBe(false);
191
+ expect(result.prNumber).toBe(42);
192
+ expect(result.message).toContain('Failed to clean');
193
+ expect(result.message).toContain('Permission denied');
194
+ });
195
+ });
196
+ describe('cleanWorktrees', () => {
197
+ it('cleans multiple worktrees', () => {
198
+ const worktrees = [
199
+ makeWorktreeInfo({ prNumber: 1, path: '/path1' }),
200
+ makeWorktreeInfo({ prNumber: 2, path: '/path2' }),
201
+ ];
202
+ const options = makeOptions();
203
+ const deps = makeDeps();
204
+ const results = cleanWorktrees(worktrees, options, deps);
205
+ expect(results).toHaveLength(2);
206
+ expect(deps.removeWorktree).toHaveBeenCalledTimes(2);
207
+ });
208
+ it('returns array of results', () => {
209
+ const worktrees = [
210
+ makeWorktreeInfo({ prNumber: 1 }),
211
+ makeWorktreeInfo({ prNumber: 2, hasChanges: true }),
212
+ ];
213
+ const options = makeOptions({ force: false });
214
+ const deps = makeDeps();
215
+ const results = cleanWorktrees(worktrees, options, deps);
216
+ expect(results[0].success).toBe(true);
217
+ expect(results[1].success).toBe(false);
218
+ });
219
+ });
220
+ describe('formatPrState', () => {
221
+ it('formats MERGED to lowercase', () => {
222
+ expect(formatPrState('MERGED')).toBe('merged');
223
+ });
224
+ it('formats CLOSED to lowercase', () => {
225
+ expect(formatPrState('CLOSED')).toBe('closed');
226
+ });
227
+ it('formats OPEN to lowercase', () => {
228
+ expect(formatPrState('OPEN')).toBe('open');
229
+ });
230
+ it('formats UNKNOWN to lowercase', () => {
231
+ expect(formatPrState('UNKNOWN')).toBe('unknown');
232
+ });
233
+ });
234
+ describe('summarizeResults', () => {
235
+ it('summarizes all successful results', () => {
236
+ const results = [
237
+ { success: true, prNumber: 1, message: '' },
238
+ { success: true, prNumber: 2, message: '' },
239
+ ];
240
+ const summary = summarizeResults(results);
241
+ expect(summary.total).toBe(2);
242
+ expect(summary.cleaned).toBe(2);
243
+ expect(summary.failed).toBe(0);
244
+ });
245
+ it('summarizes mixed results', () => {
246
+ const results = [
247
+ { success: true, prNumber: 1, message: '' },
248
+ { success: false, prNumber: 2, message: '' },
249
+ { success: true, prNumber: 3, message: '' },
250
+ ];
251
+ const summary = summarizeResults(results);
252
+ expect(summary.total).toBe(3);
253
+ expect(summary.cleaned).toBe(2);
254
+ expect(summary.failed).toBe(1);
255
+ });
256
+ it('handles empty results', () => {
257
+ const summary = summarizeResults([]);
258
+ expect(summary.total).toBe(0);
259
+ expect(summary.cleaned).toBe(0);
260
+ expect(summary.failed).toBe(0);
261
+ });
262
+ });
263
+ });
264
+ //# sourceMappingURL=cleanup.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.test.js","sourceRoot":"","sources":["../../../src/lib/cleanpr/cleanup.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * cleanpr library - public API exports
3
+ */
4
+ export type { CleanOptions, PrState, WorktreeInfo, ParseResult, CleanupResult } from './types.js';
5
+ export { parseArgs, getHelpText } from './args.js';
6
+ export type { GatherDeps } from './worktree-info.js';
7
+ export { extractPrNumber, gatherPrWorktreeInfo, createDefaultDeps } from './worktree-info.js';
8
+ export type { CleanupDeps, GroupedWorktrees, CleanupSummary } from './cleanup.js';
9
+ export { groupWorktreesByState, getCleanableWorktrees, findWorktreeByPrNumber, canCleanWorktree, cleanWorktree, cleanWorktrees, formatPrState, summarizeResults, } from './cleanup.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/cleanpr/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGlG,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGnD,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG9F,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * cleanpr library - public API exports
3
+ */
4
+ // Argument parsing
5
+ export { parseArgs, getHelpText } from './args.js';
6
+ export { extractPrNumber, gatherPrWorktreeInfo, createDefaultDeps } from './worktree-info.js';
7
+ export { groupWorktreesByState, getCleanableWorktrees, findWorktreeByPrNumber, canCleanWorktree, cleanWorktree, cleanWorktrees, formatPrState, summarizeResults, } from './cleanup.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/cleanpr/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,mBAAmB;AACnB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAInD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAI9F,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * cleanpr types - shared type definitions
3
+ */
4
+ /**
5
+ * CLI options for cleanpr command
6
+ */
7
+ export interface CleanOptions {
8
+ deleteRemote: boolean;
9
+ force: boolean;
10
+ all: boolean;
11
+ interactive: boolean;
12
+ }
13
+ /**
14
+ * PR state from GitHub
15
+ */
16
+ export type PrState = 'OPEN' | 'CLOSED' | 'MERGED' | 'UNKNOWN';
17
+ /**
18
+ * Worktree information for cleanup
19
+ */
20
+ export interface WorktreeInfo {
21
+ path: string;
22
+ branch: string | null;
23
+ commit: string;
24
+ prNumber: number;
25
+ prState: PrState;
26
+ hasChanges: boolean;
27
+ }
28
+ /**
29
+ * Result from argument parsing - discriminated union
30
+ */
31
+ export type ParseResult = {
32
+ kind: 'success';
33
+ prNumber: number | null;
34
+ options: CleanOptions;
35
+ } | {
36
+ kind: 'help';
37
+ } | {
38
+ kind: 'error';
39
+ message: string;
40
+ };
41
+ /**
42
+ * Result from cleanup operation
43
+ */
44
+ export interface CleanupResult {
45
+ success: boolean;
46
+ prNumber: number;
47
+ message: string;
48
+ }
49
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/cleanpr/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * cleanpr types - shared type definitions
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/cleanpr/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * cleanpr worktree-info - gather worktree information with dependency injection
3
+ */
4
+ import type { Worktree } from '../git.js';
5
+ import type { PrState, WorktreeInfo } from './types.js';
6
+ /**
7
+ * Dependencies interface for testing
8
+ */
9
+ export interface GatherDeps {
10
+ listWorktrees: (cwd?: string) => Worktree[];
11
+ hasUncommittedChanges: (worktreePath: string) => boolean;
12
+ getPrState: (prNumber: number) => Promise<PrState>;
13
+ }
14
+ /**
15
+ * Extract PR number from worktree path - pure function
16
+ */
17
+ export declare function extractPrNumber(worktreePath: string, worktreePattern?: string): number | null;
18
+ /**
19
+ * Gather worktree information for PR worktrees only
20
+ * Uses dependency injection for testability
21
+ */
22
+ export declare function gatherPrWorktreeInfo(repoRoot: string, worktreePattern: string | undefined, deps: GatherDeps): Promise<WorktreeInfo[]>;
23
+ /**
24
+ * Create default dependencies using real implementations
25
+ */
26
+ export declare function createDefaultDeps(): GatherDeps;
27
+ //# sourceMappingURL=worktree-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-info.d.ts","sourceRoot":"","sources":["../../../src/lib/cleanpr/worktree-info.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;IAC5C,qBAAqB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;IACzD,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACpD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0B7F;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,EAAE,CAAC,CA6BzB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,CA6B9C"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * cleanpr worktree-info - gather worktree information with dependency injection
3
+ */
4
+ import * as path from 'path';
5
+ import { execSync } from 'child_process';
6
+ import * as git from '../git.js';
7
+ import * as github from '../github.js';
8
+ /**
9
+ * Extract PR number from worktree path - pure function
10
+ */
11
+ export function extractPrNumber(worktreePath, worktreePattern) {
12
+ const name = path.basename(worktreePath);
13
+ // Try pattern-based extraction if pattern provided
14
+ if (worktreePattern?.includes('{number}')) {
15
+ const regexStr = worktreePattern
16
+ .replace('{repo}', '.*')
17
+ .replace('{number}', '(\\d+)')
18
+ .replace('.', '\\.');
19
+ const match = name.match(new RegExp(regexStr));
20
+ if (match) {
21
+ return parseInt(match[1], 10);
22
+ }
23
+ }
24
+ // Fallback: try common patterns
25
+ const patterns = [/\.pr(\d+)$/, /\.pr-(\d+)$/, /-pr(\d+)$/, /_pr(\d+)$/];
26
+ for (const p of patterns) {
27
+ const match = name.match(p);
28
+ if (match) {
29
+ return parseInt(match[1], 10);
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+ /**
35
+ * Gather worktree information for PR worktrees only
36
+ * Uses dependency injection for testability
37
+ */
38
+ export async function gatherPrWorktreeInfo(repoRoot, worktreePattern, deps) {
39
+ const worktrees = deps.listWorktrees(repoRoot);
40
+ const result = [];
41
+ for (const wt of worktrees) {
42
+ const prNumber = extractPrNumber(wt.path, worktreePattern);
43
+ // Skip non-PR worktrees
44
+ if (prNumber === null) {
45
+ continue;
46
+ }
47
+ const prState = await deps.getPrState(prNumber);
48
+ const hasChanges = deps.hasUncommittedChanges(wt.path);
49
+ result.push({
50
+ path: wt.path,
51
+ branch: wt.branch,
52
+ commit: wt.commit,
53
+ prNumber,
54
+ prState,
55
+ hasChanges,
56
+ });
57
+ }
58
+ // Sort by PR number
59
+ result.sort((a, b) => a.prNumber - b.prNumber);
60
+ return result;
61
+ }
62
+ /**
63
+ * Create default dependencies using real implementations
64
+ */
65
+ export function createDefaultDeps() {
66
+ return {
67
+ listWorktrees: (cwd) => git.listWorktrees(cwd),
68
+ hasUncommittedChanges: (worktreePath) => {
69
+ try {
70
+ const status = execSync('git status --porcelain', {
71
+ cwd: worktreePath,
72
+ encoding: 'utf-8',
73
+ stdio: ['pipe', 'pipe', 'pipe'],
74
+ }).trim();
75
+ return status.length > 0;
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ },
81
+ getPrState: async (prNumber) => {
82
+ try {
83
+ const pr = github.getPr(prNumber);
84
+ if (!pr) {
85
+ return 'UNKNOWN';
86
+ }
87
+ return pr.state;
88
+ }
89
+ catch {
90
+ return 'UNKNOWN';
91
+ }
92
+ },
93
+ };
94
+ }
95
+ //# sourceMappingURL=worktree-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-info.js","sourceRoot":"","sources":["../../../src/lib/cleanpr/worktree-info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=worktree-info.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-info.test.d.ts","sourceRoot":"","sources":["../../../src/lib/cleanpr/worktree-info.test.ts"],"names":[],"mappings":""}