@poetic-ai/poetic 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (782) hide show
  1. package/.github/SECURITY.md +47 -0
  2. package/.nvmrc +1 -0
  3. package/.poetic/README.md +37 -0
  4. package/.poetic/providers/catalog.json +12051 -0
  5. package/.poetic/providers/pricing.json +1272 -0
  6. package/.poetic/providers/registry.json +3369 -0
  7. package/CHANGELOG.md +552 -0
  8. package/CODE_OF_CONDUCT.md +40 -0
  9. package/CONTRIBUTING.md +23 -0
  10. package/INSTALL.md +454 -0
  11. package/LICENSE +21 -0
  12. package/README.md +474 -0
  13. package/dist/BasicOptimizationCompetitionRunner-5H5TBYO4.js +153 -0
  14. package/dist/ExecutionTracker-UVONC4C6.js +16 -0
  15. package/dist/OptimizationConfig-7DFY2TST.js +17 -0
  16. package/dist/OptimizationEngine-JIMGP3LY.js +1597 -0
  17. package/dist/PromptStore-U6ZD3ZMQ.js +18 -0
  18. package/dist/actions-LUJPINLJ.js +322 -0
  19. package/dist/agent-ingest-3DJUJ7FU.js +53 -0
  20. package/dist/aggregator-DNCBINFO.js +12 -0
  21. package/dist/ai-judge-5QT5QJVU.js +156 -0
  22. package/dist/allowlist-grounding-RO6HKUFI.js +16 -0
  23. package/dist/allowlist-utils-23V7TJ3G.js +28 -0
  24. package/dist/anchored-turn-service-JULUCUIK.js +489 -0
  25. package/dist/api-transport-4TYTNLTJ.js +1087 -0
  26. package/dist/apply-completion-mode-AW2MOS3R.js +89 -0
  27. package/dist/artifact-migrator-23L45ISD.js +267 -0
  28. package/dist/ask-HWVV6QFR.js +135 -0
  29. package/dist/auth-5KEDKAPP.js +67 -0
  30. package/dist/auth-7TT3JINV.js +78 -0
  31. package/dist/auth-E6XUNZ5M.js +68 -0
  32. package/dist/auth-H3XDZE22.js +134 -0
  33. package/dist/auth-OC4E6633.js +71 -0
  34. package/dist/auth-S4CTX4GQ.js +44 -0
  35. package/dist/auth-YLH3S7EY.js +69 -0
  36. package/dist/auth-liveness-TDDEZY3T.js +46 -0
  37. package/dist/auto-optimizer-VPRWOWGU.js +80 -0
  38. package/dist/autoloop-cleanup-JOGKTLWA.js +109 -0
  39. package/dist/autoloop-evidence-gates-PCDALGVJ.js +38 -0
  40. package/dist/autoloop-gate-policy-Z7FVJVXV.js +175 -0
  41. package/dist/autoloop-helpers-2KTK43GL.js +22 -0
  42. package/dist/autoloop-ledger-W7QO62PX.js +96 -0
  43. package/dist/autoloop-ledger-subscriber-Z5RW5EIE.js +162 -0
  44. package/dist/autoloop-run-defaults-FERGRZGP.js +19 -0
  45. package/dist/autoloop-run-lock-CT2NWSV3.js +197 -0
  46. package/dist/autoloop-success-J2VKKBXQ.js +85 -0
  47. package/dist/autoloop-termination-summary-RN75F422.js +58 -0
  48. package/dist/autoloop-trajectory-XFIEXP5Z.js +282 -0
  49. package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
  50. package/dist/autonomous-loop-controller-PW4XVFGQ.js +4120 -0
  51. package/dist/backend-P3DAYRP7.js +29 -0
  52. package/dist/background-executor-CBN552V4.js +257 -0
  53. package/dist/backlog-execution-intent-U4XYPTV6.js +15 -0
  54. package/dist/backup-active-store-5WXG6SXT.js +17 -0
  55. package/dist/backup-telemetry-db-XGLXAA3N.js +254 -0
  56. package/dist/basic-competition-master-VCSBJVRN.js +344 -0
  57. package/dist/branch-archive-manager-RP6FP3ZC.js +254 -0
  58. package/dist/branch-cleanup-manager-RSHAI7YR.js +20 -0
  59. package/dist/build-gate-YHGRB4QB.js +71 -0
  60. package/dist/change-summary-WY7J5TOX.js +33 -0
  61. package/dist/chunk-23A26CSN.js +123 -0
  62. package/dist/chunk-27UTJD3M.js +265 -0
  63. package/dist/chunk-2A5CILN3.js +310 -0
  64. package/dist/chunk-2AQUWJPW.js +225 -0
  65. package/dist/chunk-2BZ53J6J.js +2344 -0
  66. package/dist/chunk-2DY5KNVM.js +276 -0
  67. package/dist/chunk-2EIA4RBE.js +659 -0
  68. package/dist/chunk-2IUXIGQD.js +1064 -0
  69. package/dist/chunk-2N42MS2Z.js +2193 -0
  70. package/dist/chunk-2QJ3H3L7.js +42 -0
  71. package/dist/chunk-2QLYTVYX.js +791 -0
  72. package/dist/chunk-2VSQMRCB.js +18 -0
  73. package/dist/chunk-2XQXYBM2.js +130 -0
  74. package/dist/chunk-2YFUIER7.js +426 -0
  75. package/dist/chunk-34CNP2HB.js +148 -0
  76. package/dist/chunk-35P3W3JX.js +456 -0
  77. package/dist/chunk-36PEBZAF.js +18 -0
  78. package/dist/chunk-3AOKYKA7.js +22 -0
  79. package/dist/chunk-3BCUNHKF.js +475 -0
  80. package/dist/chunk-3FLXLLB7.js +26 -0
  81. package/dist/chunk-3FOZ2VHV.js +100 -0
  82. package/dist/chunk-3G6FZCRF.js +106 -0
  83. package/dist/chunk-3M57DADF.js +44 -0
  84. package/dist/chunk-3S62LLWJ.js +543 -0
  85. package/dist/chunk-3ZPQLGV7.js +2904 -0
  86. package/dist/chunk-44N5WZZH.js +45 -0
  87. package/dist/chunk-45FPSA3B.js +125 -0
  88. package/dist/chunk-4BJ3O4RQ.js +929 -0
  89. package/dist/chunk-4BOP7T6L.js +2321 -0
  90. package/dist/chunk-4BTDUT2S.js +42 -0
  91. package/dist/chunk-4CSS7WVI.js +143 -0
  92. package/dist/chunk-4CUY7AFY.js +247 -0
  93. package/dist/chunk-4GSN5O5J.js +62 -0
  94. package/dist/chunk-4HN6DF7V.js +1027 -0
  95. package/dist/chunk-4IAPOG5V.js +415 -0
  96. package/dist/chunk-4IYIZQWV.js +48 -0
  97. package/dist/chunk-4NXPXE62.js +84 -0
  98. package/dist/chunk-4RCCF5BR.js +712 -0
  99. package/dist/chunk-4V7NAQ4R.js +19527 -0
  100. package/dist/chunk-4VJITV4P.js +445 -0
  101. package/dist/chunk-4YX7J6QL.js +1859 -0
  102. package/dist/chunk-527OBWQB.js +338 -0
  103. package/dist/chunk-5D4A7E3D.js +448 -0
  104. package/dist/chunk-5DLKYTQX.js +4003 -0
  105. package/dist/chunk-5EERLVZB.js +139 -0
  106. package/dist/chunk-5H72XE4H.js +256 -0
  107. package/dist/chunk-5HDP7XZG.js +91 -0
  108. package/dist/chunk-5LAMRH4X.js +969 -0
  109. package/dist/chunk-5LTN43AS.js +1972 -0
  110. package/dist/chunk-5RBHQYDB.js +2206 -0
  111. package/dist/chunk-5WCQRDRB.js +588 -0
  112. package/dist/chunk-5WRLK5KW.js +700 -0
  113. package/dist/chunk-5ZCXC23G.js +595 -0
  114. package/dist/chunk-6BM72ZMG.js +31 -0
  115. package/dist/chunk-6EDAJH2I.js +68 -0
  116. package/dist/chunk-6EQKFDBH.js +457 -0
  117. package/dist/chunk-6MFRHTRI.js +115 -0
  118. package/dist/chunk-6TZJRKNW.js +321 -0
  119. package/dist/chunk-6V7HGQFZ.js +20 -0
  120. package/dist/chunk-6VWVO2TU.js +3746 -0
  121. package/dist/chunk-6Y5TWI7H.js +146 -0
  122. package/dist/chunk-6Y5U7UFY.js +91 -0
  123. package/dist/chunk-6ZLAK3XG.js +14 -0
  124. package/dist/chunk-72XCRQED.js +34 -0
  125. package/dist/chunk-72YTZMAM.js +589 -0
  126. package/dist/chunk-73BBJOKA.js +263 -0
  127. package/dist/chunk-73NCTWKL.js +188 -0
  128. package/dist/chunk-77I6G4CO.js +1 -0
  129. package/dist/chunk-7DHRDWFS.js +3104 -0
  130. package/dist/chunk-7DNSNKJV.js +78 -0
  131. package/dist/chunk-7FMJVYBS.js +307 -0
  132. package/dist/chunk-7GDRQBQC.js +419 -0
  133. package/dist/chunk-7GPCEFUV.js +270 -0
  134. package/dist/chunk-7IL4A2PP.js +948 -0
  135. package/dist/chunk-7MMLMXO6.js +3679 -0
  136. package/dist/chunk-7QCZSLBH.js +1 -0
  137. package/dist/chunk-7R2WLDOS.js +62 -0
  138. package/dist/chunk-7T7RUJI7.js +949 -0
  139. package/dist/chunk-A2WKSVX7.js +43 -0
  140. package/dist/chunk-A3YGID55.js +133 -0
  141. package/dist/chunk-A722DEVA.js +14 -0
  142. package/dist/chunk-ACDIT7OP.js +1376 -0
  143. package/dist/chunk-ACKIPAOJ.js +302 -0
  144. package/dist/chunk-APPNGGN7.js +365 -0
  145. package/dist/chunk-APV6MK5E.js +137 -0
  146. package/dist/chunk-ASEP3M2W.js +968 -0
  147. package/dist/chunk-AT4TNPWW.js +2931 -0
  148. package/dist/chunk-ATVKCSGT.js +250 -0
  149. package/dist/chunk-AURFMVCD.js +899 -0
  150. package/dist/chunk-AX6GWE7V.js +47 -0
  151. package/dist/chunk-AY5EWJPF.js +385 -0
  152. package/dist/chunk-BAV2HJXS.js +194 -0
  153. package/dist/chunk-BBHRN366.js +89 -0
  154. package/dist/chunk-BBPSTTPA.js +1004 -0
  155. package/dist/chunk-BDATUDDJ.js +992 -0
  156. package/dist/chunk-BKE5PG5L.js +20414 -0
  157. package/dist/chunk-BLPHWMDK.js +797 -0
  158. package/dist/chunk-BSE4R6XD.js +322 -0
  159. package/dist/chunk-BXGMAU4A.js +396 -0
  160. package/dist/chunk-BXI4NXL3.js +507 -0
  161. package/dist/chunk-BZU2O43F.js +1125 -0
  162. package/dist/chunk-C3L6YQ7P.js +147 -0
  163. package/dist/chunk-C57KJOUQ.js +121 -0
  164. package/dist/chunk-CCV7BPSY.js +118 -0
  165. package/dist/chunk-CD7ISXA4.js +826 -0
  166. package/dist/chunk-CE5OZBYY.js +21 -0
  167. package/dist/chunk-CFBIG37O.js +154 -0
  168. package/dist/chunk-CJC6GZ46.js +457 -0
  169. package/dist/chunk-CKCDGXIV.js +408 -0
  170. package/dist/chunk-CKNX3TTP.js +10338 -0
  171. package/dist/chunk-CLKSETWE.js +10 -0
  172. package/dist/chunk-CP7H3HSP.js +1552 -0
  173. package/dist/chunk-CPLEWXNZ.js +66 -0
  174. package/dist/chunk-CQM3A35X.js +844 -0
  175. package/dist/chunk-CS6P76D3.js +103 -0
  176. package/dist/chunk-CTLUBNCW.js +622 -0
  177. package/dist/chunk-CUSRN6RJ.js +632 -0
  178. package/dist/chunk-D5EP5D2W.js +26 -0
  179. package/dist/chunk-D5RYINO7.js +412 -0
  180. package/dist/chunk-DBFS4HMH.js +751 -0
  181. package/dist/chunk-DC4ZYMXJ.js +115 -0
  182. package/dist/chunk-DCBZP442.js +9243 -0
  183. package/dist/chunk-DCYF7EKG.js +26 -0
  184. package/dist/chunk-DDMAFNUK.js +5351 -0
  185. package/dist/chunk-DF5SLDE4.js +966 -0
  186. package/dist/chunk-DJFW7SMX.js +348 -0
  187. package/dist/chunk-DQFLLBJW.js +121 -0
  188. package/dist/chunk-DSFM56OA.js +1203 -0
  189. package/dist/chunk-DTY4APYV.js +218 -0
  190. package/dist/chunk-DXH5JBRS.js +437 -0
  191. package/dist/chunk-E3NTPHEO.js +194 -0
  192. package/dist/chunk-E74LUIID.js +302 -0
  193. package/dist/chunk-EI57M5BI.js +194 -0
  194. package/dist/chunk-EJ4ZAWLV.js +305 -0
  195. package/dist/chunk-EJGCZGUF.js +1483 -0
  196. package/dist/chunk-EK2U3YEG.js +486 -0
  197. package/dist/chunk-ELMFYNV7.js +109 -0
  198. package/dist/chunk-ENRGKNR5.js +25 -0
  199. package/dist/chunk-ETYDXCK7.js +679 -0
  200. package/dist/chunk-EYRH3W74.js +239 -0
  201. package/dist/chunk-F23DIWNN.js +1024 -0
  202. package/dist/chunk-F5JO7HAS.js +94 -0
  203. package/dist/chunk-F7ER6ANO.js +174 -0
  204. package/dist/chunk-FATUVIIN.js +374 -0
  205. package/dist/chunk-FC23CTXV.js +322 -0
  206. package/dist/chunk-FD4ERYEG.js +22 -0
  207. package/dist/chunk-FH7WOJAE.js +79 -0
  208. package/dist/chunk-FHOWVDF5.js +1342 -0
  209. package/dist/chunk-FKAUPHMR.js +96 -0
  210. package/dist/chunk-FONNFJXA.js +137 -0
  211. package/dist/chunk-FQ7FSZRW.js +75 -0
  212. package/dist/chunk-FRG57FPM.js +240 -0
  213. package/dist/chunk-FUVP64ER.js +31 -0
  214. package/dist/chunk-FYOILAN5.js +6818 -0
  215. package/dist/chunk-G35UYQ6Z.js +69 -0
  216. package/dist/chunk-G36W2T2S.js +1143 -0
  217. package/dist/chunk-G3L2L5XZ.js +49 -0
  218. package/dist/chunk-G4THLFV3.js +148 -0
  219. package/dist/chunk-GAFJEYLK.js +29 -0
  220. package/dist/chunk-GFGYB2ZU.js +1689 -0
  221. package/dist/chunk-GG6KJYW6.js +85 -0
  222. package/dist/chunk-GHHFDU2U.js +55 -0
  223. package/dist/chunk-GHTZSQB7.js +57 -0
  224. package/dist/chunk-GK37ILCX.js +1231 -0
  225. package/dist/chunk-GKN3HMN4.js +2809 -0
  226. package/dist/chunk-GNVDBVJP.js +156 -0
  227. package/dist/chunk-GPEL3FBM.js +924 -0
  228. package/dist/chunk-GPSNGPZS.js +1604 -0
  229. package/dist/chunk-GSGD5E4C.js +30 -0
  230. package/dist/chunk-GSUQJJXQ.js +331 -0
  231. package/dist/chunk-GSV226X6.js +110 -0
  232. package/dist/chunk-H2AYQIHW.js +224 -0
  233. package/dist/chunk-H66DXFS5.js +1374 -0
  234. package/dist/chunk-H6G7QRMQ.js +35 -0
  235. package/dist/chunk-H7JAGHZT.js +59 -0
  236. package/dist/chunk-H7ZEFECA.js +316 -0
  237. package/dist/chunk-HAC6EHZZ.js +79 -0
  238. package/dist/chunk-HIO33P3G.js +19 -0
  239. package/dist/chunk-HMVQIPH3.js +547 -0
  240. package/dist/chunk-HOYBYAOA.js +257 -0
  241. package/dist/chunk-HX5P3CSP.js +1784 -0
  242. package/dist/chunk-I46EG2XQ.js +65 -0
  243. package/dist/chunk-I4NPDSCB.js +279 -0
  244. package/dist/chunk-I5WRT7ZR.js +514 -0
  245. package/dist/chunk-IC7I6YIJ.js +301 -0
  246. package/dist/chunk-IDCSOZVN.js +78 -0
  247. package/dist/chunk-IFCBYECK.js +112 -0
  248. package/dist/chunk-IFZCPEY2.js +66 -0
  249. package/dist/chunk-IKFP2KUR.js +48 -0
  250. package/dist/chunk-IRFBN336.js +878 -0
  251. package/dist/chunk-IUXNGKA6.js +152 -0
  252. package/dist/chunk-IV2RVAN7.js +1356 -0
  253. package/dist/chunk-IZYIQQ7X.js +53 -0
  254. package/dist/chunk-J3UUR7DE.js +210 -0
  255. package/dist/chunk-J54VUAY2.js +566 -0
  256. package/dist/chunk-J62KPGII.js +464 -0
  257. package/dist/chunk-J6P3FWWW.js +130 -0
  258. package/dist/chunk-JKBHJQMT.js +434 -0
  259. package/dist/chunk-JLS65NUQ.js +14 -0
  260. package/dist/chunk-JOSYEJKY.js +141 -0
  261. package/dist/chunk-JPKSXKNB.js +94 -0
  262. package/dist/chunk-JQNJB2BB.js +2440 -0
  263. package/dist/chunk-JRVNSWSQ.js +2626 -0
  264. package/dist/chunk-JSWMRQYG.js +28 -0
  265. package/dist/chunk-JZKNBBIB.js +152 -0
  266. package/dist/chunk-K54Y7MLK.js +160 -0
  267. package/dist/chunk-K65546RE.js +183 -0
  268. package/dist/chunk-KM3F7SYE.js +702 -0
  269. package/dist/chunk-KNDYMVWN.js +102 -0
  270. package/dist/chunk-KNT72VR6.js +132 -0
  271. package/dist/chunk-KP6YILMU.js +482 -0
  272. package/dist/chunk-KQEBSK3T.js +274 -0
  273. package/dist/chunk-KT6VHSPF.js +84 -0
  274. package/dist/chunk-KTMW65UX.js +14 -0
  275. package/dist/chunk-KZ5CJVBP.js +1813 -0
  276. package/dist/chunk-L4427KOE.js +26 -0
  277. package/dist/chunk-L6OM4A22.js +189 -0
  278. package/dist/chunk-L7E6XCRA.js +1042 -0
  279. package/dist/chunk-L7JZLXQL.js +173 -0
  280. package/dist/chunk-LAMKBTXX.js +40 -0
  281. package/dist/chunk-LDCF2MKN.js +132 -0
  282. package/dist/chunk-LEIIWPWQ.js +78 -0
  283. package/dist/chunk-LFTQVYBB.js +31 -0
  284. package/dist/chunk-LG3PDRTR.js +2872 -0
  285. package/dist/chunk-LGHII5ET.js +23 -0
  286. package/dist/chunk-LH5QY22X.js +1205 -0
  287. package/dist/chunk-LIVJ6266.js +438 -0
  288. package/dist/chunk-LKRAR3IH.js +276 -0
  289. package/dist/chunk-LO23NABI.js +3063 -0
  290. package/dist/chunk-LO3X5NLS.js +326 -0
  291. package/dist/chunk-LPITVM7M.js +339 -0
  292. package/dist/chunk-LR5IJIGV.js +810 -0
  293. package/dist/chunk-LRGMHROI.js +79 -0
  294. package/dist/chunk-LUVKFFWR.js +315 -0
  295. package/dist/chunk-LWCBNGH6.js +35 -0
  296. package/dist/chunk-LWTN3WRV.js +260 -0
  297. package/dist/chunk-M3HQYKQX.js +308 -0
  298. package/dist/chunk-M6GVSPEH.js +1016 -0
  299. package/dist/chunk-MF5HP6XV.js +221 -0
  300. package/dist/chunk-MHLCBZJB.js +328 -0
  301. package/dist/chunk-MN6PL4AN.js +120 -0
  302. package/dist/chunk-MOEY65Z6.js +5678 -0
  303. package/dist/chunk-MQ4WA34C.js +206 -0
  304. package/dist/chunk-MWHF5V7U.js +223 -0
  305. package/dist/chunk-MWHLBPNU.js +211 -0
  306. package/dist/chunk-MWK5UZQ3.js +1068 -0
  307. package/dist/chunk-MYLH2S4G.js +64 -0
  308. package/dist/chunk-MZ5WYKNA.js +28 -0
  309. package/dist/chunk-N4VTRA7K.js +131 -0
  310. package/dist/chunk-N5DX4JAK.js +12 -0
  311. package/dist/chunk-N65O4XTH.js +5011 -0
  312. package/dist/chunk-NEQUQHOX.js +223 -0
  313. package/dist/chunk-NGK6PEOG.js +25 -0
  314. package/dist/chunk-NJVD4PWE.js +1033 -0
  315. package/dist/chunk-NM6PMYY4.js +768 -0
  316. package/dist/chunk-NN4PJDHP.js +708 -0
  317. package/dist/chunk-NP2V3L7K.js +226 -0
  318. package/dist/chunk-NRLY536M.js +260 -0
  319. package/dist/chunk-NRNE225N.js +1270 -0
  320. package/dist/chunk-NS2K2GTP.js +605 -0
  321. package/dist/chunk-NS33V3IM.js +51 -0
  322. package/dist/chunk-NSHASMZZ.js +71 -0
  323. package/dist/chunk-NWOYOA6H.js +378 -0
  324. package/dist/chunk-NWRUSEXG.js +322 -0
  325. package/dist/chunk-NZGDAWIP.js +1905 -0
  326. package/dist/chunk-O47UOKU3.js +395 -0
  327. package/dist/chunk-O4G2W3ST.js +9831 -0
  328. package/dist/chunk-O6V4PNLO.js +63 -0
  329. package/dist/chunk-OA4GPILI.js +624 -0
  330. package/dist/chunk-OGMSYL6J.js +227 -0
  331. package/dist/chunk-OIS7J26S.js +319 -0
  332. package/dist/chunk-OMX5VL43.js +79 -0
  333. package/dist/chunk-ON3G73BU.js +264 -0
  334. package/dist/chunk-OPYFYTWQ.js +220 -0
  335. package/dist/chunk-OQ6K46CK.js +1734 -0
  336. package/dist/chunk-OYZYO7TV.js +47 -0
  337. package/dist/chunk-OZ4REHIN.js +4386 -0
  338. package/dist/chunk-P47VN5F4.js +282 -0
  339. package/dist/chunk-P5I4X7A7.js +353 -0
  340. package/dist/chunk-P6VQROCO.js +594 -0
  341. package/dist/chunk-P7CQGPLS.js +30 -0
  342. package/dist/chunk-PCAGC5MR.js +1763 -0
  343. package/dist/chunk-PFTQBXS6.js +5181 -0
  344. package/dist/chunk-PGSPX4SU.js +15 -0
  345. package/dist/chunk-PIKLF7BM.js +432 -0
  346. package/dist/chunk-PJWJ3SAV.js +22 -0
  347. package/dist/chunk-PKIFMV72.js +100 -0
  348. package/dist/chunk-PL37JDNA.js +189 -0
  349. package/dist/chunk-PTH5E5XO.js +195 -0
  350. package/dist/chunk-PW6AXLQC.js +4128 -0
  351. package/dist/chunk-PYITM4N2.js +79 -0
  352. package/dist/chunk-PZ5AY32C.js +10 -0
  353. package/dist/chunk-Q3RO7N35.js +45 -0
  354. package/dist/chunk-Q3WIC6GQ.js +2670 -0
  355. package/dist/chunk-Q5XIXSHX.js +271 -0
  356. package/dist/chunk-QGJDMEOV.js +34 -0
  357. package/dist/chunk-QNOB37UH.js +58 -0
  358. package/dist/chunk-QOCOVLUH.js +462 -0
  359. package/dist/chunk-QTCJ5CC5.js +172 -0
  360. package/dist/chunk-QVFV5IP2.js +232 -0
  361. package/dist/chunk-QVZMFDYG.js +29 -0
  362. package/dist/chunk-R35PEUKH.js +511 -0
  363. package/dist/chunk-R4UWBC35.js +200 -0
  364. package/dist/chunk-R6MLCREW.js +44 -0
  365. package/dist/chunk-R6W23LKN.js +254 -0
  366. package/dist/chunk-R7XDDX2A.js +4007 -0
  367. package/dist/chunk-RDFRCT64.js +168 -0
  368. package/dist/chunk-RE5VZDFQ.js +58 -0
  369. package/dist/chunk-RGROYC2G.js +638 -0
  370. package/dist/chunk-RGWHUI5E.js +68 -0
  371. package/dist/chunk-RHVG6UNL.js +205 -0
  372. package/dist/chunk-RI4EX2QE.js +18 -0
  373. package/dist/chunk-RJAAKDRX.js +17 -0
  374. package/dist/chunk-ROMHOSMQ.js +185 -0
  375. package/dist/chunk-RWREC3KJ.js +517 -0
  376. package/dist/chunk-RYNETRDJ.js +118 -0
  377. package/dist/chunk-RZY7RKM5.js +500 -0
  378. package/dist/chunk-S2MNWFAG.js +52 -0
  379. package/dist/chunk-S2VQCZO4.js +22 -0
  380. package/dist/chunk-S54MKU6V.js +117 -0
  381. package/dist/chunk-S5OIDFRM.js +302 -0
  382. package/dist/chunk-SCW4ZF6R.js +150 -0
  383. package/dist/chunk-SLS2N4PH.js +2213 -0
  384. package/dist/chunk-SNLBO4BF.js +247 -0
  385. package/dist/chunk-SP3LFU6B.js +60 -0
  386. package/dist/chunk-SQQTDDQA.js +537 -0
  387. package/dist/chunk-STV6LYYE.js +45 -0
  388. package/dist/chunk-SURZ2WFE.js +326 -0
  389. package/dist/chunk-SZ7DL357.js +1047 -0
  390. package/dist/chunk-T5E4NQCM.js +5742 -0
  391. package/dist/chunk-TAJPCXSB.js +13 -0
  392. package/dist/chunk-TAOOYK3P.js +358 -0
  393. package/dist/chunk-TDSEX5CF.js +24 -0
  394. package/dist/chunk-TFTGP7Z7.js +174 -0
  395. package/dist/chunk-TGON4N4O.js +197 -0
  396. package/dist/chunk-TGQZHDY2.js +2373 -0
  397. package/dist/chunk-TJJZ2OKV.js +6783 -0
  398. package/dist/chunk-TRSVUPCX.js +25 -0
  399. package/dist/chunk-TSXGRLPR.js +107 -0
  400. package/dist/chunk-U2S3YEX3.js +224 -0
  401. package/dist/chunk-U45RTRGY.js +818 -0
  402. package/dist/chunk-U6C3VVWS.js +13 -0
  403. package/dist/chunk-UDMS5AD3.js +307 -0
  404. package/dist/chunk-UGX7GI37.js +94 -0
  405. package/dist/chunk-UH3JJSHK.js +1 -0
  406. package/dist/chunk-UHRBTZYY.js +208 -0
  407. package/dist/chunk-UHT2KRG5.js +193 -0
  408. package/dist/chunk-UI2F6DJ5.js +118 -0
  409. package/dist/chunk-UMAKSB4Z.js +284 -0
  410. package/dist/chunk-UR2IBGIM.js +521 -0
  411. package/dist/chunk-UUH2RVKS.js +585 -0
  412. package/dist/chunk-UVJ4PJDK.js +4533 -0
  413. package/dist/chunk-V53UG2OT.js +9924 -0
  414. package/dist/chunk-V72RMBM4.js +48 -0
  415. package/dist/chunk-VBNCKCCI.js +16 -0
  416. package/dist/chunk-VNSYKC25.js +24 -0
  417. package/dist/chunk-VPHVFK4A.js +1984 -0
  418. package/dist/chunk-VTLNJQ44.js +133 -0
  419. package/dist/chunk-VTW7HP3R.js +100 -0
  420. package/dist/chunk-VVGEPBPS.js +218 -0
  421. package/dist/chunk-VVLLL7I4.js +166 -0
  422. package/dist/chunk-VX3UMWB7.js +483 -0
  423. package/dist/chunk-VXF4Q3FW.js +20 -0
  424. package/dist/chunk-W3JMT2YY.js +712 -0
  425. package/dist/chunk-WDUORIHF.js +877 -0
  426. package/dist/chunk-WDVTY4U6.js +148 -0
  427. package/dist/chunk-WIFZCHEG.js +12566 -0
  428. package/dist/chunk-WIRN3F75.js +736 -0
  429. package/dist/chunk-WMPU2UOV.js +82 -0
  430. package/dist/chunk-WTOKKE2V.js +784 -0
  431. package/dist/chunk-WX5IRLF6.js +740 -0
  432. package/dist/chunk-WZ6U3O7I.js +1581 -0
  433. package/dist/chunk-XAONGNST.js +57 -0
  434. package/dist/chunk-XB5YLCLB.js +13 -0
  435. package/dist/chunk-XEP5NQ5Y.js +688 -0
  436. package/dist/chunk-XGYF2QMZ.js +351 -0
  437. package/dist/chunk-XHEKQENB.js +255 -0
  438. package/dist/chunk-XNO4FM6X.js +1124 -0
  439. package/dist/chunk-XPHKYHO4.js +878 -0
  440. package/dist/chunk-XPK2I4NC.js +405 -0
  441. package/dist/chunk-XPU2XADL.js +2175 -0
  442. package/dist/chunk-XQD2B6BB.js +507 -0
  443. package/dist/chunk-XT2ZQVTC.js +558 -0
  444. package/dist/chunk-XTXJGGUV.js +351 -0
  445. package/dist/chunk-XUXVDPSZ.js +50 -0
  446. package/dist/chunk-XV7NZL4B.js +57 -0
  447. package/dist/chunk-XZE4XARH.js +563 -0
  448. package/dist/chunk-XZYR5EDO.js +152 -0
  449. package/dist/chunk-Y3J4JMTU.js +61 -0
  450. package/dist/chunk-Y55LZN5U.js +52 -0
  451. package/dist/chunk-Y5VN7DMP.js +112 -0
  452. package/dist/chunk-Y67VAHN4.js +459 -0
  453. package/dist/chunk-YAXSKEUH.js +3544 -0
  454. package/dist/chunk-YB3JD4E6.js +975 -0
  455. package/dist/chunk-YESZJFK6.js +220 -0
  456. package/dist/chunk-YGXKOBQQ.js +292 -0
  457. package/dist/chunk-YMX76IOS.js +31 -0
  458. package/dist/chunk-YOTXESEH.js +257 -0
  459. package/dist/chunk-YTYIEZQY.js +119 -0
  460. package/dist/chunk-YVORHQ2S.js +579 -0
  461. package/dist/chunk-Z2CUQDAR.js +3429 -0
  462. package/dist/chunk-Z2KYOFHS.js +7000 -0
  463. package/dist/chunk-Z6PC7QX6.js +161 -0
  464. package/dist/chunk-ZDTGECTN.js +235 -0
  465. package/dist/chunk-ZIPWI2LY.js +151 -0
  466. package/dist/chunk-ZSKKMTQJ.js +554 -0
  467. package/dist/chunk-ZTT5IVPY.js +1160 -0
  468. package/dist/chunk-ZX65UI5W.js +78 -0
  469. package/dist/chunk-ZYG7GGKO.js +218 -0
  470. package/dist/chunk-ZZZUL4OF.js +38 -0
  471. package/dist/cli-utils-IXL26KJT.js +40 -0
  472. package/dist/cli-validation-WLXWLUJL.js +111 -0
  473. package/dist/commit-utils-P7CRJF5N.js +202 -0
  474. package/dist/compete-config-resolver-R5ULXMYH.js +76 -0
  475. package/dist/compete-request-62JESVET.js +364 -0
  476. package/dist/compete-results-QEPG6FZX.js +208 -0
  477. package/dist/competition-outcome-tracker-R32OOZ43.js +38 -0
  478. package/dist/config-JCOKXOQT.js +166 -0
  479. package/dist/config-audit-EL3GHXS7.js +360 -0
  480. package/dist/config-explain-TNILDEVJ.js +12 -0
  481. package/dist/config-loader-VPFPFO4B.js +38 -0
  482. package/dist/config-manager-7T4E2BQO.js +67 -0
  483. package/dist/config-validator-KKOHOW7O.js +72 -0
  484. package/dist/cost-YC42XUF3.js +53 -0
  485. package/dist/coverage-orchestrator-CISNKJC2.js +772 -0
  486. package/dist/coverage-scanner-YVD62MLH.js +12 -0
  487. package/dist/createCompetitionRunner-LJG6ZQSO.js +46 -0
  488. package/dist/data-migration-state-VJK64DLT.js +31 -0
  489. package/dist/db-migrator-XSEIOGWY.js +34 -0
  490. package/dist/discovery-JGYGDD25.js +25 -0
  491. package/dist/doctor-GJOYE7AE.js +186 -0
  492. package/dist/domain-analyzer-AWF3RP6E.js +29 -0
  493. package/dist/ensure-initialized-744DIZEZ.js +52 -0
  494. package/dist/entry.js +940 -0
  495. package/dist/environment-YS45U5ZI.js +81 -0
  496. package/dist/error-parser-core-PPZ36A4S.js +50 -0
  497. package/dist/escalation-ladder-MKTCEGSA.js +130 -0
  498. package/dist/evaluation-context-KV4GZNN7.js +35 -0
  499. package/dist/evidence-plan-resolver-GBSYSAPX.js +85 -0
  500. package/dist/execution-data-writer-3ODTBDLH.js +53 -0
  501. package/dist/execution-policy-applier-ZHD3DCF3.js +31 -0
  502. package/dist/execution-preflight-Z4Y64V3I.js +209 -0
  503. package/dist/execution-roles-R3DPPMD3.js +66 -0
  504. package/dist/exit-code-error-Z4SW2DVK.js +14 -0
  505. package/dist/external-temp-cleanup-N2RZH4QP.js +311 -0
  506. package/dist/factory-XBN7DFIM.js +149 -0
  507. package/dist/file-utils-XIVR2ZMA.js +47 -0
  508. package/dist/flywheel-autoloop-executor-UILGOFFK.js +249 -0
  509. package/dist/flywheel-competition-executor-JOBEXTRB.js +259 -0
  510. package/dist/flywheel-executor-6JFLA6J5.js +369 -0
  511. package/dist/flywheel-git-isolation-UC5NIEVU.js +48 -0
  512. package/dist/flywheel-manifest-5UC4VBMA.js +108 -0
  513. package/dist/flywheel-model-defaults-7CVKP53V.js +27 -0
  514. package/dist/flywheel-preflight-XEY5SHM6.js +104 -0
  515. package/dist/flywheel-resume-7HELH7QS.js +23 -0
  516. package/dist/flywheel-safety-7U7DPOAP.js +28 -0
  517. package/dist/flywheel-scope-decision-ZHKF6ZIN.js +11 -0
  518. package/dist/get-telemetry-logger-DPVWWIYY.js +73 -0
  519. package/dist/git-worktree-IY6V6DUO.js +18 -0
  520. package/dist/github-pr-manager-4LXEKJTA.js +211 -0
  521. package/dist/guidance-profile-config-E7XJL2VP.js +117 -0
  522. package/dist/guidance-profile-renderer-QK2YMAAP.js +21 -0
  523. package/dist/index-query-4JEUKA44.js +31 -0
  524. package/dist/index.js +108661 -0
  525. package/dist/instructions-6BURLQJC.js +64 -0
  526. package/dist/invoke-provider-auth-GRUYP44M.js +223 -0
  527. package/dist/judge-scoring.json +80 -0
  528. package/dist/judge-test.js +555 -0
  529. package/dist/lab-mode-OTWVHN63.js +39 -0
  530. package/dist/lab-utils-BJRFLGK4.js +23 -0
  531. package/dist/linux-host-class-UY4KVLFD.js +29 -0
  532. package/dist/llm-judge-executor-F7Z3HO77.js +133 -0
  533. package/dist/local-executor-CEHWE2PL.js +223 -0
  534. package/dist/logger-33TR6EE5.js +72 -0
  535. package/dist/loop-spec-XTLQAVZ7.js +191 -0
  536. package/dist/manager-2HJG5CLT.js +25 -0
  537. package/dist/matrix-prompt-builder-6UDN5X3F.js +497 -0
  538. package/dist/matrix-result-parser-7W35EUOV.js +15 -0
  539. package/dist/metadata-HQ43NDEK.js +22 -0
  540. package/dist/model-invocations-db-QBO4Y7WZ.js +38 -0
  541. package/dist/monitor-XGYBG2DW.js +72 -0
  542. package/dist/next-PB5ZXZKB.js +90 -0
  543. package/dist/next-ZBDK725T.js +69 -0
  544. package/dist/optimization-config-resolver-O6WKR47U.js +75 -0
  545. package/dist/package-3YCWIQQ5.js +10 -0
  546. package/dist/parallel-orchestrator-NL7YJJU2.js +297 -0
  547. package/dist/parallel-worker.js +279 -0
  548. package/dist/parse-git-status-PIAF3OTP.js +10 -0
  549. package/dist/path-security-ETTH6TZL.js +39 -0
  550. package/dist/pattern-bank-UNJR5ADV.js +15 -0
  551. package/dist/plan-backlog-list-fast-VAGYBV3J.js +270 -0
  552. package/dist/plan-backlog-show-fast-SG2CZPW3.js +406 -0
  553. package/dist/plan-sprint-list-fast-LURAX47V.js +162 -0
  554. package/dist/plan-sprint-status-fast-FJAODCHD.js +208 -0
  555. package/dist/plan-task-status-fast-HNYBMQI4.js +349 -0
  556. package/dist/plan-to-flywheel-Z4U3GWPN.js +456 -0
  557. package/dist/planning-backlog-3CQ5QQBQ.js +319 -0
  558. package/dist/poetic-root-V5DNXEAE.js +17 -0
  559. package/dist/preflight-OPANWMME.js +12 -0
  560. package/dist/process-registry-PDZJPTAS.js +27 -0
  561. package/dist/process-scanner-C22SYXYD.js +22 -0
  562. package/dist/processes-KMQUD7HY.js +29 -0
  563. package/dist/processes-json-fast-IBDXZ6WW.js +135 -0
  564. package/dist/profile-SE5EVXAP.js +149 -0
  565. package/dist/prompts-WZZPGWBX.js +168 -0
  566. package/dist/protected-branches-RNTEX7ET.js +57 -0
  567. package/dist/provider-aware-resource-manager-QBTZJMNP.js +18 -0
  568. package/dist/provider-matrix-N5X57V3Y.js +154 -0
  569. package/dist/provider-matrix-renderer-MZDWKKID.js +139 -0
  570. package/dist/provider-output-forwarding-DERID3TP.js +30 -0
  571. package/dist/provider-registry-J5NRBJKI.js +128 -0
  572. package/dist/provider-temp-cleanup-KYGLF6YU.js +14 -0
  573. package/dist/prune-engine-Q6E2DXBN.js +451 -0
  574. package/dist/quality-gate-YRHMQAEI.js +70 -0
  575. package/dist/quickstart-FIRLKGJI.js +62 -0
  576. package/dist/readiness-VZTMSG6J.js +96 -0
  577. package/dist/registry-YODFY77A.js +153 -0
  578. package/dist/repair-helpers-TTV5FEF4.js +117 -0
  579. package/dist/repo-root-2IGD4H7X.js +22 -0
  580. package/dist/resolution-engine-D6TX6FRG.js +127 -0
  581. package/dist/resolve-provider-cli-O2P6XZBZ.js +35 -0
  582. package/dist/restore-telemetry-db-BQL6DTQF.js +360 -0
  583. package/dist/result-streamer-WEHW476R.js +19 -0
  584. package/dist/routing-events-DHPUZDDF.js +27 -0
  585. package/dist/routing-history-store-UWCEXAP3.js +46 -0
  586. package/dist/routing-planner-F5WQEUOM.js +160 -0
  587. package/dist/run-poetic-tui-J6LWRJUP.js +13517 -0
  588. package/dist/run-simulation.js +376 -0
  589. package/dist/runner-CS2TNGHA.js +1092 -0
  590. package/dist/runner-HHH7ZN2Z.js +1571 -0
  591. package/dist/safety-OCC4KJJR.js +64 -0
  592. package/dist/safety-stanza-7SV3HGG3.js +60 -0
  593. package/dist/sandbox-32QXJEMV.js +81 -0
  594. package/dist/sandbox-RSO7VP6V.js +94 -0
  595. package/dist/schema-extensions.sql +234 -0
  596. package/dist/security-2KI5XNDG.js +17 -0
  597. package/dist/setup-bb-plugin-QAQWZCV5.js +738 -0
  598. package/dist/setup-claude-code-P7BTTSPO.js +317 -0
  599. package/dist/setup-temp-cleanup-GASCWZ2I.js +20 -0
  600. package/dist/shared-utils-D6U6UREP.js +37 -0
  601. package/dist/simple-artifact-goal-OTXNGZY6.js +25 -0
  602. package/dist/sprint-UIXPYOXQ.js +338 -0
  603. package/dist/sprint-bridge-4BHMSC3M.js +68 -0
  604. package/dist/sprint-execution-service-2B7WHL5L.js +311 -0
  605. package/dist/sprint-manager-IDQUDNQI.js +91 -0
  606. package/dist/sqlite-wrapper-UDWCTNLJ.js +17 -0
  607. package/dist/stale-cleanup-orchestrator-XWXV7KCZ.js +62 -0
  608. package/dist/storage-access-F6ALDN4S.js +22 -0
  609. package/dist/synthesis-XD6EDVHF.js +185 -0
  610. package/dist/task-classifier-LNLXSHOM.js +494 -0
  611. package/dist/task-list-fast-PTMA4LUC.js +147 -0
  612. package/dist/task-manager-XAT7GOWB.js +93 -0
  613. package/dist/task-splitter-U7DJ7W6A.js +79 -0
  614. package/dist/task-type-detector-OLVOMXZO.js +21 -0
  615. package/dist/task-type-resolver-KKNQYSB4.js +42 -0
  616. package/dist/telemetry-5HWBBXLX.js +131 -0
  617. package/dist/telemetry-health-tracker-DMSSGBZ2.js +11 -0
  618. package/dist/telemetry-path-resolver-7ICSG276.js +28 -0
  619. package/dist/telemetry-reliability-XUOZNZZ6.js +125 -0
  620. package/dist/token-estimator-MEQUL3EJ.js +37 -0
  621. package/dist/transports-KNSSV2V4.js +255 -0
  622. package/dist/unified-cost-tracker-4TFRBVPR.js +35 -0
  623. package/dist/unified-state-cleanup-LJPF2BOW.js +276 -0
  624. package/dist/universal-cost-calculator-BAJV35GA.js +42 -0
  625. package/dist/user-agents-GHUGCSKN.js +22 -0
  626. package/dist/variant-delivery-state-KLRNG6XA.js +33 -0
  627. package/dist/variant-state-cleanup-MZGGLQAJ.js +280 -0
  628. package/dist/variant-success-PJXWE3ZV.js +12 -0
  629. package/dist/variant-worker-KUWKBLAH.js +4196 -0
  630. package/dist/variant-worker.js +24 -0
  631. package/dist/variants-JE2FSAQS.js +233 -0
  632. package/dist/verification-toolchains-V24UHW6Q.js +28 -0
  633. package/dist/verify-commands-H3DTCSGI.js +37 -0
  634. package/dist/warning-EGQGUUIO.js +12 -0
  635. package/dist/work-edge-RWEDWJZF.js +49 -0
  636. package/dist/work-item-writer-WHAVZXAY.js +19 -0
  637. package/dist/worker-7SA2VS2Y.js +1435 -0
  638. package/dist/worker.js +19 -0
  639. package/dist/worktree-metrics-3DFUYVYE.js +26 -0
  640. package/dist/writeback-VZKHYHSN.js +44 -0
  641. package/docs/CLI_REFERENCE.md +7042 -0
  642. package/docs/PROVIDER_SETUP.md +1570 -0
  643. package/docs/README.md +96 -0
  644. package/docs/TROUBLESHOOTING.md +2232 -0
  645. package/docs/getting-started/QUICK_START.md +294 -0
  646. package/docs/getting-started/README.md +188 -0
  647. package/docs/getting-started/SETUP.md +52 -0
  648. package/docs/reference/AGENT_CONTEXT.md +38 -0
  649. package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
  650. package/docs/reference/README.md +381 -0
  651. package/docs/reference/SECURITY.md +262 -0
  652. package/integrations/bb-plugin-poetic/README.md +362 -0
  653. package/integrations/bb-plugin-poetic/app.css +341 -0
  654. package/integrations/bb-plugin-poetic/app.tsx +5059 -0
  655. package/integrations/bb-plugin-poetic/package.json +45 -0
  656. package/integrations/bb-plugin-poetic/server.ts +444 -0
  657. package/integrations/bb-plugin-poetic/src/adapter.ts +3312 -0
  658. package/integrations/bb-plugin-poetic/src/backlog-authoring-model.ts +150 -0
  659. package/integrations/bb-plugin-poetic/src/backlog-authoring-schema.ts +355 -0
  660. package/integrations/bb-plugin-poetic/src/backlog-authoring-service.ts +419 -0
  661. package/integrations/bb-plugin-poetic/src/backlog-authoring-view.ts +1026 -0
  662. package/integrations/bb-plugin-poetic/src/competition-defaults-schema.ts +122 -0
  663. package/integrations/bb-plugin-poetic/src/competition-defaults-service.ts +105 -0
  664. package/integrations/bb-plugin-poetic/src/competition-defaults-view.ts +138 -0
  665. package/integrations/bb-plugin-poetic/src/contract.ts +615 -0
  666. package/integrations/bb-plugin-poetic/src/finalize-model.ts +205 -0
  667. package/integrations/bb-plugin-poetic/src/finalize-schema.ts +158 -0
  668. package/integrations/bb-plugin-poetic/src/finalize-service.ts +382 -0
  669. package/integrations/bb-plugin-poetic/src/finalize-view.ts +159 -0
  670. package/integrations/bb-plugin-poetic/src/judge-operations-readback.ts +303 -0
  671. package/integrations/bb-plugin-poetic/src/judge-operations-schema.ts +33 -0
  672. package/integrations/bb-plugin-poetic/src/judge-operations-view.ts +459 -0
  673. package/integrations/bb-plugin-poetic/src/model.ts +1302 -0
  674. package/integrations/bb-plugin-poetic/src/monitor-service.ts +233 -0
  675. package/integrations/bb-plugin-poetic/src/panel-read-ux.ts +97 -0
  676. package/integrations/bb-plugin-poetic/src/patch-preview-schema.ts +166 -0
  677. package/integrations/bb-plugin-poetic/src/patch-preview-service.ts +480 -0
  678. package/integrations/bb-plugin-poetic/src/patch-preview-view.ts +109 -0
  679. package/integrations/bb-plugin-poetic/src/planning-readback.ts +204 -0
  680. package/integrations/bb-plugin-poetic/src/planning-service.ts +594 -0
  681. package/integrations/bb-plugin-poetic/src/planning-workspace-schema.ts +95 -0
  682. package/integrations/bb-plugin-poetic/src/planning-workspace.ts +323 -0
  683. package/integrations/bb-plugin-poetic/src/poll-handoff.ts +136 -0
  684. package/integrations/bb-plugin-poetic/src/project-target-server.ts +21 -0
  685. package/integrations/bb-plugin-poetic/src/project-target.ts +45 -0
  686. package/integrations/bb-plugin-poetic/src/reference-index.ts +192 -0
  687. package/integrations/bb-plugin-poetic/src/repository-schema.ts +30 -0
  688. package/integrations/bb-plugin-poetic/src/result-explorer-view.ts +597 -0
  689. package/integrations/bb-plugin-poetic/src/result-readback-model.ts +163 -0
  690. package/integrations/bb-plugin-poetic/src/result-readback-schema.ts +319 -0
  691. package/integrations/bb-plugin-poetic/src/result-readback-service.ts +333 -0
  692. package/integrations/bb-plugin-poetic/src/run-page-view.ts +177 -0
  693. package/integrations/bb-plugin-poetic/src/setup-config-schema.ts +291 -0
  694. package/integrations/bb-plugin-poetic/src/setup-config-service.ts +590 -0
  695. package/integrations/bb-plugin-poetic/src/setup-config-view.ts +413 -0
  696. package/integrations/bb-plugin-poetic/src/sprint-close-model.ts +150 -0
  697. package/integrations/bb-plugin-poetic/src/sprint-close-schema.ts +136 -0
  698. package/integrations/bb-plugin-poetic/src/sprint-close-service.ts +341 -0
  699. package/integrations/bb-plugin-poetic/src/sprint-close-view.ts +116 -0
  700. package/integrations/bb-plugin-poetic/src/sprint-composition-model.ts +714 -0
  701. package/integrations/bb-plugin-poetic/src/sprint-composition-readback.ts +231 -0
  702. package/integrations/bb-plugin-poetic/src/sprint-composition-schema.ts +601 -0
  703. package/integrations/bb-plugin-poetic/src/sprint-composition-service.ts +775 -0
  704. package/integrations/bb-plugin-poetic/src/sprint-composition-view.ts +1221 -0
  705. package/integrations/bb-plugin-poetic/src/task-authoring-model.ts +567 -0
  706. package/integrations/bb-plugin-poetic/src/task-authoring-schema.ts +635 -0
  707. package/integrations/bb-plugin-poetic/src/task-authoring-service.ts +842 -0
  708. package/integrations/bb-plugin-poetic/src/task-authoring-view.ts +1227 -0
  709. package/integrations/bb-plugin-poetic/src/task-detail-readback.ts +56 -0
  710. package/integrations/bb-plugin-poetic/src/task-detail-schema.ts +144 -0
  711. package/integrations/bb-plugin-poetic/src/task-navigation.ts +446 -0
  712. package/integrations/bb-plugin-poetic/src/workbench-route.ts +74 -0
  713. package/integrations/bb-plugin-poetic/tests/host-contract.test.ts +773 -0
  714. package/integrations/bb-plugin-poetic/tsconfig.json +18 -0
  715. package/integrations/bb-plugin-poetic/types/PROVENANCE.json +52 -0
  716. package/integrations/bb-plugin-poetic/types/bb-plugin-sdk-app.d.ts +1444 -0
  717. package/integrations/bb-plugin-poetic/types/bb-plugin-sdk.d.ts +13030 -0
  718. package/integrations/bb-plugin-poetic/vitest.host.config.ts +71 -0
  719. package/npm-shrinkwrap.json +4950 -0
  720. package/package.json +331 -0
  721. package/schemas/README.md +80 -0
  722. package/schemas/config-v1.schema.json +136 -0
  723. package/schemas/execution-config.schema.json +47 -0
  724. package/schemas/judge-scoring.schema.json +370 -0
  725. package/schemas/poetic.config.schema.json +2214 -0
  726. package/schemas/provider-config.schema.json +203 -0
  727. package/schemas/telemetry-config.schema.json +79 -0
  728. package/schemas/user-preferences.schema.json +141 -0
  729. package/scripts/assert-node-runtime.mjs +140 -0
  730. package/scripts/preflight-native.mjs +49 -0
  731. package/scripts/preinstall-node-check.mjs +78 -0
  732. package/scripts/setup-git-hooks.mjs +24 -0
  733. package/scripts/sync.sh +2722 -0
  734. package/scripts/write-node-launcher.sh +108 -0
  735. package/src/resources/gemini/slash-packs/default/plan.toml +15 -0
  736. package/src/resources/gemini/slash-packs/default/summary.toml +16 -0
  737. package/src/resources/gemini/slash-packs/default/tests.toml +16 -0
  738. package/templates/.poetic/README.md +37 -0
  739. package/templates/.poetic/agents/README.md +296 -0
  740. package/templates/.poetic/agents/api-documenter.md +147 -0
  741. package/templates/.poetic/agents/backend-architect.md +31 -0
  742. package/templates/.poetic/agents/code-reviewer.md +157 -0
  743. package/templates/.poetic/agents/data-scientist.md +179 -0
  744. package/templates/.poetic/agents/database-optimizer.md +145 -0
  745. package/templates/.poetic/agents/debugger.md +31 -0
  746. package/templates/.poetic/agents/deployment-engineer.md +164 -0
  747. package/templates/.poetic/agents/devops-troubleshooter.md +139 -0
  748. package/templates/.poetic/agents/frontend-developer.md +150 -0
  749. package/templates/.poetic/agents/javascript-pro.md +36 -0
  750. package/templates/.poetic/agents/performance-engineer.md +151 -0
  751. package/templates/.poetic/agents/python-pro.md +137 -0
  752. package/templates/.poetic/agents/test-automator.md +147 -0
  753. package/templates/.poetic/agents/typescript-pro.md +34 -0
  754. package/templates/.poetic/config/poetic.config.jsonc +69 -0
  755. package/templates/.poetic/config/project-context.template.json +6 -0
  756. package/templates/.poetic/config/task-type-aliases.presets/kanban.yaml +14 -0
  757. package/templates/.poetic/config/task-type-aliases.presets/scrum.yaml +17 -0
  758. package/templates/.poetic/config/task-type-aliases.presets/xp.yaml +12 -0
  759. package/templates/.poetic/config/task-type-aliases.yaml +28 -0
  760. package/templates/.poetic/gitignore.template +55 -0
  761. package/templates/.poetic/task-types/analysis.yaml +40 -0
  762. package/templates/.poetic/task-types/architecture.yaml +38 -0
  763. package/templates/.poetic/task-types/doc.yaml +35 -0
  764. package/templates/.poetic/task-types/feature.yaml +23 -0
  765. package/templates/.poetic/task-types/general.yaml +6 -0
  766. package/templates/.poetic/task-types/security.yaml +39 -0
  767. package/templates/AGENTS.template.md +99 -0
  768. package/templates/CLAUDE.template.md +1 -0
  769. package/templates/GEMINI.template.md +1 -0
  770. package/templates/builtin-workflows/code-review.yaml +73 -0
  771. package/templates/builtin-workflows/compete-streak.yaml +78 -0
  772. package/templates/builtin-workflows/hello-verify.yaml +10 -0
  773. package/templates/builtin-workflows/judge-regression.yaml +114 -0
  774. package/templates/builtin-workflows/skills/code-review/SKILL.md +60 -0
  775. package/templates/builtin-workflows/skills/hello-verify/SKILL.md +6 -0
  776. package/templates/guard-kit/GUARD_SETUP.md.template +255 -0
  777. package/templates/guard-kit/check.mjs.template +777 -0
  778. package/templates/guard-kit/config.json.template +6 -0
  779. package/templates/guard-kit/poetic-guard.yml.template +189 -0
  780. package/templates/profiles/README.md +56 -0
  781. package/templates/profiles/frontier-claude.json +27 -0
  782. package/templates/profiles/frontier-codex.json +26 -0
