@camaradesuk/git-worktree-tools 1.8.0 → 1.10.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 (353) hide show
  1. package/README.md +48 -27
  2. package/dist/cli/cleanpr.js +74 -53
  3. package/dist/cli/cleanpr.js.map +1 -1
  4. package/dist/cli/cleanpr.test.js +2 -0
  5. package/dist/cli/cleanpr.test.js.map +1 -1
  6. package/dist/cli/lswt.js +32 -56
  7. package/dist/cli/lswt.js.map +1 -1
  8. package/dist/cli/lswt.test.js +17 -27
  9. package/dist/cli/lswt.test.js.map +1 -1
  10. package/dist/cli/newpr.d.ts +13 -1
  11. package/dist/cli/newpr.d.ts.map +1 -1
  12. package/dist/cli/newpr.js +350 -151
  13. package/dist/cli/newpr.js.map +1 -1
  14. package/dist/cli/newpr.test.js +314 -5
  15. package/dist/cli/newpr.test.js.map +1 -1
  16. package/dist/cli/prs.d.ts +3 -10
  17. package/dist/cli/prs.d.ts.map +1 -1
  18. package/dist/cli/prs.js +6 -168
  19. package/dist/cli/prs.js.map +1 -1
  20. package/dist/cli/prs.test.js +55 -0
  21. package/dist/cli/prs.test.js.map +1 -1
  22. package/dist/cli/wt/clean.d.ts +6 -2
  23. package/dist/cli/wt/clean.d.ts.map +1 -1
  24. package/dist/cli/wt/clean.js +401 -20
  25. package/dist/cli/wt/clean.js.map +1 -1
  26. package/dist/cli/wt/clean.test.d.ts +8 -0
  27. package/dist/cli/wt/clean.test.d.ts.map +1 -0
  28. package/dist/cli/wt/clean.test.js +624 -0
  29. package/dist/cli/wt/clean.test.js.map +1 -0
  30. package/dist/cli/wt/completion.d.ts +3 -0
  31. package/dist/cli/wt/completion.d.ts.map +1 -1
  32. package/dist/cli/wt/completion.js +80 -9
  33. package/dist/cli/wt/completion.js.map +1 -1
  34. package/dist/cli/wt/completion.test.js +102 -0
  35. package/dist/cli/wt/completion.test.js.map +1 -1
  36. package/dist/cli/wt/config.d.ts +3 -1
  37. package/dist/cli/wt/config.d.ts.map +1 -1
  38. package/dist/cli/wt/config.js +323 -32
  39. package/dist/cli/wt/config.js.map +1 -1
  40. package/dist/cli/wt/config.test.d.ts +2 -0
  41. package/dist/cli/wt/config.test.d.ts.map +1 -1
  42. package/dist/cli/wt/config.test.js +206 -26
  43. package/dist/cli/wt/config.test.js.map +1 -1
  44. package/dist/cli/wt/interactive-menu.d.ts +2 -0
  45. package/dist/cli/wt/interactive-menu.d.ts.map +1 -1
  46. package/dist/cli/wt/interactive-menu.js +346 -73
  47. package/dist/cli/wt/interactive-menu.js.map +1 -1
  48. package/dist/cli/wt/interactive-menu.test.d.ts +4 -2
  49. package/dist/cli/wt/interactive-menu.test.d.ts.map +1 -1
  50. package/dist/cli/wt/interactive-menu.test.js +383 -323
  51. package/dist/cli/wt/interactive-menu.test.js.map +1 -1
  52. package/dist/cli/wt/link.d.ts +3 -1
  53. package/dist/cli/wt/link.d.ts.map +1 -1
  54. package/dist/cli/wt/link.js +125 -38
  55. package/dist/cli/wt/link.js.map +1 -1
  56. package/dist/cli/wt/list.d.ts +4 -1
  57. package/dist/cli/wt/list.d.ts.map +1 -1
  58. package/dist/cli/wt/list.js +85 -16
  59. package/dist/cli/wt/list.js.map +1 -1
  60. package/dist/cli/wt/list.test.d.ts +10 -0
  61. package/dist/cli/wt/list.test.d.ts.map +1 -0
  62. package/dist/cli/wt/list.test.js +157 -0
  63. package/dist/cli/wt/list.test.js.map +1 -0
  64. package/dist/cli/wt/new.d.ts +8 -2
  65. package/dist/cli/wt/new.d.ts.map +1 -1
  66. package/dist/cli/wt/new.js +91 -46
  67. package/dist/cli/wt/new.js.map +1 -1
  68. package/dist/cli/wt/prs.d.ts +2 -1
  69. package/dist/cli/wt/prs.d.ts.map +1 -1
  70. package/dist/cli/wt/prs.js +3 -164
  71. package/dist/cli/wt/prs.js.map +1 -1
  72. package/dist/cli/wt/run-command.d.ts +4 -2
  73. package/dist/cli/wt/run-command.d.ts.map +1 -1
  74. package/dist/cli/wt/run-command.js +6 -4
  75. package/dist/cli/wt/run-command.js.map +1 -1
  76. package/dist/cli/wt/state.d.ts +3 -1
  77. package/dist/cli/wt/state.d.ts.map +1 -1
  78. package/dist/cli/wt/state.js +74 -10
  79. package/dist/cli/wt/state.js.map +1 -1
  80. package/dist/cli/wt/state.test.d.ts +9 -0
  81. package/dist/cli/wt/state.test.d.ts.map +1 -0
  82. package/dist/cli/wt/state.test.js +127 -0
  83. package/dist/cli/wt/state.test.js.map +1 -0
  84. package/dist/cli/wt/wt.test.d.ts +2 -2
  85. package/dist/cli/wt/wt.test.js +430 -212
  86. package/dist/cli/wt/wt.test.js.map +1 -1
  87. package/dist/cli/wt.d.ts.map +1 -1
  88. package/dist/cli/wt.js +50 -36
  89. package/dist/cli/wt.js.map +1 -1
  90. package/dist/cli/wt.unit.test.js +16 -38
  91. package/dist/cli/wt.unit.test.js.map +1 -1
  92. package/dist/cli/wtconfig.d.ts +1 -0
  93. package/dist/cli/wtconfig.d.ts.map +1 -1
  94. package/dist/cli/wtconfig.js +213 -21
  95. package/dist/cli/wtconfig.js.map +1 -1
  96. package/dist/cli/wtconfig.test.js +3 -0
  97. package/dist/cli/wtconfig.test.js.map +1 -1
  98. package/dist/cli/wtlink.js +116 -73
  99. package/dist/cli/wtlink.js.map +1 -1
  100. package/dist/cli/wtstate.js +21 -2
  101. package/dist/cli/wtstate.js.map +1 -1
  102. package/dist/e2e/wt/interactive-menu.e2e.test.js +17 -17
  103. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +1 -1
  104. package/dist/lib/ai/types.d.ts +12 -0
  105. package/dist/lib/ai/types.d.ts.map +1 -1
  106. package/dist/lib/ai/types.js.map +1 -1
  107. package/dist/lib/cleanpr/args.d.ts.map +1 -1
  108. package/dist/lib/cleanpr/args.js +20 -0
  109. package/dist/lib/cleanpr/args.js.map +1 -1
  110. package/dist/lib/cleanpr/types.d.ts +6 -0
  111. package/dist/lib/cleanpr/types.d.ts.map +1 -1
  112. package/dist/lib/cleanpr/worktree-info.d.ts.map +1 -1
  113. package/dist/lib/cleanpr/worktree-info.js +1 -6
  114. package/dist/lib/cleanpr/worktree-info.js.map +1 -1
  115. package/dist/lib/cleanpr/worktree-info.test.js +10 -13
  116. package/dist/lib/cleanpr/worktree-info.test.js.map +1 -1
  117. package/dist/lib/colors.d.ts +5 -0
  118. package/dist/lib/colors.d.ts.map +1 -1
  119. package/dist/lib/colors.js +13 -6
  120. package/dist/lib/colors.js.map +1 -1
  121. package/dist/lib/config-editor.d.ts.map +1 -1
  122. package/dist/lib/config-editor.js.map +1 -1
  123. package/dist/lib/config-migration/detector.d.ts +25 -0
  124. package/dist/lib/config-migration/detector.d.ts.map +1 -0
  125. package/dist/lib/config-migration/detector.js +372 -0
  126. package/dist/lib/config-migration/detector.js.map +1 -0
  127. package/dist/lib/config-migration/detector.test.d.ts +5 -0
  128. package/dist/lib/config-migration/detector.test.d.ts.map +1 -0
  129. package/dist/lib/config-migration/detector.test.js +201 -0
  130. package/dist/lib/config-migration/detector.test.js.map +1 -0
  131. package/dist/lib/config-migration/index.d.ts +29 -0
  132. package/dist/lib/config-migration/index.d.ts.map +1 -0
  133. package/dist/lib/config-migration/index.js +33 -0
  134. package/dist/lib/config-migration/index.js.map +1 -0
  135. package/dist/lib/config-migration/reporter.d.ts +53 -0
  136. package/dist/lib/config-migration/reporter.d.ts.map +1 -0
  137. package/dist/lib/config-migration/reporter.js +257 -0
  138. package/dist/lib/config-migration/reporter.js.map +1 -0
  139. package/dist/lib/config-migration/reporter.test.d.ts +5 -0
  140. package/dist/lib/config-migration/reporter.test.d.ts.map +1 -0
  141. package/dist/lib/config-migration/reporter.test.js +305 -0
  142. package/dist/lib/config-migration/reporter.test.js.map +1 -0
  143. package/dist/lib/config-migration/runner.d.ts +46 -0
  144. package/dist/lib/config-migration/runner.d.ts.map +1 -0
  145. package/dist/lib/config-migration/runner.js +364 -0
  146. package/dist/lib/config-migration/runner.js.map +1 -0
  147. package/dist/lib/config-migration/runner.test.d.ts +5 -0
  148. package/dist/lib/config-migration/runner.test.d.ts.map +1 -0
  149. package/dist/lib/config-migration/runner.test.js +235 -0
  150. package/dist/lib/config-migration/runner.test.js.map +1 -0
  151. package/dist/lib/config-migration/types.d.ts +120 -0
  152. package/dist/lib/config-migration/types.d.ts.map +1 -0
  153. package/dist/lib/config-migration/types.js +70 -0
  154. package/dist/lib/config-migration/types.js.map +1 -0
  155. package/dist/lib/config-validation.d.ts.map +1 -1
  156. package/dist/lib/config-validation.js +6 -0
  157. package/dist/lib/config-validation.js.map +1 -1
  158. package/dist/lib/config-validation.test.js +25 -0
  159. package/dist/lib/config-validation.test.js.map +1 -1
  160. package/dist/lib/config.d.ts +31 -7
  161. package/dist/lib/config.d.ts.map +1 -1
  162. package/dist/lib/config.js +2 -0
  163. package/dist/lib/config.js.map +1 -1
  164. package/dist/lib/config.test.js +3 -15
  165. package/dist/lib/config.test.js.map +1 -1
  166. package/dist/lib/constants.d.ts +12 -4
  167. package/dist/lib/constants.d.ts.map +1 -1
  168. package/dist/lib/constants.js +24 -5
  169. package/dist/lib/constants.js.map +1 -1
  170. package/dist/lib/constants.test.js +88 -29
  171. package/dist/lib/constants.test.js.map +1 -1
  172. package/dist/lib/deprecation.d.ts +18 -0
  173. package/dist/lib/deprecation.d.ts.map +1 -0
  174. package/dist/lib/deprecation.js +28 -0
  175. package/dist/lib/deprecation.js.map +1 -0
  176. package/dist/lib/deprecation.test.d.ts +2 -0
  177. package/dist/lib/deprecation.test.d.ts.map +1 -0
  178. package/dist/lib/deprecation.test.js +71 -0
  179. package/dist/lib/deprecation.test.js.map +1 -0
  180. package/dist/lib/hooks/confirmation.d.ts +49 -0
  181. package/dist/lib/hooks/confirmation.d.ts.map +1 -0
  182. package/dist/lib/hooks/confirmation.js +147 -0
  183. package/dist/lib/hooks/confirmation.js.map +1 -0
  184. package/dist/lib/hooks/confirmation.test.d.ts +7 -0
  185. package/dist/lib/hooks/confirmation.test.d.ts.map +1 -0
  186. package/dist/lib/hooks/confirmation.test.js +300 -0
  187. package/dist/lib/hooks/confirmation.test.js.map +1 -0
  188. package/dist/lib/hooks/executor.d.ts +16 -1
  189. package/dist/lib/hooks/executor.d.ts.map +1 -1
  190. package/dist/lib/hooks/executor.js +53 -4
  191. package/dist/lib/hooks/executor.js.map +1 -1
  192. package/dist/lib/hooks/index.d.ts +4 -2
  193. package/dist/lib/hooks/index.d.ts.map +1 -1
  194. package/dist/lib/hooks/index.js +3 -2
  195. package/dist/lib/hooks/index.js.map +1 -1
  196. package/dist/lib/hooks/types.d.ts +16 -0
  197. package/dist/lib/hooks/types.d.ts.map +1 -1
  198. package/dist/lib/hooks/types.js +12 -0
  199. package/dist/lib/hooks/types.js.map +1 -1
  200. package/dist/lib/logger.d.ts +40 -155
  201. package/dist/lib/logger.d.ts.map +1 -1
  202. package/dist/lib/logger.js +349 -420
  203. package/dist/lib/logger.js.map +1 -1
  204. package/dist/lib/logger.test.d.ts +10 -1
  205. package/dist/lib/logger.test.d.ts.map +1 -1
  206. package/dist/lib/logger.test.js +658 -258
  207. package/dist/lib/logger.test.js.map +1 -1
  208. package/dist/lib/lswt/action-executors.d.ts +2 -0
  209. package/dist/lib/lswt/action-executors.d.ts.map +1 -1
  210. package/dist/lib/lswt/action-executors.js +4 -3
  211. package/dist/lib/lswt/action-executors.js.map +1 -1
  212. package/dist/lib/lswt/action-executors.test.js +7 -0
  213. package/dist/lib/lswt/action-executors.test.js.map +1 -1
  214. package/dist/lib/lswt/args.d.ts.map +1 -1
  215. package/dist/lib/lswt/args.js +15 -1
  216. package/dist/lib/lswt/args.js.map +1 -1
  217. package/dist/lib/lswt/environment.d.ts +21 -2
  218. package/dist/lib/lswt/environment.d.ts.map +1 -1
  219. package/dist/lib/lswt/environment.js +73 -32
  220. package/dist/lib/lswt/environment.js.map +1 -1
  221. package/dist/lib/lswt/environment.test.js +79 -1
  222. package/dist/lib/lswt/environment.test.js.map +1 -1
  223. package/dist/lib/lswt/index.d.ts +1 -0
  224. package/dist/lib/lswt/index.d.ts.map +1 -1
  225. package/dist/lib/lswt/index.js +2 -0
  226. package/dist/lib/lswt/index.js.map +1 -1
  227. package/dist/lib/lswt/table.d.ts +15 -0
  228. package/dist/lib/lswt/table.d.ts.map +1 -0
  229. package/dist/lib/lswt/table.js +61 -0
  230. package/dist/lib/lswt/table.js.map +1 -0
  231. package/dist/lib/lswt/table.test.d.ts +5 -0
  232. package/dist/lib/lswt/table.test.d.ts.map +1 -0
  233. package/dist/lib/lswt/table.test.js +262 -0
  234. package/dist/lib/lswt/table.test.js.map +1 -0
  235. package/dist/lib/lswt/types.d.ts +4 -0
  236. package/dist/lib/lswt/types.d.ts.map +1 -1
  237. package/dist/lib/lswt/worktree-info.d.ts.map +1 -1
  238. package/dist/lib/lswt/worktree-info.js +1 -6
  239. package/dist/lib/lswt/worktree-info.js.map +1 -1
  240. package/dist/lib/lswt/worktree-info.test.js +5 -17
  241. package/dist/lib/lswt/worktree-info.test.js.map +1 -1
  242. package/dist/lib/newpr/args.d.ts.map +1 -1
  243. package/dist/lib/newpr/args.js +36 -1
  244. package/dist/lib/newpr/args.js.map +1 -1
  245. package/dist/lib/newpr/hook-runner.d.ts +11 -0
  246. package/dist/lib/newpr/hook-runner.d.ts.map +1 -1
  247. package/dist/lib/newpr/hook-runner.js +49 -1
  248. package/dist/lib/newpr/hook-runner.js.map +1 -1
  249. package/dist/lib/newpr/hook-runner.test.js +121 -0
  250. package/dist/lib/newpr/hook-runner.test.js.map +1 -1
  251. package/dist/lib/newpr/plan-generator.d.ts +121 -0
  252. package/dist/lib/newpr/plan-generator.d.ts.map +1 -0
  253. package/dist/lib/newpr/plan-generator.js +185 -0
  254. package/dist/lib/newpr/plan-generator.js.map +1 -0
  255. package/dist/lib/newpr/plan-generator.test.d.ts +7 -0
  256. package/dist/lib/newpr/plan-generator.test.d.ts.map +1 -0
  257. package/dist/lib/newpr/plan-generator.test.js +387 -0
  258. package/dist/lib/newpr/plan-generator.test.js.map +1 -0
  259. package/dist/lib/newpr/types.d.ts +12 -0
  260. package/dist/lib/newpr/types.d.ts.map +1 -1
  261. package/dist/lib/prs/actions.d.ts +5 -1
  262. package/dist/lib/prs/actions.d.ts.map +1 -1
  263. package/dist/lib/prs/actions.js +12 -10
  264. package/dist/lib/prs/actions.js.map +1 -1
  265. package/dist/lib/prs/actions.test.js +48 -5
  266. package/dist/lib/prs/actions.test.js.map +1 -1
  267. package/dist/lib/prs/command.d.ts +21 -0
  268. package/dist/lib/prs/command.d.ts.map +1 -0
  269. package/dist/lib/prs/command.js +175 -0
  270. package/dist/lib/prs/command.js.map +1 -0
  271. package/dist/lib/prs/command.test.d.ts +11 -0
  272. package/dist/lib/prs/command.test.d.ts.map +1 -0
  273. package/dist/lib/prs/command.test.js +409 -0
  274. package/dist/lib/prs/command.test.js.map +1 -0
  275. package/dist/lib/prs/interactive.d.ts.map +1 -1
  276. package/dist/lib/prs/interactive.js +15 -2
  277. package/dist/lib/prs/interactive.js.map +1 -1
  278. package/dist/lib/prs/interactive.test.js +153 -0
  279. package/dist/lib/prs/interactive.test.js.map +1 -1
  280. package/dist/lib/prs/types.d.ts +15 -0
  281. package/dist/lib/prs/types.d.ts.map +1 -1
  282. package/dist/lib/ui/error.d.ts +31 -0
  283. package/dist/lib/ui/error.d.ts.map +1 -0
  284. package/dist/lib/ui/error.js +47 -0
  285. package/dist/lib/ui/error.js.map +1 -0
  286. package/dist/lib/ui/error.test.d.ts +2 -0
  287. package/dist/lib/ui/error.test.d.ts.map +1 -0
  288. package/dist/lib/ui/error.test.js +143 -0
  289. package/dist/lib/ui/error.test.js.map +1 -0
  290. package/dist/lib/ui/index.d.ts +15 -0
  291. package/dist/lib/ui/index.d.ts.map +1 -0
  292. package/dist/lib/ui/index.js +19 -0
  293. package/dist/lib/ui/index.js.map +1 -0
  294. package/dist/lib/ui/output.d.ts +18 -0
  295. package/dist/lib/ui/output.d.ts.map +1 -0
  296. package/dist/lib/ui/output.js +31 -0
  297. package/dist/lib/ui/output.js.map +1 -0
  298. package/dist/lib/ui/output.test.d.ts +2 -0
  299. package/dist/lib/ui/output.test.d.ts.map +1 -0
  300. package/dist/lib/ui/output.test.js +59 -0
  301. package/dist/lib/ui/output.test.js.map +1 -0
  302. package/dist/lib/ui/spinner.d.ts +10 -0
  303. package/dist/lib/ui/spinner.d.ts.map +1 -0
  304. package/dist/lib/ui/spinner.js +10 -0
  305. package/dist/lib/ui/spinner.js.map +1 -0
  306. package/dist/lib/ui/status.d.ts +65 -0
  307. package/dist/lib/ui/status.d.ts.map +1 -0
  308. package/dist/lib/ui/status.js +100 -0
  309. package/dist/lib/ui/status.js.map +1 -0
  310. package/dist/lib/ui/status.test.d.ts +2 -0
  311. package/dist/lib/ui/status.test.d.ts.map +1 -0
  312. package/dist/lib/ui/status.test.js +158 -0
  313. package/dist/lib/ui/status.test.js.map +1 -0
  314. package/dist/lib/ui/table.d.ts +39 -0
  315. package/dist/lib/ui/table.d.ts.map +1 -0
  316. package/dist/lib/ui/table.js +45 -0
  317. package/dist/lib/ui/table.js.map +1 -0
  318. package/dist/lib/ui/table.test.d.ts +2 -0
  319. package/dist/lib/ui/table.test.d.ts.map +1 -0
  320. package/dist/lib/ui/table.test.js +115 -0
  321. package/dist/lib/ui/table.test.js.map +1 -0
  322. package/dist/lib/ui/theme.d.ts +34 -0
  323. package/dist/lib/ui/theme.d.ts.map +1 -0
  324. package/dist/lib/ui/theme.js +37 -0
  325. package/dist/lib/ui/theme.js.map +1 -0
  326. package/dist/lib/ui/theme.test.d.ts +2 -0
  327. package/dist/lib/ui/theme.test.d.ts.map +1 -0
  328. package/dist/lib/ui/theme.test.js +76 -0
  329. package/dist/lib/ui/theme.test.js.map +1 -0
  330. package/dist/lib/wtconfig/environment.d.ts +18 -1
  331. package/dist/lib/wtconfig/environment.d.ts.map +1 -1
  332. package/dist/lib/wtconfig/environment.js +60 -24
  333. package/dist/lib/wtconfig/environment.js.map +1 -1
  334. package/dist/lib/wtconfig/environment.test.js +45 -1
  335. package/dist/lib/wtconfig/environment.test.js.map +1 -1
  336. package/dist/lib/wtlink/config-manifest.test.js +26 -0
  337. package/dist/lib/wtlink/config-manifest.test.js.map +1 -1
  338. package/dist/lib/wtlink/link-configs.js +7 -7
  339. package/dist/lib/wtlink/link-configs.js.map +1 -1
  340. package/dist/lib/wtlink/validate-manifest.d.ts.map +1 -1
  341. package/dist/lib/wtlink/validate-manifest.js +5 -5
  342. package/dist/lib/wtlink/validate-manifest.js.map +1 -1
  343. package/dist/lib/wtstate/args.d.ts.map +1 -1
  344. package/dist/lib/wtstate/args.js +2 -0
  345. package/dist/lib/wtstate/args.js.map +1 -1
  346. package/dist/mcp/server.d.ts +2 -1
  347. package/dist/mcp/server.d.ts.map +1 -1
  348. package/dist/mcp/server.js +264 -44
  349. package/dist/mcp/server.js.map +1 -1
  350. package/dist/mcp/server.test.js +111 -0
  351. package/dist/mcp/server.test.js.map +1 -1
  352. package/package.json +3 -1
  353. package/schemas/worktreerc.schema.json +23 -0
