@camaradesuk/git-worktree-tools 1.10.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 (426) hide show
  1. package/README.md +4 -4
  2. package/package.json +12 -3
  3. package/dist/api/list.test.d.ts +0 -5
  4. package/dist/api/list.test.d.ts.map +0 -1
  5. package/dist/api/list.test.js +0 -390
  6. package/dist/api/list.test.js.map +0 -1
  7. package/dist/cli/cleanpr.test.d.ts +0 -2
  8. package/dist/cli/cleanpr.test.d.ts.map +0 -1
  9. package/dist/cli/cleanpr.test.js +0 -954
  10. package/dist/cli/cleanpr.test.js.map +0 -1
  11. package/dist/cli/lswt.test.d.ts +0 -2
  12. package/dist/cli/lswt.test.d.ts.map +0 -1
  13. package/dist/cli/lswt.test.js +0 -376
  14. package/dist/cli/lswt.test.js.map +0 -1
  15. package/dist/cli/newpr.test.d.ts +0 -2
  16. package/dist/cli/newpr.test.d.ts.map +0 -1
  17. package/dist/cli/newpr.test.js +0 -1182
  18. package/dist/cli/newpr.test.js.map +0 -1
  19. package/dist/cli/prs.test.d.ts +0 -8
  20. package/dist/cli/prs.test.d.ts.map +0 -1
  21. package/dist/cli/prs.test.js +0 -463
  22. package/dist/cli/prs.test.js.map +0 -1
  23. package/dist/cli/wt/clean.test.d.ts +0 -8
  24. package/dist/cli/wt/clean.test.d.ts.map +0 -1
  25. package/dist/cli/wt/clean.test.js +0 -624
  26. package/dist/cli/wt/clean.test.js.map +0 -1
  27. package/dist/cli/wt/completion.test.d.ts +0 -5
  28. package/dist/cli/wt/completion.test.d.ts.map +0 -1
  29. package/dist/cli/wt/completion.test.js +0 -275
  30. package/dist/cli/wt/completion.test.js.map +0 -1
  31. package/dist/cli/wt/config.test.d.ts +0 -7
  32. package/dist/cli/wt/config.test.d.ts.map +0 -1
  33. package/dist/cli/wt/config.test.js +0 -440
  34. package/dist/cli/wt/config.test.js.map +0 -1
  35. package/dist/cli/wt/entry.test.d.ts +0 -8
  36. package/dist/cli/wt/entry.test.d.ts.map +0 -1
  37. package/dist/cli/wt/entry.test.js +0 -201
  38. package/dist/cli/wt/entry.test.js.map +0 -1
  39. package/dist/cli/wt/init.test.d.ts +0 -5
  40. package/dist/cli/wt/init.test.d.ts.map +0 -1
  41. package/dist/cli/wt/init.test.js +0 -165
  42. package/dist/cli/wt/init.test.js.map +0 -1
  43. package/dist/cli/wt/init.unit.test.d.ts +0 -5
  44. package/dist/cli/wt/init.unit.test.d.ts.map +0 -1
  45. package/dist/cli/wt/init.unit.test.js +0 -432
  46. package/dist/cli/wt/init.unit.test.js.map +0 -1
  47. package/dist/cli/wt/interactive-menu.test.d.ts +0 -12
  48. package/dist/cli/wt/interactive-menu.test.d.ts.map +0 -1
  49. package/dist/cli/wt/interactive-menu.test.js +0 -796
  50. package/dist/cli/wt/interactive-menu.test.js.map +0 -1
  51. package/dist/cli/wt/list.test.d.ts +0 -10
  52. package/dist/cli/wt/list.test.d.ts.map +0 -1
  53. package/dist/cli/wt/list.test.js +0 -157
  54. package/dist/cli/wt/list.test.js.map +0 -1
  55. package/dist/cli/wt/prs.test.d.ts +0 -5
  56. package/dist/cli/wt/prs.test.d.ts.map +0 -1
  57. package/dist/cli/wt/prs.test.js +0 -410
  58. package/dist/cli/wt/prs.test.js.map +0 -1
  59. package/dist/cli/wt/run-command.test.d.ts +0 -5
  60. package/dist/cli/wt/run-command.test.d.ts.map +0 -1
  61. package/dist/cli/wt/run-command.test.js +0 -88
  62. package/dist/cli/wt/run-command.test.js.map +0 -1
  63. package/dist/cli/wt/state.test.d.ts +0 -9
  64. package/dist/cli/wt/state.test.d.ts.map +0 -1
  65. package/dist/cli/wt/state.test.js +0 -127
  66. package/dist/cli/wt/state.test.js.map +0 -1
  67. package/dist/cli/wt/wt.test.d.ts +0 -8
  68. package/dist/cli/wt/wt.test.d.ts.map +0 -1
  69. package/dist/cli/wt/wt.test.js +0 -739
  70. package/dist/cli/wt/wt.test.js.map +0 -1
  71. package/dist/cli/wt.unit.test.d.ts +0 -7
  72. package/dist/cli/wt.unit.test.d.ts.map +0 -1
  73. package/dist/cli/wt.unit.test.js +0 -160
  74. package/dist/cli/wt.unit.test.js.map +0 -1
  75. package/dist/cli/wtconfig.test.d.ts +0 -5
  76. package/dist/cli/wtconfig.test.d.ts.map +0 -1
  77. package/dist/cli/wtconfig.test.js +0 -1289
  78. package/dist/cli/wtconfig.test.js.map +0 -1
  79. package/dist/cli/wtlink.test.d.ts +0 -2
  80. package/dist/cli/wtlink.test.d.ts.map +0 -1
  81. package/dist/cli/wtlink.test.js +0 -249
  82. package/dist/cli/wtlink.test.js.map +0 -1
  83. package/dist/cli/wtstate.test.d.ts +0 -5
  84. package/dist/cli/wtstate.test.d.ts.map +0 -1
  85. package/dist/cli/wtstate.test.js +0 -193
  86. package/dist/cli/wtstate.test.js.map +0 -1
  87. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +0 -2
  88. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +0 -1
  89. package/dist/e2e/cleanpr/cleanpr.e2e.test.js +0 -326
  90. package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +0 -1
  91. package/dist/e2e/cli.e2e.test.d.ts +0 -2
  92. package/dist/e2e/cli.e2e.test.d.ts.map +0 -1
  93. package/dist/e2e/cli.e2e.test.js +0 -417
  94. package/dist/e2e/cli.e2e.test.js.map +0 -1
  95. package/dist/e2e/lswt/lswt.e2e.test.d.ts +0 -2
  96. package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +0 -1
  97. package/dist/e2e/lswt/lswt.e2e.test.js +0 -361
  98. package/dist/e2e/lswt/lswt.e2e.test.js.map +0 -1
  99. package/dist/e2e/newpr/newpr.e2e.test.d.ts +0 -2
  100. package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +0 -1
  101. package/dist/e2e/newpr/newpr.e2e.test.js +0 -286
  102. package/dist/e2e/newpr/newpr.e2e.test.js.map +0 -1
  103. package/dist/e2e/newpr/scenarios.e2e.test.d.ts +0 -2
  104. package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +0 -1
  105. package/dist/e2e/newpr/scenarios.e2e.test.js +0 -426
  106. package/dist/e2e/newpr/scenarios.e2e.test.js.map +0 -1
  107. package/dist/e2e/newpr-full-flow.e2e.test.d.ts +0 -2
  108. package/dist/e2e/newpr-full-flow.e2e.test.d.ts.map +0 -1
  109. package/dist/e2e/newpr-full-flow.e2e.test.js +0 -280
  110. package/dist/e2e/newpr-full-flow.e2e.test.js.map +0 -1
  111. package/dist/e2e/prs/prs.e2e.test.d.ts +0 -7
  112. package/dist/e2e/prs/prs.e2e.test.d.ts.map +0 -1
  113. package/dist/e2e/prs/prs.e2e.test.js +0 -606
  114. package/dist/e2e/prs/prs.e2e.test.js.map +0 -1
  115. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +0 -2
  116. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +0 -1
  117. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +0 -298
  118. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +0 -1
  119. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts +0 -8
  120. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts.map +0 -1
  121. package/dist/e2e/wt/interactive-menu.e2e.test.js +0 -583
  122. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +0 -1
  123. package/dist/e2e/wt/wt.e2e.test.d.ts +0 -9
  124. package/dist/e2e/wt/wt.e2e.test.d.ts.map +0 -1
  125. package/dist/e2e/wt/wt.e2e.test.js +0 -597
  126. package/dist/e2e/wt/wt.e2e.test.js.map +0 -1
  127. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +0 -2
  128. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +0 -1
  129. package/dist/e2e/wtlink/wtlink.e2e.test.js +0 -416
  130. package/dist/e2e/wtlink/wtlink.e2e.test.js.map +0 -1
  131. package/dist/integration/git.integration.test.d.ts +0 -2
  132. package/dist/integration/git.integration.test.d.ts.map +0 -1
  133. package/dist/integration/git.integration.test.js +0 -336
  134. package/dist/integration/git.integration.test.js.map +0 -1
  135. package/dist/integration/lswt-remote-pr.integration.test.d.ts +0 -2
  136. package/dist/integration/lswt-remote-pr.integration.test.d.ts.map +0 -1
  137. package/dist/integration/lswt-remote-pr.integration.test.js +0 -222
  138. package/dist/integration/lswt-remote-pr.integration.test.js.map +0 -1
  139. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts +0 -2
  140. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts.map +0 -1
  141. package/dist/integration/newpr-branchfrom-head.integration.test.js +0 -498
  142. package/dist/integration/newpr-branchfrom-head.integration.test.js.map +0 -1
  143. package/dist/integration/newpr.integration.test.d.ts +0 -2
  144. package/dist/integration/newpr.integration.test.d.ts.map +0 -1
  145. package/dist/integration/newpr.integration.test.js +0 -460
  146. package/dist/integration/newpr.integration.test.js.map +0 -1
  147. package/dist/integration/prs.integration.test.d.ts +0 -8
  148. package/dist/integration/prs.integration.test.d.ts.map +0 -1
  149. package/dist/integration/prs.integration.test.js +0 -478
  150. package/dist/integration/prs.integration.test.js.map +0 -1
  151. package/dist/lib/ai/base-provider.test.d.ts +0 -7
  152. package/dist/lib/ai/base-provider.test.d.ts.map +0 -1
  153. package/dist/lib/ai/base-provider.test.js +0 -319
  154. package/dist/lib/ai/base-provider.test.js.map +0 -1
  155. package/dist/lib/ai/cli-provider.test.d.ts +0 -5
  156. package/dist/lib/ai/cli-provider.test.d.ts.map +0 -1
  157. package/dist/lib/ai/cli-provider.test.js +0 -460
  158. package/dist/lib/ai/cli-provider.test.js.map +0 -1
  159. package/dist/lib/ai/fallback-provider.test.d.ts +0 -7
  160. package/dist/lib/ai/fallback-provider.test.d.ts.map +0 -1
  161. package/dist/lib/ai/fallback-provider.test.js +0 -165
  162. package/dist/lib/ai/fallback-provider.test.js.map +0 -1
  163. package/dist/lib/ai/generation-service.test.d.ts +0 -7
  164. package/dist/lib/ai/generation-service.test.d.ts.map +0 -1
  165. package/dist/lib/ai/generation-service.test.js +0 -213
  166. package/dist/lib/ai/generation-service.test.js.map +0 -1
  167. package/dist/lib/ai/provider-manager.test.d.ts +0 -5
  168. package/dist/lib/ai/provider-manager.test.d.ts.map +0 -1
  169. package/dist/lib/ai/provider-manager.test.js +0 -312
  170. package/dist/lib/ai/provider-manager.test.js.map +0 -1
  171. package/dist/lib/ai/repo-docs.test.d.ts +0 -5
  172. package/dist/lib/ai/repo-docs.test.d.ts.map +0 -1
  173. package/dist/lib/ai/repo-docs.test.js +0 -357
  174. package/dist/lib/ai/repo-docs.test.js.map +0 -1
  175. package/dist/lib/cleanpr/args.test.d.ts +0 -2
  176. package/dist/lib/cleanpr/args.test.d.ts.map +0 -1
  177. package/dist/lib/cleanpr/args.test.js +0 -269
  178. package/dist/lib/cleanpr/args.test.js.map +0 -1
  179. package/dist/lib/cleanpr/cleanup.test.d.ts +0 -2
  180. package/dist/lib/cleanpr/cleanup.test.d.ts.map +0 -1
  181. package/dist/lib/cleanpr/cleanup.test.js +0 -296
  182. package/dist/lib/cleanpr/cleanup.test.js.map +0 -1
  183. package/dist/lib/cleanpr/worktree-info.test.d.ts +0 -2
  184. package/dist/lib/cleanpr/worktree-info.test.d.ts.map +0 -1
  185. package/dist/lib/cleanpr/worktree-info.test.js +0 -228
  186. package/dist/lib/cleanpr/worktree-info.test.js.map +0 -1
  187. package/dist/lib/colors.test.d.ts +0 -2
  188. package/dist/lib/colors.test.d.ts.map +0 -1
  189. package/dist/lib/colors.test.js +0 -142
  190. package/dist/lib/colors.test.js.map +0 -1
  191. package/dist/lib/config-editor.test.d.ts +0 -11
  192. package/dist/lib/config-editor.test.d.ts.map +0 -1
  193. package/dist/lib/config-editor.test.js +0 -526
  194. package/dist/lib/config-editor.test.js.map +0 -1
  195. package/dist/lib/config-migration/detector.test.d.ts +0 -5
  196. package/dist/lib/config-migration/detector.test.d.ts.map +0 -1
  197. package/dist/lib/config-migration/detector.test.js +0 -201
  198. package/dist/lib/config-migration/detector.test.js.map +0 -1
  199. package/dist/lib/config-migration/reporter.test.d.ts +0 -5
  200. package/dist/lib/config-migration/reporter.test.d.ts.map +0 -1
  201. package/dist/lib/config-migration/reporter.test.js +0 -305
  202. package/dist/lib/config-migration/reporter.test.js.map +0 -1
  203. package/dist/lib/config-migration/runner.test.d.ts +0 -5
  204. package/dist/lib/config-migration/runner.test.d.ts.map +0 -1
  205. package/dist/lib/config-migration/runner.test.js +0 -235
  206. package/dist/lib/config-migration/runner.test.js.map +0 -1
  207. package/dist/lib/config-validation.test.d.ts +0 -5
  208. package/dist/lib/config-validation.test.d.ts.map +0 -1
  209. package/dist/lib/config-validation.test.js +0 -423
  210. package/dist/lib/config-validation.test.js.map +0 -1
  211. package/dist/lib/config.test.d.ts +0 -2
  212. package/dist/lib/config.test.d.ts.map +0 -1
  213. package/dist/lib/config.test.js +0 -554
  214. package/dist/lib/config.test.js.map +0 -1
  215. package/dist/lib/constants.test.d.ts +0 -5
  216. package/dist/lib/constants.test.d.ts.map +0 -1
  217. package/dist/lib/constants.test.js +0 -180
  218. package/dist/lib/constants.test.js.map +0 -1
  219. package/dist/lib/deprecation.test.d.ts +0 -2
  220. package/dist/lib/deprecation.test.d.ts.map +0 -1
  221. package/dist/lib/deprecation.test.js +0 -71
  222. package/dist/lib/deprecation.test.js.map +0 -1
  223. package/dist/lib/errors.test.d.ts +0 -2
  224. package/dist/lib/errors.test.d.ts.map +0 -1
  225. package/dist/lib/errors.test.js +0 -117
  226. package/dist/lib/errors.test.js.map +0 -1
  227. package/dist/lib/git.test.d.ts +0 -2
  228. package/dist/lib/git.test.d.ts.map +0 -1
  229. package/dist/lib/git.test.js +0 -608
  230. package/dist/lib/git.test.js.map +0 -1
  231. package/dist/lib/github.test.d.ts +0 -2
  232. package/dist/lib/github.test.d.ts.map +0 -1
  233. package/dist/lib/github.test.js +0 -441
  234. package/dist/lib/github.test.js.map +0 -1
  235. package/dist/lib/global-check.test.d.ts +0 -5
  236. package/dist/lib/global-check.test.d.ts.map +0 -1
  237. package/dist/lib/global-check.test.js +0 -150
  238. package/dist/lib/global-check.test.js.map +0 -1
  239. package/dist/lib/global-config.test.d.ts +0 -5
  240. package/dist/lib/global-config.test.d.ts.map +0 -1
  241. package/dist/lib/global-config.test.js +0 -282
  242. package/dist/lib/global-config.test.js.map +0 -1
  243. package/dist/lib/hooks/confirmation.test.d.ts +0 -7
  244. package/dist/lib/hooks/confirmation.test.d.ts.map +0 -1
  245. package/dist/lib/hooks/confirmation.test.js +0 -300
  246. package/dist/lib/hooks/confirmation.test.js.map +0 -1
  247. package/dist/lib/hooks/executor.test.d.ts +0 -5
  248. package/dist/lib/hooks/executor.test.d.ts.map +0 -1
  249. package/dist/lib/hooks/executor.test.js +0 -648
  250. package/dist/lib/hooks/executor.test.js.map +0 -1
  251. package/dist/lib/hooks/templates.test.d.ts +0 -5
  252. package/dist/lib/hooks/templates.test.d.ts.map +0 -1
  253. package/dist/lib/hooks/templates.test.js +0 -163
  254. package/dist/lib/hooks/templates.test.js.map +0 -1
  255. package/dist/lib/hooks/types.test.d.ts +0 -5
  256. package/dist/lib/hooks/types.test.d.ts.map +0 -1
  257. package/dist/lib/hooks/types.test.js +0 -132
  258. package/dist/lib/hooks/types.test.js.map +0 -1
  259. package/dist/lib/json-output.test.d.ts +0 -5
  260. package/dist/lib/json-output.test.d.ts.map +0 -1
  261. package/dist/lib/json-output.test.js +0 -261
  262. package/dist/lib/json-output.test.js.map +0 -1
  263. package/dist/lib/logger.test.d.ts +0 -14
  264. package/dist/lib/logger.test.d.ts.map +0 -1
  265. package/dist/lib/logger.test.js +0 -692
  266. package/dist/lib/logger.test.js.map +0 -1
  267. package/dist/lib/lswt/action-executors.test.d.ts +0 -2
  268. package/dist/lib/lswt/action-executors.test.d.ts.map +0 -1
  269. package/dist/lib/lswt/action-executors.test.js +0 -1127
  270. package/dist/lib/lswt/action-executors.test.js.map +0 -1
  271. package/dist/lib/lswt/actions.test.d.ts +0 -2
  272. package/dist/lib/lswt/actions.test.d.ts.map +0 -1
  273. package/dist/lib/lswt/actions.test.js +0 -497
  274. package/dist/lib/lswt/actions.test.js.map +0 -1
  275. package/dist/lib/lswt/args.test.d.ts +0 -2
  276. package/dist/lib/lswt/args.test.d.ts.map +0 -1
  277. package/dist/lib/lswt/args.test.js +0 -195
  278. package/dist/lib/lswt/args.test.js.map +0 -1
  279. package/dist/lib/lswt/environment.test.d.ts +0 -2
  280. package/dist/lib/lswt/environment.test.d.ts.map +0 -1
  281. package/dist/lib/lswt/environment.test.js +0 -544
  282. package/dist/lib/lswt/environment.test.js.map +0 -1
  283. package/dist/lib/lswt/formatters.test.d.ts +0 -2
  284. package/dist/lib/lswt/formatters.test.d.ts.map +0 -1
  285. package/dist/lib/lswt/formatters.test.js +0 -323
  286. package/dist/lib/lswt/formatters.test.js.map +0 -1
  287. package/dist/lib/lswt/fuzzy-search.test.d.ts +0 -5
  288. package/dist/lib/lswt/fuzzy-search.test.d.ts.map +0 -1
  289. package/dist/lib/lswt/fuzzy-search.test.js +0 -207
  290. package/dist/lib/lswt/fuzzy-search.test.js.map +0 -1
  291. package/dist/lib/lswt/interactive.test.d.ts +0 -2
  292. package/dist/lib/lswt/interactive.test.d.ts.map +0 -1
  293. package/dist/lib/lswt/interactive.test.js +0 -771
  294. package/dist/lib/lswt/interactive.test.js.map +0 -1
  295. package/dist/lib/lswt/table.test.d.ts +0 -5
  296. package/dist/lib/lswt/table.test.d.ts.map +0 -1
  297. package/dist/lib/lswt/table.test.js +0 -262
  298. package/dist/lib/lswt/table.test.js.map +0 -1
  299. package/dist/lib/lswt/worktree-info.test.d.ts +0 -2
  300. package/dist/lib/lswt/worktree-info.test.d.ts.map +0 -1
  301. package/dist/lib/lswt/worktree-info.test.js +0 -484
  302. package/dist/lib/lswt/worktree-info.test.js.map +0 -1
  303. package/dist/lib/newpr/action-deps.test.d.ts +0 -5
  304. package/dist/lib/newpr/action-deps.test.d.ts.map +0 -1
  305. package/dist/lib/newpr/action-deps.test.js +0 -111
  306. package/dist/lib/newpr/action-deps.test.js.map +0 -1
  307. package/dist/lib/newpr/actions.test.d.ts +0 -2
  308. package/dist/lib/newpr/actions.test.d.ts.map +0 -1
  309. package/dist/lib/newpr/actions.test.js +0 -254
  310. package/dist/lib/newpr/actions.test.js.map +0 -1
  311. package/dist/lib/newpr/args.test.d.ts +0 -2
  312. package/dist/lib/newpr/args.test.d.ts.map +0 -1
  313. package/dist/lib/newpr/args.test.js +0 -479
  314. package/dist/lib/newpr/args.test.js.map +0 -1
  315. package/dist/lib/newpr/hook-runner.test.d.ts +0 -7
  316. package/dist/lib/newpr/hook-runner.test.d.ts.map +0 -1
  317. package/dist/lib/newpr/hook-runner.test.js +0 -422
  318. package/dist/lib/newpr/hook-runner.test.js.map +0 -1
  319. package/dist/lib/newpr/plan-generator.test.d.ts +0 -7
  320. package/dist/lib/newpr/plan-generator.test.d.ts.map +0 -1
  321. package/dist/lib/newpr/plan-generator.test.js +0 -387
  322. package/dist/lib/newpr/plan-generator.test.js.map +0 -1
  323. package/dist/lib/newpr/scenario-handler.test.d.ts +0 -2
  324. package/dist/lib/newpr/scenario-handler.test.d.ts.map +0 -1
  325. package/dist/lib/newpr/scenario-handler.test.js +0 -256
  326. package/dist/lib/newpr/scenario-handler.test.js.map +0 -1
  327. package/dist/lib/prompts.test.d.ts +0 -2
  328. package/dist/lib/prompts.test.d.ts.map +0 -1
  329. package/dist/lib/prompts.test.js +0 -807
  330. package/dist/lib/prompts.test.js.map +0 -1
  331. package/dist/lib/prs/actions.test.d.ts +0 -5
  332. package/dist/lib/prs/actions.test.d.ts.map +0 -1
  333. package/dist/lib/prs/actions.test.js +0 -356
  334. package/dist/lib/prs/actions.test.js.map +0 -1
  335. package/dist/lib/prs/command.test.d.ts +0 -11
  336. package/dist/lib/prs/command.test.d.ts.map +0 -1
  337. package/dist/lib/prs/command.test.js +0 -409
  338. package/dist/lib/prs/command.test.js.map +0 -1
  339. package/dist/lib/prs/data.test.d.ts +0 -5
  340. package/dist/lib/prs/data.test.d.ts.map +0 -1
  341. package/dist/lib/prs/data.test.js +0 -417
  342. package/dist/lib/prs/data.test.js.map +0 -1
  343. package/dist/lib/prs/details.test.d.ts +0 -5
  344. package/dist/lib/prs/details.test.d.ts.map +0 -1
  345. package/dist/lib/prs/details.test.js +0 -325
  346. package/dist/lib/prs/details.test.js.map +0 -1
  347. package/dist/lib/prs/filters.test.d.ts +0 -5
  348. package/dist/lib/prs/filters.test.d.ts.map +0 -1
  349. package/dist/lib/prs/filters.test.js +0 -312
  350. package/dist/lib/prs/filters.test.js.map +0 -1
  351. package/dist/lib/prs/formatters.test.d.ts +0 -2
  352. package/dist/lib/prs/formatters.test.d.ts.map +0 -1
  353. package/dist/lib/prs/formatters.test.js +0 -387
  354. package/dist/lib/prs/formatters.test.js.map +0 -1
  355. package/dist/lib/prs/interactive.test.d.ts +0 -5
  356. package/dist/lib/prs/interactive.test.d.ts.map +0 -1
  357. package/dist/lib/prs/interactive.test.js +0 -517
  358. package/dist/lib/prs/interactive.test.js.map +0 -1
  359. package/dist/lib/schema.test.d.ts +0 -10
  360. package/dist/lib/schema.test.d.ts.map +0 -1
  361. package/dist/lib/schema.test.js +0 -309
  362. package/dist/lib/schema.test.js.map +0 -1
  363. package/dist/lib/state-detection.test.d.ts +0 -2
  364. package/dist/lib/state-detection.test.d.ts.map +0 -1
  365. package/dist/lib/state-detection.test.js +0 -451
  366. package/dist/lib/state-detection.test.js.map +0 -1
  367. package/dist/lib/ui/error.test.d.ts +0 -2
  368. package/dist/lib/ui/error.test.d.ts.map +0 -1
  369. package/dist/lib/ui/error.test.js +0 -143
  370. package/dist/lib/ui/error.test.js.map +0 -1
  371. package/dist/lib/ui/output.test.d.ts +0 -2
  372. package/dist/lib/ui/output.test.d.ts.map +0 -1
  373. package/dist/lib/ui/output.test.js +0 -59
  374. package/dist/lib/ui/output.test.js.map +0 -1
  375. package/dist/lib/ui/status.test.d.ts +0 -2
  376. package/dist/lib/ui/status.test.d.ts.map +0 -1
  377. package/dist/lib/ui/status.test.js +0 -158
  378. package/dist/lib/ui/status.test.js.map +0 -1
  379. package/dist/lib/ui/table.test.d.ts +0 -2
  380. package/dist/lib/ui/table.test.d.ts.map +0 -1
  381. package/dist/lib/ui/table.test.js +0 -115
  382. package/dist/lib/ui/table.test.js.map +0 -1
  383. package/dist/lib/ui/theme.test.d.ts +0 -2
  384. package/dist/lib/ui/theme.test.d.ts.map +0 -1
  385. package/dist/lib/ui/theme.test.js +0 -76
  386. package/dist/lib/ui/theme.test.js.map +0 -1
  387. package/dist/lib/wtconfig/config-manager.test.d.ts +0 -5
  388. package/dist/lib/wtconfig/config-manager.test.d.ts.map +0 -1
  389. package/dist/lib/wtconfig/config-manager.test.js +0 -501
  390. package/dist/lib/wtconfig/config-manager.test.js.map +0 -1
  391. package/dist/lib/wtconfig/environment.test.d.ts +0 -5
  392. package/dist/lib/wtconfig/environment.test.d.ts.map +0 -1
  393. package/dist/lib/wtconfig/environment.test.js +0 -285
  394. package/dist/lib/wtconfig/environment.test.js.map +0 -1
  395. package/dist/lib/wtlink/config-manifest.test.d.ts +0 -2
  396. package/dist/lib/wtlink/config-manifest.test.d.ts.map +0 -1
  397. package/dist/lib/wtlink/config-manifest.test.js +0 -486
  398. package/dist/lib/wtlink/config-manifest.test.js.map +0 -1
  399. package/dist/lib/wtlink/link-configs.test.d.ts +0 -2
  400. package/dist/lib/wtlink/link-configs.test.d.ts.map +0 -1
  401. package/dist/lib/wtlink/link-configs.test.js +0 -612
  402. package/dist/lib/wtlink/link-configs.test.js.map +0 -1
  403. package/dist/lib/wtlink/main-menu.test.d.ts +0 -5
  404. package/dist/lib/wtlink/main-menu.test.d.ts.map +0 -1
  405. package/dist/lib/wtlink/main-menu.test.js +0 -126
  406. package/dist/lib/wtlink/main-menu.test.js.map +0 -1
  407. package/dist/lib/wtlink/manage-manifest.test.d.ts +0 -2
  408. package/dist/lib/wtlink/manage-manifest.test.d.ts.map +0 -1
  409. package/dist/lib/wtlink/manage-manifest.test.js +0 -714
  410. package/dist/lib/wtlink/manage-manifest.test.js.map +0 -1
  411. package/dist/lib/wtlink/validate-manifest.test.d.ts +0 -2
  412. package/dist/lib/wtlink/validate-manifest.test.d.ts.map +0 -1
  413. package/dist/lib/wtlink/validate-manifest.test.js +0 -220
  414. package/dist/lib/wtlink/validate-manifest.test.js.map +0 -1
  415. package/dist/lib/wtstate/analyze.test.d.ts +0 -5
  416. package/dist/lib/wtstate/analyze.test.d.ts.map +0 -1
  417. package/dist/lib/wtstate/analyze.test.js +0 -282
  418. package/dist/lib/wtstate/analyze.test.js.map +0 -1
  419. package/dist/lib/wtstate/args.test.d.ts +0 -5
  420. package/dist/lib/wtstate/args.test.d.ts.map +0 -1
  421. package/dist/lib/wtstate/args.test.js +0 -120
  422. package/dist/lib/wtstate/args.test.js.map +0 -1
  423. package/dist/mcp/server.test.d.ts +0 -9
  424. package/dist/mcp/server.test.d.ts.map +0 -1
  425. package/dist/mcp/server.test.js +0 -550
  426. package/dist/mcp/server.test.js.map +0 -1
