@camaradesuk/git-worktree-tools 1.9.0 → 1.11.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 (531) hide show
  1. package/README.md +52 -31
  2. package/dist/cli/cleanpr.js +74 -53
  3. package/dist/cli/cleanpr.js.map +1 -1
  4. package/dist/cli/lswt.js +32 -56
  5. package/dist/cli/lswt.js.map +1 -1
  6. package/dist/cli/newpr.d.ts +13 -1
  7. package/dist/cli/newpr.d.ts.map +1 -1
  8. package/dist/cli/newpr.js +159 -153
  9. package/dist/cli/newpr.js.map +1 -1
  10. package/dist/cli/prs.d.ts +3 -10
  11. package/dist/cli/prs.d.ts.map +1 -1
  12. package/dist/cli/prs.js +6 -168
  13. package/dist/cli/prs.js.map +1 -1
  14. package/dist/cli/wt/clean.d.ts +6 -2
  15. package/dist/cli/wt/clean.d.ts.map +1 -1
  16. package/dist/cli/wt/clean.js +401 -20
  17. package/dist/cli/wt/clean.js.map +1 -1
  18. package/dist/cli/wt/completion.d.ts +3 -0
  19. package/dist/cli/wt/completion.d.ts.map +1 -1
  20. package/dist/cli/wt/completion.js +80 -9
  21. package/dist/cli/wt/completion.js.map +1 -1
  22. package/dist/cli/wt/config.d.ts +3 -1
  23. package/dist/cli/wt/config.d.ts.map +1 -1
  24. package/dist/cli/wt/config.js +323 -32
  25. package/dist/cli/wt/config.js.map +1 -1
  26. package/dist/cli/wt/interactive-menu.d.ts +2 -0
  27. package/dist/cli/wt/interactive-menu.d.ts.map +1 -1
  28. package/dist/cli/wt/interactive-menu.js +346 -73
  29. package/dist/cli/wt/interactive-menu.js.map +1 -1
  30. package/dist/cli/wt/link.d.ts +3 -1
  31. package/dist/cli/wt/link.d.ts.map +1 -1
  32. package/dist/cli/wt/link.js +125 -38
  33. package/dist/cli/wt/link.js.map +1 -1
  34. package/dist/cli/wt/list.d.ts +4 -1
  35. package/dist/cli/wt/list.d.ts.map +1 -1
  36. package/dist/cli/wt/list.js +85 -16
  37. package/dist/cli/wt/list.js.map +1 -1
  38. package/dist/cli/wt/new.d.ts +8 -2
  39. package/dist/cli/wt/new.d.ts.map +1 -1
  40. package/dist/cli/wt/new.js +91 -46
  41. package/dist/cli/wt/new.js.map +1 -1
  42. package/dist/cli/wt/prs.d.ts +2 -1
  43. package/dist/cli/wt/prs.d.ts.map +1 -1
  44. package/dist/cli/wt/prs.js +3 -164
  45. package/dist/cli/wt/prs.js.map +1 -1
  46. package/dist/cli/wt/run-command.d.ts +4 -2
  47. package/dist/cli/wt/run-command.d.ts.map +1 -1
  48. package/dist/cli/wt/run-command.js +6 -4
  49. package/dist/cli/wt/run-command.js.map +1 -1
  50. package/dist/cli/wt/state.d.ts +3 -1
  51. package/dist/cli/wt/state.d.ts.map +1 -1
  52. package/dist/cli/wt/state.js +74 -10
  53. package/dist/cli/wt/state.js.map +1 -1
  54. package/dist/cli/wt.d.ts.map +1 -1
  55. package/dist/cli/wt.js +50 -36
  56. package/dist/cli/wt.js.map +1 -1
  57. package/dist/cli/wtconfig.js +99 -22
  58. package/dist/cli/wtconfig.js.map +1 -1
  59. package/dist/cli/wtlink.js +85 -61
  60. package/dist/cli/wtlink.js.map +1 -1
  61. package/dist/cli/wtstate.js +21 -2
  62. package/dist/cli/wtstate.js.map +1 -1
  63. package/dist/lib/cleanpr/args.d.ts.map +1 -1
  64. package/dist/lib/cleanpr/args.js +20 -0
  65. package/dist/lib/cleanpr/args.js.map +1 -1
  66. package/dist/lib/cleanpr/types.d.ts +6 -0
  67. package/dist/lib/cleanpr/types.d.ts.map +1 -1
  68. package/dist/lib/colors.d.ts +5 -0
  69. package/dist/lib/colors.d.ts.map +1 -1
  70. package/dist/lib/colors.js +13 -6
  71. package/dist/lib/colors.js.map +1 -1
  72. package/dist/lib/constants.d.ts +12 -4
  73. package/dist/lib/constants.d.ts.map +1 -1
  74. package/dist/lib/constants.js +24 -5
  75. package/dist/lib/constants.js.map +1 -1
  76. package/dist/lib/deprecation.d.ts +18 -0
  77. package/dist/lib/deprecation.d.ts.map +1 -0
  78. package/dist/lib/deprecation.js +28 -0
  79. package/dist/lib/deprecation.js.map +1 -0
  80. package/dist/lib/logger.d.ts +40 -155
  81. package/dist/lib/logger.d.ts.map +1 -1
  82. package/dist/lib/logger.js +349 -420
  83. package/dist/lib/logger.js.map +1 -1
  84. package/dist/lib/lswt/args.d.ts.map +1 -1
  85. package/dist/lib/lswt/args.js +15 -1
  86. package/dist/lib/lswt/args.js.map +1 -1
  87. package/dist/lib/lswt/index.d.ts +1 -0
  88. package/dist/lib/lswt/index.d.ts.map +1 -1
  89. package/dist/lib/lswt/index.js +2 -0
  90. package/dist/lib/lswt/index.js.map +1 -1
  91. package/dist/lib/lswt/table.d.ts +15 -0
  92. package/dist/lib/lswt/table.d.ts.map +1 -0
  93. package/dist/lib/lswt/table.js +61 -0
  94. package/dist/lib/lswt/table.js.map +1 -0
  95. package/dist/lib/lswt/types.d.ts +4 -0
  96. package/dist/lib/lswt/types.d.ts.map +1 -1
  97. package/dist/lib/newpr/args.d.ts.map +1 -1
  98. package/dist/lib/newpr/args.js +21 -0
  99. package/dist/lib/newpr/args.js.map +1 -1
  100. package/dist/lib/newpr/types.d.ts +6 -0
  101. package/dist/lib/newpr/types.d.ts.map +1 -1
  102. package/dist/lib/prs/command.d.ts +21 -0
  103. package/dist/lib/prs/command.d.ts.map +1 -0
  104. package/dist/lib/prs/command.js +175 -0
  105. package/dist/lib/prs/command.js.map +1 -0
  106. package/dist/lib/prs/interactive.d.ts.map +1 -1
  107. package/dist/lib/prs/interactive.js +15 -2
  108. package/dist/lib/prs/interactive.js.map +1 -1
  109. package/dist/lib/prs/types.d.ts +15 -0
  110. package/dist/lib/prs/types.d.ts.map +1 -1
  111. package/dist/lib/ui/error.d.ts +31 -0
  112. package/dist/lib/ui/error.d.ts.map +1 -0
  113. package/dist/lib/ui/error.js +47 -0
  114. package/dist/lib/ui/error.js.map +1 -0
  115. package/dist/lib/ui/index.d.ts +15 -0
  116. package/dist/lib/ui/index.d.ts.map +1 -0
  117. package/dist/lib/ui/index.js +19 -0
  118. package/dist/lib/ui/index.js.map +1 -0
  119. package/dist/lib/ui/output.d.ts +18 -0
  120. package/dist/lib/ui/output.d.ts.map +1 -0
  121. package/dist/lib/ui/output.js +31 -0
  122. package/dist/lib/ui/output.js.map +1 -0
  123. package/dist/lib/ui/spinner.d.ts +10 -0
  124. package/dist/lib/ui/spinner.d.ts.map +1 -0
  125. package/dist/lib/ui/spinner.js +10 -0
  126. package/dist/lib/ui/spinner.js.map +1 -0
  127. package/dist/lib/ui/status.d.ts +65 -0
  128. package/dist/lib/ui/status.d.ts.map +1 -0
  129. package/dist/lib/ui/status.js +100 -0
  130. package/dist/lib/ui/status.js.map +1 -0
  131. package/dist/lib/ui/table.d.ts +39 -0
  132. package/dist/lib/ui/table.d.ts.map +1 -0
  133. package/dist/lib/ui/table.js +45 -0
  134. package/dist/lib/ui/table.js.map +1 -0
  135. package/dist/lib/ui/theme.d.ts +34 -0
  136. package/dist/lib/ui/theme.d.ts.map +1 -0
  137. package/dist/lib/ui/theme.js +37 -0
  138. package/dist/lib/ui/theme.js.map +1 -0
  139. package/dist/lib/wtlink/link-configs.js +7 -7
  140. package/dist/lib/wtlink/link-configs.js.map +1 -1
  141. package/dist/lib/wtlink/validate-manifest.d.ts.map +1 -1
  142. package/dist/lib/wtlink/validate-manifest.js +5 -5
  143. package/dist/lib/wtlink/validate-manifest.js.map +1 -1
  144. package/dist/lib/wtstate/args.d.ts.map +1 -1
  145. package/dist/lib/wtstate/args.js +2 -0
  146. package/dist/lib/wtstate/args.js.map +1 -1
  147. package/dist/mcp/server.d.ts +2 -1
  148. package/dist/mcp/server.d.ts.map +1 -1
  149. package/dist/mcp/server.js +264 -44
  150. package/dist/mcp/server.js.map +1 -1
  151. package/package.json +13 -3
  152. package/dist/api/list.test.d.ts +0 -5
  153. package/dist/api/list.test.d.ts.map +0 -1
  154. package/dist/api/list.test.js +0 -390
  155. package/dist/api/list.test.js.map +0 -1
  156. package/dist/cli/cleanpr.test.d.ts +0 -2
  157. package/dist/cli/cleanpr.test.d.ts.map +0 -1
  158. package/dist/cli/cleanpr.test.js +0 -954
  159. package/dist/cli/cleanpr.test.js.map +0 -1
  160. package/dist/cli/lswt.test.d.ts +0 -2
  161. package/dist/cli/lswt.test.d.ts.map +0 -1
  162. package/dist/cli/lswt.test.js +0 -386
  163. package/dist/cli/lswt.test.js.map +0 -1
  164. package/dist/cli/newpr.test.d.ts +0 -2
  165. package/dist/cli/newpr.test.d.ts.map +0 -1
  166. package/dist/cli/newpr.test.js +0 -1182
  167. package/dist/cli/newpr.test.js.map +0 -1
  168. package/dist/cli/prs.test.d.ts +0 -8
  169. package/dist/cli/prs.test.d.ts.map +0 -1
  170. package/dist/cli/prs.test.js +0 -410
  171. package/dist/cli/prs.test.js.map +0 -1
  172. package/dist/cli/wt/completion.test.d.ts +0 -5
  173. package/dist/cli/wt/completion.test.d.ts.map +0 -1
  174. package/dist/cli/wt/completion.test.js +0 -173
  175. package/dist/cli/wt/completion.test.js.map +0 -1
  176. package/dist/cli/wt/config.test.d.ts +0 -5
  177. package/dist/cli/wt/config.test.d.ts.map +0 -1
  178. package/dist/cli/wt/config.test.js +0 -260
  179. package/dist/cli/wt/config.test.js.map +0 -1
  180. package/dist/cli/wt/entry.test.d.ts +0 -8
  181. package/dist/cli/wt/entry.test.d.ts.map +0 -1
  182. package/dist/cli/wt/entry.test.js +0 -201
  183. package/dist/cli/wt/entry.test.js.map +0 -1
  184. package/dist/cli/wt/init.test.d.ts +0 -5
  185. package/dist/cli/wt/init.test.d.ts.map +0 -1
  186. package/dist/cli/wt/init.test.js +0 -165
  187. package/dist/cli/wt/init.test.js.map +0 -1
  188. package/dist/cli/wt/init.unit.test.d.ts +0 -5
  189. package/dist/cli/wt/init.unit.test.d.ts.map +0 -1
  190. package/dist/cli/wt/init.unit.test.js +0 -432
  191. package/dist/cli/wt/init.unit.test.js.map +0 -1
  192. package/dist/cli/wt/interactive-menu.test.d.ts +0 -10
  193. package/dist/cli/wt/interactive-menu.test.d.ts.map +0 -1
  194. package/dist/cli/wt/interactive-menu.test.js +0 -739
  195. package/dist/cli/wt/interactive-menu.test.js.map +0 -1
  196. package/dist/cli/wt/prs.test.d.ts +0 -5
  197. package/dist/cli/wt/prs.test.d.ts.map +0 -1
  198. package/dist/cli/wt/prs.test.js +0 -410
  199. package/dist/cli/wt/prs.test.js.map +0 -1
  200. package/dist/cli/wt/run-command.test.d.ts +0 -5
  201. package/dist/cli/wt/run-command.test.d.ts.map +0 -1
  202. package/dist/cli/wt/run-command.test.js +0 -88
  203. package/dist/cli/wt/run-command.test.js.map +0 -1
  204. package/dist/cli/wt/wt.test.d.ts +0 -8
  205. package/dist/cli/wt/wt.test.d.ts.map +0 -1
  206. package/dist/cli/wt/wt.test.js +0 -521
  207. package/dist/cli/wt/wt.test.js.map +0 -1
  208. package/dist/cli/wt.unit.test.d.ts +0 -7
  209. package/dist/cli/wt.unit.test.d.ts.map +0 -1
  210. package/dist/cli/wt.unit.test.js +0 -182
  211. package/dist/cli/wt.unit.test.js.map +0 -1
  212. package/dist/cli/wtconfig.test.d.ts +0 -5
  213. package/dist/cli/wtconfig.test.d.ts.map +0 -1
  214. package/dist/cli/wtconfig.test.js +0 -1289
  215. package/dist/cli/wtconfig.test.js.map +0 -1
  216. package/dist/cli/wtlink.test.d.ts +0 -2
  217. package/dist/cli/wtlink.test.d.ts.map +0 -1
  218. package/dist/cli/wtlink.test.js +0 -249
  219. package/dist/cli/wtlink.test.js.map +0 -1
  220. package/dist/cli/wtstate.test.d.ts +0 -5
  221. package/dist/cli/wtstate.test.d.ts.map +0 -1
  222. package/dist/cli/wtstate.test.js +0 -193
  223. package/dist/cli/wtstate.test.js.map +0 -1
  224. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +0 -2
  225. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +0 -1
  226. package/dist/e2e/cleanpr/cleanpr.e2e.test.js +0 -326
  227. package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +0 -1
  228. package/dist/e2e/cli.e2e.test.d.ts +0 -2
  229. package/dist/e2e/cli.e2e.test.d.ts.map +0 -1
  230. package/dist/e2e/cli.e2e.test.js +0 -417
  231. package/dist/e2e/cli.e2e.test.js.map +0 -1
  232. package/dist/e2e/lswt/lswt.e2e.test.d.ts +0 -2
  233. package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +0 -1
  234. package/dist/e2e/lswt/lswt.e2e.test.js +0 -361
  235. package/dist/e2e/lswt/lswt.e2e.test.js.map +0 -1
  236. package/dist/e2e/newpr/newpr.e2e.test.d.ts +0 -2
  237. package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +0 -1
  238. package/dist/e2e/newpr/newpr.e2e.test.js +0 -286
  239. package/dist/e2e/newpr/newpr.e2e.test.js.map +0 -1
  240. package/dist/e2e/newpr/scenarios.e2e.test.d.ts +0 -2
  241. package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +0 -1
  242. package/dist/e2e/newpr/scenarios.e2e.test.js +0 -426
  243. package/dist/e2e/newpr/scenarios.e2e.test.js.map +0 -1
  244. package/dist/e2e/newpr-full-flow.e2e.test.d.ts +0 -2
  245. package/dist/e2e/newpr-full-flow.e2e.test.d.ts.map +0 -1
  246. package/dist/e2e/newpr-full-flow.e2e.test.js +0 -280
  247. package/dist/e2e/newpr-full-flow.e2e.test.js.map +0 -1
  248. package/dist/e2e/prs/prs.e2e.test.d.ts +0 -7
  249. package/dist/e2e/prs/prs.e2e.test.d.ts.map +0 -1
  250. package/dist/e2e/prs/prs.e2e.test.js +0 -606
  251. package/dist/e2e/prs/prs.e2e.test.js.map +0 -1
  252. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +0 -2
  253. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +0 -1
  254. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +0 -298
  255. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +0 -1
  256. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts +0 -8
  257. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts.map +0 -1
  258. package/dist/e2e/wt/interactive-menu.e2e.test.js +0 -583
  259. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +0 -1
  260. package/dist/e2e/wt/wt.e2e.test.d.ts +0 -9
  261. package/dist/e2e/wt/wt.e2e.test.d.ts.map +0 -1
  262. package/dist/e2e/wt/wt.e2e.test.js +0 -597
  263. package/dist/e2e/wt/wt.e2e.test.js.map +0 -1
  264. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +0 -2
  265. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +0 -1
  266. package/dist/e2e/wtlink/wtlink.e2e.test.js +0 -416
  267. package/dist/e2e/wtlink/wtlink.e2e.test.js.map +0 -1
  268. package/dist/integration/git.integration.test.d.ts +0 -2
  269. package/dist/integration/git.integration.test.d.ts.map +0 -1
  270. package/dist/integration/git.integration.test.js +0 -336
  271. package/dist/integration/git.integration.test.js.map +0 -1
  272. package/dist/integration/lswt-remote-pr.integration.test.d.ts +0 -2
  273. package/dist/integration/lswt-remote-pr.integration.test.d.ts.map +0 -1
  274. package/dist/integration/lswt-remote-pr.integration.test.js +0 -222
  275. package/dist/integration/lswt-remote-pr.integration.test.js.map +0 -1
  276. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts +0 -2
  277. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts.map +0 -1
  278. package/dist/integration/newpr-branchfrom-head.integration.test.js +0 -498
  279. package/dist/integration/newpr-branchfrom-head.integration.test.js.map +0 -1
  280. package/dist/integration/newpr.integration.test.d.ts +0 -2
  281. package/dist/integration/newpr.integration.test.d.ts.map +0 -1
  282. package/dist/integration/newpr.integration.test.js +0 -460
  283. package/dist/integration/newpr.integration.test.js.map +0 -1
  284. package/dist/integration/prs.integration.test.d.ts +0 -8
  285. package/dist/integration/prs.integration.test.d.ts.map +0 -1
  286. package/dist/integration/prs.integration.test.js +0 -478
  287. package/dist/integration/prs.integration.test.js.map +0 -1
  288. package/dist/lib/ai/base-provider.test.d.ts +0 -7
  289. package/dist/lib/ai/base-provider.test.d.ts.map +0 -1
  290. package/dist/lib/ai/base-provider.test.js +0 -319
  291. package/dist/lib/ai/base-provider.test.js.map +0 -1
  292. package/dist/lib/ai/cli-provider.test.d.ts +0 -5
  293. package/dist/lib/ai/cli-provider.test.d.ts.map +0 -1
  294. package/dist/lib/ai/cli-provider.test.js +0 -460
  295. package/dist/lib/ai/cli-provider.test.js.map +0 -1
  296. package/dist/lib/ai/fallback-provider.test.d.ts +0 -7
  297. package/dist/lib/ai/fallback-provider.test.d.ts.map +0 -1
  298. package/dist/lib/ai/fallback-provider.test.js +0 -165
  299. package/dist/lib/ai/fallback-provider.test.js.map +0 -1
  300. package/dist/lib/ai/generation-service.test.d.ts +0 -7
  301. package/dist/lib/ai/generation-service.test.d.ts.map +0 -1
  302. package/dist/lib/ai/generation-service.test.js +0 -213
  303. package/dist/lib/ai/generation-service.test.js.map +0 -1
  304. package/dist/lib/ai/provider-manager.test.d.ts +0 -5
  305. package/dist/lib/ai/provider-manager.test.d.ts.map +0 -1
  306. package/dist/lib/ai/provider-manager.test.js +0 -312
  307. package/dist/lib/ai/provider-manager.test.js.map +0 -1
  308. package/dist/lib/ai/repo-docs.test.d.ts +0 -5
  309. package/dist/lib/ai/repo-docs.test.d.ts.map +0 -1
  310. package/dist/lib/ai/repo-docs.test.js +0 -357
  311. package/dist/lib/ai/repo-docs.test.js.map +0 -1
  312. package/dist/lib/cleanpr/args.test.d.ts +0 -2
  313. package/dist/lib/cleanpr/args.test.d.ts.map +0 -1
  314. package/dist/lib/cleanpr/args.test.js +0 -269
  315. package/dist/lib/cleanpr/args.test.js.map +0 -1
  316. package/dist/lib/cleanpr/cleanup.test.d.ts +0 -2
  317. package/dist/lib/cleanpr/cleanup.test.d.ts.map +0 -1
  318. package/dist/lib/cleanpr/cleanup.test.js +0 -296
  319. package/dist/lib/cleanpr/cleanup.test.js.map +0 -1
  320. package/dist/lib/cleanpr/worktree-info.test.d.ts +0 -2
  321. package/dist/lib/cleanpr/worktree-info.test.d.ts.map +0 -1
  322. package/dist/lib/cleanpr/worktree-info.test.js +0 -228
  323. package/dist/lib/cleanpr/worktree-info.test.js.map +0 -1
  324. package/dist/lib/colors.test.d.ts +0 -2
  325. package/dist/lib/colors.test.d.ts.map +0 -1
  326. package/dist/lib/colors.test.js +0 -142
  327. package/dist/lib/colors.test.js.map +0 -1
  328. package/dist/lib/config-editor.test.d.ts +0 -11
  329. package/dist/lib/config-editor.test.d.ts.map +0 -1
  330. package/dist/lib/config-editor.test.js +0 -526
  331. package/dist/lib/config-editor.test.js.map +0 -1
  332. package/dist/lib/config-migration/detector.test.d.ts +0 -5
  333. package/dist/lib/config-migration/detector.test.d.ts.map +0 -1
  334. package/dist/lib/config-migration/detector.test.js +0 -201
  335. package/dist/lib/config-migration/detector.test.js.map +0 -1
  336. package/dist/lib/config-migration/reporter.test.d.ts +0 -5
  337. package/dist/lib/config-migration/reporter.test.d.ts.map +0 -1
  338. package/dist/lib/config-migration/reporter.test.js +0 -305
  339. package/dist/lib/config-migration/reporter.test.js.map +0 -1
  340. package/dist/lib/config-migration/runner.test.d.ts +0 -5
  341. package/dist/lib/config-migration/runner.test.d.ts.map +0 -1
  342. package/dist/lib/config-migration/runner.test.js +0 -235
  343. package/dist/lib/config-migration/runner.test.js.map +0 -1
  344. package/dist/lib/config-validation.test.d.ts +0 -5
  345. package/dist/lib/config-validation.test.d.ts.map +0 -1
  346. package/dist/lib/config-validation.test.js +0 -423
  347. package/dist/lib/config-validation.test.js.map +0 -1
  348. package/dist/lib/config.test.d.ts +0 -2
  349. package/dist/lib/config.test.d.ts.map +0 -1
  350. package/dist/lib/config.test.js +0 -566
  351. package/dist/lib/config.test.js.map +0 -1
  352. package/dist/lib/constants.test.d.ts +0 -5
  353. package/dist/lib/constants.test.d.ts.map +0 -1
  354. package/dist/lib/constants.test.js +0 -121
  355. package/dist/lib/constants.test.js.map +0 -1
  356. package/dist/lib/errors.test.d.ts +0 -2
  357. package/dist/lib/errors.test.d.ts.map +0 -1
  358. package/dist/lib/errors.test.js +0 -117
  359. package/dist/lib/errors.test.js.map +0 -1
  360. package/dist/lib/git.test.d.ts +0 -2
  361. package/dist/lib/git.test.d.ts.map +0 -1
  362. package/dist/lib/git.test.js +0 -608
  363. package/dist/lib/git.test.js.map +0 -1
  364. package/dist/lib/github.test.d.ts +0 -2
  365. package/dist/lib/github.test.d.ts.map +0 -1
  366. package/dist/lib/github.test.js +0 -441
  367. package/dist/lib/github.test.js.map +0 -1
  368. package/dist/lib/global-check.test.d.ts +0 -5
  369. package/dist/lib/global-check.test.d.ts.map +0 -1
  370. package/dist/lib/global-check.test.js +0 -150
  371. package/dist/lib/global-check.test.js.map +0 -1
  372. package/dist/lib/global-config.test.d.ts +0 -5
  373. package/dist/lib/global-config.test.d.ts.map +0 -1
  374. package/dist/lib/global-config.test.js +0 -282
  375. package/dist/lib/global-config.test.js.map +0 -1
  376. package/dist/lib/hooks/confirmation.test.d.ts +0 -7
  377. package/dist/lib/hooks/confirmation.test.d.ts.map +0 -1
  378. package/dist/lib/hooks/confirmation.test.js +0 -300
  379. package/dist/lib/hooks/confirmation.test.js.map +0 -1
  380. package/dist/lib/hooks/executor.test.d.ts +0 -5
  381. package/dist/lib/hooks/executor.test.d.ts.map +0 -1
  382. package/dist/lib/hooks/executor.test.js +0 -648
  383. package/dist/lib/hooks/executor.test.js.map +0 -1
  384. package/dist/lib/hooks/templates.test.d.ts +0 -5
  385. package/dist/lib/hooks/templates.test.d.ts.map +0 -1
  386. package/dist/lib/hooks/templates.test.js +0 -163
  387. package/dist/lib/hooks/templates.test.js.map +0 -1
  388. package/dist/lib/hooks/types.test.d.ts +0 -5
  389. package/dist/lib/hooks/types.test.d.ts.map +0 -1
  390. package/dist/lib/hooks/types.test.js +0 -132
  391. package/dist/lib/hooks/types.test.js.map +0 -1
  392. package/dist/lib/json-output.test.d.ts +0 -5
  393. package/dist/lib/json-output.test.d.ts.map +0 -1
  394. package/dist/lib/json-output.test.js +0 -261
  395. package/dist/lib/json-output.test.js.map +0 -1
  396. package/dist/lib/logger.test.d.ts +0 -5
  397. package/dist/lib/logger.test.d.ts.map +0 -1
  398. package/dist/lib/logger.test.js +0 -292
  399. package/dist/lib/logger.test.js.map +0 -1
  400. package/dist/lib/lswt/action-executors.test.d.ts +0 -2
  401. package/dist/lib/lswt/action-executors.test.d.ts.map +0 -1
  402. package/dist/lib/lswt/action-executors.test.js +0 -1127
  403. package/dist/lib/lswt/action-executors.test.js.map +0 -1
  404. package/dist/lib/lswt/actions.test.d.ts +0 -2
  405. package/dist/lib/lswt/actions.test.d.ts.map +0 -1
  406. package/dist/lib/lswt/actions.test.js +0 -497
  407. package/dist/lib/lswt/actions.test.js.map +0 -1
  408. package/dist/lib/lswt/args.test.d.ts +0 -2
  409. package/dist/lib/lswt/args.test.d.ts.map +0 -1
  410. package/dist/lib/lswt/args.test.js +0 -195
  411. package/dist/lib/lswt/args.test.js.map +0 -1
  412. package/dist/lib/lswt/environment.test.d.ts +0 -2
  413. package/dist/lib/lswt/environment.test.d.ts.map +0 -1
  414. package/dist/lib/lswt/environment.test.js +0 -544
  415. package/dist/lib/lswt/environment.test.js.map +0 -1
  416. package/dist/lib/lswt/formatters.test.d.ts +0 -2
  417. package/dist/lib/lswt/formatters.test.d.ts.map +0 -1
  418. package/dist/lib/lswt/formatters.test.js +0 -323
  419. package/dist/lib/lswt/formatters.test.js.map +0 -1
  420. package/dist/lib/lswt/fuzzy-search.test.d.ts +0 -5
  421. package/dist/lib/lswt/fuzzy-search.test.d.ts.map +0 -1
  422. package/dist/lib/lswt/fuzzy-search.test.js +0 -207
  423. package/dist/lib/lswt/fuzzy-search.test.js.map +0 -1
  424. package/dist/lib/lswt/interactive.test.d.ts +0 -2
  425. package/dist/lib/lswt/interactive.test.d.ts.map +0 -1
  426. package/dist/lib/lswt/interactive.test.js +0 -771
  427. package/dist/lib/lswt/interactive.test.js.map +0 -1
  428. package/dist/lib/lswt/worktree-info.test.d.ts +0 -2
  429. package/dist/lib/lswt/worktree-info.test.d.ts.map +0 -1
  430. package/dist/lib/lswt/worktree-info.test.js +0 -484
  431. package/dist/lib/lswt/worktree-info.test.js.map +0 -1
  432. package/dist/lib/newpr/action-deps.test.d.ts +0 -5
  433. package/dist/lib/newpr/action-deps.test.d.ts.map +0 -1
  434. package/dist/lib/newpr/action-deps.test.js +0 -111
  435. package/dist/lib/newpr/action-deps.test.js.map +0 -1
  436. package/dist/lib/newpr/actions.test.d.ts +0 -2
  437. package/dist/lib/newpr/actions.test.d.ts.map +0 -1
  438. package/dist/lib/newpr/actions.test.js +0 -254
  439. package/dist/lib/newpr/actions.test.js.map +0 -1
  440. package/dist/lib/newpr/args.test.d.ts +0 -2
  441. package/dist/lib/newpr/args.test.d.ts.map +0 -1
  442. package/dist/lib/newpr/args.test.js +0 -479
  443. package/dist/lib/newpr/args.test.js.map +0 -1
  444. package/dist/lib/newpr/hook-runner.test.d.ts +0 -7
  445. package/dist/lib/newpr/hook-runner.test.d.ts.map +0 -1
  446. package/dist/lib/newpr/hook-runner.test.js +0 -422
  447. package/dist/lib/newpr/hook-runner.test.js.map +0 -1
  448. package/dist/lib/newpr/plan-generator.test.d.ts +0 -7
  449. package/dist/lib/newpr/plan-generator.test.d.ts.map +0 -1
  450. package/dist/lib/newpr/plan-generator.test.js +0 -387
  451. package/dist/lib/newpr/plan-generator.test.js.map +0 -1
  452. package/dist/lib/newpr/scenario-handler.test.d.ts +0 -2
  453. package/dist/lib/newpr/scenario-handler.test.d.ts.map +0 -1
  454. package/dist/lib/newpr/scenario-handler.test.js +0 -256
  455. package/dist/lib/newpr/scenario-handler.test.js.map +0 -1
  456. package/dist/lib/prompts.test.d.ts +0 -2
  457. package/dist/lib/prompts.test.d.ts.map +0 -1
  458. package/dist/lib/prompts.test.js +0 -807
  459. package/dist/lib/prompts.test.js.map +0 -1
  460. package/dist/lib/prs/actions.test.d.ts +0 -5
  461. package/dist/lib/prs/actions.test.d.ts.map +0 -1
  462. package/dist/lib/prs/actions.test.js +0 -356
  463. package/dist/lib/prs/actions.test.js.map +0 -1
  464. package/dist/lib/prs/data.test.d.ts +0 -5
  465. package/dist/lib/prs/data.test.d.ts.map +0 -1
  466. package/dist/lib/prs/data.test.js +0 -417
  467. package/dist/lib/prs/data.test.js.map +0 -1
  468. package/dist/lib/prs/details.test.d.ts +0 -5
  469. package/dist/lib/prs/details.test.d.ts.map +0 -1
  470. package/dist/lib/prs/details.test.js +0 -325
  471. package/dist/lib/prs/details.test.js.map +0 -1
  472. package/dist/lib/prs/filters.test.d.ts +0 -5
  473. package/dist/lib/prs/filters.test.d.ts.map +0 -1
  474. package/dist/lib/prs/filters.test.js +0 -312
  475. package/dist/lib/prs/filters.test.js.map +0 -1
  476. package/dist/lib/prs/formatters.test.d.ts +0 -2
  477. package/dist/lib/prs/formatters.test.d.ts.map +0 -1
  478. package/dist/lib/prs/formatters.test.js +0 -387
  479. package/dist/lib/prs/formatters.test.js.map +0 -1
  480. package/dist/lib/prs/interactive.test.d.ts +0 -5
  481. package/dist/lib/prs/interactive.test.d.ts.map +0 -1
  482. package/dist/lib/prs/interactive.test.js +0 -364
  483. package/dist/lib/prs/interactive.test.js.map +0 -1
  484. package/dist/lib/schema.test.d.ts +0 -10
  485. package/dist/lib/schema.test.d.ts.map +0 -1
  486. package/dist/lib/schema.test.js +0 -309
  487. package/dist/lib/schema.test.js.map +0 -1
  488. package/dist/lib/state-detection.test.d.ts +0 -2
  489. package/dist/lib/state-detection.test.d.ts.map +0 -1
  490. package/dist/lib/state-detection.test.js +0 -451
  491. package/dist/lib/state-detection.test.js.map +0 -1
  492. package/dist/lib/wtconfig/config-manager.test.d.ts +0 -5
  493. package/dist/lib/wtconfig/config-manager.test.d.ts.map +0 -1
  494. package/dist/lib/wtconfig/config-manager.test.js +0 -501
  495. package/dist/lib/wtconfig/config-manager.test.js.map +0 -1
  496. package/dist/lib/wtconfig/environment.test.d.ts +0 -5
  497. package/dist/lib/wtconfig/environment.test.d.ts.map +0 -1
  498. package/dist/lib/wtconfig/environment.test.js +0 -285
  499. package/dist/lib/wtconfig/environment.test.js.map +0 -1
  500. package/dist/lib/wtlink/config-manifest.test.d.ts +0 -2
  501. package/dist/lib/wtlink/config-manifest.test.d.ts.map +0 -1
  502. package/dist/lib/wtlink/config-manifest.test.js +0 -486
  503. package/dist/lib/wtlink/config-manifest.test.js.map +0 -1
  504. package/dist/lib/wtlink/link-configs.test.d.ts +0 -2
  505. package/dist/lib/wtlink/link-configs.test.d.ts.map +0 -1
  506. package/dist/lib/wtlink/link-configs.test.js +0 -612
  507. package/dist/lib/wtlink/link-configs.test.js.map +0 -1
  508. package/dist/lib/wtlink/main-menu.test.d.ts +0 -5
  509. package/dist/lib/wtlink/main-menu.test.d.ts.map +0 -1
  510. package/dist/lib/wtlink/main-menu.test.js +0 -126
  511. package/dist/lib/wtlink/main-menu.test.js.map +0 -1
  512. package/dist/lib/wtlink/manage-manifest.test.d.ts +0 -2
  513. package/dist/lib/wtlink/manage-manifest.test.d.ts.map +0 -1
  514. package/dist/lib/wtlink/manage-manifest.test.js +0 -714
  515. package/dist/lib/wtlink/manage-manifest.test.js.map +0 -1
  516. package/dist/lib/wtlink/validate-manifest.test.d.ts +0 -2
  517. package/dist/lib/wtlink/validate-manifest.test.d.ts.map +0 -1
  518. package/dist/lib/wtlink/validate-manifest.test.js +0 -220
  519. package/dist/lib/wtlink/validate-manifest.test.js.map +0 -1
  520. package/dist/lib/wtstate/analyze.test.d.ts +0 -5
  521. package/dist/lib/wtstate/analyze.test.d.ts.map +0 -1
  522. package/dist/lib/wtstate/analyze.test.js +0 -282
  523. package/dist/lib/wtstate/analyze.test.js.map +0 -1
  524. package/dist/lib/wtstate/args.test.d.ts +0 -5
  525. package/dist/lib/wtstate/args.test.d.ts.map +0 -1
  526. package/dist/lib/wtstate/args.test.js +0 -120
  527. package/dist/lib/wtstate/args.test.js.map +0 -1
  528. package/dist/mcp/server.test.d.ts +0 -9
  529. package/dist/mcp/server.test.d.ts.map +0 -1
  530. package/dist/mcp/server.test.js +0 -439
  531. package/dist/mcp/server.test.js.map +0 -1