@@ -0,0 +1,115 @@
1
+ import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
2
+ import { printTable } from './table.js';
3
+ import { setJsonMode } from './output.js';
4
+ import { setColorEnabled } from '../colors.js';
5
+ describe('ui/table', () => {
6
+ let logSpy;
7
+ beforeEach(() => {
8
+ logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
9
+ setColorEnabled(true);
10
+ });
11
+ afterEach(() => {
12
+ setJsonMode(false);
13
+ vi.restoreAllMocks();
14
+ });
15
+ it('prints formatted rows with labels and fields', () => {
16
+ printTable({
17
+ rows: [
18
+ {
19
+ label: 'PR #42',
20
+ fields: [
21
+ { key: 'Branch', value: 'feat/test' },
22
+ { key: 'Path', value: '/tmp/repo.pr42' },
23
+ ],
24
+ },
25
+ ],
26
+ });
27
+ const allOutput = logSpy.mock.calls.map((c) => c[0]);
28
+ expect(allOutput.some((line) => line.includes('PR #42'))).toBe(true);
29
+ expect(allOutput.some((line) => line.includes('Branch'))).toBe(true);
30
+ expect(allOutput.some((line) => line.includes('feat/test'))).toBe(true);
31
+ expect(allOutput.some((line) => line.includes('Path'))).toBe(true);
32
+ });
33
+ it('prints title when provided', () => {
34
+ printTable({
35
+ title: 'myrepo worktrees:',
36
+ rows: [
37
+ {
38
+ label: 'main',
39
+ fields: [{ key: 'Branch', value: 'main' }],
40
+ },
41
+ ],
42
+ });
43
+ const allOutput = logSpy.mock.calls.map((c) => c[0]);
44
+ expect(allOutput.some((line) => line.includes('myrepo worktrees:'))).toBe(true);
45
+ });
46
+ it('appends indicator to label when provided', () => {
47
+ printTable({
48
+ rows: [
49
+ {
50
+ label: 'PR #42',
51
+ indicator: ' *',
52
+ fields: [{ key: 'Branch', value: 'feat/test' }],
53
+ },
54
+ ],
55
+ });
56
+ const allOutput = logSpy.mock.calls.map((c) => c[0]);
57
+ const labelLine = allOutput.find((line) => line.includes('PR #42'));
58
+ expect(labelLine).toContain(' *');
59
+ });
60
+ it('prints nothing for empty rows', () => {
61
+ printTable({ rows: [] });
62
+ expect(logSpy).not.toHaveBeenCalled();
63
+ });
64
+ it('prints summary line when provided', () => {
65
+ printTable({
66
+ rows: [
67
+ {
68
+ label: 'main',
69
+ fields: [{ key: 'Branch', value: 'main' }],
70
+ },
71
+ ],
72
+ summary: '3 worktrees | 2 PRs | 1 open',
73
+ });
74
+ const allOutput = logSpy.mock.calls.map((c) => c[0]);
75
+ expect(allOutput.some((line) => line.includes('3 worktrees'))).toBe(true);
76
+ });
77
+ it('aligns field keys across all rows', () => {
78
+ printTable({
79
+ rows: [
80
+ {
81
+ label: 'Row 1',
82
+ fields: [
83
+ { key: 'Branch', value: 'main' },
84
+ { key: 'Path', value: '/tmp/main' },
85
+ ],
86
+ },
87
+ {
88
+ label: 'Row 2',
89
+ fields: [
90
+ { key: 'Branch', value: 'feat/x' },
91
+ { key: 'Commit', value: 'abc123' },
92
+ ],
93
+ },
94
+ ],
95
+ });
96
+ // All field lines should have consistent key padding
97
+ const fieldLines = logSpy.mock.calls
98
+ .map((c) => c[0])
99
+ .filter((line) => line.includes('Branch') || line.includes('Path') || line.includes('Commit'));
100
+ // Each field starts with 4 spaces of indent
101
+ for (const line of fieldLines) {
102
+ expect(line).toMatch(/^\s{4}/);
103
+ }
104
+ });
105
+ it('no-ops when JSON mode is active', () => {
106
+ setJsonMode(true);
107
+ printTable({
108
+ title: 'Test',
109
+ rows: [{ label: 'item', fields: [{ key: 'k', value: 'v' }] }],
110
+ summary: 'summary',
111
+ });
112
+ expect(logSpy).not.toHaveBeenCalled();
113
+ });
114
+ });
115
+ //# sourceMappingURL=table.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.test.js","sourceRoot":"","sources":["../../../src/lib/ui/table.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Centralized theme constants for UI output.
3
+ *
4
+ * Provides raw icons and box-drawing characters used by all other ui/ modules.
5
+ * colors.ts still provides the semantic functions (success(), error(), etc.)
6
+ * that combine icon + color. theme.ts provides the raw constants for cases
7
+ * where you need just the icon or just the box-drawing chars.
8
+ */
9
+ export declare const icons: {
10
+ readonly success: "✓";
11
+ readonly error: "✗";
12
+ readonly warning: "⚠";
13
+ readonly info: "ℹ";
14
+ readonly bullet: "•";
15
+ readonly arrow: "▶";
16
+ readonly change: "*";
17
+ };
18
+ export declare const box: {
19
+ readonly horizontal: "═";
20
+ readonly vertical: "║";
21
+ readonly topLeft: "╔";
22
+ readonly topRight: "╗";
23
+ readonly bottomLeft: "╚";
24
+ readonly bottomRight: "╝";
25
+ readonly line: "─";
26
+ };
27
+ /**
28
+ * Returns a compact change indicator: red " *" when changes exist, empty string otherwise.
29
+ *
30
+ * Standardizes the inconsistency where lswt uses `colors.red(' *')`
31
+ * and cleanpr uses `colors.red(' [has changes]')`.
32
+ */
33
+ export declare function changeIndicator(hasChanges: boolean): string;
34
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../src/lib/ui/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,KAAK;;;;;;;;CAQR,CAAC;AAEX,eAAO,MAAM,GAAG;;;;;;;;CAQN,CAAC;AAEX;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,CAE3D"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Centralized theme constants for UI output.
3
+ *
4
+ * Provides raw icons and box-drawing characters used by all other ui/ modules.
5
+ * colors.ts still provides the semantic functions (success(), error(), etc.)
6
+ * that combine icon + color. theme.ts provides the raw constants for cases
7
+ * where you need just the icon or just the box-drawing chars.
8
+ */
9
+ import * as colors from '../colors.js';
10
+ export const icons = {
11
+ success: '\u2713',
12
+ error: '\u2717',
13
+ warning: '\u26A0',
14
+ info: '\u2139',
15
+ bullet: '\u2022',
16
+ arrow: '\u25B6',
17
+ change: '*',
18
+ };
19
+ export const box = {
20
+ horizontal: '\u2550',
21
+ vertical: '\u2551',
22
+ topLeft: '\u2554',
23
+ topRight: '\u2557',
24
+ bottomLeft: '\u255A',
25
+ bottomRight: '\u255D',
26
+ line: '\u2500',
27
+ };
28
+ /**
29
+ * Returns a compact change indicator: red " *" when changes exist, empty string otherwise.
30
+ *
31
+ * Standardizes the inconsistency where lswt uses `colors.red(' *')`
32
+ * and cleanpr uses `colors.red(' [has changes]')`.
33
+ */
34
+ export function changeIndicator(hasChanges) {
35
+ return hasChanges ? colors.red(` ${icons.change}`) : '';
36
+ }
37
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../../src/lib/ui/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,GAAG;CACH,CAAC;AAEX,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,UAAU,EAAE,QAAQ;IACpB,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,QAAQ;IACjB,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,QAAQ;IACpB,WAAW,EAAE,QAAQ;IACrB,IAAI,EAAE,QAAQ;CACN,CAAC;AAEX;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,UAAmB;IACjD,OAAO,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=theme.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.test.d.ts","sourceRoot":"","sources":["../../../src/lib/ui/theme.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,76 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { icons, box, changeIndicator } from './theme.js';
3
+ import { setColorEnabled } from '../colors.js';
4
+ describe('ui/theme', () => {
5
+ beforeEach(() => {
6
+ // Enable colors for predictable output
7
+ setColorEnabled(true);
8
+ });
9
+ describe('icons', () => {
10
+ it('exports all expected icon constants', () => {
11
+ expect(icons.success).toBe('\u2713');
12
+ expect(icons.error).toBe('\u2717');
13
+ expect(icons.warning).toBe('\u26A0');
14
+ expect(icons.info).toBe('\u2139');
15
+ expect(icons.bullet).toBe('\u2022');
16
+ expect(icons.arrow).toBe('\u25B6');
17
+ expect(icons.change).toBe('*');
18
+ });
19
+ it('icons object is readonly', () => {
20
+ // TypeScript enforces this at compile time via `as const`,
21
+ // but verify the object has the right shape at runtime
22
+ expect(Object.keys(icons)).toEqual([
23
+ 'success',
24
+ 'error',
25
+ 'warning',
26
+ 'info',
27
+ 'bullet',
28
+ 'arrow',
29
+ 'change',
30
+ ]);
31
+ });
32
+ });
33
+ describe('box', () => {
34
+ it('exports all expected box-drawing constants', () => {
35
+ expect(box.horizontal).toBe('\u2550');
36
+ expect(box.vertical).toBe('\u2551');
37
+ expect(box.topLeft).toBe('\u2554');
38
+ expect(box.topRight).toBe('\u2557');
39
+ expect(box.bottomLeft).toBe('\u255A');
40
+ expect(box.bottomRight).toBe('\u255D');
41
+ expect(box.line).toBe('\u2500');
42
+ });
43
+ it('box object is readonly', () => {
44
+ expect(Object.keys(box)).toEqual([
45
+ 'horizontal',
46
+ 'vertical',
47
+ 'topLeft',
48
+ 'topRight',
49
+ 'bottomLeft',
50
+ 'bottomRight',
51
+ 'line',
52
+ ]);
53
+ });
54
+ });
55
+ describe('changeIndicator', () => {
56
+ it('returns a string containing * when hasChanges is true', () => {
57
+ const result = changeIndicator(true);
58
+ expect(result).toContain('*');
59
+ });
60
+ it('returns empty string when hasChanges is false', () => {
61
+ const result = changeIndicator(false);
62
+ expect(result).toBe('');
63
+ });
64
+ it('includes red ANSI code when changes exist and colors enabled', () => {
65
+ const result = changeIndicator(true);
66
+ // Should contain the red ANSI escape code
67
+ expect(result).toContain('\x1b[31m');
68
+ });
69
+ it('returns plain * without color when colors disabled', () => {
70
+ setColorEnabled(false);
71
+ const result = changeIndicator(true);
72
+ expect(result).toBe(' *');
73
+ });
74
+ });
75
+ });
76
+ //# sourceMappingURL=theme.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.test.js","sourceRoot":"","sources":["../../../src/lib/ui/theme.test.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,23 @@
4
4
  * Detects installed tools and environment configuration for the setup wizard.
