@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,807 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import readline from 'readline';
3
- import { promptChoiceIndex, promptChoice, promptConfirm, promptInput, printHeader, printListItem, withSpinner, UserNavigatedBack, } from './prompts.js';
4
- // Mock readline
5
- vi.mock('readline', () => ({
6
- default: {
7
- createInterface: vi.fn(),
8
- emitKeypressEvents: vi.fn(),
9
- },
10
- }));
11
- // Mock console.log
12
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
13
- const stdoutWriteSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
14
- describe('prompts', () => {
15
- let mockRl;
16
- beforeEach(() => {
17
- vi.clearAllMocks();
18
- mockRl = {
19
- question: vi.fn(),
20
- close: vi.fn(),
21
- on: vi.fn(),
22
- };
23
- vi.mocked(readline.createInterface).mockReturnValue(mockRl);
24
- });
25
- afterEach(() => {
26
- consoleSpy.mockClear();
27
- stdoutWriteSpy.mockClear();
28
- });
29
- describe('promptChoiceIndex', () => {
30
- it('displays prompt and options', async () => {
31
- mockRl.question.mockImplementation((_, callback) => {
32
- callback('1');
33
- });
34
- await promptChoiceIndex('Choose an option:', ['Option A', 'Option B', 'Option C']);
35
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Choose an option:'));
36
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Option A'));
37
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Option B'));
38
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Option C'));
39
- });
40
- it('returns 1-based index of selected option', async () => {
41
- mockRl.question.mockImplementation((_, callback) => {
42
- callback('2');
43
- });
44
- const result = await promptChoiceIndex('Choose:', ['A', 'B', 'C']);
45
- expect(result).toBe(2);
46
- expect(mockRl.close).toHaveBeenCalled();
47
- });
48
- it('re-prompts on invalid input', async () => {
49
- let callCount = 0;
50
- mockRl.question.mockImplementation((_, callback) => {
51
- callCount++;
52
- if (callCount === 1) {
53
- callback('invalid');
54
- }
55
- else if (callCount === 2) {
56
- callback('5'); // out of range
57
- }
58
- else {
59
- callback('1'); // valid
60
- }
61
- });
62
- const result = await promptChoiceIndex('Choose:', ['A', 'B']);
63
- expect(result).toBe(1);
64
- expect(mockRl.question).toHaveBeenCalledTimes(3);
65
- });
66
- it('re-prompts on empty input', async () => {
67
- let callCount = 0;
68
- mockRl.question.mockImplementation((_, callback) => {
69
- callCount++;
70
- if (callCount === 1) {
71
- callback('');
72
- }
73
- else {
74
- callback('1');
75
- }
76
- });
77
- const result = await promptChoiceIndex('Choose:', ['A']);
78
- expect(result).toBe(1);
79
- expect(mockRl.question).toHaveBeenCalledTimes(2);
80
- });
81
- it('rejects on quit command', async () => {
82
- mockRl.question.mockImplementation((_, callback) => {
83
- callback('q');
84
- });
85
- await expect(promptChoiceIndex('Choose:', ['A', 'B'])).rejects.toThrow('User cancelled');
86
- });
87
- it('rejects on quit word', async () => {
88
- mockRl.question.mockImplementation((_, callback) => {
89
- callback('quit');
90
- });
91
- await expect(promptChoiceIndex('Choose:', ['A'])).rejects.toThrow('User cancelled');
92
- });
93
- it('rejects on SIGINT', async () => {
94
- let sigintHandler = null;
95
- mockRl.on.mockImplementation((event, handler) => {
96
- if (event === 'SIGINT') {
97
- sigintHandler = handler;
98
- }
99
- return mockRl;
100
- });
101
- mockRl.question.mockImplementation(() => {
102
- setImmediate(() => {
103
- if (sigintHandler) {
104
- sigintHandler();
105
- }
106
- });
107
- });
108
- await expect(promptChoiceIndex('Choose:', ['A', 'B'])).rejects.toThrow('User cancelled');
109
- expect(mockRl.close).toHaveBeenCalled();
110
- });
111
- });
112
- describe('promptChoice', () => {
113
- it('returns value of selected option', async () => {
114
- mockRl.question.mockImplementation((_, callback) => {
115
- callback('2');
116
- });
117
- const result = await promptChoice('Choose:', [
118
- { label: 'First', value: 'first-value' },
119
- { label: 'Second', value: 'second-value' },
120
- { label: 'Third', value: 'third-value' },
121
- ]);
122
- expect(result).toBe('second-value');
123
- });
124
- it('displays descriptions when provided', async () => {
125
- mockRl.question.mockImplementation((_, callback) => {
126
- callback('1');
127
- });
128
- await promptChoice('Choose:', [
129
- { label: 'Option', description: 'A helpful description', value: 'opt' },
130
- ]);
131
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('A helpful description'));
132
- });
133
- it('works with typed values', async () => {
134
- mockRl.question.mockImplementation((_, callback) => {
135
- callback('1');
136
- });
137
- const result = await promptChoice('Choose:', [
138
- { label: 'Item 1', value: { id: 1, name: 'One' } },
139
- { label: 'Item 2', value: { id: 2, name: 'Two' } },
140
- ]);
141
- expect(result).toEqual({ id: 1, name: 'One' });
142
- });
143
- it('re-prompts on invalid choice', async () => {
144
- let callCount = 0;
145
- mockRl.question.mockImplementation((_, callback) => {
146
- callCount++;
147
- if (callCount === 1) {
148
- callback('99'); // invalid choice
149
- }
150
- else {
151
- callback('1'); // valid choice
152
- }
153
- });
154
- const result = await promptChoice('Choose:', [
155
- { label: 'Option A', value: 'a' },
156
- { label: 'Option B', value: 'b' },
157
- ]);
158
- expect(result).toBe('a');
159
- expect(mockRl.question).toHaveBeenCalledTimes(2);
160
- });
161
- it('re-prompts on empty input', async () => {
162
- let callCount = 0;
163
- mockRl.question.mockImplementation((_, callback) => {
164
- callCount++;
165
- if (callCount === 1) {
166
- callback(''); // empty input
167
- }
168
- else {
169
- callback('1'); // valid choice
170
- }
171
- });
172
- const result = await promptChoice('Choose:', [{ label: 'Option A', value: 'a' }]);
173
- expect(result).toBe('a');
174
- expect(mockRl.question).toHaveBeenCalledTimes(2);
175
- });
176
- it('rejects on quit command', async () => {
177
- mockRl.question.mockImplementation((_, callback) => {
178
- callback('q');
179
- });
180
- await expect(promptChoice('Choose:', [{ label: 'A', value: 'a' }])).rejects.toThrow('User cancelled');
181
- });
182
- it('rejects on quit word', async () => {
183
- mockRl.question.mockImplementation((_, callback) => {
184
- callback('quit');
185
- });
186
- await expect(promptChoice('Choose:', [{ label: 'A', value: 'a' }])).rejects.toThrow('User cancelled');
187
- });
188
- it('rejects on SIGINT', async () => {
189
- let sigintHandler = null;
190
- mockRl.on.mockImplementation((event, handler) => {
191
- if (event === 'SIGINT') {
192
- sigintHandler = handler;
193
- }
194
- return mockRl;
195
- });
196
- mockRl.question.mockImplementation(() => {
197
- setImmediate(() => {
198
- if (sigintHandler) {
199
- sigintHandler();
200
- }
201
- });
202
- });
203
- await expect(promptChoice('Choose:', [{ label: 'A', value: 'a' }])).rejects.toThrow('User cancelled');
204
- expect(mockRl.close).toHaveBeenCalled();
205
- });
206
- });
207
- describe('promptConfirm', () => {
208
- it('returns true for y input', async () => {
209
- mockRl.question.mockImplementation((_, callback) => {
210
- callback('y');
211
- });
212
- const result = await promptConfirm('Continue?');
213
- expect(result).toBe(true);
214
- });
215
- it('returns true for yes input', async () => {
216
- mockRl.question.mockImplementation((_, callback) => {
217
- callback('yes');
218
- });
219
- const result = await promptConfirm('Continue?');
220
- expect(result).toBe(true);
221
- });
222
- it('returns true for Y input (case insensitive)', async () => {
223
- mockRl.question.mockImplementation((_, callback) => {
224
- callback('Y');
225
- });
226
- const result = await promptConfirm('Continue?');
227
- expect(result).toBe(true);
228
- });
229
- it('returns false for n input', async () => {
230
- mockRl.question.mockImplementation((_, callback) => {
231
- callback('n');
232
- });
233
- const result = await promptConfirm('Continue?');
234
- expect(result).toBe(false);
235
- });
236
- it('returns false for no input', async () => {
237
- mockRl.question.mockImplementation((_, callback) => {
238
- callback('no');
239
- });
240
- const result = await promptConfirm('Continue?');
241
- expect(result).toBe(false);
242
- });
243
- it('returns default false for empty input', async () => {
244
- mockRl.question.mockImplementation((_, callback) => {
245
- callback('');
246
- });
247
- const result = await promptConfirm('Continue?');
248
- expect(result).toBe(false);
249
- });
250
- it('returns default true when specified', async () => {
251
- mockRl.question.mockImplementation((_, callback) => {
252
- callback('');
253
- });
254
- const result = await promptConfirm('Continue?', true);
255
- expect(result).toBe(true);
256
- });
257
- it('returns default for invalid input', async () => {
258
- mockRl.question.mockImplementation((_, callback) => {
259
- callback('maybe');
260
- });
261
- const result = await promptConfirm('Continue?', true);
262
- expect(result).toBe(true);
263
- });
264
- it('displays correct hint for default false', async () => {
265
- mockRl.question.mockImplementation((question, callback) => {
266
- expect(question).toContain('[y/N]');
267
- callback('');
268
- });
269
- await promptConfirm('Continue?', false);
270
- });
271
- it('displays correct hint for default true', async () => {
272
- mockRl.question.mockImplementation((question, callback) => {
273
- expect(question).toContain('[Y/n]');
274
- callback('');
275
- });
276
- await promptConfirm('Continue?', true);
277
- });
278
- it('rejects on SIGINT', async () => {
279
- let sigintHandler = null;
280
- mockRl.on.mockImplementation((event, handler) => {
281
- if (event === 'SIGINT') {
282
- sigintHandler = handler;
283
- }
284
- return mockRl;
285
- });
286
- mockRl.question.mockImplementation(() => {
287
- // Trigger SIGINT asynchronously to allow Promise to be set up
288
- setImmediate(() => {
289
- if (sigintHandler) {
290
- sigintHandler();
291
- }
292
- });
293
- });
294
- await expect(promptConfirm('Continue?')).rejects.toThrow('User cancelled');
295
- expect(mockRl.close).toHaveBeenCalled();
296
- });
297
- });
298
- describe('promptInput', () => {
299
- it('returns user input', async () => {
300
- mockRl.question.mockImplementation((_, callback) => {
301
- callback('user input');
302
- });
303
- const result = await promptInput('Enter value:');
304
- expect(result).toBe('user input');
305
- });
306
- it('trims whitespace', async () => {
307
- mockRl.question.mockImplementation((_, callback) => {
308
- callback(' trimmed ');
309
- });
310
- const result = await promptInput('Enter value:');
311
- expect(result).toBe('trimmed');
312
- });
313
- it('returns default for empty input', async () => {
314
- mockRl.question.mockImplementation((_, callback) => {
315
- callback('');
316
- });
317
- const result = await promptInput('Enter value:', 'default');
318
- expect(result).toBe('default');
319
- });
320
- it('returns empty string if no default and empty input', async () => {
321
- mockRl.question.mockImplementation((_, callback) => {
322
- callback('');
323
- });
324
- const result = await promptInput('Enter value:');
325
- expect(result).toBe('');
326
- });
327
- it('displays default value hint', async () => {
328
- mockRl.question.mockImplementation((question, callback) => {
329
- expect(question).toContain('[default-value]');
330
- callback('');
331
- });
332
- await promptInput('Enter:', 'default-value');
333
- });
334
- it('rejects on SIGINT', async () => {
335
- let sigintHandler = null;
336
- mockRl.on.mockImplementation((event, handler) => {
337
- if (event === 'SIGINT') {
338
- sigintHandler = handler;
339
- }
340
- return mockRl;
341
- });
342
- mockRl.question.mockImplementation(() => {
343
- // Trigger SIGINT asynchronously to allow Promise to be set up
344
- setImmediate(() => {
345
- if (sigintHandler) {
346
- sigintHandler();
347
- }
348
- });
349
- });
350
- await expect(promptInput('Enter value:')).rejects.toThrow('User cancelled');
351
- expect(mockRl.close).toHaveBeenCalled();
352
- });
353
- });
354
- describe('printHeader', () => {
355
- it('prints formatted header', () => {
356
- printHeader('Test Header');
357
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Test Header'));
358
- });
359
- });
360
- describe('printListItem', () => {
361
- it('prints bullet point item', () => {
362
- printListItem('List item');
363
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('•'));
364
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('List item'));
365
- });
366
- it('prints indented item', () => {
367
- printListItem('Indented item', 2);
368
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringMatching(/^\s{4}•/));
369
- });
370
- });
371
- describe('withSpinner', () => {
372
- let originalIsTTY;
373
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
374
- let stdoutWriteSpy;
375
- beforeEach(() => {
376
- originalIsTTY = process.stdout.isTTY;
377
- stdoutWriteSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
378
- vi.useFakeTimers();
379
- });
380
- afterEach(() => {
381
- Object.defineProperty(process.stdout, 'isTTY', {
382
- value: originalIsTTY,
383
- writable: true,
384
- configurable: true,
385
- });
386
- stdoutWriteSpy.mockRestore();
387
- vi.useRealTimers();
388
- });
389
- it('returns the result of the operation', async () => {
390
- Object.defineProperty(process.stdout, 'isTTY', {
391
- value: false,
392
- writable: true,
393
- configurable: true,
394
- });
395
- const result = await withSpinner('Loading...', async () => 'test-result');
396
- expect(result).toBe('test-result');
397
- });
398
- it('logs message when not a TTY', async () => {
399
- Object.defineProperty(process.stdout, 'isTTY', {
400
- value: false,
401
- writable: true,
402
- configurable: true,
403
- });
404
- await withSpinner('Loading data', async () => 'done');
405
- expect(consoleSpy).toHaveBeenCalledWith('Loading data');
406
- });
407
- it('shows spinner animation when TTY', async () => {
408
- Object.defineProperty(process.stdout, 'isTTY', {
409
- value: true,
410
- writable: true,
411
- configurable: true,
412
- });
413
- const promise = withSpinner('Processing', async () => {
414
- await new Promise((resolve) => setTimeout(resolve, 100));
415
- return 'done';
416
- });
417
- // Advance timers to trigger spinner frames
418
- await vi.advanceTimersByTimeAsync(80);
419
- expect(stdoutWriteSpy).toHaveBeenCalled();
420
- // Complete the operation
421
- await vi.advanceTimersByTimeAsync(100);
422
- await promise;
423
- });
424
- it('clears spinner on success when TTY', async () => {
425
- Object.defineProperty(process.stdout, 'isTTY', {
426
- value: true,
427
- writable: true,
428
- configurable: true,
429
- });
430
- const promise = withSpinner('Test', async () => 'result');
431
- await promise;
432
- // Should have written to clear the line
433
- expect(stdoutWriteSpy).toHaveBeenCalledWith(expect.stringContaining('\r'));
434
- });
435
- it('throws error from operation', async () => {
436
- Object.defineProperty(process.stdout, 'isTTY', {
437
- value: false,
438
- writable: true,
439
- configurable: true,
440
- });
441
- await expect(withSpinner('Failing', async () => {
442
- throw new Error('Operation failed');
443
- })).rejects.toThrow('Operation failed');
444
- });
445
- it('clears spinner on error when TTY', async () => {
446
- Object.defineProperty(process.stdout, 'isTTY', {
447
- value: true,
448
- writable: true,
449
- configurable: true,
450
- });
451
- const promise = withSpinner('Error test', async () => {
452
- throw new Error('Test error');
453
- });
454
- await expect(promise).rejects.toThrow('Test error');
455
- // Should have written to clear the line
456
- expect(stdoutWriteSpy).toHaveBeenCalledWith(expect.stringContaining('\r'));
457
- });
458
- });
459
- describe('arrow-key navigation (TTY mode)', () => {
460
- let originalIsTTY;
461
- let mockStdinOn;
462
- let mockStdinRemoveListener;
463
- let mockStdinSetRawMode;
464
- let mockStdinResume;
465
- let mockStdinPause;
466
- beforeEach(() => {
467
- originalIsTTY = process.stdin.isTTY;
468
- // Set up TTY mode
469
- Object.defineProperty(process.stdin, 'isTTY', {
470
- value: true,
471
- writable: true,
472
- configurable: true,
473
- });
474
- // Mock stdin methods
475
- mockStdinOn = vi.fn();
476
- mockStdinRemoveListener = vi.fn();
477
- mockStdinSetRawMode = vi.fn();
478
- mockStdinResume = vi.fn();
479
- mockStdinPause = vi.fn();
480
- // Apply mocks to process.stdin
481
- vi.spyOn(process.stdin, 'on').mockImplementation(mockStdinOn);
482
- vi.spyOn(process.stdin, 'removeListener').mockImplementation(mockStdinRemoveListener);
483
- // Mock setRawMode, resume, pause
484
- Object.defineProperty(process.stdin, 'setRawMode', {
485
- value: mockStdinSetRawMode,
486
- writable: true,
487
- configurable: true,
488
- });
489
- vi.spyOn(process.stdin, 'resume').mockImplementation(mockStdinResume);
490
- vi.spyOn(process.stdin, 'pause').mockImplementation(mockStdinPause);
491
- });
492
- afterEach(() => {
493
- Object.defineProperty(process.stdin, 'isTTY', {
494
- value: originalIsTTY,
495
- writable: true,
496
- configurable: true,
497
- });
498
- vi.restoreAllMocks();
499
- });
500
- describe('promptChoiceIndex with arrow keys', () => {
501
- it('enters arrow-key mode when TTY is available', async () => {
502
- // Simulate Enter key immediately after setup
503
- mockStdinOn.mockImplementation((event, handler) => {
504
- if (event === 'keypress') {
505
- // Simulate pressing Enter immediately
506
- setImmediate(() => {
507
- handler('', { name: 'return' });
508
- });
509
- }
510
- return process.stdin;
511
- });
512
- const result = await promptChoiceIndex('Choose:', ['A', 'B', 'C']);
513
- expect(result).toBe(1); // First option selected (1-based)
514
- expect(mockStdinSetRawMode).toHaveBeenCalledWith(true);
515
- expect(mockStdinResume).toHaveBeenCalled();
516
- });
517
- it('navigates down with arrow key', async () => {
518
- let keypressHandler = null;
519
- mockStdinOn.mockImplementation((event, handler) => {
520
- if (event === 'keypress') {
521
- keypressHandler = handler;
522
- // Simulate pressing down then enter
523
- setImmediate(() => {
524
- handler('', { name: 'down' });
525
- setImmediate(() => {
526
- handler('', { name: 'return' });
527
- });
528
- });
529
- }
530
- return process.stdin;
531
- });
532
- const result = await promptChoiceIndex('Choose:', ['A', 'B', 'C']);
533
- expect(result).toBe(2); // Second option selected (1-based)
534
- });
535
- it('navigates up with arrow key', async () => {
536
- mockStdinOn.mockImplementation((event, handler) => {
537
- if (event === 'keypress') {
538
- // Simulate pressing up (wraps to end) then enter
539
- setImmediate(() => {
540
- handler('', { name: 'up' });
541
- setImmediate(() => {
542
- handler('', { name: 'return' });
543
- });
544
- });
545
- }
546
- return process.stdin;
547
- });
548
- const result = await promptChoiceIndex('Choose:', ['A', 'B', 'C']);
549
- expect(result).toBe(3); // Last option selected (wraps around, 1-based)
550
- });
551
- it('rejects on q key press', async () => {
552
- mockStdinOn.mockImplementation((event, handler) => {
553
- if (event === 'keypress') {
554
- setImmediate(() => {
555
- handler('q', { name: 'q' });
556
- });
557
- }
558
- return process.stdin;
559
- });
560
- await expect(promptChoiceIndex('Choose:', ['A', 'B'])).rejects.toThrow('User cancelled');
561
- });
562
- it('rejects on Q key press', async () => {
563
- mockStdinOn.mockImplementation((event, handler) => {
564
- if (event === 'keypress') {
565
- setImmediate(() => {
566
- handler('Q', { name: 'Q' });
567
- });
568
- }
569
- return process.stdin;
570
- });
571
- await expect(promptChoiceIndex('Choose:', ['A', 'B'])).rejects.toThrow('User cancelled');
572
- });
573
- it('rejects on Ctrl+C', async () => {
574
- mockStdinOn.mockImplementation((event, handler) => {
575
- if (event === 'keypress') {
576
- setImmediate(() => {
577
- handler('', { name: 'c', ctrl: true });
578
- });
579
- }
580
- return process.stdin;
581
- });
582
- await expect(promptChoiceIndex('Choose:', ['A', 'B'])).rejects.toThrow('User cancelled');
583
- });
584
- it('cleans up stdin on selection', async () => {
585
- mockStdinOn.mockImplementation((event, handler) => {
586
- if (event === 'keypress') {
587
- setImmediate(() => {
588
- handler('', { name: 'return' });
589
- });
590
- }
591
- return process.stdin;
592
- });
593
- await promptChoiceIndex('Choose:', ['A', 'B']);
594
- expect(mockStdinRemoveListener).toHaveBeenCalledWith('keypress', expect.any(Function));
595
- expect(mockStdinSetRawMode).toHaveBeenCalledWith(false);
596
- expect(mockStdinPause).toHaveBeenCalled();
597
- });
598
- it('wraps around when navigating past last option', async () => {
599
- mockStdinOn.mockImplementation((event, handler) => {
600
- if (event === 'keypress') {
601
- setImmediate(() => {
602
- // Navigate down 3 times on a 3-item list (wraps to first)
603
- handler('', { name: 'down' });
604
- setImmediate(() => {
605
- handler('', { name: 'down' });
606
- setImmediate(() => {
607
- handler('', { name: 'down' });
608
- setImmediate(() => {
609
- handler('', { name: 'return' });
610
- });
611
- });
612
- });
613
- });
614
- }
615
- return process.stdin;
616
- });
617
- const result = await promptChoiceIndex('Choose:', ['A', 'B', 'C']);
618
- expect(result).toBe(1); // Wrapped back to first (1-based)
619
- });
620
- it('calls readline emitKeypressEvents', async () => {
621
- mockStdinOn.mockImplementation((event, handler) => {
622
- if (event === 'keypress') {
623
- setImmediate(() => {
624
- handler('', { name: 'return' });
625
- });
626
- }
627
- return process.stdin;
628
- });
629
- await promptChoiceIndex('Choose:', ['Option A', 'Option B']);
630
- // Check readline.emitKeypressEvents was called
631
- expect(readline.emitKeypressEvents).toHaveBeenCalledWith(process.stdin);
632
- });
633
- });
634
- describe('promptChoice with arrow keys', () => {
635
- it('returns value of selected option', async () => {
636
- mockStdinOn.mockImplementation((event, handler) => {
637
- if (event === 'keypress') {
638
- setImmediate(() => {
639
- handler('', { name: 'down' });
640
- setImmediate(() => {
641
- handler('', { name: 'return' });
642
- });
643
- });
644
- }
645
- return process.stdin;
646
- });
647
- const result = await promptChoice('Choose:', [
648
- { label: 'First', value: 'first-value' },
649
- { label: 'Second', value: 'second-value' },
650
- ]);
651
- expect(result).toBe('second-value');
652
- });
653
- it('handles options with descriptions', async () => {
654
- mockStdinOn.mockImplementation((event, handler) => {
655
- if (event === 'keypress') {
656
- setImmediate(() => {
657
- handler('', { name: 'return' });
658
- });
659
- }
660
- return process.stdin;
661
- });
662
- const result = await promptChoice('Choose:', [
663
- { label: 'Option', description: 'A helpful description', value: 'opt' },
664
- ]);
665
- expect(result).toBe('opt');
666
- });
667
- it('rejects on q key press', async () => {
668
- mockStdinOn.mockImplementation((event, handler) => {
669
- if (event === 'keypress') {
670
- setImmediate(() => {
671
- handler('q', {});
672
- });
673
- }
674
- return process.stdin;
675
- });
676
- await expect(promptChoice('Choose:', [{ label: 'A', value: 'a' }])).rejects.toThrow('User cancelled');
677
- });
678
- it('rejects on Ctrl+C', async () => {
679
- mockStdinOn.mockImplementation((event, handler) => {
680
- if (event === 'keypress') {
681
- setImmediate(() => {
682
- handler('', { name: 'c', ctrl: true });
683
- });
684
- }
685
- return process.stdin;
686
- });
687
- await expect(promptChoice('Choose:', [{ label: 'A', value: 'a' }])).rejects.toThrow('User cancelled');
688
- });
689
- it('navigates up and wraps to last option', async () => {
690
- mockStdinOn.mockImplementation((event, handler) => {
691
- if (event === 'keypress') {
692
- setImmediate(() => {
693
- handler('', { name: 'up' });
694
- setImmediate(() => {
695
- handler('', { name: 'return' });
696
- });
697
- });
698
- }
699
- return process.stdin;
700
- });
701
- const result = await promptChoice('Choose:', [
702
- { label: 'First', value: 'first' },
703
- { label: 'Second', value: 'second' },
704
- { label: 'Third', value: 'third' },
705
- ]);
706
- expect(result).toBe('third'); // Wrapped to last
707
- });
708
- it('navigates down and wraps to first option', async () => {
709
- mockStdinOn.mockImplementation((event, handler) => {
710
- if (event === 'keypress') {
711
- setImmediate(() => {
712
- handler('', { name: 'down' });
713
- setImmediate(() => {
714
- handler('', { name: 'down' });
715
- setImmediate(() => {
716
- handler('', { name: 'down' });
717
- setImmediate(() => {
718
- handler('', { name: 'return' });
719
- });
720
- });
721
- });
722
- });
723
- }
724
- return process.stdin;
725
- });
726
- const result = await promptChoice('Choose:', [
727
- { label: 'First', value: 'first' },
728
- { label: 'Second', value: 'second' },
729
- { label: 'Third', value: 'third' },
730
- ]);
731
- expect(result).toBe('first'); // Wrapped to first
732
- });
733
- it('selects with right arrow key', async () => {
734
- mockStdinOn.mockImplementation((event, handler) => {
735
- if (event === 'keypress') {
736
- setImmediate(() => {
737
- handler('', { name: 'down' });
738
- setImmediate(() => {
739
- handler('', { name: 'right' }); // Right arrow to select
740
- });
741
- });
742
- }
743
- return process.stdin;
744
- });
745
- const result = await promptChoice('Choose:', [
746
- { label: 'First', value: 'first' },
747
- { label: 'Second', value: 'second' },
748
- ]);
749
- expect(result).toBe('second');
750
- });
751
- it('rejects with UserNavigatedBack on left arrow', async () => {
752
- mockStdinOn.mockImplementation((event, handler) => {
753
- if (event === 'keypress') {
754
- setImmediate(() => {
755
- handler('', { name: 'left' }); // Left arrow to go back
756
- });
757
- }
758
- return process.stdin;
759
- });
760
- await expect(promptChoice('Choose:', [{ label: 'A', value: 'a' }])).rejects.toBeInstanceOf(UserNavigatedBack);
761
- });
762
- });
763
- describe('promptChoiceIndex left/right arrow navigation', () => {
764
- it('selects with right arrow key', async () => {
765
- mockStdinOn.mockImplementation((event, handler) => {
766
- if (event === 'keypress') {
767
- setImmediate(() => {
768
- handler('', { name: 'down' });
769
- setImmediate(() => {
770
- handler('', { name: 'right' }); // Right arrow to select
771
- });
772
- });
773
- }
774
- return process.stdin;
775
- });
776
- const result = await promptChoiceIndex('Choose:', ['A', 'B', 'C']);
777
- expect(result).toBe(2); // Second option (1-based)
778
- });
779
- it('rejects with UserNavigatedBack on left arrow', async () => {
780
- mockStdinOn.mockImplementation((event, handler) => {
781
- if (event === 'keypress') {
782
- setImmediate(() => {
783
- handler('', { name: 'left' }); // Left arrow to go back
784
- });
785
- }
786
- return process.stdin;
787
- });
788
- await expect(promptChoiceIndex('Choose:', ['A', 'B'])).rejects.toBeInstanceOf(UserNavigatedBack);
789
- });
790
- });
791
- });
792
- describe('UserNavigatedBack', () => {
793
- it('is an Error instance', () => {
794
- const error = new UserNavigatedBack();
795
- expect(error).toBeInstanceOf(Error);
796
- });
797
- it('has correct name', () => {
798
- const error = new UserNavigatedBack();
799
- expect(error.name).toBe('UserNavigatedBack');
800
- });
801
- it('has correct message', () => {
802
- const error = new UserNavigatedBack();
803
- expect(error.message).toBe('User navigated back');
804
- });
805
- });
806
- });
807
- //# sourceMappingURL=prompts.test.js.map