@camaradesuk/git-worktree-tools 1.10.0 → 1.11.0

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