@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.
Files changed (878) hide show
  1. package/.build-project/providers/catalog.json +13951 -0
  2. package/.build-project/providers/pricing.json +1978 -0
  3. package/.build-project/providers/registry.json +4103 -0
  4. package/.github/SECURITY.md +75 -0
  5. package/.nvmrc +1 -0
  6. package/CHANGELOG.md +661 -0
  7. package/CODE_OF_CONDUCT.md +44 -0
  8. package/CONTRIBUTING.md +24 -0
  9. package/INSTALL.md +623 -0
  10. package/LICENSE +21 -0
  11. package/README.md +118 -2
  12. package/THIRD_PARTY_NOTICES.txt +26 -0
  13. package/dist/ai-judge-UE5UOYOO.js +191 -0
  14. package/dist/allowlist-grounding-KPLN6NC5.js +16 -0
  15. package/dist/allowlist-utils-MZZKKXRD.js +31 -0
  16. package/dist/apply-completion-mode-EM37UZHB.js +110 -0
  17. package/dist/artifact-migrator-WPACNSEP.js +276 -0
  18. package/dist/ask-2OZ4JFQR.js +176 -0
  19. package/dist/auth-6UKBTJUQ.js +185 -0
  20. package/dist/auth-H5KJL6HL.js +165 -0
  21. package/dist/auth-LVJRJDMU.js +12 -0
  22. package/dist/auth-NHZOCNRR.js +94 -0
  23. package/dist/auth-PBXHWXGW.js +95 -0
  24. package/dist/auth-T7Y5DCAH.js +91 -0
  25. package/dist/auth-TVVKCHQW.js +13 -0
  26. package/dist/auth-UHB2UCSS.js +97 -0
  27. package/dist/auth-VACA3VUL.js +98 -0
  28. package/dist/auth-VVLC77S3.js +44 -0
  29. package/dist/auth-liveness-XO4AGDDD.js +53 -0
  30. package/dist/autoloop-cleanup-SI3VGAAR.js +106 -0
  31. package/dist/autoloop-evidence-gates-J5GG5YQB.js +39 -0
  32. package/dist/autoloop-gate-policy-SUNAEP6Q.js +169 -0
  33. package/dist/autoloop-helpers-VQGQNTT6.js +52 -0
  34. package/dist/autoloop-ledger-P6TIDP7C.js +96 -0
  35. package/dist/autoloop-ledger-subscriber-HFAGOZXH.js +161 -0
  36. package/dist/autoloop-run-defaults-GWGZBNT7.js +27 -0
  37. package/dist/autoloop-run-lock-GBWRM5A2.js +197 -0
  38. package/dist/autoloop-success-C32QVWOP.js +93 -0
  39. package/dist/autoloop-termination-summary-GI6IBQWD.js +58 -0
  40. package/dist/autoloop-trajectory-AMKSQISD.js +70 -0
  41. package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
  42. package/dist/automatic-branch-cleanup-R62X2C5O.js +49 -0
  43. package/dist/autonomous-loop-controller-2WL363LW.js +4386 -0
  44. package/dist/backend-YUTFDZXZ.js +30 -0
  45. package/dist/background-executor-Z3ODTMD7.js +260 -0
  46. package/dist/backlog-75QPEAMW.js +403 -0
  47. package/dist/backlog-execution-intent-GWUV5TUK.js +19 -0
  48. package/dist/backup-active-store-XHWLN34M.js +16 -0
  49. package/dist/backup-machine-stores-UI4LTJOY.js +251 -0
  50. package/dist/backup-telemetry-db-Z4ICYCNW.js +26 -0
  51. package/dist/branch-archive-manager-FMSQ7YJF.js +18 -0
  52. package/dist/branch-cleanup-manager-ST6FJGND.js +35 -0
  53. package/dist/build-gate-7NKWPY62.js +68 -0
  54. package/dist/build-root-S7DINODY.js +18 -0
  55. package/dist/change-summary-R6CB6VXJ.js +50 -0
  56. package/dist/chunk-24MNKKOM.js +173 -0
  57. package/dist/chunk-2H6VZFIO.js +235 -0
  58. package/dist/chunk-2JIX3EKV.js +39 -0
  59. package/dist/chunk-2KO7HVZM.js +106 -0
  60. package/dist/chunk-2L36U25O.js +100 -0
  61. package/dist/chunk-2NMNFUQA.js +475 -0
  62. package/dist/chunk-2OUAEH67.js +83 -0
  63. package/dist/chunk-2VLJUXJU.js +115 -0
  64. package/dist/chunk-2VUEDIUM.js +77 -0
  65. package/dist/chunk-2Y2IIHPI.js +430 -0
  66. package/dist/chunk-2YRG3LHZ.js +220 -0
  67. package/dist/chunk-2Z5Q3SUY.js +65 -0
  68. package/dist/chunk-32IYXIE5.js +873 -0
  69. package/dist/chunk-33IGPPUI.js +292 -0
  70. package/dist/chunk-352PCJLK.js +283 -0
  71. package/dist/chunk-35J4NE6S.js +226 -0
  72. package/dist/chunk-3C7WBIVK.js +1016 -0
  73. package/dist/chunk-3H3EY6U7.js +1225 -0
  74. package/dist/chunk-3H4MWYIC.js +198 -0
  75. package/dist/chunk-3HHWQR3N.js +2479 -0
  76. package/dist/chunk-3JKNRYEE.js +14 -0
  77. package/dist/chunk-3LECCYZY.js +128 -0
  78. package/dist/chunk-3LOY6YZI.js +852 -0
  79. package/dist/chunk-3M57DADF.js +44 -0
  80. package/dist/chunk-3NOTLVLG.js +3803 -0
  81. package/dist/chunk-3OPP2OZB.js +1480 -0
  82. package/dist/chunk-3P5IN5E7.js +9 -0
  83. package/dist/chunk-3PL22IYZ.js +20 -0
  84. package/dist/chunk-3REDAJUJ.js +14 -0
  85. package/dist/chunk-3S2R4XJI.js +203 -0
  86. package/dist/chunk-3UBZI5DW.js +61 -0
  87. package/dist/chunk-3VV5OBGG.js +308 -0
  88. package/dist/chunk-3WY5TU2O.js +823 -0
  89. package/dist/chunk-43OKHTW4.js +82 -0
  90. package/dist/chunk-45KUJBDI.js +112 -0
  91. package/dist/chunk-47X5LM7B.js +224 -0
  92. package/dist/chunk-4B6FQJ77.js +268 -0
  93. package/dist/chunk-4BTDUT2S.js +42 -0
  94. package/dist/chunk-4DJL2VXA.js +24 -0
  95. package/dist/chunk-4EBSXZ73.js +48 -0
  96. package/dist/chunk-4QKP6I4C.js +294 -0
  97. package/dist/chunk-4U6XK2DG.js +300 -0
  98. package/dist/chunk-4UMRUFBD.js +132 -0
  99. package/dist/chunk-4US4SYJ4.js +569 -0
  100. package/dist/chunk-4ZPLWEZO.js +154 -0
  101. package/dist/chunk-56WPYDJH.js +624 -0
  102. package/dist/chunk-57WRCJJW.js +50 -0
  103. package/dist/chunk-5AW4RMNG.js +24 -0
  104. package/dist/chunk-5EQN56OZ.js +155 -0
  105. package/dist/chunk-5F43TUIN.js +38 -0
  106. package/dist/chunk-5FKHIKTS.js +115 -0
  107. package/dist/chunk-5HDP7XZG.js +91 -0
  108. package/dist/chunk-5KQETTNS.js +152 -0
  109. package/dist/chunk-5PDVN2KO.js +498 -0
  110. package/dist/chunk-5UBIFVRD.js +509 -0
  111. package/dist/chunk-5YDE3Q62.js +46 -0
  112. package/dist/chunk-626AJVMU.js +302 -0
  113. package/dist/chunk-633XZ7UF.js +3583 -0
  114. package/dist/chunk-63DHNHGA.js +236 -0
  115. package/dist/chunk-666656AR.js +568 -0
  116. package/dist/chunk-67YRJPJO.js +19 -0
  117. package/dist/chunk-6CAU7VBA.js +20 -0
  118. package/dist/chunk-6CB3KJRY.js +21 -0
  119. package/dist/chunk-6DBMALXL.js +29 -0
  120. package/dist/chunk-6E25C4IA.js +269 -0
  121. package/dist/chunk-6FIBNIQU.js +73 -0
  122. package/dist/chunk-6G57FYBV.js +189 -0
  123. package/dist/chunk-6KZKRTG3.js +4885 -0
  124. package/dist/chunk-6LAH2UV2.js +525 -0
  125. package/dist/chunk-6PZY2TTU.js +921 -0
  126. package/dist/chunk-6T6NHXK4.js +230 -0
  127. package/dist/chunk-6TBEX4R4.js +432 -0
  128. package/dist/chunk-6TRD7TEE.js +911 -0
  129. package/dist/chunk-6XCP2RAI.js +47 -0
  130. package/dist/chunk-726G6WDL.js +351 -0
  131. package/dist/chunk-75EMT7BF.js +616 -0
  132. package/dist/chunk-762ACDZJ.js +4696 -0
  133. package/dist/chunk-77I6G4CO.js +1 -0
  134. package/dist/chunk-7DJ6SQH3.js +510 -0
  135. package/dist/chunk-7HPCIOMA.js +1383 -0
  136. package/dist/chunk-7HYBSRPZ.js +17503 -0
  137. package/dist/chunk-7KBEOPVB.js +73 -0
  138. package/dist/chunk-7LHJDJB3.js +2222 -0
  139. package/dist/chunk-7NVJMH52.js +306 -0
  140. package/dist/chunk-7RMARDVH.js +33 -0
  141. package/dist/chunk-7SEWU4QG.js +36 -0
  142. package/dist/chunk-7TUTZTI2.js +911 -0
  143. package/dist/chunk-7VBDFPUM.js +340 -0
  144. package/dist/chunk-7VRJHTGZ.js +6406 -0
  145. package/dist/chunk-7YAOUUKK.js +493 -0
  146. package/dist/chunk-AAAODV76.js +860 -0
  147. package/dist/chunk-AB4HUJVQ.js +339 -0
  148. package/dist/chunk-AEQWV746.js +611 -0
  149. package/dist/chunk-AHU3FKPA.js +11639 -0
  150. package/dist/chunk-AISTV5XU.js +226 -0
  151. package/dist/chunk-AJBTKGJZ.js +48 -0
  152. package/dist/chunk-AJJNW7XT.js +248 -0
  153. package/dist/chunk-AJN5Y5YZ.js +160 -0
  154. package/dist/chunk-ALDTFNZ3.js +150 -0
  155. package/dist/chunk-ARARVIZK.js +281 -0
  156. package/dist/chunk-ATBM6AW5.js +53 -0
  157. package/dist/chunk-ATKEKM3E.js +206 -0
  158. package/dist/chunk-AUJLW6JZ.js +92 -0
  159. package/dist/chunk-AY3MHEFM.js +24 -0
  160. package/dist/chunk-B7PYTV72.js +236 -0
  161. package/dist/chunk-B7YRSULE.js +1423 -0
  162. package/dist/chunk-BAWJNMWF.js +339 -0
  163. package/dist/chunk-BBPIILO2.js +88 -0
  164. package/dist/chunk-BD3PGW6A.js +957 -0
  165. package/dist/chunk-BDPYFAB4.js +44 -0
  166. package/dist/chunk-BIUV23HH.js +729 -0
  167. package/dist/chunk-BQ3VAGXH.js +243 -0
  168. package/dist/chunk-BQJOGAWT.js +31 -0
  169. package/dist/chunk-BT7EG7CO.js +68 -0
  170. package/dist/chunk-BV3XQQLU.js +27 -0
  171. package/dist/chunk-BY6ODHNZ.js +78 -0
  172. package/dist/chunk-BZRLSZNV.js +79 -0
  173. package/dist/chunk-C3DH3NCY.js +2773 -0
  174. package/dist/chunk-C3KCMAJP.js +756 -0
  175. package/dist/chunk-C7AGUJ5K.js +267 -0
  176. package/dist/chunk-CBSWKQCX.js +342 -0
  177. package/dist/chunk-CE5OZBYY.js +21 -0
  178. package/dist/chunk-CFCVYHSW.js +373 -0
  179. package/dist/chunk-CHA2HDE5.js +126 -0
  180. package/dist/chunk-CIHWPGS5.js +146 -0
  181. package/dist/chunk-CJBSZX3F.js +127 -0
  182. package/dist/chunk-CLA6QIJM.js +43 -0
  183. package/dist/chunk-CPSVQR2I.js +365 -0
  184. package/dist/chunk-CRPRVNQ4.js +254 -0
  185. package/dist/chunk-CSIE4Y7C.js +1093 -0
  186. package/dist/chunk-CSOPSYDY.js +142 -0
  187. package/dist/chunk-CSXLLEGB.js +205 -0
  188. package/dist/chunk-CTDLERWU.js +293 -0
  189. package/dist/chunk-CULBXMSK.js +110 -0
  190. package/dist/chunk-D2M2Y5ID.js +21 -0
  191. package/dist/chunk-D37WY7SH.js +1060 -0
  192. package/dist/chunk-D4VJFCGZ.js +89 -0
  193. package/dist/chunk-D6WTZMZB.js +48 -0
  194. package/dist/chunk-DBHOWDUH.js +976 -0
  195. package/dist/chunk-DCACX7BV.js +19364 -0
  196. package/dist/chunk-DFHX4XYA.js +128 -0
  197. package/dist/chunk-DIKBRRKE.js +176 -0
  198. package/dist/chunk-DJG5RIOR.js +9 -0
  199. package/dist/chunk-DNIOIISW.js +616 -0
  200. package/dist/chunk-DOA5G7IA.js +315 -0
  201. package/dist/chunk-DP7FKP6W.js +855 -0
  202. package/dist/chunk-DS2JZ677.js +79 -0
  203. package/dist/chunk-DSRLVYBS.js +82 -0
  204. package/dist/chunk-EAEVKNJA.js +209 -0
  205. package/dist/chunk-EEUESN3T.js +575 -0
  206. package/dist/chunk-EJ4LUU5Y.js +73 -0
  207. package/dist/chunk-EJIWTPSZ.js +1063 -0
  208. package/dist/chunk-EJVCDTAN.js +116 -0
  209. package/dist/chunk-EKLUBDBQ.js +627 -0
  210. package/dist/chunk-EN62WLFD.js +849 -0
  211. package/dist/chunk-ENYRCL43.js +26 -0
  212. package/dist/chunk-EP22ZMFO.js +273 -0
  213. package/dist/chunk-EP4SVAVI.js +87 -0
  214. package/dist/chunk-EPAMVGI3.js +1562 -0
  215. package/dist/chunk-EPRMH6HO.js +24 -0
  216. package/dist/chunk-ES6NWJ36.js +4057 -0
  217. package/dist/chunk-ETA2K4KI.js +30 -0
  218. package/dist/chunk-ETAD4NKD.js +31 -0
  219. package/dist/chunk-EUWIIDQ7.js +93 -0
  220. package/dist/chunk-EVE3OD2W.js +141 -0
  221. package/dist/chunk-EXA26FFC.js +459 -0
  222. package/dist/chunk-EXSPAA35.js +244 -0
  223. package/dist/chunk-F55YABKV.js +258 -0
  224. package/dist/chunk-F5DNGU5W.js +27 -0
  225. package/dist/chunk-F622MJYV.js +103 -0
  226. package/dist/chunk-F6NIQD74.js +5111 -0
  227. package/dist/chunk-FAWJTC34.js +43 -0
  228. package/dist/chunk-FAZBRHGG.js +47 -0
  229. package/dist/chunk-FIEUSGNJ.js +39 -0
  230. package/dist/chunk-FKCG7K6H.js +1146 -0
  231. package/dist/chunk-FOVVXV45.js +229 -0
  232. package/dist/chunk-FRBPKBFE.js +30 -0
  233. package/dist/chunk-FSA5BPFI.js +268 -0
  234. package/dist/chunk-FSJ5TTZ3.js +29 -0
  235. package/dist/chunk-FT7SGLXT.js +193 -0
  236. package/dist/chunk-FUUVZZUB.js +62 -0
  237. package/dist/chunk-FYMRVUNZ.js +1697 -0
  238. package/dist/chunk-FYTAA5FG.js +162 -0
  239. package/dist/chunk-G3VB2UCZ.js +3892 -0
  240. package/dist/chunk-G6OIMVXH.js +405 -0
  241. package/dist/chunk-G7PQCXVH.js +228 -0
  242. package/dist/chunk-GAB6UW52.js +1087 -0
  243. package/dist/chunk-GAFJEYLK.js +29 -0
  244. package/dist/chunk-GC4CRMTS.js +642 -0
  245. package/dist/chunk-GFHSIWHL.js +5297 -0
  246. package/dist/chunk-GI5M67YA.js +735 -0
  247. package/dist/chunk-GIJWHUWF.js +191 -0
  248. package/dist/chunk-GO6DRECI.js +1 -0
  249. package/dist/chunk-GOFVBTMN.js +314 -0
  250. package/dist/chunk-GQIP72ZJ.js +13 -0
  251. package/dist/chunk-GQXLXRFA.js +28 -0
  252. package/dist/chunk-GT6HFKJB.js +48 -0
  253. package/dist/chunk-GVJGSSKM.js +174 -0
  254. package/dist/chunk-GWHGTG37.js +36 -0
  255. package/dist/chunk-GZAJHLKO.js +18 -0
  256. package/dist/chunk-GZK62I3N.js +314 -0
  257. package/dist/chunk-H3HGMISG.js +483 -0
  258. package/dist/chunk-H3ISZJMJ.js +403 -0
  259. package/dist/chunk-H4HXVWEC.js +9 -0
  260. package/dist/chunk-H6MJGKAW.js +120 -0
  261. package/dist/chunk-HBTTGVR5.js +353 -0
  262. package/dist/chunk-HBZ322WZ.js +35 -0
  263. package/dist/chunk-HEP3ILP4.js +34 -0
  264. package/dist/chunk-HGFXODKO.js +106 -0
  265. package/dist/chunk-HHWDTB6S.js +59 -0
  266. package/dist/chunk-HKO45NLZ.js +286 -0
  267. package/dist/chunk-HLVTEA6A.js +89 -0
  268. package/dist/chunk-HS3SY6HN.js +160 -0
  269. package/dist/chunk-HT5OCGKN.js +899 -0
  270. package/dist/chunk-HXIIEMGF.js +78 -0
  271. package/dist/chunk-I56TH7VM.js +46 -0
  272. package/dist/chunk-I6FN3R5D.js +352 -0
  273. package/dist/chunk-I7SCBHJN.js +655 -0
  274. package/dist/chunk-IJM4GKAT.js +529 -0
  275. package/dist/chunk-IMEYU36R.js +344 -0
  276. package/dist/chunk-INJ3SS6A.js +936 -0
  277. package/dist/chunk-IUKOPCCE.js +441 -0
  278. package/dist/chunk-IVEPZQJO.js +33 -0
  279. package/dist/chunk-IVZEONFC.js +43 -0
  280. package/dist/chunk-IWBHRSG7.js +936 -0
  281. package/dist/chunk-IYY3HQAD.js +484 -0
  282. package/dist/chunk-J2ICMYDA.js +48 -0
  283. package/dist/chunk-J2QCFLUN.js +505 -0
  284. package/dist/chunk-J5HM6V5P.js +1039 -0
  285. package/dist/chunk-J6NZX6QH.js +398 -0
  286. package/dist/chunk-JBBB2Y47.js +432 -0
  287. package/dist/chunk-JDCZQZU7.js +42 -0
  288. package/dist/chunk-JEDNXGSS.js +169 -0
  289. package/dist/chunk-JHP7OT6K.js +89 -0
  290. package/dist/chunk-JLS65NUQ.js +14 -0
  291. package/dist/chunk-JNMWYMC6.js +38 -0
  292. package/dist/chunk-JNSTWNNW.js +25 -0
  293. package/dist/chunk-JOSK6GEU.js +9564 -0
  294. package/dist/chunk-JQUMSIGC.js +100 -0
  295. package/dist/chunk-JVHGMURQ.js +1106 -0
  296. package/dist/chunk-JYXS47FQ.js +951 -0
  297. package/dist/chunk-K2ZMW2Z5.js +2147 -0
  298. package/dist/chunk-K7FAFORM.js +14 -0
  299. package/dist/chunk-KBJXX3ON.js +333 -0
  300. package/dist/chunk-KHFKVQWY.js +486 -0
  301. package/dist/chunk-KHMEI3DQ.js +173 -0
  302. package/dist/chunk-KHW3UD7B.js +69 -0
  303. package/dist/chunk-KKQKWAMF.js +365 -0
  304. package/dist/chunk-KOKXJV2U.js +455 -0
  305. package/dist/chunk-KQ4NGOJI.js +14 -0
  306. package/dist/chunk-KQYQOXMS.js +342 -0
  307. package/dist/chunk-KTMW65UX.js +14 -0
  308. package/dist/chunk-KUEWV2JH.js +593 -0
  309. package/dist/chunk-KXYDV3HP.js +1523 -0
  310. package/dist/chunk-KZ4JMGZ5.js +96 -0
  311. package/dist/chunk-KZWGBUIO.js +2659 -0
  312. package/dist/chunk-L2CBG5IX.js +1892 -0
  313. package/dist/chunk-L2S235CU.js +314 -0
  314. package/dist/chunk-L32WD57F.js +98 -0
  315. package/dist/chunk-LDJCKAJP.js +123 -0
  316. package/dist/chunk-LDWNBEN7.js +541 -0
  317. package/dist/chunk-LJVH57G2.js +241 -0
  318. package/dist/chunk-LPQ7NZEN.js +209 -0
  319. package/dist/chunk-LRGH3CCV.js +148 -0
  320. package/dist/chunk-LULOGMMM.js +1133 -0
  321. package/dist/chunk-LWGKN2GY.js +8284 -0
  322. package/dist/chunk-LX4F24ZH.js +157 -0
  323. package/dist/chunk-M4BUEXXF.js +839 -0
  324. package/dist/chunk-M6UHOC4I.js +553 -0
  325. package/dist/chunk-MCBNWZNO.js +657 -0
  326. package/dist/chunk-MEMSY6VY.js +223 -0
  327. package/dist/chunk-MHLEZQQI.js +145 -0
  328. package/dist/chunk-MJ6WNSIX.js +192 -0
  329. package/dist/chunk-MKASIKWZ.js +442 -0
  330. package/dist/chunk-MNOVBYFU.js +60 -0
  331. package/dist/chunk-MO2BYAAF.js +2896 -0
  332. package/dist/chunk-MP6P7Y2A.js +180 -0
  333. package/dist/chunk-MQ4TFJAG.js +3365 -0
  334. package/dist/chunk-MT2WAIR3.js +131 -0
  335. package/dist/chunk-MTU7VTNN.js +1122 -0
  336. package/dist/chunk-MULMXX4V.js +150 -0
  337. package/dist/chunk-MW2DWWVA.js +147 -0
  338. package/dist/chunk-MY3ZPUN4.js +151 -0
  339. package/dist/chunk-MYLH2S4G.js +64 -0
  340. package/dist/chunk-MZ5WYKNA.js +28 -0
  341. package/dist/chunk-N3Q2JNPV.js +249 -0
  342. package/dist/chunk-N5DX4JAK.js +12 -0
  343. package/dist/chunk-NAINGKHF.js +35 -0
  344. package/dist/chunk-NEQUQHOX.js +223 -0
  345. package/dist/chunk-NHNPEZS4.js +1408 -0
  346. package/dist/chunk-NHTIXJCR.js +17 -0
  347. package/dist/chunk-NKLPMBNV.js +1154 -0
  348. package/dist/chunk-NMVZ5YES.js +199 -0
  349. package/dist/chunk-NRFRY3GE.js +256 -0
  350. package/dist/chunk-NTD6CSI6.js +1266 -0
  351. package/dist/chunk-NUO7B3SH.js +318 -0
  352. package/dist/chunk-NVOHIJKG.js +1319 -0
  353. package/dist/chunk-NXH3RX7O.js +523 -0
  354. package/dist/chunk-NXZ3DURF.js +257 -0
  355. package/dist/chunk-O26L6F7F.js +209 -0
  356. package/dist/chunk-O5RRIUEP.js +124 -0
  357. package/dist/chunk-O5X6BKAO.js +10 -0
  358. package/dist/chunk-O6ZQUVTR.js +31 -0
  359. package/dist/chunk-O7FE75QZ.js +306 -0
  360. package/dist/chunk-OC7Z6AJQ.js +81 -0
  361. package/dist/chunk-OH7IEZ63.js +307 -0
  362. package/dist/chunk-OI734GRS.js +115 -0
  363. package/dist/chunk-OJBH62DK.js +684 -0
  364. package/dist/chunk-OKJLVSTJ.js +247 -0
  365. package/dist/chunk-OMX5VL43.js +79 -0
  366. package/dist/chunk-ONHAMBN6.js +12 -0
  367. package/dist/chunk-ONYPLIVE.js +753 -0
  368. package/dist/chunk-OSK7QWPD.js +637 -0
  369. package/dist/chunk-OTXLMJKP.js +438 -0
  370. package/dist/chunk-OV5PKQMA.js +213 -0
  371. package/dist/chunk-OXK5HA4B.js +31 -0
  372. package/dist/chunk-OYDWFQA4.js +272 -0
  373. package/dist/chunk-OZAUKWHB.js +22 -0
  374. package/dist/chunk-P5P2EKGH.js +94 -0
  375. package/dist/chunk-P6SSWAKY.js +29 -0
  376. package/dist/chunk-P7CQGPLS.js +30 -0
  377. package/dist/chunk-P7RVCHQV.js +197 -0
  378. package/dist/chunk-PEBWDYIW.js +726 -0
  379. package/dist/chunk-PFCXFO7A.js +9193 -0
  380. package/dist/chunk-PFLDWMX6.js +168 -0
  381. package/dist/chunk-PHZGLQSK.js +15883 -0
  382. package/dist/chunk-PNFTPNSR.js +20 -0
  383. package/dist/chunk-PPHXX4W7.js +175 -0
  384. package/dist/chunk-PPZESPJT.js +262 -0
  385. package/dist/chunk-PRDHI2L5.js +296 -0
  386. package/dist/chunk-PSTKWHHN.js +32 -0
  387. package/dist/chunk-PV53ODOT.js +555 -0
  388. package/dist/chunk-PVJBTI7P.js +24 -0
  389. package/dist/chunk-PXKERBKX.js +100 -0
  390. package/dist/chunk-PZ5AY32C.js +10 -0
  391. package/dist/chunk-Q3DHEZA5.js +85 -0
  392. package/dist/chunk-Q5RZDVQK.js +204 -0
  393. package/dist/chunk-Q64IR2Z2.js +4933 -0
  394. package/dist/chunk-Q6Z5UGPL.js +398 -0
  395. package/dist/chunk-QAMAV4DT.js +627 -0
  396. package/dist/chunk-QBWF4444.js +112 -0
  397. package/dist/chunk-QDKYT4CI.js +22805 -0
  398. package/dist/chunk-QFLBRWCJ.js +126 -0
  399. package/dist/chunk-QILAQACE.js +107 -0
  400. package/dist/chunk-QJ6OEH4K.js +3683 -0
  401. package/dist/chunk-QK3NLYTV.js +320 -0
  402. package/dist/chunk-QOFLUS24.js +535 -0
  403. package/dist/chunk-QOIASNEJ.js +98 -0
  404. package/dist/chunk-QP4UTSOV.js +3587 -0
  405. package/dist/chunk-QP5ST7RI.js +904 -0
  406. package/dist/chunk-QS5AGRZN.js +167 -0
  407. package/dist/chunk-QTAOU53N.js +107 -0
  408. package/dist/chunk-QTCLJHLZ.js +351 -0
  409. package/dist/chunk-QTOLTG4L.js +119 -0
  410. package/dist/chunk-QWDV4OSL.js +142 -0
  411. package/dist/chunk-QWMQ74KD.js +508 -0
  412. package/dist/chunk-QX6LOMMH.js +158 -0
  413. package/dist/chunk-QXBKIHY7.js +238 -0
  414. package/dist/chunk-QXBKTJT6.js +270 -0
  415. package/dist/chunk-QYQOVOLR.js +196 -0
  416. package/dist/chunk-R2CKS6WT.js +73 -0
  417. package/dist/chunk-R2TIYG7U.js +68 -0
  418. package/dist/chunk-R2W3LESH.js +465 -0
  419. package/dist/chunk-R5EXHMUN.js +100 -0
  420. package/dist/chunk-RBBTBCHX.js +289 -0
  421. package/dist/chunk-RBKLOUXA.js +121 -0
  422. package/dist/chunk-RCP2Y6DQ.js +86 -0
  423. package/dist/chunk-RCYEJSD5.js +260 -0
  424. package/dist/chunk-RFDVSI4N.js +134 -0
  425. package/dist/chunk-RGJU63FV.js +1717 -0
  426. package/dist/chunk-RI4EX2QE.js +18 -0
  427. package/dist/chunk-RIMARPCF.js +152 -0
  428. package/dist/chunk-RJ6RSNT6.js +42 -0
  429. package/dist/chunk-RNI2GUIF.js +131 -0
  430. package/dist/chunk-RPHUWJ3K.js +264 -0
  431. package/dist/chunk-RPIMAMV7.js +361 -0
  432. package/dist/chunk-RQFX6YRN.js +49 -0
  433. package/dist/chunk-RRC5BL7B.js +285 -0
  434. package/dist/chunk-RSYTSBOO.js +79 -0
  435. package/dist/chunk-RWQQIKIC.js +35 -0
  436. package/dist/chunk-RZUBOZH2.js +373 -0
  437. package/dist/chunk-S2E632FQ.js +380 -0
  438. package/dist/chunk-S2VQCZO4.js +22 -0
  439. package/dist/chunk-S2XIMQJQ.js +681 -0
  440. package/dist/chunk-S47ISY27.js +183 -0
  441. package/dist/chunk-S6I4KISU.js +142 -0
  442. package/dist/chunk-S6TAFQI5.js +2403 -0
  443. package/dist/chunk-SBBNT5ZJ.js +27 -0
  444. package/dist/chunk-SDJV2DTQ.js +491 -0
  445. package/dist/chunk-SDPIFNLD.js +33 -0
  446. package/dist/chunk-SF6YK3JI.js +835 -0
  447. package/dist/chunk-SK3ZFONO.js +976 -0
  448. package/dist/chunk-SKTFRFQ7.js +1775 -0
  449. package/dist/chunk-SNGM452K.js +2002 -0
  450. package/dist/chunk-STW7OFOA.js +581 -0
  451. package/dist/chunk-SU6UFUQY.js +1351 -0
  452. package/dist/chunk-SVJM3LJA.js +27 -0
  453. package/dist/chunk-SVUNZOPG.js +129 -0
  454. package/dist/chunk-T5XLUYV3.js +34 -0
  455. package/dist/chunk-T7E5JS6N.js +57 -0
  456. package/dist/chunk-TA3N5MMO.js +450 -0
  457. package/dist/chunk-TAJPCXSB.js +13 -0
  458. package/dist/chunk-TDEMDRN2.js +1639 -0
  459. package/dist/chunk-TDSEX5CF.js +24 -0
  460. package/dist/chunk-TGCVL74Y.js +28 -0
  461. package/dist/chunk-TGXXYDL4.js +1012 -0
  462. package/dist/chunk-TIKTYUJO.js +296 -0
  463. package/dist/chunk-TIZAJD4M.js +6029 -0
  464. package/dist/chunk-TLSEZZCG.js +5549 -0
  465. package/dist/chunk-TMBDRHAX.js +19 -0
  466. package/dist/chunk-TRURQUBP.js +1217 -0
  467. package/dist/chunk-TSQ256N5.js +152 -0
  468. package/dist/chunk-TUQMMFEQ.js +2244 -0
  469. package/dist/chunk-U424MJLC.js +81 -0
  470. package/dist/chunk-U4DRS6ZW.js +11 -0
  471. package/dist/chunk-U5KS22IN.js +204 -0
  472. package/dist/chunk-UAPHFJPN.js +673 -0
  473. package/dist/chunk-UB7LQITD.js +1040 -0
  474. package/dist/chunk-UBVRHGAZ.js +237 -0
  475. package/dist/chunk-UDNNAQN5.js +98 -0
  476. package/dist/chunk-UJP3XM54.js +342 -0
  477. package/dist/chunk-UJYDH2MW.js +305 -0
  478. package/dist/chunk-UKMPASIC.js +399 -0
  479. package/dist/chunk-UKUL3EHK.js +763 -0
  480. package/dist/chunk-UPHU64NB.js +1327 -0
  481. package/dist/chunk-URMSZXAD.js +43 -0
  482. package/dist/chunk-US3RT6CY.js +525 -0
  483. package/dist/chunk-UTDEOPKV.js +30 -0
  484. package/dist/chunk-UUUDKV7N.js +13 -0
  485. package/dist/chunk-UVKWU3SM.js +39 -0
  486. package/dist/chunk-V2TVPO3X.js +521 -0
  487. package/dist/chunk-V3KLVK7B.js +398 -0
  488. package/dist/chunk-V3YFFHDR.js +17 -0
  489. package/dist/chunk-VAG6GUBR.js +1162 -0
  490. package/dist/chunk-VBENAHDA.js +1814 -0
  491. package/dist/chunk-VBNCKCCI.js +16 -0
  492. package/dist/chunk-VCGSWN5M.js +1300 -0
  493. package/dist/chunk-VE2O2I7M.js +115 -0
  494. package/dist/chunk-VIFHYTI5.js +31 -0
  495. package/dist/chunk-VJER3FUS.js +5080 -0
  496. package/dist/chunk-VLMDM56Q.js +268 -0
  497. package/dist/chunk-VMFZEVVX.js +99 -0
  498. package/dist/chunk-VNDPQVUZ.js +1853 -0
  499. package/dist/chunk-VSPJRLGA.js +4783 -0
  500. package/dist/chunk-VSWC5ZXI.js +103 -0
  501. package/dist/chunk-VYI4DSZP.js +2017 -0
  502. package/dist/chunk-W4BAIQ6L.js +1212 -0
  503. package/dist/chunk-W7VQAL2K.js +2203 -0
  504. package/dist/chunk-WEI3ZDZH.js +33 -0
  505. package/dist/chunk-WEIUS5NT.js +26 -0
  506. package/dist/chunk-WEW7UFWE.js +546 -0
  507. package/dist/chunk-WGQAXLNA.js +384 -0
  508. package/dist/chunk-WJAL4JL3.js +206 -0
  509. package/dist/chunk-WKFOJ5ZG.js +141 -0
  510. package/dist/chunk-WMWQEFLN.js +2177 -0
  511. package/dist/chunk-WNECKKO2.js +154 -0
  512. package/dist/chunk-WPKLYOAM.js +195 -0
  513. package/dist/chunk-WSH37YQN.js +243 -0
  514. package/dist/chunk-WV3KQDPE.js +84 -0
  515. package/dist/chunk-WZFC4V4U.js +389 -0
  516. package/dist/chunk-XCOIBNET.js +13 -0
  517. package/dist/chunk-XDM65LBX.js +53 -0
  518. package/dist/chunk-XGU6PBO5.js +645 -0
  519. package/dist/chunk-XHOI4V62.js +43 -0
  520. package/dist/chunk-XIBVFMLQ.js +6858 -0
  521. package/dist/chunk-XJ2E7YEJ.js +117 -0
  522. package/dist/chunk-XON4ZCYX.js +69 -0
  523. package/dist/chunk-XQPEWJPI.js +127 -0
  524. package/dist/chunk-XSJTIFUY.js +31 -0
  525. package/dist/chunk-XT7OVWM3.js +64 -0
  526. package/dist/chunk-XTXYIISX.js +1104 -0
  527. package/dist/chunk-XV7NZL4B.js +57 -0
  528. package/dist/chunk-XWIZ6B5S.js +109 -0
  529. package/dist/chunk-XWLIKOBX.js +240 -0
  530. package/dist/chunk-XZOXEIN4.js +156 -0
  531. package/dist/chunk-XZRS7I7W.js +3673 -0
  532. package/dist/chunk-Y4ZDDHB6.js +44 -0
  533. package/dist/chunk-Y733RB7T.js +194 -0
  534. package/dist/chunk-YBHUB4XR.js +14931 -0
  535. package/dist/chunk-YKC75XK4.js +147 -0
  536. package/dist/chunk-YKMXFVK7.js +27 -0
  537. package/dist/chunk-YO5BAJ55.js +225 -0
  538. package/dist/chunk-YPDCLXNZ.js +568 -0
  539. package/dist/chunk-YSQPGVFK.js +116 -0
  540. package/dist/chunk-YTVVTIWJ.js +716 -0
  541. package/dist/chunk-YVCMDVBB.js +698 -0
  542. package/dist/chunk-YYTOA6DP.js +114 -0
  543. package/dist/chunk-Z5WGNULV.js +88 -0
  544. package/dist/chunk-Z6NGVVXG.js +66 -0
  545. package/dist/chunk-Z7CDQNH3.js +20 -0
  546. package/dist/chunk-ZH4G3FU5.js +187 -0
  547. package/dist/chunk-ZJB6SQPA.js +257 -0
  548. package/dist/chunk-ZL6E4HMY.js +42 -0
  549. package/dist/chunk-ZMLOC3DW.js +62 -0
  550. package/dist/chunk-ZORW64QH.js +101 -0
  551. package/dist/chunk-ZVVD2XGV.js +1369 -0
  552. package/dist/cli-utils-ER33ODC5.js +31 -0
  553. package/dist/cli-validation-6CHPTANV.js +146 -0
  554. package/dist/commit-utils-3STAY7C7.js +49 -0
  555. package/dist/compatibility-notice-IHNXR2JR.js +21 -0
  556. package/dist/compete-config-resolver-V3GDNJMM.js +125 -0
  557. package/dist/compete-results-XUM3PJHS.js +318 -0
  558. package/dist/competition-outcome-tracker-NWSMVUPG.js +62 -0
  559. package/dist/config-4HHE4OIK.js +238 -0
  560. package/dist/config-D6YAZASH.js +10 -0
  561. package/dist/config-MIPRDYYV.js +46 -0
  562. package/dist/config-audit-GA5DCUAI.js +371 -0
  563. package/dist/config-explain-4LMO556H.js +71 -0
  564. package/dist/config-loader-RGP634PC.js +51 -0
  565. package/dist/config-manager-J2UTO635.js +114 -0
  566. package/dist/config-merger-TVUJBZTS.js +14 -0
  567. package/dist/config-validator-H4ZVIE56.js +122 -0
  568. package/dist/cost-HSIV5U2Y.js +85 -0
  569. package/dist/data-migration-state-OAUL2WPQ.js +35 -0
  570. package/dist/db-migrator-NUOW5NKR.js +34 -0
  571. package/dist/default-paths-UILB62BN.js +49 -0
  572. package/dist/discovery-V6GYUJUC.js +53 -0
  573. package/dist/doctor-BBSMCDWE.js +271 -0
  574. package/dist/doctor-context-blocks-LPY75VZA.js +231 -0
  575. package/dist/doctor-instructions-import-JXHDDOE5.js +70 -0
  576. package/dist/doctor-purpose-6YJOXPBE.js +30 -0
  577. package/dist/domain-analyzer-S35ABUNA.js +48 -0
  578. package/dist/ensure-initialized-Q6PEU55O.js +78 -0
  579. package/dist/entry.js +922 -0
  580. package/dist/error-parser-core-MZFMFANN.js +70 -0
  581. package/dist/evaluation-context-GQBYDAEV.js +63 -0
  582. package/dist/evidence-plan-resolver-5FUAP3SA.js +111 -0
  583. package/dist/execution-data-writer-YCG5UH37.js +72 -0
  584. package/dist/execution-policy-applier-PWZM5LNA.js +63 -0
  585. package/dist/execution-preflight-DASJWWQF.js +223 -0
  586. package/dist/execution-roles-KNSNNB2D.js +112 -0
  587. package/dist/exit-code-error-QIY5DOKF.js +18 -0
  588. package/dist/external-temp-cleanup-CAW7LQ6R.js +360 -0
  589. package/dist/factory-YCYCB7AE.js +209 -0
  590. package/dist/file-utils-ZQYNBQBW.js +45 -0
  591. package/dist/flywheel-allowlist-revert-H22HA6JE.js +21 -0
  592. package/dist/flywheel-autoloop-executor-PDOASJEZ.js +316 -0
  593. package/dist/flywheel-autoloop-unverified-TOKYFCDC.js +36 -0
  594. package/dist/flywheel-competition-executor-YJUMMEJO.js +320 -0
  595. package/dist/flywheel-executor-JWU43KAY.js +437 -0
  596. package/dist/flywheel-git-isolation-FQ2TRWMB.js +56 -0
  597. package/dist/flywheel-manifest-HDPNMWWF.js +114 -0
  598. package/dist/flywheel-model-defaults-UHAKTZT3.js +110 -0
  599. package/dist/flywheel-preflight-III2C7TH.js +163 -0
  600. package/dist/flywheel-resume-2O45MS7Y.js +31 -0
  601. package/dist/flywheel-resume-execution-lease-P2BK257J.js +59 -0
  602. package/dist/flywheel-safety-AVAVFXIJ.js +19 -0
  603. package/dist/flywheel-scope-decision-ALJUUNGG.js +14 -0
  604. package/dist/get-telemetry-logger-MPDVO2JA.js +155 -0
  605. package/dist/git-message-style-KCXGMTDT.js +104 -0
  606. package/dist/guidance-profile-config-G3K5YQOO.js +113 -0
  607. package/dist/guidance-profile-renderer-TX4TNDFL.js +23 -0
  608. package/dist/identity-XLQJ4YJF.js +25 -0
  609. package/dist/index-query-6NUY4FKX.js +37 -0
  610. package/dist/index.js +85588 -0
  611. package/dist/indexer-DL54CM3K.js +44 -0
  612. package/dist/init-OUZ72344.js +245 -0
  613. package/dist/instructions-import-offer-NSYXSITC.js +363 -0
  614. package/dist/instructions-run-NBII7W36.js +114 -0
  615. package/dist/interrupted-work-E4TLKJLE.js +43 -0
  616. package/dist/invoke-provider-auth-NEWEIHCI.js +38 -0
  617. package/dist/judge-scoring.json +64 -0
  618. package/dist/lab-mode-YXQ2Y3NG.js +44 -0
  619. package/dist/lab-utils-5QAMDJR5.js +29 -0
  620. package/dist/linux-host-class-YDWQX65O.js +31 -0
  621. package/dist/llm-judge-executor-OJSNCTFJ.js +179 -0
  622. package/dist/local-ci-config-VZ4WWDT5.js +48 -0
  623. package/dist/local-executor-DCMDDRX2.js +280 -0
  624. package/dist/logger-5KNKS3O4.js +154 -0
  625. package/dist/matrix-prompt-builder-4ZBOGZSB.js +527 -0
  626. package/dist/matrix-result-parser-EZJM4YXP.js +14 -0
  627. package/dist/merge-batch-RTEEMVDB.js +313 -0
  628. package/dist/merge-batch-members-VIWGVRHP.js +24 -0
  629. package/dist/merge-queue-TIIUSOY6.js +126 -0
  630. package/dist/merge-queue-trust-DUNZ4J65.js +21 -0
  631. package/dist/metadata-UKSMWM6J.js +29 -0
  632. package/dist/model-catalog-readiness-R5KJBP5M.js +202 -0
  633. package/dist/model-invocations-db-XTUPPQ34.js +70 -0
  634. package/dist/model-resolver-JFZ2MHOJ.js +39 -0
  635. package/dist/model-resolver-SCQ57KAQ.js +217 -0
  636. package/dist/model-roles-D3OR4NAH.js +110 -0
  637. package/dist/monitor-F4SIU5G2.js +96 -0
  638. package/dist/nested-worktrees-2WUWQ75N.js +23 -0
  639. package/dist/next-S3IRLVER.js +96 -0
  640. package/dist/next-UKPFRXOO.js +148 -0
  641. package/dist/opportunistic-TL4S26VX.js +86 -0
  642. package/dist/optimization-config-resolver-NAEIYU6A.js +148 -0
  643. package/dist/package-HJR4QJT4.js +10 -0
  644. package/dist/parse-git-status-7PIYFPS2.js +21 -0
  645. package/dist/path-security-5WJSY56G.js +41 -0
  646. package/dist/paths-JUI7C4KU.js +45 -0
  647. package/dist/plan-backlog-list-fast-SSTQL5XP.js +89 -0
  648. package/dist/plan-backlog-show-fast-PFRAQ3JB.js +114 -0
  649. package/dist/plan-sprint-list-fast-HD2KBZSY.js +110 -0
  650. package/dist/plan-sprint-status-fast-YFYH7WQF.js +116 -0
  651. package/dist/plan-task-status-fast-JU5PNLUU.js +114 -0
  652. package/dist/plan-to-flywheel-PY5MSY2H.js +529 -0
  653. package/dist/preflight-PJHGTJNZ.js +12 -0
  654. package/dist/process-registry-B4ZUCN7T.js +28 -0
  655. package/dist/process-scanner-TU3QHWVB.js +23 -0
  656. package/dist/processes-6FHVGT72.js +28 -0
  657. package/dist/processes-json-fast-YWTMUWXB.js +72 -0
  658. package/dist/profile-HWTC56SG.js +209 -0
  659. package/dist/project-runtime-paths-2UQNG5Y4.js +41 -0
  660. package/dist/protected-branches-N36LDBFY.js +71 -0
  661. package/dist/provider-aware-resource-manager-YTFAHNGJ.js +40 -0
  662. package/dist/provider-matrix-2KO2V5OM.js +214 -0
  663. package/dist/provider-matrix-renderer-MEC3PER7.js +139 -0
  664. package/dist/provider-output-forwarding-2AHL7YMA.js +26 -0
  665. package/dist/provider-registry-WCZ65QHC.js +136 -0
  666. package/dist/provider-temp-cleanup-IUNPJCZF.js +14 -0
  667. package/dist/prune-engine-EOQVWEP6.js +448 -0
  668. package/dist/publication-turn-S42RZTQF.js +44 -0
  669. package/dist/quality-gate-JQMVCKOO.js +72 -0
  670. package/dist/quickstart-3O6FRCFB.js +105 -0
  671. package/dist/readiness-GW6ABRHB.js +139 -0
  672. package/dist/readiness-KFZCXDTT.js +215 -0
  673. package/dist/registry-7XG376SY.js +217 -0
  674. package/dist/repair-helpers-TTV5FEF4.js +117 -0
  675. package/dist/repo-root-YG6MQZDW.js +28 -0
  676. package/dist/resolution-engine-FFEK7HQ2.js +187 -0
  677. package/dist/resolve-provider-cli-ZEXVZKET.js +44 -0
  678. package/dist/restore-telemetry-db-E7BR5PO7.js +459 -0
  679. package/dist/routing-events-AW6SRZ6G.js +13 -0
  680. package/dist/routing-history-store-FMDDQL6W.js +39 -0
  681. package/dist/routing-planner-C6OHO3EY.js +221 -0
  682. package/dist/runner-KHDNQ5KU.js +1194 -0
  683. package/dist/runner-PIS2BW7Y.js +1801 -0
  684. package/dist/safety-E3JJVSFL.js +67 -0
  685. package/dist/safety-stanza-HE6GXP4G.js +49 -0
  686. package/dist/sandbox-7LBZC5PE.js +72 -0
  687. package/dist/sandbox-ASWCDYZL.js +80 -0
  688. package/dist/schema-extensions.sql +234 -0
  689. package/dist/security-JI22TBEB.js +17 -0
  690. package/dist/setup-bb-plugin-FQXLA76Y.js +531 -0
  691. package/dist/setup-claude-code-NF4ZSHVE.js +197 -0
  692. package/dist/setup-temp-cleanup-2APZ4HMA.js +29 -0
  693. package/dist/shared-utils-34HJZ6JX.js +40 -0
  694. package/dist/simple-artifact-goal-MQLDDMMX.js +29 -0
  695. package/dist/sprint-N7JFTEGL.js +403 -0
  696. package/dist/sprint-bridge-KJXIBNRJ.js +117 -0
  697. package/dist/sprint-completion-dependents-34SR7JVL.js +43 -0
  698. package/dist/sprint-execution-service-A6JPUBWY.js +376 -0
  699. package/dist/sprint-manager-MU2ZUWN2.js +140 -0
  700. package/dist/sqlite-timeout-config-U2CT4LKU.js +13 -0
  701. package/dist/sqlite-wrapper-FSGJ2QEW.js +19 -0
  702. package/dist/stale-cleanup-orchestrator-4X6324VF.js +71 -0
  703. package/dist/storage-access-I3V5LER7.js +31 -0
  704. package/dist/store-XVG64ZR2.js +25 -0
  705. package/dist/task-classifier-MN2DYE5R.js +558 -0
  706. package/dist/task-list-fast-7AT6LTTA.js +112 -0
  707. package/dist/task-manager-LHPBBRRE.js +136 -0
  708. package/dist/task-report-OLPAWBTK.js +64 -0
  709. package/dist/task-type-detector-6RG3YNZF.js +27 -0
  710. package/dist/task-type-resolver-EQHOUIHT.js +64 -0
  711. package/dist/telemetry-5VYSK772.js +212 -0
  712. package/dist/telemetry-health-tracker-4GFW2EMP.js +12 -0
  713. package/dist/telemetry-path-resolver-H3NFHHQY.js +34 -0
  714. package/dist/telemetry-reliability-URJDTNPZ.js +76 -0
  715. package/dist/transports-NREZQTJK.js +106 -0
  716. package/dist/unified-cost-tracker-5MTBJ2CL.js +59 -0
  717. package/dist/unified-state-cleanup-GGAXLHXF.js +292 -0
  718. package/dist/universal-cost-calculator-JTFEJVWK.js +70 -0
  719. package/dist/user-agents-QLIGPLP2.js +30 -0
  720. package/dist/variant-execution-I4ZZUAWY.js +319 -0
  721. package/dist/variant-opt-parser-JHCXKY2K.js +251 -0
  722. package/dist/variant-request-input-PL37N3AN.js +11 -0
  723. package/dist/variant-state-cleanup-KHMXRBZN.js +287 -0
  724. package/dist/variant-worker-COB5YTJX.js +4517 -0
  725. package/dist/variant-worker.js +26 -0
  726. package/dist/variants-XGDSXYG3.js +267 -0
  727. package/dist/verification-command-YSPU4VBH.js +66 -0
  728. package/dist/verify-command-timeout-DQUYH33Z.js +11 -0
  729. package/dist/verify-commands-LOHMOFKC.js +65 -0
  730. package/dist/warning-JSKSFKBT.js +13 -0
  731. package/dist/work-edge-K65NHVWY.js +50 -0
  732. package/dist/work-item-writer-KY5ZWZWW.js +30 -0
  733. package/dist/worker-JNXXEIT6.js +1504 -0
  734. package/dist/worker.js +21 -0
  735. package/dist/workspace-tree-identity-JO5PSKTW.js +52 -0
  736. package/dist/worktree-environment-WTVABAQW.js +64 -0
  737. package/dist/worktree-metrics-VZRQI26T.js +66 -0
  738. package/dist/writeback-TQFQBJNU.js +50 -0
  739. package/docs/CLI_REFERENCE.md +8287 -0
  740. package/docs/PROVIDER_SETUP.md +1737 -0
  741. package/docs/README.md +96 -0
  742. package/docs/TROUBLESHOOTING.md +2209 -0
  743. package/docs/getting-started/QUICK_START.md +260 -0
  744. package/docs/getting-started/README.md +198 -0
  745. package/docs/getting-started/SETUP.md +25 -0
  746. package/docs/reference/AGENT_CONTEXT.md +84 -0
  747. package/docs/reference/DELIVERY_ONBOARDING.md +198 -0
  748. package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
  749. package/docs/reference/SECURITY.md +291 -0
  750. package/docs/reference/TELEMETRY_PRIVACY.md +259 -0
  751. package/integrations/bb-plugin-build/README.md +391 -0
  752. package/integrations/bb-plugin-build/app.css +431 -0
  753. package/integrations/bb-plugin-build/app.tsx +6210 -0
  754. package/integrations/bb-plugin-build/package.json +45 -0
  755. package/integrations/bb-plugin-build/server.ts +488 -0
  756. package/integrations/bb-plugin-build/src/adapter.ts +3672 -0
  757. package/integrations/bb-plugin-build/src/backlog-authoring-model.ts +150 -0
  758. package/integrations/bb-plugin-build/src/backlog-authoring-schema.ts +458 -0
  759. package/integrations/bb-plugin-build/src/backlog-authoring-service.ts +467 -0
  760. package/integrations/bb-plugin-build/src/backlog-authoring-view.ts +1025 -0
  761. package/integrations/bb-plugin-build/src/command-evidence-schema.ts +13 -0
  762. package/integrations/bb-plugin-build/src/competition-defaults-schema.ts +122 -0
  763. package/integrations/bb-plugin-build/src/competition-defaults-service.ts +105 -0
  764. package/integrations/bb-plugin-build/src/competition-defaults-view.ts +138 -0
  765. package/integrations/bb-plugin-build/src/contract.ts +718 -0
  766. package/integrations/bb-plugin-build/src/execution-activity-view.ts +98 -0
  767. package/integrations/bb-plugin-build/src/finalize-model.ts +205 -0
  768. package/integrations/bb-plugin-build/src/finalize-schema.ts +150 -0
  769. package/integrations/bb-plugin-build/src/finalize-service.ts +330 -0
  770. package/integrations/bb-plugin-build/src/finalize-view.ts +159 -0
  771. package/integrations/bb-plugin-build/src/judge-operations-readback.ts +303 -0
  772. package/integrations/bb-plugin-build/src/judge-operations-schema.ts +33 -0
  773. package/integrations/bb-plugin-build/src/judge-operations-view.ts +459 -0
  774. package/integrations/bb-plugin-build/src/model.ts +1318 -0
  775. package/integrations/bb-plugin-build/src/monitor-service.ts +233 -0
  776. package/integrations/bb-plugin-build/src/panel-read-ux.ts +97 -0
  777. package/integrations/bb-plugin-build/src/patch-preview-schema.ts +166 -0
  778. package/integrations/bb-plugin-build/src/patch-preview-service.ts +480 -0
  779. package/integrations/bb-plugin-build/src/patch-preview-view.ts +109 -0
  780. package/integrations/bb-plugin-build/src/planning-readback.ts +228 -0
  781. package/integrations/bb-plugin-build/src/planning-service.ts +647 -0
  782. package/integrations/bb-plugin-build/src/planning-sync-evidence.ts +37 -0
  783. package/integrations/bb-plugin-build/src/planning-workspace-readback.ts +33 -0
  784. package/integrations/bb-plugin-build/src/planning-workspace-schema.ts +131 -0
  785. package/integrations/bb-plugin-build/src/planning-workspace.ts +333 -0
  786. package/integrations/bb-plugin-build/src/poll-handoff.ts +136 -0
  787. package/integrations/bb-plugin-build/src/project-target-server.ts +21 -0
  788. package/integrations/bb-plugin-build/src/project-target.ts +45 -0
  789. package/integrations/bb-plugin-build/src/reference-index.ts +218 -0
  790. package/integrations/bb-plugin-build/src/repository-identity.ts +17 -0
  791. package/integrations/bb-plugin-build/src/repository-schema.ts +30 -0
  792. package/integrations/bb-plugin-build/src/result-explorer-view.ts +597 -0
  793. package/integrations/bb-plugin-build/src/result-readback-model.ts +163 -0
  794. package/integrations/bb-plugin-build/src/result-readback-schema.ts +319 -0
  795. package/integrations/bb-plugin-build/src/result-readback-service.ts +333 -0
  796. package/integrations/bb-plugin-build/src/run-page-view.ts +332 -0
  797. package/integrations/bb-plugin-build/src/setup-config-schema.ts +293 -0
  798. package/integrations/bb-plugin-build/src/setup-config-service.ts +620 -0
  799. package/integrations/bb-plugin-build/src/setup-config-view.ts +388 -0
  800. package/integrations/bb-plugin-build/src/sprint-close-model.ts +150 -0
  801. package/integrations/bb-plugin-build/src/sprint-close-schema.ts +128 -0
  802. package/integrations/bb-plugin-build/src/sprint-close-service.ts +293 -0
  803. package/integrations/bb-plugin-build/src/sprint-close-view.ts +116 -0
  804. package/integrations/bb-plugin-build/src/sprint-composition-model.ts +709 -0
  805. package/integrations/bb-plugin-build/src/sprint-composition-readback.ts +231 -0
  806. package/integrations/bb-plugin-build/src/sprint-composition-schema.ts +597 -0
  807. package/integrations/bb-plugin-build/src/sprint-composition-service.ts +773 -0
  808. package/integrations/bb-plugin-build/src/sprint-composition-view.ts +1221 -0
  809. package/integrations/bb-plugin-build/src/sprint-execution-schema.ts +188 -0
  810. package/integrations/bb-plugin-build/src/sprint-execution-service.ts +289 -0
  811. package/integrations/bb-plugin-build/src/sprint-execution-view.ts +54 -0
  812. package/integrations/bb-plugin-build/src/task-authoring-model.ts +563 -0
  813. package/integrations/bb-plugin-build/src/task-authoring-schema.ts +629 -0
  814. package/integrations/bb-plugin-build/src/task-authoring-service.ts +842 -0
  815. package/integrations/bb-plugin-build/src/task-authoring-view.ts +1227 -0
  816. package/integrations/bb-plugin-build/src/task-catalog-schema.ts +46 -0
  817. package/integrations/bb-plugin-build/src/task-catalog-service.ts +44 -0
  818. package/integrations/bb-plugin-build/src/task-detail-readback.ts +56 -0
  819. package/integrations/bb-plugin-build/src/task-detail-schema.ts +171 -0
  820. package/integrations/bb-plugin-build/src/task-navigation.ts +446 -0
  821. package/integrations/bb-plugin-build/src/workbench-route.ts +74 -0
  822. package/package.json +306 -4
  823. package/schemas/README.md +80 -0
  824. package/schemas/build.config.schema.json +2110 -0
  825. package/schemas/config-v1.schema.json +136 -0
  826. package/schemas/execution-config.schema.json +47 -0
  827. package/schemas/judge-scoring.schema.json +257 -0
  828. package/schemas/provider-config.schema.json +179 -0
  829. package/schemas/telemetry-config.schema.json +79 -0
  830. package/schemas/user-preferences.schema.json +141 -0
  831. package/scripts/assert-node-runtime.mjs +146 -0
  832. package/scripts/preflight-native.mjs +49 -0
  833. package/scripts/setup-git-hooks.mjs +39 -0
  834. package/scripts/sync.sh +2871 -0
  835. package/scripts/write-node-launcher.sh +138 -0
  836. package/src/resources/gemini/slash-packs/default/plan.toml +15 -0
  837. package/src/resources/gemini/slash-packs/default/summary.toml +16 -0
  838. package/src/resources/gemini/slash-packs/default/tests.toml +16 -0
  839. package/templates/.build-project/README.md +41 -0
  840. package/templates/.build-project/agents/README.md +50 -0
  841. package/templates/.build-project/agents/architect.md +10 -0
  842. package/templates/.build-project/agents/code-reviewer.md +10 -0
  843. package/templates/.build-project/agents/debugger.md +10 -0
  844. package/templates/.build-project/agents/documenter.md +10 -0
  845. package/templates/.build-project/agents/test-automator.md +10 -0
  846. package/templates/.build-project/config/build.config.jsonc +64 -0
  847. package/templates/.build-project/config/project-context.template.json +6 -0
  848. package/templates/.build-project/config/task-type-aliases.presets/kanban.yaml +14 -0
  849. package/templates/.build-project/config/task-type-aliases.presets/scrum.yaml +17 -0
  850. package/templates/.build-project/config/task-type-aliases.presets/xp.yaml +12 -0
  851. package/templates/.build-project/config/task-type-aliases.yaml +29 -0
  852. package/templates/.build-project/gitignore.template +70 -0
  853. package/templates/.build-project/task-types/analysis.yaml +38 -0
  854. package/templates/.build-project/task-types/architecture.yaml +35 -0
  855. package/templates/.build-project/task-types/doc.yaml +34 -0
  856. package/templates/.build-project/task-types/feature.yaml +22 -0
  857. package/templates/.build-project/task-types/general.yaml +4 -0
  858. package/templates/.build-project/task-types/security.yaml +38 -0
  859. package/templates/AGENTS.template.md +85 -0
  860. package/templates/CLAUDE.template.md +1 -0
  861. package/templates/GEMINI.template.md +1 -0
  862. package/templates/builtin-workflows/code-review.yaml +73 -0
  863. package/templates/builtin-workflows/skills/code-review/SKILL.md +61 -0
  864. package/templates/builtin-workflows/skills/execution-contract-analysis/SKILL.md +24 -0
  865. package/templates/builtin-workflows/skills/execution-contract-code/SKILL.md +19 -0
  866. package/templates/builtin-workflows/skills/execution-contract-structured/SKILL.md +17 -0
  867. package/templates/ci/incident-intake.mjs +787 -0
  868. package/templates/ci/incidents.yml.template +103 -0
  869. package/templates/ci/node.yml.template +17 -0
  870. package/templates/ci/python.yml.template +17 -0
  871. package/templates/guard-kit/GUARD_SETUP.md.template +258 -0
  872. package/templates/guard-kit/build-guard.yml.template +189 -0
  873. package/templates/guard-kit/check.mjs.template +932 -0
  874. package/templates/guard-kit/config.json.template +7 -0
  875. package/templates/guard-kit/policy.json.template +1 -0
  876. package/templates/profiles/README.md +57 -0
  877. package/templates/profiles/frontier-claude.json +23 -0
  878. package/templates/profiles/frontier-codex.json +23 -0
