@camaradesuk/git-worktree-tools 1.2.0 → 1.3.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 (78) hide show
  1. package/README.md +33 -13
  2. package/dist/cli/cleanpr.test.js +12 -2
  3. package/dist/cli/cleanpr.test.js.map +1 -1
  4. package/dist/cli/lswt.js +8 -1
  5. package/dist/cli/lswt.js.map +1 -1
  6. package/dist/cli/lswt.test.js +16 -2
  7. package/dist/cli/lswt.test.js.map +1 -1
  8. package/dist/cli/newpr.js +4 -4
  9. package/dist/cli/newpr.js.map +1 -1
  10. package/dist/cli/newpr.test.js +121 -7
  11. package/dist/cli/newpr.test.js.map +1 -1
  12. package/dist/integration/newpr.integration.test.js +36 -0
  13. package/dist/integration/newpr.integration.test.js.map +1 -1
  14. package/dist/lib/config.d.ts +6 -0
  15. package/dist/lib/config.d.ts.map +1 -1
  16. package/dist/lib/config.js +1 -0
  17. package/dist/lib/config.js.map +1 -1
  18. package/dist/lib/git.test.js +58 -0
  19. package/dist/lib/git.test.js.map +1 -1
  20. package/dist/lib/github.test.js +20 -0
  21. package/dist/lib/github.test.js.map +1 -1
  22. package/dist/lib/lswt/action-executors.d.ts +32 -0
  23. package/dist/lib/lswt/action-executors.d.ts.map +1 -0
  24. package/dist/lib/lswt/action-executors.js +489 -0
  25. package/dist/lib/lswt/action-executors.js.map +1 -0
  26. package/dist/lib/lswt/action-executors.test.d.ts +2 -0
  27. package/dist/lib/lswt/action-executors.test.d.ts.map +1 -0
  28. package/dist/lib/lswt/action-executors.test.js +749 -0
  29. package/dist/lib/lswt/action-executors.test.js.map +1 -0
  30. package/dist/lib/lswt/actions.d.ts +25 -0
  31. package/dist/lib/lswt/actions.d.ts.map +1 -0
  32. package/dist/lib/lswt/actions.js +187 -0
  33. package/dist/lib/lswt/actions.js.map +1 -0
  34. package/dist/lib/lswt/actions.test.d.ts +2 -0
  35. package/dist/lib/lswt/actions.test.d.ts.map +1 -0
  36. package/dist/lib/lswt/actions.test.js +359 -0
  37. package/dist/lib/lswt/actions.test.js.map +1 -0
  38. package/dist/lib/lswt/args.d.ts.map +1 -1
  39. package/dist/lib/lswt/args.js +44 -8
  40. package/dist/lib/lswt/args.js.map +1 -1
  41. package/dist/lib/lswt/args.test.js +70 -10
  42. package/dist/lib/lswt/args.test.js.map +1 -1
  43. package/dist/lib/lswt/environment.d.ts +43 -0
  44. package/dist/lib/lswt/environment.d.ts.map +1 -0
  45. package/dist/lib/lswt/environment.js +143 -0
  46. package/dist/lib/lswt/environment.js.map +1 -0
  47. package/dist/lib/lswt/environment.test.d.ts +2 -0
  48. package/dist/lib/lswt/environment.test.d.ts.map +1 -0
  49. package/dist/lib/lswt/environment.test.js +339 -0
  50. package/dist/lib/lswt/environment.test.js.map +1 -0
  51. package/dist/lib/lswt/formatters.d.ts.map +1 -1
  52. package/dist/lib/lswt/formatters.js +1 -0
  53. package/dist/lib/lswt/formatters.js.map +1 -1
  54. package/dist/lib/lswt/formatters.test.js +26 -0
  55. package/dist/lib/lswt/formatters.test.js.map +1 -1
  56. package/dist/lib/lswt/index.d.ts +7 -2
  57. package/dist/lib/lswt/index.d.ts.map +1 -1
  58. package/dist/lib/lswt/index.js +7 -0
  59. package/dist/lib/lswt/index.js.map +1 -1
  60. package/dist/lib/lswt/interactive.d.ts +24 -0
  61. package/dist/lib/lswt/interactive.d.ts.map +1 -0
  62. package/dist/lib/lswt/interactive.js +245 -0
  63. package/dist/lib/lswt/interactive.js.map +1 -0
  64. package/dist/lib/lswt/interactive.test.d.ts +2 -0
  65. package/dist/lib/lswt/interactive.test.d.ts.map +1 -0
  66. package/dist/lib/lswt/interactive.test.js +383 -0
  67. package/dist/lib/lswt/interactive.test.js.map +1 -0
  68. package/dist/lib/lswt/types.d.ts +52 -1
  69. package/dist/lib/lswt/types.d.ts.map +1 -1
  70. package/dist/lib/lswt/worktree-info.d.ts +8 -1
  71. package/dist/lib/lswt/worktree-info.d.ts.map +1 -1
  72. package/dist/lib/lswt/worktree-info.js +14 -4
  73. package/dist/lib/lswt/worktree-info.js.map +1 -1
  74. package/dist/lib/lswt/worktree-info.test.js +153 -16
  75. package/dist/lib/lswt/worktree-info.test.js.map +1 -1
  76. package/dist/lib/prompts.test.js +208 -1
  77. package/dist/lib/prompts.test.js.map +1 -1
  78. package/package.json +13 -2
