@camaradesuk/git-worktree-tools 1.7.0 → 1.9.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 (295) hide show
  1. package/README.md +69 -8
  2. package/dist/cli/cleanpr.js +11 -5
  3. package/dist/cli/cleanpr.js.map +1 -1
  4. package/dist/cli/cleanpr.test.js +12 -1
  5. package/dist/cli/cleanpr.test.js.map +1 -1
  6. package/dist/cli/newpr.js +302 -37
  7. package/dist/cli/newpr.js.map +1 -1
  8. package/dist/cli/newpr.test.js +336 -9
  9. package/dist/cli/newpr.test.js.map +1 -1
  10. package/dist/cli/prs.d.ts +22 -0
  11. package/dist/cli/prs.d.ts.map +1 -0
  12. package/dist/cli/prs.js +275 -0
  13. package/dist/cli/prs.js.map +1 -0
  14. package/dist/cli/prs.test.d.ts +8 -0
  15. package/dist/cli/prs.test.d.ts.map +1 -0
  16. package/dist/cli/prs.test.js +410 -0
  17. package/dist/cli/prs.test.js.map +1 -0
  18. package/dist/cli/wt/interactive-menu.d.ts +2 -0
  19. package/dist/cli/wt/interactive-menu.d.ts.map +1 -1
  20. package/dist/cli/wt/interactive-menu.js +17 -0
  21. package/dist/cli/wt/interactive-menu.js.map +1 -1
  22. package/dist/cli/wt/interactive-menu.test.js +28 -0
  23. package/dist/cli/wt/interactive-menu.test.js.map +1 -1
  24. package/dist/cli/wt/prs.d.ts +21 -0
  25. package/dist/cli/wt/prs.d.ts.map +1 -0
  26. package/dist/cli/wt/prs.js +251 -0
  27. package/dist/cli/wt/prs.js.map +1 -0
  28. package/dist/cli/wt/prs.test.d.ts +5 -0
  29. package/dist/cli/wt/prs.test.d.ts.map +1 -0
  30. package/dist/cli/wt/prs.test.js +410 -0
  31. package/dist/cli/wt/prs.test.js.map +1 -0
  32. package/dist/cli/wt.d.ts +1 -0
  33. package/dist/cli/wt.d.ts.map +1 -1
  34. package/dist/cli/wt.js +5 -0
  35. package/dist/cli/wt.js.map +1 -1
  36. package/dist/cli/wtconfig.d.ts +1 -0
  37. package/dist/cli/wtconfig.d.ts.map +1 -1
  38. package/dist/cli/wtconfig.js +115 -0
  39. package/dist/cli/wtconfig.js.map +1 -1
  40. package/dist/cli/wtconfig.test.js +6 -0
  41. package/dist/cli/wtconfig.test.js.map +1 -1
  42. package/dist/cli/wtlink.d.ts +2 -1
  43. package/dist/cli/wtlink.d.ts.map +1 -1
  44. package/dist/cli/wtlink.js +60 -2
  45. package/dist/cli/wtlink.js.map +1 -1
  46. package/dist/e2e/cli.e2e.test.js +6 -2
  47. package/dist/e2e/cli.e2e.test.js.map +1 -1
  48. package/dist/e2e/helpers/cli-runner.d.ts.map +1 -1
  49. package/dist/e2e/helpers/cli-runner.js +1 -0
  50. package/dist/e2e/helpers/cli-runner.js.map +1 -1
  51. package/dist/e2e/helpers/gh-mock.d.ts.map +1 -1
  52. package/dist/e2e/helpers/gh-mock.js +55 -1
  53. package/dist/e2e/helpers/gh-mock.js.map +1 -1
  54. package/dist/e2e/helpers/pty-wrapper.d.ts +15 -0
  55. package/dist/e2e/helpers/pty-wrapper.d.ts.map +1 -1
  56. package/dist/e2e/helpers/pty-wrapper.js +65 -0
  57. package/dist/e2e/helpers/pty-wrapper.js.map +1 -1
  58. package/dist/e2e/newpr-full-flow.e2e.test.js +1 -0
  59. package/dist/e2e/newpr-full-flow.e2e.test.js.map +1 -1
  60. package/dist/e2e/prs/prs.e2e.test.d.ts +7 -0
  61. package/dist/e2e/prs/prs.e2e.test.d.ts.map +1 -0
  62. package/dist/e2e/prs/prs.e2e.test.js +606 -0
  63. package/dist/e2e/prs/prs.e2e.test.js.map +1 -0
  64. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts +8 -0
  65. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts.map +1 -0
  66. package/dist/e2e/wt/interactive-menu.e2e.test.js +583 -0
  67. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +1 -0
  68. package/dist/e2e/wt/wt.e2e.test.js +217 -4
  69. package/dist/e2e/wt/wt.e2e.test.js.map +1 -1
  70. package/dist/integration/prs.integration.test.d.ts +8 -0
  71. package/dist/integration/prs.integration.test.d.ts.map +1 -0
  72. package/dist/integration/prs.integration.test.js +478 -0
  73. package/dist/integration/prs.integration.test.js.map +1 -0
  74. package/dist/lib/ai/types.d.ts +12 -0
  75. package/dist/lib/ai/types.d.ts.map +1 -1
  76. package/dist/lib/ai/types.js.map +1 -1
  77. package/dist/lib/cleanpr/worktree-info.d.ts.map +1 -1
  78. package/dist/lib/cleanpr/worktree-info.js +1 -6
  79. package/dist/lib/cleanpr/worktree-info.js.map +1 -1
  80. package/dist/lib/cleanpr/worktree-info.test.js +10 -13
  81. package/dist/lib/cleanpr/worktree-info.test.js.map +1 -1
  82. package/dist/lib/config-editor.d.ts.map +1 -1
  83. package/dist/lib/config-editor.js.map +1 -1
  84. package/dist/lib/config-migration/detector.d.ts +25 -0
  85. package/dist/lib/config-migration/detector.d.ts.map +1 -0
  86. package/dist/lib/config-migration/detector.js +372 -0
  87. package/dist/lib/config-migration/detector.js.map +1 -0
  88. package/dist/lib/config-migration/detector.test.d.ts +5 -0
  89. package/dist/lib/config-migration/detector.test.d.ts.map +1 -0
  90. package/dist/lib/config-migration/detector.test.js +201 -0
  91. package/dist/lib/config-migration/detector.test.js.map +1 -0
  92. package/dist/lib/config-migration/index.d.ts +29 -0
  93. package/dist/lib/config-migration/index.d.ts.map +1 -0
  94. package/dist/lib/config-migration/index.js +33 -0
  95. package/dist/lib/config-migration/index.js.map +1 -0
  96. package/dist/lib/config-migration/reporter.d.ts +53 -0
  97. package/dist/lib/config-migration/reporter.d.ts.map +1 -0
  98. package/dist/lib/config-migration/reporter.js +257 -0
  99. package/dist/lib/config-migration/reporter.js.map +1 -0
  100. package/dist/lib/config-migration/reporter.test.d.ts +5 -0
  101. package/dist/lib/config-migration/reporter.test.d.ts.map +1 -0
  102. package/dist/lib/config-migration/reporter.test.js +305 -0
  103. package/dist/lib/config-migration/reporter.test.js.map +1 -0
  104. package/dist/lib/config-migration/runner.d.ts +46 -0
  105. package/dist/lib/config-migration/runner.d.ts.map +1 -0
  106. package/dist/lib/config-migration/runner.js +364 -0
  107. package/dist/lib/config-migration/runner.js.map +1 -0
  108. package/dist/lib/config-migration/runner.test.d.ts +5 -0
  109. package/dist/lib/config-migration/runner.test.d.ts.map +1 -0
  110. package/dist/lib/config-migration/runner.test.js +235 -0
  111. package/dist/lib/config-migration/runner.test.js.map +1 -0
  112. package/dist/lib/config-migration/types.d.ts +120 -0
  113. package/dist/lib/config-migration/types.d.ts.map +1 -0
  114. package/dist/lib/config-migration/types.js +70 -0
  115. package/dist/lib/config-migration/types.js.map +1 -0
  116. package/dist/lib/config-validation.d.ts.map +1 -1
  117. package/dist/lib/config-validation.js +62 -0
  118. package/dist/lib/config-validation.js.map +1 -1
  119. package/dist/lib/config-validation.test.js +25 -0
  120. package/dist/lib/config-validation.test.js.map +1 -1
  121. package/dist/lib/config.d.ts +65 -7
  122. package/dist/lib/config.d.ts.map +1 -1
  123. package/dist/lib/config.js +12 -0
  124. package/dist/lib/config.js.map +1 -1
  125. package/dist/lib/git.d.ts +32 -0
  126. package/dist/lib/git.d.ts.map +1 -1
  127. package/dist/lib/git.js +95 -1
  128. package/dist/lib/git.js.map +1 -1
  129. package/dist/lib/git.test.js +118 -1
  130. package/dist/lib/git.test.js.map +1 -1
  131. package/dist/lib/github.d.ts +41 -0
  132. package/dist/lib/github.d.ts.map +1 -1
  133. package/dist/lib/github.js +109 -0
  134. package/dist/lib/github.js.map +1 -1
  135. package/dist/lib/global-check.d.ts +2 -2
  136. package/dist/lib/global-check.js +3 -3
  137. package/dist/lib/global-check.js.map +1 -1
  138. package/dist/lib/global-check.test.js +3 -6
  139. package/dist/lib/global-check.test.js.map +1 -1
  140. package/dist/lib/hooks/confirmation.d.ts +49 -0
  141. package/dist/lib/hooks/confirmation.d.ts.map +1 -0
  142. package/dist/lib/hooks/confirmation.js +147 -0
  143. package/dist/lib/hooks/confirmation.js.map +1 -0
  144. package/dist/lib/hooks/confirmation.test.d.ts +7 -0
  145. package/dist/lib/hooks/confirmation.test.d.ts.map +1 -0
  146. package/dist/lib/hooks/confirmation.test.js +300 -0
  147. package/dist/lib/hooks/confirmation.test.js.map +1 -0
  148. package/dist/lib/hooks/executor.d.ts +16 -1
  149. package/dist/lib/hooks/executor.d.ts.map +1 -1
  150. package/dist/lib/hooks/executor.js +53 -4
  151. package/dist/lib/hooks/executor.js.map +1 -1
  152. package/dist/lib/hooks/index.d.ts +4 -2
  153. package/dist/lib/hooks/index.d.ts.map +1 -1
  154. package/dist/lib/hooks/index.js +3 -2
  155. package/dist/lib/hooks/index.js.map +1 -1
  156. package/dist/lib/hooks/types.d.ts +16 -0
  157. package/dist/lib/hooks/types.d.ts.map +1 -1
  158. package/dist/lib/hooks/types.js +12 -0
  159. package/dist/lib/hooks/types.js.map +1 -1
  160. package/dist/lib/json-output.d.ts +1 -0
  161. package/dist/lib/json-output.d.ts.map +1 -1
  162. package/dist/lib/json-output.js +2 -0
  163. package/dist/lib/json-output.js.map +1 -1
  164. package/dist/lib/lswt/action-executors.d.ts +2 -0
  165. package/dist/lib/lswt/action-executors.d.ts.map +1 -1
  166. package/dist/lib/lswt/action-executors.js +6 -4
  167. package/dist/lib/lswt/action-executors.js.map +1 -1
  168. package/dist/lib/lswt/action-executors.test.js +8 -0
  169. package/dist/lib/lswt/action-executors.test.js.map +1 -1
  170. package/dist/lib/lswt/actions.d.ts +1 -0
  171. package/dist/lib/lswt/actions.d.ts.map +1 -1
  172. package/dist/lib/lswt/actions.js +38 -10
  173. package/dist/lib/lswt/actions.js.map +1 -1
  174. package/dist/lib/lswt/actions.test.js +34 -22
  175. package/dist/lib/lswt/actions.test.js.map +1 -1
  176. package/dist/lib/lswt/environment.d.ts +21 -2
  177. package/dist/lib/lswt/environment.d.ts.map +1 -1
  178. package/dist/lib/lswt/environment.js +73 -32
  179. package/dist/lib/lswt/environment.js.map +1 -1
  180. package/dist/lib/lswt/environment.test.js +79 -1
  181. package/dist/lib/lswt/environment.test.js.map +1 -1
  182. package/dist/lib/lswt/interactive.js +8 -8
  183. package/dist/lib/lswt/interactive.js.map +1 -1
  184. package/dist/lib/lswt/worktree-info.d.ts.map +1 -1
  185. package/dist/lib/lswt/worktree-info.js +1 -6
  186. package/dist/lib/lswt/worktree-info.js.map +1 -1
  187. package/dist/lib/lswt/worktree-info.test.js +5 -17
  188. package/dist/lib/lswt/worktree-info.test.js.map +1 -1
  189. package/dist/lib/newpr/args.d.ts.map +1 -1
  190. package/dist/lib/newpr/args.js +15 -1
  191. package/dist/lib/newpr/args.js.map +1 -1
  192. package/dist/lib/newpr/hook-runner.d.ts +11 -0
  193. package/dist/lib/newpr/hook-runner.d.ts.map +1 -1
  194. package/dist/lib/newpr/hook-runner.js +49 -1
  195. package/dist/lib/newpr/hook-runner.js.map +1 -1
  196. package/dist/lib/newpr/hook-runner.test.js +121 -0
  197. package/dist/lib/newpr/hook-runner.test.js.map +1 -1
  198. package/dist/lib/newpr/plan-generator.d.ts +121 -0
  199. package/dist/lib/newpr/plan-generator.d.ts.map +1 -0
  200. package/dist/lib/newpr/plan-generator.js +185 -0
  201. package/dist/lib/newpr/plan-generator.js.map +1 -0
  202. package/dist/lib/newpr/plan-generator.test.d.ts +7 -0
  203. package/dist/lib/newpr/plan-generator.test.d.ts.map +1 -0
  204. package/dist/lib/newpr/plan-generator.test.js +387 -0
  205. package/dist/lib/newpr/plan-generator.test.js.map +1 -0
  206. package/dist/lib/newpr/types.d.ts +6 -0
  207. package/dist/lib/newpr/types.d.ts.map +1 -1
  208. package/dist/lib/prompts.d.ts.map +1 -1
  209. package/dist/lib/prompts.js +16 -12
  210. package/dist/lib/prompts.js.map +1 -1
  211. package/dist/lib/prs/actions.d.ts +74 -0
  212. package/dist/lib/prs/actions.d.ts.map +1 -0
  213. package/dist/lib/prs/actions.js +446 -0
  214. package/dist/lib/prs/actions.js.map +1 -0
  215. package/dist/lib/prs/actions.test.d.ts +5 -0
  216. package/dist/lib/prs/actions.test.d.ts.map +1 -0
  217. package/dist/lib/prs/actions.test.js +356 -0
  218. package/dist/lib/prs/actions.test.js.map +1 -0
  219. package/dist/lib/prs/data.d.ts +48 -0
  220. package/dist/lib/prs/data.d.ts.map +1 -0
  221. package/dist/lib/prs/data.js +171 -0
  222. package/dist/lib/prs/data.js.map +1 -0
  223. package/dist/lib/prs/data.test.d.ts +5 -0
  224. package/dist/lib/prs/data.test.d.ts.map +1 -0
  225. package/dist/lib/prs/data.test.js +417 -0
  226. package/dist/lib/prs/data.test.js.map +1 -0
  227. package/dist/lib/prs/details.d.ts +57 -0
  228. package/dist/lib/prs/details.d.ts.map +1 -0
  229. package/dist/lib/prs/details.js +246 -0
  230. package/dist/lib/prs/details.js.map +1 -0
  231. package/dist/lib/prs/details.test.d.ts +5 -0
  232. package/dist/lib/prs/details.test.d.ts.map +1 -0
  233. package/dist/lib/prs/details.test.js +325 -0
  234. package/dist/lib/prs/details.test.js.map +1 -0
  235. package/dist/lib/prs/filters.d.ts +56 -0
  236. package/dist/lib/prs/filters.d.ts.map +1 -0
  237. package/dist/lib/prs/filters.js +171 -0
  238. package/dist/lib/prs/filters.js.map +1 -0
  239. package/dist/lib/prs/filters.test.d.ts +5 -0
  240. package/dist/lib/prs/filters.test.d.ts.map +1 -0
  241. package/dist/lib/prs/filters.test.js +312 -0
  242. package/dist/lib/prs/filters.test.js.map +1 -0
  243. package/dist/lib/prs/formatters.d.ts +83 -0
  244. package/dist/lib/prs/formatters.d.ts.map +1 -0
  245. package/dist/lib/prs/formatters.js +389 -0
  246. package/dist/lib/prs/formatters.js.map +1 -0
  247. package/dist/lib/prs/formatters.test.d.ts +2 -0
  248. package/dist/lib/prs/formatters.test.d.ts.map +1 -0
  249. package/dist/lib/prs/formatters.test.js +387 -0
  250. package/dist/lib/prs/formatters.test.js.map +1 -0
  251. package/dist/lib/prs/interactive.d.ts +50 -0
  252. package/dist/lib/prs/interactive.d.ts.map +1 -0
  253. package/dist/lib/prs/interactive.js +453 -0
  254. package/dist/lib/prs/interactive.js.map +1 -0
  255. package/dist/lib/prs/interactive.test.d.ts +5 -0
  256. package/dist/lib/prs/interactive.test.d.ts.map +1 -0
  257. package/dist/lib/prs/interactive.test.js +364 -0
  258. package/dist/lib/prs/interactive.test.js.map +1 -0
  259. package/dist/lib/prs/types.d.ts +152 -0
  260. package/dist/lib/prs/types.d.ts.map +1 -0
  261. package/dist/lib/prs/types.js +17 -0
  262. package/dist/lib/prs/types.js.map +1 -0
  263. package/dist/lib/wtconfig/environment.d.ts +18 -1
  264. package/dist/lib/wtconfig/environment.d.ts.map +1 -1
  265. package/dist/lib/wtconfig/environment.js +60 -24
  266. package/dist/lib/wtconfig/environment.js.map +1 -1
  267. package/dist/lib/wtconfig/environment.test.js +45 -1
  268. package/dist/lib/wtconfig/environment.test.js.map +1 -1
  269. package/dist/lib/wtlink/config-manifest.d.ts +101 -0
  270. package/dist/lib/wtlink/config-manifest.d.ts.map +1 -0
  271. package/dist/lib/wtlink/config-manifest.js +219 -0
  272. package/dist/lib/wtlink/config-manifest.js.map +1 -0
  273. package/dist/lib/wtlink/config-manifest.test.d.ts +2 -0
  274. package/dist/lib/wtlink/config-manifest.test.d.ts.map +1 -0
  275. package/dist/lib/wtlink/config-manifest.test.js +486 -0
  276. package/dist/lib/wtlink/config-manifest.test.js.map +1 -0
  277. package/dist/lib/wtlink/link-configs.d.ts.map +1 -1
  278. package/dist/lib/wtlink/link-configs.js +36 -11
  279. package/dist/lib/wtlink/link-configs.js.map +1 -1
  280. package/dist/lib/wtlink/main-menu.d.ts.map +1 -1
  281. package/dist/lib/wtlink/main-menu.js +58 -50
  282. package/dist/lib/wtlink/main-menu.js.map +1 -1
  283. package/dist/lib/wtlink/main-menu.test.js +42 -40
  284. package/dist/lib/wtlink/main-menu.test.js.map +1 -1
  285. package/dist/lib/wtlink/manage-manifest.d.ts +9 -0
  286. package/dist/lib/wtlink/manage-manifest.d.ts.map +1 -1
  287. package/dist/lib/wtlink/manage-manifest.js +346 -25
  288. package/dist/lib/wtlink/manage-manifest.js.map +1 -1
  289. package/dist/lib/wtlink/manage-manifest.test.js +52 -1
  290. package/dist/lib/wtlink/manage-manifest.test.js.map +1 -1
  291. package/dist/lib/wtlink/validate-manifest.d.ts.map +1 -1
  292. package/dist/lib/wtlink/validate-manifest.js +27 -6
  293. package/dist/lib/wtlink/validate-manifest.js.map +1 -1
  294. package/package.json +2 -1
  295. package/schemas/worktreerc.schema.json +49 -1