@@ -1,739 +0,0 @@
1
- /**
2
- * Integration tests for interactive menu flows
3
- *
4
- * These tests verify that each menu flow:
5
- * 1. Gathers the correct user inputs
6
- * 2. Passes the correct arguments to subcommands
7
- * 3. Handles cancellation and back navigation correctly
8
- */
9
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
10
- // Mock modules before importing the module under test
11
- vi.mock('../../lib/prompts.js', () => {
12
- // Define UserNavigatedBack inside the factory to avoid hoisting issues
13
- class MockUserNavigatedBack extends Error {
14
- constructor() {
15
- super('User navigated back');
16
- this.name = 'UserNavigatedBack';
17
- }
18
- }
19
- return {
20
- promptChoice: vi.fn(),
21
- promptInput: vi.fn(),
22
- promptConfirm: vi.fn(),
23
- UserNavigatedBack: MockUserNavigatedBack,
24
- };
25
- });
26
- vi.mock('./run-command.js', () => ({
27
- runSubcommand: vi.fn(() => {
28
- // Mock never returns - simulate process.exit
29
- throw new Error('process.exit called');
30
- }),
31
- }));
32
- vi.mock('../../lib/config.js', () => ({
33
- loadConfig: vi.fn(() => ({
34
- configVersion: 1,
35
- sharedRepos: [],
36
- baseBranch: 'main',
37
- draftPr: true,
38
- worktreePattern: '{repo}.pr{number}',
39
- worktreeParent: '..',
40
- syncPatterns: [],
41
- branchPrefix: 'feat',
42
- previewLabel: 'preview',
43
- preferredEditor: 'vscode',
44
- ai: {
45
- provider: 'auto',
46
- fallback: 'none',
47
- branchName: false,
48
- prTitle: false,
49
- prDescription: false,
50
- commitMessage: false,
51
- planDocument: false,
52
- },
53
- hooks: {},
54
- hookDefaults: { timeout: 30000, maxTimeout: 60000 },
55
- plugins: [],
56
- generators: {},
57
- integrations: {},
58
- logging: { level: 'info', timestamps: true },
59
- global: { warnNotGlobal: true },
60
- wtlink: { enabled: [], disabled: [] },
61
- })),
62
- }));
63
- vi.mock('../../lib/git.js', () => ({
64
- getRepoRoot: vi.fn(() => '/mock/repo'),
65
- listLocalBranches: vi.fn(() => ['feat/existing-branch', 'fix/bug-fix', 'main', 'develop']),
66
- }));
67
- // Import mocked modules
68
- import { promptChoice, promptInput, promptConfirm } from '../../lib/prompts.js';
69
- import { runSubcommand } from './run-command.js';
70
- import { loadConfig } from '../../lib/config.js';
71
- import * as git from '../../lib/git.js';
72
- // Import flows after mocks are set up
73
- import { flows, showMainMenu } from './interactive-menu.js';
74
- // Mock console.log to keep test output clean
75
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
76
- describe('Interactive Menu Flows', () => {
77
- beforeEach(() => {
78
- vi.clearAllMocks();
79
- });
80
- afterEach(() => {
81
- consoleSpy.mockClear();
82
- });
83
- describe('handleListWorktrees', () => {
84
- it('calls lswt subcommand with no args', async () => {
85
- try {
86
- await flows.handleListWorktrees();
87
- }
88
- catch {
89
- // Expected - runSubcommand throws
90
- }
91
- expect(runSubcommand).toHaveBeenCalledWith('lswt', []);
92
- });
93
- });
94
- describe('handleBrowsePRs', () => {
95
- it('calls prs subcommand with no args', async () => {
96
- try {
97
- await flows.handleBrowsePRs();
98
- }
99
- catch {
100
- // Expected - runSubcommand throws
101
- }
102
- expect(runSubcommand).toHaveBeenCalledWith('prs', []);
103
- });
104
- });
105
- describe('handleShowState', () => {
106
- it('calls wtstate subcommand with no args', async () => {
107
- try {
108
- await flows.handleShowState();
109
- }
110
- catch {
111
- // Expected - runSubcommand throws
112
- }
113
- expect(runSubcommand).toHaveBeenCalledWith('wtstate', []);
114
- });
115
- });
116
- describe('handleNewPR', () => {
117
- it('returns CANCELLED when user selects back', async () => {
118
- vi.mocked(promptChoice).mockResolvedValueOnce('back');
119
- const result = await flows.handleNewPR();
120
- expect(result).toEqual({ completed: false, returnToMenu: true });
121
- expect(runSubcommand).not.toHaveBeenCalled();
122
- });
123
- it('handles user cancellation (Ctrl+C)', async () => {
124
- vi.mocked(promptChoice).mockRejectedValueOnce(new Error('User cancelled'));
125
- const result = await flows.handleNewPR();
126
- expect(result).toEqual({ completed: false, returnToMenu: true });
127
- });
128
- describe('from-description flow', () => {
129
- it('gathers all inputs and calls newpr with correct args', async () => {
130
- vi.mocked(promptChoice)
131
- .mockResolvedValueOnce('from-description') // New PR sub-menu
132
- .mockResolvedValueOnce(true); // Draft PR selection
133
- vi.mocked(promptInput)
134
- .mockResolvedValueOnce('Add dark mode support') // Description
135
- .mockResolvedValueOnce('main'); // Base branch
136
- vi.mocked(promptConfirm)
137
- .mockResolvedValueOnce(false) // Install deps
138
- .mockResolvedValueOnce(false); // Open VS Code
139
- try {
140
- await flows.handleNewPR();
141
- }
142
- catch {
143
- // Expected
144
- }
145
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['Add dark mode support']);
146
- });
147
- it('passes --ready flag when not draft', async () => {
148
- vi.mocked(promptChoice)
149
- .mockResolvedValueOnce('from-description')
150
- .mockResolvedValueOnce(false); // Ready for review (not draft)
151
- vi.mocked(promptInput)
152
- .mockResolvedValueOnce('Fix critical bug')
153
- .mockResolvedValueOnce('main');
154
- vi.mocked(promptConfirm).mockResolvedValueOnce(false).mockResolvedValueOnce(false);
155
- try {
156
- await flows.handleNewPR();
157
- }
158
- catch {
159
- // Expected
160
- }
161
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['Fix critical bug', '--ready']);
162
- });
163
- it('passes --base flag when not main', async () => {
164
- vi.mocked(promptChoice)
165
- .mockResolvedValueOnce('from-description')
166
- .mockResolvedValueOnce(true);
167
- vi.mocked(promptInput)
168
- .mockResolvedValueOnce('Feature work')
169
- .mockResolvedValueOnce('develop'); // Non-main base branch
170
- vi.mocked(promptConfirm).mockResolvedValueOnce(false).mockResolvedValueOnce(false);
171
- try {
172
- await flows.handleNewPR();
173
- }
174
- catch {
175
- // Expected
176
- }
177
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['Feature work', '--base', 'develop']);
178
- });
179
- it('passes --install flag when requested', async () => {
180
- vi.mocked(promptChoice)
181
- .mockResolvedValueOnce('from-description')
182
- .mockResolvedValueOnce(true);
183
- vi.mocked(promptInput).mockResolvedValueOnce('Add feature').mockResolvedValueOnce('main');
184
- vi.mocked(promptConfirm)
185
- .mockResolvedValueOnce(true) // Install deps
186
- .mockResolvedValueOnce(false);
187
- try {
188
- await flows.handleNewPR();
189
- }
190
- catch {
191
- // Expected
192
- }
193
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['Add feature', '--install']);
194
- });
195
- it('passes --code flag when requested', async () => {
196
- vi.mocked(promptChoice)
197
- .mockResolvedValueOnce('from-description')
198
- .mockResolvedValueOnce(true);
199
- vi.mocked(promptInput).mockResolvedValueOnce('Add feature').mockResolvedValueOnce('main');
200
- vi.mocked(promptConfirm).mockResolvedValueOnce(false).mockResolvedValueOnce(true); // Open VS Code
201
- try {
202
- await flows.handleNewPR();
203
- }
204
- catch {
205
- // Expected
206
- }
207
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['Add feature', '--code']);
208
- });
209
- it('passes all optional flags together', async () => {
210
- vi.mocked(promptChoice)
211
- .mockResolvedValueOnce('from-description')
212
- .mockResolvedValueOnce(false); // Ready
213
- vi.mocked(promptInput)
214
- .mockResolvedValueOnce('Full feature')
215
- .mockResolvedValueOnce('develop');
216
- vi.mocked(promptConfirm)
217
- .mockResolvedValueOnce(true) // Install
218
- .mockResolvedValueOnce(true); // VS Code
219
- try {
220
- await flows.handleNewPR();
221
- }
222
- catch {
223
- // Expected
224
- }
225
- expect(runSubcommand).toHaveBeenCalledWith('newpr', [
226
- 'Full feature',
227
- '--base',
228
- 'develop',
229
- '--ready',
230
- '--install',
231
- '--code',
232
- ]);
233
- });
234
- it('returns CANCELLED when description is empty', async () => {
235
- vi.mocked(promptChoice).mockResolvedValueOnce('from-description');
236
- vi.mocked(promptInput).mockResolvedValueOnce(''); // Empty description
237
- const result = await flows.handleNewPR();
238
- expect(result).toEqual({ completed: false, returnToMenu: true });
239
- expect(runSubcommand).not.toHaveBeenCalled();
240
- });
241
- it('handles user cancellation during input', async () => {
242
- vi.mocked(promptChoice).mockResolvedValueOnce('from-description');
243
- vi.mocked(promptInput).mockRejectedValueOnce(new Error('User cancelled'));
244
- const result = await flows.handleNewPR();
245
- expect(result).toEqual({ completed: false, returnToMenu: true });
246
- });
247
- });
248
- describe('from-pr flow', () => {
249
- it('gathers PR number and calls newpr with --pr flag', async () => {
250
- vi.mocked(promptChoice).mockResolvedValueOnce('from-pr');
251
- vi.mocked(promptInput).mockResolvedValueOnce('42');
252
- vi.mocked(promptConfirm).mockResolvedValueOnce(false).mockResolvedValueOnce(false);
253
- try {
254
- await flows.handleNewPR();
255
- }
256
- catch {
257
- // Expected
258
- }
259
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['--pr', '42']);
260
- });
261
- it('passes --install and --code flags', async () => {
262
- vi.mocked(promptChoice).mockResolvedValueOnce('from-pr');
263
- vi.mocked(promptInput).mockResolvedValueOnce('123');
264
- vi.mocked(promptConfirm)
265
- .mockResolvedValueOnce(true) // Install
266
- .mockResolvedValueOnce(true); // VS Code
267
- try {
268
- await flows.handleNewPR();
269
- }
270
- catch {
271
- // Expected
272
- }
273
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['--pr', '123', '--install', '--code']);
274
- });
275
- it('returns CANCELLED when PR number is empty', async () => {
276
- vi.mocked(promptChoice).mockResolvedValueOnce('from-pr');
277
- vi.mocked(promptInput).mockResolvedValueOnce('');
278
- const result = await flows.handleNewPR();
279
- expect(result).toEqual({ completed: false, returnToMenu: true });
280
- expect(runSubcommand).not.toHaveBeenCalled();
281
- });
282
- it('returns CANCELLED when PR number is invalid', async () => {
283
- vi.mocked(promptChoice).mockResolvedValueOnce('from-pr');
284
- vi.mocked(promptInput).mockResolvedValueOnce('not-a-number');
285
- const result = await flows.handleNewPR();
286
- expect(result).toEqual({ completed: false, returnToMenu: true });
287
- expect(runSubcommand).not.toHaveBeenCalled();
288
- });
289
- it('returns CANCELLED when PR number is zero', async () => {
290
- vi.mocked(promptChoice).mockResolvedValueOnce('from-pr');
291
- vi.mocked(promptInput).mockResolvedValueOnce('0');
292
- const result = await flows.handleNewPR();
293
- expect(result).toEqual({ completed: false, returnToMenu: true });
294
- expect(runSubcommand).not.toHaveBeenCalled();
295
- });
296
- it('returns CANCELLED when PR number is negative', async () => {
297
- vi.mocked(promptChoice).mockResolvedValueOnce('from-pr');
298
- vi.mocked(promptInput).mockResolvedValueOnce('-5');
299
- const result = await flows.handleNewPR();
300
- expect(result).toEqual({ completed: false, returnToMenu: true });
301
- expect(runSubcommand).not.toHaveBeenCalled();
302
- });
303
- });
304
- describe('from-branch flow', () => {
305
- it('allows selecting from existing branches', async () => {
306
- vi.mocked(promptChoice)
307
- .mockResolvedValueOnce('from-branch') // New PR sub-menu
308
- .mockResolvedValueOnce('feat/existing-branch') // Select branch
309
- .mockResolvedValueOnce(true); // Draft PR
310
- vi.mocked(promptInput).mockResolvedValueOnce('main');
311
- try {
312
- await flows.handleNewPR();
313
- }
314
- catch {
315
- // Expected
316
- }
317
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['--branch', 'feat/existing-branch']);
318
- });
319
- it('allows typing custom branch name', async () => {
320
- vi.mocked(promptChoice)
321
- .mockResolvedValueOnce('from-branch')
322
- .mockResolvedValueOnce('__custom__') // Select custom option
323
- .mockResolvedValueOnce(true);
324
- vi.mocked(promptInput)
325
- .mockResolvedValueOnce('feat/my-new-branch') // Custom branch name
326
- .mockResolvedValueOnce('main');
327
- try {
328
- await flows.handleNewPR();
329
- }
330
- catch {
331
- // Expected
332
- }
333
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['--branch', 'feat/my-new-branch']);
334
- });
335
- it('passes --base and --ready flags', async () => {
336
- vi.mocked(promptChoice)
337
- .mockResolvedValueOnce('from-branch')
338
- .mockResolvedValueOnce('fix/bug-fix')
339
- .mockResolvedValueOnce(false); // Ready for review
340
- vi.mocked(promptInput).mockResolvedValueOnce('develop');
341
- try {
342
- await flows.handleNewPR();
343
- }
344
- catch {
345
- // Expected
346
- }
347
- expect(runSubcommand).toHaveBeenCalledWith('newpr', [
348
- '--branch',
349
- 'fix/bug-fix',
350
- '--base',
351
- 'develop',
352
- '--ready',
353
- ]);
354
- });
355
- it('returns CANCELLED when branch name is empty', async () => {
356
- vi.mocked(promptChoice)
357
- .mockResolvedValueOnce('from-branch')
358
- .mockResolvedValueOnce('__custom__');
359
- vi.mocked(promptInput).mockResolvedValueOnce(''); // Empty branch name
360
- const result = await flows.handleNewPR();
361
- expect(result).toEqual({ completed: false, returnToMenu: true });
362
- expect(runSubcommand).not.toHaveBeenCalled();
363
- });
364
- it('handles empty branch list gracefully', async () => {
365
- // Mock empty branch list
366
- vi.mocked(git.listLocalBranches).mockReturnValueOnce([]);
367
- vi.mocked(promptChoice).mockResolvedValueOnce('from-branch');
368
- vi.mocked(promptInput)
369
- .mockResolvedValueOnce('feat/new-branch') // Manual branch input
370
- .mockResolvedValueOnce('main');
371
- vi.mocked(promptChoice).mockResolvedValueOnce(true); // Draft
372
- try {
373
- await flows.handleNewPR();
374
- }
375
- catch {
376
- // Expected
377
- }
378
- // Should have prompted for branch name directly
379
- expect(promptInput).toHaveBeenCalledWith('Branch name');
380
- });
381
- });
382
- });
383
- describe('handleCleanPRs', () => {
384
- it('returns CANCELLED when user selects back', async () => {
385
- vi.mocked(promptChoice).mockResolvedValueOnce('back');
386
- const result = await flows.handleCleanPRs();
387
- expect(result).toEqual({ completed: false, returnToMenu: true });
388
- expect(runSubcommand).not.toHaveBeenCalled();
389
- });
390
- describe('clean-all', () => {
391
- it('calls cleanpr with --all after confirmation', async () => {
392
- vi.mocked(promptChoice).mockResolvedValueOnce('clean-all');
393
- vi.mocked(promptConfirm).mockResolvedValueOnce(true);
394
- try {
395
- await flows.handleCleanPRs();
396
- }
397
- catch {
398
- // Expected
399
- }
400
- expect(runSubcommand).toHaveBeenCalledWith('cleanpr', ['--all']);
401
- });
402
- it('returns CANCELLED when not confirmed', async () => {
403
- vi.mocked(promptChoice).mockResolvedValueOnce('clean-all');
404
- vi.mocked(promptConfirm).mockResolvedValueOnce(false);
405
- const result = await flows.handleCleanPRs();
406
- expect(result).toEqual({ completed: false, returnToMenu: true });
407
- expect(runSubcommand).not.toHaveBeenCalled();
408
- });
409
- });
410
- describe('clean-specific', () => {
411
- it('calls cleanpr with PR number', async () => {
412
- vi.mocked(promptChoice).mockResolvedValueOnce('clean-specific');
413
- vi.mocked(promptInput).mockResolvedValueOnce('42');
414
- try {
415
- await flows.handleCleanPRs();
416
- }
417
- catch {
418
- // Expected
419
- }
420
- expect(runSubcommand).toHaveBeenCalledWith('cleanpr', ['42']);
421
- });
422
- it('returns CANCELLED when PR number is empty', async () => {
423
- vi.mocked(promptChoice).mockResolvedValueOnce('clean-specific');
424
- vi.mocked(promptInput).mockResolvedValueOnce('');
425
- const result = await flows.handleCleanPRs();
426
- expect(result).toEqual({ completed: false, returnToMenu: true });
427
- });
428
- it('returns CANCELLED when PR number is invalid', async () => {
429
- vi.mocked(promptChoice).mockResolvedValueOnce('clean-specific');
430
- vi.mocked(promptInput).mockResolvedValueOnce('invalid');
431
- const result = await flows.handleCleanPRs();
432
- expect(result).toEqual({ completed: false, returnToMenu: true });
433
- });
434
- });
435
- describe('dry-run', () => {
436
- it('calls cleanpr with --dry-run', async () => {
437
- vi.mocked(promptChoice).mockResolvedValueOnce('dry-run');
438
- try {
439
- await flows.handleCleanPRs();
440
- }
441
- catch {
442
- // Expected
443
- }
444
- expect(runSubcommand).toHaveBeenCalledWith('cleanpr', ['--dry-run']);
445
- });
446
- });
447
- it('handles user cancellation', async () => {
448
- vi.mocked(promptChoice).mockRejectedValueOnce(new Error('User cancelled'));
449
- const result = await flows.handleCleanPRs();
450
- expect(result).toEqual({ completed: false, returnToMenu: true });
451
- });
452
- });
453
- describe('handleLinkConfig', () => {
454
- it('returns CANCELLED when user selects back', async () => {
455
- vi.mocked(promptChoice).mockResolvedValueOnce('back');
456
- const result = await flows.handleLinkConfig();
457
- expect(result).toEqual({ completed: false, returnToMenu: true });
458
- expect(runSubcommand).not.toHaveBeenCalled();
459
- });
460
- it('view calls wtlink list', async () => {
461
- vi.mocked(promptChoice).mockResolvedValueOnce('view');
462
- try {
463
- await flows.handleLinkConfig();
464
- }
465
- catch {
466
- // Expected
467
- }
468
- expect(runSubcommand).toHaveBeenCalledWith('wtlink', ['list']);
469
- });
470
- it('sync calls wtlink sync', async () => {
471
- vi.mocked(promptChoice).mockResolvedValueOnce('sync');
472
- try {
473
- await flows.handleLinkConfig();
474
- }
475
- catch {
476
- // Expected
477
- }
478
- expect(runSubcommand).toHaveBeenCalledWith('wtlink', ['sync']);
479
- });
480
- it('add calls wtlink add with file path', async () => {
481
- vi.mocked(promptChoice).mockResolvedValueOnce('add');
482
- vi.mocked(promptInput).mockResolvedValueOnce('.env');
483
- try {
484
- await flows.handleLinkConfig();
485
- }
486
- catch {
487
- // Expected
488
- }
489
- expect(runSubcommand).toHaveBeenCalledWith('wtlink', ['add', '.env']);
490
- });
491
- it('add returns CANCELLED when file path is empty', async () => {
492
- vi.mocked(promptChoice).mockResolvedValueOnce('add');
493
- vi.mocked(promptInput).mockResolvedValueOnce('');
494
- const result = await flows.handleLinkConfig();
495
- expect(result).toEqual({ completed: false, returnToMenu: true });
496
- expect(runSubcommand).not.toHaveBeenCalled();
497
- });
498
- it('remove calls wtlink remove with file path', async () => {
499
- vi.mocked(promptChoice).mockResolvedValueOnce('remove');
500
- vi.mocked(promptInput).mockResolvedValueOnce('.env.local');
501
- try {
502
- await flows.handleLinkConfig();
503
- }
504
- catch {
505
- // Expected
506
- }
507
- expect(runSubcommand).toHaveBeenCalledWith('wtlink', ['remove', '.env.local']);
508
- });
509
- it('remove returns CANCELLED when file path is empty', async () => {
510
- vi.mocked(promptChoice).mockResolvedValueOnce('remove');
511
- vi.mocked(promptInput).mockResolvedValueOnce('');
512
- const result = await flows.handleLinkConfig();
513
- expect(result).toEqual({ completed: false, returnToMenu: true });
514
- });
515
- it('validate calls wtlink validate', async () => {
516
- vi.mocked(promptChoice).mockResolvedValueOnce('validate');
517
- try {
518
- await flows.handleLinkConfig();
519
- }
520
- catch {
521
- // Expected
522
- }
523
- expect(runSubcommand).toHaveBeenCalledWith('wtlink', ['validate']);
524
- });
525
- it('handles user cancellation', async () => {
526
- vi.mocked(promptChoice).mockRejectedValueOnce(new Error('User cancelled'));
527
- const result = await flows.handleLinkConfig();
528
- expect(result).toEqual({ completed: false, returnToMenu: true });
529
- });
530
- });
531
- describe('handleConfigure', () => {
532
- it('returns CANCELLED when user selects back', async () => {
533
- vi.mocked(promptChoice).mockResolvedValueOnce('back');
534
- const result = await flows.handleConfigure();
535
- expect(result).toEqual({ completed: false, returnToMenu: true });
536
- expect(runSubcommand).not.toHaveBeenCalled();
537
- });
538
- it('view calls wtconfig show', async () => {
539
- vi.mocked(promptChoice).mockResolvedValueOnce('view');
540
- try {
541
- await flows.handleConfigure();
542
- }
543
- catch {
544
- // Expected
545
- }
546
- expect(runSubcommand).toHaveBeenCalledWith('wtconfig', ['show']);
547
- });
548
- it('init calls wtconfig init after confirmation', async () => {
549
- vi.mocked(promptChoice).mockResolvedValueOnce('init');
550
- vi.mocked(promptConfirm).mockResolvedValueOnce(true);
551
- try {
552
- await flows.handleConfigure();
553
- }
554
- catch {
555
- // Expected
556
- }
557
- expect(runSubcommand).toHaveBeenCalledWith('wtconfig', ['init']);
558
- });
559
- it('init returns CANCELLED when not confirmed', async () => {
560
- vi.mocked(promptChoice).mockResolvedValueOnce('init');
561
- vi.mocked(promptConfirm).mockResolvedValueOnce(false);
562
- const result = await flows.handleConfigure();
563
- expect(result).toEqual({ completed: false, returnToMenu: true });
564
- expect(runSubcommand).not.toHaveBeenCalled();
565
- });
566
- it('edit calls wtconfig set with setting and value', async () => {
567
- vi.mocked(promptChoice).mockResolvedValueOnce('edit').mockResolvedValueOnce('baseBranch');
568
- vi.mocked(promptInput).mockResolvedValueOnce('develop');
569
- try {
570
- await flows.handleConfigure();
571
- }
572
- catch {
573
- // Expected
574
- }
575
- expect(runSubcommand).toHaveBeenCalledWith('wtconfig', ['set', 'baseBranch', 'develop']);
576
- });
577
- it('edit returns CANCELLED when value is empty', async () => {
578
- vi.mocked(promptChoice).mockResolvedValueOnce('edit').mockResolvedValueOnce('branchPrefix');
579
- vi.mocked(promptInput).mockResolvedValueOnce('');
580
- const result = await flows.handleConfigure();
581
- expect(result).toEqual({ completed: false, returnToMenu: true });
582
- expect(runSubcommand).not.toHaveBeenCalled();
583
- });
584
- it('handles user cancellation', async () => {
585
- vi.mocked(promptChoice).mockRejectedValueOnce(new Error('User cancelled'));
586
- const result = await flows.handleConfigure();
587
- expect(result).toEqual({ completed: false, returnToMenu: true });
588
- });
589
- });
590
- describe('showMainMenu', () => {
591
- it('exits on exit selection', async () => {
592
- vi.mocked(promptChoice).mockResolvedValueOnce('exit');
593
- await showMainMenu();
594
- expect(runSubcommand).not.toHaveBeenCalled();
595
- });
596
- it('exits on user cancellation', async () => {
597
- vi.mocked(promptChoice).mockRejectedValueOnce(new Error('User cancelled'));
598
- await showMainMenu();
599
- expect(runSubcommand).not.toHaveBeenCalled();
600
- });
601
- it('re-throws non-cancellation errors', async () => {
602
- vi.mocked(promptChoice).mockRejectedValueOnce(new Error('Some other error'));
603
- await expect(showMainMenu()).rejects.toThrow('Some other error');
604
- });
605
- it('returns to menu when flow returns returnToMenu=true', async () => {
606
- vi.mocked(promptChoice)
607
- .mockResolvedValueOnce('new-pr') // First: select new-pr
608
- .mockResolvedValueOnce('back') // Then: go back from new-pr sub-menu
609
- .mockResolvedValueOnce('exit'); // Finally: exit
610
- await showMainMenu();
611
- // Should have called promptChoice 3 times (menu -> sub-menu -> back to menu -> exit)
612
- expect(promptChoice).toHaveBeenCalledTimes(3);
613
- });
614
- it('handles list worktrees selection', async () => {
615
- vi.mocked(promptChoice).mockResolvedValueOnce('list');
616
- try {
617
- await showMainMenu();
618
- }
619
- catch {
620
- // Expected - runSubcommand throws
621
- }
622
- expect(runSubcommand).toHaveBeenCalledWith('lswt', []);
623
- });
624
- it('handles browse PRs selection', async () => {
625
- vi.mocked(promptChoice).mockResolvedValueOnce('browse-prs');
626
- try {
627
- await showMainMenu();
628
- }
629
- catch {
630
- // Expected - runSubcommand throws
631
- }
632
- expect(runSubcommand).toHaveBeenCalledWith('prs', []);
633
- });
634
- it('handles show state selection', async () => {
635
- vi.mocked(promptChoice).mockResolvedValueOnce('state');
636
- try {
637
- await showMainMenu();
638
- }
639
- catch {
640
- // Expected
641
- }
642
- expect(runSubcommand).toHaveBeenCalledWith('wtstate', []);
643
- });
644
- });
645
- describe('FlowResult types', () => {
646
- it('CANCELLED has correct structure', async () => {
647
- vi.mocked(promptChoice).mockResolvedValueOnce('back');
648
- const result = await flows.handleNewPR();
649
- expect(result.completed).toBe(false);
650
- expect(result.returnToMenu).toBe(true);
651
- });
652
- it('flows that run subcommands return COMPLETED_EXIT', async () => {
653
- vi.mocked(promptChoice).mockResolvedValueOnce('dry-run');
654
- // We can't test the actual return value since runSubcommand throws,
655
- // but we can verify the flow attempted to call the subcommand
656
- try {
657
- await flows.handleCleanPRs();
658
- }
659
- catch {
660
- // Expected
661
- }
662
- expect(runSubcommand).toHaveBeenCalled();
663
- });
664
- });
665
- });
666
- describe('Config loading in flows', () => {
667
- beforeEach(() => {
668
- vi.clearAllMocks();
669
- });
670
- it('uses config default for base branch', async () => {
671
- // Set up config mock to return custom baseBranch
672
- vi.mocked(loadConfig).mockReturnValueOnce({
673
- configVersion: 1,
674
- sharedRepos: [],
675
- baseBranch: 'develop',
676
- draftPr: true,
677
- worktreePattern: '{repo}.pr{number}',
678
- worktreeParent: '..',
679
- syncPatterns: [],
680
- branchPrefix: 'feat',
681
- previewLabel: 'preview',
682
- preferredEditor: 'vscode',
683
- ai: {
684
- provider: 'auto',
685
- fallback: 'none',
686
- branchName: false,
687
- prTitle: false,
688
- prDescription: false,
689
- commitMessage: false,
690
- planDocument: false,
691
- },
692
- hooks: {},
693
- hookDefaults: { timeout: 30000, maxTimeout: 60000 },
694
- plugins: [],
695
- generators: {},
696
- integrations: {},
697
- logging: { level: 'info', timestamps: true },
698
- global: { warnNotGlobal: true },
699
- wtlink: { enabled: [], disabled: [] },
700
- linkConfigFiles: undefined,
701
- });
702
- vi.mocked(promptChoice).mockResolvedValueOnce('from-description').mockResolvedValueOnce(true);
703
- vi.mocked(promptInput).mockResolvedValueOnce('Test feature').mockResolvedValueOnce('develop'); // User accepts default
704
- vi.mocked(promptConfirm).mockResolvedValueOnce(false).mockResolvedValueOnce(false);
705
- try {
706
- await flows.handleNewPR();
707
- }
708
- catch {
709
- // Expected
710
- }
711
- // Verify loadConfig was called
712
- expect(loadConfig).toHaveBeenCalled();
713
- // Since user entered 'develop' (matching config default), no --base flag
714
- expect(runSubcommand).toHaveBeenCalledWith('newpr', ['Test feature', '--base', 'develop']);
715
- });
716
- });
717
- describe('Git branch listing in flows', () => {
718
- beforeEach(() => {
719
- vi.clearAllMocks();
720
- });
721
- it('filters out main/master/develop from branch selection', async () => {
722
- // The mock already returns ['feat/existing-branch', 'fix/bug-fix', 'main', 'develop']
723
- // The flow should filter out main and develop
724
- vi.mocked(promptChoice)
725
- .mockResolvedValueOnce('from-branch')
726
- .mockResolvedValueOnce('feat/existing-branch')
727
- .mockResolvedValueOnce(true);
728
- vi.mocked(promptInput).mockResolvedValueOnce('main');
729
- try {
730
- await flows.handleNewPR();
731
- }
732
- catch {
733
- // Expected
734
- }
735
- // Check that listLocalBranches was called
736
- expect(git.listLocalBranches).toHaveBeenCalled();
737
- });
738
- });
739
- //# sourceMappingURL=interactive-menu.test.js.map