@@ -0,0 +1,359 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { buildActionMenu, formatWorktreeChoice, formatShortcutLegend, getActionShortcut, ACTION_SHORTCUTS, } from './actions.js';
3
+ describe('lswt/actions', () => {
4
+ const makeWorktree = (overrides = {}) => ({
5
+ path: '/home/user/repo',
6
+ name: 'repo',
7
+ branch: 'main',
8
+ commit: 'abc123',
9
+ type: 'main',
10
+ prNumber: null,
11
+ prState: null,
12
+ isDraft: null,
13
+ hasChanges: false,
14
+ ...overrides,
15
+ });
16
+ const makeEnv = (overrides = {}) => ({
17
+ hasVscode: true,
18
+ hasCursor: false,
19
+ defaultEditor: 'vscode',
20
+ platform: 'linux',
21
+ isInteractive: true,
22
+ shell: '/bin/bash',
23
+ gitVersion: { major: 2, minor: 39, patch: 0, raw: 'git version 2.39.0' },
24
+ ...overrides,
25
+ });
26
+ describe('ACTION_SHORTCUTS', () => {
27
+ it('has shortcuts for all main actions', () => {
28
+ expect(ACTION_SHORTCUTS.open_editor).toBe('e');
29
+ expect(ACTION_SHORTCUTS.open_terminal).toBe('t');
30
+ expect(ACTION_SHORTCUTS.open_pr_url).toBe('p');
31
+ expect(ACTION_SHORTCUTS.create_pr).toBe('p');
32
+ expect(ACTION_SHORTCUTS.show_details).toBe('d');
33
+ expect(ACTION_SHORTCUTS.copy_path).toBe('c');
34
+ expect(ACTION_SHORTCUTS.remove_worktree).toBe('r');
35
+ expect(ACTION_SHORTCUTS.link_configs).toBe('l');
36
+ expect(ACTION_SHORTCUTS.exit).toBe('q');
37
+ });
38
+ it('has null shortcut for back action', () => {
39
+ expect(ACTION_SHORTCUTS.back).toBeNull();
40
+ });
41
+ });
42
+ describe('getActionShortcut', () => {
43
+ it('returns shortcut for action', () => {
44
+ expect(getActionShortcut('open_editor')).toBe('e');
45
+ expect(getActionShortcut('open_terminal')).toBe('t');
46
+ expect(getActionShortcut('exit')).toBe('q');
47
+ });
48
+ it('returns null for back action', () => {
49
+ expect(getActionShortcut('back')).toBeNull();
50
+ });
51
+ });
52
+ describe('buildActionMenu', () => {
53
+ describe('for main worktree', () => {
54
+ it('includes common actions', () => {
55
+ const worktree = makeWorktree({ type: 'main' });
56
+ const env = makeEnv();
57
+ const menu = buildActionMenu(worktree, env);
58
+ const values = menu.map((m) => m.value);
59
+ expect(values).toContain('open_editor');
60
+ expect(values).toContain('open_terminal');
61
+ expect(values).toContain('copy_path');
62
+ expect(values).toContain('show_details');
63
+ expect(values).toContain('link_configs');
64
+ expect(values).toContain('back');
65
+ expect(values).toContain('exit');
66
+ });
67
+ it('does not include remove_worktree for main', () => {
68
+ const worktree = makeWorktree({ type: 'main' });
69
+ const env = makeEnv();
70
+ const menu = buildActionMenu(worktree, env);
71
+ const values = menu.map((m) => m.value);
72
+ expect(values).not.toContain('remove_worktree');
73
+ });
74
+ it('does not include PR actions for main', () => {
75
+ const worktree = makeWorktree({ type: 'main' });
76
+ const env = makeEnv();
77
+ const menu = buildActionMenu(worktree, env);
78
+ const values = menu.map((m) => m.value);
79
+ expect(values).not.toContain('open_pr_url');
80
+ expect(values).not.toContain('create_pr');
81
+ });
82
+ });
83
+ describe('for PR worktree', () => {
84
+ it('includes open_pr_url action', () => {
85
+ const worktree = makeWorktree({
86
+ type: 'pr',
87
+ prNumber: 123,
88
+ prState: 'OPEN',
89
+ });
90
+ const env = makeEnv();
91
+ const menu = buildActionMenu(worktree, env);
92
+ const values = menu.map((m) => m.value);
93
+ expect(values).toContain('open_pr_url');
94
+ });
95
+ it('includes remove_worktree action', () => {
96
+ const worktree = makeWorktree({
97
+ type: 'pr',
98
+ prNumber: 123,
99
+ prState: 'OPEN',
100
+ });
101
+ const env = makeEnv();
102
+ const menu = buildActionMenu(worktree, env);
103
+ const values = menu.map((m) => m.value);
104
+ expect(values).toContain('remove_worktree');
105
+ });
106
+ it('labels remove with PR status when merged', () => {
107
+ const worktree = makeWorktree({
108
+ type: 'pr',
109
+ prNumber: 123,
110
+ prState: 'MERGED',
111
+ });
112
+ const env = makeEnv();
113
+ const menu = buildActionMenu(worktree, env);
114
+ const removeAction = menu.find((m) => m.value === 'remove_worktree');
115
+ expect(removeAction?.name).toContain('merged');
116
+ });
117
+ it('labels remove with PR status when closed', () => {
118
+ const worktree = makeWorktree({
119
+ type: 'pr',
120
+ prNumber: 123,
121
+ prState: 'CLOSED',
122
+ });
123
+ const env = makeEnv();
124
+ const menu = buildActionMenu(worktree, env);
125
+ const removeAction = menu.find((m) => m.value === 'remove_worktree');
126
+ expect(removeAction?.name).toContain('closed');
127
+ });
128
+ it('does not include create_pr', () => {
129
+ const worktree = makeWorktree({
130
+ type: 'pr',
131
+ prNumber: 123,
132
+ prState: 'OPEN',
133
+ });
134
+ const env = makeEnv();
135
+ const menu = buildActionMenu(worktree, env);
136
+ const values = menu.map((m) => m.value);
137
+ expect(values).not.toContain('create_pr');
138
+ });
139
+ });
140
+ describe('for branch worktree', () => {
141
+ it('includes create_pr action', () => {
142
+ const worktree = makeWorktree({
143
+ type: 'branch',
144
+ branch: 'feature-branch',
145
+ });
146
+ const env = makeEnv();
147
+ const menu = buildActionMenu(worktree, env);
148
+ const values = menu.map((m) => m.value);
149
+ expect(values).toContain('create_pr');
150
+ });
151
+ it('includes remove_worktree action', () => {
152
+ const worktree = makeWorktree({
153
+ type: 'branch',
154
+ branch: 'feature-branch',
155
+ });
156
+ const env = makeEnv();
157
+ const menu = buildActionMenu(worktree, env);
158
+ const values = menu.map((m) => m.value);
159
+ expect(values).toContain('remove_worktree');
160
+ });
161
+ it('does not include open_pr_url', () => {
162
+ const worktree = makeWorktree({
163
+ type: 'branch',
164
+ branch: 'feature-branch',
165
+ });
166
+ const env = makeEnv();
167
+ const menu = buildActionMenu(worktree, env);
168
+ const values = menu.map((m) => m.value);
169
+ expect(values).not.toContain('open_pr_url');
170
+ });
171
+ });
172
+ describe('for detached worktree', () => {
173
+ it('includes remove_worktree action', () => {
174
+ const worktree = makeWorktree({
175
+ type: 'detached',
176
+ branch: null,
177
+ });
178
+ const env = makeEnv();
179
+ const menu = buildActionMenu(worktree, env);
180
+ const values = menu.map((m) => m.value);
181
+ expect(values).toContain('remove_worktree');
182
+ });
183
+ it('does not include PR-related actions', () => {
184
+ const worktree = makeWorktree({
185
+ type: 'detached',
186
+ branch: null,
187
+ });
188
+ const env = makeEnv();
189
+ const menu = buildActionMenu(worktree, env);
190
+ const values = menu.map((m) => m.value);
191
+ expect(values).not.toContain('open_pr_url');
192
+ expect(values).not.toContain('create_pr');
193
+ });
194
+ });
195
+ describe('editor action', () => {
196
+ it('is enabled when VSCode is available', () => {
197
+ const worktree = makeWorktree();
198
+ const env = makeEnv({ hasVscode: true, defaultEditor: 'vscode' });
199
+ const menu = buildActionMenu(worktree, env);
200
+ const editorAction = menu.find((m) => m.value === 'open_editor');
201
+ expect(editorAction?.disabled).toBeUndefined();
202
+ expect(editorAction?.name).toContain('VSCode');
203
+ });
204
+ it('is enabled when Cursor is available', () => {
205
+ const worktree = makeWorktree();
206
+ const env = makeEnv({
207
+ hasVscode: false,
208
+ hasCursor: true,
209
+ defaultEditor: 'cursor',
210
+ });
211
+ const menu = buildActionMenu(worktree, env);
212
+ const editorAction = menu.find((m) => m.value === 'open_editor');
213
+ expect(editorAction?.disabled).toBeUndefined();
214
+ expect(editorAction?.name).toContain('Cursor');
215
+ });
216
+ it('is disabled when no editor is available', () => {
217
+ const worktree = makeWorktree();
218
+ const env = makeEnv({
219
+ hasVscode: false,
220
+ hasCursor: false,
221
+ defaultEditor: null,
222
+ });
223
+ const menu = buildActionMenu(worktree, env);
224
+ const editorAction = menu.find((m) => m.value === 'open_editor');
225
+ expect(editorAction?.disabled).toBe('No editor found (VSCode or Cursor)');
226
+ });
227
+ });
228
+ describe('shortcuts', () => {
229
+ it('assigns shortcuts to actions', () => {
230
+ const worktree = makeWorktree({ type: 'pr', prNumber: 1 });
231
+ const env = makeEnv();
232
+ const menu = buildActionMenu(worktree, env);
233
+ const editorAction = menu.find((m) => m.value === 'open_editor');
234
+ const terminalAction = menu.find((m) => m.value === 'open_terminal');
235
+ const copyAction = menu.find((m) => m.value === 'copy_path');
236
+ const exitAction = menu.find((m) => m.value === 'exit');
237
+ expect(editorAction?.shortcut).toBe('e');
238
+ expect(terminalAction?.shortcut).toBe('t');
239
+ expect(copyAction?.shortcut).toBe('c');
240
+ expect(exitAction?.shortcut).toBe('q');
241
+ });
242
+ it('back action has no shortcut', () => {
243
+ const worktree = makeWorktree();
244
+ const env = makeEnv();
245
+ const menu = buildActionMenu(worktree, env);
246
+ const backAction = menu.find((m) => m.value === 'back');
247
+ expect(backAction?.shortcut).toBeUndefined();
248
+ });
249
+ });
250
+ });
251
+ describe('formatWorktreeChoice', () => {
252
+ it('formats main worktree', () => {
253
+ const worktree = makeWorktree({ type: 'main', hasChanges: false });
254
+ const result = formatWorktreeChoice(worktree);
255
+ expect(result).toContain('[main]');
256
+ expect(result).toContain('main');
257
+ expect(result).toContain('clean');
258
+ });
259
+ it('formats PR worktree with status', () => {
260
+ const worktree = makeWorktree({
261
+ type: 'pr',
262
+ prNumber: 42,
263
+ prState: 'OPEN',
264
+ branch: 'feat/something',
265
+ });
266
+ const result = formatWorktreeChoice(worktree);
267
+ expect(result).toContain('[PR #42]');
268
+ expect(result).toContain('feat/something');
269
+ expect(result).toContain('OPEN');
270
+ });
271
+ it('formats PR worktree as draft', () => {
272
+ const worktree = makeWorktree({
273
+ type: 'pr',
274
+ prNumber: 42,
275
+ prState: 'OPEN',
276
+ isDraft: true,
277
+ branch: 'feat/something',
278
+ });
279
+ const result = formatWorktreeChoice(worktree);
280
+ expect(result).toContain('[PR #42 DRAFT]');
281
+ });
282
+ it('formats branch worktree', () => {
283
+ const worktree = makeWorktree({
284
+ type: 'branch',
285
+ branch: 'feature-branch',
286
+ });
287
+ const result = formatWorktreeChoice(worktree);
288
+ expect(result).toContain('[branch]');
289
+ expect(result).toContain('feature-branch');
290
+ });
291
+ it('formats detached worktree', () => {
292
+ const worktree = makeWorktree({
293
+ type: 'detached',
294
+ branch: null,
295
+ });
296
+ const result = formatWorktreeChoice(worktree);
297
+ expect(result).toContain('[detached]');
298
+ expect(result).toContain('(detached)');
299
+ });
300
+ it('shows has changes indicator', () => {
301
+ const worktree = makeWorktree({
302
+ type: 'branch',
303
+ branch: 'feature',
304
+ hasChanges: true,
305
+ });
306
+ const result = formatWorktreeChoice(worktree);
307
+ expect(result).toContain('has changes');
308
+ });
309
+ });
310
+ describe('formatShortcutLegend', () => {
311
+ it('includes common shortcuts for all worktree types', () => {
312
+ const worktree = makeWorktree({ type: 'main' });
313
+ const result = formatShortcutLegend(worktree);
314
+ expect(result).toContain('e: editor');
315
+ expect(result).toContain('t: terminal');
316
+ expect(result).toContain('d: details');
317
+ expect(result).toContain('c: copy');
318
+ expect(result).toContain('l: link');
319
+ expect(result).toContain('q: quit');
320
+ });
321
+ it('excludes remove shortcut for main worktree', () => {
322
+ const worktree = makeWorktree({ type: 'main' });
323
+ const result = formatShortcutLegend(worktree);
324
+ expect(result).not.toContain('r: remove');
325
+ });
326
+ it('includes remove shortcut for non-main worktrees', () => {
327
+ const worktree = makeWorktree({
328
+ type: 'pr',
329
+ prNumber: 1,
330
+ prState: 'OPEN',
331
+ });
332
+ const result = formatShortcutLegend(worktree);
333
+ expect(result).toContain('r: remove');
334
+ });
335
+ it('shows PR shortcut for PR worktrees', () => {
336
+ const worktree = makeWorktree({
337
+ type: 'pr',
338
+ prNumber: 1,
339
+ prState: 'OPEN',
340
+ });
341
+ const result = formatShortcutLegend(worktree);
342
+ expect(result).toContain('p: PR');
343
+ });
344
+ it('shows create PR shortcut for branch worktrees', () => {
345
+ const worktree = makeWorktree({
346
+ type: 'branch',
347
+ branch: 'feature',
348
+ });
349
+ const result = formatShortcutLegend(worktree);
350
+ expect(result).toContain('p: create PR');
351
+ });
352
+ it('returns comma-separated list', () => {
353
+ const worktree = makeWorktree({ type: 'main' });
354
+ const result = formatShortcutLegend(worktree);
355
+ expect(result).toMatch(/^\w+: \w+, /);
356
+ });
357
+ });
358
+ });
359
+ //# sourceMappingURL=actions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.test.js","sourceRoot":"","sources":["../../../src/lib/lswt/actions.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,MAAM,YAAY,GAAG,CAAC,YAAsC,EAAE,EAAmB,EAAE,CAAC,CAAC;QACnF,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,KAAK;QACjB,GAAG,SAAS;KACb,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,CAAC,YAAsC,EAAE,EAAmB,EAAE,CAAC,CAAC;QAC9E,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,KAAK;QAChB,aAAa,EAAE,QAAQ;QACvB,QAAQ,EAAE,OAAO;QACjB,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,WAAW;QAClB,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,oBAAoB,EAAE;QACxE,GAAG,SAAS;KACb,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjD,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChD,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnD,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChD,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnD,MAAM,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrD,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;YACjC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;gBACjC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBAChD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;gBAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;gBACtC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;gBACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;gBACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBACjC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;gBACnD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBAChD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;gBAC9C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBAChD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;gBAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;YAC/B,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;gBACrC,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,IAAI;oBACV,QAAQ,EAAE,GAAG;oBACb,OAAO,EAAE,MAAM;iBAChB,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;gBACzC,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,IAAI;oBACV,QAAQ,EAAE,GAAG;oBACb,OAAO,EAAE,MAAM;iBAChB,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;gBAClD,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,IAAI;oBACV,QAAQ,EAAE,GAAG;oBACb,OAAO,EAAE,QAAQ;iBAClB,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,iBAAiB,CAAC,CAAC;gBACrE,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;gBAClD,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,IAAI;oBACV,QAAQ,EAAE,GAAG;oBACb,OAAO,EAAE,QAAQ;iBAClB,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,iBAAiB,CAAC,CAAC;gBACrE,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;gBACpC,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,IAAI;oBACV,QAAQ,EAAE,GAAG;oBACb,OAAO,EAAE,MAAM;iBAChB,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;YACnC,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;gBACnC,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,gBAAgB;iBACzB,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;gBACzC,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,gBAAgB;iBACzB,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;gBACtC,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,gBAAgB;iBACzB,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;YACrC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;gBACzC,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,IAAI;iBACb,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;gBAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,IAAI;iBACb,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;gBAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;YAC7B,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;gBAC7C,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAClE,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC;gBACjE,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;gBAC/C,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;gBAC7C,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,OAAO,CAAC;oBAClB,SAAS,EAAE,KAAK;oBAChB,SAAS,EAAE,IAAI;oBACf,aAAa,EAAE,QAAQ;iBACxB,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC;gBACjE,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;gBAC/C,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;gBACjD,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,OAAO,CAAC;oBAClB,SAAS,EAAE,KAAK;oBAChB,SAAS,EAAE,KAAK;oBAChB,aAAa,EAAE,IAAI;iBACpB,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC;gBACjE,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YAC5E,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;YACzB,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;gBACtC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC3D,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC;gBACjE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,eAAe,CAAC,CAAC;gBACrE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC;gBAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;gBAExD,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACzC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC3C,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACvC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;gBACrC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAE5C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;gBACxD,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;YAC/C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAC/B,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;YACnE,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,QAAQ,GAAG,YAAY,CAAC;gBAC5B,IAAI,EAAE,IAAI;gBACV,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,MAAM;gBACf,MAAM,EAAE,gBAAgB;aACzB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,QAAQ,GAAG,YAAY,CAAC;gBAC5B,IAAI,EAAE,IAAI;gBACV,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,MAAM;gBACf,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,gBAAgB;aACzB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;YACjC,MAAM,QAAQ,GAAG,YAAY,CAAC;gBAC5B,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,gBAAgB;aACzB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,QAAQ,GAAG,YAAY,CAAC;gBAC5B,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,QAAQ,GAAG,YAAY,CAAC;gBAC5B,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,SAAS;gBACjB,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,QAAQ,GAAG,YAAY,CAAC;gBAC5B,IAAI,EAAE,IAAI;gBACV,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,MAAM;aAChB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC;gBAC5B,IAAI,EAAE,IAAI;gBACV,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,MAAM;aAChB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,QAAQ,GAAG,YAAY,CAAC;gBAC5B,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAgCrD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAwBpC"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAgDrD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CA6CpC"}
@@ -10,6 +10,7 @@ export function parseArgs(argv) {
10
10
  showStatus: false,
11
11
  json: false,
12
12
  verbose: false,
13
+ interactive: undefined, // undefined = auto-detect based on TTY
13
14
  };
