@poetic-ai/poetic 1.42.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 (782) hide show
  1. package/.github/SECURITY.md +47 -0
  2. package/.nvmrc +1 -0
  3. package/.poetic/README.md +37 -0
  4. package/.poetic/providers/catalog.json +12051 -0
  5. package/.poetic/providers/pricing.json +1272 -0
  6. package/.poetic/providers/registry.json +3369 -0
  7. package/CHANGELOG.md +552 -0
  8. package/CODE_OF_CONDUCT.md +40 -0
  9. package/CONTRIBUTING.md +23 -0
  10. package/INSTALL.md +454 -0
  11. package/LICENSE +21 -0
  12. package/README.md +474 -0
  13. package/dist/BasicOptimizationCompetitionRunner-5H5TBYO4.js +153 -0
  14. package/dist/ExecutionTracker-UVONC4C6.js +16 -0
  15. package/dist/OptimizationConfig-7DFY2TST.js +17 -0
  16. package/dist/OptimizationEngine-JIMGP3LY.js +1597 -0
  17. package/dist/PromptStore-U6ZD3ZMQ.js +18 -0
  18. package/dist/actions-LUJPINLJ.js +322 -0
  19. package/dist/agent-ingest-3DJUJ7FU.js +53 -0
  20. package/dist/aggregator-DNCBINFO.js +12 -0
  21. package/dist/ai-judge-5QT5QJVU.js +156 -0
  22. package/dist/allowlist-grounding-RO6HKUFI.js +16 -0
  23. package/dist/allowlist-utils-23V7TJ3G.js +28 -0
  24. package/dist/anchored-turn-service-JULUCUIK.js +489 -0
  25. package/dist/api-transport-4TYTNLTJ.js +1087 -0
  26. package/dist/apply-completion-mode-AW2MOS3R.js +89 -0
  27. package/dist/artifact-migrator-23L45ISD.js +267 -0
  28. package/dist/ask-HWVV6QFR.js +135 -0
  29. package/dist/auth-5KEDKAPP.js +67 -0
  30. package/dist/auth-7TT3JINV.js +78 -0
  31. package/dist/auth-E6XUNZ5M.js +68 -0
  32. package/dist/auth-H3XDZE22.js +134 -0
  33. package/dist/auth-OC4E6633.js +71 -0
  34. package/dist/auth-S4CTX4GQ.js +44 -0
  35. package/dist/auth-YLH3S7EY.js +69 -0
  36. package/dist/auth-liveness-TDDEZY3T.js +46 -0
  37. package/dist/auto-optimizer-VPRWOWGU.js +80 -0
  38. package/dist/autoloop-cleanup-JOGKTLWA.js +109 -0
  39. package/dist/autoloop-evidence-gates-PCDALGVJ.js +38 -0
  40. package/dist/autoloop-gate-policy-Z7FVJVXV.js +175 -0
  41. package/dist/autoloop-helpers-2KTK43GL.js +22 -0
  42. package/dist/autoloop-ledger-W7QO62PX.js +96 -0
  43. package/dist/autoloop-ledger-subscriber-Z5RW5EIE.js +162 -0
  44. package/dist/autoloop-run-defaults-FERGRZGP.js +19 -0
  45. package/dist/autoloop-run-lock-CT2NWSV3.js +197 -0
  46. package/dist/autoloop-success-J2VKKBXQ.js +85 -0
  47. package/dist/autoloop-termination-summary-RN75F422.js +58 -0
  48. package/dist/autoloop-trajectory-XFIEXP5Z.js +282 -0
  49. package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
  50. package/dist/autonomous-loop-controller-PW4XVFGQ.js +4120 -0
  51. package/dist/backend-P3DAYRP7.js +29 -0
  52. package/dist/background-executor-CBN552V4.js +257 -0
  53. package/dist/backlog-execution-intent-U4XYPTV6.js +15 -0
  54. package/dist/backup-active-store-5WXG6SXT.js +17 -0
  55. package/dist/backup-telemetry-db-XGLXAA3N.js +254 -0
  56. package/dist/basic-competition-master-VCSBJVRN.js +344 -0
  57. package/dist/branch-archive-manager-RP6FP3ZC.js +254 -0
  58. package/dist/branch-cleanup-manager-RSHAI7YR.js +20 -0
  59. package/dist/build-gate-YHGRB4QB.js +71 -0
  60. package/dist/change-summary-WY7J5TOX.js +33 -0
  61. package/dist/chunk-23A26CSN.js +123 -0
  62. package/dist/chunk-27UTJD3M.js +265 -0
  63. package/dist/chunk-2A5CILN3.js +310 -0
  64. package/dist/chunk-2AQUWJPW.js +225 -0
  65. package/dist/chunk-2BZ53J6J.js +2344 -0
  66. package/dist/chunk-2DY5KNVM.js +276 -0
  67. package/dist/chunk-2EIA4RBE.js +659 -0
  68. package/dist/chunk-2IUXIGQD.js +1064 -0
  69. package/dist/chunk-2N42MS2Z.js +2193 -0
  70. package/dist/chunk-2QJ3H3L7.js +42 -0
  71. package/dist/chunk-2QLYTVYX.js +791 -0
  72. package/dist/chunk-2VSQMRCB.js +18 -0
  73. package/dist/chunk-2XQXYBM2.js +130 -0
  74. package/dist/chunk-2YFUIER7.js +426 -0
  75. package/dist/chunk-34CNP2HB.js +148 -0
  76. package/dist/chunk-35P3W3JX.js +456 -0
  77. package/dist/chunk-36PEBZAF.js +18 -0
  78. package/dist/chunk-3AOKYKA7.js +22 -0
  79. package/dist/chunk-3BCUNHKF.js +475 -0
  80. package/dist/chunk-3FLXLLB7.js +26 -0
  81. package/dist/chunk-3FOZ2VHV.js +100 -0
  82. package/dist/chunk-3G6FZCRF.js +106 -0
  83. package/dist/chunk-3M57DADF.js +44 -0
  84. package/dist/chunk-3S62LLWJ.js +543 -0
  85. package/dist/chunk-3ZPQLGV7.js +2904 -0
  86. package/dist/chunk-44N5WZZH.js +45 -0
  87. package/dist/chunk-45FPSA3B.js +125 -0
  88. package/dist/chunk-4BJ3O4RQ.js +929 -0
  89. package/dist/chunk-4BOP7T6L.js +2321 -0
  90. package/dist/chunk-4BTDUT2S.js +42 -0
  91. package/dist/chunk-4CSS7WVI.js +143 -0
  92. package/dist/chunk-4CUY7AFY.js +247 -0
  93. package/dist/chunk-4GSN5O5J.js +62 -0
  94. package/dist/chunk-4HN6DF7V.js +1027 -0
  95. package/dist/chunk-4IAPOG5V.js +415 -0
  96. package/dist/chunk-4IYIZQWV.js +48 -0
  97. package/dist/chunk-4NXPXE62.js +84 -0
  98. package/dist/chunk-4RCCF5BR.js +712 -0
  99. package/dist/chunk-4V7NAQ4R.js +19527 -0
  100. package/dist/chunk-4VJITV4P.js +445 -0
  101. package/dist/chunk-4YX7J6QL.js +1859 -0
  102. package/dist/chunk-527OBWQB.js +338 -0
  103. package/dist/chunk-5D4A7E3D.js +448 -0
  104. package/dist/chunk-5DLKYTQX.js +4003 -0
  105. package/dist/chunk-5EERLVZB.js +139 -0
  106. package/dist/chunk-5H72XE4H.js +256 -0
  107. package/dist/chunk-5HDP7XZG.js +91 -0
  108. package/dist/chunk-5LAMRH4X.js +969 -0
  109. package/dist/chunk-5LTN43AS.js +1972 -0
  110. package/dist/chunk-5RBHQYDB.js +2206 -0
  111. package/dist/chunk-5WCQRDRB.js +588 -0
  112. package/dist/chunk-5WRLK5KW.js +700 -0
  113. package/dist/chunk-5ZCXC23G.js +595 -0
  114. package/dist/chunk-6BM72ZMG.js +31 -0
  115. package/dist/chunk-6EDAJH2I.js +68 -0
  116. package/dist/chunk-6EQKFDBH.js +457 -0
  117. package/dist/chunk-6MFRHTRI.js +115 -0
  118. package/dist/chunk-6TZJRKNW.js +321 -0
  119. package/dist/chunk-6V7HGQFZ.js +20 -0
  120. package/dist/chunk-6VWVO2TU.js +3746 -0
  121. package/dist/chunk-6Y5TWI7H.js +146 -0
  122. package/dist/chunk-6Y5U7UFY.js +91 -0
  123. package/dist/chunk-6ZLAK3XG.js +14 -0
  124. package/dist/chunk-72XCRQED.js +34 -0
  125. package/dist/chunk-72YTZMAM.js +589 -0
  126. package/dist/chunk-73BBJOKA.js +263 -0
  127. package/dist/chunk-73NCTWKL.js +188 -0
  128. package/dist/chunk-77I6G4CO.js +1 -0
  129. package/dist/chunk-7DHRDWFS.js +3104 -0
  130. package/dist/chunk-7DNSNKJV.js +78 -0
  131. package/dist/chunk-7FMJVYBS.js +307 -0
  132. package/dist/chunk-7GDRQBQC.js +419 -0
  133. package/dist/chunk-7GPCEFUV.js +270 -0
  134. package/dist/chunk-7IL4A2PP.js +948 -0
  135. package/dist/chunk-7MMLMXO6.js +3679 -0
  136. package/dist/chunk-7QCZSLBH.js +1 -0
  137. package/dist/chunk-7R2WLDOS.js +62 -0
  138. package/dist/chunk-7T7RUJI7.js +949 -0
  139. package/dist/chunk-A2WKSVX7.js +43 -0
  140. package/dist/chunk-A3YGID55.js +133 -0
  141. package/dist/chunk-A722DEVA.js +14 -0
  142. package/dist/chunk-ACDIT7OP.js +1376 -0
  143. package/dist/chunk-ACKIPAOJ.js +302 -0
  144. package/dist/chunk-APPNGGN7.js +365 -0
  145. package/dist/chunk-APV6MK5E.js +137 -0
  146. package/dist/chunk-ASEP3M2W.js +968 -0
  147. package/dist/chunk-AT4TNPWW.js +2931 -0
  148. package/dist/chunk-ATVKCSGT.js +250 -0
  149. package/dist/chunk-AURFMVCD.js +899 -0
  150. package/dist/chunk-AX6GWE7V.js +47 -0
  151. package/dist/chunk-AY5EWJPF.js +385 -0
  152. package/dist/chunk-BAV2HJXS.js +194 -0
  153. package/dist/chunk-BBHRN366.js +89 -0
  154. package/dist/chunk-BBPSTTPA.js +1004 -0
  155. package/dist/chunk-BDATUDDJ.js +992 -0
  156. package/dist/chunk-BKE5PG5L.js +20414 -0
  157. package/dist/chunk-BLPHWMDK.js +797 -0
  158. package/dist/chunk-BSE4R6XD.js +322 -0
  159. package/dist/chunk-BXGMAU4A.js +396 -0
  160. package/dist/chunk-BXI4NXL3.js +507 -0
  161. package/dist/chunk-BZU2O43F.js +1125 -0
  162. package/dist/chunk-C3L6YQ7P.js +147 -0
  163. package/dist/chunk-C57KJOUQ.js +121 -0
  164. package/dist/chunk-CCV7BPSY.js +118 -0
  165. package/dist/chunk-CD7ISXA4.js +826 -0
  166. package/dist/chunk-CE5OZBYY.js +21 -0
  167. package/dist/chunk-CFBIG37O.js +154 -0
  168. package/dist/chunk-CJC6GZ46.js +457 -0
  169. package/dist/chunk-CKCDGXIV.js +408 -0
  170. package/dist/chunk-CKNX3TTP.js +10338 -0
  171. package/dist/chunk-CLKSETWE.js +10 -0
  172. package/dist/chunk-CP7H3HSP.js +1552 -0
  173. package/dist/chunk-CPLEWXNZ.js +66 -0
  174. package/dist/chunk-CQM3A35X.js +844 -0
  175. package/dist/chunk-CS6P76D3.js +103 -0
  176. package/dist/chunk-CTLUBNCW.js +622 -0
  177. package/dist/chunk-CUSRN6RJ.js +632 -0
  178. package/dist/chunk-D5EP5D2W.js +26 -0
  179. package/dist/chunk-D5RYINO7.js +412 -0
  180. package/dist/chunk-DBFS4HMH.js +751 -0
  181. package/dist/chunk-DC4ZYMXJ.js +115 -0
  182. package/dist/chunk-DCBZP442.js +9243 -0
  183. package/dist/chunk-DCYF7EKG.js +26 -0
  184. package/dist/chunk-DDMAFNUK.js +5351 -0
  185. package/dist/chunk-DF5SLDE4.js +966 -0
  186. package/dist/chunk-DJFW7SMX.js +348 -0
  187. package/dist/chunk-DQFLLBJW.js +121 -0
  188. package/dist/chunk-DSFM56OA.js +1203 -0
  189. package/dist/chunk-DTY4APYV.js +218 -0
  190. package/dist/chunk-DXH5JBRS.js +437 -0
  191. package/dist/chunk-E3NTPHEO.js +194 -0
  192. package/dist/chunk-E74LUIID.js +302 -0
  193. package/dist/chunk-EI57M5BI.js +194 -0
  194. package/dist/chunk-EJ4ZAWLV.js +305 -0
  195. package/dist/chunk-EJGCZGUF.js +1483 -0
  196. package/dist/chunk-EK2U3YEG.js +486 -0
  197. package/dist/chunk-ELMFYNV7.js +109 -0
  198. package/dist/chunk-ENRGKNR5.js +25 -0
  199. package/dist/chunk-ETYDXCK7.js +679 -0
  200. package/dist/chunk-EYRH3W74.js +239 -0
  201. package/dist/chunk-F23DIWNN.js +1024 -0
  202. package/dist/chunk-F5JO7HAS.js +94 -0
  203. package/dist/chunk-F7ER6ANO.js +174 -0
  204. package/dist/chunk-FATUVIIN.js +374 -0
  205. package/dist/chunk-FC23CTXV.js +322 -0
  206. package/dist/chunk-FD4ERYEG.js +22 -0
  207. package/dist/chunk-FH7WOJAE.js +79 -0
  208. package/dist/chunk-FHOWVDF5.js +1342 -0
  209. package/dist/chunk-FKAUPHMR.js +96 -0
  210. package/dist/chunk-FONNFJXA.js +137 -0
  211. package/dist/chunk-FQ7FSZRW.js +75 -0
  212. package/dist/chunk-FRG57FPM.js +240 -0
  213. package/dist/chunk-FUVP64ER.js +31 -0
  214. package/dist/chunk-FYOILAN5.js +6818 -0
  215. package/dist/chunk-G35UYQ6Z.js +69 -0
  216. package/dist/chunk-G36W2T2S.js +1143 -0
  217. package/dist/chunk-G3L2L5XZ.js +49 -0
  218. package/dist/chunk-G4THLFV3.js +148 -0
  219. package/dist/chunk-GAFJEYLK.js +29 -0
  220. package/dist/chunk-GFGYB2ZU.js +1689 -0
  221. package/dist/chunk-GG6KJYW6.js +85 -0
  222. package/dist/chunk-GHHFDU2U.js +55 -0
  223. package/dist/chunk-GHTZSQB7.js +57 -0
  224. package/dist/chunk-GK37ILCX.js +1231 -0
  225. package/dist/chunk-GKN3HMN4.js +2809 -0
  226. package/dist/chunk-GNVDBVJP.js +156 -0
  227. package/dist/chunk-GPEL3FBM.js +924 -0
  228. package/dist/chunk-GPSNGPZS.js +1604 -0
  229. package/dist/chunk-GSGD5E4C.js +30 -0
  230. package/dist/chunk-GSUQJJXQ.js +331 -0
  231. package/dist/chunk-GSV226X6.js +110 -0
  232. package/dist/chunk-H2AYQIHW.js +224 -0
  233. package/dist/chunk-H66DXFS5.js +1374 -0
  234. package/dist/chunk-H6G7QRMQ.js +35 -0
  235. package/dist/chunk-H7JAGHZT.js +59 -0
  236. package/dist/chunk-H7ZEFECA.js +316 -0
  237. package/dist/chunk-HAC6EHZZ.js +79 -0
  238. package/dist/chunk-HIO33P3G.js +19 -0
  239. package/dist/chunk-HMVQIPH3.js +547 -0
  240. package/dist/chunk-HOYBYAOA.js +257 -0
  241. package/dist/chunk-HX5P3CSP.js +1784 -0
  242. package/dist/chunk-I46EG2XQ.js +65 -0
  243. package/dist/chunk-I4NPDSCB.js +279 -0
  244. package/dist/chunk-I5WRT7ZR.js +514 -0
  245. package/dist/chunk-IC7I6YIJ.js +301 -0
  246. package/dist/chunk-IDCSOZVN.js +78 -0
  247. package/dist/chunk-IFCBYECK.js +112 -0
  248. package/dist/chunk-IFZCPEY2.js +66 -0
  249. package/dist/chunk-IKFP2KUR.js +48 -0
  250. package/dist/chunk-IRFBN336.js +878 -0
  251. package/dist/chunk-IUXNGKA6.js +152 -0
  252. package/dist/chunk-IV2RVAN7.js +1356 -0
  253. package/dist/chunk-IZYIQQ7X.js +53 -0
  254. package/dist/chunk-J3UUR7DE.js +210 -0
  255. package/dist/chunk-J54VUAY2.js +566 -0
  256. package/dist/chunk-J62KPGII.js +464 -0
  257. package/dist/chunk-J6P3FWWW.js +130 -0
  258. package/dist/chunk-JKBHJQMT.js +434 -0
  259. package/dist/chunk-JLS65NUQ.js +14 -0
  260. package/dist/chunk-JOSYEJKY.js +141 -0
  261. package/dist/chunk-JPKSXKNB.js +94 -0
  262. package/dist/chunk-JQNJB2BB.js +2440 -0
  263. package/dist/chunk-JRVNSWSQ.js +2626 -0
  264. package/dist/chunk-JSWMRQYG.js +28 -0
  265. package/dist/chunk-JZKNBBIB.js +152 -0
  266. package/dist/chunk-K54Y7MLK.js +160 -0
  267. package/dist/chunk-K65546RE.js +183 -0
  268. package/dist/chunk-KM3F7SYE.js +702 -0
  269. package/dist/chunk-KNDYMVWN.js +102 -0
  270. package/dist/chunk-KNT72VR6.js +132 -0
  271. package/dist/chunk-KP6YILMU.js +482 -0
  272. package/dist/chunk-KQEBSK3T.js +274 -0
  273. package/dist/chunk-KT6VHSPF.js +84 -0
  274. package/dist/chunk-KTMW65UX.js +14 -0
  275. package/dist/chunk-KZ5CJVBP.js +1813 -0
  276. package/dist/chunk-L4427KOE.js +26 -0
  277. package/dist/chunk-L6OM4A22.js +189 -0
  278. package/dist/chunk-L7E6XCRA.js +1042 -0
  279. package/dist/chunk-L7JZLXQL.js +173 -0
  280. package/dist/chunk-LAMKBTXX.js +40 -0
  281. package/dist/chunk-LDCF2MKN.js +132 -0
  282. package/dist/chunk-LEIIWPWQ.js +78 -0
  283. package/dist/chunk-LFTQVYBB.js +31 -0
  284. package/dist/chunk-LG3PDRTR.js +2872 -0
  285. package/dist/chunk-LGHII5ET.js +23 -0
  286. package/dist/chunk-LH5QY22X.js +1205 -0
  287. package/dist/chunk-LIVJ6266.js +438 -0
  288. package/dist/chunk-LKRAR3IH.js +276 -0
  289. package/dist/chunk-LO23NABI.js +3063 -0
  290. package/dist/chunk-LO3X5NLS.js +326 -0
  291. package/dist/chunk-LPITVM7M.js +339 -0
  292. package/dist/chunk-LR5IJIGV.js +810 -0
  293. package/dist/chunk-LRGMHROI.js +79 -0
  294. package/dist/chunk-LUVKFFWR.js +315 -0
  295. package/dist/chunk-LWCBNGH6.js +35 -0
  296. package/dist/chunk-LWTN3WRV.js +260 -0
  297. package/dist/chunk-M3HQYKQX.js +308 -0
  298. package/dist/chunk-M6GVSPEH.js +1016 -0
  299. package/dist/chunk-MF5HP6XV.js +221 -0
  300. package/dist/chunk-MHLCBZJB.js +328 -0
  301. package/dist/chunk-MN6PL4AN.js +120 -0
  302. package/dist/chunk-MOEY65Z6.js +5678 -0
  303. package/dist/chunk-MQ4WA34C.js +206 -0
  304. package/dist/chunk-MWHF5V7U.js +223 -0
  305. package/dist/chunk-MWHLBPNU.js +211 -0
  306. package/dist/chunk-MWK5UZQ3.js +1068 -0
  307. package/dist/chunk-MYLH2S4G.js +64 -0
  308. package/dist/chunk-MZ5WYKNA.js +28 -0
  309. package/dist/chunk-N4VTRA7K.js +131 -0
  310. package/dist/chunk-N5DX4JAK.js +12 -0
  311. package/dist/chunk-N65O4XTH.js +5011 -0
  312. package/dist/chunk-NEQUQHOX.js +223 -0
  313. package/dist/chunk-NGK6PEOG.js +25 -0
  314. package/dist/chunk-NJVD4PWE.js +1033 -0
  315. package/dist/chunk-NM6PMYY4.js +768 -0
  316. package/dist/chunk-NN4PJDHP.js +708 -0
  317. package/dist/chunk-NP2V3L7K.js +226 -0
  318. package/dist/chunk-NRLY536M.js +260 -0
  319. package/dist/chunk-NRNE225N.js +1270 -0
  320. package/dist/chunk-NS2K2GTP.js +605 -0
  321. package/dist/chunk-NS33V3IM.js +51 -0
  322. package/dist/chunk-NSHASMZZ.js +71 -0
  323. package/dist/chunk-NWOYOA6H.js +378 -0
  324. package/dist/chunk-NWRUSEXG.js +322 -0
  325. package/dist/chunk-NZGDAWIP.js +1905 -0
  326. package/dist/chunk-O47UOKU3.js +395 -0
  327. package/dist/chunk-O4G2W3ST.js +9831 -0
  328. package/dist/chunk-O6V4PNLO.js +63 -0
  329. package/dist/chunk-OA4GPILI.js +624 -0
  330. package/dist/chunk-OGMSYL6J.js +227 -0
  331. package/dist/chunk-OIS7J26S.js +319 -0
  332. package/dist/chunk-OMX5VL43.js +79 -0
  333. package/dist/chunk-ON3G73BU.js +264 -0
  334. package/dist/chunk-OPYFYTWQ.js +220 -0
  335. package/dist/chunk-OQ6K46CK.js +1734 -0
  336. package/dist/chunk-OYZYO7TV.js +47 -0
  337. package/dist/chunk-OZ4REHIN.js +4386 -0
  338. package/dist/chunk-P47VN5F4.js +282 -0
  339. package/dist/chunk-P5I4X7A7.js +353 -0
  340. package/dist/chunk-P6VQROCO.js +594 -0
  341. package/dist/chunk-P7CQGPLS.js +30 -0
  342. package/dist/chunk-PCAGC5MR.js +1763 -0
  343. package/dist/chunk-PFTQBXS6.js +5181 -0
  344. package/dist/chunk-PGSPX4SU.js +15 -0
  345. package/dist/chunk-PIKLF7BM.js +432 -0
  346. package/dist/chunk-PJWJ3SAV.js +22 -0
  347. package/dist/chunk-PKIFMV72.js +100 -0
  348. package/dist/chunk-PL37JDNA.js +189 -0
  349. package/dist/chunk-PTH5E5XO.js +195 -0
  350. package/dist/chunk-PW6AXLQC.js +4128 -0
  351. package/dist/chunk-PYITM4N2.js +79 -0
  352. package/dist/chunk-PZ5AY32C.js +10 -0
  353. package/dist/chunk-Q3RO7N35.js +45 -0
  354. package/dist/chunk-Q3WIC6GQ.js +2670 -0
  355. package/dist/chunk-Q5XIXSHX.js +271 -0
  356. package/dist/chunk-QGJDMEOV.js +34 -0
  357. package/dist/chunk-QNOB37UH.js +58 -0
  358. package/dist/chunk-QOCOVLUH.js +462 -0
  359. package/dist/chunk-QTCJ5CC5.js +172 -0
  360. package/dist/chunk-QVFV5IP2.js +232 -0
  361. package/dist/chunk-QVZMFDYG.js +29 -0
  362. package/dist/chunk-R35PEUKH.js +511 -0
  363. package/dist/chunk-R4UWBC35.js +200 -0
  364. package/dist/chunk-R6MLCREW.js +44 -0
  365. package/dist/chunk-R6W23LKN.js +254 -0
  366. package/dist/chunk-R7XDDX2A.js +4007 -0
  367. package/dist/chunk-RDFRCT64.js +168 -0
  368. package/dist/chunk-RE5VZDFQ.js +58 -0
  369. package/dist/chunk-RGROYC2G.js +638 -0
  370. package/dist/chunk-RGWHUI5E.js +68 -0
  371. package/dist/chunk-RHVG6UNL.js +205 -0
  372. package/dist/chunk-RI4EX2QE.js +18 -0
  373. package/dist/chunk-RJAAKDRX.js +17 -0
  374. package/dist/chunk-ROMHOSMQ.js +185 -0
  375. package/dist/chunk-RWREC3KJ.js +517 -0
  376. package/dist/chunk-RYNETRDJ.js +118 -0
  377. package/dist/chunk-RZY7RKM5.js +500 -0
  378. package/dist/chunk-S2MNWFAG.js +52 -0
  379. package/dist/chunk-S2VQCZO4.js +22 -0
  380. package/dist/chunk-S54MKU6V.js +117 -0
  381. package/dist/chunk-S5OIDFRM.js +302 -0
  382. package/dist/chunk-SCW4ZF6R.js +150 -0
  383. package/dist/chunk-SLS2N4PH.js +2213 -0
  384. package/dist/chunk-SNLBO4BF.js +247 -0
  385. package/dist/chunk-SP3LFU6B.js +60 -0
  386. package/dist/chunk-SQQTDDQA.js +537 -0
  387. package/dist/chunk-STV6LYYE.js +45 -0
  388. package/dist/chunk-SURZ2WFE.js +326 -0
  389. package/dist/chunk-SZ7DL357.js +1047 -0
  390. package/dist/chunk-T5E4NQCM.js +5742 -0
  391. package/dist/chunk-TAJPCXSB.js +13 -0
  392. package/dist/chunk-TAOOYK3P.js +358 -0
  393. package/dist/chunk-TDSEX5CF.js +24 -0
  394. package/dist/chunk-TFTGP7Z7.js +174 -0
  395. package/dist/chunk-TGON4N4O.js +197 -0
  396. package/dist/chunk-TGQZHDY2.js +2373 -0
  397. package/dist/chunk-TJJZ2OKV.js +6783 -0
  398. package/dist/chunk-TRSVUPCX.js +25 -0
  399. package/dist/chunk-TSXGRLPR.js +107 -0
  400. package/dist/chunk-U2S3YEX3.js +224 -0
  401. package/dist/chunk-U45RTRGY.js +818 -0
  402. package/dist/chunk-U6C3VVWS.js +13 -0
  403. package/dist/chunk-UDMS5AD3.js +307 -0
  404. package/dist/chunk-UGX7GI37.js +94 -0
  405. package/dist/chunk-UH3JJSHK.js +1 -0
  406. package/dist/chunk-UHRBTZYY.js +208 -0
  407. package/dist/chunk-UHT2KRG5.js +193 -0
  408. package/dist/chunk-UI2F6DJ5.js +118 -0
  409. package/dist/chunk-UMAKSB4Z.js +284 -0
  410. package/dist/chunk-UR2IBGIM.js +521 -0
  411. package/dist/chunk-UUH2RVKS.js +585 -0
  412. package/dist/chunk-UVJ4PJDK.js +4533 -0
  413. package/dist/chunk-V53UG2OT.js +9924 -0
  414. package/dist/chunk-V72RMBM4.js +48 -0
  415. package/dist/chunk-VBNCKCCI.js +16 -0
  416. package/dist/chunk-VNSYKC25.js +24 -0
  417. package/dist/chunk-VPHVFK4A.js +1984 -0
  418. package/dist/chunk-VTLNJQ44.js +133 -0
  419. package/dist/chunk-VTW7HP3R.js +100 -0
  420. package/dist/chunk-VVGEPBPS.js +218 -0
  421. package/dist/chunk-VVLLL7I4.js +166 -0
  422. package/dist/chunk-VX3UMWB7.js +483 -0
  423. package/dist/chunk-VXF4Q3FW.js +20 -0
  424. package/dist/chunk-W3JMT2YY.js +712 -0
  425. package/dist/chunk-WDUORIHF.js +877 -0
  426. package/dist/chunk-WDVTY4U6.js +148 -0
  427. package/dist/chunk-WIFZCHEG.js +12566 -0
  428. package/dist/chunk-WIRN3F75.js +736 -0
  429. package/dist/chunk-WMPU2UOV.js +82 -0
  430. package/dist/chunk-WTOKKE2V.js +784 -0
  431. package/dist/chunk-WX5IRLF6.js +740 -0
  432. package/dist/chunk-WZ6U3O7I.js +1581 -0
  433. package/dist/chunk-XAONGNST.js +57 -0
  434. package/dist/chunk-XB5YLCLB.js +13 -0
  435. package/dist/chunk-XEP5NQ5Y.js +688 -0
  436. package/dist/chunk-XGYF2QMZ.js +351 -0
  437. package/dist/chunk-XHEKQENB.js +255 -0
  438. package/dist/chunk-XNO4FM6X.js +1124 -0
  439. package/dist/chunk-XPHKYHO4.js +878 -0
  440. package/dist/chunk-XPK2I4NC.js +405 -0
  441. package/dist/chunk-XPU2XADL.js +2175 -0
  442. package/dist/chunk-XQD2B6BB.js +507 -0
  443. package/dist/chunk-XT2ZQVTC.js +558 -0
  444. package/dist/chunk-XTXJGGUV.js +351 -0
  445. package/dist/chunk-XUXVDPSZ.js +50 -0
  446. package/dist/chunk-XV7NZL4B.js +57 -0
  447. package/dist/chunk-XZE4XARH.js +563 -0
  448. package/dist/chunk-XZYR5EDO.js +152 -0
  449. package/dist/chunk-Y3J4JMTU.js +61 -0
  450. package/dist/chunk-Y55LZN5U.js +52 -0
  451. package/dist/chunk-Y5VN7DMP.js +112 -0
  452. package/dist/chunk-Y67VAHN4.js +459 -0
  453. package/dist/chunk-YAXSKEUH.js +3544 -0
  454. package/dist/chunk-YB3JD4E6.js +975 -0
  455. package/dist/chunk-YESZJFK6.js +220 -0
  456. package/dist/chunk-YGXKOBQQ.js +292 -0
  457. package/dist/chunk-YMX76IOS.js +31 -0
  458. package/dist/chunk-YOTXESEH.js +257 -0
  459. package/dist/chunk-YTYIEZQY.js +119 -0
  460. package/dist/chunk-YVORHQ2S.js +579 -0
  461. package/dist/chunk-Z2CUQDAR.js +3429 -0
  462. package/dist/chunk-Z2KYOFHS.js +7000 -0
  463. package/dist/chunk-Z6PC7QX6.js +161 -0
  464. package/dist/chunk-ZDTGECTN.js +235 -0
  465. package/dist/chunk-ZIPWI2LY.js +151 -0
  466. package/dist/chunk-ZSKKMTQJ.js +554 -0
  467. package/dist/chunk-ZTT5IVPY.js +1160 -0
  468. package/dist/chunk-ZX65UI5W.js +78 -0
  469. package/dist/chunk-ZYG7GGKO.js +218 -0
  470. package/dist/chunk-ZZZUL4OF.js +38 -0
  471. package/dist/cli-utils-IXL26KJT.js +40 -0
  472. package/dist/cli-validation-WLXWLUJL.js +111 -0
  473. package/dist/commit-utils-P7CRJF5N.js +202 -0
  474. package/dist/compete-config-resolver-R5ULXMYH.js +76 -0
  475. package/dist/compete-request-62JESVET.js +364 -0
  476. package/dist/compete-results-QEPG6FZX.js +208 -0
  477. package/dist/competition-outcome-tracker-R32OOZ43.js +38 -0
  478. package/dist/config-JCOKXOQT.js +166 -0
  479. package/dist/config-audit-EL3GHXS7.js +360 -0
  480. package/dist/config-explain-TNILDEVJ.js +12 -0
  481. package/dist/config-loader-VPFPFO4B.js +38 -0
  482. package/dist/config-manager-7T4E2BQO.js +67 -0
  483. package/dist/config-validator-KKOHOW7O.js +72 -0
  484. package/dist/cost-YC42XUF3.js +53 -0
  485. package/dist/coverage-orchestrator-CISNKJC2.js +772 -0
  486. package/dist/coverage-scanner-YVD62MLH.js +12 -0
  487. package/dist/createCompetitionRunner-LJG6ZQSO.js +46 -0
  488. package/dist/data-migration-state-VJK64DLT.js +31 -0
  489. package/dist/db-migrator-XSEIOGWY.js +34 -0
  490. package/dist/discovery-JGYGDD25.js +25 -0
  491. package/dist/doctor-GJOYE7AE.js +186 -0
  492. package/dist/domain-analyzer-AWF3RP6E.js +29 -0
  493. package/dist/ensure-initialized-744DIZEZ.js +52 -0
  494. package/dist/entry.js +940 -0
  495. package/dist/environment-YS45U5ZI.js +81 -0
  496. package/dist/error-parser-core-PPZ36A4S.js +50 -0
  497. package/dist/escalation-ladder-MKTCEGSA.js +130 -0
  498. package/dist/evaluation-context-KV4GZNN7.js +35 -0
  499. package/dist/evidence-plan-resolver-GBSYSAPX.js +85 -0
  500. package/dist/execution-data-writer-3ODTBDLH.js +53 -0
  501. package/dist/execution-policy-applier-ZHD3DCF3.js +31 -0
  502. package/dist/execution-preflight-Z4Y64V3I.js +209 -0
  503. package/dist/execution-roles-R3DPPMD3.js +66 -0
  504. package/dist/exit-code-error-Z4SW2DVK.js +14 -0
  505. package/dist/external-temp-cleanup-N2RZH4QP.js +311 -0
  506. package/dist/factory-XBN7DFIM.js +149 -0
  507. package/dist/file-utils-XIVR2ZMA.js +47 -0
  508. package/dist/flywheel-autoloop-executor-UILGOFFK.js +249 -0
  509. package/dist/flywheel-competition-executor-JOBEXTRB.js +259 -0
  510. package/dist/flywheel-executor-6JFLA6J5.js +369 -0
  511. package/dist/flywheel-git-isolation-UC5NIEVU.js +48 -0
  512. package/dist/flywheel-manifest-5UC4VBMA.js +108 -0
  513. package/dist/flywheel-model-defaults-7CVKP53V.js +27 -0
  514. package/dist/flywheel-preflight-XEY5SHM6.js +104 -0
  515. package/dist/flywheel-resume-7HELH7QS.js +23 -0
  516. package/dist/flywheel-safety-7U7DPOAP.js +28 -0
  517. package/dist/flywheel-scope-decision-ZHKF6ZIN.js +11 -0
  518. package/dist/get-telemetry-logger-DPVWWIYY.js +73 -0
  519. package/dist/git-worktree-IY6V6DUO.js +18 -0
  520. package/dist/github-pr-manager-4LXEKJTA.js +211 -0
  521. package/dist/guidance-profile-config-E7XJL2VP.js +117 -0
  522. package/dist/guidance-profile-renderer-QK2YMAAP.js +21 -0
  523. package/dist/index-query-4JEUKA44.js +31 -0
  524. package/dist/index.js +108661 -0
  525. package/dist/instructions-6BURLQJC.js +64 -0
  526. package/dist/invoke-provider-auth-GRUYP44M.js +223 -0
  527. package/dist/judge-scoring.json +80 -0
  528. package/dist/judge-test.js +555 -0
  529. package/dist/lab-mode-OTWVHN63.js +39 -0
  530. package/dist/lab-utils-BJRFLGK4.js +23 -0
  531. package/dist/linux-host-class-UY4KVLFD.js +29 -0
  532. package/dist/llm-judge-executor-F7Z3HO77.js +133 -0
  533. package/dist/local-executor-CEHWE2PL.js +223 -0
  534. package/dist/logger-33TR6EE5.js +72 -0
  535. package/dist/loop-spec-XTLQAVZ7.js +191 -0
  536. package/dist/manager-2HJG5CLT.js +25 -0
  537. package/dist/matrix-prompt-builder-6UDN5X3F.js +497 -0
  538. package/dist/matrix-result-parser-7W35EUOV.js +15 -0
  539. package/dist/metadata-HQ43NDEK.js +22 -0
  540. package/dist/model-invocations-db-QBO4Y7WZ.js +38 -0
  541. package/dist/monitor-XGYBG2DW.js +72 -0
  542. package/dist/next-PB5ZXZKB.js +90 -0
  543. package/dist/next-ZBDK725T.js +69 -0
  544. package/dist/optimization-config-resolver-O6WKR47U.js +75 -0
  545. package/dist/package-3YCWIQQ5.js +10 -0
  546. package/dist/parallel-orchestrator-NL7YJJU2.js +297 -0
  547. package/dist/parallel-worker.js +279 -0
  548. package/dist/parse-git-status-PIAF3OTP.js +10 -0
  549. package/dist/path-security-ETTH6TZL.js +39 -0
  550. package/dist/pattern-bank-UNJR5ADV.js +15 -0
  551. package/dist/plan-backlog-list-fast-VAGYBV3J.js +270 -0
  552. package/dist/plan-backlog-show-fast-SG2CZPW3.js +406 -0
  553. package/dist/plan-sprint-list-fast-LURAX47V.js +162 -0
  554. package/dist/plan-sprint-status-fast-FJAODCHD.js +208 -0
  555. package/dist/plan-task-status-fast-HNYBMQI4.js +349 -0
  556. package/dist/plan-to-flywheel-Z4U3GWPN.js +456 -0
  557. package/dist/planning-backlog-3CQ5QQBQ.js +319 -0
  558. package/dist/poetic-root-V5DNXEAE.js +17 -0
  559. package/dist/preflight-OPANWMME.js +12 -0
  560. package/dist/process-registry-PDZJPTAS.js +27 -0
  561. package/dist/process-scanner-C22SYXYD.js +22 -0
  562. package/dist/processes-KMQUD7HY.js +29 -0
  563. package/dist/processes-json-fast-IBDXZ6WW.js +135 -0
  564. package/dist/profile-SE5EVXAP.js +149 -0
  565. package/dist/prompts-WZZPGWBX.js +168 -0
  566. package/dist/protected-branches-RNTEX7ET.js +57 -0
  567. package/dist/provider-aware-resource-manager-QBTZJMNP.js +18 -0
  568. package/dist/provider-matrix-N5X57V3Y.js +154 -0
  569. package/dist/provider-matrix-renderer-MZDWKKID.js +139 -0
  570. package/dist/provider-output-forwarding-DERID3TP.js +30 -0
  571. package/dist/provider-registry-J5NRBJKI.js +128 -0
  572. package/dist/provider-temp-cleanup-KYGLF6YU.js +14 -0
  573. package/dist/prune-engine-Q6E2DXBN.js +451 -0
  574. package/dist/quality-gate-YRHMQAEI.js +70 -0
  575. package/dist/quickstart-FIRLKGJI.js +62 -0
  576. package/dist/readiness-VZTMSG6J.js +96 -0
  577. package/dist/registry-YODFY77A.js +153 -0
  578. package/dist/repair-helpers-TTV5FEF4.js +117 -0
  579. package/dist/repo-root-2IGD4H7X.js +22 -0
  580. package/dist/resolution-engine-D6TX6FRG.js +127 -0
  581. package/dist/resolve-provider-cli-O2P6XZBZ.js +35 -0
  582. package/dist/restore-telemetry-db-BQL6DTQF.js +360 -0
  583. package/dist/result-streamer-WEHW476R.js +19 -0
  584. package/dist/routing-events-DHPUZDDF.js +27 -0
  585. package/dist/routing-history-store-UWCEXAP3.js +46 -0
  586. package/dist/routing-planner-F5WQEUOM.js +160 -0
  587. package/dist/run-poetic-tui-J6LWRJUP.js +13517 -0
  588. package/dist/run-simulation.js +376 -0
  589. package/dist/runner-CS2TNGHA.js +1092 -0
  590. package/dist/runner-HHH7ZN2Z.js +1571 -0
  591. package/dist/safety-OCC4KJJR.js +64 -0
  592. package/dist/safety-stanza-7SV3HGG3.js +60 -0
  593. package/dist/sandbox-32QXJEMV.js +81 -0
  594. package/dist/sandbox-RSO7VP6V.js +94 -0
  595. package/dist/schema-extensions.sql +234 -0
  596. package/dist/security-2KI5XNDG.js +17 -0
  597. package/dist/setup-bb-plugin-QAQWZCV5.js +738 -0
  598. package/dist/setup-claude-code-P7BTTSPO.js +317 -0
  599. package/dist/setup-temp-cleanup-GASCWZ2I.js +20 -0
  600. package/dist/shared-utils-D6U6UREP.js +37 -0
  601. package/dist/simple-artifact-goal-OTXNGZY6.js +25 -0
  602. package/dist/sprint-UIXPYOXQ.js +338 -0
  603. package/dist/sprint-bridge-4BHMSC3M.js +68 -0
  604. package/dist/sprint-execution-service-2B7WHL5L.js +311 -0
  605. package/dist/sprint-manager-IDQUDNQI.js +91 -0
  606. package/dist/sqlite-wrapper-UDWCTNLJ.js +17 -0
  607. package/dist/stale-cleanup-orchestrator-XWXV7KCZ.js +62 -0
  608. package/dist/storage-access-F6ALDN4S.js +22 -0
  609. package/dist/synthesis-XD6EDVHF.js +185 -0
  610. package/dist/task-classifier-LNLXSHOM.js +494 -0
  611. package/dist/task-list-fast-PTMA4LUC.js +147 -0
  612. package/dist/task-manager-XAT7GOWB.js +93 -0
  613. package/dist/task-splitter-U7DJ7W6A.js +79 -0
  614. package/dist/task-type-detector-OLVOMXZO.js +21 -0
  615. package/dist/task-type-resolver-KKNQYSB4.js +42 -0
  616. package/dist/telemetry-5HWBBXLX.js +131 -0
  617. package/dist/telemetry-health-tracker-DMSSGBZ2.js +11 -0
  618. package/dist/telemetry-path-resolver-7ICSG276.js +28 -0
  619. package/dist/telemetry-reliability-XUOZNZZ6.js +125 -0
  620. package/dist/token-estimator-MEQUL3EJ.js +37 -0
  621. package/dist/transports-KNSSV2V4.js +255 -0
  622. package/dist/unified-cost-tracker-4TFRBVPR.js +35 -0
  623. package/dist/unified-state-cleanup-LJPF2BOW.js +276 -0
  624. package/dist/universal-cost-calculator-BAJV35GA.js +42 -0
  625. package/dist/user-agents-GHUGCSKN.js +22 -0
  626. package/dist/variant-delivery-state-KLRNG6XA.js +33 -0
  627. package/dist/variant-state-cleanup-MZGGLQAJ.js +280 -0
  628. package/dist/variant-success-PJXWE3ZV.js +12 -0
  629. package/dist/variant-worker-KUWKBLAH.js +4196 -0
  630. package/dist/variant-worker.js +24 -0
  631. package/dist/variants-JE2FSAQS.js +233 -0
  632. package/dist/verification-toolchains-V24UHW6Q.js +28 -0
  633. package/dist/verify-commands-H3DTCSGI.js +37 -0
  634. package/dist/warning-EGQGUUIO.js +12 -0
  635. package/dist/work-edge-RWEDWJZF.js +49 -0
  636. package/dist/work-item-writer-WHAVZXAY.js +19 -0
  637. package/dist/worker-7SA2VS2Y.js +1435 -0
  638. package/dist/worker.js +19 -0
  639. package/dist/worktree-metrics-3DFUYVYE.js +26 -0
  640. package/dist/writeback-VZKHYHSN.js +44 -0
  641. package/docs/CLI_REFERENCE.md +7042 -0
  642. package/docs/PROVIDER_SETUP.md +1570 -0
  643. package/docs/README.md +96 -0
  644. package/docs/TROUBLESHOOTING.md +2232 -0
  645. package/docs/getting-started/QUICK_START.md +294 -0
  646. package/docs/getting-started/README.md +188 -0
  647. package/docs/getting-started/SETUP.md +52 -0
  648. package/docs/reference/AGENT_CONTEXT.md +38 -0
  649. package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
  650. package/docs/reference/README.md +381 -0
  651. package/docs/reference/SECURITY.md +262 -0
  652. package/integrations/bb-plugin-poetic/README.md +362 -0
  653. package/integrations/bb-plugin-poetic/app.css +341 -0
  654. package/integrations/bb-plugin-poetic/app.tsx +5059 -0
  655. package/integrations/bb-plugin-poetic/package.json +45 -0
  656. package/integrations/bb-plugin-poetic/server.ts +444 -0
  657. package/integrations/bb-plugin-poetic/src/adapter.ts +3312 -0
  658. package/integrations/bb-plugin-poetic/src/backlog-authoring-model.ts +150 -0
  659. package/integrations/bb-plugin-poetic/src/backlog-authoring-schema.ts +355 -0
  660. package/integrations/bb-plugin-poetic/src/backlog-authoring-service.ts +419 -0
  661. package/integrations/bb-plugin-poetic/src/backlog-authoring-view.ts +1026 -0
  662. package/integrations/bb-plugin-poetic/src/competition-defaults-schema.ts +122 -0
  663. package/integrations/bb-plugin-poetic/src/competition-defaults-service.ts +105 -0
  664. package/integrations/bb-plugin-poetic/src/competition-defaults-view.ts +138 -0
  665. package/integrations/bb-plugin-poetic/src/contract.ts +615 -0
  666. package/integrations/bb-plugin-poetic/src/finalize-model.ts +205 -0
  667. package/integrations/bb-plugin-poetic/src/finalize-schema.ts +158 -0
  668. package/integrations/bb-plugin-poetic/src/finalize-service.ts +382 -0
  669. package/integrations/bb-plugin-poetic/src/finalize-view.ts +159 -0
  670. package/integrations/bb-plugin-poetic/src/judge-operations-readback.ts +303 -0
  671. package/integrations/bb-plugin-poetic/src/judge-operations-schema.ts +33 -0
  672. package/integrations/bb-plugin-poetic/src/judge-operations-view.ts +459 -0
  673. package/integrations/bb-plugin-poetic/src/model.ts +1302 -0
  674. package/integrations/bb-plugin-poetic/src/monitor-service.ts +233 -0
  675. package/integrations/bb-plugin-poetic/src/panel-read-ux.ts +97 -0
  676. package/integrations/bb-plugin-poetic/src/patch-preview-schema.ts +166 -0
  677. package/integrations/bb-plugin-poetic/src/patch-preview-service.ts +480 -0
  678. package/integrations/bb-plugin-poetic/src/patch-preview-view.ts +109 -0
  679. package/integrations/bb-plugin-poetic/src/planning-readback.ts +204 -0
  680. package/integrations/bb-plugin-poetic/src/planning-service.ts +594 -0
  681. package/integrations/bb-plugin-poetic/src/planning-workspace-schema.ts +95 -0
  682. package/integrations/bb-plugin-poetic/src/planning-workspace.ts +323 -0
  683. package/integrations/bb-plugin-poetic/src/poll-handoff.ts +136 -0
  684. package/integrations/bb-plugin-poetic/src/project-target-server.ts +21 -0
  685. package/integrations/bb-plugin-poetic/src/project-target.ts +45 -0
  686. package/integrations/bb-plugin-poetic/src/reference-index.ts +192 -0
  687. package/integrations/bb-plugin-poetic/src/repository-schema.ts +30 -0
  688. package/integrations/bb-plugin-poetic/src/result-explorer-view.ts +597 -0
  689. package/integrations/bb-plugin-poetic/src/result-readback-model.ts +163 -0
  690. package/integrations/bb-plugin-poetic/src/result-readback-schema.ts +319 -0
  691. package/integrations/bb-plugin-poetic/src/result-readback-service.ts +333 -0
  692. package/integrations/bb-plugin-poetic/src/run-page-view.ts +177 -0
  693. package/integrations/bb-plugin-poetic/src/setup-config-schema.ts +291 -0
  694. package/integrations/bb-plugin-poetic/src/setup-config-service.ts +590 -0
  695. package/integrations/bb-plugin-poetic/src/setup-config-view.ts +413 -0
  696. package/integrations/bb-plugin-poetic/src/sprint-close-model.ts +150 -0
  697. package/integrations/bb-plugin-poetic/src/sprint-close-schema.ts +136 -0
  698. package/integrations/bb-plugin-poetic/src/sprint-close-service.ts +341 -0
  699. package/integrations/bb-plugin-poetic/src/sprint-close-view.ts +116 -0
  700. package/integrations/bb-plugin-poetic/src/sprint-composition-model.ts +714 -0
  701. package/integrations/bb-plugin-poetic/src/sprint-composition-readback.ts +231 -0
  702. package/integrations/bb-plugin-poetic/src/sprint-composition-schema.ts +601 -0
  703. package/integrations/bb-plugin-poetic/src/sprint-composition-service.ts +775 -0
  704. package/integrations/bb-plugin-poetic/src/sprint-composition-view.ts +1221 -0
  705. package/integrations/bb-plugin-poetic/src/task-authoring-model.ts +567 -0
  706. package/integrations/bb-plugin-poetic/src/task-authoring-schema.ts +635 -0
  707. package/integrations/bb-plugin-poetic/src/task-authoring-service.ts +842 -0
  708. package/integrations/bb-plugin-poetic/src/task-authoring-view.ts +1227 -0
  709. package/integrations/bb-plugin-poetic/src/task-detail-readback.ts +56 -0
  710. package/integrations/bb-plugin-poetic/src/task-detail-schema.ts +144 -0
  711. package/integrations/bb-plugin-poetic/src/task-navigation.ts +446 -0
  712. package/integrations/bb-plugin-poetic/src/workbench-route.ts +74 -0
  713. package/integrations/bb-plugin-poetic/tests/host-contract.test.ts +773 -0
  714. package/integrations/bb-plugin-poetic/tsconfig.json +18 -0
  715. package/integrations/bb-plugin-poetic/types/PROVENANCE.json +52 -0
  716. package/integrations/bb-plugin-poetic/types/bb-plugin-sdk-app.d.ts +1444 -0
  717. package/integrations/bb-plugin-poetic/types/bb-plugin-sdk.d.ts +13030 -0
  718. package/integrations/bb-plugin-poetic/vitest.host.config.ts +71 -0
  719. package/npm-shrinkwrap.json +4950 -0
  720. package/package.json +331 -0
  721. package/schemas/README.md +80 -0
  722. package/schemas/config-v1.schema.json +136 -0
  723. package/schemas/execution-config.schema.json +47 -0
  724. package/schemas/judge-scoring.schema.json +370 -0
  725. package/schemas/poetic.config.schema.json +2214 -0
  726. package/schemas/provider-config.schema.json +203 -0
  727. package/schemas/telemetry-config.schema.json +79 -0
  728. package/schemas/user-preferences.schema.json +141 -0
  729. package/scripts/assert-node-runtime.mjs +140 -0
  730. package/scripts/preflight-native.mjs +49 -0
  731. package/scripts/preinstall-node-check.mjs +78 -0
  732. package/scripts/setup-git-hooks.mjs +24 -0
  733. package/scripts/sync.sh +2722 -0
  734. package/scripts/write-node-launcher.sh +108 -0
  735. package/src/resources/gemini/slash-packs/default/plan.toml +15 -0
  736. package/src/resources/gemini/slash-packs/default/summary.toml +16 -0
  737. package/src/resources/gemini/slash-packs/default/tests.toml +16 -0
  738. package/templates/.poetic/README.md +37 -0
  739. package/templates/.poetic/agents/README.md +296 -0
  740. package/templates/.poetic/agents/api-documenter.md +147 -0
  741. package/templates/.poetic/agents/backend-architect.md +31 -0
  742. package/templates/.poetic/agents/code-reviewer.md +157 -0
  743. package/templates/.poetic/agents/data-scientist.md +179 -0
  744. package/templates/.poetic/agents/database-optimizer.md +145 -0
  745. package/templates/.poetic/agents/debugger.md +31 -0
  746. package/templates/.poetic/agents/deployment-engineer.md +164 -0
  747. package/templates/.poetic/agents/devops-troubleshooter.md +139 -0
  748. package/templates/.poetic/agents/frontend-developer.md +150 -0
  749. package/templates/.poetic/agents/javascript-pro.md +36 -0
  750. package/templates/.poetic/agents/performance-engineer.md +151 -0
  751. package/templates/.poetic/agents/python-pro.md +137 -0
  752. package/templates/.poetic/agents/test-automator.md +147 -0
  753. package/templates/.poetic/agents/typescript-pro.md +34 -0
  754. package/templates/.poetic/config/poetic.config.jsonc +69 -0
  755. package/templates/.poetic/config/project-context.template.json +6 -0
  756. package/templates/.poetic/config/task-type-aliases.presets/kanban.yaml +14 -0
  757. package/templates/.poetic/config/task-type-aliases.presets/scrum.yaml +17 -0
  758. package/templates/.poetic/config/task-type-aliases.presets/xp.yaml +12 -0
  759. package/templates/.poetic/config/task-type-aliases.yaml +28 -0
  760. package/templates/.poetic/gitignore.template +55 -0
  761. package/templates/.poetic/task-types/analysis.yaml +40 -0
  762. package/templates/.poetic/task-types/architecture.yaml +38 -0
  763. package/templates/.poetic/task-types/doc.yaml +35 -0
  764. package/templates/.poetic/task-types/feature.yaml +23 -0
  765. package/templates/.poetic/task-types/general.yaml +6 -0
  766. package/templates/.poetic/task-types/security.yaml +39 -0
  767. package/templates/AGENTS.template.md +99 -0
  768. package/templates/CLAUDE.template.md +1 -0
  769. package/templates/GEMINI.template.md +1 -0
  770. package/templates/builtin-workflows/code-review.yaml +73 -0
  771. package/templates/builtin-workflows/compete-streak.yaml +78 -0
  772. package/templates/builtin-workflows/hello-verify.yaml +10 -0
  773. package/templates/builtin-workflows/judge-regression.yaml +114 -0
  774. package/templates/builtin-workflows/skills/code-review/SKILL.md +60 -0
  775. package/templates/builtin-workflows/skills/hello-verify/SKILL.md +6 -0
  776. package/templates/guard-kit/GUARD_SETUP.md.template +255 -0
  777. package/templates/guard-kit/check.mjs.template +777 -0
  778. package/templates/guard-kit/config.json.template +6 -0
  779. package/templates/guard-kit/poetic-guard.yml.template +189 -0
  780. package/templates/profiles/README.md +56 -0
  781. package/templates/profiles/frontier-claude.json +27 -0
  782. package/templates/profiles/frontier-codex.json +26 -0
