@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.
- package/.github/SECURITY.md +47 -0
- package/.nvmrc +1 -0
- package/.poetic/README.md +37 -0
- package/.poetic/providers/catalog.json +12051 -0
- package/.poetic/providers/pricing.json +1272 -0
- package/.poetic/providers/registry.json +3369 -0
- package/CHANGELOG.md +552 -0
- package/CODE_OF_CONDUCT.md +40 -0
- package/CONTRIBUTING.md +23 -0
- package/INSTALL.md +454 -0
- package/LICENSE +21 -0
- package/README.md +474 -0
- package/dist/BasicOptimizationCompetitionRunner-5H5TBYO4.js +153 -0
- package/dist/ExecutionTracker-UVONC4C6.js +16 -0
- package/dist/OptimizationConfig-7DFY2TST.js +17 -0
- package/dist/OptimizationEngine-JIMGP3LY.js +1597 -0
- package/dist/PromptStore-U6ZD3ZMQ.js +18 -0
- package/dist/actions-LUJPINLJ.js +322 -0
- package/dist/agent-ingest-3DJUJ7FU.js +53 -0
- package/dist/aggregator-DNCBINFO.js +12 -0
- package/dist/ai-judge-5QT5QJVU.js +156 -0
- package/dist/allowlist-grounding-RO6HKUFI.js +16 -0
- package/dist/allowlist-utils-23V7TJ3G.js +28 -0
- package/dist/anchored-turn-service-JULUCUIK.js +489 -0
- package/dist/api-transport-4TYTNLTJ.js +1087 -0
- package/dist/apply-completion-mode-AW2MOS3R.js +89 -0
- package/dist/artifact-migrator-23L45ISD.js +267 -0
- package/dist/ask-HWVV6QFR.js +135 -0
- package/dist/auth-5KEDKAPP.js +67 -0
- package/dist/auth-7TT3JINV.js +78 -0
- package/dist/auth-E6XUNZ5M.js +68 -0
- package/dist/auth-H3XDZE22.js +134 -0
- package/dist/auth-OC4E6633.js +71 -0
- package/dist/auth-S4CTX4GQ.js +44 -0
- package/dist/auth-YLH3S7EY.js +69 -0
- package/dist/auth-liveness-TDDEZY3T.js +46 -0
- package/dist/auto-optimizer-VPRWOWGU.js +80 -0
- package/dist/autoloop-cleanup-JOGKTLWA.js +109 -0
- package/dist/autoloop-evidence-gates-PCDALGVJ.js +38 -0
- package/dist/autoloop-gate-policy-Z7FVJVXV.js +175 -0
- package/dist/autoloop-helpers-2KTK43GL.js +22 -0
- package/dist/autoloop-ledger-W7QO62PX.js +96 -0
- package/dist/autoloop-ledger-subscriber-Z5RW5EIE.js +162 -0
- package/dist/autoloop-run-defaults-FERGRZGP.js +19 -0
- package/dist/autoloop-run-lock-CT2NWSV3.js +197 -0
- package/dist/autoloop-success-J2VKKBXQ.js +85 -0
- package/dist/autoloop-termination-summary-RN75F422.js +58 -0
- package/dist/autoloop-trajectory-XFIEXP5Z.js +282 -0
- package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
- package/dist/autonomous-loop-controller-PW4XVFGQ.js +4120 -0
- package/dist/backend-P3DAYRP7.js +29 -0
- package/dist/background-executor-CBN552V4.js +257 -0
- package/dist/backlog-execution-intent-U4XYPTV6.js +15 -0
- package/dist/backup-active-store-5WXG6SXT.js +17 -0
- package/dist/backup-telemetry-db-XGLXAA3N.js +254 -0
- package/dist/basic-competition-master-VCSBJVRN.js +344 -0
- package/dist/branch-archive-manager-RP6FP3ZC.js +254 -0
- package/dist/branch-cleanup-manager-RSHAI7YR.js +20 -0
- package/dist/build-gate-YHGRB4QB.js +71 -0
- package/dist/change-summary-WY7J5TOX.js +33 -0
- package/dist/chunk-23A26CSN.js +123 -0
- package/dist/chunk-27UTJD3M.js +265 -0
- package/dist/chunk-2A5CILN3.js +310 -0
- package/dist/chunk-2AQUWJPW.js +225 -0
- package/dist/chunk-2BZ53J6J.js +2344 -0
- package/dist/chunk-2DY5KNVM.js +276 -0
- package/dist/chunk-2EIA4RBE.js +659 -0
- package/dist/chunk-2IUXIGQD.js +1064 -0
- package/dist/chunk-2N42MS2Z.js +2193 -0
- package/dist/chunk-2QJ3H3L7.js +42 -0
- package/dist/chunk-2QLYTVYX.js +791 -0
- package/dist/chunk-2VSQMRCB.js +18 -0
- package/dist/chunk-2XQXYBM2.js +130 -0
- package/dist/chunk-2YFUIER7.js +426 -0
- package/dist/chunk-34CNP2HB.js +148 -0
- package/dist/chunk-35P3W3JX.js +456 -0
- package/dist/chunk-36PEBZAF.js +18 -0
- package/dist/chunk-3AOKYKA7.js +22 -0
- package/dist/chunk-3BCUNHKF.js +475 -0
- package/dist/chunk-3FLXLLB7.js +26 -0
- package/dist/chunk-3FOZ2VHV.js +100 -0
- package/dist/chunk-3G6FZCRF.js +106 -0
- package/dist/chunk-3M57DADF.js +44 -0
- package/dist/chunk-3S62LLWJ.js +543 -0
- package/dist/chunk-3ZPQLGV7.js +2904 -0
- package/dist/chunk-44N5WZZH.js +45 -0
- package/dist/chunk-45FPSA3B.js +125 -0
- package/dist/chunk-4BJ3O4RQ.js +929 -0
- package/dist/chunk-4BOP7T6L.js +2321 -0
- package/dist/chunk-4BTDUT2S.js +42 -0
- package/dist/chunk-4CSS7WVI.js +143 -0
- package/dist/chunk-4CUY7AFY.js +247 -0
- package/dist/chunk-4GSN5O5J.js +62 -0
- package/dist/chunk-4HN6DF7V.js +1027 -0
- package/dist/chunk-4IAPOG5V.js +415 -0
- package/dist/chunk-4IYIZQWV.js +48 -0
- package/dist/chunk-4NXPXE62.js +84 -0
- package/dist/chunk-4RCCF5BR.js +712 -0
- package/dist/chunk-4V7NAQ4R.js +19527 -0
- package/dist/chunk-4VJITV4P.js +445 -0
- package/dist/chunk-4YX7J6QL.js +1859 -0
- package/dist/chunk-527OBWQB.js +338 -0
- package/dist/chunk-5D4A7E3D.js +448 -0
- package/dist/chunk-5DLKYTQX.js +4003 -0
- package/dist/chunk-5EERLVZB.js +139 -0
- package/dist/chunk-5H72XE4H.js +256 -0
- package/dist/chunk-5HDP7XZG.js +91 -0
- package/dist/chunk-5LAMRH4X.js +969 -0
- package/dist/chunk-5LTN43AS.js +1972 -0
- package/dist/chunk-5RBHQYDB.js +2206 -0
- package/dist/chunk-5WCQRDRB.js +588 -0
- package/dist/chunk-5WRLK5KW.js +700 -0
- package/dist/chunk-5ZCXC23G.js +595 -0
- package/dist/chunk-6BM72ZMG.js +31 -0
- package/dist/chunk-6EDAJH2I.js +68 -0
- package/dist/chunk-6EQKFDBH.js +457 -0
- package/dist/chunk-6MFRHTRI.js +115 -0
- package/dist/chunk-6TZJRKNW.js +321 -0
- package/dist/chunk-6V7HGQFZ.js +20 -0
- package/dist/chunk-6VWVO2TU.js +3746 -0
- package/dist/chunk-6Y5TWI7H.js +146 -0
- package/dist/chunk-6Y5U7UFY.js +91 -0
- package/dist/chunk-6ZLAK3XG.js +14 -0
- package/dist/chunk-72XCRQED.js +34 -0
- package/dist/chunk-72YTZMAM.js +589 -0
- package/dist/chunk-73BBJOKA.js +263 -0
- package/dist/chunk-73NCTWKL.js +188 -0
- package/dist/chunk-77I6G4CO.js +1 -0
- package/dist/chunk-7DHRDWFS.js +3104 -0
- package/dist/chunk-7DNSNKJV.js +78 -0
- package/dist/chunk-7FMJVYBS.js +307 -0
- package/dist/chunk-7GDRQBQC.js +419 -0
- package/dist/chunk-7GPCEFUV.js +270 -0
- package/dist/chunk-7IL4A2PP.js +948 -0
- package/dist/chunk-7MMLMXO6.js +3679 -0
- package/dist/chunk-7QCZSLBH.js +1 -0
- package/dist/chunk-7R2WLDOS.js +62 -0
- package/dist/chunk-7T7RUJI7.js +949 -0
- package/dist/chunk-A2WKSVX7.js +43 -0
- package/dist/chunk-A3YGID55.js +133 -0
- package/dist/chunk-A722DEVA.js +14 -0
- package/dist/chunk-ACDIT7OP.js +1376 -0
- package/dist/chunk-ACKIPAOJ.js +302 -0
- package/dist/chunk-APPNGGN7.js +365 -0
- package/dist/chunk-APV6MK5E.js +137 -0
- package/dist/chunk-ASEP3M2W.js +968 -0
- package/dist/chunk-AT4TNPWW.js +2931 -0
- package/dist/chunk-ATVKCSGT.js +250 -0
- package/dist/chunk-AURFMVCD.js +899 -0
- package/dist/chunk-AX6GWE7V.js +47 -0
- package/dist/chunk-AY5EWJPF.js +385 -0
- package/dist/chunk-BAV2HJXS.js +194 -0
- package/dist/chunk-BBHRN366.js +89 -0
- package/dist/chunk-BBPSTTPA.js +1004 -0
- package/dist/chunk-BDATUDDJ.js +992 -0
- package/dist/chunk-BKE5PG5L.js +20414 -0
- package/dist/chunk-BLPHWMDK.js +797 -0
- package/dist/chunk-BSE4R6XD.js +322 -0
- package/dist/chunk-BXGMAU4A.js +396 -0
- package/dist/chunk-BXI4NXL3.js +507 -0
- package/dist/chunk-BZU2O43F.js +1125 -0
- package/dist/chunk-C3L6YQ7P.js +147 -0
- package/dist/chunk-C57KJOUQ.js +121 -0
- package/dist/chunk-CCV7BPSY.js +118 -0
- package/dist/chunk-CD7ISXA4.js +826 -0
- package/dist/chunk-CE5OZBYY.js +21 -0
- package/dist/chunk-CFBIG37O.js +154 -0
- package/dist/chunk-CJC6GZ46.js +457 -0
- package/dist/chunk-CKCDGXIV.js +408 -0
- package/dist/chunk-CKNX3TTP.js +10338 -0
- package/dist/chunk-CLKSETWE.js +10 -0
- package/dist/chunk-CP7H3HSP.js +1552 -0
- package/dist/chunk-CPLEWXNZ.js +66 -0
- package/dist/chunk-CQM3A35X.js +844 -0
- package/dist/chunk-CS6P76D3.js +103 -0
- package/dist/chunk-CTLUBNCW.js +622 -0
- package/dist/chunk-CUSRN6RJ.js +632 -0
- package/dist/chunk-D5EP5D2W.js +26 -0
- package/dist/chunk-D5RYINO7.js +412 -0
- package/dist/chunk-DBFS4HMH.js +751 -0
- package/dist/chunk-DC4ZYMXJ.js +115 -0
- package/dist/chunk-DCBZP442.js +9243 -0
- package/dist/chunk-DCYF7EKG.js +26 -0
- package/dist/chunk-DDMAFNUK.js +5351 -0
- package/dist/chunk-DF5SLDE4.js +966 -0
- package/dist/chunk-DJFW7SMX.js +348 -0
- package/dist/chunk-DQFLLBJW.js +121 -0
- package/dist/chunk-DSFM56OA.js +1203 -0
- package/dist/chunk-DTY4APYV.js +218 -0
- package/dist/chunk-DXH5JBRS.js +437 -0
- package/dist/chunk-E3NTPHEO.js +194 -0
- package/dist/chunk-E74LUIID.js +302 -0
- package/dist/chunk-EI57M5BI.js +194 -0
- package/dist/chunk-EJ4ZAWLV.js +305 -0
- package/dist/chunk-EJGCZGUF.js +1483 -0
- package/dist/chunk-EK2U3YEG.js +486 -0
- package/dist/chunk-ELMFYNV7.js +109 -0
- package/dist/chunk-ENRGKNR5.js +25 -0
- package/dist/chunk-ETYDXCK7.js +679 -0
- package/dist/chunk-EYRH3W74.js +239 -0
- package/dist/chunk-F23DIWNN.js +1024 -0
- package/dist/chunk-F5JO7HAS.js +94 -0
- package/dist/chunk-F7ER6ANO.js +174 -0
- package/dist/chunk-FATUVIIN.js +374 -0
- package/dist/chunk-FC23CTXV.js +322 -0
- package/dist/chunk-FD4ERYEG.js +22 -0
- package/dist/chunk-FH7WOJAE.js +79 -0
- package/dist/chunk-FHOWVDF5.js +1342 -0
- package/dist/chunk-FKAUPHMR.js +96 -0
- package/dist/chunk-FONNFJXA.js +137 -0
- package/dist/chunk-FQ7FSZRW.js +75 -0
- package/dist/chunk-FRG57FPM.js +240 -0
- package/dist/chunk-FUVP64ER.js +31 -0
- package/dist/chunk-FYOILAN5.js +6818 -0
- package/dist/chunk-G35UYQ6Z.js +69 -0
- package/dist/chunk-G36W2T2S.js +1143 -0
- package/dist/chunk-G3L2L5XZ.js +49 -0
- package/dist/chunk-G4THLFV3.js +148 -0
- package/dist/chunk-GAFJEYLK.js +29 -0
- package/dist/chunk-GFGYB2ZU.js +1689 -0
- package/dist/chunk-GG6KJYW6.js +85 -0
- package/dist/chunk-GHHFDU2U.js +55 -0
- package/dist/chunk-GHTZSQB7.js +57 -0
- package/dist/chunk-GK37ILCX.js +1231 -0
- package/dist/chunk-GKN3HMN4.js +2809 -0
- package/dist/chunk-GNVDBVJP.js +156 -0
- package/dist/chunk-GPEL3FBM.js +924 -0
- package/dist/chunk-GPSNGPZS.js +1604 -0
- package/dist/chunk-GSGD5E4C.js +30 -0
- package/dist/chunk-GSUQJJXQ.js +331 -0
- package/dist/chunk-GSV226X6.js +110 -0
- package/dist/chunk-H2AYQIHW.js +224 -0
- package/dist/chunk-H66DXFS5.js +1374 -0
- package/dist/chunk-H6G7QRMQ.js +35 -0
- package/dist/chunk-H7JAGHZT.js +59 -0
- package/dist/chunk-H7ZEFECA.js +316 -0
- package/dist/chunk-HAC6EHZZ.js +79 -0
- package/dist/chunk-HIO33P3G.js +19 -0
- package/dist/chunk-HMVQIPH3.js +547 -0
- package/dist/chunk-HOYBYAOA.js +257 -0
- package/dist/chunk-HX5P3CSP.js +1784 -0
- package/dist/chunk-I46EG2XQ.js +65 -0
- package/dist/chunk-I4NPDSCB.js +279 -0
- package/dist/chunk-I5WRT7ZR.js +514 -0
- package/dist/chunk-IC7I6YIJ.js +301 -0
- package/dist/chunk-IDCSOZVN.js +78 -0
- package/dist/chunk-IFCBYECK.js +112 -0
- package/dist/chunk-IFZCPEY2.js +66 -0
- package/dist/chunk-IKFP2KUR.js +48 -0
- package/dist/chunk-IRFBN336.js +878 -0
- package/dist/chunk-IUXNGKA6.js +152 -0
- package/dist/chunk-IV2RVAN7.js +1356 -0
- package/dist/chunk-IZYIQQ7X.js +53 -0
- package/dist/chunk-J3UUR7DE.js +210 -0
- package/dist/chunk-J54VUAY2.js +566 -0
- package/dist/chunk-J62KPGII.js +464 -0
- package/dist/chunk-J6P3FWWW.js +130 -0
- package/dist/chunk-JKBHJQMT.js +434 -0
- package/dist/chunk-JLS65NUQ.js +14 -0
- package/dist/chunk-JOSYEJKY.js +141 -0
- package/dist/chunk-JPKSXKNB.js +94 -0
- package/dist/chunk-JQNJB2BB.js +2440 -0
- package/dist/chunk-JRVNSWSQ.js +2626 -0
- package/dist/chunk-JSWMRQYG.js +28 -0
- package/dist/chunk-JZKNBBIB.js +152 -0
- package/dist/chunk-K54Y7MLK.js +160 -0
- package/dist/chunk-K65546RE.js +183 -0
- package/dist/chunk-KM3F7SYE.js +702 -0
- package/dist/chunk-KNDYMVWN.js +102 -0
- package/dist/chunk-KNT72VR6.js +132 -0
- package/dist/chunk-KP6YILMU.js +482 -0
- package/dist/chunk-KQEBSK3T.js +274 -0
- package/dist/chunk-KT6VHSPF.js +84 -0
- package/dist/chunk-KTMW65UX.js +14 -0
- package/dist/chunk-KZ5CJVBP.js +1813 -0
- package/dist/chunk-L4427KOE.js +26 -0
- package/dist/chunk-L6OM4A22.js +189 -0
- package/dist/chunk-L7E6XCRA.js +1042 -0
- package/dist/chunk-L7JZLXQL.js +173 -0
- package/dist/chunk-LAMKBTXX.js +40 -0
- package/dist/chunk-LDCF2MKN.js +132 -0
- package/dist/chunk-LEIIWPWQ.js +78 -0
- package/dist/chunk-LFTQVYBB.js +31 -0
- package/dist/chunk-LG3PDRTR.js +2872 -0
- package/dist/chunk-LGHII5ET.js +23 -0
- package/dist/chunk-LH5QY22X.js +1205 -0
- package/dist/chunk-LIVJ6266.js +438 -0
- package/dist/chunk-LKRAR3IH.js +276 -0
- package/dist/chunk-LO23NABI.js +3063 -0
- package/dist/chunk-LO3X5NLS.js +326 -0
- package/dist/chunk-LPITVM7M.js +339 -0
- package/dist/chunk-LR5IJIGV.js +810 -0
- package/dist/chunk-LRGMHROI.js +79 -0
- package/dist/chunk-LUVKFFWR.js +315 -0
- package/dist/chunk-LWCBNGH6.js +35 -0
- package/dist/chunk-LWTN3WRV.js +260 -0
- package/dist/chunk-M3HQYKQX.js +308 -0
- package/dist/chunk-M6GVSPEH.js +1016 -0
- package/dist/chunk-MF5HP6XV.js +221 -0
- package/dist/chunk-MHLCBZJB.js +328 -0
- package/dist/chunk-MN6PL4AN.js +120 -0
- package/dist/chunk-MOEY65Z6.js +5678 -0
- package/dist/chunk-MQ4WA34C.js +206 -0
- package/dist/chunk-MWHF5V7U.js +223 -0
- package/dist/chunk-MWHLBPNU.js +211 -0
- package/dist/chunk-MWK5UZQ3.js +1068 -0
- package/dist/chunk-MYLH2S4G.js +64 -0
- package/dist/chunk-MZ5WYKNA.js +28 -0
- package/dist/chunk-N4VTRA7K.js +131 -0
- package/dist/chunk-N5DX4JAK.js +12 -0
- package/dist/chunk-N65O4XTH.js +5011 -0
- package/dist/chunk-NEQUQHOX.js +223 -0
- package/dist/chunk-NGK6PEOG.js +25 -0
- package/dist/chunk-NJVD4PWE.js +1033 -0
- package/dist/chunk-NM6PMYY4.js +768 -0
- package/dist/chunk-NN4PJDHP.js +708 -0
- package/dist/chunk-NP2V3L7K.js +226 -0
- package/dist/chunk-NRLY536M.js +260 -0
- package/dist/chunk-NRNE225N.js +1270 -0
- package/dist/chunk-NS2K2GTP.js +605 -0
- package/dist/chunk-NS33V3IM.js +51 -0
- package/dist/chunk-NSHASMZZ.js +71 -0
- package/dist/chunk-NWOYOA6H.js +378 -0
- package/dist/chunk-NWRUSEXG.js +322 -0
- package/dist/chunk-NZGDAWIP.js +1905 -0
- package/dist/chunk-O47UOKU3.js +395 -0
- package/dist/chunk-O4G2W3ST.js +9831 -0
- package/dist/chunk-O6V4PNLO.js +63 -0
- package/dist/chunk-OA4GPILI.js +624 -0
- package/dist/chunk-OGMSYL6J.js +227 -0
- package/dist/chunk-OIS7J26S.js +319 -0
- package/dist/chunk-OMX5VL43.js +79 -0
- package/dist/chunk-ON3G73BU.js +264 -0
- package/dist/chunk-OPYFYTWQ.js +220 -0
- package/dist/chunk-OQ6K46CK.js +1734 -0
- package/dist/chunk-OYZYO7TV.js +47 -0
- package/dist/chunk-OZ4REHIN.js +4386 -0
- package/dist/chunk-P47VN5F4.js +282 -0
- package/dist/chunk-P5I4X7A7.js +353 -0
- package/dist/chunk-P6VQROCO.js +594 -0
- package/dist/chunk-P7CQGPLS.js +30 -0
- package/dist/chunk-PCAGC5MR.js +1763 -0
- package/dist/chunk-PFTQBXS6.js +5181 -0
- package/dist/chunk-PGSPX4SU.js +15 -0
- package/dist/chunk-PIKLF7BM.js +432 -0
- package/dist/chunk-PJWJ3SAV.js +22 -0
- package/dist/chunk-PKIFMV72.js +100 -0
- package/dist/chunk-PL37JDNA.js +189 -0
- package/dist/chunk-PTH5E5XO.js +195 -0
- package/dist/chunk-PW6AXLQC.js +4128 -0
- package/dist/chunk-PYITM4N2.js +79 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-Q3RO7N35.js +45 -0
- package/dist/chunk-Q3WIC6GQ.js +2670 -0
- package/dist/chunk-Q5XIXSHX.js +271 -0
- package/dist/chunk-QGJDMEOV.js +34 -0
- package/dist/chunk-QNOB37UH.js +58 -0
- package/dist/chunk-QOCOVLUH.js +462 -0
- package/dist/chunk-QTCJ5CC5.js +172 -0
- package/dist/chunk-QVFV5IP2.js +232 -0
- package/dist/chunk-QVZMFDYG.js +29 -0
- package/dist/chunk-R35PEUKH.js +511 -0
- package/dist/chunk-R4UWBC35.js +200 -0
- package/dist/chunk-R6MLCREW.js +44 -0
- package/dist/chunk-R6W23LKN.js +254 -0
- package/dist/chunk-R7XDDX2A.js +4007 -0
- package/dist/chunk-RDFRCT64.js +168 -0
- package/dist/chunk-RE5VZDFQ.js +58 -0
- package/dist/chunk-RGROYC2G.js +638 -0
- package/dist/chunk-RGWHUI5E.js +68 -0
- package/dist/chunk-RHVG6UNL.js +205 -0
- package/dist/chunk-RI4EX2QE.js +18 -0
- package/dist/chunk-RJAAKDRX.js +17 -0
- package/dist/chunk-ROMHOSMQ.js +185 -0
- package/dist/chunk-RWREC3KJ.js +517 -0
- package/dist/chunk-RYNETRDJ.js +118 -0
- package/dist/chunk-RZY7RKM5.js +500 -0
- package/dist/chunk-S2MNWFAG.js +52 -0
- package/dist/chunk-S2VQCZO4.js +22 -0
- package/dist/chunk-S54MKU6V.js +117 -0
- package/dist/chunk-S5OIDFRM.js +302 -0
- package/dist/chunk-SCW4ZF6R.js +150 -0
- package/dist/chunk-SLS2N4PH.js +2213 -0
- package/dist/chunk-SNLBO4BF.js +247 -0
- package/dist/chunk-SP3LFU6B.js +60 -0
- package/dist/chunk-SQQTDDQA.js +537 -0
- package/dist/chunk-STV6LYYE.js +45 -0
- package/dist/chunk-SURZ2WFE.js +326 -0
- package/dist/chunk-SZ7DL357.js +1047 -0
- package/dist/chunk-T5E4NQCM.js +5742 -0
- package/dist/chunk-TAJPCXSB.js +13 -0
- package/dist/chunk-TAOOYK3P.js +358 -0
- package/dist/chunk-TDSEX5CF.js +24 -0
- package/dist/chunk-TFTGP7Z7.js +174 -0
- package/dist/chunk-TGON4N4O.js +197 -0
- package/dist/chunk-TGQZHDY2.js +2373 -0
- package/dist/chunk-TJJZ2OKV.js +6783 -0
- package/dist/chunk-TRSVUPCX.js +25 -0
- package/dist/chunk-TSXGRLPR.js +107 -0
- package/dist/chunk-U2S3YEX3.js +224 -0
- package/dist/chunk-U45RTRGY.js +818 -0
- package/dist/chunk-U6C3VVWS.js +13 -0
- package/dist/chunk-UDMS5AD3.js +307 -0
- package/dist/chunk-UGX7GI37.js +94 -0
- package/dist/chunk-UH3JJSHK.js +1 -0
- package/dist/chunk-UHRBTZYY.js +208 -0
- package/dist/chunk-UHT2KRG5.js +193 -0
- package/dist/chunk-UI2F6DJ5.js +118 -0
- package/dist/chunk-UMAKSB4Z.js +284 -0
- package/dist/chunk-UR2IBGIM.js +521 -0
- package/dist/chunk-UUH2RVKS.js +585 -0
- package/dist/chunk-UVJ4PJDK.js +4533 -0
- package/dist/chunk-V53UG2OT.js +9924 -0
- package/dist/chunk-V72RMBM4.js +48 -0
- package/dist/chunk-VBNCKCCI.js +16 -0
- package/dist/chunk-VNSYKC25.js +24 -0
- package/dist/chunk-VPHVFK4A.js +1984 -0
- package/dist/chunk-VTLNJQ44.js +133 -0
- package/dist/chunk-VTW7HP3R.js +100 -0
- package/dist/chunk-VVGEPBPS.js +218 -0
- package/dist/chunk-VVLLL7I4.js +166 -0
- package/dist/chunk-VX3UMWB7.js +483 -0
- package/dist/chunk-VXF4Q3FW.js +20 -0
- package/dist/chunk-W3JMT2YY.js +712 -0
- package/dist/chunk-WDUORIHF.js +877 -0
- package/dist/chunk-WDVTY4U6.js +148 -0
- package/dist/chunk-WIFZCHEG.js +12566 -0
- package/dist/chunk-WIRN3F75.js +736 -0
- package/dist/chunk-WMPU2UOV.js +82 -0
- package/dist/chunk-WTOKKE2V.js +784 -0
- package/dist/chunk-WX5IRLF6.js +740 -0
- package/dist/chunk-WZ6U3O7I.js +1581 -0
- package/dist/chunk-XAONGNST.js +57 -0
- package/dist/chunk-XB5YLCLB.js +13 -0
- package/dist/chunk-XEP5NQ5Y.js +688 -0
- package/dist/chunk-XGYF2QMZ.js +351 -0
- package/dist/chunk-XHEKQENB.js +255 -0
- package/dist/chunk-XNO4FM6X.js +1124 -0
- package/dist/chunk-XPHKYHO4.js +878 -0
- package/dist/chunk-XPK2I4NC.js +405 -0
- package/dist/chunk-XPU2XADL.js +2175 -0
- package/dist/chunk-XQD2B6BB.js +507 -0
- package/dist/chunk-XT2ZQVTC.js +558 -0
- package/dist/chunk-XTXJGGUV.js +351 -0
- package/dist/chunk-XUXVDPSZ.js +50 -0
- package/dist/chunk-XV7NZL4B.js +57 -0
- package/dist/chunk-XZE4XARH.js +563 -0
- package/dist/chunk-XZYR5EDO.js +152 -0
- package/dist/chunk-Y3J4JMTU.js +61 -0
- package/dist/chunk-Y55LZN5U.js +52 -0
- package/dist/chunk-Y5VN7DMP.js +112 -0
- package/dist/chunk-Y67VAHN4.js +459 -0
- package/dist/chunk-YAXSKEUH.js +3544 -0
- package/dist/chunk-YB3JD4E6.js +975 -0
- package/dist/chunk-YESZJFK6.js +220 -0
- package/dist/chunk-YGXKOBQQ.js +292 -0
- package/dist/chunk-YMX76IOS.js +31 -0
- package/dist/chunk-YOTXESEH.js +257 -0
- package/dist/chunk-YTYIEZQY.js +119 -0
- package/dist/chunk-YVORHQ2S.js +579 -0
- package/dist/chunk-Z2CUQDAR.js +3429 -0
- package/dist/chunk-Z2KYOFHS.js +7000 -0
- package/dist/chunk-Z6PC7QX6.js +161 -0
- package/dist/chunk-ZDTGECTN.js +235 -0
- package/dist/chunk-ZIPWI2LY.js +151 -0
- package/dist/chunk-ZSKKMTQJ.js +554 -0
- package/dist/chunk-ZTT5IVPY.js +1160 -0
- package/dist/chunk-ZX65UI5W.js +78 -0
- package/dist/chunk-ZYG7GGKO.js +218 -0
- package/dist/chunk-ZZZUL4OF.js +38 -0
- package/dist/cli-utils-IXL26KJT.js +40 -0
- package/dist/cli-validation-WLXWLUJL.js +111 -0
- package/dist/commit-utils-P7CRJF5N.js +202 -0
- package/dist/compete-config-resolver-R5ULXMYH.js +76 -0
- package/dist/compete-request-62JESVET.js +364 -0
- package/dist/compete-results-QEPG6FZX.js +208 -0
- package/dist/competition-outcome-tracker-R32OOZ43.js +38 -0
- package/dist/config-JCOKXOQT.js +166 -0
- package/dist/config-audit-EL3GHXS7.js +360 -0
- package/dist/config-explain-TNILDEVJ.js +12 -0
- package/dist/config-loader-VPFPFO4B.js +38 -0
- package/dist/config-manager-7T4E2BQO.js +67 -0
- package/dist/config-validator-KKOHOW7O.js +72 -0
- package/dist/cost-YC42XUF3.js +53 -0
- package/dist/coverage-orchestrator-CISNKJC2.js +772 -0
- package/dist/coverage-scanner-YVD62MLH.js +12 -0
- package/dist/createCompetitionRunner-LJG6ZQSO.js +46 -0
- package/dist/data-migration-state-VJK64DLT.js +31 -0
- package/dist/db-migrator-XSEIOGWY.js +34 -0
- package/dist/discovery-JGYGDD25.js +25 -0
- package/dist/doctor-GJOYE7AE.js +186 -0
- package/dist/domain-analyzer-AWF3RP6E.js +29 -0
- package/dist/ensure-initialized-744DIZEZ.js +52 -0
- package/dist/entry.js +940 -0
- package/dist/environment-YS45U5ZI.js +81 -0
- package/dist/error-parser-core-PPZ36A4S.js +50 -0
- package/dist/escalation-ladder-MKTCEGSA.js +130 -0
- package/dist/evaluation-context-KV4GZNN7.js +35 -0
- package/dist/evidence-plan-resolver-GBSYSAPX.js +85 -0
- package/dist/execution-data-writer-3ODTBDLH.js +53 -0
- package/dist/execution-policy-applier-ZHD3DCF3.js +31 -0
- package/dist/execution-preflight-Z4Y64V3I.js +209 -0
- package/dist/execution-roles-R3DPPMD3.js +66 -0
- package/dist/exit-code-error-Z4SW2DVK.js +14 -0
- package/dist/external-temp-cleanup-N2RZH4QP.js +311 -0
- package/dist/factory-XBN7DFIM.js +149 -0
- package/dist/file-utils-XIVR2ZMA.js +47 -0
- package/dist/flywheel-autoloop-executor-UILGOFFK.js +249 -0
- package/dist/flywheel-competition-executor-JOBEXTRB.js +259 -0
- package/dist/flywheel-executor-6JFLA6J5.js +369 -0
- package/dist/flywheel-git-isolation-UC5NIEVU.js +48 -0
- package/dist/flywheel-manifest-5UC4VBMA.js +108 -0
- package/dist/flywheel-model-defaults-7CVKP53V.js +27 -0
- package/dist/flywheel-preflight-XEY5SHM6.js +104 -0
- package/dist/flywheel-resume-7HELH7QS.js +23 -0
- package/dist/flywheel-safety-7U7DPOAP.js +28 -0
- package/dist/flywheel-scope-decision-ZHKF6ZIN.js +11 -0
- package/dist/get-telemetry-logger-DPVWWIYY.js +73 -0
- package/dist/git-worktree-IY6V6DUO.js +18 -0
- package/dist/github-pr-manager-4LXEKJTA.js +211 -0
- package/dist/guidance-profile-config-E7XJL2VP.js +117 -0
- package/dist/guidance-profile-renderer-QK2YMAAP.js +21 -0
- package/dist/index-query-4JEUKA44.js +31 -0
- package/dist/index.js +108661 -0
- package/dist/instructions-6BURLQJC.js +64 -0
- package/dist/invoke-provider-auth-GRUYP44M.js +223 -0
- package/dist/judge-scoring.json +80 -0
- package/dist/judge-test.js +555 -0
- package/dist/lab-mode-OTWVHN63.js +39 -0
- package/dist/lab-utils-BJRFLGK4.js +23 -0
- package/dist/linux-host-class-UY4KVLFD.js +29 -0
- package/dist/llm-judge-executor-F7Z3HO77.js +133 -0
- package/dist/local-executor-CEHWE2PL.js +223 -0
- package/dist/logger-33TR6EE5.js +72 -0
- package/dist/loop-spec-XTLQAVZ7.js +191 -0
- package/dist/manager-2HJG5CLT.js +25 -0
- package/dist/matrix-prompt-builder-6UDN5X3F.js +497 -0
- package/dist/matrix-result-parser-7W35EUOV.js +15 -0
- package/dist/metadata-HQ43NDEK.js +22 -0
- package/dist/model-invocations-db-QBO4Y7WZ.js +38 -0
- package/dist/monitor-XGYBG2DW.js +72 -0
- package/dist/next-PB5ZXZKB.js +90 -0
- package/dist/next-ZBDK725T.js +69 -0
- package/dist/optimization-config-resolver-O6WKR47U.js +75 -0
- package/dist/package-3YCWIQQ5.js +10 -0
- package/dist/parallel-orchestrator-NL7YJJU2.js +297 -0
- package/dist/parallel-worker.js +279 -0
- package/dist/parse-git-status-PIAF3OTP.js +10 -0
- package/dist/path-security-ETTH6TZL.js +39 -0
- package/dist/pattern-bank-UNJR5ADV.js +15 -0
- package/dist/plan-backlog-list-fast-VAGYBV3J.js +270 -0
- package/dist/plan-backlog-show-fast-SG2CZPW3.js +406 -0
- package/dist/plan-sprint-list-fast-LURAX47V.js +162 -0
- package/dist/plan-sprint-status-fast-FJAODCHD.js +208 -0
- package/dist/plan-task-status-fast-HNYBMQI4.js +349 -0
- package/dist/plan-to-flywheel-Z4U3GWPN.js +456 -0
- package/dist/planning-backlog-3CQ5QQBQ.js +319 -0
- package/dist/poetic-root-V5DNXEAE.js +17 -0
- package/dist/preflight-OPANWMME.js +12 -0
- package/dist/process-registry-PDZJPTAS.js +27 -0
- package/dist/process-scanner-C22SYXYD.js +22 -0
- package/dist/processes-KMQUD7HY.js +29 -0
- package/dist/processes-json-fast-IBDXZ6WW.js +135 -0
- package/dist/profile-SE5EVXAP.js +149 -0
- package/dist/prompts-WZZPGWBX.js +168 -0
- package/dist/protected-branches-RNTEX7ET.js +57 -0
- package/dist/provider-aware-resource-manager-QBTZJMNP.js +18 -0
- package/dist/provider-matrix-N5X57V3Y.js +154 -0
- package/dist/provider-matrix-renderer-MZDWKKID.js +139 -0
- package/dist/provider-output-forwarding-DERID3TP.js +30 -0
- package/dist/provider-registry-J5NRBJKI.js +128 -0
- package/dist/provider-temp-cleanup-KYGLF6YU.js +14 -0
- package/dist/prune-engine-Q6E2DXBN.js +451 -0
- package/dist/quality-gate-YRHMQAEI.js +70 -0
- package/dist/quickstart-FIRLKGJI.js +62 -0
- package/dist/readiness-VZTMSG6J.js +96 -0
- package/dist/registry-YODFY77A.js +153 -0
- package/dist/repair-helpers-TTV5FEF4.js +117 -0
- package/dist/repo-root-2IGD4H7X.js +22 -0
- package/dist/resolution-engine-D6TX6FRG.js +127 -0
- package/dist/resolve-provider-cli-O2P6XZBZ.js +35 -0
- package/dist/restore-telemetry-db-BQL6DTQF.js +360 -0
- package/dist/result-streamer-WEHW476R.js +19 -0
- package/dist/routing-events-DHPUZDDF.js +27 -0
- package/dist/routing-history-store-UWCEXAP3.js +46 -0
- package/dist/routing-planner-F5WQEUOM.js +160 -0
- package/dist/run-poetic-tui-J6LWRJUP.js +13517 -0
- package/dist/run-simulation.js +376 -0
- package/dist/runner-CS2TNGHA.js +1092 -0
- package/dist/runner-HHH7ZN2Z.js +1571 -0
- package/dist/safety-OCC4KJJR.js +64 -0
- package/dist/safety-stanza-7SV3HGG3.js +60 -0
- package/dist/sandbox-32QXJEMV.js +81 -0
- package/dist/sandbox-RSO7VP6V.js +94 -0
- package/dist/schema-extensions.sql +234 -0
- package/dist/security-2KI5XNDG.js +17 -0
- package/dist/setup-bb-plugin-QAQWZCV5.js +738 -0
- package/dist/setup-claude-code-P7BTTSPO.js +317 -0
- package/dist/setup-temp-cleanup-GASCWZ2I.js +20 -0
- package/dist/shared-utils-D6U6UREP.js +37 -0
- package/dist/simple-artifact-goal-OTXNGZY6.js +25 -0
- package/dist/sprint-UIXPYOXQ.js +338 -0
- package/dist/sprint-bridge-4BHMSC3M.js +68 -0
- package/dist/sprint-execution-service-2B7WHL5L.js +311 -0
- package/dist/sprint-manager-IDQUDNQI.js +91 -0
- package/dist/sqlite-wrapper-UDWCTNLJ.js +17 -0
- package/dist/stale-cleanup-orchestrator-XWXV7KCZ.js +62 -0
- package/dist/storage-access-F6ALDN4S.js +22 -0
- package/dist/synthesis-XD6EDVHF.js +185 -0
- package/dist/task-classifier-LNLXSHOM.js +494 -0
- package/dist/task-list-fast-PTMA4LUC.js +147 -0
- package/dist/task-manager-XAT7GOWB.js +93 -0
- package/dist/task-splitter-U7DJ7W6A.js +79 -0
- package/dist/task-type-detector-OLVOMXZO.js +21 -0
- package/dist/task-type-resolver-KKNQYSB4.js +42 -0
- package/dist/telemetry-5HWBBXLX.js +131 -0
- package/dist/telemetry-health-tracker-DMSSGBZ2.js +11 -0
- package/dist/telemetry-path-resolver-7ICSG276.js +28 -0
- package/dist/telemetry-reliability-XUOZNZZ6.js +125 -0
- package/dist/token-estimator-MEQUL3EJ.js +37 -0
- package/dist/transports-KNSSV2V4.js +255 -0
- package/dist/unified-cost-tracker-4TFRBVPR.js +35 -0
- package/dist/unified-state-cleanup-LJPF2BOW.js +276 -0
- package/dist/universal-cost-calculator-BAJV35GA.js +42 -0
- package/dist/user-agents-GHUGCSKN.js +22 -0
- package/dist/variant-delivery-state-KLRNG6XA.js +33 -0
- package/dist/variant-state-cleanup-MZGGLQAJ.js +280 -0
- package/dist/variant-success-PJXWE3ZV.js +12 -0
- package/dist/variant-worker-KUWKBLAH.js +4196 -0
- package/dist/variant-worker.js +24 -0
- package/dist/variants-JE2FSAQS.js +233 -0
- package/dist/verification-toolchains-V24UHW6Q.js +28 -0
- package/dist/verify-commands-H3DTCSGI.js +37 -0
- package/dist/warning-EGQGUUIO.js +12 -0
- package/dist/work-edge-RWEDWJZF.js +49 -0
- package/dist/work-item-writer-WHAVZXAY.js +19 -0
- package/dist/worker-7SA2VS2Y.js +1435 -0
- package/dist/worker.js +19 -0
- package/dist/worktree-metrics-3DFUYVYE.js +26 -0
- package/dist/writeback-VZKHYHSN.js +44 -0
- package/docs/CLI_REFERENCE.md +7042 -0
- package/docs/PROVIDER_SETUP.md +1570 -0
- package/docs/README.md +96 -0
- package/docs/TROUBLESHOOTING.md +2232 -0
- package/docs/getting-started/QUICK_START.md +294 -0
- package/docs/getting-started/README.md +188 -0
- package/docs/getting-started/SETUP.md +52 -0
- package/docs/reference/AGENT_CONTEXT.md +38 -0
- package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
- package/docs/reference/README.md +381 -0
- package/docs/reference/SECURITY.md +262 -0
- package/integrations/bb-plugin-poetic/README.md +362 -0
- package/integrations/bb-plugin-poetic/app.css +341 -0
- package/integrations/bb-plugin-poetic/app.tsx +5059 -0
- package/integrations/bb-plugin-poetic/package.json +45 -0
- package/integrations/bb-plugin-poetic/server.ts +444 -0
- package/integrations/bb-plugin-poetic/src/adapter.ts +3312 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-model.ts +150 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-schema.ts +355 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-service.ts +419 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-view.ts +1026 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-schema.ts +122 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-service.ts +105 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-view.ts +138 -0
- package/integrations/bb-plugin-poetic/src/contract.ts +615 -0
- package/integrations/bb-plugin-poetic/src/finalize-model.ts +205 -0
- package/integrations/bb-plugin-poetic/src/finalize-schema.ts +158 -0
- package/integrations/bb-plugin-poetic/src/finalize-service.ts +382 -0
- package/integrations/bb-plugin-poetic/src/finalize-view.ts +159 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-readback.ts +303 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-schema.ts +33 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-view.ts +459 -0
- package/integrations/bb-plugin-poetic/src/model.ts +1302 -0
- package/integrations/bb-plugin-poetic/src/monitor-service.ts +233 -0
- package/integrations/bb-plugin-poetic/src/panel-read-ux.ts +97 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-schema.ts +166 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-service.ts +480 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-view.ts +109 -0
- package/integrations/bb-plugin-poetic/src/planning-readback.ts +204 -0
- package/integrations/bb-plugin-poetic/src/planning-service.ts +594 -0
- package/integrations/bb-plugin-poetic/src/planning-workspace-schema.ts +95 -0
- package/integrations/bb-plugin-poetic/src/planning-workspace.ts +323 -0
- package/integrations/bb-plugin-poetic/src/poll-handoff.ts +136 -0
- package/integrations/bb-plugin-poetic/src/project-target-server.ts +21 -0
- package/integrations/bb-plugin-poetic/src/project-target.ts +45 -0
- package/integrations/bb-plugin-poetic/src/reference-index.ts +192 -0
- package/integrations/bb-plugin-poetic/src/repository-schema.ts +30 -0
- package/integrations/bb-plugin-poetic/src/result-explorer-view.ts +597 -0
- package/integrations/bb-plugin-poetic/src/result-readback-model.ts +163 -0
- package/integrations/bb-plugin-poetic/src/result-readback-schema.ts +319 -0
- package/integrations/bb-plugin-poetic/src/result-readback-service.ts +333 -0
- package/integrations/bb-plugin-poetic/src/run-page-view.ts +177 -0
- package/integrations/bb-plugin-poetic/src/setup-config-schema.ts +291 -0
- package/integrations/bb-plugin-poetic/src/setup-config-service.ts +590 -0
- package/integrations/bb-plugin-poetic/src/setup-config-view.ts +413 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-model.ts +150 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-schema.ts +136 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-service.ts +341 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-view.ts +116 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-model.ts +714 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-readback.ts +231 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-schema.ts +601 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-service.ts +775 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-view.ts +1221 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-model.ts +567 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-schema.ts +635 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-service.ts +842 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-view.ts +1227 -0
- package/integrations/bb-plugin-poetic/src/task-detail-readback.ts +56 -0
- package/integrations/bb-plugin-poetic/src/task-detail-schema.ts +144 -0
- package/integrations/bb-plugin-poetic/src/task-navigation.ts +446 -0
- package/integrations/bb-plugin-poetic/src/workbench-route.ts +74 -0
- package/integrations/bb-plugin-poetic/tests/host-contract.test.ts +773 -0
- package/integrations/bb-plugin-poetic/tsconfig.json +18 -0
- package/integrations/bb-plugin-poetic/types/PROVENANCE.json +52 -0
- package/integrations/bb-plugin-poetic/types/bb-plugin-sdk-app.d.ts +1444 -0
- package/integrations/bb-plugin-poetic/types/bb-plugin-sdk.d.ts +13030 -0
- package/integrations/bb-plugin-poetic/vitest.host.config.ts +71 -0
- package/npm-shrinkwrap.json +4950 -0
- package/package.json +331 -0
- package/schemas/README.md +80 -0
- package/schemas/config-v1.schema.json +136 -0
- package/schemas/execution-config.schema.json +47 -0
- package/schemas/judge-scoring.schema.json +370 -0
- package/schemas/poetic.config.schema.json +2214 -0
- package/schemas/provider-config.schema.json +203 -0
- package/schemas/telemetry-config.schema.json +79 -0
- package/schemas/user-preferences.schema.json +141 -0
- package/scripts/assert-node-runtime.mjs +140 -0
- package/scripts/preflight-native.mjs +49 -0
- package/scripts/preinstall-node-check.mjs +78 -0
- package/scripts/setup-git-hooks.mjs +24 -0
- package/scripts/sync.sh +2722 -0
- package/scripts/write-node-launcher.sh +108 -0
- package/src/resources/gemini/slash-packs/default/plan.toml +15 -0
- package/src/resources/gemini/slash-packs/default/summary.toml +16 -0
- package/src/resources/gemini/slash-packs/default/tests.toml +16 -0
- package/templates/.poetic/README.md +37 -0
- package/templates/.poetic/agents/README.md +296 -0
- package/templates/.poetic/agents/api-documenter.md +147 -0
- package/templates/.poetic/agents/backend-architect.md +31 -0
- package/templates/.poetic/agents/code-reviewer.md +157 -0
- package/templates/.poetic/agents/data-scientist.md +179 -0
- package/templates/.poetic/agents/database-optimizer.md +145 -0
- package/templates/.poetic/agents/debugger.md +31 -0
- package/templates/.poetic/agents/deployment-engineer.md +164 -0
- package/templates/.poetic/agents/devops-troubleshooter.md +139 -0
- package/templates/.poetic/agents/frontend-developer.md +150 -0
- package/templates/.poetic/agents/javascript-pro.md +36 -0
- package/templates/.poetic/agents/performance-engineer.md +151 -0
- package/templates/.poetic/agents/python-pro.md +137 -0
- package/templates/.poetic/agents/test-automator.md +147 -0
- package/templates/.poetic/agents/typescript-pro.md +34 -0
- package/templates/.poetic/config/poetic.config.jsonc +69 -0
- package/templates/.poetic/config/project-context.template.json +6 -0
- package/templates/.poetic/config/task-type-aliases.presets/kanban.yaml +14 -0
- package/templates/.poetic/config/task-type-aliases.presets/scrum.yaml +17 -0
- package/templates/.poetic/config/task-type-aliases.presets/xp.yaml +12 -0
- package/templates/.poetic/config/task-type-aliases.yaml +28 -0
- package/templates/.poetic/gitignore.template +55 -0
- package/templates/.poetic/task-types/analysis.yaml +40 -0
- package/templates/.poetic/task-types/architecture.yaml +38 -0
- package/templates/.poetic/task-types/doc.yaml +35 -0
- package/templates/.poetic/task-types/feature.yaml +23 -0
- package/templates/.poetic/task-types/general.yaml +6 -0
- package/templates/.poetic/task-types/security.yaml +39 -0
- package/templates/AGENTS.template.md +99 -0
- package/templates/CLAUDE.template.md +1 -0
- package/templates/GEMINI.template.md +1 -0
- package/templates/builtin-workflows/code-review.yaml +73 -0
- package/templates/builtin-workflows/compete-streak.yaml +78 -0
- package/templates/builtin-workflows/hello-verify.yaml +10 -0
- package/templates/builtin-workflows/judge-regression.yaml +114 -0
- package/templates/builtin-workflows/skills/code-review/SKILL.md +60 -0
- package/templates/builtin-workflows/skills/hello-verify/SKILL.md +6 -0
- package/templates/guard-kit/GUARD_SETUP.md.template +255 -0
- package/templates/guard-kit/check.mjs.template +777 -0
- package/templates/guard-kit/config.json.template +6 -0
- package/templates/guard-kit/poetic-guard.yml.template +189 -0
- package/templates/profiles/README.md +56 -0
- package/templates/profiles/frontier-claude.json +27 -0
- package/templates/profiles/frontier-codex.json +26 -0
|
@@ -0,0 +1,966 @@
|
|
|
1
|
+
import {
|
|
2
|
+
enqueueBranchCleanup,
|
|
3
|
+
getBranchCleanupQueuePath
|
|
4
|
+
} from "./chunk-TGON4N4O.js";
|
|
5
|
+
import {
|
|
6
|
+
CLEANUP_LOCK_FILENAME,
|
|
7
|
+
describeCleanupLockState,
|
|
8
|
+
formatCleanupLockContentionMessage,
|
|
9
|
+
isActiveRun,
|
|
10
|
+
isCleanupLockContentionError,
|
|
11
|
+
tryWithCleanupLock,
|
|
12
|
+
withCleanupLock
|
|
13
|
+
} from "./chunk-I5WRT7ZR.js";
|
|
14
|
+
import {
|
|
15
|
+
pruneGitWorktreeEntries
|
|
16
|
+
} from "./chunk-5EERLVZB.js";
|
|
17
|
+
import {
|
|
18
|
+
isProtectedPipelineBranch
|
|
19
|
+
} from "./chunk-XQD2B6BB.js";
|
|
20
|
+
import {
|
|
21
|
+
formatBytes
|
|
22
|
+
} from "./chunk-JLS65NUQ.js";
|
|
23
|
+
import {
|
|
24
|
+
isQuietOutputRequested
|
|
25
|
+
} from "./chunk-FKAUPHMR.js";
|
|
26
|
+
import {
|
|
27
|
+
LabPathResolver
|
|
28
|
+
} from "./chunk-7GDRQBQC.js";
|
|
29
|
+
import {
|
|
30
|
+
findProjectRoot
|
|
31
|
+
} from "./chunk-L6OM4A22.js";
|
|
32
|
+
import {
|
|
33
|
+
canonicalizePath,
|
|
34
|
+
safeRmDir
|
|
35
|
+
} from "./chunk-G4THLFV3.js";
|
|
36
|
+
import {
|
|
37
|
+
resolveWorktreeBase
|
|
38
|
+
} from "./chunk-UUH2RVKS.js";
|
|
39
|
+
import {
|
|
40
|
+
emitWarning
|
|
41
|
+
} from "./chunk-EJGCZGUF.js";
|
|
42
|
+
import {
|
|
43
|
+
POETIC_DEBUG,
|
|
44
|
+
POETIC_WORKTREE_TTL_DAYS,
|
|
45
|
+
readEnv,
|
|
46
|
+
readRawEnv
|
|
47
|
+
} from "./chunk-5DLKYTQX.js";
|
|
48
|
+
|
|
49
|
+
// src/utils/worktree-cleanup.ts
|
|
50
|
+
import { execFileSync } from "child_process";
|
|
51
|
+
import { existsSync, readFileSync } from "fs";
|
|
52
|
+
import { readdir, stat } from "fs/promises";
|
|
53
|
+
import { basename, isAbsolute, join, relative, resolve, sep } from "path";
|
|
54
|
+
import { execa } from "execa";
|
|
55
|
+
var DEFAULT_WORKTREE_TTL_DAYS = 1;
|
|
56
|
+
var MIN_WORKTREE_CLEANUP_AGE_MS = 60 * 60 * 1e3;
|
|
57
|
+
var LABS_RELATIVE_PATH = ".poetic/labs";
|
|
58
|
+
function isCleanupLockArtifactName(name) {
|
|
59
|
+
return name === CLEANUP_LOCK_FILENAME || name === `${CLEANUP_LOCK_FILENAME}.lock`;
|
|
60
|
+
}
|
|
61
|
+
function logCleanupMessage(message) {
|
|
62
|
+
if (isQuietOutputRequested()) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
console.log(message);
|
|
66
|
+
}
|
|
67
|
+
var worktreeCleanupMutexTail = Promise.resolve();
|
|
68
|
+
function runWorktreeCleanupSerialized(fn) {
|
|
69
|
+
const run = worktreeCleanupMutexTail.then(fn);
|
|
70
|
+
worktreeCleanupMutexTail = run.then(
|
|
71
|
+
() => void 0,
|
|
72
|
+
() => void 0
|
|
73
|
+
);
|
|
74
|
+
return run;
|
|
75
|
+
}
|
|
76
|
+
function pathDepth(pathValue) {
|
|
77
|
+
return pathValue.split(sep).filter(Boolean).length;
|
|
78
|
+
}
|
|
79
|
+
function isNestedPath(parentPath, maybeChildPath) {
|
|
80
|
+
const parent = canonicalizePath(parentPath);
|
|
81
|
+
const child = canonicalizePath(maybeChildPath);
|
|
82
|
+
return child !== parent && child.startsWith(`${parent}${sep}`);
|
|
83
|
+
}
|
|
84
|
+
function isPathWithinDir(candidatePath, dirPath) {
|
|
85
|
+
const rel = relative(dirPath, candidatePath);
|
|
86
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
87
|
+
}
|
|
88
|
+
function isCanonicalLabWorktreePath(candidatePath) {
|
|
89
|
+
const segments = resolve(candidatePath).split(sep);
|
|
90
|
+
const tail = segments.slice(-7);
|
|
91
|
+
return tail.length === 7 && tail[0] === ".poetic" && tail[1] === "labs" && tail[3] === "runs" && tail[5] === "worktrees";
|
|
92
|
+
}
|
|
93
|
+
function getMaxWorktreeAge() {
|
|
94
|
+
const raw = readRawEnv(POETIC_WORKTREE_TTL_DAYS);
|
|
95
|
+
if (raw === void 0) {
|
|
96
|
+
return DEFAULT_WORKTREE_TTL_DAYS * 24 * 60 * 60 * 1e3;
|
|
97
|
+
}
|
|
98
|
+
const parsed = Number.parseInt(raw, 10);
|
|
99
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
100
|
+
emitWarning(
|
|
101
|
+
"CFG-002",
|
|
102
|
+
{
|
|
103
|
+
subsystem: "utils",
|
|
104
|
+
executionPhase: "setup"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
severity: "WARN" /* WARN */,
|
|
108
|
+
metadata: {
|
|
109
|
+
configKey: "POETIC_WORKTREE_TTL_DAYS",
|
|
110
|
+
invalidValue: raw,
|
|
111
|
+
fallbackValue: DEFAULT_WORKTREE_TTL_DAYS
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
return DEFAULT_WORKTREE_TTL_DAYS * 24 * 60 * 60 * 1e3;
|
|
116
|
+
}
|
|
117
|
+
return parsed * 24 * 60 * 60 * 1e3;
|
|
118
|
+
}
|
|
119
|
+
var WorktreeCleanupManager = class {
|
|
120
|
+
baseDir;
|
|
121
|
+
constructor(baseDir) {
|
|
122
|
+
this.baseDir = baseDir;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get worktree base directory
|
|
126
|
+
*
|
|
127
|
+
* @returns Absolute path to worktree base directory
|
|
128
|
+
*/
|
|
129
|
+
getWorktreeBase() {
|
|
130
|
+
if (this.baseDir) {
|
|
131
|
+
return this.baseDir;
|
|
132
|
+
}
|
|
133
|
+
return resolveWorktreeBase();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Read directories under the given path and add them to the candidate map
|
|
137
|
+
*/
|
|
138
|
+
async populateCandidatesFromDir(dirPath, source, map, labPaths) {
|
|
139
|
+
if (!existsSync(dirPath)) return;
|
|
140
|
+
try {
|
|
141
|
+
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
142
|
+
for (const entry of entries) {
|
|
143
|
+
if (isCleanupLockArtifactName(entry.name)) continue;
|
|
144
|
+
if (!entry.isDirectory()) continue;
|
|
145
|
+
const entryPath = resolve(dirPath, entry.name);
|
|
146
|
+
if (map.has(entryPath)) continue;
|
|
147
|
+
map.set(entryPath, {
|
|
148
|
+
path: entryPath,
|
|
149
|
+
name: entry.name,
|
|
150
|
+
source,
|
|
151
|
+
registeredGitWorktree: false
|
|
152
|
+
});
|
|
153
|
+
if (source === "lab") {
|
|
154
|
+
labPaths.add(entryPath);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
} catch (error) {
|
|
158
|
+
this.logDebug(`Failed to read worktree directory ${dirPath}`, error);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Discover lab worktrees under .poetic/labs
|
|
163
|
+
*/
|
|
164
|
+
async discoverLabWorktrees(repoRoot, map, labPaths) {
|
|
165
|
+
const labsRoot = resolve(repoRoot, LABS_RELATIVE_PATH);
|
|
166
|
+
if (!existsSync(labsRoot)) return;
|
|
167
|
+
try {
|
|
168
|
+
const labs = await readdir(labsRoot, { withFileTypes: true });
|
|
169
|
+
for (const labEntry of labs) {
|
|
170
|
+
if (!labEntry.isDirectory()) continue;
|
|
171
|
+
const runsPath = join(labsRoot, labEntry.name, "runs");
|
|
172
|
+
if (!existsSync(runsPath)) continue;
|
|
173
|
+
const runs = await readdir(runsPath, { withFileTypes: true });
|
|
174
|
+
for (const runEntry of runs) {
|
|
175
|
+
if (!runEntry.isDirectory()) continue;
|
|
176
|
+
const worktreesPath = join(runsPath, runEntry.name, "worktrees");
|
|
177
|
+
await this.populateCandidatesFromDir(worktreesPath, "lab", map, labPaths);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
} catch (error) {
|
|
181
|
+
this.logDebug("Failed to discover lab worktrees", error);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Discover worktrees created by older Poetic versions under the target repo.
|
|
186
|
+
* New default worktree pools live outside the checkout, but cleanup must still
|
|
187
|
+
* drain this legacy location so old crash debris does not keep tainting host
|
|
188
|
+
* verification or test discovery.
|
|
189
|
+
*/
|
|
190
|
+
async discoverLegacyRepoLocalWorktrees(repoRoot, map, labPaths) {
|
|
191
|
+
if (this.baseDir) return;
|
|
192
|
+
const legacyWorktreeBase = resolve(repoRoot, ".poetic/tmp/worktrees");
|
|
193
|
+
if (resolve(this.getWorktreeBase()) === legacyWorktreeBase) return;
|
|
194
|
+
await this.populateCandidatesFromDir(legacyWorktreeBase, "standard", map, labPaths);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Discover stale worktree-shaped directories that escaped the standard
|
|
198
|
+
* .poetic/tmp/worktrees bucket. These are limited to directories with a .git
|
|
199
|
+
* file whose gitdir target no longer exists, so regular tmp directories are
|
|
200
|
+
* not promoted into worktree cleanup candidates.
|
|
201
|
+
*/
|
|
202
|
+
async discoverBrokenMetadataTmpWorktrees(repoRoot, map) {
|
|
203
|
+
if (this.baseDir) return;
|
|
204
|
+
const tmpRoot = resolve(repoRoot, ".poetic/tmp");
|
|
205
|
+
if (!existsSync(tmpRoot)) return;
|
|
206
|
+
const visit = async (dirPath, depth) => {
|
|
207
|
+
if (depth > 3) return;
|
|
208
|
+
if (existsSync(join(dirPath, ".git")) && this.hasBrokenGitdirPointer(dirPath)) {
|
|
209
|
+
if (!map.has(dirPath)) {
|
|
210
|
+
map.set(dirPath, {
|
|
211
|
+
path: dirPath,
|
|
212
|
+
name: basename(dirPath),
|
|
213
|
+
source: "standard",
|
|
214
|
+
registeredGitWorktree: false
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
let entries;
|
|
220
|
+
try {
|
|
221
|
+
entries = await readdir(dirPath, { withFileTypes: true });
|
|
222
|
+
} catch (error) {
|
|
223
|
+
this.logDebug(`Failed to scan tmp directory ${dirPath}`, error);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
for (const entry of entries) {
|
|
227
|
+
if (!entry.isDirectory()) continue;
|
|
228
|
+
await visit(join(dirPath, entry.name), depth + 1);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
await visit(tmpRoot, 0);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* True when a git-discovered worktree lives under a Poetic-managed cleanup root.
|
|
235
|
+
* External manual worktrees registered in Git but outside these roots are preserved.
|
|
236
|
+
*/
|
|
237
|
+
isUnderPoeticManagedCleanupRoot(candidatePath, repoRoot, worktreeBase) {
|
|
238
|
+
const resolved = resolve(candidatePath);
|
|
239
|
+
if (isPathWithinDir(resolved, resolve(worktreeBase))) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
if (isPathWithinDir(resolved, resolve(repoRoot, LABS_RELATIVE_PATH)) || isCanonicalLabWorktreePath(resolved)) {
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
return isPathWithinDir(resolved, resolve(repoRoot, ".poetic/tmp"));
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Parse git worktree metadata for both branch-backed and detached worktrees.
|
|
249
|
+
*/
|
|
250
|
+
async discoverGitWorktreeEntries(repoRoot) {
|
|
251
|
+
const entries = [];
|
|
252
|
+
try {
|
|
253
|
+
const { stdout } = await execa("git", ["worktree", "list", "--porcelain"], {
|
|
254
|
+
cwd: repoRoot,
|
|
255
|
+
stdio: "pipe"
|
|
256
|
+
});
|
|
257
|
+
const lines = stdout.split("\n");
|
|
258
|
+
let current = null;
|
|
259
|
+
const flushCurrent = () => {
|
|
260
|
+
if (current) {
|
|
261
|
+
entries.push(current);
|
|
262
|
+
current = null;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
for (const line of lines) {
|
|
266
|
+
if (line.startsWith("worktree ")) {
|
|
267
|
+
flushCurrent();
|
|
268
|
+
current = {
|
|
269
|
+
path: resolve(repoRoot, line.substring("worktree ".length).trim()),
|
|
270
|
+
detached: false
|
|
271
|
+
};
|
|
272
|
+
} else if (line.startsWith("branch ") && current) {
|
|
273
|
+
const branchRef = line.substring("branch ".length).trim();
|
|
274
|
+
current.branchName = branchRef.replace(/^refs\/heads\//, "");
|
|
275
|
+
} else if (line === "detached" && current) {
|
|
276
|
+
current.detached = true;
|
|
277
|
+
} else if (line.trim() === "") {
|
|
278
|
+
flushCurrent();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
flushCurrent();
|
|
282
|
+
} catch (error) {
|
|
283
|
+
this.logDebug("Failed to list git worktrees", error);
|
|
284
|
+
}
|
|
285
|
+
return entries;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Build a map of all known worktree candidates
|
|
289
|
+
*/
|
|
290
|
+
async gatherWorktreeCandidates(includeBrokenMetadata) {
|
|
291
|
+
const repoRoot = findProjectRoot(process.cwd()) ?? process.cwd();
|
|
292
|
+
const candidateMap = /* @__PURE__ */ new Map();
|
|
293
|
+
const labPaths = /* @__PURE__ */ new Set();
|
|
294
|
+
await this.populateCandidatesFromDir(
|
|
295
|
+
this.getWorktreeBase(),
|
|
296
|
+
"standard",
|
|
297
|
+
candidateMap,
|
|
298
|
+
labPaths
|
|
299
|
+
);
|
|
300
|
+
await this.discoverLegacyRepoLocalWorktrees(repoRoot, candidateMap, labPaths);
|
|
301
|
+
await this.discoverLabWorktrees(repoRoot, candidateMap, labPaths);
|
|
302
|
+
if (includeBrokenMetadata) {
|
|
303
|
+
await this.discoverBrokenMetadataTmpWorktrees(repoRoot, candidateMap);
|
|
304
|
+
}
|
|
305
|
+
const inGitRepo = isInsideGitWorkTree(repoRoot);
|
|
306
|
+
const gitEntries = inGitRepo ? await this.discoverGitWorktreeEntries(repoRoot) : [];
|
|
307
|
+
const registeredWorktreePaths = new Set(
|
|
308
|
+
gitEntries.map((entry) => canonicalizePath(entry.path))
|
|
309
|
+
);
|
|
310
|
+
for (const entry of gitEntries) {
|
|
311
|
+
const existing = candidateMap.get(entry.path);
|
|
312
|
+
if (existing) {
|
|
313
|
+
existing.branchName ??= entry.branchName;
|
|
314
|
+
existing.detached = entry.detached;
|
|
315
|
+
existing.registeredGitWorktree = true;
|
|
316
|
+
existing.missingOnDisk = !existsSync(entry.path);
|
|
317
|
+
if (isCanonicalLabWorktreePath(entry.path)) {
|
|
318
|
+
existing.source = "lab";
|
|
319
|
+
labPaths.add(entry.path);
|
|
320
|
+
}
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
const source = labPaths.has(entry.path) || isCanonicalLabWorktreePath(entry.path) ? "lab" : "git";
|
|
324
|
+
candidateMap.set(entry.path, {
|
|
325
|
+
path: entry.path,
|
|
326
|
+
name: basename(entry.path),
|
|
327
|
+
branchName: entry.branchName,
|
|
328
|
+
detached: entry.detached,
|
|
329
|
+
missingOnDisk: !existsSync(entry.path),
|
|
330
|
+
source,
|
|
331
|
+
registeredGitWorktree: true
|
|
332
|
+
});
|
|
333
|
+
if (source === "lab") {
|
|
334
|
+
labPaths.add(entry.path);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
const canonicalRoot = canonicalizePath(repoRoot);
|
|
338
|
+
for (const [path, _candidate] of candidateMap) {
|
|
339
|
+
if (canonicalizePath(path) === canonicalRoot) {
|
|
340
|
+
candidateMap.delete(path);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return {
|
|
344
|
+
repoRoot,
|
|
345
|
+
candidates: Array.from(candidateMap.values()),
|
|
346
|
+
registeredWorktreePaths
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Get size of a directory recursively
|
|
351
|
+
*
|
|
352
|
+
* Applies conservative traversal limits to avoid runaway recursion on
|
|
353
|
+
* pathological directory structures or mocked filesystems in tests.
|
|
354
|
+
*
|
|
355
|
+
* @param dirPath Directory path
|
|
356
|
+
* @param maxDepth Maximum recursion depth to prevent stack overflow (default: 50)
|
|
357
|
+
* @param currentDepth Current recursion depth (internal use)
|
|
358
|
+
* @param traversal Tracker for total entries visited (internal use)
|
|
359
|
+
* @returns Size in bytes
|
|
360
|
+
* @private
|
|
361
|
+
*/
|
|
362
|
+
async getDirSize(dirPath, maxDepth = 50, currentDepth = 0, traversal = { count: 0 }) {
|
|
363
|
+
let size = 0;
|
|
364
|
+
const MAX_TRAVERSAL_ENTRIES = 5e3;
|
|
365
|
+
if (currentDepth >= maxDepth) {
|
|
366
|
+
this.logDebug(
|
|
367
|
+
`Max depth ${maxDepth} reached for ${dirPath}`,
|
|
368
|
+
new Error("Max depth exceeded")
|
|
369
|
+
);
|
|
370
|
+
return size;
|
|
371
|
+
}
|
|
372
|
+
traversal.count++;
|
|
373
|
+
if (traversal.count > MAX_TRAVERSAL_ENTRIES) {
|
|
374
|
+
this.logDebug(
|
|
375
|
+
`Traversal limit ${MAX_TRAVERSAL_ENTRIES} reached for ${dirPath}`,
|
|
376
|
+
new Error("Traversal limit exceeded")
|
|
377
|
+
);
|
|
378
|
+
return size;
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
382
|
+
for (const entry of entries) {
|
|
383
|
+
const entryPath = join(dirPath, entry.name);
|
|
384
|
+
if (entry.isDirectory()) {
|
|
385
|
+
size += await this.getDirSize(entryPath, maxDepth, currentDepth + 1, traversal);
|
|
386
|
+
} else if (entry.isFile()) {
|
|
387
|
+
const stats = await stat(entryPath);
|
|
388
|
+
size += stats.size;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
} catch (error) {
|
|
392
|
+
this.logDebug(`Failed to calculate size for ${dirPath}`, error);
|
|
393
|
+
}
|
|
394
|
+
return size;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Format age in human-readable form
|
|
398
|
+
*
|
|
399
|
+
* @param ms Age in milliseconds
|
|
400
|
+
* @returns Formatted age string
|
|
401
|
+
* @private
|
|
402
|
+
*/
|
|
403
|
+
formatAge(ms) {
|
|
404
|
+
const hours = Math.floor(ms / (60 * 60 * 1e3));
|
|
405
|
+
const days = Math.floor(hours / 24);
|
|
406
|
+
if (days > 0) {
|
|
407
|
+
return `${days}d ${hours % 24}h`;
|
|
408
|
+
}
|
|
409
|
+
return `${hours}h`;
|
|
410
|
+
}
|
|
411
|
+
hasBrokenGitdirPointer(worktreePath) {
|
|
412
|
+
const gitFilePath = join(worktreePath, ".git");
|
|
413
|
+
if (!existsSync(gitFilePath)) {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
try {
|
|
417
|
+
const gitFile = readFileSync(gitFilePath, "utf8");
|
|
418
|
+
const match = gitFile.match(/^gitdir:\s*(.+)$/m);
|
|
419
|
+
if (!match) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
const gitdirTarget = match[1]?.trim();
|
|
423
|
+
if (!gitdirTarget) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
const gitdirPath = resolve(worktreePath, gitdirTarget);
|
|
427
|
+
return !existsSync(gitdirPath);
|
|
428
|
+
} catch {
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async inspectWorktreeChangeState(worktreePath) {
|
|
433
|
+
if (this.hasBrokenGitdirPointer(worktreePath)) {
|
|
434
|
+
return "broken-gitdir";
|
|
435
|
+
}
|
|
436
|
+
try {
|
|
437
|
+
const result = await execa(
|
|
438
|
+
"git",
|
|
439
|
+
["-C", worktreePath, "status", "--porcelain=v1", "--untracked-files=all"],
|
|
440
|
+
{
|
|
441
|
+
stdio: "pipe",
|
|
442
|
+
reject: false,
|
|
443
|
+
timeout: 1e4
|
|
444
|
+
}
|
|
445
|
+
);
|
|
446
|
+
if (result?.exitCode === void 0 || result.exitCode === 0) {
|
|
447
|
+
return (result?.stdout ?? "").trim().length > 0 ? "dirty" : "clean";
|
|
448
|
+
}
|
|
449
|
+
} catch {
|
|
450
|
+
}
|
|
451
|
+
return existsSync(join(worktreePath, ".git")) ? "uninspectable" : "clean";
|
|
452
|
+
}
|
|
453
|
+
async resolveBranchHeadSha(repoRoot, branchName) {
|
|
454
|
+
try {
|
|
455
|
+
const { stdout } = await execa(
|
|
456
|
+
"git",
|
|
457
|
+
["rev-parse", "--verify", `refs/heads/${branchName}^{commit}`],
|
|
458
|
+
{
|
|
459
|
+
cwd: repoRoot,
|
|
460
|
+
stdio: "pipe"
|
|
461
|
+
}
|
|
462
|
+
);
|
|
463
|
+
return stdout.trim() || void 0;
|
|
464
|
+
} catch {
|
|
465
|
+
return void 0;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
async resolveCurrentBranchName(repoRoot) {
|
|
469
|
+
try {
|
|
470
|
+
const { stdout } = await execa("git", ["branch", "--show-current"], {
|
|
471
|
+
cwd: repoRoot,
|
|
472
|
+
stdio: "pipe"
|
|
473
|
+
});
|
|
474
|
+
return stdout.trim() || void 0;
|
|
475
|
+
} catch {
|
|
476
|
+
return void 0;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
shouldFailClosedForMissingGitMetadata(candidate) {
|
|
480
|
+
return !this.baseDir && candidate.source === "standard" && !candidate.registeredGitWorktree && !existsSync(join(candidate.path, ".git"));
|
|
481
|
+
}
|
|
482
|
+
canCleanBrokenMetadataCandidate(candidate) {
|
|
483
|
+
return candidate.source === "standard" && !candidate.registeredGitWorktree;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Clean up old worktrees
|
|
487
|
+
*
|
|
488
|
+
* Deletes worktrees older than TTL (default 1 day) to prevent disk bloat.
|
|
489
|
+
* Worktrees are temporary build artifacts and should not accumulate.
|
|
490
|
+
*
|
|
491
|
+
* @param options Optional cleanup options (dry-run, age override)
|
|
492
|
+
* @returns Cleanup report with statistics
|
|
493
|
+
*/
|
|
494
|
+
async cleanup(options) {
|
|
495
|
+
const dryRun = options?.dryRun ?? false;
|
|
496
|
+
const baseDir = this.getWorktreeBase();
|
|
497
|
+
return runWorktreeCleanupSerialized(async () => {
|
|
498
|
+
const body = () => this.cleanupSerializedBody(options);
|
|
499
|
+
if (dryRun) {
|
|
500
|
+
if (!existsSync(baseDir)) {
|
|
501
|
+
return await body();
|
|
502
|
+
}
|
|
503
|
+
const lockedResult = await tryWithCleanupLock(baseDir, body);
|
|
504
|
+
if (lockedResult !== null) {
|
|
505
|
+
return lockedResult;
|
|
506
|
+
}
|
|
507
|
+
const diagnostics = await describeCleanupLockState(baseDir);
|
|
508
|
+
const report = await body();
|
|
509
|
+
report.lockPreviewDegraded = true;
|
|
510
|
+
report.lockDiagnostics = diagnostics;
|
|
511
|
+
return report;
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
return await withCleanupLock(baseDir, body);
|
|
515
|
+
} catch (error) {
|
|
516
|
+
if (isCleanupLockContentionError(error)) {
|
|
517
|
+
const diagnostics = await describeCleanupLockState(baseDir);
|
|
518
|
+
throw Object.assign(
|
|
519
|
+
new Error(formatCleanupLockContentionMessage(diagnostics, "execute")),
|
|
520
|
+
{ code: "ELOCKED", file: diagnostics.lockPath }
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
throw error;
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
async cleanupSerializedBody(options) {
|
|
528
|
+
const maxAge = options?.maxAgeMs ?? getMaxWorktreeAge();
|
|
529
|
+
const dryRun = options?.dryRun ?? false;
|
|
530
|
+
const includeLabs = options?.includeLabs ?? false;
|
|
531
|
+
const verbose = options?.verbose ?? true;
|
|
532
|
+
const verbosePreserved = options?.verbosePreserved ?? false;
|
|
533
|
+
const pruneEvery = Math.max(1, options?.pruneEvery ?? 50);
|
|
534
|
+
const limit = Math.max(0, Math.floor(options?.limit ?? 0));
|
|
535
|
+
const estimateSize = options?.estimateSize ?? true;
|
|
536
|
+
const includeBrokenMetadata = options?.includeBrokenMetadata ?? false;
|
|
537
|
+
let registeredCleanupsSincePrune = 0;
|
|
538
|
+
if (maxAge === 0) {
|
|
539
|
+
emitWarning(
|
|
540
|
+
"CFG-006",
|
|
541
|
+
{
|
|
542
|
+
subsystem: "utils",
|
|
543
|
+
executionPhase: "cleanup"
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
severity: "WARN" /* WARN */,
|
|
547
|
+
metadata: {
|
|
548
|
+
configKey: "maxAge",
|
|
549
|
+
invalidValue: 0,
|
|
550
|
+
message: "maxAge=0 matches age-eligible worktrees, but fresh worktrees are still protected by the minimum age gate."
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
const report = {
|
|
556
|
+
deleted: 0,
|
|
557
|
+
freedBytes: 0,
|
|
558
|
+
deletedWorktrees: [],
|
|
559
|
+
dryRun,
|
|
560
|
+
deletedLabWorktrees: [],
|
|
561
|
+
skippedLabWorktrees: []
|
|
562
|
+
};
|
|
563
|
+
const recordPreserved = (candidate, reason) => {
|
|
564
|
+
report.preservedWorktrees ??= [];
|
|
565
|
+
if (report.preservedWorktrees.some(
|
|
566
|
+
(entry) => entry.path === candidate.path && entry.reason === reason
|
|
567
|
+
)) {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
report.preservedWorktrees.push({
|
|
571
|
+
name: candidate.name,
|
|
572
|
+
path: candidate.path,
|
|
573
|
+
source: candidate.source,
|
|
574
|
+
reason
|
|
575
|
+
});
|
|
576
|
+
};
|
|
577
|
+
try {
|
|
578
|
+
let { repoRoot, candidates, registeredWorktreePaths } = await this.gatherWorktreeCandidates(includeBrokenMetadata);
|
|
579
|
+
const pruneGitRegistryForRepo = async (force = false) => {
|
|
580
|
+
if (dryRun) return;
|
|
581
|
+
if (!force && registeredCleanupsSincePrune < pruneEvery) return;
|
|
582
|
+
registeredCleanupsSincePrune = 0;
|
|
583
|
+
const entriesBeforePrune = await this.discoverGitWorktreeEntries(repoRoot);
|
|
584
|
+
const missingBeforePrune = entriesBeforePrune.filter(
|
|
585
|
+
(entry) => !existsSync(entry.path)
|
|
586
|
+
).length;
|
|
587
|
+
let result = await pruneGitWorktreeEntries({
|
|
588
|
+
cwd: repoRoot,
|
|
589
|
+
expireNow: true,
|
|
590
|
+
verbose: true
|
|
591
|
+
});
|
|
592
|
+
let refreshedEntries = await this.discoverGitWorktreeEntries(repoRoot);
|
|
593
|
+
const stillMissingAfterPrune = () => refreshedEntries.some((entry) => !existsSync(entry.path));
|
|
594
|
+
for (const delayMs of [250, 750, 1500]) {
|
|
595
|
+
if (result.prunedEntries === 0 || !stillMissingAfterPrune()) {
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
await new Promise((resolve2) => setTimeout(resolve2, delayMs));
|
|
599
|
+
const retryResult = await pruneGitWorktreeEntries({
|
|
600
|
+
cwd: repoRoot,
|
|
601
|
+
expireNow: true,
|
|
602
|
+
verbose: true
|
|
603
|
+
});
|
|
604
|
+
result = {
|
|
605
|
+
stdout: `${result.stdout}
|
|
606
|
+
${retryResult.stdout}`,
|
|
607
|
+
stderr: `${result.stderr}
|
|
608
|
+
${retryResult.stderr}`,
|
|
609
|
+
prunedEntries: result.prunedEntries + retryResult.prunedEntries
|
|
610
|
+
};
|
|
611
|
+
refreshedEntries = await this.discoverGitWorktreeEntries(repoRoot);
|
|
612
|
+
}
|
|
613
|
+
const missingAfterPrune = refreshedEntries.filter(
|
|
614
|
+
(entry) => !existsSync(entry.path)
|
|
615
|
+
).length;
|
|
616
|
+
const observedPrunedEntries = missingBeforePrune > 0 ? Math.max(0, missingBeforePrune - missingAfterPrune) : result.prunedEntries;
|
|
617
|
+
report.prunedGitWorktreeEntries = (report.prunedGitWorktreeEntries ?? 0) + observedPrunedEntries;
|
|
618
|
+
registeredWorktreePaths.clear();
|
|
619
|
+
for (const entry of refreshedEntries) {
|
|
620
|
+
registeredWorktreePaths.add(canonicalizePath(entry.path));
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
if (candidates.length === 0) {
|
|
624
|
+
return report;
|
|
625
|
+
}
|
|
626
|
+
if (!dryRun) {
|
|
627
|
+
const missingCandidates = candidates.filter((candidate) => candidate.missingOnDisk);
|
|
628
|
+
if (missingCandidates.length > 0) {
|
|
629
|
+
await pruneGitRegistryForRepo(true);
|
|
630
|
+
const prunedMissingPaths = /* @__PURE__ */ new Set();
|
|
631
|
+
for (const candidate of missingCandidates) {
|
|
632
|
+
const canonicalPath = canonicalizePath(candidate.path);
|
|
633
|
+
if (!registeredWorktreePaths.has(canonicalPath)) {
|
|
634
|
+
prunedMissingPaths.add(canonicalPath);
|
|
635
|
+
report.deleted++;
|
|
636
|
+
report.deletedWorktrees.push(candidate.name);
|
|
637
|
+
report.deletedWorktreePaths ??= [];
|
|
638
|
+
report.deletedWorktreePaths.push(candidate.path);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
if (prunedMissingPaths.size > 0) {
|
|
642
|
+
candidates = candidates.filter(
|
|
643
|
+
(candidate) => !prunedMissingPaths.has(canonicalizePath(candidate.path))
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
const labResolver = LabPathResolver.getInstance();
|
|
649
|
+
const labModeActive = labResolver.isLabMode();
|
|
650
|
+
const skipLabCleanup = !includeLabs;
|
|
651
|
+
const labCandidates = candidates.filter((c) => c.source === "lab");
|
|
652
|
+
const actionableCandidatesAll = skipLabCleanup ? candidates.filter((c) => c.source !== "lab") : candidates;
|
|
653
|
+
const actionableCandidates = actionableCandidatesAll.map((candidate, index) => ({ candidate, index })).sort((a, b) => {
|
|
654
|
+
if (a.candidate.missingOnDisk !== b.candidate.missingOnDisk) {
|
|
655
|
+
return a.candidate.missingOnDisk ? -1 : 1;
|
|
656
|
+
}
|
|
657
|
+
const depthDelta = pathDepth(canonicalizePath(b.candidate.path)) - pathDepth(canonicalizePath(a.candidate.path));
|
|
658
|
+
if (depthDelta !== 0) {
|
|
659
|
+
return depthDelta;
|
|
660
|
+
}
|
|
661
|
+
return a.index - b.index;
|
|
662
|
+
}).map(({ candidate }) => candidate).slice(0, limit > 0 ? limit : void 0);
|
|
663
|
+
if (limit > 0 && actionableCandidatesAll.length > limit) {
|
|
664
|
+
logCleanupMessage(
|
|
665
|
+
`Worktree cleanup limited to first ${limit} of ${actionableCandidatesAll.length} eligible candidate(s). Re-run to continue.`
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
if (skipLabCleanup && labCandidates.length > 0) {
|
|
669
|
+
report.skippedLabWorktrees = labCandidates.map((c) => c.name);
|
|
670
|
+
for (const candidate of labCandidates) {
|
|
671
|
+
recordPreserved(candidate, "lab");
|
|
672
|
+
}
|
|
673
|
+
const message = labModeActive ? `Lab mode active - preserving ${labCandidates.length} lab worktree(s). Use '--include-labs' to override.` : `Skipped ${labCandidates.length} lab worktree(s). Use '--include-labs' to override.`;
|
|
674
|
+
if (verbose && verbosePreserved) {
|
|
675
|
+
logCleanupMessage(message);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
for (const candidate of actionableCandidates) {
|
|
679
|
+
try {
|
|
680
|
+
if (candidate.missingOnDisk) {
|
|
681
|
+
report.skippedUninspectableWorktrees ??= [];
|
|
682
|
+
report.skippedUninspectableWorktrees.push(candidate.name);
|
|
683
|
+
recordPreserved(candidate, "missing-registered-path");
|
|
684
|
+
if (dryRun && verbose) {
|
|
685
|
+
logCleanupMessage(
|
|
686
|
+
`[DRY RUN] Would preserve missing registered worktree until Git registry prune confirms removal: ${candidate.name}`
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
const stats = await stat(candidate.path);
|
|
692
|
+
const age = Date.now() - stats.mtimeMs;
|
|
693
|
+
if (age < MIN_WORKTREE_CLEANUP_AGE_MS) {
|
|
694
|
+
if (dryRun) {
|
|
695
|
+
recordPreserved(candidate, "too-recent");
|
|
696
|
+
}
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
if (age <= maxAge) {
|
|
700
|
+
if (dryRun) {
|
|
701
|
+
recordPreserved(candidate, "too-recent");
|
|
702
|
+
}
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
705
|
+
if (await isActiveRun(candidate.path)) {
|
|
706
|
+
recordPreserved(candidate, "active-run");
|
|
707
|
+
if (verbose) {
|
|
708
|
+
logCleanupMessage(`Skipping active worktree (live run): ${candidate.name}`);
|
|
709
|
+
}
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
const descriptor = candidate.source === "lab" ? `[lab] ${candidate.name}` : candidate.name;
|
|
713
|
+
const missingGitMetadata = this.shouldFailClosedForMissingGitMetadata(candidate) || includeBrokenMetadata && candidate.source === "standard" && !candidate.registeredGitWorktree && !existsSync(join(candidate.path, ".git"));
|
|
714
|
+
if (missingGitMetadata && (!includeBrokenMetadata || !this.canCleanBrokenMetadataCandidate(candidate))) {
|
|
715
|
+
report.skippedUninspectableWorktrees ??= [];
|
|
716
|
+
report.skippedUninspectableWorktrees.push(candidate.name);
|
|
717
|
+
recordPreserved(candidate, "uninspectable");
|
|
718
|
+
if (verbose) {
|
|
719
|
+
logCleanupMessage(`Skipping uninspectable worktree: ${descriptor}`);
|
|
720
|
+
}
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
const changeState = missingGitMetadata ? "broken-gitdir" : await this.inspectWorktreeChangeState(candidate.path);
|
|
724
|
+
if (changeState === "dirty") {
|
|
725
|
+
report.skippedDirtyWorktrees ??= [];
|
|
726
|
+
report.skippedDirtyWorktrees.push(candidate.name);
|
|
727
|
+
recordPreserved(candidate, "dirty");
|
|
728
|
+
if (verbose && verbosePreserved) {
|
|
729
|
+
logCleanupMessage(`Skipping dirty worktree: ${descriptor}`);
|
|
730
|
+
}
|
|
731
|
+
continue;
|
|
732
|
+
}
|
|
733
|
+
if (changeState === "broken-gitdir" && (!includeBrokenMetadata || !this.canCleanBrokenMetadataCandidate(candidate))) {
|
|
734
|
+
report.skippedUninspectableWorktrees ??= [];
|
|
735
|
+
report.skippedUninspectableWorktrees.push(candidate.name);
|
|
736
|
+
recordPreserved(candidate, "uninspectable");
|
|
737
|
+
if (verbose) {
|
|
738
|
+
logCleanupMessage(`Skipping uninspectable worktree: ${descriptor}`);
|
|
739
|
+
}
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
if (changeState === "uninspectable") {
|
|
743
|
+
report.skippedUninspectableWorktrees ??= [];
|
|
744
|
+
report.skippedUninspectableWorktrees.push(candidate.name);
|
|
745
|
+
recordPreserved(candidate, "uninspectable");
|
|
746
|
+
if (verbose) {
|
|
747
|
+
logCleanupMessage(`Skipping uninspectable worktree: ${descriptor}`);
|
|
748
|
+
}
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
if (candidate.source === "git" && !this.isUnderPoeticManagedCleanupRoot(candidate.path, repoRoot, this.getWorktreeBase())) {
|
|
752
|
+
recordPreserved(candidate, "external-git-worktree");
|
|
753
|
+
if (verbose && verbosePreserved) {
|
|
754
|
+
logCleanupMessage(`Preserving external git worktree: ${descriptor}`);
|
|
755
|
+
}
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
if (candidate.branchName && (isProtectedPipelineBranch(candidate.branchName) || candidate.branchName === await this.resolveCurrentBranchName(repoRoot))) {
|
|
759
|
+
recordPreserved(candidate, "branch-attached-protected-current");
|
|
760
|
+
if (verbose) {
|
|
761
|
+
logCleanupMessage(
|
|
762
|
+
`Preserving protected/current branch-attached worktree: ${descriptor}`
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
767
|
+
if ([...registeredWorktreePaths].some(
|
|
768
|
+
(registeredPath) => isNestedPath(candidate.path, registeredPath) && existsSync(registeredPath)
|
|
769
|
+
)) {
|
|
770
|
+
report.skippedUninspectableWorktrees ??= [];
|
|
771
|
+
report.skippedUninspectableWorktrees.push(candidate.name);
|
|
772
|
+
recordPreserved(candidate, "nested-child");
|
|
773
|
+
if (verbose) {
|
|
774
|
+
logCleanupMessage(
|
|
775
|
+
`Skipping parent worktree with registered nested child: ${descriptor}`
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
const size = estimateSize ? await this.getDirSize(candidate.path) : 0;
|
|
781
|
+
if (dryRun) {
|
|
782
|
+
if (verbose) {
|
|
783
|
+
const sizeLabel = estimateSize ? `, ${formatBytes(size)}` : "";
|
|
784
|
+
const metadataLabel = changeState === "broken-gitdir" ? ", broken Git metadata" : "";
|
|
785
|
+
logCleanupMessage(
|
|
786
|
+
`[DRY RUN] Would clean up old worktree: ${descriptor} (${this.formatAge(age)} old${sizeLabel}${metadataLabel})`
|
|
787
|
+
);
|
|
788
|
+
}
|
|
789
|
+
report.deleted++;
|
|
790
|
+
report.freedBytes += size;
|
|
791
|
+
report.deletedWorktrees.push(candidate.name);
|
|
792
|
+
report.deletedWorktreePaths ??= [];
|
|
793
|
+
report.deletedWorktreePaths.push(candidate.path);
|
|
794
|
+
if (changeState === "broken-gitdir") {
|
|
795
|
+
report.deletedBrokenMetadataWorktrees ??= [];
|
|
796
|
+
report.deletedBrokenMetadataWorktrees.push(candidate.name);
|
|
797
|
+
}
|
|
798
|
+
if (candidate.source === "lab") {
|
|
799
|
+
report.deletedLabWorktrees.push(candidate.name);
|
|
800
|
+
}
|
|
801
|
+
continue;
|
|
802
|
+
}
|
|
803
|
+
if (verbose) {
|
|
804
|
+
logCleanupMessage(
|
|
805
|
+
`Cleaning up old worktree: ${descriptor} (${this.formatAge(age)} old, ${formatBytes(size)})`
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
let removed = false;
|
|
809
|
+
const canFastRemoveRegisteredWorktree = candidate.registeredGitWorktree && candidate.detached && !candidate.branchName;
|
|
810
|
+
if (candidate.registeredGitWorktree && !canFastRemoveRegisteredWorktree) {
|
|
811
|
+
const removal = await execa("git", ["worktree", "remove", candidate.path, "--force"], {
|
|
812
|
+
cwd: repoRoot,
|
|
813
|
+
stdio: "pipe",
|
|
814
|
+
reject: false
|
|
815
|
+
});
|
|
816
|
+
removed = removal.exitCode === 0;
|
|
817
|
+
registeredCleanupsSincePrune++;
|
|
818
|
+
await pruneGitRegistryForRepo();
|
|
819
|
+
}
|
|
820
|
+
if (!removed) {
|
|
821
|
+
const rmResult = await safeRmDir(candidate.path, {
|
|
822
|
+
protectedPaths: [repoRoot],
|
|
823
|
+
managedRoots: [
|
|
824
|
+
this.getWorktreeBase(),
|
|
825
|
+
resolve(repoRoot, ".poetic/tmp"),
|
|
826
|
+
resolve(repoRoot, LABS_RELATIVE_PATH)
|
|
827
|
+
],
|
|
828
|
+
dryRun
|
|
829
|
+
});
|
|
830
|
+
if (!rmResult.deleted) {
|
|
831
|
+
this.logDebug(`SAFETY: ${rmResult.reason}`, new Error("safeRmDir refused"));
|
|
832
|
+
continue;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (!existsSync(candidate.path)) {
|
|
836
|
+
report.deleted++;
|
|
837
|
+
report.freedBytes += size;
|
|
838
|
+
report.deletedWorktrees.push(candidate.name);
|
|
839
|
+
report.deletedWorktreePaths ??= [];
|
|
840
|
+
report.deletedWorktreePaths.push(candidate.path);
|
|
841
|
+
if (changeState === "broken-gitdir") {
|
|
842
|
+
report.deletedBrokenMetadataWorktrees ??= [];
|
|
843
|
+
report.deletedBrokenMetadataWorktrees.push(candidate.name);
|
|
844
|
+
}
|
|
845
|
+
if (candidate.source === "lab") {
|
|
846
|
+
report.deletedLabWorktrees.push(candidate.name);
|
|
847
|
+
}
|
|
848
|
+
if (candidate.branchName) {
|
|
849
|
+
try {
|
|
850
|
+
await enqueueBranchCleanup(candidate.branchName, {
|
|
851
|
+
reason: "worktree-cleanup",
|
|
852
|
+
queuePath: getBranchCleanupQueuePath(repoRoot),
|
|
853
|
+
expectedHeadSha: await this.resolveBranchHeadSha(repoRoot, candidate.branchName)
|
|
854
|
+
});
|
|
855
|
+
} catch (error) {
|
|
856
|
+
this.logDebug(
|
|
857
|
+
`Failed to queue branch cleanup for ${candidate.branchName}`,
|
|
858
|
+
error ?? "unknown error"
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
} catch (error) {
|
|
864
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
865
|
+
if (/ENOENT: no such file or directory, stat /.test(message)) {
|
|
866
|
+
this.logDebug(
|
|
867
|
+
`Skipping disappearing worktree candidate during cleanup: ${candidate.name}`,
|
|
868
|
+
error
|
|
869
|
+
);
|
|
870
|
+
continue;
|
|
871
|
+
}
|
|
872
|
+
emitWarning(
|
|
873
|
+
"WS-003",
|
|
874
|
+
{
|
|
875
|
+
subsystem: "utils",
|
|
876
|
+
executionPhase: "cleanup"
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
severity: "WARN" /* WARN */,
|
|
880
|
+
metadata: {
|
|
881
|
+
worktreeName: candidate.name,
|
|
882
|
+
error: message,
|
|
883
|
+
operation: "cleanupWorktree"
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
if (!dryRun && report.deleted > 0) {
|
|
890
|
+
await pruneGitRegistryForRepo(true);
|
|
891
|
+
}
|
|
892
|
+
if (report.deleted > 0) {
|
|
893
|
+
const prefix = dryRun ? "[DRY RUN] Would clean" : "Cleaned";
|
|
894
|
+
const sizeLabel = estimateSize ? `${dryRun ? "would free" : "freed"} ${formatBytes(report.freedBytes)}` : "size not estimated";
|
|
895
|
+
logCleanupMessage(`${prefix} ${report.deleted} worktree(s), ${sizeLabel}
|
|
896
|
+
`);
|
|
897
|
+
}
|
|
898
|
+
if (verbose && verbosePreserved && report.skippedDirtyWorktrees && report.skippedDirtyWorktrees.length > 0) {
|
|
899
|
+
logCleanupMessage(
|
|
900
|
+
`Skipped ${report.skippedDirtyWorktrees.length} dirty worktree(s) with local changes.`
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
if (!dryRun && report.deletedBrokenMetadataWorktrees && report.deletedBrokenMetadataWorktrees.length > 0) {
|
|
904
|
+
logCleanupMessage(
|
|
905
|
+
`Cleaned ${report.deletedBrokenMetadataWorktrees.length} worktree(s) with broken Git metadata after explicit opt-in.`
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
if (!dryRun && (report.prunedGitWorktreeEntries ?? 0) > 0) {
|
|
909
|
+
logCleanupMessage(`Pruned ${report.prunedGitWorktreeEntries} stale Git worktree entries.`);
|
|
910
|
+
}
|
|
911
|
+
if (report.skippedUninspectableWorktrees && report.skippedUninspectableWorktrees.length > 0) {
|
|
912
|
+
logCleanupMessage(
|
|
913
|
+
`Skipped ${report.skippedUninspectableWorktrees.length} uninspectable worktree(s) with broken or unreadable Git metadata.`
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
} catch (error) {
|
|
917
|
+
console.error("Worktree cleanup failed:", error);
|
|
918
|
+
}
|
|
919
|
+
return report;
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* Format bytes for human-readable output
|
|
923
|
+
*
|
|
924
|
+
* @param bytes Size in bytes
|
|
925
|
+
* @returns Formatted size string
|
|
926
|
+
* @private
|
|
927
|
+
*/
|
|
928
|
+
logDebug(message, error) {
|
|
929
|
+
if (!readEnv(POETIC_DEBUG).value) return;
|
|
930
|
+
const errMessage = error instanceof Error ? error.message : String(error);
|
|
931
|
+
console.debug(`[worktree-cleanup] ${message}: ${errMessage}`);
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
function isInsideGitWorkTree(cwd) {
|
|
935
|
+
try {
|
|
936
|
+
const opts = {
|
|
937
|
+
cwd,
|
|
938
|
+
timeout: 3e3,
|
|
939
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
940
|
+
};
|
|
941
|
+
const out = execFileSync("git", ["rev-parse", "--is-inside-work-tree"], opts).toString().trim();
|
|
942
|
+
return out === "true";
|
|
943
|
+
} catch {
|
|
944
|
+
return false;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
function runWorktreeCleanup() {
|
|
948
|
+
setImmediate(async () => {
|
|
949
|
+
try {
|
|
950
|
+
const manager = new WorktreeCleanupManager();
|
|
951
|
+
await manager.cleanup();
|
|
952
|
+
} catch (error) {
|
|
953
|
+
if (isCleanupLockContentionError(error)) {
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
console.error("Worktree cleanup failed:", error);
|
|
957
|
+
}
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
export {
|
|
962
|
+
getMaxWorktreeAge,
|
|
963
|
+
WorktreeCleanupManager,
|
|
964
|
+
runWorktreeCleanup
|
|
965
|
+
};
|
|
966
|
+
//# sourceMappingURL=chunk-DF5SLDE4.js.map
|