5
5
  */
6
6
  import type { EnvironmentInfo } from './types.js';
7
+ /**
8
+ * Dependencies for environment detection (injectable for testing)
9
+ */
10
+ export interface EnvironmentDeps {
11
+ /** Check if a command exists in PATH */
12
+ commandExists: (command: string) => boolean;
13
+ /** Run a command and return output, or null on error */
14
+ runCommand: (command: string, args: string[]) => string | null;
15
+ }
16
+ /**
17
+ * Create default environment dependencies
18
+ */
19
+ export declare function createDefaultEnvironmentDeps(): EnvironmentDeps;
20
+ /**
21
+ * Reset environment deps to defaults (for testing)
22
+ */
23
+ export declare function resetEnvironmentDeps(): void;
7
24
  /**
8
25
  * Detect default branch from git config or common conventions
9
26
  */
@@ -11,7 +28,7 @@ export declare function detectDefaultBranch(repoRoot?: string): string;
11
28
  /**
12
29
  * Detect full environment information
13
30
  */
14
- export declare function detectEnvironment(cwd?: string): EnvironmentInfo;
31
+ export declare function detectEnvironment(cwd?: string, deps?: EnvironmentDeps): EnvironmentInfo;
15
32
  /**
16
33
  * Get install command for detected package manager
17
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../../src/lib/wtconfig/environment.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAmLlD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAkB7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe,CAS/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAY3F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,EAC3B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GACtC,MAAM,GAAG,IAAI,CASf"}
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../../src/lib/wtconfig/environment.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,wDAAwD;IACxD,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI,CAAC;CAChE;AA6CD;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAK9D;AAKD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAwID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAkC7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,eAAe,CAYvF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAY3F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,EAC3B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GACtC,MAAM,GAAG,IAAI,CASf"}
@@ -7,9 +7,9 @@ import { spawnSync } from 'child_process';
7
7
  import fs from 'fs';
8
8
  import path from 'path';
9
9
  /**
10
- * Check if a command exists in PATH
10
+ * Check if a command exists in PATH (implementation)
11
11
  */