14
15
  for (const arg of argv) {
15
16
  switch (arg) {
@@ -28,12 +29,26 @@ export function parseArgs(argv) {
28
29
  case '--verbose':
29
30
  options.verbose = true;
30
31
  break;
32
+ case '-i':
33
+ case '--interactive':
34
+ options.interactive = true;
35
+ break;
36
+ case '--no-interactive':
37
+ options.interactive = false;
38
+ break;
31
39
  default:
32
40
  if (arg.startsWith('-')) {
33
41
  return { kind: 'error', message: `Unknown option: ${arg}` };
34
42
  }
35
43
  }
36
44
  }
45
+ // Validate: --json and --interactive cannot be used together
46
+ if (options.json && options.interactive === true) {
47
+ return {
48
+ kind: 'error',
49
+ message: '--json and --interactive cannot be used together',
50
+ };
51
+ }
37
52
  return { kind: 'success', options };
38
53
  }
39
54
  /**
@@ -46,19 +61,40 @@ USAGE
46
61
  lswt [options]
47
62
 
48
63
  OPTIONS
49
- -s, --status Include PR status from GitHub (open/merged/closed)
50
- -j, --json Output as JSON
51
- -v, --verbose Show more details (commit hashes, full paths)
52
- -h, --help Show this help message
64
+ -s, --status Include PR status from GitHub (open/merged/closed)
65
+ -j, --json Output as JSON
66
+ -v, --verbose Show more details (commit hashes, full paths)
67
+ -i, --interactive Enable interactive mode (default in TTY)
68
+ --no-interactive Disable interactive mode
69
+ -h, --help Show this help message
53
70
 
54
71
  EXAMPLES
55
- lswt # List all worktrees
56
- lswt --status # Include PR status (requires gh cli)
57
- lswt --json # Output as JSON for scripting
72
+ lswt # Interactive mode (default in terminal)
73
+ lswt --no-interactive # List-only mode
74
+ lswt --status # Include PR status (requires gh cli)
75
+ lswt --json # Output as JSON for scripting
76
+ lswt | cat # Automatically uses list mode when piped
77
+
78
+ INTERACTIVE MODE
79
+ When running in a terminal, lswt enters interactive mode where you can
80
+ select a worktree and perform actions like:
81
+ - Open in editor (VSCode/Cursor)
82
+ - Open terminal at worktree path
83
+ - Open PR in browser
84
+ - Create PR from branch
85
+ - Remove worktree
86
+ - Link config files
87
+ - Copy path to clipboard
88
+
89
+ SHORTCUTS (in interactive mode)
90
+ e - Open in editor t - Open terminal
91
+ p - Open/Create PR d - Show details
92
+ c - Copy path r - Remove worktree
93
+ l - Link configs q - Quit
58
94
 
59
95
  OUTPUT
60
96
  Shows each worktree with:
61
- - Type indicator: [main], [PR #123 OPEN], [branch], [detached]
97
+ - Type indicator: [main], [PR #123 OPEN], [PR #45 DRAFT], [branch], [detached]
62
98
  - Branch name
63
99
  - Path (relative or absolute based on context)
64
100
  - Uncommitted changes indicator
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../../../src/lib/lswt/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,OAAO,GAAgB;QAC3B,UAAU,EAAE,KAAK;QACjB,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,KAAK;KACf,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACX,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC1B,KAAK,IAAI,CAAC;YACV,KAAK,UAAU;gBACb,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;gBAC1B,MAAM;YACR,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACX,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;gBACpB,MAAM;YACR,KAAK,IAAI,CAAC;YACV,KAAK,WAAW;gBACd,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,MAAM;YACR;gBACE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,EAAE,EAAE,CAAC;gBAC9D,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;CAsBR,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../../src/lib/lswt/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,OAAO,GAAgB;QAC3B,UAAU,EAAE,KAAK;QACjB,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,SAAS,EAAE,uCAAuC;KAChE,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACX,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC1B,KAAK,IAAI,CAAC;YACV,KAAK,UAAU;gBACb,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;gBAC1B,MAAM;YACR,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACX,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;gBACpB,MAAM;YACR,KAAK,IAAI,CAAC;YACV,KAAK,WAAW;gBACd,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,MAAM;YACR,KAAK,IAAI,CAAC;YACV,KAAK,eAAe;gBAClB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;gBAC3B,MAAM;YACR,KAAK,kBAAkB;gBACrB,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC;gBAC5B,MAAM;YACR;gBACE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,EAAE,EAAE,CAAC;gBAC9D,CAAC;QACL,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QACjD,OAAO;YACL,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,kDAAkD;SAC5D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CR,CAAC;AACF,CAAC"}
@@ -6,63 +6,63 @@ describe('lswt/args', () => {
6
6
  const result = parseArgs([]);
7
7
  expect(result).toEqual({
8
8
  kind: 'success',
9
- options: { showStatus: false, json: false, verbose: false },
9
+ options: { showStatus: false, json: false, verbose: false, interactive: undefined },
10
10
  });
11
11
  });
12
12
  it('parses --status flag', () => {
13
13
  const result = parseArgs(['--status']);
14
14
  expect(result).toEqual({
15
15
  kind: 'success',
16
- options: { showStatus: true, json: false, verbose: false },
16
+ options: { showStatus: true, json: false, verbose: false, interactive: undefined },
17
17
  });
18
18
  });
19
19
  it('parses -s shorthand', () => {
20
20
  const result = parseArgs(['-s']);
21
21
  expect(result).toEqual({
22
22
  kind: 'success',
23
- options: { showStatus: true, json: false, verbose: false },
23
+ options: { showStatus: true, json: false, verbose: false, interactive: undefined },
24
24
  });
25
25
  });
26
26
  it('parses --json flag', () => {
27
27
  const result = parseArgs(['--json']);
28
28
  expect(result).toEqual({
29
29
  kind: 'success',
30
- options: { showStatus: false, json: true, verbose: false },
30
+ options: { showStatus: false, json: true, verbose: false, interactive: undefined },
31
31
  });
32
32
  });
33
33
  it('parses -j shorthand', () => {
34
34
  const result = parseArgs(['-j']);
35
35
  expect(result).toEqual({
36
36
  kind: 'success',
37
- options: { showStatus: false, json: true, verbose: false },
37
+ options: { showStatus: false, json: true, verbose: false, interactive: undefined },
38
38
  });
39
39
  });
40
40
  it('parses --verbose flag', () => {
41
41
  const result = parseArgs(['--verbose']);
42
42
  expect(result).toEqual({
43
43
  kind: 'success',
44
- options: { showStatus: false, json: false, verbose: true },
44
+ options: { showStatus: false, json: false, verbose: true, interactive: undefined },
45
45
  });
46
46
  });
47
47
  it('parses -v shorthand', () => {
48
48
  const result = parseArgs(['-v']);
49
49
  expect(result).toEqual({
50
50
  kind: 'success',
51
- options: { showStatus: false, json: false, verbose: true },
51
+ options: { showStatus: false, json: false, verbose: true, interactive: undefined },
52
52
  });
53
53
  });
54
54
  it('parses multiple flags', () => {
55
55
  const result = parseArgs(['-s', '-j', '-v']);
56
56
  expect(result).toEqual({
57
57
  kind: 'success',
58
- options: { showStatus: true, json: true, verbose: true },
58
+ options: { showStatus: true, json: true, verbose: true, interactive: undefined },
59
59
  });
60
60
  });
61
61
  it('parses combined long flags', () => {
62
62
  const result = parseArgs(['--status', '--json', '--verbose']);
63
63
  expect(result).toEqual({
64
64
  kind: 'success',
65
- options: { showStatus: true, json: true, verbose: true },
65
+ options: { showStatus: true, json: true, verbose: true, interactive: undefined },
66
66
  });
67
67
  });
68
68
  it('returns help for --help', () => {
@@ -91,7 +91,56 @@ describe('lswt/args', () => {
91
91
  const result = parseArgs(['something']);
92
92
  expect(result).toEqual({
93
93
  kind: 'success',
94
- options: { showStatus: false, json: false, verbose: false },
94
+ options: { showStatus: false, json: false, verbose: false, interactive: undefined },
95
+ });
96
+ });
97
+ it('parses --interactive flag', () => {
98
+ const result = parseArgs(['--interactive']);
99
+ expect(result).toEqual({
100
+ kind: 'success',
101
+ options: { showStatus: false, json: false, verbose: false, interactive: true },
102
+ });
103
+ });
104
+ it('parses -i shorthand', () => {
105
+ const result = parseArgs(['-i']);
106
+ expect(result).toEqual({
107
+ kind: 'success',
108
+ options: { showStatus: false, json: false, verbose: false, interactive: true },
109
+ });
110
+ });
111
+ it('parses --no-interactive flag', () => {
112
+ const result = parseArgs(['--no-interactive']);
113
+ expect(result).toEqual({
114
+ kind: 'success',
115
+ options: { showStatus: false, json: false, verbose: false, interactive: false },
116
+ });
117
+ });
118
+ it('returns error when --json and --interactive are used together', () => {
119
+ const result = parseArgs(['--json', '--interactive']);
120
+ expect(result).toEqual({
121
+ kind: 'error',
122
+ message: '--json and --interactive cannot be used together',
123
+ });
124
+ });
125
+ it('returns error when -j and -i are used together', () => {
126
+ const result = parseArgs(['-j', '-i']);
127
+ expect(result).toEqual({
128
+ kind: 'error',
129
+ message: '--json and --interactive cannot be used together',
130
+ });
131
+ });
132
+ it('allows --json with --no-interactive', () => {
133
+ const result = parseArgs(['--json', '--no-interactive']);
134
+ expect(result).toEqual({
135
+ kind: 'success',
136
+ options: { showStatus: false, json: true, verbose: false, interactive: false },
137
+ });
138
+ });
139
+ it('parses --interactive with other flags', () => {
140
+ const result = parseArgs(['--status', '--interactive', '--verbose']);
141
+ expect(result).toEqual({
142
+ kind: 'success',
143
+ options: { showStatus: true, json: false, verbose: true, interactive: true },
95
144
  });
96
145
  });
97
146
  it('stops processing after help flag', () => {
@@ -114,6 +163,8 @@ describe('lswt/args', () => {
114
163
  expect(help).toContain('--json');
115
164
  expect(help).toContain('--verbose');
116
165
  expect(help).toContain('--help');
166
+ expect(help).toContain('--interactive');
167
+ expect(help).toContain('--no-interactive');
117
168
  });
118
169
  it('returns help text containing short options', () => {
119
170
  const help = getHelpText();
@@ -121,6 +172,15 @@ describe('lswt/args', () => {
121
172
  expect(help).toContain('-j');
122
173
  expect(help).toContain('-v');
123
174
  expect(help).toContain('-h');
175
+ expect(help).toContain('-i');
176
+ });
177
+ it('returns help text containing interactive mode section', () => {
178
+ const help = getHelpText();
179
+ expect(help).toContain('INTERACTIVE MODE');
180
+ });
181
+ it('returns help text containing shortcuts section', () => {
182
+ const help = getHelpText();
183
+ expect(help).toContain('SHORTCUTS');
124
184
  });
125
185
  it('returns help text containing usage section', () => {
126
186
  const help = getHelpText();