@camaradesuk/git-worktree-tools 1.9.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. package/README.md +52 -31
  2. package/dist/cli/cleanpr.js +74 -53
  3. package/dist/cli/cleanpr.js.map +1 -1
  4. package/dist/cli/lswt.js +32 -56
  5. package/dist/cli/lswt.js.map +1 -1
  6. package/dist/cli/newpr.d.ts +13 -1
  7. package/dist/cli/newpr.d.ts.map +1 -1
  8. package/dist/cli/newpr.js +159 -153
  9. package/dist/cli/newpr.js.map +1 -1
  10. package/dist/cli/prs.d.ts +3 -10
  11. package/dist/cli/prs.d.ts.map +1 -1
  12. package/dist/cli/prs.js +6 -168
  13. package/dist/cli/prs.js.map +1 -1
  14. package/dist/cli/wt/clean.d.ts +6 -2
  15. package/dist/cli/wt/clean.d.ts.map +1 -1
  16. package/dist/cli/wt/clean.js +401 -20
  17. package/dist/cli/wt/clean.js.map +1 -1
  18. package/dist/cli/wt/completion.d.ts +3 -0
  19. package/dist/cli/wt/completion.d.ts.map +1 -1
  20. package/dist/cli/wt/completion.js +80 -9
  21. package/dist/cli/wt/completion.js.map +1 -1
  22. package/dist/cli/wt/config.d.ts +3 -1
  23. package/dist/cli/wt/config.d.ts.map +1 -1
  24. package/dist/cli/wt/config.js +323 -32
  25. package/dist/cli/wt/config.js.map +1 -1
  26. package/dist/cli/wt/interactive-menu.d.ts +2 -0
  27. package/dist/cli/wt/interactive-menu.d.ts.map +1 -1
  28. package/dist/cli/wt/interactive-menu.js +346 -73
  29. package/dist/cli/wt/interactive-menu.js.map +1 -1
  30. package/dist/cli/wt/link.d.ts +3 -1
  31. package/dist/cli/wt/link.d.ts.map +1 -1
  32. package/dist/cli/wt/link.js +125 -38
  33. package/dist/cli/wt/link.js.map +1 -1
  34. package/dist/cli/wt/list.d.ts +4 -1
  35. package/dist/cli/wt/list.d.ts.map +1 -1
  36. package/dist/cli/wt/list.js +85 -16
  37. package/dist/cli/wt/list.js.map +1 -1
  38. package/dist/cli/wt/new.d.ts +8 -2
  39. package/dist/cli/wt/new.d.ts.map +1 -1
  40. package/dist/cli/wt/new.js +91 -46
  41. package/dist/cli/wt/new.js.map +1 -1
  42. package/dist/cli/wt/prs.d.ts +2 -1
  43. package/dist/cli/wt/prs.d.ts.map +1 -1
  44. package/dist/cli/wt/prs.js +3 -164
  45. package/dist/cli/wt/prs.js.map +1 -1
  46. package/dist/cli/wt/run-command.d.ts +4 -2
  47. package/dist/cli/wt/run-command.d.ts.map +1 -1
  48. package/dist/cli/wt/run-command.js +6 -4
  49. package/dist/cli/wt/run-command.js.map +1 -1
  50. package/dist/cli/wt/state.d.ts +3 -1
  51. package/dist/cli/wt/state.d.ts.map +1 -1
  52. package/dist/cli/wt/state.js +74 -10
  53. package/dist/cli/wt/state.js.map +1 -1
  54. package/dist/cli/wt.d.ts.map +1 -1
  55. package/dist/cli/wt.js +50 -36
  56. package/dist/cli/wt.js.map +1 -1
  57. package/dist/cli/wtconfig.js +99 -22
  58. package/dist/cli/wtconfig.js.map +1 -1
  59. package/dist/cli/wtlink.js +85 -61
  60. package/dist/cli/wtlink.js.map +1 -1
  61. package/dist/cli/wtstate.js +21 -2
  62. package/dist/cli/wtstate.js.map +1 -1
  63. package/dist/lib/cleanpr/args.d.ts.map +1 -1
  64. package/dist/lib/cleanpr/args.js +20 -0
  65. package/dist/lib/cleanpr/args.js.map +1 -1
  66. package/dist/lib/cleanpr/types.d.ts +6 -0
  67. package/dist/lib/cleanpr/types.d.ts.map +1 -1
  68. package/dist/lib/colors.d.ts +5 -0
  69. package/dist/lib/colors.d.ts.map +1 -1
  70. package/dist/lib/colors.js +13 -6
  71. package/dist/lib/colors.js.map +1 -1
  72. package/dist/lib/constants.d.ts +12 -4
  73. package/dist/lib/constants.d.ts.map +1 -1
  74. package/dist/lib/constants.js +24 -5
  75. package/dist/lib/constants.js.map +1 -1
  76. package/dist/lib/deprecation.d.ts +18 -0
  77. package/dist/lib/deprecation.d.ts.map +1 -0
  78. package/dist/lib/deprecation.js +28 -0
  79. package/dist/lib/deprecation.js.map +1 -0
  80. package/dist/lib/logger.d.ts +40 -155
  81. package/dist/lib/logger.d.ts.map +1 -1
  82. package/dist/lib/logger.js +349 -420
  83. package/dist/lib/logger.js.map +1 -1
  84. package/dist/lib/lswt/args.d.ts.map +1 -1
  85. package/dist/lib/lswt/args.js +15 -1
  86. package/dist/lib/lswt/args.js.map +1 -1
  87. package/dist/lib/lswt/index.d.ts +1 -0
  88. package/dist/lib/lswt/index.d.ts.map +1 -1
  89. package/dist/lib/lswt/index.js +2 -0
  90. package/dist/lib/lswt/index.js.map +1 -1
  91. package/dist/lib/lswt/table.d.ts +15 -0
  92. package/dist/lib/lswt/table.d.ts.map +1 -0
  93. package/dist/lib/lswt/table.js +61 -0
  94. package/dist/lib/lswt/table.js.map +1 -0
  95. package/dist/lib/lswt/types.d.ts +4 -0
  96. package/dist/lib/lswt/types.d.ts.map +1 -1
  97. package/dist/lib/newpr/args.d.ts.map +1 -1
  98. package/dist/lib/newpr/args.js +21 -0
  99. package/dist/lib/newpr/args.js.map +1 -1
  100. package/dist/lib/newpr/types.d.ts +6 -0
  101. package/dist/lib/newpr/types.d.ts.map +1 -1
  102. package/dist/lib/prs/command.d.ts +21 -0
  103. package/dist/lib/prs/command.d.ts.map +1 -0
  104. package/dist/lib/prs/command.js +175 -0
  105. package/dist/lib/prs/command.js.map +1 -0
  106. package/dist/lib/prs/interactive.d.ts.map +1 -1
  107. package/dist/lib/prs/interactive.js +15 -2
  108. package/dist/lib/prs/interactive.js.map +1 -1
  109. package/dist/lib/prs/types.d.ts +15 -0
  110. package/dist/lib/prs/types.d.ts.map +1 -1
  111. package/dist/lib/ui/error.d.ts +31 -0
  112. package/dist/lib/ui/error.d.ts.map +1 -0
  113. package/dist/lib/ui/error.js +47 -0
  114. package/dist/lib/ui/error.js.map +1 -0
  115. package/dist/lib/ui/index.d.ts +15 -0
  116. package/dist/lib/ui/index.d.ts.map +1 -0
  117. package/dist/lib/ui/index.js +19 -0
  118. package/dist/lib/ui/index.js.map +1 -0
  119. package/dist/lib/ui/output.d.ts +18 -0
  120. package/dist/lib/ui/output.d.ts.map +1 -0
  121. package/dist/lib/ui/output.js +31 -0
  122. package/dist/lib/ui/output.js.map +1 -0
  123. package/dist/lib/ui/spinner.d.ts +10 -0
  124. package/dist/lib/ui/spinner.d.ts.map +1 -0
  125. package/dist/lib/ui/spinner.js +10 -0
  126. package/dist/lib/ui/spinner.js.map +1 -0
  127. package/dist/lib/ui/status.d.ts +65 -0
  128. package/dist/lib/ui/status.d.ts.map +1 -0
  129. package/dist/lib/ui/status.js +100 -0
  130. package/dist/lib/ui/status.js.map +1 -0
  131. package/dist/lib/ui/table.d.ts +39 -0
  132. package/dist/lib/ui/table.d.ts.map +1 -0
  133. package/dist/lib/ui/table.js +45 -0
  134. package/dist/lib/ui/table.js.map +1 -0
  135. package/dist/lib/ui/theme.d.ts +34 -0
  136. package/dist/lib/ui/theme.d.ts.map +1 -0
  137. package/dist/lib/ui/theme.js +37 -0
  138. package/dist/lib/ui/theme.js.map +1 -0
  139. package/dist/lib/wtlink/link-configs.js +7 -7
  140. package/dist/lib/wtlink/link-configs.js.map +1 -1
  141. package/dist/lib/wtlink/validate-manifest.d.ts.map +1 -1
  142. package/dist/lib/wtlink/validate-manifest.js +5 -5
  143. package/dist/lib/wtlink/validate-manifest.js.map +1 -1
  144. package/dist/lib/wtstate/args.d.ts.map +1 -1
  145. package/dist/lib/wtstate/args.js +2 -0
  146. package/dist/lib/wtstate/args.js.map +1 -1
  147. package/dist/mcp/server.d.ts +2 -1
  148. package/dist/mcp/server.d.ts.map +1 -1
  149. package/dist/mcp/server.js +264 -44
  150. package/dist/mcp/server.js.map +1 -1
  151. package/package.json +13 -3
  152. package/dist/api/list.test.d.ts +0 -5
  153. package/dist/api/list.test.d.ts.map +0 -1
  154. package/dist/api/list.test.js +0 -390
  155. package/dist/api/list.test.js.map +0 -1
  156. package/dist/cli/cleanpr.test.d.ts +0 -2
  157. package/dist/cli/cleanpr.test.d.ts.map +0 -1
  158. package/dist/cli/cleanpr.test.js +0 -954
  159. package/dist/cli/cleanpr.test.js.map +0 -1
  160. package/dist/cli/lswt.test.d.ts +0 -2
  161. package/dist/cli/lswt.test.d.ts.map +0 -1
  162. package/dist/cli/lswt.test.js +0 -386
  163. package/dist/cli/lswt.test.js.map +0 -1
  164. package/dist/cli/newpr.test.d.ts +0 -2
  165. package/dist/cli/newpr.test.d.ts.map +0 -1
  166. package/dist/cli/newpr.test.js +0 -1182
  167. package/dist/cli/newpr.test.js.map +0 -1
  168. package/dist/cli/prs.test.d.ts +0 -8
  169. package/dist/cli/prs.test.d.ts.map +0 -1
  170. package/dist/cli/prs.test.js +0 -410
  171. package/dist/cli/prs.test.js.map +0 -1
  172. package/dist/cli/wt/completion.test.d.ts +0 -5
  173. package/dist/cli/wt/completion.test.d.ts.map +0 -1
  174. package/dist/cli/wt/completion.test.js +0 -173
  175. package/dist/cli/wt/completion.test.js.map +0 -1
  176. package/dist/cli/wt/config.test.d.ts +0 -5
  177. package/dist/cli/wt/config.test.d.ts.map +0 -1
  178. package/dist/cli/wt/config.test.js +0 -260
  179. package/dist/cli/wt/config.test.js.map +0 -1
  180. package/dist/cli/wt/entry.test.d.ts +0 -8
  181. package/dist/cli/wt/entry.test.d.ts.map +0 -1
  182. package/dist/cli/wt/entry.test.js +0 -201
  183. package/dist/cli/wt/entry.test.js.map +0 -1
  184. package/dist/cli/wt/init.test.d.ts +0 -5
  185. package/dist/cli/wt/init.test.d.ts.map +0 -1
  186. package/dist/cli/wt/init.test.js +0 -165
  187. package/dist/cli/wt/init.test.js.map +0 -1
  188. package/dist/cli/wt/init.unit.test.d.ts +0 -5
  189. package/dist/cli/wt/init.unit.test.d.ts.map +0 -1
  190. package/dist/cli/wt/init.unit.test.js +0 -432
  191. package/dist/cli/wt/init.unit.test.js.map +0 -1
  192. package/dist/cli/wt/interactive-menu.test.d.ts +0 -10
  193. package/dist/cli/wt/interactive-menu.test.d.ts.map +0 -1
  194. package/dist/cli/wt/interactive-menu.test.js +0 -739
  195. package/dist/cli/wt/interactive-menu.test.js.map +0 -1
  196. package/dist/cli/wt/prs.test.d.ts +0 -5
  197. package/dist/cli/wt/prs.test.d.ts.map +0 -1
  198. package/dist/cli/wt/prs.test.js +0 -410
  199. package/dist/cli/wt/prs.test.js.map +0 -1
  200. package/dist/cli/wt/run-command.test.d.ts +0 -5
  201. package/dist/cli/wt/run-command.test.d.ts.map +0 -1
  202. package/dist/cli/wt/run-command.test.js +0 -88
  203. package/dist/cli/wt/run-command.test.js.map +0 -1
  204. package/dist/cli/wt/wt.test.d.ts +0 -8
  205. package/dist/cli/wt/wt.test.d.ts.map +0 -1
  206. package/dist/cli/wt/wt.test.js +0 -521
  207. package/dist/cli/wt/wt.test.js.map +0 -1
  208. package/dist/cli/wt.unit.test.d.ts +0 -7
  209. package/dist/cli/wt.unit.test.d.ts.map +0 -1
  210. package/dist/cli/wt.unit.test.js +0 -182
  211. package/dist/cli/wt.unit.test.js.map +0 -1
  212. package/dist/cli/wtconfig.test.d.ts +0 -5
  213. package/dist/cli/wtconfig.test.d.ts.map +0 -1
  214. package/dist/cli/wtconfig.test.js +0 -1289
  215. package/dist/cli/wtconfig.test.js.map +0 -1
  216. package/dist/cli/wtlink.test.d.ts +0 -2
  217. package/dist/cli/wtlink.test.d.ts.map +0 -1
  218. package/dist/cli/wtlink.test.js +0 -249
  219. package/dist/cli/wtlink.test.js.map +0 -1
  220. package/dist/cli/wtstate.test.d.ts +0 -5
  221. package/dist/cli/wtstate.test.d.ts.map +0 -1
  222. package/dist/cli/wtstate.test.js +0 -193
  223. package/dist/cli/wtstate.test.js.map +0 -1
  224. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +0 -2
  225. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +0 -1
  226. package/dist/e2e/cleanpr/cleanpr.e2e.test.js +0 -326
  227. package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +0 -1
  228. package/dist/e2e/cli.e2e.test.d.ts +0 -2
  229. package/dist/e2e/cli.e2e.test.d.ts.map +0 -1
  230. package/dist/e2e/cli.e2e.test.js +0 -417
  231. package/dist/e2e/cli.e2e.test.js.map +0 -1
  232. package/dist/e2e/lswt/lswt.e2e.test.d.ts +0 -2
  233. package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +0 -1
  234. package/dist/e2e/lswt/lswt.e2e.test.js +0 -361
  235. package/dist/e2e/lswt/lswt.e2e.test.js.map +0 -1
  236. package/dist/e2e/newpr/newpr.e2e.test.d.ts +0 -2
  237. package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +0 -1
  238. package/dist/e2e/newpr/newpr.e2e.test.js +0 -286
  239. package/dist/e2e/newpr/newpr.e2e.test.js.map +0 -1
  240. package/dist/e2e/newpr/scenarios.e2e.test.d.ts +0 -2
  241. package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +0 -1
  242. package/dist/e2e/newpr/scenarios.e2e.test.js +0 -426
  243. package/dist/e2e/newpr/scenarios.e2e.test.js.map +0 -1
  244. package/dist/e2e/newpr-full-flow.e2e.test.d.ts +0 -2
  245. package/dist/e2e/newpr-full-flow.e2e.test.d.ts.map +0 -1
  246. package/dist/e2e/newpr-full-flow.e2e.test.js +0 -280
  247. package/dist/e2e/newpr-full-flow.e2e.test.js.map +0 -1
  248. package/dist/e2e/prs/prs.e2e.test.d.ts +0 -7
  249. package/dist/e2e/prs/prs.e2e.test.d.ts.map +0 -1
  250. package/dist/e2e/prs/prs.e2e.test.js +0 -606
  251. package/dist/e2e/prs/prs.e2e.test.js.map +0 -1
  252. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +0 -2
  253. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +0 -1
  254. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +0 -298
  255. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +0 -1
  256. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts +0 -8
  257. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts.map +0 -1
  258. package/dist/e2e/wt/interactive-menu.e2e.test.js +0 -583
  259. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +0 -1
  260. package/dist/e2e/wt/wt.e2e.test.d.ts +0 -9
  261. package/dist/e2e/wt/wt.e2e.test.d.ts.map +0 -1
  262. package/dist/e2e/wt/wt.e2e.test.js +0 -597
  263. package/dist/e2e/wt/wt.e2e.test.js.map +0 -1
  264. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +0 -2
  265. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +0 -1
  266. package/dist/e2e/wtlink/wtlink.e2e.test.js +0 -416
  267. package/dist/e2e/wtlink/wtlink.e2e.test.js.map +0 -1
  268. package/dist/integration/git.integration.test.d.ts +0 -2
  269. package/dist/integration/git.integration.test.d.ts.map +0 -1
  270. package/dist/integration/git.integration.test.js +0 -336
  271. package/dist/integration/git.integration.test.js.map +0 -1
  272. package/dist/integration/lswt-remote-pr.integration.test.d.ts +0 -2
  273. package/dist/integration/lswt-remote-pr.integration.test.d.ts.map +0 -1
  274. package/dist/integration/lswt-remote-pr.integration.test.js +0 -222
  275. package/dist/integration/lswt-remote-pr.integration.test.js.map +0 -1
  276. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts +0 -2
  277. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts.map +0 -1
  278. package/dist/integration/newpr-branchfrom-head.integration.test.js +0 -498
  279. package/dist/integration/newpr-branchfrom-head.integration.test.js.map +0 -1
  280. package/dist/integration/newpr.integration.test.d.ts +0 -2
  281. package/dist/integration/newpr.integration.test.d.ts.map +0 -1
  282. package/dist/integration/newpr.integration.test.js +0 -460
  283. package/dist/integration/newpr.integration.test.js.map +0 -1
  284. package/dist/integration/prs.integration.test.d.ts +0 -8
  285. package/dist/integration/prs.integration.test.d.ts.map +0 -1
  286. package/dist/integration/prs.integration.test.js +0 -478
  287. package/dist/integration/prs.integration.test.js.map +0 -1
  288. package/dist/lib/ai/base-provider.test.d.ts +0 -7
  289. package/dist/lib/ai/base-provider.test.d.ts.map +0 -1
  290. package/dist/lib/ai/base-provider.test.js +0 -319
  291. package/dist/lib/ai/base-provider.test.js.map +0 -1
  292. package/dist/lib/ai/cli-provider.test.d.ts +0 -5
  293. package/dist/lib/ai/cli-provider.test.d.ts.map +0 -1
  294. package/dist/lib/ai/cli-provider.test.js +0 -460
  295. package/dist/lib/ai/cli-provider.test.js.map +0 -1
  296. package/dist/lib/ai/fallback-provider.test.d.ts +0 -7
  297. package/dist/lib/ai/fallback-provider.test.d.ts.map +0 -1
  298. package/dist/lib/ai/fallback-provider.test.js +0 -165
  299. package/dist/lib/ai/fallback-provider.test.js.map +0 -1
  300. package/dist/lib/ai/generation-service.test.d.ts +0 -7
  301. package/dist/lib/ai/generation-service.test.d.ts.map +0 -1
  302. package/dist/lib/ai/generation-service.test.js +0 -213
  303. package/dist/lib/ai/generation-service.test.js.map +0 -1
  304. package/dist/lib/ai/provider-manager.test.d.ts +0 -5
  305. package/dist/lib/ai/provider-manager.test.d.ts.map +0 -1
  306. package/dist/lib/ai/provider-manager.test.js +0 -312
  307. package/dist/lib/ai/provider-manager.test.js.map +0 -1
  308. package/dist/lib/ai/repo-docs.test.d.ts +0 -5
  309. package/dist/lib/ai/repo-docs.test.d.ts.map +0 -1
  310. package/dist/lib/ai/repo-docs.test.js +0 -357
  311. package/dist/lib/ai/repo-docs.test.js.map +0 -1
  312. package/dist/lib/cleanpr/args.test.d.ts +0 -2
  313. package/dist/lib/cleanpr/args.test.d.ts.map +0 -1
  314. package/dist/lib/cleanpr/args.test.js +0 -269
  315. package/dist/lib/cleanpr/args.test.js.map +0 -1
  316. package/dist/lib/cleanpr/cleanup.test.d.ts +0 -2
  317. package/dist/lib/cleanpr/cleanup.test.d.ts.map +0 -1
  318. package/dist/lib/cleanpr/cleanup.test.js +0 -296
  319. package/dist/lib/cleanpr/cleanup.test.js.map +0 -1
  320. package/dist/lib/cleanpr/worktree-info.test.d.ts +0 -2
  321. package/dist/lib/cleanpr/worktree-info.test.d.ts.map +0 -1
  322. package/dist/lib/cleanpr/worktree-info.test.js +0 -228
  323. package/dist/lib/cleanpr/worktree-info.test.js.map +0 -1
  324. package/dist/lib/colors.test.d.ts +0 -2
  325. package/dist/lib/colors.test.d.ts.map +0 -1
  326. package/dist/lib/colors.test.js +0 -142
  327. package/dist/lib/colors.test.js.map +0 -1
  328. package/dist/lib/config-editor.test.d.ts +0 -11
  329. package/dist/lib/config-editor.test.d.ts.map +0 -1
  330. package/dist/lib/config-editor.test.js +0 -526
  331. package/dist/lib/config-editor.test.js.map +0 -1
  332. package/dist/lib/config-migration/detector.test.d.ts +0 -5
  333. package/dist/lib/config-migration/detector.test.d.ts.map +0 -1
  334. package/dist/lib/config-migration/detector.test.js +0 -201
  335. package/dist/lib/config-migration/detector.test.js.map +0 -1
  336. package/dist/lib/config-migration/reporter.test.d.ts +0 -5
  337. package/dist/lib/config-migration/reporter.test.d.ts.map +0 -1
  338. package/dist/lib/config-migration/reporter.test.js +0 -305
  339. package/dist/lib/config-migration/reporter.test.js.map +0 -1
  340. package/dist/lib/config-migration/runner.test.d.ts +0 -5
  341. package/dist/lib/config-migration/runner.test.d.ts.map +0 -1
  342. package/dist/lib/config-migration/runner.test.js +0 -235
  343. package/dist/lib/config-migration/runner.test.js.map +0 -1
  344. package/dist/lib/config-validation.test.d.ts +0 -5
  345. package/dist/lib/config-validation.test.d.ts.map +0 -1
  346. package/dist/lib/config-validation.test.js +0 -423
  347. package/dist/lib/config-validation.test.js.map +0 -1
  348. package/dist/lib/config.test.d.ts +0 -2
  349. package/dist/lib/config.test.d.ts.map +0 -1
  350. package/dist/lib/config.test.js +0 -566
  351. package/dist/lib/config.test.js.map +0 -1
  352. package/dist/lib/constants.test.d.ts +0 -5
  353. package/dist/lib/constants.test.d.ts.map +0 -1
  354. package/dist/lib/constants.test.js +0 -121
  355. package/dist/lib/constants.test.js.map +0 -1
  356. package/dist/lib/errors.test.d.ts +0 -2
  357. package/dist/lib/errors.test.d.ts.map +0 -1
  358. package/dist/lib/errors.test.js +0 -117
  359. package/dist/lib/errors.test.js.map +0 -1
  360. package/dist/lib/git.test.d.ts +0 -2
  361. package/dist/lib/git.test.d.ts.map +0 -1
  362. package/dist/lib/git.test.js +0 -608
  363. package/dist/lib/git.test.js.map +0 -1
  364. package/dist/lib/github.test.d.ts +0 -2
  365. package/dist/lib/github.test.d.ts.map +0 -1
  366. package/dist/lib/github.test.js +0 -441
  367. package/dist/lib/github.test.js.map +0 -1
  368. package/dist/lib/global-check.test.d.ts +0 -5
  369. package/dist/lib/global-check.test.d.ts.map +0 -1
  370. package/dist/lib/global-check.test.js +0 -150
  371. package/dist/lib/global-check.test.js.map +0 -1
  372. package/dist/lib/global-config.test.d.ts +0 -5
  373. package/dist/lib/global-config.test.d.ts.map +0 -1
  374. package/dist/lib/global-config.test.js +0 -282
  375. package/dist/lib/global-config.test.js.map +0 -1
  376. package/dist/lib/hooks/confirmation.test.d.ts +0 -7
  377. package/dist/lib/hooks/confirmation.test.d.ts.map +0 -1
  378. package/dist/lib/hooks/confirmation.test.js +0 -300
  379. package/dist/lib/hooks/confirmation.test.js.map +0 -1
  380. package/dist/lib/hooks/executor.test.d.ts +0 -5
  381. package/dist/lib/hooks/executor.test.d.ts.map +0 -1
  382. package/dist/lib/hooks/executor.test.js +0 -648
  383. package/dist/lib/hooks/executor.test.js.map +0 -1
  384. package/dist/lib/hooks/templates.test.d.ts +0 -5
  385. package/dist/lib/hooks/templates.test.d.ts.map +0 -1
  386. package/dist/lib/hooks/templates.test.js +0 -163
  387. package/dist/lib/hooks/templates.test.js.map +0 -1
  388. package/dist/lib/hooks/types.test.d.ts +0 -5
  389. package/dist/lib/hooks/types.test.d.ts.map +0 -1
  390. package/dist/lib/hooks/types.test.js +0 -132
  391. package/dist/lib/hooks/types.test.js.map +0 -1
  392. package/dist/lib/json-output.test.d.ts +0 -5
  393. package/dist/lib/json-output.test.d.ts.map +0 -1
  394. package/dist/lib/json-output.test.js +0 -261
  395. package/dist/lib/json-output.test.js.map +0 -1
  396. package/dist/lib/logger.test.d.ts +0 -5
  397. package/dist/lib/logger.test.d.ts.map +0 -1
  398. package/dist/lib/logger.test.js +0 -292
  399. package/dist/lib/logger.test.js.map +0 -1
  400. package/dist/lib/lswt/action-executors.test.d.ts +0 -2
  401. package/dist/lib/lswt/action-executors.test.d.ts.map +0 -1
  402. package/dist/lib/lswt/action-executors.test.js +0 -1127
  403. package/dist/lib/lswt/action-executors.test.js.map +0 -1
  404. package/dist/lib/lswt/actions.test.d.ts +0 -2
  405. package/dist/lib/lswt/actions.test.d.ts.map +0 -1
  406. package/dist/lib/lswt/actions.test.js +0 -497
  407. package/dist/lib/lswt/actions.test.js.map +0 -1
  408. package/dist/lib/lswt/args.test.d.ts +0 -2
  409. package/dist/lib/lswt/args.test.d.ts.map +0 -1
  410. package/dist/lib/lswt/args.test.js +0 -195
  411. package/dist/lib/lswt/args.test.js.map +0 -1
  412. package/dist/lib/lswt/environment.test.d.ts +0 -2
  413. package/dist/lib/lswt/environment.test.d.ts.map +0 -1
  414. package/dist/lib/lswt/environment.test.js +0 -544
  415. package/dist/lib/lswt/environment.test.js.map +0 -1
  416. package/dist/lib/lswt/formatters.test.d.ts +0 -2
  417. package/dist/lib/lswt/formatters.test.d.ts.map +0 -1
  418. package/dist/lib/lswt/formatters.test.js +0 -323
  419. package/dist/lib/lswt/formatters.test.js.map +0 -1
  420. package/dist/lib/lswt/fuzzy-search.test.d.ts +0 -5
  421. package/dist/lib/lswt/fuzzy-search.test.d.ts.map +0 -1
  422. package/dist/lib/lswt/fuzzy-search.test.js +0 -207
  423. package/dist/lib/lswt/fuzzy-search.test.js.map +0 -1
  424. package/dist/lib/lswt/interactive.test.d.ts +0 -2
  425. package/dist/lib/lswt/interactive.test.d.ts.map +0 -1
  426. package/dist/lib/lswt/interactive.test.js +0 -771
  427. package/dist/lib/lswt/interactive.test.js.map +0 -1
  428. package/dist/lib/lswt/worktree-info.test.d.ts +0 -2
  429. package/dist/lib/lswt/worktree-info.test.d.ts.map +0 -1
  430. package/dist/lib/lswt/worktree-info.test.js +0 -484
  431. package/dist/lib/lswt/worktree-info.test.js.map +0 -1
  432. package/dist/lib/newpr/action-deps.test.d.ts +0 -5
  433. package/dist/lib/newpr/action-deps.test.d.ts.map +0 -1
  434. package/dist/lib/newpr/action-deps.test.js +0 -111
  435. package/dist/lib/newpr/action-deps.test.js.map +0 -1
  436. package/dist/lib/newpr/actions.test.d.ts +0 -2
  437. package/dist/lib/newpr/actions.test.d.ts.map +0 -1
  438. package/dist/lib/newpr/actions.test.js +0 -254
  439. package/dist/lib/newpr/actions.test.js.map +0 -1
  440. package/dist/lib/newpr/args.test.d.ts +0 -2
  441. package/dist/lib/newpr/args.test.d.ts.map +0 -1
  442. package/dist/lib/newpr/args.test.js +0 -479
  443. package/dist/lib/newpr/args.test.js.map +0 -1
  444. package/dist/lib/newpr/hook-runner.test.d.ts +0 -7
  445. package/dist/lib/newpr/hook-runner.test.d.ts.map +0 -1
  446. package/dist/lib/newpr/hook-runner.test.js +0 -422
  447. package/dist/lib/newpr/hook-runner.test.js.map +0 -1
  448. package/dist/lib/newpr/plan-generator.test.d.ts +0 -7
  449. package/dist/lib/newpr/plan-generator.test.d.ts.map +0 -1
  450. package/dist/lib/newpr/plan-generator.test.js +0 -387
  451. package/dist/lib/newpr/plan-generator.test.js.map +0 -1
  452. package/dist/lib/newpr/scenario-handler.test.d.ts +0 -2
  453. package/dist/lib/newpr/scenario-handler.test.d.ts.map +0 -1
  454. package/dist/lib/newpr/scenario-handler.test.js +0 -256
  455. package/dist/lib/newpr/scenario-handler.test.js.map +0 -1
  456. package/dist/lib/prompts.test.d.ts +0 -2
  457. package/dist/lib/prompts.test.d.ts.map +0 -1
  458. package/dist/lib/prompts.test.js +0 -807
  459. package/dist/lib/prompts.test.js.map +0 -1
  460. package/dist/lib/prs/actions.test.d.ts +0 -5
  461. package/dist/lib/prs/actions.test.d.ts.map +0 -1
  462. package/dist/lib/prs/actions.test.js +0 -356
  463. package/dist/lib/prs/actions.test.js.map +0 -1
  464. package/dist/lib/prs/data.test.d.ts +0 -5
  465. package/dist/lib/prs/data.test.d.ts.map +0 -1
  466. package/dist/lib/prs/data.test.js +0 -417
  467. package/dist/lib/prs/data.test.js.map +0 -1
  468. package/dist/lib/prs/details.test.d.ts +0 -5
  469. package/dist/lib/prs/details.test.d.ts.map +0 -1
  470. package/dist/lib/prs/details.test.js +0 -325
  471. package/dist/lib/prs/details.test.js.map +0 -1
  472. package/dist/lib/prs/filters.test.d.ts +0 -5
  473. package/dist/lib/prs/filters.test.d.ts.map +0 -1
  474. package/dist/lib/prs/filters.test.js +0 -312
  475. package/dist/lib/prs/filters.test.js.map +0 -1
  476. package/dist/lib/prs/formatters.test.d.ts +0 -2
  477. package/dist/lib/prs/formatters.test.d.ts.map +0 -1
  478. package/dist/lib/prs/formatters.test.js +0 -387
  479. package/dist/lib/prs/formatters.test.js.map +0 -1
  480. package/dist/lib/prs/interactive.test.d.ts +0 -5
  481. package/dist/lib/prs/interactive.test.d.ts.map +0 -1
  482. package/dist/lib/prs/interactive.test.js +0 -364
  483. package/dist/lib/prs/interactive.test.js.map +0 -1
  484. package/dist/lib/schema.test.d.ts +0 -10
  485. package/dist/lib/schema.test.d.ts.map +0 -1
  486. package/dist/lib/schema.test.js +0 -309
  487. package/dist/lib/schema.test.js.map +0 -1
  488. package/dist/lib/state-detection.test.d.ts +0 -2
  489. package/dist/lib/state-detection.test.d.ts.map +0 -1
  490. package/dist/lib/state-detection.test.js +0 -451
  491. package/dist/lib/state-detection.test.js.map +0 -1
  492. package/dist/lib/wtconfig/config-manager.test.d.ts +0 -5
  493. package/dist/lib/wtconfig/config-manager.test.d.ts.map +0 -1
  494. package/dist/lib/wtconfig/config-manager.test.js +0 -501
  495. package/dist/lib/wtconfig/config-manager.test.js.map +0 -1
  496. package/dist/lib/wtconfig/environment.test.d.ts +0 -5
  497. package/dist/lib/wtconfig/environment.test.d.ts.map +0 -1
  498. package/dist/lib/wtconfig/environment.test.js +0 -285
  499. package/dist/lib/wtconfig/environment.test.js.map +0 -1
  500. package/dist/lib/wtlink/config-manifest.test.d.ts +0 -2
  501. package/dist/lib/wtlink/config-manifest.test.d.ts.map +0 -1
  502. package/dist/lib/wtlink/config-manifest.test.js +0 -486
  503. package/dist/lib/wtlink/config-manifest.test.js.map +0 -1
  504. package/dist/lib/wtlink/link-configs.test.d.ts +0 -2
  505. package/dist/lib/wtlink/link-configs.test.d.ts.map +0 -1
  506. package/dist/lib/wtlink/link-configs.test.js +0 -612
  507. package/dist/lib/wtlink/link-configs.test.js.map +0 -1
  508. package/dist/lib/wtlink/main-menu.test.d.ts +0 -5
  509. package/dist/lib/wtlink/main-menu.test.d.ts.map +0 -1
  510. package/dist/lib/wtlink/main-menu.test.js +0 -126
  511. package/dist/lib/wtlink/main-menu.test.js.map +0 -1
  512. package/dist/lib/wtlink/manage-manifest.test.d.ts +0 -2
  513. package/dist/lib/wtlink/manage-manifest.test.d.ts.map +0 -1
  514. package/dist/lib/wtlink/manage-manifest.test.js +0 -714
  515. package/dist/lib/wtlink/manage-manifest.test.js.map +0 -1
  516. package/dist/lib/wtlink/validate-manifest.test.d.ts +0 -2
  517. package/dist/lib/wtlink/validate-manifest.test.d.ts.map +0 -1
  518. package/dist/lib/wtlink/validate-manifest.test.js +0 -220
  519. package/dist/lib/wtlink/validate-manifest.test.js.map +0 -1
  520. package/dist/lib/wtstate/analyze.test.d.ts +0 -5
  521. package/dist/lib/wtstate/analyze.test.d.ts.map +0 -1
  522. package/dist/lib/wtstate/analyze.test.js +0 -282
  523. package/dist/lib/wtstate/analyze.test.js.map +0 -1
  524. package/dist/lib/wtstate/args.test.d.ts +0 -5
  525. package/dist/lib/wtstate/args.test.d.ts.map +0 -1
  526. package/dist/lib/wtstate/args.test.js +0 -120
  527. package/dist/lib/wtstate/args.test.js.map +0 -1
  528. package/dist/mcp/server.test.d.ts +0 -9
  529. package/dist/mcp/server.test.d.ts.map +0 -1
  530. package/dist/mcp/server.test.js +0 -439
  531. package/dist/mcp/server.test.js.map +0 -1
