@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,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