@@ -0,0 +1,364 @@
1
+ /**
2
+ * Tests for PR interactive browser
3
+ */
4
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
5
+ import { getActionForShortcut, filterPrsBySearch, formatPrChoice, printPrHeader, runPrInteractiveMode, createDefaultPrInteractiveDeps, } from './interactive.js';
6
+ import { createDefaultFilterState } from './types.js';
7
+ // Helper to create mock PR display items
8
+ function createMockPr(overrides = {}) {
9
+ return {
10
+ number: 1,
11
+ title: 'Test PR',
12
+ state: 'OPEN',
13
+ isDraft: false,
14
+ url: 'https://github.com/test/repo/pull/1',
15
+ headBranch: 'feat/test',
16
+ baseBranch: 'main',
17
+ author: 'testuser',
18
+ createdAt: new Date().toISOString(),
19
+ updatedAt: new Date().toISOString(),
20
+ labels: [],
21
+ reviewDecision: null,
22
+ approvalCount: 0,
23
+ reviewCount: 0,
24
+ checksStatus: null,
25
+ additions: 10,
26
+ deletions: 5,
27
+ changedFiles: 2,
28
+ hasWorktree: false,
29
+ worktreePath: null,
30
+ ...overrides,
31
+ };
32
+ }
33
+ // Helper to create mock interactive deps with sensible defaults
34
+ function createMockDeps(overrides = {}) {
35
+ return {
36
+ selectPr: vi.fn().mockResolvedValue({ pr: null, action: null }),
37
+ pressEnterToContinue: vi.fn().mockResolvedValue(undefined),
38
+ showDetails: vi.fn().mockResolvedValue('back'),
39
+ executeAction: vi.fn().mockResolvedValue({ success: true }),
40
+ ...overrides,
41
+ };
42
+ }
43
+ describe('interactive', () => {
44
+ describe('getActionForShortcut', () => {
45
+ it('should return create_worktree for "w" when PR has no worktree', () => {
46
+ const pr = createMockPr({ hasWorktree: false });
47
+ expect(getActionForShortcut('w', pr)).toBe('create_worktree');
48
+ });
49
+ it('should return open_worktree for "w" when PR has worktree', () => {
50
+ const pr = createMockPr({ hasWorktree: true, worktreePath: '/path/to/worktree' });
51
+ expect(getActionForShortcut('w', pr)).toBe('open_worktree');
52
+ });
53
+ it('should return open_browser for "b"', () => {
54
+ const pr = createMockPr();
55
+ expect(getActionForShortcut('b', pr)).toBe('open_browser');
56
+ });
57
+ it('should return null for "e" when PR has no worktree', () => {
58
+ const pr = createMockPr({ hasWorktree: false });
59
+ expect(getActionForShortcut('e', pr)).toBe(null);
60
+ });
61
+ it('should return open_editor for "e" when PR has worktree', () => {
62
+ const pr = createMockPr({ hasWorktree: true, worktreePath: '/path/to/worktree' });
63
+ expect(getActionForShortcut('e', pr)).toBe('open_editor');
64
+ });
65
+ it('should return null for "t" when PR has no worktree', () => {
66
+ const pr = createMockPr({ hasWorktree: false });
67
+ expect(getActionForShortcut('t', pr)).toBe(null);
68
+ });
69
+ it('should return open_terminal for "t" when PR has worktree', () => {
70
+ const pr = createMockPr({ hasWorktree: true, worktreePath: '/path/to/worktree' });
71
+ expect(getActionForShortcut('t', pr)).toBe('open_terminal');
72
+ });
73
+ it('should return copy_url for "c"', () => {
74
+ const pr = createMockPr();
75
+ expect(getActionForShortcut('c', pr)).toBe('copy_url');
76
+ });
77
+ it('should return copy_number for "n"', () => {
78
+ const pr = createMockPr();
79
+ expect(getActionForShortcut('n', pr)).toBe('copy_number');
80
+ });
81
+ it('should return null for "d" (now a filter key, not a PR action)', () => {
82
+ const pr = createMockPr();
83
+ // 'd' is now used for drafts filter toggle, not show_details
84
+ expect(getActionForShortcut('d', pr)).toBe(null);
85
+ });
86
+ it('should return refresh for "r"', () => {
87
+ const pr = createMockPr();
88
+ expect(getActionForShortcut('r', pr)).toBe('refresh');
89
+ });
90
+ it('should return exit for "q"', () => {
91
+ const pr = createMockPr();
92
+ expect(getActionForShortcut('q', pr)).toBe('exit');
93
+ });
94
+ it('should return null for unknown key', () => {
95
+ const pr = createMockPr();
96
+ expect(getActionForShortcut('z', pr)).toBe(null);
97
+ });
98
+ });
99
+ describe('filterPrsBySearch', () => {
100
+ const prs = [
101
+ createMockPr({
102
+ number: 1,
103
+ title: 'Add dark mode',
104
+ author: 'alice',
105
+ headBranch: 'feat/dark-mode',
106
+ }),
107
+ createMockPr({ number: 2, title: 'Fix login bug', author: 'bob', headBranch: 'fix/login' }),
108
+ createMockPr({ number: 3, title: 'Update docs', author: 'alice', headBranch: 'docs/update' }),
109
+ ];
110
+ it('should return all PRs when no search pattern', () => {
111
+ const result = filterPrsBySearch(prs, '');
112
+ expect(result).toHaveLength(3);
113
+ expect(result.map((r) => r.originalIndex)).toEqual([0, 1, 2]);
114
+ });
115
+ it('should filter by title', () => {
116
+ const result = filterPrsBySearch(prs, 'dark');
117
+ expect(result).toHaveLength(1);
118
+ expect(result[0].pr.number).toBe(1);
119
+ });
120
+ it('should filter by PR number', () => {
121
+ const result = filterPrsBySearch(prs, '#2');
122
+ expect(result).toHaveLength(1);
123
+ expect(result[0].pr.number).toBe(2);
124
+ });
125
+ it('should filter by author', () => {
126
+ const result = filterPrsBySearch(prs, '@alice');
127
+ expect(result).toHaveLength(2);
128
+ expect(result.map((r) => r.pr.number)).toEqual([1, 3]);
129
+ });
130
+ it('should filter by branch name', () => {
131
+ const result = filterPrsBySearch(prs, 'feat/dark');
132
+ expect(result).toHaveLength(1);
133
+ expect(result[0].pr.number).toBe(1);
134
+ });
135
+ it('should be case-insensitive', () => {
136
+ const result = filterPrsBySearch(prs, 'DARK');
137
+ expect(result).toHaveLength(1);
138
+ expect(result[0].pr.number).toBe(1);
139
+ });
140
+ it('should preserve original indices', () => {
141
+ const result = filterPrsBySearch(prs, 'alice');
142
+ expect(result).toHaveLength(2);
143
+ expect(result[0].originalIndex).toBe(0);
144
+ expect(result[1].originalIndex).toBe(2);
145
+ });
146
+ });
147
+ describe('formatPrChoice', () => {
148
+ it('should format selected PR with indicator', () => {
149
+ const pr = createMockPr({ number: 42, title: 'Test PR' });
150
+ const result = formatPrChoice(pr, 4, true, 'preview');
151
+ expect(result).toContain('❯');
152
+ });
153
+ it('should format unselected PR without indicator', () => {
154
+ const pr = createMockPr({ number: 42, title: 'Test PR' });
155
+ const result = formatPrChoice(pr, 4, false, 'preview');
156
+ expect(result.startsWith(' ')).toBe(true);
157
+ expect(result).not.toContain('❯');
158
+ });
159
+ it('should include PR number', () => {
160
+ const pr = createMockPr({ number: 123, title: 'Test PR' });
161
+ const result = formatPrChoice(pr, 5, false, 'preview');
162
+ expect(result).toContain('#123');
163
+ });
164
+ });
165
+ describe('printPrHeader', () => {
166
+ let consoleSpy;
167
+ beforeEach(() => {
168
+ consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
169
+ });
170
+ afterEach(() => {
171
+ consoleSpy.mockRestore();
172
+ });
173
+ it('should print header, summary, and filter indicator', () => {
174
+ const prs = [createMockPr(), createMockPr({ state: 'MERGED' })];
175
+ const filterState = createDefaultFilterState();
176
+ printPrHeader('test-repo', prs, filterState);
177
+ expect(consoleSpy).toHaveBeenCalled();
178
+ const allOutput = consoleSpy.mock.calls.map((call) => call[0]).join('\n');
179
+ expect(allOutput).toContain('test-repo');
180
+ expect(allOutput).toContain('2 PRs');
181
+ expect(allOutput).toContain('Showing:');
182
+ });
183
+ });
184
+ describe('runPrInteractiveMode', () => {
185
+ let consoleSpy;
186
+ let clearSpy;
187
+ beforeEach(() => {
188
+ consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
189
+ clearSpy = vi.spyOn(console, 'clear').mockImplementation(() => { });
190
+ });
191
+ afterEach(() => {
192
+ consoleSpy.mockRestore();
193
+ clearSpy.mockRestore();
194
+ });
195
+ it('should stay interactive when no PRs found and allow exit', async () => {
196
+ const deps = createMockDeps({
197
+ selectPr: vi.fn().mockResolvedValue({ pr: null, action: 'exit' }),
198
+ });
199
+ await runPrInteractiveMode([], 'test-repo', 'preview', undefined, deps);
200
+ // Should still call selectPr to allow user to quit gracefully
201
+ expect(deps.selectPr).toHaveBeenCalledTimes(1);
202
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Goodbye'));
203
+ });
204
+ it('should exit on null PR selection (exit selected)', async () => {
205
+ const prs = [createMockPr()];
206
+ const deps = createMockDeps({
207
+ selectPr: vi.fn().mockResolvedValue({ pr: null, action: null }),
208
+ });
209
+ await runPrInteractiveMode(prs, 'test-repo', 'preview', undefined, deps);
210
+ expect(deps.selectPr).toHaveBeenCalledTimes(1);
211
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Goodbye'));
212
+ });
213
+ it('should exit on exit action', async () => {
214
+ const pr = createMockPr();
215
+ const deps = createMockDeps({
216
+ selectPr: vi.fn().mockResolvedValue({ pr, action: 'exit' }),
217
+ });
218
+ await runPrInteractiveMode([pr], 'test-repo', 'preview', undefined, deps);
219
+ expect(deps.selectPr).toHaveBeenCalledTimes(1);
220
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Goodbye'));
221
+ });
222
+ it('should execute action and show success message when action is selected', async () => {
223
+ const pr = createMockPr({ number: 42 });
224
+ let callCount = 0;
225
+ const mockExecuteAction = vi.fn().mockResolvedValue({
226
+ success: true,
227
+ message: 'Opened PR #42 in browser',
228
+ });
229
+ const deps = createMockDeps({
230
+ selectPr: vi.fn().mockImplementation(() => {
231
+ callCount++;
232
+ if (callCount === 1) {
233
+ return Promise.resolve({ pr, action: 'open_browser' });
234
+ }
235
+ return Promise.resolve({ pr: null, action: null });
236
+ }),
237
+ executeAction: mockExecuteAction,
238
+ });
239
+ await runPrInteractiveMode([pr], 'test-repo', 'preview', undefined, deps);
240
+ expect(mockExecuteAction).toHaveBeenCalledWith('open_browser', pr);
241
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Opened PR #42 in browser'));
242
+ expect(deps.pressEnterToContinue).toHaveBeenCalled();
243
+ });
244
+ it('should show detail view when PR is selected without action', async () => {
245
+ const pr = createMockPr({ number: 42, title: 'Test PR' });
246
+ let callCount = 0;
247
+ const mockShowDetails = vi.fn().mockResolvedValue('back');
248
+ const deps = createMockDeps({
249
+ selectPr: vi.fn().mockImplementation(() => {
250
+ callCount++;
251
+ if (callCount === 1) {
252
+ return Promise.resolve({ pr, action: null });
253
+ }
254
+ return Promise.resolve({ pr: null, action: null });
255
+ }),
256
+ showDetails: mockShowDetails,
257
+ });
258
+ await runPrInteractiveMode([pr], 'test-repo', 'preview', undefined, deps);
259
+ expect(mockShowDetails).toHaveBeenCalledWith(pr);
260
+ });
261
+ it('should switch to MERGED filter when filter_show_merged action is received', async () => {
262
+ const openPr = createMockPr({ number: 1, state: 'OPEN' });
263
+ const mergedPr = createMockPr({ number: 2, state: 'MERGED' });
264
+ let callCount = 0;
265
+ const deps = createMockDeps({
266
+ selectPr: vi.fn().mockImplementation(() => {
267
+ callCount++;
268
+ if (callCount === 1) {
269
+ // First call: switch to show MERGED only
270
+ return Promise.resolve({ pr: null, action: 'filter_show_merged' });
271
+ }
272
+ if (callCount === 2) {
273
+ // Second call: exit
274
+ return Promise.resolve({ pr: null, action: 'exit' });
275
+ }
276
+ return Promise.resolve({ pr: null, action: null });
277
+ }),
278
+ });
279
+ // Start with default filter (OPEN only), pass both PRs
280
+ await runPrInteractiveMode([openPr, mergedPr], 'test-repo', 'preview', undefined, deps);
281
+ // Should have been called twice - once for filter change, once for exit
282
+ expect(deps.selectPr).toHaveBeenCalledTimes(2);
283
+ });
284
+ it('should re-filter PRs after exclusive state selection', async () => {
285
+ const openPr = createMockPr({ number: 1, state: 'OPEN' });
286
+ const mergedPr = createMockPr({ number: 2, state: 'MERGED' });
287
+ const receivedPrs = [];
288
+ let callCount = 0;
289
+ const deps = createMockDeps({
290
+ selectPr: vi.fn().mockImplementation((prs) => {
291
+ receivedPrs.push([...prs]);
292
+ callCount++;
293
+ if (callCount === 1) {
294
+ // First call with OPEN filter: should see 1 PR (open)
295
+ return Promise.resolve({ pr: null, action: 'filter_show_merged' });
296
+ }
297
+ if (callCount === 2) {
298
+ // Second call after switching to MERGED: should see 1 PR (merged)
299
+ return Promise.resolve({ pr: null, action: 'filter_show_all' });
300
+ }
301
+ if (callCount === 3) {
302
+ // Third call after showing ALL: should see 2 PRs
303
+ return Promise.resolve({ pr: null, action: 'exit' });
304
+ }
305
+ return Promise.resolve({ pr: null, action: null });
306
+ }),
307
+ });
308
+ // Start with default filter (OPEN only)
309
+ await runPrInteractiveMode([openPr, mergedPr], 'test-repo', 'preview', undefined, deps);
310
+ // First call: OPEN only -> 1 PR (the open one)
311
+ expect(receivedPrs[0]).toHaveLength(1);
312
+ expect(receivedPrs[0][0].state).toBe('OPEN');
313
+ // Second call: MERGED only -> 1 PR (the merged one)
314
+ expect(receivedPrs[1]).toHaveLength(1);
315
+ expect(receivedPrs[1][0].state).toBe('MERGED');
316
+ // Third call: ALL states -> 2 PRs
317
+ expect(receivedPrs[2]).toHaveLength(2);
318
+ });
319
+ it('should cycle draft filter when filter_toggle_drafts action is received', async () => {
320
+ const regularPr = createMockPr({ number: 1, state: 'OPEN', isDraft: false });
321
+ const draftPr = createMockPr({ number: 2, state: 'OPEN', isDraft: true });
322
+ const receivedPrs = [];
323
+ let callCount = 0;
324
+ const deps = createMockDeps({
325
+ selectPr: vi.fn().mockImplementation((prs) => {
326
+ receivedPrs.push([...prs]);
327
+ callCount++;
328
+ if (callCount === 1) {
329
+ // First call: includes drafts (default) -> toggle to drafts only
330
+ return Promise.resolve({ pr: null, action: 'filter_toggle_drafts' });
331
+ }
332
+ if (callCount === 2) {
333
+ // Second call: drafts only -> toggle to exclude drafts
334
+ return Promise.resolve({ pr: null, action: 'filter_toggle_drafts' });
335
+ }
336
+ if (callCount === 3) {
337
+ // Third call: no drafts -> toggle back to include
338
+ return Promise.resolve({ pr: null, action: 'exit' });
339
+ }
340
+ return Promise.resolve({ pr: null, action: null });
341
+ }),
342
+ });
343
+ await runPrInteractiveMode([regularPr, draftPr], 'test-repo', 'preview', undefined, deps);
344
+ // First call: include drafts (default) -> 2 PRs
345
+ expect(receivedPrs[0]).toHaveLength(2);
346
+ // Second call: drafts only -> 1 PR (the draft)
347
+ expect(receivedPrs[1]).toHaveLength(1);
348
+ expect(receivedPrs[1][0].isDraft).toBe(true);
349
+ // Third call: no drafts -> 1 PR (the non-draft)
350
+ expect(receivedPrs[2]).toHaveLength(1);
351
+ expect(receivedPrs[2][0].isDraft).toBe(false);
352
+ });
353
+ });
354
+ describe('createDefaultPrInteractiveDeps', () => {
355
+ it('should return deps object with required functions', () => {
356
+ const deps = createDefaultPrInteractiveDeps();
357
+ expect(deps).toHaveProperty('selectPr');
358
+ expect(deps).toHaveProperty('pressEnterToContinue');
359
+ expect(typeof deps.selectPr).toBe('function');
360
+ expect(typeof deps.pressEnterToContinue).toBe('function');
361
+ });
362
+ });
363
+ });
364
+ //# sourceMappingURL=interactive.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.test.js","sourceRoot":"","sources":["../../../src/lib/prs/interactive.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Type definitions for PR browser feature
3
+ */
4
+ import type { PrListItem as GhPrListItem, ListPrsExtendedOptions as GhListPrsExtendedOptions } from '../github.js';
5
+ export type PrListItem = GhPrListItem;
6
+ export type ListPrsExtendedOptions = GhListPrsExtendedOptions;
7
+ /**
8
+ * PR display item with worktree correlation
9
+ */
10
+ export interface PrDisplayItem extends GhPrListItem {
11
+ /** Whether a local worktree exists for this PR's branch */
12
+ hasWorktree: boolean;
13
+ /** Path to the worktree (if exists) */
14
+ worktreePath: string | null;
15
+ }
16
+ /**
17
+ * Filter state for PR list
18
+ */
19
+ export interface PrFilterState {
20
+ /** Which PR states to show */
21
+ states: Set<'OPEN' | 'MERGED' | 'CLOSED'>;
22
+ /** How to handle drafts: true=include, false=exclude, 'only'=drafts only */
23
+ showDrafts: boolean | 'only';
24
+ /** Filter by labels (show PRs with ANY of these labels) */
25
+ labels: string[];
26
+ /** Filter by author (null = all authors) */
27
+ author: string | null;
28
+ /** Filter by worktree presence: true=only with WT, false=only without, null=all */
29
+ hasWorktree: boolean | null;
30
+ /** Fuzzy search query on title/number/author */
31
+ searchQuery: string;
32
+ }
33
+ /**
34
+ * Create default filter state (show open PRs)
35
+ */
36
+ export declare function createDefaultFilterState(): PrFilterState;
37
+ /**
38
+ * Actions available for PRs
39
+ */
40
+ export type PrAction = 'create_worktree' | 'open_worktree' | 'open_browser' | 'open_editor' | 'open_terminal' | 'copy_url' | 'copy_number' | 'show_details' | 'refresh' | 'back' | 'exit' | 'filter_show_open' | 'filter_show_merged' | 'filter_show_closed' | 'filter_show_all' | 'filter_toggle_drafts';
41
+ /**
42
+ * Result from executing a PR action
43
+ */
44
+ export interface PrActionResult {
45
+ /** Whether the action succeeded */
46
+ success: boolean;
47
+ /** Optional message to display */
48
+ message?: string;
49
+ /** Whether to refresh the PR list */
50
+ shouldRefresh?: boolean;
51
+ /** Whether to exit the interactive mode */
52
+ shouldExit?: boolean;
53
+ }
54
+ /**
55
+ * Selection result from the PR list
56
+ */
57
+ export interface PrSelectionResult {
58
+ /** Selected PR (null if exit selected) */
59
+ pr: PrDisplayItem | null;
60
+ /** Action triggered by shortcut key (null if Enter pressed) */
61
+ action: PrAction | null;
62
+ }
63
+ /**
64
+ * Options for the wt prs command
65
+ */
66
+ export interface PrsCommandOptions {
67
+ /** State filter */
68
+ state: 'open' | 'closed' | 'merged' | 'all';
69
+ /** Author filter */
70
+ author?: string;
71
+ /** Label filter */
72
+ label?: string[];
73
+ /** Show only drafts */
74
+ draft?: boolean;
75
+ /** Exclude drafts */
76
+ noDraft?: boolean;
77
+ /** Show only PRs with worktrees */
78
+ withWorktree?: boolean;
79
+ /** Maximum PRs to fetch */
80
+ limit: number;
81
+ /** Output as JSON */
82
+ json?: boolean;
83
+ /** Disable interactive mode */
84
+ noInteractive?: boolean;
85
+ /** Force refresh from GitHub */
86
+ refresh?: boolean;
87
+ }
88
+ /**
89
+ * PR cache entry
90
+ */
91
+ export interface PrCacheEntry {
92
+ /** Cached PR list */
93
+ prs: PrListItem[];
94
+ /** When the cache was populated */
95
+ timestamp: number;
96
+ /** Cache TTL in milliseconds */
97
+ ttl: number;
98
+ }
99
+ /**
100
+ * Dependencies for PR data operations (injectable for testing)
101
+ */
102
+ export interface PrDataDeps {
103
+ /** Fetch PRs from GitHub */
104
+ fetchPrs: (options: ListPrsExtendedOptions, cwd?: string) => PrListItem[];
105
+ /** Get worktree list */
106
+ getWorktrees: (cwd?: string) => Array<{
107
+ path: string;
108
+ branch: string | null;
109
+ }>;
110
+ /** Get current time (for cache testing) */
111
+ now: () => number;
112
+ }
113
+ /**
114
+ * Dependencies for interactive PR browser (injectable for testing)
115
+ */
116
+ export interface PrInteractiveDeps {
117
+ /** Select a PR from the list */
118
+ selectPr: (prs: PrDisplayItem[], filterState: PrFilterState) => Promise<PrSelectionResult>;
119
+ /** Show PR detail view */
120
+ showDetails: (pr: PrDisplayItem) => Promise<PrAction>;
121
+ /** Show filter menu */
122
+ showFilterMenu: (currentFilters: PrFilterState) => Promise<PrFilterState | null>;
123
+ /** Wait for user to press Enter */
124
+ pressEnterToContinue: () => Promise<void>;
125
+ }
126
+ /**
127
+ * JSON output for wt prs --json
128
+ */
129
+ export interface PrsJsonOutput {
130
+ /** Whether the command succeeded */
131
+ success: boolean;
132
+ /** Command name */
133
+ command: 'prs';
134
+ /** ISO timestamp */
135
+ timestamp: string;
136
+ /** PR data */
137
+ data: {
138
+ /** Total PRs fetched */
139
+ total: number;
140
+ /** Active filter state */
141
+ filters: {
142
+ states: string[];
143
+ showDrafts: boolean | 'only';
144
+ labels: string[];
145
+ author: string | null;
146
+ hasWorktree: boolean | null;
147
+ };
148
+ /** PR list */
149
+ prs: PrDisplayItem[];
150
+ };
151
+ }
152
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/prs/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Type definitions for PR browser feature
3
+ */
4
+ /**
5
+ * Create default filter state (show open PRs)
6
+ */
7
+ export function createDefaultFilterState() {
8
+ return {
9
+ states: new Set(['OPEN']),
10
+ showDrafts: true,
11
+ labels: [],
12
+ author: null,
13
+ hasWorktree: null,
14
+ searchQuery: '',
15
+ };
16
+ }
17
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/prs/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuCH;;GAEG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;QACzB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,IAAI;QACZ,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,EAAE;KAChB,CAAC;AACJ,CAAC"}
@@ -4,6 +4,23 @@
4
4
  * Detects installed tools and environment configuration for the setup wizard.
