@camaradesuk/git-worktree-tools 1.10.0 → 1.12.0

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