@@ -0,0 +1,1581 @@
1
+ import {
2
+ killTmuxSessionWithPaneFallback,
3
+ markTmuxSessionOrphaned,
4
+ recordTmuxSessionPanePid,
5
+ registerTmuxSession,
6
+ unregisterTmuxSession
7
+ } from "./chunk-4CUY7AFY.js";
8
+ import {
9
+ CircuitBreakerError,
10
+ createCircuitBreakerOptions,
11
+ executeWithCircuitBreaker
12
+ } from "./chunk-MWK5UZQ3.js";
13
+ import {
14
+ shouldExcludeFile
15
+ } from "./chunk-NS33V3IM.js";
16
+ import {
17
+ DEFAULT_TIMEOUT,
18
+ POETIC_PROCESS_GROUP_OWNER_ENV,
19
+ TMUX_COMPLETION_SIGNAL_GRACE_MS,
20
+ acquireProcessSlot,
21
+ assertProviderBypassHasBoundaryProof,
22
+ createLogger,
23
+ getProcessLifecycleManager,
24
+ globalProcessLimiter,
25
+ providerExecutionTransportStreamOptions,
26
+ resolveProviderProcessGroupOwnership
27
+ } from "./chunk-PFTQBXS6.js";
28
+ import {
29
+ evaluateCpuTimeProgressStreak,
30
+ readCpuTimeSeconds,
31
+ resolveIdleTimeoutsMs
32
+ } from "./chunk-E3NTPHEO.js";
33
+ import {
34
+ getProviderRuntimeQuirks
35
+ } from "./chunk-FC23CTXV.js";
36
+ import {
37
+ createRetryOptions,
38
+ withRetry
39
+ } from "./chunk-CKNX3TTP.js";
40
+ import {
41
+ ModelInvocationsDB,
42
+ ensurePendingInvocationCostEnrichment,
43
+ generateInvocationId,
44
+ resolveInvocationRegistryVersion,
45
+ resolveInvocationsDbPath
46
+ } from "./chunk-GKN3HMN4.js";
47
+ import {
48
+ JsonParseError,
49
+ safeJsonParse
50
+ } from "./chunk-S54MKU6V.js";
51
+ import {
52
+ isSandboxAuthorityEnvVar
53
+ } from "./chunk-6TZJRKNW.js";
54
+ import {
55
+ wrapWithSandbox
56
+ } from "./chunk-PCAGC5MR.js";
57
+ import {
58
+ execGit
59
+ } from "./chunk-KNDYMVWN.js";
60
+ import {
61
+ ProviderExecutionError,
62
+ providerExecutionErrorStreamOptions
63
+ } from "./chunk-LUVKFFWR.js";
64
+ import {
65
+ quotePosixShellArg
66
+ } from "./chunk-N5DX4JAK.js";
67
+ import {
68
+ ProviderRegistry
69
+ } from "./chunk-AT4TNPWW.js";
70
+ import {
71
+ resolvePoeticRoot
72
+ } from "./chunk-LEIIWPWQ.js";
73
+ import {
74
+ debugLog,
75
+ emitWarning
76
+ } from "./chunk-EJGCZGUF.js";
77
+ import {
78
+ POETIC_ACTIVE_TASK_ID,
79
+ POETIC_MOCK_PROVIDERS,
80
+ POETIC_TIMEOUT_MS,
81
+ POETIC_WORKER_VARIANT,
82
+ readEnv
83
+ } from "./chunk-5DLKYTQX.js";
84
+
85
+ // src/core/providers/shared/execution-transport.ts
86
+ import { randomBytes } from "crypto";
87
+ import * as fs from "fs/promises";
88
+ import { open as fsOpen } from "fs/promises";
89
+ import * as path from "path";
90
+ import { StringDecoder } from "string_decoder";
91
+ import { execa } from "execa";
92
+ var transportLogger = createLogger("ExecutionTransport");
93
+ var VALID_EXECUTION_TRANSPORT_MODES = [
94
+ "auto",
95
+ "headless",
96
+ "tmux-exec",
97
+ "interactive"
98
+ ];
99
+ function isTmuxExecStatusAuthoritative(input) {
100
+ return input.statusPresent && !input.sessionAlive;
101
+ }
102
+ function parseExecutionTransportMode(value) {
103
+ if (!value) return void 0;
104
+ const normalized = value.trim().toLowerCase();
105
+ if (normalized === "interactive") {
106
+ return "tmux-exec";
107
+ }
108
+ if (VALID_EXECUTION_TRANSPORT_MODES.includes(normalized)) {
109
+ return normalized;
110
+ }
111
+ return void 0;
112
+ }
113
+ var tmuxAvailabilityProbe;
114
+ async function isTmuxAvailable() {
115
+ if (tmuxAvailabilityProbe === void 0) {
116
+ tmuxAvailabilityProbe = (async () => {
117
+ try {
118
+ const result = await execa("tmux", ["-V"], { reject: false });
119
+ return result.exitCode === 0;
120
+ } catch {
121
+ return false;
122
+ }
123
+ })();
124
+ }
125
+ return tmuxAvailabilityProbe;
126
+ }
127
+ function resolveRequestedTransportMode(options) {
128
+ const providerKey = options.provider?.trim().toUpperCase().replace(/[^A-Z0-9_]/g, "_");
129
+ const envRequested = (providerKey ? parseExecutionTransportMode(options.env?.[`POETIC_${providerKey}_EXECUTION_TRANSPORT`]) : void 0) ?? parseExecutionTransportMode(options.env?.POETIC_PROVIDER_EXECUTION_TRANSPORT) ?? parseExecutionTransportMode(options.env?.POETIC_EXECUTION_TRANSPORT);
130
+ const requested = options.requested ?? envRequested ?? options.configured ?? "headless";
131
+ return requested === "interactive" ? "tmux-exec" : requested;
132
+ }
133
+ async function resolveExecutionTransportMode(options) {
134
+ const normalizedRequested = resolveRequestedTransportMode({
135
+ requested: options.requested,
136
+ configured: options.configured,
137
+ env: options.env,
138
+ provider: options.provider
139
+ });
140
+ if (normalizedRequested === "headless") return "headless";
141
+ const available = await (options.tmuxAvailable ?? isTmuxAvailable)();
142
+ if (available) return "tmux-exec";
143
+ if (normalizedRequested === "tmux-exec") {
144
+ throw new ProviderExecutionError(
145
+ "tmux-exec provider execution transport requires tmux, but tmux was not found on PATH.",
146
+ { retryable: false, reason: "tmux_exec_transport_unavailable" }
147
+ );
148
+ }
149
+ return "headless";
150
+ }
151
+ async function resolveProviderTransportDecision(options) {
152
+ const quirks = getProviderRuntimeQuirks(options.provider);
153
+ const requestedMode = resolveRequestedTransportMode({
154
+ requested: options.requested,
155
+ configured: options.configured,
156
+ env: options.env,
157
+ provider: options.provider
158
+ });
159
+ if (options.forceHeadlessReason) {
160
+ const requested = requestedMode === "headless" ? "headless" : "tmux-exec";
161
+ return {
162
+ resolved: "headless",
163
+ requested,
164
+ downgradeReason: requested === "tmux-exec" ? options.forceHeadlessReason : void 0
165
+ };
166
+ }
167
+ const support = quirks?.tmuxExecSupport ?? "none";
168
+ if (support === "none") {
169
+ if (requestedMode === "tmux-exec") {
170
+ return {
171
+ resolved: "headless",
172
+ requested: "tmux-exec",
173
+ downgradeReason: `${options.provider} is not validated for tmux-exec under a pane pty; using headless`
174
+ };
175
+ }
176
+ return { resolved: "headless", requested: "headless" };
177
+ }
178
+ const resolved = await resolveExecutionTransportMode({
179
+ requested: options.requested,
180
+ configured: options.configured,
181
+ env: options.env,
182
+ provider: options.provider,
183
+ tmuxAvailable: options.tmuxAvailable
184
+ });
185
+ if (resolved !== "tmux-exec") {
186
+ return { resolved, requested: resolved };
187
+ }
188
+ if (support === "read-only") {
189
+ const isReadOnly = options.executionIntent === "analysis" || options.readOnlyWorkingDir === true;
190
+ if (!isReadOnly) {
191
+ return {
192
+ resolved: "headless",
193
+ requested: "tmux-exec",
194
+ downgradeReason: `${options.provider} supports tmux-exec only for analysis/read-only runs; using headless for this write-intent run`
195
+ };
196
+ }
197
+ }
198
+ return { resolved: "tmux-exec", requested: "tmux-exec" };
199
+ }
200
+ function reportTransportDecision(provider, decision, debug) {
201
+ if (decision.downgradeReason) {
202
+ transportLogger.warn(
203
+ `[${provider}] execution transport downgraded: ${decision.downgradeReason}`,
204
+ {
205
+ provider,
206
+ requested: decision.requested,
207
+ resolved: decision.resolved
208
+ }
209
+ );
210
+ return;
211
+ }
212
+ debug?.(`[${provider}] execution transport resolved to ${decision.resolved}`, {
213
+ provider,
214
+ resolved: decision.resolved
215
+ });
216
+ }
217
+ async function selectProviderExecutor(options) {
218
+ const decision = await resolveProviderTransportDecision(options);
219
+ options.onDecision?.(decision);
220
+ const execute = decision.resolved === "tmux-exec" ? executeProviderCommandTmuxExec : options.headless;
221
+ return { execute, decision };
222
+ }
223
+ function sessionName(providerName) {
224
+ const safeProvider = providerName.toLowerCase().replace(/[^a-z0-9_-]/g, "-").replace(/^-+|-+$/g, "").slice(0, 24);
225
+ return `poetic-${safeProvider || "provider"}-${randomBytes(4).toString("hex")}`;
226
+ }
227
+ async function writePromptFile(tmpDir, input) {
228
+ if (input === void 0) return void 0;
229
+ const file = path.join(tmpDir, "prompt.txt");
230
+ await fs.writeFile(file, input, { mode: 384 });
231
+ return file;
232
+ }
233
+ async function writeEnvFile(tmpDir, env) {
234
+ const ownership = resolveProviderProcessGroupOwnership();
235
+ const paneEnv = {
236
+ ...commandEnvironment(env),
237
+ [POETIC_PROCESS_GROUP_OWNER_ENV]: ownership.owner
238
+ };
239
+ const lines = Object.entries(commandEnvironment(paneEnv)).filter(
240
+ (entry) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(entry[0]) && typeof entry[1] === "string"
241
+ ).map(([key, value]) => `export ${key}=${quotePosixShellArg(value)}`);
242
+ const file = path.join(tmpDir, "env.sh");
243
+ await fs.writeFile(file, lines.length > 0 ? `${lines.join("\n")}
244
+ ` : "", { mode: 384 });
245
+ return file;
246
+ }
247
+ function resolveCommandName(command) {
248
+ const posix2 = path.posix.basename(command);
249
+ const win322 = path.win32.basename(command);
250
+ const basename = posix2.length <= win322.length ? posix2 : win322;
251
+ return basename.replace(/\.(exe|cmd|bat|ps1)$/i, "").toLowerCase().replace(/[^a-z0-9_-]/g, "_");
252
+ }
253
+ function commandEnvironment(env) {
254
+ const source = env ?? process.env;
255
+ const next = { ...source };
256
+ for (const key of Object.keys(next)) {
257
+ if (isSandboxAuthorityEnvVar(key)) {
258
+ delete next[key];
259
+ }
260
+ }
261
+ return next;
262
+ }
263
+ function buildTmuxShellCommand(options) {
264
+ const argv = [options.command, ...options.args].map(quotePosixShellArg).join(" ");
265
+ const input = options.promptFile ? ` < ${quotePosixShellArg(options.promptFile)}` : " < /dev/null";
266
+ const output = ` > ${quotePosixShellArg(options.stdoutFile)} 2> ${quotePosixShellArg(options.stderrFile)}`;
267
+ const innerScript = [
268
+ `. ${quotePosixShellArg(options.envFile)}`,
269
+ `rm -f ${quotePosixShellArg(options.envFile)}`,
270
+ `exec ${argv}${input}${output}`
271
+ ].join("; ");
272
+ const runner = `env -i sh -c ${quotePosixShellArg(innerScript)}`;
273
+ return [
274
+ runner,
275
+ "status=$?",
276
+ `printf '%s' "$status" > ${quotePosixShellArg(options.statusFile)}`,
277
+ 'exit "$status"'
278
+ ].join("; ");
279
+ }
280
+ async function readTextIfPresent(file) {
281
+ try {
282
+ return await fs.readFile(file, "utf8");
283
+ } catch (error) {
284
+ if (error.code === "ENOENT") return "";
285
+ throw error;
286
+ }
287
+ }
288
+ var OutputFileTail = class {
289
+ constructor(file) {
290
+ this.file = file;
291
+ }
292
+ file;
293
+ offset = 0;
294
+ decoder = new StringDecoder("utf8");
295
+ /** Read any bytes appended since the last call (bytes + decoded text). */
296
+ async read() {
297
+ let handle;
298
+ try {
299
+ handle = await fsOpen(this.file, "r");
300
+ const { size } = await handle.stat();
301
+ if (size <= this.offset) {
302
+ if (size < this.offset) {
303
+ this.offset = 0;
304
+ this.decoder = new StringDecoder("utf8");
305
+ }
306
+ return { bytes: Buffer.alloc(0), text: "" };
307
+ }
308
+ const length = size - this.offset;
309
+ const buffer = Buffer.allocUnsafe(length);
310
+ const { bytesRead } = await handle.read(buffer, 0, length, this.offset);
311
+ this.offset += bytesRead;
312
+ const bytes = Buffer.from(buffer.subarray(0, bytesRead));
313
+ const text = this.decoder.write(bytes);
314
+ return { bytes, text };
315
+ } catch (error) {
316
+ if (error.code === "ENOENT") {
317
+ return { bytes: Buffer.alloc(0), text: "" };
318
+ }
319
+ throw error;
320
+ } finally {
321
+ await handle?.close().catch(() => {
322
+ });
323
+ }
324
+ }
325
+ /**
326
+ * Flush incomplete multibyte sequence as presentation text only.
327
+ * Authoritative raw observers already received those bytes on the read that
328
+ * advanced the offset — do not re-deliver them as raw chunks.
329
+ */
330
+ flushText() {
331
+ return this.decoder.end();
332
+ }
333
+ };
334
+ function deliverRawBytes(observer, bytes) {
335
+ if (!observer || bytes.length === 0) {
336
+ return;
337
+ }
338
+ try {
339
+ observer(bytes);
340
+ } catch {
341
+ }
342
+ }
343
+ function sleep(ms) {
344
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
345
+ }
346
+ function parseTmuxPanePid(value) {
347
+ const text = value?.trim();
348
+ if (!text || !/^\d+$/.test(text)) return void 0;
349
+ const pid = Number.parseInt(text, 10);
350
+ return Number.isInteger(pid) && pid > 0 ? pid : void 0;
351
+ }
352
+ function firstUsefulDiagnosticLine(text) {
353
+ return text.split(/\r?\n/).map((line) => line.trim()).find((line) => line.length > 0) ?? "no error output";
354
+ }
355
+ function tmuxTransportStreamOptions(fullStdout, fullStderr, options) {
356
+ return providerExecutionTransportStreamOptions(fullStdout, fullStderr, {
357
+ maxPublicLength: options?.maxPublicLength ?? 4096
358
+ });
359
+ }
360
+ function throwIfTmuxNonZeroExit(options, result, fullStreams) {
361
+ if (result.exitCode === 0) {
362
+ return;
363
+ }
364
+ const streams = tmuxTransportStreamOptions(
365
+ fullStreams?.stdout ?? result.stdout,
366
+ fullStreams?.stderr ?? result.stderr,
367
+ { maxPublicLength: 4096 }
368
+ );
369
+ const diagnostic = firstUsefulDiagnosticLine(streams.stderr || streams.stdout || "");
370
+ throw new ProviderExecutionError(
371
+ `${options.metadata.name} CLI exited with code ${result.exitCode}: ${diagnostic}`,
372
+ {
373
+ retryable: false,
374
+ exitCode: result.exitCode,
375
+ reason: "non_zero_exit",
376
+ ...streams
377
+ }
378
+ );
379
+ }
380
+ async function tmuxSessionExists(session, env) {
381
+ const result = await execa("tmux", ["has-session", "-t", session], {
382
+ env: tmuxClientEnv(env),
383
+ reject: false,
384
+ timeout: 5e3
385
+ }).catch(() => void 0);
386
+ return result?.exitCode === 0;
387
+ }
388
+ async function killTmuxSession(params) {
389
+ return killTmuxSessionWithPaneFallback({
390
+ session: params.session,
391
+ tmuxEnv: params.env,
392
+ panePid: params.panePid,
393
+ timeoutMs: 1e4
394
+ });
395
+ }
396
+ async function registerTmuxProcessLifecycle(params) {
397
+ const plm = getProcessLifecycleManager();
398
+ if (!plm) return void 0;
399
+ try {
400
+ return await plm.registerProcessWithOptions({
401
+ completionPromise: params.completionPromise,
402
+ terminateFn: async () => {
403
+ await params.terminate();
404
+ },
405
+ verificationFn: async () => true,
406
+ processType: "local",
407
+ timeoutMs: 0,
408
+ metadata: {
409
+ provider: params.options.metadata.name,
410
+ command: params.options.command,
411
+ args: params.options.args,
412
+ cwd: params.options.workingDir,
413
+ transport: "tmux-exec",
414
+ session: params.session,
415
+ ...params.panePid !== void 0 ? { panePid: params.panePid } : {},
416
+ startTime: Date.now()
417
+ }
418
+ });
419
+ } catch (error) {
420
+ transportLogger.warn("[tmux-exec] ProcessLifecycleManager registration failed", {
421
+ provider: params.options.metadata.name,
422
+ error: error instanceof Error ? error.message : String(error)
423
+ });
424
+ return void 0;
425
+ }
426
+ }
427
+ function tmuxClientEnv(env) {
428
+ const source = env ?? process.env;
429
+ const allowList = ["PATH", "HOME", "TMUX", "TMUX_TMPDIR", "TMPDIR", "USER", "LOGNAME", "TERM"];
430
+ const minimal = {};
431
+ for (const key of allowList) {
432
+ const value = source[key];
433
+ if (typeof value === "string") {
434
+ minimal[key] = value;
435
+ }
436
+ }
437
+ return minimal;
438
+ }
439
+ async function removeTmpDir(tmpDir) {
440
+ await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => {
441
+ });
442
+ }
443
+ async function executeProviderCommandTmuxExec(options) {
444
+ const session = sessionName(options.metadata.id ?? options.metadata.name);
445
+ const timeout = options.timeout ?? DEFAULT_TIMEOUT;
446
+ const idleTimeouts = resolveIdleTimeoutsMs(options.command, options.args, timeout, {
447
+ idleWarnMs: options.idleWarnMs,
448
+ idleKillMs: options.idleKillMs
449
+ });
450
+ const tmpDir = await fs.mkdtemp(path.join("/var/tmp", "poetic-tmux-exec-"));
451
+ const stdoutFile = path.join(tmpDir, "stdout.log");
452
+ const stderrFile = path.join(tmpDir, "stderr.log");
453
+ const statusFile = path.join(tmpDir, "status");
454
+ let shellCommand;
455
+ try {
456
+ const promptFile = await writePromptFile(tmpDir, options.input);
457
+ const envFile = await writeEnvFile(tmpDir, options.env);
458
+ await fs.writeFile(stdoutFile, "");
459
+ await fs.writeFile(stderrFile, "");
460
+ const sandboxed = options.disablePoeticSandbox === true ? { command: options.command, args: options.args, sandboxed: false } : wrapWithSandbox({
461
+ workingDir: options.workingDir,
462
+ command: options.command,
463
+ args: options.args,
464
+ providerName: options.metadata.name,
465
+ extraWritePaths: options.extraWritePaths,
466
+ readOnlyWorkingDir: options.readOnlyWorkingDir,
467
+ // Provider execution path (tmux transport), so the same
468
+ // write-boundary requirement as base-runner applies. Read-only runs
469
+ // still pass readOnlyWorkingDir and stay exempt.
470
+ requiresBoundaryForWrites: true,
471
+ env: options.env,
472
+ providerId: options.metadata.id ?? resolveCommandName(options.command)
473
+ });
474
+ assertProviderBypassHasBoundaryProof(
475
+ options.metadata,
476
+ options.args,
477
+ sandboxed,
478
+ options.providerInternalSandboxBypass
479
+ );
480
+ shellCommand = buildTmuxShellCommand({
481
+ command: sandboxed.command,
482
+ args: sandboxed.args,
483
+ envFile,
484
+ promptFile,
485
+ stdoutFile,
486
+ stderrFile,
487
+ statusFile
488
+ });
489
+ } catch (error) {
490
+ await removeTmpDir(tmpDir);
491
+ throw error;
492
+ }
493
+ const readFullTerminalStdout = () => readTextIfPresent(stdoutFile);
494
+ const readFullTerminalStderr = () => readTextIfPresent(stderrFile);
495
+ const startedAt = Date.now();
496
+ let aborted = false;
497
+ let stdoutTail;
498
+ let stderrTail;
499
+ let firstOutputSeen = false;
500
+ let completionSignalSeen = false;
501
+ let completionSignalSeenAt = null;
502
+ let exitedForCompletionSignal = false;
503
+ let lastActivityAt = startedAt;
504
+ const completionSignalGraceMs = Math.max(
505
+ 0,
506
+ options.completionSignalGraceMs ?? TMUX_COMPLETION_SIGNAL_GRACE_MS
507
+ );
508
+ let tmuxPanePid;
509
+ let lastCpuTimeSeconds;
510
+ let consecutiveBusyCpuPolls = 0;
511
+ const abort = async () => {
512
+ aborted = true;
513
+ return killTmuxSession({ session, env: options.env, panePid: tmuxPanePid });
514
+ };
515
+ const abortListener = () => {
516
+ void abort();
517
+ };
518
+ const limiterDescription = `${options.metadata.name} tmux-exec provider command: ${options.command}`.trim();
519
+ let reservation;
520
+ try {
521
+ stdoutTail = new OutputFileTail(stdoutFile);
522
+ stderrTail = new OutputFileTail(stderrFile);
523
+ if (options.abortSignal?.aborted) {
524
+ throw new ProviderExecutionError(`[${options.metadata.name}] Provider execution aborted`, {
525
+ retryable: false,
526
+ reason: "abort"
527
+ });
528
+ }
529
+ const reservationOrWait = acquireProcessSlot(limiterDescription, options.abortSignal);
530
+ reservation = reservationOrWait instanceof Promise ? await reservationOrWait : reservationOrWait;
531
+ } catch (error) {
532
+ await removeTmpDir(tmpDir);
533
+ throw error;
534
+ }
535
+ let activeReservationId = typeof reservation === "number" ? reservation : void 0;
536
+ const reservationRenewTimer = activeReservationId !== void 0 ? setInterval(() => {
537
+ if (activeReservationId === void 0) return;
538
+ if (globalProcessLimiter.renewReservation(activeReservationId)) return;
539
+ const replacement = globalProcessLimiter.reserve();
540
+ activeReservationId = typeof replacement === "number" ? replacement : void 0;
541
+ }, 1e4) : void 0;
542
+ reservationRenewTimer?.unref?.();
543
+ const releaseReservation = () => {
544
+ if (reservationRenewTimer) {
545
+ clearInterval(reservationRenewTimer);
546
+ }
547
+ if (activeReservationId !== void 0) {
548
+ globalProcessLimiter.cancelReservation(activeReservationId);
549
+ activeReservationId = void 0;
550
+ }
551
+ };
552
+ options.abortSignal?.addEventListener("abort", abortListener, { once: true });
553
+ let tmuxPlmProcessId;
554
+ let registryPersisted = false;
555
+ let sessionStarted = false;
556
+ let settleTmuxPlmCompletion;
557
+ try {
558
+ await registerTmuxSession(session, {
559
+ env: options.env,
560
+ category: "variant",
561
+ type: "spawned",
562
+ provider: options.metadata.id ?? options.metadata.name,
563
+ tmpDir
564
+ });
565
+ registryPersisted = true;
566
+ if (aborted || options.abortSignal?.aborted) {
567
+ throw new ProviderExecutionError(`[${options.metadata.name}] Provider execution aborted`, {
568
+ retryable: false,
569
+ reason: "abort",
570
+ ...tmuxTransportStreamOptions(
571
+ await readFullTerminalStdout(),
572
+ await readFullTerminalStderr()
573
+ )
574
+ });
575
+ }
576
+ options.beforeSpawn?.();
577
+ const tmuxLaunch = await execa(
578
+ "tmux",
579
+ [
580
+ "new-session",
581
+ "-d",
582
+ "-P",
583
+ "-F",
584
+ "#{pane_pid}",
585
+ "-s",
586
+ session,
587
+ "-c",
588
+ options.workingDir,
589
+ shellCommand
590
+ ],
591
+ {
592
+ // Launch the tmux CLIENT with a minimal env. Provider secrets travel
593
+ // ONLY through the 0600 env file sourced inside the pane; handing them
594
+ // to the client would leak them into the tmux server/session env if
595
+ // this call starts the server.
596
+ env: tmuxClientEnv(options.env),
597
+ cancelSignal: options.abortSignal,
598
+ reject: true
599
+ }
600
+ );
601
+ sessionStarted = true;
602
+ tmuxPanePid = parseTmuxPanePid(tmuxLaunch.stdout);
603
+ await recordTmuxSessionPanePid(session, tmuxPanePid);
604
+ const tmuxPlmCompletion = new Promise((resolve2, reject) => {
605
+ settleTmuxPlmCompletion = { resolve: resolve2, reject, settled: false };
606
+ });
607
+ tmuxPlmCompletion.catch(() => {
608
+ });
609
+ tmuxPlmProcessId = await registerTmuxProcessLifecycle({
610
+ options,
611
+ session,
612
+ panePid: tmuxPanePid,
613
+ completionPromise: tmuxPlmCompletion,
614
+ terminate: abort
615
+ });
616
+ const drainUnreadRawTails = async () => {
617
+ const stdout = await stdoutTail.read();
618
+ const stderr = await stderrTail.read();
619
+ deliverRawBytes(options.onStdoutChunk, stdout.bytes);
620
+ deliverRawBytes(options.onStderrChunk, stderr.bytes);
621
+ };
622
+ while (!aborted) {
623
+ const stdoutChunk = await stdoutTail.read();
624
+ const stderrChunk = await stderrTail.read();
625
+ if (stdoutChunk.bytes.length > 0) {
626
+ const now = Date.now();
627
+ lastActivityAt = now;
628
+ options.onActivity?.({ source: "stdout", timestampMs: now });
629
+ if (!firstOutputSeen && stdoutChunk.text.trim().length > 0) {
630
+ firstOutputSeen = true;
631
+ options.onFirstOutput?.(now);
632
+ }
633
+ deliverRawBytes(options.onStdoutChunk, stdoutChunk.bytes);
634
+ if (stdoutChunk.text.length > 0) {
635
+ try {
636
+ if (options.completionSignal?.(stdoutChunk.text, "stdout") === true) {
637
+ completionSignalSeen = true;
638
+ completionSignalSeenAt ??= Date.now();
639
+ }
640
+ } catch {
641
+ }
642
+ if (options.streamOutput === true) {
643
+ options.onData?.(stdoutChunk.text);
644
+ }
645
+ }
646
+ }
647
+ if (stderrChunk.bytes.length > 0) {
648
+ const now = Date.now();
649
+ lastActivityAt = now;
650
+ options.onActivity?.({ source: "stderr", timestampMs: now });
651
+ deliverRawBytes(options.onStderrChunk, stderrChunk.bytes);
652
+ if (stderrChunk.text.length > 0) {
653
+ try {
654
+ if (options.completionSignal?.(stderrChunk.text, "stderr") === true) {
655
+ completionSignalSeen = true;
656
+ completionSignalSeenAt ??= Date.now();
657
+ }
658
+ } catch {
659
+ }
660
+ if (options.streamOutput === true) {
661
+ options.onErrorData?.(stderrChunk.text);
662
+ }
663
+ }
664
+ }
665
+ if (idleTimeouts) {
666
+ const currentCpuTimeSeconds = tmuxPanePid === void 0 ? void 0 : readCpuTimeSeconds(tmuxPanePid);
667
+ const cpuProgress = evaluateCpuTimeProgressStreak({
668
+ currentCpuSeconds: currentCpuTimeSeconds,
669
+ previousCpuSeconds: lastCpuTimeSeconds,
670
+ currentBusyPolls: consecutiveBusyCpuPolls
671
+ });
672
+ consecutiveBusyCpuPolls = cpuProgress.nextBusyPolls;
673
+ if (currentCpuTimeSeconds !== void 0) {
674
+ lastCpuTimeSeconds = currentCpuTimeSeconds;
675
+ }
676
+ if (cpuProgress.shouldCountAsActivity) {
677
+ const now = Date.now();
678
+ lastActivityAt = now;
679
+ options.onActivity?.({ source: "cpu", timestampMs: now });
680
+ }
681
+ const idleFor = Date.now() - lastActivityAt;
682
+ if (idleFor >= idleTimeouts.killMs) {
683
+ options.onIdleTermination?.();
684
+ const killResult = await abort();
685
+ await drainUnreadRawTails();
686
+ const fullStdout2 = await readFullTerminalStdout();
687
+ const fullStderr2 = await readFullTerminalStderr();
688
+ const stderrDetail = fullStderr2.trim().length > 0 ? " Recent stderr was captured privately." : "";
689
+ const killDetail = killResult.removed ? "" : " Tmux session removal failed after pane SIGTERM/SIGKILL fallback; registry retained for orphan cleanup.";
690
+ throw new ProviderExecutionError(
691
+ `[${options.metadata.name}] tmux-exec provider execution idle timed out after ${Math.round(
692
+ idleTimeouts.killMs / 1e3
693
+ )}s with no stdout/stderr activity.${stderrDetail}${killDetail}`,
694
+ {
695
+ retryable: false,
696
+ reason: "idle_timeout",
697
+ idleTerminated: true,
698
+ ...tmuxTransportStreamOptions(fullStdout2, fullStderr2)
699
+ }
700
+ );
701
+ }
702
+ }
703
+ const statusText2 = await readTextIfPresent(statusFile);
704
+ if (isTmuxExecStatusAuthoritative({
705
+ statusPresent: statusText2.trim().length > 0,
706
+ sessionAlive: sessionStarted ? await tmuxSessionExists(session, options.env) : false
707
+ })) {
708
+ break;
709
+ }
710
+ if (completionSignalSeen && completionSignalSeenAt !== null && Date.now() - completionSignalSeenAt >= completionSignalGraceMs) {
711
+ exitedForCompletionSignal = true;
712
+ await killTmuxSession({ session, env: options.env, panePid: tmuxPanePid });
713
+ break;
714
+ }
715
+ if (Date.now() - startedAt > timeout) {
716
+ const killResult = await abort();
717
+ await drainUnreadRawTails();
718
+ const killDetail = killResult.removed ? "" : "; tmux session removal failed after pane SIGTERM/SIGKILL fallback; registry retained for orphan cleanup";
719
+ throw new ProviderExecutionError(
720
+ `[${options.metadata.name}] tmux-exec provider execution timed out after ${timeout}ms${killDetail}`,
721
+ {
722
+ retryable: false,
723
+ reason: "timeout",
724
+ ...tmuxTransportStreamOptions(
725
+ await readFullTerminalStdout(),
726
+ await readFullTerminalStderr()
727
+ )
728
+ }
729
+ );
730
+ }
731
+ await sleep(250);
732
+ }
733
+ if (aborted) {
734
+ await drainUnreadRawTails();
735
+ throw new ProviderExecutionError(`[${options.metadata.name}] Provider execution aborted`, {
736
+ retryable: false,
737
+ reason: "abort",
738
+ ...tmuxTransportStreamOptions(
739
+ await readFullTerminalStdout(),
740
+ await readFullTerminalStderr()
741
+ )
742
+ });
743
+ }
744
+ const finalStdout = await stdoutTail.read();
745
+ const finalStderr = await stderrTail.read();
746
+ const finalStdoutText = finalStdout.text + stdoutTail.flushText();
747
+ const finalStderrText = finalStderr.text + stderrTail.flushText();
748
+ deliverRawBytes(options.onStdoutChunk, finalStdout.bytes);
749
+ deliverRawBytes(options.onStderrChunk, finalStderr.bytes);
750
+ if (finalStdoutText.length > 0) {
751
+ try {
752
+ if (options.completionSignal?.(finalStdoutText, "stdout") === true) {
753
+ completionSignalSeen = true;
754
+ completionSignalSeenAt ??= Date.now();
755
+ }
756
+ } catch {
757
+ }
758
+ }
759
+ if (finalStderrText.length > 0) {
760
+ try {
761
+ if (options.completionSignal?.(finalStderrText, "stderr") === true) {
762
+ completionSignalSeen = true;
763
+ completionSignalSeenAt ??= Date.now();
764
+ }
765
+ } catch {
766
+ }
767
+ }
768
+ if (options.streamOutput === true) {
769
+ if (finalStdoutText) options.onData?.(finalStdoutText);
770
+ if (finalStderrText) options.onErrorData?.(finalStderrText);
771
+ }
772
+ const statusText = await readTextIfPresent(statusFile);
773
+ const trimmedStatus = statusText.trim();
774
+ const statusIsValid = /^-?\d+$/.test(trimmedStatus);
775
+ let resolvedExitCode;
776
+ if (statusIsValid) {
777
+ resolvedExitCode = Number.parseInt(trimmedStatus, 10);
778
+ } else if (exitedForCompletionSignal || completionSignalSeen) {
779
+ resolvedExitCode = 0;
780
+ } else {
781
+ resolvedExitCode = 1;
782
+ }
783
+ const fullStdout = await readTextIfPresent(stdoutFile);
784
+ const fullStderr = await readTextIfPresent(stderrFile);
785
+ const dualPublic = resolvedExitCode === 0 ? void 0 : tmuxTransportStreamOptions(fullStdout, fullStderr, {
786
+ maxPublicLength: 4096
787
+ });
788
+ const publicStdout = resolvedExitCode === 0 ? fullStdout : dualPublic?.stdout ?? "";
789
+ const publicStderr = resolvedExitCode === 0 ? fullStderr : dualPublic?.stderr ?? "";
790
+ if (options.streamOutput !== true) {
791
+ if (publicStdout) options.onData?.(publicStdout);
792
+ if (publicStderr) options.onErrorData?.(publicStderr);
793
+ } else if (resolvedExitCode === 1 && !statusIsValid && !exitedForCompletionSignal && !completionSignalSeen) {
794
+ options.onErrorData?.(
795
+ `[${options.metadata.name}] tmux-exec produced no terminal exit status; treating as failure.`
796
+ );
797
+ }
798
+ const result = {
799
+ stdout: publicStdout,
800
+ stderr: publicStderr,
801
+ exitCode: resolvedExitCode,
802
+ ...tmuxPanePid !== void 0 ? { pid: tmuxPanePid } : {}
803
+ };
804
+ throwIfTmuxNonZeroExit(options, result, { stdout: fullStdout, stderr: fullStderr });
805
+ if (settleTmuxPlmCompletion && !settleTmuxPlmCompletion.settled) {
806
+ settleTmuxPlmCompletion.settled = true;
807
+ settleTmuxPlmCompletion.resolve(result);
808
+ }
809
+ return result;
810
+ } catch (error) {
811
+ if (settleTmuxPlmCompletion && !settleTmuxPlmCompletion.settled) {
812
+ settleTmuxPlmCompletion.settled = true;
813
+ settleTmuxPlmCompletion.reject(error);
814
+ }
815
+ throw error;
816
+ } finally {
817
+ options.abortSignal?.removeEventListener("abort", abortListener);
818
+ releaseReservation();
819
+ let orphanHandoffSucceeded = false;
820
+ if (registryPersisted) {
821
+ try {
822
+ orphanHandoffSucceeded = await markTmuxSessionOrphaned(session);
823
+ } catch (error) {
824
+ transportLogger.warn("[tmux-exec] failed to mark retained tmux session orphaned", {
825
+ provider: options.metadata.name,
826
+ session,
827
+ error: error instanceof Error ? error.message : String(error)
828
+ });
829
+ }
830
+ }
831
+ const killResult = registryPersisted || sessionStarted ? await killTmuxSession({ session, env: options.env, panePid: tmuxPanePid }) : { removed: true, killed: false };
832
+ if (killResult.removed) {
833
+ await unregisterTmuxSession(session);
834
+ }
835
+ if (killResult.removed) {
836
+ if (tmuxPlmProcessId) {
837
+ getProcessLifecycleManager()?.unregisterProcess(tmuxPlmProcessId);
838
+ }
839
+ await removeTmpDir(tmpDir);
840
+ } else {
841
+ if (orphanHandoffSucceeded && tmuxPlmProcessId) {
842
+ getProcessLifecycleManager()?.unregisterProcess(tmuxPlmProcessId);
843
+ }
844
+ transportLogger.warn("[tmux-exec] tmux session cleanup failed; retaining registry record", {
845
+ provider: options.metadata.name,
846
+ session,
847
+ ...tmuxPanePid !== void 0 ? { panePid: tmuxPanePid } : {},
848
+ registryOrphaned: orphanHandoffSucceeded
849
+ });
850
+ }
851
+ }
852
+ }
853
+
854
+ // src/core/providers/shared/invocation-telemetry.ts
855
+ import path2 from "path";
856
+ async function recordInvocationTiming(record) {
857
+ try {
858
+ const requestSentMs = Number(record.timeRequestSentMs);
859
+ if (!Number.isFinite(requestSentMs) || requestSentMs <= 0) {
860
+ return;
861
+ }
862
+ const executionSource = resolveInvocationExecutionSource(record);
863
+ const providerId = normalizeTelemetryId(record.providerId);
864
+ const modelId = normalizeTelemetryId(record.canonicalModelId) ?? normalizeTelemetryId(record.modelId);
865
+ if (executionSource === "live" && (!providerId || !modelId)) {
866
+ debugLog("[Telemetry] Skipped live invocation timing without provider/model identity");
867
+ return;
868
+ }
869
+ const firstTokenMs = typeof record.timeFirstTokenMs === "number" && Number.isFinite(record.timeFirstTokenMs) ? record.timeFirstTokenMs : null;
870
+ const lastTokenMs = typeof record.timeLastTokenMs === "number" && Number.isFinite(record.timeLastTokenMs) ? record.timeLastTokenMs : null;
871
+ const timeToFirstTokenMs = firstTokenMs !== null ? Math.max(0, Math.floor(firstTokenMs - requestSentMs)) : null;
872
+ const totalTimeMs = lastTokenMs !== null ? Math.max(0, Math.floor(lastTokenMs - requestSentMs)) : null;
873
+ const poeticDir = record.poeticDir ?? path2.join(resolvePoeticRoot(process.cwd()), ".poetic");
874
+ const invocationsDbPath = resolveInvocationsDbPath(poeticDir);
875
+ const db = new ModelInvocationsDB(invocationsDbPath);
876
+ try {
877
+ const registryVersion = resolveInvocationRegistryVersion(db);
878
+ db.insertInvocation({
879
+ id: generateInvocationId(),
880
+ timestamp: requestSentMs,
881
+ providerId: providerId ?? "unknown",
882
+ modelId: modelId ?? "auto",
883
+ registryVersion,
884
+ tokensIn: record.tokensIn ?? null,
885
+ tokensOut: record.tokensOut ?? null,
886
+ timeRequestSentMs: requestSentMs,
887
+ timeFirstTokenMs: firstTokenMs,
888
+ timeLastTokenMs: lastTokenMs,
889
+ timeToFirstTokenMs,
890
+ totalTimeMs,
891
+ status: record.status,
892
+ errorCode: record.errorCode ?? null,
893
+ agentRole: record.agentRole ?? null,
894
+ copilotSubcommand: record.copilotSubcommand ?? null,
895
+ parentWorkflowId: record.parentWorkflowId ?? null,
896
+ executionSource,
897
+ // ModelIdentity fields (canonicalModelId already mapped into modelId above)
898
+ requestedModelId: normalizeTelemetryId(record.requestedModelId),
899
+ executionModelId: normalizeTelemetryId(record.executionModelId),
900
+ reportedModelId: normalizeTelemetryId(record.reportedModelId),
901
+ backend: normalizeTelemetryId(record.backend),
902
+ scope: normalizeTelemetryId(record.scope),
903
+ contextSelector: normalizeTelemetryId(record.contextSelector),
904
+ resolutionSource: normalizeTelemetryId(record.resolutionSource),
905
+ ...resolveInvocationCostAttribution(record)
906
+ });
907
+ try {
908
+ await ensurePendingInvocationCostEnrichment(db, {
909
+ aggregate: false,
910
+ refreshRegistrySnapshot: false
911
+ });
912
+ } catch (error) {
913
+ debugLog(
914
+ `[Telemetry] Failed to enrich invocation cost: ${error instanceof Error ? error.message : String(error)}`
915
+ );
916
+ }
917
+ } finally {
918
+ db.close();
919
+ }
920
+ } catch (error) {
921
+ debugLog(
922
+ `[Telemetry] Failed to record invocation timing: ${error instanceof Error ? error.message : String(error)}`
923
+ );
924
+ }
925
+ }
926
+ function resolveInvocationExecutionSource(record = {}) {
927
+ if (record.executionSource) return record.executionSource;
928
+ const env = record.env;
929
+ if (env?.POETIC_MOCK_PROVIDERS === "1") {
930
+ return "mock";
931
+ }
932
+ if (process.env.NODE_ENV === "test" || process.env.VITEST === "true") return "test";
933
+ if (readEnv(POETIC_MOCK_PROVIDERS).value === "1") return "mock";
934
+ return "live";
935
+ }
936
+ function normalizeTelemetryId(value) {
937
+ if (typeof value !== "string") return null;
938
+ const trimmed = value.trim();
939
+ return trimmed.length > 0 ? trimmed : null;
940
+ }
941
+ function firstTelemetryId(...values) {
942
+ for (const value of values) {
943
+ const normalized = normalizeTelemetryId(value);
944
+ if (normalized) return normalized;
945
+ }
946
+ return null;
947
+ }
948
+ function resolveEnvAttributionId(record, key, spec) {
949
+ if (record.env) {
950
+ return normalizeTelemetryId(record.env[key]);
951
+ }
952
+ const value = readEnv(spec).value;
953
+ return typeof value === "string" ? normalizeTelemetryId(value) : null;
954
+ }
955
+ function resolveInvocationCostAttribution(record) {
956
+ const taskId = firstTelemetryId(
957
+ record.taskId,
958
+ resolveEnvAttributionId(record, POETIC_ACTIVE_TASK_ID.name, POETIC_ACTIVE_TASK_ID)
959
+ );
960
+ const variantId = firstTelemetryId(
961
+ record.variantId,
962
+ resolveEnvAttributionId(record, POETIC_WORKER_VARIANT.name, POETIC_WORKER_VARIANT)
963
+ );
964
+ const competitionId = firstTelemetryId(record.competitionId, taskId);
965
+ return { taskId, competitionId, variantId };
966
+ }
967
+
968
+ // src/core/providers/shared/provider-timeout.ts
969
+ function resolveProviderTimeoutMs(providerId, explicitTimeoutMs) {
970
+ if (typeof explicitTimeoutMs === "number" && explicitTimeoutMs > 0) {
971
+ return explicitTimeoutMs;
972
+ }
973
+ const parsedProviderEnv = readProviderTimeoutEnvMs(providerId);
974
+ if (parsedProviderEnv !== void 0) {
975
+ return parsedProviderEnv;
976
+ }
977
+ const parsedGlobalEnv = readEnv(POETIC_TIMEOUT_MS).value;
978
+ if (parsedGlobalEnv !== void 0 && parsedGlobalEnv > 0) {
979
+ return parsedGlobalEnv;
980
+ }
981
+ try {
982
+ const timeoutFromConfig = ProviderRegistry.getTimeout(providerId);
983
+ if (typeof timeoutFromConfig === "number" && timeoutFromConfig > 0) return timeoutFromConfig;
984
+ } catch {
985
+ }
986
+ return DEFAULT_TIMEOUT;
987
+ }
988
+ function readProviderTimeoutEnvMs(providerId) {
989
+ const providerEnvKey = `POETIC_TIMEOUT_${providerId.toUpperCase()}_MS`;
990
+ const providerEnv = process.env[providerEnvKey];
991
+ const parsed = providerEnv ? Number.parseInt(providerEnv, 10) : NaN;
992
+ return !Number.isNaN(parsed) && parsed > 0 ? parsed : void 0;
993
+ }
994
+
995
+ // src/core/providers/shared/retry-budget.ts
996
+ var RetryBudget = class {
997
+ maxTotalAttempts;
998
+ usedAttempts;
999
+ constructor(options) {
1000
+ this.maxTotalAttempts = options?.maxTotalAttempts ?? 5;
1001
+ this.usedAttempts = 0;
1002
+ }
1003
+ /**
1004
+ * Returns true if there are remaining attempts in the budget.
1005
+ */
1006
+ hasRemaining() {
1007
+ return this.usedAttempts < this.maxTotalAttempts;
1008
+ }
1009
+ /**
1010
+ * Number of remaining attempts.
1011
+ */
1012
+ get remaining() {
1013
+ return Math.max(0, this.maxTotalAttempts - this.usedAttempts);
1014
+ }
1015
+ /**
1016
+ * Number of attempts consumed so far.
1017
+ */
1018
+ get used() {
1019
+ return this.usedAttempts;
1020
+ }
1021
+ /**
1022
+ * Consume one attempt from the budget.
1023
+ * @returns true if the attempt was allowed, false if the budget is exhausted.
1024
+ */
1025
+ consume() {
1026
+ if (this.usedAttempts >= this.maxTotalAttempts) {
1027
+ return false;
1028
+ }
1029
+ this.usedAttempts += 1;
1030
+ return true;
1031
+ }
1032
+ /**
1033
+ * Reset the budget to its initial state.
1034
+ */
1035
+ reset() {
1036
+ this.usedAttempts = 0;
1037
+ }
1038
+ };
1039
+
1040
+ // src/core/providers/shared/retry-worktree-state.ts
1041
+ import { createHash } from "crypto";
1042
+ import { promises as fs2 } from "fs";
1043
+ import * as path3 from "path";
1044
+ async function captureRetryWorktreeState(workingDir) {
1045
+ try {
1046
+ const [head, status, staged, unstaged, untracked] = await Promise.all([
1047
+ execGit(["rev-parse", "HEAD"], { cwd: workingDir }),
1048
+ execGit(["status", "--porcelain=v1", "--untracked-files=all", "-z"], {
1049
+ cwd: workingDir
1050
+ }),
1051
+ execGit(["diff", "--cached", "--binary", "--full-index", "--no-ext-diff"], {
1052
+ cwd: workingDir
1053
+ }),
1054
+ execGit(["diff", "--binary", "--full-index", "--no-ext-diff"], { cwd: workingDir }),
1055
+ execGit(["ls-files", "--others", "--exclude-standard", "-z"], { cwd: workingDir })
1056
+ ]);
1057
+ const failed = [head, status, staged, unstaged, untracked].find(
1058
+ (result) => result.exitCode !== 0
1059
+ );
1060
+ if (failed) {
1061
+ return {
1062
+ available: false,
1063
+ error: failed.stderr.trim() || "git state query failed"
1064
+ };
1065
+ }
1066
+ const hash = createHash("sha256");
1067
+ for (const [label, value] of [
1068
+ ["head", head.stdout],
1069
+ ["status", status.stdout],
1070
+ ["staged", staged.stdout],
1071
+ ["unstaged", unstaged.stdout]
1072
+ ]) {
1073
+ hash.update(label).update("\0").update(value).update("\0");
1074
+ }
1075
+ const untrackedPaths = untracked.stdout.split("\0").filter(Boolean).sort();
1076
+ for (const relativePath of untrackedPaths) {
1077
+ const absolutePath = path3.join(workingDir, relativePath);
1078
+ const stats = await fs2.lstat(absolutePath);
1079
+ hash.update("untracked\0").update(relativePath).update("\0");
1080
+ if (stats.isSymbolicLink()) {
1081
+ hash.update("symlink\0").update(await fs2.readlink(absolutePath));
1082
+ } else if (stats.isFile()) {
1083
+ hash.update("file\0").update(await fs2.readFile(absolutePath));
1084
+ } else {
1085
+ hash.update(`other:${stats.mode}:${stats.size}\0`);
1086
+ }
1087
+ hash.update("\0");
1088
+ }
1089
+ return { available: true, fingerprint: hash.digest("hex") };
1090
+ } catch (error) {
1091
+ return {
1092
+ available: false,
1093
+ error: error instanceof Error ? error.message : String(error)
1094
+ };
1095
+ }
1096
+ }
1097
+ function suppressUnsafeRetryAfterMutatedWorktree(providerName, reason, originalError, detail) {
1098
+ const explanation = reason === "changed" ? "the failed attempt changed HEAD, the index, the working tree, or untracked files" : `Poetic could not verify that the worktree stayed unchanged${detail ? `: ${detail}` : ""}`;
1099
+ return new ProviderExecutionError(
1100
+ `${providerName} retry suppressed because ${explanation}. Inspect the worktree and preserve or revert the attempt's changes before running ${providerName} again.`,
1101
+ {
1102
+ retryable: false,
1103
+ reason: reason === "changed" ? "workspace_changed_during_attempt" : "workspace_state_unknown",
1104
+ providerName,
1105
+ cause: originalError
1106
+ }
1107
+ );
1108
+ }
1109
+ function isRetryableProviderError(error) {
1110
+ return error instanceof ProviderExecutionError && error.retryable === true;
1111
+ }
1112
+ async function rejectUnsafeFullPromptRetry(options) {
1113
+ if (!options.requireCleanState && !isRetryableProviderError(options.error) || options.isResumeSafe === true) {
1114
+ return;
1115
+ }
1116
+ const attemptEndState = await captureRetryWorktreeState(options.workingDir);
1117
+ if (!options.attemptStartState.available || !attemptEndState.available) {
1118
+ throw suppressUnsafeRetryAfterMutatedWorktree(
1119
+ options.providerName,
1120
+ "unavailable",
1121
+ options.error,
1122
+ options.attemptStartState.error ?? attemptEndState.error
1123
+ );
1124
+ }
1125
+ if (options.attemptStartState.fingerprint !== attemptEndState.fingerprint) {
1126
+ throw suppressUnsafeRetryAfterMutatedWorktree(options.providerName, "changed", options.error);
1127
+ }
1128
+ }
1129
+
1130
+ // src/core/providers/shared/workspace-edits-parser.ts
1131
+ import * as path4 from "path";
1132
+ function isUnsafePath(candidate, options = {}) {
1133
+ if (!candidate) return true;
1134
+ const { rootDir = process.cwd(), allowAbsolute = false, allowHomeExpansion = false } = options;
1135
+ const normalized = candidate.normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\\/g, "/");
1136
+ if (normalized.includes("\0")) return true;
1137
+ if (!allowAbsolute && path4.isAbsolute(candidate)) return true;
1138
+ if (!allowHomeExpansion && normalized.startsWith("~")) return true;
1139
+ if (normalized.startsWith("../")) return true;
1140
+ if (normalized.includes("/../")) return true;
1141
+ if (/^[a-zA-Z]:[\\/]/.test(candidate)) return true;
1142
+ try {
1143
+ const resolved = path4.resolve(rootDir, normalized);
1144
+ const resolvedRoot = path4.resolve(rootDir);
1145
+ const relative2 = path4.relative(resolvedRoot, resolved);
1146
+ const escapesRoot = relative2.startsWith("..") || path4.isAbsolute(relative2);
1147
+ return escapesRoot;
1148
+ } catch {
1149
+ return true;
1150
+ }
1151
+ }
1152
+ function parseWorkspaceEditsFromJsonl(rawOutput, options = {}) {
1153
+ if (!rawOutput) {
1154
+ return { cleanedOutput: rawOutput, edits: [], errors: [] };
1155
+ }
1156
+ const edits = [];
1157
+ const errors = [];
1158
+ const kept = [];
1159
+ const pathSafetyOptions = options.workspaceRoot ? { rootDir: options.workspaceRoot } : {};
1160
+ for (const line of rawOutput.split("\n")) {
1161
+ const trimmed = line.trim();
1162
+ if (!trimmed.startsWith("{")) {
1163
+ kept.push(line);
1164
+ continue;
1165
+ }
1166
+ let parsed = null;
1167
+ try {
1168
+ parsed = safeJsonParse(trimmed, {
1169
+ debug: false,
1170
+ context: "workspace edit JSON"
1171
+ });
1172
+ } catch (error) {
1173
+ const baseMessage = error instanceof JsonParseError ? error.message : `Failed to parse workspace edit JSON: ${error instanceof Error ? error.message : String(error)}`;
1174
+ const message = `Malformed workspace edit (${baseMessage})`;
1175
+ errors.push(message);
1176
+ options.onError?.(message);
1177
+ kept.push(line);
1178
+ continue;
1179
+ }
1180
+ if (parsed.type && parsed.type !== "poetic_edit") {
1181
+ kept.push(line);
1182
+ continue;
1183
+ }
1184
+ if (!parsed.op || !parsed.path) {
1185
+ const message = `Incomplete workspace edit payload (missing op/path): ${trimmed}`;
1186
+ errors.push(message);
1187
+ options.onError?.(message);
1188
+ kept.push(line);
1189
+ continue;
1190
+ }
1191
+ const validOps = ["writeFile", "appendFile", "deleteFile", "renameFile"];
1192
+ if (!validOps.includes(parsed.op)) {
1193
+ const message = `Invalid workspace edit operation "${parsed.op}" (expected: ${validOps.join(", ")})`;
1194
+ errors.push(message);
1195
+ options.onError?.(message);
1196
+ kept.push(line);
1197
+ continue;
1198
+ }
1199
+ if (isUnsafePath(parsed.path, pathSafetyOptions) || parsed.fromPath && isUnsafePath(parsed.fromPath, pathSafetyOptions)) {
1200
+ const message = `Rejected unsafe workspace edit path: ${parsed.path}${parsed.fromPath ? ` (from: ${parsed.fromPath})` : ""}`;
1201
+ errors.push(message);
1202
+ options.onError?.(message);
1203
+ kept.push(line);
1204
+ continue;
1205
+ }
1206
+ edits.push({
1207
+ op: parsed.op,
1208
+ path: parsed.path.replace(/\\/g, "/"),
1209
+ contents: parsed.contents,
1210
+ fromPath: parsed.fromPath?.replace(/\\/g, "/")
1211
+ });
1212
+ }
1213
+ return {
1214
+ cleanedOutput: kept.join("\n"),
1215
+ edits,
1216
+ errors
1217
+ };
1218
+ }
1219
+
1220
+ // src/core/providers/shared/write-workspace-edits.ts
1221
+ import * as fs3 from "fs/promises";
1222
+ import * as path5 from "path";
1223
+ var MAX_WRITE_RETRIES = 3;
1224
+ var RETRY_BASE_DELAY_MS = 10;
1225
+ async function appendWithRetry(editsFile, payload) {
1226
+ let attempt = 0;
1227
+ while (true) {
1228
+ try {
1229
+ await fs3.appendFile(editsFile, payload, "utf8");
1230
+ return;
1231
+ } catch (error) {
1232
+ attempt += 1;
1233
+ if (attempt >= MAX_WRITE_RETRIES) {
1234
+ throw error;
1235
+ }
1236
+ const delayMs = RETRY_BASE_DELAY_MS * 2 ** (attempt - 1);
1237
+ await new Promise((resolve2) => setTimeout(resolve2, delayMs));
1238
+ }
1239
+ }
1240
+ }
1241
+ async function writeWorkspaceEditsToFile(worktreePath, edits) {
1242
+ if (!edits || edits.length === 0) {
1243
+ return { success: true, written: 0, failed: 0, skipped: 0 };
1244
+ }
1245
+ const editsDir = path5.join(worktreePath, ".poetic");
1246
+ const editsFile = path5.join(editsDir, "edits.jsonl");
1247
+ let written = 0;
1248
+ let skipped = 0;
1249
+ try {
1250
+ await fs3.mkdir(editsDir, { recursive: true });
1251
+ const payloads = [];
1252
+ for (const edit of edits) {
1253
+ if (isUnsafePath(edit.path, { rootDir: worktreePath }) || shouldExcludeFile(edit.path) || edit.fromPath && (isUnsafePath(edit.fromPath, { rootDir: worktreePath }) || shouldExcludeFile(edit.fromPath))) {
1254
+ emitWarning(
1255
+ "WS-003",
1256
+ {
1257
+ subsystem: "workspace-edits",
1258
+ executionPhase: "execution"
1259
+ },
1260
+ {
1261
+ severity: "WARN" /* WARN */,
1262
+ metadata: {
1263
+ error: "Unsafe workspace edit path",
1264
+ path: edit.path,
1265
+ fromPath: edit.fromPath,
1266
+ operation: "writeWorkspaceEdits"
1267
+ }
1268
+ }
1269
+ );
1270
+ skipped += 1;
1271
+ continue;
1272
+ }
1273
+ const payload = {
1274
+ type: "poetic_edit",
1275
+ op: edit.op,
1276
+ path: edit.path,
1277
+ ...edit.contents !== void 0 ? { contents: edit.contents } : {},
1278
+ ...edit.fromPath !== void 0 ? { fromPath: edit.fromPath } : {}
1279
+ };
1280
+ payloads.push(`${JSON.stringify(payload)}
1281
+ `);
1282
+ }
1283
+ if (payloads.length > 0) {
1284
+ await appendWithRetry(editsFile, payloads.join(""));
1285
+ written = payloads.length;
1286
+ }
1287
+ return {
1288
+ success: written > 0 || skipped === 0,
1289
+ written,
1290
+ failed: written === 0 && skipped > 0 ? skipped : 0,
1291
+ skipped,
1292
+ ...written === 0 && skipped > 0 ? { error: "All workspace edits were skipped by safety filters" } : {}
1293
+ };
1294
+ } catch (error) {
1295
+ const errorMessage2 = error instanceof Error ? error.message : String(error);
1296
+ emitWarning(
1297
+ "WS-003",
1298
+ {
1299
+ subsystem: "workspace-edits",
1300
+ executionPhase: "execution"
1301
+ },
1302
+ {
1303
+ severity: "ERROR" /* ERROR */,
1304
+ metadata: {
1305
+ error: errorMessage2,
1306
+ operation: "writeWorkspaceEdits",
1307
+ editsFile
1308
+ }
1309
+ }
1310
+ );
1311
+ return {
1312
+ success: false,
1313
+ written,
1314
+ failed: edits.length - written - skipped,
1315
+ skipped,
1316
+ error: errorMessage2
1317
+ };
1318
+ }
1319
+ }
1320
+
1321
+ // src/core/providers/shared/runner-lifecycle.ts
1322
+ var DEFAULT_PROVIDER_CIRCUIT_BREAKER_OPTIONS = createCircuitBreakerOptions({
1323
+ failureThreshold: 5,
1324
+ recoveryTimeout: 6e4
1325
+ });
1326
+ async function executeWithResilience(fn, options) {
1327
+ const {
1328
+ providerName,
1329
+ operation = "execute_prompt",
1330
+ maxAttempts = 3,
1331
+ retryBudget,
1332
+ onRetry,
1333
+ abortSignal,
1334
+ circuitBreakerOptions = DEFAULT_PROVIDER_CIRCUIT_BREAKER_OPTIONS,
1335
+ errorParser,
1336
+ providerId,
1337
+ fastRetryMode = false,
1338
+ initialDelayMs,
1339
+ maxDelayMs,
1340
+ backoffMultiplier,
1341
+ deadlineMs,
1342
+ minimumAttemptTimeMs,
1343
+ circuitBreakerScope,
1344
+ retryWorktreeDir,
1345
+ isRetryResumeSafe
1346
+ } = options;
1347
+ const retryOptions = createRetryOptions({
1348
+ providerName,
1349
+ operation,
1350
+ maxAttempts,
1351
+ initialDelayMs: fastRetryMode ? 0 : initialDelayMs,
1352
+ maxDelayMs: fastRetryMode ? 0 : maxDelayMs,
1353
+ backoffMultiplier,
1354
+ retryBudget,
1355
+ onRetry,
1356
+ abortSignal,
1357
+ suppressDelayFloors: fastRetryMode,
1358
+ deadlineMs,
1359
+ minimumAttemptTimeMs
1360
+ });
1361
+ const wrappedFn = async () => {
1362
+ const attemptStartState = retryWorktreeDir ? await captureRetryWorktreeState(retryWorktreeDir) : void 0;
1363
+ try {
1364
+ return await executeWithCircuitBreaker(
1365
+ providerName,
1366
+ fn,
1367
+ circuitBreakerOptions,
1368
+ circuitBreakerScope
1369
+ );
1370
+ } catch (error) {
1371
+ const thrown = errorParser ? wrapProviderError(error, errorParser, providerId ?? providerName) : error;
1372
+ if (retryWorktreeDir && attemptStartState) {
1373
+ await rejectUnsafeFullPromptRetry({
1374
+ workingDir: retryWorktreeDir,
1375
+ attemptStartState,
1376
+ error: thrown,
1377
+ providerName: providerId ?? providerName,
1378
+ isResumeSafe: isRetryResumeSafe?.() === true
1379
+ });
1380
+ }
1381
+ throw thrown;
1382
+ }
1383
+ };
1384
+ return withRetry(wrappedFn, retryOptions);
1385
+ }
1386
+ function wrapProviderError(error, errorParser, providerId) {
1387
+ if (error instanceof CircuitBreakerError) {
1388
+ return new ProviderExecutionError(error.message, {
1389
+ retryable: false,
1390
+ reason: "circuit_open",
1391
+ providerName: providerId,
1392
+ cause: error
1393
+ });
1394
+ }
1395
+ const parsed = errorParser(error);
1396
+ if (error instanceof ProviderExecutionError) {
1397
+ const GENERIC_FALLBACK_REASONS = /* @__PURE__ */ new Set(["non_zero_exit", "provider_cli_error"]);
1398
+ const hasExplicitTerminalReason = typeof error.reason === "string" && error.reason.length > 0 && !GENERIC_FALLBACK_REASONS.has(error.reason);
1399
+ const retryable = error.retryable === false && hasExplicitTerminalReason ? false : parsed.retryable;
1400
+ return new ProviderExecutionError(error.message, {
1401
+ retryable,
1402
+ exitCode: error.exitCode,
1403
+ statusCode: error.statusCode,
1404
+ reason: error.reason,
1405
+ signal: error.signal,
1406
+ terminationSource: error.terminationSource,
1407
+ // Preserve truncated public fields and non-enumerable full raw carriers.
1408
+ ...providerExecutionErrorStreamOptions(error),
1409
+ providerName: providerId,
1410
+ cause: error.cause,
1411
+ parsedError: parsed
1412
+ });
1413
+ }
1414
+ const originalMessage = error instanceof Error ? error.message : String(error);
1415
+ return new ProviderExecutionError(originalMessage, {
1416
+ retryable: parsed.retryable,
1417
+ providerName: providerId,
1418
+ cause: error,
1419
+ parsedError: parsed
1420
+ });
1421
+ }
1422
+ async function persistWorkspaceEdits(workingDir, edits) {
1423
+ if (edits.length === 0) return;
1424
+ try {
1425
+ await writeWorkspaceEditsToFile(workingDir, edits);
1426
+ } catch (error) {
1427
+ if (process.env.NODE_ENV !== "test") {
1428
+ console.warn(
1429
+ `[runner-lifecycle] Failed to persist workspace edits for ${workingDir}: ${error instanceof Error ? error.message : String(error)}`
1430
+ );
1431
+ }
1432
+ }
1433
+ }
1434
+
1435
+ // src/core/providers/shared/workspace-retry-safety.ts
1436
+ import { createHash as createHash2 } from "crypto";
1437
+ import { promises as fs4 } from "fs";
1438
+ import * as path6 from "path";
1439
+ function isEnoentError(error) {
1440
+ return Boolean(
1441
+ error && typeof error === "object" && "code" in error && error.code === "ENOENT"
1442
+ );
1443
+ }
1444
+ function errorMessage(error) {
1445
+ return error instanceof Error ? error.message : String(error);
1446
+ }
1447
+ async function captureWorkspaceFingerprintOnce(workingDir) {
1448
+ const [head, status, staged, unstaged, untracked] = await Promise.all([
1449
+ execGit(["rev-parse", "HEAD"], { cwd: workingDir }),
1450
+ execGit(["status", "--porcelain=v1", "--untracked-files=all", "-z"], {
1451
+ cwd: workingDir
1452
+ }),
1453
+ execGit(["diff", "--cached", "--binary", "--full-index", "--no-ext-diff"], {
1454
+ cwd: workingDir
1455
+ }),
1456
+ execGit(["diff", "--binary", "--full-index", "--no-ext-diff"], { cwd: workingDir }),
1457
+ execGit(["ls-files", "--others", "--exclude-standard", "-z"], { cwd: workingDir })
1458
+ ]);
1459
+ const failed = [status, staged, unstaged, untracked].find((result) => result.exitCode !== 0);
1460
+ if (failed) {
1461
+ return {
1462
+ kind: "unavailable",
1463
+ error: failed.stderr.trim() || "git state query failed"
1464
+ };
1465
+ }
1466
+ const hash = createHash2("sha256");
1467
+ for (const [label, value] of [
1468
+ ["head", head.exitCode === 0 ? head.stdout : "<unborn>"],
1469
+ ["status", status.stdout],
1470
+ ["staged", staged.stdout],
1471
+ ["unstaged", unstaged.stdout]
1472
+ ]) {
1473
+ hash.update(label).update("\0").update(value).update("\0");
1474
+ }
1475
+ const untrackedPaths = untracked.stdout.split("\0").filter(Boolean).sort();
1476
+ for (const relativePath of untrackedPaths) {
1477
+ const absolutePath = path6.join(workingDir, relativePath);
1478
+ let stats;
1479
+ try {
1480
+ stats = await fs4.lstat(absolutePath);
1481
+ } catch (error) {
1482
+ if (isEnoentError(error)) {
1483
+ return { kind: "unstable", error: errorMessage(error) };
1484
+ }
1485
+ throw error;
1486
+ }
1487
+ hash.update("untracked\0").update(relativePath).update("\0");
1488
+ try {
1489
+ if (stats.isSymbolicLink()) {
1490
+ hash.update("symlink\0").update(await fs4.readlink(absolutePath));
1491
+ } else if (stats.isFile()) {
1492
+ hash.update("file\0").update(await fs4.readFile(absolutePath));
1493
+ } else {
1494
+ hash.update(`other:${stats.mode}:${stats.size}\0`);
1495
+ }
1496
+ } catch (error) {
1497
+ if (isEnoentError(error)) {
1498
+ return { kind: "unstable", error: errorMessage(error) };
1499
+ }
1500
+ throw error;
1501
+ }
1502
+ hash.update("\0");
1503
+ }
1504
+ return { kind: "ready", fingerprint: hash.digest("hex") };
1505
+ }
1506
+ async function captureWorkspaceRetryState(workingDir) {
1507
+ try {
1508
+ const insideWorkTree = await execGit(["rev-parse", "--is-inside-work-tree"], {
1509
+ cwd: workingDir
1510
+ });
1511
+ if (insideWorkTree.exitCode !== 0 || insideWorkTree.stdout.trim() !== "true") {
1512
+ return {
1513
+ available: false,
1514
+ error: insideWorkTree.stderr.trim() || "working directory is not inside a Git worktree"
1515
+ };
1516
+ }
1517
+ const first = await captureWorkspaceFingerprintOnce(workingDir);
1518
+ if (first.kind === "ready") {
1519
+ return { available: true, fingerprint: first.fingerprint };
1520
+ }
1521
+ if (first.kind === "unavailable") {
1522
+ return { available: false, error: first.error };
1523
+ }
1524
+ const second = await captureWorkspaceFingerprintOnce(workingDir);
1525
+ if (second.kind === "ready") {
1526
+ return { available: true, fingerprint: second.fingerprint };
1527
+ }
1528
+ return {
1529
+ available: false,
1530
+ error: second.error
1531
+ };
1532
+ } catch (error) {
1533
+ return {
1534
+ available: false,
1535
+ error: errorMessage(error)
1536
+ };
1537
+ }
1538
+ }
1539
+ async function assertWorkspaceRetryIsSafe(options) {
1540
+ if (!options.retryable) {
1541
+ return;
1542
+ }
1543
+ const attemptEndState = await captureWorkspaceRetryState(options.workingDir);
1544
+ const unavailable = !options.attemptStartState.available || !attemptEndState.available;
1545
+ const changed = !unavailable && options.attemptStartState.fingerprint !== attemptEndState.fingerprint;
1546
+ if (!unavailable && !changed) {
1547
+ return;
1548
+ }
1549
+ const detail = options.attemptStartState.error ?? attemptEndState.error ?? "workspace fingerprint could not be captured";
1550
+ const explanation = changed ? "the failed attempt changed HEAD, the index, the working tree, or untracked files" : `Poetic could not verify that the worktree stayed unchanged: ${detail}`;
1551
+ throw new ProviderExecutionError(
1552
+ `${options.providerName} retry suppressed because ${explanation}. Inspect the worktree and preserve or revert the attempt changes before retrying.`,
1553
+ {
1554
+ retryable: false,
1555
+ reason: changed ? "workspace_changed_during_attempt" : "workspace_state_unknown",
1556
+ providerName: options.providerId,
1557
+ cause: options.originalError instanceof Error ? options.originalError : void 0
1558
+ }
1559
+ );
1560
+ }
1561
+
1562
+ export {
1563
+ resolveProviderTransportDecision,
1564
+ reportTransportDecision,
1565
+ selectProviderExecutor,
1566
+ executeProviderCommandTmuxExec,
1567
+ recordInvocationTiming,
1568
+ resolveProviderTimeoutMs,
1569
+ readProviderTimeoutEnvMs,
1570
+ RetryBudget,
1571
+ captureRetryWorktreeState,
1572
+ rejectUnsafeFullPromptRetry,
1573
+ parseWorkspaceEditsFromJsonl,
1574
+ DEFAULT_PROVIDER_CIRCUIT_BREAKER_OPTIONS,
1575
+ executeWithResilience,
1576
+ wrapProviderError,
1577
+ persistWorkspaceEdits,
1578
+ captureWorkspaceRetryState,
1579
+ assertWorkspaceRetryIsSafe
1580
+ };
1581
+ //# sourceMappingURL=chunk-WZ6U3O7I.js.map