@camaradesuk/git-worktree-tools 1.9.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. package/README.md +52 -31
  2. package/dist/cli/cleanpr.js +74 -53
  3. package/dist/cli/cleanpr.js.map +1 -1
  4. package/dist/cli/lswt.js +32 -56
  5. package/dist/cli/lswt.js.map +1 -1
  6. package/dist/cli/newpr.d.ts +13 -1
  7. package/dist/cli/newpr.d.ts.map +1 -1
  8. package/dist/cli/newpr.js +159 -153
  9. package/dist/cli/newpr.js.map +1 -1
  10. package/dist/cli/prs.d.ts +3 -10
  11. package/dist/cli/prs.d.ts.map +1 -1
  12. package/dist/cli/prs.js +6 -168
  13. package/dist/cli/prs.js.map +1 -1
  14. package/dist/cli/wt/clean.d.ts +6 -2
  15. package/dist/cli/wt/clean.d.ts.map +1 -1
  16. package/dist/cli/wt/clean.js +401 -20
  17. package/dist/cli/wt/clean.js.map +1 -1
  18. package/dist/cli/wt/completion.d.ts +3 -0
  19. package/dist/cli/wt/completion.d.ts.map +1 -1
  20. package/dist/cli/wt/completion.js +80 -9
  21. package/dist/cli/wt/completion.js.map +1 -1
  22. package/dist/cli/wt/config.d.ts +3 -1
  23. package/dist/cli/wt/config.d.ts.map +1 -1
  24. package/dist/cli/wt/config.js +323 -32
  25. package/dist/cli/wt/config.js.map +1 -1
  26. package/dist/cli/wt/interactive-menu.d.ts +2 -0
  27. package/dist/cli/wt/interactive-menu.d.ts.map +1 -1
  28. package/dist/cli/wt/interactive-menu.js +346 -73
  29. package/dist/cli/wt/interactive-menu.js.map +1 -1
  30. package/dist/cli/wt/link.d.ts +3 -1
  31. package/dist/cli/wt/link.d.ts.map +1 -1
  32. package/dist/cli/wt/link.js +125 -38
  33. package/dist/cli/wt/link.js.map +1 -1
  34. package/dist/cli/wt/list.d.ts +4 -1
  35. package/dist/cli/wt/list.d.ts.map +1 -1
  36. package/dist/cli/wt/list.js +85 -16
  37. package/dist/cli/wt/list.js.map +1 -1
  38. package/dist/cli/wt/new.d.ts +8 -2
  39. package/dist/cli/wt/new.d.ts.map +1 -1
  40. package/dist/cli/wt/new.js +91 -46
  41. package/dist/cli/wt/new.js.map +1 -1
  42. package/dist/cli/wt/prs.d.ts +2 -1
  43. package/dist/cli/wt/prs.d.ts.map +1 -1
  44. package/dist/cli/wt/prs.js +3 -164
  45. package/dist/cli/wt/prs.js.map +1 -1
  46. package/dist/cli/wt/run-command.d.ts +4 -2
  47. package/dist/cli/wt/run-command.d.ts.map +1 -1
  48. package/dist/cli/wt/run-command.js +6 -4
  49. package/dist/cli/wt/run-command.js.map +1 -1
  50. package/dist/cli/wt/state.d.ts +3 -1
  51. package/dist/cli/wt/state.d.ts.map +1 -1
  52. package/dist/cli/wt/state.js +74 -10
  53. package/dist/cli/wt/state.js.map +1 -1
  54. package/dist/cli/wt.d.ts.map +1 -1
  55. package/dist/cli/wt.js +50 -36
  56. package/dist/cli/wt.js.map +1 -1
  57. package/dist/cli/wtconfig.js +99 -22
  58. package/dist/cli/wtconfig.js.map +1 -1
  59. package/dist/cli/wtlink.js +85 -61
  60. package/dist/cli/wtlink.js.map +1 -1
  61. package/dist/cli/wtstate.js +21 -2
  62. package/dist/cli/wtstate.js.map +1 -1
  63. package/dist/lib/cleanpr/args.d.ts.map +1 -1
  64. package/dist/lib/cleanpr/args.js +20 -0
  65. package/dist/lib/cleanpr/args.js.map +1 -1
  66. package/dist/lib/cleanpr/types.d.ts +6 -0
  67. package/dist/lib/cleanpr/types.d.ts.map +1 -1
  68. package/dist/lib/colors.d.ts +5 -0
  69. package/dist/lib/colors.d.ts.map +1 -1
  70. package/dist/lib/colors.js +13 -6
  71. package/dist/lib/colors.js.map +1 -1
  72. package/dist/lib/constants.d.ts +12 -4
  73. package/dist/lib/constants.d.ts.map +1 -1
  74. package/dist/lib/constants.js +24 -5
  75. package/dist/lib/constants.js.map +1 -1
  76. package/dist/lib/deprecation.d.ts +18 -0
  77. package/dist/lib/deprecation.d.ts.map +1 -0
  78. package/dist/lib/deprecation.js +28 -0
  79. package/dist/lib/deprecation.js.map +1 -0
  80. package/dist/lib/logger.d.ts +40 -155
  81. package/dist/lib/logger.d.ts.map +1 -1
  82. package/dist/lib/logger.js +349 -420
  83. package/dist/lib/logger.js.map +1 -1
  84. package/dist/lib/lswt/args.d.ts.map +1 -1
  85. package/dist/lib/lswt/args.js +15 -1
  86. package/dist/lib/lswt/args.js.map +1 -1
  87. package/dist/lib/lswt/index.d.ts +1 -0
  88. package/dist/lib/lswt/index.d.ts.map +1 -1
  89. package/dist/lib/lswt/index.js +2 -0
  90. package/dist/lib/lswt/index.js.map +1 -1
  91. package/dist/lib/lswt/table.d.ts +15 -0
  92. package/dist/lib/lswt/table.d.ts.map +1 -0
  93. package/dist/lib/lswt/table.js +61 -0
  94. package/dist/lib/lswt/table.js.map +1 -0
  95. package/dist/lib/lswt/types.d.ts +4 -0
  96. package/dist/lib/lswt/types.d.ts.map +1 -1
  97. package/dist/lib/newpr/args.d.ts.map +1 -1
  98. package/dist/lib/newpr/args.js +21 -0
  99. package/dist/lib/newpr/args.js.map +1 -1
  100. package/dist/lib/newpr/types.d.ts +6 -0
  101. package/dist/lib/newpr/types.d.ts.map +1 -1
  102. package/dist/lib/prs/command.d.ts +21 -0
  103. package/dist/lib/prs/command.d.ts.map +1 -0
  104. package/dist/lib/prs/command.js +175 -0
  105. package/dist/lib/prs/command.js.map +1 -0
  106. package/dist/lib/prs/interactive.d.ts.map +1 -1
  107. package/dist/lib/prs/interactive.js +15 -2
  108. package/dist/lib/prs/interactive.js.map +1 -1
  109. package/dist/lib/prs/types.d.ts +15 -0
  110. package/dist/lib/prs/types.d.ts.map +1 -1
  111. package/dist/lib/ui/error.d.ts +31 -0
  112. package/dist/lib/ui/error.d.ts.map +1 -0
  113. package/dist/lib/ui/error.js +47 -0
  114. package/dist/lib/ui/error.js.map +1 -0
  115. package/dist/lib/ui/index.d.ts +15 -0
  116. package/dist/lib/ui/index.d.ts.map +1 -0
  117. package/dist/lib/ui/index.js +19 -0
  118. package/dist/lib/ui/index.js.map +1 -0
  119. package/dist/lib/ui/output.d.ts +18 -0
  120. package/dist/lib/ui/output.d.ts.map +1 -0
  121. package/dist/lib/ui/output.js +31 -0
  122. package/dist/lib/ui/output.js.map +1 -0
  123. package/dist/lib/ui/spinner.d.ts +10 -0
  124. package/dist/lib/ui/spinner.d.ts.map +1 -0
  125. package/dist/lib/ui/spinner.js +10 -0
  126. package/dist/lib/ui/spinner.js.map +1 -0
  127. package/dist/lib/ui/status.d.ts +65 -0
  128. package/dist/lib/ui/status.d.ts.map +1 -0
  129. package/dist/lib/ui/status.js +100 -0
  130. package/dist/lib/ui/status.js.map +1 -0
  131. package/dist/lib/ui/table.d.ts +39 -0
  132. package/dist/lib/ui/table.d.ts.map +1 -0
  133. package/dist/lib/ui/table.js +45 -0
  134. package/dist/lib/ui/table.js.map +1 -0
  135. package/dist/lib/ui/theme.d.ts +34 -0
  136. package/dist/lib/ui/theme.d.ts.map +1 -0
  137. package/dist/lib/ui/theme.js +37 -0
  138. package/dist/lib/ui/theme.js.map +1 -0
  139. package/dist/lib/wtlink/link-configs.js +7 -7
  140. package/dist/lib/wtlink/link-configs.js.map +1 -1
  141. package/dist/lib/wtlink/validate-manifest.d.ts.map +1 -1
  142. package/dist/lib/wtlink/validate-manifest.js +5 -5
  143. package/dist/lib/wtlink/validate-manifest.js.map +1 -1
  144. package/dist/lib/wtstate/args.d.ts.map +1 -1
  145. package/dist/lib/wtstate/args.js +2 -0
  146. package/dist/lib/wtstate/args.js.map +1 -1
  147. package/dist/mcp/server.d.ts +2 -1
  148. package/dist/mcp/server.d.ts.map +1 -1
  149. package/dist/mcp/server.js +264 -44
  150. package/dist/mcp/server.js.map +1 -1
  151. package/package.json +13 -3
  152. package/dist/api/list.test.d.ts +0 -5
  153. package/dist/api/list.test.d.ts.map +0 -1
  154. package/dist/api/list.test.js +0 -390
  155. package/dist/api/list.test.js.map +0 -1
  156. package/dist/cli/cleanpr.test.d.ts +0 -2
  157. package/dist/cli/cleanpr.test.d.ts.map +0 -1
  158. package/dist/cli/cleanpr.test.js +0 -954
  159. package/dist/cli/cleanpr.test.js.map +0 -1
  160. package/dist/cli/lswt.test.d.ts +0 -2
  161. package/dist/cli/lswt.test.d.ts.map +0 -1
  162. package/dist/cli/lswt.test.js +0 -386
  163. package/dist/cli/lswt.test.js.map +0 -1
  164. package/dist/cli/newpr.test.d.ts +0 -2
  165. package/dist/cli/newpr.test.d.ts.map +0 -1
  166. package/dist/cli/newpr.test.js +0 -1182
  167. package/dist/cli/newpr.test.js.map +0 -1
  168. package/dist/cli/prs.test.d.ts +0 -8
  169. package/dist/cli/prs.test.d.ts.map +0 -1
  170. package/dist/cli/prs.test.js +0 -410
  171. package/dist/cli/prs.test.js.map +0 -1
  172. package/dist/cli/wt/completion.test.d.ts +0 -5
  173. package/dist/cli/wt/completion.test.d.ts.map +0 -1
  174. package/dist/cli/wt/completion.test.js +0 -173
  175. package/dist/cli/wt/completion.test.js.map +0 -1
  176. package/dist/cli/wt/config.test.d.ts +0 -5
  177. package/dist/cli/wt/config.test.d.ts.map +0 -1
  178. package/dist/cli/wt/config.test.js +0 -260
  179. package/dist/cli/wt/config.test.js.map +0 -1
  180. package/dist/cli/wt/entry.test.d.ts +0 -8
  181. package/dist/cli/wt/entry.test.d.ts.map +0 -1
  182. package/dist/cli/wt/entry.test.js +0 -201
  183. package/dist/cli/wt/entry.test.js.map +0 -1
  184. package/dist/cli/wt/init.test.d.ts +0 -5
  185. package/dist/cli/wt/init.test.d.ts.map +0 -1
  186. package/dist/cli/wt/init.test.js +0 -165
  187. package/dist/cli/wt/init.test.js.map +0 -1
  188. package/dist/cli/wt/init.unit.test.d.ts +0 -5
  189. package/dist/cli/wt/init.unit.test.d.ts.map +0 -1
  190. package/dist/cli/wt/init.unit.test.js +0 -432
  191. package/dist/cli/wt/init.unit.test.js.map +0 -1
  192. package/dist/cli/wt/interactive-menu.test.d.ts +0 -10
  193. package/dist/cli/wt/interactive-menu.test.d.ts.map +0 -1
  194. package/dist/cli/wt/interactive-menu.test.js +0 -739
  195. package/dist/cli/wt/interactive-menu.test.js.map +0 -1
  196. package/dist/cli/wt/prs.test.d.ts +0 -5
  197. package/dist/cli/wt/prs.test.d.ts.map +0 -1
  198. package/dist/cli/wt/prs.test.js +0 -410
  199. package/dist/cli/wt/prs.test.js.map +0 -1
  200. package/dist/cli/wt/run-command.test.d.ts +0 -5
  201. package/dist/cli/wt/run-command.test.d.ts.map +0 -1
  202. package/dist/cli/wt/run-command.test.js +0 -88
  203. package/dist/cli/wt/run-command.test.js.map +0 -1
  204. package/dist/cli/wt/wt.test.d.ts +0 -8
  205. package/dist/cli/wt/wt.test.d.ts.map +0 -1
  206. package/dist/cli/wt/wt.test.js +0 -521
  207. package/dist/cli/wt/wt.test.js.map +0 -1
  208. package/dist/cli/wt.unit.test.d.ts +0 -7
  209. package/dist/cli/wt.unit.test.d.ts.map +0 -1
  210. package/dist/cli/wt.unit.test.js +0 -182
  211. package/dist/cli/wt.unit.test.js.map +0 -1
  212. package/dist/cli/wtconfig.test.d.ts +0 -5
  213. package/dist/cli/wtconfig.test.d.ts.map +0 -1
  214. package/dist/cli/wtconfig.test.js +0 -1289
  215. package/dist/cli/wtconfig.test.js.map +0 -1
  216. package/dist/cli/wtlink.test.d.ts +0 -2
  217. package/dist/cli/wtlink.test.d.ts.map +0 -1
  218. package/dist/cli/wtlink.test.js +0 -249
  219. package/dist/cli/wtlink.test.js.map +0 -1
  220. package/dist/cli/wtstate.test.d.ts +0 -5
  221. package/dist/cli/wtstate.test.d.ts.map +0 -1
  222. package/dist/cli/wtstate.test.js +0 -193
  223. package/dist/cli/wtstate.test.js.map +0 -1
  224. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +0 -2
  225. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +0 -1
  226. package/dist/e2e/cleanpr/cleanpr.e2e.test.js +0 -326
  227. package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +0 -1
  228. package/dist/e2e/cli.e2e.test.d.ts +0 -2
  229. package/dist/e2e/cli.e2e.test.d.ts.map +0 -1
  230. package/dist/e2e/cli.e2e.test.js +0 -417
  231. package/dist/e2e/cli.e2e.test.js.map +0 -1
  232. package/dist/e2e/lswt/lswt.e2e.test.d.ts +0 -2
  233. package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +0 -1
  234. package/dist/e2e/lswt/lswt.e2e.test.js +0 -361
  235. package/dist/e2e/lswt/lswt.e2e.test.js.map +0 -1
  236. package/dist/e2e/newpr/newpr.e2e.test.d.ts +0 -2
  237. package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +0 -1
  238. package/dist/e2e/newpr/newpr.e2e.test.js +0 -286
  239. package/dist/e2e/newpr/newpr.e2e.test.js.map +0 -1
  240. package/dist/e2e/newpr/scenarios.e2e.test.d.ts +0 -2
  241. package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +0 -1
  242. package/dist/e2e/newpr/scenarios.e2e.test.js +0 -426
  243. package/dist/e2e/newpr/scenarios.e2e.test.js.map +0 -1
  244. package/dist/e2e/newpr-full-flow.e2e.test.d.ts +0 -2
  245. package/dist/e2e/newpr-full-flow.e2e.test.d.ts.map +0 -1
  246. package/dist/e2e/newpr-full-flow.e2e.test.js +0 -280
  247. package/dist/e2e/newpr-full-flow.e2e.test.js.map +0 -1
  248. package/dist/e2e/prs/prs.e2e.test.d.ts +0 -7
  249. package/dist/e2e/prs/prs.e2e.test.d.ts.map +0 -1
  250. package/dist/e2e/prs/prs.e2e.test.js +0 -606
  251. package/dist/e2e/prs/prs.e2e.test.js.map +0 -1
  252. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +0 -2
  253. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +0 -1
  254. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +0 -298
  255. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +0 -1
  256. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts +0 -8
  257. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts.map +0 -1
  258. package/dist/e2e/wt/interactive-menu.e2e.test.js +0 -583
  259. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +0 -1
  260. package/dist/e2e/wt/wt.e2e.test.d.ts +0 -9
  261. package/dist/e2e/wt/wt.e2e.test.d.ts.map +0 -1
  262. package/dist/e2e/wt/wt.e2e.test.js +0 -597
  263. package/dist/e2e/wt/wt.e2e.test.js.map +0 -1
  264. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +0 -2
  265. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +0 -1
  266. package/dist/e2e/wtlink/wtlink.e2e.test.js +0 -416
  267. package/dist/e2e/wtlink/wtlink.e2e.test.js.map +0 -1
  268. package/dist/integration/git.integration.test.d.ts +0 -2
  269. package/dist/integration/git.integration.test.d.ts.map +0 -1
  270. package/dist/integration/git.integration.test.js +0 -336
  271. package/dist/integration/git.integration.test.js.map +0 -1
  272. package/dist/integration/lswt-remote-pr.integration.test.d.ts +0 -2
  273. package/dist/integration/lswt-remote-pr.integration.test.d.ts.map +0 -1
  274. package/dist/integration/lswt-remote-pr.integration.test.js +0 -222
  275. package/dist/integration/lswt-remote-pr.integration.test.js.map +0 -1
  276. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts +0 -2
  277. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts.map +0 -1
  278. package/dist/integration/newpr-branchfrom-head.integration.test.js +0 -498
  279. package/dist/integration/newpr-branchfrom-head.integration.test.js.map +0 -1
  280. package/dist/integration/newpr.integration.test.d.ts +0 -2
  281. package/dist/integration/newpr.integration.test.d.ts.map +0 -1
  282. package/dist/integration/newpr.integration.test.js +0 -460
  283. package/dist/integration/newpr.integration.test.js.map +0 -1
  284. package/dist/integration/prs.integration.test.d.ts +0 -8
  285. package/dist/integration/prs.integration.test.d.ts.map +0 -1
  286. package/dist/integration/prs.integration.test.js +0 -478
  287. package/dist/integration/prs.integration.test.js.map +0 -1
  288. package/dist/lib/ai/base-provider.test.d.ts +0 -7
  289. package/dist/lib/ai/base-provider.test.d.ts.map +0 -1
  290. package/dist/lib/ai/base-provider.test.js +0 -319
  291. package/dist/lib/ai/base-provider.test.js.map +0 -1
  292. package/dist/lib/ai/cli-provider.test.d.ts +0 -5
  293. package/dist/lib/ai/cli-provider.test.d.ts.map +0 -1
  294. package/dist/lib/ai/cli-provider.test.js +0 -460
  295. package/dist/lib/ai/cli-provider.test.js.map +0 -1
  296. package/dist/lib/ai/fallback-provider.test.d.ts +0 -7
  297. package/dist/lib/ai/fallback-provider.test.d.ts.map +0 -1
  298. package/dist/lib/ai/fallback-provider.test.js +0 -165
  299. package/dist/lib/ai/fallback-provider.test.js.map +0 -1
  300. package/dist/lib/ai/generation-service.test.d.ts +0 -7
  301. package/dist/lib/ai/generation-service.test.d.ts.map +0 -1
  302. package/dist/lib/ai/generation-service.test.js +0 -213
  303. package/dist/lib/ai/generation-service.test.js.map +0 -1
  304. package/dist/lib/ai/provider-manager.test.d.ts +0 -5
  305. package/dist/lib/ai/provider-manager.test.d.ts.map +0 -1
  306. package/dist/lib/ai/provider-manager.test.js +0 -312
  307. package/dist/lib/ai/provider-manager.test.js.map +0 -1
  308. package/dist/lib/ai/repo-docs.test.d.ts +0 -5
  309. package/dist/lib/ai/repo-docs.test.d.ts.map +0 -1
  310. package/dist/lib/ai/repo-docs.test.js +0 -357
  311. package/dist/lib/ai/repo-docs.test.js.map +0 -1
  312. package/dist/lib/cleanpr/args.test.d.ts +0 -2
  313. package/dist/lib/cleanpr/args.test.d.ts.map +0 -1
  314. package/dist/lib/cleanpr/args.test.js +0 -269
  315. package/dist/lib/cleanpr/args.test.js.map +0 -1
  316. package/dist/lib/cleanpr/cleanup.test.d.ts +0 -2
  317. package/dist/lib/cleanpr/cleanup.test.d.ts.map +0 -1
  318. package/dist/lib/cleanpr/cleanup.test.js +0 -296
  319. package/dist/lib/cleanpr/cleanup.test.js.map +0 -1
  320. package/dist/lib/cleanpr/worktree-info.test.d.ts +0 -2
  321. package/dist/lib/cleanpr/worktree-info.test.d.ts.map +0 -1
  322. package/dist/lib/cleanpr/worktree-info.test.js +0 -228
  323. package/dist/lib/cleanpr/worktree-info.test.js.map +0 -1
  324. package/dist/lib/colors.test.d.ts +0 -2
  325. package/dist/lib/colors.test.d.ts.map +0 -1
  326. package/dist/lib/colors.test.js +0 -142
  327. package/dist/lib/colors.test.js.map +0 -1
  328. package/dist/lib/config-editor.test.d.ts +0 -11
  329. package/dist/lib/config-editor.test.d.ts.map +0 -1
  330. package/dist/lib/config-editor.test.js +0 -526
  331. package/dist/lib/config-editor.test.js.map +0 -1
  332. package/dist/lib/config-migration/detector.test.d.ts +0 -5
  333. package/dist/lib/config-migration/detector.test.d.ts.map +0 -1
  334. package/dist/lib/config-migration/detector.test.js +0 -201
  335. package/dist/lib/config-migration/detector.test.js.map +0 -1
  336. package/dist/lib/config-migration/reporter.test.d.ts +0 -5
  337. package/dist/lib/config-migration/reporter.test.d.ts.map +0 -1
  338. package/dist/lib/config-migration/reporter.test.js +0 -305
  339. package/dist/lib/config-migration/reporter.test.js.map +0 -1
  340. package/dist/lib/config-migration/runner.test.d.ts +0 -5
  341. package/dist/lib/config-migration/runner.test.d.ts.map +0 -1
  342. package/dist/lib/config-migration/runner.test.js +0 -235
  343. package/dist/lib/config-migration/runner.test.js.map +0 -1
  344. package/dist/lib/config-validation.test.d.ts +0 -5
  345. package/dist/lib/config-validation.test.d.ts.map +0 -1
  346. package/dist/lib/config-validation.test.js +0 -423
  347. package/dist/lib/config-validation.test.js.map +0 -1
  348. package/dist/lib/config.test.d.ts +0 -2
  349. package/dist/lib/config.test.d.ts.map +0 -1
  350. package/dist/lib/config.test.js +0 -566
  351. package/dist/lib/config.test.js.map +0 -1
  352. package/dist/lib/constants.test.d.ts +0 -5
  353. package/dist/lib/constants.test.d.ts.map +0 -1
  354. package/dist/lib/constants.test.js +0 -121
  355. package/dist/lib/constants.test.js.map +0 -1
  356. package/dist/lib/errors.test.d.ts +0 -2
  357. package/dist/lib/errors.test.d.ts.map +0 -1
  358. package/dist/lib/errors.test.js +0 -117
  359. package/dist/lib/errors.test.js.map +0 -1
  360. package/dist/lib/git.test.d.ts +0 -2
  361. package/dist/lib/git.test.d.ts.map +0 -1
  362. package/dist/lib/git.test.js +0 -608
  363. package/dist/lib/git.test.js.map +0 -1
  364. package/dist/lib/github.test.d.ts +0 -2
  365. package/dist/lib/github.test.d.ts.map +0 -1
  366. package/dist/lib/github.test.js +0 -441
  367. package/dist/lib/github.test.js.map +0 -1
  368. package/dist/lib/global-check.test.d.ts +0 -5
  369. package/dist/lib/global-check.test.d.ts.map +0 -1
  370. package/dist/lib/global-check.test.js +0 -150
  371. package/dist/lib/global-check.test.js.map +0 -1
  372. package/dist/lib/global-config.test.d.ts +0 -5
  373. package/dist/lib/global-config.test.d.ts.map +0 -1
  374. package/dist/lib/global-config.test.js +0 -282
  375. package/dist/lib/global-config.test.js.map +0 -1
  376. package/dist/lib/hooks/confirmation.test.d.ts +0 -7
  377. package/dist/lib/hooks/confirmation.test.d.ts.map +0 -1
  378. package/dist/lib/hooks/confirmation.test.js +0 -300
  379. package/dist/lib/hooks/confirmation.test.js.map +0 -1
  380. package/dist/lib/hooks/executor.test.d.ts +0 -5
  381. package/dist/lib/hooks/executor.test.d.ts.map +0 -1
  382. package/dist/lib/hooks/executor.test.js +0 -648
  383. package/dist/lib/hooks/executor.test.js.map +0 -1
  384. package/dist/lib/hooks/templates.test.d.ts +0 -5
  385. package/dist/lib/hooks/templates.test.d.ts.map +0 -1
  386. package/dist/lib/hooks/templates.test.js +0 -163
  387. package/dist/lib/hooks/templates.test.js.map +0 -1
  388. package/dist/lib/hooks/types.test.d.ts +0 -5
  389. package/dist/lib/hooks/types.test.d.ts.map +0 -1
  390. package/dist/lib/hooks/types.test.js +0 -132
  391. package/dist/lib/hooks/types.test.js.map +0 -1
  392. package/dist/lib/json-output.test.d.ts +0 -5
  393. package/dist/lib/json-output.test.d.ts.map +0 -1
  394. package/dist/lib/json-output.test.js +0 -261
  395. package/dist/lib/json-output.test.js.map +0 -1
  396. package/dist/lib/logger.test.d.ts +0 -5
  397. package/dist/lib/logger.test.d.ts.map +0 -1
  398. package/dist/lib/logger.test.js +0 -292
  399. package/dist/lib/logger.test.js.map +0 -1
  400. package/dist/lib/lswt/action-executors.test.d.ts +0 -2
  401. package/dist/lib/lswt/action-executors.test.d.ts.map +0 -1
  402. package/dist/lib/lswt/action-executors.test.js +0 -1127
  403. package/dist/lib/lswt/action-executors.test.js.map +0 -1
  404. package/dist/lib/lswt/actions.test.d.ts +0 -2
  405. package/dist/lib/lswt/actions.test.d.ts.map +0 -1
  406. package/dist/lib/lswt/actions.test.js +0 -497
  407. package/dist/lib/lswt/actions.test.js.map +0 -1
  408. package/dist/lib/lswt/args.test.d.ts +0 -2
  409. package/dist/lib/lswt/args.test.d.ts.map +0 -1
  410. package/dist/lib/lswt/args.test.js +0 -195
  411. package/dist/lib/lswt/args.test.js.map +0 -1
  412. package/dist/lib/lswt/environment.test.d.ts +0 -2
  413. package/dist/lib/lswt/environment.test.d.ts.map +0 -1
  414. package/dist/lib/lswt/environment.test.js +0 -544
  415. package/dist/lib/lswt/environment.test.js.map +0 -1
  416. package/dist/lib/lswt/formatters.test.d.ts +0 -2
  417. package/dist/lib/lswt/formatters.test.d.ts.map +0 -1
  418. package/dist/lib/lswt/formatters.test.js +0 -323
  419. package/dist/lib/lswt/formatters.test.js.map +0 -1
  420. package/dist/lib/lswt/fuzzy-search.test.d.ts +0 -5
  421. package/dist/lib/lswt/fuzzy-search.test.d.ts.map +0 -1
  422. package/dist/lib/lswt/fuzzy-search.test.js +0 -207
  423. package/dist/lib/lswt/fuzzy-search.test.js.map +0 -1
  424. package/dist/lib/lswt/interactive.test.d.ts +0 -2
  425. package/dist/lib/lswt/interactive.test.d.ts.map +0 -1
  426. package/dist/lib/lswt/interactive.test.js +0 -771
  427. package/dist/lib/lswt/interactive.test.js.map +0 -1
  428. package/dist/lib/lswt/worktree-info.test.d.ts +0 -2
  429. package/dist/lib/lswt/worktree-info.test.d.ts.map +0 -1
  430. package/dist/lib/lswt/worktree-info.test.js +0 -484
  431. package/dist/lib/lswt/worktree-info.test.js.map +0 -1
  432. package/dist/lib/newpr/action-deps.test.d.ts +0 -5
  433. package/dist/lib/newpr/action-deps.test.d.ts.map +0 -1
  434. package/dist/lib/newpr/action-deps.test.js +0 -111
  435. package/dist/lib/newpr/action-deps.test.js.map +0 -1
  436. package/dist/lib/newpr/actions.test.d.ts +0 -2
  437. package/dist/lib/newpr/actions.test.d.ts.map +0 -1
  438. package/dist/lib/newpr/actions.test.js +0 -254
  439. package/dist/lib/newpr/actions.test.js.map +0 -1
  440. package/dist/lib/newpr/args.test.d.ts +0 -2
  441. package/dist/lib/newpr/args.test.d.ts.map +0 -1
  442. package/dist/lib/newpr/args.test.js +0 -479
  443. package/dist/lib/newpr/args.test.js.map +0 -1
  444. package/dist/lib/newpr/hook-runner.test.d.ts +0 -7
  445. package/dist/lib/newpr/hook-runner.test.d.ts.map +0 -1
  446. package/dist/lib/newpr/hook-runner.test.js +0 -422
  447. package/dist/lib/newpr/hook-runner.test.js.map +0 -1
  448. package/dist/lib/newpr/plan-generator.test.d.ts +0 -7
  449. package/dist/lib/newpr/plan-generator.test.d.ts.map +0 -1
  450. package/dist/lib/newpr/plan-generator.test.js +0 -387
  451. package/dist/lib/newpr/plan-generator.test.js.map +0 -1
  452. package/dist/lib/newpr/scenario-handler.test.d.ts +0 -2
  453. package/dist/lib/newpr/scenario-handler.test.d.ts.map +0 -1
  454. package/dist/lib/newpr/scenario-handler.test.js +0 -256
  455. package/dist/lib/newpr/scenario-handler.test.js.map +0 -1
  456. package/dist/lib/prompts.test.d.ts +0 -2
  457. package/dist/lib/prompts.test.d.ts.map +0 -1
  458. package/dist/lib/prompts.test.js +0 -807
  459. package/dist/lib/prompts.test.js.map +0 -1
  460. package/dist/lib/prs/actions.test.d.ts +0 -5
  461. package/dist/lib/prs/actions.test.d.ts.map +0 -1
  462. package/dist/lib/prs/actions.test.js +0 -356
  463. package/dist/lib/prs/actions.test.js.map +0 -1
  464. package/dist/lib/prs/data.test.d.ts +0 -5
  465. package/dist/lib/prs/data.test.d.ts.map +0 -1
  466. package/dist/lib/prs/data.test.js +0 -417
  467. package/dist/lib/prs/data.test.js.map +0 -1
  468. package/dist/lib/prs/details.test.d.ts +0 -5
  469. package/dist/lib/prs/details.test.d.ts.map +0 -1
  470. package/dist/lib/prs/details.test.js +0 -325
  471. package/dist/lib/prs/details.test.js.map +0 -1
  472. package/dist/lib/prs/filters.test.d.ts +0 -5
  473. package/dist/lib/prs/filters.test.d.ts.map +0 -1
  474. package/dist/lib/prs/filters.test.js +0 -312
  475. package/dist/lib/prs/filters.test.js.map +0 -1
  476. package/dist/lib/prs/formatters.test.d.ts +0 -2
  477. package/dist/lib/prs/formatters.test.d.ts.map +0 -1
  478. package/dist/lib/prs/formatters.test.js +0 -387
  479. package/dist/lib/prs/formatters.test.js.map +0 -1
  480. package/dist/lib/prs/interactive.test.d.ts +0 -5
  481. package/dist/lib/prs/interactive.test.d.ts.map +0 -1
  482. package/dist/lib/prs/interactive.test.js +0 -364
  483. package/dist/lib/prs/interactive.test.js.map +0 -1
  484. package/dist/lib/schema.test.d.ts +0 -10
  485. package/dist/lib/schema.test.d.ts.map +0 -1
  486. package/dist/lib/schema.test.js +0 -309
  487. package/dist/lib/schema.test.js.map +0 -1
  488. package/dist/lib/state-detection.test.d.ts +0 -2
  489. package/dist/lib/state-detection.test.d.ts.map +0 -1
  490. package/dist/lib/state-detection.test.js +0 -451
  491. package/dist/lib/state-detection.test.js.map +0 -1
  492. package/dist/lib/wtconfig/config-manager.test.d.ts +0 -5
  493. package/dist/lib/wtconfig/config-manager.test.d.ts.map +0 -1
  494. package/dist/lib/wtconfig/config-manager.test.js +0 -501
  495. package/dist/lib/wtconfig/config-manager.test.js.map +0 -1
  496. package/dist/lib/wtconfig/environment.test.d.ts +0 -5
  497. package/dist/lib/wtconfig/environment.test.d.ts.map +0 -1
  498. package/dist/lib/wtconfig/environment.test.js +0 -285
  499. package/dist/lib/wtconfig/environment.test.js.map +0 -1
  500. package/dist/lib/wtlink/config-manifest.test.d.ts +0 -2
  501. package/dist/lib/wtlink/config-manifest.test.d.ts.map +0 -1
  502. package/dist/lib/wtlink/config-manifest.test.js +0 -486
  503. package/dist/lib/wtlink/config-manifest.test.js.map +0 -1
  504. package/dist/lib/wtlink/link-configs.test.d.ts +0 -2
  505. package/dist/lib/wtlink/link-configs.test.d.ts.map +0 -1
  506. package/dist/lib/wtlink/link-configs.test.js +0 -612
  507. package/dist/lib/wtlink/link-configs.test.js.map +0 -1
  508. package/dist/lib/wtlink/main-menu.test.d.ts +0 -5
  509. package/dist/lib/wtlink/main-menu.test.d.ts.map +0 -1
  510. package/dist/lib/wtlink/main-menu.test.js +0 -126
  511. package/dist/lib/wtlink/main-menu.test.js.map +0 -1
  512. package/dist/lib/wtlink/manage-manifest.test.d.ts +0 -2
  513. package/dist/lib/wtlink/manage-manifest.test.d.ts.map +0 -1
  514. package/dist/lib/wtlink/manage-manifest.test.js +0 -714
  515. package/dist/lib/wtlink/manage-manifest.test.js.map +0 -1
  516. package/dist/lib/wtlink/validate-manifest.test.d.ts +0 -2
  517. package/dist/lib/wtlink/validate-manifest.test.d.ts.map +0 -1
  518. package/dist/lib/wtlink/validate-manifest.test.js +0 -220
  519. package/dist/lib/wtlink/validate-manifest.test.js.map +0 -1
  520. package/dist/lib/wtstate/analyze.test.d.ts +0 -5
  521. package/dist/lib/wtstate/analyze.test.d.ts.map +0 -1
  522. package/dist/lib/wtstate/analyze.test.js +0 -282
  523. package/dist/lib/wtstate/analyze.test.js.map +0 -1
  524. package/dist/lib/wtstate/args.test.d.ts +0 -5
  525. package/dist/lib/wtstate/args.test.d.ts.map +0 -1
  526. package/dist/lib/wtstate/args.test.js +0 -120
  527. package/dist/lib/wtstate/args.test.js.map +0 -1
  528. package/dist/mcp/server.test.d.ts +0 -9
  529. package/dist/mcp/server.test.d.ts.map +0 -1
  530. package/dist/mcp/server.test.js +0 -439
  531. package/dist/mcp/server.test.js.map +0 -1
