@ebrindley/build 0.0.0-stage → 1.42.1-rc28
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/.build-project/providers/catalog.json +13951 -0
- package/.build-project/providers/pricing.json +1978 -0
- package/.build-project/providers/registry.json +4103 -0
- package/.github/SECURITY.md +75 -0
- package/.nvmrc +1 -0
- package/CHANGELOG.md +661 -0
- package/CODE_OF_CONDUCT.md +44 -0
- package/CONTRIBUTING.md +24 -0
- package/INSTALL.md +623 -0
- package/LICENSE +21 -0
- package/README.md +118 -2
- package/THIRD_PARTY_NOTICES.txt +26 -0
- package/dist/ai-judge-UE5UOYOO.js +191 -0
- package/dist/allowlist-grounding-KPLN6NC5.js +16 -0
- package/dist/allowlist-utils-MZZKKXRD.js +31 -0
- package/dist/apply-completion-mode-EM37UZHB.js +110 -0
- package/dist/artifact-migrator-WPACNSEP.js +276 -0
- package/dist/ask-2OZ4JFQR.js +176 -0
- package/dist/auth-6UKBTJUQ.js +185 -0
- package/dist/auth-H5KJL6HL.js +165 -0
- package/dist/auth-LVJRJDMU.js +12 -0
- package/dist/auth-NHZOCNRR.js +94 -0
- package/dist/auth-PBXHWXGW.js +95 -0
- package/dist/auth-T7Y5DCAH.js +91 -0
- package/dist/auth-TVVKCHQW.js +13 -0
- package/dist/auth-UHB2UCSS.js +97 -0
- package/dist/auth-VACA3VUL.js +98 -0
- package/dist/auth-VVLC77S3.js +44 -0
- package/dist/auth-liveness-XO4AGDDD.js +53 -0
- package/dist/autoloop-cleanup-SI3VGAAR.js +106 -0
- package/dist/autoloop-evidence-gates-J5GG5YQB.js +39 -0
- package/dist/autoloop-gate-policy-SUNAEP6Q.js +169 -0
- package/dist/autoloop-helpers-VQGQNTT6.js +52 -0
- package/dist/autoloop-ledger-P6TIDP7C.js +96 -0
- package/dist/autoloop-ledger-subscriber-HFAGOZXH.js +161 -0
- package/dist/autoloop-run-defaults-GWGZBNT7.js +27 -0
- package/dist/autoloop-run-lock-GBWRM5A2.js +197 -0
- package/dist/autoloop-success-C32QVWOP.js +93 -0
- package/dist/autoloop-termination-summary-GI6IBQWD.js +58 -0
- package/dist/autoloop-trajectory-AMKSQISD.js +70 -0
- package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
- package/dist/automatic-branch-cleanup-R62X2C5O.js +49 -0
- package/dist/autonomous-loop-controller-2WL363LW.js +4386 -0
- package/dist/backend-YUTFDZXZ.js +30 -0
- package/dist/background-executor-Z3ODTMD7.js +260 -0
- package/dist/backlog-75QPEAMW.js +403 -0
- package/dist/backlog-execution-intent-GWUV5TUK.js +19 -0
- package/dist/backup-active-store-XHWLN34M.js +16 -0
- package/dist/backup-machine-stores-UI4LTJOY.js +251 -0
- package/dist/backup-telemetry-db-Z4ICYCNW.js +26 -0
- package/dist/branch-archive-manager-FMSQ7YJF.js +18 -0
- package/dist/branch-cleanup-manager-ST6FJGND.js +35 -0
- package/dist/build-gate-7NKWPY62.js +68 -0
- package/dist/build-root-S7DINODY.js +18 -0
- package/dist/change-summary-R6CB6VXJ.js +50 -0
- package/dist/chunk-24MNKKOM.js +173 -0
- package/dist/chunk-2H6VZFIO.js +235 -0
- package/dist/chunk-2JIX3EKV.js +39 -0
- package/dist/chunk-2KO7HVZM.js +106 -0
- package/dist/chunk-2L36U25O.js +100 -0
- package/dist/chunk-2NMNFUQA.js +475 -0
- package/dist/chunk-2OUAEH67.js +83 -0
- package/dist/chunk-2VLJUXJU.js +115 -0
- package/dist/chunk-2VUEDIUM.js +77 -0
- package/dist/chunk-2Y2IIHPI.js +430 -0
- package/dist/chunk-2YRG3LHZ.js +220 -0
- package/dist/chunk-2Z5Q3SUY.js +65 -0
- package/dist/chunk-32IYXIE5.js +873 -0
- package/dist/chunk-33IGPPUI.js +292 -0
- package/dist/chunk-352PCJLK.js +283 -0
- package/dist/chunk-35J4NE6S.js +226 -0
- package/dist/chunk-3C7WBIVK.js +1016 -0
- package/dist/chunk-3H3EY6U7.js +1225 -0
- package/dist/chunk-3H4MWYIC.js +198 -0
- package/dist/chunk-3HHWQR3N.js +2479 -0
- package/dist/chunk-3JKNRYEE.js +14 -0
- package/dist/chunk-3LECCYZY.js +128 -0
- package/dist/chunk-3LOY6YZI.js +852 -0
- package/dist/chunk-3M57DADF.js +44 -0
- package/dist/chunk-3NOTLVLG.js +3803 -0
- package/dist/chunk-3OPP2OZB.js +1480 -0
- package/dist/chunk-3P5IN5E7.js +9 -0
- package/dist/chunk-3PL22IYZ.js +20 -0
- package/dist/chunk-3REDAJUJ.js +14 -0
- package/dist/chunk-3S2R4XJI.js +203 -0
- package/dist/chunk-3UBZI5DW.js +61 -0
- package/dist/chunk-3VV5OBGG.js +308 -0
- package/dist/chunk-3WY5TU2O.js +823 -0
- package/dist/chunk-43OKHTW4.js +82 -0
- package/dist/chunk-45KUJBDI.js +112 -0
- package/dist/chunk-47X5LM7B.js +224 -0
- package/dist/chunk-4B6FQJ77.js +268 -0
- package/dist/chunk-4BTDUT2S.js +42 -0
- package/dist/chunk-4DJL2VXA.js +24 -0
- package/dist/chunk-4EBSXZ73.js +48 -0
- package/dist/chunk-4QKP6I4C.js +294 -0
- package/dist/chunk-4U6XK2DG.js +300 -0
- package/dist/chunk-4UMRUFBD.js +132 -0
- package/dist/chunk-4US4SYJ4.js +569 -0
- package/dist/chunk-4ZPLWEZO.js +154 -0
- package/dist/chunk-56WPYDJH.js +624 -0
- package/dist/chunk-57WRCJJW.js +50 -0
- package/dist/chunk-5AW4RMNG.js +24 -0
- package/dist/chunk-5EQN56OZ.js +155 -0
- package/dist/chunk-5F43TUIN.js +38 -0
- package/dist/chunk-5FKHIKTS.js +115 -0
- package/dist/chunk-5HDP7XZG.js +91 -0
- package/dist/chunk-5KQETTNS.js +152 -0
- package/dist/chunk-5PDVN2KO.js +498 -0
- package/dist/chunk-5UBIFVRD.js +509 -0
- package/dist/chunk-5YDE3Q62.js +46 -0
- package/dist/chunk-626AJVMU.js +302 -0
- package/dist/chunk-633XZ7UF.js +3583 -0
- package/dist/chunk-63DHNHGA.js +236 -0
- package/dist/chunk-666656AR.js +568 -0
- package/dist/chunk-67YRJPJO.js +19 -0
- package/dist/chunk-6CAU7VBA.js +20 -0
- package/dist/chunk-6CB3KJRY.js +21 -0
- package/dist/chunk-6DBMALXL.js +29 -0
- package/dist/chunk-6E25C4IA.js +269 -0
- package/dist/chunk-6FIBNIQU.js +73 -0
- package/dist/chunk-6G57FYBV.js +189 -0
- package/dist/chunk-6KZKRTG3.js +4885 -0
- package/dist/chunk-6LAH2UV2.js +525 -0
- package/dist/chunk-6PZY2TTU.js +921 -0
- package/dist/chunk-6T6NHXK4.js +230 -0
- package/dist/chunk-6TBEX4R4.js +432 -0
- package/dist/chunk-6TRD7TEE.js +911 -0
- package/dist/chunk-6XCP2RAI.js +47 -0
- package/dist/chunk-726G6WDL.js +351 -0
- package/dist/chunk-75EMT7BF.js +616 -0
- package/dist/chunk-762ACDZJ.js +4696 -0
- package/dist/chunk-77I6G4CO.js +1 -0
- package/dist/chunk-7DJ6SQH3.js +510 -0
- package/dist/chunk-7HPCIOMA.js +1383 -0
- package/dist/chunk-7HYBSRPZ.js +17503 -0
- package/dist/chunk-7KBEOPVB.js +73 -0
- package/dist/chunk-7LHJDJB3.js +2222 -0
- package/dist/chunk-7NVJMH52.js +306 -0
- package/dist/chunk-7RMARDVH.js +33 -0
- package/dist/chunk-7SEWU4QG.js +36 -0
- package/dist/chunk-7TUTZTI2.js +911 -0
- package/dist/chunk-7VBDFPUM.js +340 -0
- package/dist/chunk-7VRJHTGZ.js +6406 -0
- package/dist/chunk-7YAOUUKK.js +493 -0
- package/dist/chunk-AAAODV76.js +860 -0
- package/dist/chunk-AB4HUJVQ.js +339 -0
- package/dist/chunk-AEQWV746.js +611 -0
- package/dist/chunk-AHU3FKPA.js +11639 -0
- package/dist/chunk-AISTV5XU.js +226 -0
- package/dist/chunk-AJBTKGJZ.js +48 -0
- package/dist/chunk-AJJNW7XT.js +248 -0
- package/dist/chunk-AJN5Y5YZ.js +160 -0
- package/dist/chunk-ALDTFNZ3.js +150 -0
- package/dist/chunk-ARARVIZK.js +281 -0
- package/dist/chunk-ATBM6AW5.js +53 -0
- package/dist/chunk-ATKEKM3E.js +206 -0
- package/dist/chunk-AUJLW6JZ.js +92 -0
- package/dist/chunk-AY3MHEFM.js +24 -0
- package/dist/chunk-B7PYTV72.js +236 -0
- package/dist/chunk-B7YRSULE.js +1423 -0
- package/dist/chunk-BAWJNMWF.js +339 -0
- package/dist/chunk-BBPIILO2.js +88 -0
- package/dist/chunk-BD3PGW6A.js +957 -0
- package/dist/chunk-BDPYFAB4.js +44 -0
- package/dist/chunk-BIUV23HH.js +729 -0
- package/dist/chunk-BQ3VAGXH.js +243 -0
- package/dist/chunk-BQJOGAWT.js +31 -0
- package/dist/chunk-BT7EG7CO.js +68 -0
- package/dist/chunk-BV3XQQLU.js +27 -0
- package/dist/chunk-BY6ODHNZ.js +78 -0
- package/dist/chunk-BZRLSZNV.js +79 -0
- package/dist/chunk-C3DH3NCY.js +2773 -0
- package/dist/chunk-C3KCMAJP.js +756 -0
- package/dist/chunk-C7AGUJ5K.js +267 -0
- package/dist/chunk-CBSWKQCX.js +342 -0
- package/dist/chunk-CE5OZBYY.js +21 -0
- package/dist/chunk-CFCVYHSW.js +373 -0
- package/dist/chunk-CHA2HDE5.js +126 -0
- package/dist/chunk-CIHWPGS5.js +146 -0
- package/dist/chunk-CJBSZX3F.js +127 -0
- package/dist/chunk-CLA6QIJM.js +43 -0
- package/dist/chunk-CPSVQR2I.js +365 -0
- package/dist/chunk-CRPRVNQ4.js +254 -0
- package/dist/chunk-CSIE4Y7C.js +1093 -0
- package/dist/chunk-CSOPSYDY.js +142 -0
- package/dist/chunk-CSXLLEGB.js +205 -0
- package/dist/chunk-CTDLERWU.js +293 -0
- package/dist/chunk-CULBXMSK.js +110 -0
- package/dist/chunk-D2M2Y5ID.js +21 -0
- package/dist/chunk-D37WY7SH.js +1060 -0
- package/dist/chunk-D4VJFCGZ.js +89 -0
- package/dist/chunk-D6WTZMZB.js +48 -0
- package/dist/chunk-DBHOWDUH.js +976 -0
- package/dist/chunk-DCACX7BV.js +19364 -0
- package/dist/chunk-DFHX4XYA.js +128 -0
- package/dist/chunk-DIKBRRKE.js +176 -0
- package/dist/chunk-DJG5RIOR.js +9 -0
- package/dist/chunk-DNIOIISW.js +616 -0
- package/dist/chunk-DOA5G7IA.js +315 -0
- package/dist/chunk-DP7FKP6W.js +855 -0
- package/dist/chunk-DS2JZ677.js +79 -0
- package/dist/chunk-DSRLVYBS.js +82 -0
- package/dist/chunk-EAEVKNJA.js +209 -0
- package/dist/chunk-EEUESN3T.js +575 -0
- package/dist/chunk-EJ4LUU5Y.js +73 -0
- package/dist/chunk-EJIWTPSZ.js +1063 -0
- package/dist/chunk-EJVCDTAN.js +116 -0
- package/dist/chunk-EKLUBDBQ.js +627 -0
- package/dist/chunk-EN62WLFD.js +849 -0
- package/dist/chunk-ENYRCL43.js +26 -0
- package/dist/chunk-EP22ZMFO.js +273 -0
- package/dist/chunk-EP4SVAVI.js +87 -0
- package/dist/chunk-EPAMVGI3.js +1562 -0
- package/dist/chunk-EPRMH6HO.js +24 -0
- package/dist/chunk-ES6NWJ36.js +4057 -0
- package/dist/chunk-ETA2K4KI.js +30 -0
- package/dist/chunk-ETAD4NKD.js +31 -0
- package/dist/chunk-EUWIIDQ7.js +93 -0
- package/dist/chunk-EVE3OD2W.js +141 -0
- package/dist/chunk-EXA26FFC.js +459 -0
- package/dist/chunk-EXSPAA35.js +244 -0
- package/dist/chunk-F55YABKV.js +258 -0
- package/dist/chunk-F5DNGU5W.js +27 -0
- package/dist/chunk-F622MJYV.js +103 -0
- package/dist/chunk-F6NIQD74.js +5111 -0
- package/dist/chunk-FAWJTC34.js +43 -0
- package/dist/chunk-FAZBRHGG.js +47 -0
- package/dist/chunk-FIEUSGNJ.js +39 -0
- package/dist/chunk-FKCG7K6H.js +1146 -0
- package/dist/chunk-FOVVXV45.js +229 -0
- package/dist/chunk-FRBPKBFE.js +30 -0
- package/dist/chunk-FSA5BPFI.js +268 -0
- package/dist/chunk-FSJ5TTZ3.js +29 -0
- package/dist/chunk-FT7SGLXT.js +193 -0
- package/dist/chunk-FUUVZZUB.js +62 -0
- package/dist/chunk-FYMRVUNZ.js +1697 -0
- package/dist/chunk-FYTAA5FG.js +162 -0
- package/dist/chunk-G3VB2UCZ.js +3892 -0
- package/dist/chunk-G6OIMVXH.js +405 -0
- package/dist/chunk-G7PQCXVH.js +228 -0
- package/dist/chunk-GAB6UW52.js +1087 -0
- package/dist/chunk-GAFJEYLK.js +29 -0
- package/dist/chunk-GC4CRMTS.js +642 -0
- package/dist/chunk-GFHSIWHL.js +5297 -0
- package/dist/chunk-GI5M67YA.js +735 -0
- package/dist/chunk-GIJWHUWF.js +191 -0
- package/dist/chunk-GO6DRECI.js +1 -0
- package/dist/chunk-GOFVBTMN.js +314 -0
- package/dist/chunk-GQIP72ZJ.js +13 -0
- package/dist/chunk-GQXLXRFA.js +28 -0
- package/dist/chunk-GT6HFKJB.js +48 -0
- package/dist/chunk-GVJGSSKM.js +174 -0
- package/dist/chunk-GWHGTG37.js +36 -0
- package/dist/chunk-GZAJHLKO.js +18 -0
- package/dist/chunk-GZK62I3N.js +314 -0
- package/dist/chunk-H3HGMISG.js +483 -0
- package/dist/chunk-H3ISZJMJ.js +403 -0
- package/dist/chunk-H4HXVWEC.js +9 -0
- package/dist/chunk-H6MJGKAW.js +120 -0
- package/dist/chunk-HBTTGVR5.js +353 -0
- package/dist/chunk-HBZ322WZ.js +35 -0
- package/dist/chunk-HEP3ILP4.js +34 -0
- package/dist/chunk-HGFXODKO.js +106 -0
- package/dist/chunk-HHWDTB6S.js +59 -0
- package/dist/chunk-HKO45NLZ.js +286 -0
- package/dist/chunk-HLVTEA6A.js +89 -0
- package/dist/chunk-HS3SY6HN.js +160 -0
- package/dist/chunk-HT5OCGKN.js +899 -0
- package/dist/chunk-HXIIEMGF.js +78 -0
- package/dist/chunk-I56TH7VM.js +46 -0
- package/dist/chunk-I6FN3R5D.js +352 -0
- package/dist/chunk-I7SCBHJN.js +655 -0
- package/dist/chunk-IJM4GKAT.js +529 -0
- package/dist/chunk-IMEYU36R.js +344 -0
- package/dist/chunk-INJ3SS6A.js +936 -0
- package/dist/chunk-IUKOPCCE.js +441 -0
- package/dist/chunk-IVEPZQJO.js +33 -0
- package/dist/chunk-IVZEONFC.js +43 -0
- package/dist/chunk-IWBHRSG7.js +936 -0
- package/dist/chunk-IYY3HQAD.js +484 -0
- package/dist/chunk-J2ICMYDA.js +48 -0
- package/dist/chunk-J2QCFLUN.js +505 -0
- package/dist/chunk-J5HM6V5P.js +1039 -0
- package/dist/chunk-J6NZX6QH.js +398 -0
- package/dist/chunk-JBBB2Y47.js +432 -0
- package/dist/chunk-JDCZQZU7.js +42 -0
- package/dist/chunk-JEDNXGSS.js +169 -0
- package/dist/chunk-JHP7OT6K.js +89 -0
- package/dist/chunk-JLS65NUQ.js +14 -0
- package/dist/chunk-JNMWYMC6.js +38 -0
- package/dist/chunk-JNSTWNNW.js +25 -0
- package/dist/chunk-JOSK6GEU.js +9564 -0
- package/dist/chunk-JQUMSIGC.js +100 -0
- package/dist/chunk-JVHGMURQ.js +1106 -0
- package/dist/chunk-JYXS47FQ.js +951 -0
- package/dist/chunk-K2ZMW2Z5.js +2147 -0
- package/dist/chunk-K7FAFORM.js +14 -0
- package/dist/chunk-KBJXX3ON.js +333 -0
- package/dist/chunk-KHFKVQWY.js +486 -0
- package/dist/chunk-KHMEI3DQ.js +173 -0
- package/dist/chunk-KHW3UD7B.js +69 -0
- package/dist/chunk-KKQKWAMF.js +365 -0
- package/dist/chunk-KOKXJV2U.js +455 -0
- package/dist/chunk-KQ4NGOJI.js +14 -0
- package/dist/chunk-KQYQOXMS.js +342 -0
- package/dist/chunk-KTMW65UX.js +14 -0
- package/dist/chunk-KUEWV2JH.js +593 -0
- package/dist/chunk-KXYDV3HP.js +1523 -0
- package/dist/chunk-KZ4JMGZ5.js +96 -0
- package/dist/chunk-KZWGBUIO.js +2659 -0
- package/dist/chunk-L2CBG5IX.js +1892 -0
- package/dist/chunk-L2S235CU.js +314 -0
- package/dist/chunk-L32WD57F.js +98 -0
- package/dist/chunk-LDJCKAJP.js +123 -0
- package/dist/chunk-LDWNBEN7.js +541 -0
- package/dist/chunk-LJVH57G2.js +241 -0
- package/dist/chunk-LPQ7NZEN.js +209 -0
- package/dist/chunk-LRGH3CCV.js +148 -0
- package/dist/chunk-LULOGMMM.js +1133 -0
- package/dist/chunk-LWGKN2GY.js +8284 -0
- package/dist/chunk-LX4F24ZH.js +157 -0
- package/dist/chunk-M4BUEXXF.js +839 -0
- package/dist/chunk-M6UHOC4I.js +553 -0
- package/dist/chunk-MCBNWZNO.js +657 -0
- package/dist/chunk-MEMSY6VY.js +223 -0
- package/dist/chunk-MHLEZQQI.js +145 -0
- package/dist/chunk-MJ6WNSIX.js +192 -0
- package/dist/chunk-MKASIKWZ.js +442 -0
- package/dist/chunk-MNOVBYFU.js +60 -0
- package/dist/chunk-MO2BYAAF.js +2896 -0
- package/dist/chunk-MP6P7Y2A.js +180 -0
- package/dist/chunk-MQ4TFJAG.js +3365 -0
- package/dist/chunk-MT2WAIR3.js +131 -0
- package/dist/chunk-MTU7VTNN.js +1122 -0
- package/dist/chunk-MULMXX4V.js +150 -0
- package/dist/chunk-MW2DWWVA.js +147 -0
- package/dist/chunk-MY3ZPUN4.js +151 -0
- package/dist/chunk-MYLH2S4G.js +64 -0
- package/dist/chunk-MZ5WYKNA.js +28 -0
- package/dist/chunk-N3Q2JNPV.js +249 -0
- package/dist/chunk-N5DX4JAK.js +12 -0
- package/dist/chunk-NAINGKHF.js +35 -0
- package/dist/chunk-NEQUQHOX.js +223 -0
- package/dist/chunk-NHNPEZS4.js +1408 -0
- package/dist/chunk-NHTIXJCR.js +17 -0
- package/dist/chunk-NKLPMBNV.js +1154 -0
- package/dist/chunk-NMVZ5YES.js +199 -0
- package/dist/chunk-NRFRY3GE.js +256 -0
- package/dist/chunk-NTD6CSI6.js +1266 -0
- package/dist/chunk-NUO7B3SH.js +318 -0
- package/dist/chunk-NVOHIJKG.js +1319 -0
- package/dist/chunk-NXH3RX7O.js +523 -0
- package/dist/chunk-NXZ3DURF.js +257 -0
- package/dist/chunk-O26L6F7F.js +209 -0
- package/dist/chunk-O5RRIUEP.js +124 -0
- package/dist/chunk-O5X6BKAO.js +10 -0
- package/dist/chunk-O6ZQUVTR.js +31 -0
- package/dist/chunk-O7FE75QZ.js +306 -0
- package/dist/chunk-OC7Z6AJQ.js +81 -0
- package/dist/chunk-OH7IEZ63.js +307 -0
- package/dist/chunk-OI734GRS.js +115 -0
- package/dist/chunk-OJBH62DK.js +684 -0
- package/dist/chunk-OKJLVSTJ.js +247 -0
- package/dist/chunk-OMX5VL43.js +79 -0
- package/dist/chunk-ONHAMBN6.js +12 -0
- package/dist/chunk-ONYPLIVE.js +753 -0
- package/dist/chunk-OSK7QWPD.js +637 -0
- package/dist/chunk-OTXLMJKP.js +438 -0
- package/dist/chunk-OV5PKQMA.js +213 -0
- package/dist/chunk-OXK5HA4B.js +31 -0
- package/dist/chunk-OYDWFQA4.js +272 -0
- package/dist/chunk-OZAUKWHB.js +22 -0
- package/dist/chunk-P5P2EKGH.js +94 -0
- package/dist/chunk-P6SSWAKY.js +29 -0
- package/dist/chunk-P7CQGPLS.js +30 -0
- package/dist/chunk-P7RVCHQV.js +197 -0
- package/dist/chunk-PEBWDYIW.js +726 -0
- package/dist/chunk-PFCXFO7A.js +9193 -0
- package/dist/chunk-PFLDWMX6.js +168 -0
- package/dist/chunk-PHZGLQSK.js +15883 -0
- package/dist/chunk-PNFTPNSR.js +20 -0
- package/dist/chunk-PPHXX4W7.js +175 -0
- package/dist/chunk-PPZESPJT.js +262 -0
- package/dist/chunk-PRDHI2L5.js +296 -0
- package/dist/chunk-PSTKWHHN.js +32 -0
- package/dist/chunk-PV53ODOT.js +555 -0
- package/dist/chunk-PVJBTI7P.js +24 -0
- package/dist/chunk-PXKERBKX.js +100 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-Q3DHEZA5.js +85 -0
- package/dist/chunk-Q5RZDVQK.js +204 -0
- package/dist/chunk-Q64IR2Z2.js +4933 -0
- package/dist/chunk-Q6Z5UGPL.js +398 -0
- package/dist/chunk-QAMAV4DT.js +627 -0
- package/dist/chunk-QBWF4444.js +112 -0
- package/dist/chunk-QDKYT4CI.js +22805 -0
- package/dist/chunk-QFLBRWCJ.js +126 -0
- package/dist/chunk-QILAQACE.js +107 -0
- package/dist/chunk-QJ6OEH4K.js +3683 -0
- package/dist/chunk-QK3NLYTV.js +320 -0
- package/dist/chunk-QOFLUS24.js +535 -0
- package/dist/chunk-QOIASNEJ.js +98 -0
- package/dist/chunk-QP4UTSOV.js +3587 -0
- package/dist/chunk-QP5ST7RI.js +904 -0
- package/dist/chunk-QS5AGRZN.js +167 -0
- package/dist/chunk-QTAOU53N.js +107 -0
- package/dist/chunk-QTCLJHLZ.js +351 -0
- package/dist/chunk-QTOLTG4L.js +119 -0
- package/dist/chunk-QWDV4OSL.js +142 -0
- package/dist/chunk-QWMQ74KD.js +508 -0
- package/dist/chunk-QX6LOMMH.js +158 -0
- package/dist/chunk-QXBKIHY7.js +238 -0
- package/dist/chunk-QXBKTJT6.js +270 -0
- package/dist/chunk-QYQOVOLR.js +196 -0
- package/dist/chunk-R2CKS6WT.js +73 -0
- package/dist/chunk-R2TIYG7U.js +68 -0
- package/dist/chunk-R2W3LESH.js +465 -0
- package/dist/chunk-R5EXHMUN.js +100 -0
- package/dist/chunk-RBBTBCHX.js +289 -0
- package/dist/chunk-RBKLOUXA.js +121 -0
- package/dist/chunk-RCP2Y6DQ.js +86 -0
- package/dist/chunk-RCYEJSD5.js +260 -0
- package/dist/chunk-RFDVSI4N.js +134 -0
- package/dist/chunk-RGJU63FV.js +1717 -0
- package/dist/chunk-RI4EX2QE.js +18 -0
- package/dist/chunk-RIMARPCF.js +152 -0
- package/dist/chunk-RJ6RSNT6.js +42 -0
- package/dist/chunk-RNI2GUIF.js +131 -0
- package/dist/chunk-RPHUWJ3K.js +264 -0
- package/dist/chunk-RPIMAMV7.js +361 -0
- package/dist/chunk-RQFX6YRN.js +49 -0
- package/dist/chunk-RRC5BL7B.js +285 -0
- package/dist/chunk-RSYTSBOO.js +79 -0
- package/dist/chunk-RWQQIKIC.js +35 -0
- package/dist/chunk-RZUBOZH2.js +373 -0
- package/dist/chunk-S2E632FQ.js +380 -0
- package/dist/chunk-S2VQCZO4.js +22 -0
- package/dist/chunk-S2XIMQJQ.js +681 -0
- package/dist/chunk-S47ISY27.js +183 -0
- package/dist/chunk-S6I4KISU.js +142 -0
- package/dist/chunk-S6TAFQI5.js +2403 -0
- package/dist/chunk-SBBNT5ZJ.js +27 -0
- package/dist/chunk-SDJV2DTQ.js +491 -0
- package/dist/chunk-SDPIFNLD.js +33 -0
- package/dist/chunk-SF6YK3JI.js +835 -0
- package/dist/chunk-SK3ZFONO.js +976 -0
- package/dist/chunk-SKTFRFQ7.js +1775 -0
- package/dist/chunk-SNGM452K.js +2002 -0
- package/dist/chunk-STW7OFOA.js +581 -0
- package/dist/chunk-SU6UFUQY.js +1351 -0
- package/dist/chunk-SVJM3LJA.js +27 -0
- package/dist/chunk-SVUNZOPG.js +129 -0
- package/dist/chunk-T5XLUYV3.js +34 -0
- package/dist/chunk-T7E5JS6N.js +57 -0
- package/dist/chunk-TA3N5MMO.js +450 -0
- package/dist/chunk-TAJPCXSB.js +13 -0
- package/dist/chunk-TDEMDRN2.js +1639 -0
- package/dist/chunk-TDSEX5CF.js +24 -0
- package/dist/chunk-TGCVL74Y.js +28 -0
- package/dist/chunk-TGXXYDL4.js +1012 -0
- package/dist/chunk-TIKTYUJO.js +296 -0
- package/dist/chunk-TIZAJD4M.js +6029 -0
- package/dist/chunk-TLSEZZCG.js +5549 -0
- package/dist/chunk-TMBDRHAX.js +19 -0
- package/dist/chunk-TRURQUBP.js +1217 -0
- package/dist/chunk-TSQ256N5.js +152 -0
- package/dist/chunk-TUQMMFEQ.js +2244 -0
- package/dist/chunk-U424MJLC.js +81 -0
- package/dist/chunk-U4DRS6ZW.js +11 -0
- package/dist/chunk-U5KS22IN.js +204 -0
- package/dist/chunk-UAPHFJPN.js +673 -0
- package/dist/chunk-UB7LQITD.js +1040 -0
- package/dist/chunk-UBVRHGAZ.js +237 -0
- package/dist/chunk-UDNNAQN5.js +98 -0
- package/dist/chunk-UJP3XM54.js +342 -0
- package/dist/chunk-UJYDH2MW.js +305 -0
- package/dist/chunk-UKMPASIC.js +399 -0
- package/dist/chunk-UKUL3EHK.js +763 -0
- package/dist/chunk-UPHU64NB.js +1327 -0
- package/dist/chunk-URMSZXAD.js +43 -0
- package/dist/chunk-US3RT6CY.js +525 -0
- package/dist/chunk-UTDEOPKV.js +30 -0
- package/dist/chunk-UUUDKV7N.js +13 -0
- package/dist/chunk-UVKWU3SM.js +39 -0
- package/dist/chunk-V2TVPO3X.js +521 -0
- package/dist/chunk-V3KLVK7B.js +398 -0
- package/dist/chunk-V3YFFHDR.js +17 -0
- package/dist/chunk-VAG6GUBR.js +1162 -0
- package/dist/chunk-VBENAHDA.js +1814 -0
- package/dist/chunk-VBNCKCCI.js +16 -0
- package/dist/chunk-VCGSWN5M.js +1300 -0
- package/dist/chunk-VE2O2I7M.js +115 -0
- package/dist/chunk-VIFHYTI5.js +31 -0
- package/dist/chunk-VJER3FUS.js +5080 -0
- package/dist/chunk-VLMDM56Q.js +268 -0
- package/dist/chunk-VMFZEVVX.js +99 -0
- package/dist/chunk-VNDPQVUZ.js +1853 -0
- package/dist/chunk-VSPJRLGA.js +4783 -0
- package/dist/chunk-VSWC5ZXI.js +103 -0
- package/dist/chunk-VYI4DSZP.js +2017 -0
- package/dist/chunk-W4BAIQ6L.js +1212 -0
- package/dist/chunk-W7VQAL2K.js +2203 -0
- package/dist/chunk-WEI3ZDZH.js +33 -0
- package/dist/chunk-WEIUS5NT.js +26 -0
- package/dist/chunk-WEW7UFWE.js +546 -0
- package/dist/chunk-WGQAXLNA.js +384 -0
- package/dist/chunk-WJAL4JL3.js +206 -0
- package/dist/chunk-WKFOJ5ZG.js +141 -0
- package/dist/chunk-WMWQEFLN.js +2177 -0
- package/dist/chunk-WNECKKO2.js +154 -0
- package/dist/chunk-WPKLYOAM.js +195 -0
- package/dist/chunk-WSH37YQN.js +243 -0
- package/dist/chunk-WV3KQDPE.js +84 -0
- package/dist/chunk-WZFC4V4U.js +389 -0
- package/dist/chunk-XCOIBNET.js +13 -0
- package/dist/chunk-XDM65LBX.js +53 -0
- package/dist/chunk-XGU6PBO5.js +645 -0
- package/dist/chunk-XHOI4V62.js +43 -0
- package/dist/chunk-XIBVFMLQ.js +6858 -0
- package/dist/chunk-XJ2E7YEJ.js +117 -0
- package/dist/chunk-XON4ZCYX.js +69 -0
- package/dist/chunk-XQPEWJPI.js +127 -0
- package/dist/chunk-XSJTIFUY.js +31 -0
- package/dist/chunk-XT7OVWM3.js +64 -0
- package/dist/chunk-XTXYIISX.js +1104 -0
- package/dist/chunk-XV7NZL4B.js +57 -0
- package/dist/chunk-XWIZ6B5S.js +109 -0
- package/dist/chunk-XWLIKOBX.js +240 -0
- package/dist/chunk-XZOXEIN4.js +156 -0
- package/dist/chunk-XZRS7I7W.js +3673 -0
- package/dist/chunk-Y4ZDDHB6.js +44 -0
- package/dist/chunk-Y733RB7T.js +194 -0
- package/dist/chunk-YBHUB4XR.js +14931 -0
- package/dist/chunk-YKC75XK4.js +147 -0
- package/dist/chunk-YKMXFVK7.js +27 -0
- package/dist/chunk-YO5BAJ55.js +225 -0
- package/dist/chunk-YPDCLXNZ.js +568 -0
- package/dist/chunk-YSQPGVFK.js +116 -0
- package/dist/chunk-YTVVTIWJ.js +716 -0
- package/dist/chunk-YVCMDVBB.js +698 -0
- package/dist/chunk-YYTOA6DP.js +114 -0
- package/dist/chunk-Z5WGNULV.js +88 -0
- package/dist/chunk-Z6NGVVXG.js +66 -0
- package/dist/chunk-Z7CDQNH3.js +20 -0
- package/dist/chunk-ZH4G3FU5.js +187 -0
- package/dist/chunk-ZJB6SQPA.js +257 -0
- package/dist/chunk-ZL6E4HMY.js +42 -0
- package/dist/chunk-ZMLOC3DW.js +62 -0
- package/dist/chunk-ZORW64QH.js +101 -0
- package/dist/chunk-ZVVD2XGV.js +1369 -0
- package/dist/cli-utils-ER33ODC5.js +31 -0
- package/dist/cli-validation-6CHPTANV.js +146 -0
- package/dist/commit-utils-3STAY7C7.js +49 -0
- package/dist/compatibility-notice-IHNXR2JR.js +21 -0
- package/dist/compete-config-resolver-V3GDNJMM.js +125 -0
- package/dist/compete-results-XUM3PJHS.js +318 -0
- package/dist/competition-outcome-tracker-NWSMVUPG.js +62 -0
- package/dist/config-4HHE4OIK.js +238 -0
- package/dist/config-D6YAZASH.js +10 -0
- package/dist/config-MIPRDYYV.js +46 -0
- package/dist/config-audit-GA5DCUAI.js +371 -0
- package/dist/config-explain-4LMO556H.js +71 -0
- package/dist/config-loader-RGP634PC.js +51 -0
- package/dist/config-manager-J2UTO635.js +114 -0
- package/dist/config-merger-TVUJBZTS.js +14 -0
- package/dist/config-validator-H4ZVIE56.js +122 -0
- package/dist/cost-HSIV5U2Y.js +85 -0
- package/dist/data-migration-state-OAUL2WPQ.js +35 -0
- package/dist/db-migrator-NUOW5NKR.js +34 -0
- package/dist/default-paths-UILB62BN.js +49 -0
- package/dist/discovery-V6GYUJUC.js +53 -0
- package/dist/doctor-BBSMCDWE.js +271 -0
- package/dist/doctor-context-blocks-LPY75VZA.js +231 -0
- package/dist/doctor-instructions-import-JXHDDOE5.js +70 -0
- package/dist/doctor-purpose-6YJOXPBE.js +30 -0
- package/dist/domain-analyzer-S35ABUNA.js +48 -0
- package/dist/ensure-initialized-Q6PEU55O.js +78 -0
- package/dist/entry.js +922 -0
- package/dist/error-parser-core-MZFMFANN.js +70 -0
- package/dist/evaluation-context-GQBYDAEV.js +63 -0
- package/dist/evidence-plan-resolver-5FUAP3SA.js +111 -0
- package/dist/execution-data-writer-YCG5UH37.js +72 -0
- package/dist/execution-policy-applier-PWZM5LNA.js +63 -0
- package/dist/execution-preflight-DASJWWQF.js +223 -0
- package/dist/execution-roles-KNSNNB2D.js +112 -0
- package/dist/exit-code-error-QIY5DOKF.js +18 -0
- package/dist/external-temp-cleanup-CAW7LQ6R.js +360 -0
- package/dist/factory-YCYCB7AE.js +209 -0
- package/dist/file-utils-ZQYNBQBW.js +45 -0
- package/dist/flywheel-allowlist-revert-H22HA6JE.js +21 -0
- package/dist/flywheel-autoloop-executor-PDOASJEZ.js +316 -0
- package/dist/flywheel-autoloop-unverified-TOKYFCDC.js +36 -0
- package/dist/flywheel-competition-executor-YJUMMEJO.js +320 -0
- package/dist/flywheel-executor-JWU43KAY.js +437 -0
- package/dist/flywheel-git-isolation-FQ2TRWMB.js +56 -0
- package/dist/flywheel-manifest-HDPNMWWF.js +114 -0
- package/dist/flywheel-model-defaults-UHAKTZT3.js +110 -0
- package/dist/flywheel-preflight-III2C7TH.js +163 -0
- package/dist/flywheel-resume-2O45MS7Y.js +31 -0
- package/dist/flywheel-resume-execution-lease-P2BK257J.js +59 -0
- package/dist/flywheel-safety-AVAVFXIJ.js +19 -0
- package/dist/flywheel-scope-decision-ALJUUNGG.js +14 -0
- package/dist/get-telemetry-logger-MPDVO2JA.js +155 -0
- package/dist/git-message-style-KCXGMTDT.js +104 -0
- package/dist/guidance-profile-config-G3K5YQOO.js +113 -0
- package/dist/guidance-profile-renderer-TX4TNDFL.js +23 -0
- package/dist/identity-XLQJ4YJF.js +25 -0
- package/dist/index-query-6NUY4FKX.js +37 -0
- package/dist/index.js +85588 -0
- package/dist/indexer-DL54CM3K.js +44 -0
- package/dist/init-OUZ72344.js +245 -0
- package/dist/instructions-import-offer-NSYXSITC.js +363 -0
- package/dist/instructions-run-NBII7W36.js +114 -0
- package/dist/interrupted-work-E4TLKJLE.js +43 -0
- package/dist/invoke-provider-auth-NEWEIHCI.js +38 -0
- package/dist/judge-scoring.json +64 -0
- package/dist/lab-mode-YXQ2Y3NG.js +44 -0
- package/dist/lab-utils-5QAMDJR5.js +29 -0
- package/dist/linux-host-class-YDWQX65O.js +31 -0
- package/dist/llm-judge-executor-OJSNCTFJ.js +179 -0
- package/dist/local-ci-config-VZ4WWDT5.js +48 -0
- package/dist/local-executor-DCMDDRX2.js +280 -0
- package/dist/logger-5KNKS3O4.js +154 -0
- package/dist/matrix-prompt-builder-4ZBOGZSB.js +527 -0
- package/dist/matrix-result-parser-EZJM4YXP.js +14 -0
- package/dist/merge-batch-RTEEMVDB.js +313 -0
- package/dist/merge-batch-members-VIWGVRHP.js +24 -0
- package/dist/merge-queue-TIIUSOY6.js +126 -0
- package/dist/merge-queue-trust-DUNZ4J65.js +21 -0
- package/dist/metadata-UKSMWM6J.js +29 -0
- package/dist/model-catalog-readiness-R5KJBP5M.js +202 -0
- package/dist/model-invocations-db-XTUPPQ34.js +70 -0
- package/dist/model-resolver-JFZ2MHOJ.js +39 -0
- package/dist/model-resolver-SCQ57KAQ.js +217 -0
- package/dist/model-roles-D3OR4NAH.js +110 -0
- package/dist/monitor-F4SIU5G2.js +96 -0
- package/dist/nested-worktrees-2WUWQ75N.js +23 -0
- package/dist/next-S3IRLVER.js +96 -0
- package/dist/next-UKPFRXOO.js +148 -0
- package/dist/opportunistic-TL4S26VX.js +86 -0
- package/dist/optimization-config-resolver-NAEIYU6A.js +148 -0
- package/dist/package-HJR4QJT4.js +10 -0
- package/dist/parse-git-status-7PIYFPS2.js +21 -0
- package/dist/path-security-5WJSY56G.js +41 -0
- package/dist/paths-JUI7C4KU.js +45 -0
- package/dist/plan-backlog-list-fast-SSTQL5XP.js +89 -0
- package/dist/plan-backlog-show-fast-PFRAQ3JB.js +114 -0
- package/dist/plan-sprint-list-fast-HD2KBZSY.js +110 -0
- package/dist/plan-sprint-status-fast-YFYH7WQF.js +116 -0
- package/dist/plan-task-status-fast-JU5PNLUU.js +114 -0
- package/dist/plan-to-flywheel-PY5MSY2H.js +529 -0
- package/dist/preflight-PJHGTJNZ.js +12 -0
- package/dist/process-registry-B4ZUCN7T.js +28 -0
- package/dist/process-scanner-TU3QHWVB.js +23 -0
- package/dist/processes-6FHVGT72.js +28 -0
- package/dist/processes-json-fast-YWTMUWXB.js +72 -0
- package/dist/profile-HWTC56SG.js +209 -0
- package/dist/project-runtime-paths-2UQNG5Y4.js +41 -0
- package/dist/protected-branches-N36LDBFY.js +71 -0
- package/dist/provider-aware-resource-manager-YTFAHNGJ.js +40 -0
- package/dist/provider-matrix-2KO2V5OM.js +214 -0
- package/dist/provider-matrix-renderer-MEC3PER7.js +139 -0
- package/dist/provider-output-forwarding-2AHL7YMA.js +26 -0
- package/dist/provider-registry-WCZ65QHC.js +136 -0
- package/dist/provider-temp-cleanup-IUNPJCZF.js +14 -0
- package/dist/prune-engine-EOQVWEP6.js +448 -0
- package/dist/publication-turn-S42RZTQF.js +44 -0
- package/dist/quality-gate-JQMVCKOO.js +72 -0
- package/dist/quickstart-3O6FRCFB.js +105 -0
- package/dist/readiness-GW6ABRHB.js +139 -0
- package/dist/readiness-KFZCXDTT.js +215 -0
- package/dist/registry-7XG376SY.js +217 -0
- package/dist/repair-helpers-TTV5FEF4.js +117 -0
- package/dist/repo-root-YG6MQZDW.js +28 -0
- package/dist/resolution-engine-FFEK7HQ2.js +187 -0
- package/dist/resolve-provider-cli-ZEXVZKET.js +44 -0
- package/dist/restore-telemetry-db-E7BR5PO7.js +459 -0
- package/dist/routing-events-AW6SRZ6G.js +13 -0
- package/dist/routing-history-store-FMDDQL6W.js +39 -0
- package/dist/routing-planner-C6OHO3EY.js +221 -0
- package/dist/runner-KHDNQ5KU.js +1194 -0
- package/dist/runner-PIS2BW7Y.js +1801 -0
- package/dist/safety-E3JJVSFL.js +67 -0
- package/dist/safety-stanza-HE6GXP4G.js +49 -0
- package/dist/sandbox-7LBZC5PE.js +72 -0
- package/dist/sandbox-ASWCDYZL.js +80 -0
- package/dist/schema-extensions.sql +234 -0
- package/dist/security-JI22TBEB.js +17 -0
- package/dist/setup-bb-plugin-FQXLA76Y.js +531 -0
- package/dist/setup-claude-code-NF4ZSHVE.js +197 -0
- package/dist/setup-temp-cleanup-2APZ4HMA.js +29 -0
- package/dist/shared-utils-34HJZ6JX.js +40 -0
- package/dist/simple-artifact-goal-MQLDDMMX.js +29 -0
- package/dist/sprint-N7JFTEGL.js +403 -0
- package/dist/sprint-bridge-KJXIBNRJ.js +117 -0
- package/dist/sprint-completion-dependents-34SR7JVL.js +43 -0
- package/dist/sprint-execution-service-A6JPUBWY.js +376 -0
- package/dist/sprint-manager-MU2ZUWN2.js +140 -0
- package/dist/sqlite-timeout-config-U2CT4LKU.js +13 -0
- package/dist/sqlite-wrapper-FSGJ2QEW.js +19 -0
- package/dist/stale-cleanup-orchestrator-4X6324VF.js +71 -0
- package/dist/storage-access-I3V5LER7.js +31 -0
- package/dist/store-XVG64ZR2.js +25 -0
- package/dist/task-classifier-MN2DYE5R.js +558 -0
- package/dist/task-list-fast-7AT6LTTA.js +112 -0
- package/dist/task-manager-LHPBBRRE.js +136 -0
- package/dist/task-report-OLPAWBTK.js +64 -0
- package/dist/task-type-detector-6RG3YNZF.js +27 -0
- package/dist/task-type-resolver-EQHOUIHT.js +64 -0
- package/dist/telemetry-5VYSK772.js +212 -0
- package/dist/telemetry-health-tracker-4GFW2EMP.js +12 -0
- package/dist/telemetry-path-resolver-H3NFHHQY.js +34 -0
- package/dist/telemetry-reliability-URJDTNPZ.js +76 -0
- package/dist/transports-NREZQTJK.js +106 -0
- package/dist/unified-cost-tracker-5MTBJ2CL.js +59 -0
- package/dist/unified-state-cleanup-GGAXLHXF.js +292 -0
- package/dist/universal-cost-calculator-JTFEJVWK.js +70 -0
- package/dist/user-agents-QLIGPLP2.js +30 -0
- package/dist/variant-execution-I4ZZUAWY.js +319 -0
- package/dist/variant-opt-parser-JHCXKY2K.js +251 -0
- package/dist/variant-request-input-PL37N3AN.js +11 -0
- package/dist/variant-state-cleanup-KHMXRBZN.js +287 -0
- package/dist/variant-worker-COB5YTJX.js +4517 -0
- package/dist/variant-worker.js +26 -0
- package/dist/variants-XGDSXYG3.js +267 -0
- package/dist/verification-command-YSPU4VBH.js +66 -0
- package/dist/verify-command-timeout-DQUYH33Z.js +11 -0
- package/dist/verify-commands-LOHMOFKC.js +65 -0
- package/dist/warning-JSKSFKBT.js +13 -0
- package/dist/work-edge-K65NHVWY.js +50 -0
- package/dist/work-item-writer-KY5ZWZWW.js +30 -0
- package/dist/worker-JNXXEIT6.js +1504 -0
- package/dist/worker.js +21 -0
- package/dist/workspace-tree-identity-JO5PSKTW.js +52 -0
- package/dist/worktree-environment-WTVABAQW.js +64 -0
- package/dist/worktree-metrics-VZRQI26T.js +66 -0
- package/dist/writeback-TQFQBJNU.js +50 -0
- package/docs/CLI_REFERENCE.md +8287 -0
- package/docs/PROVIDER_SETUP.md +1737 -0
- package/docs/README.md +96 -0
- package/docs/TROUBLESHOOTING.md +2209 -0
- package/docs/getting-started/QUICK_START.md +260 -0
- package/docs/getting-started/README.md +198 -0
- package/docs/getting-started/SETUP.md +25 -0
- package/docs/reference/AGENT_CONTEXT.md +84 -0
- package/docs/reference/DELIVERY_ONBOARDING.md +198 -0
- package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
- package/docs/reference/SECURITY.md +291 -0
- package/docs/reference/TELEMETRY_PRIVACY.md +259 -0
- package/integrations/bb-plugin-build/README.md +391 -0
- package/integrations/bb-plugin-build/app.css +431 -0
- package/integrations/bb-plugin-build/app.tsx +6210 -0
- package/integrations/bb-plugin-build/package.json +45 -0
- package/integrations/bb-plugin-build/server.ts +488 -0
- package/integrations/bb-plugin-build/src/adapter.ts +3672 -0
- package/integrations/bb-plugin-build/src/backlog-authoring-model.ts +150 -0
- package/integrations/bb-plugin-build/src/backlog-authoring-schema.ts +458 -0
- package/integrations/bb-plugin-build/src/backlog-authoring-service.ts +467 -0
- package/integrations/bb-plugin-build/src/backlog-authoring-view.ts +1025 -0
- package/integrations/bb-plugin-build/src/command-evidence-schema.ts +13 -0
- package/integrations/bb-plugin-build/src/competition-defaults-schema.ts +122 -0
- package/integrations/bb-plugin-build/src/competition-defaults-service.ts +105 -0
- package/integrations/bb-plugin-build/src/competition-defaults-view.ts +138 -0
- package/integrations/bb-plugin-build/src/contract.ts +718 -0
- package/integrations/bb-plugin-build/src/execution-activity-view.ts +98 -0
- package/integrations/bb-plugin-build/src/finalize-model.ts +205 -0
- package/integrations/bb-plugin-build/src/finalize-schema.ts +150 -0
- package/integrations/bb-plugin-build/src/finalize-service.ts +330 -0
- package/integrations/bb-plugin-build/src/finalize-view.ts +159 -0
- package/integrations/bb-plugin-build/src/judge-operations-readback.ts +303 -0
- package/integrations/bb-plugin-build/src/judge-operations-schema.ts +33 -0
- package/integrations/bb-plugin-build/src/judge-operations-view.ts +459 -0
- package/integrations/bb-plugin-build/src/model.ts +1318 -0
- package/integrations/bb-plugin-build/src/monitor-service.ts +233 -0
- package/integrations/bb-plugin-build/src/panel-read-ux.ts +97 -0
- package/integrations/bb-plugin-build/src/patch-preview-schema.ts +166 -0
- package/integrations/bb-plugin-build/src/patch-preview-service.ts +480 -0
- package/integrations/bb-plugin-build/src/patch-preview-view.ts +109 -0
- package/integrations/bb-plugin-build/src/planning-readback.ts +228 -0
- package/integrations/bb-plugin-build/src/planning-service.ts +647 -0
- package/integrations/bb-plugin-build/src/planning-sync-evidence.ts +37 -0
- package/integrations/bb-plugin-build/src/planning-workspace-readback.ts +33 -0
- package/integrations/bb-plugin-build/src/planning-workspace-schema.ts +131 -0
- package/integrations/bb-plugin-build/src/planning-workspace.ts +333 -0
- package/integrations/bb-plugin-build/src/poll-handoff.ts +136 -0
- package/integrations/bb-plugin-build/src/project-target-server.ts +21 -0
- package/integrations/bb-plugin-build/src/project-target.ts +45 -0
- package/integrations/bb-plugin-build/src/reference-index.ts +218 -0
- package/integrations/bb-plugin-build/src/repository-identity.ts +17 -0
- package/integrations/bb-plugin-build/src/repository-schema.ts +30 -0
- package/integrations/bb-plugin-build/src/result-explorer-view.ts +597 -0
- package/integrations/bb-plugin-build/src/result-readback-model.ts +163 -0
- package/integrations/bb-plugin-build/src/result-readback-schema.ts +319 -0
- package/integrations/bb-plugin-build/src/result-readback-service.ts +333 -0
- package/integrations/bb-plugin-build/src/run-page-view.ts +332 -0
- package/integrations/bb-plugin-build/src/setup-config-schema.ts +293 -0
- package/integrations/bb-plugin-build/src/setup-config-service.ts +620 -0
- package/integrations/bb-plugin-build/src/setup-config-view.ts +388 -0
- package/integrations/bb-plugin-build/src/sprint-close-model.ts +150 -0
- package/integrations/bb-plugin-build/src/sprint-close-schema.ts +128 -0
- package/integrations/bb-plugin-build/src/sprint-close-service.ts +293 -0
- package/integrations/bb-plugin-build/src/sprint-close-view.ts +116 -0
- package/integrations/bb-plugin-build/src/sprint-composition-model.ts +709 -0
- package/integrations/bb-plugin-build/src/sprint-composition-readback.ts +231 -0
- package/integrations/bb-plugin-build/src/sprint-composition-schema.ts +597 -0
- package/integrations/bb-plugin-build/src/sprint-composition-service.ts +773 -0
- package/integrations/bb-plugin-build/src/sprint-composition-view.ts +1221 -0
- package/integrations/bb-plugin-build/src/sprint-execution-schema.ts +188 -0
- package/integrations/bb-plugin-build/src/sprint-execution-service.ts +289 -0
- package/integrations/bb-plugin-build/src/sprint-execution-view.ts +54 -0
- package/integrations/bb-plugin-build/src/task-authoring-model.ts +563 -0
- package/integrations/bb-plugin-build/src/task-authoring-schema.ts +629 -0
- package/integrations/bb-plugin-build/src/task-authoring-service.ts +842 -0
- package/integrations/bb-plugin-build/src/task-authoring-view.ts +1227 -0
- package/integrations/bb-plugin-build/src/task-catalog-schema.ts +46 -0
- package/integrations/bb-plugin-build/src/task-catalog-service.ts +44 -0
- package/integrations/bb-plugin-build/src/task-detail-readback.ts +56 -0
- package/integrations/bb-plugin-build/src/task-detail-schema.ts +171 -0
- package/integrations/bb-plugin-build/src/task-navigation.ts +446 -0
- package/integrations/bb-plugin-build/src/workbench-route.ts +74 -0
- package/package.json +306 -4
- package/schemas/README.md +80 -0
- package/schemas/build.config.schema.json +2110 -0
- package/schemas/config-v1.schema.json +136 -0
- package/schemas/execution-config.schema.json +47 -0
- package/schemas/judge-scoring.schema.json +257 -0
- package/schemas/provider-config.schema.json +179 -0
- package/schemas/telemetry-config.schema.json +79 -0
- package/schemas/user-preferences.schema.json +141 -0
- package/scripts/assert-node-runtime.mjs +146 -0
- package/scripts/preflight-native.mjs +49 -0
- package/scripts/setup-git-hooks.mjs +39 -0
- package/scripts/sync.sh +2871 -0
- package/scripts/write-node-launcher.sh +138 -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/.build-project/README.md +41 -0
- package/templates/.build-project/agents/README.md +50 -0
- package/templates/.build-project/agents/architect.md +10 -0
- package/templates/.build-project/agents/code-reviewer.md +10 -0
- package/templates/.build-project/agents/debugger.md +10 -0
- package/templates/.build-project/agents/documenter.md +10 -0
- package/templates/.build-project/agents/test-automator.md +10 -0
- package/templates/.build-project/config/build.config.jsonc +64 -0
- package/templates/.build-project/config/project-context.template.json +6 -0
- package/templates/.build-project/config/task-type-aliases.presets/kanban.yaml +14 -0
- package/templates/.build-project/config/task-type-aliases.presets/scrum.yaml +17 -0
- package/templates/.build-project/config/task-type-aliases.presets/xp.yaml +12 -0
- package/templates/.build-project/config/task-type-aliases.yaml +29 -0
- package/templates/.build-project/gitignore.template +70 -0
- package/templates/.build-project/task-types/analysis.yaml +38 -0
- package/templates/.build-project/task-types/architecture.yaml +35 -0
- package/templates/.build-project/task-types/doc.yaml +34 -0
- package/templates/.build-project/task-types/feature.yaml +22 -0
- package/templates/.build-project/task-types/general.yaml +4 -0
- package/templates/.build-project/task-types/security.yaml +38 -0
- package/templates/AGENTS.template.md +85 -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/skills/code-review/SKILL.md +61 -0
- package/templates/builtin-workflows/skills/execution-contract-analysis/SKILL.md +24 -0
- package/templates/builtin-workflows/skills/execution-contract-code/SKILL.md +19 -0
- package/templates/builtin-workflows/skills/execution-contract-structured/SKILL.md +17 -0
- package/templates/ci/incident-intake.mjs +787 -0
- package/templates/ci/incidents.yml.template +103 -0
- package/templates/ci/node.yml.template +17 -0
- package/templates/ci/python.yml.template +17 -0
- package/templates/guard-kit/GUARD_SETUP.md.template +258 -0
- package/templates/guard-kit/build-guard.yml.template +189 -0
- package/templates/guard-kit/check.mjs.template +932 -0
- package/templates/guard-kit/config.json.template +7 -0
- package/templates/guard-kit/policy.json.template +1 -0
- package/templates/profiles/README.md +57 -0
- package/templates/profiles/frontier-claude.json +23 -0
- package/templates/profiles/frontier-codex.json +23 -0
|
@@ -0,0 +1,1106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logDebug
|
|
3
|
+
} from "./chunk-ETAD4NKD.js";
|
|
4
|
+
import {
|
|
5
|
+
ProviderRegistry,
|
|
6
|
+
registerProviderRegistryReloadInvalidator
|
|
7
|
+
} from "./chunk-QJ6OEH4K.js";
|
|
8
|
+
import {
|
|
9
|
+
resolveBuildRoot
|
|
10
|
+
} from "./chunk-CHA2HDE5.js";
|
|
11
|
+
|
|
12
|
+
// src/core/safety/circuit-breaker.ts
|
|
13
|
+
var CircuitState = /* @__PURE__ */ ((CircuitState2) => {
|
|
14
|
+
CircuitState2["CLOSED"] = "closed";
|
|
15
|
+
CircuitState2["OPEN"] = "open";
|
|
16
|
+
CircuitState2["HALF_OPEN"] = "half_open";
|
|
17
|
+
return CircuitState2;
|
|
18
|
+
})(CircuitState || {});
|
|
19
|
+
var CircuitBreaker = class {
|
|
20
|
+
options;
|
|
21
|
+
state = "closed" /* CLOSED */;
|
|
22
|
+
failures = [];
|
|
23
|
+
// Timestamp array
|
|
24
|
+
successes = [];
|
|
25
|
+
// Timestamp array
|
|
26
|
+
/** HALF_OPEN probes admitted but not yet resolved; bounded by halfOpenMaxCalls. */
|
|
27
|
+
halfOpenCallsInFlight = 0;
|
|
28
|
+
/** Probe slots still awaiting an outcome. Cleared on every state transition. */
|
|
29
|
+
liveProbes = /* @__PURE__ */ new Set();
|
|
30
|
+
nextProbeId = 0;
|
|
31
|
+
/**
|
|
32
|
+
* When the circuit last entered OPEN. Recovery is measured from this instant,
|
|
33
|
+
* not from the newest failure timestamp, so the failure window (which is
|
|
34
|
+
* pruned by cleanupOldData) cannot cap a longer recoveryTimeout.
|
|
35
|
+
*/
|
|
36
|
+
openedAt;
|
|
37
|
+
rejectedCalls = 0;
|
|
38
|
+
totalResponseTime = 0;
|
|
39
|
+
totalSuccessfulCalls = 0;
|
|
40
|
+
constructor(options = {}) {
|
|
41
|
+
const recoveryTimeout = options.timeout ?? options.recoveryTimeout ?? 3e4;
|
|
42
|
+
const failureWindow = options.windowMs ?? options.failureWindow ?? 6e4;
|
|
43
|
+
if (options.halfOpenMaxCalls !== void 0 && options.halfOpenMaxCalls < 1) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`halfOpenMaxCalls must be >= 1 (got ${options.halfOpenMaxCalls}); a value of 0 makes HALF_OPEN state non-functional`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
this.options = {
|
|
49
|
+
failureThreshold: options.failureThreshold ?? 5,
|
|
50
|
+
errorThreshold: options.errorThreshold,
|
|
51
|
+
minRequests: options.minRequests ?? 5,
|
|
52
|
+
failureWindow,
|
|
53
|
+
windowMs: failureWindow,
|
|
54
|
+
recoveryTimeout,
|
|
55
|
+
timeout: recoveryTimeout,
|
|
56
|
+
halfOpenMaxCalls: options.halfOpenMaxCalls ?? 1,
|
|
57
|
+
baseDelay: options.baseDelay ?? 1e3,
|
|
58
|
+
maxDelay: options.maxDelay ?? 3e4,
|
|
59
|
+
// 30 seconds
|
|
60
|
+
isFailure: options.isFailure
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Execute a function through the circuit breaker
|
|
65
|
+
* @returns Promise that resolves with the function result or rejects with CircuitBreakerError
|
|
66
|
+
*/
|
|
67
|
+
async execute(fn) {
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
this.cleanupOldData(now);
|
|
70
|
+
if (this.state === "open" /* OPEN */) {
|
|
71
|
+
if (this.canAttemptRecovery(now)) {
|
|
72
|
+
this.enterHalfOpen();
|
|
73
|
+
} else {
|
|
74
|
+
this.rejectedCalls++;
|
|
75
|
+
const waitTime = Math.max(0, this.options.recoveryTimeout - (now - (this.openedAt ?? now)));
|
|
76
|
+
throw new CircuitBreakerError("Circuit breaker is OPEN. Rejected call.", {
|
|
77
|
+
state: this.state,
|
|
78
|
+
waitTime,
|
|
79
|
+
metrics: this.getMetrics()
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let admission;
|
|
84
|
+
if (this.state === "half_open" /* HALF_OPEN */) {
|
|
85
|
+
if (this.halfOpenCallsInFlight >= this.options.halfOpenMaxCalls) {
|
|
86
|
+
this.rejectedCalls++;
|
|
87
|
+
throw new CircuitBreakerError("Circuit breaker is HALF_OPEN and test limit reached.", {
|
|
88
|
+
state: this.state,
|
|
89
|
+
waitTime: this.options.recoveryTimeout,
|
|
90
|
+
metrics: this.getMetrics()
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
admission = this.reserveProbe();
|
|
94
|
+
}
|
|
95
|
+
const startTime = Date.now();
|
|
96
|
+
try {
|
|
97
|
+
const result = await fn();
|
|
98
|
+
const responseTime = Date.now() - startTime;
|
|
99
|
+
this.recordSuccessInternal(responseTime);
|
|
100
|
+
if (this.releaseProbe(admission) && this.state === "half_open" /* HALF_OPEN */) {
|
|
101
|
+
this.closeCircuit();
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (this.options.isFailure && !this.options.isFailure(error)) {
|
|
106
|
+
this.releaseProbe(admission);
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
const responseTime = Date.now() - startTime;
|
|
110
|
+
this.recordFailureInternal(responseTime);
|
|
111
|
+
if (this.releaseProbe(admission) && this.state === "half_open" /* HALF_OPEN */) {
|
|
112
|
+
this.openCircuit();
|
|
113
|
+
} else if (this.state === "closed" /* CLOSED */ && this.shouldOpenCircuit()) {
|
|
114
|
+
this.openCircuit();
|
|
115
|
+
}
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get current circuit breaker metrics
|
|
121
|
+
*/
|
|
122
|
+
getMetrics() {
|
|
123
|
+
const latestFailure = this.failures.at(-1);
|
|
124
|
+
return {
|
|
125
|
+
state: this.state,
|
|
126
|
+
failureCount: this.failures.length,
|
|
127
|
+
successCount: this.successes.length,
|
|
128
|
+
lastFailureTime: latestFailure,
|
|
129
|
+
rejectedCalls: this.rejectedCalls,
|
|
130
|
+
averageResponseTime: this.totalSuccessfulCalls > 0 ? Math.round(this.totalResponseTime / this.totalSuccessfulCalls) : 0,
|
|
131
|
+
nextRecoveryAttempt: this.openedAt !== void 0 ? this.openedAt + this.options.recoveryTimeout : void 0
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Force the circuit breaker to OPEN state (for testing)
|
|
136
|
+
*/
|
|
137
|
+
forceOpen() {
|
|
138
|
+
this.openCircuit();
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Reset the circuit breaker to CLOSED state (for testing)
|
|
142
|
+
*/
|
|
143
|
+
reset() {
|
|
144
|
+
this.state = "closed" /* CLOSED */;
|
|
145
|
+
this.failures = [];
|
|
146
|
+
this.successes = [];
|
|
147
|
+
this.halfOpenCallsInFlight = 0;
|
|
148
|
+
this.liveProbes.clear();
|
|
149
|
+
this.openedAt = void 0;
|
|
150
|
+
this.rejectedCalls = 0;
|
|
151
|
+
this.totalResponseTime = 0;
|
|
152
|
+
this.totalSuccessfulCalls = 0;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Calculate exponential backoff delay
|
|
156
|
+
*/
|
|
157
|
+
getBackoffDelay() {
|
|
158
|
+
const failureCount = Math.min(this.failures.length, 10);
|
|
159
|
+
const delay = this.options.baseDelay * 2 ** Math.max(0, failureCount - 1);
|
|
160
|
+
return Math.min(delay, this.options.maxDelay);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Inspect whether an admission would currently succeed (manual usage pattern).
|
|
164
|
+
*
|
|
165
|
+
* Read-only with respect to admission: it never transitions OPEN → HALF_OPEN
|
|
166
|
+
* and never consumes a probe slot, so it can be called any number of times
|
|
167
|
+
* (for example a coarse pre-check before deciding what to admit). It still
|
|
168
|
+
* prunes the statistics window, which is bookkeeping rather than admission
|
|
169
|
+
* state.
|
|
170
|
+
*
|
|
171
|
+
* @returns true if the circuit would admit a request right now
|
|
172
|
+
*/
|
|
173
|
+
isRequestAllowed() {
|
|
174
|
+
const now = Date.now();
|
|
175
|
+
this.cleanupOldData(now);
|
|
176
|
+
if (this.state === "closed" /* CLOSED */) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
if (this.state === "open" /* OPEN */) {
|
|
180
|
+
return this.canAttemptRecovery(now);
|
|
181
|
+
}
|
|
182
|
+
return this.halfOpenCallsInFlight < this.options.halfOpenMaxCalls;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Check if a request can be made (for manual usage pattern).
|
|
186
|
+
*
|
|
187
|
+
* Inspection alias for {@link isRequestAllowed}; it does not reserve anything.
|
|
188
|
+
* Callers that are about to make a real call must use {@link tryAdmit}.
|
|
189
|
+
*
|
|
190
|
+
* @returns true if circuit allows request, false if circuit is OPEN
|
|
191
|
+
*/
|
|
192
|
+
canMakeRequest() {
|
|
193
|
+
return this.isRequestAllowed();
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Admit one real request (manual usage pattern).
|
|
197
|
+
*
|
|
198
|
+
* Performs the OPEN → HALF_OPEN transition once the recovery timeout has
|
|
199
|
+
* elapsed and reserves one probe slot bounded by `halfOpenMaxCalls`, so
|
|
200
|
+
* concurrent recovery probes cannot exceed that bound. Pair the returned
|
|
201
|
+
* handle with exactly one `recordSuccess`/`recordFailure` call.
|
|
202
|
+
*
|
|
203
|
+
* @returns an admission handle, or null when the circuit refuses the request
|
|
204
|
+
*/
|
|
205
|
+
tryAdmit() {
|
|
206
|
+
const now = Date.now();
|
|
207
|
+
this.cleanupOldData(now);
|
|
208
|
+
if (this.state === "closed" /* CLOSED */) {
|
|
209
|
+
return { state: "closed" /* CLOSED */ };
|
|
210
|
+
}
|
|
211
|
+
if (this.state === "open" /* OPEN */) {
|
|
212
|
+
if (!this.canAttemptRecovery(now)) return null;
|
|
213
|
+
this.enterHalfOpen();
|
|
214
|
+
}
|
|
215
|
+
if (this.halfOpenCallsInFlight >= this.options.halfOpenMaxCalls) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
return this.reserveProbe();
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Record a successful request (for manual usage pattern).
|
|
222
|
+
*
|
|
223
|
+
* @param admission - handle from {@link tryAdmit}. A success for an admitted
|
|
224
|
+
* HALF_OPEN probe closes the circuit; a success without a handle, or from a
|
|
225
|
+
* request admitted before the circuit opened, only updates statistics.
|
|
226
|
+
*/
|
|
227
|
+
recordSuccess(admission) {
|
|
228
|
+
const now = Date.now();
|
|
229
|
+
this.cleanupOldData(now);
|
|
230
|
+
this.successes.push(now);
|
|
231
|
+
this.totalSuccessfulCalls++;
|
|
232
|
+
if (this.releaseProbe(admission) && this.state === "half_open" /* HALF_OPEN */) {
|
|
233
|
+
this.closeCircuit();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Record a failed request (for manual usage pattern).
|
|
238
|
+
*
|
|
239
|
+
* @param admission - handle from {@link tryAdmit}. A failure for an admitted
|
|
240
|
+
* HALF_OPEN probe reopens the circuit and restarts the recovery clock; a
|
|
241
|
+
* failure without a handle only updates statistics, which can still trip a
|
|
242
|
+
* CLOSED circuit through the configured threshold.
|
|
243
|
+
*/
|
|
244
|
+
recordFailure(admission) {
|
|
245
|
+
const now = Date.now();
|
|
246
|
+
this.cleanupOldData(now);
|
|
247
|
+
this.failures.push(now);
|
|
248
|
+
if (this.releaseProbe(admission) && this.state === "half_open" /* HALF_OPEN */) {
|
|
249
|
+
this.openCircuit();
|
|
250
|
+
} else if (this.state === "closed" /* CLOSED */ && this.shouldOpenCircuit()) {
|
|
251
|
+
this.openCircuit();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
canAttemptRecovery(now) {
|
|
255
|
+
if (this.openedAt === void 0) return true;
|
|
256
|
+
return now - this.openedAt >= this.options.recoveryTimeout;
|
|
257
|
+
}
|
|
258
|
+
/** Enter OPEN and start the recovery clock from now. */
|
|
259
|
+
openCircuit() {
|
|
260
|
+
this.state = "open" /* OPEN */;
|
|
261
|
+
this.openedAt = Date.now();
|
|
262
|
+
this.halfOpenCallsInFlight = 0;
|
|
263
|
+
this.liveProbes.clear();
|
|
264
|
+
}
|
|
265
|
+
/** Enter HALF_OPEN with a fresh set of probe slots. */
|
|
266
|
+
enterHalfOpen() {
|
|
267
|
+
this.state = "half_open" /* HALF_OPEN */;
|
|
268
|
+
this.halfOpenCallsInFlight = 0;
|
|
269
|
+
this.liveProbes.clear();
|
|
270
|
+
}
|
|
271
|
+
/** Enter CLOSED, clearing the failure history that tripped the circuit. */
|
|
272
|
+
closeCircuit() {
|
|
273
|
+
this.state = "closed" /* CLOSED */;
|
|
274
|
+
this.failures = [];
|
|
275
|
+
this.halfOpenCallsInFlight = 0;
|
|
276
|
+
this.liveProbes.clear();
|
|
277
|
+
this.openedAt = void 0;
|
|
278
|
+
}
|
|
279
|
+
/** Reserve one HALF_OPEN probe slot. */
|
|
280
|
+
reserveProbe() {
|
|
281
|
+
this.halfOpenCallsInFlight++;
|
|
282
|
+
const probeId = ++this.nextProbeId;
|
|
283
|
+
this.liveProbes.add(probeId);
|
|
284
|
+
return { state: "half_open" /* HALF_OPEN */, probeId };
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Release the probe slot held by an admission.
|
|
288
|
+
*
|
|
289
|
+
* @returns true when the admission was a probe still awaiting its outcome, so
|
|
290
|
+
* only that outcome may drive a HALF_OPEN transition. Stale handles (their
|
|
291
|
+
* generation of probes ended when the circuit last changed state) and
|
|
292
|
+
* handle-less outcomes return false.
|
|
293
|
+
*/
|
|
294
|
+
releaseProbe(admission) {
|
|
295
|
+
const probeId = admission?.probeId;
|
|
296
|
+
if (probeId === void 0 || !this.liveProbes.delete(probeId)) return false;
|
|
297
|
+
this.halfOpenCallsInFlight = Math.max(0, this.halfOpenCallsInFlight - 1);
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
shouldOpenCircuit() {
|
|
301
|
+
if (this.options.errorThreshold !== void 0) {
|
|
302
|
+
const total = this.failures.length + this.successes.length;
|
|
303
|
+
if (total < this.options.minRequests) {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
const errorRate = this.failures.length / total;
|
|
307
|
+
return errorRate > this.options.errorThreshold;
|
|
308
|
+
}
|
|
309
|
+
return this.failures.length >= this.options.failureThreshold;
|
|
310
|
+
}
|
|
311
|
+
recordFailureInternal(_responseTime) {
|
|
312
|
+
const now = Date.now();
|
|
313
|
+
this.failures.push(now);
|
|
314
|
+
}
|
|
315
|
+
recordSuccessInternal(responseTime) {
|
|
316
|
+
const now = Date.now();
|
|
317
|
+
this.successes.push(now);
|
|
318
|
+
this.totalSuccessfulCalls++;
|
|
319
|
+
this.totalResponseTime += responseTime;
|
|
320
|
+
if (this.state === "half_open" /* HALF_OPEN */) {
|
|
321
|
+
this.failures = [];
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Prune the sliding statistics window used by the trip decision.
|
|
326
|
+
*
|
|
327
|
+
* This deliberately does not touch `openedAt`: recovery timing is independent
|
|
328
|
+
* of the failure window, so a `recoveryTimeout` longer than `failureWindow` is
|
|
329
|
+
* honored instead of being capped at the moment the last failure ages out.
|
|
330
|
+
*/
|
|
331
|
+
cleanupOldData(now) {
|
|
332
|
+
const cutoff = now - this.options.failureWindow;
|
|
333
|
+
this.failures = this.failures.filter((timestamp) => timestamp > cutoff);
|
|
334
|
+
this.successes = this.successes.filter((timestamp) => timestamp > cutoff);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
var CircuitBreakerError = class extends Error {
|
|
338
|
+
state;
|
|
339
|
+
waitTime;
|
|
340
|
+
metrics;
|
|
341
|
+
constructor(message, options) {
|
|
342
|
+
super(message);
|
|
343
|
+
this.name = "CircuitBreakerError";
|
|
344
|
+
this.state = options.state;
|
|
345
|
+
this.waitTime = options.waitTime;
|
|
346
|
+
this.metrics = options.metrics;
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
function createCircuitBreakerOptions(options) {
|
|
350
|
+
return {
|
|
351
|
+
failureThreshold: options.failureThreshold ?? 5,
|
|
352
|
+
errorThreshold: options.errorThreshold,
|
|
353
|
+
minRequests: options.minRequests ?? 5,
|
|
354
|
+
failureWindow: options.failureWindow ?? options.windowMs ?? 6e4,
|
|
355
|
+
windowMs: options.windowMs ?? options.failureWindow ?? 6e4,
|
|
356
|
+
recoveryTimeout: options.recoveryTimeout ?? options.timeout ?? 3e4,
|
|
357
|
+
timeout: options.timeout ?? options.recoveryTimeout ?? 3e4,
|
|
358
|
+
halfOpenMaxCalls: options.halfOpenMaxCalls ?? 1,
|
|
359
|
+
baseDelay: options.baseDelay ?? 1e3,
|
|
360
|
+
maxDelay: options.maxDelay ?? 3e4
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// src/core/safety/circuit-breaker-registry.ts
|
|
365
|
+
var CircuitBreakerRegistry = class {
|
|
366
|
+
breakers = /* @__PURE__ */ new Map();
|
|
367
|
+
defaultOptions;
|
|
368
|
+
/**
|
|
369
|
+
* Creates a new circuit breaker registry
|
|
370
|
+
* @param defaultOptions - Default options to apply to all circuit breakers
|
|
371
|
+
*/
|
|
372
|
+
constructor(defaultOptions = {}) {
|
|
373
|
+
this.defaultOptions = defaultOptions;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Gets or creates a circuit breaker for the specified provider.
|
|
377
|
+
* @param provider - The provider name (e.g., 'gemini', 'claude')
|
|
378
|
+
* @param options - Optional circuit breaker configuration (merged with defaults)
|
|
379
|
+
* @returns The circuit breaker instance for this provider
|
|
380
|
+
*/
|
|
381
|
+
getBreaker(provider, options = {}) {
|
|
382
|
+
let breaker = this.breakers.get(provider);
|
|
383
|
+
if (!breaker) {
|
|
384
|
+
const mergedOptions = {
|
|
385
|
+
failureThreshold: 5,
|
|
386
|
+
recoveryTimeout: 3e4,
|
|
387
|
+
...this.defaultOptions,
|
|
388
|
+
...options
|
|
389
|
+
};
|
|
390
|
+
breaker = new CircuitBreaker(mergedOptions);
|
|
391
|
+
this.breakers.set(provider, breaker);
|
|
392
|
+
}
|
|
393
|
+
return breaker;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Resets the circuit breaker for a specific provider.
|
|
397
|
+
* @param provider - The provider name
|
|
398
|
+
*/
|
|
399
|
+
resetBreaker(provider) {
|
|
400
|
+
const breaker = this.breakers.get(provider);
|
|
401
|
+
if (breaker) {
|
|
402
|
+
breaker.reset();
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Removes the circuit breaker for a specific provider.
|
|
407
|
+
* This completely removes the breaker from the registry.
|
|
408
|
+
* @param provider - The provider name
|
|
409
|
+
*/
|
|
410
|
+
removeBreaker(provider) {
|
|
411
|
+
this.breakers.delete(provider);
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Resets all circuit breakers in the registry.
|
|
415
|
+
*/
|
|
416
|
+
resetAllBreakers() {
|
|
417
|
+
for (const breaker of this.breakers.values()) {
|
|
418
|
+
breaker.reset();
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Removes all circuit breakers from the registry.
|
|
423
|
+
*/
|
|
424
|
+
clear() {
|
|
425
|
+
this.breakers.clear();
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Gets all circuit breakers in the registry.
|
|
429
|
+
* @returns Map of provider names to circuit breakers
|
|
430
|
+
*/
|
|
431
|
+
getAllBreakers() {
|
|
432
|
+
return this.breakers;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Checks if a circuit breaker exists for the specified provider.
|
|
436
|
+
* @param provider - The provider name
|
|
437
|
+
* @returns true if a breaker exists, false otherwise
|
|
438
|
+
*/
|
|
439
|
+
hasBreaker(provider) {
|
|
440
|
+
return this.breakers.has(provider);
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Gets the number of registered circuit breakers.
|
|
444
|
+
* @returns The count of circuit breakers
|
|
445
|
+
*/
|
|
446
|
+
get size() {
|
|
447
|
+
return this.breakers.size;
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
// src/core/safety/file-token-bucket.ts
|
|
452
|
+
import { promises as fs } from "fs";
|
|
453
|
+
import path from "path";
|
|
454
|
+
import { setTimeout as timersSetTimeout } from "timers/promises";
|
|
455
|
+
var DEFAULT_STATE_DIR = path.join(process.cwd(), ".build-project", "rate-limits");
|
|
456
|
+
var DEFAULT_STALE_LOCK_THRESHOLD_MS = 6e4;
|
|
457
|
+
var DEFAULT_MAX_WAIT_MS = 3e4;
|
|
458
|
+
var LOCK_RETRY_INTERVAL_MS = 50;
|
|
459
|
+
var FileTokenBucket = class {
|
|
460
|
+
key;
|
|
461
|
+
bucketSize;
|
|
462
|
+
refillRate;
|
|
463
|
+
initialTokens;
|
|
464
|
+
stateDir;
|
|
465
|
+
staleLockThresholdMs;
|
|
466
|
+
maxWaitMs;
|
|
467
|
+
// In-memory fallback for sync operations (tryAcquire)
|
|
468
|
+
inMemoryTokens;
|
|
469
|
+
inMemoryLastRefill;
|
|
470
|
+
inMemoryTotalWaitMs = 0;
|
|
471
|
+
inMemoryTotalRequests = 0;
|
|
472
|
+
constructor(key, options) {
|
|
473
|
+
this.key = key.replace(/[^a-zA-Z0-9_.-]/g, "_").replace(/\.{2,}/g, "_");
|
|
474
|
+
this.bucketSize = options.bucketSize;
|
|
475
|
+
this.refillRate = options.refillRate;
|
|
476
|
+
this.initialTokens = options.initialTokens ?? options.bucketSize;
|
|
477
|
+
this.stateDir = options.stateDir ?? DEFAULT_STATE_DIR;
|
|
478
|
+
this.staleLockThresholdMs = options.staleLockThresholdMs ?? DEFAULT_STALE_LOCK_THRESHOLD_MS;
|
|
479
|
+
this.maxWaitMs = options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
|
|
480
|
+
this.inMemoryTokens = this.initialTokens;
|
|
481
|
+
this.inMemoryLastRefill = Date.now();
|
|
482
|
+
}
|
|
483
|
+
get statePath() {
|
|
484
|
+
return path.join(this.stateDir, `${this.key}.json`);
|
|
485
|
+
}
|
|
486
|
+
get lockPath() {
|
|
487
|
+
return path.join(this.stateDir, `${this.key}.lock`);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Acquire tokens from the cross-process bucket (async - waits if insufficient).
|
|
491
|
+
*/
|
|
492
|
+
async acquire(tokens = 1) {
|
|
493
|
+
await this.ensureStateDir();
|
|
494
|
+
const deadline = Date.now() + this.maxWaitMs;
|
|
495
|
+
while (Date.now() < deadline) {
|
|
496
|
+
const acquired = await this.tryAcquireFromFile(tokens);
|
|
497
|
+
if (acquired.success) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
const waitMs = Math.min(acquired.waitMs ?? 500, deadline - Date.now());
|
|
501
|
+
if (waitMs <= 0) break;
|
|
502
|
+
await timersSetTimeout(waitMs);
|
|
503
|
+
}
|
|
504
|
+
throw new Error(
|
|
505
|
+
`FileTokenBucket(${this.key}): timed out waiting for ${tokens} token(s) after ${this.maxWaitMs}ms`
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Try to acquire tokens without waiting (non-blocking).
|
|
510
|
+
* Falls back to in-memory bucket for synchronous operation.
|
|
511
|
+
*/
|
|
512
|
+
tryAcquire(tokens = 1) {
|
|
513
|
+
this.inMemoryTotalRequests += 1;
|
|
514
|
+
this.refillInMemory();
|
|
515
|
+
if (this.inMemoryTokens >= tokens) {
|
|
516
|
+
this.inMemoryTokens -= tokens;
|
|
517
|
+
return true;
|
|
518
|
+
}
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Get current metrics (in-memory snapshot).
|
|
523
|
+
*/
|
|
524
|
+
getMetrics() {
|
|
525
|
+
this.refillInMemory();
|
|
526
|
+
return {
|
|
527
|
+
availableTokens: this.inMemoryTokens,
|
|
528
|
+
bucketSize: this.bucketSize,
|
|
529
|
+
refillRate: this.refillRate,
|
|
530
|
+
lastRefillTime: this.inMemoryLastRefill,
|
|
531
|
+
totalWaitTimeMs: this.inMemoryTotalWaitMs,
|
|
532
|
+
totalRequests: this.inMemoryTotalRequests
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Reset both in-memory and file-based state.
|
|
537
|
+
* WARNING: Not safe to call during concurrent acquire/release operations.
|
|
538
|
+
* Only use when no other callers are active (e.g., between test runs).
|
|
539
|
+
*/
|
|
540
|
+
reset() {
|
|
541
|
+
this.inMemoryTokens = this.initialTokens;
|
|
542
|
+
this.inMemoryLastRefill = Date.now();
|
|
543
|
+
this.inMemoryTotalWaitMs = 0;
|
|
544
|
+
this.inMemoryTotalRequests = 0;
|
|
545
|
+
fs.unlink(this.statePath).catch(() => {
|
|
546
|
+
});
|
|
547
|
+
fs.unlink(this.lockPath).catch(() => {
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
// --- Internal file-based operations ---
|
|
551
|
+
async ensureStateDir() {
|
|
552
|
+
await fs.mkdir(this.stateDir, { recursive: true });
|
|
553
|
+
}
|
|
554
|
+
async tryAcquireFromFile(tokens) {
|
|
555
|
+
let lockHandle;
|
|
556
|
+
try {
|
|
557
|
+
lockHandle = await this.acquireLock();
|
|
558
|
+
if (!lockHandle) {
|
|
559
|
+
return { success: false, waitMs: LOCK_RETRY_INTERVAL_MS };
|
|
560
|
+
}
|
|
561
|
+
const state = await this.readState();
|
|
562
|
+
this.refillState(state);
|
|
563
|
+
state.totalRequests += 1;
|
|
564
|
+
if (state.availableTokens >= tokens) {
|
|
565
|
+
state.availableTokens -= tokens;
|
|
566
|
+
await this.writeState(state);
|
|
567
|
+
this.inMemoryTokens = state.availableTokens;
|
|
568
|
+
this.inMemoryLastRefill = state.lastRefillTime;
|
|
569
|
+
this.inMemoryTotalRequests = state.totalRequests;
|
|
570
|
+
this.inMemoryTotalWaitMs = state.totalWaitTimeMs;
|
|
571
|
+
return { success: true };
|
|
572
|
+
}
|
|
573
|
+
const tokensNeeded = tokens - state.availableTokens;
|
|
574
|
+
const waitMs = Math.ceil(tokensNeeded / this.refillRate * 1e3);
|
|
575
|
+
state.totalWaitTimeMs += waitMs;
|
|
576
|
+
await this.writeState(state);
|
|
577
|
+
return { success: false, waitMs };
|
|
578
|
+
} finally {
|
|
579
|
+
await this.releaseLock(lockHandle);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
async acquireLock() {
|
|
583
|
+
try {
|
|
584
|
+
const lockStat = await fs.stat(this.lockPath);
|
|
585
|
+
if (Date.now() - lockStat.mtimeMs > this.staleLockThresholdMs) {
|
|
586
|
+
await fs.unlink(this.lockPath).catch(() => {
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
} catch {
|
|
590
|
+
}
|
|
591
|
+
try {
|
|
592
|
+
const handle = await fs.open(this.lockPath, "wx");
|
|
593
|
+
await handle.write(`${process.pid}
|
|
594
|
+
`);
|
|
595
|
+
return handle;
|
|
596
|
+
} catch {
|
|
597
|
+
return void 0;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
async releaseLock(handle) {
|
|
601
|
+
if (handle) {
|
|
602
|
+
await handle.close().catch(() => {
|
|
603
|
+
});
|
|
604
|
+
await fs.unlink(this.lockPath).catch(() => {
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
async readState() {
|
|
609
|
+
try {
|
|
610
|
+
const content = await fs.readFile(this.statePath, "utf-8");
|
|
611
|
+
const parsed = JSON.parse(content);
|
|
612
|
+
if (typeof parsed.availableTokens === "number" && typeof parsed.lastRefillTime === "number") {
|
|
613
|
+
return parsed;
|
|
614
|
+
}
|
|
615
|
+
} catch {
|
|
616
|
+
}
|
|
617
|
+
return {
|
|
618
|
+
availableTokens: this.initialTokens,
|
|
619
|
+
lastRefillTime: Date.now(),
|
|
620
|
+
totalWaitTimeMs: 0,
|
|
621
|
+
totalRequests: 0
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
async writeState(state) {
|
|
625
|
+
const content = JSON.stringify(state);
|
|
626
|
+
const fd = await fs.open(this.statePath, "w");
|
|
627
|
+
try {
|
|
628
|
+
await fd.write(content);
|
|
629
|
+
await fd.datasync();
|
|
630
|
+
} finally {
|
|
631
|
+
await fd.close();
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
refillState(state) {
|
|
635
|
+
const now = Date.now();
|
|
636
|
+
const elapsedMs = now - state.lastRefillTime;
|
|
637
|
+
const elapsedSeconds = elapsedMs / 1e3;
|
|
638
|
+
const tokensToAdd = elapsedSeconds * this.refillRate;
|
|
639
|
+
if (tokensToAdd > 0) {
|
|
640
|
+
state.availableTokens = Math.min(this.bucketSize, state.availableTokens + tokensToAdd);
|
|
641
|
+
state.lastRefillTime = now;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
refillInMemory() {
|
|
645
|
+
const now = Date.now();
|
|
646
|
+
const elapsedMs = now - this.inMemoryLastRefill;
|
|
647
|
+
const elapsedSeconds = elapsedMs / 1e3;
|
|
648
|
+
const tokensToAdd = elapsedSeconds * this.refillRate;
|
|
649
|
+
if (tokensToAdd > 0) {
|
|
650
|
+
this.inMemoryTokens = Math.min(this.bucketSize, this.inMemoryTokens + tokensToAdd);
|
|
651
|
+
this.inMemoryLastRefill = now;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
// src/core/safety/rate-limiter-factory.ts
|
|
657
|
+
import * as fsSync from "fs";
|
|
658
|
+
import path2 from "path";
|
|
659
|
+
|
|
660
|
+
// src/core/safety/token-bucket.ts
|
|
661
|
+
var TokenBucket = class {
|
|
662
|
+
options;
|
|
663
|
+
availableTokens;
|
|
664
|
+
lastRefillTime;
|
|
665
|
+
totalWaitTimeMs = 0;
|
|
666
|
+
totalRequests = 0;
|
|
667
|
+
_queue = Promise.resolve();
|
|
668
|
+
queuedAcquires = 0;
|
|
669
|
+
generation = 0;
|
|
670
|
+
constructor(options) {
|
|
671
|
+
this.options = {
|
|
672
|
+
bucketSize: options.bucketSize,
|
|
673
|
+
refillRate: options.refillRate,
|
|
674
|
+
initialTokens: options.initialTokens ?? options.bucketSize
|
|
675
|
+
};
|
|
676
|
+
this.availableTokens = this.options.initialTokens;
|
|
677
|
+
this.lastRefillTime = Date.now();
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Acquire tokens from the bucket (async - waits if insufficient tokens)
|
|
681
|
+
* @param tokens - Number of tokens to acquire (default: 1)
|
|
682
|
+
* @returns Promise that resolves when tokens are acquired
|
|
683
|
+
*/
|
|
684
|
+
async acquire(tokens = 1) {
|
|
685
|
+
if (tokens > this.options.bucketSize) {
|
|
686
|
+
throw new Error(
|
|
687
|
+
`TokenBucket cannot acquire ${tokens} token(s); bucket size is ${this.options.bucketSize}`
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
const generationAtEnqueue = this.generation;
|
|
691
|
+
const execute = async () => {
|
|
692
|
+
if (generationAtEnqueue !== this.generation) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
this.prepareAcquire();
|
|
696
|
+
if (this.availableTokens >= tokens) {
|
|
697
|
+
this.availableTokens -= tokens;
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
const tokensNeeded = tokens - this.availableTokens;
|
|
701
|
+
if (this.options.refillRate <= 0) {
|
|
702
|
+
throw new Error(
|
|
703
|
+
`TokenBucket cannot acquire ${tokens} token(s); refill rate is zero or negative`
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
const waitTimeMs = tokensNeeded / this.options.refillRate * 1e3;
|
|
707
|
+
this.totalWaitTimeMs += waitTimeMs;
|
|
708
|
+
await this.sleep(waitTimeMs);
|
|
709
|
+
if (generationAtEnqueue !== this.generation) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
this.refreshState();
|
|
713
|
+
this.availableTokens = Math.max(0, this.availableTokens - tokens);
|
|
714
|
+
};
|
|
715
|
+
this.queuedAcquires++;
|
|
716
|
+
const next = this.queuedAcquires === 1 ? execute() : this._queue.then(execute, execute);
|
|
717
|
+
this._queue = next.finally(() => {
|
|
718
|
+
if (this.queuedAcquires > 0) {
|
|
719
|
+
this.queuedAcquires--;
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
return this._queue;
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Try to acquire tokens without waiting (non-blocking)
|
|
726
|
+
* @param tokens - Number of tokens to acquire (default: 1)
|
|
727
|
+
* @returns true if tokens were acquired, false if insufficient tokens
|
|
728
|
+
*/
|
|
729
|
+
tryAcquire(tokens = 1) {
|
|
730
|
+
if (tokens > this.options.bucketSize) {
|
|
731
|
+
return false;
|
|
732
|
+
}
|
|
733
|
+
if (this.queuedAcquires > 0) {
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
this.prepareAcquire();
|
|
737
|
+
if (this.availableTokens >= tokens) {
|
|
738
|
+
this.availableTokens -= tokens;
|
|
739
|
+
return true;
|
|
740
|
+
}
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Get current token bucket metrics
|
|
745
|
+
*/
|
|
746
|
+
getMetrics() {
|
|
747
|
+
this.refreshState();
|
|
748
|
+
return {
|
|
749
|
+
availableTokens: this.availableTokens,
|
|
750
|
+
bucketSize: this.options.bucketSize,
|
|
751
|
+
refillRate: this.options.refillRate,
|
|
752
|
+
lastRefillTime: this.lastRefillTime,
|
|
753
|
+
totalWaitTimeMs: this.totalWaitTimeMs,
|
|
754
|
+
totalRequests: this.totalRequests
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Reset the token bucket to initial state (for testing)
|
|
759
|
+
*/
|
|
760
|
+
reset() {
|
|
761
|
+
this.generation++;
|
|
762
|
+
this._queue = Promise.resolve();
|
|
763
|
+
this.queuedAcquires = 0;
|
|
764
|
+
this.availableTokens = this.options.initialTokens;
|
|
765
|
+
this.lastRefillTime = Date.now();
|
|
766
|
+
this.totalWaitTimeMs = 0;
|
|
767
|
+
this.totalRequests = 0;
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Get current number of available tokens
|
|
771
|
+
*/
|
|
772
|
+
getAvailableTokens() {
|
|
773
|
+
this.refreshState();
|
|
774
|
+
return this.availableTokens;
|
|
775
|
+
}
|
|
776
|
+
refreshState() {
|
|
777
|
+
const now = Date.now();
|
|
778
|
+
this.refillTokens(now);
|
|
779
|
+
}
|
|
780
|
+
prepareAcquire() {
|
|
781
|
+
this.totalRequests++;
|
|
782
|
+
this.refreshState();
|
|
783
|
+
}
|
|
784
|
+
refillTokens(now) {
|
|
785
|
+
const elapsedMs = now - this.lastRefillTime;
|
|
786
|
+
const elapsedSeconds = elapsedMs / 1e3;
|
|
787
|
+
const tokensToAdd = elapsedSeconds * this.options.refillRate;
|
|
788
|
+
if (tokensToAdd > 0) {
|
|
789
|
+
this.availableTokens = Math.min(this.options.bucketSize, this.availableTokens + tokensToAdd);
|
|
790
|
+
this.lastRefillTime = now;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
sleep(ms) {
|
|
794
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
var TokenBucketError = class extends Error {
|
|
798
|
+
availableTokens;
|
|
799
|
+
requiredTokens;
|
|
800
|
+
metrics;
|
|
801
|
+
constructor(message, options) {
|
|
802
|
+
super(message);
|
|
803
|
+
this.name = "TokenBucketError";
|
|
804
|
+
this.availableTokens = options.availableTokens;
|
|
805
|
+
this.requiredTokens = options.requiredTokens;
|
|
806
|
+
this.metrics = options.metrics;
|
|
807
|
+
}
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
// src/core/safety/rate-limiter-registry.ts
|
|
811
|
+
var RateLimiterRegistry = class {
|
|
812
|
+
buckets = /* @__PURE__ */ new Map();
|
|
813
|
+
defaultOptions;
|
|
814
|
+
bucketFactory;
|
|
815
|
+
/**
|
|
816
|
+
* Creates a new rate limiter registry
|
|
817
|
+
* @param defaultOptions - Default options to apply to all token buckets
|
|
818
|
+
* @param bucketFactory - Optional factory for creating buckets (defaults to in-memory TokenBucket)
|
|
819
|
+
*/
|
|
820
|
+
constructor(defaultOptions = {}, bucketFactory) {
|
|
821
|
+
this.defaultOptions = defaultOptions;
|
|
822
|
+
this.bucketFactory = bucketFactory ?? ((_key, opts) => new TokenBucket(opts));
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Gets or creates a token bucket for the specified provider and optional model.
|
|
826
|
+
* @param provider - The provider name (e.g., 'gemini', 'claude')
|
|
827
|
+
* @param model - Optional model name (e.g., 'gpt-4', 'claude-3-opus')
|
|
828
|
+
* @param options - Optional token bucket configuration (merged with defaults)
|
|
829
|
+
* @returns The token bucket instance for this provider/model combination
|
|
830
|
+
*/
|
|
831
|
+
getBucket(provider, model, options = {}) {
|
|
832
|
+
const key = model ? `${provider}:${model}` : provider;
|
|
833
|
+
let bucket = this.buckets.get(key);
|
|
834
|
+
if (!bucket) {
|
|
835
|
+
const mergedOptions = {
|
|
836
|
+
bucketSize: 60,
|
|
837
|
+
refillRate: 1,
|
|
838
|
+
...this.defaultOptions,
|
|
839
|
+
...options
|
|
840
|
+
};
|
|
841
|
+
bucket = this.bucketFactory(key, mergedOptions);
|
|
842
|
+
this.buckets.set(key, bucket);
|
|
843
|
+
}
|
|
844
|
+
return bucket;
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Resets the token bucket for a specific provider/model combination.
|
|
848
|
+
* @param provider - The provider name
|
|
849
|
+
* @param model - Optional model name
|
|
850
|
+
*/
|
|
851
|
+
resetBucket(provider, model) {
|
|
852
|
+
const key = model ? `${provider}:${model}` : provider;
|
|
853
|
+
const bucket = this.buckets.get(key);
|
|
854
|
+
if (bucket) {
|
|
855
|
+
bucket.reset();
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Removes the token bucket for a specific provider/model combination.
|
|
860
|
+
* This completely removes the bucket from the registry.
|
|
861
|
+
* @param provider - The provider name
|
|
862
|
+
* @param model - Optional model name
|
|
863
|
+
*/
|
|
864
|
+
removeBucket(provider, model) {
|
|
865
|
+
const key = model ? `${provider}:${model}` : provider;
|
|
866
|
+
this.buckets.delete(key);
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Resets all token buckets in the registry.
|
|
870
|
+
*/
|
|
871
|
+
resetAllBuckets() {
|
|
872
|
+
for (const bucket of this.buckets.values()) {
|
|
873
|
+
bucket.reset();
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Removes all token buckets from the registry.
|
|
878
|
+
*/
|
|
879
|
+
clear() {
|
|
880
|
+
this.buckets.clear();
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Gets all token buckets in the registry.
|
|
884
|
+
* @returns Map of provider:model keys to token buckets
|
|
885
|
+
*/
|
|
886
|
+
getAllBuckets() {
|
|
887
|
+
return this.buckets;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Checks if a token bucket exists for the specified provider/model combination.
|
|
891
|
+
* @param provider - The provider name
|
|
892
|
+
* @param model - Optional model name
|
|
893
|
+
* @returns true if a bucket exists, false otherwise
|
|
894
|
+
*/
|
|
895
|
+
hasBucket(provider, model) {
|
|
896
|
+
const key = model ? `${provider}:${model}` : provider;
|
|
897
|
+
return this.buckets.has(key);
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Gets the number of registered token buckets.
|
|
901
|
+
* @returns The count of token buckets
|
|
902
|
+
*/
|
|
903
|
+
get size() {
|
|
904
|
+
return this.buckets.size;
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
// src/core/safety/rate-limiter-factory.ts
|
|
909
|
+
var DEFAULT_RATE_LIMITS = {
|
|
910
|
+
bucketSize: 10,
|
|
911
|
+
// 10 request burst
|
|
912
|
+
refillRate: 0.83
|
|
913
|
+
// ~50 RPM
|
|
914
|
+
};
|
|
915
|
+
function resolveRefillRate(entry) {
|
|
916
|
+
if (typeof entry?.refill_rate === "number" && Number.isFinite(entry.refill_rate)) {
|
|
917
|
+
return entry.refill_rate;
|
|
918
|
+
}
|
|
919
|
+
if (typeof entry?.rpm === "number" && Number.isFinite(entry.rpm)) {
|
|
920
|
+
return entry.rpm / 60;
|
|
921
|
+
}
|
|
922
|
+
return DEFAULT_RATE_LIMITS.refillRate;
|
|
923
|
+
}
|
|
924
|
+
function configToOptions(config) {
|
|
925
|
+
if (!config) {
|
|
926
|
+
return DEFAULT_RATE_LIMITS;
|
|
927
|
+
}
|
|
928
|
+
const entry = config.default || {
|
|
929
|
+
rpm: config.rpm,
|
|
930
|
+
bucket_size: config.bucket_size,
|
|
931
|
+
refill_rate: config.refill_rate
|
|
932
|
+
};
|
|
933
|
+
return {
|
|
934
|
+
bucketSize: entry.bucket_size ?? DEFAULT_RATE_LIMITS.bucketSize,
|
|
935
|
+
refillRate: resolveRefillRate(entry)
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
function shouldUseDistributedRateLimiting() {
|
|
939
|
+
if (process.env.BUILD_DISTRIBUTED_RATE_LIMIT === "1") {
|
|
940
|
+
return true;
|
|
941
|
+
}
|
|
942
|
+
const agents = Number.parseInt(process.env.BUILD_AGENTS ?? "1", 10);
|
|
943
|
+
return !Number.isNaN(agents) && agents > 1;
|
|
944
|
+
}
|
|
945
|
+
function getRateLimitStateDir() {
|
|
946
|
+
return path2.join(resolveBuildRoot(), ".build-project", "rate-limits");
|
|
947
|
+
}
|
|
948
|
+
function createFileBucketFactory() {
|
|
949
|
+
const stateDir = getRateLimitStateDir();
|
|
950
|
+
return (key, options) => new FileTokenBucket(key, { ...options, stateDir });
|
|
951
|
+
}
|
|
952
|
+
function createRateLimiterFromConfig(providerId) {
|
|
953
|
+
let config = null;
|
|
954
|
+
let defaultOptions = DEFAULT_RATE_LIMITS;
|
|
955
|
+
try {
|
|
956
|
+
const registryConfig = ProviderRegistry.load();
|
|
957
|
+
if (registryConfig.defaults?.rate_limits) {
|
|
958
|
+
defaultOptions = configToOptions(registryConfig.defaults.rate_limits);
|
|
959
|
+
}
|
|
960
|
+
const providerConfig = providerId ? registryConfig.providers[providerId] : void 0;
|
|
961
|
+
if (providerConfig?.rate_limits) {
|
|
962
|
+
defaultOptions = configToOptions(providerConfig.rate_limits);
|
|
963
|
+
}
|
|
964
|
+
config = registryConfig;
|
|
965
|
+
} catch {
|
|
966
|
+
}
|
|
967
|
+
const bucketFactory = shouldUseDistributedRateLimiting() ? createFileBucketFactory() : void 0;
|
|
968
|
+
const registry = new RateLimiterRegistry(defaultOptions, bucketFactory);
|
|
969
|
+
if (config) {
|
|
970
|
+
const registryConfig = config;
|
|
971
|
+
for (const [provider, providerConfig] of Object.entries(registryConfig.providers)) {
|
|
972
|
+
if (providerConfig.rate_limits?.models) {
|
|
973
|
+
for (const [model, modelConfig] of Object.entries(providerConfig.rate_limits.models)) {
|
|
974
|
+
registry.getBucket(provider, model, {
|
|
975
|
+
bucketSize: modelConfig.bucket_size,
|
|
976
|
+
refillRate: resolveRefillRate(modelConfig)
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
return registry;
|
|
983
|
+
}
|
|
984
|
+
function getRateLimitOptions(providerId, modelId) {
|
|
985
|
+
try {
|
|
986
|
+
const config = ProviderRegistry.load();
|
|
987
|
+
const providerConfig = config.providers[providerId];
|
|
988
|
+
const rateLimits = providerConfig?.rate_limits;
|
|
989
|
+
const modelConfig = modelId ? rateLimits?.models?.[modelId] : void 0;
|
|
990
|
+
if (modelConfig) {
|
|
991
|
+
return {
|
|
992
|
+
bucketSize: modelConfig.bucket_size,
|
|
993
|
+
refillRate: resolveRefillRate(modelConfig)
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
if (rateLimits) {
|
|
997
|
+
return configToOptions(rateLimits);
|
|
998
|
+
}
|
|
999
|
+
if (config.defaults?.rate_limits) {
|
|
1000
|
+
return configToOptions(config.defaults.rate_limits);
|
|
1001
|
+
}
|
|
1002
|
+
} catch {
|
|
1003
|
+
}
|
|
1004
|
+
return DEFAULT_RATE_LIMITS;
|
|
1005
|
+
}
|
|
1006
|
+
var globalRegistry = null;
|
|
1007
|
+
function getGlobalRateLimiterRegistry() {
|
|
1008
|
+
if (!globalRegistry) {
|
|
1009
|
+
globalRegistry = createRateLimiterFromConfig();
|
|
1010
|
+
}
|
|
1011
|
+
return globalRegistry;
|
|
1012
|
+
}
|
|
1013
|
+
function clearGlobalRateLimiterRegistryCache() {
|
|
1014
|
+
globalRegistry = null;
|
|
1015
|
+
}
|
|
1016
|
+
registerProviderRegistryReloadInvalidator(clearGlobalRateLimiterRegistryCache);
|
|
1017
|
+
function resetGlobalRateLimiterRegistry() {
|
|
1018
|
+
if (globalRegistry) {
|
|
1019
|
+
globalRegistry.clear();
|
|
1020
|
+
globalRegistry = null;
|
|
1021
|
+
}
|
|
1022
|
+
if (shouldUseDistributedRateLimiting()) {
|
|
1023
|
+
const stateDir = getRateLimitStateDir();
|
|
1024
|
+
try {
|
|
1025
|
+
if (fsSync.existsSync(stateDir)) {
|
|
1026
|
+
for (const entry of fsSync.readdirSync(stateDir)) {
|
|
1027
|
+
if (entry.endsWith(".json")) {
|
|
1028
|
+
fsSync.rmSync(path2.join(stateDir, entry), { force: true });
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
} catch {
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// src/core/safety/index.ts
|
|
1038
|
+
async function acquireRateLimitToken(provider, model, options) {
|
|
1039
|
+
const registry = getGlobalRateLimiterRegistry();
|
|
1040
|
+
const isNewBucket = !registry.hasBucket(provider, model);
|
|
1041
|
+
const bucket = registry.getBucket(provider, model, options ?? {});
|
|
1042
|
+
if (isNewBucket && options != null && (typeof options.bucketSize === "number" || typeof options.refillRate === "number")) {
|
|
1043
|
+
logDebug(
|
|
1044
|
+
"rate-limiter",
|
|
1045
|
+
`Created rate limit bucket provider=${provider} model=${model ?? "(default)"} bucketSize=${String(options.bucketSize)} refillRate=${String(options.refillRate)}`
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
await bucket.acquire();
|
|
1049
|
+
}
|
|
1050
|
+
var globalRegistry2;
|
|
1051
|
+
var scopedRegistries = /* @__PURE__ */ new Map();
|
|
1052
|
+
function getOrCreateGlobalRegistry() {
|
|
1053
|
+
if (!globalRegistry2) {
|
|
1054
|
+
globalRegistry2 = new CircuitBreakerRegistry();
|
|
1055
|
+
}
|
|
1056
|
+
return globalRegistry2;
|
|
1057
|
+
}
|
|
1058
|
+
function getScopedRegistry(scope) {
|
|
1059
|
+
let registry = scopedRegistries.get(scope);
|
|
1060
|
+
if (!registry) {
|
|
1061
|
+
registry = new CircuitBreakerRegistry();
|
|
1062
|
+
scopedRegistries.set(scope, registry);
|
|
1063
|
+
}
|
|
1064
|
+
return registry;
|
|
1065
|
+
}
|
|
1066
|
+
function clearScopedRegistry(scope) {
|
|
1067
|
+
scopedRegistries.delete(scope);
|
|
1068
|
+
}
|
|
1069
|
+
async function executeWithCircuitBreaker(providerName, fn, options = {}, scope) {
|
|
1070
|
+
const registry = scope ? getScopedRegistry(scope) : getOrCreateGlobalRegistry();
|
|
1071
|
+
const breaker = registry.getBreaker(providerName, options);
|
|
1072
|
+
return await breaker.execute(fn);
|
|
1073
|
+
}
|
|
1074
|
+
function resetAllCircuitBreakers() {
|
|
1075
|
+
getOrCreateGlobalRegistry().clear();
|
|
1076
|
+
}
|
|
1077
|
+
function _getGlobalRegistry() {
|
|
1078
|
+
return getOrCreateGlobalRegistry();
|
|
1079
|
+
}
|
|
1080
|
+
function _clearGlobalRegistry() {
|
|
1081
|
+
getOrCreateGlobalRegistry().clear();
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
export {
|
|
1085
|
+
CircuitState,
|
|
1086
|
+
CircuitBreaker,
|
|
1087
|
+
CircuitBreakerError,
|
|
1088
|
+
createCircuitBreakerOptions,
|
|
1089
|
+
CircuitBreakerRegistry,
|
|
1090
|
+
FileTokenBucket,
|
|
1091
|
+
TokenBucket,
|
|
1092
|
+
TokenBucketError,
|
|
1093
|
+
RateLimiterRegistry,
|
|
1094
|
+
createRateLimiterFromConfig,
|
|
1095
|
+
getRateLimitOptions,
|
|
1096
|
+
getGlobalRateLimiterRegistry,
|
|
1097
|
+
resetGlobalRateLimiterRegistry,
|
|
1098
|
+
acquireRateLimitToken,
|
|
1099
|
+
getScopedRegistry,
|
|
1100
|
+
clearScopedRegistry,
|
|
1101
|
+
executeWithCircuitBreaker,
|
|
1102
|
+
resetAllCircuitBreakers,
|
|
1103
|
+
_getGlobalRegistry,
|
|
1104
|
+
_clearGlobalRegistry
|
|
1105
|
+
};
|
|
1106
|
+
//# sourceMappingURL=chunk-JVHGMURQ.js.map
|