@camaradesuk/git-worktree-tools 1.10.0 → 1.12.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 (431) hide show
  1. package/README.md +4 -4
  2. package/dist/lib/config.d.ts +2 -1
  3. package/dist/lib/config.d.ts.map +1 -1
  4. package/dist/lib/config.js +11 -0
  5. package/dist/lib/config.js.map +1 -1
  6. package/package.json +12 -3
  7. package/schemas/worktreerc.schema.json +1 -1
  8. package/dist/api/list.test.d.ts +0 -5
  9. package/dist/api/list.test.d.ts.map +0 -1
  10. package/dist/api/list.test.js +0 -390
  11. package/dist/api/list.test.js.map +0 -1
  12. package/dist/cli/cleanpr.test.d.ts +0 -2
  13. package/dist/cli/cleanpr.test.d.ts.map +0 -1
  14. package/dist/cli/cleanpr.test.js +0 -954
  15. package/dist/cli/cleanpr.test.js.map +0 -1
  16. package/dist/cli/lswt.test.d.ts +0 -2
  17. package/dist/cli/lswt.test.d.ts.map +0 -1
  18. package/dist/cli/lswt.test.js +0 -376
  19. package/dist/cli/lswt.test.js.map +0 -1
  20. package/dist/cli/newpr.test.d.ts +0 -2
  21. package/dist/cli/newpr.test.d.ts.map +0 -1
  22. package/dist/cli/newpr.test.js +0 -1182
  23. package/dist/cli/newpr.test.js.map +0 -1
  24. package/dist/cli/prs.test.d.ts +0 -8
  25. package/dist/cli/prs.test.d.ts.map +0 -1
  26. package/dist/cli/prs.test.js +0 -463
  27. package/dist/cli/prs.test.js.map +0 -1
  28. package/dist/cli/wt/clean.test.d.ts +0 -8
  29. package/dist/cli/wt/clean.test.d.ts.map +0 -1
  30. package/dist/cli/wt/clean.test.js +0 -624
  31. package/dist/cli/wt/clean.test.js.map +0 -1
  32. package/dist/cli/wt/completion.test.d.ts +0 -5
  33. package/dist/cli/wt/completion.test.d.ts.map +0 -1
  34. package/dist/cli/wt/completion.test.js +0 -275
  35. package/dist/cli/wt/completion.test.js.map +0 -1
  36. package/dist/cli/wt/config.test.d.ts +0 -7
  37. package/dist/cli/wt/config.test.d.ts.map +0 -1
  38. package/dist/cli/wt/config.test.js +0 -440
  39. package/dist/cli/wt/config.test.js.map +0 -1
  40. package/dist/cli/wt/entry.test.d.ts +0 -8
  41. package/dist/cli/wt/entry.test.d.ts.map +0 -1
  42. package/dist/cli/wt/entry.test.js +0 -201
  43. package/dist/cli/wt/entry.test.js.map +0 -1
  44. package/dist/cli/wt/init.test.d.ts +0 -5
  45. package/dist/cli/wt/init.test.d.ts.map +0 -1
  46. package/dist/cli/wt/init.test.js +0 -165
  47. package/dist/cli/wt/init.test.js.map +0 -1
  48. package/dist/cli/wt/init.unit.test.d.ts +0 -5
  49. package/dist/cli/wt/init.unit.test.d.ts.map +0 -1
  50. package/dist/cli/wt/init.unit.test.js +0 -432
  51. package/dist/cli/wt/init.unit.test.js.map +0 -1
  52. package/dist/cli/wt/interactive-menu.test.d.ts +0 -12
  53. package/dist/cli/wt/interactive-menu.test.d.ts.map +0 -1
  54. package/dist/cli/wt/interactive-menu.test.js +0 -796
  55. package/dist/cli/wt/interactive-menu.test.js.map +0 -1
  56. package/dist/cli/wt/list.test.d.ts +0 -10
  57. package/dist/cli/wt/list.test.d.ts.map +0 -1
  58. package/dist/cli/wt/list.test.js +0 -157
  59. package/dist/cli/wt/list.test.js.map +0 -1
  60. package/dist/cli/wt/prs.test.d.ts +0 -5
  61. package/dist/cli/wt/prs.test.d.ts.map +0 -1
  62. package/dist/cli/wt/prs.test.js +0 -410
  63. package/dist/cli/wt/prs.test.js.map +0 -1
  64. package/dist/cli/wt/run-command.test.d.ts +0 -5
  65. package/dist/cli/wt/run-command.test.d.ts.map +0 -1
  66. package/dist/cli/wt/run-command.test.js +0 -88
  67. package/dist/cli/wt/run-command.test.js.map +0 -1
  68. package/dist/cli/wt/state.test.d.ts +0 -9
  69. package/dist/cli/wt/state.test.d.ts.map +0 -1
  70. package/dist/cli/wt/state.test.js +0 -127
  71. package/dist/cli/wt/state.test.js.map +0 -1
  72. package/dist/cli/wt/wt.test.d.ts +0 -8
  73. package/dist/cli/wt/wt.test.d.ts.map +0 -1
  74. package/dist/cli/wt/wt.test.js +0 -739
  75. package/dist/cli/wt/wt.test.js.map +0 -1
  76. package/dist/cli/wt.unit.test.d.ts +0 -7
  77. package/dist/cli/wt.unit.test.d.ts.map +0 -1
  78. package/dist/cli/wt.unit.test.js +0 -160
  79. package/dist/cli/wt.unit.test.js.map +0 -1
  80. package/dist/cli/wtconfig.test.d.ts +0 -5
  81. package/dist/cli/wtconfig.test.d.ts.map +0 -1
  82. package/dist/cli/wtconfig.test.js +0 -1289
  83. package/dist/cli/wtconfig.test.js.map +0 -1
  84. package/dist/cli/wtlink.test.d.ts +0 -2
  85. package/dist/cli/wtlink.test.d.ts.map +0 -1
  86. package/dist/cli/wtlink.test.js +0 -249
  87. package/dist/cli/wtlink.test.js.map +0 -1
  88. package/dist/cli/wtstate.test.d.ts +0 -5
  89. package/dist/cli/wtstate.test.d.ts.map +0 -1
  90. package/dist/cli/wtstate.test.js +0 -193
  91. package/dist/cli/wtstate.test.js.map +0 -1
  92. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +0 -2
  93. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +0 -1
  94. package/dist/e2e/cleanpr/cleanpr.e2e.test.js +0 -326
  95. package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +0 -1
  96. package/dist/e2e/cli.e2e.test.d.ts +0 -2
  97. package/dist/e2e/cli.e2e.test.d.ts.map +0 -1
  98. package/dist/e2e/cli.e2e.test.js +0 -417
  99. package/dist/e2e/cli.e2e.test.js.map +0 -1
  100. package/dist/e2e/lswt/lswt.e2e.test.d.ts +0 -2
  101. package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +0 -1
  102. package/dist/e2e/lswt/lswt.e2e.test.js +0 -361
  103. package/dist/e2e/lswt/lswt.e2e.test.js.map +0 -1
  104. package/dist/e2e/newpr/newpr.e2e.test.d.ts +0 -2
  105. package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +0 -1
  106. package/dist/e2e/newpr/newpr.e2e.test.js +0 -286
  107. package/dist/e2e/newpr/newpr.e2e.test.js.map +0 -1
  108. package/dist/e2e/newpr/scenarios.e2e.test.d.ts +0 -2
  109. package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +0 -1
  110. package/dist/e2e/newpr/scenarios.e2e.test.js +0 -426
  111. package/dist/e2e/newpr/scenarios.e2e.test.js.map +0 -1
  112. package/dist/e2e/newpr-full-flow.e2e.test.d.ts +0 -2
  113. package/dist/e2e/newpr-full-flow.e2e.test.d.ts.map +0 -1
  114. package/dist/e2e/newpr-full-flow.e2e.test.js +0 -280
  115. package/dist/e2e/newpr-full-flow.e2e.test.js.map +0 -1
  116. package/dist/e2e/prs/prs.e2e.test.d.ts +0 -7
  117. package/dist/e2e/prs/prs.e2e.test.d.ts.map +0 -1
  118. package/dist/e2e/prs/prs.e2e.test.js +0 -606
  119. package/dist/e2e/prs/prs.e2e.test.js.map +0 -1
  120. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +0 -2
  121. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +0 -1
  122. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +0 -298
  123. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +0 -1
  124. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts +0 -8
  125. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts.map +0 -1
  126. package/dist/e2e/wt/interactive-menu.e2e.test.js +0 -583
  127. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +0 -1
  128. package/dist/e2e/wt/wt.e2e.test.d.ts +0 -9
  129. package/dist/e2e/wt/wt.e2e.test.d.ts.map +0 -1
  130. package/dist/e2e/wt/wt.e2e.test.js +0 -597
  131. package/dist/e2e/wt/wt.e2e.test.js.map +0 -1
  132. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +0 -2
  133. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +0 -1
  134. package/dist/e2e/wtlink/wtlink.e2e.test.js +0 -416
  135. package/dist/e2e/wtlink/wtlink.e2e.test.js.map +0 -1
  136. package/dist/integration/git.integration.test.d.ts +0 -2
  137. package/dist/integration/git.integration.test.d.ts.map +0 -1
  138. package/dist/integration/git.integration.test.js +0 -336
  139. package/dist/integration/git.integration.test.js.map +0 -1
  140. package/dist/integration/lswt-remote-pr.integration.test.d.ts +0 -2
  141. package/dist/integration/lswt-remote-pr.integration.test.d.ts.map +0 -1
  142. package/dist/integration/lswt-remote-pr.integration.test.js +0 -222
  143. package/dist/integration/lswt-remote-pr.integration.test.js.map +0 -1
  144. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts +0 -2
  145. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts.map +0 -1
  146. package/dist/integration/newpr-branchfrom-head.integration.test.js +0 -498
  147. package/dist/integration/newpr-branchfrom-head.integration.test.js.map +0 -1
  148. package/dist/integration/newpr.integration.test.d.ts +0 -2
  149. package/dist/integration/newpr.integration.test.d.ts.map +0 -1
  150. package/dist/integration/newpr.integration.test.js +0 -460
  151. package/dist/integration/newpr.integration.test.js.map +0 -1
  152. package/dist/integration/prs.integration.test.d.ts +0 -8
  153. package/dist/integration/prs.integration.test.d.ts.map +0 -1
  154. package/dist/integration/prs.integration.test.js +0 -478
  155. package/dist/integration/prs.integration.test.js.map +0 -1
  156. package/dist/lib/ai/base-provider.test.d.ts +0 -7
  157. package/dist/lib/ai/base-provider.test.d.ts.map +0 -1
  158. package/dist/lib/ai/base-provider.test.js +0 -319
  159. package/dist/lib/ai/base-provider.test.js.map +0 -1
  160. package/dist/lib/ai/cli-provider.test.d.ts +0 -5
  161. package/dist/lib/ai/cli-provider.test.d.ts.map +0 -1
  162. package/dist/lib/ai/cli-provider.test.js +0 -460
  163. package/dist/lib/ai/cli-provider.test.js.map +0 -1
  164. package/dist/lib/ai/fallback-provider.test.d.ts +0 -7
  165. package/dist/lib/ai/fallback-provider.test.d.ts.map +0 -1
  166. package/dist/lib/ai/fallback-provider.test.js +0 -165
  167. package/dist/lib/ai/fallback-provider.test.js.map +0 -1
  168. package/dist/lib/ai/generation-service.test.d.ts +0 -7
  169. package/dist/lib/ai/generation-service.test.d.ts.map +0 -1
  170. package/dist/lib/ai/generation-service.test.js +0 -213
  171. package/dist/lib/ai/generation-service.test.js.map +0 -1
  172. package/dist/lib/ai/provider-manager.test.d.ts +0 -5
  173. package/dist/lib/ai/provider-manager.test.d.ts.map +0 -1
  174. package/dist/lib/ai/provider-manager.test.js +0 -312
  175. package/dist/lib/ai/provider-manager.test.js.map +0 -1
  176. package/dist/lib/ai/repo-docs.test.d.ts +0 -5
  177. package/dist/lib/ai/repo-docs.test.d.ts.map +0 -1
  178. package/dist/lib/ai/repo-docs.test.js +0 -357
  179. package/dist/lib/ai/repo-docs.test.js.map +0 -1
  180. package/dist/lib/cleanpr/args.test.d.ts +0 -2
  181. package/dist/lib/cleanpr/args.test.d.ts.map +0 -1
  182. package/dist/lib/cleanpr/args.test.js +0 -269
  183. package/dist/lib/cleanpr/args.test.js.map +0 -1
  184. package/dist/lib/cleanpr/cleanup.test.d.ts +0 -2
  185. package/dist/lib/cleanpr/cleanup.test.d.ts.map +0 -1
  186. package/dist/lib/cleanpr/cleanup.test.js +0 -296
  187. package/dist/lib/cleanpr/cleanup.test.js.map +0 -1
  188. package/dist/lib/cleanpr/worktree-info.test.d.ts +0 -2
  189. package/dist/lib/cleanpr/worktree-info.test.d.ts.map +0 -1
  190. package/dist/lib/cleanpr/worktree-info.test.js +0 -228
  191. package/dist/lib/cleanpr/worktree-info.test.js.map +0 -1
  192. package/dist/lib/colors.test.d.ts +0 -2
  193. package/dist/lib/colors.test.d.ts.map +0 -1
  194. package/dist/lib/colors.test.js +0 -142
  195. package/dist/lib/colors.test.js.map +0 -1
  196. package/dist/lib/config-editor.test.d.ts +0 -11
  197. package/dist/lib/config-editor.test.d.ts.map +0 -1
  198. package/dist/lib/config-editor.test.js +0 -526
  199. package/dist/lib/config-editor.test.js.map +0 -1
  200. package/dist/lib/config-migration/detector.test.d.ts +0 -5
  201. package/dist/lib/config-migration/detector.test.d.ts.map +0 -1
  202. package/dist/lib/config-migration/detector.test.js +0 -201
  203. package/dist/lib/config-migration/detector.test.js.map +0 -1
  204. package/dist/lib/config-migration/reporter.test.d.ts +0 -5
  205. package/dist/lib/config-migration/reporter.test.d.ts.map +0 -1
  206. package/dist/lib/config-migration/reporter.test.js +0 -305
  207. package/dist/lib/config-migration/reporter.test.js.map +0 -1
  208. package/dist/lib/config-migration/runner.test.d.ts +0 -5
  209. package/dist/lib/config-migration/runner.test.d.ts.map +0 -1
  210. package/dist/lib/config-migration/runner.test.js +0 -235
  211. package/dist/lib/config-migration/runner.test.js.map +0 -1
  212. package/dist/lib/config-validation.test.d.ts +0 -5
  213. package/dist/lib/config-validation.test.d.ts.map +0 -1
  214. package/dist/lib/config-validation.test.js +0 -423
  215. package/dist/lib/config-validation.test.js.map +0 -1
  216. package/dist/lib/config.test.d.ts +0 -2
  217. package/dist/lib/config.test.d.ts.map +0 -1
  218. package/dist/lib/config.test.js +0 -554
  219. package/dist/lib/config.test.js.map +0 -1
  220. package/dist/lib/constants.test.d.ts +0 -5
  221. package/dist/lib/constants.test.d.ts.map +0 -1
  222. package/dist/lib/constants.test.js +0 -180
  223. package/dist/lib/constants.test.js.map +0 -1
  224. package/dist/lib/deprecation.test.d.ts +0 -2
  225. package/dist/lib/deprecation.test.d.ts.map +0 -1
  226. package/dist/lib/deprecation.test.js +0 -71
  227. package/dist/lib/deprecation.test.js.map +0 -1
  228. package/dist/lib/errors.test.d.ts +0 -2
  229. package/dist/lib/errors.test.d.ts.map +0 -1
  230. package/dist/lib/errors.test.js +0 -117
  231. package/dist/lib/errors.test.js.map +0 -1
  232. package/dist/lib/git.test.d.ts +0 -2
  233. package/dist/lib/git.test.d.ts.map +0 -1
  234. package/dist/lib/git.test.js +0 -608
  235. package/dist/lib/git.test.js.map +0 -1
  236. package/dist/lib/github.test.d.ts +0 -2
  237. package/dist/lib/github.test.d.ts.map +0 -1
  238. package/dist/lib/github.test.js +0 -441
  239. package/dist/lib/github.test.js.map +0 -1
  240. package/dist/lib/global-check.test.d.ts +0 -5
  241. package/dist/lib/global-check.test.d.ts.map +0 -1
  242. package/dist/lib/global-check.test.js +0 -150
  243. package/dist/lib/global-check.test.js.map +0 -1
  244. package/dist/lib/global-config.test.d.ts +0 -5
  245. package/dist/lib/global-config.test.d.ts.map +0 -1
  246. package/dist/lib/global-config.test.js +0 -282
  247. package/dist/lib/global-config.test.js.map +0 -1
  248. package/dist/lib/hooks/confirmation.test.d.ts +0 -7
  249. package/dist/lib/hooks/confirmation.test.d.ts.map +0 -1
  250. package/dist/lib/hooks/confirmation.test.js +0 -300
  251. package/dist/lib/hooks/confirmation.test.js.map +0 -1
  252. package/dist/lib/hooks/executor.test.d.ts +0 -5
  253. package/dist/lib/hooks/executor.test.d.ts.map +0 -1
  254. package/dist/lib/hooks/executor.test.js +0 -648
  255. package/dist/lib/hooks/executor.test.js.map +0 -1
  256. package/dist/lib/hooks/templates.test.d.ts +0 -5
  257. package/dist/lib/hooks/templates.test.d.ts.map +0 -1
  258. package/dist/lib/hooks/templates.test.js +0 -163
  259. package/dist/lib/hooks/templates.test.js.map +0 -1
  260. package/dist/lib/hooks/types.test.d.ts +0 -5
  261. package/dist/lib/hooks/types.test.d.ts.map +0 -1
  262. package/dist/lib/hooks/types.test.js +0 -132
  263. package/dist/lib/hooks/types.test.js.map +0 -1
  264. package/dist/lib/json-output.test.d.ts +0 -5
  265. package/dist/lib/json-output.test.d.ts.map +0 -1
  266. package/dist/lib/json-output.test.js +0 -261
  267. package/dist/lib/json-output.test.js.map +0 -1
  268. package/dist/lib/logger.test.d.ts +0 -14
  269. package/dist/lib/logger.test.d.ts.map +0 -1
  270. package/dist/lib/logger.test.js +0 -692
  271. package/dist/lib/logger.test.js.map +0 -1
  272. package/dist/lib/lswt/action-executors.test.d.ts +0 -2
  273. package/dist/lib/lswt/action-executors.test.d.ts.map +0 -1
  274. package/dist/lib/lswt/action-executors.test.js +0 -1127
  275. package/dist/lib/lswt/action-executors.test.js.map +0 -1
  276. package/dist/lib/lswt/actions.test.d.ts +0 -2
  277. package/dist/lib/lswt/actions.test.d.ts.map +0 -1
  278. package/dist/lib/lswt/actions.test.js +0 -497
  279. package/dist/lib/lswt/actions.test.js.map +0 -1
  280. package/dist/lib/lswt/args.test.d.ts +0 -2
  281. package/dist/lib/lswt/args.test.d.ts.map +0 -1
  282. package/dist/lib/lswt/args.test.js +0 -195
  283. package/dist/lib/lswt/args.test.js.map +0 -1
  284. package/dist/lib/lswt/environment.test.d.ts +0 -2
  285. package/dist/lib/lswt/environment.test.d.ts.map +0 -1
  286. package/dist/lib/lswt/environment.test.js +0 -544
  287. package/dist/lib/lswt/environment.test.js.map +0 -1
  288. package/dist/lib/lswt/formatters.test.d.ts +0 -2
  289. package/dist/lib/lswt/formatters.test.d.ts.map +0 -1
  290. package/dist/lib/lswt/formatters.test.js +0 -323
  291. package/dist/lib/lswt/formatters.test.js.map +0 -1
  292. package/dist/lib/lswt/fuzzy-search.test.d.ts +0 -5
  293. package/dist/lib/lswt/fuzzy-search.test.d.ts.map +0 -1
  294. package/dist/lib/lswt/fuzzy-search.test.js +0 -207
  295. package/dist/lib/lswt/fuzzy-search.test.js.map +0 -1
  296. package/dist/lib/lswt/interactive.test.d.ts +0 -2
  297. package/dist/lib/lswt/interactive.test.d.ts.map +0 -1
  298. package/dist/lib/lswt/interactive.test.js +0 -771
  299. package/dist/lib/lswt/interactive.test.js.map +0 -1
  300. package/dist/lib/lswt/table.test.d.ts +0 -5
  301. package/dist/lib/lswt/table.test.d.ts.map +0 -1
  302. package/dist/lib/lswt/table.test.js +0 -262
  303. package/dist/lib/lswt/table.test.js.map +0 -1
  304. package/dist/lib/lswt/worktree-info.test.d.ts +0 -2
  305. package/dist/lib/lswt/worktree-info.test.d.ts.map +0 -1
  306. package/dist/lib/lswt/worktree-info.test.js +0 -484
  307. package/dist/lib/lswt/worktree-info.test.js.map +0 -1
  308. package/dist/lib/newpr/action-deps.test.d.ts +0 -5
  309. package/dist/lib/newpr/action-deps.test.d.ts.map +0 -1
  310. package/dist/lib/newpr/action-deps.test.js +0 -111
  311. package/dist/lib/newpr/action-deps.test.js.map +0 -1
  312. package/dist/lib/newpr/actions.test.d.ts +0 -2
  313. package/dist/lib/newpr/actions.test.d.ts.map +0 -1
  314. package/dist/lib/newpr/actions.test.js +0 -254
  315. package/dist/lib/newpr/actions.test.js.map +0 -1
  316. package/dist/lib/newpr/args.test.d.ts +0 -2
  317. package/dist/lib/newpr/args.test.d.ts.map +0 -1
  318. package/dist/lib/newpr/args.test.js +0 -479
  319. package/dist/lib/newpr/args.test.js.map +0 -1
  320. package/dist/lib/newpr/hook-runner.test.d.ts +0 -7
  321. package/dist/lib/newpr/hook-runner.test.d.ts.map +0 -1
  322. package/dist/lib/newpr/hook-runner.test.js +0 -422
  323. package/dist/lib/newpr/hook-runner.test.js.map +0 -1
  324. package/dist/lib/newpr/plan-generator.test.d.ts +0 -7
  325. package/dist/lib/newpr/plan-generator.test.d.ts.map +0 -1
  326. package/dist/lib/newpr/plan-generator.test.js +0 -387
  327. package/dist/lib/newpr/plan-generator.test.js.map +0 -1
  328. package/dist/lib/newpr/scenario-handler.test.d.ts +0 -2
  329. package/dist/lib/newpr/scenario-handler.test.d.ts.map +0 -1
  330. package/dist/lib/newpr/scenario-handler.test.js +0 -256
  331. package/dist/lib/newpr/scenario-handler.test.js.map +0 -1
  332. package/dist/lib/prompts.test.d.ts +0 -2
  333. package/dist/lib/prompts.test.d.ts.map +0 -1
  334. package/dist/lib/prompts.test.js +0 -807
  335. package/dist/lib/prompts.test.js.map +0 -1
  336. package/dist/lib/prs/actions.test.d.ts +0 -5
  337. package/dist/lib/prs/actions.test.d.ts.map +0 -1
  338. package/dist/lib/prs/actions.test.js +0 -356
  339. package/dist/lib/prs/actions.test.js.map +0 -1
  340. package/dist/lib/prs/command.test.d.ts +0 -11
  341. package/dist/lib/prs/command.test.d.ts.map +0 -1
  342. package/dist/lib/prs/command.test.js +0 -409
  343. package/dist/lib/prs/command.test.js.map +0 -1
  344. package/dist/lib/prs/data.test.d.ts +0 -5
  345. package/dist/lib/prs/data.test.d.ts.map +0 -1
  346. package/dist/lib/prs/data.test.js +0 -417
  347. package/dist/lib/prs/data.test.js.map +0 -1
  348. package/dist/lib/prs/details.test.d.ts +0 -5
  349. package/dist/lib/prs/details.test.d.ts.map +0 -1
  350. package/dist/lib/prs/details.test.js +0 -325
  351. package/dist/lib/prs/details.test.js.map +0 -1
  352. package/dist/lib/prs/filters.test.d.ts +0 -5
  353. package/dist/lib/prs/filters.test.d.ts.map +0 -1
  354. package/dist/lib/prs/filters.test.js +0 -312
  355. package/dist/lib/prs/filters.test.js.map +0 -1
  356. package/dist/lib/prs/formatters.test.d.ts +0 -2
  357. package/dist/lib/prs/formatters.test.d.ts.map +0 -1
  358. package/dist/lib/prs/formatters.test.js +0 -387
  359. package/dist/lib/prs/formatters.test.js.map +0 -1
  360. package/dist/lib/prs/interactive.test.d.ts +0 -5
  361. package/dist/lib/prs/interactive.test.d.ts.map +0 -1
  362. package/dist/lib/prs/interactive.test.js +0 -517
  363. package/dist/lib/prs/interactive.test.js.map +0 -1
  364. package/dist/lib/schema.test.d.ts +0 -10
  365. package/dist/lib/schema.test.d.ts.map +0 -1
  366. package/dist/lib/schema.test.js +0 -309
  367. package/dist/lib/schema.test.js.map +0 -1
  368. package/dist/lib/state-detection.test.d.ts +0 -2
  369. package/dist/lib/state-detection.test.d.ts.map +0 -1
  370. package/dist/lib/state-detection.test.js +0 -451
  371. package/dist/lib/state-detection.test.js.map +0 -1
  372. package/dist/lib/ui/error.test.d.ts +0 -2
  373. package/dist/lib/ui/error.test.d.ts.map +0 -1
  374. package/dist/lib/ui/error.test.js +0 -143
  375. package/dist/lib/ui/error.test.js.map +0 -1
  376. package/dist/lib/ui/output.test.d.ts +0 -2
  377. package/dist/lib/ui/output.test.d.ts.map +0 -1
  378. package/dist/lib/ui/output.test.js +0 -59
  379. package/dist/lib/ui/output.test.js.map +0 -1
  380. package/dist/lib/ui/status.test.d.ts +0 -2
  381. package/dist/lib/ui/status.test.d.ts.map +0 -1
  382. package/dist/lib/ui/status.test.js +0 -158
  383. package/dist/lib/ui/status.test.js.map +0 -1
  384. package/dist/lib/ui/table.test.d.ts +0 -2
  385. package/dist/lib/ui/table.test.d.ts.map +0 -1
  386. package/dist/lib/ui/table.test.js +0 -115
  387. package/dist/lib/ui/table.test.js.map +0 -1
  388. package/dist/lib/ui/theme.test.d.ts +0 -2
  389. package/dist/lib/ui/theme.test.d.ts.map +0 -1
  390. package/dist/lib/ui/theme.test.js +0 -76
  391. package/dist/lib/ui/theme.test.js.map +0 -1
  392. package/dist/lib/wtconfig/config-manager.test.d.ts +0 -5
  393. package/dist/lib/wtconfig/config-manager.test.d.ts.map +0 -1
  394. package/dist/lib/wtconfig/config-manager.test.js +0 -501
  395. package/dist/lib/wtconfig/config-manager.test.js.map +0 -1
  396. package/dist/lib/wtconfig/environment.test.d.ts +0 -5
  397. package/dist/lib/wtconfig/environment.test.d.ts.map +0 -1
  398. package/dist/lib/wtconfig/environment.test.js +0 -285
  399. package/dist/lib/wtconfig/environment.test.js.map +0 -1
  400. package/dist/lib/wtlink/config-manifest.test.d.ts +0 -2
  401. package/dist/lib/wtlink/config-manifest.test.d.ts.map +0 -1
  402. package/dist/lib/wtlink/config-manifest.test.js +0 -486
  403. package/dist/lib/wtlink/config-manifest.test.js.map +0 -1
  404. package/dist/lib/wtlink/link-configs.test.d.ts +0 -2
  405. package/dist/lib/wtlink/link-configs.test.d.ts.map +0 -1
  406. package/dist/lib/wtlink/link-configs.test.js +0 -612
  407. package/dist/lib/wtlink/link-configs.test.js.map +0 -1
  408. package/dist/lib/wtlink/main-menu.test.d.ts +0 -5
  409. package/dist/lib/wtlink/main-menu.test.d.ts.map +0 -1
  410. package/dist/lib/wtlink/main-menu.test.js +0 -126
  411. package/dist/lib/wtlink/main-menu.test.js.map +0 -1
  412. package/dist/lib/wtlink/manage-manifest.test.d.ts +0 -2
  413. package/dist/lib/wtlink/manage-manifest.test.d.ts.map +0 -1
  414. package/dist/lib/wtlink/manage-manifest.test.js +0 -714
  415. package/dist/lib/wtlink/manage-manifest.test.js.map +0 -1
  416. package/dist/lib/wtlink/validate-manifest.test.d.ts +0 -2
  417. package/dist/lib/wtlink/validate-manifest.test.d.ts.map +0 -1
  418. package/dist/lib/wtlink/validate-manifest.test.js +0 -220
  419. package/dist/lib/wtlink/validate-manifest.test.js.map +0 -1
  420. package/dist/lib/wtstate/analyze.test.d.ts +0 -5
  421. package/dist/lib/wtstate/analyze.test.d.ts.map +0 -1
  422. package/dist/lib/wtstate/analyze.test.js +0 -282
  423. package/dist/lib/wtstate/analyze.test.js.map +0 -1
  424. package/dist/lib/wtstate/args.test.d.ts +0 -5
  425. package/dist/lib/wtstate/args.test.d.ts.map +0 -1
  426. package/dist/lib/wtstate/args.test.js +0 -120
  427. package/dist/lib/wtstate/args.test.js.map +0 -1
  428. package/dist/mcp/server.test.d.ts +0 -9
  429. package/dist/mcp/server.test.d.ts.map +0 -1
  430. package/dist/mcp/server.test.js +0 -550
  431. 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