5
5
  */
6
6
  import type { EnvironmentInfo } from './types.js';
7
+ /**
8
+ * Dependencies for environment detection (injectable for testing)
9
+ */
10
+ export interface EnvironmentDeps {
11
+ /** Check if a command exists in PATH */
12
+ commandExists: (command: string) => boolean;
13
+ /** Run a command and return output, or null on error */
14
+ runCommand: (command: string, args: string[]) => string | null;
15
+ }
16
+ /**
17
+ * Create default environment dependencies
18
+ */
19
+ export declare function createDefaultEnvironmentDeps(): EnvironmentDeps;
20
+ /**
21
+ * Reset environment deps to defaults (for testing)
22
+ */
23
+ export declare function resetEnvironmentDeps(): void;
7
24
  /**
8
25
  * Detect default branch from git config or common conventions
9
26
  */
@@ -11,7 +28,7 @@ export declare function detectDefaultBranch(repoRoot?: string): string;
11
28
  /**
12
29
  * Detect full environment information
13
30
  */
14
- export declare function detectEnvironment(cwd?: string): EnvironmentInfo;
31
+ export declare function detectEnvironment(cwd?: string, deps?: EnvironmentDeps): EnvironmentInfo;
15
32
  /**
16
33
  * Get install command for detected package manager
17
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../../src/lib/wtconfig/environment.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAmLlD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAkB7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe,CAS/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAY3F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,EAC3B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GACtC,MAAM,GAAG,IAAI,CASf"}
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../../src/lib/wtconfig/environment.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,wDAAwD;IACxD,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI,CAAC;CAChE;AA6CD;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAK9D;AAKD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAwID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAkC7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,eAAe,CAYvF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAY3F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,EAC3B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GACtC,MAAM,GAAG,IAAI,CASf"}