@camaradesuk/git-worktree-tools 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (426) hide show
  1. package/README.md +4 -4
  2. package/package.json +12 -3
  3. package/dist/api/list.test.d.ts +0 -5
  4. package/dist/api/list.test.d.ts.map +0 -1
  5. package/dist/api/list.test.js +0 -390
  6. package/dist/api/list.test.js.map +0 -1
  7. package/dist/cli/cleanpr.test.d.ts +0 -2
  8. package/dist/cli/cleanpr.test.d.ts.map +0 -1
  9. package/dist/cli/cleanpr.test.js +0 -954
  10. package/dist/cli/cleanpr.test.js.map +0 -1
  11. package/dist/cli/lswt.test.d.ts +0 -2
  12. package/dist/cli/lswt.test.d.ts.map +0 -1
  13. package/dist/cli/lswt.test.js +0 -376
  14. package/dist/cli/lswt.test.js.map +0 -1
  15. package/dist/cli/newpr.test.d.ts +0 -2
  16. package/dist/cli/newpr.test.d.ts.map +0 -1
  17. package/dist/cli/newpr.test.js +0 -1182
  18. package/dist/cli/newpr.test.js.map +0 -1
  19. package/dist/cli/prs.test.d.ts +0 -8
  20. package/dist/cli/prs.test.d.ts.map +0 -1
  21. package/dist/cli/prs.test.js +0 -463
  22. package/dist/cli/prs.test.js.map +0 -1
  23. package/dist/cli/wt/clean.test.d.ts +0 -8
  24. package/dist/cli/wt/clean.test.d.ts.map +0 -1
  25. package/dist/cli/wt/clean.test.js +0 -624
  26. package/dist/cli/wt/clean.test.js.map +0 -1
  27. package/dist/cli/wt/completion.test.d.ts +0 -5
  28. package/dist/cli/wt/completion.test.d.ts.map +0 -1
  29. package/dist/cli/wt/completion.test.js +0 -275
  30. package/dist/cli/wt/completion.test.js.map +0 -1
  31. package/dist/cli/wt/config.test.d.ts +0 -7
  32. package/dist/cli/wt/config.test.d.ts.map +0 -1
  33. package/dist/cli/wt/config.test.js +0 -440
  34. package/dist/cli/wt/config.test.js.map +0 -1
  35. package/dist/cli/wt/entry.test.d.ts +0 -8
  36. package/dist/cli/wt/entry.test.d.ts.map +0 -1
  37. package/dist/cli/wt/entry.test.js +0 -201
  38. package/dist/cli/wt/entry.test.js.map +0 -1
  39. package/dist/cli/wt/init.test.d.ts +0 -5
  40. package/dist/cli/wt/init.test.d.ts.map +0 -1
  41. package/dist/cli/wt/init.test.js +0 -165
  42. package/dist/cli/wt/init.test.js.map +0 -1
  43. package/dist/cli/wt/init.unit.test.d.ts +0 -5
  44. package/dist/cli/wt/init.unit.test.d.ts.map +0 -1
  45. package/dist/cli/wt/init.unit.test.js +0 -432
  46. package/dist/cli/wt/init.unit.test.js.map +0 -1
  47. package/dist/cli/wt/interactive-menu.test.d.ts +0 -12
  48. package/dist/cli/wt/interactive-menu.test.d.ts.map +0 -1
  49. package/dist/cli/wt/interactive-menu.test.js +0 -796
  50. package/dist/cli/wt/interactive-menu.test.js.map +0 -1
  51. package/dist/cli/wt/list.test.d.ts +0 -10
  52. package/dist/cli/wt/list.test.d.ts.map +0 -1
  53. package/dist/cli/wt/list.test.js +0 -157
  54. package/dist/cli/wt/list.test.js.map +0 -1
  55. package/dist/cli/wt/prs.test.d.ts +0 -5
  56. package/dist/cli/wt/prs.test.d.ts.map +0 -1
  57. package/dist/cli/wt/prs.test.js +0 -410
  58. package/dist/cli/wt/prs.test.js.map +0 -1
  59. package/dist/cli/wt/run-command.test.d.ts +0 -5
  60. package/dist/cli/wt/run-command.test.d.ts.map +0 -1
  61. package/dist/cli/wt/run-command.test.js +0 -88
  62. package/dist/cli/wt/run-command.test.js.map +0 -1
  63. package/dist/cli/wt/state.test.d.ts +0 -9
  64. package/dist/cli/wt/state.test.d.ts.map +0 -1
  65. package/dist/cli/wt/state.test.js +0 -127
  66. package/dist/cli/wt/state.test.js.map +0 -1
  67. package/dist/cli/wt/wt.test.d.ts +0 -8
  68. package/dist/cli/wt/wt.test.d.ts.map +0 -1
  69. package/dist/cli/wt/wt.test.js +0 -739
  70. package/dist/cli/wt/wt.test.js.map +0 -1
  71. package/dist/cli/wt.unit.test.d.ts +0 -7
  72. package/dist/cli/wt.unit.test.d.ts.map +0 -1
  73. package/dist/cli/wt.unit.test.js +0 -160
  74. package/dist/cli/wt.unit.test.js.map +0 -1
  75. package/dist/cli/wtconfig.test.d.ts +0 -5
  76. package/dist/cli/wtconfig.test.d.ts.map +0 -1
  77. package/dist/cli/wtconfig.test.js +0 -1289
  78. package/dist/cli/wtconfig.test.js.map +0 -1
  79. package/dist/cli/wtlink.test.d.ts +0 -2
  80. package/dist/cli/wtlink.test.d.ts.map +0 -1
  81. package/dist/cli/wtlink.test.js +0 -249
  82. package/dist/cli/wtlink.test.js.map +0 -1
  83. package/dist/cli/wtstate.test.d.ts +0 -5
  84. package/dist/cli/wtstate.test.d.ts.map +0 -1
  85. package/dist/cli/wtstate.test.js +0 -193
  86. package/dist/cli/wtstate.test.js.map +0 -1
  87. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +0 -2
  88. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +0 -1
  89. package/dist/e2e/cleanpr/cleanpr.e2e.test.js +0 -326
  90. package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +0 -1
  91. package/dist/e2e/cli.e2e.test.d.ts +0 -2
  92. package/dist/e2e/cli.e2e.test.d.ts.map +0 -1
  93. package/dist/e2e/cli.e2e.test.js +0 -417
  94. package/dist/e2e/cli.e2e.test.js.map +0 -1
  95. package/dist/e2e/lswt/lswt.e2e.test.d.ts +0 -2
  96. package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +0 -1
  97. package/dist/e2e/lswt/lswt.e2e.test.js +0 -361
  98. package/dist/e2e/lswt/lswt.e2e.test.js.map +0 -1
  99. package/dist/e2e/newpr/newpr.e2e.test.d.ts +0 -2
  100. package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +0 -1
  101. package/dist/e2e/newpr/newpr.e2e.test.js +0 -286
  102. package/dist/e2e/newpr/newpr.e2e.test.js.map +0 -1
  103. package/dist/e2e/newpr/scenarios.e2e.test.d.ts +0 -2
  104. package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +0 -1
  105. package/dist/e2e/newpr/scenarios.e2e.test.js +0 -426
  106. package/dist/e2e/newpr/scenarios.e2e.test.js.map +0 -1
  107. package/dist/e2e/newpr-full-flow.e2e.test.d.ts +0 -2
  108. package/dist/e2e/newpr-full-flow.e2e.test.d.ts.map +0 -1
  109. package/dist/e2e/newpr-full-flow.e2e.test.js +0 -280
  110. package/dist/e2e/newpr-full-flow.e2e.test.js.map +0 -1
  111. package/dist/e2e/prs/prs.e2e.test.d.ts +0 -7
  112. package/dist/e2e/prs/prs.e2e.test.d.ts.map +0 -1
  113. package/dist/e2e/prs/prs.e2e.test.js +0 -606
  114. package/dist/e2e/prs/prs.e2e.test.js.map +0 -1
  115. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +0 -2
  116. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +0 -1
  117. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +0 -298
  118. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +0 -1
  119. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts +0 -8
  120. package/dist/e2e/wt/interactive-menu.e2e.test.d.ts.map +0 -1
  121. package/dist/e2e/wt/interactive-menu.e2e.test.js +0 -583
  122. package/dist/e2e/wt/interactive-menu.e2e.test.js.map +0 -1
  123. package/dist/e2e/wt/wt.e2e.test.d.ts +0 -9
  124. package/dist/e2e/wt/wt.e2e.test.d.ts.map +0 -1
  125. package/dist/e2e/wt/wt.e2e.test.js +0 -597
  126. package/dist/e2e/wt/wt.e2e.test.js.map +0 -1
  127. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +0 -2
  128. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +0 -1
  129. package/dist/e2e/wtlink/wtlink.e2e.test.js +0 -416
  130. package/dist/e2e/wtlink/wtlink.e2e.test.js.map +0 -1
  131. package/dist/integration/git.integration.test.d.ts +0 -2
  132. package/dist/integration/git.integration.test.d.ts.map +0 -1
  133. package/dist/integration/git.integration.test.js +0 -336
  134. package/dist/integration/git.integration.test.js.map +0 -1
  135. package/dist/integration/lswt-remote-pr.integration.test.d.ts +0 -2
  136. package/dist/integration/lswt-remote-pr.integration.test.d.ts.map +0 -1
  137. package/dist/integration/lswt-remote-pr.integration.test.js +0 -222
  138. package/dist/integration/lswt-remote-pr.integration.test.js.map +0 -1
  139. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts +0 -2
  140. package/dist/integration/newpr-branchfrom-head.integration.test.d.ts.map +0 -1
  141. package/dist/integration/newpr-branchfrom-head.integration.test.js +0 -498
  142. package/dist/integration/newpr-branchfrom-head.integration.test.js.map +0 -1
  143. package/dist/integration/newpr.integration.test.d.ts +0 -2
  144. package/dist/integration/newpr.integration.test.d.ts.map +0 -1
  145. package/dist/integration/newpr.integration.test.js +0 -460
  146. package/dist/integration/newpr.integration.test.js.map +0 -1
  147. package/dist/integration/prs.integration.test.d.ts +0 -8
  148. package/dist/integration/prs.integration.test.d.ts.map +0 -1
  149. package/dist/integration/prs.integration.test.js +0 -478
  150. package/dist/integration/prs.integration.test.js.map +0 -1
  151. package/dist/lib/ai/base-provider.test.d.ts +0 -7
  152. package/dist/lib/ai/base-provider.test.d.ts.map +0 -1
  153. package/dist/lib/ai/base-provider.test.js +0 -319
  154. package/dist/lib/ai/base-provider.test.js.map +0 -1
  155. package/dist/lib/ai/cli-provider.test.d.ts +0 -5
  156. package/dist/lib/ai/cli-provider.test.d.ts.map +0 -1
  157. package/dist/lib/ai/cli-provider.test.js +0 -460
  158. package/dist/lib/ai/cli-provider.test.js.map +0 -1
  159. package/dist/lib/ai/fallback-provider.test.d.ts +0 -7
  160. package/dist/lib/ai/fallback-provider.test.d.ts.map +0 -1
  161. package/dist/lib/ai/fallback-provider.test.js +0 -165
  162. package/dist/lib/ai/fallback-provider.test.js.map +0 -1
  163. package/dist/lib/ai/generation-service.test.d.ts +0 -7
  164. package/dist/lib/ai/generation-service.test.d.ts.map +0 -1
  165. package/dist/lib/ai/generation-service.test.js +0 -213
  166. package/dist/lib/ai/generation-service.test.js.map +0 -1
  167. package/dist/lib/ai/provider-manager.test.d.ts +0 -5
  168. package/dist/lib/ai/provider-manager.test.d.ts.map +0 -1
  169. package/dist/lib/ai/provider-manager.test.js +0 -312
  170. package/dist/lib/ai/provider-manager.test.js.map +0 -1
  171. package/dist/lib/ai/repo-docs.test.d.ts +0 -5
  172. package/dist/lib/ai/repo-docs.test.d.ts.map +0 -1
  173. package/dist/lib/ai/repo-docs.test.js +0 -357
  174. package/dist/lib/ai/repo-docs.test.js.map +0 -1
  175. package/dist/lib/cleanpr/args.test.d.ts +0 -2
  176. package/dist/lib/cleanpr/args.test.d.ts.map +0 -1
  177. package/dist/lib/cleanpr/args.test.js +0 -269
  178. package/dist/lib/cleanpr/args.test.js.map +0 -1
  179. package/dist/lib/cleanpr/cleanup.test.d.ts +0 -2
  180. package/dist/lib/cleanpr/cleanup.test.d.ts.map +0 -1
  181. package/dist/lib/cleanpr/cleanup.test.js +0 -296
  182. package/dist/lib/cleanpr/cleanup.test.js.map +0 -1
  183. package/dist/lib/cleanpr/worktree-info.test.d.ts +0 -2
  184. package/dist/lib/cleanpr/worktree-info.test.d.ts.map +0 -1
  185. package/dist/lib/cleanpr/worktree-info.test.js +0 -228
  186. package/dist/lib/cleanpr/worktree-info.test.js.map +0 -1
  187. package/dist/lib/colors.test.d.ts +0 -2
  188. package/dist/lib/colors.test.d.ts.map +0 -1
  189. package/dist/lib/colors.test.js +0 -142
  190. package/dist/lib/colors.test.js.map +0 -1
  191. package/dist/lib/config-editor.test.d.ts +0 -11
  192. package/dist/lib/config-editor.test.d.ts.map +0 -1
  193. package/dist/lib/config-editor.test.js +0 -526
  194. package/dist/lib/config-editor.test.js.map +0 -1
  195. package/dist/lib/config-migration/detector.test.d.ts +0 -5
  196. package/dist/lib/config-migration/detector.test.d.ts.map +0 -1
  197. package/dist/lib/config-migration/detector.test.js +0 -201
  198. package/dist/lib/config-migration/detector.test.js.map +0 -1
  199. package/dist/lib/config-migration/reporter.test.d.ts +0 -5
  200. package/dist/lib/config-migration/reporter.test.d.ts.map +0 -1
  201. package/dist/lib/config-migration/reporter.test.js +0 -305
  202. package/dist/lib/config-migration/reporter.test.js.map +0 -1
  203. package/dist/lib/config-migration/runner.test.d.ts +0 -5
  204. package/dist/lib/config-migration/runner.test.d.ts.map +0 -1
  205. package/dist/lib/config-migration/runner.test.js +0 -235
  206. package/dist/lib/config-migration/runner.test.js.map +0 -1
  207. package/dist/lib/config-validation.test.d.ts +0 -5
  208. package/dist/lib/config-validation.test.d.ts.map +0 -1
  209. package/dist/lib/config-validation.test.js +0 -423
  210. package/dist/lib/config-validation.test.js.map +0 -1
  211. package/dist/lib/config.test.d.ts +0 -2
  212. package/dist/lib/config.test.d.ts.map +0 -1
  213. package/dist/lib/config.test.js +0 -554
  214. package/dist/lib/config.test.js.map +0 -1
  215. package/dist/lib/constants.test.d.ts +0 -5
  216. package/dist/lib/constants.test.d.ts.map +0 -1
  217. package/dist/lib/constants.test.js +0 -180
  218. package/dist/lib/constants.test.js.map +0 -1
  219. package/dist/lib/deprecation.test.d.ts +0 -2
  220. package/dist/lib/deprecation.test.d.ts.map +0 -1
  221. package/dist/lib/deprecation.test.js +0 -71
  222. package/dist/lib/deprecation.test.js.map +0 -1
  223. package/dist/lib/errors.test.d.ts +0 -2
  224. package/dist/lib/errors.test.d.ts.map +0 -1
  225. package/dist/lib/errors.test.js +0 -117
  226. package/dist/lib/errors.test.js.map +0 -1
  227. package/dist/lib/git.test.d.ts +0 -2
  228. package/dist/lib/git.test.d.ts.map +0 -1
  229. package/dist/lib/git.test.js +0 -608
  230. package/dist/lib/git.test.js.map +0 -1
  231. package/dist/lib/github.test.d.ts +0 -2
  232. package/dist/lib/github.test.d.ts.map +0 -1
  233. package/dist/lib/github.test.js +0 -441
  234. package/dist/lib/github.test.js.map +0 -1
  235. package/dist/lib/global-check.test.d.ts +0 -5
  236. package/dist/lib/global-check.test.d.ts.map +0 -1
  237. package/dist/lib/global-check.test.js +0 -150
  238. package/dist/lib/global-check.test.js.map +0 -1
  239. package/dist/lib/global-config.test.d.ts +0 -5
  240. package/dist/lib/global-config.test.d.ts.map +0 -1
  241. package/dist/lib/global-config.test.js +0 -282
  242. package/dist/lib/global-config.test.js.map +0 -1
  243. package/dist/lib/hooks/confirmation.test.d.ts +0 -7
  244. package/dist/lib/hooks/confirmation.test.d.ts.map +0 -1
  245. package/dist/lib/hooks/confirmation.test.js +0 -300
  246. package/dist/lib/hooks/confirmation.test.js.map +0 -1
  247. package/dist/lib/hooks/executor.test.d.ts +0 -5
  248. package/dist/lib/hooks/executor.test.d.ts.map +0 -1
  249. package/dist/lib/hooks/executor.test.js +0 -648
  250. package/dist/lib/hooks/executor.test.js.map +0 -1
  251. package/dist/lib/hooks/templates.test.d.ts +0 -5
  252. package/dist/lib/hooks/templates.test.d.ts.map +0 -1
  253. package/dist/lib/hooks/templates.test.js +0 -163
  254. package/dist/lib/hooks/templates.test.js.map +0 -1
  255. package/dist/lib/hooks/types.test.d.ts +0 -5
  256. package/dist/lib/hooks/types.test.d.ts.map +0 -1
  257. package/dist/lib/hooks/types.test.js +0 -132
  258. package/dist/lib/hooks/types.test.js.map +0 -1
  259. package/dist/lib/json-output.test.d.ts +0 -5
  260. package/dist/lib/json-output.test.d.ts.map +0 -1
  261. package/dist/lib/json-output.test.js +0 -261
  262. package/dist/lib/json-output.test.js.map +0 -1
  263. package/dist/lib/logger.test.d.ts +0 -14
  264. package/dist/lib/logger.test.d.ts.map +0 -1
  265. package/dist/lib/logger.test.js +0 -692
  266. package/dist/lib/logger.test.js.map +0 -1
  267. package/dist/lib/lswt/action-executors.test.d.ts +0 -2
  268. package/dist/lib/lswt/action-executors.test.d.ts.map +0 -1
  269. package/dist/lib/lswt/action-executors.test.js +0 -1127
  270. package/dist/lib/lswt/action-executors.test.js.map +0 -1
  271. package/dist/lib/lswt/actions.test.d.ts +0 -2
  272. package/dist/lib/lswt/actions.test.d.ts.map +0 -1
  273. package/dist/lib/lswt/actions.test.js +0 -497
  274. package/dist/lib/lswt/actions.test.js.map +0 -1
  275. package/dist/lib/lswt/args.test.d.ts +0 -2
  276. package/dist/lib/lswt/args.test.d.ts.map +0 -1
  277. package/dist/lib/lswt/args.test.js +0 -195
  278. package/dist/lib/lswt/args.test.js.map +0 -1
  279. package/dist/lib/lswt/environment.test.d.ts +0 -2
  280. package/dist/lib/lswt/environment.test.d.ts.map +0 -1
  281. package/dist/lib/lswt/environment.test.js +0 -544
  282. package/dist/lib/lswt/environment.test.js.map +0 -1
  283. package/dist/lib/lswt/formatters.test.d.ts +0 -2
  284. package/dist/lib/lswt/formatters.test.d.ts.map +0 -1
  285. package/dist/lib/lswt/formatters.test.js +0 -323
  286. package/dist/lib/lswt/formatters.test.js.map +0 -1
  287. package/dist/lib/lswt/fuzzy-search.test.d.ts +0 -5
  288. package/dist/lib/lswt/fuzzy-search.test.d.ts.map +0 -1
  289. package/dist/lib/lswt/fuzzy-search.test.js +0 -207
  290. package/dist/lib/lswt/fuzzy-search.test.js.map +0 -1
  291. package/dist/lib/lswt/interactive.test.d.ts +0 -2
  292. package/dist/lib/lswt/interactive.test.d.ts.map +0 -1
  293. package/dist/lib/lswt/interactive.test.js +0 -771
  294. package/dist/lib/lswt/interactive.test.js.map +0 -1
  295. package/dist/lib/lswt/table.test.d.ts +0 -5
  296. package/dist/lib/lswt/table.test.d.ts.map +0 -1
  297. package/dist/lib/lswt/table.test.js +0 -262
  298. package/dist/lib/lswt/table.test.js.map +0 -1
  299. package/dist/lib/lswt/worktree-info.test.d.ts +0 -2
  300. package/dist/lib/lswt/worktree-info.test.d.ts.map +0 -1
  301. package/dist/lib/lswt/worktree-info.test.js +0 -484
  302. package/dist/lib/lswt/worktree-info.test.js.map +0 -1
  303. package/dist/lib/newpr/action-deps.test.d.ts +0 -5
  304. package/dist/lib/newpr/action-deps.test.d.ts.map +0 -1
  305. package/dist/lib/newpr/action-deps.test.js +0 -111
  306. package/dist/lib/newpr/action-deps.test.js.map +0 -1
  307. package/dist/lib/newpr/actions.test.d.ts +0 -2
  308. package/dist/lib/newpr/actions.test.d.ts.map +0 -1
  309. package/dist/lib/newpr/actions.test.js +0 -254
  310. package/dist/lib/newpr/actions.test.js.map +0 -1
  311. package/dist/lib/newpr/args.test.d.ts +0 -2
  312. package/dist/lib/newpr/args.test.d.ts.map +0 -1
  313. package/dist/lib/newpr/args.test.js +0 -479
  314. package/dist/lib/newpr/args.test.js.map +0 -1
  315. package/dist/lib/newpr/hook-runner.test.d.ts +0 -7
  316. package/dist/lib/newpr/hook-runner.test.d.ts.map +0 -1
  317. package/dist/lib/newpr/hook-runner.test.js +0 -422
  318. package/dist/lib/newpr/hook-runner.test.js.map +0 -1
  319. package/dist/lib/newpr/plan-generator.test.d.ts +0 -7
  320. package/dist/lib/newpr/plan-generator.test.d.ts.map +0 -1
  321. package/dist/lib/newpr/plan-generator.test.js +0 -387
  322. package/dist/lib/newpr/plan-generator.test.js.map +0 -1
  323. package/dist/lib/newpr/scenario-handler.test.d.ts +0 -2
  324. package/dist/lib/newpr/scenario-handler.test.d.ts.map +0 -1
  325. package/dist/lib/newpr/scenario-handler.test.js +0 -256
  326. package/dist/lib/newpr/scenario-handler.test.js.map +0 -1
  327. package/dist/lib/prompts.test.d.ts +0 -2
  328. package/dist/lib/prompts.test.d.ts.map +0 -1
  329. package/dist/lib/prompts.test.js +0 -807
  330. package/dist/lib/prompts.test.js.map +0 -1
  331. package/dist/lib/prs/actions.test.d.ts +0 -5
  332. package/dist/lib/prs/actions.test.d.ts.map +0 -1
  333. package/dist/lib/prs/actions.test.js +0 -356
  334. package/dist/lib/prs/actions.test.js.map +0 -1
  335. package/dist/lib/prs/command.test.d.ts +0 -11
  336. package/dist/lib/prs/command.test.d.ts.map +0 -1
  337. package/dist/lib/prs/command.test.js +0 -409
  338. package/dist/lib/prs/command.test.js.map +0 -1
  339. package/dist/lib/prs/data.test.d.ts +0 -5
  340. package/dist/lib/prs/data.test.d.ts.map +0 -1
  341. package/dist/lib/prs/data.test.js +0 -417
  342. package/dist/lib/prs/data.test.js.map +0 -1
  343. package/dist/lib/prs/details.test.d.ts +0 -5
  344. package/dist/lib/prs/details.test.d.ts.map +0 -1
  345. package/dist/lib/prs/details.test.js +0 -325
  346. package/dist/lib/prs/details.test.js.map +0 -1
  347. package/dist/lib/prs/filters.test.d.ts +0 -5
  348. package/dist/lib/prs/filters.test.d.ts.map +0 -1
  349. package/dist/lib/prs/filters.test.js +0 -312
  350. package/dist/lib/prs/filters.test.js.map +0 -1
  351. package/dist/lib/prs/formatters.test.d.ts +0 -2
  352. package/dist/lib/prs/formatters.test.d.ts.map +0 -1
  353. package/dist/lib/prs/formatters.test.js +0 -387
  354. package/dist/lib/prs/formatters.test.js.map +0 -1
  355. package/dist/lib/prs/interactive.test.d.ts +0 -5
  356. package/dist/lib/prs/interactive.test.d.ts.map +0 -1
  357. package/dist/lib/prs/interactive.test.js +0 -517
  358. package/dist/lib/prs/interactive.test.js.map +0 -1
  359. package/dist/lib/schema.test.d.ts +0 -10
  360. package/dist/lib/schema.test.d.ts.map +0 -1
  361. package/dist/lib/schema.test.js +0 -309
  362. package/dist/lib/schema.test.js.map +0 -1
  363. package/dist/lib/state-detection.test.d.ts +0 -2
  364. package/dist/lib/state-detection.test.d.ts.map +0 -1
  365. package/dist/lib/state-detection.test.js +0 -451
  366. package/dist/lib/state-detection.test.js.map +0 -1
  367. package/dist/lib/ui/error.test.d.ts +0 -2
  368. package/dist/lib/ui/error.test.d.ts.map +0 -1
  369. package/dist/lib/ui/error.test.js +0 -143
  370. package/dist/lib/ui/error.test.js.map +0 -1
  371. package/dist/lib/ui/output.test.d.ts +0 -2
  372. package/dist/lib/ui/output.test.d.ts.map +0 -1
  373. package/dist/lib/ui/output.test.js +0 -59
  374. package/dist/lib/ui/output.test.js.map +0 -1
  375. package/dist/lib/ui/status.test.d.ts +0 -2
  376. package/dist/lib/ui/status.test.d.ts.map +0 -1
  377. package/dist/lib/ui/status.test.js +0 -158
  378. package/dist/lib/ui/status.test.js.map +0 -1
  379. package/dist/lib/ui/table.test.d.ts +0 -2
  380. package/dist/lib/ui/table.test.d.ts.map +0 -1
  381. package/dist/lib/ui/table.test.js +0 -115
  382. package/dist/lib/ui/table.test.js.map +0 -1
  383. package/dist/lib/ui/theme.test.d.ts +0 -2
  384. package/dist/lib/ui/theme.test.d.ts.map +0 -1
  385. package/dist/lib/ui/theme.test.js +0 -76
  386. package/dist/lib/ui/theme.test.js.map +0 -1
  387. package/dist/lib/wtconfig/config-manager.test.d.ts +0 -5
  388. package/dist/lib/wtconfig/config-manager.test.d.ts.map +0 -1
  389. package/dist/lib/wtconfig/config-manager.test.js +0 -501
  390. package/dist/lib/wtconfig/config-manager.test.js.map +0 -1
  391. package/dist/lib/wtconfig/environment.test.d.ts +0 -5
  392. package/dist/lib/wtconfig/environment.test.d.ts.map +0 -1
  393. package/dist/lib/wtconfig/environment.test.js +0 -285
  394. package/dist/lib/wtconfig/environment.test.js.map +0 -1
  395. package/dist/lib/wtlink/config-manifest.test.d.ts +0 -2
  396. package/dist/lib/wtlink/config-manifest.test.d.ts.map +0 -1
  397. package/dist/lib/wtlink/config-manifest.test.js +0 -486
  398. package/dist/lib/wtlink/config-manifest.test.js.map +0 -1
  399. package/dist/lib/wtlink/link-configs.test.d.ts +0 -2
  400. package/dist/lib/wtlink/link-configs.test.d.ts.map +0 -1
  401. package/dist/lib/wtlink/link-configs.test.js +0 -612
  402. package/dist/lib/wtlink/link-configs.test.js.map +0 -1
  403. package/dist/lib/wtlink/main-menu.test.d.ts +0 -5
  404. package/dist/lib/wtlink/main-menu.test.d.ts.map +0 -1
  405. package/dist/lib/wtlink/main-menu.test.js +0 -126
  406. package/dist/lib/wtlink/main-menu.test.js.map +0 -1
  407. package/dist/lib/wtlink/manage-manifest.test.d.ts +0 -2
  408. package/dist/lib/wtlink/manage-manifest.test.d.ts.map +0 -1
  409. package/dist/lib/wtlink/manage-manifest.test.js +0 -714
  410. package/dist/lib/wtlink/manage-manifest.test.js.map +0 -1
  411. package/dist/lib/wtlink/validate-manifest.test.d.ts +0 -2
  412. package/dist/lib/wtlink/validate-manifest.test.d.ts.map +0 -1
  413. package/dist/lib/wtlink/validate-manifest.test.js +0 -220
  414. package/dist/lib/wtlink/validate-manifest.test.js.map +0 -1
  415. package/dist/lib/wtstate/analyze.test.d.ts +0 -5
  416. package/dist/lib/wtstate/analyze.test.d.ts.map +0 -1
  417. package/dist/lib/wtstate/analyze.test.js +0 -282
  418. package/dist/lib/wtstate/analyze.test.js.map +0 -1
  419. package/dist/lib/wtstate/args.test.d.ts +0 -5
  420. package/dist/lib/wtstate/args.test.d.ts.map +0 -1
  421. package/dist/lib/wtstate/args.test.js +0 -120
  422. package/dist/lib/wtstate/args.test.js.map +0 -1
  423. package/dist/mcp/server.test.d.ts +0 -9
  424. package/dist/mcp/server.test.d.ts.map +0 -1
  425. package/dist/mcp/server.test.js +0 -550
  426. package/dist/mcp/server.test.js.map +0 -1
