@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,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