@camaradesuk/git-worktree-tools 1.8.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) hide show
  1. package/README.md +48 -27
  2. package/dist/cli/cleanpr.js +74 -53
  3. package/dist/cli/cleanpr.js.map +1 -1
  4. package/dist/cli/cleanpr.test.js +2 -0
  5. package/dist/cli/cleanpr.test.js.map +1 -1
  6. package/dist/cli/lswt.js +32 -56
  7. package/dist/cli/lswt.js.map +1 -1
  8. package/dist/cli/lswt.test.js +17 -27
  9. package/dist/cli/lswt.test.js.map +1 -1
  10. package/dist/cli/newpr.d.ts +13 -1
  11. package/dist/cli/newpr.d.ts.map +1 -1
  12. package/dist/cli/newpr.js +350 -151
  13. package/dist/cli/newpr.js.map +1 -1
  14. package/dist/cli/newpr.test.js +314 -5
  15. package/dist/cli/newpr.test.js.map +1 -1
  16. package/dist/cli/prs.d.ts +3 -10
  17. package/dist/cli/prs.d.ts.map +1 -1
  18. package/dist/cli/prs.js +6 -168
  19. package/dist/cli/prs.js.map +1 -1
  20. package/dist/cli/prs.test.js +55 -0
  21. package/dist/cli/prs.test.js.map +1 -1
  22. package/dist/cli/wt/clean.d.ts +6 -2
  23. package/dist/cli/wt/clean.d.ts.map +1 -1
  24. package/dist/cli/wt/clean.js +401 -20
  25. package/dist/cli/wt/clean.js.map +1 -1
  26. package/dist/cli/wt/clean.test.d.ts +8 -0
  27. package/dist/cli/wt/clean.test.d.ts.map +1 -0
  28. package/dist/cli/wt/clean.test.js +624 -0
  29. package/dist/cli/wt/clean.test.js.map +1 -0
  30. package/dist/cli/wt/completion.d.ts +3 -0
  31. package/dist/cli/wt/completion.d.ts.map +1 -1
  32. package/dist/cli/wt/completion.js +80 -9
  33. package/dist/cli/wt/completion.js.map +1 -1
  34. package/dist/cli/wt/completion.test.js +102 -0
  35. package/dist/cli/wt/completion.test.js.map +1 -1
  36. package/dist/cli/wt/config.d.ts +3 -1
  37. package/dist/cli/wt/config.d.ts.map +1 -1
  38. package/dist/cli/wt/config.js +323 -32
  39. package/dist/cli/wt/config.js.map +1 -1
  40. package/dist/cli/wt/config.test.d.ts +2 -0
  41. package/dist/cli/wt/config.test.d.ts.map +1 -1
  42. package/dist/cli/wt/config.test.js +206 -26
  43. package/dist/cli/wt/config.test.js.map +1 -1
  44. package/dist/cli/wt/interactive-menu.d.ts +2 -0
  45. package/dist/cli/wt/interactive-menu.d.ts.map +1 -1
  46. package/dist/cli/wt/interactive-menu.js +346 -73
  47. package/dist/cli/wt/interactive-menu.js.map +1 -1
  48. package/dist/cli/wt/interactive-menu.test.d.ts +4 -2
  49. package/dist/cli/wt/interactive-menu.test.d.ts.map +1 -1
  50. package/dist/cli/wt/interactive-menu.test.js +383 -323
  51. package/dist/cli/wt/interactive-menu.test.js.map +1 -1
  52. package/dist/cli/wt/link.d.ts +3 -1
  53. package/dist/cli/wt/link.d.ts.map +1 -1
  54. package/dist/cli/wt/link.js +125 -38
  55. package/dist/cli/wt/link.js.map +1 -1
  56. package/dist/cli/wt/list.d.ts +4 -1
  57. package/dist/cli/wt/list.d.ts.map +1 -1
  58. package/dist/cli/wt/list.js +85 -16
  59. package/dist/cli/wt/list.js.map +1 -1
  60. package/dist/cli/wt/list.test.d.ts +10 -0
  61. package/dist/cli/wt/list.test.d.ts.map +1 -0
  62. package/dist/cli/wt/list.test.js +157 -0
  63. package/dist/cli/wt/list.test.js.map +1 -0
  64. package/dist/cli/wt/new.d.ts +8 -2
  65. package/dist/cli/wt/new.d.ts.map +1 -1
  66. package/dist/cli/wt/new.js +91 -46
  67. package/dist/cli/wt/new.js.map +1 -1
  68. package/dist/cli/wt/prs.d.ts +2 -1
  69. package/dist/cli/wt/prs.d.ts.map +1 -1
  70. package/dist/cli/wt/prs.js +3 -164
  71. package/dist/cli/wt/prs.js.map +1 -1
  72. package/dist/cli/wt/run-command.d.ts +4 -2
  73. package/dist/cli/wt/run-command.d.ts.map +1 -1
  74. package/dist/cli/wt/run-command.js +6 -4
  75. package/dist/cli/wt/run-command.js.map +1 -1
  76. package/dist/cli/wt/state.d.ts +3 -1
  77. package/dist/cli/wt/state.d.ts.map +1 -1
  78. package/dist/cli/wt/state.js +74 -10
  79. package/dist/cli/wt/state.js.map +1 -1
  80. package/dist/cli/wt/state.test.d.ts +9 -0
  81. package/dist/cli/wt/state.test.d.ts.map +1 -0
  82. package/dist/cli/wt/state.test.js +127 -0
  83. package/dist/cli/wt/state.test.js.map +1 -0
  84. package/dist/cli/wt/wt.test.d.ts +2 -2
  85. package/dist/cli/wt/wt.test.js +430 -212
  86. package/dist/cli/wt/wt.test.js.map +1 -1
  87. package/dist/cli/wt.d.ts.map +1 -1
  88. package/dist/cli/wt.js +50 -36
  89. package/dist/cli/wt.js.map +1 -1
  90. package/dist/cli/wt.unit.test.js +16 -38
  91. package/dist/cli/wt.unit.test.js.map +1 -1
  92. package/dist/cli/wtconfig.d.ts +1 -0
  93. package/dist/cli/wtconfig.d.ts.map +1 -1
  94. package/dist/cli/wtconfig.js +213 -21
  95. package/dist/cli/wtconfig.js.map +1 -1
  96. package/dist/cli/wtconfig.test.js +3 -0
  97. package/dist/cli/wtconfig.test.js.map +1 -1
  98. package/dist/cli/wtlink.js +116 -73
  99. package/dist/cli/wtlink.js.map +1 -1
  100. package/dist/cli/wtstate.js +21 -2
  101. package/dist/cli/wtstate.js.map +1 -1
  102. package/dist/e2e/wt/interactive-menu.e2e.test.js +17 -17
  103. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +1 -1
  104. package/dist/lib/ai/types.d.ts +12 -0
  105. package/dist/lib/ai/types.d.ts.map +1 -1
  106. package/dist/lib/ai/types.js.map +1 -1
  107. package/dist/lib/cleanpr/args.d.ts.map +1 -1
  108. package/dist/lib/cleanpr/args.js +20 -0
  109. package/dist/lib/cleanpr/args.js.map +1 -1
  110. package/dist/lib/cleanpr/types.d.ts +6 -0
  111. package/dist/lib/cleanpr/types.d.ts.map +1 -1
  112. package/dist/lib/cleanpr/worktree-info.d.ts.map +1 -1
  113. package/dist/lib/cleanpr/worktree-info.js +1 -6
  114. package/dist/lib/cleanpr/worktree-info.js.map +1 -1
  115. package/dist/lib/cleanpr/worktree-info.test.js +10 -13
  116. package/dist/lib/cleanpr/worktree-info.test.js.map +1 -1
  117. package/dist/lib/colors.d.ts +5 -0
  118. package/dist/lib/colors.d.ts.map +1 -1
  119. package/dist/lib/colors.js +13 -6
  120. package/dist/lib/colors.js.map +1 -1
  121. package/dist/lib/config-editor.d.ts.map +1 -1
  122. package/dist/lib/config-editor.js.map +1 -1
  123. package/dist/lib/config-migration/detector.d.ts +25 -0
  124. package/dist/lib/config-migration/detector.d.ts.map +1 -0
  125. package/dist/lib/config-migration/detector.js +372 -0
  126. package/dist/lib/config-migration/detector.js.map +1 -0
  127. package/dist/lib/config-migration/detector.test.d.ts +5 -0
  128. package/dist/lib/config-migration/detector.test.d.ts.map +1 -0
  129. package/dist/lib/config-migration/detector.test.js +201 -0
  130. package/dist/lib/config-migration/detector.test.js.map +1 -0
  131. package/dist/lib/config-migration/index.d.ts +29 -0
  132. package/dist/lib/config-migration/index.d.ts.map +1 -0
  133. package/dist/lib/config-migration/index.js +33 -0
  134. package/dist/lib/config-migration/index.js.map +1 -0
  135. package/dist/lib/config-migration/reporter.d.ts +53 -0
  136. package/dist/lib/config-migration/reporter.d.ts.map +1 -0
  137. package/dist/lib/config-migration/reporter.js +257 -0
  138. package/dist/lib/config-migration/reporter.js.map +1 -0
  139. package/dist/lib/config-migration/reporter.test.d.ts +5 -0
  140. package/dist/lib/config-migration/reporter.test.d.ts.map +1 -0
  141. package/dist/lib/config-migration/reporter.test.js +305 -0
  142. package/dist/lib/config-migration/reporter.test.js.map +1 -0
  143. package/dist/lib/config-migration/runner.d.ts +46 -0
  144. package/dist/lib/config-migration/runner.d.ts.map +1 -0
  145. package/dist/lib/config-migration/runner.js +364 -0
  146. package/dist/lib/config-migration/runner.js.map +1 -0
  147. package/dist/lib/config-migration/runner.test.d.ts +5 -0
  148. package/dist/lib/config-migration/runner.test.d.ts.map +1 -0
  149. package/dist/lib/config-migration/runner.test.js +235 -0
  150. package/dist/lib/config-migration/runner.test.js.map +1 -0
  151. package/dist/lib/config-migration/types.d.ts +120 -0
  152. package/dist/lib/config-migration/types.d.ts.map +1 -0
  153. package/dist/lib/config-migration/types.js +70 -0
  154. package/dist/lib/config-migration/types.js.map +1 -0
  155. package/dist/lib/config-validation.d.ts.map +1 -1
  156. package/dist/lib/config-validation.js +6 -0
  157. package/dist/lib/config-validation.js.map +1 -1
  158. package/dist/lib/config-validation.test.js +25 -0
  159. package/dist/lib/config-validation.test.js.map +1 -1
  160. package/dist/lib/config.d.ts +31 -7
  161. package/dist/lib/config.d.ts.map +1 -1
  162. package/dist/lib/config.js +2 -0
  163. package/dist/lib/config.js.map +1 -1
  164. package/dist/lib/config.test.js +3 -15
  165. package/dist/lib/config.test.js.map +1 -1
  166. package/dist/lib/constants.d.ts +12 -4
  167. package/dist/lib/constants.d.ts.map +1 -1
  168. package/dist/lib/constants.js +24 -5
  169. package/dist/lib/constants.js.map +1 -1
  170. package/dist/lib/constants.test.js +88 -29
  171. package/dist/lib/constants.test.js.map +1 -1
  172. package/dist/lib/deprecation.d.ts +18 -0
  173. package/dist/lib/deprecation.d.ts.map +1 -0
  174. package/dist/lib/deprecation.js +28 -0
  175. package/dist/lib/deprecation.js.map +1 -0
  176. package/dist/lib/deprecation.test.d.ts +2 -0
  177. package/dist/lib/deprecation.test.d.ts.map +1 -0
  178. package/dist/lib/deprecation.test.js +71 -0
  179. package/dist/lib/deprecation.test.js.map +1 -0
  180. package/dist/lib/hooks/confirmation.d.ts +49 -0
  181. package/dist/lib/hooks/confirmation.d.ts.map +1 -0
  182. package/dist/lib/hooks/confirmation.js +147 -0
  183. package/dist/lib/hooks/confirmation.js.map +1 -0
  184. package/dist/lib/hooks/confirmation.test.d.ts +7 -0
  185. package/dist/lib/hooks/confirmation.test.d.ts.map +1 -0
  186. package/dist/lib/hooks/confirmation.test.js +300 -0
  187. package/dist/lib/hooks/confirmation.test.js.map +1 -0
  188. package/dist/lib/hooks/executor.d.ts +16 -1
  189. package/dist/lib/hooks/executor.d.ts.map +1 -1
  190. package/dist/lib/hooks/executor.js +53 -4
  191. package/dist/lib/hooks/executor.js.map +1 -1
  192. package/dist/lib/hooks/index.d.ts +4 -2
  193. package/dist/lib/hooks/index.d.ts.map +1 -1
  194. package/dist/lib/hooks/index.js +3 -2
  195. package/dist/lib/hooks/index.js.map +1 -1
  196. package/dist/lib/hooks/types.d.ts +16 -0
  197. package/dist/lib/hooks/types.d.ts.map +1 -1
  198. package/dist/lib/hooks/types.js +12 -0
  199. package/dist/lib/hooks/types.js.map +1 -1
  200. package/dist/lib/logger.d.ts +40 -155
  201. package/dist/lib/logger.d.ts.map +1 -1
  202. package/dist/lib/logger.js +349 -420
  203. package/dist/lib/logger.js.map +1 -1
  204. package/dist/lib/logger.test.d.ts +10 -1
  205. package/dist/lib/logger.test.d.ts.map +1 -1
  206. package/dist/lib/logger.test.js +658 -258
  207. package/dist/lib/logger.test.js.map +1 -1
  208. package/dist/lib/lswt/action-executors.d.ts +2 -0
  209. package/dist/lib/lswt/action-executors.d.ts.map +1 -1
  210. package/dist/lib/lswt/action-executors.js +4 -3
  211. package/dist/lib/lswt/action-executors.js.map +1 -1
  212. package/dist/lib/lswt/action-executors.test.js +7 -0
  213. package/dist/lib/lswt/action-executors.test.js.map +1 -1
  214. package/dist/lib/lswt/args.d.ts.map +1 -1
  215. package/dist/lib/lswt/args.js +15 -1
  216. package/dist/lib/lswt/args.js.map +1 -1
  217. package/dist/lib/lswt/environment.d.ts +21 -2
  218. package/dist/lib/lswt/environment.d.ts.map +1 -1
  219. package/dist/lib/lswt/environment.js +73 -32
  220. package/dist/lib/lswt/environment.js.map +1 -1
  221. package/dist/lib/lswt/environment.test.js +79 -1
  222. package/dist/lib/lswt/environment.test.js.map +1 -1
  223. package/dist/lib/lswt/index.d.ts +1 -0
  224. package/dist/lib/lswt/index.d.ts.map +1 -1
  225. package/dist/lib/lswt/index.js +2 -0
  226. package/dist/lib/lswt/index.js.map +1 -1
  227. package/dist/lib/lswt/table.d.ts +15 -0
  228. package/dist/lib/lswt/table.d.ts.map +1 -0
  229. package/dist/lib/lswt/table.js +61 -0
  230. package/dist/lib/lswt/table.js.map +1 -0
  231. package/dist/lib/lswt/table.test.d.ts +5 -0
  232. package/dist/lib/lswt/table.test.d.ts.map +1 -0
  233. package/dist/lib/lswt/table.test.js +262 -0
  234. package/dist/lib/lswt/table.test.js.map +1 -0
  235. package/dist/lib/lswt/types.d.ts +4 -0
  236. package/dist/lib/lswt/types.d.ts.map +1 -1
  237. package/dist/lib/lswt/worktree-info.d.ts.map +1 -1
  238. package/dist/lib/lswt/worktree-info.js +1 -6
  239. package/dist/lib/lswt/worktree-info.js.map +1 -1
  240. package/dist/lib/lswt/worktree-info.test.js +5 -17
  241. package/dist/lib/lswt/worktree-info.test.js.map +1 -1
  242. package/dist/lib/newpr/args.d.ts.map +1 -1
  243. package/dist/lib/newpr/args.js +36 -1
  244. package/dist/lib/newpr/args.js.map +1 -1
  245. package/dist/lib/newpr/hook-runner.d.ts +11 -0
  246. package/dist/lib/newpr/hook-runner.d.ts.map +1 -1
  247. package/dist/lib/newpr/hook-runner.js +49 -1
  248. package/dist/lib/newpr/hook-runner.js.map +1 -1
  249. package/dist/lib/newpr/hook-runner.test.js +121 -0
  250. package/dist/lib/newpr/hook-runner.test.js.map +1 -1
  251. package/dist/lib/newpr/plan-generator.d.ts +121 -0
  252. package/dist/lib/newpr/plan-generator.d.ts.map +1 -0
  253. package/dist/lib/newpr/plan-generator.js +185 -0
  254. package/dist/lib/newpr/plan-generator.js.map +1 -0
  255. package/dist/lib/newpr/plan-generator.test.d.ts +7 -0
  256. package/dist/lib/newpr/plan-generator.test.d.ts.map +1 -0
  257. package/dist/lib/newpr/plan-generator.test.js +387 -0
  258. package/dist/lib/newpr/plan-generator.test.js.map +1 -0
  259. package/dist/lib/newpr/types.d.ts +12 -0
  260. package/dist/lib/newpr/types.d.ts.map +1 -1
  261. package/dist/lib/prs/actions.d.ts +5 -1
  262. package/dist/lib/prs/actions.d.ts.map +1 -1
  263. package/dist/lib/prs/actions.js +12 -10
  264. package/dist/lib/prs/actions.js.map +1 -1
  265. package/dist/lib/prs/actions.test.js +48 -5
  266. package/dist/lib/prs/actions.test.js.map +1 -1
  267. package/dist/lib/prs/command.d.ts +21 -0
  268. package/dist/lib/prs/command.d.ts.map +1 -0
  269. package/dist/lib/prs/command.js +175 -0
  270. package/dist/lib/prs/command.js.map +1 -0
  271. package/dist/lib/prs/command.test.d.ts +11 -0
  272. package/dist/lib/prs/command.test.d.ts.map +1 -0
  273. package/dist/lib/prs/command.test.js +409 -0
  274. package/dist/lib/prs/command.test.js.map +1 -0
  275. package/dist/lib/prs/interactive.d.ts.map +1 -1
  276. package/dist/lib/prs/interactive.js +15 -2
  277. package/dist/lib/prs/interactive.js.map +1 -1
  278. package/dist/lib/prs/interactive.test.js +153 -0
  279. package/dist/lib/prs/interactive.test.js.map +1 -1
  280. package/dist/lib/prs/types.d.ts +15 -0
  281. package/dist/lib/prs/types.d.ts.map +1 -1
  282. package/dist/lib/ui/error.d.ts +31 -0
  283. package/dist/lib/ui/error.d.ts.map +1 -0
  284. package/dist/lib/ui/error.js +47 -0
  285. package/dist/lib/ui/error.js.map +1 -0
  286. package/dist/lib/ui/error.test.d.ts +2 -0
  287. package/dist/lib/ui/error.test.d.ts.map +1 -0
  288. package/dist/lib/ui/error.test.js +143 -0
  289. package/dist/lib/ui/error.test.js.map +1 -0
  290. package/dist/lib/ui/index.d.ts +15 -0
  291. package/dist/lib/ui/index.d.ts.map +1 -0
  292. package/dist/lib/ui/index.js +19 -0
  293. package/dist/lib/ui/index.js.map +1 -0
  294. package/dist/lib/ui/output.d.ts +18 -0
  295. package/dist/lib/ui/output.d.ts.map +1 -0
  296. package/dist/lib/ui/output.js +31 -0
  297. package/dist/lib/ui/output.js.map +1 -0
  298. package/dist/lib/ui/output.test.d.ts +2 -0
  299. package/dist/lib/ui/output.test.d.ts.map +1 -0
  300. package/dist/lib/ui/output.test.js +59 -0
  301. package/dist/lib/ui/output.test.js.map +1 -0
  302. package/dist/lib/ui/spinner.d.ts +10 -0
  303. package/dist/lib/ui/spinner.d.ts.map +1 -0
  304. package/dist/lib/ui/spinner.js +10 -0
  305. package/dist/lib/ui/spinner.js.map +1 -0
  306. package/dist/lib/ui/status.d.ts +65 -0
  307. package/dist/lib/ui/status.d.ts.map +1 -0
  308. package/dist/lib/ui/status.js +100 -0
  309. package/dist/lib/ui/status.js.map +1 -0
  310. package/dist/lib/ui/status.test.d.ts +2 -0
  311. package/dist/lib/ui/status.test.d.ts.map +1 -0
  312. package/dist/lib/ui/status.test.js +158 -0
  313. package/dist/lib/ui/status.test.js.map +1 -0
  314. package/dist/lib/ui/table.d.ts +39 -0
  315. package/dist/lib/ui/table.d.ts.map +1 -0
  316. package/dist/lib/ui/table.js +45 -0
  317. package/dist/lib/ui/table.js.map +1 -0
  318. package/dist/lib/ui/table.test.d.ts +2 -0
  319. package/dist/lib/ui/table.test.d.ts.map +1 -0
  320. package/dist/lib/ui/table.test.js +115 -0
  321. package/dist/lib/ui/table.test.js.map +1 -0
  322. package/dist/lib/ui/theme.d.ts +34 -0
  323. package/dist/lib/ui/theme.d.ts.map +1 -0
  324. package/dist/lib/ui/theme.js +37 -0
  325. package/dist/lib/ui/theme.js.map +1 -0
  326. package/dist/lib/ui/theme.test.d.ts +2 -0
  327. package/dist/lib/ui/theme.test.d.ts.map +1 -0
  328. package/dist/lib/ui/theme.test.js +76 -0
  329. package/dist/lib/ui/theme.test.js.map +1 -0
  330. package/dist/lib/wtconfig/environment.d.ts +18 -1
  331. package/dist/lib/wtconfig/environment.d.ts.map +1 -1
  332. package/dist/lib/wtconfig/environment.js +60 -24
  333. package/dist/lib/wtconfig/environment.js.map +1 -1
  334. package/dist/lib/wtconfig/environment.test.js +45 -1
  335. package/dist/lib/wtconfig/environment.test.js.map +1 -1
  336. package/dist/lib/wtlink/config-manifest.test.js +26 -0
  337. package/dist/lib/wtlink/config-manifest.test.js.map +1 -1
  338. package/dist/lib/wtlink/link-configs.js +7 -7
  339. package/dist/lib/wtlink/link-configs.js.map +1 -1
  340. package/dist/lib/wtlink/validate-manifest.d.ts.map +1 -1
  341. package/dist/lib/wtlink/validate-manifest.js +5 -5
  342. package/dist/lib/wtlink/validate-manifest.js.map +1 -1
  343. package/dist/lib/wtstate/args.d.ts.map +1 -1
  344. package/dist/lib/wtstate/args.js +2 -0
  345. package/dist/lib/wtstate/args.js.map +1 -1
  346. package/dist/mcp/server.d.ts +2 -1
  347. package/dist/mcp/server.d.ts.map +1 -1
  348. package/dist/mcp/server.js +264 -44
  349. package/dist/mcp/server.js.map +1 -1
  350. package/dist/mcp/server.test.js +111 -0
  351. package/dist/mcp/server.test.js.map +1 -1
  352. package/package.json +3 -1
  353. package/schemas/worktreerc.schema.json +23 -0
