@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,777 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Poetic guardrail kit gate (kit version {{KIT_VERSION}}).
|
|
4
|
+
*
|
|
5
|
+
* Self-contained, vendored gate script. Zero npm dependencies: only node:
|
|
6
|
+
* builtins are imported. Requires Node >= 24 (ESM, modern fs). Runs at gate
|
|
7
|
+
* time with no Poetic, no npm, and no network.
|
|
8
|
+
*
|
|
9
|
+
* Runs four check families over the diff between a base ref and HEAD:
|
|
10
|
+
* 1. baseline-anti-inflation: ratchet baseline JSONs under baselines/ may
|
|
11
|
+
* only shrink. Any per-key count increase, new key, or a surviving count
|
|
12
|
+
* retyped away from number fails. A baseline file that is new at the base
|
|
13
|
+
* ref is skipped (introducing a ratchet is a gate-critical human merge).
|
|
14
|
+
* 2. secret-scan: added diff lines matched against provider key formats plus
|
|
15
|
+
* config.json extraSecretPatterns.
|
|
16
|
+
* 3. artifact-paths: changed paths matched against generated deny defaults
|
|
17
|
+
* plus config.json extraDenyPaths / extraArtifactPatterns.
|
|
18
|
+
* 4. guard-integrity: any changed path under this guard directory (check.mjs,
|
|
19
|
+
* config.json, baselines) is a gate-critical finding. Matching is
|
|
20
|
+
* case-INSENSITIVE (a case-variant path like .poetic/Guard/x collides with
|
|
21
|
+
* the guard dir on case-insensitive filesystems). EXEMPTION: a plain
|
|
22
|
+
* 'M' modification of a baselines/*.json file that is a pure shrink/removal
|
|
23
|
+
* (verified via merge-base vs HEAD with the built-in count comparison, and
|
|
24
|
+
* only while baseline-anti-inflation is on) is NOT a guard-integrity
|
|
25
|
+
* finding and does NOT untrust branch config — routine ratchet-downs merge
|
|
26
|
+
* without a human. Deletions, renames, new keys, inflation, retypes, and
|
|
27
|
+
* unparseable baselines are never exempt.
|
|
28
|
+
*
|
|
29
|
+
* Exit codes:
|
|
30
|
+
* 0 clean.
|
|
31
|
+
* 1 hard failure (baseline inflation, secret, artifact path). Blocks merge.
|
|
32
|
+
* 2 only guard-integrity findings (gate machinery changed) with no hard
|
|
33
|
+
* failure. Softer than 1: merge automation treats this as
|
|
34
|
+
* require-human-merge rather than block. A hard finding always dominates,
|
|
35
|
+
* so exit 1 wins when both are present.
|
|
36
|
+
*
|
|
37
|
+
* Config (this-dir config.json, all keys optional): baseRef, extraDenyPaths,
|
|
38
|
+
* extraSecretPatterns, extraArtifactPatterns. Config tunes policy VALUES only;
|
|
39
|
+
* it cannot enable or disable a check. Check on/off lives in the generated
|
|
40
|
+
* manifest below and is not consumer-editable.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import { execFileSync } from 'node:child_process';
|
|
44
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync } from 'node:fs';
|
|
45
|
+
import { basename, dirname, join, relative } from 'node:path';
|
|
46
|
+
import { fileURLToPath } from 'node:url';
|
|
47
|
+
|
|
48
|
+
const MANIFEST = {{GENERATED_MANIFEST}};
|
|
49
|
+
|
|
50
|
+
// Fail CLOSED on a malformed manifest. Every check family gates on
|
|
51
|
+
// MANIFEST.checks.<key>; if the renderer and this template ever disagree on
|
|
52
|
+
// the manifest shape, a missing key must abort the run — never silently skip
|
|
53
|
+
// a check (a skipped check reads as a pass to merge automation).
|
|
54
|
+
const REQUIRED_CHECK_KEYS = [
|
|
55
|
+
'baselineAntiInflation',
|
|
56
|
+
'secretScan',
|
|
57
|
+
'artifactPaths',
|
|
58
|
+
'guardIntegrity',
|
|
59
|
+
];
|
|
60
|
+
for (const key of REQUIRED_CHECK_KEYS) {
|
|
61
|
+
if (typeof MANIFEST?.checks?.[key] !== 'boolean') {
|
|
62
|
+
process.stderr.write(
|
|
63
|
+
`Error: guard manifest is malformed (checks.${key} missing). ` +
|
|
64
|
+
'The generated gate is unusable; re-run: poetic init --guardrails --reinstall-guard\n'
|
|
65
|
+
);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!Array.isArray(MANIFEST.defaultDenyPaths)) {
|
|
70
|
+
process.stderr.write(
|
|
71
|
+
'Error: guard manifest is malformed (defaultDenyPaths missing). ' +
|
|
72
|
+
'Re-run: poetic init --guardrails --reinstall-guard\n'
|
|
73
|
+
);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// The guard directory is normally where this script lives. POETIC_GUARD_DIR
|
|
78
|
+
// overrides it for the trusted-base invocation pattern: CI extracts the BASE
|
|
79
|
+
// branch's copy of check.mjs to a temp path and runs that copy against the
|
|
80
|
+
// PR checkout (a PR-owned script could otherwise strip its own
|
|
81
|
+
// guard-integrity check before it runs). See the generated CI guidance.
|
|
82
|
+
/**
|
|
83
|
+
* Resolve symlinks so path comparisons against git output are stable (macOS:
|
|
84
|
+
* /var/... vs /private/var/...). Tolerates a missing path by realpathing the
|
|
85
|
+
* nearest existing ancestor and re-appending the missing tail — needed when a
|
|
86
|
+
* PR deletes the guard dir and POETIC_GUARD_DIR points at the gap.
|
|
87
|
+
*/
|
|
88
|
+
function realpathBestEffort(target) {
|
|
89
|
+
let head = target;
|
|
90
|
+
let tail = '';
|
|
91
|
+
for (;;) {
|
|
92
|
+
try {
|
|
93
|
+
const real = realpathSync(head);
|
|
94
|
+
return tail ? join(real, tail) : real;
|
|
95
|
+
} catch {
|
|
96
|
+
const parent = dirname(head);
|
|
97
|
+
if (parent === head) return target;
|
|
98
|
+
tail = tail ? join(basename(head), tail) : basename(head);
|
|
99
|
+
head = parent;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const SCRIPT_DIR = realpathBestEffort(
|
|
105
|
+
process.env.POETIC_GUARD_DIR
|
|
106
|
+
? process.env.POETIC_GUARD_DIR
|
|
107
|
+
: dirname(fileURLToPath(import.meta.url))
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Baked-in provider key formats. Fixture/test values must not match these.
|
|
111
|
+
const SECRET_PATTERNS = [
|
|
112
|
+
{ rule: 'openai-key', source: 'sk-[a-zA-Z0-9]{48}' },
|
|
113
|
+
{ rule: 'openai-project-key', source: 'sk-proj-[A-Za-z0-9_-]{20,}' },
|
|
114
|
+
{ rule: 'openai-service-account-key', source: 'sk-svcacct-[a-zA-Z0-9_-]{20,}' },
|
|
115
|
+
{ rule: 'openai-admin-key', source: 'sk-admin-[a-zA-Z0-9_-]{20,}' },
|
|
116
|
+
{ rule: 'anthropic-key', source: 'sk-ant-[a-zA-Z0-9_-]{20,}' },
|
|
117
|
+
{ rule: 'openrouter-key', source: 'sk-or-v1-[a-zA-Z0-9]{20,}' },
|
|
118
|
+
{ rule: 'xai-key', source: 'xai-[a-zA-Z0-9]{20,}' },
|
|
119
|
+
{ rule: 'google-key', source: 'AIzaSy[a-zA-Z0-9_-]{20,}' },
|
|
120
|
+
{ rule: 'slack-token', source: 'xox[baprs]-[a-zA-Z0-9-]{10,}' },
|
|
121
|
+
{ rule: 'github-token', source: 'gh[pousr]_[a-zA-Z0-9]{36,}' },
|
|
122
|
+
{ rule: 'github-pat', source: 'github_pat_[a-zA-Z0-9_]{22,}' },
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
/** Normalize any git path to forward slashes before matching. */
|
|
126
|
+
function normalizePath(value) {
|
|
127
|
+
return value.replace(/\\/g, '/');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Case-insensitive prefix test for the guard NAMESPACE. Guard-integrity must
|
|
132
|
+
* catch case-variant paths (.poetic/Guard/x, .Poetic/guard/y): on a
|
|
133
|
+
* case-sensitive CI runner those are distinct paths, but when the merged
|
|
134
|
+
* branch is later checked out on a case-insensitive filesystem (macOS,
|
|
135
|
+
* Windows) they materialize INSIDE the real guard directory. Detection is
|
|
136
|
+
* deliberately broader than the exact tracked case; the shrink-only baseline
|
|
137
|
+
* exemption stays case-EXACT (fail closed: a case-variant baseline path is a
|
|
138
|
+
* guard finding, never an exemption).
|
|
139
|
+
*/
|
|
140
|
+
function isUnderGuardNamespace(filePath, guardDirPrefix) {
|
|
141
|
+
return filePath.toLowerCase().startsWith(guardDirPrefix.toLowerCase());
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Escape a baseline object key (or array item) for use in a flattened path.
|
|
146
|
+
* The separators '.' and '|' plus the escape character itself are escaped so
|
|
147
|
+
* distinct JSON structures can never flatten to colliding paths — without
|
|
148
|
+
* this, base {"a.b": 5} vs head {"a": {"b": 2}, "a.b": 9} would collide and
|
|
149
|
+
* the decoy could mask a count increase (baseline keys are commonly file
|
|
150
|
+
* paths, which contain dots).
|
|
151
|
+
*/
|
|
152
|
+
function escapeBaselineKey(key) {
|
|
153
|
+
return key.replace(/[\\.|]/g, (ch) => `\\${ch}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Flattened paths are rooted at '$' so the root value itself has a path
|
|
157
|
+
// distinct from every child (an empty-string key yields '$.', not '$').
|
|
158
|
+
const BASELINE_ROOT_PATH = '$';
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Flattens a baseline JSON value into countable entries.
|
|
162
|
+
* - number leaf -> { "<path>": n }
|
|
163
|
+
* - string array leaf -> { "<path>|<item>": 1 } (identity sets)
|
|
164
|
+
* - other scalars are ignored (generatedAt, regex sources, scan roots).
|
|
165
|
+
*/
|
|
166
|
+
function flattenBaselineCounts(value, path = BASELINE_ROOT_PATH, out = {}) {
|
|
167
|
+
if (typeof value === 'number') {
|
|
168
|
+
out[path] = value;
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
if (Array.isArray(value)) {
|
|
172
|
+
for (const item of value) {
|
|
173
|
+
if (typeof item === 'string') {
|
|
174
|
+
out[`${path}|${escapeBaselineKey(item)}`] = 1;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
if (value && typeof value === 'object') {
|
|
180
|
+
for (const [key, child] of Object.entries(value)) {
|
|
181
|
+
flattenBaselineCounts(child, `${path}.${escapeBaselineKey(key)}`, out);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Records the JSON type of every path (leaves AND containers). Combined with
|
|
189
|
+
* the generalized type comparison in compareBaselineCounts, this makes any
|
|
190
|
+
* base-vs-head type change at a surviving path a violation, so a count cannot
|
|
191
|
+
* be silently retyped away — not to a scalar (5 -> "999"), not to a container
|
|
192
|
+
* (5 -> {} or {note:"x"}, which flattens to no counts and would otherwise
|
|
193
|
+
* read as a clean removal), and not via container swaps (["x"] -> {note:"x"},
|
|
194
|
+
* or replacing the whole file's object with an array/scalar).
|
|
195
|
+
*/
|
|
196
|
+
function collectLeafTypes(value, path = BASELINE_ROOT_PATH, out = {}) {
|
|
197
|
+
if (value === null || typeof value !== 'object') {
|
|
198
|
+
// typeof null is 'object'; record it distinctly so null cannot alias an
|
|
199
|
+
// object container in the type comparison.
|
|
200
|
+
out[path] = value === null ? 'null' : typeof value;
|
|
201
|
+
return out;
|
|
202
|
+
}
|
|
203
|
+
if (Array.isArray(value)) {
|
|
204
|
+
out[path] = 'array';
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
207
|
+
out[path] = 'object';
|
|
208
|
+
for (const [key, child] of Object.entries(value)) {
|
|
209
|
+
collectLeafTypes(child, `${path}.${escapeBaselineKey(key)}`, out);
|
|
210
|
+
}
|
|
211
|
+
return out;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Returns violation objects (rule/message/fix) for a single baseline file. */
|
|
215
|
+
function compareBaselineCounts(baseCounts, headCounts, baseTypes, headTypes) {
|
|
216
|
+
const violations = [];
|
|
217
|
+
for (const [key, headValue] of Object.entries(headCounts)) {
|
|
218
|
+
const baseValue = baseCounts[key];
|
|
219
|
+
if (baseValue === undefined) {
|
|
220
|
+
violations.push({
|
|
221
|
+
rule: 'new-baseline-key',
|
|
222
|
+
message: `new baseline key: ${key} (${headValue})`,
|
|
223
|
+
fix: 'Remove the new baseline key, or land it as a gate-critical human merge.',
|
|
224
|
+
});
|
|
225
|
+
} else if (headValue > baseValue) {
|
|
226
|
+
violations.push({
|
|
227
|
+
rule: 'count-increase',
|
|
228
|
+
message: `baseline count increased: ${key} (${baseValue} -> ${headValue})`,
|
|
229
|
+
fix: 'Reduce the count to at most the base value; baselines only shrink.',
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Generalized retype rule: any path present at BOTH base and head whose JSON
|
|
234
|
+
// type changed is a violation. Removals (head type undefined) stay legal —
|
|
235
|
+
// that is the shrink direction. This closes container swaps that carry no
|
|
236
|
+
// counts on either side (array -> object, object -> scalar, root retypes).
|
|
237
|
+
for (const [key, baseType] of Object.entries(baseTypes)) {
|
|
238
|
+
const headType = headTypes[key];
|
|
239
|
+
if (headType !== undefined && headType !== baseType) {
|
|
240
|
+
violations.push({
|
|
241
|
+
rule: 'count-retype',
|
|
242
|
+
message: `baseline value retyped (must keep its type): ${key} (${baseType} -> ${headType})`,
|
|
243
|
+
fix: 'Keep baseline value types stable; land schema changes as a gate-critical human merge.',
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return violations;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Shrink-only baseline exemption for guard-integrity.
|
|
252
|
+
*
|
|
253
|
+
* Security-critical: this decides whether a changed guard-dir file skips the
|
|
254
|
+
* guard-integrity finding AND keeps branch config trusted. It runs inside the
|
|
255
|
+
* FIRST check block, before any consumer-config regex compiles, so it must use
|
|
256
|
+
* ONLY git show + JSON.parse + the built-in count helpers — it must never
|
|
257
|
+
* compile or evaluate anything derived from config.json (a branch could plant a
|
|
258
|
+
* ReDoS payload there).
|
|
259
|
+
*
|
|
260
|
+
* A file qualifies ONLY if ALL hold:
|
|
261
|
+
* (a) it is under baselinesDir and ends with .json;
|
|
262
|
+
* (b) its git status is a plain 'M' (parseNameStatusZ marks rename sources as
|
|
263
|
+
* 'D' and destinations as R/C — neither is 'M', so renames never qualify;
|
|
264
|
+
* deletions are 'D', also never eligible);
|
|
265
|
+
* (c) MANIFEST.checks.baselineAntiInflation is true (no validator otherwise);
|
|
266
|
+
* (d) both merge-base and HEAD content parse as JSON;
|
|
267
|
+
* (e) compareBaselineCounts over the flattened counts returns ZERO violations
|
|
268
|
+
* (pure shrink/removal — no new key, no count increase, no retype).
|
|
269
|
+
* Any failure => not exempt (falls through to the normal guard-integrity path).
|
|
270
|
+
*/
|
|
271
|
+
function isShrinkOnlyBaselineChange(entry, mergeBase, baselinesDir) {
|
|
272
|
+
if (entry.status !== 'M') return false;
|
|
273
|
+
if (!(entry.path.startsWith(baselinesDir) && entry.path.endsWith('.json'))) return false;
|
|
274
|
+
if (!MANIFEST.checks.baselineAntiInflation) return false;
|
|
275
|
+
const baseContent = git(['show', `${mergeBase}:${entry.path}`], { allowFailure: true });
|
|
276
|
+
const headContent = git(['show', `HEAD:${entry.path}`], { allowFailure: true });
|
|
277
|
+
if (baseContent === null || headContent === null) return false;
|
|
278
|
+
let baseJson;
|
|
279
|
+
let headJson;
|
|
280
|
+
try {
|
|
281
|
+
baseJson = JSON.parse(baseContent);
|
|
282
|
+
headJson = JSON.parse(headContent);
|
|
283
|
+
} catch {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
const violations = compareBaselineCounts(
|
|
287
|
+
flattenBaselineCounts(baseJson),
|
|
288
|
+
flattenBaselineCounts(headJson),
|
|
289
|
+
collectLeafTypes(baseJson),
|
|
290
|
+
collectLeafTypes(headJson)
|
|
291
|
+
);
|
|
292
|
+
return violations.length === 0;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Git cwd: prefer the guard dir when it exists (normal case), else fall back
|
|
296
|
+
// to the process cwd. The fallback matters for the trusted-base pattern when
|
|
297
|
+
// a PR DELETES the entire guard directory: POETIC_GUARD_DIR then points at a
|
|
298
|
+
// missing path, and spawning git from it would crash with a generic error
|
|
299
|
+
// instead of reaching the guard-integrity verdict (exit 2).
|
|
300
|
+
const GIT_CWD = existsSync(SCRIPT_DIR) ? SCRIPT_DIR : process.cwd();
|
|
301
|
+
|
|
302
|
+
function git(args, options = {}) {
|
|
303
|
+
try {
|
|
304
|
+
return execFileSync('git', args, {
|
|
305
|
+
cwd: GIT_CWD,
|
|
306
|
+
encoding: 'utf8',
|
|
307
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
308
|
+
});
|
|
309
|
+
} catch (error) {
|
|
310
|
+
if (options.allowFailure) {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
throw error;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function isCI() {
|
|
318
|
+
const value = process.env.CI;
|
|
319
|
+
return Boolean(value) && value !== '0' && value.toLowerCase() !== 'false';
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function loadConfig() {
|
|
323
|
+
const configPath = join(SCRIPT_DIR, 'config.json');
|
|
324
|
+
if (!existsSync(configPath)) {
|
|
325
|
+
return {};
|
|
326
|
+
}
|
|
327
|
+
let raw;
|
|
328
|
+
try {
|
|
329
|
+
raw = readFileSync(configPath, 'utf8');
|
|
330
|
+
} catch (error) {
|
|
331
|
+
throw new Error(`cannot read config.json at ${configPath}: ${error.message}`);
|
|
332
|
+
}
|
|
333
|
+
try {
|
|
334
|
+
return JSON.parse(raw);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
throw new Error(`unparseable config.json at ${configPath}: ${error.message}`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function parseArgs(argv) {
|
|
341
|
+
const parsed = {
|
|
342
|
+
formatJson: false,
|
|
343
|
+
updateBaseline: false,
|
|
344
|
+
listChecks: false,
|
|
345
|
+
base: null,
|
|
346
|
+
};
|
|
347
|
+
for (let i = 0; i < argv.length; i++) {
|
|
348
|
+
const arg = argv[i];
|
|
349
|
+
if (arg === '--format') {
|
|
350
|
+
parsed.formatJson = argv[++i] === 'json';
|
|
351
|
+
} else if (arg === '--format=json') {
|
|
352
|
+
parsed.formatJson = true;
|
|
353
|
+
} else if (arg === '--update-baseline') {
|
|
354
|
+
parsed.updateBaseline = true;
|
|
355
|
+
} else if (arg === '--list-checks') {
|
|
356
|
+
parsed.listChecks = true;
|
|
357
|
+
} else if (arg === '--base') {
|
|
358
|
+
parsed.base = argv[++i] ?? null;
|
|
359
|
+
} else if (arg.startsWith('--base=')) {
|
|
360
|
+
parsed.base = arg.slice('--base='.length);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return parsed;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function resolveBaseRef(config, cliBase) {
|
|
367
|
+
if (cliBase) {
|
|
368
|
+
return cliBase;
|
|
369
|
+
}
|
|
370
|
+
if (process.env.POETIC_GUARD_BASE_REF) {
|
|
371
|
+
return process.env.POETIC_GUARD_BASE_REF;
|
|
372
|
+
}
|
|
373
|
+
const githubBase = (process.env.GITHUB_BASE_REF ?? '').trim();
|
|
374
|
+
if (githubBase) {
|
|
375
|
+
return `origin/${githubBase}`;
|
|
376
|
+
}
|
|
377
|
+
// config.json is BRANCH-OWNED, so it must never choose the base in CI: a
|
|
378
|
+
// PR could set baseRef to HEAD, empty the diff, and disable every check.
|
|
379
|
+
// Locally it is a convenience only (local runs are feedback, CI is the
|
|
380
|
+
// enforcement point). In CI the base comes from env/flags/origin/HEAD or
|
|
381
|
+
// the run fails closed.
|
|
382
|
+
if (config.baseRef && !isCI()) {
|
|
383
|
+
return config.baseRef;
|
|
384
|
+
}
|
|
385
|
+
const originHead = git(['symbolic-ref', '--quiet', 'refs/remotes/origin/HEAD'], {
|
|
386
|
+
allowFailure: true,
|
|
387
|
+
});
|
|
388
|
+
if (originHead) {
|
|
389
|
+
return originHead.trim().replace(/^refs\/remotes\//, '');
|
|
390
|
+
}
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/** Parse `git diff --name-status -z` into a de-duplicated changed-path list. */
|
|
395
|
+
function parseNameStatusZ(raw) {
|
|
396
|
+
const tokens = raw.split('\0');
|
|
397
|
+
const entries = new Map();
|
|
398
|
+
const add = (path, status) => {
|
|
399
|
+
if (path && !entries.has(normalizePath(path))) {
|
|
400
|
+
entries.set(normalizePath(path), status);
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
let i = 0;
|
|
404
|
+
while (i < tokens.length) {
|
|
405
|
+
const status = tokens[i];
|
|
406
|
+
if (!status) {
|
|
407
|
+
i++;
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
if (/^[RC]\d*$/.test(status)) {
|
|
411
|
+
// Rename/copy: the source path effectively left (deleted) and the
|
|
412
|
+
// destination arrived.
|
|
413
|
+
add(tokens[i + 1], 'D');
|
|
414
|
+
add(tokens[i + 2], status[0]);
|
|
415
|
+
i += 3;
|
|
416
|
+
} else {
|
|
417
|
+
add(tokens[i + 1], status[0]);
|
|
418
|
+
i += 2;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return [...entries].map(([path, status]) => ({ path, status }));
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function compileSecretMatchers(config) {
|
|
425
|
+
const matchers = SECRET_PATTERNS.map((entry) => ({
|
|
426
|
+
rule: entry.rule,
|
|
427
|
+
regex: new RegExp(entry.source),
|
|
428
|
+
}));
|
|
429
|
+
const extra = Array.isArray(config.extraSecretPatterns) ? config.extraSecretPatterns : [];
|
|
430
|
+
for (const source of extra) {
|
|
431
|
+
matchers.push({ rule: `config-secret:${source}`, regex: new RegExp(source) });
|
|
432
|
+
}
|
|
433
|
+
return matchers;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Restricted glob matcher for deny PATHS: `*` matches within a path segment,
|
|
438
|
+
* `**` matches across segments. Deliberately tiny — no npm glob library at
|
|
439
|
+
* gate time.
|
|
440
|
+
*/
|
|
441
|
+
function globToRegex(pattern) {
|
|
442
|
+
// `**/` matches zero or more whole directories (so `**/*.log` matches a
|
|
443
|
+
// root-level `debug.log`); a bare `**` matches anything including slashes.
|
|
444
|
+
const parts = pattern.split(/\*\*\//);
|
|
445
|
+
const segment = (part) =>
|
|
446
|
+
part
|
|
447
|
+
.split('**')
|
|
448
|
+
.map((piece) =>
|
|
449
|
+
piece
|
|
450
|
+
.split('*')
|
|
451
|
+
.map((literal) => literal.replace(/[.+^${}()|[\]\\?]/g, '\\$&'))
|
|
452
|
+
.join('[^/]*')
|
|
453
|
+
)
|
|
454
|
+
.join('.*');
|
|
455
|
+
const source = parts.map(segment).join('(?:[^/]+/)*');
|
|
456
|
+
return new RegExp(`^${source}$`);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function compileArtifactMatchers(config) {
|
|
460
|
+
// defaultDenyPaths and extraDenyPaths are GLOBS (path patterns);
|
|
461
|
+
// extraArtifactPatterns are raw regex sources for advanced consumers.
|
|
462
|
+
const globs = [
|
|
463
|
+
...(Array.isArray(MANIFEST.defaultDenyPaths) ? MANIFEST.defaultDenyPaths : []),
|
|
464
|
+
...(Array.isArray(config.extraDenyPaths) ? config.extraDenyPaths : []),
|
|
465
|
+
];
|
|
466
|
+
const matchers = globs.map((source) => ({ source, regex: globToRegex(source) }));
|
|
467
|
+
for (const source of Array.isArray(config.extraArtifactPatterns)
|
|
468
|
+
? config.extraArtifactPatterns
|
|
469
|
+
: []) {
|
|
470
|
+
matchers.push({ source, regex: new RegExp(source) });
|
|
471
|
+
}
|
|
472
|
+
return matchers;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
function renderHuman(baseRef, findings, changedCount) {
|
|
476
|
+
const lines = [];
|
|
477
|
+
for (const finding of findings) {
|
|
478
|
+
const label = finding.check === 'guard-integrity' ? 'Warning' : 'Error';
|
|
479
|
+
lines.push(`${label}: [${finding.check}] ${finding.file}: ${finding.message}`);
|
|
480
|
+
if (finding.fix) {
|
|
481
|
+
lines.push(` fix: ${finding.fix}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (findings.length === 0) {
|
|
485
|
+
lines.push(`OK: guard checks passed (${changedCount} changed file(s) vs ${baseRef}).`);
|
|
486
|
+
}
|
|
487
|
+
return lines.join('\n');
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function main() {
|
|
491
|
+
const args = parseArgs(process.argv.slice(2));
|
|
492
|
+
|
|
493
|
+
if (args.listChecks) {
|
|
494
|
+
process.stdout.write(`${JSON.stringify(MANIFEST, null, 2)}\n`);
|
|
495
|
+
process.exit(0);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (args.updateBaseline) {
|
|
499
|
+
if (isCI()) {
|
|
500
|
+
process.stderr.write('Error: refusing --update-baseline in CI.\n');
|
|
501
|
+
process.exit(1);
|
|
502
|
+
}
|
|
503
|
+
mkdirSync(join(SCRIPT_DIR, 'baselines'), { recursive: true });
|
|
504
|
+
process.stdout.write(
|
|
505
|
+
'Info: --update-baseline is dormant. No count-producing scanners exist yet, so\n' +
|
|
506
|
+
'baselines/ stays empty and anti-inflation has nothing to compare. The engine is\n' +
|
|
507
|
+
'present but inert until stack scanners are wired in a later phase.\n'
|
|
508
|
+
);
|
|
509
|
+
process.exit(0);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const config = loadConfig();
|
|
513
|
+
const emitFailure = (rule, message, fix) => {
|
|
514
|
+
process.stderr.write(`Error: ${message}\n`);
|
|
515
|
+
process.stderr.write(` fix: ${fix}\n`);
|
|
516
|
+
if (args.formatJson) {
|
|
517
|
+
process.stdout.write(
|
|
518
|
+
`${JSON.stringify(
|
|
519
|
+
{ baseRef: null, mergeBase: null, findings: [{ check: 'git', rule, file: '', message, fix }] },
|
|
520
|
+
null,
|
|
521
|
+
2
|
|
522
|
+
)}\n`
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
process.exit(1);
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
const baseRef = resolveBaseRef(config, args.base);
|
|
529
|
+
if (!baseRef) {
|
|
530
|
+
emitFailure(
|
|
531
|
+
'base-resolution',
|
|
532
|
+
'cannot determine a base ref (fail closed).',
|
|
533
|
+
'Pass --base <ref>, set POETIC_GUARD_BASE_REF, set config.json baseRef, or ensure origin/HEAD resolves.'
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (git(['rev-parse', '--verify', '--quiet', baseRef], { allowFailure: true }) === null) {
|
|
538
|
+
emitFailure(
|
|
539
|
+
'base-resolution',
|
|
540
|
+
`cannot resolve base ref '${baseRef}' (fail closed).`,
|
|
541
|
+
`Fetch the base branch (git fetch origin) or set POETIC_GUARD_BASE_REF / config.json baseRef to a resolvable ref.`
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
const mergeBaseRaw = git(['merge-base', baseRef, 'HEAD'], { allowFailure: true });
|
|
546
|
+
const mergeBase = mergeBaseRaw ? mergeBaseRaw.trim() : '';
|
|
547
|
+
if (!mergeBase) {
|
|
548
|
+
emitFailure(
|
|
549
|
+
'shallow-clone',
|
|
550
|
+
`no merge base between '${baseRef}' and HEAD (likely a shallow clone).`,
|
|
551
|
+
'Use fetch-depth: 0 in your CI checkout, or run git fetch --unshallow, then retry.'
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
const repoRoot = normalizePath(git(['rev-parse', '--show-toplevel']).trim());
|
|
556
|
+
const guardDir = `${normalizePath(relative(repoRoot, SCRIPT_DIR))}/`;
|
|
557
|
+
const baselinesDir = `${normalizePath(relative(repoRoot, join(SCRIPT_DIR, 'baselines')))}/`;
|
|
558
|
+
|
|
559
|
+
// Deletions (D) are included: deleting a guard file or baseline is a change
|
|
560
|
+
// the guard-integrity check must see (a deleted baseline would otherwise
|
|
561
|
+
// bypass anti-inflation entirely). Per-check policy on deletions:
|
|
562
|
+
// guard-integrity: sees them (that is the point);
|
|
563
|
+
// artifact-paths: skips them (removing a committed artifact is cleanup);
|
|
564
|
+
// secret-scan: skips naturally (deleted files add no lines);
|
|
565
|
+
// anti-inflation: a deleted baseline is guard-integrity's finding.
|
|
566
|
+
const changedEntries = parseNameStatusZ(
|
|
567
|
+
git(['diff', '--name-status', '-z', '-M', '--diff-filter=ACDMRT', mergeBase, 'HEAD']) ?? ''
|
|
568
|
+
);
|
|
569
|
+
const changedFiles = changedEntries.map((entry) => entry.path);
|
|
570
|
+
const presentFiles = changedEntries
|
|
571
|
+
.filter((entry) => entry.status !== 'D')
|
|
572
|
+
.map((entry) => entry.path);
|
|
573
|
+
|
|
574
|
+
const findings = [];
|
|
575
|
+
const addFinding = (check, rule, file, message, fix) => {
|
|
576
|
+
findings.push({ check, rule, file, message, fix });
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
// Check 4 (guard integrity) runs FIRST, before any consumer-config-derived
|
|
580
|
+
// matcher executes: config.json is branch-owned, so a PR could plant a
|
|
581
|
+
// pathological regex (ReDoS) in extraSecretPatterns to hang or hard-fail
|
|
582
|
+
// the run before the guard-change verdict is reached. When guard files
|
|
583
|
+
// changed, the branch config is untrusted — content checks still run, but
|
|
584
|
+
// with BUILT-IN matchers only.
|
|
585
|
+
// Shrink-only baseline exemption: a plain 'M' baselines/*.json that is a pure
|
|
586
|
+
// shrink/removal is a routine ratchet-down, not gate-machinery tampering. It
|
|
587
|
+
// skips the guard-integrity finding and keeps branch config trusted. The
|
|
588
|
+
// check uses only git show + JSON.parse + built-in helpers (no config regex),
|
|
589
|
+
// preserving the ordering property that no branch-owned pattern executes
|
|
590
|
+
// before the guard verdict.
|
|
591
|
+
const guardChanged = [];
|
|
592
|
+
if (MANIFEST.checks.guardIntegrity) {
|
|
593
|
+
for (const entry of changedEntries) {
|
|
594
|
+
if (!isUnderGuardNamespace(entry.path, guardDir)) {
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
// The shrink exemption requires the EXACT tracked case: a case-variant
|
|
598
|
+
// baseline path is namespace pollution, not a ratchet-down.
|
|
599
|
+
if (
|
|
600
|
+
entry.path.startsWith(guardDir) &&
|
|
601
|
+
isShrinkOnlyBaselineChange(entry, mergeBase, baselinesDir)
|
|
602
|
+
) {
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
guardChanged.push(entry.path);
|
|
606
|
+
const caseVariant = !entry.path.startsWith(guardDir);
|
|
607
|
+
addFinding(
|
|
608
|
+
'guard-integrity',
|
|
609
|
+
caseVariant ? 'guard-namespace-case-variant' : 'guard-change',
|
|
610
|
+
entry.path,
|
|
611
|
+
caseVariant
|
|
612
|
+
? 'case-variant path collides with the guard directory namespace'
|
|
613
|
+
: 'gate machinery changed under the guard directory',
|
|
614
|
+
caseVariant
|
|
615
|
+
? 'Remove the path; on case-insensitive filesystems it materializes inside the guard directory.'
|
|
616
|
+
: 'Land guard changes via poetic init --guardrails, or require a human merge.'
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
const trustBranchConfig = guardChanged.length === 0;
|
|
621
|
+
const effectiveConfig = trustBranchConfig ? config : {};
|
|
622
|
+
if (!trustBranchConfig) {
|
|
623
|
+
process.stderr.write(
|
|
624
|
+
'Info: guard files changed in this diff; consumer config.json is untrusted for this run (built-in checks only).\n'
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Check 1: baseline anti-inflation.
|
|
629
|
+
if (MANIFEST.checks.baselineAntiInflation) {
|
|
630
|
+
const baselineFiles = presentFiles.filter(
|
|
631
|
+
(file) => file.startsWith(baselinesDir) && file.endsWith('.json')
|
|
632
|
+
);
|
|
633
|
+
for (const file of baselineFiles) {
|
|
634
|
+
const baseContent = git(['show', `${mergeBase}:${file}`], { allowFailure: true });
|
|
635
|
+
if (baseContent === null) {
|
|
636
|
+
// New baseline at base: introducing a ratchet is gate-critical elsewhere.
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
let baseJson;
|
|
640
|
+
let headJson;
|
|
641
|
+
try {
|
|
642
|
+
baseJson = JSON.parse(baseContent);
|
|
643
|
+
headJson = JSON.parse(git(['show', `HEAD:${file}`], { allowFailure: true }) ?? 'null');
|
|
644
|
+
} catch {
|
|
645
|
+
addFinding(
|
|
646
|
+
'baseline-anti-inflation',
|
|
647
|
+
'unparseable-baseline',
|
|
648
|
+
file,
|
|
649
|
+
'baseline JSON is not parseable',
|
|
650
|
+
'Restore valid JSON for the baseline file.'
|
|
651
|
+
);
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
const violations = compareBaselineCounts(
|
|
655
|
+
flattenBaselineCounts(baseJson),
|
|
656
|
+
flattenBaselineCounts(headJson),
|
|
657
|
+
collectLeafTypes(baseJson),
|
|
658
|
+
collectLeafTypes(headJson)
|
|
659
|
+
);
|
|
660
|
+
for (const violation of violations) {
|
|
661
|
+
addFinding('baseline-anti-inflation', violation.rule, file, violation.message, violation.fix);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// Check 2: secrets in added lines.
|
|
667
|
+
if (MANIFEST.checks.secretScan) {
|
|
668
|
+
const matchers = compileSecretMatchers(effectiveConfig);
|
|
669
|
+
for (const file of presentFiles) {
|
|
670
|
+
// Pathspec is repo-root-relative; git runs from SCRIPT_DIR, so anchor
|
|
671
|
+
// at the repo root with (top) and add (literal) so filenames containing
|
|
672
|
+
// glob metacharacters ([, *, ?) are addressed literally. allowFailure
|
|
673
|
+
// is NOT used here: a diff failure for a known-changed path must fail
|
|
674
|
+
// the gate loudly, never read as an empty (secret-free) diff.
|
|
675
|
+
const diff = git(['diff', mergeBase, 'HEAD', '--', `:(top,literal)${file}`]);
|
|
676
|
+
for (const rawLine of diff.split('\n')) {
|
|
677
|
+
if (!rawLine.startsWith('+') || rawLine.startsWith('+++')) {
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
// Strip the diff marker so anchored consumer patterns (^MYCO_) match
|
|
681
|
+
// content at the start of an added line.
|
|
682
|
+
const line = rawLine.slice(1);
|
|
683
|
+
for (const matcher of matchers) {
|
|
684
|
+
if (matcher.regex.test(line)) {
|
|
685
|
+
addFinding(
|
|
686
|
+
'secret-scan',
|
|
687
|
+
matcher.rule,
|
|
688
|
+
file,
|
|
689
|
+
`potential secret in an added line (${matcher.rule})`,
|
|
690
|
+
'Remove the credential and rotate it; never commit secrets.'
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// Check 3: artifact paths.
|
|
699
|
+
if (MANIFEST.checks.artifactPaths) {
|
|
700
|
+
const matchers = compileArtifactMatchers(effectiveConfig);
|
|
701
|
+
// Deletions skipped: removing a committed artifact is cleanup, not a
|
|
702
|
+
// violation.
|
|
703
|
+
for (const file of presentFiles) {
|
|
704
|
+
for (const matcher of matchers) {
|
|
705
|
+
if (matcher.regex.test(file)) {
|
|
706
|
+
addFinding(
|
|
707
|
+
'artifact-paths',
|
|
708
|
+
`deny:${matcher.source}`,
|
|
709
|
+
file,
|
|
710
|
+
'artifact/generated path must not be committed',
|
|
711
|
+
'Remove the path from the commit and add it to .gitignore.'
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// De-duplicate findings by (check, rule, file).
|
|
719
|
+
const seen = new Set();
|
|
720
|
+
let deduped = [];
|
|
721
|
+
for (const finding of findings) {
|
|
722
|
+
const key = `${finding.check}\u0000${finding.rule}\u0000${finding.file}`;
|
|
723
|
+
if (seen.has(key)) {
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
seen.add(key);
|
|
727
|
+
deduped.push(finding);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// Guard self-change escape hatch: honored only outside CI.
|
|
731
|
+
const allowSelfChange = process.env.POETIC_GUARD_ALLOW_SELF_CHANGE === '1' && !isCI();
|
|
732
|
+
let selfChangeSuppressed = false;
|
|
733
|
+
if (allowSelfChange) {
|
|
734
|
+
const before = deduped.length;
|
|
735
|
+
deduped = deduped.filter((finding) => finding.check !== 'guard-integrity');
|
|
736
|
+
selfChangeSuppressed = deduped.length !== before;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
const guardFindings = deduped.filter((finding) => finding.check === 'guard-integrity');
|
|
740
|
+
const hardFindings = deduped.filter((finding) => finding.check !== 'guard-integrity');
|
|
741
|
+
|
|
742
|
+
let exitCode = 0;
|
|
743
|
+
if (hardFindings.length > 0) {
|
|
744
|
+
exitCode = 1;
|
|
745
|
+
} else if (guardFindings.length > 0) {
|
|
746
|
+
exitCode = 2;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
if (args.formatJson) {
|
|
750
|
+
process.stdout.write(`${JSON.stringify({ baseRef, mergeBase, findings: deduped }, null, 2)}\n`);
|
|
751
|
+
process.exit(exitCode);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
if (selfChangeSuppressed) {
|
|
755
|
+
process.stderr.write('Info: guard self-change allowed (POETIC_GUARD_ALLOW_SELF_CHANGE=1, not CI).\n');
|
|
756
|
+
}
|
|
757
|
+
const rendered = renderHuman(baseRef, deduped, changedFiles.length);
|
|
758
|
+
const stream = exitCode === 0 ? process.stdout : process.stderr;
|
|
759
|
+
stream.write(`${rendered}\n`);
|
|
760
|
+
if (exitCode === 2) {
|
|
761
|
+
stream.write('Guard machinery changed: this requires a human merge (exit 2).\n');
|
|
762
|
+
}
|
|
763
|
+
process.exit(exitCode);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// This module is an EXECUTABLE gate, not a library: it runs main() (which calls
|
|
767
|
+
// process.exit) at import time. Do not export or import its helpers — any
|
|
768
|
+
// import would execute the gate. Tests exercise it via subprocess execution
|
|
769
|
+
// (see tests/unit/guard-kit/check-script.test.ts), never by importing.
|
|
770
|
+
try {
|
|
771
|
+
main();
|
|
772
|
+
} catch (error) {
|
|
773
|
+
process.stderr.write(
|
|
774
|
+
`Error: guard check failed - ${error instanceof Error ? error.message : String(error)}\n`
|
|
775
|
+
);
|
|
776
|
+
process.exit(1);
|
|
777
|
+
}
|