12
- function commandExists(command) {
12
+ function commandExistsImpl(command) {
13
13
  try {
14
14
  const isWindows = process.platform === 'win32';
15
15
  if (isWindows) {
@@ -32,9 +32,9 @@ function commandExists(command) {
32
32
  }
33
33
  }
34
34
  /**
35
- * Run a command and return output, or null on error
35
+ * Run a command and return output, or null on error (implementation)
36
36
  */
37
- function runCommand(command, args) {
37
+ function runCommandImpl(command, args) {
38
38
  try {
39
39
  const result = spawnSync(command, args, {
40
40
  encoding: 'utf8',
@@ -50,6 +50,23 @@ function runCommand(command, args) {
50
50
  return null;
51
51
  }
52
52
  }
53
+ /**
54
+ * Create default environment dependencies
55
+ */
56
+ export function createDefaultEnvironmentDeps() {
57
+ return {
58
+ commandExists: commandExistsImpl,
59
+ runCommand: runCommandImpl,
60
+ };
61
+ }
62
+ // Module-level deps instance (set by detectEnvironment)
63
+ let currentDeps = createDefaultEnvironmentDeps();
64
+ /**
65
+ * Reset environment deps to defaults (for testing)
66
+ */
67
+ export function resetEnvironmentDeps() {
68
+ currentDeps = createDefaultEnvironmentDeps();
69
+ }
53
70
  /**
54
71
  * Detect operating system
55
72
  *
@@ -71,7 +88,7 @@ function detectOS() {
71
88
  * Detect git installation and configuration
72
89
  */
73
90
  function detectGit() {
74
- const version = runCommand('git', ['--version']);
91
+ const version = currentDeps.runCommand('git', ['--version']);
75
92
  if (!version) {
76
93
  return {
77
94
  version: null,
@@ -83,8 +100,8 @@ function detectGit() {
83
100
  // Extract version number (e.g., "git version 2.43.0" -> "2.43.0")
84
101
  const versionMatch = version.match(/git version (\d+\.\d+\.\d+)/);
85
102
  const versionNumber = versionMatch ? versionMatch[1] : version;
86
- const user = runCommand('git', ['config', '--global', 'user.name']);
87
- const email = runCommand('git', ['config', '--global', 'user.email']);
103
+ const user = currentDeps.runCommand('git', ['config', '--global', 'user.name']);
104
+ const email = currentDeps.runCommand('git', ['config', '--global', 'user.email']);
88
105
  return {
89
106
  version: versionNumber,
90
107
  configured: !!(user && email),
@@ -96,7 +113,7 @@ function detectGit() {
96
113
  * Detect GitHub CLI installation and authentication
97
114
  */
98
115
  function detectGitHub() {
99
- const installed = commandExists('gh');
116
+ const installed = currentDeps.commandExists('gh');
100
117
  if (!installed) {
101
118
  return {
102
119
  installed: false,
@@ -105,13 +122,13 @@ function detectGitHub() {
105
122
  };
106
123
  }
107
124
  // Check authentication status
108
- const authStatus = runCommand('gh', ['auth', 'status']);
125
+ const authStatus = currentDeps.runCommand('gh', ['auth', 'status']);
109
126
  const authenticated = authStatus !== null;
110
127
  // Get authenticated user
111
128
  let user = null;
112
129
  if (authenticated) {
113
130
  try {
114
- const userJson = runCommand('gh', ['api', 'user', '-q', '.login']);
131
+ const userJson = currentDeps.runCommand('gh', ['api', 'user', '-q', '.login']);
115
132
  user = userJson;
116
133
  }
117
134
  catch {
@@ -130,10 +147,10 @@ function detectGitHub() {
130
147
  */
131
148
  function detectAI() {
132
149
  return {
133
- claudeCode: commandExists('claude'),
134
- geminiCLI: commandExists('gemini'),
135
- ollama: commandExists('ollama'),
136
- codexCLI: commandExists('codex'),
150
+ claudeCode: currentDeps.commandExists('claude'),
151
+ geminiCLI: currentDeps.commandExists('gemini'),
152
+ ollama: currentDeps.commandExists('ollama'),
153
+ codexCLI: currentDeps.commandExists('codex'),
137
154
  };
138
155
  }
139
156
  /**
@@ -155,13 +172,13 @@ function detectPackageManager(cwd) {
155
172
  return 'npm';
156
173
  }
157
174
  // Check for installed package managers
158
- if (commandExists('pnpm'))
175
+ if (currentDeps.commandExists('pnpm'))
159
176
  return 'pnpm';
160
- if (commandExists('yarn'))
177
+ if (currentDeps.commandExists('yarn'))
161
178
  return 'yarn';
162
- if (commandExists('bun'))
179
+ if (currentDeps.commandExists('bun'))
163
180
  return 'bun';
164
- if (commandExists('npm'))
181
+ if (currentDeps.commandExists('npm'))
165
182
  return 'npm';
166
183
  return null;
167
184
  }
@@ -170,8 +187,8 @@ function detectPackageManager(cwd) {
170
187
  */
171
188
  function detectIDE() {
172
189
  return {
173
- vscode: commandExists('code'),
174
- cursor: commandExists('cursor'),
190
+ vscode: currentDeps.commandExists('code'),
191
+ cursor: currentDeps.commandExists('cursor'),
175
192
  };
176
193
  }
177
194
  /**
@@ -179,16 +196,32 @@ function detectIDE() {
179
196
  */
180
197
  export function detectDefaultBranch(repoRoot) {
181
198
  // Try to get from git config
182
- const initDefaultBranch = runCommand('git', ['config', '--global', 'init.defaultBranch']);
199
+ const initDefaultBranch = currentDeps.runCommand('git', [
200
+ 'config',
201
+ '--global',
202
+ 'init.defaultBranch',
203
+ ]);
183
204
  if (initDefaultBranch) {
184
205
  return initDefaultBranch;
185
206
  }
186
207
  // If in a repo, check what exists
187
208
  if (repoRoot) {
188
- const mainExists = runCommand('git', ['-C', repoRoot, 'rev-parse', '--verify', 'main']);
209
+ const mainExists = currentDeps.runCommand('git', [
210
+ '-C',
211
+ repoRoot,
212
+ 'rev-parse',
213
+ '--verify',
214
+ 'main',
215
+ ]);
189
216
  if (mainExists !== null)
190
217
  return 'main';
191
- const masterExists = runCommand('git', ['-C', repoRoot, 'rev-parse', '--verify', 'master']);
218
+ const masterExists = currentDeps.runCommand('git', [
219
+ '-C',
220
+ repoRoot,
221
+ 'rev-parse',
222
+ '--verify',
223
+ 'master',
224
+ ]);
192
225
  if (masterExists !== null)
193
226
  return 'master';
194
227
  }
@@ -198,7 +231,10 @@ export function detectDefaultBranch(repoRoot) {
198
231
  /**
199
232
  * Detect full environment information
200
233
  */
201
- export function detectEnvironment(cwd) {
234
+ export function detectEnvironment(cwd, deps) {
235
+ if (deps) {
236
+ currentDeps = deps;
237
+ }
202
238
  return {
203
239
  os: detectOS(),
204
240
  git: detectGit(),
@@ -1 +1 @@
1
- {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/lib/wtconfig/environment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/lib/wtconfig/environment.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
5
5
  import { spawnSync } from 'child_process';
6
6
  import fs from 'fs';
7
- import { detectEnvironment, detectDefaultBranch, getInstallCommand, getEditorCommand, } from './environment.js';
7
+ import { detectEnvironment, detectDefaultBranch, getInstallCommand, getEditorCommand, createDefaultEnvironmentDeps, resetEnvironmentDeps, } from './environment.js';
8
8
  vi.mock('child_process');
9
9
  vi.mock('fs');
10
10
  describe('environment', () => {
@@ -13,6 +13,8 @@ describe('environment', () => {
13
13
  beforeEach(() => {
14
14
  vi.clearAllMocks();
15
15
  process.env = { ...originalEnv };
16
+ // Reset module-level deps to defaults (uses mocked spawnSync)
17
+ resetEnvironmentDeps();
16
18
  // Mock spawnSync to return not found by default
17
19
  vi.mocked(spawnSync).mockReturnValue({
18
20
  status: 1,
@@ -177,6 +179,39 @@ describe('environment', () => {
177
179
  expect(result.ide.vscode).toBe(true);
178
180
  expect(result.ide.cursor).toBe(true);
179
181
  });
182
+ it('accepts mock deps for dependency injection', () => {
183
+ const mockDeps = {
184
+ commandExists: vi.fn().mockImplementation((cmd) => {
185
+ return cmd === 'code' || cmd === 'gh';
186
+ }),
187
+ runCommand: vi.fn().mockImplementation((cmd, args) => {
188
+ if (cmd === 'git' && args[0] === '--version') {
189
+ return 'git version 2.45.0';
190
+ }
191
+ if (cmd === 'git' && args[0] === 'config' && args[2] === 'user.name') {
192
+ return 'Mock User';
193
+ }
194
+ if (cmd === 'git' && args[0] === 'config' && args[2] === 'user.email') {
195
+ return 'mock@example.com';
196
+ }
197
+ if (cmd === 'gh' && args[0] === 'auth') {
198
+ return 'Logged in';
199
+ }
200
+ if (cmd === 'gh' && args[0] === 'api') {
201
+ return 'mockuser';
202
+ }
203
+ return null;
204
+ }),
205
+ };
206
+ const result = detectEnvironment(undefined, mockDeps);
207
+ expect(result.git.version).toBe('2.45.0');
208
+ expect(result.git.user).toBe('Mock User');
209
+ expect(result.git.email).toBe('mock@example.com');
210
+ expect(result.github.installed).toBe(true);
211
+ expect(result.ide.vscode).toBe(true);
212
+ expect(mockDeps.commandExists).toHaveBeenCalled();
213
+ expect(mockDeps.runCommand).toHaveBeenCalled();
214
+ });
180
215
  });
181
216
  describe('detectDefaultBranch', () => {
182
217
  it('returns main by default', () => {
@@ -211,6 +246,15 @@ describe('environment', () => {
211
246
  expect(getInstallCommand(null)).toBe('npm install');
212
247
  });
213
248
  });
249
+ describe('createDefaultEnvironmentDeps', () => {
250
+ it('returns deps object with required functions', () => {
251
+ const deps = createDefaultEnvironmentDeps();
252
+ expect(deps).toHaveProperty('commandExists');
253
+ expect(deps).toHaveProperty('runCommand');
254
+ expect(typeof deps.commandExists).toBe('function');
255
+ expect(typeof deps.runCommand).toBe('function');
256
+ });
257
+ });
214
258
  describe('getEditorCommand', () => {
215
259
  it('returns cursor command when cursor preferred and available', () => {
216
260
  const ide = { vscode: true, cursor: true };