@@ -1,648 +0,0 @@
1
- /**
2
- * Hook Executor Tests
3
- */
4
- import { describe, it, expect, vi } from 'vitest';
5
- import { HookExecutor, createHookExecutor } from './executor.js';
6
- import os from 'os';
7
- import path from 'path';
8
- import fs from 'fs';
9
- // Basic context for tests
10
- const createTestContext = (overrides = {}) => ({
11
- repoRoot: os.tmpdir(),
12
- baseBranch: 'main',
13
- ...overrides,
14
- });
15
- describe('HookExecutor', () => {
16
- describe('constructor', () => {
17
- it('creates executor with empty config', () => {
18
- const executor = new HookExecutor();
19
- expect(executor.hasHook('post-worktree')).toBe(false);
20
- });
21
- it('creates executor with config', () => {
22
- const config = {
23
- 'post-worktree': 'echo "hello"',
24
- };
25
- const executor = new HookExecutor(config);
26
- expect(executor.hasHook('post-worktree')).toBe(true);
27
- });
28
- });
29
- describe('hasHook', () => {
30
- it('returns true for configured hooks', () => {
31
- const config = {
32
- 'post-worktree': 'echo "test"',
33
- 'pre-branch': 'echo "branch"',
34
- };
35
- const executor = new HookExecutor(config);
36
- expect(executor.hasHook('post-worktree')).toBe(true);
37
- expect(executor.hasHook('pre-branch')).toBe(true);
38
- expect(executor.hasHook('post-pr')).toBe(false);
39
- });
40
- });
41
- describe('getConfiguredHooks', () => {
42
- it('returns list of configured hooks', () => {
43
- const config = {
44
- 'post-worktree': 'echo "test"',
45
- 'pre-branch': 'echo "branch"',
46
- cleanup: 'echo "cleanup"',
47
- };
48
- const executor = new HookExecutor(config);
49
- const hooks = executor.getConfiguredHooks();
50
- expect(hooks).toHaveLength(3);
51
- expect(hooks).toContain('post-worktree');
52
- expect(hooks).toContain('pre-branch');
53
- expect(hooks).toContain('cleanup');
54
- });
55
- });
56
- describe('executeHook', () => {
57
- it('returns skipped result when hook not configured', async () => {
58
- const executor = new HookExecutor({});
59
- const context = createTestContext();
60
- const result = await executor.executeHook('post-worktree', context);
61
- expect(result.success).toBe(true);
62
- expect(result.skipped).toBe(true);
63
- expect(result.skipReason).toContain('No hook configured');
64
- });
65
- it('executes simple command hook', async () => {
66
- const config = {
67
- 'post-analyze': 'echo "test output"',
68
- };
69
- const executor = new HookExecutor(config);
70
- const context = createTestContext();
71
- const result = await executor.executeHook('post-analyze', context);
72
- expect(result.success).toBe(true);
73
- expect(result.output).toContain('test output');
74
- });
75
- it('executes multiple command hooks in sequence', async () => {
76
- const config = {
77
- 'post-analyze': ['echo "first"', 'echo "second"'],
78
- };
79
- const executor = new HookExecutor(config);
80
- const context = createTestContext();
81
- const result = await executor.executeHook('post-analyze', context);
82
- expect(result.success).toBe(true);
83
- expect(result.output).toContain('first');
84
- expect(result.output).toContain('second');
85
- });
86
- it('stops on first failing command in multiple hooks', async () => {
87
- const config = {
88
- 'post-analyze': ['echo "first"', 'exit 1', 'echo "third"'],
89
- };
90
- const executor = new HookExecutor(config);
91
- const context = createTestContext();
92
- const result = await executor.executeHook('post-analyze', context);
93
- expect(result.success).toBe(false);
94
- expect(result.output).toContain('first');
95
- expect(result.output).not.toContain('third');
96
- });
97
- it('expands template variables in command', async () => {
98
- const config = {
99
- 'post-branch': 'echo "Branch: {{BRANCH_NAME}}"',
100
- };
101
- const executor = new HookExecutor(config);
102
- const context = createTestContext({
103
- branchName: 'feat/test-branch',
104
- });
105
- const result = await executor.executeHook('post-branch', context);
106
- expect(result.success).toBe(true);
107
- expect(result.output).toContain('feat/test-branch');
108
- });
109
- it('sets environment variables from context', async () => {
110
- // Use a platform-appropriate command to echo env var
111
- const cmd = process.platform === 'win32' ? 'echo %WT_BRANCH_NAME%' : 'echo $WT_BRANCH_NAME';
112
- const config = {
113
- 'post-branch': cmd,
114
- };
115
- const executor = new HookExecutor(config);
116
- const context = createTestContext({
117
- branchName: 'feat/env-test',
118
- });
119
- const result = await executor.executeHook('post-branch', context);
120
- expect(result.success).toBe(true);
121
- expect(result.output).toContain('feat/env-test');
122
- });
123
- it('handles complex hook with condition (true)', async () => {
124
- // Create a temp file to test exists condition
125
- const tempFile = path.join(os.tmpdir(), 'test-exists.txt');
126
- fs.writeFileSync(tempFile, 'test');
127
- try {
128
- const config = {
129
- 'post-worktree': {
130
- command: 'echo "file exists"',
131
- if: 'exists:test-exists.txt',
132
- },
133
- };
134
- const executor = new HookExecutor(config);
135
- const context = createTestContext();
136
- const result = await executor.executeHook('post-worktree', context);
137
- expect(result.success).toBe(true);
138
- expect(result.skipped).toBeFalsy();
139
- expect(result.output).toContain('file exists');
140
- }
141
- finally {
142
- fs.unlinkSync(tempFile);
143
- }
144
- });
145
- it('handles complex hook with condition (false)', async () => {
146
- const config = {
147
- 'post-worktree': {
148
- command: 'echo "should not run"',
149
- if: 'exists:nonexistent-file-12345.txt',
150
- },
151
- };
152
- const executor = new HookExecutor(config);
153
- const context = createTestContext();
154
- const result = await executor.executeHook('post-worktree', context);
155
- expect(result.success).toBe(true);
156
- expect(result.skipped).toBe(true);
157
- expect(result.skipReason).toContain('Condition not met');
158
- });
159
- it('handles failOnError: false', async () => {
160
- const config = {
161
- 'post-analyze': {
162
- command: 'exit 1',
163
- failOnError: false,
164
- },
165
- };
166
- const executor = new HookExecutor(config);
167
- const context = createTestContext();
168
- const result = await executor.executeHook('post-analyze', context);
169
- // Should succeed because failOnError is false
170
- expect(result.success).toBe(true);
171
- expect(result.error).toContain('Non-fatal');
172
- });
173
- it('respects dry-run mode', async () => {
174
- const config = {
175
- 'post-worktree': 'rm -rf /',
176
- };
177
- const executor = new HookExecutor(config, { dryRun: true });
178
- const context = createTestContext();
179
- const result = await executor.executeHook('post-worktree', context);
180
- expect(result.success).toBe(true);
181
- expect(result.skipped).toBe(true);
182
- expect(result.skipReason).toBe('dry-run mode');
183
- expect(result.output).toContain('DRY RUN');
184
- });
185
- });
186
- describe('executeHooks', () => {
187
- it('executes multiple hooks in sequence', async () => {
188
- const config = {
189
- 'pre-branch': 'echo "pre"',
190
- 'post-branch': 'echo "post"',
191
- };
192
- const executor = new HookExecutor(config);
193
- const context = createTestContext();
194
- const results = await executor.executeHooks(['pre-branch', 'post-branch'], context);
195
- expect(results).toHaveLength(2);
196
- expect(results[0].hook).toBe('pre-branch');
197
- expect(results[0].success).toBe(true);
198
- expect(results[1].hook).toBe('post-branch');
199
- expect(results[1].success).toBe(true);
200
- });
201
- it('stops on first failure', async () => {
202
- const config = {
203
- 'pre-branch': 'exit 1',
204
- 'post-branch': 'echo "should not run"',
205
- };
206
- const executor = new HookExecutor(config);
207
- const context = createTestContext();
208
- const results = await executor.executeHooks(['pre-branch', 'post-branch'], context);
209
- // Executor stops after first failure, so only 1 result
210
- expect(results).toHaveLength(1);
211
- expect(results[0].success).toBe(false);
212
- expect(results[0].hook).toBe('pre-branch');
213
- });
214
- it('skips non-configured hooks', async () => {
215
- const config = {
216
- 'post-branch': 'echo "configured"',
217
- };
218
- const executor = new HookExecutor(config);
219
- const context = createTestContext();
220
- const results = await executor.executeHooks(['pre-branch', 'post-branch', 'post-pr'], context);
221
- expect(results).toHaveLength(3);
222
- expect(results[0].skipped).toBe(true);
223
- expect(results[1].success).toBe(true);
224
- expect(results[2].skipped).toBe(true);
225
- });
226
- });
227
- });
228
- describe('HookExecutor additional coverage', () => {
229
- describe('template variable expansion', () => {
230
- it('expands PR_NUMBER variable', async () => {
231
- const config = {
232
- 'post-pr': 'echo "PR: {{PR_NUMBER}}"',
233
- };
234
- const executor = new HookExecutor(config);
235
- const context = createTestContext({
236
- prNumber: 123,
237
- });
238
- const result = await executor.executeHook('post-pr', context);
239
- expect(result.success).toBe(true);
240
- expect(result.output).toContain('123');
241
- });
242
- it('expands PR_URL variable', async () => {
243
- const config = {
244
- 'post-pr': 'echo "URL: {{PR_URL}}"',
245
- };
246
- const executor = new HookExecutor(config);
247
- const context = createTestContext({
248
- prUrl: 'https://github.com/org/repo/pull/42',
249
- });
250
- const result = await executor.executeHook('post-pr', context);
251
- expect(result.success).toBe(true);
252
- expect(result.output).toContain('github.com');
253
- });
254
- it('expands WORKTREE_PATH variable', async () => {
255
- const config = {
256
- 'post-worktree': 'echo "Path: {{WORKTREE_PATH}}"',
257
- };
258
- const executor = new HookExecutor(config);
259
- const context = createTestContext({
260
- worktreePath: '/path/to/worktree',
261
- });
262
- const result = await executor.executeHook('post-worktree', context);
263
- expect(result.success).toBe(true);
264
- expect(result.output).toContain('/path/to/worktree');
265
- });
266
- it('expands DESCRIPTION variable', async () => {
267
- const config = {
268
- 'pre-analyze': 'echo "Desc: {{DESCRIPTION}}"',
269
- };
270
- const executor = new HookExecutor(config);
271
- const context = createTestContext({
272
- description: 'Test feature',
273
- });
274
- const result = await executor.executeHook('pre-analyze', context);
275
- expect(result.success).toBe(true);
276
- expect(result.output).toContain('Test feature');
277
- });
278
- it('expands SCENARIO and ACTION variables', async () => {
279
- const config = {
280
- 'post-analyze': 'echo "{{SCENARIO}} - {{ACTION}}"',
281
- };
282
- const executor = new HookExecutor(config);
283
- const context = createTestContext({
284
- scenario: 'main_clean_same',
285
- action: 'empty_commit',
286
- });
287
- const result = await executor.executeHook('post-analyze', context);
288
- expect(result.success).toBe(true);
289
- expect(result.output).toContain('main_clean_same');
290
- expect(result.output).toContain('empty_commit');
291
- });
292
- it('replaces unknown variables with empty string', async () => {
293
- const config = {
294
- 'pre-analyze': 'echo "Unknown: {{UNKNOWN_VAR}}"',
295
- };
296
- const executor = new HookExecutor(config);
297
- const context = createTestContext();
298
- const result = await executor.executeHook('pre-analyze', context);
299
- expect(result.success).toBe(true);
300
- expect(result.output).toContain('Unknown:');
301
- });
302
- });
303
- describe('condition evaluation', () => {
304
- it('evaluates not: condition (negation)', async () => {
305
- const config = {
306
- 'post-worktree': {
307
- command: 'echo "no file"',
308
- if: 'not:exists:nonexistent-file-xyz.txt',
309
- },
310
- };
311
- const executor = new HookExecutor(config);
312
- const context = createTestContext();
313
- const result = await executor.executeHook('post-worktree', context);
314
- // Should run because file doesn't exist, and we negate that
315
- expect(result.success).toBe(true);
316
- expect(result.skipped).toBeFalsy();
317
- expect(result.output).toContain('no file');
318
- });
319
- it('evaluates env: condition (true)', async () => {
320
- // PATH env var should always exist
321
- const config = {
322
- 'post-analyze': {
323
- command: 'echo "has PATH"',
324
- if: 'env:PATH',
325
- },
326
- };
327
- const executor = new HookExecutor(config);
328
- const context = createTestContext();
329
- const result = await executor.executeHook('post-analyze', context);
330
- expect(result.success).toBe(true);
331
- expect(result.skipped).toBeFalsy();
332
- });
333
- it('evaluates env: condition (false)', async () => {
334
- const config = {
335
- 'post-analyze': {
336
- command: 'echo "should not run"',
337
- if: 'env:NONEXISTENT_VAR_XYZ_ABC_123',
338
- },
339
- };
340
- const executor = new HookExecutor(config);
341
- const context = createTestContext();
342
- const result = await executor.executeHook('post-analyze', context);
343
- expect(result.success).toBe(true);
344
- expect(result.skipped).toBe(true);
345
- });
346
- it('evaluates has-changes condition (true)', async () => {
347
- const config = {
348
- 'post-analyze': {
349
- command: 'echo "has changes"',
350
- if: 'has-changes',
351
- },
352
- };
353
- const executor = new HookExecutor(config);
354
- const context = createTestContext({
355
- stagedFiles: ['file.ts'],
356
- });
357
- const result = await executor.executeHook('post-analyze', context);
358
- expect(result.success).toBe(true);
359
- expect(result.skipped).toBeFalsy();
360
- });
361
- it('evaluates has-changes condition (false)', async () => {
362
- const config = {
363
- 'post-analyze': {
364
- command: 'echo "no changes"',
365
- if: 'has-changes',
366
- },
367
- };
368
- const executor = new HookExecutor(config);
369
- const context = createTestContext({
370
- stagedFiles: [],
371
- unstagedFiles: [],
372
- });
373
- const result = await executor.executeHook('post-analyze', context);
374
- expect(result.success).toBe(true);
375
- expect(result.skipped).toBe(true);
376
- });
377
- it('evaluates has-staged condition (true)', async () => {
378
- const config = {
379
- 'pre-commit': {
380
- command: 'echo "staged files"',
381
- if: 'has-staged',
382
- },
383
- };
384
- const executor = new HookExecutor(config);
385
- const context = createTestContext({
386
- stagedFiles: ['file.ts'],
387
- });
388
- const result = await executor.executeHook('pre-commit', context);
389
- expect(result.success).toBe(true);
390
- expect(result.skipped).toBeFalsy();
391
- });
392
- it('evaluates has-staged condition (false)', async () => {
393
- const config = {
394
- 'pre-commit': {
395
- command: 'echo "no staged"',
396
- if: 'has-staged',
397
- },
398
- };
399
- const executor = new HookExecutor(config);
400
- const context = createTestContext({
401
- stagedFiles: [],
402
- });
403
- const result = await executor.executeHook('pre-commit', context);
404
- expect(result.success).toBe(true);
405
- expect(result.skipped).toBe(true);
406
- });
407
- it('evaluates scenario: condition (match)', async () => {
408
- const config = {
409
- 'post-analyze': {
410
- command: 'echo "clean main"',
411
- if: 'scenario:main_clean_same',
412
- },
413
- };
414
- const executor = new HookExecutor(config);
415
- const context = createTestContext({
416
- scenario: 'main_clean_same',
417
- });
418
- const result = await executor.executeHook('post-analyze', context);
419
- expect(result.success).toBe(true);
420
- expect(result.skipped).toBeFalsy();
421
- });
422
- it('evaluates scenario: condition (no match)', async () => {
423
- const config = {
424
- 'post-analyze': {
425
- command: 'echo "clean main"',
426
- if: 'scenario:main_clean_same',
427
- },
428
- };
429
- const executor = new HookExecutor(config);
430
- const context = createTestContext({
431
- scenario: 'branch_with_changes',
432
- });
433
- const result = await executor.executeHook('post-analyze', context);
434
- expect(result.success).toBe(true);
435
- expect(result.skipped).toBe(true);
436
- });
437
- it('unknown condition defaults to true', async () => {
438
- const config = {
439
- 'post-analyze': {
440
- command: 'echo "runs anyway"',
441
- if: 'unknown-condition-xyz',
442
- },
443
- };
444
- const executor = new HookExecutor(config);
445
- const context = createTestContext();
446
- const result = await executor.executeHook('post-analyze', context);
447
- expect(result.success).toBe(true);
448
- expect(result.skipped).toBeFalsy();
449
- });
450
- });
451
- describe('complex hook script execution', () => {
452
- it('executes JavaScript file script', async () => {
453
- // Use a unique filename to avoid conflicts
454
- const scriptPath = path.join(os.tmpdir(), `test-hook-${Date.now()}.js`);
455
- fs.writeFileSync(scriptPath, 'console.log("JS hook executed")');
456
- try {
457
- const config = {
458
- 'post-worktree': {
459
- script: scriptPath,
460
- },
461
- };
462
- const executor = new HookExecutor(config);
463
- const context = createTestContext();
464
- const result = await executor.executeHook('post-worktree', context);
465
- // On Windows CI, Node.js execution in temp directories can be unreliable
466
- // Skip assertion if the failure is due to Windows-specific path/execution issues
467
- if (!result.success && process.platform === 'win32') {
468
- // Accept the result on Windows if it's a path/command execution issue
469
- expect(result.error).toBeDefined();
470
- }
471
- else {
472
- expect(result.success).toBe(true);
473
- expect(result.output).toContain('JS hook executed');
474
- }
475
- }
476
- finally {
477
- if (fs.existsSync(scriptPath)) {
478
- fs.unlinkSync(scriptPath);
479
- }
480
- }
481
- });
482
- it('returns error when script not found', async () => {
483
- const config = {
484
- 'post-worktree': {
485
- script: '/nonexistent/path/hook.js',
486
- },
487
- };
488
- const executor = new HookExecutor(config);
489
- const context = createTestContext();
490
- const result = await executor.executeHook('post-worktree', context);
491
- expect(result.success).toBe(true); // failOnError defaults to false
492
- expect(result.error).toContain('Script not found');
493
- });
494
- it('returns error when script not found with failOnError: true', async () => {
495
- const config = {
496
- 'post-worktree': {
497
- script: '/nonexistent/path/hook.js',
498
- failOnError: true,
499
- },
500
- };
501
- const executor = new HookExecutor(config);
502
- const context = createTestContext();
503
- const result = await executor.executeHook('post-worktree', context);
504
- expect(result.success).toBe(false);
505
- expect(result.error).toContain('Script not found');
506
- });
507
- it('returns error when neither command nor script specified', async () => {
508
- const config = {
509
- 'post-analyze': {
510
- if: 'has-changes',
511
- // Neither command nor script
512
- },
513
- };
514
- const executor = new HookExecutor(config);
515
- const context = createTestContext({
516
- stagedFiles: ['file.ts'],
517
- });
518
- const result = await executor.executeHook('post-analyze', context);
519
- expect(result.success).toBe(false);
520
- expect(result.error).toContain('must specify either');
521
- });
522
- it('handles shell script (.sh) files', async () => {
523
- // Skip on Windows
524
- if (process.platform === 'win32') {
525
- return;
526
- }
527
- const scriptPath = path.join(os.tmpdir(), 'test-hook.sh');
528
- fs.writeFileSync(scriptPath, '#!/bin/sh\necho "Shell hook"');
529
- fs.chmodSync(scriptPath, '755');
530
- try {
531
- const config = {
532
- 'post-worktree': {
533
- script: scriptPath,
534
- },
535
- };
536
- const executor = new HookExecutor(config);
537
- const context = createTestContext();
538
- const result = await executor.executeHook('post-worktree', context);
539
- expect(result.success).toBe(true);
540
- expect(result.output).toContain('Shell hook');
541
- }
542
- finally {
543
- fs.unlinkSync(scriptPath);
544
- }
545
- });
546
- });
547
- describe('complex hook dry-run mode', () => {
548
- it('returns dry-run result for complex hook', async () => {
549
- const config = {
550
- 'post-worktree': {
551
- command: 'rm -rf /',
552
- if: 'has-changes',
553
- },
554
- };
555
- const executor = new HookExecutor(config, { dryRun: true });
556
- const context = createTestContext({
557
- stagedFiles: ['file.ts'],
558
- });
559
- const result = await executor.executeHook('post-worktree', context);
560
- expect(result.success).toBe(true);
561
- expect(result.skipped).toBe(true);
562
- expect(result.output).toContain('DRY RUN');
563
- });
564
- it('returns dry-run result for multiple commands', async () => {
565
- const config = {
566
- 'post-analyze': ['echo "first"', 'echo "second"'],
567
- };
568
- const executor = new HookExecutor(config, { dryRun: true });
569
- const context = createTestContext();
570
- const result = await executor.executeHook('post-analyze', context);
571
- expect(result.success).toBe(true);
572
- expect(result.skipped).toBe(true);
573
- expect(result.output).toContain('DRY RUN');
574
- expect(result.output).toContain('first');
575
- expect(result.output).toContain('second');
576
- });
577
- });
578
- describe('verbose mode', () => {
579
- it('logs hook execution in verbose mode', async () => {
580
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
581
- const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
582
- try {
583
- const config = {
584
- 'post-analyze': 'echo "verbose test"',
585
- };
586
- const executor = new HookExecutor(config, { verbose: true });
587
- const context = createTestContext();
588
- await executor.executeHook('post-analyze', context);
589
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Executing hook'));
590
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('completed'));
591
- }
592
- finally {
593
- consoleSpy.mockRestore();
594
- consoleErrorSpy.mockRestore();
595
- }
596
- });
597
- it('logs errors in verbose mode when hook fails', async () => {
598
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
599
- const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
600
- try {
601
- const config = {
602
- 'post-analyze': 'exit 1',
603
- };
604
- const executor = new HookExecutor(config, { verbose: true });
605
- const context = createTestContext();
606
- await executor.executeHook('post-analyze', context);
607
- expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('failed'));
608
- }
609
- finally {
610
- consoleSpy.mockRestore();
611
- consoleErrorSpy.mockRestore();
612
- }
613
- });
614
- });
615
- describe('complex hook with custom env', () => {
616
- it('passes custom environment variables', async () => {
617
- const cmd = process.platform === 'win32' ? 'echo %CUSTOM_VAR%' : 'echo $CUSTOM_VAR';
618
- const config = {
619
- 'post-analyze': {
620
- command: cmd,
621
- env: {
622
- CUSTOM_VAR: 'custom_value',
623
- },
624
- },
625
- };
626
- const executor = new HookExecutor(config);
627
- const context = createTestContext();
628
- const result = await executor.executeHook('post-analyze', context);
629
- expect(result.success).toBe(true);
630
- expect(result.output).toContain('custom_value');
631
- });
632
- });
633
- });
634
- describe('createHookExecutor', () => {
635
- it('creates executor with config', () => {
636
- const config = {
637
- 'post-worktree': 'echo "test"',
638
- };
639
- const executor = createHookExecutor(config);
640
- expect(executor).toBeInstanceOf(HookExecutor);
641
- expect(executor.hasHook('post-worktree')).toBe(true);
642
- });
643
- it('creates executor with options', () => {
644
- const executor = createHookExecutor({}, { dryRun: true, verbose: true });
645
- expect(executor).toBeInstanceOf(HookExecutor);
646
- });
647
- });
648
- //# sourceMappingURL=executor.test.js.map