@@ -0,0 +1,3583 @@
1
+ import {
2
+ globalProcessLimiter
3
+ } from "./chunk-SF6YK3JI.js";
4
+ import {
5
+ classifyAndWrapExecaError,
6
+ exitCodeToSignal,
7
+ formatTerminationRemedy,
8
+ hasSignal,
9
+ redactProviderArgv,
10
+ resolveTerminationExitCode
11
+ } from "./chunk-JBBB2Y47.js";
12
+ import {
13
+ evaluateCpuTimeProgressStreak,
14
+ readCpuTimeSeconds,
15
+ resolveIdleTimeoutsMs
16
+ } from "./chunk-WJAL4JL3.js";
17
+ import {
18
+ providerExecutionTransportStreamOptions,
19
+ sanitizeDiagnosticOutput,
20
+ sanitizeDiagnosticText
21
+ } from "./chunk-RBKLOUXA.js";
22
+ import {
23
+ TelemetryLogger
24
+ } from "./chunk-PFCXFO7A.js";
25
+ import {
26
+ requestProcessExit
27
+ } from "./chunk-GC4CRMTS.js";
28
+ import {
29
+ createLogger
30
+ } from "./chunk-3OPP2OZB.js";
31
+ import {
32
+ detectSandboxBoundaryAttestation,
33
+ wrapWithSandbox
34
+ } from "./chunk-B7YRSULE.js";
35
+ import {
36
+ BUILD_TEMP_MARKER_FILENAME,
37
+ markBuildTempDirSync
38
+ } from "./chunk-D6WTZMZB.js";
39
+ import {
40
+ chunkToText,
41
+ createLineBufferedStreamProcessor,
42
+ processOutput,
43
+ selectBestErrorSummary
44
+ } from "./chunk-TUQMMFEQ.js";
45
+ import {
46
+ isSignalableProcessGroupId,
47
+ signalProcessGroup
48
+ } from "./chunk-6CB3KJRY.js";
49
+ import {
50
+ safeRmDir
51
+ } from "./chunk-ALDTFNZ3.js";
52
+ import {
53
+ normalizeEngineId
54
+ } from "./chunk-KKQKWAMF.js";
55
+ import {
56
+ authorizeLinuxHostClassWrites
57
+ } from "./chunk-V2TVPO3X.js";
58
+ import {
59
+ ProviderExecutionError
60
+ } from "./chunk-RRC5BL7B.js";
61
+ import {
62
+ formatHostTimeoutTerminationDetail,
63
+ isHostTimeoutAbortReason
64
+ } from "./chunk-M6UHOC4I.js";
65
+ import {
66
+ createCleanChildEnv,
67
+ isSandboxAuthorityEnvVar,
68
+ stripClaudeSessionEnv
69
+ } from "./chunk-WGQAXLNA.js";
70
+ import {
71
+ DEFAULT_TIMEOUT_MS
72
+ } from "./chunk-I56TH7VM.js";
73
+ import {
74
+ BUILD_PROCESS_SLOT_WAIT_MS,
75
+ BUILD_SUBPROCESS_PID_WAIT_MS,
76
+ BUILD_VARIANT_WORKER,
77
+ emitWarning,
78
+ isDebugMode,
79
+ isPathDebug,
80
+ isTimeoutDebug,
81
+ readEnv
82
+ } from "./chunk-7VRJHTGZ.js";
83
+ import {
84
+ sanitizeError
85
+ } from "./chunk-CPSVQR2I.js";
86
+
87
+ // src/core/execution/boundary-telemetry.ts
88
+ function emitBoundaryTriggered(event) {
89
+ const { trigger, workloadClass, effectiveCeilingMs, elapsedMs, source } = event;
90
+ const severity = trigger === "ceiling" ? "ERROR" /* ERROR */ : "WARN" /* WARN */;
91
+ emitWarning(
92
+ "EB-001",
93
+ {
94
+ taskId: event.taskId ?? "unknown",
95
+ subsystem: "execution",
96
+ executionPhase: "execution"
97
+ },
98
+ {
99
+ severity,
100
+ skipConsole: true,
101
+ metadata: {
102
+ ...event.metadata,
103
+ trigger,
104
+ workloadClass,
105
+ effectiveCeilingMs,
106
+ elapsedMs,
107
+ source,
108
+ ...event.idleDurationMs !== void 0 ? { idleDurationMs: event.idleDurationMs } : {},
109
+ ...event.stagnantChecks !== void 0 ? { stagnantChecks: event.stagnantChecks } : {},
110
+ type: "execution_boundary_triggered"
111
+ }
112
+ }
113
+ );
114
+ const level = trigger === "ceiling" ? "warn" : "debug";
115
+ const msg = `[ExecutionBoundary] ${trigger} fired for ${workloadClass} after ${elapsedMs}ms (ceiling: ${effectiveCeilingMs}ms, source: ${source})`;
116
+ if (level === "warn") {
117
+ console.warn(msg);
118
+ } else if (isDebugMode() || process.env.DEBUG) {
119
+ console.debug(msg);
120
+ }
121
+ }
122
+
123
+ // src/core/process-lifecycle-context.ts
124
+ var processLifecycleManager;
125
+ function setProcessLifecycleManager(manager) {
126
+ processLifecycleManager = manager;
127
+ }
128
+ function getProcessLifecycleManager() {
129
+ return processLifecycleManager;
130
+ }
131
+
132
+ // src/core/providers/shared/raw-chunk-observers.ts
133
+ function isNonEmptyRawChunk(chunk) {
134
+ if (typeof chunk === "string") {
135
+ return chunk.length > 0;
136
+ }
137
+ return chunk.byteLength > 0;
138
+ }
139
+ function rawChunkToBuffer(chunk) {
140
+ if (typeof chunk === "string") {
141
+ if (chunk.length === 0) {
142
+ return Buffer.alloc(0);
143
+ }
144
+ return Buffer.from(chunk, "utf8");
145
+ }
146
+ if (chunk.byteLength === 0) {
147
+ return Buffer.alloc(0);
148
+ }
149
+ return Buffer.from(chunk);
150
+ }
151
+ function composeRawChunkObservers(...observers) {
152
+ const active2 = observers.filter((o) => typeof o === "function");
153
+ if (active2.length === 0) return void 0;
154
+ if (active2.length === 1) return active2[0];
155
+ return (chunk) => {
156
+ for (const observer of active2) {
157
+ try {
158
+ observer(chunk);
159
+ } catch {
160
+ }
161
+ }
162
+ };
163
+ }
164
+
165
+ // src/core/providers/shared/tmux-completion-signal.ts
166
+ var TMUX_COMPLETION_SIGNAL_GRACE_MS = 1500;
167
+ var DEFAULT_MAX_PENDING_LINE_BYTES = 1024 * 1024;
168
+ function defaultShouldCheckPendingLine(pendingLine) {
169
+ return pendingLine.trimEnd().endsWith("}");
170
+ }
171
+ function createLineDelimitedTmuxCompletionSignal(lineConcludes, opts) {
172
+ let pendingLine = "";
173
+ let concluded = false;
174
+ const maxPendingLineBytes = opts?.maxPendingLineBytes ?? DEFAULT_MAX_PENDING_LINE_BYTES;
175
+ const shouldCheckPendingLine = opts?.shouldCheckPendingLine ?? defaultShouldCheckPendingLine;
176
+ const lineConcludesSafely = (line) => {
177
+ try {
178
+ return lineConcludes(line);
179
+ } catch {
180
+ return false;
181
+ }
182
+ };
183
+ return (chunk, stream) => {
184
+ if (concluded) return true;
185
+ if (stream !== "stdout" || !chunk) return false;
186
+ const combined = pendingLine + chunk;
187
+ const lines = combined.split(/\r?\n/);
188
+ pendingLine = lines.pop() ?? "";
189
+ if (pendingLine.length > maxPendingLineBytes) {
190
+ pendingLine = pendingLine.slice(-maxPendingLineBytes);
191
+ }
192
+ for (const line of lines) {
193
+ if (lineConcludesSafely(line)) {
194
+ concluded = true;
195
+ return true;
196
+ }
197
+ }
198
+ if (shouldCheckPendingLine(pendingLine) && lineConcludesSafely(pendingLine)) {
199
+ concluded = true;
200
+ return true;
201
+ }
202
+ return false;
203
+ };
204
+ }
205
+
206
+ // src/core/providers/shared/variant-launch.ts
207
+ import { AsyncLocalStorage } from "async_hooks";
208
+ var active = new AsyncLocalStorage();
209
+ function withVariantInvocation(invocation, run) {
210
+ return active.run(invocation, run);
211
+ }
212
+ function activeVariantServiceTier() {
213
+ return active.getStore()?.resolution.resolved.serviceTier;
214
+ }
215
+ function prepareVariantCommand(command, model, effort) {
216
+ active.getStore()?.prepare({
217
+ ...model ? { model } : {},
218
+ ...effort ? { effort } : {}
219
+ });
220
+ return command;
221
+ }
222
+ function observeVariantProcessSpawn(process2) {
223
+ const invocation = active.getStore();
224
+ if (invocation) process2.once("spawn", () => invocation.submitted());
225
+ }
226
+ function recordVariantTmuxLaunch() {
227
+ active.getStore()?.submitted();
228
+ }
229
+
230
+ // src/core/providers/shared/base-runner.ts
231
+ import { createHash } from "crypto";
232
+ import os3 from "os";
233
+ import path2 from "path";
234
+ import { StringDecoder as StringDecoder2 } from "string_decoder";
235
+
236
+ // src/core/providers/shared/file-backed-stdout.ts
237
+ import * as fs from "fs";
238
+ import { StringDecoder } from "string_decoder";
239
+ var FILE_BACKED_STDOUT_DEFAULT_MAX_BYTES = 256 * 1024 * 1024;
240
+ var FILE_BACKED_STDOUT_MIN_FREE_BYTES = 8 * 1024 * 1024;
241
+ var DEFAULT_POLL_INTERVAL_MS = 25;
242
+ var TRUTHY_OVERRIDES = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
243
+ var FALSY_OVERRIDES = /* @__PURE__ */ new Set(["0", "false", "no", "off"]);
244
+ var FILE_BACKED_STDOUT_ENV_NAME = "BUILD_PROVIDER_FILE_BACKED_STDOUT";
245
+ function resolveFileBackedStdoutOverride(env = process.env) {
246
+ const raw = env[FILE_BACKED_STDOUT_ENV_NAME];
247
+ if (raw === void 0 || raw === "") return void 0;
248
+ const lower = raw.toLowerCase();
249
+ if (TRUTHY_OVERRIDES.has(lower)) return true;
250
+ if (FALSY_OVERRIDES.has(lower)) return false;
251
+ throw new Error(
252
+ `Invalid boolean value for ${FILE_BACKED_STDOUT_ENV_NAME}: "${raw}". Expected one of: 1, true, yes, on, 0, false, no, off`
253
+ );
254
+ }
255
+ var MAX_SLICE_BYTES = 1024 * 1024;
256
+ var SETTLE_ATTEMPTS = 5;
257
+ function spoolFilesystemFreeBytes(dir) {
258
+ if (typeof fs.statfsSync !== "function") return void 0;
259
+ try {
260
+ const stats = fs.statfsSync(dir);
261
+ const available = Number(stats.bavail) * Number(stats.bsize);
262
+ return Number.isFinite(available) && available >= 0 ? available : void 0;
263
+ } catch {
264
+ return void 0;
265
+ }
266
+ }
267
+ function createStdoutSpoolTailer(options) {
268
+ const pollIntervalMs = Math.max(1, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
269
+ const decoder = new StringDecoder("utf8");
270
+ let offset = 0;
271
+ let polling = false;
272
+ let timer;
273
+ let inflight;
274
+ let failure;
275
+ const recordFailure = (candidate) => {
276
+ if (failure) return;
277
+ failure = candidate;
278
+ polling = false;
279
+ options.onFailure(candidate);
280
+ };
281
+ const asMessage = (error) => error instanceof Error ? error.message : String(error);
282
+ const pump = async () => {
283
+ for (; ; ) {
284
+ if (failure) return;
285
+ const size = await options.stream.statSize();
286
+ if (size > options.maxBytes) {
287
+ recordFailure({
288
+ reason: "output_ceiling_exceeded",
289
+ message: `provider stdout exceeded the ${options.maxBytes} byte capture ceiling (${size} bytes spooled)`
290
+ });
291
+ return;
292
+ }
293
+ if (size <= offset) return;
294
+ const bytes = await options.stream.readAt(offset, Math.min(size - offset, MAX_SLICE_BYTES));
295
+ if (bytes.length === 0) return;
296
+ offset += bytes.length;
297
+ try {
298
+ options.onBytes(bytes, decoder.write(bytes));
299
+ } catch (error) {
300
+ recordFailure({
301
+ reason: "stdout_spool_consume_failed",
302
+ message: `processing spooled provider stdout failed: ${asMessage(error)}`
303
+ });
304
+ return;
305
+ }
306
+ }
307
+ };
308
+ const tick = () => {
309
+ if (!polling || inflight) return;
310
+ inflight = pump().catch((error) => {
311
+ recordFailure({
312
+ reason: "stdout_spool_read_failed",
313
+ message: `reading spooled provider stdout failed: ${asMessage(error)}`
314
+ });
315
+ }).finally(() => {
316
+ inflight = void 0;
317
+ if (polling) {
318
+ timer = setTimeout(tick, pollIntervalMs);
319
+ timer.unref?.();
320
+ }
321
+ });
322
+ };
323
+ const readToEnd = async () => {
324
+ polling = false;
325
+ if (timer) {
326
+ clearTimeout(timer);
327
+ timer = void 0;
328
+ }
329
+ if (inflight) {
330
+ try {
331
+ await inflight;
332
+ } catch {
333
+ }
334
+ }
335
+ if (failure) return;
336
+ try {
337
+ await pump();
338
+ } catch (error) {
339
+ recordFailure({
340
+ reason: "stdout_spool_read_failed",
341
+ message: `final drain of spooled provider stdout failed: ${asMessage(error)}`
342
+ });
343
+ }
344
+ };
345
+ let flushed = false;
346
+ const flushDecoder = () => {
347
+ if (flushed) return;
348
+ flushed = true;
349
+ const tail = decoder.end();
350
+ if (!tail || failure) return;
351
+ try {
352
+ options.onBytes(void 0, tail);
353
+ } catch (error) {
354
+ recordFailure({
355
+ reason: "stdout_spool_consume_failed",
356
+ message: `flushing spooled provider stdout failed: ${asMessage(error)}`
357
+ });
358
+ }
359
+ };
360
+ return {
361
+ bytesObserved: () => offset,
362
+ failure: () => failure,
363
+ start() {
364
+ if (polling) return;
365
+ polling = true;
366
+ tick();
367
+ },
368
+ drain: readToEnd,
369
+ async finish() {
370
+ let size;
371
+ for (let attempt = 0; attempt < SETTLE_ATTEMPTS; attempt += 1) {
372
+ await readToEnd();
373
+ if (failure) break;
374
+ try {
375
+ size = await options.stream.statSize();
376
+ } catch (error) {
377
+ recordFailure({
378
+ reason: "stdout_spool_read_failed",
379
+ message: `measuring the spooled provider stdout failed: ${asMessage(error)}`
380
+ });
381
+ break;
382
+ }
383
+ if (size === offset) break;
384
+ }
385
+ if (!failure && size !== void 0 && size !== offset) {
386
+ recordFailure({
387
+ reason: "stdout_spool_read_failed",
388
+ message: `provider stdout spool never settled: ${size} bytes on disk but ${offset} read after ${SETTLE_ATTEMPTS} passes`
389
+ });
390
+ }
391
+ flushDecoder();
392
+ return size;
393
+ }
394
+ };
395
+ }
396
+
397
+ // src/core/providers/shared/private-spool.ts
398
+ import * as fs2 from "fs";
399
+ import * as os from "os";
400
+ import * as path from "path";
401
+ var PrivateSpoolError = class extends Error {
402
+ constructor(message) {
403
+ super(message);
404
+ this.name = "PrivateSpoolError";
405
+ }
406
+ };
407
+ var EXCL_RDWR_FLAGS = fs2.constants.O_RDWR | fs2.constants.O_CREAT | fs2.constants.O_EXCL | (fs2.constants.O_NOFOLLOW ?? 0);
408
+ function writeAllToFd(fd, buffer, createError) {
409
+ return new Promise((resolve, reject) => {
410
+ let offset = 0;
411
+ const writeNext = () => {
412
+ if (offset >= buffer.length) {
413
+ resolve();
414
+ return;
415
+ }
416
+ fs2.write(fd, buffer, offset, buffer.length - offset, null, (error, written) => {
417
+ if (error) {
418
+ reject(error);
419
+ return;
420
+ }
421
+ if (typeof written !== "number" || written <= 0) {
422
+ reject(createError("write made no progress"));
423
+ return;
424
+ }
425
+ offset += written;
426
+ writeNext();
427
+ });
428
+ };
429
+ writeNext();
430
+ });
431
+ }
432
+ function fsyncFd(fd) {
433
+ return new Promise((resolve, reject) => {
434
+ fs2.fsync(fd, (error) => {
435
+ if (error) reject(error);
436
+ else resolve();
437
+ });
438
+ });
439
+ }
440
+ function closeFd(fd) {
441
+ return new Promise((resolve, reject) => {
442
+ fs2.close(fd, (error) => {
443
+ if (error) reject(error);
444
+ else resolve();
445
+ });
446
+ });
447
+ }
448
+ function fstatSize(fd) {
449
+ return new Promise((resolve, reject) => {
450
+ fs2.fstat(fd, (error, stats) => {
451
+ if (error) reject(error);
452
+ else resolve(stats.size);
453
+ });
454
+ });
455
+ }
456
+ function readAtFd(fd, position, length) {
457
+ if (length <= 0) return Promise.resolve(Buffer.alloc(0));
458
+ const buffer = Buffer.allocUnsafe(length);
459
+ return new Promise((resolve, reject) => {
460
+ fs2.read(fd, buffer, 0, length, position, (error, bytesRead) => {
461
+ if (error) {
462
+ reject(error);
463
+ return;
464
+ }
465
+ resolve(Buffer.from(buffer.subarray(0, bytesRead)));
466
+ });
467
+ });
468
+ }
469
+ function cleanupPartiallyInitializedSpool(dir, leaves) {
470
+ for (const leaf of leaves) {
471
+ try {
472
+ fs2.unlinkSync(leaf);
473
+ } catch {
474
+ }
475
+ }
476
+ try {
477
+ fs2.rmdirSync(dir);
478
+ } catch {
479
+ }
480
+ }
481
+ function createPrivateSpool(options) {
482
+ const errorLabel = options.errorLabel ?? "private spool";
483
+ const createError = options.createError ?? ((message) => new PrivateSpoolError(message));
484
+ const fail = (message) => createError(`${errorLabel} ${message}`);
485
+ if (options.streams.length === 0) {
486
+ throw fail("requires at least one stream");
487
+ }
488
+ const label = (options.label ?? "spool").replace(/[^a-zA-Z0-9._-]+/g, "-").slice(0, 40);
489
+ const dir = fs2.mkdtempSync(path.join(os.tmpdir(), `build-${label}-`));
490
+ fs2.chmodSync(dir, 448);
491
+ markBuildTempDirSync(dir);
492
+ const states = /* @__PURE__ */ new Map();
493
+ const leafPaths = [path.join(dir, BUILD_TEMP_MARKER_FILENAME)];
494
+ try {
495
+ for (const name of options.streams) {
496
+ if (states.has(name)) {
497
+ throw fail(`duplicate stream '${name}'`);
498
+ }
499
+ if (!/^[a-zA-Z0-9._-]+$/.test(name) || name === "." || name === "..") {
500
+ throw fail(`invalid stream name '${name}'`);
501
+ }
502
+ const leaf = path.join(dir, `${name}.spool`);
503
+ leafPaths.push(leaf);
504
+ const fd = fs2.openSync(leaf, EXCL_RDWR_FLAGS, 384);
505
+ fs2.fchmodSync(fd, 384);
506
+ states.set(name, { name, path: leaf, fd, sawEnqueuedWrite: false });
507
+ }
508
+ } catch (error) {
509
+ for (const state of states.values()) {
510
+ if (state.fd !== null) {
511
+ try {
512
+ fs2.closeSync(state.fd);
513
+ } catch {
514
+ }
515
+ }
516
+ }
517
+ cleanupPartiallyInitializedSpool(dir, leafPaths);
518
+ throw error;
519
+ }
520
+ let writeChain = Promise.resolve();
521
+ let writeError;
522
+ let finalized = false;
523
+ let disposed = false;
524
+ const closeHeldFds = async () => {
525
+ const fds = [];
526
+ for (const state of states.values()) {
527
+ if (state.fd !== null) {
528
+ fds.push(state.fd);
529
+ state.fd = null;
530
+ }
531
+ }
532
+ for (const fd of fds) {
533
+ try {
534
+ await closeFd(fd);
535
+ } catch {
536
+ }
537
+ }
538
+ };
539
+ const makeStream = (state) => ({
540
+ get name() {
541
+ return state.name;
542
+ },
543
+ get path() {
544
+ return state.path;
545
+ },
546
+ get sawEnqueuedWrite() {
547
+ return state.sawEnqueuedWrite;
548
+ },
549
+ enqueue(chunk) {
550
+ if (disposed || finalized || state.fd === null) return;
551
+ if (!isNonEmptyRawChunk(chunk)) return;
552
+ const targetFd = state.fd;
553
+ const buffer = rawChunkToBuffer(chunk);
554
+ if (buffer.length === 0) return;
555
+ state.sawEnqueuedWrite = true;
556
+ writeChain = writeChain.then(async () => {
557
+ if (disposed) return;
558
+ await writeAllToFd(targetFd, buffer, fail);
559
+ }).catch((error) => {
560
+ if (!writeError) {
561
+ writeError = error instanceof Error ? error : fail(String(error));
562
+ }
563
+ });
564
+ },
565
+ requireOpenFd() {
566
+ if (disposed) throw fail("already disposed");
567
+ if (state.fd === null) throw fail(`${state.name} FD not available`);
568
+ return state.fd;
569
+ },
570
+ requireFinalizedFd() {
571
+ if (disposed) throw fail("already disposed");
572
+ if (!finalized || state.fd === null) {
573
+ throw fail(`${state.name} FD not available (finalize first)`);
574
+ }
575
+ return state.fd;
576
+ },
577
+ async statSize() {
578
+ if (disposed) throw fail("already disposed");
579
+ if (state.fd === null) throw fail(`${state.name} FD not available`);
580
+ return fstatSize(state.fd);
581
+ },
582
+ async readAt(position, length) {
583
+ if (disposed) throw fail("already disposed");
584
+ if (state.fd === null) throw fail(`${state.name} FD not available`);
585
+ return readAtFd(state.fd, position, length);
586
+ }
587
+ });
588
+ const streams = /* @__PURE__ */ new Map();
589
+ for (const state of states.values()) {
590
+ streams.set(state.name, makeStream(state));
591
+ }
592
+ return {
593
+ get dir() {
594
+ return dir;
595
+ },
596
+ stream(name) {
597
+ const stream = streams.get(name);
598
+ if (!stream) {
599
+ throw fail(`unknown stream '${name}'`);
600
+ }
601
+ return stream;
602
+ },
603
+ async finalize() {
604
+ if (disposed) throw fail("already disposed");
605
+ if (finalized) return;
606
+ await writeChain;
607
+ if (writeError) {
608
+ await closeHeldFds();
609
+ throw fail(`write failed: ${writeError.message}`);
610
+ }
611
+ try {
612
+ for (const state of states.values()) {
613
+ if (state.fd !== null) {
614
+ await fsyncFd(state.fd);
615
+ }
616
+ }
617
+ } catch (error) {
618
+ await closeHeldFds();
619
+ const message = error instanceof Error ? error.message : String(error);
620
+ throw fail(`fsync failed: ${message}`);
621
+ }
622
+ finalized = true;
623
+ },
624
+ async dispose() {
625
+ if (disposed) return;
626
+ disposed = true;
627
+ try {
628
+ await writeChain;
629
+ } catch {
630
+ }
631
+ await closeHeldFds();
632
+ try {
633
+ await safeRmDir(dir, {
634
+ protectedPaths: [os.tmpdir()],
635
+ managedRoots: [os.tmpdir()]
636
+ });
637
+ } catch {
638
+ }
639
+ }
640
+ };
641
+ }
642
+
643
+ // src/core/providers/shared/process-signals.ts
644
+ var BUILD_PROCESS_GROUP_OWNER_ENV = "BUILD_PROCESS_GROUP_OWNER";
645
+ var BUILD_PROVIDER_PROCESS_GROUP_MARKER_PREFIX = "__BUILD_PROVIDER_PROCESS_GROUP_PID__:";
646
+ var BUILD_PROVIDER_PROCESS_GROUP_CLEARED_MARKER_PREFIX = "__BUILD_PROVIDER_PROCESS_GROUP_CLEARED__:";
647
+ function isReportableProviderProcessGroupPid(pid) {
648
+ return isSignalableProcessGroupId(pid);
649
+ }
650
+ function shouldEmitWorkerProcessGroupMarker(pid) {
651
+ return readEnv(BUILD_VARIANT_WORKER).value === true && process.platform !== "win32" && isReportableProviderProcessGroupPid(pid);
652
+ }
653
+ function isProviderProcessGroupMarkerLine(line) {
654
+ return line.startsWith(BUILD_PROVIDER_PROCESS_GROUP_MARKER_PREFIX) || line.startsWith(BUILD_PROVIDER_PROCESS_GROUP_CLEARED_MARKER_PREFIX);
655
+ }
656
+ function resolveProviderProcessGroupOwnership() {
657
+ return {
658
+ owner: "runner",
659
+ detach: process.platform !== "win32"
660
+ };
661
+ }
662
+ function emitProviderProcessGroupMarker(pid) {
663
+ if (!shouldEmitWorkerProcessGroupMarker(pid)) {
664
+ return;
665
+ }
666
+ try {
667
+ process.stdout.write(`${BUILD_PROVIDER_PROCESS_GROUP_MARKER_PREFIX}${pid}
668
+ `);
669
+ } catch {
670
+ }
671
+ }
672
+ function emitProviderProcessGroupClearedMarker(pid) {
673
+ if (!shouldEmitWorkerProcessGroupMarker(pid)) {
674
+ return;
675
+ }
676
+ try {
677
+ process.stdout.write(`${BUILD_PROVIDER_PROCESS_GROUP_CLEARED_MARKER_PREFIX}${pid}
678
+ `);
679
+ } catch {
680
+ }
681
+ }
682
+ function isNoSuchProcess(error) {
683
+ return error?.code === "ESRCH";
684
+ }
685
+ async function ensureDetachedProviderProcessGroupGone(pid, timeoutMs = 2e3) {
686
+ if (process.platform === "win32" || !isReportableProviderProcessGroupPid(pid)) {
687
+ return true;
688
+ }
689
+ try {
690
+ signalProcessGroup(pid, 0);
691
+ } catch (error) {
692
+ return isNoSuchProcess(error);
693
+ }
694
+ try {
695
+ signalProcessGroup(pid, "SIGKILL");
696
+ } catch (error) {
697
+ return isNoSuchProcess(error);
698
+ }
699
+ const deadline = Date.now() + Math.max(0, timeoutMs);
700
+ while (Date.now() < deadline) {
701
+ try {
702
+ signalProcessGroup(pid, 0);
703
+ } catch (error) {
704
+ return isNoSuchProcess(error);
705
+ }
706
+ await new Promise((resolve) => setTimeout(resolve, 25));
707
+ }
708
+ return false;
709
+ }
710
+ function sendSignalToSubprocessTree(subprocess, signal) {
711
+ let delivered = false;
712
+ if (process.platform !== "win32" && isSignalableProcessGroupId(subprocess.pid)) {
713
+ try {
714
+ signalProcessGroup(subprocess.pid, signal);
715
+ delivered = true;
716
+ } catch {
717
+ }
718
+ }
719
+ try {
720
+ subprocess.kill(signal);
721
+ delivered = true;
722
+ } catch {
723
+ }
724
+ return delivered;
725
+ }
726
+
727
+ // src/core/providers/shared/process-slot-reservation.ts
728
+ import { execa } from "execa";
729
+ var DEFAULT_PROCESS_SLOT_WAIT_MS = 3e4;
730
+ var PROCESS_SLOT_POLL_MS = 100;
731
+ function releaseProcessSlotReservation(reservation) {
732
+ if (reservation !== void 0) {
733
+ globalProcessLimiter.cancelReservation(reservation);
734
+ }
735
+ }
736
+ function getProcessSlotWaitBudgetMs() {
737
+ const raw = readEnv(BUILD_PROCESS_SLOT_WAIT_MS).value ?? DEFAULT_PROCESS_SLOT_WAIT_MS;
738
+ return Math.max(0, Math.min(3e5, raw));
739
+ }
740
+ function tryReserveProcessSlot() {
741
+ if (typeof globalProcessLimiter.reserve === "function") {
742
+ const reservation = globalProcessLimiter.reserve();
743
+ if (reservation !== null) {
744
+ return reservation;
745
+ }
746
+ } else {
747
+ const canSpawn = typeof globalProcessLimiter.canSpawn === "function" ? globalProcessLimiter.canSpawn() : true;
748
+ if (canSpawn) {
749
+ return void 0;
750
+ }
751
+ }
752
+ return null;
753
+ }
754
+ function processSlotAbortError(limiterDescription) {
755
+ return new Error(`Process slot wait aborted before spawn: ${limiterDescription}`);
756
+ }
757
+ function throwIfReservationAborted(reservation, limiterDescription, abortSignal) {
758
+ if (!abortSignal?.aborted) {
759
+ return;
760
+ }
761
+ releaseProcessSlotReservation(reservation);
762
+ throw processSlotAbortError(limiterDescription);
763
+ }
764
+ function acquireProcessSlot(limiterDescription, abortSignal) {
765
+ const immediateReservation = tryReserveProcessSlot();
766
+ if (immediateReservation !== null) {
767
+ throwIfReservationAborted(immediateReservation, limiterDescription, abortSignal);
768
+ return immediateReservation;
769
+ }
770
+ return waitForProcessSlot(limiterDescription, abortSignal);
771
+ }
772
+ async function waitForProcessSlot(limiterDescription, abortSignal) {
773
+ const waitBudgetMs = getProcessSlotWaitBudgetMs();
774
+ const deadline = Date.now() + waitBudgetMs;
775
+ while (true) {
776
+ const reservation = tryReserveProcessSlot();
777
+ if (reservation !== null) {
778
+ throwIfReservationAborted(reservation, limiterDescription, abortSignal);
779
+ return reservation;
780
+ }
781
+ if (abortSignal?.aborted) {
782
+ throw processSlotAbortError(limiterDescription);
783
+ }
784
+ const remainingMs = deadline - Date.now();
785
+ if (remainingMs <= 0 || waitBudgetMs === 0) {
786
+ throw new Error(
787
+ `Process limit reached before spawn after waiting ${waitBudgetMs}ms: ${limiterDescription}. Wait for existing provider processes to complete or increase BUILD_MAX_PROCESSES.`
788
+ );
789
+ }
790
+ await new Promise((resolve, reject) => {
791
+ const timer = setTimeout(
792
+ () => {
793
+ abortSignal?.removeEventListener("abort", onAbort);
794
+ resolve();
795
+ },
796
+ Math.min(PROCESS_SLOT_POLL_MS, remainingMs)
797
+ );
798
+ const onAbort = () => {
799
+ clearTimeout(timer);
800
+ abortSignal?.removeEventListener("abort", onAbort);
801
+ reject(processSlotAbortError(limiterDescription));
802
+ };
803
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
804
+ });
805
+ if (abortSignal?.aborted) {
806
+ throw processSlotAbortError(limiterDescription);
807
+ }
808
+ }
809
+ }
810
+ function spawnProviderSubprocess(command, args, options, reservation) {
811
+ try {
812
+ return execa(command, args, options);
813
+ } catch (spawnErr) {
814
+ releaseProcessSlotReservation(reservation);
815
+ throw spawnErr;
816
+ }
817
+ }
818
+
819
+ // src/core/providers/shared/sandbox-bypass-guard.ts
820
+ import os2 from "os";
821
+ var PROVIDER_INTERNAL_SANDBOX_BYPASS_FLAGS = /* @__PURE__ */ new Set([
822
+ "--dangerously-bypass-approvals-and-sandbox",
823
+ "--dangerously-skip-permissions",
824
+ "--yolo",
825
+ "--allow-all-tools",
826
+ "--always-approve",
827
+ "--trust-all-tools"
828
+ ]);
829
+ var PROVIDER_INTERNAL_SANDBOX_BYPASS_OPTION_VALUES = /* @__PURE__ */ new Map([
830
+ ["--permission-mode", /* @__PURE__ */ new Set(["acceptEdits", "auto", "dontAsk", "bypassPermissions"])],
831
+ ["--sandbox", /* @__PURE__ */ new Set(["disabled"])]
832
+ ]);
833
+ function parseBooleanLikeFlagValue(value) {
834
+ const normalized = value.trim().toLowerCase();
835
+ return normalized === "true" || normalized === "1" || normalized === "yes";
836
+ }
837
+ function hasAcceptedPolicyBoundaryProof(sandboxed) {
838
+ const { boundaryProof, policyProof } = sandboxed;
839
+ if (boundaryProof === "wrap_applied" && policyProof === "wrap_applied") {
840
+ return true;
841
+ }
842
+ if ((boundaryProof === "inherited_outer" || boundaryProof === "container") && policyProof === "capability_probe") {
843
+ return true;
844
+ }
845
+ if (os2.platform() === "linux" && (boundaryProof === "linux_isolated" || boundaryProof === "linux_acknowledged") && policyProof === "linux_host_class") {
846
+ return true;
847
+ }
848
+ return false;
849
+ }
850
+ var HOST_CLASS_BYPASS_PROVENANCES = /* @__PURE__ */ new Set([
851
+ "linux_isolated",
852
+ "linux_acknowledged"
853
+ ]);
854
+ function formatHostClassBypassNotice(providerName, provenance) {
855
+ if (!HOST_CLASS_BYPASS_PROVENANCES.has(provenance)) return void 0;
856
+ return `Info: ${providerName} internal sandbox is bypassed for this run because the Linux host class provides the boundary (provenance=${provenance}).`;
857
+ }
858
+ function emitHostClassBypassNotice(providerName, providerId, options = {}) {
859
+ const { provenance } = detectSandboxBoundaryAttestation(providerName, providerId, options);
860
+ const notice = formatHostClassBypassNotice(providerName, provenance);
861
+ if (!notice) return;
862
+ console.warn(notice);
863
+ }
864
+ function findProviderInternalSandboxBypass(args) {
865
+ for (let index = 0; index < args.length; index += 1) {
866
+ const arg = args[index];
867
+ if (!arg) continue;
868
+ if (PROVIDER_INTERNAL_SANDBOX_BYPASS_FLAGS.has(arg)) return arg;
869
+ for (const flag of PROVIDER_INTERNAL_SANDBOX_BYPASS_FLAGS) {
870
+ if (arg.startsWith(`${flag}=`)) {
871
+ const value = arg.slice(flag.length + 1);
872
+ if (parseBooleanLikeFlagValue(value)) return flag;
873
+ }
874
+ }
875
+ const equalsIndex = arg.indexOf("=");
876
+ if (equalsIndex > 0) {
877
+ const option = arg.slice(0, equalsIndex);
878
+ const value = arg.slice(equalsIndex + 1);
879
+ const bypassValues2 = PROVIDER_INTERNAL_SANDBOX_BYPASS_OPTION_VALUES.get(option);
880
+ if (bypassValues2?.has(value)) return `${option}=${value}`;
881
+ }
882
+ const bypassValues = PROVIDER_INTERNAL_SANDBOX_BYPASS_OPTION_VALUES.get(arg);
883
+ const next = args[index + 1];
884
+ if (next && bypassValues?.has(next)) return `${arg} ${next}`;
885
+ }
886
+ return void 0;
887
+ }
888
+ function assertProviderBypassHasBoundaryProof(metadata, args, sandboxed, explicitBypass) {
889
+ const bypassFlag = explicitBypass ?? findProviderInternalSandboxBypass(args);
890
+ if (!bypassFlag || hasAcceptedPolicyBoundaryProof(sandboxed)) return;
891
+ if (sandboxed.boundaryProof) {
892
+ throw new ProviderExecutionError(
893
+ `[${metadata.name}] Provider internal sandbox bypass (${bypassFlag}) requires a sandbox policy boundary for this exact invocation, but the final provider command only has security boundary proof (${sandboxed.boundaryProof}) [reason=sandbox_capability_denied]`,
894
+ {
895
+ retryable: false,
896
+ reason: "sandbox_capability_denied",
897
+ providerName: metadata.name
898
+ }
899
+ );
900
+ }
901
+ if (os2.platform() === "linux") {
902
+ authorizeLinuxHostClassWrites();
903
+ }
904
+ throw new ProviderExecutionError(
905
+ `[${metadata.name}] Provider internal sandbox bypass (${bypassFlag}) requires a sandbox boundary for this exact invocation, but the final provider command has no boundary proof [reason=sandbox_boundary_required]`,
906
+ {
907
+ retryable: false,
908
+ reason: "sandbox_boundary_required",
909
+ providerName: metadata.name
910
+ }
911
+ );
912
+ }
913
+
914
+ // src/core/providers/shared/sandbox-path-denial.ts
915
+ var SANDBOX_PATH_DENIED_REASON = "sandbox_path_denied";
916
+ var SEATBELT_BOUNDARY_PROOFS = /* @__PURE__ */ new Set([
917
+ "wrap_applied",
918
+ "inherited_outer"
919
+ ]);
920
+ var MAX_SCANNED_STDERR_CHARS = 16384;
921
+ var MAX_SCANNED_LINE_CHARS = 2048;
922
+ var MAX_REPORTED_PATH_CHARS = 512;
923
+ var PATH = String.raw`(?:\/|~\/)`;
924
+ var NODE_FILE_OPS = "open|mkdir|mkdtemp|rename|unlink|rmdir|rm|copyfile|symlink|link|scandir|opendir|access|stat|lstat|utime";
925
+ var DENIAL_PATTERNS = [
926
+ // node: EPERM: operation not permitted, open '/path'
927
+ new RegExp(
928
+ String.raw`\bEPERM: operation not permitted, (?:${NODE_FILE_OPS}) '(${PATH}[^'\n]+)'`,
929
+ "i"
930
+ ),
931
+ // python: [Errno 1] Operation not permitted: '/path'
932
+ new RegExp(String.raw`operation not permitted: '(${PATH}[^'\n]+)'`, "i"),
933
+ // zsh: <script>:<line>: operation not permitted: /path
934
+ new RegExp(String.raw`operation not permitted: (${PATH}.*?)\s*$`, "i"),
935
+ // bash, dash, go: /path: Operation not permitted
936
+ new RegExp(String.raw`(${PATH}[^\n:']*): operation not permitted\b`, "i")
937
+ ];
938
+ var NON_PATH_EPERM = /sandbox_apply|(?:^|:\s)(?:ch(?:own|mod|grp|flags)|kill|set[ug]id|ptrace)(?::|\s+[/~])|\b(?:l?ch(?:own|mod|flags)|kill|set[ug]id)\s*\(/i;
939
+ var TRACE_TAIL = /^(?:\s+at\s|\s+(?:errno|code|syscall|path|dest):\s|\}|Node\.js v|Bun v)/;
940
+ function detectSandboxPathDenial(stderr) {
941
+ const lines = stderr.slice(-MAX_SCANNED_STDERR_CHARS).split(/\r?\n/).filter((line) => line.trim().length > 0);
942
+ let end = lines.length - 1;
943
+ while (end >= 0 && TRACE_TAIL.test(lines[end] ?? "")) end--;
944
+ const last = lines[end];
945
+ if (!last || last.length > MAX_SCANNED_LINE_CHARS) return void 0;
946
+ let start = end;
947
+ while (start > 0 && /^\s/.test(lines[start - 1] ?? "")) start--;
948
+ const block = lines.slice(start).filter((line) => !/^\s+at\s/.test(line));
949
+ if (block.some((line) => NON_PATH_EPERM.test(line))) return void 0;
950
+ for (const pattern of DENIAL_PATTERNS) {
951
+ const path3 = pattern.exec(last)?.[1]?.trim();
952
+ if (path3) return { path: path3 };
953
+ }
954
+ return void 0;
955
+ }
956
+ function sandboxPathDenialError(metadata, sandbox, exit, maxPublicLength) {
957
+ const { exitCode } = exit;
958
+ if (sandbox?.sandboxed !== true || !SEATBELT_BOUNDARY_PROOFS.has(sandbox.boundaryProof)) {
959
+ return void 0;
960
+ }
961
+ if (exitCode === void 0 || exitCode === 0) return void 0;
962
+ if (exit.stdout.trim().length > 0 || (exit.stdoutBytes ?? 0) > 0) return void 0;
963
+ const denial = detectSandboxPathDenial(exit.stderr);
964
+ if (!denial) return void 0;
965
+ const path3 = sanitizeDiagnosticText(denial.path).slice(0, MAX_REPORTED_PATH_CHARS);
966
+ const providerId = normalizeEngineId(metadata.id ?? metadata.name);
967
+ return new ProviderExecutionError(
968
+ `${metadata.name} CLI exited with code ${exitCode} after reporting access denied to ${path3} while running inside the sandbox. If the command Build runs for ${metadata.name} is a wrapper or launcher that writes outside the run's workspace, point Build at the real binary with providers.${providerId}.cli.command in your user providers.yaml or BUILD_${providerId.toUpperCase()}_CLI_COMMAND.`,
969
+ {
970
+ retryable: false,
971
+ exitCode,
972
+ reason: SANDBOX_PATH_DENIED_REASON,
973
+ ...providerExecutionTransportStreamOptions(exit.stdout, exit.stderr, { maxPublicLength })
974
+ }
975
+ );
976
+ }
977
+
978
+ // src/core/memory/guardian.ts
979
+ import { randomBytes } from "crypto";
980
+ import { totalmem } from "os";
981
+ import { getHeapStatistics } from "v8";
982
+
983
+ // src/core/memory/provider-profiles.ts
984
+ function cloneProfile(profile) {
985
+ return {
986
+ ...profile,
987
+ gracefulDegradation: { ...profile.gracefulDegradation }
988
+ };
989
+ }
990
+ function cloneProfiles(profiles) {
991
+ return Object.fromEntries(
992
+ Object.entries(profiles).map(([providerId, profile]) => [providerId, cloneProfile(profile)])
993
+ );
994
+ }
995
+ var DEFAULT_PROFILES = {
996
+ default: {
997
+ warnThreshold: 0.85,
998
+ criticalThreshold: 0.9,
999
+ emergencyThreshold: 0.95,
1000
+ gracefulDegradation: {
1001
+ enabled: true,
1002
+ reduceParallelism: true,
1003
+ slowPolling: true
1004
+ },
1005
+ maxProcesses: 10
1006
+ },
1007
+ claude: {
1008
+ warnThreshold: 0.8,
1009
+ criticalThreshold: 0.88,
1010
+ emergencyThreshold: 0.93,
1011
+ gracefulDegradation: {
1012
+ enabled: true,
1013
+ reduceParallelism: true,
1014
+ slowPolling: true
1015
+ },
1016
+ maxProcesses: 3
1017
+ },
1018
+ gemini: {
1019
+ warnThreshold: 0.85,
1020
+ criticalThreshold: 0.92,
1021
+ emergencyThreshold: 0.96,
1022
+ gracefulDegradation: {
1023
+ enabled: true,
1024
+ reduceParallelism: true,
1025
+ slowPolling: false
1026
+ },
1027
+ maxProcesses: 8
1028
+ },
1029
+ codex: {
1030
+ warnThreshold: 0.82,
1031
+ criticalThreshold: 0.89,
1032
+ emergencyThreshold: 0.94,
1033
+ gracefulDegradation: {
1034
+ enabled: true,
1035
+ reduceParallelism: true,
1036
+ slowPolling: true
1037
+ },
1038
+ maxProcesses: 2
1039
+ },
1040
+ cursor: {
1041
+ warnThreshold: 0.75,
1042
+ criticalThreshold: 0.85,
1043
+ emergencyThreshold: 0.92,
1044
+ gracefulDegradation: {
1045
+ enabled: true,
1046
+ reduceParallelism: true,
1047
+ slowPolling: true
1048
+ },
1049
+ maxProcesses: 1
1050
+ },
1051
+ copilot: {
1052
+ warnThreshold: 0.78,
1053
+ criticalThreshold: 0.86,
1054
+ emergencyThreshold: 0.92,
1055
+ gracefulDegradation: {
1056
+ enabled: true,
1057
+ reduceParallelism: true,
1058
+ slowPolling: true
1059
+ },
1060
+ maxProcesses: 3
1061
+ },
1062
+ opencode: {
1063
+ warnThreshold: 0.85,
1064
+ criticalThreshold: 0.9,
1065
+ emergencyThreshold: 0.95,
1066
+ gracefulDegradation: {
1067
+ enabled: true,
1068
+ reduceParallelism: true,
1069
+ slowPolling: true
1070
+ },
1071
+ maxProcesses: 3
1072
+ },
1073
+ grok: {
1074
+ warnThreshold: 0.85,
1075
+ criticalThreshold: 0.92,
1076
+ emergencyThreshold: 0.96,
1077
+ gracefulDegradation: {
1078
+ enabled: true,
1079
+ reduceParallelism: true,
1080
+ slowPolling: true
1081
+ },
1082
+ maxProcesses: 3
1083
+ }
1084
+ };
1085
+ var MemoryProfilesManager = class _MemoryProfilesManager {
1086
+ static instance;
1087
+ profiles = cloneProfiles(DEFAULT_PROFILES);
1088
+ constructor() {
1089
+ }
1090
+ /**
1091
+ * Synchronous singleton construction. JavaScript module execution is single-threaded
1092
+ * here, so an event-loop-blocking spin lock is unnecessary and unsafe.
1093
+ */
1094
+ static getInstance() {
1095
+ if (_MemoryProfilesManager.instance) {
1096
+ return _MemoryProfilesManager.instance;
1097
+ }
1098
+ _MemoryProfilesManager.instance = new _MemoryProfilesManager();
1099
+ return _MemoryProfilesManager.instance;
1100
+ }
1101
+ /**
1102
+ * Replace profiles explicitly for an embedding or test harness.
1103
+ * Production startup does not call this from providers.yaml.
1104
+ */
1105
+ loadProfiles(config) {
1106
+ this.profiles = {
1107
+ ...cloneProfiles(DEFAULT_PROFILES),
1108
+ ...cloneProfiles(config)
1109
+ };
1110
+ }
1111
+ /**
1112
+ * Get profile for a specific provider
1113
+ * Falls back to 'default' if provider-specific profile not found
1114
+ */
1115
+ getProfile(providerId) {
1116
+ return cloneProfile(this.profiles[providerId] || this.profiles.default);
1117
+ }
1118
+ /**
1119
+ * Get all loaded profiles
1120
+ */
1121
+ getAllProfiles() {
1122
+ return cloneProfiles(this.profiles);
1123
+ }
1124
+ /**
1125
+ * Check if a memory ratio requires warning
1126
+ */
1127
+ shouldWarn(providerId, ratio) {
1128
+ const profile = this.getProfile(providerId);
1129
+ return ratio >= profile.warnThreshold;
1130
+ }
1131
+ /**
1132
+ * Check if memory ratio is at critical threshold
1133
+ */
1134
+ isCritical(providerId, ratio) {
1135
+ const profile = this.getProfile(providerId);
1136
+ return ratio >= profile.criticalThreshold;
1137
+ }
1138
+ /**
1139
+ * Check if memory ratio is at emergency threshold
1140
+ */
1141
+ isEmergency(providerId, ratio) {
1142
+ const profile = this.getProfile(providerId);
1143
+ return ratio >= profile.emergencyThreshold;
1144
+ }
1145
+ /**
1146
+ * Get graceful degradation strategy for provider
1147
+ */
1148
+ getGracefulDegradationStrategy(providerId) {
1149
+ const profile = this.getProfile(providerId);
1150
+ return profile.gracefulDegradation;
1151
+ }
1152
+ /**
1153
+ * Get max concurrent processes for provider
1154
+ */
1155
+ getMaxProcesses(providerId) {
1156
+ const profile = this.getProfile(providerId);
1157
+ return profile.maxProcesses;
1158
+ }
1159
+ /**
1160
+ * Reset to defaults (for testing)
1161
+ */
1162
+ static resetForTesting() {
1163
+ if (_MemoryProfilesManager.instance) {
1164
+ _MemoryProfilesManager.instance.profiles = cloneProfiles(DEFAULT_PROFILES);
1165
+ }
1166
+ }
1167
+ };
1168
+ function getMemoryProfilesManager() {
1169
+ return MemoryProfilesManager.getInstance();
1170
+ }
1171
+
1172
+ // src/core/memory/guardian.ts
1173
+ var MemoryGuardian = class _MemoryGuardian {
1174
+ static instance;
1175
+ trackedProcesses = /* @__PURE__ */ new Map();
1176
+ pids = [];
1177
+ // LIFO ordering, de-duplicated (legacy support)
1178
+ interval;
1179
+ isShuttingDown = false;
1180
+ isActive = false;
1181
+ exitHandlerRegistered = false;
1182
+ emergencyHandler;
1183
+ handleExit = () => {
1184
+ this.stop();
1185
+ };
1186
+ // CRITICAL FIX: Track active kill operations to prevent race conditions
1187
+ activeKillOperations = /* @__PURE__ */ new Set();
1188
+ // Adaptive intervals (ms)
1189
+ // Increased from 2s/1s/500ms to reduce overhead and false alarms
1190
+ currentInterval = 1e4;
1191
+ // Start slow (10s)
1192
+ NORMAL_INTERVAL = 1e4;
1193
+ // 10s when < warn threshold
1194
+ WARNING_INTERVAL = 5e3;
1195
+ // 5s when warn-critical
1196
+ CRITICAL_INTERVAL = 2e3;
1197
+ // 2s when > critical threshold
1198
+ // Kill strategy configuration
1199
+ // - Default: Warn at provider warn%, kill at critical%+ (hybrid approach)
1200
+ // - BUILD_MEMORY_KILL=0: Never kill (log-only mode)
1201
+ // - BUILD_MEMORY_KILL=1: Kill at all thresholds (aggressive mode)
1202
+ killMode = this.getKillMode();
1203
+ lastCheckTime = 0;
1204
+ lastWarnTime = 0;
1205
+ // Default thresholds (fallback if provider profiles not available)
1206
+ DEFAULT_WARN = 0.85;
1207
+ DEFAULT_CRIT = 0.9;
1208
+ DEFAULT_EMRG = 0.95;
1209
+ constructor() {
1210
+ }
1211
+ resolveRssLimitMb() {
1212
+ const explicitMb = parseInt(process.env.BUILD_RSS_LIMIT_MB || "", 10);
1213
+ if (!Number.isNaN(explicitMb) && explicitMb > 0) {
1214
+ return explicitMb;
1215
+ }
1216
+ const pctRaw = process.env.BUILD_RSS_LIMIT_PCT;
1217
+ if (!pctRaw) return null;
1218
+ const pct = Number(pctRaw);
1219
+ if (!Number.isFinite(pct) || pct <= 0) return null;
1220
+ const totalMb = totalmem() / (1024 * 1024);
1221
+ const derived = Math.floor(totalMb * pct / 100);
1222
+ return derived > 0 ? derived : null;
1223
+ }
1224
+ static getInstance() {
1225
+ if (!_MemoryGuardian.instance) {
1226
+ _MemoryGuardian.instance = new _MemoryGuardian();
1227
+ }
1228
+ return _MemoryGuardian.instance;
1229
+ }
1230
+ /**
1231
+ * Determine kill mode from environment variable
1232
+ * - '0' or 'false': Never kill (log-only)
1233
+ * - '1' or 'true': Kill at all thresholds (aggressive)
1234
+ * - undefined or other: Hybrid (warn only at warn-crit%, kill at crit%+)
1235
+ */
1236
+ getKillMode() {
1237
+ const env = process.env.BUILD_MEMORY_KILL;
1238
+ if (env === "0" || env === "false") {
1239
+ return "never";
1240
+ }
1241
+ if (env === "1" || env === "true") {
1242
+ return "always";
1243
+ }
1244
+ return "hybrid";
1245
+ }
1246
+ /**
1247
+ * Get memory thresholds for a provider
1248
+ */
1249
+ getThresholds(provider) {
1250
+ try {
1251
+ const profilesManager = getMemoryProfilesManager();
1252
+ const profile = profilesManager.getProfile(provider || "default");
1253
+ return {
1254
+ warn: profile.warnThreshold,
1255
+ crit: profile.criticalThreshold,
1256
+ emrg: profile.emergencyThreshold
1257
+ };
1258
+ } catch {
1259
+ return {
1260
+ warn: this.DEFAULT_WARN,
1261
+ crit: this.DEFAULT_CRIT,
1262
+ emrg: this.DEFAULT_EMRG
1263
+ };
1264
+ }
1265
+ }
1266
+ /**
1267
+ * Phase 1: Evaluate a single process memory sample and return a decision.
1268
+ * PLM calls this instead of using hard-coded thresholds.
1269
+ *
1270
+ * Policy:
1271
+ * - If no RSS limit configured (BUILD_RSS_LIMIT_MB/PCT), warn-only (never kill)
1272
+ * - If RSS limit configured but killMode='never', warn-only
1273
+ * - If RSS limit configured and kill enabled, kill at/above limit
1274
+ * - Runaway (2x limit) gets immediate kill (graceMs=0)
1275
+ */
1276
+ evaluateProcessSample(sample) {
1277
+ const rssLimitMB = this.resolveRssLimitMb();
1278
+ const killEnabled = rssLimitMB !== null && this.killMode !== "never";
1279
+ const rssMB = sample.rssMB;
1280
+ const details = {
1281
+ processId: sample.processId,
1282
+ pid: sample.pid,
1283
+ rssMB,
1284
+ rssLimitMB,
1285
+ provider: sample.provider ?? null,
1286
+ command: sample.command ?? null,
1287
+ workloadClass: sample.workloadClass,
1288
+ killMode: this.killMode
1289
+ };
1290
+ if (!rssLimitMB) {
1291
+ if (rssMB >= 1e3) {
1292
+ return {
1293
+ action: "warn",
1294
+ reason: "high_rss_no_cap_configured",
1295
+ details
1296
+ };
1297
+ }
1298
+ return { action: "none" };
1299
+ }
1300
+ const warnAtMB = Math.floor(rssLimitMB * 0.8);
1301
+ const runawayAtMB = rssLimitMB * 2;
1302
+ if (rssMB >= runawayAtMB) {
1303
+ if (!killEnabled) {
1304
+ return { action: "warn", reason: "runaway_rss_would_kill_but_disabled", details };
1305
+ }
1306
+ return {
1307
+ action: "kill",
1308
+ reason: "runaway",
1309
+ graceMs: 0,
1310
+ // immediate
1311
+ details
1312
+ };
1313
+ }
1314
+ if (rssMB >= rssLimitMB) {
1315
+ if (!killEnabled) {
1316
+ return { action: "warn", reason: "over_cap_would_kill_but_disabled", details };
1317
+ }
1318
+ return {
1319
+ action: "kill",
1320
+ reason: "over_cap",
1321
+ graceMs: 5e3,
1322
+ // SIGTERM -> wait -> SIGKILL
1323
+ details
1324
+ };
1325
+ }
1326
+ if (rssMB >= warnAtMB) {
1327
+ return { action: "warn", reason: "approaching_rss_cap", details };
1328
+ }
1329
+ return { action: "none" };
1330
+ }
1331
+ /**
1332
+ * Start memory monitoring with adaptive intervals
1333
+ */
1334
+ start() {
1335
+ if (this.isActive) return;
1336
+ this.isActive = true;
1337
+ this.scheduleCheck();
1338
+ if (!this.exitHandlerRegistered) {
1339
+ process.on("exit", this.handleExit);
1340
+ this.exitHandlerRegistered = true;
1341
+ }
1342
+ }
1343
+ /**
1344
+ * Stop monitoring and cleanup
1345
+ */
1346
+ stop() {
1347
+ this.isActive = false;
1348
+ if (this.interval) {
1349
+ clearTimeout(this.interval);
1350
+ this.interval = void 0;
1351
+ }
1352
+ if (this.exitHandlerRegistered) {
1353
+ process.off("exit", this.handleExit);
1354
+ this.exitHandlerRegistered = false;
1355
+ }
1356
+ }
1357
+ /**
1358
+ * Schedule next check with adaptive interval
1359
+ */
1360
+ scheduleCheck() {
1361
+ if (!this.isActive) {
1362
+ return;
1363
+ }
1364
+ this.interval = setTimeout(() => {
1365
+ this.check();
1366
+ if (this.isActive) {
1367
+ this.scheduleCheck();
1368
+ }
1369
+ }, this.currentInterval);
1370
+ }
1371
+ /**
1372
+ * Ultra-lightweight memory check
1373
+ * Target: <1ms execution time
1374
+ */
1375
+ check() {
1376
+ const now = Date.now();
1377
+ if (now - this.lastCheckTime < 100) return;
1378
+ this.lastCheckTime = now;
1379
+ const { heapUsed, rss } = process.memoryUsage();
1380
+ const { heap_size_limit } = getHeapStatistics();
1381
+ let ratio = heapUsed / heap_size_limit;
1382
+ const rssLimitMb = this.resolveRssLimitMb();
1383
+ if (typeof rssLimitMb === "number" && rssLimitMb > 0) {
1384
+ const rssRatio = rss / (rssLimitMb * 1024 * 1024);
1385
+ if (rssRatio > ratio) ratio = rssRatio;
1386
+ }
1387
+ const currentProvider = this.getMostCommonProvider();
1388
+ const thresholds = this.getThresholds(currentProvider);
1389
+ if (ratio < thresholds.warn) {
1390
+ this.currentInterval = this.NORMAL_INTERVAL;
1391
+ return;
1392
+ }
1393
+ if (ratio >= thresholds.emrg) {
1394
+ this.emergencyKill(ratio, thresholds);
1395
+ return;
1396
+ }
1397
+ if (ratio >= thresholds.crit) {
1398
+ this.currentInterval = this.CRITICAL_INTERVAL;
1399
+ if (!this.isShuttingDown) {
1400
+ this.gracefulKill(ratio, thresholds);
1401
+ }
1402
+ return;
1403
+ }
1404
+ this.currentInterval = this.WARNING_INTERVAL;
1405
+ this.warn(ratio, currentProvider);
1406
+ }
1407
+ /**
1408
+ * Track a process for memory management
1409
+ *
1410
+ * CRITICAL FIX: Ensure atomic updates to both data structures to prevent
1411
+ * inconsistent state between legacy array and new Map tracking systems.
1412
+ */
1413
+ track(pid, provider) {
1414
+ if (!pid || pid <= 0) {
1415
+ return;
1416
+ }
1417
+ const trackingInfo = {
1418
+ pid,
1419
+ provider,
1420
+ startedAt: Date.now()
1421
+ };
1422
+ if (!this.pids.includes(pid)) {
1423
+ this.pids.push(pid);
1424
+ }
1425
+ this.trackedProcesses.set(pid, trackingInfo);
1426
+ }
1427
+ /**
1428
+ * Untrack a process
1429
+ */
1430
+ untrack(pid) {
1431
+ const idx = this.pids.indexOf(pid);
1432
+ if (idx !== -1) {
1433
+ this.pids.splice(idx, 1);
1434
+ }
1435
+ this.trackedProcesses.delete(pid);
1436
+ }
1437
+ /**
1438
+ * Get most common provider from tracked processes
1439
+ */
1440
+ getMostCommonProvider() {
1441
+ const providers = /* @__PURE__ */ new Map();
1442
+ for (const tracking of this.trackedProcesses.values()) {
1443
+ if (tracking.provider) {
1444
+ providers.set(tracking.provider, (providers.get(tracking.provider) || 0) + 1);
1445
+ }
1446
+ }
1447
+ let maxProvider;
1448
+ let maxCount = 0;
1449
+ for (const [provider, count] of providers) {
1450
+ if (count > maxCount) {
1451
+ maxProvider = provider;
1452
+ maxCount = count;
1453
+ }
1454
+ }
1455
+ return maxProvider;
1456
+ }
1457
+ /**
1458
+ * Warn (minimal logging, max once per 10s)
1459
+ */
1460
+ warn(ratio, provider) {
1461
+ const now = Date.now();
1462
+ if (now - this.lastWarnTime < 1e4) return;
1463
+ this.lastWarnTime = now;
1464
+ const pct = Math.floor(ratio * 100);
1465
+ const processCount = this.trackedProcesses.size || this.pids.length;
1466
+ emitWarning(
1467
+ "PERF-002",
1468
+ {
1469
+ subsystem: "memory-guardian",
1470
+ provider,
1471
+ executionPhase: "execution"
1472
+ },
1473
+ {
1474
+ severity: pct >= 85 ? "WARN" /* WARN */ : "INFO" /* INFO */,
1475
+ metadata: {
1476
+ percentage: pct,
1477
+ processCount,
1478
+ killMode: this.killMode,
1479
+ threshold: "warn"
1480
+ }
1481
+ }
1482
+ );
1483
+ if (this.killMode === "never") {
1484
+ emitWarning(
1485
+ "CFG-002",
1486
+ {
1487
+ subsystem: "memory-guardian",
1488
+ executionPhase: "execution"
1489
+ },
1490
+ {
1491
+ severity: "INFO" /* INFO */,
1492
+ metadata: {
1493
+ setting: "BUILD_MEMORY_KILL",
1494
+ value: "0",
1495
+ message: "Log-only mode: Set BUILD_MEMORY_KILL=1 to enable process termination"
1496
+ }
1497
+ }
1498
+ );
1499
+ } else if (this.killMode === "hybrid") {
1500
+ const profile = this.getThresholds(provider);
1501
+ emitWarning(
1502
+ "PERF-002",
1503
+ {
1504
+ subsystem: "memory-guardian",
1505
+ provider,
1506
+ executionPhase: "execution"
1507
+ },
1508
+ {
1509
+ severity: "INFO" /* INFO */,
1510
+ metadata: {
1511
+ killThreshold: Math.floor(profile.crit * 100),
1512
+ currentUsage: pct,
1513
+ message: `Hybrid mode: Will kill processes at ${Math.floor(profile.crit * 100)}%+ (currently ${pct}%)`
1514
+ }
1515
+ }
1516
+ );
1517
+ }
1518
+ }
1519
+ /**
1520
+ * Graceful kill - newest processes first
1521
+ * Kill 50% of processes to free memory quickly
1522
+ * Respects kill mode: never (log only), hybrid (kill at critical%+), always (kill at all thresholds)
1523
+ *
1524
+ * CRITICAL FIX: Track active kill operations to prevent race conditions and ensure
1525
+ * proper state synchronization during concurrent kill operations.
1526
+ */
1527
+ gracefulKill(ratio, _thresholds = this.getThresholds()) {
1528
+ const pct = Math.floor(ratio * 100);
1529
+ const operationId = `graceful-${Date.now()}-${randomBytes(8).toString("hex")}`;
1530
+ if (this.killMode === "never") {
1531
+ const allPids2 = this.getTerminationPids();
1532
+ emitWarning(
1533
+ "PERF-002",
1534
+ {
1535
+ subsystem: "memory-guardian",
1536
+ executionPhase: "execution"
1537
+ },
1538
+ {
1539
+ severity: "ERROR" /* ERROR */,
1540
+ metadata: {
1541
+ percentage: pct,
1542
+ threshold: "critical",
1543
+ killMode: "never",
1544
+ wouldKillCount: Math.max(1, Math.floor(allPids2.length / 2)),
1545
+ trackedPids: allPids2,
1546
+ message: `CRITICAL: ${pct}% memory - would kill processes (log-only mode)`
1547
+ }
1548
+ }
1549
+ );
1550
+ emitWarning(
1551
+ "CFG-002",
1552
+ {
1553
+ subsystem: "memory-guardian",
1554
+ executionPhase: "execution"
1555
+ },
1556
+ {
1557
+ severity: "ERROR" /* ERROR */,
1558
+ metadata: {
1559
+ setting: "BUILD_MEMORY_KILL",
1560
+ value: "0",
1561
+ message: "Set BUILD_MEMORY_KILL=1 or remove BUILD_MEMORY_KILL=0 to enable process termination"
1562
+ }
1563
+ }
1564
+ );
1565
+ return;
1566
+ }
1567
+ this.activeKillOperations.add(operationId);
1568
+ this.isShuttingDown = true;
1569
+ const allPids = this.getTerminationPids();
1570
+ const killCount = Math.max(1, Math.floor(allPids.length / 2));
1571
+ emitWarning(
1572
+ "PERF-002",
1573
+ {
1574
+ subsystem: "memory-guardian",
1575
+ executionPhase: "execution"
1576
+ },
1577
+ {
1578
+ severity: "ERROR" /* ERROR */,
1579
+ metadata: {
1580
+ percentage: pct,
1581
+ threshold: "critical",
1582
+ killMode: this.killMode,
1583
+ killCount,
1584
+ totalProcesses: allPids.length,
1585
+ operationId,
1586
+ message: `CRITICAL: ${pct}% memory - killing newest processes (${this.killMode} mode)`
1587
+ }
1588
+ }
1589
+ );
1590
+ const killedPids = [];
1591
+ for (let i = 0; i < killCount && allPids.length > 0; i++) {
1592
+ const pid = allPids.pop();
1593
+ try {
1594
+ process.kill(pid, "SIGTERM");
1595
+ killedPids.push(pid);
1596
+ } catch {
1597
+ }
1598
+ }
1599
+ emitWarning(
1600
+ "PERF-002",
1601
+ {
1602
+ subsystem: "memory-guardian",
1603
+ executionPhase: "cleanup"
1604
+ },
1605
+ {
1606
+ severity: "ERROR" /* ERROR */,
1607
+ metadata: {
1608
+ killedCount: killedPids.length,
1609
+ killedPids,
1610
+ operationId,
1611
+ message: `Killed ${killedPids.length} processes: ${killedPids.join(", ")}`
1612
+ }
1613
+ }
1614
+ );
1615
+ setTimeout(() => {
1616
+ try {
1617
+ for (const pid of killedPids) {
1618
+ try {
1619
+ process.kill(pid, 0);
1620
+ try {
1621
+ process.kill(pid, "SIGKILL");
1622
+ } catch {
1623
+ }
1624
+ } catch {
1625
+ }
1626
+ }
1627
+ } finally {
1628
+ this.activeKillOperations.delete(operationId);
1629
+ if (this.activeKillOperations.size === 0) {
1630
+ this.isShuttingDown = false;
1631
+ }
1632
+ emitWarning(
1633
+ "PERF-002",
1634
+ {
1635
+ subsystem: "memory-guardian",
1636
+ executionPhase: "cleanup"
1637
+ },
1638
+ {
1639
+ severity: "INFO" /* INFO */,
1640
+ metadata: {
1641
+ operationId,
1642
+ message: "Graceful kill operation completed"
1643
+ }
1644
+ }
1645
+ );
1646
+ }
1647
+ }, 3e3);
1648
+ }
1649
+ /**
1650
+ * Emergency kill - all processes immediately
1651
+ * Last resort at emergency% heap usage
1652
+ * Respects kill mode: never (log only), hybrid/always (kill all processes)
1653
+ *
1654
+ * CRITICAL FIX: Add proper error handling and cleanup to prevent
1655
+ * inconsistent state during emergency termination.
1656
+ */
1657
+ emergencyKill(ratio, _thresholds = this.getThresholds()) {
1658
+ const pct = Math.floor(ratio * 100);
1659
+ const operationId = `emergency-${Date.now()}-${randomBytes(8).toString("hex")}`;
1660
+ this.activeKillOperations.add(operationId);
1661
+ try {
1662
+ if (this.killMode === "never") {
1663
+ const allPids2 = this.getTerminationPids();
1664
+ emitWarning(
1665
+ "PERF-002",
1666
+ {
1667
+ subsystem: "memory-guardian",
1668
+ executionPhase: "execution"
1669
+ },
1670
+ {
1671
+ severity: "ERROR" /* ERROR */,
1672
+ metadata: {
1673
+ percentage: pct,
1674
+ threshold: "emergency",
1675
+ killMode: "never",
1676
+ wouldKillCount: allPids2.length,
1677
+ trackedPids: allPids2,
1678
+ operationId,
1679
+ message: `EMERGENCY: ${pct}% memory - would kill ALL processes (log-only mode)`
1680
+ }
1681
+ }
1682
+ );
1683
+ emitWarning(
1684
+ "CFG-002",
1685
+ {
1686
+ subsystem: "memory-guardian",
1687
+ executionPhase: "execution"
1688
+ },
1689
+ {
1690
+ severity: "ERROR" /* ERROR */,
1691
+ metadata: {
1692
+ setting: "BUILD_MEMORY_KILL",
1693
+ value: "0",
1694
+ criticalWarning: "SYSTEM AT RISK OF OOM CRASH - Manual intervention strongly recommended",
1695
+ message: "Set BUILD_MEMORY_KILL=1 or remove BUILD_MEMORY_KILL=0 to enable process termination"
1696
+ }
1697
+ }
1698
+ );
1699
+ return;
1700
+ }
1701
+ const limiterOwned = this.getTrackedPids().length === 0;
1702
+ const allPids = this.getTerminationPids();
1703
+ if (allPids.length === 0) {
1704
+ emitWarning(
1705
+ "PERF-002",
1706
+ {
1707
+ subsystem: "memory-guardian",
1708
+ executionPhase: "execution"
1709
+ },
1710
+ {
1711
+ severity: "ERROR" /* ERROR */,
1712
+ metadata: {
1713
+ percentage: pct,
1714
+ threshold: "emergency",
1715
+ processCount: 0,
1716
+ operationId,
1717
+ action: "skipping forced exit to prevent data loss",
1718
+ message: `EMERGENCY: ${pct}% memory - no tracked child processes`
1719
+ }
1720
+ }
1721
+ );
1722
+ this.currentInterval = this.CRITICAL_INTERVAL;
1723
+ return;
1724
+ }
1725
+ emitWarning(
1726
+ "PERF-002",
1727
+ {
1728
+ subsystem: "memory-guardian",
1729
+ executionPhase: "execution"
1730
+ },
1731
+ {
1732
+ severity: "ERROR" /* ERROR */,
1733
+ metadata: {
1734
+ percentage: pct,
1735
+ threshold: "emergency",
1736
+ killMode: this.killMode,
1737
+ killCount: allPids.length,
1738
+ operationId,
1739
+ message: `EMERGENCY: ${pct}% memory - killing ALL ${allPids.length} processes (${this.killMode} mode)`
1740
+ }
1741
+ }
1742
+ );
1743
+ const killedCount = allPids.length;
1744
+ const successfulKills = [];
1745
+ const failedKills = [];
1746
+ for (const pid of allPids) {
1747
+ try {
1748
+ if (limiterOwned && process.platform !== "win32") {
1749
+ try {
1750
+ signalProcessGroup(pid, "SIGKILL");
1751
+ } catch {
1752
+ process.kill(pid, "SIGKILL");
1753
+ }
1754
+ } else {
1755
+ process.kill(pid, "SIGKILL");
1756
+ }
1757
+ successfulKills.push(pid);
1758
+ } catch (error) {
1759
+ failedKills.push({ pid, error });
1760
+ }
1761
+ }
1762
+ emitWarning(
1763
+ "PERF-002",
1764
+ {
1765
+ subsystem: "memory-guardian",
1766
+ executionPhase: "cleanup"
1767
+ },
1768
+ {
1769
+ severity: "ERROR" /* ERROR */,
1770
+ metadata: {
1771
+ successfulKills: successfulKills.length,
1772
+ totalAttempted: killedCount,
1773
+ killedPids: successfulKills,
1774
+ operationId,
1775
+ message: `Force-killed ${successfulKills.length}/${killedCount} processes to prevent crash`
1776
+ }
1777
+ }
1778
+ );
1779
+ if (failedKills.length > 0) {
1780
+ emitWarning(
1781
+ "PERF-002",
1782
+ {
1783
+ subsystem: "memory-guardian",
1784
+ executionPhase: "cleanup"
1785
+ },
1786
+ {
1787
+ severity: "ERROR" /* ERROR */,
1788
+ metadata: {
1789
+ failedCount: failedKills.length,
1790
+ failedPids: failedKills.map((f) => f.pid),
1791
+ operationId,
1792
+ message: `Failed to kill ${failedKills.length} processes: ${failedKills.map((f) => f.pid).join(", ")}`
1793
+ }
1794
+ }
1795
+ );
1796
+ }
1797
+ this.pids.length = 0;
1798
+ this.trackedProcesses.clear();
1799
+ this.stop();
1800
+ const handler = this.emergencyHandler;
1801
+ if (handler) {
1802
+ try {
1803
+ handler({ pct, killedCount: successfulKills.length, pids: successfulKills });
1804
+ } catch (handlerError) {
1805
+ emitWarning(
1806
+ "PERF-002",
1807
+ {
1808
+ subsystem: "memory-guardian",
1809
+ executionPhase: "cleanup"
1810
+ },
1811
+ {
1812
+ severity: "ERROR" /* ERROR */,
1813
+ metadata: {
1814
+ error: String(handlerError),
1815
+ operationId,
1816
+ message: `Emergency handler failed: ${handlerError}`
1817
+ }
1818
+ }
1819
+ );
1820
+ requestProcessExit(1);
1821
+ }
1822
+ } else {
1823
+ requestProcessExit(1);
1824
+ }
1825
+ } finally {
1826
+ this.activeKillOperations.delete(operationId);
1827
+ }
1828
+ }
1829
+ /**
1830
+ * Get current memory status (for debugging)
1831
+ */
1832
+ getStatus() {
1833
+ const usage = process.memoryUsage();
1834
+ const { heap_size_limit } = getHeapStatistics();
1835
+ return {
1836
+ heapUsedMB: Math.round(usage.heapUsed / 1024 / 1024),
1837
+ heapTotalMB: Math.round(heap_size_limit / 1024 / 1024),
1838
+ heapUsedPercent: Math.round(usage.heapUsed / heap_size_limit * 100),
1839
+ processCount: Math.max(this.trackedProcesses.size, this.pids.length),
1840
+ interval: this.currentInterval,
1841
+ mostCommonProvider: this.getMostCommonProvider()
1842
+ };
1843
+ }
1844
+ /**
1845
+ * Get tracked PIDs (for testing)
1846
+ */
1847
+ getTrackedPids() {
1848
+ return [
1849
+ ...this.trackedProcesses.keys(),
1850
+ ...this.pids.filter((p) => !this.trackedProcesses.has(p))
1851
+ ];
1852
+ }
1853
+ /**
1854
+ * One ownership policy for both termination stages. Preserve direct tracking
1855
+ * precedence; competition parents fall back to the workers they registered
1856
+ * with the process limiter. Return oldest first for newest-first shedding.
1857
+ */
1858
+ getTerminationPids() {
1859
+ const direct = this.getTrackedPids();
1860
+ if (direct.length > 0) return direct;
1861
+ return globalProcessLimiter.getTrackedProcesses().filter(
1862
+ (tracked) => tracked.pid !== void 0 && Number.isInteger(tracked.pid) && tracked.pid > 0
1863
+ ).sort((a, b) => b.ageMs - a.ageMs).map((tracked) => tracked.pid);
1864
+ }
1865
+ /**
1866
+ * Check if log-only mode is enabled
1867
+ */
1868
+ isLogOnly() {
1869
+ return this.killMode === "never";
1870
+ }
1871
+ /**
1872
+ * Get current kill mode
1873
+ */
1874
+ getKillModeStatus() {
1875
+ return this.killMode;
1876
+ }
1877
+ /**
1878
+ * Register an emergency handler. If set, the guardian will call this instead of exiting.
1879
+ */
1880
+ setEmergencyHandler(handler) {
1881
+ this.emergencyHandler = handler;
1882
+ }
1883
+ /**
1884
+ * Reset instance (for testing only)
1885
+ */
1886
+ static resetForTesting() {
1887
+ if (_MemoryGuardian.instance) {
1888
+ if (_MemoryGuardian.instance.exitHandlerRegistered) {
1889
+ process.off("exit", _MemoryGuardian.instance.handleExit);
1890
+ _MemoryGuardian.instance.exitHandlerRegistered = false;
1891
+ }
1892
+ _MemoryGuardian.instance.stop();
1893
+ _MemoryGuardian.instance.pids.length = 0;
1894
+ _MemoryGuardian.instance.trackedProcesses.clear();
1895
+ _MemoryGuardian.instance.isShuttingDown = false;
1896
+ _MemoryGuardian.instance.lastCheckTime = 0;
1897
+ _MemoryGuardian.instance.lastWarnTime = 0;
1898
+ _MemoryGuardian.instance.currentInterval = 1e4;
1899
+ }
1900
+ _MemoryGuardian.instance = void 0;
1901
+ }
1902
+ };
1903
+
1904
+ // src/core/providers/shared/subprocess-tracking.ts
1905
+ var logger = createLogger("ProviderRunner");
1906
+ function trackSubprocess(subprocess) {
1907
+ if (!subprocess) {
1908
+ return null;
1909
+ }
1910
+ const guardian = MemoryGuardian.getInstance();
1911
+ const trackedPid = typeof subprocess.pid === "number" && subprocess.pid > 0 ? subprocess.pid : null;
1912
+ if (trackedPid) {
1913
+ guardian.track(trackedPid);
1914
+ }
1915
+ return trackedPid;
1916
+ }
1917
+ var subprocessFallbackTracking = /* @__PURE__ */ new WeakMap();
1918
+ var fallbackSubprocesses = /* @__PURE__ */ new Map();
1919
+ var fallbackCleanupRegistered = false;
1920
+ function getFallbackTrackedSubprocesses() {
1921
+ return Array.from(fallbackSubprocesses.values());
1922
+ }
1923
+ function killAllFallbackTrackedSubprocesses(signal = "SIGTERM") {
1924
+ let killed = 0;
1925
+ for (const subprocess of getFallbackTrackedSubprocesses()) {
1926
+ if (killFallbackSubprocess(subprocess, signal)) {
1927
+ killed += 1;
1928
+ }
1929
+ }
1930
+ return killed;
1931
+ }
1932
+ var fallbackExitHandler;
1933
+ function registerFallbackCleanup() {
1934
+ if (fallbackCleanupRegistered) {
1935
+ return;
1936
+ }
1937
+ fallbackCleanupRegistered = true;
1938
+ fallbackExitHandler = () => {
1939
+ killAllFallbackTrackedSubprocesses("SIGTERM");
1940
+ killAllFallbackTrackedSubprocesses("SIGKILL");
1941
+ };
1942
+ process.removeListener("exit", fallbackExitHandler);
1943
+ process.on("exit", fallbackExitHandler);
1944
+ }
1945
+ function killFallbackSubprocess(subprocess, signal = "SIGTERM") {
1946
+ try {
1947
+ return sendSignalToSubprocessTree(subprocess, signal);
1948
+ } catch (error) {
1949
+ logger.warn(`[BaseRunner] Failed to kill fallback subprocess: ${error}`);
1950
+ return false;
1951
+ }
1952
+ }
1953
+ async function trackSubprocessAsync(subprocess) {
1954
+ if (!subprocess) {
1955
+ return null;
1956
+ }
1957
+ const guardian = MemoryGuardian.getInstance();
1958
+ let trackedPid = null;
1959
+ const maxPidWaitMs = Math.max(250, readEnv(BUILD_SUBPROCESS_PID_WAIT_MS).value ?? 2e3);
1960
+ await new Promise((resolve) => {
1961
+ let settled = false;
1962
+ let pollInterval;
1963
+ const finish = () => {
1964
+ if (settled) return;
1965
+ settled = true;
1966
+ if (pollInterval) {
1967
+ clearInterval(pollInterval);
1968
+ }
1969
+ resolve();
1970
+ };
1971
+ const exitListener = () => {
1972
+ finish();
1973
+ };
1974
+ subprocess.once?.("exit", exitListener);
1975
+ subprocess.once?.("close", exitListener);
1976
+ if (typeof subprocess.pid === "number" && subprocess.pid > 0) {
1977
+ trackedPid = subprocess.pid;
1978
+ guardian.track(subprocess.pid);
1979
+ finish();
1980
+ } else {
1981
+ const PID_POLL_INTERVAL_MS = 25;
1982
+ const startTime = Date.now();
1983
+ pollInterval = setInterval(() => {
1984
+ if (typeof subprocess.pid === "number" && subprocess.pid > 0) {
1985
+ trackedPid = subprocess.pid;
1986
+ guardian.track(subprocess.pid);
1987
+ finish();
1988
+ } else if (Date.now() - startTime >= maxPidWaitMs) {
1989
+ if (!subprocess.killed && (subprocess.exitCode ?? null) === null) {
1990
+ const subprocessId = /* @__PURE__ */ Symbol("subprocess-fallback");
1991
+ subprocessFallbackTracking.set(subprocess, subprocessId);
1992
+ fallbackSubprocesses.set(subprocessId, subprocess);
1993
+ registerFallbackCleanup();
1994
+ logger.warn(
1995
+ `[BaseRunner] PID not available after ${maxPidWaitMs}ms - using fallback tracking by subprocess reference`,
1996
+ { maxWaitMs: maxPidWaitMs }
1997
+ );
1998
+ }
1999
+ finish();
2000
+ }
2001
+ }, PID_POLL_INTERVAL_MS);
2002
+ pollInterval.unref?.();
2003
+ }
2004
+ });
2005
+ return trackedPid;
2006
+ }
2007
+ function untrackSubprocess(trackedPid, subprocess) {
2008
+ if (trackedPid) {
2009
+ const guardian = MemoryGuardian.getInstance();
2010
+ guardian.untrack(trackedPid);
2011
+ } else if (subprocess) {
2012
+ const subprocessId = subprocessFallbackTracking.get(subprocess);
2013
+ if (subprocessId) {
2014
+ fallbackSubprocesses.delete(subprocessId);
2015
+ subprocessFallbackTracking.delete(subprocess);
2016
+ }
2017
+ }
2018
+ }
2019
+
2020
+ // src/core/providers/shared/base-runner.ts
2021
+ var logger2 = createLogger("ProviderRunner");
2022
+ var PROVIDER_TERMINATION_GRACE_MS = 2e3;
2023
+ var PROVIDER_ARGV_PAYLOAD_REDACTION = "[argv-redacted]";
2024
+ var PROVIDER_SINGLE_ARG_MAX_SAFE_BYTES = 128 * 1024;
2025
+ var PROVIDER_PROCESS_ARG_ENV_MAX_SAFE_BYTES = 256 * 1024;
2026
+ function computePromptFingerprint(prompt) {
2027
+ return createHash("sha256").update(prompt).digest("hex");
2028
+ }
2029
+ var DEFAULT_TIMEOUT = DEFAULT_TIMEOUT_MS;
2030
+ var DEFAULT_STREAM_CAPTURE_BYTES = 1024 * 1024;
2031
+ function throwIfAbortAlreadyRequested(abortSignal, providerName) {
2032
+ if (!abortSignal?.aborted) {
2033
+ return;
2034
+ }
2035
+ const hostTimeout = isHostTimeoutAbortReason(abortSignal.reason);
2036
+ const detail = hostTimeout ? formatHostTimeoutTerminationDetail(abortSignal.reason) : void 0;
2037
+ throw new ProviderExecutionError(
2038
+ `[${providerName}] Provider execution aborted before subprocess start${detail ? ` (${detail})` : ""}`,
2039
+ {
2040
+ retryable: false,
2041
+ reason: hostTimeout ? "timeout" : "abort",
2042
+ terminationSource: "abortSignal",
2043
+ providerName
2044
+ }
2045
+ );
2046
+ }
2047
+ var BoundedOutputBuffer = class {
2048
+ chunks = [];
2049
+ bytes = 0;
2050
+ append(chunk, maxBytes) {
2051
+ if (!chunk) {
2052
+ return;
2053
+ }
2054
+ if (!Number.isFinite(maxBytes) || maxBytes <= 0) {
2055
+ this.clear();
2056
+ return;
2057
+ }
2058
+ const boundedMaxBytes = Math.floor(maxBytes);
2059
+ if (boundedMaxBytes <= 0) {
2060
+ this.clear();
2061
+ return;
2062
+ }
2063
+ const nextChunk = chunk;
2064
+ const nextChunkBytes = Buffer.byteLength(nextChunk, "utf8");
2065
+ if (nextChunkBytes >= boundedMaxBytes) {
2066
+ const tail = trimUtf8Tail(nextChunk, boundedMaxBytes);
2067
+ this.chunks.length = 0;
2068
+ this.bytes = 0;
2069
+ if (tail.text) {
2070
+ this.chunks.push(tail.text);
2071
+ this.bytes = tail.bytes;
2072
+ }
2073
+ return;
2074
+ }
2075
+ this.chunks.push(nextChunk);
2076
+ this.bytes += nextChunkBytes;
2077
+ while (this.bytes > boundedMaxBytes && this.chunks.length > 0) {
2078
+ const overflowBytes = this.bytes - boundedMaxBytes;
2079
+ const first = this.chunks[0] ?? "";
2080
+ const firstBytes = Buffer.byteLength(first, "utf8");
2081
+ if (firstBytes <= overflowBytes) {
2082
+ this.chunks.shift();
2083
+ this.bytes -= firstBytes;
2084
+ continue;
2085
+ }
2086
+ const trimmed = trimUtf8Tail(first, firstBytes - overflowBytes);
2087
+ if (trimmed.text) {
2088
+ this.chunks[0] = trimmed.text;
2089
+ this.bytes = this.bytes - firstBytes + trimmed.bytes;
2090
+ } else {
2091
+ this.chunks.shift();
2092
+ this.bytes -= firstBytes;
2093
+ }
2094
+ break;
2095
+ }
2096
+ }
2097
+ toString() {
2098
+ return this.chunks.join("");
2099
+ }
2100
+ clear() {
2101
+ this.chunks.length = 0;
2102
+ this.bytes = 0;
2103
+ }
2104
+ };
2105
+ function trimUtf8Tail(text, maxBytes) {
2106
+ if (!Number.isFinite(maxBytes) || maxBytes <= 0) {
2107
+ return { text: "", bytes: 0 };
2108
+ }
2109
+ const buffer = Buffer.from(text, "utf8");
2110
+ if (buffer.length <= maxBytes) {
2111
+ return { text, bytes: buffer.length };
2112
+ }
2113
+ let start = buffer.length - Math.floor(maxBytes);
2114
+ while (start < buffer.length && ((buffer[start] ?? 0) & 192) === 128) {
2115
+ start += 1;
2116
+ }
2117
+ const tail = buffer.subarray(start);
2118
+ return { text: tail.toString("utf8"), bytes: tail.length };
2119
+ }
2120
+ function sanitizeExecutionEnv(env, options) {
2121
+ if (!env) {
2122
+ if (isDebugMode()) {
2123
+ console.warn("[BaseRunner] executeProviderCommand fallbacked to marker-stripped process.env");
2124
+ }
2125
+ return createCleanChildEnv();
2126
+ }
2127
+ const sanitized = stripClaudeSessionEnv(env);
2128
+ for (const key of Object.keys(sanitized)) {
2129
+ if (isSandboxAuthorityEnvVar(key)) {
2130
+ delete sanitized[key];
2131
+ }
2132
+ }
2133
+ if (options?.preserveClaudeBackendFlags === true) {
2134
+ if (env.CLAUDE_CODE_USE_BEDROCK !== void 0) {
2135
+ sanitized.CLAUDE_CODE_USE_BEDROCK = env.CLAUDE_CODE_USE_BEDROCK;
2136
+ }
2137
+ if (env.CLAUDE_CODE_USE_VERTEX !== void 0) {
2138
+ sanitized.CLAUDE_CODE_USE_VERTEX = env.CLAUDE_CODE_USE_VERTEX;
2139
+ }
2140
+ if (env.CLAUDE_CODE_USE_FOUNDRY !== void 0) {
2141
+ sanitized.CLAUDE_CODE_USE_FOUNDRY = env.CLAUDE_CODE_USE_FOUNDRY;
2142
+ }
2143
+ }
2144
+ return sanitized;
2145
+ }
2146
+ function resolveCommandName(command) {
2147
+ const posix = path2.posix.basename(command);
2148
+ const win32 = path2.win32.basename(command);
2149
+ const basename = posix.length <= win32.length ? posix : win32;
2150
+ return basename.replace(/\.(exe|cmd|bat|ps1)$/i, "").toUpperCase().replace(/[^A-Z0-9]/g, "_");
2151
+ }
2152
+ function redactProviderArgvForRunnerDiagnostics(args) {
2153
+ return redactProviderArgv(args).map((arg) => {
2154
+ if (arg === "[REDACTED]") return arg;
2155
+ if (/[\r\n]/.test(arg)) return PROVIDER_ARGV_PAYLOAD_REDACTION;
2156
+ if (/\s/.test(arg)) return PROVIDER_ARGV_PAYLOAD_REDACTION;
2157
+ if (arg.length > 200) return PROVIDER_ARGV_PAYLOAD_REDACTION;
2158
+ return arg;
2159
+ });
2160
+ }
2161
+ function formatRedactedCommandSignature(command, args) {
2162
+ const [redactedCommand = command] = redactProviderArgv([command]);
2163
+ return [redactedCommand, ...redactProviderArgvForRunnerDiagnostics(args)].join(" ").trim();
2164
+ }
2165
+ function logPlmVerificationFailure(details) {
2166
+ logger2.warn(`[BaseRunner] PLM verification failed for ${details.provider}`, {
2167
+ provider: details.provider,
2168
+ command: details.command,
2169
+ argCount: details.args.length,
2170
+ exitCode: details.code,
2171
+ signal: details.signal,
2172
+ hasExited: details.hasExited,
2173
+ stderr: sanitizeDiagnosticOutput(details.stderr, 2e3)
2174
+ });
2175
+ }
2176
+ function hasPlmExitEvidence(details) {
2177
+ return details.hasExited || details.code !== null || details.signal !== null;
2178
+ }
2179
+ var TERMINATION_PRIORITY = {
2180
+ abort: 100,
2181
+ hard_timeout: 90,
2182
+ timeout: 80,
2183
+ plm_timeout: 70,
2184
+ plm_abort: 60,
2185
+ plm_cancelled: 50,
2186
+ idle_timeout: 40,
2187
+ unknown: 0
2188
+ };
2189
+ function createProviderTerminationController(params) {
2190
+ const { subprocess, startTime, timeout, providerName, command } = params;
2191
+ const processState = {
2192
+ hasExited: false,
2193
+ exitCode: null,
2194
+ exitSignal: null,
2195
+ exitAt: null,
2196
+ sigtermSentAt: null,
2197
+ sigkillSentAt: null
2198
+ };
2199
+ const terminationState = {
2200
+ attempts: [],
2201
+ getPrimaryRecord() {
2202
+ const activeAttempts = this.attempts.filter((attempt) => attempt.requestedAfterExit !== true);
2203
+ if (activeAttempts.length === 0) return null;
2204
+ const priorityFor = (reason) => TERMINATION_PRIORITY[reason] ?? 0;
2205
+ return activeAttempts.reduce((best, current) => {
2206
+ const bestPriority = priorityFor(best.reason);
2207
+ const currentPriority = priorityFor(current.reason);
2208
+ return currentPriority > bestPriority ? current : best;
2209
+ });
2210
+ }
2211
+ };
2212
+ let hardTimeoutTimer;
2213
+ let terminationForceKillTimer;
2214
+ let stdioClosed = false;
2215
+ const exitWaiters = /* @__PURE__ */ new Set();
2216
+ const clearTerminationTimer = () => {
2217
+ if (hardTimeoutTimer) {
2218
+ clearTimeout(hardTimeoutTimer);
2219
+ hardTimeoutTimer = void 0;
2220
+ }
2221
+ if (terminationForceKillTimer) {
2222
+ clearTimeout(terminationForceKillTimer);
2223
+ terminationForceKillTimer = void 0;
2224
+ }
2225
+ };
2226
+ const markExited = (code, signal) => {
2227
+ if (processState.hasExited) return;
2228
+ processState.hasExited = true;
2229
+ processState.exitCode = code;
2230
+ processState.exitSignal = signal;
2231
+ processState.exitAt = Date.now();
2232
+ for (const resolve of exitWaiters) {
2233
+ resolve();
2234
+ }
2235
+ exitWaiters.clear();
2236
+ };
2237
+ const waitForExitOrTimeout = async (timeoutMs) => {
2238
+ if (processState.hasExited || timeoutMs <= 0) return;
2239
+ await new Promise((resolve) => {
2240
+ let timer;
2241
+ const finish = () => {
2242
+ if (timer) {
2243
+ clearTimeout(timer);
2244
+ }
2245
+ exitWaiters.delete(finish);
2246
+ resolve();
2247
+ };
2248
+ exitWaiters.add(finish);
2249
+ timer = setTimeout(finish, timeoutMs);
2250
+ timer.unref?.();
2251
+ });
2252
+ };
2253
+ subprocess.on("exit", (code, signal) => {
2254
+ markExited(code, signal ?? null);
2255
+ });
2256
+ subprocess.on("close", (code, signal) => {
2257
+ markExited(code, signal ?? null);
2258
+ stdioClosed = true;
2259
+ clearTerminationTimer();
2260
+ });
2261
+ const requestTermination = (reason, source, detail, boundaryEvent) => {
2262
+ const record = {
2263
+ reason,
2264
+ source,
2265
+ detail,
2266
+ requestedAt: Date.now(),
2267
+ requestedAfterExit: processState.hasExited
2268
+ };
2269
+ terminationState.attempts.push(record);
2270
+ if (processState.hasExited) {
2271
+ if (!stdioClosed && processState.sigkillSentAt === null) {
2272
+ if (sendSignalToSubprocessTree(subprocess, "SIGKILL")) {
2273
+ processState.sigkillSentAt = Date.now();
2274
+ }
2275
+ }
2276
+ return true;
2277
+ }
2278
+ const isFirstRequest = terminationState.attempts.length === 1;
2279
+ if (!isFirstRequest) {
2280
+ return false;
2281
+ }
2282
+ if (reason === "idle_timeout") {
2283
+ emitBoundaryTriggered({
2284
+ trigger: "idle",
2285
+ workloadClass: "agent-run",
2286
+ effectiveCeilingMs: timeout,
2287
+ elapsedMs: Math.max(0, Date.now() - startTime),
2288
+ source: "base-runner",
2289
+ idleDurationMs: boundaryEvent?.idleDurationMs,
2290
+ metadata: {
2291
+ provider: providerName,
2292
+ command
2293
+ }
2294
+ });
2295
+ } else if (reason === "hard_timeout" || reason === "timeout" || reason === "plm_timeout") {
2296
+ emitBoundaryTriggered({
2297
+ trigger: "ceiling",
2298
+ workloadClass: "agent-run",
2299
+ effectiveCeilingMs: timeout,
2300
+ elapsedMs: Math.max(0, Date.now() - startTime),
2301
+ source: "base-runner",
2302
+ metadata: {
2303
+ provider: providerName,
2304
+ command
2305
+ }
2306
+ });
2307
+ }
2308
+ if (processState.sigtermSentAt === null) {
2309
+ if (sendSignalToSubprocessTree(subprocess, "SIGTERM")) {
2310
+ processState.sigtermSentAt = Date.now();
2311
+ }
2312
+ }
2313
+ terminationForceKillTimer = setTimeout(() => {
2314
+ if (stdioClosed) return;
2315
+ if (processState.sigkillSentAt !== null) return;
2316
+ if (sendSignalToSubprocessTree(subprocess, "SIGKILL")) {
2317
+ processState.sigkillSentAt = Date.now();
2318
+ }
2319
+ }, PROVIDER_TERMINATION_GRACE_MS);
2320
+ terminationForceKillTimer.unref?.();
2321
+ return true;
2322
+ };
2323
+ if (Number.isFinite(timeout) && timeout > 0) {
2324
+ hardTimeoutTimer = setTimeout(() => {
2325
+ requestTermination(
2326
+ "timeout",
2327
+ "base-runner:hard-timeout",
2328
+ `timeout after ${Math.round(timeout / 1e3)}s`
2329
+ );
2330
+ }, timeout);
2331
+ hardTimeoutTimer.unref?.();
2332
+ }
2333
+ return {
2334
+ processState,
2335
+ terminationState,
2336
+ requestTermination,
2337
+ markExited,
2338
+ clearTerminationTimer,
2339
+ waitForExitOrTimeout
2340
+ };
2341
+ }
2342
+ async function drainProviderTerminationGrace(terminationController) {
2343
+ const { processState } = terminationController;
2344
+ if (terminationController.terminationState.getPrimaryRecord() === null) return;
2345
+ if (processState.hasExited) return;
2346
+ if (processState.sigtermSentAt === null) return;
2347
+ if (processState.sigkillSentAt !== null) return;
2348
+ const elapsedMs = Date.now() - processState.sigtermSentAt;
2349
+ const remainingMs = Math.max(0, PROVIDER_TERMINATION_GRACE_MS - elapsedMs);
2350
+ if (remainingMs > 0) {
2351
+ await terminationController.waitForExitOrTimeout(remainingMs);
2352
+ }
2353
+ }
2354
+ function trackProviderSubprocess(subprocess, mode) {
2355
+ return mode === "async" ? trackSubprocessAsync(subprocess) : trackSubprocess(subprocess);
2356
+ }
2357
+ function registerProviderProcessLimiter(params) {
2358
+ const {
2359
+ subprocess,
2360
+ limiterDescription,
2361
+ timeout,
2362
+ reservation,
2363
+ requestTermination,
2364
+ trackedPid,
2365
+ onRegistrationFailure
2366
+ } = params;
2367
+ try {
2368
+ return globalProcessLimiter.track(
2369
+ subprocess,
2370
+ limiterDescription,
2371
+ timeout,
2372
+ (request) => {
2373
+ const detail = `timeout after ${Math.round(request.timeoutMs / 1e3)}s`;
2374
+ requestTermination(request.reason, request.source, detail);
2375
+ },
2376
+ reservation
2377
+ );
2378
+ } catch (err) {
2379
+ sendSignalToSubprocessTree(subprocess, "SIGKILL");
2380
+ untrackSubprocess(trackedPid, subprocess);
2381
+ try {
2382
+ onRegistrationFailure?.();
2383
+ } catch {
2384
+ }
2385
+ throw err;
2386
+ }
2387
+ }
2388
+ async function registerProviderProcessLifecycle(params) {
2389
+ const {
2390
+ subprocess,
2391
+ completionPromise,
2392
+ processState,
2393
+ exitStatus,
2394
+ requestTermination,
2395
+ activityState,
2396
+ stderrChunks,
2397
+ providerName,
2398
+ command,
2399
+ args,
2400
+ workingDir,
2401
+ ownsProcessGroup
2402
+ } = params;
2403
+ try {
2404
+ const plm = getProcessLifecycleManager();
2405
+ if (!plm) {
2406
+ return void 0;
2407
+ }
2408
+ return await plm.registerProcessWithOptions({
2409
+ completionPromise,
2410
+ terminateFn: async (request) => {
2411
+ const mappedReason = request.reason === "timeout" ? "hard_timeout" : `plm_${request.reason}`;
2412
+ const detail = `PLM requested termination: ${request.reason}`;
2413
+ requestTermination(mappedReason, request.source, detail);
2414
+ },
2415
+ verificationFn: async () => {
2416
+ const code = processState.exitCode ?? exitStatus.code ?? subprocess.exitCode ?? null;
2417
+ const signal = processState.exitSignal ?? exitStatus.signal ?? subprocess?.signal ?? null;
2418
+ const verified = hasPlmExitEvidence({
2419
+ code,
2420
+ signal: signal == null ? null : String(signal),
2421
+ hasExited: processState.hasExited
2422
+ });
2423
+ if (!verified) {
2424
+ logPlmVerificationFailure({
2425
+ provider: providerName,
2426
+ command,
2427
+ args,
2428
+ code,
2429
+ signal: signal == null ? null : String(signal),
2430
+ hasExited: processState.hasExited,
2431
+ stderr: stderrChunks.join("").trim().slice(0, 2e3)
2432
+ });
2433
+ }
2434
+ return verified;
2435
+ },
2436
+ processType: "local",
2437
+ timeoutMs: 0,
2438
+ metadata: {
2439
+ provider: providerName,
2440
+ command,
2441
+ args,
2442
+ cwd: workingDir,
2443
+ startTime: Date.now()
2444
+ },
2445
+ progressCallback: async () => ({
2446
+ filesChanged: 0,
2447
+ outputLines: activityState.outputLines,
2448
+ lastActivityTimestamp: activityState.lastActivityAt
2449
+ }),
2450
+ childProcess: subprocess,
2451
+ ownsProcessGroup
2452
+ });
2453
+ } catch (err) {
2454
+ logger2.warn(`[BaseRunner] ProcessLifecycleManager registration failed: ${err}`, {
2455
+ provider: providerName
2456
+ });
2457
+ return void 0;
2458
+ }
2459
+ }
2460
+ function startProviderIdleMonitor(params) {
2461
+ const {
2462
+ subprocess,
2463
+ activityState,
2464
+ terminationState,
2465
+ requestTermination,
2466
+ command,
2467
+ timeout,
2468
+ providerName,
2469
+ variantLabel,
2470
+ commandSignature,
2471
+ stderrChunks,
2472
+ onActivity,
2473
+ onIdleTermination,
2474
+ idleTimeouts
2475
+ } = params;
2476
+ if (!idleTimeouts) {
2477
+ return void 0;
2478
+ }
2479
+ const { warnMs, killMs } = idleTimeouts;
2480
+ const idlePollMs = Math.max(250, Math.min(3e4, Math.floor(warnMs / 2)));
2481
+ if (isDebugMode() || isTimeoutDebug()) {
2482
+ logger2.debug(
2483
+ `[BaseRunner] Idle config (${providerName}) variant=${variantLabel} timeout=${timeout}ms warn=${warnMs}ms kill=${killMs}ms poll=${idlePollMs}ms command=${commandSignature}`,
2484
+ {
2485
+ provider: providerName,
2486
+ variantLabel,
2487
+ timeout,
2488
+ warnMs,
2489
+ killMs,
2490
+ idlePollMs,
2491
+ command: commandSignature
2492
+ }
2493
+ );
2494
+ }
2495
+ let idleWarned = false;
2496
+ let lastCpuTimeSeconds;
2497
+ const idleMonitorInterval = setInterval(() => {
2498
+ if (terminationState.attempts.length > 0) return;
2499
+ const now = Date.now();
2500
+ const pid = subprocess?.pid;
2501
+ const currentCpuSeconds = typeof pid === "number" ? readCpuTimeSeconds(pid) : void 0;
2502
+ const cpuActivity = evaluateCpuTimeProgressStreak({
2503
+ currentCpuSeconds,
2504
+ previousCpuSeconds: lastCpuTimeSeconds,
2505
+ currentBusyPolls: activityState.consecutiveBusyCpuPolls
2506
+ });
2507
+ lastCpuTimeSeconds = currentCpuSeconds;
2508
+ activityState.consecutiveBusyCpuPolls = cpuActivity.nextBusyPolls;
2509
+ if (cpuActivity.shouldCountAsActivity) {
2510
+ activityState.lastActivityAt = now;
2511
+ onActivity?.({ source: "cpu", timestampMs: now });
2512
+ }
2513
+ const idleFor = now - activityState.lastActivityAt;
2514
+ if (!idleWarned && idleFor >= warnMs) {
2515
+ idleWarned = true;
2516
+ logger2.warn(
2517
+ `[BaseRunner] ${providerName} subprocess appears idle for ${Math.round(idleFor / 1e3)}s (warn=${Math.round(warnMs / 1e3)}s kill=${Math.round(killMs / 1e3)}s) - ${command}`,
2518
+ {
2519
+ provider: providerName,
2520
+ command,
2521
+ idleForMs: Math.round(idleFor / 1e3) * 1e3,
2522
+ warnMs,
2523
+ killMs
2524
+ }
2525
+ );
2526
+ }
2527
+ if (idleFor >= killMs) {
2528
+ const detail = `idle timeout after ${Math.round(killMs / 1e3)}s with no stdout/stderr/CPU activity`;
2529
+ const recentStderr = stderrChunks.join("").trim();
2530
+ if (recentStderr) {
2531
+ const sanitizedRecentStderr = sanitizeError(new Error(recentStderr.slice(-500))).message;
2532
+ logger2.warn(`[BaseRunner] Recent stderr before idle kill:
2533
+ ${sanitizedRecentStderr}`, {
2534
+ provider: providerName,
2535
+ command,
2536
+ idleForMs: Math.round(idleFor / 1e3) * 1e3,
2537
+ warnMs,
2538
+ killMs
2539
+ });
2540
+ }
2541
+ onIdleTermination?.();
2542
+ const won = requestTermination("idle_timeout", "base-runner:idle-monitor", detail, {
2543
+ idleDurationMs: Math.round(idleFor / 1e3) * 1e3
2544
+ });
2545
+ if (won) {
2546
+ logger2.warn(`[BaseRunner] Terminating idle subprocess (${providerName}): ${detail}`, {
2547
+ provider: providerName,
2548
+ command,
2549
+ idleForMs: Math.round(idleFor / 1e3) * 1e3,
2550
+ warnMs,
2551
+ killMs
2552
+ });
2553
+ }
2554
+ }
2555
+ }, idlePollMs);
2556
+ idleMonitorInterval.unref?.();
2557
+ return idleMonitorInterval;
2558
+ }
2559
+ function startProviderTimeoutWatchdog(params) {
2560
+ const { processState, startTime, timeout, providerName } = params;
2561
+ return setInterval(() => {
2562
+ const elapsed = Date.now() - startTime;
2563
+ if (elapsed > timeout * 0.75 && !processState.hasExited) {
2564
+ logger2.debug(
2565
+ `[BaseRunner] Subprocess approaching timeout (${Math.round(elapsed / 1e3)}s / ${Math.round(timeout / 1e3)}s) - ${providerName}`,
2566
+ {
2567
+ provider: providerName,
2568
+ elapsedMs: Math.round(elapsed),
2569
+ timeoutMs: timeout
2570
+ }
2571
+ );
2572
+ }
2573
+ }, 3e4);
2574
+ }
2575
+ function removeStreamDataListener(subprocess, streamName, listener) {
2576
+ try {
2577
+ const stream = subprocess?.[streamName];
2578
+ if (typeof stream?.removeListener === "function") {
2579
+ stream.removeListener("data", listener);
2580
+ } else if (typeof stream?.off === "function") {
2581
+ stream.off("data", listener);
2582
+ }
2583
+ } catch {
2584
+ }
2585
+ }
2586
+ function cleanupProviderExecutionResources(params) {
2587
+ const {
2588
+ watchdogInterval,
2589
+ idleMonitorInterval,
2590
+ terminationController,
2591
+ abortSignal,
2592
+ abortListener,
2593
+ subprocess,
2594
+ stdoutDataListener,
2595
+ stderrListener,
2596
+ plmProcessId,
2597
+ limiterId,
2598
+ trackedPid,
2599
+ workingDir,
2600
+ providerName
2601
+ } = params;
2602
+ if (watchdogInterval) {
2603
+ clearInterval(watchdogInterval);
2604
+ }
2605
+ if (idleMonitorInterval) {
2606
+ clearInterval(idleMonitorInterval);
2607
+ }
2608
+ terminationController.clearTerminationTimer();
2609
+ if (abortSignal && abortListener) {
2610
+ abortSignal.removeEventListener("abort", abortListener);
2611
+ }
2612
+ removeStreamDataListener(subprocess, "stdout", stdoutDataListener);
2613
+ removeStreamDataListener(subprocess, "stderr", stderrListener);
2614
+ const cleanupErrors = [];
2615
+ const { processState } = terminationController;
2616
+ if (!processState.hasExited) {
2617
+ if (processState.sigtermSentAt === null) {
2618
+ if (sendSignalToSubprocessTree(subprocess, "SIGTERM")) {
2619
+ processState.sigtermSentAt = Date.now();
2620
+ }
2621
+ }
2622
+ if (processState.sigkillSentAt === null) {
2623
+ if (sendSignalToSubprocessTree(subprocess, "SIGKILL")) {
2624
+ processState.sigkillSentAt = Date.now();
2625
+ }
2626
+ }
2627
+ }
2628
+ if (plmProcessId) {
2629
+ try {
2630
+ const plm = getProcessLifecycleManager();
2631
+ plm?.unregisterProcess(plmProcessId);
2632
+ } catch (error) {
2633
+ cleanupErrors.push(error instanceof Error ? error : new Error(String(error)));
2634
+ }
2635
+ }
2636
+ if (limiterId !== void 0) {
2637
+ try {
2638
+ globalProcessLimiter.untrack(limiterId);
2639
+ } catch (error) {
2640
+ cleanupErrors.push(error instanceof Error ? error : new Error(String(error)));
2641
+ }
2642
+ }
2643
+ try {
2644
+ untrackSubprocess(trackedPid, subprocess);
2645
+ } catch (error) {
2646
+ cleanupErrors.push(error instanceof Error ? error : new Error(String(error)));
2647
+ }
2648
+ if (cleanupErrors.length > 0) {
2649
+ try {
2650
+ const telemetryLogger = TelemetryLogger.getInstance({
2651
+ buildDir: resolveTelemetryBuildDir(workingDir)
2652
+ });
2653
+ telemetryLogger.logCostEvent("resource_cleanup_failed", {
2654
+ errors: cleanupErrors.map((e) => e.message),
2655
+ errorCount: cleanupErrors.length,
2656
+ limiterId: limiterId ?? null,
2657
+ pid: trackedPid ?? null,
2658
+ provider: providerName,
2659
+ timestamp: Date.now()
2660
+ });
2661
+ } catch (telemetryError) {
2662
+ logger2.warn(`Failed to log cleanup error to telemetry: ${telemetryError}`);
2663
+ }
2664
+ logger2.warn("Resource cleanup errors occurred:", {
2665
+ provider: providerName,
2666
+ errorCount: cleanupErrors.length,
2667
+ limiterId: limiterId ?? null,
2668
+ pid: trackedPid ?? null
2669
+ });
2670
+ if (process.env.NODE_ENV === "test") {
2671
+ logger2.error(
2672
+ `[BaseRunner] Resource cleanup failed: ${cleanupErrors.length} error(s) - ${cleanupErrors.map((e) => e.message).join("; ")}`,
2673
+ void 0,
2674
+ {
2675
+ provider: providerName,
2676
+ errorCount: cleanupErrors.length,
2677
+ limiterId: limiterId ?? null,
2678
+ pid: trackedPid ?? null
2679
+ }
2680
+ );
2681
+ }
2682
+ }
2683
+ }
2684
+ function prepareCommand(command, args, workingDir, metadata, sandboxOptions) {
2685
+ if (sandboxOptions?.disableBuildSandbox === true) {
2686
+ return { command, args, sandboxed: false };
2687
+ }
2688
+ const result = wrapWithSandbox({
2689
+ workingDir,
2690
+ command,
2691
+ args,
2692
+ providerName: metadata.name,
2693
+ extraWritePaths: sandboxOptions?.extraWritePaths,
2694
+ readOnlyWorkingDir: sandboxOptions?.readOnlyWorkingDir,
2695
+ // This is the provider execution path, so it must not run write-capable
2696
+ // automation without an accepted boundary. Read-only runs still pass
2697
+ // readOnlyWorkingDir and stay exempt.
2698
+ requiresBoundaryForWrites: true,
2699
+ env: sandboxOptions?.env,
2700
+ // Prefer stable provider ids when available, otherwise derive a stable-ish id
2701
+ // from the command basename (e.g. "copilot", "cursor-agent").
2702
+ providerId: metadata.id ?? resolveCommandName(command)
2703
+ });
2704
+ if (result.sandboxed && isDebugMode()) {
2705
+ logger2.debug(`[BaseRunner] Sandboxed ${metadata.name} execution in ${workingDir}`, {
2706
+ provider: metadata.name,
2707
+ workingDir
2708
+ });
2709
+ }
2710
+ return result;
2711
+ }
2712
+ function computeArgvBytes(command, args, env) {
2713
+ let argBytes = Buffer.byteLength(command, "utf8") + 1;
2714
+ let maxArgBytes = Buffer.byteLength(command, "utf8");
2715
+ for (const arg of args) {
2716
+ const bytes = Buffer.byteLength(arg, "utf8");
2717
+ argBytes += bytes + 1;
2718
+ maxArgBytes = Math.max(maxArgBytes, bytes);
2719
+ }
2720
+ let envBytes = 0;
2721
+ for (const [key, value] of Object.entries(env)) {
2722
+ if (value === void 0) continue;
2723
+ envBytes += Buffer.byteLength(key, "utf8") + 1 + Buffer.byteLength(value, "utf8") + 1;
2724
+ }
2725
+ return { argBytes, envBytes, totalBytes: argBytes + envBytes, maxArgBytes };
2726
+ }
2727
+ function throwIfProviderArgvTooLarge(command, args, env, metadata) {
2728
+ const { argBytes, envBytes, totalBytes, maxArgBytes } = computeArgvBytes(command, args, env);
2729
+ if (totalBytes <= PROVIDER_PROCESS_ARG_ENV_MAX_SAFE_BYTES && maxArgBytes <= PROVIDER_SINGLE_ARG_MAX_SAFE_BYTES) {
2730
+ return;
2731
+ }
2732
+ throw new ProviderExecutionError(
2733
+ `[${metadata.name}] Provider command argv/env is too large before spawn (argvBytes=${argBytes}, envBytes=${envBytes}, totalBytes=${totalBytes}, maxArgBytes=${maxArgBytes}). Use stdin or a prompt-file/config-file transport for large provider prompts or config payloads. [reason=argument_list_too_long]`,
2734
+ {
2735
+ retryable: false,
2736
+ reason: "argument_list_too_long",
2737
+ providerName: metadata.name
2738
+ }
2739
+ );
2740
+ }
2741
+ function resolveTelemetryBuildDir(workingDir) {
2742
+ return path2.join(path2.resolve(workingDir), ".build-project");
2743
+ }
2744
+ function resultIsOurCancellation(result) {
2745
+ if (result == null || typeof result !== "object") {
2746
+ return false;
2747
+ }
2748
+ const r = result;
2749
+ if (r.isCanceled === true || r.canceled === true) return true;
2750
+ if (r.isTerminated === true && (r.signal === "SIGTERM" || r.signal === "SIGKILL")) {
2751
+ return true;
2752
+ }
2753
+ if (r.signal === "SIGTERM" || r.signal === "SIGKILL") return true;
2754
+ return false;
2755
+ }
2756
+ function shouldPreserveTerminationPartialOutput(record) {
2757
+ return record.reason === "timeout" || record.reason === "hard_timeout" || record.reason === "plm_timeout" || record.reason === "idle_timeout" || record.reason === "abort" || // Spool failures kill the child, and what was captured before the failure is
2758
+ // the evidence for diagnosing it.
2759
+ record.reason === "output_ceiling_exceeded" || record.reason === "stdout_spool_read_failed" || record.reason === "stdout_spool_consume_failed";
2760
+ }
2761
+ async function executeProviderCommand(options) {
2762
+ return executeProviderCommandImpl(options, "immediate");
2763
+ }
2764
+ async function executeProviderCommandAsync(options) {
2765
+ return executeProviderCommandImpl(options, "async");
2766
+ }
2767
+ async function executeProviderCommandImpl(options, trackMode) {
2768
+ const {
2769
+ command,
2770
+ args,
2771
+ workingDir,
2772
+ env,
2773
+ preserveClaudeBackendFlags = false,
2774
+ input,
2775
+ stdinMode = "pipe",
2776
+ timeout = DEFAULT_TIMEOUT,
2777
+ maxBufferBytes,
2778
+ extraWritePaths,
2779
+ readOnlyWorkingDir,
2780
+ disableBuildSandbox,
2781
+ providerInternalSandboxBypass,
2782
+ abortSignal,
2783
+ beforeSpawn,
2784
+ metadata,
2785
+ onData,
2786
+ onErrorData,
2787
+ onStderrChunk,
2788
+ onStdoutChunk,
2789
+ onActivity,
2790
+ onIdleTermination,
2791
+ formatLine,
2792
+ passThroughUnformatted = false,
2793
+ streamOutput = false,
2794
+ variantLabel,
2795
+ idleWarnMs: optIdleWarnMs,
2796
+ idleKillMs: optIdleKillMs,
2797
+ fileBackedStdout = false,
2798
+ fileBackedStdoutMaxBytes
2799
+ } = options;
2800
+ const useStreamingOutput = streamOutput === true;
2801
+ const useFileBackedStdout = fileBackedStdout === true;
2802
+ const fileBackedMaxBytes = typeof fileBackedStdoutMaxBytes === "number" && Number.isFinite(fileBackedStdoutMaxBytes) && fileBackedStdoutMaxBytes > 0 ? Math.floor(fileBackedStdoutMaxBytes) : FILE_BACKED_STDOUT_DEFAULT_MAX_BYTES;
2803
+ throwIfAbortAlreadyRequested(abortSignal, metadata.name);
2804
+ const idleTimeouts = resolveIdleTimeoutsMs(command, args, timeout, {
2805
+ idleWarnMs: optIdleWarnMs,
2806
+ idleKillMs: optIdleKillMs
2807
+ });
2808
+ const startTime = Date.now();
2809
+ if (isTimeoutDebug()) {
2810
+ logger2.debug(
2811
+ `[BaseRunner] Starting ${metadata.name} with timeout ${timeout}ms (${Math.round(timeout / 6e4)}m)`,
2812
+ {
2813
+ provider: metadata.name,
2814
+ command,
2815
+ workingDir,
2816
+ timeout,
2817
+ variantLabel
2818
+ }
2819
+ );
2820
+ }
2821
+ if (isPathDebug()) {
2822
+ logger2.debug(`[base-runner] Executing ${metadata.name} in cwd: ${workingDir}`, {
2823
+ provider: metadata.name,
2824
+ command,
2825
+ workingDir,
2826
+ timeout,
2827
+ variantLabel
2828
+ });
2829
+ if (workingDir.includes("build-worktrees-")) {
2830
+ const expectedUid = os3.userInfo().uid.toString();
2831
+ if (!workingDir.includes(`build-worktrees-${expectedUid}`)) {
2832
+ logger2.warn(`[base-runner] cwd UID mismatch - expected ${expectedUid} in: ${workingDir}`, {
2833
+ provider: metadata.name,
2834
+ command,
2835
+ workingDir,
2836
+ timeout,
2837
+ variantLabel
2838
+ });
2839
+ }
2840
+ }
2841
+ }
2842
+ const internalController = new AbortController();
2843
+ const sandboxed = prepareCommand(command, args, workingDir, metadata, {
2844
+ extraWritePaths,
2845
+ readOnlyWorkingDir,
2846
+ disableBuildSandbox,
2847
+ env
2848
+ });
2849
+ assertProviderBypassHasBoundaryProof(metadata, args, sandboxed, providerInternalSandboxBypass);
2850
+ const { command: sandboxedCommand, args: sandboxedArgs } = sandboxed;
2851
+ const childEnv = sanitizeExecutionEnv(env, { preserveClaudeBackendFlags });
2852
+ const processGroupOwnership = resolveProviderProcessGroupOwnership();
2853
+ childEnv[BUILD_PROCESS_GROUP_OWNER_ENV] = processGroupOwnership.owner;
2854
+ childEnv.PWD = path2.resolve(workingDir);
2855
+ throwIfProviderArgvTooLarge(sandboxedCommand, sandboxedArgs, childEnv, metadata);
2856
+ const commandSignature = formatRedactedCommandSignature(sandboxedCommand, sandboxedArgs);
2857
+ const resolvedVariantLabel = variantLabel ?? "unknown";
2858
+ const limiterDescription = `${metadata.name} provider command: ${formatRedactedCommandSignature(command, args)}`.trim();
2859
+ const reservationOrWait = acquireProcessSlot(limiterDescription, abortSignal);
2860
+ const reservation = reservationOrWait instanceof Promise ? await reservationOrWait : reservationOrWait;
2861
+ let stdoutSpool;
2862
+ let stdoutSpoolFd;
2863
+ try {
2864
+ throwIfAbortAlreadyRequested(abortSignal, metadata.name);
2865
+ if (useFileBackedStdout) {
2866
+ stdoutSpool = createPrivateSpool({
2867
+ label: `stdout-${metadata.name}`,
2868
+ streams: ["stdout"],
2869
+ errorLabel: "stdout spool"
2870
+ });
2871
+ const freeBytes = spoolFilesystemFreeBytes(stdoutSpool.dir);
2872
+ if (freeBytes !== void 0 && freeBytes < FILE_BACKED_STDOUT_MIN_FREE_BYTES) {
2873
+ throw new ProviderExecutionError(
2874
+ `${metadata.name} CLI not started: stdout spool filesystem has ${freeBytes} bytes free, below the ${FILE_BACKED_STDOUT_MIN_FREE_BYTES} byte floor.`,
2875
+ {
2876
+ retryable: false,
2877
+ reason: "stdout_spool_insufficient_space",
2878
+ providerName: metadata.name
2879
+ }
2880
+ );
2881
+ }
2882
+ stdoutSpoolFd = stdoutSpool.stream("stdout").requireOpenFd();
2883
+ }
2884
+ beforeSpawn?.();
2885
+ } catch (error) {
2886
+ if (stdoutSpool) {
2887
+ await stdoutSpool.dispose().catch(() => {
2888
+ });
2889
+ }
2890
+ releaseProcessSlotReservation(reservation);
2891
+ throw error;
2892
+ }
2893
+ const spawnOptions = {
2894
+ cwd: workingDir,
2895
+ env: childEnv,
2896
+ extendEnv: false,
2897
+ input,
2898
+ ...stdinMode === "ignore" && input === void 0 ? { stdin: "ignore" } : {},
2899
+ // The child writes stdout straight to the spool inode. execa then reports
2900
+ // `subprocess.stdout` as null and `result.stdout` as undefined, so the
2901
+ // captured spool contents become the authoritative stdout below.
2902
+ //
2903
+ // The cast is deliberate: execa's types admit only the literals 3-9 for a
2904
+ // descriptor here, while the runtime passes any integer through to Node's
2905
+ // stdio, which shares that descriptor with the child. Verified on execa
2906
+ // 9.6.1 / Node 24 with descriptor 42: exit 0 and all 500,000 bytes landed on
2907
+ // the spool inode.
2908
+ ...stdoutSpoolFd !== void 0 ? { stdout: stdoutSpoolFd } : {},
2909
+ cancelSignal: internalController.signal,
2910
+ all: false,
2911
+ reject: false,
2912
+ detached: processGroupOwnership.detach,
2913
+ timeout: 0,
2914
+ buffer: !useStreamingOutput,
2915
+ ...!useStreamingOutput && typeof maxBufferBytes === "number" && Number.isFinite(maxBufferBytes) && maxBufferBytes > 0 ? { maxBuffer: Math.floor(maxBufferBytes) } : {}
2916
+ };
2917
+ const subprocess = spawnProviderSubprocess(
2918
+ sandboxedCommand,
2919
+ sandboxedArgs,
2920
+ spawnOptions,
2921
+ reservation
2922
+ );
2923
+ observeVariantProcessSpawn(subprocess);
2924
+ const providerProcessGroupPid = subprocess.pid;
2925
+ emitProviderProcessGroupMarker(providerProcessGroupPid);
2926
+ const terminationController = createProviderTerminationController({
2927
+ subprocess,
2928
+ startTime,
2929
+ timeout,
2930
+ providerName: metadata.name,
2931
+ command
2932
+ });
2933
+ const { processState, terminationState, requestTermination, markExited } = terminationController;
2934
+ const requestTerminationFromAbortSignal = (signal) => {
2935
+ if (isHostTimeoutAbortReason(signal.reason)) {
2936
+ requestTermination(
2937
+ "timeout",
2938
+ "abortSignal",
2939
+ formatHostTimeoutTerminationDetail(signal.reason)
2940
+ );
2941
+ return;
2942
+ }
2943
+ requestTermination("abort", "abortSignal");
2944
+ };
2945
+ let abortListener;
2946
+ if (abortSignal) {
2947
+ if (abortSignal.aborted) {
2948
+ internalController.abort();
2949
+ requestTerminationFromAbortSignal(abortSignal);
2950
+ } else {
2951
+ abortListener = () => {
2952
+ internalController.abort();
2953
+ requestTerminationFromAbortSignal(abortSignal);
2954
+ };
2955
+ abortSignal.addEventListener("abort", abortListener, { once: true });
2956
+ }
2957
+ }
2958
+ const activityState = {
2959
+ outputLines: 0,
2960
+ lastActivityAt: Date.now(),
2961
+ consecutiveBusyCpuPolls: 0
2962
+ };
2963
+ const stderrChunks = [];
2964
+ const stdoutChunks = [];
2965
+ const streamCaptureLimit = typeof maxBufferBytes === "number" && Number.isFinite(maxBufferBytes) && maxBufferBytes > 0 ? Math.floor(maxBufferBytes) : DEFAULT_STREAM_CAPTURE_BYTES;
2966
+ const capturedStdout = new BoundedOutputBuffer();
2967
+ const capturedStderr = new BoundedOutputBuffer();
2968
+ const resolveResultStdout = (result) => useFileBackedStdout ? capturedStdout.toString() || result.stdout : result.stdout;
2969
+ let streamingStdoutProcessor;
2970
+ let streamingStderrProcessor;
2971
+ let streamCallbackError;
2972
+ const captureStreamCallbackError = (error, streamName) => {
2973
+ if (streamCallbackError) {
2974
+ return;
2975
+ }
2976
+ streamCallbackError = error;
2977
+ logger2.error(
2978
+ `[BaseRunner] Streaming ${streamName} callback failed: ${String(error)}`,
2979
+ void 0,
2980
+ {
2981
+ provider: metadata.name,
2982
+ stream: streamName
2983
+ }
2984
+ );
2985
+ };
2986
+ if (useStreamingOutput) {
2987
+ streamingStdoutProcessor = createLineBufferedStreamProcessor((line) => {
2988
+ if (!onData || streamCallbackError) {
2989
+ return;
2990
+ }
2991
+ try {
2992
+ if (formatLine) {
2993
+ const formatted = formatLine(line);
2994
+ if (formatted) {
2995
+ onData(`${formatted}
2996
+ `);
2997
+ } else if (passThroughUnformatted) {
2998
+ onData(`${line}
2999
+ `);
3000
+ }
3001
+ } else {
3002
+ onData(`${line}
3003
+ `);
3004
+ }
3005
+ } catch (error) {
3006
+ captureStreamCallbackError(error, "stdout");
3007
+ }
3008
+ });
3009
+ streamingStderrProcessor = createLineBufferedStreamProcessor((line) => {
3010
+ if (!onErrorData || streamCallbackError) {
3011
+ return;
3012
+ }
3013
+ try {
3014
+ onErrorData(line);
3015
+ } catch (error) {
3016
+ captureStreamCallbackError(error, "stderr");
3017
+ }
3018
+ });
3019
+ }
3020
+ const bumpActivity = (chunk, source = "stdout") => {
3021
+ if (chunk == null) return;
3022
+ const now = Date.now();
3023
+ activityState.lastActivityAt = now;
3024
+ const text = chunkToText(chunk);
3025
+ if (text) {
3026
+ activityState.outputLines += text.split(/\r?\n/).filter(Boolean).length;
3027
+ onActivity?.({ source, timestampMs: now });
3028
+ }
3029
+ };
3030
+ const completionSignal = options.completionSignal;
3031
+ const completionSignalGraceMs = Math.max(
3032
+ 0,
3033
+ options.completionSignalGraceMs ?? TMUX_COMPLETION_SIGNAL_GRACE_MS
3034
+ );
3035
+ let completionSignalGraceTimer;
3036
+ let completionSignalEarlyExit = false;
3037
+ const observeCompletionSignal = (text, stream) => {
3038
+ if (!completionSignal || completionSignalGraceTimer || processState.hasExited) return;
3039
+ let signalled = false;
3040
+ try {
3041
+ signalled = completionSignal(text, stream) === true;
3042
+ } catch {
3043
+ return;
3044
+ }
3045
+ if (!signalled) return;
3046
+ completionSignalGraceTimer = setTimeout(() => {
3047
+ if (processState.hasExited) return;
3048
+ if (terminationState.getPrimaryRecord() !== null) return;
3049
+ completionSignalEarlyExit = true;
3050
+ if (processState.sigtermSentAt === null) {
3051
+ if (sendSignalToSubprocessTree(subprocess, "SIGTERM")) {
3052
+ processState.sigtermSentAt = Date.now();
3053
+ }
3054
+ }
3055
+ internalController.abort();
3056
+ }, completionSignalGraceMs);
3057
+ completionSignalGraceTimer.unref?.();
3058
+ };
3059
+ const deliverRawChunk = (observer, chunk) => {
3060
+ if (!observer) {
3061
+ return;
3062
+ }
3063
+ let raw;
3064
+ if (Buffer.isBuffer(chunk)) {
3065
+ if (chunk.length === 0) return;
3066
+ raw = Buffer.from(chunk);
3067
+ } else if (chunk instanceof Uint8Array) {
3068
+ if (chunk.byteLength === 0) return;
3069
+ raw = Buffer.from(chunk);
3070
+ } else if (typeof chunk === "string") {
3071
+ if (chunk.length === 0) return;
3072
+ raw = chunk;
3073
+ } else {
3074
+ return;
3075
+ }
3076
+ try {
3077
+ observer(raw);
3078
+ } catch {
3079
+ }
3080
+ };
3081
+ let firstOutputFiredInExec = false;
3082
+ const ingestStdout = (raw, text) => {
3083
+ bumpActivity(text);
3084
+ if (!firstOutputFiredInExec && text) {
3085
+ firstOutputFiredInExec = true;
3086
+ options.onFirstOutput?.(Date.now());
3087
+ }
3088
+ if (raw !== void 0) {
3089
+ deliverRawChunk(onStdoutChunk, raw);
3090
+ }
3091
+ if (text) {
3092
+ observeCompletionSignal(text, "stdout");
3093
+ }
3094
+ if ((useStreamingOutput || completionSignal || useFileBackedStdout) && text) {
3095
+ capturedStdout.append(text, streamCaptureLimit);
3096
+ stdoutChunks.push(text);
3097
+ if (stdoutChunks.length > 5) {
3098
+ stdoutChunks.shift();
3099
+ }
3100
+ }
3101
+ if (useStreamingOutput) {
3102
+ streamingStdoutProcessor?.push(text);
3103
+ }
3104
+ };
3105
+ const stdoutDecoder = new StringDecoder2("utf8");
3106
+ const stderrDecoder = new StringDecoder2("utf8");
3107
+ let pipeDecodersFlushed = false;
3108
+ const decodePipeChunk = (decoder, chunk) => {
3109
+ if (Buffer.isBuffer(chunk)) return decoder.write(chunk);
3110
+ if (chunk instanceof Uint8Array) return decoder.write(Buffer.from(chunk));
3111
+ return chunkToText(chunk);
3112
+ };
3113
+ const stdoutDataListener = (chunk) => {
3114
+ ingestStdout(chunk, decodePipeChunk(stdoutDecoder, chunk));
3115
+ };
3116
+ let stdoutSpoolFailure;
3117
+ let stdoutSpoolTailer;
3118
+ if (stdoutSpool !== void 0) {
3119
+ stdoutSpoolTailer = createStdoutSpoolTailer({
3120
+ stream: stdoutSpool.stream("stdout"),
3121
+ maxBytes: fileBackedMaxBytes,
3122
+ onBytes: (bytes, text) => {
3123
+ ingestStdout(bytes, text);
3124
+ },
3125
+ onFailure: (failure) => {
3126
+ if (stdoutSpoolFailure) return;
3127
+ stdoutSpoolFailure = failure;
3128
+ requestTermination(failure.reason, "base-runner:stdout-spool", failure.message);
3129
+ }
3130
+ });
3131
+ stdoutSpoolTailer.start();
3132
+ }
3133
+ if (typeof subprocess?.stdout?.on === "function") {
3134
+ subprocess.stdout.on("data", stdoutDataListener);
3135
+ } else if (stdoutSpool === void 0 && isDebugMode()) {
3136
+ console.warn("[base-runner] subprocess.stdout not available \u2014 diagnostics may be incomplete");
3137
+ }
3138
+ const ingestStderr = (raw, text) => {
3139
+ if (raw !== void 0) {
3140
+ deliverRawChunk(onStderrChunk, raw);
3141
+ }
3142
+ if (text) {
3143
+ bumpActivity(text, "stderr");
3144
+ if (useStreamingOutput || completionSignal) {
3145
+ capturedStderr.append(text, streamCaptureLimit);
3146
+ }
3147
+ stderrChunks.push(text);
3148
+ if (stderrChunks.length > 5) {
3149
+ stderrChunks.shift();
3150
+ }
3151
+ observeCompletionSignal(text, "stderr");
3152
+ }
3153
+ if (useStreamingOutput) {
3154
+ streamingStderrProcessor?.push(text);
3155
+ }
3156
+ };
3157
+ const stderrListener = (chunk) => {
3158
+ ingestStderr(chunk, decodePipeChunk(stderrDecoder, chunk));
3159
+ };
3160
+ const flushPipeDecoders = () => {
3161
+ if (pipeDecodersFlushed) return;
3162
+ pipeDecodersFlushed = true;
3163
+ const stdoutRemainder = stdoutDecoder.end();
3164
+ if (stdoutRemainder) ingestStdout(void 0, stdoutRemainder);
3165
+ const stderrRemainder = stderrDecoder.end();
3166
+ if (stderrRemainder) ingestStderr(void 0, stderrRemainder);
3167
+ };
3168
+ if (typeof subprocess?.stderr?.on === "function") {
3169
+ subprocess.stderr.on("data", stderrListener);
3170
+ }
3171
+ const exitStatus = {
3172
+ code: null,
3173
+ signal: null
3174
+ };
3175
+ const completionPromise = (async () => {
3176
+ const result = await subprocess;
3177
+ exitStatus.code = result.exitCode ?? null;
3178
+ exitStatus.signal = result?.signal ?? null;
3179
+ if (!processState.hasExited) {
3180
+ markExited(exitStatus.code, exitStatus.signal);
3181
+ }
3182
+ return result;
3183
+ })();
3184
+ let enteredTry = false;
3185
+ completionPromise.catch((err) => {
3186
+ if (!enteredTry) {
3187
+ const message = err instanceof Error ? err.message : String(err);
3188
+ logger2.error(`[BaseRunner] Subprocess rejected before await: ${message}`, void 0, {
3189
+ provider: metadata.name
3190
+ });
3191
+ }
3192
+ });
3193
+ let trackedPid = null;
3194
+ let limiterId;
3195
+ const registerLimiter = () => registerProviderProcessLimiter({
3196
+ subprocess,
3197
+ limiterDescription,
3198
+ timeout,
3199
+ reservation,
3200
+ requestTermination,
3201
+ trackedPid,
3202
+ onRegistrationFailure: () => {
3203
+ terminationController.clearTerminationTimer();
3204
+ if (abortSignal && abortListener) {
3205
+ abortSignal.removeEventListener("abort", abortListener);
3206
+ }
3207
+ removeStreamDataListener(subprocess, "stdout", stdoutDataListener);
3208
+ removeStreamDataListener(subprocess, "stderr", stderrListener);
3209
+ }
3210
+ });
3211
+ try {
3212
+ if (trackMode === "async") {
3213
+ limiterId = registerLimiter();
3214
+ trackedPid = await trackProviderSubprocess(subprocess, "async");
3215
+ } else {
3216
+ trackedPid = trackProviderSubprocess(subprocess, "immediate");
3217
+ limiterId = registerLimiter();
3218
+ }
3219
+ } catch (error) {
3220
+ try {
3221
+ if (limiterId !== void 0) {
3222
+ globalProcessLimiter.untrack(limiterId);
3223
+ limiterId = void 0;
3224
+ } else if (reservation !== void 0) {
3225
+ globalProcessLimiter.cancelReservation(reservation);
3226
+ }
3227
+ } catch (cleanupError) {
3228
+ logger2.warn("[BaseRunner] Failed to release process limiter after tracking setup failure", {
3229
+ cleanupError: sanitizeError(
3230
+ cleanupError instanceof Error ? cleanupError : new Error(String(cleanupError))
3231
+ ).message
3232
+ });
3233
+ }
3234
+ sendSignalToSubprocessTree(subprocess, "SIGKILL");
3235
+ terminationController.clearTerminationTimer();
3236
+ if (abortSignal && abortListener) {
3237
+ abortSignal.removeEventListener("abort", abortListener);
3238
+ }
3239
+ removeStreamDataListener(subprocess, "stdout", stdoutDataListener);
3240
+ removeStreamDataListener(subprocess, "stderr", stderrListener);
3241
+ if (stdoutSpool) {
3242
+ await stdoutSpool.dispose().catch(() => {
3243
+ });
3244
+ }
3245
+ untrackSubprocess(trackedPid, subprocess);
3246
+ throw error;
3247
+ }
3248
+ const plmProcessId = await registerProviderProcessLifecycle({
3249
+ subprocess,
3250
+ completionPromise,
3251
+ processState,
3252
+ exitStatus,
3253
+ requestTermination,
3254
+ activityState,
3255
+ stderrChunks,
3256
+ providerName: metadata.name,
3257
+ command,
3258
+ args,
3259
+ workingDir,
3260
+ ownsProcessGroup: processGroupOwnership.detach
3261
+ });
3262
+ let idleMonitorInterval;
3263
+ let watchdogInterval;
3264
+ enteredTry = true;
3265
+ try {
3266
+ idleMonitorInterval = startProviderIdleMonitor({
3267
+ subprocess,
3268
+ activityState,
3269
+ terminationState,
3270
+ requestTermination,
3271
+ command,
3272
+ timeout,
3273
+ providerName: metadata.name,
3274
+ variantLabel: resolvedVariantLabel,
3275
+ commandSignature,
3276
+ stderrChunks,
3277
+ onActivity,
3278
+ onIdleTermination,
3279
+ idleTimeouts
3280
+ });
3281
+ watchdogInterval = startProviderTimeoutWatchdog({
3282
+ processState,
3283
+ startTime,
3284
+ timeout,
3285
+ providerName: metadata.name
3286
+ });
3287
+ const result = await completionPromise;
3288
+ const failure = result;
3289
+ if (failure.failed && (failure.isMaxBuffer || failure.code === "ENOENT")) throw result;
3290
+ flushPipeDecoders();
3291
+ let stdoutSpoolBytes;
3292
+ let stdoutSpoolDiskExhausted;
3293
+ if (stdoutSpoolTailer && stdoutSpool) {
3294
+ await stdoutSpoolTailer.drain();
3295
+ stdoutSpoolFailure ??= stdoutSpoolTailer.failure();
3296
+ try {
3297
+ await stdoutSpool.finalize();
3298
+ stdoutSpoolBytes = await stdoutSpoolTailer.finish();
3299
+ stdoutSpoolFailure ??= stdoutSpoolTailer.failure();
3300
+ } catch (error) {
3301
+ stdoutSpoolFailure ??= {
3302
+ reason: "stdout_spool_read_failed",
3303
+ message: `finalizing the provider stdout spool failed: ${error instanceof Error ? error.message : String(error)}`
3304
+ };
3305
+ }
3306
+ const freeBytes = spoolFilesystemFreeBytes(stdoutSpool.dir);
3307
+ if (freeBytes !== void 0 && freeBytes < FILE_BACKED_STDOUT_MIN_FREE_BYTES) {
3308
+ stdoutSpoolDiskExhausted = true;
3309
+ }
3310
+ }
3311
+ const spoolMeasuredBytes = stdoutSpoolBytes !== void 0 && stdoutSpoolBytes > 0 ? stdoutSpoolBytes : void 0;
3312
+ if (useStreamingOutput) {
3313
+ streamingStdoutProcessor?.flush();
3314
+ streamingStderrProcessor?.flush();
3315
+ if (streamCallbackError) {
3316
+ throw streamCallbackError;
3317
+ }
3318
+ } else {
3319
+ processOutput(
3320
+ resolveResultStdout(result),
3321
+ result.stderr,
3322
+ onData,
3323
+ onErrorData,
3324
+ formatLine,
3325
+ passThroughUnformatted
3326
+ );
3327
+ }
3328
+ if (stdoutSpoolFailure !== void 0) {
3329
+ throw new ProviderExecutionError(
3330
+ `${metadata.name} CLI stdout capture failed: ${stdoutSpoolFailure.message}`,
3331
+ {
3332
+ retryable: false,
3333
+ exitCode: result.exitCode ?? void 0,
3334
+ reason: stdoutSpoolFailure.reason,
3335
+ providerName: metadata.name,
3336
+ includeStdoutTail: true,
3337
+ ...providerExecutionTransportStreamOptions(
3338
+ capturedStdout.toString(),
3339
+ result.stderr || capturedStderr.toString(),
3340
+ { streamBytes: { stdout: spoolMeasuredBytes } }
3341
+ )
3342
+ }
3343
+ );
3344
+ }
3345
+ if (completionSignalEarlyExit && terminationState.getPrimaryRecord() === null && resultIsOurCancellation(result)) {
3346
+ return {
3347
+ stdout: capturedStdout.toString() || stdoutChunks.join("") || resolveResultStdout(result) || "",
3348
+ stderr: capturedStderr.toString() || stderrChunks.join("") || result.stderr || "",
3349
+ exitCode: 0,
3350
+ ...stdoutSpoolBytes !== void 0 ? { stdoutBytes: stdoutSpoolBytes } : {},
3351
+ ...stdoutSpoolDiskExhausted ? { stdoutSpoolDiskExhausted: true } : {}
3352
+ };
3353
+ }
3354
+ const successfulTermination = terminationState.getPrimaryRecord();
3355
+ if (result.exitCode === 0 && successfulTermination !== null) {
3356
+ const detailSuffix = successfulTermination.detail ? ` (${successfulTermination.detail})` : "";
3357
+ const preservePartialOutput = shouldPreserveTerminationPartialOutput(successfulTermination);
3358
+ const terminationStdout = resolveResultStdout(result) || (preservePartialOutput ? capturedStdout.toString() || stdoutChunks.join("") : "");
3359
+ const terminationStderr = result.stderr || (preservePartialOutput ? capturedStderr.toString() || stderrChunks.join("") : "");
3360
+ throw new ProviderExecutionError(
3361
+ `${metadata.name} CLI terminated (${successfulTermination.reason} via ${successfulTermination.source})${detailSuffix}.${formatTerminationRemedy(successfulTermination.reason, timeout)}`,
3362
+ {
3363
+ retryable: false,
3364
+ exitCode: resolveTerminationExitCode(
3365
+ successfulTermination.reason,
3366
+ result.exitCode ?? void 0
3367
+ ),
3368
+ reason: successfulTermination.reason,
3369
+ signal: hasSignal(result) ? result.signal : void 0,
3370
+ terminationSource: successfulTermination.source,
3371
+ ...providerExecutionTransportStreamOptions(terminationStdout, terminationStderr, {
3372
+ streamBytes: { stdout: spoolMeasuredBytes }
3373
+ })
3374
+ }
3375
+ );
3376
+ }
3377
+ if (result.exitCode !== 0) {
3378
+ const bufferedStderr = stderrChunks.join("").trim();
3379
+ const bufferedStdout = useStreamingOutput || useFileBackedStdout ? stdoutChunks.join("").trim() : "";
3380
+ const rawErrorOutput = result.stderr?.trim() || bufferedStderr || bufferedStdout || resolveResultStdout(result)?.trim() || "no error output";
3381
+ const decoratedErrorOutput = rawErrorOutput === "no error output" ? `${rawErrorOutput} (command: ${commandSignature})` : rawErrorOutput;
3382
+ const selectedLine = selectBestErrorSummary(
3383
+ decoratedErrorOutput,
3384
+ bufferedStdout || resolveResultStdout(result)?.trim()
3385
+ ) ?? "";
3386
+ const sanitizedSelectedLine = selectedLine ? sanitizeError(new Error(selectedLine)).message : selectedLine;
3387
+ const termination = terminationState.getPrimaryRecord();
3388
+ if (termination !== null) {
3389
+ const signal = hasSignal(result) ? result.signal : void 0;
3390
+ const detailSuffix = termination.detail ? ` (${termination.detail})` : "";
3391
+ const preservePartialOutput = shouldPreserveTerminationPartialOutput(termination);
3392
+ const terminationStdout = resolveResultStdout(result) || (preservePartialOutput ? capturedStdout.toString() || stdoutChunks.join("") : "");
3393
+ const terminationStderr = result.stderr || (preservePartialOutput ? capturedStderr.toString() || stderrChunks.join("") : "");
3394
+ throw new ProviderExecutionError(
3395
+ `${metadata.name} CLI terminated (${termination.reason} via ${termination.source})${detailSuffix}: ${sanitizedSelectedLine}${formatTerminationRemedy(termination.reason, timeout)}`,
3396
+ {
3397
+ retryable: false,
3398
+ exitCode: resolveTerminationExitCode(termination.reason, result.exitCode ?? void 0),
3399
+ reason: termination.reason,
3400
+ signal,
3401
+ terminationSource: termination.source,
3402
+ ...providerExecutionTransportStreamOptions(
3403
+ terminationStdout,
3404
+ terminationStderr || bufferedStderr || "",
3405
+ { streamBytes: { stdout: spoolMeasuredBytes } }
3406
+ )
3407
+ }
3408
+ );
3409
+ }
3410
+ let terminationReason;
3411
+ let reason;
3412
+ if (result.exitCode === void 0) {
3413
+ if (hasSignal(result)) {
3414
+ const signal = result.signal;
3415
+ if (signal === "SIGTERM") {
3416
+ terminationReason = "killed by SIGTERM signal (timeout or manual termination)";
3417
+ reason = "signal_sigterm";
3418
+ } else if (signal === "SIGKILL") {
3419
+ terminationReason = "force killed by SIGKILL signal (unresponsive process)";
3420
+ reason = "signal_sigkill";
3421
+ } else {
3422
+ terminationReason = `killed by signal ${signal}`;
3423
+ reason = `signal_${signal.toLowerCase()}`;
3424
+ }
3425
+ } else {
3426
+ terminationReason = "crashed or terminated abnormally (no exit code)";
3427
+ reason = "abnormal_termination";
3428
+ }
3429
+ } else {
3430
+ const decodedSignal = exitCodeToSignal(result.exitCode, result.signal ?? void 0);
3431
+ if (decodedSignal) {
3432
+ if (decodedSignal === "SIGTERM") {
3433
+ terminationReason = `killed by SIGTERM signal (exit code ${result.exitCode})`;
3434
+ reason = "signal_sigterm";
3435
+ } else if (decodedSignal === "SIGKILL") {
3436
+ terminationReason = `force killed by SIGKILL signal (exit code ${result.exitCode})`;
3437
+ reason = "signal_sigkill";
3438
+ } else {
3439
+ terminationReason = `killed by signal ${decodedSignal} (exit code ${result.exitCode})`;
3440
+ reason = `signal_${decodedSignal.toLowerCase()}`;
3441
+ }
3442
+ } else {
3443
+ terminationReason = `exited with code ${result.exitCode}`;
3444
+ reason = "non_zero_exit";
3445
+ }
3446
+ }
3447
+ const fullStdout = resolveResultStdout(result) || (useStreamingOutput || useFileBackedStdout ? capturedStdout.toString() || bufferedStdout : "") || "";
3448
+ const fullStderr = result.stderr || bufferedStderr || "";
3449
+ if (reason === "non_zero_exit") {
3450
+ const denial = sandboxPathDenialError(metadata, sandboxed, {
3451
+ exitCode: result.exitCode,
3452
+ stdout: fullStdout,
3453
+ stderr: fullStderr,
3454
+ stdoutBytes: spoolMeasuredBytes
3455
+ });
3456
+ if (denial) throw denial;
3457
+ }
3458
+ throw new ProviderExecutionError(
3459
+ `${metadata.name} CLI ${terminationReason}: ${sanitizedSelectedLine}`,
3460
+ {
3461
+ retryable: false,
3462
+ exitCode: result.exitCode ?? void 0,
3463
+ reason,
3464
+ signal: result.signal ?? void 0,
3465
+ ...providerExecutionTransportStreamOptions(fullStdout, fullStderr, {
3466
+ streamBytes: { stdout: spoolMeasuredBytes }
3467
+ })
3468
+ }
3469
+ );
3470
+ }
3471
+ return {
3472
+ stdout: useFileBackedStdout ? resolveResultStdout(result) || "" : useStreamingOutput ? capturedStdout.toString() : result.stdout || "",
3473
+ stderr: useStreamingOutput ? capturedStderr.toString() : result.stderr || "",
3474
+ exitCode: result.exitCode,
3475
+ // Authoritative size from the spool inode. `stdout` above is
3476
+ // display-bounded, so a caller reporting a stream size must use this.
3477
+ // Reported only when bytes were actually measured: a zero-byte spool
3478
+ // alongside non-empty execa output means the redirect did not apply, and
3479
+ // zero would then be a claim about a stream this never saw.
3480
+ ...spoolMeasuredBytes !== void 0 ? { stdoutBytes: spoolMeasuredBytes } : {},
3481
+ ...stdoutSpoolDiskExhausted ? { stdoutSpoolDiskExhausted: true } : {}
3482
+ };
3483
+ } catch (error) {
3484
+ flushPipeDecoders();
3485
+ let failurePathSpoolBytes;
3486
+ if (stdoutSpoolTailer) {
3487
+ try {
3488
+ failurePathSpoolBytes = await stdoutSpoolTailer.finish();
3489
+ } catch {
3490
+ }
3491
+ }
3492
+ if (streamCallbackError && error === streamCallbackError) {
3493
+ throw error;
3494
+ }
3495
+ if (completionSignalEarlyExit && terminationState.getPrimaryRecord() === null && resultIsOurCancellation(error)) {
3496
+ return {
3497
+ stdout: capturedStdout.toString() || stdoutChunks.join(""),
3498
+ stderr: capturedStderr.toString() || stderrChunks.join(""),
3499
+ exitCode: 0
3500
+ };
3501
+ }
3502
+ throw classifyAndWrapExecaError({
3503
+ error,
3504
+ metadata,
3505
+ terminationState,
3506
+ startTime,
3507
+ timeout,
3508
+ maxBufferBytes,
3509
+ command,
3510
+ args,
3511
+ workingDir,
3512
+ // Under a file-backed stdout the execa error carries no stdout at all —
3513
+ // the child wrote to the spool, not to a pipe execa was reading. Without
3514
+ // these the timeout and abort classifications would lose every byte of
3515
+ // partial output, which is precisely the evidence a hung provider run is
3516
+ // diagnosed from.
3517
+ capturedStdout: capturedStdout.toString() || void 0,
3518
+ capturedStderr: capturedStderr.toString() || void 0,
3519
+ ...failurePathSpoolBytes !== void 0 && failurePathSpoolBytes > 0 ? { streamBytes: { stdout: failurePathSpoolBytes } } : {}
3520
+ });
3521
+ } finally {
3522
+ if (completionSignalGraceTimer) {
3523
+ clearTimeout(completionSignalGraceTimer);
3524
+ }
3525
+ if (stdoutSpool) {
3526
+ await stdoutSpool.dispose().catch(() => {
3527
+ });
3528
+ }
3529
+ await drainProviderTerminationGrace(terminationController);
3530
+ cleanupProviderExecutionResources({
3531
+ watchdogInterval,
3532
+ idleMonitorInterval,
3533
+ terminationController,
3534
+ abortSignal,
3535
+ abortListener,
3536
+ subprocess,
3537
+ stdoutDataListener,
3538
+ stderrListener,
3539
+ plmProcessId,
3540
+ limiterId,
3541
+ trackedPid,
3542
+ workingDir,
3543
+ providerName: metadata.name
3544
+ });
3545
+ if (processGroupOwnership.detach && await ensureDetachedProviderProcessGroupGone(providerProcessGroupPid)) {
3546
+ emitProviderProcessGroupClearedMarker(providerProcessGroupPid);
3547
+ }
3548
+ }
3549
+ }
3550
+
3551
+ export {
3552
+ emitBoundaryTriggered,
3553
+ setProcessLifecycleManager,
3554
+ getProcessLifecycleManager,
3555
+ resolveFileBackedStdoutOverride,
3556
+ isNonEmptyRawChunk,
3557
+ rawChunkToBuffer,
3558
+ composeRawChunkObservers,
3559
+ createPrivateSpool,
3560
+ BUILD_PROCESS_GROUP_OWNER_ENV,
3561
+ BUILD_PROVIDER_PROCESS_GROUP_MARKER_PREFIX,
3562
+ BUILD_PROVIDER_PROCESS_GROUP_CLEARED_MARKER_PREFIX,
3563
+ isProviderProcessGroupMarkerLine,
3564
+ resolveProviderProcessGroupOwnership,
3565
+ acquireProcessSlot,
3566
+ hasAcceptedPolicyBoundaryProof,
3567
+ emitHostClassBypassNotice,
3568
+ assertProviderBypassHasBoundaryProof,
3569
+ sandboxPathDenialError,
3570
+ MemoryGuardian,
3571
+ killAllFallbackTrackedSubprocesses,
3572
+ TMUX_COMPLETION_SIGNAL_GRACE_MS,
3573
+ createLineDelimitedTmuxCompletionSignal,
3574
+ withVariantInvocation,
3575
+ activeVariantServiceTier,
3576
+ prepareVariantCommand,
3577
+ recordVariantTmuxLaunch,
3578
+ computePromptFingerprint,
3579
+ DEFAULT_TIMEOUT,
3580
+ executeProviderCommand,
3581
+ executeProviderCommandAsync
3582
+ };
3583
+ //# sourceMappingURL=chunk-633XZ7UF.js.map