@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,233 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { extractPrNumber, isMainWorktree, formatTypeLabel, sortWorktrees, getDisplayPath, formatJsonOutput, } from './formatters.js';
3
+ describe('lswt/formatters', () => {
4
+ describe('extractPrNumber', () => {
5
+ it('extracts PR number from .pr123 pattern', () => {
6
+ expect(extractPrNumber('/home/user/repo.pr123')).toBe(123);
7
+ });
8
+ it('extracts PR number from .pr-123 pattern', () => {
9
+ expect(extractPrNumber('/home/user/repo.pr-42')).toBe(42);
10
+ });
11
+ it('extracts PR number from -pr123 pattern', () => {
12
+ expect(extractPrNumber('/home/user/repo-pr99')).toBe(99);
13
+ });
14
+ it('extracts PR number from _pr123 pattern', () => {
15
+ expect(extractPrNumber('/home/user/repo_pr5')).toBe(5);
16
+ });
17
+ it('returns null for non-PR path', () => {
18
+ expect(extractPrNumber('/home/user/repo')).toBeNull();
19
+ });
20
+ it('returns null for path with pr in middle', () => {
21
+ expect(extractPrNumber('/home/user/project-name')).toBeNull();
22
+ });
23
+ it('extracts from nested path', () => {
24
+ expect(extractPrNumber('/workspace/projects/myrepo.pr42')).toBe(42);
25
+ });
26
+ });
27
+ describe('isMainWorktree', () => {
28
+ it('returns true when paths match', () => {
29
+ expect(isMainWorktree('/home/user/repo', '/home/user/repo')).toBe(true);
30
+ });
31
+ it('returns false when paths differ', () => {
32
+ expect(isMainWorktree('/home/user/repo.pr1', '/home/user/repo')).toBe(false);
33
+ });
34
+ it('handles trailing slashes', () => {
35
+ expect(isMainWorktree('/home/user/repo/', '/home/user/repo')).toBe(true);
36
+ });
37
+ it('resolves relative paths', () => {
38
+ expect(isMainWorktree('/home/user/../user/repo', '/home/user/repo')).toBe(true);
39
+ });
40
+ });
41
+ describe('formatTypeLabel', () => {
42
+ const makeDisplay = (overrides = {}) => ({
43
+ path: '/repo',
44
+ name: 'repo',
45
+ branch: 'main',
46
+ commit: 'abc123',
47
+ type: 'main',
48
+ prNumber: null,
49
+ prState: null,
50
+ hasChanges: false,
51
+ ...overrides,
52
+ });
53
+ it('formats main worktree', () => {
54
+ const display = makeDisplay({ type: 'main' });
55
+ expect(formatTypeLabel(display)).toEqual({ text: '[main]', color: 'cyan' });
56
+ });
57
+ it('formats PR with OPEN state', () => {
58
+ const display = makeDisplay({ type: 'pr', prNumber: 1, prState: 'OPEN' });
59
+ expect(formatTypeLabel(display)).toEqual({ text: '[PR #1 OPEN]', color: 'green' });
60
+ });
61
+ it('formats PR with MERGED state', () => {
62
+ const display = makeDisplay({ type: 'pr', prNumber: 2, prState: 'MERGED' });
63
+ expect(formatTypeLabel(display)).toEqual({ text: '[PR #2 MERGED]', color: 'yellow' });
64
+ });
65
+ it('formats PR with CLOSED state', () => {
66
+ const display = makeDisplay({ type: 'pr', prNumber: 3, prState: 'CLOSED' });
67
+ expect(formatTypeLabel(display)).toEqual({ text: '[PR #3 CLOSED]', color: 'red' });
68
+ });
69
+ it('formats PR with unknown state', () => {
70
+ const display = makeDisplay({ type: 'pr', prNumber: 4, prState: null });
71
+ expect(formatTypeLabel(display)).toEqual({ text: '[PR #4]', color: 'dim' });
72
+ });
73
+ it('formats branch type', () => {
74
+ const display = makeDisplay({ type: 'branch' });
75
+ expect(formatTypeLabel(display)).toEqual({ text: '[branch]', color: 'blue' });
76
+ });
77
+ it('formats detached type', () => {
78
+ const display = makeDisplay({ type: 'detached', branch: null });
79
+ expect(formatTypeLabel(display)).toEqual({ text: '[detached]', color: 'dim' });
80
+ });
81
+ });
82
+ describe('sortWorktrees', () => {
83
+ const makeWorktree = (type, prNumber, name) => ({
84
+ path: `/path/${name}`,
85
+ name,
86
+ branch: 'b',
87
+ commit: 'c',
88
+ type,
89
+ prNumber,
90
+ prState: null,
91
+ hasChanges: false,
92
+ });
93
+ it('puts main first', () => {
94
+ const worktrees = [makeWorktree('pr', 1, 'repo.pr1'), makeWorktree('main', null, 'repo')];
95
+ const sorted = sortWorktrees(worktrees);
96
+ expect(sorted[0].type).toBe('main');
97
+ });
98
+ it('sorts PRs by number', () => {
99
+ const worktrees = [
100
+ makeWorktree('pr', 10, 'repo.pr10'),
101
+ makeWorktree('pr', 2, 'repo.pr2'),
102
+ makeWorktree('pr', 5, 'repo.pr5'),
103
+ ];
104
+ const sorted = sortWorktrees(worktrees);
105
+ expect(sorted.map((w) => w.prNumber)).toEqual([2, 5, 10]);
106
+ });
107
+ it('puts PRs before branches', () => {
108
+ const worktrees = [
109
+ makeWorktree('branch', null, 'feature'),
110
+ makeWorktree('pr', 1, 'repo.pr1'),
111
+ ];
112
+ const sorted = sortWorktrees(worktrees);
113
+ expect(sorted[0].type).toBe('pr');
114
+ });
115
+ it('sorts branches alphabetically', () => {
116
+ const worktrees = [
117
+ makeWorktree('branch', null, 'zebra'),
118
+ makeWorktree('branch', null, 'alpha'),
119
+ ];
120
+ const sorted = sortWorktrees(worktrees);
121
+ expect(sorted.map((w) => w.name)).toEqual(['alpha', 'zebra']);
122
+ });
123
+ it('does not mutate original array', () => {
124
+ const worktrees = [makeWorktree('pr', 1, 'a'), makeWorktree('main', null, 'b')];
125
+ const originalFirst = worktrees[0];
126
+ sortWorktrees(worktrees);
127
+ expect(worktrees[0]).toBe(originalFirst);
128
+ });
129
+ it('handles empty array', () => {
130
+ expect(sortWorktrees([])).toEqual([]);
131
+ });
132
+ it('handles single item', () => {
133
+ const worktrees = [makeWorktree('main', null, 'repo')];
134
+ const sorted = sortWorktrees(worktrees);
135
+ expect(sorted).toHaveLength(1);
136
+ });
137
+ });
138
+ describe('getDisplayPath', () => {
139
+ it('returns full path in verbose mode', () => {
140
+ expect(getDisplayPath('/home/user/repo', '/home/user', true)).toBe('/home/user/repo');
141
+ });
142
+ it('returns relative path when in same directory', () => {
143
+ expect(getDisplayPath('/home/user/repo.pr1', '/home/user/repo', false)).toBe('../repo.pr1');
144
+ });
145
+ it('returns dot for current directory', () => {
146
+ expect(getDisplayPath('/home/user/repo', '/home/user/repo', false)).toBe('.');
147
+ });
148
+ it('returns relative path when in parent directory', () => {
149
+ expect(getDisplayPath('/home/user/repo.pr1', '/home/user', false)).toBe('repo.pr1');
150
+ });
151
+ it('returns full path when not related', () => {
152
+ expect(getDisplayPath('/other/path/repo', '/home/user/repo', false)).toBe('/other/path/repo');
153
+ });
154
+ });
155
+ describe('formatJsonOutput', () => {
156
+ it('formats empty array', () => {
157
+ expect(formatJsonOutput([])).toBe('[]');
158
+ });
159
+ it('formats worktrees as JSON', () => {
160
+ const worktrees = [
161
+ {
162
+ path: '/repo',
163
+ name: 'repo',
164
+ branch: 'main',
165
+ commit: 'abc123',
166
+ type: 'main',
167
+ prNumber: null,
168
+ prState: null,
169
+ hasChanges: false,
170
+ },
171
+ ];
172
+ const json = formatJsonOutput(worktrees);
173
+ const parsed = JSON.parse(json);
174
+ expect(parsed).toHaveLength(1);
175
+ expect(parsed[0].path).toBe('/repo');
176
+ expect(parsed[0].type).toBe('main');
177
+ });
178
+ it('includes all fields', () => {
179
+ const worktrees = [
180
+ {
181
+ path: '/repo.pr1',
182
+ name: 'repo.pr1',
183
+ branch: 'feature',
184
+ commit: 'def456',
185
+ type: 'pr',
186
+ prNumber: 1,
187
+ prState: 'OPEN',
188
+ hasChanges: true,
189
+ },
190
+ ];
191
+ const json = formatJsonOutput(worktrees);
192
+ const parsed = JSON.parse(json);
193
+ expect(parsed[0]).toEqual({
194
+ path: '/repo.pr1',
195
+ name: 'repo.pr1',
196
+ branch: 'feature',
197
+ commit: 'def456',
198
+ type: 'pr',
199
+ prNumber: 1,
200
+ prState: 'OPEN',
201
+ hasChanges: true,
202
+ });
203
+ });
204
+ it('formats multiple worktrees', () => {
205
+ const worktrees = [
206
+ {
207
+ path: '/repo',
208
+ name: 'repo',
209
+ branch: 'main',
210
+ commit: 'a',
211
+ type: 'main',
212
+ prNumber: null,
213
+ prState: null,
214
+ hasChanges: false,
215
+ },
216
+ {
217
+ path: '/repo.pr1',
218
+ name: 'repo.pr1',
219
+ branch: 'f',
220
+ commit: 'b',
221
+ type: 'pr',
222
+ prNumber: 1,
223
+ prState: 'OPEN',
224
+ hasChanges: true,
225
+ },
226
+ ];
227
+ const json = formatJsonOutput(worktrees);
228
+ const parsed = JSON.parse(json);
229
+ expect(parsed).toHaveLength(2);
230
+ });
231
+ });
232
+ });
233
+ //# sourceMappingURL=formatters.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.test.js","sourceRoot":"","sources":["../../../src/lib/lswt/formatters.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * lswt library - public API exports
3
+ */
4
+ export type { ListOptions, WorktreeDisplay, ParseResult, TypeLabel } from './types.js';
5
+ export { parseArgs, getHelpText } from './args.js';
6
+ export { extractPrNumber, isMainWorktree, formatTypeLabel, sortWorktrees, getDisplayPath, formatJsonOutput, } from './formatters.js';
7
+ export type { GatherDeps } from './worktree-info.js';
8
+ export { gatherWorktreeInfo, createDefaultDeps } from './worktree-info.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGnD,OAAO,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * lswt library - public API exports
3
+ */
4
+ // Argument parsing
5
+ export { parseArgs, getHelpText } from './args.js';
6
+ // Formatters
7
+ export { extractPrNumber, isMainWorktree, formatTypeLabel, sortWorktrees, getDisplayPath, formatJsonOutput, } from './formatters.js';
8
+ export { gatherWorktreeInfo, createDefaultDeps } from './worktree-info.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/lswt/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,mBAAmB;AACnB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEnD,aAAa;AACb,OAAO,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * lswt types - shared type definitions
3
+ */
4
+ /**
5
+ * CLI options for lswt command
6
+ */
7
+ export interface ListOptions {
8
+ showStatus: boolean;
9
+ json: boolean;
10
+ verbose: boolean;
11
+ }
12
+ /**
13
+ * Worktree display information
14
+ */
15
+ export interface WorktreeDisplay {
16
+ path: string;
17
+ name: string;
18
+ branch: string | null;
19
+ commit: string;
20
+ type: 'main' | 'pr' | 'branch' | 'detached';
21
+ prNumber: number | null;
22
+ prState: string | null;
23
+ hasChanges: boolean;
24
+ }
25
+ /**
26
+ * Result from argument parsing - discriminated union for pure function
27
+ */
28
+ export type ParseResult = {
29
+ kind: 'success';
30
+ options: ListOptions;
31
+ } | {
32
+ kind: 'help';
33
+ } | {
34
+ kind: 'error';
35
+ message: string;
36
+ };
37
+ /**
38
+ * Type label with color name for CLI to apply
39
+ */
40
+ export interface TypeLabel {
41
+ text: string;
42
+ color: 'cyan' | 'green' | 'yellow' | 'red' | 'blue' | 'dim';
43
+ }
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC5C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;CAC7D"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * lswt 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/lswt/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * lswt worktree-info - gather worktree information with dependency injection
3
+ */
4
+ import type { Worktree } from '../git.js';
5
+ import type { ListOptions, WorktreeDisplay } 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<string | null>;
13
+ }
14
+ /**
15
+ * Gather worktree information - core business logic
16
+ * Uses dependency injection for testability
17
+ */
18
+ export declare function gatherWorktreeInfo(repoRoot: string, options: ListOptions, deps: GatherDeps): Promise<WorktreeDisplay[]>;
19
+ /**
20
+ * Create default dependencies using real implementations
21
+ */
22
+ export declare function createDefaultDeps(): GatherDeps;
23
+ //# sourceMappingURL=worktree-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-info.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/worktree-info.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG/D;;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,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,eAAe,EAAE,CAAC,CAuC5B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,CA0B9C"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * lswt 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
+ import { extractPrNumber, isMainWorktree, sortWorktrees } from './formatters.js';
9
+ /**
10
+ * Gather worktree information - core business logic
11
+ * Uses dependency injection for testability
12
+ */
13
+ export async function gatherWorktreeInfo(repoRoot, options, deps) {
14
+ const worktrees = deps.listWorktrees(repoRoot);
15
+ const result = [];
16
+ for (const wt of worktrees) {
17
+ const name = path.basename(wt.path);
18
+ const prNumber = extractPrNumber(wt.path);
19
+ const isMain = isMainWorktree(wt.path, repoRoot);
20
+ const hasChanges = deps.hasUncommittedChanges(wt.path);
21
+ let type;
22
+ let prState = null;
23
+ if (isMain) {
24
+ type = 'main';
25
+ }
26
+ else if (prNumber !== null) {
27
+ type = 'pr';
28
+ if (options.showStatus) {
29
+ prState = await deps.getPrState(prNumber);
30
+ }
31
+ }
32
+ else if (wt.branch) {
33
+ type = 'branch';
34
+ }
35
+ else {
36
+ type = 'detached';
37
+ }
38
+ result.push({
39
+ path: wt.path,
40
+ name,
41
+ branch: wt.branch,
42
+ commit: wt.commit,
43
+ type,
44
+ prNumber,
45
+ prState,
46
+ hasChanges,
47
+ });
48
+ }
49
+ return sortWorktrees(result);
50
+ }
51
+ /**
52
+ * Create default dependencies using real implementations
53
+ */
54
+ export function createDefaultDeps() {
55
+ return {
56
+ listWorktrees: (cwd) => git.listWorktrees(cwd),
57
+ hasUncommittedChanges: (worktreePath) => {
58
+ try {
59
+ const status = execSync('git status --porcelain', {
60
+ cwd: worktreePath,
61
+ encoding: 'utf-8',
62
+ stdio: ['pipe', 'pipe', 'pipe'],
63
+ }).trim();
64
+ return status.length > 0;
65
+ }
66
+ catch {
67
+ return false;
68
+ }
69
+ },
70
+ getPrState: async (prNumber) => {
71
+ try {
72
+ const pr = github.getPr(prNumber);
73
+ return pr?.state ?? null;
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ },
79
+ };
80
+ }
81
+ //# sourceMappingURL=worktree-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-info.js","sourceRoot":"","sources":["../../../src/lib/lswt/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/lswt/worktree-info.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,190 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { gatherWorktreeInfo, createDefaultDeps } from './worktree-info.js';
3
+ describe('lswt/worktree-info', () => {
4
+ const makeWorktree = (overrides = {}) => ({
5
+ path: '/home/user/repo',
6
+ branch: 'main',
7
+ commit: 'abc123',
8
+ isMain: true,
9
+ isBare: false,
10
+ isLocked: false,
11
+ isPrunable: false,
12
+ ...overrides,
13
+ });
14
+ const makeDeps = (overrides = {}) => ({
15
+ listWorktrees: () => [],
16
+ hasUncommittedChanges: () => false,
17
+ getPrState: async () => null,
18
+ ...overrides,
19
+ });
20
+ const defaultOptions = {
21
+ showStatus: false,
22
+ json: false,
23
+ verbose: false,
24
+ };
25
+ describe('gatherWorktreeInfo', () => {
26
+ it('returns empty array when no worktrees', async () => {
27
+ const deps = makeDeps({ listWorktrees: () => [] });
28
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
29
+ expect(result).toEqual([]);
30
+ });
31
+ it('identifies main worktree', async () => {
32
+ const worktrees = [makeWorktree({ path: '/home/user/repo', branch: 'main' })];
33
+ const deps = makeDeps({ listWorktrees: () => worktrees });
34
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
35
+ expect(result).toHaveLength(1);
36
+ expect(result[0].type).toBe('main');
37
+ expect(result[0].name).toBe('repo');
38
+ });
39
+ it('identifies PR worktree from path pattern', async () => {
40
+ const worktrees = [
41
+ makeWorktree({ path: '/home/user/repo', branch: 'main' }),
42
+ makeWorktree({ path: '/home/user/repo.pr42', branch: 'feature', isMain: false }),
43
+ ];
44
+ const deps = makeDeps({ listWorktrees: () => worktrees });
45
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
46
+ expect(result).toHaveLength(2);
47
+ expect(result[0].type).toBe('main');
48
+ expect(result[1].type).toBe('pr');
49
+ expect(result[1].prNumber).toBe(42);
50
+ });
51
+ it('identifies branch worktree', async () => {
52
+ const worktrees = [
53
+ makeWorktree({ path: '/home/user/repo', branch: 'main' }),
54
+ makeWorktree({ path: '/home/user/feature-branch', branch: 'feature', isMain: false }),
55
+ ];
56
+ const deps = makeDeps({ listWorktrees: () => worktrees });
57
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
58
+ expect(result).toHaveLength(2);
59
+ const branchWorktree = result.find((w) => w.name === 'feature-branch');
60
+ expect(branchWorktree?.type).toBe('branch');
61
+ });
62
+ it('identifies detached worktree', async () => {
63
+ const worktrees = [
64
+ makeWorktree({ path: '/home/user/repo', branch: 'main' }),
65
+ makeWorktree({ path: '/home/user/detached-wt', branch: null, isMain: false }),
66
+ ];
67
+ const deps = makeDeps({ listWorktrees: () => worktrees });
68
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
69
+ expect(result).toHaveLength(2);
70
+ const detachedWorktree = result.find((w) => w.name === 'detached-wt');
71
+ expect(detachedWorktree?.type).toBe('detached');
72
+ });
73
+ it('includes hasChanges from dependency', async () => {
74
+ const worktrees = [makeWorktree({ path: '/home/user/repo', branch: 'main' })];
75
+ const deps = makeDeps({
76
+ listWorktrees: () => worktrees,
77
+ hasUncommittedChanges: () => true,
78
+ });
79
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
80
+ expect(result[0].hasChanges).toBe(true);
81
+ });
82
+ it('does not fetch PR state when showStatus is false', async () => {
83
+ const worktrees = [
84
+ makeWorktree({ path: '/home/user/repo.pr1', branch: 'feature', isMain: false }),
85
+ ];
86
+ const getPrState = vi.fn().mockResolvedValue('OPEN');
87
+ const deps = makeDeps({
88
+ listWorktrees: () => worktrees,
89
+ getPrState,
90
+ });
91
+ await gatherWorktreeInfo('/home/user/other', { ...defaultOptions, showStatus: false }, deps);
92
+ expect(getPrState).not.toHaveBeenCalled();
93
+ });
94
+ it('fetches PR state when showStatus is true', async () => {
95
+ const worktrees = [
96
+ makeWorktree({ path: '/home/user/repo.pr1', branch: 'feature', isMain: false }),
97
+ ];
98
+ const getPrState = vi.fn().mockResolvedValue('OPEN');
99
+ const deps = makeDeps({
100
+ listWorktrees: () => worktrees,
101
+ getPrState,
102
+ });
103
+ const result = await gatherWorktreeInfo('/home/user/other', { ...defaultOptions, showStatus: true }, deps);
104
+ expect(getPrState).toHaveBeenCalledWith(1);
105
+ expect(result[0].prState).toBe('OPEN');
106
+ });
107
+ it('handles null PR state', async () => {
108
+ const worktrees = [
109
+ makeWorktree({ path: '/home/user/repo.pr99', branch: 'feature', isMain: false }),
110
+ ];
111
+ const deps = makeDeps({
112
+ listWorktrees: () => worktrees,
113
+ getPrState: async () => null,
114
+ });
115
+ const result = await gatherWorktreeInfo('/home/user/other', { ...defaultOptions, showStatus: true }, deps);
116
+ expect(result[0].prState).toBeNull();
117
+ });
118
+ it('returns sorted worktrees (main first, then PRs by number)', async () => {
119
+ const worktrees = [
120
+ makeWorktree({ path: '/home/user/repo.pr10', branch: 'f1', isMain: false }),
121
+ makeWorktree({ path: '/home/user/repo.pr2', branch: 'f2', isMain: false }),
122
+ makeWorktree({ path: '/home/user/repo', branch: 'main' }),
123
+ ];
124
+ const deps = makeDeps({ listWorktrees: () => worktrees });
125
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
126
+ expect(result[0].type).toBe('main');
127
+ expect(result[1].prNumber).toBe(2);
128
+ expect(result[2].prNumber).toBe(10);
129
+ });
130
+ it('includes commit from worktree', async () => {
131
+ const worktrees = [makeWorktree({ path: '/home/user/repo', commit: 'deadbeef' })];
132
+ const deps = makeDeps({ listWorktrees: () => worktrees });
133
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
134
+ expect(result[0].commit).toBe('deadbeef');
135
+ });
136
+ it('includes branch from worktree', async () => {
137
+ const worktrees = [makeWorktree({ path: '/home/user/repo', branch: 'develop' })];
138
+ const deps = makeDeps({ listWorktrees: () => worktrees });
139
+ const result = await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
140
+ expect(result[0].branch).toBe('develop');
141
+ });
142
+ it('calls hasUncommittedChanges for each worktree', async () => {
143
+ const worktrees = [
144
+ makeWorktree({ path: '/home/user/repo', branch: 'main' }),
145
+ makeWorktree({ path: '/home/user/repo.pr1', branch: 'f1', isMain: false }),
146
+ ];
147
+ const hasUncommittedChanges = vi.fn().mockReturnValue(false);
148
+ const deps = makeDeps({
149
+ listWorktrees: () => worktrees,
150
+ hasUncommittedChanges,
151
+ });
152
+ await gatherWorktreeInfo('/home/user/repo', defaultOptions, deps);
153
+ expect(hasUncommittedChanges).toHaveBeenCalledTimes(2);
154
+ expect(hasUncommittedChanges).toHaveBeenCalledWith('/home/user/repo');
155
+ expect(hasUncommittedChanges).toHaveBeenCalledWith('/home/user/repo.pr1');
156
+ });
157
+ it('handles multiple PR state fetches', async () => {
158
+ const worktrees = [
159
+ makeWorktree({ path: '/home/user/repo.pr1', branch: 'f1', isMain: false }),
160
+ makeWorktree({ path: '/home/user/repo.pr2', branch: 'f2', isMain: false }),
161
+ makeWorktree({ path: '/home/user/repo.pr3', branch: 'f3', isMain: false }),
162
+ ];
163
+ const getPrState = vi
164
+ .fn()
165
+ .mockResolvedValueOnce('OPEN')
166
+ .mockResolvedValueOnce('MERGED')
167
+ .mockResolvedValueOnce('CLOSED');
168
+ const deps = makeDeps({
169
+ listWorktrees: () => worktrees,
170
+ getPrState,
171
+ });
172
+ const result = await gatherWorktreeInfo('/home/user/other', { ...defaultOptions, showStatus: true }, deps);
173
+ expect(result[0].prState).toBe('OPEN');
174
+ expect(result[1].prState).toBe('MERGED');
175
+ expect(result[2].prState).toBe('CLOSED');
176
+ });
177
+ });
178
+ describe('createDefaultDeps', () => {
179
+ it('returns object with required methods', () => {
180
+ const deps = createDefaultDeps();
181
+ expect(deps).toHaveProperty('listWorktrees');
182
+ expect(deps).toHaveProperty('hasUncommittedChanges');
183
+ expect(deps).toHaveProperty('getPrState');
184
+ expect(typeof deps.listWorktrees).toBe('function');
185
+ expect(typeof deps.hasUncommittedChanges).toBe('function');
186
+ expect(typeof deps.getPrState).toBe('function');
187
+ });
188
+ });
189
+ });
190
+ //# sourceMappingURL=worktree-info.test.js.map