@@ -1,714 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import * as fs from 'fs';
3
- import * as path from 'path';
4
- import * as os from 'os';
5
- import { getAllFiles, getAllDirectories, getFileDecision, getFolderStates, getFolderStateBreakdown, isItemVisible, buildFileTree, findNodeByPath, getHierarchicalViewItems, getFlatViewItems, getVisibleItems, getDisplayItems, isCommonIgnoreDir, COMMON_IGNORE_DIRS, groupByTopDirectory, executeVimCommand, run, } from './manage-manifest.js';
6
- // Mock git module
7
- vi.mock('../git.js', () => ({
8
- checkGitInstalled: vi.fn().mockReturnValue(true),
9
- getRepoRoot: vi.fn().mockReturnValue('/mock/repo'),
10
- getMainWorktreeRoot: vi.fn().mockReturnValue('/mock/main-worktree'),
11
- isGitIgnored: vi.fn().mockReturnValue(true),
12
- exec: vi.fn(),
13
- }));
14
- // Mock inquirer
15
- vi.mock('inquirer', () => ({
16
- default: {
17
- prompt: vi.fn(),
18
- },
19
- }));
20
- // Mock console methods
21
- const mockConsoleLog = vi.spyOn(console, 'log').mockImplementation(() => { });
22
- vi.spyOn(console, 'error').mockImplementation(() => { });
23
- vi.spyOn(console, 'clear').mockImplementation(() => { });
24
- import * as git from '../git.js';
25
- describe('wtlink/manage-manifest pure functions', () => {
26
- // Helper to create a simple file tree
27
- const createSimpleTree = () => ({
28
- path: '',
29
- isDirectory: true,
30
- children: [
31
- {
32
- path: 'src',
33
- isDirectory: true,
34
- children: [
35
- { path: 'src/index.ts', isDirectory: false, children: [] },
36
- { path: 'src/utils.ts', isDirectory: false, children: [] },
37
- ],
38
- },
39
- { path: 'config.json', isDirectory: false, children: [] },
40
- ],
41
- });
42
- describe('getAllFiles', () => {
43
- it('returns single file for non-directory node', () => {
44
- const node = { path: 'file.ts', isDirectory: false, children: [] };
45
- expect(getAllFiles(node)).toEqual(['file.ts']);
46
- });
47
- it('returns all nested files for directory', () => {
48
- const tree = createSimpleTree();
49
- const files = getAllFiles(tree);
50
- expect(files).toContain('src/index.ts');
51
- expect(files).toContain('src/utils.ts');
52
- expect(files).toContain('config.json');
53
- expect(files).toHaveLength(3);
54
- });
55
- it('returns empty array for empty directory', () => {
56
- const node = { path: 'empty', isDirectory: true, children: [] };
57
- expect(getAllFiles(node)).toEqual([]);
58
- });
59
- });
60
- describe('getAllDirectories', () => {
61
- it('returns empty array for file node', () => {
62
- const node = { path: 'file.ts', isDirectory: false, children: [] };
63
- expect(getAllDirectories(node)).toEqual([]);
64
- });
65
- it('returns all nested directories', () => {
66
- const tree = {
67
- path: '',
68
- isDirectory: true,
69
- children: [
70
- {
71
- path: 'src',
72
- isDirectory: true,
73
- children: [{ path: 'src/lib', isDirectory: true, children: [] }],
74
- },
75
- { path: 'config', isDirectory: true, children: [] },
76
- ],
77
- };
78
- const dirs = getAllDirectories(tree);
79
- expect(dirs.map((d) => d.path)).toContain('src');
80
- expect(dirs.map((d) => d.path)).toContain('src/lib');
81
- expect(dirs.map((d) => d.path)).toContain('config');
82
- expect(dirs).toHaveLength(3);
83
- });
84
- });
85
- describe('getFileDecision', () => {
86
- it('returns decision from map when present', () => {
87
- const decisions = new Map([['file.ts', 'add']]);
88
- expect(getFileDecision(decisions, 'file.ts')).toBe('add');
89
- });
90
- it('returns undecided when file not in map', () => {
91
- const decisions = new Map();
92
- expect(getFileDecision(decisions, 'unknown.ts')).toBe('undecided');
93
- });
94
- it('handles all decision types', () => {
95
- const decisions = new Map([
96
- ['add.ts', 'add'],
97
- ['comment.ts', 'comment'],
98
- ['skip.ts', 'skip'],
99
- ]);
100
- expect(getFileDecision(decisions, 'add.ts')).toBe('add');
101
- expect(getFileDecision(decisions, 'comment.ts')).toBe('comment');
102
- expect(getFileDecision(decisions, 'skip.ts')).toBe('skip');
103
- });
104
- });
105
- describe('getFolderStates', () => {
106
- it('returns single state for file', () => {
107
- const node = { path: 'file.ts', isDirectory: false, children: [] };
108
- const decisions = new Map([['file.ts', 'add']]);
109
- expect(getFolderStates(node, decisions)).toEqual(new Set(['add']));
110
- });
111
- it('returns undecided for file not in decisions', () => {
112
- const node = { path: 'file.ts', isDirectory: false, children: [] };
113
- const decisions = new Map();
114
- expect(getFolderStates(node, decisions)).toEqual(new Set(['undecided']));
115
- });
116
- it('returns all states for mixed folder', () => {
117
- const tree = createSimpleTree();
118
- const srcNode = tree.children[0];
119
- const decisions = new Map([
120
- ['src/index.ts', 'add'],
121
- ['src/utils.ts', 'skip'],
122
- ]);
123
- const states = getFolderStates(srcNode, decisions);
124
- expect(states.has('add')).toBe(true);
125
- expect(states.has('skip')).toBe(true);
126
- expect(states.has('undecided')).toBe(false);
127
- });
128
- it('includes undecided for partially decided folder', () => {
129
- const tree = createSimpleTree();
130
- const srcNode = tree.children[0];
131
- const decisions = new Map([['src/index.ts', 'add']]);
132
- const states = getFolderStates(srcNode, decisions);
133
- expect(states.has('add')).toBe(true);
134
- expect(states.has('undecided')).toBe(true);
135
- });
136
- });
137
- describe('getFolderStateBreakdown', () => {
138
- it('returns correct counts for folder', () => {
139
- const tree = createSimpleTree();
140
- const decisions = new Map([
141
- ['src/index.ts', 'add'],
142
- ['src/utils.ts', 'comment'],
143
- ['config.json', 'skip'],
144
- ]);
145
- const breakdown = getFolderStateBreakdown(tree, decisions);
146
- expect(breakdown).toEqual({ add: 1, comment: 1, skip: 1, undecided: 0 });
147
- });
148
- it('counts undecided files', () => {
149
- const tree = createSimpleTree();
150
- const decisions = new Map([['src/index.ts', 'add']]);
151
- const breakdown = getFolderStateBreakdown(tree, decisions);
152
- expect(breakdown.add).toBe(1);
153
- expect(breakdown.undecided).toBe(2);
154
- });
155
- });
156
- describe('isItemVisible', () => {
157
- it('returns false when no filters active', () => {
158
- const item = {
159
- path: 'file.ts',
160
- isDirectory: false,
161
- states: new Set(['add']),
162
- };
163
- expect(isItemVisible(item, new Set())).toBe(false);
164
- });
165
- it('returns true when item state matches filter', () => {
166
- const item = {
167
- path: 'file.ts',
168
- isDirectory: false,
169
- states: new Set(['add']),
170
- };
171
- expect(isItemVisible(item, new Set(['add']))).toBe(true);
172
- });
173
- it('returns true when any state matches', () => {
174
- const item = {
175
- path: 'folder',
176
- isDirectory: true,
177
- states: new Set(['add', 'skip']),
178
- };
179
- expect(isItemVisible(item, new Set(['add']))).toBe(true);
180
- expect(isItemVisible(item, new Set(['skip']))).toBe(true);
181
- });
182
- it('returns false when no state matches', () => {
183
- const item = {
184
- path: 'file.ts',
185
- isDirectory: false,
186
- states: new Set(['add']),
187
- };
188
- expect(isItemVisible(item, new Set(['skip', 'comment']))).toBe(false);
189
- });
190
- });
191
- describe('buildFileTree', () => {
192
- it('builds tree from flat file list', () => {
193
- const files = ['src/index.ts', 'src/lib/utils.ts', 'config.json'];
194
- const tree = buildFileTree(files);
195
- expect(tree.path).toBe('');
196
- expect(tree.isDirectory).toBe(true);
197
- expect(tree.children).toHaveLength(2); // src, config.json
198
- });
199
- it('handles empty file list', () => {
200
- const tree = buildFileTree([]);
201
- expect(tree.path).toBe('');
202
- expect(tree.isDirectory).toBe(true);
203
- expect(tree.children).toHaveLength(0);
204
- });
205
- it('creates proper hierarchy', () => {
206
- const files = ['a/b/c/file.ts'];
207
- const tree = buildFileTree(files);
208
- // Navigate down the tree
209
- expect(tree.children).toHaveLength(1);
210
- const a = tree.children[0];
211
- expect(a.path).toBe('a');
212
- expect(a.isDirectory).toBe(true);
213
- const b = a.children[0];
214
- expect(b.path).toBe('a/b');
215
- expect(b.isDirectory).toBe(true);
216
- const c = b.children[0];
217
- expect(c.path).toBe('a/b/c');
218
- expect(c.isDirectory).toBe(true);
219
- const file = c.children[0];
220
- expect(file.path).toBe('a/b/c/file.ts');
221
- expect(file.isDirectory).toBe(false);
222
- });
223
- });
224
- describe('findNodeByPath', () => {
225
- it('finds root node', () => {
226
- const tree = createSimpleTree();
227
- const found = findNodeByPath(tree, '');
228
- expect(found).toBe(tree);
229
- });
230
- it('finds nested directory', () => {
231
- const tree = createSimpleTree();
232
- const found = findNodeByPath(tree, 'src');
233
- expect(found?.path).toBe('src');
234
- expect(found?.isDirectory).toBe(true);
235
- });
236
- it('finds nested file', () => {
237
- const tree = createSimpleTree();
238
- const found = findNodeByPath(tree, 'src/index.ts');
239
- expect(found?.path).toBe('src/index.ts');
240
- expect(found?.isDirectory).toBe(false);
241
- });
242
- it('returns null for non-existent path', () => {
243
- const tree = createSimpleTree();
244
- expect(findNodeByPath(tree, 'nonexistent')).toBeNull();
245
- });
246
- });
247
- describe('getHierarchicalViewItems', () => {
248
- it('returns root children when navigation stack empty', () => {
249
- const tree = createSimpleTree();
250
- const decisions = new Map();
251
- const items = getHierarchicalViewItems(tree, [], decisions);
252
- expect(items).toHaveLength(2); // src folder and config.json
253
- });
254
- it('returns folder children when navigated', () => {
255
- const tree = createSimpleTree();
256
- const decisions = new Map();
257
- const items = getHierarchicalViewItems(tree, ['src'], decisions);
258
- expect(items).toHaveLength(2); // index.ts and utils.ts
259
- expect(items.every((i) => i.path.startsWith('src/'))).toBe(true);
260
- });
261
- it('sorts folders before files', () => {
262
- const tree = createSimpleTree();
263
- const decisions = new Map();
264
- const items = getHierarchicalViewItems(tree, [], decisions);
265
- // src folder should come before config.json file
266
- const srcIndex = items.findIndex((i) => i.path === 'src');
267
- const configIndex = items.findIndex((i) => i.path === 'config.json');
268
- expect(srcIndex).toBeLessThan(configIndex);
269
- });
270
- });
271
- describe('getFlatViewItems', () => {
272
- it('returns all directories and files', () => {
273
- const tree = createSimpleTree();
274
- const decisions = new Map();
275
- const items = getFlatViewItems(tree, decisions);
276
- // Should have 1 directory (src) and 3 files
277
- expect(items.some((i) => i.path === 'src' && i.isDirectory)).toBe(true);
278
- expect(items.some((i) => i.path === 'src/index.ts')).toBe(true);
279
- expect(items.some((i) => i.path === 'src/utils.ts')).toBe(true);
280
- expect(items.some((i) => i.path === 'config.json')).toBe(true);
281
- });
282
- it('sorts alphabetically', () => {
283
- const tree = createSimpleTree();
284
- const decisions = new Map();
285
- const items = getFlatViewItems(tree, decisions);
286
- const paths = items.map((i) => i.path);
287
- const sorted = [...paths].sort();
288
- expect(paths).toEqual(sorted);
289
- });
290
- });
291
- describe('getVisibleItems', () => {
292
- it('filters items based on active filters', () => {
293
- const tree = createSimpleTree();
294
- const decisions = new Map([
295
- ['src/index.ts', 'add'],
296
- ['src/utils.ts', 'skip'],
297
- ['config.json', 'add'],
298
- ]);
299
- const state = {
300
- fileTree: tree,
301
- decisions,
302
- viewMode: 'flat',
303
- activeFilters: new Set(['add']),
304
- showHelp: false,
305
- navigationStack: [],
306
- cursorIndex: 0,
307
- scrollOffset: 0,
308
- };
309
- const items = getVisibleItems(state);
310
- // Should show items with 'add' state - src folder (contains add), src/index.ts, config.json
311
- expect(items.some((i) => i.path === 'src/index.ts')).toBe(true);
312
- expect(items.some((i) => i.path === 'config.json')).toBe(true);
313
- expect(items.some((i) => i.path === 'src/utils.ts')).toBe(false);
314
- });
315
- it('shows nothing when no filters active', () => {
316
- const tree = createSimpleTree();
317
- const state = {
318
- fileTree: tree,
319
- decisions: new Map(),
320
- viewMode: 'flat',
321
- activeFilters: new Set(),
322
- showHelp: false,
323
- navigationStack: [],
324
- cursorIndex: 0,
325
- scrollOffset: 0,
326
- };
327
- const items = getVisibleItems(state);
328
- expect(items).toHaveLength(0);
329
- });
330
- });
331
- describe('getDisplayItems', () => {
332
- it('adds back navigation in hierarchical mode when navigated', () => {
333
- const tree = createSimpleTree();
334
- const state = {
335
- fileTree: tree,
336
- decisions: new Map(),
337
- viewMode: 'hierarchical',
338
- activeFilters: new Set(['undecided']),
339
- showHelp: false,
340
- navigationStack: ['src'],
341
- cursorIndex: 0,
342
- scrollOffset: 0,
343
- };
344
- const items = getDisplayItems(state);
345
- expect(items[0].path).toBe('..');
346
- });
347
- it('does not add back navigation at root', () => {
348
- const tree = createSimpleTree();
349
- const state = {
350
- fileTree: tree,
351
- decisions: new Map(),
352
- viewMode: 'hierarchical',
353
- activeFilters: new Set(['undecided']),
354
- showHelp: false,
355
- navigationStack: [],
356
- cursorIndex: 0,
357
- scrollOffset: 0,
358
- };
359
- const items = getDisplayItems(state);
360
- expect(items[0]?.path).not.toBe('..');
361
- });
362
- it('does not add back navigation in flat mode', () => {
363
- const tree = createSimpleTree();
364
- const state = {
365
- fileTree: tree,
366
- decisions: new Map(),
367
- viewMode: 'flat',
368
- activeFilters: new Set(['undecided']),
369
- showHelp: false,
370
- navigationStack: ['src'],
371
- cursorIndex: 0,
372
- scrollOffset: 0,
373
- };
374
- const items = getDisplayItems(state);
375
- expect(items.every((i) => i.path !== '..')).toBe(true);
376
- });
377
- });
378
- describe('isCommonIgnoreDir', () => {
379
- it('returns true for common ignore directories', () => {
380
- expect(isCommonIgnoreDir('node_modules')).toBe(true);
381
- expect(isCommonIgnoreDir('.git')).toBe(true);
382
- expect(isCommonIgnoreDir('dist')).toBe(true);
383
- expect(isCommonIgnoreDir('coverage')).toBe(true);
384
- });
385
- it('returns true for nested ignore directories', () => {
386
- expect(isCommonIgnoreDir('src/node_modules')).toBe(true);
387
- expect(isCommonIgnoreDir('packages/lib/dist')).toBe(true);
388
- });
389
- it('returns false for regular directories', () => {
390
- expect(isCommonIgnoreDir('src')).toBe(false);
391
- expect(isCommonIgnoreDir('lib')).toBe(false);
392
- expect(isCommonIgnoreDir('components')).toBe(false);
393
- });
394
- });
395
- describe('COMMON_IGNORE_DIRS', () => {
396
- it('contains expected directories', () => {
397
- expect(COMMON_IGNORE_DIRS).toContain('node_modules');
398
- expect(COMMON_IGNORE_DIRS).toContain('.git');
399
- expect(COMMON_IGNORE_DIRS).toContain('dist');
400
- expect(COMMON_IGNORE_DIRS).toContain('build');
401
- expect(COMMON_IGNORE_DIRS).toContain('coverage');
402
- });
403
- });
404
- describe('groupByTopDirectory', () => {
405
- it('groups files by top-level directory', () => {
406
- const files = ['src/index.ts', 'src/utils.ts', 'lib/helper.ts', 'config.json'];
407
- const groups = groupByTopDirectory(files);
408
- expect(groups.get('src')).toBe(2);
409
- expect(groups.get('lib')).toBe(1);
410
- expect(groups.get('.')).toBe(1); // root level files
411
- });
412
- it('handles empty file list', () => {
413
- const groups = groupByTopDirectory([]);
414
- expect(groups.size).toBe(0);
415
- });
416
- it('handles root-level files only', () => {
417
- const files = ['file1.ts', 'file2.ts', 'file3.ts'];
418
- const groups = groupByTopDirectory(files);
419
- expect(groups.get('.')).toBe(3);
420
- expect(groups.size).toBe(1);
421
- });
422
- it('handles deeply nested files', () => {
423
- const files = ['a/b/c/d/file.ts', 'a/b/x/file.ts', 'a/other.ts'];
424
- const groups = groupByTopDirectory(files);
425
- // All should be grouped under 'a'
426
- expect(groups.get('a')).toBe(3);
427
- });
428
- it('sorts groups by count descending', () => {
429
- const files = ['lib/a.ts', 'src/a.ts', 'src/b.ts', 'src/c.ts', 'config.json', 'other.json'];
430
- const groups = groupByTopDirectory(files);
431
- const entries = [...groups.entries()];
432
- // src (3) should come before . (2) should come before lib (1)
433
- expect(entries[0][0]).toBe('src');
434
- expect(entries[0][1]).toBe(3);
435
- expect(entries[1][0]).toBe('.');
436
- expect(entries[1][1]).toBe(2);
437
- expect(entries[2][0]).toBe('lib');
438
- expect(entries[2][1]).toBe(1);
439
- });
440
- });
441
- describe('executeVimCommand', () => {
442
- it('returns "quit" for :q command', () => {
443
- expect(executeVimCommand('q')).toBe('quit');
444
- });
445
- it('returns "force-quit" for :q! command', () => {
446
- expect(executeVimCommand('q!')).toBe('force-quit');
447
- });
448
- it('returns "save" for :w command', () => {
449
- expect(executeVimCommand('w')).toBe('save');
450
- });
451
- it('returns "save-quit" for :wq command', () => {
452
- expect(executeVimCommand('wq')).toBe('save-quit');
453
- });
454
- it('returns "save-quit" for :x command', () => {
455
- expect(executeVimCommand('x')).toBe('save-quit');
456
- });
457
- it('returns null for unknown commands', () => {
458
- expect(executeVimCommand('unknown')).toBeNull();
459
- expect(executeVimCommand('help')).toBeNull();
460
- expect(executeVimCommand('exit')).toBeNull();
461
- expect(executeVimCommand('')).toBeNull();
462
- });
463
- it('handles whitespace in commands', () => {
464
- expect(executeVimCommand(' q ')).toBe('quit');
465
- expect(executeVimCommand('\tq\t')).toBe('quit');
466
- expect(executeVimCommand(' wq ')).toBe('save-quit');
467
- expect(executeVimCommand(' w ')).toBe('save');
468
- });
469
- it('is case-insensitive', () => {
470
- expect(executeVimCommand('Q')).toBe('quit');
471
- expect(executeVimCommand('Q!')).toBe('force-quit');
472
- expect(executeVimCommand('W')).toBe('save');
473
- expect(executeVimCommand('WQ')).toBe('save-quit');
474
- expect(executeVimCommand('X')).toBe('save-quit');
475
- expect(executeVimCommand('Wq')).toBe('save-quit');
476
- expect(executeVimCommand('wQ')).toBe('save-quit');
477
- });
478
- it('returns null for partial matches', () => {
479
- expect(executeVimCommand('qa')).toBeNull();
480
- expect(executeVimCommand('wqa')).toBeNull();
481
- expect(executeVimCommand('q!!')).toBeNull();
482
- expect(executeVimCommand('write')).toBeNull();
483
- expect(executeVimCommand('quit')).toBeNull();
484
- });
485
- it('handles edge cases', () => {
486
- // Just the bang should not be valid
487
- expect(executeVimCommand('!')).toBeNull();
488
- // Just whitespace
489
- expect(executeVimCommand(' ')).toBeNull();
490
- });
491
- });
492
- describe('getDisplayItems - edge cases', () => {
493
- it('does not add back navigation when not showing undecided only', () => {
494
- const tree = createSimpleTree();
495
- const state = {
496
- fileTree: tree,
497
- decisions: new Map(),
498
- viewMode: 'hierarchical',
499
- activeFilters: new Set(['undecided', 'add']), // Multiple filters
500
- showHelp: false,
501
- navigationStack: ['src'],
502
- cursorIndex: 0,
503
- scrollOffset: 0,
504
- };
505
- const items = getDisplayItems(state);
506
- // Should not have back navigation because not showing undecided only
507
- expect(items.every((i) => i.path !== '..')).toBe(true);
508
- });
509
- });
510
- });
511
- // Mock child_process for getIgnoredFiles
512
- vi.mock('child_process', async (importOriginal) => {
513
- const actual = await importOriginal();
514
- return {
515
- ...actual,
516
- execSync: vi.fn().mockReturnValue(''),
517
- };
518
- });
519
- import { execSync } from 'child_process';
520
- describe('wtlink/manage-manifest TUI functions', () => {
521
- let tempDir;
522
- let gitRoot;
523
- let mainWorktreeRoot;
524
- let manifestPath;
525
- beforeEach(() => {
526
- vi.clearAllMocks();
527
- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'manage-manifest-test-'));
528
- gitRoot = path.join(tempDir, 'worktree');
529
- mainWorktreeRoot = path.join(tempDir, 'main');
530
- fs.mkdirSync(gitRoot, { recursive: true });
531
- fs.mkdirSync(mainWorktreeRoot, { recursive: true });
532
- manifestPath = path.join(mainWorktreeRoot, '.wtlink');
533
- // Set up git mocks
534
- vi.mocked(git.getRepoRoot).mockReturnValue(gitRoot);
535
- vi.mocked(git.getMainWorktreeRoot).mockReturnValue(mainWorktreeRoot);
536
- vi.mocked(git.isGitIgnored).mockReturnValue(true);
537
- vi.mocked(execSync).mockReturnValue(Buffer.from(''));
538
- });
539
- afterEach(() => {
540
- fs.rmSync(tempDir, { recursive: true, force: true });
541
- vi.clearAllMocks();
542
- });
543
- describe('run', () => {
544
- it('should report manifest is up to date when no changes needed', async () => {
545
- // Create empty manifest and no ignored files
546
- fs.writeFileSync(manifestPath, '');
547
- // Mock git ls-files to return empty (no ignored files)
548
- vi.mocked(execSync).mockReturnValue(Buffer.from(''));
549
- const argv = {
550
- nonInteractive: true,
551
- clean: false,
552
- dryRun: false,
553
- manifestFile: '.wtlink',
554
- backup: false,
555
- verbose: false,
556
- };
557
- await run(argv);
558
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('up to date'));
559
- });
560
- it('should handle deleted entries in clean mode', async () => {
561
- // Create manifest with entry that doesn't exist in filesystem
562
- fs.writeFileSync(manifestPath, 'deleted-file.txt');
563
- // Mock git ls-files to return empty (no new ignored files)
564
- vi.mocked(execSync).mockReturnValue(Buffer.from(''));
565
- const argv = {
566
- nonInteractive: true,
567
- clean: true,
568
- dryRun: false,
569
- manifestFile: '.wtlink',
570
- backup: false,
571
- verbose: false,
572
- };
573
- await run(argv);
574
- // In clean mode, deleted entries should be removed
575
- expect(mockConsoleLog).toHaveBeenCalled();
576
- });
577
- it('should handle dry-run mode without modifying manifest', async () => {
578
- const originalContent = 'existing-file.txt';
579
- fs.writeFileSync(manifestPath, originalContent);
580
- // Create the existing file in worktree
581
- fs.writeFileSync(path.join(gitRoot, 'existing-file.txt'), 'content');
582
- // Mock new ignored file
583
- vi.mocked(execSync).mockReturnValue(Buffer.from('new-ignored-file.txt'));
584
- const argv = {
585
- nonInteractive: true,
586
- clean: false,
587
- dryRun: true,
588
- manifestFile: '.wtlink',
589
- backup: false,
590
- verbose: false,
591
- };
592
- await run(argv);
593
- // Manifest should not be modified in dry-run mode
594
- const finalContent = fs.readFileSync(manifestPath, 'utf-8');
595
- expect(finalContent).toBe(originalContent);
596
- });
597
- it('should handle tracked entries warning in clean mode', async () => {
598
- // Create manifest with an entry that is now tracked (not ignored)
599
- fs.writeFileSync(manifestPath, 'now-tracked.txt');
600
- fs.writeFileSync(path.join(gitRoot, 'now-tracked.txt'), 'content');
601
- // Mock file as not ignored (tracked by git)
602
- vi.mocked(git.isGitIgnored).mockReturnValue(false);
603
- vi.mocked(execSync).mockReturnValue(Buffer.from(''));
604
- const argv = {
605
- nonInteractive: true,
606
- clean: true,
607
- dryRun: false,
608
- manifestFile: '.wtlink',
609
- backup: false,
610
- verbose: false,
611
- };
612
- await run(argv);
613
- // Should show warning about tracked files
614
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('TRACKED'));
615
- });
616
- it('should create backup when backup option is enabled and manifest changes', async () => {
617
- // Create manifest with a deleted entry (file doesn't exist)
618
- const originalContent = 'deleted-file.txt';
619
- fs.writeFileSync(manifestPath, originalContent);
620
- // Mock no new ignored files, file doesn't exist so it's "deleted"
621
- vi.mocked(execSync).mockReturnValue(Buffer.from(''));
622
- const argv = {
623
- nonInteractive: true,
624
- clean: true, // clean mode will remove deleted entries
625
- dryRun: false,
626
- manifestFile: '.wtlink',
627
- backup: true,
628
- verbose: false,
629
- };
630
- await run(argv);
631
- // Backup file should be created when manifest is modified
632
- const backupPath = manifestPath + '.bak';
633
- if (fs.existsSync(backupPath)) {
634
- expect(fs.readFileSync(backupPath, 'utf-8')).toBe(originalContent);
635
- }
636
- // If backup wasn't created, it means manifest wasn't modified - that's also valid
637
- });
638
- it('should add new ignored files as commented in non-interactive mode', async () => {
639
- // Create empty manifest
640
- fs.writeFileSync(manifestPath, '');
641
- // Mock new ignored files
642
- vi.mocked(execSync).mockReturnValue(Buffer.from('new-file.txt\nconfig.json'));
643
- const argv = {
644
- nonInteractive: true,
645
- clean: false,
646
- dryRun: false,
647
- manifestFile: '.wtlink',
648
- backup: false,
649
- verbose: false,
650
- };
651
- await run(argv);
652
- // New files should be added as commented
653
- const content = fs.readFileSync(manifestPath, 'utf-8');
654
- expect(content).toContain('# new-file.txt');
655
- expect(content).toContain('# config.json');
656
- });
657
- it('should show verbose output when verbose flag is set', async () => {
658
- // Create empty manifest
659
- fs.writeFileSync(manifestPath, '');
660
- // Mock many new ignored files
661
- const files = Array.from({ length: 100 }, (_, i) => `file${i}.txt`).join('\n');
662
- vi.mocked(execSync).mockReturnValue(Buffer.from(files));
663
- const argv = {
664
- nonInteractive: true,
665
- clean: false,
666
- dryRun: true,
667
- manifestFile: '.wtlink',
668
- backup: false,
669
- verbose: true, // verbose mode
670
- };
671
- await run(argv);
672
- // With verbose mode, should see individual file names logged
673
- expect(mockConsoleLog).toHaveBeenCalled();
674
- });
675
- it('should show summary for large file sets in dry-run without verbose', async () => {
676
- // Create empty manifest
677
- fs.writeFileSync(manifestPath, '');
678
- // Mock many new ignored files in src/ directory
679
- const files = Array.from({ length: 100 }, (_, i) => `src/file${i}.txt`).join('\n');
680
- vi.mocked(execSync).mockReturnValue(Buffer.from(files));
681
- const argv = {
682
- nonInteractive: true,
683
- clean: false,
684
- dryRun: true,
685
- manifestFile: '.wtlink',
686
- backup: false,
687
- verbose: false, // no verbose
688
- };
689
- await run(argv);
690
- // Should show summary instead of full list
691
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('100'));
692
- });
693
- it('should handle git ls-files error gracefully', async () => {
694
- // Create empty manifest
695
- fs.writeFileSync(manifestPath, '');
696
- // Mock git ls-files to throw error
697
- vi.mocked(execSync).mockImplementation(() => {
698
- throw new Error('Git command failed');
699
- });
700
- const argv = {
701
- nonInteractive: true,
702
- clean: false,
703
- dryRun: false,
704
- manifestFile: '.wtlink',
705
- backup: false,
706
- verbose: false,
707
- };
708
- await run(argv);
709
- // Should show warning and continue
710
- expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('up to date'));
711
- });
712
- });
713
- });
714
- //# sourceMappingURL=manage-manifest.test.js.map