@@ -1,692 +0,0 @@
1
- /**
2
- * Comprehensive tests for logger.ts (consola-based)
3
- *
4
- * Covers:
5
- * - parseLogLevel mapping
6
- * - LogLevel compatibility export
7
- * - initializeLogger level resolution (flag precedence)
8
- * - DEBUG=newpr deprecation path
9
- * - AuditFileReporter (write, JSONL, directory creation, rotation)
10
- * - ConditionalStderrReporter (verbose/non-verbose conditional output)
11
- * - Process exit handler (synchronous audit summary)
12
- */
13
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
14
- import fs from 'fs';
15
- import path from 'path';
16
- import os from 'os';
17
- import { parseLogLevel, initializeLogger, logger, LogLevel, setAuditContext, _resetForTesting, } from './logger.js';
18
- // ---------------------------------------------------------------------------
19
- // Test-level helpers
20
- // ---------------------------------------------------------------------------
21
- /** Saved env vars to restore after each test */
22
- let savedEnv;
23
- /** Per-test temp directory */
24
- let tempDir;
25
- function createTempDir() {
26
- return fs.mkdtempSync(path.join(os.tmpdir(), 'logger-test-'));
27
- }
28
- function cleanupTempDir(dir) {
29
- if (dir && fs.existsSync(dir)) {
30
- fs.rmSync(dir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
31
- }
32
- }
33
- /**
34
- * Wait for an audit log file to have non-empty content.
35
- * Polls every 50ms up to the given timeout (default 2s).
36
- * WriteStream flush timing varies across platforms/Node versions.
37
- */
38
- async function waitForAuditContent(filePath, timeoutMs = 2000) {
39
- const start = Date.now();
40
- while (Date.now() - start < timeoutMs) {
41
- try {
42
- const content = fs.readFileSync(filePath, 'utf-8');
43
- if (content.length > 0)
44
- return content;
45
- }
46
- catch {
47
- // file may not exist yet
48
- }
49
- await new Promise((resolve) => setTimeout(resolve, 50));
50
- }
51
- // Final attempt — return whatever is there (may be empty, test will fail with a clear message)
52
- try {
53
- return fs.readFileSync(filePath, 'utf-8');
54
- }
55
- catch {
56
- return '';
57
- }
58
- }
59
- // ---------------------------------------------------------------------------
60
- // parseLogLevel
61
- // ---------------------------------------------------------------------------
62
- describe('parseLogLevel', () => {
63
- it('parses "debug" to 4', () => {
64
- expect(parseLogLevel('debug')).toBe(4);
65
- });
66
- it('parses "info" to 3', () => {
67
- expect(parseLogLevel('info')).toBe(3);
68
- });
69
- it('parses "warn" to 1', () => {
70
- expect(parseLogLevel('warn')).toBe(1);
71
- });
72
- it('parses "warning" to 1', () => {
73
- expect(parseLogLevel('warning')).toBe(1);
74
- });
75
- it('parses "error" to 0', () => {
76
- expect(parseLogLevel('error')).toBe(0);
77
- });
78
- it('parses "silent" to -999', () => {
79
- expect(parseLogLevel('silent')).toBe(-999);
80
- });
81
- it('parses "trace" to 5', () => {
82
- expect(parseLogLevel('trace')).toBe(5);
83
- });
84
- it('parses "verbose" to 4 (alias for debug)', () => {
85
- expect(parseLogLevel('verbose')).toBe(4);
86
- });
87
- it('is case insensitive — "DEBUG" returns 4', () => {
88
- expect(parseLogLevel('DEBUG')).toBe(4);
89
- });
90
- it('is case insensitive — mixed case "Error" returns 0', () => {
91
- expect(parseLogLevel('Error')).toBe(0);
92
- });
93
- it('returns undefined for "unknown"', () => {
94
- expect(parseLogLevel('unknown')).toBeUndefined();
95
- });
96
- it('returns undefined for empty string', () => {
97
- expect(parseLogLevel('')).toBeUndefined();
98
- });
99
- it('returns undefined for numeric strings', () => {
100
- expect(parseLogLevel('99')).toBeUndefined();
101
- expect(parseLogLevel('3')).toBeUndefined();
102
- });
103
- it('trims whitespace', () => {
104
- expect(parseLogLevel(' info ')).toBe(3);
105
- expect(parseLogLevel('\tdebug\n')).toBe(4);
106
- });
107
- });
108
- // ---------------------------------------------------------------------------
109
- // LogLevel compatibility export
110
- // ---------------------------------------------------------------------------
111
- describe('LogLevel compatibility export', () => {
112
- it('LogLevel.SILENT exists and equals -999', () => {
113
- expect(LogLevel.SILENT).toBe(-999);
114
- });
115
- it('LogLevel.ERROR equals 0', () => {
116
- expect(LogLevel.ERROR).toBe(0);
117
- });
118
- it('LogLevel.WARN equals 1', () => {
119
- expect(LogLevel.WARN).toBe(1);
120
- });
121
- it('LogLevel.INFO equals 3', () => {
122
- expect(LogLevel.INFO).toBe(3);
123
- });
124
- it('LogLevel.DEBUG equals 4', () => {
125
- expect(LogLevel.DEBUG).toBe(4);
126
- });
127
- it('LogLevel.TRACE equals 5', () => {
128
- expect(LogLevel.TRACE).toBe(5);
129
- });
130
- });
131
- // ---------------------------------------------------------------------------
132
- // Logger singleton
133
- // ---------------------------------------------------------------------------
134
- describe('Logger singleton', () => {
135
- beforeEach(() => {
136
- _resetForTesting();
137
- });
138
- it('returns same instance on repeated access', () => {
139
- const instance1 = logger;
140
- const instance2 = logger;
141
- expect(instance1).toBe(instance2);
142
- });
143
- it('defaults to level 3 (INFO) after reset', () => {
144
- expect(logger.level).toBe(3);
145
- });
146
- it('has standard logging methods', () => {
147
- expect(typeof logger.error).toBe('function');
148
- expect(typeof logger.warn).toBe('function');
149
- expect(typeof logger.info).toBe('function');
150
- expect(typeof logger.debug).toBe('function');
151
- expect(typeof logger.trace).toBe('function');
152
- });
153
- });
154
- // ---------------------------------------------------------------------------
155
- // initializeLogger — level resolution
156
- // ---------------------------------------------------------------------------
157
- describe('initializeLogger level resolution', () => {
158
- beforeEach(() => {
159
- _resetForTesting();
160
- savedEnv = {
161
- GWT_LOG_LEVEL: process.env.GWT_LOG_LEVEL,
162
- DEBUG: process.env.DEBUG,
163
- NO_COLOR: process.env.NO_COLOR,
164
- };
165
- delete process.env.GWT_LOG_LEVEL;
166
- delete process.env.DEBUG;
167
- });
168
- afterEach(() => {
169
- _resetForTesting();
170
- for (const [key, value] of Object.entries(savedEnv)) {
171
- if (value === undefined) {
172
- delete process.env[key];
173
- }
174
- else {
175
- process.env[key] = value;
176
- }
177
- }
178
- });
179
- it('quiet flag sets level to 0 (error only) regardless of env', () => {
180
- process.env.GWT_LOG_LEVEL = 'debug';
181
- initializeLogger({ quiet: true });
182
- expect(logger.level).toBe(0);
183
- });
184
- it('verbose flag sets level to 4 (debug)', () => {
185
- initializeLogger({ verbose: true });
186
- expect(logger.level).toBe(4);
187
- });
188
- it('GWT_LOG_LEVEL=debug with no flags sets level to 4', () => {
189
- process.env.GWT_LOG_LEVEL = 'debug';
190
- initializeLogger({});
191
- expect(logger.level).toBe(4);
192
- });
193
- it('GWT_LOG_LEVEL=warn with no flags sets level to 1', () => {
194
- process.env.GWT_LOG_LEVEL = 'warn';
195
- initializeLogger({});
196
- expect(logger.level).toBe(1);
197
- });
198
- it('quiet flag overrides GWT_LOG_LEVEL=debug (CLI flag wins)', () => {
199
- process.env.GWT_LOG_LEVEL = 'debug';
200
- initializeLogger({ quiet: true });
201
- expect(logger.level).toBe(0);
202
- });
203
- it('no flags and no env var defaults to level 3 (INFO)', () => {
204
- initializeLogger({});
205
- expect(logger.level).toBe(3);
206
- });
207
- it('quiet flag takes priority over verbose when both are set', () => {
208
- initializeLogger({ quiet: true, verbose: true });
209
- expect(logger.level).toBe(0);
210
- });
211
- it('GWT_LOG_LEVEL with invalid value falls back to INFO', () => {
212
- process.env.GWT_LOG_LEVEL = 'bananas';
213
- initializeLogger({});
214
- expect(logger.level).toBe(3);
215
- });
216
- it('verbose flag overrides GWT_LOG_LEVEL=warn (CLI flag wins)', () => {
217
- process.env.GWT_LOG_LEVEL = 'warn';
218
- initializeLogger({ verbose: true });
219
- expect(logger.level).toBe(4);
220
- });
221
- it('sets reporters when called', () => {
222
- initializeLogger({});
223
- expect(logger.options.reporters).toBeDefined();
224
- expect(logger.options.reporters.length).toBeGreaterThan(0);
225
- });
226
- });
227
- // ---------------------------------------------------------------------------
228
- // DEBUG=newpr deprecation path
229
- // ---------------------------------------------------------------------------
230
- describe('DEBUG=newpr deprecation path', () => {
231
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
232
- let stderrSpy;
233
- beforeEach(() => {
234
- _resetForTesting();
235
- savedEnv = {
236
- GWT_LOG_LEVEL: process.env.GWT_LOG_LEVEL,
237
- DEBUG: process.env.DEBUG,
238
- };
239
- delete process.env.GWT_LOG_LEVEL;
240
- delete process.env.DEBUG;
241
- stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
242
- });
243
- afterEach(() => {
244
- stderrSpy.mockRestore();
245
- _resetForTesting();
246
- for (const [key, value] of Object.entries(savedEnv)) {
247
- if (value === undefined) {
248
- delete process.env[key];
249
- }
250
- else {
251
- process.env[key] = value;
252
- }
253
- }
254
- });
255
- it('DEBUG=newpr sets level to 4 (debug) and prints deprecation warning', () => {
256
- process.env.DEBUG = 'newpr';
257
- initializeLogger({});
258
- expect(logger.level).toBe(4);
259
- expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('WARNING: DEBUG=newpr is deprecated'));
260
- });
261
- it('DEBUG=newpr deprecation warning fires exactly once across multiple calls', () => {
262
- process.env.DEBUG = 'newpr';
263
- initializeLogger({});
264
- initializeLogger({});
265
- const deprecationCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('deprecated'));
266
- expect(deprecationCalls).toHaveLength(1);
267
- });
268
- it('DEBUG=* activates debug level and prints deprecation warning', () => {
269
- process.env.DEBUG = '*';
270
- initializeLogger({});
271
- expect(logger.level).toBe(4);
272
- expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('deprecated'));
273
- });
274
- it('DEBUG=1 activates debug level and prints deprecation warning', () => {
275
- process.env.DEBUG = '1';
276
- initializeLogger({});
277
- expect(logger.level).toBe(4);
278
- expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('deprecated'));
279
- });
280
- it('DEBUG=something_else does NOT activate debug — level stays at default', () => {
281
- process.env.DEBUG = 'something_else';
282
- initializeLogger({});
283
- expect(logger.level).toBe(3);
284
- const deprecationCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('deprecated'));
285
- expect(deprecationCalls).toHaveLength(0);
286
- });
287
- it('GWT_LOG_LEVEL takes priority over DEBUG=newpr', () => {
288
- process.env.GWT_LOG_LEVEL = 'warn';
289
- process.env.DEBUG = 'newpr';
290
- initializeLogger({});
291
- expect(logger.level).toBe(1);
292
- });
293
- });
294
- // ---------------------------------------------------------------------------
295
- // _resetForTesting
296
- // ---------------------------------------------------------------------------
297
- describe('_resetForTesting', () => {
298
- it('resets logger level to INFO (3)', () => {
299
- logger.level = 0;
300
- _resetForTesting();
301
- expect(logger.level).toBe(3);
302
- });
303
- it('clears reporters', () => {
304
- initializeLogger({ verbose: true });
305
- _resetForTesting();
306
- expect(logger.options.reporters).toEqual([]);
307
- });
308
- it('resets deprecation warning flag so it can fire again', () => {
309
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
310
- const origDebug = process.env.DEBUG;
311
- const origGwt = process.env.GWT_LOG_LEVEL;
312
- delete process.env.GWT_LOG_LEVEL;
313
- process.env.DEBUG = 'newpr';
314
- initializeLogger({});
315
- _resetForTesting();
316
- delete process.env.GWT_LOG_LEVEL;
317
- process.env.DEBUG = 'newpr';
318
- initializeLogger({});
319
- const deprecationCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('deprecated'));
320
- expect(deprecationCalls).toHaveLength(2);
321
- stderrSpy.mockRestore();
322
- if (origDebug === undefined)
323
- delete process.env.DEBUG;
324
- else
325
- process.env.DEBUG = origDebug;
326
- if (origGwt === undefined)
327
- delete process.env.GWT_LOG_LEVEL;
328
- else
329
- process.env.GWT_LOG_LEVEL = origGwt;
330
- });
331
- });
332
- // ---------------------------------------------------------------------------
333
- // AuditFileReporter
334
- // ---------------------------------------------------------------------------
335
- describe('AuditFileReporter', () => {
336
- beforeEach(() => {
337
- _resetForTesting();
338
- tempDir = createTempDir();
339
- savedEnv = {
340
- GWT_LOG_LEVEL: process.env.GWT_LOG_LEVEL,
341
- DEBUG: process.env.DEBUG,
342
- };
343
- delete process.env.GWT_LOG_LEVEL;
344
- delete process.env.DEBUG;
345
- });
346
- afterEach(() => {
347
- _resetForTesting();
348
- cleanupTempDir(tempDir);
349
- for (const [key, value] of Object.entries(savedEnv)) {
350
- if (value === undefined) {
351
- delete process.env[key];
352
- }
353
- else {
354
- process.env[key] = value;
355
- }
356
- }
357
- });
358
- it('writes a log entry to the audit log file', async () => {
359
- const constantsMod = await import('./constants.js');
360
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
361
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
362
- initializeLogger({ commandName: 'test-cmd' });
363
- logger.info('test audit message');
364
- const auditPath = path.join(tempDir, 'audit.log');
365
- const content = await waitForAuditContent(auditPath);
366
- expect(content).toContain('test audit message');
367
- stderrSpy.mockRestore();
368
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
369
- });
370
- it('audit log entries contain timestamp, level, and message', async () => {
371
- const constantsMod = await import('./constants.js');
372
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
373
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
374
- initializeLogger({ commandName: 'test-cmd' });
375
- logger.warn('something went wrong');
376
- const auditPath = path.join(tempDir, 'audit.log');
377
- const content = await waitForAuditContent(auditPath);
378
- expect(content).toMatch(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
379
- expect(content).toMatch(/WARN/);
380
- expect(content).toContain('something went wrong');
381
- stderrSpy.mockRestore();
382
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
383
- });
384
- it('writes JSONL entries when json mode is active', async () => {
385
- const constantsMod = await import('./constants.js');
386
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
387
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
388
- initializeLogger({ json: true, commandName: 'test-cmd' });
389
- logger.info('json test message');
390
- const auditPath = path.join(tempDir, 'audit.log');
391
- const content = (await waitForAuditContent(auditPath)).trim();
392
- const lines = content.split('\n').filter((l) => l.trim().length > 0);
393
- for (const line of lines) {
394
- const parsed = JSON.parse(line);
395
- expect(parsed).toHaveProperty('timestamp');
396
- expect(parsed).toHaveProperty('level');
397
- expect(parsed).toHaveProperty('message');
398
- }
399
- const hasMessage = lines.some((line) => {
400
- const parsed = JSON.parse(line);
401
- return parsed.message.includes('json test message');
402
- });
403
- expect(hasMessage).toBe(true);
404
- stderrSpy.mockRestore();
405
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
406
- });
407
- it('creates audit directory automatically if it does not exist', async () => {
408
- const nestedDir = path.join(tempDir, 'nested', 'subdir');
409
- const constantsMod = await import('./constants.js');
410
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(nestedDir);
411
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
412
- expect(fs.existsSync(nestedDir)).toBe(false);
413
- initializeLogger({ commandName: 'test-cmd' });
414
- expect(fs.existsSync(nestedDir)).toBe(true);
415
- stderrSpy.mockRestore();
416
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
417
- });
418
- });
419
- // ---------------------------------------------------------------------------
420
- // Rotation
421
- // ---------------------------------------------------------------------------
422
- describe('Audit log rotation', () => {
423
- beforeEach(() => {
424
- _resetForTesting();
425
- tempDir = createTempDir();
426
- savedEnv = {
427
- GWT_LOG_LEVEL: process.env.GWT_LOG_LEVEL,
428
- DEBUG: process.env.DEBUG,
429
- };
430
- delete process.env.GWT_LOG_LEVEL;
431
- delete process.env.DEBUG;
432
- });
433
- afterEach(() => {
434
- _resetForTesting();
435
- cleanupTempDir(tempDir);
436
- for (const [key, value] of Object.entries(savedEnv)) {
437
- if (value === undefined) {
438
- delete process.env[key];
439
- }
440
- else {
441
- process.env[key] = value;
442
- }
443
- }
444
- });
445
- it('rotates a file larger than 10MB to audit.log.1', async () => {
446
- const constantsMod = await import('./constants.js');
447
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
448
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
449
- const auditPath = path.join(tempDir, 'audit.log');
450
- const bigContent = 'x'.repeat(10 * 1024 * 1024 + 100);
451
- fs.writeFileSync(auditPath, bigContent);
452
- initializeLogger({ commandName: 'test-cmd' });
453
- expect(fs.existsSync(path.join(tempDir, 'audit.log.1'))).toBe(true);
454
- const rotatedContent = fs.readFileSync(path.join(tempDir, 'audit.log.1'), 'utf-8');
455
- expect(rotatedContent).toBe(bigContent);
456
- logger.info('post-rotation entry');
457
- await waitForAuditContent(auditPath);
458
- expect(fs.existsSync(auditPath)).toBe(true);
459
- const newSize = fs.statSync(auditPath).size;
460
- expect(newSize).toBeLessThan(10 * 1024 * 1024);
461
- stderrSpy.mockRestore();
462
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
463
- });
464
- it('shifts existing rotated files: .1 becomes .2, original becomes .1, oldest deleted', async () => {
465
- const constantsMod = await import('./constants.js');
466
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
467
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
468
- const auditPath = path.join(tempDir, 'audit.log');
469
- const bigContent = 'x'.repeat(10 * 1024 * 1024 + 100);
470
- fs.writeFileSync(auditPath, bigContent);
471
- fs.writeFileSync(auditPath + '.1', 'rotated-1-content');
472
- fs.writeFileSync(auditPath + '.2', 'rotated-2-content-to-be-deleted');
473
- initializeLogger({ commandName: 'test-cmd' });
474
- expect(fs.readFileSync(auditPath + '.2', 'utf-8')).toBe('rotated-1-content');
475
- expect(fs.readFileSync(auditPath + '.1', 'utf-8')).toBe(bigContent);
476
- stderrSpy.mockRestore();
477
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
478
- });
479
- it('rotation failure does not crash the tool', async () => {
480
- const constantsMod = await import('./constants.js');
481
- const badDir = path.join(tempDir, 'readonly-test');
482
- fs.mkdirSync(badDir);
483
- const auditPath = path.join(badDir, 'audit.log');
484
- const bigContent = 'x'.repeat(10 * 1024 * 1024 + 100);
485
- fs.writeFileSync(auditPath, bigContent);
486
- fs.chmodSync(badDir, 0o444);
487
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(badDir);
488
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
489
- expect(() => initializeLogger({ commandName: 'test-cmd' })).not.toThrow();
490
- fs.chmodSync(badDir, 0o755);
491
- stderrSpy.mockRestore();
492
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
493
- });
494
- });
495
- // ---------------------------------------------------------------------------
496
- // ConditionalStderrReporter
497
- // ---------------------------------------------------------------------------
498
- describe('ConditionalStderrReporter', () => {
499
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
500
- let stderrSpy;
501
- beforeEach(() => {
502
- _resetForTesting();
503
- savedEnv = {
504
- GWT_LOG_LEVEL: process.env.GWT_LOG_LEVEL,
505
- DEBUG: process.env.DEBUG,
506
- };
507
- delete process.env.GWT_LOG_LEVEL;
508
- delete process.env.DEBUG;
509
- stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
510
- });
511
- afterEach(() => {
512
- stderrSpy.mockRestore();
513
- _resetForTesting();
514
- for (const [key, value] of Object.entries(savedEnv)) {
515
- if (value === undefined) {
516
- delete process.env[key];
517
- }
518
- else {
519
- process.env[key] = value;
520
- }
521
- }
522
- });
523
- describe('non-verbose mode (default)', () => {
524
- beforeEach(() => {
525
- initializeLogger({});
526
- });
527
- it('error writes to stderr', () => {
528
- logger.error('err-msg');
529
- const errorCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('err-msg'));
530
- expect(errorCalls.length).toBeGreaterThan(0);
531
- });
532
- it('warn writes to stderr', () => {
533
- logger.warn('wrn-msg');
534
- const warnCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('wrn-msg'));
535
- expect(warnCalls.length).toBeGreaterThan(0);
536
- });
537
- it('info does NOT write to stderr', () => {
538
- logger.info('inf-msg');
539
- const infoCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('inf-msg'));
540
- expect(infoCalls.length).toBe(0);
541
- });
542
- it('debug does NOT write to stderr', () => {
543
- logger.debug('dbg-msg');
544
- const debugCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('dbg-msg'));
545
- expect(debugCalls.length).toBe(0);
546
- });
547
- });
548
- describe('verbose mode', () => {
549
- beforeEach(() => {
550
- initializeLogger({ verbose: true });
551
- });
552
- it('error writes to stderr', () => {
553
- logger.error('err-verbose');
554
- const errorCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('err-verbose'));
555
- expect(errorCalls.length).toBeGreaterThan(0);
556
- });
557
- it('warn writes to stderr', () => {
558
- logger.warn('wrn-verbose');
559
- const warnCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('wrn-verbose'));
560
- expect(warnCalls.length).toBeGreaterThan(0);
561
- });
562
- it('info writes to stderr in verbose mode', () => {
563
- logger.info('inf-verbose');
564
- const infoCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('inf-verbose'));
565
- expect(infoCalls.length).toBeGreaterThan(0);
566
- });
567
- it('debug writes to stderr in verbose mode', () => {
568
- logger.debug('dbg-verbose');
569
- const debugCalls = stderrSpy.mock.calls.filter((call) => typeof call[0] === 'string' && call[0].includes('dbg-verbose'));
570
- expect(debugCalls.length).toBeGreaterThan(0);
571
- });
572
- });
573
- });
574
- // ---------------------------------------------------------------------------
575
- // Process exit handler / audit session summary
576
- // ---------------------------------------------------------------------------
577
- describe('Process exit handler', () => {
578
- beforeEach(() => {
579
- _resetForTesting();
580
- tempDir = createTempDir();
581
- savedEnv = {
582
- GWT_LOG_LEVEL: process.env.GWT_LOG_LEVEL,
583
- DEBUG: process.env.DEBUG,
584
- };
585
- delete process.env.GWT_LOG_LEVEL;
586
- delete process.env.DEBUG;
587
- });
588
- afterEach(() => {
589
- _resetForTesting();
590
- cleanupTempDir(tempDir);
591
- for (const [key, value] of Object.entries(savedEnv)) {
592
- if (value === undefined) {
593
- delete process.env[key];
594
- }
595
- else {
596
- process.env[key] = value;
597
- }
598
- }
599
- });
600
- it('exit handler writes audit summary via fs.appendFileSync', async () => {
601
- const constantsMod = await import('./constants.js');
602
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
603
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
604
- const appendSpy = vi.spyOn(fs, 'appendFileSync');
605
- initializeLogger({ commandName: 'test-exit' });
606
- setAuditContext({ prNumber: 42 });
607
- process.emit('exit', 0);
608
- expect(appendSpy).toHaveBeenCalled();
609
- const lastCall = appendSpy.mock.calls.find((call) => typeof call[1] === 'string' && call[1].includes('test-exit'));
610
- expect(lastCall).toBeDefined();
611
- const writtenContent = lastCall[1];
612
- expect(writtenContent).toContain('test-exit');
613
- expect(writtenContent).toContain('exit=0');
614
- appendSpy.mockRestore();
615
- stderrSpy.mockRestore();
616
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
617
- });
618
- it('exit handler includes duration as a positive number', async () => {
619
- const constantsMod = await import('./constants.js');
620
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
621
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
622
- const appendSpy = vi.spyOn(fs, 'appendFileSync');
623
- initializeLogger({ commandName: 'duration-test' });
624
- await new Promise((resolve) => setTimeout(resolve, 50));
625
- process.emit('exit', 0);
626
- const exitCall = appendSpy.mock.calls.find((call) => typeof call[1] === 'string' && call[1].includes('duration-test'));
627
- expect(exitCall).toBeDefined();
628
- const writtenContent = exitCall[1];
629
- const durationMatch = writtenContent.match(/duration=(\d+)ms/);
630
- expect(durationMatch).toBeTruthy();
631
- const duration = parseInt(durationMatch[1], 10);
632
- expect(duration).toBeGreaterThanOrEqual(0);
633
- appendSpy.mockRestore();
634
- stderrSpy.mockRestore();
635
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
636
- });
637
- it('exit handler writes JSON format when json mode is active', async () => {
638
- const constantsMod = await import('./constants.js');
639
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
640
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
641
- const appendSpy = vi.spyOn(fs, 'appendFileSync');
642
- initializeLogger({ json: true, commandName: 'json-exit-test' });
643
- setAuditContext({ prNumber: 99 });
644
- process.emit('exit', 1);
645
- const exitCall = appendSpy.mock.calls.find((call) => typeof call[1] === 'string' && call[1].includes('json-exit-test'));
646
- expect(exitCall).toBeDefined();
647
- const writtenContent = exitCall[1].trim();
648
- const parsed = JSON.parse(writtenContent);
649
- expect(parsed.command).toBe('json-exit-test');
650
- expect(parsed.exitCode).toBe(1);
651
- expect(parsed.prNumber).toBe(99);
652
- expect(parsed.type).toBe('session');
653
- expect(parsed.durationMs).toBeGreaterThanOrEqual(0);
654
- appendSpy.mockRestore();
655
- stderrSpy.mockRestore();
656
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
657
- });
658
- it('exit handler fails silently if audit log path is inaccessible', async () => {
659
- const constantsMod = await import('./constants.js');
660
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue('/nonexistent/path/deep/nest');
661
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
662
- initializeLogger({ commandName: 'fail-silently-test' });
663
- expect(() => process.emit('exit', 0)).not.toThrow();
664
- stderrSpy.mockRestore();
665
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
666
- });
667
- });
668
- // ---------------------------------------------------------------------------
669
- // setAuditContext
670
- // ---------------------------------------------------------------------------
671
- describe('setAuditContext', () => {
672
- beforeEach(() => {
673
- _resetForTesting();
674
- });
675
- it('merges additional metadata into audit context', async () => {
676
- const constantsMod = await import('./constants.js');
677
- const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
678
- tempDir = createTempDir();
679
- vi.spyOn(constantsMod, 'getGlobalDataDir').mockReturnValue(tempDir);
680
- const appendSpy = vi.spyOn(fs, 'appendFileSync');
681
- initializeLogger({ commandName: 'context-test' });
682
- setAuditContext({ worktreePath: '/tmp/worktree', prNumber: 123 });
683
- process.emit('exit', 0);
684
- const exitCall = appendSpy.mock.calls.find((call) => typeof call[1] === 'string' && call[1].includes('context-test'));
685
- expect(exitCall).toBeDefined();
686
- appendSpy.mockRestore();
687
- stderrSpy.mockRestore();
688
- vi.mocked(constantsMod.getGlobalDataDir).mockRestore();
689
- cleanupTempDir(tempDir);
690
- });
691
- });
692
- //# sourceMappingURL=logger.test.js.map