@camaradesuk/git-worktree-tools 1.10.0 → 1.12.0

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