@@ -1,624 +0,0 @@
1
- /**
2
- * Tests for wt clean command handler
3
- *
4
- * Exercises the handler through different code paths to cover internal
5
- * helper functions: outputJsonResult, outputJsonError, resultToCleanedInfo, printWorktree.
6
- */
7
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
8
- // Mock all dependencies before imports
9
- vi.mock('child_process', () => ({
10
- execSync: vi.fn(),
11
- }));
12
- vi.mock('../../lib/git.js', () => ({
13
- getRepoRoot: vi.fn().mockReturnValue('/fake/repo'),
14
- getMainWorktreeRoot: vi.fn().mockReturnValue('/fake/repo'),
15
- removeWorktree: vi.fn(),
16
- pruneWorktrees: vi.fn(),
17
- }));
18
- vi.mock('../../lib/github.js', () => ({
19
- isGhInstalled: vi.fn().mockReturnValue(true),
20
- }));
21
- vi.mock('../../lib/prompts.js', () => ({
22
- withSpinner: vi.fn((_msg, fn) => fn()),
23
- promptChoice: vi.fn(),
24
- promptConfirm: vi.fn(),
25
- }));
26
- vi.mock('../../lib/config.js', () => ({
27
- loadConfig: vi.fn().mockReturnValue({
28
- worktreePattern: '{repo}.pr{number}',
29
- baseBranch: 'main',
30
- }),
31
- }));
32
- vi.mock('../../lib/logger.js', () => ({
33
- logger: { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() },
34
- }));
35
- vi.mock('../../lib/colors.js', () => ({
36
- error: vi.fn((s) => s),
37
- dim: vi.fn((s) => s),
38
- success: vi.fn((s) => s),
39
- info: vi.fn((s) => s),
40
- cyan: vi.fn((s) => s),
41
- yellow: vi.fn((s) => s),
42
- red: vi.fn((s) => s),
43
- green: vi.fn((s) => s),
44
- bold: vi.fn((s) => s),
45
- warning: vi.fn((s) => s),
46
- }));
47
- vi.mock('../../lib/cleanpr/index.js', () => ({
48
- gatherPrWorktreeInfo: vi.fn().mockResolvedValue([]),
49
- createDefaultDeps: vi.fn().mockReturnValue({}),
50
- groupWorktreesByState: vi.fn().mockReturnValue({ merged: [], closed: [], open: [], unknown: [] }),
51
- getCleanableWorktrees: vi.fn().mockReturnValue([]),
52
- findWorktreeByPrNumber: vi.fn().mockReturnValue(null),
53
- cleanWorktree: vi.fn().mockReturnValue({
54
- success: true,
55
- prNumber: 42,
56
- message: 'Cleaned PR #42',
57
- localBranchDeleted: true,
58
- remoteBranchDeleted: false,
59
- }),
60
- summarizeResults: vi.fn().mockReturnValue({ cleaned: 0, total: 0, failed: 0 }),
61
- }));
62
- vi.mock('../../lib/ui/index.js', () => ({
63
- setJsonMode: vi.fn(),
64
- isJsonMode: vi.fn().mockReturnValue(false),
65
- printStatus: vi.fn(),
66
- printDim: vi.fn(),
67
- printError: vi.fn(),
68
- printHeader: vi.fn(),
69
- printNextSteps: vi.fn(),
70
- changeIndicator: vi.fn().mockReturnValue(''),
71
- errorToDisplay: vi.fn().mockReturnValue({ title: 'error' }),
72
- }));
73
- vi.mock('../../lib/json-output.js', async (importOriginal) => {
74
- const actual = await importOriginal();
75
- return {
76
- ...actual,
77
- createSuccessResult: vi.fn().mockReturnValue({ success: true }),
78
- createErrorResult: vi.fn().mockReturnValue({ success: false }),
79
- formatJsonResult: vi.fn().mockReturnValue('{}'),
80
- };
81
- });
82
- // Import the command under test
83
- import { cleanCommand } from './clean.js';
84
- // Import mocked modules for assertions and setup
85
- import * as git from '../../lib/git.js';
86
- import * as github from '../../lib/github.js';
87
- import { gatherPrWorktreeInfo, getCleanableWorktrees, findWorktreeByPrNumber, cleanWorktree, summarizeResults, groupWorktreesByState, } from '../../lib/cleanpr/index.js';
88
- import { setJsonMode, printError, printStatus, printDim, printNextSteps, changeIndicator, } from '../../lib/ui/index.js';
89
- import { createSuccessResult, createErrorResult, formatJsonResult, ErrorCode, } from '../../lib/json-output.js';
90
- // Mock process.exit - throws to halt execution (mimics real exit behavior)
91
- class ExitError extends Error {
92
- code;
93
- constructor(code) {
94
- super(`process.exit(${code})`);
95
- this.code = code;
96
- }
97
- }
98
- const mockExit = vi.spyOn(process, 'exit').mockImplementation((code) => {
99
- throw new ExitError(code);
100
- });
101
- // Capture console.log output for JSON assertions
102
- const mockConsoleLog = vi.spyOn(console, 'log').mockImplementation(() => { });
103
- function makeWorktree(overrides = {}) {
104
- return {
105
- path: '/fake/repo.pr42',
106
- branch: 'feat/thing',
107
- commit: 'abc1234',
108
- prNumber: 42,
109
- prState: 'MERGED',
110
- hasChanges: false,
111
- ...overrides,
112
- };
113
- }
114
- function makeCleanupResult(overrides = {}) {
115
- return {
116
- success: true,
117
- prNumber: 42,
118
- message: 'Cleaned PR #42',
119
- localBranchDeleted: true,
120
- remoteBranchDeleted: false,
121
- ...overrides,
122
- };
123
- }
124
- describe('wt clean handler', () => {
125
- beforeEach(() => {
126
- vi.clearAllMocks();
127
- // Restore default mock return values
128
- vi.mocked(git.getRepoRoot).mockReturnValue('/fake/repo');
129
- vi.mocked(github.isGhInstalled).mockReturnValue(true);
130
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([]);
131
- vi.mocked(getCleanableWorktrees).mockReturnValue([]);
132
- vi.mocked(findWorktreeByPrNumber).mockReturnValue(undefined);
133
- vi.mocked(changeIndicator).mockReturnValue('');
134
- });
135
- afterEach(() => {
136
- mockExit.mockClear();
137
- mockConsoleLog.mockClear();
138
- });
139
- // =========================================================================
140
- // Error paths with JSON output
141
- // =========================================================================
142
- describe('prerequisite errors with --json', () => {
143
- it('outputs JSON error when gh is not installed', async () => {
144
- vi.mocked(github.isGhInstalled).mockReturnValue(false);
145
- await expect(cleanCommand.handler({
146
- all: true,
147
- 'dry-run': false,
148
- force: false,
149
- json: true,
150
- })).rejects.toThrow(ExitError);
151
- expect(setJsonMode).toHaveBeenCalledWith(true);
152
- expect(createErrorResult).toHaveBeenCalledWith('cleanpr', ErrorCode.GH_NOT_INSTALLED, expect.stringContaining('GitHub CLI'));
153
- expect(formatJsonResult).toHaveBeenCalled();
154
- expect(mockConsoleLog).toHaveBeenCalledWith('{}');
155
- expect(mockExit).toHaveBeenCalledWith(1);
156
- });
157
- it('outputs JSON error when not in a git repo', async () => {
158
- vi.mocked(git.getRepoRoot).mockReturnValue(null);
159
- await expect(cleanCommand.handler({
160
- all: true,
161
- 'dry-run': false,
162
- force: false,
163
- json: true,
164
- })).rejects.toThrow(ExitError);
165
- expect(createErrorResult).toHaveBeenCalledWith('cleanpr', ErrorCode.NOT_GIT_REPO, expect.stringContaining('git repository'));
166
- expect(formatJsonResult).toHaveBeenCalled();
167
- expect(mockExit).toHaveBeenCalledWith(1);
168
- });
169
- });
170
- // =========================================================================
171
- // --all --json: no worktrees found
172
- // =========================================================================
173
- describe('--all --json with no worktrees', () => {
174
- it('outputs JSON success with zero cleaned message', async () => {
175
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([]);
176
- vi.mocked(getCleanableWorktrees).mockReturnValue([]);
177
- await cleanCommand.handler({
178
- all: true,
179
- 'dry-run': false,
180
- force: false,
181
- json: true,
182
- });
183
- // cleanAll path: no cleanable worktrees, json mode -> outputs success JSON directly
184
- expect(createSuccessResult).toHaveBeenCalledWith('cleanpr', expect.objectContaining({
185
- totalCleaned: 0,
186
- totalSkipped: 0,
187
- message: expect.stringContaining('No merged or closed'),
188
- }));
189
- expect(formatJsonResult).toHaveBeenCalled();
190
- expect(mockConsoleLog).toHaveBeenCalledWith('{}');
191
- });
192
- });
193
- // =========================================================================
194
- // --all --json: cleanable worktrees found (exercises outputJsonResult non-dry-run)
195
- // =========================================================================
196
- describe('--all --json with cleanable worktrees', () => {
197
- it('outputs JSON result with cleaned worktrees', async () => {
198
- const wt1 = makeWorktree({
199
- prNumber: 10,
200
- branch: 'feat/a',
201
- path: '/fake/repo.pr10',
202
- prState: 'MERGED',
203
- });
204
- const wt2 = makeWorktree({
205
- prNumber: 20,
206
- branch: 'feat/b',
207
- path: '/fake/repo.pr20',
208
- prState: 'CLOSED',
209
- });
210
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt1, wt2]);
211
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt1, wt2]);
212
- vi.mocked(cleanWorktree)
213
- .mockReturnValueOnce(makeCleanupResult({ prNumber: 10, message: 'Cleaned PR #10' }))
214
- .mockReturnValueOnce(makeCleanupResult({ prNumber: 20, message: 'Cleaned PR #20' }));
215
- await cleanCommand.handler({
216
- all: true,
217
- 'dry-run': false,
218
- force: false,
219
- json: true,
220
- });
221
- // outputJsonResult called for non-dry-run path
222
- expect(cleanWorktree).toHaveBeenCalledTimes(2);
223
- expect(createSuccessResult).toHaveBeenCalledWith('cleanpr', expect.objectContaining({
224
- totalCleaned: 2,
225
- totalSkipped: 0,
226
- }));
227
- // printStatus should NOT be called in json mode
228
- expect(printStatus).not.toHaveBeenCalled();
229
- });
230
- it('includes skipped entries for failed cleanups', async () => {
231
- const wt1 = makeWorktree({ prNumber: 10, path: '/fake/repo.pr10' });
232
- const wt2 = makeWorktree({ prNumber: 20, path: '/fake/repo.pr20' });
233
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt1, wt2]);
234
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt1, wt2]);
235
- vi.mocked(cleanWorktree)
236
- .mockReturnValueOnce(makeCleanupResult({ prNumber: 10, success: true }))
237
- .mockReturnValueOnce(makeCleanupResult({ prNumber: 20, success: false, message: 'Has uncommitted changes' }));
238
- await cleanCommand.handler({
239
- all: true,
240
- 'dry-run': false,
241
- force: false,
242
- json: true,
243
- });
244
- expect(createSuccessResult).toHaveBeenCalledWith('cleanpr', expect.objectContaining({
245
- totalCleaned: 1,
246
- totalSkipped: 1,
247
- }));
248
- });
249
- });
250
- // =========================================================================
251
- // --all --json --dry-run: exercises outputJsonResult dry-run branch
252
- // =========================================================================
253
- describe('--all --json --dry-run with cleanable worktrees', () => {
254
- it('outputs dry-run JSON with wouldClean entries', async () => {
255
- const wt1 = makeWorktree({
256
- prNumber: 10,
257
- branch: 'feat/a',
258
- path: '/fake/repo.pr10',
259
- prState: 'MERGED',
260
- });
261
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt1]);
262
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt1]);
263
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult({ prNumber: 10, success: true, dryRun: true }));
264
- await cleanCommand.handler({
265
- all: true,
266
- 'dry-run': true,
267
- force: false,
268
- json: true,
269
- });
270
- expect(createSuccessResult).toHaveBeenCalledWith('cleanpr', expect.objectContaining({
271
- wouldClean: expect.arrayContaining([
272
- expect.objectContaining({ prNumber: 10, branch: 'feat/a' }),
273
- ]),
274
- totalWouldClean: 1,
275
- message: expect.stringContaining('Would clean 1 PR worktree'),
276
- }));
277
- });
278
- it('outputs dry-run JSON with zero wouldClean when all fail', async () => {
279
- const wt1 = makeWorktree({ prNumber: 10, path: '/fake/repo.pr10' });
280
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt1]);
281
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt1]);
282
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult({ prNumber: 10, success: false, message: 'Failed' }));
283
- await cleanCommand.handler({
284
- all: true,
285
- 'dry-run': true,
286
- force: false,
287
- json: true,
288
- });
289
- expect(createSuccessResult).toHaveBeenCalledWith('cleanpr', expect.objectContaining({
290
- wouldClean: [],
291
- totalWouldClean: 0,
292
- message: expect.stringContaining('No PR worktrees would be cleaned'),
293
- }));
294
- });
295
- });
296
- // =========================================================================
297
- // Specific PR number path (cleanSpecific)
298
- // =========================================================================
299
- describe('specific PR number', () => {
300
- it('cleans specific PR and outputs JSON result', async () => {
301
- const wt = makeWorktree({ prNumber: 42, branch: 'feat/thing', path: '/fake/repo.pr42' });
302
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt]);
303
- vi.mocked(findWorktreeByPrNumber).mockReturnValue(wt);
304
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult({ prNumber: 42 }));
305
- await cleanCommand.handler({
306
- prNumber: 42,
307
- all: false,
308
- 'dry-run': false,
309
- force: false,
310
- json: true,
311
- });
312
- expect(findWorktreeByPrNumber).toHaveBeenCalled();
313
- expect(cleanWorktree).toHaveBeenCalledTimes(1);
314
- // JSON output via outputJsonResult
315
- expect(createSuccessResult).toHaveBeenCalledWith('cleanpr', expect.objectContaining({
316
- totalCleaned: 1,
317
- }));
318
- });
319
- it('outputs JSON error when specific PR not found', async () => {
320
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([]);
321
- vi.mocked(findWorktreeByPrNumber).mockReturnValue(undefined);
322
- await expect(cleanCommand.handler({
323
- prNumber: 999,
324
- all: false,
325
- 'dry-run': false,
326
- force: false,
327
- json: true,
328
- })).rejects.toThrow(ExitError);
329
- // outputJsonError path
330
- expect(createErrorResult).toHaveBeenCalledWith('cleanpr', ErrorCode.PR_NOT_FOUND, expect.stringContaining('No worktree found for PR #999'));
331
- expect(mockExit).toHaveBeenCalledWith(1);
332
- });
333
- it('prints error display when specific PR not found without --json', async () => {
334
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([]);
335
- vi.mocked(findWorktreeByPrNumber).mockReturnValue(undefined);
336
- await expect(cleanCommand.handler({
337
- prNumber: 999,
338
- all: false,
339
- 'dry-run': false,
340
- force: false,
341
- json: false,
342
- })).rejects.toThrow(ExitError);
343
- expect(printError).toHaveBeenCalledWith(expect.objectContaining({
344
- title: expect.stringContaining('No worktree found for PR #999'),
345
- }));
346
- expect(mockExit).toHaveBeenCalledWith(1);
347
- });
348
- it('prints success status for non-json specific PR cleanup', async () => {
349
- const wt = makeWorktree({ prNumber: 42 });
350
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt]);
351
- vi.mocked(findWorktreeByPrNumber).mockReturnValue(wt);
352
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult({ prNumber: 42, success: true }));
353
- await cleanCommand.handler({
354
- prNumber: 42,
355
- all: false,
356
- 'dry-run': false,
357
- force: false,
358
- json: false,
359
- });
360
- expect(printStatus).toHaveBeenCalledWith('info', expect.stringContaining('Cleaning PR #42'));
361
- expect(printDim).toHaveBeenCalled();
362
- expect(printStatus).toHaveBeenCalledWith('success', expect.stringContaining('PR #42 worktree cleaned up successfully'));
363
- expect(printNextSteps).toHaveBeenCalled();
364
- });
365
- it('prints dry-run info status for specific PR', async () => {
366
- const wt = makeWorktree({ prNumber: 42 });
367
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt]);
368
- vi.mocked(findWorktreeByPrNumber).mockReturnValue(wt);
369
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult({ prNumber: 42, success: true, message: 'Would clean PR #42' }));
370
- await cleanCommand.handler({
371
- prNumber: 42,
372
- all: false,
373
- 'dry-run': true,
374
- force: false,
375
- json: false,
376
- });
377
- expect(printStatus).toHaveBeenCalledWith('info', expect.stringContaining('Would clean'));
378
- });
379
- it('prints warning and exits 1 on failed specific PR cleanup', async () => {
380
- const wt = makeWorktree({ prNumber: 42 });
381
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt]);
382
- vi.mocked(findWorktreeByPrNumber).mockReturnValue(wt);
383
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult({ prNumber: 42, success: false, message: 'Has uncommitted changes' }));
384
- await expect(cleanCommand.handler({
385
- prNumber: 42,
386
- all: false,
387
- 'dry-run': false,
388
- force: false,
389
- json: false,
390
- })).rejects.toThrow(ExitError);
391
- expect(printStatus).toHaveBeenCalledWith('warning', 'Has uncommitted changes');
392
- expect(mockExit).toHaveBeenCalledWith(1);
393
- });
394
- });
395
- // =========================================================================
396
- // --all without --json: text output paths
397
- // =========================================================================
398
- describe('--all without --json (text output)', () => {
399
- it('prints info when no cleanable worktrees found', async () => {
400
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([]);
401
- vi.mocked(getCleanableWorktrees).mockReturnValue([]);
402
- await cleanCommand.handler({
403
- all: true,
404
- 'dry-run': false,
405
- force: false,
406
- json: false,
407
- });
408
- expect(printStatus).toHaveBeenCalledWith('info', expect.stringContaining('No merged or closed'));
409
- });
410
- it('prints success/warning per worktree and summary', async () => {
411
- const wt1 = makeWorktree({ prNumber: 10 });
412
- const wt2 = makeWorktree({ prNumber: 20 });
413
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt1, wt2]);
414
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt1, wt2]);
415
- vi.mocked(cleanWorktree)
416
- .mockReturnValueOnce(makeCleanupResult({ prNumber: 10, success: true, message: 'Cleaned #10' }))
417
- .mockReturnValueOnce(makeCleanupResult({ prNumber: 20, success: false, message: 'Failed #20' }));
418
- vi.mocked(summarizeResults).mockReturnValue({ cleaned: 1, total: 2, failed: 1 });
419
- await cleanCommand.handler({
420
- all: true,
421
- 'dry-run': false,
422
- force: false,
423
- json: false,
424
- });
425
- expect(printStatus).toHaveBeenCalledWith('success', 'Cleaned #10');
426
- expect(printStatus).toHaveBeenCalledWith('warning', 'Failed #20');
427
- expect(printStatus).toHaveBeenCalledWith('success', expect.stringContaining('Cleaned 1 of 2'));
428
- });
429
- it('prints dry-run summary for text output', async () => {
430
- const wt1 = makeWorktree({ prNumber: 10 });
431
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt1]);
432
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt1]);
433
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult({ prNumber: 10, success: true, message: 'Would clean' }));
434
- vi.mocked(summarizeResults).mockReturnValue({ cleaned: 1, total: 1, failed: 0 });
435
- await cleanCommand.handler({
436
- all: true,
437
- 'dry-run': true,
438
- force: false,
439
- json: false,
440
- });
441
- expect(printStatus).toHaveBeenCalledWith('info', expect.stringContaining('Would clean 1 of 1'));
442
- });
443
- it('shows next steps when worktrees were cleaned', async () => {
444
- const wt1 = makeWorktree({ prNumber: 10 });
445
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt1]);
446
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt1]);
447
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult({ prNumber: 10, success: true }));
448
- vi.mocked(summarizeResults).mockReturnValue({ cleaned: 1, total: 1, failed: 0 });
449
- await cleanCommand.handler({
450
- all: true,
451
- 'dry-run': false,
452
- force: false,
453
- json: false,
454
- });
455
- expect(printNextSteps).toHaveBeenCalled();
456
- });
457
- });
458
- // =========================================================================
459
- // Interactive mode with --json (not supported)
460
- // =========================================================================
461
- describe('interactive mode with --json', () => {
462
- it('outputs JSON error for interactive + json combination', async () => {
463
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([]);
464
- await expect(cleanCommand.handler({
465
- all: false,
466
- 'dry-run': false,
467
- force: false,
468
- json: true,
469
- // prNumber is undefined -> interactive mode
470
- })).rejects.toThrow(ExitError);
471
- expect(createErrorResult).toHaveBeenCalledWith('cleanpr', ErrorCode.INVALID_ARGUMENT, expect.stringContaining('Interactive mode not supported'));
472
- expect(mockExit).toHaveBeenCalledWith(1);
473
- });
474
- });
475
- // =========================================================================
476
- // printWorktree coverage (via interactiveClean path)
477
- // =========================================================================
478
- describe('interactive mode (non-json)', () => {
479
- it('prints grouped worktrees and shows no-cleanable message', async () => {
480
- const openWt = makeWorktree({ prNumber: 10, prState: 'OPEN', branch: 'feat/open' });
481
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([openWt]);
482
- vi.mocked(groupWorktreesByState).mockReturnValue({
483
- merged: [],
484
- closed: [],
485
- open: [openWt],
486
- unknown: [],
487
- });
488
- vi.mocked(getCleanableWorktrees).mockReturnValue([]);
489
- await cleanCommand.handler({
490
- all: false,
491
- 'dry-run': false,
492
- force: false,
493
- json: false,
494
- });
495
- // printWorktree is called for open worktrees
496
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('PR #10: feat/open'));
497
- expect(printStatus).toHaveBeenCalledWith('info', expect.stringContaining('No merged or closed PRs to clean'));
498
- });
499
- it('prints all four groups when all states present', async () => {
500
- const merged = makeWorktree({ prNumber: 1, prState: 'MERGED', branch: 'feat/merged' });
501
- const closed = makeWorktree({ prNumber: 2, prState: 'CLOSED', branch: 'feat/closed' });
502
- const open = makeWorktree({ prNumber: 3, prState: 'OPEN', branch: 'feat/open' });
503
- const unknown = makeWorktree({ prNumber: 4, prState: 'UNKNOWN', branch: 'feat/unknown' });
504
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([merged, closed, open, unknown]);
505
- vi.mocked(groupWorktreesByState).mockReturnValue({
506
- merged: [merged],
507
- closed: [closed],
508
- open: [open],
509
- unknown: [unknown],
510
- });
511
- vi.mocked(getCleanableWorktrees).mockReturnValue([]);
512
- await cleanCommand.handler({
513
- all: false,
514
- 'dry-run': false,
515
- force: false,
516
- json: false,
517
- });
518
- // Each group header is printed
519
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Merged (1)'));
520
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Closed (1)'));
521
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Open (1)'));
522
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Unknown (1)'));
523
- // printWorktree called for each
524
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('PR #1: feat/merged'));
525
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('PR #2: feat/closed'));
526
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('PR #3: feat/open'));
527
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('PR #4: feat/unknown'));
528
- });
529
- it('prints "No PR worktrees found" when list is empty', async () => {
530
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([]);
531
- await cleanCommand.handler({
532
- all: false,
533
- 'dry-run': false,
534
- force: false,
535
- json: false,
536
- });
537
- expect(printStatus).toHaveBeenCalledWith('info', 'No PR worktrees found.');
538
- });
539
- });
540
- // =========================================================================
541
- // printWorktree with changes indicator
542
- // =========================================================================
543
- describe('printWorktree with changes', () => {
544
- it('includes change indicator in output', async () => {
545
- const wt = makeWorktree({ prNumber: 55, branch: 'feat/dirty', hasChanges: true });
546
- vi.mocked(changeIndicator).mockReturnValue(' [modified]');
547
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt]);
548
- vi.mocked(groupWorktreesByState).mockReturnValue({
549
- merged: [wt],
550
- closed: [],
551
- open: [],
552
- unknown: [],
553
- });
554
- vi.mocked(getCleanableWorktrees).mockReturnValue([]);
555
- await cleanCommand.handler({
556
- all: false,
557
- 'dry-run': false,
558
- force: false,
559
- json: false,
560
- });
561
- expect(changeIndicator).toHaveBeenCalledWith(true);
562
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('PR #55: feat/dirty [modified]'));
563
- });
564
- });
565
- // =========================================================================
566
- // Options mapping
567
- // =========================================================================
568
- describe('options mapping', () => {
569
- it('maps --delete-remote to options.deleteRemote', async () => {
570
- const wt = makeWorktree({ prNumber: 42 });
571
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt]);
572
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt]);
573
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult());
574
- await cleanCommand.handler({
575
- all: true,
576
- 'dry-run': false,
577
- force: false,
578
- 'delete-remote': true,
579
- json: false,
580
- });
581
- expect(cleanWorktree).toHaveBeenCalledWith(wt, expect.objectContaining({ deleteRemote: true }), expect.any(Object));
582
- });
583
- it('maps --force to options.force', async () => {
584
- const wt = makeWorktree({ prNumber: 42 });
585
- vi.mocked(gatherPrWorktreeInfo).mockResolvedValue([wt]);
586
- vi.mocked(getCleanableWorktrees).mockReturnValue([wt]);
587
- vi.mocked(cleanWorktree).mockReturnValue(makeCleanupResult());
588
- await cleanCommand.handler({
589
- all: true,
590
- 'dry-run': false,
591
- force: true,
592
- json: false,
593
- });
594
- expect(cleanWorktree).toHaveBeenCalledWith(wt, expect.objectContaining({ force: true }), expect.any(Object));
595
- });
596
- });
597
- // =========================================================================
598
- // JSON mode skips spinner
599
- // =========================================================================
600
- describe('spinner behavior', () => {
601
- it('skips spinner in json mode and calls gatherPrWorktreeInfo directly', async () => {
602
- const { withSpinner } = await import('../../lib/prompts.js');
603
- await cleanCommand.handler({
604
- all: true,
605
- 'dry-run': false,
606
- force: false,
607
- json: true,
608
- });
609
- expect(withSpinner).not.toHaveBeenCalled();
610
- expect(gatherPrWorktreeInfo).toHaveBeenCalled();
611
- });
612
- it('uses spinner in non-json mode', async () => {
613
- const { withSpinner } = await import('../../lib/prompts.js');
614
- await cleanCommand.handler({
615
- all: true,
616
- 'dry-run': false,
617
- force: false,
618
- json: false,
619
- });
620
- expect(withSpinner).toHaveBeenCalledWith('Scanning worktrees...', expect.any(Function));
621
- });
622
- });
623
- });
624
- //# sourceMappingURL=clean.test.js.map