@@ -0,0 +1,2213 @@
1
+ import {
2
+ createBranchCleanupManager
3
+ } from "./chunk-7IL4A2PP.js";
4
+ import {
5
+ processScanner
6
+ } from "./chunk-U2S3YEX3.js";
7
+ import {
8
+ processRegistry
9
+ } from "./chunk-XPHKYHO4.js";
10
+ import {
11
+ processRemoteBranchCleanupQueue
12
+ } from "./chunk-BXI4NXL3.js";
13
+ import {
14
+ WORKFLOW_HEARTBEAT_STALE_AFTER_MS,
15
+ getWorkflowExecutionStatus,
16
+ getWorkflowLastActivityMs
17
+ } from "./chunk-CQM3A35X.js";
18
+ import {
19
+ reapOrphanedTmuxSessions
20
+ } from "./chunk-4CUY7AFY.js";
21
+ import {
22
+ DbSizeManager,
23
+ resolveRetentionConfig
24
+ } from "./chunk-J62KPGII.js";
25
+ import {
26
+ parseJsonWithContext
27
+ } from "./chunk-QVZMFDYG.js";
28
+ import {
29
+ WorktreeCleanupManager
30
+ } from "./chunk-DF5SLDE4.js";
31
+ import {
32
+ collectActiveRunPids
33
+ } from "./chunk-I5WRT7ZR.js";
34
+ import {
35
+ pruneGitWorktreeEntries
36
+ } from "./chunk-5EERLVZB.js";
37
+ import {
38
+ formatBytes
39
+ } from "./chunk-JLS65NUQ.js";
40
+ import {
41
+ getRuntimeEnv
42
+ } from "./chunk-ENRGKNR5.js";
43
+ import {
44
+ findProjectRoot
45
+ } from "./chunk-L6OM4A22.js";
46
+ import {
47
+ resolveWorktreeBase
48
+ } from "./chunk-UUH2RVKS.js";
49
+
50
+ // src/core/cleanup/stale-cleanup-orchestrator.ts
51
+ import { appendFile, mkdir as mkdir4, readdir as readdir3, readFile as readFile7, stat as stat8, writeFile as writeFile2 } from "fs/promises";
52
+ import { tmpdir } from "os";
53
+ import { basename, dirname, resolve as resolve6 } from "path";
54
+ import { execa } from "execa";
55
+
56
+ // src/telemetry/cleanup.ts
57
+ import * as fs from "fs";
58
+ import { readFile, rename, writeFile } from "fs/promises";
59
+ import * as path from "path";
60
+ import { promisify } from "util";
61
+ var stat2 = promisify(fs.stat);
62
+ var readdir2 = promisify(fs.readdir);
63
+ var unlink2 = promisify(fs.unlink);
64
+ var rm2 = promisify(fs.rm);
65
+ function cleanupActionLabel(action, dryRun) {
66
+ if (!dryRun) {
67
+ return action;
68
+ }
69
+ switch (action) {
70
+ case "DELETED":
71
+ return "WOULD DELETE";
72
+ case "ARCHIVED":
73
+ return "WOULD ARCHIVE";
74
+ case "SIZE-CAP":
75
+ return "WOULD SIZE-CAP";
76
+ default:
77
+ return `WOULD ${action}`;
78
+ }
79
+ }
80
+ async function getPathSize(filePath, stats) {
81
+ const entryStats = stats ?? await stat2(filePath);
82
+ if (!entryStats.isDirectory()) {
83
+ return entryStats.size;
84
+ }
85
+ let total = 0;
86
+ const entries = await readdir2(filePath, { withFileTypes: true });
87
+ for (const entry of entries) {
88
+ const childPath = path.join(filePath, entry.name);
89
+ if (entry.isDirectory()) {
90
+ total += await getPathSize(childPath);
91
+ } else if (entry.isFile()) {
92
+ const childStats = await stat2(childPath);
93
+ total += childStats.size;
94
+ }
95
+ }
96
+ return total;
97
+ }
98
+ function monthKeyFromBackupName(name) {
99
+ const isoMatch = name.match(/^(\d{4})-(\d{2})/);
100
+ if (isoMatch?.[1] && isoMatch[2]) {
101
+ return `${isoMatch[1]}${isoMatch[2]}`;
102
+ }
103
+ const compactMatch = name.match(/(\d{6})/);
104
+ if (compactMatch?.[1]) {
105
+ return compactMatch[1];
106
+ }
107
+ return "unknown";
108
+ }
109
+ var TelemetryCleanup = class _TelemetryCleanup {
110
+ config;
111
+ telemetryDir;
112
+ constructor(config, telemetryDir) {
113
+ this.config = config;
114
+ const poeticDir = getRuntimeEnv("POETIC_TELEMETRY_DIR") || path.join(process.cwd(), ".poetic");
115
+ this.telemetryDir = telemetryDir || path.join(poeticDir, "telemetry");
116
+ }
117
+ async cleanup(options = {}) {
118
+ const result = {
119
+ deletedBackups: 0,
120
+ deletedLogs: 0,
121
+ deletedSignalFiles: 0,
122
+ deletedMergeLedgerLines: 0,
123
+ freedSpaceBytes: 0,
124
+ vacuumExecuted: false
125
+ };
126
+ try {
127
+ const backupsDir = path.join(this.telemetryDir, "backups");
128
+ if (fs.existsSync(backupsDir)) {
129
+ const backupResult = await this.cleanupBackups(backupsDir, options);
130
+ result.deletedBackups = backupResult.deleted;
131
+ result.freedSpaceBytes += backupResult.freedBytes;
132
+ }
133
+ const logsDir = path.join(this.telemetryDir, "logs");
134
+ if (fs.existsSync(logsDir)) {
135
+ const effectiveLogsDays = options.logsDaysOverride ?? this.config.logs_days;
136
+ const logResult = await this.cleanupLogs(logsDir, effectiveLogsDays, options);
137
+ result.deletedLogs = logResult.deleted;
138
+ result.freedSpaceBytes += logResult.freedBytes;
139
+ }
140
+ const signalResult = await this.cleanupSignalFiles(
141
+ this.telemetryDir,
142
+ this.config.signal_files_retention_days,
143
+ options
144
+ );
145
+ result.deletedSignalFiles = signalResult.deleted;
146
+ result.freedSpaceBytes += signalResult.freedBytes;
147
+ const mergeLedgerResult = await this.cleanupMergeLedger(
148
+ this.telemetryDir,
149
+ this.config.signal_files_retention_days,
150
+ options
151
+ );
152
+ result.deletedMergeLedgerLines = mergeLedgerResult.deleted;
153
+ result.freedSpaceBytes += mergeLedgerResult.freedBytes;
154
+ const effectiveVacuum = options.vacuumOverride ?? this.config.vacuum_on_cleanup;
155
+ if (effectiveVacuum && !options.dryRun) {
156
+ const vacuumResult = await this.vacuumDatabase(options);
157
+ result.vacuumExecuted = vacuumResult;
158
+ }
159
+ } catch (error) {
160
+ console.error("Cleanup error:", error);
161
+ throw error;
162
+ }
163
+ return result;
164
+ }
165
+ async cleanupBackups(backupsDir, options) {
166
+ const files = await readdir2(backupsDir);
167
+ const now = Date.now();
168
+ const retentionMs = this.config.backups_days * 24 * 60 * 60 * 1e3;
169
+ const maxBackupBytes = this.config.backups_max_bytes ?? Number.POSITIVE_INFINITY;
170
+ const filesByMonth = /* @__PURE__ */ new Map();
171
+ const entries = [];
172
+ const deletedFiles = /* @__PURE__ */ new Set();
173
+ let deleted = 0;
174
+ let freedBytes = 0;
175
+ const deleteEntry = async (entry, label) => {
176
+ if (deletedFiles.has(entry.name)) return;
177
+ if (!options.dryRun) {
178
+ if (entry.isDirectory) {
179
+ await rm2(entry.path, { recursive: true, force: true });
180
+ } else {
181
+ await unlink2(entry.path);
182
+ }
183
+ }
184
+ deletedFiles.add(entry.name);
185
+ deleted++;
186
+ freedBytes += entry.size;
187
+ if (options.verbose) {
188
+ console.log(
189
+ ` [${cleanupActionLabel(label, options.dryRun ?? false)}] ${entry.name} (${formatBytes(entry.size)})`
190
+ );
191
+ }
192
+ };
193
+ for (const file of files) {
194
+ const filePath = path.join(backupsDir, file);
195
+ const stats = await stat2(filePath);
196
+ const size = await getPathSize(filePath, stats);
197
+ const month = monthKeyFromBackupName(file);
198
+ const entry = {
199
+ name: file,
200
+ path: filePath,
201
+ month,
202
+ mtime: stats.mtimeMs,
203
+ size,
204
+ isDirectory: stats.isDirectory()
205
+ };
206
+ entries.push(entry);
207
+ if (!filesByMonth.has(month)) {
208
+ filesByMonth.set(month, []);
209
+ }
210
+ filesByMonth.get(month)?.push(entry);
211
+ }
212
+ const monthsToKeep = Array.from(filesByMonth.keys()).sort().reverse().slice(0, this.config.backups_monthly_count);
213
+ for (const [month, monthFiles] of filesByMonth) {
214
+ const newestMonthlyArchive = [...monthFiles].sort((a, b) => b.mtime - a.mtime)[0];
215
+ for (const entry of monthFiles) {
216
+ const ageMs = now - entry.mtime;
217
+ if (ageMs <= retentionMs) continue;
218
+ if (!monthsToKeep.includes(month)) {
219
+ await deleteEntry(entry, "DELETED");
220
+ continue;
221
+ }
222
+ if (entry.name !== newestMonthlyArchive?.name) {
223
+ await deleteEntry(entry, "ARCHIVED");
224
+ }
225
+ }
226
+ }
227
+ const remaining = entries.filter((entry) => !deletedFiles.has(entry.name));
228
+ let remainingBytes = remaining.reduce((sum, entry) => sum + entry.size, 0);
229
+ const oldestFirst = [...remaining].sort((a, b) => a.mtime - b.mtime);
230
+ while (remainingBytes > maxBackupBytes && oldestFirst.length > 1) {
231
+ const entry = oldestFirst.shift();
232
+ if (!entry) break;
233
+ await deleteEntry(entry, "SIZE-CAP");
234
+ remainingBytes -= entry.size;
235
+ }
236
+ return { deleted, freedBytes };
237
+ }
238
+ async cleanupLogs(logsDir, logsDays, options) {
239
+ const files = await readdir2(logsDir);
240
+ const now = Date.now();
241
+ const retentionMs = logsDays * 24 * 60 * 60 * 1e3;
242
+ let deleted = 0;
243
+ let freedBytes = 0;
244
+ for (const file of files) {
245
+ const filePath = path.join(logsDir, file);
246
+ let stats;
247
+ try {
248
+ stats = await stat2(filePath);
249
+ } catch (error) {
250
+ const err = error;
251
+ if (err.code === "ENOENT") {
252
+ continue;
253
+ }
254
+ throw error;
255
+ }
256
+ const ageMs = now - stats.mtimeMs;
257
+ if (ageMs > retentionMs) {
258
+ let deleteStats = stats;
259
+ let freedBytesForEntry = await getPathSize(filePath, deleteStats);
260
+ if (!options.dryRun) {
261
+ try {
262
+ const latest = await stat2(filePath);
263
+ if (latest.mtimeMs !== stats.mtimeMs || latest.size !== stats.size) {
264
+ if (options.verbose) {
265
+ console.log(` [SKIP] ${file} changed during cleanup`);
266
+ }
267
+ continue;
268
+ }
269
+ deleteStats = latest;
270
+ freedBytesForEntry = await getPathSize(filePath, deleteStats);
271
+ } catch (error) {
272
+ const err = error;
273
+ if (err.code === "ENOENT") {
274
+ continue;
275
+ }
276
+ throw error;
277
+ }
278
+ if (deleteStats.isDirectory()) {
279
+ await rm2(filePath, { recursive: true, force: true });
280
+ } else {
281
+ await unlink2(filePath);
282
+ }
283
+ }
284
+ deleted++;
285
+ freedBytes += freedBytesForEntry;
286
+ if (options.verbose) {
287
+ console.log(
288
+ ` [${cleanupActionLabel("DELETED", options.dryRun ?? false)}] ${file} (${formatBytes(freedBytesForEntry)})`
289
+ );
290
+ }
291
+ }
292
+ }
293
+ return { deleted, freedBytes };
294
+ }
295
+ async cleanupSignalFiles(telemetryDir, retentionDays, options) {
296
+ let deleted = 0;
297
+ let freedBytes = 0;
298
+ if (!fs.existsSync(telemetryDir)) {
299
+ return { deleted, freedBytes };
300
+ }
301
+ let files;
302
+ try {
303
+ files = await readdir2(telemetryDir);
304
+ } catch {
305
+ return { deleted, freedBytes };
306
+ }
307
+ const now = Date.now();
308
+ const retentionMs = retentionDays * 24 * 60 * 60 * 1e3;
309
+ for (const file of files) {
310
+ if (!/^signals-.*\.jsonl$/.test(file)) continue;
311
+ const filePath = path.join(telemetryDir, file);
312
+ let stats;
313
+ try {
314
+ stats = await stat2(filePath);
315
+ } catch (error) {
316
+ const err = error;
317
+ if (err.code === "ENOENT") continue;
318
+ throw error;
319
+ }
320
+ if (!stats.isFile()) continue;
321
+ const ageMs = now - stats.mtimeMs;
322
+ if (ageMs <= retentionMs) continue;
323
+ if (!options.dryRun) {
324
+ try {
325
+ const latest = await stat2(filePath);
326
+ if (latest.mtimeMs !== stats.mtimeMs || latest.size !== stats.size) {
327
+ if (options.verbose) {
328
+ console.log(` [SKIP] ${file} changed during cleanup`);
329
+ }
330
+ continue;
331
+ }
332
+ } catch (error) {
333
+ const err = error;
334
+ if (err.code === "ENOENT") continue;
335
+ throw error;
336
+ }
337
+ await unlink2(filePath);
338
+ }
339
+ deleted++;
340
+ freedBytes += stats.size;
341
+ if (options.verbose) {
342
+ console.log(
343
+ ` [${cleanupActionLabel("DELETED", options.dryRun ?? false)}] ${file} (${formatBytes(stats.size)})`
344
+ );
345
+ }
346
+ }
347
+ return { deleted, freedBytes };
348
+ }
349
+ async cleanupMergeLedger(telemetryDir, retentionDays, options) {
350
+ let deleted = 0;
351
+ let freedBytes = 0;
352
+ const ledgerPath = path.join(telemetryDir, "merge-ledger.jsonl");
353
+ if (!fs.existsSync(ledgerPath)) {
354
+ return { deleted, freedBytes };
355
+ }
356
+ let stats;
357
+ try {
358
+ stats = await stat2(ledgerPath);
359
+ } catch (error) {
360
+ const err = error;
361
+ if (err.code === "ENOENT") {
362
+ return { deleted, freedBytes };
363
+ }
364
+ throw error;
365
+ }
366
+ if (!stats.isFile()) {
367
+ return { deleted, freedBytes };
368
+ }
369
+ const originalContent = await readFile(ledgerPath, "utf8");
370
+ const now = Date.now();
371
+ const retentionMs = retentionDays * 24 * 60 * 60 * 1e3;
372
+ const keptLines = [];
373
+ for (const line of originalContent.split("\n")) {
374
+ const trimmed = line.trim();
375
+ if (!trimmed) {
376
+ continue;
377
+ }
378
+ try {
379
+ const record = JSON.parse(trimmed);
380
+ const mergedAtMs = record.mergedAt ? Date.parse(record.mergedAt) : Number.NaN;
381
+ if (!Number.isFinite(mergedAtMs) || now - mergedAtMs <= retentionMs) {
382
+ keptLines.push(trimmed);
383
+ continue;
384
+ }
385
+ deleted++;
386
+ } catch {
387
+ keptLines.push(trimmed);
388
+ }
389
+ }
390
+ if (deleted === 0) {
391
+ return { deleted, freedBytes };
392
+ }
393
+ const newContent = keptLines.length > 0 ? `${keptLines.join("\n")}
394
+ ` : "";
395
+ freedBytes = Math.max(0, stats.size - Buffer.byteLength(newContent, "utf8"));
396
+ if (!options.dryRun) {
397
+ if (newContent) {
398
+ const tmpPath = `${ledgerPath}.${process.pid}.tmp`;
399
+ try {
400
+ await writeFile(tmpPath, newContent, "utf8");
401
+ await rename(tmpPath, ledgerPath);
402
+ } catch (writeError) {
403
+ try {
404
+ await unlink2(tmpPath);
405
+ } catch {
406
+ }
407
+ throw writeError;
408
+ }
409
+ } else {
410
+ await unlink2(ledgerPath);
411
+ }
412
+ }
413
+ if (options.verbose && deleted > 0) {
414
+ console.log(` [TRIMMED] merge-ledger.jsonl (${deleted} stale lines)`);
415
+ }
416
+ return { deleted, freedBytes };
417
+ }
418
+ async vacuumDatabase(options) {
419
+ try {
420
+ const sqlite3 = await import("better-sqlite3").catch(() => null);
421
+ if (!sqlite3) {
422
+ if (options.verbose) {
423
+ console.log(" [SKIP] SQLite not available for VACUUM");
424
+ }
425
+ return false;
426
+ }
427
+ const dbPaths = [
428
+ { label: "variants.db", path: path.join(this.telemetryDir, "db", "variants.db") },
429
+ { label: "validations.db", path: path.join(this.telemetryDir, "db", "validations.db") },
430
+ { label: "invocations.db", path: path.join(this.telemetryDir, "invocations.db") }
431
+ ];
432
+ const existing = dbPaths.filter((entry) => fs.existsSync(entry.path));
433
+ if (existing.length === 0) {
434
+ if (options.verbose) {
435
+ console.log(" [SKIP] No telemetry databases found to VACUUM");
436
+ }
437
+ return false;
438
+ }
439
+ let vacuumedAny = false;
440
+ for (const entry of existing) {
441
+ try {
442
+ const db = sqlite3.default(entry.path);
443
+ db.exec("VACUUM");
444
+ db.close();
445
+ vacuumedAny = true;
446
+ if (options.verbose) {
447
+ console.log(` [VACUUMED] ${entry.label}`);
448
+ }
449
+ } catch (error) {
450
+ if (options.verbose) {
451
+ console.error(` [ERROR] VACUUM failed for ${entry.label}:`, error);
452
+ }
453
+ }
454
+ }
455
+ return vacuumedAny;
456
+ } catch (error) {
457
+ if (options.verbose) {
458
+ console.error(" [ERROR] VACUUM operation failed:", error);
459
+ }
460
+ return false;
461
+ }
462
+ }
463
+ static async fromConfig(configPath, telemetryDir) {
464
+ const resolved = resolveRetentionConfig({ configFilePath: configPath ?? void 0 });
465
+ const config = {
466
+ backups_days: resolved.backupsDays,
467
+ backups_monthly_count: resolved.backupsMonthlyCount,
468
+ backups_max_bytes: resolved.backupsMaxBytes,
469
+ logs_days: resolved.logsDays,
470
+ vacuum_on_cleanup: resolved.vacuumOnCleanup,
471
+ signal_files_retention_days: resolved.signalFilesRetentionDays
472
+ };
473
+ return new _TelemetryCleanup(config, telemetryDir);
474
+ }
475
+ };
476
+
477
+ // src/core/cleanup/background-state-cleanup.ts
478
+ import { mkdir, opendir, readFile as readFile2, rename as rename2, stat as stat3 } from "fs/promises";
479
+ import { resolve } from "path";
480
+ function parseIsoDateMs(value) {
481
+ if (!value) return null;
482
+ const ms = new Date(value).getTime();
483
+ if (!Number.isFinite(ms)) return null;
484
+ return ms;
485
+ }
486
+ function isBackgroundHandle(value) {
487
+ return typeof value.taskId === "string" && value.taskId.trim().length > 0 && typeof value.status === "string" && value.status.trim().length > 0;
488
+ }
489
+ function isActiveBackgroundRun(handle) {
490
+ return handle.status === "running";
491
+ }
492
+ function isLivePid(pid) {
493
+ if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0) return false;
494
+ try {
495
+ process.kill(pid, 0);
496
+ return true;
497
+ } catch (error) {
498
+ const code = error.code;
499
+ if (code === "ESRCH") return false;
500
+ return "unknown";
501
+ }
502
+ }
503
+ function monthBucket(mtimeMs) {
504
+ const date = new Date(mtimeMs);
505
+ const year = date.getUTCFullYear();
506
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
507
+ return `${year}-${month}`;
508
+ }
509
+ async function uniqueArchivePath(targetPath) {
510
+ try {
511
+ await stat3(targetPath);
512
+ } catch {
513
+ return targetPath;
514
+ }
515
+ for (let index = 1; index < 1e3; index++) {
516
+ const candidate = `${targetPath}.${index}`;
517
+ try {
518
+ await stat3(candidate);
519
+ } catch {
520
+ return candidate;
521
+ }
522
+ }
523
+ throw new Error(`Unable to find free archive path for ${targetPath}`);
524
+ }
525
+ async function cleanupBackgroundStateFiles(options) {
526
+ const cwd = options.cwd ?? process.cwd();
527
+ const now = options.now ?? /* @__PURE__ */ new Date();
528
+ const rootDir = resolve(cwd, ".poetic/telemetry/state/background");
529
+ const archiveDir = options.archiveDir ?? resolve(cwd, ".poetic/telemetry/state/background-archive");
530
+ const maxAgeMs = options.maxAgeDays * 24 * 60 * 60 * 1e3;
531
+ const report = {
532
+ mode: options.dryRun ? "dry-run" : "executed",
533
+ rootDir,
534
+ archiveDir,
535
+ scanned: 0,
536
+ eligible: 0,
537
+ archived: 0,
538
+ kept: 0,
539
+ freedBytes: 0,
540
+ keptBecause: {},
541
+ archivedBecause: {},
542
+ items: [],
543
+ errors: []
544
+ };
545
+ const bump = (map, key) => {
546
+ map[key] = (map[key] ?? 0) + 1;
547
+ };
548
+ try {
549
+ const dir = await opendir(rootDir);
550
+ try {
551
+ for await (const d of dir) {
552
+ if (!d.isFile()) continue;
553
+ if (!d.name.endsWith(".json")) continue;
554
+ const fullPath = resolve(rootDir, d.name);
555
+ report.scanned++;
556
+ let sizeBytes = 0;
557
+ let timestampMs = 0;
558
+ let archiveDeadActiveRun = false;
559
+ try {
560
+ const st = await stat3(fullPath);
561
+ sizeBytes = st.size;
562
+ timestampMs = st.mtimeMs;
563
+ const raw = await readFile2(fullPath, "utf8");
564
+ let parsed;
565
+ try {
566
+ parsed = parseJsonWithContext(
567
+ raw,
568
+ `Background state (${d.name})`
569
+ );
570
+ } catch {
571
+ const ageDays2 = Math.floor((now.getTime() - timestampMs) / (24 * 60 * 60 * 1e3));
572
+ bump(report.keptBecause, "invalid_json");
573
+ report.kept++;
574
+ report.items.push({
575
+ path: fullPath,
576
+ sizeBytes,
577
+ ageDays: ageDays2,
578
+ decision: "keep",
579
+ reason: "invalid_json"
580
+ });
581
+ continue;
582
+ }
583
+ if (!isBackgroundHandle(parsed)) {
584
+ const ageDays2 = Math.floor((now.getTime() - timestampMs) / (24 * 60 * 60 * 1e3));
585
+ bump(report.keptBecause, "not_background_handle");
586
+ report.kept++;
587
+ report.items.push({
588
+ path: fullPath,
589
+ sizeBytes,
590
+ ageDays: ageDays2,
591
+ decision: "keep",
592
+ reason: "not_background_handle"
593
+ });
594
+ continue;
595
+ }
596
+ timestampMs = parseIsoDateMs(parsed.updatedAt) ?? parseIsoDateMs(parsed.startedAt) ?? parseIsoDateMs(parsed.createdAt) ?? timestampMs;
597
+ if (isActiveBackgroundRun(parsed)) {
598
+ const ageDays2 = Math.floor((now.getTime() - timestampMs) / (24 * 60 * 60 * 1e3));
599
+ const live = isLivePid(parsed.pid);
600
+ if (live === true || live === "unknown") {
601
+ bump(report.keptBecause, "active_run");
602
+ report.kept++;
603
+ report.items.push({
604
+ path: fullPath,
605
+ sizeBytes,
606
+ ageDays: ageDays2,
607
+ decision: "keep",
608
+ reason: "active_run"
609
+ });
610
+ continue;
611
+ }
612
+ archiveDeadActiveRun = true;
613
+ }
614
+ } catch (error) {
615
+ const msg = error instanceof Error ? error.message : String(error);
616
+ report.errors.push(`${d.name}: stat/read failed: ${msg}`);
617
+ bump(report.keptBecause, "read_error");
618
+ report.kept++;
619
+ report.items.push({
620
+ path: fullPath,
621
+ sizeBytes: 0,
622
+ ageDays: 0,
623
+ decision: "keep",
624
+ reason: "read_error"
625
+ });
626
+ continue;
627
+ }
628
+ const ageMs = now.getTime() - timestampMs;
629
+ const ageDays = Math.floor(ageMs / (24 * 60 * 60 * 1e3));
630
+ if (ageMs <= maxAgeMs && !archiveDeadActiveRun) {
631
+ bump(report.keptBecause, "too_recent");
632
+ report.kept++;
633
+ report.items.push({
634
+ path: fullPath,
635
+ sizeBytes,
636
+ ageDays,
637
+ decision: "keep",
638
+ reason: "too_recent"
639
+ });
640
+ continue;
641
+ }
642
+ report.eligible++;
643
+ const item = {
644
+ path: fullPath,
645
+ sizeBytes,
646
+ ageDays,
647
+ decision: "archive",
648
+ reason: "stale_background"
649
+ };
650
+ if (options.dryRun) {
651
+ bump(report.archivedBecause, "stale_background");
652
+ report.freedBytes += sizeBytes;
653
+ } else {
654
+ try {
655
+ const archiveMonthDir = resolve(archiveDir, monthBucket(timestampMs));
656
+ await mkdir(archiveMonthDir, { recursive: true });
657
+ const targetPath = await uniqueArchivePath(resolve(archiveMonthDir, d.name));
658
+ await rename2(fullPath, targetPath);
659
+ item.archivePath = targetPath;
660
+ report.archived++;
661
+ bump(report.archivedBecause, "stale_background");
662
+ report.freedBytes += sizeBytes;
663
+ } catch (error) {
664
+ const msg = error instanceof Error ? error.message : String(error);
665
+ report.errors.push(`${d.name}: archive failed: ${msg}`);
666
+ item.decision = "keep";
667
+ item.reason = "read_error";
668
+ report.kept++;
669
+ bump(report.keptBecause, "read_error");
670
+ report.items.push(item);
671
+ continue;
672
+ }
673
+ }
674
+ report.items.push(item);
675
+ }
676
+ } finally {
677
+ await dir.close().catch(() => {
678
+ });
679
+ }
680
+ } catch {
681
+ return report;
682
+ }
683
+ if (options.dryRun) {
684
+ report.archived = report.eligible;
685
+ }
686
+ if (!options.verbose) {
687
+ report.items = report.items.slice(0, 200);
688
+ }
689
+ return report;
690
+ }
691
+
692
+ // src/core/cleanup/competition-state-cleanup.ts
693
+ import { opendir as opendir2, readFile as readFile3, rm as rm3, stat as stat4 } from "fs/promises";
694
+ import { resolve as resolve2 } from "path";
695
+ function parseIsoDateMs2(value) {
696
+ if (!value) return null;
697
+ const ms = new Date(value).getTime();
698
+ if (!Number.isFinite(ms)) return null;
699
+ return ms;
700
+ }
701
+ function isTerminalCandidate(candidate) {
702
+ if (candidate.submittedOnly === true) return false;
703
+ if (typeof candidate.success === "boolean") return true;
704
+ if (candidate.timedOut === true) return true;
705
+ if (typeof candidate.errorMessage === "string" && candidate.errorMessage.trim().length > 0) {
706
+ return true;
707
+ }
708
+ return false;
709
+ }
710
+ function getHandleCandidates(handle) {
711
+ if (Array.isArray(handle.candidates)) return handle.candidates;
712
+ if (Array.isArray(handle.variants)) return handle.variants;
713
+ return [];
714
+ }
715
+ function isTerminalHandle(handle) {
716
+ const candidates = getHandleCandidates(handle);
717
+ if (candidates.length === 0) return false;
718
+ return candidates.every(isTerminalCandidate);
719
+ }
720
+ function describeNonTerminalMetadata(handle) {
721
+ const candidates = getHandleCandidates(handle);
722
+ const hasSubmittedOnly = candidates.length > 0 && candidates.every((candidate) => candidate.submittedOnly === true);
723
+ const hasStatusFields = candidates.some((candidate) => {
724
+ if (typeof candidate.success === "boolean") return true;
725
+ if (candidate.timedOut === true) return true;
726
+ if (typeof candidate.errorMessage === "string" && candidate.errorMessage.trim().length > 0) {
727
+ return true;
728
+ }
729
+ return false;
730
+ });
731
+ return {
732
+ hasSubmittedOnly,
733
+ hasStatusFields
734
+ };
735
+ }
736
+ function evaluateNonTerminalState(ageMs, metadata, policy) {
737
+ if (policy === "strict") {
738
+ return { keep: true, reason: "non_terminal" };
739
+ }
740
+ const hours = ageMs / (60 * 60 * 1e3);
741
+ const days = ageMs / (24 * 60 * 60 * 1e3);
742
+ if (days >= 30) {
743
+ return { keep: false, reason: "non_terminal_stale" };
744
+ }
745
+ if (metadata.hasSubmittedOnly && days >= 7) {
746
+ return { keep: false, reason: "non_terminal_submitted_expired" };
747
+ }
748
+ if (metadata.hasSubmittedOnly && hours >= 48) {
749
+ return { keep: true, reason: "non_terminal_submitted_grace" };
750
+ }
751
+ if (!metadata.hasStatusFields && hours >= 48) {
752
+ return { keep: false, reason: "non_terminal_missing_status" };
753
+ }
754
+ return { keep: true, reason: "non_terminal" };
755
+ }
756
+ async function cleanupCompetitionStateFiles(options) {
757
+ const cwd = options.cwd ?? process.cwd();
758
+ const now = options.now ?? /* @__PURE__ */ new Date();
759
+ const rootDir = resolve2(cwd, ".poetic/telemetry/state/competitions");
760
+ const maxAgeMs = options.maxAgeDays * 24 * 60 * 60 * 1e3;
761
+ const report = {
762
+ mode: options.dryRun ? "dry-run" : "executed",
763
+ rootDir,
764
+ scanned: 0,
765
+ eligible: 0,
766
+ deleted: 0,
767
+ kept: 0,
768
+ freedBytes: 0,
769
+ keptBecause: {},
770
+ deletedBecause: {},
771
+ items: [],
772
+ errors: []
773
+ };
774
+ const bump = (map, key) => {
775
+ map[key] = (map[key] ?? 0) + 1;
776
+ };
777
+ const entries = [];
778
+ try {
779
+ const dir = await opendir2(rootDir);
780
+ try {
781
+ for await (const d of dir) {
782
+ if (!d.isFile()) continue;
783
+ if (!d.name.endsWith(".json")) continue;
784
+ const fullPath = resolve2(rootDir, d.name);
785
+ report.scanned++;
786
+ try {
787
+ const st = await stat4(fullPath);
788
+ const sizeBytes = st.size;
789
+ const tsMsFromStat = st.mtimeMs;
790
+ const raw = await readFile3(fullPath, "utf8");
791
+ let parsed;
792
+ try {
793
+ parsed = parseJsonWithContext(raw, `Competition state (${d.name})`);
794
+ } catch {
795
+ const ageDays = Math.floor((now.getTime() - tsMsFromStat) / (24 * 60 * 60 * 1e3));
796
+ bump(report.keptBecause, "invalid_json");
797
+ report.kept++;
798
+ report.items.push({
799
+ path: fullPath,
800
+ sizeBytes,
801
+ ageDays,
802
+ terminal: false,
803
+ decision: "keep",
804
+ reason: "invalid_json"
805
+ });
806
+ continue;
807
+ }
808
+ const updatedMs = parseIsoDateMs2(parsed.updatedAt) ?? parseIsoDateMs2(parsed.createdAt);
809
+ const terminal = isTerminalHandle(parsed);
810
+ const metadata = describeNonTerminalMetadata(parsed);
811
+ entries.push({
812
+ name: d.name,
813
+ fullPath,
814
+ sizeBytes,
815
+ tsMs: updatedMs ?? tsMsFromStat,
816
+ terminal,
817
+ metadata
818
+ });
819
+ } catch (error) {
820
+ const msg = error instanceof Error ? error.message : String(error);
821
+ report.errors.push(`${d.name}: stat/read failed: ${msg}`);
822
+ bump(report.keptBecause, "read_error");
823
+ report.kept++;
824
+ report.items.push({
825
+ path: fullPath,
826
+ sizeBytes: 0,
827
+ ageDays: 0,
828
+ terminal: false,
829
+ decision: "keep",
830
+ reason: "read_error"
831
+ });
832
+ }
833
+ }
834
+ } finally {
835
+ await dir.close().catch(() => {
836
+ });
837
+ }
838
+ } catch (error) {
839
+ const msg = error instanceof Error ? error.message : String(error);
840
+ report.errors.push(`Failed to read ${rootDir}: ${msg}`);
841
+ return report;
842
+ }
843
+ const keepLast = Math.max(0, options.keepLast);
844
+ const keepLastSet = /* @__PURE__ */ new Set();
845
+ if (keepLast > 0) {
846
+ const sorted = [...entries].sort((a, b) => b.tsMs - a.tsMs);
847
+ for (const e of sorted.slice(0, keepLast)) {
848
+ keepLastSet.add(e.fullPath);
849
+ }
850
+ }
851
+ for (const entry of entries) {
852
+ const ageMs = now.getTime() - entry.tsMs;
853
+ const ageDays = Math.floor(ageMs / (24 * 60 * 60 * 1e3));
854
+ const terminal = entry.terminal;
855
+ const metadata = entry.metadata;
856
+ const policy = options.nonTerminalPolicy ?? (options.keepNonTerminal ? "strict" : "smart");
857
+ const isTooOld = ageMs > maxAgeMs;
858
+ let decision = "keep";
859
+ let reason = "too_recent";
860
+ if (keepLastSet.has(entry.fullPath)) {
861
+ decision = "keep";
862
+ reason = "keep_last";
863
+ bump(report.keptBecause, reason);
864
+ } else if (!isTooOld) {
865
+ decision = "keep";
866
+ reason = "too_recent";
867
+ bump(report.keptBecause, reason);
868
+ } else if (!terminal) {
869
+ const disposition = evaluateNonTerminalState(ageMs, metadata, policy);
870
+ if (disposition.keep) {
871
+ decision = "keep";
872
+ reason = disposition.reason;
873
+ bump(report.keptBecause, reason);
874
+ } else {
875
+ decision = "delete";
876
+ reason = disposition.reason;
877
+ bump(report.deletedBecause, reason);
878
+ }
879
+ } else {
880
+ decision = "delete";
881
+ reason = "stale_terminal";
882
+ bump(report.deletedBecause, reason);
883
+ }
884
+ if (decision === "delete") {
885
+ report.eligible++;
886
+ if (options.dryRun) {
887
+ report.freedBytes += entry.sizeBytes;
888
+ } else {
889
+ try {
890
+ await rm3(entry.fullPath, { force: true });
891
+ const eventsPath = entry.fullPath.replace(/\.json$/, ".events.jsonl");
892
+ await rm3(eventsPath, { force: true }).catch(() => {
893
+ });
894
+ report.deleted++;
895
+ report.freedBytes += entry.sizeBytes;
896
+ } catch (error) {
897
+ const msg = error instanceof Error ? error.message : String(error);
898
+ report.errors.push(`${entry.name}: delete failed: ${msg}`);
899
+ decision = "keep";
900
+ reason = "read_error";
901
+ bump(report.keptBecause, reason);
902
+ }
903
+ }
904
+ }
905
+ if (decision === "keep") report.kept++;
906
+ report.items.push({
907
+ path: entry.fullPath,
908
+ sizeBytes: entry.sizeBytes,
909
+ ageDays,
910
+ terminal,
911
+ decision,
912
+ reason
913
+ });
914
+ }
915
+ if (options.dryRun) {
916
+ report.deleted = report.eligible;
917
+ }
918
+ if (!options.verbose) {
919
+ report.items = report.items.slice(0, 200);
920
+ }
921
+ return report;
922
+ }
923
+
924
+ // src/core/cleanup/flywheel-tmp-cleanup.ts
925
+ import { mkdir as mkdir2, opendir as opendir3, readFile as readFile4, rename as rename3, stat as stat5 } from "fs/promises";
926
+ import { resolve as resolve3 } from "path";
927
+ var RESERVED_ENTRIES = /* @__PURE__ */ new Set(["legacy-archive", "detached", "cache"]);
928
+ function monthBucket2(mtimeMs) {
929
+ const date = new Date(mtimeMs);
930
+ const year = date.getUTCFullYear();
931
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
932
+ return `${year}-${month}`;
933
+ }
934
+ async function uniqueArchivePath2(targetPath) {
935
+ try {
936
+ await stat5(targetPath);
937
+ } catch {
938
+ return targetPath;
939
+ }
940
+ for (let index = 1; index < 1e3; index++) {
941
+ const candidate = `${targetPath}.${index}`;
942
+ try {
943
+ await stat5(candidate);
944
+ } catch {
945
+ return candidate;
946
+ }
947
+ }
948
+ throw new Error(`Unable to find free archive path for ${targetPath}`);
949
+ }
950
+ async function collectDirectoryInfo(dir) {
951
+ let sizeBytes = 0;
952
+ let newestMtimeMs = null;
953
+ async function walk(current) {
954
+ const entries = await opendir3(current);
955
+ try {
956
+ for await (const entry of entries) {
957
+ const fullPath = resolve3(current, entry.name);
958
+ if (entry.isDirectory()) {
959
+ await walk(fullPath);
960
+ continue;
961
+ }
962
+ if (!entry.isFile()) continue;
963
+ const fileStats = await stat5(fullPath);
964
+ sizeBytes += fileStats.size;
965
+ newestMtimeMs = newestMtimeMs === null ? fileStats.mtimeMs : Math.max(newestMtimeMs, fileStats.mtimeMs);
966
+ }
967
+ } finally {
968
+ await entries.close().catch(() => {
969
+ });
970
+ }
971
+ }
972
+ await walk(dir);
973
+ if (newestMtimeMs === null) {
974
+ const rootStats = await stat5(dir);
975
+ newestMtimeMs = rootStats.mtimeMs;
976
+ }
977
+ return { sizeBytes, newestMtimeMs };
978
+ }
979
+ async function readWorkflowManifest(workflowDir) {
980
+ const manifestPath = resolve3(workflowDir, "manifest.json");
981
+ try {
982
+ const raw = await readFile4(manifestPath, "utf8");
983
+ const manifest = parseJsonWithContext(
984
+ raw,
985
+ `Flywheel manifest (${manifestPath})`
986
+ );
987
+ return { manifest };
988
+ } catch (error) {
989
+ const msg = error instanceof Error ? error.message : String(error);
990
+ return { manifest: null, readError: msg };
991
+ }
992
+ }
993
+ function isActiveWorkflow(manifest, now) {
994
+ if (getWorkflowExecutionStatus({ manifest, now, branchExists: true }) === "running") {
995
+ return true;
996
+ }
997
+ if (manifest.appliedAt || manifest.stagedAt || manifest.applyError) {
998
+ return false;
999
+ }
1000
+ const lastActivityMs = getWorkflowLastActivityMs(manifest);
1001
+ if (lastActivityMs === void 0) {
1002
+ return false;
1003
+ }
1004
+ return now - lastActivityMs <= WORKFLOW_HEARTBEAT_STALE_AFTER_MS;
1005
+ }
1006
+ async function cleanupFlywheelTmpEntries(options) {
1007
+ const cwd = options.cwd ?? process.cwd();
1008
+ const now = options.now ?? /* @__PURE__ */ new Date();
1009
+ const nowMs = now.getTime();
1010
+ const rootDir = resolve3(cwd, ".poetic/tmp/flywheel");
1011
+ const archiveDir = options.archiveDir ?? resolve3(rootDir, "legacy-archive");
1012
+ const maxAgeMs = options.maxAgeDays * 24 * 60 * 60 * 1e3;
1013
+ const report = {
1014
+ mode: options.dryRun ? "dry-run" : "executed",
1015
+ rootDir,
1016
+ archiveDir,
1017
+ scanned: 0,
1018
+ eligible: 0,
1019
+ archived: 0,
1020
+ kept: 0,
1021
+ freedBytes: 0,
1022
+ keptBecause: {},
1023
+ archivedBecause: {},
1024
+ items: [],
1025
+ errors: []
1026
+ };
1027
+ const bump = (map, key) => {
1028
+ map[key] = (map[key] ?? 0) + 1;
1029
+ };
1030
+ try {
1031
+ const dir = await opendir3(rootDir);
1032
+ try {
1033
+ for await (const d of dir) {
1034
+ if (!d.isDirectory()) continue;
1035
+ const fullPath = resolve3(rootDir, d.name);
1036
+ report.scanned++;
1037
+ if (RESERVED_ENTRIES.has(d.name)) {
1038
+ bump(report.keptBecause, "reserved_entry");
1039
+ report.kept++;
1040
+ report.items.push({
1041
+ path: fullPath,
1042
+ sizeBytes: 0,
1043
+ ageDays: 0,
1044
+ decision: "keep",
1045
+ reason: "reserved_entry"
1046
+ });
1047
+ continue;
1048
+ }
1049
+ let sizeBytes = 0;
1050
+ let timestampMs = 0;
1051
+ try {
1052
+ const info = await collectDirectoryInfo(fullPath);
1053
+ sizeBytes = info.sizeBytes;
1054
+ timestampMs = info.newestMtimeMs ?? 0;
1055
+ const { manifest } = await readWorkflowManifest(fullPath);
1056
+ if (manifest && isActiveWorkflow(manifest, nowMs)) {
1057
+ bump(report.keptBecause, "active_run");
1058
+ report.kept++;
1059
+ report.items.push({
1060
+ path: fullPath,
1061
+ sizeBytes,
1062
+ ageDays: Math.floor((nowMs - timestampMs) / (24 * 60 * 60 * 1e3)),
1063
+ decision: "keep",
1064
+ reason: "active_run"
1065
+ });
1066
+ continue;
1067
+ }
1068
+ if (!manifest) {
1069
+ bump(report.keptBecause, "not_workflow_dir");
1070
+ report.kept++;
1071
+ report.items.push({
1072
+ path: fullPath,
1073
+ sizeBytes,
1074
+ ageDays: Math.floor((nowMs - timestampMs) / (24 * 60 * 60 * 1e3)),
1075
+ decision: "keep",
1076
+ reason: "not_workflow_dir"
1077
+ });
1078
+ continue;
1079
+ }
1080
+ } catch (error) {
1081
+ const msg = error instanceof Error ? error.message : String(error);
1082
+ report.errors.push(`${d.name}: stat/read failed: ${msg}`);
1083
+ bump(report.keptBecause, "read_error");
1084
+ report.kept++;
1085
+ report.items.push({
1086
+ path: fullPath,
1087
+ sizeBytes: 0,
1088
+ ageDays: 0,
1089
+ decision: "keep",
1090
+ reason: "read_error"
1091
+ });
1092
+ continue;
1093
+ }
1094
+ const ageMs = nowMs - timestampMs;
1095
+ const ageDays = Math.floor(ageMs / (24 * 60 * 60 * 1e3));
1096
+ if (ageMs <= maxAgeMs) {
1097
+ bump(report.keptBecause, "too_recent");
1098
+ report.kept++;
1099
+ report.items.push({
1100
+ path: fullPath,
1101
+ sizeBytes,
1102
+ ageDays,
1103
+ decision: "keep",
1104
+ reason: "too_recent"
1105
+ });
1106
+ continue;
1107
+ }
1108
+ report.eligible++;
1109
+ const item = {
1110
+ path: fullPath,
1111
+ sizeBytes,
1112
+ ageDays,
1113
+ decision: "archive",
1114
+ reason: "stale_workflow"
1115
+ };
1116
+ if (options.dryRun) {
1117
+ bump(report.archivedBecause, "stale_workflow");
1118
+ report.freedBytes += sizeBytes;
1119
+ } else {
1120
+ try {
1121
+ const archiveMonthDir = resolve3(archiveDir, monthBucket2(timestampMs));
1122
+ await mkdir2(archiveMonthDir, { recursive: true });
1123
+ const targetPath = await uniqueArchivePath2(resolve3(archiveMonthDir, d.name));
1124
+ await rename3(fullPath, targetPath);
1125
+ item.archivePath = targetPath;
1126
+ report.archived++;
1127
+ bump(report.archivedBecause, "stale_workflow");
1128
+ report.freedBytes += sizeBytes;
1129
+ } catch (error) {
1130
+ const msg = error instanceof Error ? error.message : String(error);
1131
+ report.errors.push(`${d.name}: archive failed: ${msg}`);
1132
+ item.decision = "keep";
1133
+ item.reason = "read_error";
1134
+ report.kept++;
1135
+ bump(report.keptBecause, "read_error");
1136
+ report.items.push(item);
1137
+ continue;
1138
+ }
1139
+ }
1140
+ report.items.push(item);
1141
+ }
1142
+ } finally {
1143
+ await dir.close().catch(() => {
1144
+ });
1145
+ }
1146
+ } catch {
1147
+ return report;
1148
+ }
1149
+ if (options.dryRun) {
1150
+ report.archived = report.eligible;
1151
+ }
1152
+ if (!options.verbose) {
1153
+ report.items = report.items.slice(0, 200);
1154
+ }
1155
+ return report;
1156
+ }
1157
+
1158
+ // src/core/cleanup/tui-session-state-cleanup.ts
1159
+ import { opendir as opendir4, readFile as readFile5, rm as rm4, stat as stat6 } from "fs/promises";
1160
+ import { resolve as resolve4 } from "path";
1161
+ function parseIsoDateMs3(value) {
1162
+ if (!value) return null;
1163
+ const ms = new Date(value).getTime();
1164
+ if (!Number.isFinite(ms)) return null;
1165
+ return ms;
1166
+ }
1167
+ function isTuiSession(value) {
1168
+ return value.version === 1 && typeof value.sessionId === "string" && value.sessionId.trim().length > 0 && Array.isArray(value.turns);
1169
+ }
1170
+ async function cleanupTuiSessionStateFiles(options) {
1171
+ const cwd = options.cwd ?? process.cwd();
1172
+ const now = options.now ?? /* @__PURE__ */ new Date();
1173
+ const rootDir = resolve4(cwd, ".poetic/telemetry/state/tui-sessions");
1174
+ const maxAgeMs = options.maxAgeDays * 24 * 60 * 60 * 1e3;
1175
+ const report = {
1176
+ mode: options.dryRun ? "dry-run" : "executed",
1177
+ rootDir,
1178
+ scanned: 0,
1179
+ eligible: 0,
1180
+ deleted: 0,
1181
+ kept: 0,
1182
+ freedBytes: 0,
1183
+ keptBecause: {},
1184
+ deletedBecause: {},
1185
+ items: [],
1186
+ errors: []
1187
+ };
1188
+ const bump = (map, key) => {
1189
+ map[key] = (map[key] ?? 0) + 1;
1190
+ };
1191
+ try {
1192
+ const dir = await opendir4(rootDir);
1193
+ try {
1194
+ for await (const d of dir) {
1195
+ if (!d.isFile()) continue;
1196
+ if (!d.name.endsWith(".json")) continue;
1197
+ const fullPath = resolve4(rootDir, d.name);
1198
+ report.scanned++;
1199
+ let sizeBytes = 0;
1200
+ let timestampMs = 0;
1201
+ try {
1202
+ const st = await stat6(fullPath);
1203
+ sizeBytes = st.size;
1204
+ timestampMs = st.mtimeMs;
1205
+ const raw = await readFile5(fullPath, "utf8");
1206
+ let parsed;
1207
+ try {
1208
+ parsed = parseJsonWithContext(raw, `TUI session state (${d.name})`);
1209
+ } catch {
1210
+ const ageDays2 = Math.floor((now.getTime() - timestampMs) / (24 * 60 * 60 * 1e3));
1211
+ bump(report.keptBecause, "invalid_json");
1212
+ report.kept++;
1213
+ report.items.push({
1214
+ path: fullPath,
1215
+ sizeBytes,
1216
+ ageDays: ageDays2,
1217
+ decision: "keep",
1218
+ reason: "invalid_json"
1219
+ });
1220
+ continue;
1221
+ }
1222
+ if (!isTuiSession(parsed)) {
1223
+ const ageDays2 = Math.floor((now.getTime() - timestampMs) / (24 * 60 * 60 * 1e3));
1224
+ bump(report.keptBecause, "not_tui_session");
1225
+ report.kept++;
1226
+ report.items.push({
1227
+ path: fullPath,
1228
+ sizeBytes,
1229
+ ageDays: ageDays2,
1230
+ decision: "keep",
1231
+ reason: "not_tui_session"
1232
+ });
1233
+ continue;
1234
+ }
1235
+ timestampMs = parseIsoDateMs3(parsed.updatedAt) ?? parseIsoDateMs3(parsed.createdAt) ?? timestampMs;
1236
+ } catch (error) {
1237
+ const msg = error instanceof Error ? error.message : String(error);
1238
+ report.errors.push(`${d.name}: stat/read failed: ${msg}`);
1239
+ bump(report.keptBecause, "read_error");
1240
+ report.kept++;
1241
+ report.items.push({
1242
+ path: fullPath,
1243
+ sizeBytes: 0,
1244
+ ageDays: 0,
1245
+ decision: "keep",
1246
+ reason: "read_error"
1247
+ });
1248
+ continue;
1249
+ }
1250
+ const ageMs = now.getTime() - timestampMs;
1251
+ const ageDays = Math.floor(ageMs / (24 * 60 * 60 * 1e3));
1252
+ if (ageMs <= maxAgeMs) {
1253
+ bump(report.keptBecause, "too_recent");
1254
+ report.kept++;
1255
+ report.items.push({
1256
+ path: fullPath,
1257
+ sizeBytes,
1258
+ ageDays,
1259
+ decision: "keep",
1260
+ reason: "too_recent"
1261
+ });
1262
+ continue;
1263
+ }
1264
+ report.eligible++;
1265
+ if (options.dryRun) {
1266
+ bump(report.deletedBecause, "stale_session");
1267
+ report.freedBytes += sizeBytes;
1268
+ } else {
1269
+ try {
1270
+ await rm4(fullPath, { force: true });
1271
+ report.deleted++;
1272
+ bump(report.deletedBecause, "stale_session");
1273
+ report.freedBytes += sizeBytes;
1274
+ } catch (error) {
1275
+ const msg = error instanceof Error ? error.message : String(error);
1276
+ report.errors.push(`${d.name}: delete failed: ${msg}`);
1277
+ report.kept++;
1278
+ bump(report.keptBecause, "read_error");
1279
+ continue;
1280
+ }
1281
+ }
1282
+ report.items.push({
1283
+ path: fullPath,
1284
+ sizeBytes,
1285
+ ageDays,
1286
+ decision: "delete",
1287
+ reason: "stale_session"
1288
+ });
1289
+ }
1290
+ } finally {
1291
+ await dir.close().catch(() => {
1292
+ });
1293
+ }
1294
+ } catch {
1295
+ return report;
1296
+ }
1297
+ if (options.dryRun) {
1298
+ report.deleted = report.eligible;
1299
+ }
1300
+ if (!options.verbose) {
1301
+ report.items = report.items.slice(0, 200);
1302
+ }
1303
+ return report;
1304
+ }
1305
+
1306
+ // src/core/cleanup/variant-telemetry-state-cleanup.ts
1307
+ import { mkdir as mkdir3, opendir as opendir5, readFile as readFile6, rename as rename4, stat as stat7 } from "fs/promises";
1308
+ import { resolve as resolve5 } from "path";
1309
+ function parseIsoDateMs4(value) {
1310
+ if (!value) return null;
1311
+ const ms = new Date(value).getTime();
1312
+ if (!Number.isFinite(ms)) return null;
1313
+ return ms;
1314
+ }
1315
+ function isActiveVariantArtifact(fileName) {
1316
+ return fileName.endsWith(".partial.json") || fileName.endsWith(".partial.json.pid") || fileName.endsWith(".partial.json.sigterm");
1317
+ }
1318
+ function isVariantState(value) {
1319
+ return typeof value.taskId === "string" && value.taskId.trim().length > 0 || typeof value.variant === "string" && value.variant.trim().length > 0 || typeof value.provider === "string" && value.provider.trim().length > 0 && typeof value.strategy === "string" && value.strategy.trim().length > 0;
1320
+ }
1321
+ function monthBucket3(mtimeMs) {
1322
+ const date = new Date(mtimeMs);
1323
+ const year = date.getUTCFullYear();
1324
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
1325
+ return `${year}-${month}`;
1326
+ }
1327
+ async function uniqueArchivePath3(targetPath) {
1328
+ try {
1329
+ await stat7(targetPath);
1330
+ } catch {
1331
+ return targetPath;
1332
+ }
1333
+ for (let index = 1; index < 1e3; index++) {
1334
+ const candidate = `${targetPath}.${index}`;
1335
+ try {
1336
+ await stat7(candidate);
1337
+ } catch {
1338
+ return candidate;
1339
+ }
1340
+ }
1341
+ throw new Error(`Unable to find free archive path for ${targetPath}`);
1342
+ }
1343
+ async function cleanupVariantTelemetryStateFiles(options) {
1344
+ const cwd = options.cwd ?? process.cwd();
1345
+ const now = options.now ?? /* @__PURE__ */ new Date();
1346
+ const rootDir = resolve5(cwd, ".poetic/telemetry/state/variants");
1347
+ const archiveDir = options.archiveDir ?? resolve5(cwd, ".poetic/telemetry/state/variants-archive");
1348
+ const maxAgeMs = options.maxAgeDays * 24 * 60 * 60 * 1e3;
1349
+ const report = {
1350
+ mode: options.dryRun ? "dry-run" : "executed",
1351
+ rootDir,
1352
+ archiveDir,
1353
+ scanned: 0,
1354
+ eligible: 0,
1355
+ archived: 0,
1356
+ kept: 0,
1357
+ freedBytes: 0,
1358
+ keptBecause: {},
1359
+ archivedBecause: {},
1360
+ items: [],
1361
+ errors: []
1362
+ };
1363
+ const bump = (map, key) => {
1364
+ map[key] = (map[key] ?? 0) + 1;
1365
+ };
1366
+ try {
1367
+ const dir = await opendir5(rootDir);
1368
+ try {
1369
+ for await (const d of dir) {
1370
+ if (!d.isFile()) continue;
1371
+ const fullPath = resolve5(rootDir, d.name);
1372
+ report.scanned++;
1373
+ if (isActiveVariantArtifact(d.name)) {
1374
+ let sizeBytes2 = 0;
1375
+ let timestampMs2 = 0;
1376
+ try {
1377
+ const st = await stat7(fullPath);
1378
+ sizeBytes2 = st.size;
1379
+ timestampMs2 = st.mtimeMs;
1380
+ } catch {
1381
+ bump(report.keptBecause, "read_error");
1382
+ report.kept++;
1383
+ report.items.push({
1384
+ path: fullPath,
1385
+ sizeBytes: 0,
1386
+ ageDays: 0,
1387
+ decision: "keep",
1388
+ reason: "read_error"
1389
+ });
1390
+ continue;
1391
+ }
1392
+ bump(report.keptBecause, "active_run");
1393
+ report.kept++;
1394
+ report.items.push({
1395
+ path: fullPath,
1396
+ sizeBytes: sizeBytes2,
1397
+ ageDays: Math.floor((now.getTime() - timestampMs2) / (24 * 60 * 60 * 1e3)),
1398
+ decision: "keep",
1399
+ reason: "active_run"
1400
+ });
1401
+ continue;
1402
+ }
1403
+ if (!d.name.endsWith(".json")) {
1404
+ bump(report.keptBecause, "not_variant_state");
1405
+ report.kept++;
1406
+ continue;
1407
+ }
1408
+ let sizeBytes = 0;
1409
+ let timestampMs = 0;
1410
+ let parsedTaskId = null;
1411
+ try {
1412
+ const st = await stat7(fullPath);
1413
+ sizeBytes = st.size;
1414
+ timestampMs = st.mtimeMs;
1415
+ const raw = await readFile6(fullPath, "utf8");
1416
+ let parsed;
1417
+ try {
1418
+ parsed = parseJsonWithContext(raw, `Variant state (${d.name})`);
1419
+ } catch {
1420
+ const ageDays2 = Math.floor((now.getTime() - timestampMs) / (24 * 60 * 60 * 1e3));
1421
+ bump(report.keptBecause, "invalid_json");
1422
+ report.kept++;
1423
+ report.items.push({
1424
+ path: fullPath,
1425
+ sizeBytes,
1426
+ ageDays: ageDays2,
1427
+ decision: "keep",
1428
+ reason: "invalid_json"
1429
+ });
1430
+ continue;
1431
+ }
1432
+ if (!isVariantState(parsed)) {
1433
+ const ageDays2 = Math.floor((now.getTime() - timestampMs) / (24 * 60 * 60 * 1e3));
1434
+ bump(report.keptBecause, "not_variant_state");
1435
+ report.kept++;
1436
+ report.items.push({
1437
+ path: fullPath,
1438
+ sizeBytes,
1439
+ ageDays: ageDays2,
1440
+ decision: "keep",
1441
+ reason: "not_variant_state"
1442
+ });
1443
+ continue;
1444
+ }
1445
+ timestampMs = parseIsoDateMs4(parsed.updatedAt) ?? parseIsoDateMs4(parsed.createdAt) ?? timestampMs;
1446
+ parsedTaskId = typeof parsed.taskId === "string" ? parsed.taskId : null;
1447
+ } catch (error) {
1448
+ const msg = error instanceof Error ? error.message : String(error);
1449
+ report.errors.push(`${d.name}: stat/read failed: ${msg}`);
1450
+ bump(report.keptBecause, "read_error");
1451
+ report.kept++;
1452
+ report.items.push({
1453
+ path: fullPath,
1454
+ sizeBytes: 0,
1455
+ ageDays: 0,
1456
+ decision: "keep",
1457
+ reason: "read_error"
1458
+ });
1459
+ continue;
1460
+ }
1461
+ const ageMs = now.getTime() - timestampMs;
1462
+ const ageDays = Math.floor(ageMs / (24 * 60 * 60 * 1e3));
1463
+ if (ageMs <= maxAgeMs) {
1464
+ bump(report.keptBecause, "too_recent");
1465
+ report.kept++;
1466
+ report.items.push({
1467
+ path: fullPath,
1468
+ sizeBytes,
1469
+ ageDays,
1470
+ decision: "keep",
1471
+ reason: "too_recent"
1472
+ });
1473
+ continue;
1474
+ }
1475
+ if (options.synthesisTaskIdsUnavailable) {
1476
+ bump(report.keptBecause, "synthesis_retention_unknown");
1477
+ report.kept++;
1478
+ report.items.push({
1479
+ path: fullPath,
1480
+ sizeBytes,
1481
+ ageDays,
1482
+ decision: "keep",
1483
+ reason: "synthesis_retention_unknown"
1484
+ });
1485
+ continue;
1486
+ }
1487
+ if (options.keepJudgedTaskIds && parsedTaskId && options.keepJudgedTaskIds.has(parsedTaskId) && ageMs <= maxAgeMs * (options.judgedRetentionMultiplier ?? 3)) {
1488
+ bump(report.keptBecause, "judged_retention");
1489
+ report.kept++;
1490
+ report.items.push({
1491
+ path: fullPath,
1492
+ sizeBytes,
1493
+ ageDays,
1494
+ decision: "keep",
1495
+ reason: "judged_retention"
1496
+ });
1497
+ continue;
1498
+ }
1499
+ if (options.keepSynthesisTaskIds && parsedTaskId && options.keepSynthesisTaskIds.has(parsedTaskId) && ageMs <= maxAgeMs * (options.judgedRetentionMultiplier ?? 3)) {
1500
+ bump(report.keptBecause, "synthesis_retention");
1501
+ report.kept++;
1502
+ report.items.push({
1503
+ path: fullPath,
1504
+ sizeBytes,
1505
+ ageDays,
1506
+ decision: "keep",
1507
+ reason: "synthesis_retention"
1508
+ });
1509
+ continue;
1510
+ }
1511
+ report.eligible++;
1512
+ const item = {
1513
+ path: fullPath,
1514
+ sizeBytes,
1515
+ ageDays,
1516
+ decision: "archive",
1517
+ reason: "stale_variant"
1518
+ };
1519
+ if (options.dryRun) {
1520
+ bump(report.archivedBecause, "stale_variant");
1521
+ report.freedBytes += sizeBytes;
1522
+ } else {
1523
+ try {
1524
+ const archiveMonthDir = resolve5(archiveDir, monthBucket3(timestampMs));
1525
+ await mkdir3(archiveMonthDir, { recursive: true });
1526
+ const targetPath = await uniqueArchivePath3(resolve5(archiveMonthDir, d.name));
1527
+ await rename4(fullPath, targetPath);
1528
+ item.archivePath = targetPath;
1529
+ report.archived++;
1530
+ bump(report.archivedBecause, "stale_variant");
1531
+ report.freedBytes += sizeBytes;
1532
+ } catch (error) {
1533
+ const msg = error instanceof Error ? error.message : String(error);
1534
+ report.errors.push(`${d.name}: archive failed: ${msg}`);
1535
+ item.decision = "keep";
1536
+ item.reason = "read_error";
1537
+ report.kept++;
1538
+ bump(report.keptBecause, "read_error");
1539
+ report.items.push(item);
1540
+ continue;
1541
+ }
1542
+ }
1543
+ report.items.push(item);
1544
+ }
1545
+ } finally {
1546
+ await dir.close().catch(() => {
1547
+ });
1548
+ }
1549
+ } catch {
1550
+ return report;
1551
+ }
1552
+ if (options.dryRun) {
1553
+ report.archived = report.eligible;
1554
+ }
1555
+ if (!options.verbose) {
1556
+ report.items = report.items.slice(0, 200);
1557
+ }
1558
+ return report;
1559
+ }
1560
+
1561
+ // src/core/cleanup/stale-cleanup-orchestrator.ts
1562
+ var DEFAULT_STALE_CLEANUP_LOG_AGE_DAYS = 7;
1563
+ var DEFAULT_STALE_CLEANUP_BRANCH_AGE_DAYS = 7;
1564
+ var DEFAULT_STALE_CLEANUP_STATE_AGE_DAYS = 30;
1565
+ var DEFAULT_STALE_CLEANUP_AUTOLOOP_AGE_DAYS = 14;
1566
+ var DEFAULT_STALE_CLEANUP_UNIFIED_STATE_AGE_DAYS = 14;
1567
+ var CLEANUP_METRICS_RELATIVE_PATH = ".poetic/tmp/cleanup-metrics.jsonl";
1568
+ var CLEANUP_METRICS_MAX_BYTES = 1e6;
1569
+ var CLEANUP_METRICS_MAX_LINES = 2e3;
1570
+ function getActiveRunSentinelRoots() {
1571
+ const repoRoot = findProjectRoot(process.cwd()) ?? process.cwd();
1572
+ return Array.from(
1573
+ /* @__PURE__ */ new Set([
1574
+ resolveWorktreeBase(),
1575
+ resolve6(tmpdir(), "poetic-worktrees"),
1576
+ resolve6(repoRoot, ".poetic/labs")
1577
+ ])
1578
+ );
1579
+ }
1580
+ async function loadJudgedTaskIdsBestEffort() {
1581
+ try {
1582
+ const { openConfiguredTelemetryDb } = await import("./storage-access-F6ALDN4S.js");
1583
+ const { listJudgedTaskIds } = await import("./competition-outcome-tracker-R32OOZ43.js");
1584
+ const { TelemetryPathResolver } = await import("./telemetry-path-resolver-7ICSG276.js");
1585
+ const { resolvePoeticRoot } = await import("./poetic-root-V5DNXEAE.js");
1586
+ const poeticDir = resolve6(resolvePoeticRoot(process.cwd()), ".poetic");
1587
+ const projectId = TelemetryPathResolver.getInstance().getProjectId(poeticDir, {
1588
+ register: false
1589
+ });
1590
+ const { db } = openConfiguredTelemetryDb();
1591
+ if (!db) return void 0;
1592
+ try {
1593
+ return listJudgedTaskIds(db, { projectId });
1594
+ } finally {
1595
+ db.close();
1596
+ }
1597
+ } catch {
1598
+ return void 0;
1599
+ }
1600
+ }
1601
+ async function loadSynthesisTaskIds() {
1602
+ const { resolvePoeticRoot } = await import("./poetic-root-V5DNXEAE.js");
1603
+ const synthesisDir = resolve6(
1604
+ resolvePoeticRoot(process.cwd()),
1605
+ ".poetic",
1606
+ "telemetry",
1607
+ "synthesis"
1608
+ );
1609
+ const ids = /* @__PURE__ */ new Set();
1610
+ try {
1611
+ for (const entry of await readdir3(synthesisDir, { withFileTypes: true })) {
1612
+ if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
1613
+ ids.add(basename(entry.name, ".json"));
1614
+ }
1615
+ } catch (error) {
1616
+ if (error?.code === "ENOENT") return void 0;
1617
+ throw error;
1618
+ }
1619
+ return ids.size > 0 ? ids : void 0;
1620
+ }
1621
+ var StaleCleanupOrchestrator = class {
1622
+ worktreeManager;
1623
+ dbSizeManager = null;
1624
+ constructor() {
1625
+ this.worktreeManager = new WorktreeCleanupManager();
1626
+ }
1627
+ async cleanup(options) {
1628
+ const report = {
1629
+ mode: options.dryRun ? "dry-run" : "executed",
1630
+ categories: [],
1631
+ totals: { freedBytes: 0, itemsCleaned: 0 }
1632
+ };
1633
+ if (options.categories.includes("worktrees")) {
1634
+ const result = await this.cleanupWorktrees(options);
1635
+ report.categories.push(result);
1636
+ report.totals.freedBytes += result.summary.freedBytes;
1637
+ report.totals.itemsCleaned += result.summary.cleaned;
1638
+ }
1639
+ if (options.categories.includes("telemetry")) {
1640
+ const result = await this.cleanupTelemetry(options);
1641
+ report.categories.push(result);
1642
+ report.totals.freedBytes += result.summary.freedBytes;
1643
+ report.totals.itemsCleaned += result.summary.cleaned;
1644
+ }
1645
+ if (options.categories.includes("processes")) {
1646
+ const result = await this.cleanupProcesses(options);
1647
+ report.categories.push(result);
1648
+ report.totals.itemsCleaned += result.summary.cleaned;
1649
+ }
1650
+ if (options.categories.includes("db")) {
1651
+ const result = await this.cleanupDatabase(options);
1652
+ report.categories.push(result);
1653
+ report.totals.freedBytes += result.summary.freedBytes;
1654
+ report.totals.itemsCleaned += result.summary.cleaned;
1655
+ }
1656
+ if (options.categories.includes("branches")) {
1657
+ const result = await this.cleanupBranches(options);
1658
+ report.categories.push(result);
1659
+ report.totals.itemsCleaned += result.summary.cleaned;
1660
+ }
1661
+ if (options.categories.includes("state")) {
1662
+ const result = await this.cleanupState(options);
1663
+ report.categories.push(result);
1664
+ report.totals.freedBytes += result.summary.freedBytes;
1665
+ report.totals.itemsCleaned += result.summary.cleaned;
1666
+ }
1667
+ if (options.categories.includes("autoloop")) {
1668
+ const result = await this.cleanupAutoloop(options);
1669
+ report.categories.push(result);
1670
+ report.totals.freedBytes += result.summary.freedBytes;
1671
+ report.totals.itemsCleaned += result.summary.cleaned;
1672
+ }
1673
+ if (options.categories.includes("unified-state")) {
1674
+ const result = await this.cleanupUnifiedState(options);
1675
+ report.categories.push(result);
1676
+ report.totals.freedBytes += result.summary.freedBytes;
1677
+ report.totals.itemsCleaned += result.summary.cleaned;
1678
+ }
1679
+ if (!options.dryRun) {
1680
+ await trackCleanupMetrics(report, options);
1681
+ }
1682
+ return report;
1683
+ }
1684
+ async cleanupWorktrees(options) {
1685
+ try {
1686
+ const result = await this.worktreeManager.cleanup({
1687
+ maxAgeMs: options.worktreeAgeMs,
1688
+ dryRun: options.dryRun,
1689
+ includeLabs: options.includeLabWorktrees,
1690
+ verbose: options.verbose,
1691
+ limit: options.worktreeLimit,
1692
+ estimateSize: options.worktreeEstimateSize,
1693
+ includeBrokenMetadata: options.worktreeIncludeBrokenMetadata
1694
+ });
1695
+ return {
1696
+ name: "worktrees",
1697
+ enabled: true,
1698
+ summary: {
1699
+ found: result.deletedWorktrees.length,
1700
+ // In dry-run, these are "would delete"
1701
+ cleaned: options.dryRun ? result.deletedWorktrees.length : result.deleted,
1702
+ freedBytes: result.freedBytes
1703
+ },
1704
+ details: {
1705
+ paths: result.deletedWorktrees,
1706
+ labCleaned: result.deletedLabWorktrees,
1707
+ labSkipped: result.skippedLabWorktrees,
1708
+ dirtySkipped: result.skippedDirtyWorktrees ?? [],
1709
+ uninspectableSkipped: result.skippedUninspectableWorktrees ?? [],
1710
+ brokenMetadataCleaned: result.deletedBrokenMetadataWorktrees ?? [],
1711
+ prunedGitWorktreeEntries: result.prunedGitWorktreeEntries ?? 0,
1712
+ preservedWorktrees: result.preservedWorktrees ?? [],
1713
+ lockPreviewDegraded: result.lockPreviewDegraded ?? false,
1714
+ lockDiagnostics: result.lockDiagnostics
1715
+ }
1716
+ };
1717
+ } catch (error) {
1718
+ return {
1719
+ name: "worktrees",
1720
+ enabled: true,
1721
+ skipped: {
1722
+ reason: error instanceof Error ? error.message : String(error)
1723
+ },
1724
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
1725
+ details: {}
1726
+ };
1727
+ }
1728
+ }
1729
+ async cleanupTelemetry(options) {
1730
+ try {
1731
+ const cleanup = await TelemetryCleanup.fromConfig();
1732
+ const result = await cleanup.cleanup({
1733
+ dryRun: options.dryRun,
1734
+ verbose: options.verbose,
1735
+ logsDaysOverride: options.logAgeDays,
1736
+ vacuumOverride: options.vacuum
1737
+ });
1738
+ return {
1739
+ name: "telemetry",
1740
+ enabled: true,
1741
+ summary: {
1742
+ found: result.deletedBackups + result.deletedLogs + result.deletedSignalFiles + result.deletedMergeLedgerLines,
1743
+ cleaned: result.deletedBackups + result.deletedLogs + result.deletedSignalFiles + result.deletedMergeLedgerLines,
1744
+ freedBytes: result.freedSpaceBytes
1745
+ },
1746
+ details: {
1747
+ deletedBackups: result.deletedBackups,
1748
+ deletedLogs: result.deletedLogs,
1749
+ deletedSignalFiles: result.deletedSignalFiles,
1750
+ deletedMergeLedgerLines: result.deletedMergeLedgerLines,
1751
+ vacuumExecuted: result.vacuumExecuted
1752
+ }
1753
+ };
1754
+ } catch (error) {
1755
+ return {
1756
+ name: "telemetry",
1757
+ enabled: true,
1758
+ skipped: {
1759
+ reason: error instanceof Error ? error.message : String(error)
1760
+ },
1761
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
1762
+ details: {}
1763
+ };
1764
+ }
1765
+ }
1766
+ async cleanupProcesses(options) {
1767
+ try {
1768
+ await processScanner.scan({ includeAll: true });
1769
+ const scanResult = await processRegistry.scan();
1770
+ const reapedTmuxSessions = await reapOrphanedTmuxSessions({ dryRun: options.dryRun });
1771
+ const unhealthyCount = scanResult.staleCount + scanResult.orphanedCount + scanResult.zombieCount;
1772
+ const protectedActiveRunPids = unhealthyCount > 0 ? await collectActiveRunPids(getActiveRunSentinelRoots()) : /* @__PURE__ */ new Set();
1773
+ const unhealthyProcessEntries = unhealthyCount > 0 ? (await processRegistry.getAll()).filter(
1774
+ (entry) => entry.health === "stale" || entry.health === "orphaned" || entry.health === "zombie"
1775
+ ) : [];
1776
+ const processTargets = unhealthyProcessEntries.filter(
1777
+ (entry) => !protectedActiveRunPids.has(entry.pid)
1778
+ );
1779
+ const skippedActiveRunPids = unhealthyProcessEntries.filter((entry) => protectedActiveRunPids.has(entry.pid)).map((entry) => entry.pid);
1780
+ const staleCount = processTargets.length;
1781
+ if (staleCount === 0 && reapedTmuxSessions.length === 0) {
1782
+ return {
1783
+ name: "processes",
1784
+ enabled: true,
1785
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
1786
+ details: { pids: [], errors: [], tmuxSessions: [], skippedActiveRunPids }
1787
+ };
1788
+ }
1789
+ const result = staleCount > 0 ? await processRegistry.cleanup({
1790
+ health: ["stale", "orphaned", "zombie"],
1791
+ pids: processTargets.map((entry) => entry.pid),
1792
+ dryRun: options.dryRun
1793
+ }) : { attempted: 0, killed: 0, failed: 0, pids: [], errors: [] };
1794
+ const tmuxCleaned = options.dryRun ? reapedTmuxSessions.length : reapedTmuxSessions.length;
1795
+ return {
1796
+ name: "processes",
1797
+ enabled: true,
1798
+ summary: {
1799
+ found: result.attempted + reapedTmuxSessions.length,
1800
+ cleaned: (options.dryRun ? result.attempted : result.killed) + tmuxCleaned,
1801
+ freedBytes: 0
1802
+ // Processes don't have a size
1803
+ },
1804
+ details: {
1805
+ pids: result.pids,
1806
+ tmuxSessions: reapedTmuxSessions,
1807
+ errors: result.errors,
1808
+ killed: result.killed,
1809
+ failed: result.failed,
1810
+ skippedActiveRunPids
1811
+ }
1812
+ };
1813
+ } catch (error) {
1814
+ return {
1815
+ name: "processes",
1816
+ enabled: true,
1817
+ skipped: {
1818
+ reason: error instanceof Error ? error.message : String(error)
1819
+ },
1820
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
1821
+ details: {}
1822
+ };
1823
+ }
1824
+ }
1825
+ async cleanupBranches(options) {
1826
+ try {
1827
+ const repoRoot = findProjectRoot(process.cwd()) ?? process.cwd();
1828
+ if (!options.dryRun) {
1829
+ await pruneGitWorktreeEntries({ cwd: repoRoot });
1830
+ }
1831
+ const branchManager = createBranchCleanupManager(repoRoot);
1832
+ const result = await branchManager.archive({
1833
+ includeBranches: true,
1834
+ // Already gated by category check
1835
+ includeTestBranches: options.includeTestBranches ?? false,
1836
+ dryRun: options.dryRun,
1837
+ allowUnmerged: options.allowUnmerged ?? false,
1838
+ confirm: options.branchConfirm,
1839
+ minAgeDays: options.branchAgeDays ?? DEFAULT_STALE_CLEANUP_BRANCH_AGE_DAYS,
1840
+ maxArchiveCount: 100,
1841
+ verbose: options.verbose
1842
+ });
1843
+ const archiveCandidates = result.branches.filter((b) => b.action === "archive");
1844
+ const archiveCount = archiveCandidates.length;
1845
+ const localCleanedCount = options.dryRun || result.mode === "executed" ? archiveCount : 0;
1846
+ const skipReasons = result.branches.filter((b) => b.action === "skip").slice(0, 10).map((b) => ({ name: b.name, reason: b.reason }));
1847
+ let remoteQueue = await processRemoteBranchCleanupQueue({
1848
+ dryRun: true,
1849
+ verbose: options.verbose,
1850
+ cwd: repoRoot
1851
+ });
1852
+ const remoteDeleteCandidates = remoteQueue.wouldDelete ?? 0;
1853
+ const remoteConfirmMatches = options.remoteBranchConfirm !== void 0 && options.remoteBranchConfirm === remoteDeleteCandidates;
1854
+ let remoteQueueErrors = [...remoteQueue.errors];
1855
+ if (!options.dryRun && result.mode === "executed" && options.remoteBranchConfirm !== void 0 && !remoteConfirmMatches) {
1856
+ remoteQueueErrors.push(
1857
+ `Remote branch cleanup queue confirmation mismatch: expected --confirm-remote ${remoteDeleteCandidates}, got ${options.remoteBranchConfirm}`
1858
+ );
1859
+ }
1860
+ if (!options.dryRun && result.mode === "executed" && remoteConfirmMatches) {
1861
+ remoteQueue = await processRemoteBranchCleanupQueue({
1862
+ dryRun: false,
1863
+ verbose: options.verbose,
1864
+ cwd: repoRoot
1865
+ });
1866
+ remoteQueueErrors = [...remoteQueueErrors, ...remoteQueue.errors];
1867
+ }
1868
+ const remoteCleanedCount = options.dryRun ? remoteDeleteCandidates : remoteQueue.mode === "executed" ? remoteQueue.deleted : 0;
1869
+ const shouldPrune = options.pruneRemoteRefs === true && !options.dryRun && remoteQueue.mode === "executed";
1870
+ const remotePrune = shouldPrune ? await execa("git", ["fetch", "--prune", "origin"], { cwd: repoRoot, reject: false }) : null;
1871
+ return {
1872
+ name: "branches",
1873
+ enabled: true,
1874
+ summary: {
1875
+ found: archiveCount + remoteQueue.found,
1876
+ cleaned: localCleanedCount + remoteCleanedCount,
1877
+ // Local branch "cleanup" is archive-by-rename (git branch -m into
1878
+ // poetic/archive/<date>/<name>), so it does not reduce the local ref
1879
+ // count. Reported separately because `cleaned` alone reads as deletion:
1880
+ // an operator running cleanup to shed refs would otherwise see a
1881
+ // non-zero cleaned count next to an unchanged `git branch` listing.
1882
+ archived: localCleanedCount,
1883
+ freedBytes: 0
1884
+ // Branches don't have a size
1885
+ },
1886
+ details: {
1887
+ mode: result.mode,
1888
+ defaultBranch: result.defaultBranch,
1889
+ patternsUsed: result.patternsUsed,
1890
+ scanned: result.scanned,
1891
+ archived: archiveCount,
1892
+ skipped: result.skipped,
1893
+ cleaned: localCleanedCount,
1894
+ skipReasons,
1895
+ circuitBreakerTriggered: result.circuitBreakerTriggered,
1896
+ errors: result.errors,
1897
+ unbornRepository: result.unbornRepository === true,
1898
+ remoteBranchCleanupQueue: {
1899
+ ...remoteQueue,
1900
+ errors: remoteQueueErrors,
1901
+ confirmationRequired: !options.dryRun && result.mode === "executed" && remoteQueue.mode !== "executed" && remoteDeleteCandidates > 0 ? remoteDeleteCandidates : void 0,
1902
+ confirmationProvided: options.remoteBranchConfirm
1903
+ },
1904
+ remotePrune: remotePrune === null ? { attempted: false } : {
1905
+ attempted: true,
1906
+ exitCode: remotePrune.exitCode,
1907
+ stderr: (remotePrune.stderr ?? "").trim()
1908
+ }
1909
+ }
1910
+ };
1911
+ } catch (error) {
1912
+ return {
1913
+ name: "branches",
1914
+ enabled: true,
1915
+ skipped: {
1916
+ reason: error instanceof Error ? error.message : String(error)
1917
+ },
1918
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
1919
+ details: {}
1920
+ };
1921
+ }
1922
+ }
1923
+ async cleanupState(options) {
1924
+ try {
1925
+ const nonTerminalPolicy = options.nonTerminalPolicy ?? (options.keepNonTerminalState === void 0 ? "smart" : options.keepNonTerminalState ? "strict" : "smart");
1926
+ const maxAgeDays = options.stateAgeDays ?? DEFAULT_STALE_CLEANUP_STATE_AGE_DAYS;
1927
+ const cleanupOptions = {
1928
+ dryRun: options.dryRun,
1929
+ verbose: options.verbose,
1930
+ maxAgeDays
1931
+ };
1932
+ const keepJudgedTaskIds = await loadJudgedTaskIdsBestEffort();
1933
+ let keepSynthesisTaskIds;
1934
+ let synthesisTaskIdsUnavailable = false;
1935
+ try {
1936
+ keepSynthesisTaskIds = await loadSynthesisTaskIds();
1937
+ } catch {
1938
+ synthesisTaskIdsUnavailable = true;
1939
+ }
1940
+ const result = await cleanupCompetitionStateFiles({
1941
+ ...cleanupOptions,
1942
+ keepNonTerminal: options.keepNonTerminalState ?? false,
1943
+ keepLast: options.keepLastState ?? 0,
1944
+ nonTerminalPolicy
1945
+ });
1946
+ const tuiSessions = await cleanupTuiSessionStateFiles(cleanupOptions);
1947
+ const background = await cleanupBackgroundStateFiles(cleanupOptions);
1948
+ const variants = await cleanupVariantTelemetryStateFiles({
1949
+ ...cleanupOptions,
1950
+ keepJudgedTaskIds,
1951
+ keepSynthesisTaskIds,
1952
+ synthesisTaskIdsUnavailable
1953
+ });
1954
+ const flywheel = await cleanupFlywheelTmpEntries(cleanupOptions);
1955
+ const keptBecause = { ...result.keptBecause };
1956
+ const deletedBecause = { ...result.deletedBecause };
1957
+ const mergeKept = (prefix, map) => {
1958
+ for (const [reason, count] of Object.entries(map)) {
1959
+ keptBecause[`${prefix}_${reason}`] = (keptBecause[`${prefix}_${reason}`] ?? 0) + count;
1960
+ }
1961
+ };
1962
+ const mergeArchived = (prefix, map) => {
1963
+ for (const [reason, count] of Object.entries(map)) {
1964
+ deletedBecause[`${prefix}_${reason}`] = (deletedBecause[`${prefix}_${reason}`] ?? 0) + count;
1965
+ }
1966
+ };
1967
+ mergeKept("tui", tuiSessions.keptBecause);
1968
+ mergeKept("background", background.keptBecause);
1969
+ mergeKept("variants", variants.keptBecause);
1970
+ mergeKept("flywheel", flywheel.keptBecause);
1971
+ mergeArchived("tui", tuiSessions.deletedBecause);
1972
+ mergeArchived("background", background.archivedBecause);
1973
+ mergeArchived("variants", variants.archivedBecause);
1974
+ mergeArchived("flywheel", flywheel.archivedBecause);
1975
+ const found = result.eligible + tuiSessions.eligible + background.eligible + variants.eligible + flywheel.eligible;
1976
+ const cleaned = options.dryRun ? found : result.deleted + tuiSessions.deleted + background.archived + variants.archived + flywheel.archived;
1977
+ const freedBytes = result.freedBytes + tuiSessions.freedBytes + background.freedBytes + variants.freedBytes + flywheel.freedBytes;
1978
+ return {
1979
+ name: "state",
1980
+ enabled: true,
1981
+ summary: {
1982
+ found,
1983
+ cleaned,
1984
+ freedBytes
1985
+ },
1986
+ details: {
1987
+ ...result,
1988
+ keptBecause,
1989
+ deletedBecause,
1990
+ tuiSessions,
1991
+ background,
1992
+ variants,
1993
+ flywheel
1994
+ }
1995
+ };
1996
+ } catch (error) {
1997
+ return {
1998
+ name: "state",
1999
+ enabled: true,
2000
+ skipped: {
2001
+ reason: error instanceof Error ? error.message : String(error)
2002
+ },
2003
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
2004
+ details: {}
2005
+ };
2006
+ }
2007
+ }
2008
+ async cleanupAutoloop(options) {
2009
+ try {
2010
+ const { cleanupAutoloopArtifacts } = await import("./autoloop-cleanup-JOGKTLWA.js");
2011
+ const result = await cleanupAutoloopArtifacts({
2012
+ dryRun: options.dryRun,
2013
+ maxAgeDays: options.autoloopAgeDays ?? DEFAULT_STALE_CLEANUP_AUTOLOOP_AGE_DAYS,
2014
+ verbose: options.verbose
2015
+ });
2016
+ return {
2017
+ name: "autoloop",
2018
+ enabled: true,
2019
+ summary: {
2020
+ found: result.eligible,
2021
+ cleaned: options.dryRun ? result.eligible : result.deleted,
2022
+ freedBytes: result.freedBytes
2023
+ },
2024
+ details: result
2025
+ };
2026
+ } catch (error) {
2027
+ return {
2028
+ name: "autoloop",
2029
+ enabled: true,
2030
+ skipped: {
2031
+ reason: error instanceof Error ? error.message : String(error)
2032
+ },
2033
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
2034
+ details: {}
2035
+ };
2036
+ }
2037
+ }
2038
+ async cleanupUnifiedState(options) {
2039
+ try {
2040
+ const { cleanupUnifiedStateFiles } = await import("./unified-state-cleanup-LJPF2BOW.js");
2041
+ const result = await cleanupUnifiedStateFiles({
2042
+ dryRun: options.dryRun,
2043
+ maxAgeDays: options.unifiedStateAgeDays ?? DEFAULT_STALE_CLEANUP_UNIFIED_STATE_AGE_DAYS,
2044
+ verbose: options.verbose
2045
+ });
2046
+ return {
2047
+ name: "unified-state",
2048
+ enabled: true,
2049
+ summary: {
2050
+ found: result.eligible,
2051
+ cleaned: options.dryRun ? result.eligible : result.deleted,
2052
+ freedBytes: result.freedBytes
2053
+ },
2054
+ details: result
2055
+ };
2056
+ } catch (error) {
2057
+ return {
2058
+ name: "unified-state",
2059
+ enabled: true,
2060
+ skipped: {
2061
+ reason: error instanceof Error ? error.message : String(error)
2062
+ },
2063
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
2064
+ details: {}
2065
+ };
2066
+ }
2067
+ }
2068
+ async cleanupDatabase(options) {
2069
+ try {
2070
+ const dbManager = await this.getDbSizeManager();
2071
+ if (!dbManager) {
2072
+ return {
2073
+ name: "db",
2074
+ enabled: true,
2075
+ skipped: {
2076
+ reason: "Database manager unavailable (better-sqlite3 or DB path missing)"
2077
+ },
2078
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
2079
+ details: {}
2080
+ };
2081
+ }
2082
+ const stats = await dbManager.getStats();
2083
+ if (stats.level === "ok" || !options.vacuum) {
2084
+ return {
2085
+ name: "db",
2086
+ enabled: true,
2087
+ skipped: stats.level === "ok" ? {
2088
+ reason: `Database under threshold (${stats.sizeFormatted})`,
2089
+ blocking: false
2090
+ } : { reason: "Vacuum not requested", blocking: false },
2091
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
2092
+ details: { level: stats.level, size: stats.sizeFormatted }
2093
+ };
2094
+ }
2095
+ const result = await dbManager.cleanup({
2096
+ olderThan: stats.level === "warning" ? 90 : 180,
2097
+ // More aggressive for warning level
2098
+ vacuum: true,
2099
+ dryRun: options.dryRun
2100
+ });
2101
+ return {
2102
+ name: "db",
2103
+ enabled: true,
2104
+ summary: {
2105
+ found: result.deletedRecords ?? 0,
2106
+ cleaned: result.deletedRecords ?? 0,
2107
+ freedBytes: result.freedBytes ?? 0
2108
+ },
2109
+ details: {
2110
+ level: stats.level,
2111
+ deletedRecords: result.deletedRecords,
2112
+ vacuumed: !options.dryRun
2113
+ }
2114
+ };
2115
+ } catch (error) {
2116
+ return {
2117
+ name: "db",
2118
+ enabled: true,
2119
+ skipped: {
2120
+ reason: error instanceof Error ? error.message : String(error)
2121
+ },
2122
+ summary: { found: 0, cleaned: 0, freedBytes: 0 },
2123
+ details: {}
2124
+ };
2125
+ }
2126
+ }
2127
+ /**
2128
+ * Lazily create a DbSizeManager with the canonical telemetry DB path.
2129
+ * Returns null if better-sqlite3 is unavailable or the DB cannot be opened.
2130
+ *
2131
+ * Note: The primary telemetry databases live under `.poetic/telemetry/db/`.
2132
+ * We target `variants.db` as it's the primary/largest database.
2133
+ */
2134
+ async getDbSizeManager() {
2135
+ if (this.dbSizeManager) {
2136
+ return this.dbSizeManager;
2137
+ }
2138
+ try {
2139
+ const sqlite = await import("better-sqlite3").catch(() => null);
2140
+ if (!sqlite) {
2141
+ return null;
2142
+ }
2143
+ const repoRoot = findProjectRoot(process.cwd()) ?? process.cwd();
2144
+ const dbPath = resolve6(repoRoot, ".poetic/telemetry/db/variants.db");
2145
+ const { existsSync: existsSync2 } = await import("fs");
2146
+ if (!existsSync2(dbPath)) {
2147
+ return null;
2148
+ }
2149
+ const DatabaseCtor = sqlite.default;
2150
+ const dbInstance = new DatabaseCtor(dbPath);
2151
+ this.dbSizeManager = new DbSizeManager(dbPath, dbInstance);
2152
+ return this.dbSizeManager;
2153
+ } catch {
2154
+ return null;
2155
+ }
2156
+ }
2157
+ };
2158
+ function createStaleCleanupOrchestrator() {
2159
+ return new StaleCleanupOrchestrator();
2160
+ }
2161
+ async function trackCleanupMetrics(report, options) {
2162
+ const repoRoot = findProjectRoot(process.cwd()) ?? process.cwd();
2163
+ const metricsPath = resolve6(repoRoot, CLEANUP_METRICS_RELATIVE_PATH);
2164
+ const payload = {
2165
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2166
+ mode: report.mode,
2167
+ categories: report.categories.map((category) => ({
2168
+ name: category.name,
2169
+ cleaned: category.summary.cleaned,
2170
+ found: category.summary.found
2171
+ })),
2172
+ totals: report.totals,
2173
+ options: {
2174
+ categories: options.categories,
2175
+ includeLabWorktrees: options.includeLabWorktrees ?? false
2176
+ }
2177
+ };
2178
+ try {
2179
+ await mkdir4(dirname(metricsPath), { recursive: true });
2180
+ await appendFile(metricsPath, `${JSON.stringify(payload)}
2181
+ `, "utf8");
2182
+ await compactCleanupMetrics(metricsPath);
2183
+ } catch (error) {
2184
+ console.debug("Failed to record cleanup metrics", error);
2185
+ }
2186
+ }
2187
+ async function compactCleanupMetrics(metricsPath) {
2188
+ let stats;
2189
+ try {
2190
+ stats = await stat8(metricsPath);
2191
+ } catch {
2192
+ return;
2193
+ }
2194
+ const content = await readFile7(metricsPath, "utf8");
2195
+ const lines = content.split("\n").filter((line) => line.length > 0);
2196
+ if (stats.size <= CLEANUP_METRICS_MAX_BYTES && lines.length <= CLEANUP_METRICS_MAX_LINES) {
2197
+ return;
2198
+ }
2199
+ const retained = lines.slice(-CLEANUP_METRICS_MAX_LINES);
2200
+ await writeFile2(metricsPath, `${retained.join("\n")}
2201
+ `, "utf8");
2202
+ }
2203
+
2204
+ export {
2205
+ DEFAULT_STALE_CLEANUP_LOG_AGE_DAYS,
2206
+ DEFAULT_STALE_CLEANUP_BRANCH_AGE_DAYS,
2207
+ DEFAULT_STALE_CLEANUP_STATE_AGE_DAYS,
2208
+ DEFAULT_STALE_CLEANUP_AUTOLOOP_AGE_DAYS,
2209
+ DEFAULT_STALE_CLEANUP_UNIFIED_STATE_AGE_DAYS,
2210
+ StaleCleanupOrchestrator,
2211
+ createStaleCleanupOrchestrator
2212
+ };
2213
+ //# sourceMappingURL=chunk-SLS2N4PH.js.map