@@ -0,0 +1,364 @@
1
+ /**
2
+ * Config Migration Runner
3
+ *
4
+ * Executes migration actions with:
5
+ * - Atomic writes (temp file + rename)
6
+ * - Backup creation before modifications
7
+ * - Rollback on failure
8
+ * - Legacy file merging
9
+ */
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import { getSchemaUrl } from '../global-config.js';
13
+ import { parseManifest } from '../wtlink/link-configs.js';
14
+ import { validateConfig } from '../config-validation.js';
15
+ import { logger } from '../logger.js';
16
+ import { BACKUP_DIRECTORY, CURRENT_CONFIG_VERSION, } from './types.js';
17
+ /**
18
+ * Normalize a file path for consistent comparison
19
+ */
20
+ function normalizePath(filePath) {
21
+ return filePath.replace(/\\/g, '/').replace(/^\.\//, '');
22
+ }
23
+ /**
24
+ * Merge wtlink configurations from existing config and legacy file
25
+ * Uses "enabled wins" conflict resolution
26
+ */
27
+ export function mergeWtlinkConfigs(existing, legacy) {
28
+ const enabledSet = new Set();
29
+ const disabledSet = new Set();
30
+ const conflicts = [];
31
+ // Add existing entries
32
+ for (const file of existing?.enabled ?? []) {
33
+ enabledSet.add(normalizePath(file));
34
+ }
35
+ for (const file of existing?.disabled ?? []) {
36
+ disabledSet.add(normalizePath(file));
37
+ }
38
+ // Merge legacy entries
39
+ for (const file of legacy.enabled) {
40
+ const norm = normalizePath(file);
41
+ if (disabledSet.has(norm)) {
42
+ // Conflict: file is disabled in config but enabled in legacy
43
+ conflicts.push(`${file}: enabled in .wtlinkrc but disabled in .worktreerc`);
44
+ // Resolution: enabled wins (more recent intent)
45
+ disabledSet.delete(norm);
46
+ }
47
+ enabledSet.add(norm);
48
+ }
49
+ for (const file of legacy.disabled) {
50
+ const norm = normalizePath(file);
51
+ if (!enabledSet.has(norm)) {
52
+ disabledSet.add(norm);
53
+ }
54
+ // If already enabled, skip (enabled takes precedence)
55
+ }
56
+ return {
57
+ enabled: Array.from(enabledSet).sort(),
58
+ disabled: Array.from(disabledSet).sort(),
59
+ conflicts,
60
+ };
61
+ }
62
+ /**
63
+ * Create a backup of the current config file
64
+ *
65
+ * @param configPath - Path to the config file to backup
66
+ * @param repoRoot - Repository root for backup directory
67
+ * @returns Path to the backup file
68
+ */
69
+ export function createConfigBackup(configPath, repoRoot) {
70
+ const backupDir = path.join(repoRoot, BACKUP_DIRECTORY);
71
+ // Create backup directory if it doesn't exist
72
+ if (!fs.existsSync(backupDir)) {
73
+ fs.mkdirSync(backupDir, { recursive: true });
74
+ logger.debug(`Created backup directory: ${backupDir}`);
75
+ }
76
+ const timestamp = Date.now();
77
+ // Add random suffix to ensure uniqueness even in same millisecond
78
+ const randomSuffix = Math.random().toString(36).slice(2, 8);
79
+ const configName = path.basename(configPath);
80
+ const backupName = `${configName}.backup.${timestamp}.${randomSuffix}`;
81
+ const backupPath = path.join(backupDir, backupName);
82
+ fs.copyFileSync(configPath, backupPath);
83
+ logger.info(`Created backup: ${backupPath}`);
84
+ return backupPath;
85
+ }
86
+ /**
87
+ * Restore config from a backup file
88
+ *
89
+ * @param backupPath - Path to the backup file
90
+ * @param configPath - Path to restore to
91
+ */
92
+ export function restoreFromBackup(backupPath, configPath) {
93
+ if (!fs.existsSync(backupPath)) {
94
+ throw new Error(`Backup file not found: ${backupPath}`);
95
+ }
96
+ fs.copyFileSync(backupPath, configPath);
97
+ logger.info(`Restored config from backup: ${backupPath}`);
98
+ }
99
+ /**
100
+ * Write config atomically using temp file + rename pattern
101
+ * This ensures the config file is never in an inconsistent state
102
+ */
103
+ async function atomicWriteConfig(configPath, config) {
104
+ const tempPath = `${configPath}.tmp.${process.pid}.${Date.now()}`;
105
+ // Ensure config has $schema
106
+ const configWithSchema = {
107
+ $schema: getSchemaUrl(),
108
+ ...config,
109
+ };
110
+ const content = JSON.stringify(configWithSchema, null, 2) + '\n';
111
+ try {
112
+ // 1. Write to temporary file
113
+ await fs.promises.writeFile(tempPath, content, { encoding: 'utf-8', mode: 0o644 });
114
+ // 2. On POSIX, sync and use atomic rename
115
+ // On Windows, skip sync (causes file locking issues) and use copy+delete
116
+ if (process.platform !== 'win32') {
117
+ // Sync to ensure data is on disk (POSIX only)
118
+ const fd = await fs.promises.open(tempPath, 'r');
119
+ try {
120
+ await fd.sync();
121
+ }
122
+ finally {
123
+ await fd.close();
124
+ }
125
+ // Atomic rename (POSIX guarantees atomicity)
126
+ await fs.promises.rename(tempPath, configPath);
127
+ }
128
+ else {
129
+ // Windows: use copy + delete approach to avoid file locking issues
130
+ // First remove target if it exists
131
+ try {
132
+ await fs.promises.unlink(configPath);
133
+ }
134
+ catch (err) {
135
+ // ENOENT is expected if target doesn't exist yet
136
+ if (err.code !== 'ENOENT') {
137
+ throw err;
138
+ }
139
+ }
140
+ // Copy temp to target
141
+ await fs.promises.copyFile(tempPath, configPath);
142
+ // Remove temp file
143
+ try {
144
+ await fs.promises.unlink(tempPath);
145
+ }
146
+ catch (err) {
147
+ // Best-effort cleanup: log non-ENOENT errors but don't fail
148
+ if (err.code !== 'ENOENT') {
149
+ logger.debug(`Failed to clean up temp file ${tempPath}: ${err.message}`);
150
+ }
151
+ }
152
+ }
153
+ logger.debug(`Atomically wrote config to: ${configPath}`);
154
+ }
155
+ catch (error) {
156
+ // Clean up temp file on any failure
157
+ try {
158
+ await fs.promises.unlink(tempPath);
159
+ }
160
+ catch (cleanupErr) {
161
+ // Best-effort cleanup: don't mask the original error
162
+ if (cleanupErr.code !== 'ENOENT') {
163
+ logger.debug(`Failed to clean up temp file ${tempPath}: ${cleanupErr.message}`);
164
+ }
165
+ }
166
+ throw error;
167
+ }
168
+ }
169
+ /**
170
+ * Parse legacy .wtlinkrc file and return enabled/disabled entries
171
+ */
172
+ function parseLegacyWtlinkrc(legacyPath) {
173
+ const content = fs.readFileSync(legacyPath, 'utf-8');
174
+ const { active, commented } = parseManifest(content);
175
+ return { enabled: active, disabled: commented };
176
+ }
177
+ /**
178
+ * Execute migration with given options
179
+ *
180
+ * @param repoRoot - Repository root path
181
+ * @param detection - Detection result from detectMigrationIssues
182
+ * @param options - Migration options
183
+ * @returns Migration result
184
+ */
185
+ export async function runMigration(repoRoot, detection, options = {}) {
186
+ const { dryRun = false, deleteLegacyFiles = false, createBackup: shouldBackup = true,
187
+ // interactive option is handled by the CLI layer
188
+ } = options;
189
+ const actionsExecuted = [];
190
+ const actionsSkipped = [];
191
+ const errors = [];
192
+ let backupPath;
193
+ // Filter to only auto-fixable issues
194
+ const autoFixableIssues = detection.issues.filter((issue) => issue.autoFixable && issue.fixAction);
195
+ if (autoFixableIssues.length === 0) {
196
+ return {
197
+ success: true,
198
+ actionsExecuted: [],
199
+ actionsSkipped: [],
200
+ errors: [],
201
+ };
202
+ }
203
+ // Dry run - just report what would be done
204
+ if (dryRun) {
205
+ return {
206
+ success: true,
207
+ actionsExecuted: [],
208
+ actionsSkipped: autoFixableIssues.map((i) => i.fixAction),
209
+ errors: [],
210
+ };
211
+ }
212
+ // Get or create config path
213
+ let configPath = detection.configPath;
214
+ if (!configPath) {
215
+ configPath = path.join(repoRoot, '.worktreerc');
216
+ }
217
+ // Load current config (or start with empty)
218
+ const config = detection.rawConfig ?? {};
219
+ // Create backup before making changes
220
+ if (shouldBackup && fs.existsSync(configPath)) {
221
+ try {
222
+ backupPath = createConfigBackup(configPath, repoRoot);
223
+ }
224
+ catch (error) {
225
+ errors.push(`Failed to create backup: ${error instanceof Error ? error.message : String(error)}`);
226
+ return {
227
+ success: false,
228
+ actionsExecuted,
229
+ actionsSkipped: autoFixableIssues.map((i) => i.fixAction),
230
+ errors,
231
+ };
232
+ }
233
+ }
234
+ // Execute each action
235
+ for (const issue of autoFixableIssues) {
236
+ const action = issue.fixAction;
237
+ try {
238
+ switch (action.type) {
239
+ case 'set_key': {
240
+ if (action.keyPath) {
241
+ config[action.keyPath] = action.value;
242
+ actionsExecuted.push(action);
243
+ logger.debug(`Set ${action.keyPath} = ${JSON.stringify(action.value)}`);
244
+ }
245
+ break;
246
+ }
247
+ case 'remove_key': {
248
+ if (action.keyPath && action.keyPath in config) {
249
+ delete config[action.keyPath];
250
+ actionsExecuted.push(action);
251
+ logger.debug(`Removed key: ${action.keyPath}`);
252
+ }
253
+ break;
254
+ }
255
+ case 'rename_key': {
256
+ if (action.oldKey && action.newKey && action.oldKey in config) {
257
+ config[action.newKey] = action.value ?? config[action.oldKey];
258
+ delete config[action.oldKey];
259
+ actionsExecuted.push(action);
260
+ logger.debug(`Renamed ${action.oldKey} to ${action.newKey}`);
261
+ }
262
+ break;
263
+ }
264
+ case 'merge_legacy_file': {
265
+ if (action.filePath && fs.existsSync(action.filePath)) {
266
+ try {
267
+ const legacyData = parseLegacyWtlinkrc(action.filePath);
268
+ const existingWtlink = config.wtlink;
269
+ const merged = mergeWtlinkConfigs(existingWtlink, legacyData);
270
+ config.wtlink = {
271
+ enabled: merged.enabled,
272
+ disabled: merged.disabled,
273
+ };
274
+ actionsExecuted.push(action);
275
+ if (merged.conflicts.length > 0) {
276
+ logger.warn(`Merge conflicts resolved (enabled wins):\n ${merged.conflicts.join('\n ')}`);
277
+ }
278
+ logger.debug(`Merged legacy wtlinkrc: ${merged.enabled.length} enabled, ${merged.disabled.length} disabled`);
279
+ }
280
+ catch (parseError) {
281
+ errors.push(`Failed to parse legacy file: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
282
+ actionsSkipped.push(action);
283
+ }
284
+ }
285
+ break;
286
+ }
287
+ case 'delete_file': {
288
+ // Only delete if explicitly requested
289
+ if (deleteLegacyFiles && action.filePath && fs.existsSync(action.filePath)) {
290
+ fs.unlinkSync(action.filePath);
291
+ actionsExecuted.push(action);
292
+ logger.debug(`Deleted file: ${action.filePath}`);
293
+ }
294
+ else {
295
+ actionsSkipped.push(action);
296
+ }
297
+ break;
298
+ }
299
+ }
300
+ }
301
+ catch (error) {
302
+ errors.push(`Failed to execute ${action.type}: ${error instanceof Error ? error.message : String(error)}`);
303
+ actionsSkipped.push(action);
304
+ }
305
+ }
306
+ // Ensure configVersion is set
307
+ if (!config.configVersion) {
308
+ config.configVersion = CURRENT_CONFIG_VERSION;
309
+ }
310
+ // Write the updated config
311
+ try {
312
+ await atomicWriteConfig(configPath, config);
313
+ }
314
+ catch (writeError) {
315
+ errors.push(`Failed to write config: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
316
+ // Try to rollback
317
+ if (backupPath) {
318
+ try {
319
+ restoreFromBackup(backupPath, configPath);
320
+ logger.info('Rolled back to backup after write failure');
321
+ }
322
+ catch (rollbackError) {
323
+ errors.push(`Failed to rollback: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`);
324
+ }
325
+ }
326
+ return {
327
+ success: false,
328
+ actionsExecuted,
329
+ actionsSkipped,
330
+ errors,
331
+ backupPath,
332
+ };
333
+ }
334
+ // Validate the migrated config
335
+ const validationResult = validateConfig(config);
336
+ if (!validationResult.valid) {
337
+ const validationErrors = validationResult.errors.map((e) => `${e.path}: ${e.message}`);
338
+ logger.warn(`Migrated config has validation warnings:\n ${validationErrors.join('\n ')}`);
339
+ // Don't fail on validation warnings - the config is still usable
340
+ }
341
+ // Optionally delete legacy files after successful migration
342
+ if (deleteLegacyFiles) {
343
+ for (const legacyPath of detection.legacyFilesFound) {
344
+ try {
345
+ if (fs.existsSync(legacyPath)) {
346
+ fs.unlinkSync(legacyPath);
347
+ logger.info(`Deleted legacy file: ${legacyPath}`);
348
+ }
349
+ }
350
+ catch (deleteError) {
351
+ errors.push(`Failed to delete legacy file ${legacyPath}: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`);
352
+ }
353
+ }
354
+ }
355
+ return {
356
+ success: errors.length === 0,
357
+ actionsExecuted,
358
+ actionsSkipped,
359
+ errors,
360
+ backupPath,
361
+ newConfigPath: configPath,
362
+ };
363
+ }
364
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/lib/config-migration/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for Config Migration Runner
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=runner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.test.d.ts","sourceRoot":"","sources":["../../../src/lib/config-migration/runner.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Tests for Config Migration Runner
3
+ */
4
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
5
+ import fs from 'fs';
6
+ import path from 'path';
7
+ import os from 'os';
8
+ import { runMigration, createConfigBackup, restoreFromBackup, mergeWtlinkConfigs, } from './runner.js';
9
+ import { detectMigrationIssues } from './detector.js';
10
+ import { BACKUP_DIRECTORY, CURRENT_CONFIG_VERSION } from './types.js';
11
+ describe('Config Migration Runner', () => {
12
+ let tempDir;
13
+ beforeEach(() => {
14
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'config-migration-runner-test-'));
15
+ });
16
+ afterEach(async () => {
17
+ // On Windows, file handles may not be released immediately after close()
18
+ // Use maxRetries to handle transient EPERM/EBUSY errors
19
+ const maxRetries = process.platform === 'win32' ? 5 : 0;
20
+ for (let i = 0; i <= maxRetries; i++) {
21
+ try {
22
+ fs.rmSync(tempDir, { recursive: true, force: true });
23
+ break;
24
+ }
25
+ catch (err) {
26
+ if (i === maxRetries)
27
+ throw err;
28
+ // Small delay before retry on Windows
29
+ await new Promise((resolve) => setTimeout(resolve, 100 * (i + 1)));
30
+ }
31
+ }
32
+ });
33
+ describe('mergeWtlinkConfigs', () => {
34
+ it('merges empty existing with legacy entries', () => {
35
+ const result = mergeWtlinkConfigs(undefined, {
36
+ enabled: ['.env.local', '.vscode/settings.json'],
37
+ disabled: ['.env.test'],
38
+ });
39
+ expect(result.enabled).toEqual(['.env.local', '.vscode/settings.json']);
40
+ expect(result.disabled).toEqual(['.env.test']);
41
+ expect(result.conflicts).toHaveLength(0);
42
+ });
43
+ it('merges existing enabled with legacy entries', () => {
44
+ const result = mergeWtlinkConfigs({ enabled: ['.env.local'], disabled: [] }, { enabled: ['.vscode/settings.json'], disabled: ['.env.test'] });
45
+ expect(result.enabled).toContain('.env.local');
46
+ expect(result.enabled).toContain('.vscode/settings.json');
47
+ expect(result.disabled).toContain('.env.test');
48
+ });
49
+ it('resolves conflicts with enabled winning', () => {
50
+ const result = mergeWtlinkConfigs({ enabled: [], disabled: ['.env.local'] }, { enabled: ['.env.local'], disabled: [] });
51
+ expect(result.enabled).toContain('.env.local');
52
+ expect(result.disabled).not.toContain('.env.local');
53
+ expect(result.conflicts).toHaveLength(1);
54
+ expect(result.conflicts[0]).toContain('.env.local');
55
+ });
56
+ it('normalizes paths with backslashes', () => {
57
+ const result = mergeWtlinkConfigs({ enabled: ['.vscode\\settings.json'], disabled: [] }, { enabled: [], disabled: [] });
58
+ expect(result.enabled).toContain('.vscode/settings.json');
59
+ });
60
+ it('removes leading ./ from paths', () => {
61
+ const result = mergeWtlinkConfigs({ enabled: ['./.env.local'], disabled: [] }, { enabled: [], disabled: [] });
62
+ expect(result.enabled).toContain('.env.local');
63
+ });
64
+ it('deduplicates entries', () => {
65
+ const result = mergeWtlinkConfigs({ enabled: ['.env.local'], disabled: [] }, { enabled: ['.env.local'], disabled: [] });
66
+ expect(result.enabled.filter((e) => e === '.env.local')).toHaveLength(1);
67
+ });
68
+ });
69
+ describe('createConfigBackup', () => {
70
+ it('creates backup in .worktree-backups directory', () => {
71
+ const configPath = path.join(tempDir, '.worktreerc');
72
+ fs.writeFileSync(configPath, JSON.stringify({ baseBranch: 'main' }));
73
+ const backupPath = createConfigBackup(configPath, tempDir);
74
+ expect(backupPath).toContain(BACKUP_DIRECTORY);
75
+ expect(fs.existsSync(backupPath)).toBe(true);
76
+ const backupContent = JSON.parse(fs.readFileSync(backupPath, 'utf-8'));
77
+ expect(backupContent.baseBranch).toBe('main');
78
+ });
79
+ it('creates backup directory if it does not exist', () => {
80
+ const configPath = path.join(tempDir, '.worktreerc');
81
+ fs.writeFileSync(configPath, '{}');
82
+ const backupDir = path.join(tempDir, BACKUP_DIRECTORY);
83
+ expect(fs.existsSync(backupDir)).toBe(false);
84
+ createConfigBackup(configPath, tempDir);
85
+ expect(fs.existsSync(backupDir)).toBe(true);
86
+ });
87
+ it('creates unique backup filenames with timestamps', () => {
88
+ const configPath = path.join(tempDir, '.worktreerc');
89
+ fs.writeFileSync(configPath, '{}');
90
+ const backup1 = createConfigBackup(configPath, tempDir);
91
+ // Small delay to ensure different timestamp
92
+ const backup2 = createConfigBackup(configPath, tempDir);
93
+ expect(backup1).not.toBe(backup2);
94
+ });
95
+ });
96
+ describe('restoreFromBackup', () => {
97
+ it('restores config from backup', () => {
98
+ const configPath = path.join(tempDir, '.worktreerc');
99
+ const backupDir = path.join(tempDir, BACKUP_DIRECTORY);
100
+ fs.mkdirSync(backupDir);
101
+ const backupPath = path.join(backupDir, '.worktreerc.backup.123');
102
+ fs.writeFileSync(backupPath, JSON.stringify({ baseBranch: 'develop' }));
103
+ // Write different content to config
104
+ fs.writeFileSync(configPath, JSON.stringify({ baseBranch: 'main' }));
105
+ restoreFromBackup(backupPath, configPath);
106
+ const restoredContent = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
107
+ expect(restoredContent.baseBranch).toBe('develop');
108
+ });
109
+ it('throws error if backup file does not exist', () => {
110
+ const backupPath = path.join(tempDir, 'nonexistent.backup');
111
+ const configPath = path.join(tempDir, '.worktreerc');
112
+ expect(() => restoreFromBackup(backupPath, configPath)).toThrow('Backup file not found');
113
+ });
114
+ });
115
+ describe('runMigration', () => {
116
+ it('sets configVersion when missing', async () => {
117
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({ baseBranch: 'main' }));
118
+ const detection = detectMigrationIssues(tempDir);
119
+ const result = await runMigration(tempDir, detection);
120
+ expect(result.success).toBe(true);
121
+ expect(result.actionsExecuted.length).toBeGreaterThan(0);
122
+ const config = JSON.parse(fs.readFileSync(path.join(tempDir, '.worktreerc'), 'utf-8'));
123
+ expect(config.configVersion).toBe(CURRENT_CONFIG_VERSION);
124
+ });
125
+ it('creates backup before migration', async () => {
126
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({ baseBranch: 'main' }));
127
+ const detection = detectMigrationIssues(tempDir);
128
+ const result = await runMigration(tempDir, detection);
129
+ expect(result.backupPath).toBeDefined();
130
+ expect(fs.existsSync(result.backupPath)).toBe(true);
131
+ });
132
+ it('merges legacy .wtlinkrc enabled entries', async () => {
133
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({ configVersion: CURRENT_CONFIG_VERSION }));
134
+ fs.writeFileSync(path.join(tempDir, '.wtlinkrc'), '.env.local\n.vscode/settings.json\n# .env.test');
135
+ const detection = detectMigrationIssues(tempDir);
136
+ const result = await runMigration(tempDir, detection);
137
+ expect(result.success).toBe(true);
138
+ const config = JSON.parse(fs.readFileSync(path.join(tempDir, '.worktreerc'), 'utf-8'));
139
+ expect(config.wtlink.enabled).toContain('.env.local');
140
+ expect(config.wtlink.enabled).toContain('.vscode/settings.json');
141
+ });
142
+ it('merges legacy .wtlinkrc disabled entries', async () => {
143
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({ configVersion: CURRENT_CONFIG_VERSION }));
144
+ fs.writeFileSync(path.join(tempDir, '.wtlinkrc'), '# .env.test\n# .env.staging');
145
+ const detection = detectMigrationIssues(tempDir);
146
+ const result = await runMigration(tempDir, detection);
147
+ expect(result.success).toBe(true);
148
+ const config = JSON.parse(fs.readFileSync(path.join(tempDir, '.worktreerc'), 'utf-8'));
149
+ expect(config.wtlink.disabled).toContain('.env.test');
150
+ expect(config.wtlink.disabled).toContain('.env.staging');
151
+ });
152
+ it('handles merge conflicts with enabled winning', async () => {
153
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({
154
+ configVersion: CURRENT_CONFIG_VERSION,
155
+ wtlink: { enabled: [], disabled: ['.env.local'] },
156
+ }));
157
+ fs.writeFileSync(path.join(tempDir, '.wtlinkrc'), '.env.local');
158
+ const detection = detectMigrationIssues(tempDir);
159
+ const result = await runMigration(tempDir, detection);
160
+ expect(result.success).toBe(true);
161
+ const config = JSON.parse(fs.readFileSync(path.join(tempDir, '.worktreerc'), 'utf-8'));
162
+ expect(config.wtlink.enabled).toContain('.env.local');
163
+ expect(config.wtlink.disabled).not.toContain('.env.local');
164
+ });
165
+ it('deletes legacy file with deleteLegacyFiles option', async () => {
166
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({ configVersion: CURRENT_CONFIG_VERSION }));
167
+ const legacyPath = path.join(tempDir, '.wtlinkrc');
168
+ fs.writeFileSync(legacyPath, '.env.local');
169
+ const detection = detectMigrationIssues(tempDir);
170
+ await runMigration(tempDir, detection, { deleteLegacyFiles: true });
171
+ expect(fs.existsSync(legacyPath)).toBe(false);
172
+ });
173
+ it('preserves legacy file without deleteLegacyFiles flag', async () => {
174
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({ configVersion: CURRENT_CONFIG_VERSION }));
175
+ const legacyPath = path.join(tempDir, '.wtlinkrc');
176
+ fs.writeFileSync(legacyPath, '.env.local');
177
+ const detection = detectMigrationIssues(tempDir);
178
+ await runMigration(tempDir, detection, { deleteLegacyFiles: false });
179
+ expect(fs.existsSync(legacyPath)).toBe(true);
180
+ });
181
+ it('dry-run makes no changes', async () => {
182
+ const configPath = path.join(tempDir, '.worktreerc');
183
+ const originalContent = JSON.stringify({ baseBranch: 'main' });
184
+ fs.writeFileSync(configPath, originalContent);
185
+ const detection = detectMigrationIssues(tempDir);
186
+ const result = await runMigration(tempDir, detection, { dryRun: true });
187
+ expect(result.success).toBe(true);
188
+ expect(result.actionsExecuted).toHaveLength(0);
189
+ expect(result.actionsSkipped.length).toBeGreaterThan(0);
190
+ // Verify file unchanged
191
+ const currentContent = fs.readFileSync(configPath, 'utf-8');
192
+ expect(currentContent).toBe(originalContent);
193
+ // Verify no backup created
194
+ const backupDir = path.join(tempDir, BACKUP_DIRECTORY);
195
+ expect(fs.existsSync(backupDir)).toBe(false);
196
+ });
197
+ it('adds $schema to migrated config', async () => {
198
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({ baseBranch: 'main' }));
199
+ const detection = detectMigrationIssues(tempDir);
200
+ await runMigration(tempDir, detection);
201
+ const config = JSON.parse(fs.readFileSync(path.join(tempDir, '.worktreerc'), 'utf-8'));
202
+ expect(config.$schema).toBeDefined();
203
+ expect(config.$schema).toContain('worktreerc.schema.json');
204
+ });
205
+ it('returns success with no actions when nothing to migrate', async () => {
206
+ fs.writeFileSync(path.join(tempDir, '.worktreerc'), JSON.stringify({ configVersion: CURRENT_CONFIG_VERSION, baseBranch: 'main' }));
207
+ const detection = detectMigrationIssues(tempDir);
208
+ const result = await runMigration(tempDir, detection);
209
+ expect(result.success).toBe(true);
210
+ expect(result.actionsExecuted).toHaveLength(0);
211
+ expect(result.errors).toHaveLength(0);
212
+ });
213
+ it('handles permission errors gracefully', async () => {
214
+ // Skip this test on Windows where permission handling is different
215
+ if (process.platform === 'win32') {
216
+ return;
217
+ }
218
+ const configPath = path.join(tempDir, '.worktreerc');
219
+ fs.writeFileSync(configPath, JSON.stringify({ baseBranch: 'main' }));
220
+ // Make the directory read-only
221
+ fs.chmodSync(tempDir, 0o444);
222
+ try {
223
+ const detection = detectMigrationIssues(tempDir);
224
+ const result = await runMigration(tempDir, detection);
225
+ expect(result.success).toBe(false);
226
+ expect(result.errors.length).toBeGreaterThan(0);
227
+ }
228
+ finally {
229
+ // Restore permissions for cleanup
230
+ fs.chmodSync(tempDir, 0o755);
231
+ }
232
+ });
233
+ });
234
+ });
235
+ //# sourceMappingURL=runner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.test.js","sourceRoot":"","sources":["../../../src/lib/config-migration/runner.test.ts"],"names":[],"mappings":"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"}