@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,2931 @@
1
+ import {
2
+ findPoeticPackageRoot
3
+ } from "./chunk-GSGD5E4C.js";
4
+ import {
5
+ getExecutionContext
6
+ } from "./chunk-UI2F6DJ5.js";
7
+ import {
8
+ normalizeReasoningEffortInput
9
+ } from "./chunk-4BTDUT2S.js";
10
+ import {
11
+ findProjectRoot,
12
+ getConfigPaths,
13
+ resolveProvidersConfigPath
14
+ } from "./chunk-L6OM4A22.js";
15
+ import {
16
+ validateConfigPath
17
+ } from "./chunk-XZE4XARH.js";
18
+ import {
19
+ debugLog,
20
+ emitWarning
21
+ } from "./chunk-EJGCZGUF.js";
22
+ import {
23
+ KEYS
24
+ } from "./chunk-5DLKYTQX.js";
25
+
26
+ // src/core/config/provider-registry.ts
27
+ import { createHash as createHash2 } from "crypto";
28
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
29
+ import { homedir } from "os";
30
+ import { join, resolve as resolve3, sep } from "path";
31
+ import { fileURLToPath } from "url";
32
+ import yaml from "js-yaml";
33
+ import { z as z2 } from "zod";
34
+
35
+ // src/core/providers/generated/catalog-digest.ts
36
+ var PROVIDER_CATALOG_SHA256 = "436ed6466f6b99fc21ef1e09ac23735ba4733abe4f8288fbd446ea03996352b5";
37
+
38
+ // src/core/providers/refresh/overlay.ts
39
+ import { existsSync, readFileSync } from "fs";
40
+ import * as fs from "fs/promises";
41
+ import { z } from "zod";
42
+ var REFRESH_OVERLAY_SCHEMA_VERSION = 1;
43
+ var UsdPer1MSchema = z.union([
44
+ z.number().nonnegative(),
45
+ z.string().regex(/^\d+(?:\.\d+)?$/, "Must be non-negative USD")
46
+ ]);
47
+ var OverlayModelAvailableEntrySchema = z.object({
48
+ id: z.string().trim().min(1),
49
+ display_name: z.string().min(1),
50
+ full_name: z.string().optional(),
51
+ capabilities: z.array(z.string()),
52
+ context_window: z.number().int().positive().optional(),
53
+ max_output_tokens: z.number().int().positive().optional(),
54
+ reasoning_effort_levels: z.array(z.string()).optional(),
55
+ notes: z.string().optional()
56
+ }).strict();
57
+ var OverlayPricingRowSchema = z.object({
58
+ input_per_1m_tokens: UsdPer1MSchema.optional(),
59
+ output_per_1m_tokens: UsdPer1MSchema.optional(),
60
+ cache_read_per_1m_tokens: UsdPer1MSchema.optional(),
61
+ cache_write_per_1m_tokens: UsdPer1MSchema.optional(),
62
+ context_window: z.number().int().positive().optional(),
63
+ features: z.record(z.string(), z.boolean()).optional(),
64
+ notes: z.string().optional(),
65
+ last_updated: z.string().optional()
66
+ }).strict();
67
+ var REFRESH_SOURCES = [
68
+ "API",
69
+ "doc-poll",
70
+ "pricing-only",
71
+ "discovery",
72
+ "static"
73
+ ];
74
+ var OverlaySliceProvenanceSchema = z.object({
75
+ source: z.enum(REFRESH_SOURCES),
76
+ fetchedAt: z.string().min(1),
77
+ freshnessMs: z.number().int().nonnegative().optional()
78
+ }).strict();
79
+ var OverlayProviderPayloadSchema = z.object({
80
+ models: z.object({
81
+ available: z.array(OverlayModelAvailableEntrySchema),
82
+ /** Treat available as the complete provider inventory, not an additive patch. */
83
+ replaceInventory: z.literal(true).optional()
84
+ }).strict().optional(),
85
+ pricing: z.object({
86
+ models: z.record(z.string(), OverlayPricingRowSchema)
87
+ }).strict().optional(),
88
+ /** Provider-level freshness / provenance. */
89
+ provenance: OverlaySliceProvenanceSchema.optional(),
90
+ /** Per-slice freshness / provenance (models vs pricing). */
91
+ slices: z.object({
92
+ models: OverlaySliceProvenanceSchema.optional(),
93
+ pricing: OverlaySliceProvenanceSchema.optional()
94
+ }).strict().optional()
95
+ }).strict();
96
+ var RefreshOverlayDocumentSchema = z.object({
97
+ schemaVersion: z.literal(REFRESH_OVERLAY_SCHEMA_VERSION),
98
+ baseCatalogDigest: z.string().min(1),
99
+ providers: z.record(z.string(), OverlayProviderPayloadSchema)
100
+ }).strict();
101
+ var REFRESH_OVERLAY_RERUN_GUIDANCE = "Refresh overlay ignored because the release catalog digest changed. Run: poetic provider refresh";
102
+ function noticeFromRefreshOverlayDisposition(disposition) {
103
+ if (disposition.status === "degraded") {
104
+ return {
105
+ status: "degraded",
106
+ reason: disposition.reason,
107
+ message: disposition.warning,
108
+ guidance: REFRESH_OVERLAY_RERUN_GUIDANCE
109
+ };
110
+ }
111
+ if (disposition.status === "rejected") {
112
+ return {
113
+ status: "rejected",
114
+ reason: disposition.reason,
115
+ message: disposition.error,
116
+ guidance: "Refresh overlay is invalid and was ignored. Run: poetic provider refresh"
117
+ };
118
+ }
119
+ return void 0;
120
+ }
121
+ function getRefreshOverlayOperatorNotice(overlayPath, expectedBaseCatalogDigest) {
122
+ if (!existsSync(overlayPath)) return void 0;
123
+ try {
124
+ const disposition = resolveRefreshOverlayDisposition(readFileSync(overlayPath, "utf8"), {
125
+ expectedBaseCatalogDigest
126
+ });
127
+ return noticeFromRefreshOverlayDisposition(disposition);
128
+ } catch {
129
+ return void 0;
130
+ }
131
+ }
132
+ function sortKeysDeep(value) {
133
+ if (Array.isArray(value)) {
134
+ return value.map(sortKeysDeep);
135
+ }
136
+ if (value && typeof value === "object") {
137
+ const sorted = {};
138
+ for (const key of Object.keys(value).sort()) {
139
+ sorted[key] = sortKeysDeep(value[key]);
140
+ }
141
+ return sorted;
142
+ }
143
+ return value;
144
+ }
145
+ function emptyRefreshOverlay(baseCatalogDigest) {
146
+ return {
147
+ schemaVersion: REFRESH_OVERLAY_SCHEMA_VERSION,
148
+ baseCatalogDigest,
149
+ providers: {}
150
+ };
151
+ }
152
+ function serializeRefreshOverlay(overlay) {
153
+ const parsed = RefreshOverlayDocumentSchema.safeParse(overlay);
154
+ if (!parsed.success) {
155
+ throw new Error(
156
+ `Cannot serialize invalid refresh overlay: ${parsed.error.issues.map((issue) => issue.message).join("; ")}`
157
+ );
158
+ }
159
+ return `${JSON.stringify(sortKeysDeep(parsed.data), null, 2)}
160
+ `;
161
+ }
162
+ function parseRefreshOverlayValue(value) {
163
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
164
+ return { ok: false, error: "Refresh overlay must be a JSON object" };
165
+ }
166
+ const parsed = RefreshOverlayDocumentSchema.safeParse(value);
167
+ if (!parsed.success) {
168
+ return {
169
+ ok: false,
170
+ error: `Invalid refresh overlay schema: ${parsed.error.issues.map((issue) => `${issue.path.join(".") || "<root>"}: ${issue.message}`).join("; ")}`
171
+ };
172
+ }
173
+ return { ok: true, overlay: parsed.data };
174
+ }
175
+ function parseRefreshOverlay(raw) {
176
+ let value;
177
+ try {
178
+ value = JSON.parse(raw);
179
+ } catch (error) {
180
+ return {
181
+ ok: false,
182
+ error: `Refresh overlay is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
183
+ };
184
+ }
185
+ return parseRefreshOverlayValue(value);
186
+ }
187
+ function resolveRefreshOverlayDisposition(input, options) {
188
+ const parsed = typeof input === "string" ? parseRefreshOverlay(input) : parseRefreshOverlayValue(input);
189
+ if (!parsed.ok) {
190
+ return { status: "rejected", reason: "invalid_schema", error: parsed.error };
191
+ }
192
+ if (options.expectedBaseCatalogDigest !== parsed.overlay.baseCatalogDigest) {
193
+ return {
194
+ status: "degraded",
195
+ reason: "base_digest_mismatch",
196
+ warning: `Refresh overlay base catalog digest mismatch: overlay=${parsed.overlay.baseCatalogDigest} expected=${options.expectedBaseCatalogDigest}; overlay ignored`,
197
+ overlay: parsed.overlay
198
+ };
199
+ }
200
+ return { status: "ready", overlay: parsed.overlay };
201
+ }
202
+ async function loadRefreshOverlayFile(overlayPath, options) {
203
+ try {
204
+ const stat = await fs.lstat(overlayPath);
205
+ if (stat.isSymbolicLink()) {
206
+ return {
207
+ status: "rejected",
208
+ reason: "invalid_schema",
209
+ error: `Provider refresh refuses a symlinked overlay: ${overlayPath}`
210
+ };
211
+ }
212
+ if (!stat.isFile()) {
213
+ return {
214
+ status: "rejected",
215
+ reason: "invalid_schema",
216
+ error: `Provider refresh overlay target is not a regular file: ${overlayPath}`
217
+ };
218
+ }
219
+ const raw = await fs.readFile(overlayPath, "utf8");
220
+ return resolveRefreshOverlayDisposition(raw, options);
221
+ } catch (error) {
222
+ if (error.code === "ENOENT") {
223
+ return { status: "absent" };
224
+ }
225
+ throw error;
226
+ }
227
+ }
228
+
229
+ // src/core/config/cache-fingerprint.ts
230
+ import { createHash } from "crypto";
231
+ import { statSync } from "fs";
232
+ import { resolve } from "path";
233
+ function digest(value) {
234
+ return createHash("sha256").update(value).digest("hex");
235
+ }
236
+ function fingerprintEnvironment(env, include = (name) => name.startsWith("POETIC_")) {
237
+ const entries = Object.entries(env).filter(([name, value]) => include(name) && value !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([name, value]) => [name, digest(value ?? "")]);
238
+ return digest(JSON.stringify(entries));
239
+ }
240
+ function fingerprintFile(filePath) {
241
+ const normalized = resolve(filePath);
242
+ try {
243
+ const stat = statSync(normalized);
244
+ return JSON.stringify({
245
+ path: normalized,
246
+ exists: true,
247
+ dev: stat.dev,
248
+ ino: stat.ino,
249
+ size: stat.size,
250
+ mtimeMs: stat.mtimeMs,
251
+ ctimeMs: stat.ctimeMs
252
+ });
253
+ } catch (error) {
254
+ const code = error.code;
255
+ return JSON.stringify({ path: normalized, exists: false, code: code ?? "UNKNOWN" });
256
+ }
257
+ }
258
+ function fingerprintFiles(filePaths) {
259
+ return digest(JSON.stringify([...new Set(filePaths)].sort().map(fingerprintFile)));
260
+ }
261
+ function combineCacheFingerprints(...parts) {
262
+ return digest(JSON.stringify(parts.filter((part) => part !== void 0)));
263
+ }
264
+
265
+ // src/core/config/config-errors.ts
266
+ var InvalidExplicitConfigError = class extends Error {
267
+ constructor(message, sourceError) {
268
+ super(message);
269
+ this.sourceError = sourceError;
270
+ this.name = "InvalidExplicitConfigError";
271
+ }
272
+ sourceError;
273
+ code = "POETIC_INVALID_EXPLICIT_CONFIG";
274
+ };
275
+ function isInvalidExplicitConfigError(error) {
276
+ return error instanceof InvalidExplicitConfigError || error instanceof Error && error.code === "POETIC_INVALID_EXPLICIT_CONFIG";
277
+ }
278
+ function isConfigValidityError(error) {
279
+ if (isInvalidExplicitConfigError(error)) return true;
280
+ return error instanceof Error && error.code === "POETIC_CONFIG_READ_INVALID";
281
+ }
282
+ function rethrowConfigValidityError(error) {
283
+ if (isConfigValidityError(error)) throw error;
284
+ }
285
+
286
+ // src/core/config/registry/dynamic-keys.ts
287
+ var DYNAMIC_KEYS = [
288
+ // Per-command idle timeouts
289
+ // Source: src/core/providers/shared/base-runner.ts
290
+ // process.env[`POETIC_IDLE_WARN_${commandName}_MS`]
291
+ {
292
+ pattern: /^POETIC_IDLE_WARN_[A-Z][A-Z0-9_]*_MS$/,
293
+ extract: (name) => {
294
+ const m = name.match(/^POETIC_IDLE_WARN_([A-Z][A-Z0-9_]*)_MS$/);
295
+ if (!m || m[1] === void 0) return null;
296
+ return { command: m[1] };
297
+ },
298
+ category: "provider",
299
+ status: "active",
300
+ description: "Per-command idle warning threshold: POETIC_IDLE_WARN_<CMD>_MS",
301
+ type: "number"
302
+ },
303
+ {
304
+ pattern: /^POETIC_IDLE_KILL_[A-Z][A-Z0-9_]*_MS$/,
305
+ extract: (name) => {
306
+ const m = name.match(/^POETIC_IDLE_KILL_([A-Z][A-Z0-9_]*)_MS$/);
307
+ if (!m || m[1] === void 0) return null;
308
+ return { command: m[1] };
309
+ },
310
+ category: "provider",
311
+ status: "active",
312
+ description: "Per-command idle kill threshold: POETIC_IDLE_KILL_<CMD>_MS",
313
+ type: "number"
314
+ },
315
+ // Per-provider timeout overrides
316
+ // Source: src/core/timeout/timeout-config.ts
317
+ // `POETIC_TIMEOUT_${normalizedProvider.toUpperCase()}_${mode.toUpperCase()}`
318
+ // `POETIC_TIMEOUT_DEFAULT_${mode.toUpperCase()}`
319
+ // Modes observed: LOCAL, CLOUD, API, REMOTE, MS, and any future mode string.
320
+ {
321
+ pattern: /^POETIC_TIMEOUT_[A-Z][A-Z0-9_]*_[A-Z][A-Z0-9]*$/,
322
+ extract: (name) => {
323
+ const m = name.match(/^POETIC_TIMEOUT_([A-Z][A-Z0-9_]*)_([A-Z][A-Z0-9]*)$/);
324
+ if (!m || m[1] === void 0 || m[2] === void 0) return null;
325
+ return { provider: m[1], mode: m[2] };
326
+ },
327
+ category: "provider",
328
+ status: "active",
329
+ description: "Per-provider/mode timeout override (ms): POETIC_TIMEOUT_<PROVIDER>_<MODE> or POETIC_TIMEOUT_DEFAULT_<MODE>",
330
+ type: "number"
331
+ },
332
+ // Per-provider timeout from provider-timeout.ts
333
+ // Source: src/core/providers/shared/provider-timeout.ts
334
+ // `POETIC_TIMEOUT_${providerId.toUpperCase()}_MS`
335
+ // This is a subset of the pattern above; the combined pattern already covers it.
336
+ // Per-provider sandbox toggles
337
+ // Source: src/core/sandbox/index.ts
338
+ // process.env[`POETIC_SANDBOX_${normalizedName}_ENABLED`]
339
+ // process.env[`POETIC_SANDBOX_${normalizedId}_ENABLED`]
340
+ {
341
+ pattern: /^POETIC_SANDBOX_[A-Z][A-Z0-9_]*_ENABLED$/,
342
+ extract: (name) => {
343
+ const m = name.match(/^POETIC_SANDBOX_([A-Z][A-Z0-9_]*)_ENABLED$/);
344
+ if (!m || m[1] === void 0) return null;
345
+ return { provider: m[1] };
346
+ },
347
+ category: "sandbox",
348
+ status: "active",
349
+ description: "Per-provider sandbox enable toggle: POETIC_SANDBOX_<PROVIDER>_ENABLED",
350
+ type: "boolean"
351
+ },
352
+ // Per-provider execution policy enforcement
353
+ // Source: src/orchestrator/execution-policy.ts
354
+ // `POETIC_EXECUTION_POLICY_ENFORCE_${provider.toUpperCase()}`
355
+ {
356
+ pattern: /^POETIC_EXECUTION_POLICY_ENFORCE_[A-Z][A-Z0-9_]*$/,
357
+ extract: (name) => {
358
+ const m = name.match(/^POETIC_EXECUTION_POLICY_ENFORCE_([A-Z][A-Z0-9_]*)$/);
359
+ if (!m || m[1] === void 0) return null;
360
+ return { provider: m[1] };
361
+ },
362
+ category: "orchestrator",
363
+ status: "active",
364
+ description: "Per-provider execution policy enforcement toggle: POETIC_EXECUTION_POLICY_ENFORCE_<PROVIDER>",
365
+ type: "boolean"
366
+ },
367
+ // Per-provider config overrides
368
+ // Source: src/core/config/provider-registry.ts
369
+ // POETIC_PROVIDER_<ID>_<KEY>=value (e.g. POETIC_PROVIDER_CODEX_TIMEOUT_MS,
370
+ // POETIC_PROVIDER_CLAUDE_ENABLED, POETIC_PROVIDER_GEMINI_MODELS_DEFAULT).
371
+ // Static REGISTRY entries that begin with POETIC_PROVIDER_ are checked
372
+ // first by isRecognizedEnvVar; this fallback recognizes the dynamic
373
+ // <PROVIDER>_<KEY> shape so legitimate overrides aren't flagged. The
374
+ // provider/key boundary is registry-dependent because both may contain
375
+ // underscores; ProviderRegistry resolves the longest registered prefix.
376
+ {
377
+ pattern: /^POETIC_PROVIDER_[A-Z0-9][A-Z0-9_-]*_[A-Z][A-Z0-9_]*$/,
378
+ extract: (name) => {
379
+ const m = name.match(/^POETIC_PROVIDER_([A-Z0-9][A-Z0-9_-]*_[A-Z][A-Z0-9_]*)$/);
380
+ if (!m || m[1] === void 0) return null;
381
+ return { providerAndKey: m[1] };
382
+ },
383
+ category: "provider",
384
+ status: "active",
385
+ description: "Per-provider config override: POETIC_PROVIDER_<ID>_<KEY>",
386
+ type: "string"
387
+ }
388
+ ];
389
+
390
+ // src/core/config/env-var-registry.ts
391
+ var REGISTRY = Object.fromEntries(
392
+ Object.entries(KEYS).map(([name, spec]) => [
393
+ name,
394
+ {
395
+ category: spec.category,
396
+ status: spec.status,
397
+ description: spec.description,
398
+ ...spec.replacement !== void 0 ? { replacement: spec.replacement } : {}
399
+ }
400
+ ])
401
+ );
402
+ function isRecognizedEnvVar(name) {
403
+ if (REGISTRY[name]) return true;
404
+ return DYNAMIC_KEYS.some((spec) => spec.pattern.test(name));
405
+ }
406
+ function getEnvVarEntry(name) {
407
+ return REGISTRY[name];
408
+ }
409
+ function levenshtein(a, b, maxDist) {
410
+ if (Math.abs(a.length - b.length) > maxDist) return maxDist + 1;
411
+ const prev = Array.from({ length: b.length + 1 }, (_, i) => i);
412
+ const curr = new Array(b.length + 1);
413
+ for (let i = 1; i <= a.length; i++) {
414
+ curr[0] = i;
415
+ for (let j = 1; j <= b.length; j++) {
416
+ curr[j] = a[i - 1] === b[j - 1] ? prev[j - 1] : 1 + Math.min(prev[j], curr[j - 1], prev[j - 1]);
417
+ }
418
+ for (let j = 0; j <= b.length; j++) prev[j] = curr[j];
419
+ }
420
+ return prev[b.length];
421
+ }
422
+ function closestRegisteredKeys(unknown, maxDist, limit) {
423
+ const candidates = [];
424
+ for (const name of Object.keys(REGISTRY)) {
425
+ const dist = levenshtein(unknown, name, maxDist);
426
+ if (dist <= maxDist) candidates.push({ name, dist });
427
+ }
428
+ candidates.sort((a, b) => a.dist - b.dist);
429
+ return candidates.slice(0, limit).map((c) => c.name);
430
+ }
431
+ function validateEnvironmentVars() {
432
+ const unrecognized = [];
433
+ for (const key of Object.keys(process.env)) {
434
+ if (!key.startsWith("POETIC_")) continue;
435
+ if (!isRecognizedEnvVar(key)) {
436
+ unrecognized.push(key);
437
+ }
438
+ }
439
+ if (process.env.POETIC_STRICT_ENV === "1" && unrecognized.length > 0) {
440
+ for (const key of unrecognized) {
441
+ const suggestions = closestRegisteredKeys(key, 2, 3);
442
+ const hint = suggestions.length > 0 ? ` (did you mean: ${suggestions.join(", ")}?)` : "";
443
+ console.warn(`[poetic] POETIC_STRICT_ENV: unrecognized env var: ${key}${hint}`);
444
+ }
445
+ }
446
+ return unrecognized;
447
+ }
448
+
449
+ // src/core/config/project-trust.ts
450
+ import { realpathSync } from "fs";
451
+ import { isAbsolute, resolve as resolve2 } from "path";
452
+ var PROJECT_EXECUTION_TRUST_ENV = "POETIC_TRUST_PROJECT_PROVIDER_TEMPLATES";
453
+ function isTrustedProjectRoot(projectRoot) {
454
+ const projectTrustValue = String(process.env[PROJECT_EXECUTION_TRUST_ENV] ?? "").trim();
455
+ if (!projectTrustValue || !isAbsolute(projectTrustValue)) return false;
456
+ try {
457
+ return realpathSync(resolve2(projectTrustValue)) === realpathSync(projectRoot);
458
+ } catch {
459
+ return false;
460
+ }
461
+ }
462
+ function formatProjectTrustInstruction(projectRoot) {
463
+ let canonical = projectRoot;
464
+ try {
465
+ canonical = realpathSync(projectRoot);
466
+ } catch {
467
+ }
468
+ return ` export ${PROJECT_EXECUTION_TRUST_ENV}=${JSON.stringify(canonical)}`;
469
+ }
470
+
471
+ // src/core/config/provider-registry-reload-invalidators.ts
472
+ var reloadInvalidators = /* @__PURE__ */ new Set();
473
+ function registerProviderRegistryReloadInvalidator(invalidator) {
474
+ reloadInvalidators.add(invalidator);
475
+ return () => {
476
+ reloadInvalidators.delete(invalidator);
477
+ };
478
+ }
479
+ function runProviderRegistryReloadInvalidators() {
480
+ for (const invalidator of reloadInvalidators) {
481
+ invalidator();
482
+ }
483
+ }
484
+
485
+ // src/core/config/provider-registry.ts
486
+ var __filename = fileURLToPath(import.meta.url);
487
+ function getEmbeddedProviderConfigPaths() {
488
+ const packageRoot = findPoeticPackageRoot(__filename);
489
+ if (!packageRoot) return [];
490
+ return [
491
+ // A source checkout authors the canonical YAML directly. Prefer it over the
492
+ // ignored generated asset so a stale prebuild output cannot shadow or break
493
+ // local authoring. The YAML path is not published in the npm package.
494
+ resolve3(packageRoot, ".poetic/config/providers.yaml"),
495
+ // Installed runtimes therefore require the packaged, digest-checked asset.
496
+ resolve3(packageRoot, ".poetic/providers/catalog.json")
497
+ ];
498
+ }
499
+ function getUserProviderRegistryPaths(cwd = process.cwd()) {
500
+ let home = "";
501
+ try {
502
+ home = homedir() ?? "";
503
+ } catch {
504
+ home = "";
505
+ }
506
+ if (!home) home = (process.env.HOME ?? process.env.USERPROFILE ?? "").trim();
507
+ const canonicalUserDir = getConfigPaths(cwd).userConfigDir;
508
+ const defaultUserDir = home ? join(home, ".poetic", "config") : "";
509
+ return [
510
+ join(canonicalUserDir, "providers.yaml"),
511
+ // ~/.config/poetic is the pre-default (XDG) registry location, kept as a
512
+ // compatibility fallback for the default layout only. An explicit
513
+ // POETIC_CONFIG_DIR/XDG root is authoritative and must not be contaminated
514
+ // by state from another user-config tree.
515
+ ...home && resolve3(canonicalUserDir) === resolve3(defaultUserDir) ? [join(home, ".config", "poetic", "providers.yaml")] : []
516
+ ];
517
+ }
518
+ function getConfiguredProviderRegistryPaths(cwd = process.cwd()) {
519
+ const projectRoot = findProjectRoot(cwd) ?? cwd;
520
+ return [
521
+ ...getUserProviderRegistryPaths(projectRoot),
522
+ resolveProvidersConfigPath({ cwd: projectRoot }),
523
+ resolve3(projectRoot, ".poetic", "config", "provider-registry.yaml.v1.backup")
524
+ ];
525
+ }
526
+ function getProviderRegistryInputPaths(cwd = process.cwd()) {
527
+ const projectRoot = findProjectRoot(cwd) ?? cwd;
528
+ return [
529
+ ...getEmbeddedProviderConfigPaths(),
530
+ resolve3(projectRoot, ".poetic", "cache", "model-update", "refresh-overlay.json"),
531
+ ...getConfiguredProviderRegistryPaths(projectRoot)
532
+ ];
533
+ }
534
+ var REMOVED_BUILTIN_PROVIDER_IDS = /* @__PURE__ */ new Set(["glm"]);
535
+ var PROJECT_POLICY_PROVIDER_FIELDS = [
536
+ "enabled",
537
+ "order",
538
+ "concurrency_hint",
539
+ "concurrency",
540
+ "timeout_ms",
541
+ "health_check_timeout_ms",
542
+ "memory",
543
+ "polling",
544
+ "bot_identity",
545
+ "env",
546
+ "retry",
547
+ "circuit_breaker",
548
+ "rate_limits",
549
+ "workspace_edits",
550
+ "generation",
551
+ "task_settings",
552
+ "options"
553
+ ];
554
+ var PROJECT_TRUSTED_EXTENSION_FIELDS = [
555
+ "transport",
556
+ "api",
557
+ "auth",
558
+ "cli",
559
+ "exec",
560
+ "engine",
561
+ "plugins",
562
+ "route_id",
563
+ "route",
564
+ "allow_unsafe_binary",
565
+ "requires",
566
+ "requires_if"
567
+ ];
568
+ var EXECUTION_SENSITIVE_PROVIDER_FIELDS = ["cli", "exec", "engine", "plugins"];
569
+ var CURSOR_ID_SYNTAX_ADMISSION_PATTERN = "^[a-z0-9][a-z0-9._-]{0,63}$";
570
+ var DateLikeStringSchema = z2.union([z2.string(), z2.date()]).transform((value) => value instanceof Date ? value.toISOString() : value);
571
+ function normalizeProviderConfigId(providerId) {
572
+ const normalized = providerId.trim().toLowerCase();
573
+ if (normalized === "cursor-cli") return "cursor";
574
+ if (normalized === "copilot-cli") return "copilot";
575
+ if (normalized === "anti-gravity" || normalized === "antigravity-cli" || normalized === "agy") {
576
+ return "antigravity";
577
+ }
578
+ return normalized;
579
+ }
580
+ function dropRemovedBuiltinProviders(raw) {
581
+ if (!raw || typeof raw !== "object") return raw;
582
+ const providers = raw.providers;
583
+ if (!providers || typeof providers !== "object") return raw;
584
+ for (const providerId of REMOVED_BUILTIN_PROVIDER_IDS) {
585
+ delete providers[providerId];
586
+ }
587
+ return raw;
588
+ }
589
+ function ensureCursorIdSyntaxAdmissionPattern(raw) {
590
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return raw;
591
+ const providers = raw.providers;
592
+ if (!providers || typeof providers !== "object" || Array.isArray(providers)) return raw;
593
+ const cursor = providers.cursor;
594
+ if (!cursor || typeof cursor !== "object" || Array.isArray(cursor)) return raw;
595
+ const models = cursor.models;
596
+ if (!models || typeof models !== "object" || Array.isArray(models)) return raw;
597
+ const patterns = models.allowed_patterns;
598
+ if (!Array.isArray(patterns)) return raw;
599
+ if (!patterns.every((pattern) => typeof pattern === "string")) return raw;
600
+ if (patterns.includes(CURSOR_ID_SYNTAX_ADMISSION_PATTERN)) return raw;
601
+ models.allowed_patterns = [
602
+ ...patterns,
603
+ CURSOR_ID_SYNTAX_ADMISSION_PATTERN
604
+ ];
605
+ return raw;
606
+ }
607
+ function projectProjectRegistryPolicy(projectRaw, embeddedRaw, options) {
608
+ if (!projectRaw || typeof projectRaw !== "object" || Array.isArray(projectRaw)) {
609
+ return projectRaw;
610
+ }
611
+ const embeddedProvidersValue = embeddedRaw && typeof embeddedRaw === "object" && !Array.isArray(embeddedRaw) ? embeddedRaw.providers : null;
612
+ if (!embeddedProvidersValue || typeof embeddedProvidersValue !== "object" || Array.isArray(embeddedProvidersValue)) {
613
+ return projectRaw;
614
+ }
615
+ const projectProvidersValue = projectRaw.providers;
616
+ if (!projectProvidersValue || typeof projectProvidersValue !== "object" || Array.isArray(projectProvidersValue)) {
617
+ return projectRaw;
618
+ }
619
+ const embeddedProviders = embeddedProvidersValue;
620
+ const projectedProviders = {};
621
+ for (const [providerId, providerValue] of Object.entries(
622
+ projectProvidersValue
623
+ )) {
624
+ if (!(providerId in embeddedProviders)) {
625
+ projectedProviders[providerId] = providerValue;
626
+ continue;
627
+ }
628
+ if (!providerValue || typeof providerValue !== "object" || Array.isArray(providerValue)) {
629
+ projectedProviders[providerId] = providerValue;
630
+ continue;
631
+ }
632
+ const sourceProvider = providerValue;
633
+ const provider = {};
634
+ for (const field of PROJECT_POLICY_PROVIDER_FIELDS) {
635
+ if (sourceProvider[field] !== void 0) provider[field] = sourceProvider[field];
636
+ }
637
+ if (options.trusted) {
638
+ for (const field of PROJECT_TRUSTED_EXTENSION_FIELDS) {
639
+ if (sourceProvider[field] !== void 0) provider[field] = sourceProvider[field];
640
+ }
641
+ } else if (sourceProvider.api && typeof sourceProvider.api === "object" && !Array.isArray(sourceProvider.api)) {
642
+ const sourceApi = sourceProvider.api;
643
+ const api = {};
644
+ for (const field of [
645
+ "stream",
646
+ "max_tokens",
647
+ "max_tool_iterations",
648
+ "per_tool_timeout_ms"
649
+ ]) {
650
+ if (sourceApi[field] !== void 0) api[field] = sourceApi[field];
651
+ }
652
+ if (Object.keys(api).length > 0) provider.api = api;
653
+ }
654
+ const modelsValue = sourceProvider.models;
655
+ if (modelsValue && typeof modelsValue === "object" && !Array.isArray(modelsValue)) {
656
+ const sourceModels = modelsValue;
657
+ const models = {};
658
+ for (const field of ["default", "default_reasoning_effort", "roles", "mappings"]) {
659
+ if (sourceModels[field] !== void 0) models[field] = sourceModels[field];
660
+ }
661
+ provider.models = models;
662
+ }
663
+ projectedProviders[providerId] = provider;
664
+ }
665
+ return {
666
+ providers: projectedProviders
667
+ };
668
+ }
669
+ function applyRefreshOverlay(baseRaw, overlay) {
670
+ if (!baseRaw || typeof baseRaw !== "object" || Array.isArray(baseRaw)) return baseRaw;
671
+ const base = structuredClone(baseRaw);
672
+ const providers = base.providers;
673
+ if (!providers || typeof providers !== "object" || Array.isArray(providers)) return baseRaw;
674
+ for (const [providerId, payload] of Object.entries(overlay.providers)) {
675
+ const provider = providers[providerId];
676
+ if (!provider || typeof provider !== "object" || Array.isArray(provider)) continue;
677
+ const providerObject = provider;
678
+ if (payload.models) {
679
+ const models = providerObject.models;
680
+ if (models && typeof models === "object" && !Array.isArray(models)) {
681
+ const modelObject = models;
682
+ if (payload.models.replaceInventory) {
683
+ modelObject.available = payload.models.available;
684
+ const access = modelObject.access;
685
+ if (access && typeof access === "object" && !Array.isArray(access)) {
686
+ const accessObject = access;
687
+ const overrides = accessObject.overrides;
688
+ if (overrides && typeof overrides === "object" && !Array.isArray(overrides)) {
689
+ const availableIds = new Set(payload.models.available.map((entry) => entry.id));
690
+ accessObject.overrides = Object.fromEntries(
691
+ Object.entries(overrides).filter(
692
+ ([modelId]) => availableIds.has(modelId)
693
+ )
694
+ );
695
+ }
696
+ }
697
+ } else {
698
+ const current = Array.isArray(modelObject.available) ? modelObject.available : [];
699
+ const overlayById = new Map(payload.models.available.map((entry) => [entry.id, entry]));
700
+ const merged = current.map((entry) => {
701
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry;
702
+ const id = entry.id;
703
+ const updated = typeof id === "string" ? overlayById.get(id) : void 0;
704
+ if (!updated) return entry;
705
+ overlayById.delete(id);
706
+ return { ...entry, ...updated };
707
+ });
708
+ modelObject.available = [...merged, ...overlayById.values()];
709
+ }
710
+ }
711
+ }
712
+ if (payload.pricing) {
713
+ const pricing = providerObject.pricing;
714
+ if (pricing && typeof pricing === "object" && !Array.isArray(pricing)) {
715
+ const pricingObject = pricing;
716
+ const currentModels = pricingObject.models && typeof pricingObject.models === "object" && !Array.isArray(pricingObject.models) ? pricingObject.models : {};
717
+ pricingObject.models = Object.fromEntries(
718
+ Object.entries({ ...currentModels, ...payload.pricing.models }).map(([id, row]) => [
719
+ id,
720
+ currentModels[id] && typeof currentModels[id] === "object" ? { ...currentModels[id], ...row } : row
721
+ ])
722
+ );
723
+ }
724
+ }
725
+ }
726
+ return base;
727
+ }
728
+ var RetryConfigSchema = z2.object({
729
+ max_attempts: z2.number().int().min(1).max(10),
730
+ initial_delay_ms: z2.number().int().min(0),
731
+ max_delay_ms: z2.number().int().min(0),
732
+ backoff_multiplier: z2.number().min(1)
733
+ }).strict();
734
+ var CircuitBreakerConfigSchema = z2.object({
735
+ failure_threshold: z2.number().int().min(1),
736
+ cooldown_ms: z2.number().int().min(0),
737
+ half_open_max_attempts: z2.number().int().min(1).optional()
738
+ }).strict();
739
+ var RateLimitEntrySchema = z2.object({
740
+ rpm: z2.number().int().min(1),
741
+ // Requests per minute
742
+ bucket_size: z2.number().int().min(1),
743
+ // Token bucket burst capacity
744
+ refill_rate: z2.number().min(0)
745
+ // Tokens per second
746
+ }).strict();
747
+ var RateLimitsConfigSchema = z2.object({
748
+ rpm: z2.number().int().min(1).optional(),
749
+ // Default RPM (convenience alias)
750
+ bucket_size: z2.number().int().min(1).optional(),
751
+ // Default bucket size
752
+ refill_rate: z2.number().min(0).optional(),
753
+ // Default refill rate
754
+ default: RateLimitEntrySchema.optional(),
755
+ // Explicit default config
756
+ models: z2.record(z2.string(), RateLimitEntrySchema).optional()
757
+ // Per-model overrides
758
+ }).strict();
759
+ var MemoryConfigSchema = z2.object({
760
+ warn_threshold: z2.number().min(0).max(1),
761
+ critical_threshold: z2.number().min(0).max(1),
762
+ emergency_threshold: z2.number().min(0).max(1),
763
+ max_processes: z2.number().int().min(1)
764
+ }).strict();
765
+ var PollingConfigSchema = z2.object({
766
+ initial_interval_ms: z2.number().int().min(0),
767
+ max_interval_ms: z2.number().int().min(0),
768
+ backoff_multiplier: z2.number().min(1),
769
+ timeout_ms: z2.number().int().min(0).optional(),
770
+ show_progress: z2.boolean()
771
+ }).strict();
772
+ var CLIConfigSchema = z2.object({
773
+ command: z2.string(),
774
+ binary: z2.string(),
775
+ install_command: z2.string().default(""),
776
+ // Installation metadata for setup automation
777
+ // - manual: show instructions only (no command execution)
778
+ // - curl: requires explicit opt-in via POETIC_ALLOW_CURL_BASH=1
779
+ install_method: z2.enum(["npm", "brew", "pipx", "curl", "manual"]).optional().default("manual"),
780
+ min_node_version: z2.string().optional(),
781
+ risk_level: z2.enum(["safe", "needs-confirmation"]).optional().default("safe"),
782
+ install_note: z2.string().optional()
783
+ }).strict();
784
+ var AuthConfigSchema = z2.object({
785
+ type: z2.enum(["cli_login", "api_key", "oauth", "cli_wrapper"]),
786
+ env_vars: z2.array(z2.string()),
787
+ skip_env_var: z2.string().optional(),
788
+ note: z2.string().optional()
789
+ }).strict();
790
+ var TemplatedAuthConfigSchema = AuthConfigSchema.default({
791
+ type: "cli_login",
792
+ env_vars: [],
793
+ skip_env_var: "POETIC_SKIP_AUTH"
794
+ });
795
+ var ProviderReleaseStatusSchema = z2.enum([
796
+ "primary_validated",
797
+ "supported_validated",
798
+ "supported_beta",
799
+ "experimental"
800
+ ]);
801
+ var JsonScalarSchema = z2.union([z2.string(), z2.number(), z2.boolean(), z2.null()]);
802
+ var ProbeExpectationSchema = z2.union([
803
+ JsonScalarSchema,
804
+ z2.object({
805
+ present: z2.boolean().optional(),
806
+ truthy: z2.boolean().optional(),
807
+ equals: JsonScalarSchema.optional()
808
+ }).strict()
809
+ ]);
810
+ var CommandProbeSchema = z2.object({
811
+ command_argv: z2.array(z2.string()).min(1),
812
+ parse_as: z2.enum(["json", "exit_code"]).optional().default("json"),
813
+ json_path: z2.string().optional(),
814
+ expect: ProbeExpectationSchema.optional(),
815
+ timeout_ms: z2.number().int().min(1).optional()
816
+ }).strict();
817
+ var ModelsDiscoverySchema = z2.object({
818
+ command_argv: z2.array(z2.string()).min(1),
819
+ json_path: z2.string().optional().default("$"),
820
+ id_path: z2.string().optional().default("id"),
821
+ ttl_hours: z2.number().positive().optional().default(24),
822
+ timeout_ms: z2.number().int().min(1).optional()
823
+ }).strict();
824
+ var LongContextPricingSchema = z2.object({
825
+ threshold_tokens: z2.number().int().optional(),
826
+ threshold: z2.number().int().optional(),
827
+ input_multiplier: z2.number().positive(),
828
+ output_multiplier: z2.number().positive(),
829
+ note: z2.string().optional()
830
+ }).strict().superRefine((value, ctx) => {
831
+ if (value.threshold_tokens === void 0 && value.threshold === void 0) {
832
+ ctx.addIssue({
833
+ code: z2.ZodIssueCode.custom,
834
+ message: "long_context_pricing requires threshold_tokens or threshold",
835
+ path: ["threshold_tokens"]
836
+ });
837
+ }
838
+ }).transform((value) => ({
839
+ threshold_tokens: value.threshold_tokens ?? value.threshold,
840
+ input_multiplier: value.input_multiplier,
841
+ output_multiplier: value.output_multiplier,
842
+ ...value.note ? { note: value.note } : {}
843
+ }));
844
+ var ModelInfoSchema = z2.object({
845
+ id: z2.string().trim().min(1),
846
+ display_name: z2.string(),
847
+ full_name: z2.string().optional(),
848
+ capabilities: z2.array(z2.string()),
849
+ context_window: z2.number().int().optional(),
850
+ long_context_pricing: LongContextPricingSchema.optional(),
851
+ context_window_beta: z2.object({
852
+ max_tokens: z2.number().int(),
853
+ beta_header: z2.string(),
854
+ pricing_note: z2.string().optional()
855
+ }).optional(),
856
+ max_output_tokens: z2.number().int().optional(),
857
+ /**
858
+ * Claude-CLI context-window selector to append to this model's `--model`
859
+ * value (only `[1m]` exists today).
860
+ *
861
+ * Deliberately top-level: the selector applies on every CLI backend, so
862
+ * nesting it under `bedrock` made it structurally impossible to declare for
863
+ * Anthropic first-party or Vertex. The nested
864
+ * `bedrock.claude_cli_context_selector` is still read as a fallback for
865
+ * configs written against the old shape.
866
+ *
867
+ * The backends are NOT identical, which is why one field plus a per-backend
868
+ * application rule beats duplicating it. What we actually know:
869
+ * - Bedrock — TESTED (live probes 2026-07-26). opus-5 / fable-5 / opus-4-8 /
870
+ * opus-4-7 / opus-4-6 / sonnet-4-6 report 200K bare and need the suffix;
871
+ * sonnet-5 is 1M bare.
872
+ * - Anthropic first-party — TESTED (live probes 2026-07-26, clean HOME so
873
+ * only the API key could authenticate). opus-5 / sonnet-5 / fable-5 /
874
+ * opus-4-8 / opus-4-7 are already 1M BARE; only opus-4-6 and sonnet-4-6
875
+ * report 200K and need the suffix. Appending to an already-1M model is a
876
+ * no-op we confirmed.
877
+ * - Vertex — NOT TESTED. No Google Cloud credits, so no probe has run. It is
878
+ * included on the strength of Anthropic's documentation, which says the
879
+ * same models support 1M there and that a model ID without `[1m]` uses
880
+ * 200K on Vertex. Documentation, not measurement.
881
+ *
882
+ * Present ONLY for models where the selector is necessary on at least one
883
+ * backend. Models at 1M unsuffixed everywhere (claude-sonnet-5) omit it, as do
884
+ * models whose declared window is 200K.
885
+ *
886
+ * `z.literal` + the surrounding `.strict()` are load-bearing: without them a
887
+ * misspelled key or value is accepted and silently dropped, which looks
888
+ * identical to "this model does not need the selector".
889
+ */
890
+ claude_cli_context_selector: z2.literal("[1m]").optional(),
891
+ bedrock: z2.object({
892
+ base_model_id: z2.string(),
893
+ global: z2.string().optional(),
894
+ us: z2.string().optional(),
895
+ eu: z2.string().optional(),
896
+ jp: z2.string().optional(),
897
+ apac: z2.string().optional(),
898
+ /**
899
+ * Deprecated location for {@link ModelInfoSchema}'s top-level
900
+ * `claude_cli_context_selector`. Retained so existing/consumer configs
901
+ * keep working; new entries declare the top-level field instead.
902
+ */
903
+ claude_cli_context_selector: z2.literal("[1m]").optional()
904
+ }).strict().optional(),
905
+ thinking: z2.object({
906
+ supported: z2.boolean().optional(),
907
+ adaptive: z2.boolean().optional(),
908
+ budget_tokens_supported: z2.boolean().optional(),
909
+ min_budget_tokens: z2.number().int().optional(),
910
+ default_budget_tokens: z2.number().int().optional(),
911
+ max_budget_tokens: z2.number().int().optional()
912
+ }).optional(),
913
+ reasoning_effort_levels: z2.array(z2.string()).optional(),
914
+ // Templated CLI provider support (Phase 1)
915
+ canonical_id: z2.string().optional(),
916
+ // Stable identity for comparisons (e.g., "claude-sonnet-4-5")
917
+ routing_id: z2.string().optional(),
918
+ // Actual ID passed to CLI (e.g., "anthropic/claude-sonnet-4-5")
919
+ notes: z2.string().optional(),
920
+ deprecation: z2.record(z2.string(), z2.unknown()).optional(),
921
+ _model_update: z2.record(z2.string(), z2.unknown()).optional()
922
+ }).strict();
923
+ var ModelAccessClassSchema = z2.enum(["first_party_pool", "premium_pool"]);
924
+ var ModelAccessConfigSchema = z2.object({
925
+ default: ModelAccessClassSchema,
926
+ overrides: z2.record(z2.string().trim().min(1), ModelAccessClassSchema).default({})
927
+ }).strict();
928
+ var ModelsConfigSchema = z2.object({
929
+ default: z2.string().trim().min(1),
930
+ default_reasoning_effort: z2.string().optional(),
931
+ roles: z2.record(z2.string().trim().min(1), z2.string().trim().min(1)).optional().default({}),
932
+ allowed_patterns: z2.array(z2.string()),
933
+ mappings: z2.record(z2.string().trim().min(1), z2.string().trim().min(1)),
934
+ // Zod v4: explicit key and value schemas
935
+ available: z2.array(ModelInfoSchema),
936
+ /**
937
+ * Admission policy for the exact-model invoke bridge.
938
+ *
939
+ * A provider whose `allowed_patterns` deliberately admit bounded future model-id
940
+ * SYNTAX (so a newly released id works before the catalog is refreshed) accepts ids
941
+ * that are well-formed but not in `available`. That is correct for ordinary
942
+ * execution and wrong for an exact pin, where a typo should be rejected before
943
+ * spawn rather than handed to the CLI.
944
+ *
945
+ * Set this on such a provider to make the exact bridge additionally require the
946
+ * resolved id to be present in the effective inventory. Providers that do not admit
947
+ * syntax-only ids leave it false and keep their declared resolution contract.
948
+ *
949
+ * This is model-resolution admission policy, NOT a runtime CLI quirk, so it belongs
950
+ * here rather than behind `getProviderRuntimeQuirks()`.
951
+ */
952
+ exact_invoke_requires_inventory: z2.boolean().optional().default(false),
953
+ access: ModelAccessConfigSchema.optional(),
954
+ discovery: ModelsDiscoverySchema.optional()
955
+ }).strict().superRefine((models, ctx) => {
956
+ if (!models.access) return;
957
+ const availableIds = new Set(models.available.map((model) => model.id));
958
+ for (const modelId of Object.keys(models.access.overrides)) {
959
+ if (!availableIds.has(modelId)) {
960
+ ctx.addIssue({
961
+ code: z2.ZodIssueCode.custom,
962
+ message: `models.access override references unavailable model: ${modelId}`,
963
+ path: ["access", "overrides", modelId]
964
+ });
965
+ }
966
+ }
967
+ });
968
+ var TemplatedModelsConfigSchema = z2.object({
969
+ default: z2.string().trim().min(1),
970
+ default_reasoning_effort: z2.string().optional(),
971
+ roles: z2.record(z2.string().trim().min(1), z2.string().trim().min(1)).optional().default({}),
972
+ allowed_patterns: z2.array(z2.string()).default([".*"]),
973
+ mappings: z2.record(z2.string().trim().min(1), z2.string().trim().min(1)).default({}),
974
+ available: z2.array(ModelInfoSchema).default([]),
975
+ /**
976
+ * See `ModelsConfigSchema.exact_invoke_requires_inventory`. Declared here too so the
977
+ * flag is readable off the `ProviderConfig` union without narrowing to the native
978
+ * branch first. It matters at least as much for templated providers, whose
979
+ * `allowed_patterns` default to `['.*']` and therefore admit any syntax.
980
+ */
981
+ exact_invoke_requires_inventory: z2.boolean().optional().default(false),
982
+ access: ModelAccessConfigSchema.optional(),
983
+ discovery: ModelsDiscoverySchema.optional()
984
+ }).strict().superRefine((models, ctx) => {
985
+ if (!models.access) return;
986
+ const availableIds = new Set(models.available.map((model) => model.id));
987
+ for (const modelId of Object.keys(models.access.overrides)) {
988
+ if (!availableIds.has(modelId)) {
989
+ ctx.addIssue({
990
+ code: z2.ZodIssueCode.custom,
991
+ message: `models.access override references unavailable model: ${modelId}`,
992
+ path: ["access", "overrides", modelId]
993
+ });
994
+ }
995
+ }
996
+ });
997
+ var TuiConversationOperationSchema = z2.enum(["start", "load/resume", "prompt", "cancel"]);
998
+ var TuiConversationCapabilityConfigSchema = z2.object({
999
+ operations: z2.array(TuiConversationOperationSchema).min(1),
1000
+ output: z2.enum(["streaming", "buffered"]),
1001
+ read_only: z2.enum(["enforced", "unproven"]),
1002
+ qualification: z2.enum(["version", "handshake"]).optional()
1003
+ }).strict();
1004
+ var CapabilitiesConfigSchema = z2.object({
1005
+ streaming: z2.boolean(),
1006
+ tool_use: z2.boolean(),
1007
+ vision: z2.boolean(),
1008
+ function_calling: z2.boolean(),
1009
+ // Provider has some historically tracked subagent-capable behavior.
1010
+ sub_agents: z2.boolean().optional().default(false),
1011
+ // Poetic can invoke provider-native subagents for `run --subagents`.
1012
+ provider_native_subagents: z2.boolean().optional().default(false),
1013
+ // Provider-level execution capabilities (narrow matrix — model-level traits are out of scope)
1014
+ // requires_pty: provider CLI needs a PTY for headless runs
1015
+ requires_pty: z2.boolean().optional(),
1016
+ // owns_rate_limit_token: provider enforces its own rate limit / handles 429 internally
1017
+ owns_rate_limit_token: z2.boolean().optional(),
1018
+ // supports_api_judge: provider has a non-CLI API channel usable by the judge/synthesis path
1019
+ supports_api_judge: z2.boolean().optional(),
1020
+ // supports_tui_agent_actions: provider may propose bounded TUI agent actions
1021
+ supports_tui_agent_actions: z2.boolean().optional(),
1022
+ // supports_ask_consult: provider has a tested read-only one-shot consultation path
1023
+ supports_ask_consult: z2.boolean().optional(),
1024
+ // requires_sandbox_interlock: provider must verify outer sandbox before spawning
1025
+ requires_sandbox_interlock: z2.boolean().optional(),
1026
+ // native_model_fallback: provider CLI supports a native fallback-model flag
1027
+ // (e.g. Claude's --fallback-model). Gates role-candidate `fallbackModelRole`.
1028
+ native_model_fallback: z2.boolean().optional(),
1029
+ // Persistent TUI conversation support is a cohesive adapter contract rather
1030
+ // than a set of independent booleans. Eligibility still requires runtime
1031
+ // readiness, qualification (when declared), and enforced read-only posture.
1032
+ tui_conversation: TuiConversationCapabilityConfigSchema.optional()
1033
+ }).strict();
1034
+ var TemplatedCapabilitiesConfigSchema = z2.object({
1035
+ streaming: z2.boolean().default(false),
1036
+ tool_use: z2.boolean().default(false),
1037
+ vision: z2.boolean().default(false),
1038
+ function_calling: z2.boolean().default(false),
1039
+ // Provider has some historically tracked subagent-capable behavior.
1040
+ sub_agents: z2.boolean().default(false),
1041
+ // Poetic can invoke provider-native subagents for `run --subagents`.
1042
+ provider_native_subagents: z2.boolean().default(false),
1043
+ // Provider-level execution capabilities (narrow matrix — model-level traits are out of scope)
1044
+ requires_pty: z2.boolean().optional(),
1045
+ owns_rate_limit_token: z2.boolean().optional(),
1046
+ supports_api_judge: z2.boolean().optional(),
1047
+ supports_tui_agent_actions: z2.boolean().optional(),
1048
+ supports_ask_consult: z2.boolean().optional(),
1049
+ requires_sandbox_interlock: z2.boolean().optional(),
1050
+ native_model_fallback: z2.boolean().optional(),
1051
+ tui_conversation: TuiConversationCapabilityConfigSchema.optional()
1052
+ }).strict().default({
1053
+ streaming: false,
1054
+ tool_use: false,
1055
+ vision: false,
1056
+ function_calling: false,
1057
+ sub_agents: false,
1058
+ provider_native_subagents: false
1059
+ });
1060
+ var BotIdentityConfigSchema = z2.object({
1061
+ display_name: z2.string(),
1062
+ usernames: z2.array(z2.string())
1063
+ }).strict();
1064
+ var EnvConfigSchema = z2.record(z2.string(), z2.string());
1065
+ var ModelPricingSchema = z2.object({
1066
+ // Prices may be stored as strings for precision/deterministic diffs (e.g. "3.00").
1067
+ // Normalize to numbers at load time for runtime cost calculation.
1068
+ input_per_1m_tokens: z2.union([z2.number(), z2.string()]).transform((value) => typeof value === "string" ? Number(value) : value).pipe(z2.number().min(0)).optional(),
1069
+ output_per_1m_tokens: z2.union([z2.number(), z2.string()]).transform((value) => typeof value === "string" ? Number(value) : value).pipe(z2.number().min(0)).optional(),
1070
+ cache_read_per_1m_tokens: z2.union([z2.number(), z2.string()]).transform((value) => typeof value === "string" ? Number(value) : value).pipe(z2.number().min(0)).optional(),
1071
+ cache_write_per_1m_tokens: z2.union([z2.number(), z2.string()]).transform((value) => typeof value === "string" ? Number(value) : value).pipe(z2.number().min(0)).optional(),
1072
+ input_per_1k_tokens: z2.union([z2.number(), z2.string()]).transform((value) => typeof value === "string" ? Number(value) : value).pipe(z2.number().min(0)).optional(),
1073
+ output_per_1k_tokens: z2.union([z2.number(), z2.string()]).transform((value) => typeof value === "string" ? Number(value) : value).pipe(z2.number().min(0)).optional(),
1074
+ base_rate_per_1k_tokens: z2.union([z2.number(), z2.string()]).transform((value) => typeof value === "string" ? Number(value) : value).pipe(z2.number().min(0)).optional(),
1075
+ premium_multiplier: z2.union([z2.number(), z2.string()]).transform((value) => typeof value === "string" ? Number(value) : value).pipe(z2.number().min(0)).optional(),
1076
+ context_window: z2.number().int().optional(),
1077
+ long_context_pricing: LongContextPricingSchema.optional(),
1078
+ features: z2.record(z2.string(), z2.boolean()).optional(),
1079
+ // Telemetry-only placeholder: pricing is intentionally absent and
1080
+ // missing-pricing telemetry errors log at debug instead of warn.
1081
+ non_metered: z2.boolean().optional(),
1082
+ notes: z2.string().optional(),
1083
+ last_updated: DateLikeStringSchema.optional(),
1084
+ _meta: z2.record(z2.string(), z2.unknown()).optional()
1085
+ }).strict();
1086
+ var ToolPricingSchema = z2.object({
1087
+ cost_per_request: z2.number().min(0).optional(),
1088
+ cost_per_read_1m_tokens: z2.number().min(0).optional(),
1089
+ cost_per_write_1m_tokens: z2.number().min(0).optional(),
1090
+ unit: z2.string().optional(),
1091
+ notes: z2.string().optional(),
1092
+ available_in: z2.array(z2.string()).optional()
1093
+ }).strict();
1094
+ var SubscriptionPricingSchema = z2.object({
1095
+ monthly_cost: z2.number().min(0).optional(),
1096
+ included_credits: z2.number().min(0).optional(),
1097
+ overage_rate_per_credit: z2.number().min(0).optional(),
1098
+ individual_monthly: z2.number().min(0).optional(),
1099
+ business_monthly_per_user: z2.number().min(0).optional(),
1100
+ enterprise_monthly_per_user: z2.number().min(0).optional()
1101
+ }).strict();
1102
+ var InfrastructurePricingSchema = z2.object({
1103
+ cloud_execution_per_minute: z2.number().min(0).optional(),
1104
+ premium_execution_per_minute: z2.number().min(0).optional(),
1105
+ proxy_routing_per_request: z2.number().min(0).optional(),
1106
+ notes: z2.string().optional()
1107
+ }).strict();
1108
+ var ProviderPricingSchema = z2.object({
1109
+ billing_mode: z2.enum(["metered", "subscription", "hybrid"]),
1110
+ currency: z2.string(),
1111
+ last_updated: DateLikeStringSchema.optional(),
1112
+ notes: z2.string().optional(),
1113
+ exchange_rate_note: z2.string().optional(),
1114
+ models: z2.record(z2.string(), ModelPricingSchema).optional(),
1115
+ tools: z2.record(z2.string(), ToolPricingSchema).optional(),
1116
+ subscription: SubscriptionPricingSchema.optional(),
1117
+ infrastructure: InfrastructurePricingSchema.optional(),
1118
+ features: z2.record(z2.string(), z2.unknown()).optional(),
1119
+ _meta: z2.record(z2.string(), z2.unknown()).optional()
1120
+ }).strict();
1121
+ var RefreshStrategyConfigSchema = z2.discriminatedUnion("kind", [
1122
+ z2.object({
1123
+ kind: z2.literal("direct"),
1124
+ // Deterministic models API to poll; absent = doc-poll only (e.g. xAI).
1125
+ models_api: z2.enum(["anthropic", "openai", "google"]).optional(),
1126
+ doc_poll: z2.boolean(),
1127
+ cli_inventory: z2.enum(["cursor", "grok"]).optional()
1128
+ }).strict(),
1129
+ z2.object({ kind: z2.literal("aggregator") }).strict(),
1130
+ z2.object({
1131
+ kind: z2.literal("static"),
1132
+ reason: z2.string().trim().min(1).optional(),
1133
+ cli_inventory: z2.enum(["cursor", "grok"]).optional()
1134
+ }).strict()
1135
+ ]);
1136
+ var DefaultPricingSchema = z2.object({
1137
+ billing_mode: z2.string(),
1138
+ currency: z2.string(),
1139
+ unit: z2.string()
1140
+ }).strict();
1141
+ var ConcurrencyConfigSchema = z2.object({
1142
+ max: z2.number().int().min(1),
1143
+ hybrid_batching: z2.boolean().optional().default(false),
1144
+ rationale: z2.string().trim().min(1)
1145
+ }).strict();
1146
+ var RouteConfigSchema = z2.object({
1147
+ // Environment variables to inject (e.g., API keys, endpoints)
1148
+ env: z2.record(z2.string(), z2.string()).optional(),
1149
+ // Auth commands to run before execution.
1150
+ //
1151
+ // SECURITY: Prefer argv form (auth_check_argv/auth_command_argv). String form is
1152
+ // treated as guidance-only and is not executed by Poetic.
1153
+ auth_check: z2.string().optional(),
1154
+ auth_command: z2.string().optional(),
1155
+ auth_clear: z2.string().optional(),
1156
+ auth_check_argv: z2.array(z2.string()).optional(),
1157
+ auth_command_argv: z2.array(z2.string()).optional(),
1158
+ auth_clear_argv: z2.array(z2.string()).optional(),
1159
+ auth_probe: CommandProbeSchema.optional(),
1160
+ // Model ID transform function name (if custom logic needed)
1161
+ model_transform: z2.string().optional()
1162
+ }).strict();
1163
+ var WorkspaceEditsConfigSchema = z2.object({
1164
+ // Detection mode: 'passthrough' (git-only), 'structured' (JSONL), or 'text-only' (analysis mode)
1165
+ mode: z2.enum(["passthrough", "structured", "text-only"]),
1166
+ // Whether to inject JSONL format instructions into prompts
1167
+ inject_jsonl: z2.boolean().optional(),
1168
+ // Whether to enforce FILE: specification in prompts
1169
+ enforce_file_targets: z2.boolean().optional()
1170
+ }).strict();
1171
+ var GenerationConfigSchema = z2.object({
1172
+ // Temperature controls output randomness (0.0 = deterministic, 1.0+ = creative)
1173
+ // For code generation, 0.2-0.4 is recommended for more deterministic output
1174
+ temperature: z2.number().min(0).max(2).optional(),
1175
+ // Nucleus sampling threshold (0.0-1.0)
1176
+ top_p: z2.number().min(0).max(1).optional(),
1177
+ // Top-k sampling (limits token choices)
1178
+ top_k: z2.number().int().min(1).optional(),
1179
+ // Maximum output tokens
1180
+ max_output_tokens: z2.number().int().min(1).optional()
1181
+ }).strict();
1182
+ var TaskSettingsSchema = z2.record(
1183
+ z2.string(),
1184
+ z2.object({
1185
+ temperature: z2.number().min(0).max(2).optional(),
1186
+ top_p: z2.number().min(0).max(1).optional(),
1187
+ top_k: z2.number().int().min(1).optional(),
1188
+ reasoning_effort: z2.preprocess((value) => {
1189
+ if (value === void 0 || value === null) return void 0;
1190
+ const normalized = normalizeReasoningEffortInput(value);
1191
+ return normalized ?? value;
1192
+ }, z2.enum(["low", "medium", "high", "xhigh", "max"]).optional()),
1193
+ thinking_budget: z2.number().int().min(1).optional()
1194
+ }).strict()
1195
+ ).optional();
1196
+ var PluginVerifySchema = z2.object({
1197
+ // Command to run for verification (e.g., "provider-plugin --version")
1198
+ command: z2.string().optional(),
1199
+ // File path that should exist (e.g., "~/.config/plugin/config.json")
1200
+ file: z2.string().optional(),
1201
+ // Pattern to match in command output
1202
+ pattern: z2.string().optional()
1203
+ }).strict();
1204
+ var PluginConfigureStepSchema = z2.object({
1205
+ // Description of what this step does
1206
+ description: z2.string(),
1207
+ // Command to run (if automated)
1208
+ command: z2.string().optional(),
1209
+ // Manual instructions (if user action required)
1210
+ instructions: z2.string().optional()
1211
+ }).strict();
1212
+ var RequirementSchema = z2.union([
1213
+ z2.object({ provider: z2.string() }).strict(),
1214
+ z2.object({ plugin: z2.string() }).strict(),
1215
+ z2.object({ binary: z2.string() }).strict()
1216
+ ]);
1217
+ var PluginSchema = z2.object({
1218
+ // Unique identifier (e.g., "provider-plugin")
1219
+ id: z2.string(),
1220
+ // Display name (e.g., "Provider Plugin")
1221
+ name: z2.string(),
1222
+ // Human-readable description
1223
+ description: z2.string(),
1224
+ // Plugin type (free-form: 'auth', 'tools', 'slash', 'agents', etc.)
1225
+ type: z2.string(),
1226
+ // Installation command
1227
+ install_command: z2.string(),
1228
+ // Installation method
1229
+ install_method: z2.enum(["npm", "brew", "pipx", "curl", "manual"]),
1230
+ // Risk level for user confirmation
1231
+ risk_level: z2.enum(["safe", "needs-confirmation"]),
1232
+ // Verification checks
1233
+ verify: PluginVerifySchema.optional(),
1234
+ // Configuration steps (optional)
1235
+ configure: z2.array(PluginConfigureStepSchema).optional(),
1236
+ // Plugin dependencies (optional)
1237
+ requires: z2.array(RequirementSchema).optional()
1238
+ }).strict();
1239
+ var ProviderOptionSchema = z2.object({
1240
+ // Option type
1241
+ type: z2.enum(["enum", "string", "bool"]),
1242
+ // Allowed values (for enum type)
1243
+ allowed: z2.array(z2.string()).optional(),
1244
+ // Default value
1245
+ default: z2.union([z2.string(), z2.boolean()]),
1246
+ // Description (shown in wizard)
1247
+ description: z2.string()
1248
+ }).strict();
1249
+ var ProviderOptionsSchema = z2.record(z2.string(), ProviderOptionSchema);
1250
+ var ConditionalRequiresSchema = z2.record(z2.string(), z2.array(RequirementSchema));
1251
+ var ProviderRequiresSchema = z2.object({
1252
+ // Always-required dependencies
1253
+ requires: z2.array(RequirementSchema).optional(),
1254
+ // Conditionally-required dependencies based on option values
1255
+ requires_if: ConditionalRequiresSchema.optional()
1256
+ }).strict();
1257
+ var ApiConfigSchema = z2.object({
1258
+ /** API base URL (host only, e.g., "https://api.anthropic.com"). */
1259
+ base_url: z2.url(),
1260
+ /** Environment variable name containing the API key. */
1261
+ api_key_env_var: z2.string(),
1262
+ /** Whether to use streaming responses (default: true). */
1263
+ stream: z2.boolean().optional().default(true),
1264
+ /** Additional HTTP headers to send with requests. */
1265
+ headers: z2.record(z2.string(), z2.string()).optional(),
1266
+ /** Max output tokens per API call. */
1267
+ max_tokens: z2.number().int().positive().optional(),
1268
+ /** Max tool-use iterations in the agentic loop (default: 50). */
1269
+ max_tool_iterations: z2.number().int().min(1).max(200).optional().default(50),
1270
+ /** Timeout per individual tool execution in ms (default: 30000). */
1271
+ per_tool_timeout_ms: z2.number().int().min(1e3).optional().default(3e4)
1272
+ }).strict().optional();
1273
+ var TemplatedCLIExecutionSchema = z2.object({
1274
+ // Base command arguments (before prompt)
1275
+ args: z2.array(z2.string()),
1276
+ // Command-line flags (e.g., {"--quiet": true, "--cwd": "{{workspace}}"})
1277
+ flags: z2.record(z2.string(), z2.union([z2.boolean(), z2.string()])).optional(),
1278
+ // Prompt placement: 'positional' (in args array) or 'stdin'
1279
+ prompt_placement: z2.enum(["positional", "stdin"]),
1280
+ // Whether to add "--" before the prompt when using positional prompt placement.
1281
+ // Defaults to true (safer); set false for CLIs that don't support "--".
1282
+ double_dash_before_prompt: z2.boolean().optional(),
1283
+ // Whether stdin is supported as fallback
1284
+ stdin_fallback: z2.boolean().optional(),
1285
+ // Template variables available for interpolation
1286
+ // (e.g., {{prompt}}, {{model.routing_id}}, {{workspace}})
1287
+ template_vars: z2.array(z2.string()).optional()
1288
+ }).strict();
1289
+ var NativeProviderConfigSchema = z2.object({
1290
+ // Basic metadata
1291
+ id: z2.string(),
1292
+ name: z2.string(),
1293
+ display_name: z2.string(),
1294
+ description: z2.string(),
1295
+ vendor: z2.string(),
1296
+ enabled: z2.boolean(),
1297
+ experimental: z2.boolean(),
1298
+ release_status: ProviderReleaseStatusSchema.optional(),
1299
+ order: z2.number().int(),
1300
+ // Provider type and transport
1301
+ type: z2.enum(["cli", "api", "cloud_cli", "cli_wrapper"]),
1302
+ transport: z2.enum(["cli", "api", "hybrid"]),
1303
+ channels: z2.array(z2.string()),
1304
+ // CLI configuration
1305
+ cli: CLIConfigSchema,
1306
+ // API transport configuration (optional, for direct API inference)
1307
+ api: ApiConfigSchema,
1308
+ // Authentication
1309
+ auth: AuthConfigSchema,
1310
+ // Models
1311
+ models: ModelsConfigSchema,
1312
+ // Capabilities
1313
+ capabilities: CapabilitiesConfigSchema,
1314
+ // Performance
1315
+ concurrency_hint: z2.enum(["low", "medium", "high"]),
1316
+ concurrency: ConcurrencyConfigSchema.optional(),
1317
+ // Timeouts
1318
+ timeout_ms: z2.number().int().min(1),
1319
+ health_check_timeout_ms: z2.number().int().min(1).optional(),
1320
+ // Memory management
1321
+ memory: MemoryConfigSchema,
1322
+ // Polling (optional, for cloud providers)
1323
+ polling: PollingConfigSchema.optional(),
1324
+ // Bot identity (optional, for cloud providers)
1325
+ bot_identity: BotIdentityConfigSchema.optional(),
1326
+ // Environment variables
1327
+ env: EnvConfigSchema,
1328
+ // Retry and circuit breaker (optional overrides)
1329
+ retry: RetryConfigSchema.optional(),
1330
+ circuit_breaker: CircuitBreakerConfigSchema.optional(),
1331
+ // Rate limits (optional overrides, new in v2.1)
1332
+ rate_limits: RateLimitsConfigSchema.optional(),
1333
+ // Pricing (optional, new in v2.0)
1334
+ pricing: ProviderPricingSchema.optional(),
1335
+ // Refresh strategy for `poetic provider refresh` (optional; providers
1336
+ // without a declaration are treated as static by the refresh dispatcher).
1337
+ refresh_strategy: RefreshStrategyConfigSchema.optional(),
1338
+ // Engine type. 'templated_cli' is DEPRECATED: the templated CLI engine was
1339
+ // removed (2026-06) and providers declaring it are no longer registered —
1340
+ // the registry emits a TMPL-001 warning instead. The value stays in the
1341
+ // schema only so user overlays still validate and the project-config
1342
+ // trust-gating security checks below keep rejecting untrusted templated
1343
+ // providers explicitly rather than failing on an unknown enum value.
1344
+ engine: z2.enum(["native", "templated_cli"]).optional().default("native"),
1345
+ // Templated CLI execution config (deprecated with engine=templated_cli)
1346
+ exec: TemplatedCLIExecutionSchema.optional(),
1347
+ // Route configuration (for model ID transforms and env injection)
1348
+ route_id: z2.string().optional(),
1349
+ // Reference to named route (future: top-level routes: section)
1350
+ route: RouteConfigSchema.optional(),
1351
+ // Inline route override
1352
+ // Workspace edit detection strategy
1353
+ workspace_edits: WorkspaceEditsConfigSchema.optional(),
1354
+ // Generation parameters (temperature, topP, etc.)
1355
+ generation: GenerationConfigSchema.optional(),
1356
+ // Task-type-aware generation settings (overrides generation defaults)
1357
+ task_settings: TaskSettingsSchema,
1358
+ // Binary allowlist for security (only used if engine=templated_cli)
1359
+ allow_unsafe_binary: z2.boolean().optional().default(false),
1360
+ // Explicit opt-in for non-allowlisted binaries
1361
+ // Plugin system (generic, any provider)
1362
+ plugins: z2.array(PluginSchema).optional(),
1363
+ // Provider options (generic, any provider)
1364
+ options: ProviderOptionsSchema.optional(),
1365
+ // Dependency management (generic, any provider)
1366
+ requires: z2.array(RequirementSchema).optional(),
1367
+ requires_if: ConditionalRequiresSchema.optional()
1368
+ }).strict();
1369
+ var TemplatedProviderConfigSchema = z2.object({
1370
+ // Basic metadata
1371
+ id: z2.string(),
1372
+ name: z2.string(),
1373
+ display_name: z2.string().optional().default(""),
1374
+ description: z2.string().optional().default(""),
1375
+ vendor: z2.string().optional().default("custom"),
1376
+ enabled: z2.boolean().optional().default(true),
1377
+ experimental: z2.boolean().optional().default(false),
1378
+ release_status: ProviderReleaseStatusSchema.optional(),
1379
+ order: z2.number().int().optional().default(99),
1380
+ // Provider type and transport
1381
+ type: z2.enum(["cli", "api", "cloud_cli", "cli_wrapper"]).optional().default("cli_wrapper"),
1382
+ transport: z2.enum(["cli", "api", "hybrid"]).optional().default("cli"),
1383
+ channels: z2.array(z2.string()).optional().default(["cli"]),
1384
+ // CLI configuration
1385
+ cli: CLIConfigSchema,
1386
+ // API transport configuration (optional, for direct API inference)
1387
+ api: ApiConfigSchema,
1388
+ // Authentication
1389
+ auth: TemplatedAuthConfigSchema,
1390
+ // Models
1391
+ models: TemplatedModelsConfigSchema,
1392
+ // Capabilities
1393
+ capabilities: TemplatedCapabilitiesConfigSchema,
1394
+ // Performance
1395
+ concurrency_hint: z2.enum(["low", "medium", "high"]).optional().default("low"),
1396
+ concurrency: ConcurrencyConfigSchema.optional(),
1397
+ // Timeouts
1398
+ timeout_ms: z2.number().int().min(1).optional().default(6e5),
1399
+ health_check_timeout_ms: z2.number().int().min(1).optional(),
1400
+ // Memory management
1401
+ memory: MemoryConfigSchema.default({
1402
+ warn_threshold: 0.85,
1403
+ critical_threshold: 0.9,
1404
+ emergency_threshold: 0.95,
1405
+ max_processes: 3
1406
+ }),
1407
+ // Polling (optional, for cloud providers)
1408
+ polling: PollingConfigSchema.optional(),
1409
+ // Bot identity (optional, for cloud providers)
1410
+ bot_identity: BotIdentityConfigSchema.optional(),
1411
+ // Environment variables
1412
+ env: EnvConfigSchema.default({}),
1413
+ // Retry and circuit breaker (optional overrides)
1414
+ retry: RetryConfigSchema.optional(),
1415
+ circuit_breaker: CircuitBreakerConfigSchema.optional(),
1416
+ // Rate limits (optional overrides)
1417
+ rate_limits: RateLimitsConfigSchema.optional(),
1418
+ // Pricing (optional)
1419
+ pricing: ProviderPricingSchema.optional(),
1420
+ // Engine selection (templated)
1421
+ engine: z2.literal("templated_cli"),
1422
+ // Templated CLI execution config (required)
1423
+ exec: TemplatedCLIExecutionSchema,
1424
+ // Route configuration (optional)
1425
+ route_id: z2.string().optional(),
1426
+ route: RouteConfigSchema.optional(),
1427
+ // Workspace edit detection strategy (optional)
1428
+ workspace_edits: WorkspaceEditsConfigSchema.optional(),
1429
+ // Generation parameters (temperature, topP, etc.)
1430
+ generation: GenerationConfigSchema.optional(),
1431
+ // Task-type-aware generation settings (overrides generation defaults)
1432
+ task_settings: TaskSettingsSchema,
1433
+ // Binary allowlist override
1434
+ allow_unsafe_binary: z2.boolean().optional().default(false),
1435
+ // Plugin system (generic, any provider)
1436
+ plugins: z2.array(PluginSchema).optional(),
1437
+ // Provider options (generic, any provider)
1438
+ options: ProviderOptionsSchema.optional(),
1439
+ // Dependency management (generic, any provider)
1440
+ requires: z2.array(RequirementSchema).optional(),
1441
+ requires_if: ConditionalRequiresSchema.optional()
1442
+ }).strict().transform((provider) => ({
1443
+ ...provider,
1444
+ display_name: provider.display_name?.trim() ? provider.display_name : provider.name,
1445
+ description: provider.description ?? ""
1446
+ }));
1447
+ var ProviderConfigSchema = z2.union([
1448
+ TemplatedProviderConfigSchema,
1449
+ NativeProviderConfigSchema
1450
+ ]);
1451
+ var DefaultsConfigSchema = z2.object({
1452
+ timeout_ms: z2.number().int().min(1),
1453
+ retry: RetryConfigSchema,
1454
+ circuit_breaker: CircuitBreakerConfigSchema,
1455
+ rate_limits: RateLimitsConfigSchema.optional(),
1456
+ memory: MemoryConfigSchema,
1457
+ polling: PollingConfigSchema,
1458
+ pricing: DefaultPricingSchema.optional()
1459
+ }).strict();
1460
+ var MetadataConfigSchema = z2.object({
1461
+ schema_version: z2.string(),
1462
+ generated_at: DateLikeStringSchema,
1463
+ description: z2.string(),
1464
+ documentation: z2.string(),
1465
+ migration_notes: z2.string().optional(),
1466
+ last_updated: DateLikeStringSchema.optional()
1467
+ }).strict();
1468
+ var ProviderRegistryConfigSchema = z2.object({
1469
+ version: z2.string(),
1470
+ defaults: DefaultsConfigSchema,
1471
+ guidance_profiles: z2.record(z2.string(), z2.unknown()).optional(),
1472
+ judge: z2.record(z2.string(), z2.unknown()).optional(),
1473
+ providers: z2.record(z2.string(), ProviderConfigSchema),
1474
+ metadata: MetadataConfigSchema
1475
+ }).strict();
1476
+ function cloneProviderRegistryValue(value) {
1477
+ return structuredClone(value);
1478
+ }
1479
+ function verifySchemaDefinitions() {
1480
+ const schemas = {
1481
+ RetryConfigSchema,
1482
+ CircuitBreakerConfigSchema,
1483
+ MemoryConfigSchema,
1484
+ PollingConfigSchema,
1485
+ CLIConfigSchema,
1486
+ AuthConfigSchema,
1487
+ ModelInfoSchema,
1488
+ ModelsConfigSchema,
1489
+ TuiConversationCapabilityConfigSchema,
1490
+ CapabilitiesConfigSchema,
1491
+ BotIdentityConfigSchema,
1492
+ EnvConfigSchema,
1493
+ ModelPricingSchema,
1494
+ ToolPricingSchema,
1495
+ SubscriptionPricingSchema,
1496
+ InfrastructurePricingSchema,
1497
+ ProviderPricingSchema,
1498
+ DefaultPricingSchema,
1499
+ PluginVerifySchema,
1500
+ PluginConfigureStepSchema,
1501
+ RequirementSchema,
1502
+ PluginSchema,
1503
+ ProviderOptionSchema,
1504
+ ProviderOptionsSchema,
1505
+ ConditionalRequiresSchema,
1506
+ ProviderRequiresSchema,
1507
+ ProviderConfigSchema,
1508
+ DefaultsConfigSchema,
1509
+ MetadataConfigSchema,
1510
+ ProviderRegistryConfigSchema
1511
+ };
1512
+ for (const [name, schema] of Object.entries(schemas)) {
1513
+ if (!schema || !("_zod" in schema)) {
1514
+ throw new Error(
1515
+ `Schema ${name} is undefined or invalid. This indicates a schema definition error. Check that all nested schemas in ${name} are properly defined. Common issue: Zod v4 requires z.record(keySchema, valueSchema) with explicit parameters.`
1516
+ );
1517
+ }
1518
+ }
1519
+ }
1520
+ verifySchemaDefinitions();
1521
+ var ProviderRegistry = class _ProviderRegistry {
1522
+ static instance = null;
1523
+ static configPath = null;
1524
+ static configSources = [];
1525
+ static cacheKey = null;
1526
+ static cacheMode = null;
1527
+ static cacheProjectRoot = null;
1528
+ constructor() {
1529
+ }
1530
+ static replaceCachedRegistry(config, configPath, cacheKey, cacheMode, projectRoot, configSources = [configPath]) {
1531
+ const replacedExistingCache = _ProviderRegistry.instance !== null && (_ProviderRegistry.configPath !== configPath || _ProviderRegistry.cacheKey !== cacheKey || _ProviderRegistry.cacheMode !== cacheMode);
1532
+ _ProviderRegistry.instance = config;
1533
+ _ProviderRegistry.configPath = configPath;
1534
+ _ProviderRegistry.configSources = [...configSources];
1535
+ _ProviderRegistry.cacheKey = cacheKey;
1536
+ _ProviderRegistry.cacheMode = cacheMode;
1537
+ _ProviderRegistry.cacheProjectRoot = projectRoot;
1538
+ if (replacedExistingCache) {
1539
+ runProviderRegistryReloadInvalidators();
1540
+ }
1541
+ return config;
1542
+ }
1543
+ /**
1544
+ * Load the unified provider registry from YAML
1545
+ *
1546
+ * @param configPath - Path to providers.yaml (defaults to .poetic/config/providers.yaml)
1547
+ * @returns Validated and merged configuration
1548
+ */
1549
+ static load(configPath, cwd = process.cwd()) {
1550
+ const projectRoot = findProjectRoot(cwd) ?? cwd;
1551
+ configPath = configPath ? resolve3(projectRoot, configPath) : void 0;
1552
+ const envCacheKey = _ProviderRegistry.buildEnvOverrideCacheKey();
1553
+ const requestedCacheKey = _ProviderRegistry.buildCacheKey(configPath, envCacheKey, projectRoot);
1554
+ if (_ProviderRegistry.instance && (_ProviderRegistry.cacheKey === requestedCacheKey || !configPath && _ProviderRegistry.cacheMode === "explicit" && _ProviderRegistry.configPath !== null && _ProviderRegistry.canReuseExplicitCacheForImplicit(
1555
+ _ProviderRegistry.configPath,
1556
+ projectRoot
1557
+ ) && _ProviderRegistry.cacheKey === _ProviderRegistry.buildCacheKey(_ProviderRegistry.configPath, envCacheKey, projectRoot))) {
1558
+ return _ProviderRegistry.instance;
1559
+ }
1560
+ const embeddedConfigPaths = getEmbeddedProviderConfigPaths();
1561
+ const isTrustedProjectForTemplatedProviders = () => isTrustedProjectRoot(projectRoot);
1562
+ const projectTrustInstruction = formatProjectTrustInstruction(projectRoot);
1563
+ const loadYamlRawIfExists = (filePath) => {
1564
+ if (!existsSync2(filePath)) return null;
1565
+ try {
1566
+ const rawYaml = readFileSync2(filePath, "utf-8");
1567
+ return yaml.load(rawYaml);
1568
+ } catch (error) {
1569
+ throw new Error(
1570
+ `Failed to load YAML at ${filePath}: ${error instanceof Error ? error.message : String(error)}`
1571
+ );
1572
+ }
1573
+ };
1574
+ const loadEmbeddedRaw = () => {
1575
+ for (const embeddedConfigPath of embeddedConfigPaths) {
1576
+ if (!existsSync2(embeddedConfigPath)) continue;
1577
+ try {
1578
+ const bytes = readFileSync2(embeddedConfigPath);
1579
+ if (embeddedConfigPath.endsWith("catalog.json")) {
1580
+ const digest2 = createHash2("sha256").update(bytes).digest("hex");
1581
+ if (digest2 !== PROVIDER_CATALOG_SHA256) {
1582
+ throw new Error(
1583
+ `Provider catalog digest mismatch: expected ${PROVIDER_CATALOG_SHA256}, received ${digest2}`
1584
+ );
1585
+ }
1586
+ }
1587
+ const raw = yaml.load(bytes.toString("utf8"));
1588
+ if (!raw) continue;
1589
+ return { path: embeddedConfigPath, raw };
1590
+ } catch (error) {
1591
+ throw new Error(
1592
+ `Failed to load packaged provider catalog at ${embeddedConfigPath}: ${error instanceof Error ? error.message : String(error)}`
1593
+ );
1594
+ }
1595
+ }
1596
+ return null;
1597
+ };
1598
+ const deepMerge = (base, overlay) => {
1599
+ if (!overlay || typeof overlay !== "object") return base;
1600
+ if (!base || typeof base !== "object") return overlay;
1601
+ const baseObj = base;
1602
+ const overlayObj = overlay;
1603
+ const out = { ...baseObj };
1604
+ for (const [key, overlayValue] of Object.entries(overlayObj)) {
1605
+ const baseValue = baseObj[key];
1606
+ if (key === "providers" && overlayValue && typeof overlayValue === "object" && !Array.isArray(overlayValue)) {
1607
+ const existingProviders = baseValue && typeof baseValue === "object" && !Array.isArray(baseValue) ? baseValue : {};
1608
+ const overlayProviders = overlayValue;
1609
+ const mergedProviders = { ...existingProviders };
1610
+ for (const [providerId, providerOverlay] of Object.entries(overlayProviders)) {
1611
+ const existingProvider = existingProviders[providerId];
1612
+ if (existingProvider && typeof existingProvider === "object" && !Array.isArray(existingProvider) && providerOverlay && typeof providerOverlay === "object" && !Array.isArray(providerOverlay)) {
1613
+ mergedProviders[providerId] = deepMerge(existingProvider, providerOverlay);
1614
+ } else {
1615
+ mergedProviders[providerId] = providerOverlay;
1616
+ }
1617
+ }
1618
+ out.providers = mergedProviders;
1619
+ continue;
1620
+ }
1621
+ if (overlayValue && typeof overlayValue === "object" && !Array.isArray(overlayValue) && !(overlayValue instanceof Date) && baseValue && typeof baseValue === "object" && !Array.isArray(baseValue) && !(baseValue instanceof Date)) {
1622
+ out[key] = deepMerge(baseValue, overlayValue);
1623
+ continue;
1624
+ }
1625
+ out[key] = overlayValue;
1626
+ }
1627
+ return out;
1628
+ };
1629
+ const isFullRegistrySnapshot = (raw, base) => {
1630
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return false;
1631
+ if (!base || typeof base !== "object" || Array.isArray(base)) return false;
1632
+ const rawObject = raw;
1633
+ const baseObject = base;
1634
+ const rawProviders = rawObject.providers;
1635
+ const baseProviders = baseObject.providers;
1636
+ if (!rawProviders || typeof rawProviders !== "object" || Array.isArray(rawProviders) || !baseProviders || typeof baseProviders !== "object" || Array.isArray(baseProviders)) {
1637
+ return false;
1638
+ }
1639
+ return "version" in rawObject && "defaults" in rawObject && "metadata" in rawObject && Object.keys(rawProviders).length > 0;
1640
+ };
1641
+ const migrateLegacyFullSnapshotOverlay = (raw, base) => {
1642
+ if (!isFullRegistrySnapshot(raw, base)) return raw;
1643
+ const migrated = cloneProviderRegistryValue(raw);
1644
+ const migratedProviders = migrated.providers;
1645
+ const baseProviders = base.providers;
1646
+ for (const [providerId, providerValue] of Object.entries(migratedProviders)) {
1647
+ const baseProviderValue = baseProviders[providerId];
1648
+ if (!baseProviderValue || typeof baseProviderValue !== "object" || Array.isArray(baseProviderValue)) {
1649
+ continue;
1650
+ }
1651
+ if (!providerValue || typeof providerValue !== "object" || Array.isArray(providerValue)) {
1652
+ continue;
1653
+ }
1654
+ const provider = providerValue;
1655
+ const modelsValue = provider.models;
1656
+ const baseModelsValue = baseProviderValue.models;
1657
+ if (!modelsValue || typeof modelsValue !== "object" || Array.isArray(modelsValue)) {
1658
+ continue;
1659
+ }
1660
+ if (!baseModelsValue || typeof baseModelsValue !== "object" || Array.isArray(baseModelsValue)) {
1661
+ continue;
1662
+ }
1663
+ const models = modelsValue;
1664
+ const baseModels = baseModelsValue;
1665
+ if (Array.isArray(baseModels.available) && Array.isArray(models.available)) {
1666
+ const availableById = /* @__PURE__ */ new Map();
1667
+ const combinedAvailable = [...baseModels.available, ...models.available];
1668
+ if (combinedAvailable.every(
1669
+ (entry) => entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.id === "string"
1670
+ )) {
1671
+ for (const entry of combinedAvailable) {
1672
+ availableById.set(entry.id, entry);
1673
+ }
1674
+ models.available = [...availableById.values()];
1675
+ }
1676
+ }
1677
+ if (Array.isArray(baseModels.allowed_patterns) && Array.isArray(models.allowed_patterns) && [...baseModels.allowed_patterns, ...models.allowed_patterns].every(
1678
+ (pattern) => typeof pattern === "string"
1679
+ )) {
1680
+ models.allowed_patterns = [
1681
+ .../* @__PURE__ */ new Set([...baseModels.allowed_patterns, ...models.allowed_patterns])
1682
+ ];
1683
+ }
1684
+ for (const key of ["mappings", "roles"]) {
1685
+ const baseRecord = baseModels[key];
1686
+ const overlayRecord = models[key];
1687
+ if (baseRecord && typeof baseRecord === "object" && !Array.isArray(baseRecord) && overlayRecord && typeof overlayRecord === "object" && !Array.isArray(overlayRecord)) {
1688
+ models[key] = {
1689
+ ...baseRecord,
1690
+ ...overlayRecord
1691
+ };
1692
+ }
1693
+ }
1694
+ }
1695
+ return migrated;
1696
+ };
1697
+ const mergeUserAvailableModels = (raw, base) => {
1698
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return raw;
1699
+ if (!base || typeof base !== "object" || Array.isArray(base)) return raw;
1700
+ const projected = cloneProviderRegistryValue(raw);
1701
+ const projectedProviders = projected.providers;
1702
+ const baseProviders = base.providers;
1703
+ if (!projectedProviders || typeof projectedProviders !== "object" || Array.isArray(projectedProviders) || !baseProviders || typeof baseProviders !== "object" || Array.isArray(baseProviders)) {
1704
+ return projected;
1705
+ }
1706
+ for (const [providerId, providerValue] of Object.entries(
1707
+ projectedProviders
1708
+ )) {
1709
+ const baseProviderValue = baseProviders[providerId];
1710
+ if (!providerValue || typeof providerValue !== "object" || Array.isArray(providerValue) || !baseProviderValue || typeof baseProviderValue !== "object" || Array.isArray(baseProviderValue)) {
1711
+ continue;
1712
+ }
1713
+ const models = providerValue.models;
1714
+ const baseModels = baseProviderValue.models;
1715
+ if (!models || typeof models !== "object" || Array.isArray(models) || !baseModels || typeof baseModels !== "object" || Array.isArray(baseModels)) {
1716
+ continue;
1717
+ }
1718
+ const userAvailable = models.available;
1719
+ const baseAvailable = baseModels.available;
1720
+ if (!Array.isArray(userAvailable) || !Array.isArray(baseAvailable)) continue;
1721
+ const combined = [...baseAvailable, ...userAvailable];
1722
+ if (!combined.every(
1723
+ (entry) => entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.id === "string"
1724
+ )) {
1725
+ continue;
1726
+ }
1727
+ const availableById = /* @__PURE__ */ new Map();
1728
+ for (const entry of combined) {
1729
+ const entryObject = entry;
1730
+ const id = entryObject.id;
1731
+ const existing = availableById.get(id);
1732
+ availableById.set(
1733
+ id,
1734
+ existing && typeof existing === "object" && !Array.isArray(existing) ? { ...existing, ...entryObject } : entry
1735
+ );
1736
+ }
1737
+ models.available = [...availableById.values()];
1738
+ }
1739
+ return projected;
1740
+ };
1741
+ const listTemplatedProviderIds = (raw) => {
1742
+ if (!raw || typeof raw !== "object") return [];
1743
+ const providers = raw.providers;
1744
+ if (!providers || typeof providers !== "object") return [];
1745
+ const templated = [];
1746
+ for (const [id, value] of Object.entries(providers)) {
1747
+ if (!value || typeof value !== "object") continue;
1748
+ const engine = value.engine;
1749
+ if (engine === "templated_cli") {
1750
+ templated.push(id);
1751
+ }
1752
+ }
1753
+ return templated;
1754
+ };
1755
+ const getRawProvider = (raw, providerId) => {
1756
+ if (!raw || typeof raw !== "object") return void 0;
1757
+ const providers = raw.providers;
1758
+ if (!providers || typeof providers !== "object") return void 0;
1759
+ return providers[providerId];
1760
+ };
1761
+ const stableJson = (value) => {
1762
+ if (Array.isArray(value)) {
1763
+ return `[${value.map((entry) => stableJson(entry)).join(",")}]`;
1764
+ }
1765
+ if (value && typeof value === "object") {
1766
+ return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`).join(",")}}`;
1767
+ }
1768
+ return JSON.stringify(value);
1769
+ };
1770
+ const normalizeProviderForTrustComparison = (providerId, provider) => {
1771
+ try {
1772
+ return ProviderConfigSchema.parse(provider);
1773
+ } catch (error) {
1774
+ debugLog(
1775
+ `[provider-registry] Failed to normalize templated provider "${providerId}" for trust comparison`,
1776
+ error instanceof Error ? error.message : String(error)
1777
+ );
1778
+ return provider;
1779
+ }
1780
+ };
1781
+ const listUntrustedTemplatedProviderIds = (raw, trustedRaw) => listTemplatedProviderIds(raw).filter((providerId) => {
1782
+ const candidate = getRawProvider(raw, providerId);
1783
+ const trusted = getRawProvider(trustedRaw, providerId);
1784
+ return !trusted || stableJson(normalizeProviderForTrustComparison(providerId, candidate)) !== stableJson(normalizeProviderForTrustComparison(providerId, trusted));
1785
+ });
1786
+ const listUntrustedExecutionFieldChanges = (raw, trustedRaw) => {
1787
+ if (!raw || typeof raw !== "object") return [];
1788
+ const providers = raw.providers;
1789
+ if (!providers || typeof providers !== "object" || Array.isArray(providers)) return [];
1790
+ const changes = [];
1791
+ for (const [providerId, candidate] of Object.entries(providers)) {
1792
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
1793
+ const candidateProvider = candidate;
1794
+ const trusted = getRawProvider(trustedRaw, providerId);
1795
+ const trustedProvider = trusted && typeof trusted === "object" && !Array.isArray(trusted) ? trusted : null;
1796
+ if (!trustedProvider) {
1797
+ const declaredFields = EXECUTION_SENSITIVE_PROVIDER_FIELDS.filter(
1798
+ (field) => candidateProvider[field] !== void 0
1799
+ );
1800
+ if (declaredFields.length > 0) {
1801
+ changes.push({ providerId, fields: [...declaredFields] });
1802
+ }
1803
+ continue;
1804
+ }
1805
+ const effective = normalizeProviderForTrustComparison(
1806
+ providerId,
1807
+ deepMerge(trustedProvider, candidateProvider)
1808
+ );
1809
+ const baseline = normalizeProviderForTrustComparison(providerId, trustedProvider);
1810
+ const changedFields = EXECUTION_SENSITIVE_PROVIDER_FIELDS.filter((field) => {
1811
+ if (candidateProvider[field] === void 0) return false;
1812
+ return stableJson(effective?.[field]) !== stableJson(baseline?.[field]);
1813
+ });
1814
+ if (changedFields.length > 0) {
1815
+ changes.push({ providerId, fields: [...changedFields] });
1816
+ }
1817
+ }
1818
+ return changes;
1819
+ };
1820
+ const listUntrustedApiIdentityChanges = (projectRaw, effectiveRaw, trustedRaw) => {
1821
+ if (!projectRaw || typeof projectRaw !== "object" || Array.isArray(projectRaw)) return [];
1822
+ const projectProviders = projectRaw.providers;
1823
+ if (!projectProviders || typeof projectProviders !== "object" || Array.isArray(projectProviders)) {
1824
+ return [];
1825
+ }
1826
+ const changes = [];
1827
+ for (const [providerId, projectValue] of Object.entries(
1828
+ projectProviders
1829
+ )) {
1830
+ if (!projectValue || typeof projectValue !== "object" || Array.isArray(projectValue)) {
1831
+ continue;
1832
+ }
1833
+ const projectProvider = projectValue;
1834
+ const effectiveProviderValue = getRawProvider(effectiveRaw, providerId);
1835
+ const trustedProviderValue = getRawProvider(trustedRaw, providerId);
1836
+ if (!effectiveProviderValue || typeof effectiveProviderValue !== "object" || Array.isArray(effectiveProviderValue)) {
1837
+ continue;
1838
+ }
1839
+ const effectiveProvider = effectiveProviderValue;
1840
+ const trustedProvider = trustedProviderValue && typeof trustedProviderValue === "object" && !Array.isArray(trustedProviderValue) ? trustedProviderValue : {};
1841
+ const effectiveApi = effectiveProvider.api && typeof effectiveProvider.api === "object" && !Array.isArray(effectiveProvider.api) ? effectiveProvider.api : {};
1842
+ const trustedApi = trustedProvider.api && typeof trustedProvider.api === "object" && !Array.isArray(trustedProvider.api) ? trustedProvider.api : {};
1843
+ const projectApi = projectProvider.api && typeof projectProvider.api === "object" && !Array.isArray(projectProvider.api) ? projectProvider.api : {};
1844
+ const effectiveChannels = Array.isArray(effectiveProvider.channels) ? effectiveProvider.channels : [];
1845
+ const apiCanRun = effectiveProvider.transport === "api" || effectiveChannels.includes("api");
1846
+ if (!apiCanRun) continue;
1847
+ const fields = [];
1848
+ if (projectProvider.transport !== void 0 && effectiveProvider.transport === "api" && trustedProvider.transport !== "api") {
1849
+ fields.push("transport");
1850
+ }
1851
+ for (const field of ["base_url", "api_key_env_var"]) {
1852
+ if (projectApi[field] !== void 0 && stableJson(effectiveApi[field]) !== stableJson(trustedApi[field])) {
1853
+ fields.push(`api.${field}`);
1854
+ }
1855
+ }
1856
+ if (fields.length > 0) {
1857
+ changes.push({ providerId, fields });
1858
+ }
1859
+ }
1860
+ return changes;
1861
+ };
1862
+ const describeExecutionFieldChanges = (changes) => changes.map(({ providerId, fields }) => `${providerId} (${fields.join(", ")})`).join(", ");
1863
+ const buildUntrustedExecutionFieldError = (changes, root) => new Error(
1864
+ `Security: Project config changes provider execution fields (${describeExecutionFieldChanges(changes)}) which are not allowed unless POETIC_TRUST_PROJECT_PROVIDER_TEMPLATES names this canonical project root.
1865
+
1866
+ These fields can select the binary Poetic executes or installs, or redirect a credentialed API request, so a cloned repo could otherwise redirect a built-in provider to attacker-controlled code or infrastructure:
1867
+ - User config: ${getUserProviderRegistryPaths(root)[0]}
1868
+ - Project config: .poetic/config/providers.yaml (requires explicit trust)
1869
+
1870
+ Providers are trusted only when their normalized execution config matches the embedded template.
1871
+
1872
+ To trust only this project, run:
1873
+ ` + projectTrustInstruction
1874
+ );
1875
+ const isAutoLoadedProjectRegistryPath = (candidatePath, root) => [
1876
+ resolveProvidersConfigPath({ cwd: root }),
1877
+ resolve3(root, ".poetic", "config", "provider-registry.yaml.v1.backup")
1878
+ ].some((registryPath) => resolve3(registryPath) === resolve3(candidatePath));
1879
+ const embedded = loadEmbeddedRaw();
1880
+ if (!embedded) {
1881
+ throw new Error("Failed to load the provider catalog. Run the provider generator and retry.");
1882
+ }
1883
+ if (configPath) {
1884
+ const pathValidation = validateConfigPath(configPath, projectRoot, { allowTempDir: false });
1885
+ if (!pathValidation.isValid) {
1886
+ throw new Error(
1887
+ `Security Error: Invalid config path "${configPath}": ${pathValidation.reason}. Risk level: ${pathValidation.riskLevel}`
1888
+ );
1889
+ }
1890
+ const raw = loadYamlRawIfExists(pathValidation.normalizedPath);
1891
+ if (!raw) {
1892
+ throw new Error(
1893
+ `Failed to read unified provider config at ${pathValidation.normalizedPath}`
1894
+ );
1895
+ }
1896
+ const templatedProviders = listUntrustedTemplatedProviderIds(raw, embedded.raw);
1897
+ const projectPoeticDir = resolve3(projectRoot, ".poetic");
1898
+ const isProjectConfig = pathValidation.normalizedPath.startsWith(projectPoeticDir + sep);
1899
+ if (isProjectConfig && templatedProviders.length > 0 && !isTrustedProjectForTemplatedProviders()) {
1900
+ throw new Error(
1901
+ `Security: Project config contains templated_cli providers (${templatedProviders.join(", ")}) which are not allowed unless POETIC_TRUST_PROJECT_PROVIDER_TEMPLATES names this canonical project root.
1902
+
1903
+ Templated CLI providers execute external binaries and should normally be configured in user scope:
1904
+ - User config: ${getUserProviderRegistryPaths(projectRoot)[0]}
1905
+ - Project config: .poetic/config/providers.yaml (requires explicit trust)
1906
+
1907
+ Built-in templated providers are trusted only when their normalized config matches the embedded template.
1908
+
1909
+ To trust only this project, run:
1910
+ ` + projectTrustInstruction
1911
+ );
1912
+ }
1913
+ if (isProjectConfig && isAutoLoadedProjectRegistryPath(pathValidation.normalizedPath, projectRoot) && !isTrustedProjectForTemplatedProviders()) {
1914
+ const executionFieldChanges = listUntrustedExecutionFieldChanges(raw, embedded.raw);
1915
+ if (executionFieldChanges.length > 0) {
1916
+ throw buildUntrustedExecutionFieldError(executionFieldChanges, projectRoot);
1917
+ }
1918
+ }
1919
+ if (isProjectConfig && isAutoLoadedProjectRegistryPath(pathValidation.normalizedPath, projectRoot) && !isTrustedProjectForTemplatedProviders()) {
1920
+ const apiIdentityChanges = listUntrustedApiIdentityChanges(raw, raw, embedded.raw);
1921
+ if (apiIdentityChanges.length > 0) {
1922
+ throw buildUntrustedExecutionFieldError(apiIdentityChanges, projectRoot);
1923
+ }
1924
+ }
1925
+ const withEnvOverrides2 = _ProviderRegistry.applyEnvOverrides(
1926
+ dropRemovedBuiltinProviders(ensureCursorIdSyntaxAdmissionPattern(raw))
1927
+ );
1928
+ const validated2 = _ProviderRegistry.parseRegistryConfig(withEnvOverrides2);
1929
+ return _ProviderRegistry.replaceCachedRegistry(
1930
+ validated2,
1931
+ pathValidation.normalizedPath,
1932
+ requestedCacheKey,
1933
+ "explicit",
1934
+ projectRoot,
1935
+ [pathValidation.normalizedPath]
1936
+ );
1937
+ }
1938
+ let mergedRaw = embedded.raw;
1939
+ const overlayPath = resolve3(
1940
+ projectRoot,
1941
+ ".poetic",
1942
+ "cache",
1943
+ "model-update",
1944
+ "refresh-overlay.json"
1945
+ );
1946
+ let appliedOverlayPath;
1947
+ if (existsSync2(overlayPath)) {
1948
+ const disposition = resolveRefreshOverlayDisposition(readFileSync2(overlayPath, "utf8"), {
1949
+ expectedBaseCatalogDigest: PROVIDER_CATALOG_SHA256
1950
+ });
1951
+ if (disposition.status === "ready") {
1952
+ mergedRaw = applyRefreshOverlay(mergedRaw, disposition.overlay);
1953
+ appliedOverlayPath = overlayPath;
1954
+ } else if (disposition.status !== "absent") {
1955
+ debugLog(
1956
+ disposition.status === "degraded" ? disposition.warning : `Refresh overlay ignored: ${disposition.error}`
1957
+ );
1958
+ }
1959
+ }
1960
+ let securityMergedRaw = mergedRaw;
1961
+ let trustedMergedRaw = mergedRaw;
1962
+ let loadedProjectRaw = null;
1963
+ const loadedConfigSources = [
1964
+ embedded.path,
1965
+ ...appliedOverlayPath ? [appliedOverlayPath] : []
1966
+ ];
1967
+ const projectConfigV2 = resolveProvidersConfigPath({ cwd: projectRoot });
1968
+ const projectConfigV1 = resolve3(
1969
+ projectRoot,
1970
+ ".poetic",
1971
+ "config",
1972
+ "provider-registry.yaml.v1.backup"
1973
+ );
1974
+ const discoveredProjectConfigPath = existsSync2(projectConfigV2) ? projectConfigV2 : existsSync2(projectConfigV1) ? projectConfigV1 : null;
1975
+ const projectConfigPath = discoveredProjectConfigPath && resolve3(discoveredProjectConfigPath) !== resolve3(embedded.path) ? discoveredProjectConfigPath : null;
1976
+ let loadedConfigPath = embedded.path;
1977
+ if (projectConfigPath) {
1978
+ const configParentDir = resolve3(projectRoot, ".poetic", "config");
1979
+ if (!existsSync2(configParentDir)) {
1980
+ throw new Error(
1981
+ `Poetic not initialized: directory '${configParentDir}' does not exist.
1982
+ Run 'poetic init' to initialize Poetic in this project.`
1983
+ );
1984
+ }
1985
+ const pathValidation = validateConfigPath(projectConfigPath, projectRoot, {
1986
+ allowTempDir: false
1987
+ });
1988
+ if (!pathValidation.isValid) {
1989
+ throw new Error(
1990
+ `Security Error: Invalid config path "${projectConfigPath}": ${pathValidation.reason}. Risk level: ${pathValidation.riskLevel}`
1991
+ );
1992
+ }
1993
+ const projectRaw = loadYamlRawIfExists(pathValidation.normalizedPath);
1994
+ if (!projectRaw) {
1995
+ throw new Error(
1996
+ `Failed to read unified provider config at ${pathValidation.normalizedPath}`
1997
+ );
1998
+ }
1999
+ loadedProjectRaw = projectRaw;
2000
+ const templatedProviders = listUntrustedTemplatedProviderIds(projectRaw, embedded.raw);
2001
+ if (templatedProviders.length > 0 && !isTrustedProjectForTemplatedProviders()) {
2002
+ throw new Error(
2003
+ `Security: Project config contains templated_cli providers (${templatedProviders.join(", ")}) which are not allowed unless POETIC_TRUST_PROJECT_PROVIDER_TEMPLATES names this canonical project root.
2004
+
2005
+ Templated CLI providers execute external binaries and should normally be configured in user scope:
2006
+ - User config: ${getUserProviderRegistryPaths(projectRoot)[0]}
2007
+ - Project config: .poetic/config/providers.yaml (requires explicit trust)
2008
+
2009
+ Built-in templated providers are trusted only when their normalized config matches the embedded template.
2010
+
2011
+ To trust only this project, run:
2012
+ ` + projectTrustInstruction
2013
+ );
2014
+ }
2015
+ const projectIsTrusted = isTrustedProjectForTemplatedProviders();
2016
+ securityMergedRaw = deepMerge(securityMergedRaw, projectRaw);
2017
+ if (!projectIsTrusted) {
2018
+ const executionFieldChanges = listUntrustedExecutionFieldChanges(projectRaw, embedded.raw);
2019
+ if (executionFieldChanges.length > 0) {
2020
+ throw buildUntrustedExecutionFieldError(executionFieldChanges, projectRoot);
2021
+ }
2022
+ }
2023
+ const projectedProjectRaw = projectProjectRegistryPolicy(projectRaw, embedded.raw, {
2024
+ trusted: projectIsTrusted
2025
+ });
2026
+ mergedRaw = deepMerge(mergedRaw, projectedProjectRaw);
2027
+ loadedConfigPath = pathValidation.normalizedPath;
2028
+ loadedConfigSources.push(pathValidation.normalizedPath);
2029
+ }
2030
+ const userRegistryPaths = getUserProviderRegistryPaths(projectRoot);
2031
+ for (const [index, candidate] of userRegistryPaths.entries()) {
2032
+ const userRaw = loadYamlRawIfExists(candidate);
2033
+ if (userRaw) {
2034
+ const migratedUserOverlay = index > 0 ? migrateLegacyFullSnapshotOverlay(userRaw, mergedRaw) : userRaw;
2035
+ const userOverlay = mergeUserAvailableModels(migratedUserOverlay, mergedRaw);
2036
+ mergedRaw = deepMerge(mergedRaw, userOverlay);
2037
+ securityMergedRaw = deepMerge(securityMergedRaw, userOverlay);
2038
+ trustedMergedRaw = deepMerge(trustedMergedRaw, userOverlay);
2039
+ loadedConfigSources.push(candidate);
2040
+ break;
2041
+ }
2042
+ }
2043
+ if (loadedProjectRaw && !isTrustedProjectForTemplatedProviders()) {
2044
+ const apiIdentityChanges = listUntrustedApiIdentityChanges(
2045
+ loadedProjectRaw,
2046
+ securityMergedRaw,
2047
+ trustedMergedRaw
2048
+ );
2049
+ if (apiIdentityChanges.length > 0) {
2050
+ throw buildUntrustedExecutionFieldError(apiIdentityChanges, projectRoot);
2051
+ }
2052
+ }
2053
+ const withEnvOverrides = _ProviderRegistry.applyEnvOverrides(
2054
+ dropRemovedBuiltinProviders(ensureCursorIdSyntaxAdmissionPattern(mergedRaw))
2055
+ );
2056
+ const validated = _ProviderRegistry.parseRegistryConfig(withEnvOverrides);
2057
+ return _ProviderRegistry.replaceCachedRegistry(
2058
+ validated,
2059
+ loadedConfigPath,
2060
+ requestedCacheKey,
2061
+ "implicit",
2062
+ projectRoot,
2063
+ loadedConfigSources
2064
+ );
2065
+ }
2066
+ /**
2067
+ * Resolve every live registry read through the same active-root view.
2068
+ *
2069
+ * A prior explicit-root load establishes which project this process is
2070
+ * serving. Rechecking that root on each read preserves file/environment
2071
+ * fingerprint invalidation without letting a later process.cwd() change
2072
+ * silently switch the live registry to another checkout.
2073
+ */
2074
+ static getActiveRegistry(registryOverride) {
2075
+ if (registryOverride) {
2076
+ return registryOverride;
2077
+ }
2078
+ if (!_ProviderRegistry.instance || !_ProviderRegistry.cacheProjectRoot) {
2079
+ return _ProviderRegistry.load();
2080
+ }
2081
+ if (_ProviderRegistry.cacheMode === "explicit" && _ProviderRegistry.configPath) {
2082
+ return _ProviderRegistry.load(_ProviderRegistry.configPath, _ProviderRegistry.cacheProjectRoot);
2083
+ }
2084
+ return _ProviderRegistry.load(void 0, _ProviderRegistry.cacheProjectRoot);
2085
+ }
2086
+ /**
2087
+ * Get configuration for a specific provider
2088
+ *
2089
+ * @param providerId - Provider identifier (e.g., 'claude', 'codex')
2090
+ * @returns Provider configuration with defaults applied
2091
+ */
2092
+ static getProviderConfig(providerId, registryOverride) {
2093
+ const registry = _ProviderRegistry.getActiveRegistry(registryOverride);
2094
+ const normalizedProviderId = normalizeProviderConfigId(providerId);
2095
+ const providerConfig = registry.providers[providerId] ?? registry.providers[normalizedProviderId];
2096
+ if (!providerConfig) {
2097
+ const availableProviders = Object.values(registry.providers).filter((provider) => provider.enabled).sort((a, b) => a.order - b.order).map((provider) => provider.id).join(", ");
2098
+ throw new Error(
2099
+ `Provider '${providerId}' not found in unified config. Available providers: ${availableProviders}`
2100
+ );
2101
+ }
2102
+ return cloneProviderRegistryValue({
2103
+ ...providerConfig,
2104
+ retry: providerConfig.retry || registry.defaults.retry,
2105
+ circuit_breaker: providerConfig.circuit_breaker || registry.defaults.circuit_breaker,
2106
+ polling: providerConfig.polling || registry.defaults.polling
2107
+ });
2108
+ }
2109
+ /**
2110
+ * Get all provider IDs
2111
+ *
2112
+ * @returns Array of provider IDs
2113
+ */
2114
+ static getAllProviderIds() {
2115
+ const registry = _ProviderRegistry.getActiveRegistry();
2116
+ return Object.keys(registry.providers);
2117
+ }
2118
+ /**
2119
+ * Get all enabled providers
2120
+ *
2121
+ * @returns Array of enabled provider configurations
2122
+ */
2123
+ static getEnabledProviders(registryOverride) {
2124
+ const registry = _ProviderRegistry.getActiveRegistry(registryOverride);
2125
+ return Object.values(registry.providers).filter((p) => p.enabled).sort((a, b) => a.order - b.order);
2126
+ }
2127
+ /**
2128
+ * Check if a provider is enabled
2129
+ *
2130
+ * @param providerId - Provider identifier
2131
+ * @returns True if provider exists and is enabled
2132
+ */
2133
+ static isProviderEnabled(providerId) {
2134
+ const registry = _ProviderRegistry.getActiveRegistry();
2135
+ const normalizedProviderId = normalizeProviderConfigId(providerId);
2136
+ const providerConfig = registry.providers[providerId] ?? registry.providers[normalizedProviderId];
2137
+ return providerConfig?.enabled || false;
2138
+ }
2139
+ /**
2140
+ * Report the source path the currently-cached registry was actually loaded
2141
+ * from.
2142
+ *
2143
+ * This is the coherent provenance signal: when the project providers.yaml is
2144
+ * absent and `load()` falls back to the embedded template seed, this returns
2145
+ * the embedded template path that was actually used — NOT the nonexistent
2146
+ * project `.poetic/config/providers.yaml` path. Diagnostics and logs should
2147
+ * read this instead of recomputing the project path (e.g. via
2148
+ * `resolveProvidersConfigPath`), which would falsely claim a project registry
2149
+ * that is not present on disk.
2150
+ *
2151
+ * Returns `null` when no registry has been loaded yet in this process.
2152
+ *
2153
+ * @returns Absolute path of the loaded registry source, or `null`.
2154
+ */
2155
+ static getLoadedConfigPath() {
2156
+ return _ProviderRegistry.configPath;
2157
+ }
2158
+ /**
2159
+ * Report every source that contributed to the currently-cached registry,
2160
+ * ordered from lowest to highest precedence.
2161
+ */
2162
+ static getLoadedConfigSources() {
2163
+ return [..._ProviderRegistry.configSources];
2164
+ }
2165
+ /**
2166
+ * Force reload configuration from disk
2167
+ * Useful for testing or when config file has been modified
2168
+ */
2169
+ /**
2170
+ * Per-provider `concurrency.max` set in USER-scope provider config only.
2171
+ *
2172
+ * Deliberately NOT read through `getProviderConfig()`. That returns the merged
2173
+ * embedded < project < user view, and `concurrency` is in
2174
+ * PROJECT_POLICY_PROVIDER_FIELDS — a list retained even for UNTRUSTED project
2175
+ * snapshots — so a cloned repository's `.poetic/config/providers.yaml` can set
2176
+ * it. The orchestrator raises how many provider processes actually run from
2177
+ * this value, spending the operator's host resources and account quota, so it
2178
+ * must come from config the operator owns. A project may still ship a lower
2179
+ * value for its own planning; it just cannot raise process concurrency.
2180
+ *
2181
+ * Returns raw declared maxima without validation or clamping; the caller owns
2182
+ * normalization and correctness ceilings. Unreadable or malformed user config
2183
+ * yields an empty map rather than failing the run: the shipped baseline is
2184
+ * always a safe fallback.
2185
+ */
2186
+ static getUserScopeProviderConcurrencyMax(cwd = process.cwd()) {
2187
+ const projectRoot = findProjectRoot(cwd) ?? cwd;
2188
+ const result = {};
2189
+ for (const candidate of getUserProviderRegistryPaths(projectRoot)) {
2190
+ if (!existsSync2(candidate)) continue;
2191
+ let raw;
2192
+ try {
2193
+ raw = yaml.load(readFileSync2(candidate, "utf-8"));
2194
+ } catch {
2195
+ return {};
2196
+ }
2197
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
2198
+ continue;
2199
+ }
2200
+ const providers = raw.providers;
2201
+ if (!providers || typeof providers !== "object" || Array.isArray(providers)) {
2202
+ return result;
2203
+ }
2204
+ for (const [providerId, providerValue] of Object.entries(
2205
+ providers
2206
+ )) {
2207
+ if (!providerValue || typeof providerValue !== "object" || Array.isArray(providerValue)) {
2208
+ continue;
2209
+ }
2210
+ const concurrency = providerValue.concurrency;
2211
+ if (!concurrency || typeof concurrency !== "object" || Array.isArray(concurrency)) {
2212
+ continue;
2213
+ }
2214
+ const max = concurrency.max;
2215
+ if (typeof max === "number" && Number.isFinite(max)) {
2216
+ result[providerId] = max;
2217
+ }
2218
+ }
2219
+ return result;
2220
+ }
2221
+ return result;
2222
+ }
2223
+ static reload() {
2224
+ _ProviderRegistry.instance = null;
2225
+ _ProviderRegistry.configPath = null;
2226
+ _ProviderRegistry.configSources = [];
2227
+ _ProviderRegistry.cacheKey = null;
2228
+ _ProviderRegistry.cacheMode = null;
2229
+ _ProviderRegistry.cacheProjectRoot = null;
2230
+ runProviderRegistryReloadInvalidators();
2231
+ }
2232
+ static buildEnvOverrideCacheKey() {
2233
+ return fingerprintEnvironment(
2234
+ { ...process.env, ...getExecutionContext().envOverrides },
2235
+ (name) => name.startsWith("POETIC_PROVIDER_") || [
2236
+ "POETIC_TRUST_PROJECT_PROVIDER_TEMPLATES",
2237
+ "POETIC_CONFIG_DIR",
2238
+ "XDG_CONFIG_HOME",
2239
+ "HOME",
2240
+ "USERPROFILE"
2241
+ ].includes(name)
2242
+ );
2243
+ }
2244
+ static buildCacheKey(configPath, envKey, projectRoot) {
2245
+ if (configPath) {
2246
+ return combineCacheFingerprints(
2247
+ `path:${resolve3(configPath)}`,
2248
+ `root:${projectRoot}`,
2249
+ envKey,
2250
+ fingerprintFiles([configPath])
2251
+ );
2252
+ }
2253
+ return combineCacheFingerprints(
2254
+ `root:${projectRoot}`,
2255
+ envKey,
2256
+ fingerprintFiles(getProviderRegistryInputPaths(projectRoot))
2257
+ );
2258
+ }
2259
+ static canReuseExplicitCacheForImplicit(configPath, projectRoot) {
2260
+ return resolve3(configPath) !== resolveProvidersConfigPath({ cwd: projectRoot });
2261
+ }
2262
+ /**
2263
+ * Apply environment variable overrides
2264
+ * Supports: POETIC_PROVIDER_<ID>_<KEY>=value
2265
+ *
2266
+ * Examples:
2267
+ * - POETIC_PROVIDER_CODEX_TIMEOUT_MS=900000
2268
+ * - POETIC_PROVIDER_CLAUDE_ENABLED=false
2269
+ * - POETIC_PROVIDER_GEMINI_MODELS_DEFAULT=gemini-2.5-flash
2270
+ *
2271
+ * @param config - Parsed YAML configuration
2272
+ * @returns Configuration with environment overrides applied
2273
+ */
2274
+ static applyEnvOverrides(config) {
2275
+ if (!config || typeof config !== "object") {
2276
+ return config;
2277
+ }
2278
+ const result = cloneProviderRegistryValue(config);
2279
+ const runtimeEnv = {
2280
+ ...process.env,
2281
+ ...getExecutionContext().envOverrides
2282
+ };
2283
+ for (const [key, value] of Object.entries(runtimeEnv)) {
2284
+ if (!key.startsWith("POETIC_PROVIDER_")) {
2285
+ continue;
2286
+ }
2287
+ if (getEnvVarEntry(key)) {
2288
+ continue;
2289
+ }
2290
+ const overrideName = key.substring("POETIC_PROVIDER_".length);
2291
+ if (!overrideName.includes("_")) {
2292
+ continue;
2293
+ }
2294
+ const providers = result.providers;
2295
+ const providerEntries = providers && typeof providers === "object" ? Object.keys(providers) : [];
2296
+ const providerId = providerEntries.filter((id) => overrideName.startsWith(`${id.toUpperCase()}_`)).sort((a, b) => b.length - a.length)[0];
2297
+ if (!providerId) {
2298
+ const claimedProvider = overrideName.split("_")[0]?.toLowerCase() ?? overrideName;
2299
+ throw new InvalidExplicitConfigError(
2300
+ `Environment variable ${key} targets unknown provider '${claimedProvider}'.`
2301
+ );
2302
+ }
2303
+ const configKey = overrideName.slice(providerId.length + 1).toLowerCase();
2304
+ const providerConfig = providers[providerId];
2305
+ if (providerConfig && typeof providerConfig === "object") {
2306
+ _ProviderRegistry.setNestedValue(
2307
+ providerConfig,
2308
+ configKey,
2309
+ String(value ?? ""),
2310
+ key
2311
+ );
2312
+ }
2313
+ }
2314
+ return result;
2315
+ }
2316
+ static dynamicProviderOverrideKeys() {
2317
+ const runtimeEnv = {
2318
+ ...process.env,
2319
+ ...getExecutionContext().envOverrides
2320
+ };
2321
+ return Object.keys(runtimeEnv).filter((key) => {
2322
+ if (!key.startsWith("POETIC_PROVIDER_") || getEnvVarEntry(key)) return false;
2323
+ return key.substring("POETIC_PROVIDER_".length).includes("_");
2324
+ });
2325
+ }
2326
+ static parseRegistryConfig(config) {
2327
+ try {
2328
+ return ProviderRegistryConfigSchema.parse(config);
2329
+ } catch (error) {
2330
+ if (error instanceof z2.ZodError) {
2331
+ const issues = error.issues.map((issue) => ` - ${issue.path.join(".")}: ${issue.message}`).join("\n");
2332
+ const overrideKeys = _ProviderRegistry.dynamicProviderOverrideKeys();
2333
+ if (overrideKeys.length > 0) {
2334
+ throw new InvalidExplicitConfigError(
2335
+ `Invalid provider environment override (${overrideKeys.join(", ")}):
2336
+ ${issues}`,
2337
+ error
2338
+ );
2339
+ }
2340
+ throw new Error(`Unified provider config validation failed:
2341
+ ${issues}`);
2342
+ }
2343
+ if (error instanceof TypeError && error.message.includes("_zod")) {
2344
+ throw new Error(
2345
+ `Schema validation failed due to undefined nested schema. This typically indicates incorrect Zod v4 syntax (e.g., z.record() requires two parameters). Original error: ${error.message}
2346
+
2347
+ Fix: Change z.record(z.string()) to z.record(z.string(), z.string()) in schema definitions.`
2348
+ );
2349
+ }
2350
+ throw error;
2351
+ }
2352
+ }
2353
+ /**
2354
+ * Set a nested value in an object using underscore notation
2355
+ *
2356
+ * @param obj - Object to modify
2357
+ * @param path - Underscore-separated path (TIMEOUT_MS -> timeout_ms, MODELS_DEFAULT -> models.default)
2358
+ * @param value - Value to set
2359
+ */
2360
+ static setNestedValue(obj, path, value, envKey) {
2361
+ const normalizedPath = path.toLowerCase();
2362
+ if (normalizedPath in obj) {
2363
+ obj[normalizedPath] = _ProviderRegistry.coerceOverrideValue(
2364
+ value,
2365
+ obj[normalizedPath],
2366
+ envKey
2367
+ );
2368
+ return;
2369
+ }
2370
+ const parts = normalizedPath.split("_");
2371
+ if (parts[0] === "models" && parts.length > 1) {
2372
+ if (typeof obj.models !== "object" || obj.models === null || Array.isArray(obj.models)) {
2373
+ obj.models = {};
2374
+ }
2375
+ const nestedPath = parts.slice(1).join("_");
2376
+ if (nestedPath === "default" && !("default" in obj.models)) {
2377
+ obj.models.default = value;
2378
+ return;
2379
+ }
2380
+ _ProviderRegistry.setNestedValue(
2381
+ obj.models,
2382
+ nestedPath,
2383
+ value,
2384
+ envKey
2385
+ );
2386
+ return;
2387
+ }
2388
+ for (let i = 1; i < parts.length; i++) {
2389
+ const firstKey = parts.slice(0, i).join("_");
2390
+ const restKey = parts.slice(i).join("_");
2391
+ if (firstKey in obj && typeof obj[firstKey] === "object" && obj[firstKey] !== null) {
2392
+ _ProviderRegistry.setNestedValue(
2393
+ obj[firstKey],
2394
+ restKey,
2395
+ value,
2396
+ envKey
2397
+ );
2398
+ return;
2399
+ }
2400
+ }
2401
+ throw new InvalidExplicitConfigError(
2402
+ `Environment variable ${envKey} targets unknown provider configuration key '${normalizedPath}'.`
2403
+ );
2404
+ }
2405
+ /**
2406
+ * Parse environment variable value to appropriate type
2407
+ *
2408
+ * @param value - String value from environment
2409
+ * @returns Parsed value (boolean, number, or string)
2410
+ */
2411
+ static coerceOverrideValue(value, destination, envKey) {
2412
+ if (typeof destination === "boolean") {
2413
+ const normalized = value.trim().toLowerCase();
2414
+ if (["1", "true", "yes", "on"].includes(normalized)) return true;
2415
+ if (["0", "false", "no", "off"].includes(normalized)) return false;
2416
+ throw new InvalidExplicitConfigError(
2417
+ `Environment variable ${envKey} must be a boolean (true/false, yes/no, on/off, or 1/0).`
2418
+ );
2419
+ }
2420
+ if (typeof destination === "number") {
2421
+ const numeric = Number(value);
2422
+ if (Number.isFinite(numeric)) return numeric;
2423
+ throw new InvalidExplicitConfigError(
2424
+ `Environment variable ${envKey} must be a finite number.`
2425
+ );
2426
+ }
2427
+ return value;
2428
+ }
2429
+ /**
2430
+ * Get global defaults
2431
+ *
2432
+ * @returns Global defaults configuration
2433
+ */
2434
+ static getDefaults() {
2435
+ const registry = _ProviderRegistry.getActiveRegistry();
2436
+ return registry.defaults;
2437
+ }
2438
+ /**
2439
+ * Get configuration metadata
2440
+ *
2441
+ * @returns Configuration metadata
2442
+ */
2443
+ static getMetadata() {
2444
+ const registry = _ProviderRegistry.getActiveRegistry();
2445
+ return registry.metadata;
2446
+ }
2447
+ /**
2448
+ * Resolve a model name for a specific provider
2449
+ * Applies model mappings and validates against allowed patterns
2450
+ *
2451
+ * @param providerId - Provider identifier
2452
+ * @param model - Model name to resolve (may be generic like 'gpt-4')
2453
+ * @returns Resolved provider-specific model name
2454
+ */
2455
+ static resolveModel(providerId, model, registryOverride) {
2456
+ const config = _ProviderRegistry.getProviderConfig(providerId, registryOverride);
2457
+ const trimmedModel = !model || model.trim() === "" ? config.models.default : model.trim();
2458
+ if (trimmedModel in config.models.mappings) {
2459
+ const mapped = config.models.mappings[trimmedModel];
2460
+ if (mapped !== void 0) {
2461
+ return mapped;
2462
+ }
2463
+ }
2464
+ for (const pattern of config.models.allowed_patterns) {
2465
+ let regex;
2466
+ try {
2467
+ regex = new RegExp(pattern);
2468
+ } catch (error) {
2469
+ debugLog(
2470
+ `Skipping invalid allowed_patterns regex for provider '${providerId}': ${pattern} (${error instanceof Error ? error.message : String(error)})`
2471
+ );
2472
+ continue;
2473
+ }
2474
+ if (regex.test(trimmedModel)) {
2475
+ return trimmedModel;
2476
+ }
2477
+ }
2478
+ const availableModels = config.models.available.map((info) => info.id);
2479
+ if (availableModels.includes(trimmedModel)) {
2480
+ return trimmedModel;
2481
+ }
2482
+ const validModels = availableModels.length > 0 ? availableModels.join(", ") : "None";
2483
+ const validPatterns = config.models.allowed_patterns.length > 0 ? config.models.allowed_patterns.join(", ") : "None";
2484
+ const registrySources = !registryOverride || registryOverride === _ProviderRegistry.instance ? _ProviderRegistry.getLoadedConfigSources() : [];
2485
+ const sourceDetail = registrySources.length > 0 ? ` Registry sources: ${registrySources.join(", ")}.` : "";
2486
+ throw new Error(
2487
+ `Model '${trimmedModel}' is not available for provider '${providerId}'. Available models: ${validModels}. Allowed patterns: ${validPatterns}.${sourceDetail}`
2488
+ );
2489
+ }
2490
+ /**
2491
+ * Get bot identity configuration for cloud providers
2492
+ *
2493
+ * @param providerId - Provider identifier
2494
+ * @returns Bot identity config if provider is cloud-based, undefined otherwise
2495
+ */
2496
+ static getBotIdentity(providerId) {
2497
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2498
+ return config.bot_identity;
2499
+ }
2500
+ /**
2501
+ * Get timeout for a specific provider
2502
+ *
2503
+ * @param providerId - Provider identifier
2504
+ * @returns Timeout in milliseconds
2505
+ */
2506
+ static getTimeout(providerId) {
2507
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2508
+ return config.timeout_ms;
2509
+ }
2510
+ /**
2511
+ * Get retry configuration for a specific provider
2512
+ *
2513
+ * @param providerId - Provider identifier
2514
+ * @returns Retry configuration with defaults applied
2515
+ */
2516
+ static getRetryConfig(providerId) {
2517
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2518
+ return config.retry || _ProviderRegistry.getDefaults().retry;
2519
+ }
2520
+ /**
2521
+ * Get circuit breaker configuration for a specific provider
2522
+ *
2523
+ * @param providerId - Provider identifier
2524
+ * @returns Circuit breaker configuration with defaults applied
2525
+ */
2526
+ static getCircuitBreakerConfig(providerId) {
2527
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2528
+ return config.circuit_breaker || _ProviderRegistry.getDefaults().circuit_breaker;
2529
+ }
2530
+ /**
2531
+ * Get memory configuration for a specific provider
2532
+ *
2533
+ * @param providerId - Provider identifier
2534
+ * @returns Memory configuration
2535
+ */
2536
+ static getMemoryConfig(providerId) {
2537
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2538
+ return config.memory;
2539
+ }
2540
+ /**
2541
+ * Get polling configuration for a specific provider
2542
+ *
2543
+ * @param providerId - Provider identifier
2544
+ * @returns Polling configuration if provider supports it, default otherwise
2545
+ */
2546
+ static getPollingConfig(providerId) {
2547
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2548
+ return config.polling || _ProviderRegistry.getDefaults().polling;
2549
+ }
2550
+ /**
2551
+ * Get pricing configuration for a specific provider
2552
+ *
2553
+ * @param providerId - Provider identifier
2554
+ * @returns Pricing configuration if available, undefined otherwise
2555
+ */
2556
+ static getProviderPricing(providerId) {
2557
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2558
+ return config.pricing;
2559
+ }
2560
+ /**
2561
+ * Get model pricing for a specific provider and model
2562
+ *
2563
+ * @param providerId - Provider identifier
2564
+ * @param modelId - Model identifier
2565
+ * @returns Model pricing if available, undefined otherwise
2566
+ */
2567
+ static getModelPricing(providerId, modelId) {
2568
+ const pricing = _ProviderRegistry.getProviderPricing(providerId);
2569
+ if (!pricing || !pricing.models) return void 0;
2570
+ return pricing.models[modelId];
2571
+ }
2572
+ /**
2573
+ * Resolve provider ID from model name using allowed_patterns
2574
+ *
2575
+ * @param model - Model name (e.g., 'gemini-2.5-flash', 'sonnet-4-5')
2576
+ * @returns Provider ID if model matches a pattern, undefined otherwise
2577
+ */
2578
+ static resolveProviderByModel(model) {
2579
+ if (!model) return void 0;
2580
+ const registry = _ProviderRegistry.getActiveRegistry();
2581
+ const isNonAuthoritativeOwnershipPattern = (pattern) => {
2582
+ const normalized = pattern.trim();
2583
+ return normalized === ".*" || normalized === "^.*$" || normalized === CURSOR_ID_SYNTAX_ADMISSION_PATTERN;
2584
+ };
2585
+ const matches = [];
2586
+ for (const [providerId, provider] of Object.entries(registry.providers)) {
2587
+ if (!provider.enabled) continue;
2588
+ const patterns = provider.models.allowed_patterns || [];
2589
+ let providerMatched = false;
2590
+ for (const pattern of patterns) {
2591
+ try {
2592
+ const regex = new RegExp(pattern, "i");
2593
+ if (regex.test(model)) {
2594
+ if (isNonAuthoritativeOwnershipPattern(pattern)) {
2595
+ continue;
2596
+ }
2597
+ providerMatched = true;
2598
+ break;
2599
+ }
2600
+ } catch (error) {
2601
+ emitWarning(
2602
+ "CFG-003",
2603
+ {
2604
+ taskId: "provider-registry",
2605
+ subsystem: "config",
2606
+ executionPhase: "setup"
2607
+ },
2608
+ {
2609
+ severity: "WARN" /* WARN */,
2610
+ metadata: {
2611
+ providerId,
2612
+ pattern,
2613
+ error: error instanceof Error ? error.message : String(error),
2614
+ operation: "resolveProviderByModel"
2615
+ }
2616
+ }
2617
+ );
2618
+ }
2619
+ }
2620
+ if (providerMatched) {
2621
+ matches.push(providerId);
2622
+ }
2623
+ }
2624
+ if (matches.length === 1) {
2625
+ return matches[0];
2626
+ }
2627
+ return void 0;
2628
+ }
2629
+ /**
2630
+ * Get plugins for a specific provider
2631
+ *
2632
+ * @param providerId - Provider identifier
2633
+ * @returns Array of plugins, or empty array if none defined
2634
+ */
2635
+ static getProviderPlugins(providerId) {
2636
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2637
+ return config.plugins || [];
2638
+ }
2639
+ /**
2640
+ * Get options for a specific provider
2641
+ *
2642
+ * @param providerId - Provider identifier
2643
+ * @returns Provider options, or empty object if none defined
2644
+ */
2645
+ static getProviderOptions(providerId) {
2646
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2647
+ return config.options || {};
2648
+ }
2649
+ /**
2650
+ * Get requirements for a specific provider
2651
+ *
2652
+ * @param providerId - Provider identifier
2653
+ * @returns Provider requirements with both unconditional and conditional deps
2654
+ */
2655
+ static getProviderRequirements(providerId) {
2656
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2657
+ return {
2658
+ requires: config.requires || [],
2659
+ requires_if: config.requires_if || {}
2660
+ };
2661
+ }
2662
+ /**
2663
+ * Get a specific plugin by ID from a provider
2664
+ *
2665
+ * @param providerId - Provider identifier
2666
+ * @param pluginId - Plugin identifier
2667
+ * @returns Plugin configuration if found, undefined otherwise
2668
+ */
2669
+ static getPlugin(providerId, pluginId) {
2670
+ const plugins = _ProviderRegistry.getProviderPlugins(providerId);
2671
+ return plugins.find((p) => p.id === pluginId);
2672
+ }
2673
+ /**
2674
+ * Get a specific option by key from a provider
2675
+ *
2676
+ * @param providerId - Provider identifier
2677
+ * @param optionKey - Option key
2678
+ * @returns Provider option if found, undefined otherwise
2679
+ */
2680
+ static getOption(providerId, optionKey) {
2681
+ const options = _ProviderRegistry.getProviderOptions(providerId);
2682
+ return options[optionKey];
2683
+ }
2684
+ /**
2685
+ * Get the default model for a provider, from static registry config.
2686
+ * For runtime-observed defaults, use provider-specific discovery.
2687
+ *
2688
+ * @param providerId - Provider identifier
2689
+ * @returns Default model ID, or undefined if not configured
2690
+ */
2691
+ static getDefaultModel(providerId, registryOverride) {
2692
+ const config = _ProviderRegistry.getProviderConfig(providerId, registryOverride);
2693
+ return config.models.default || void 0;
2694
+ }
2695
+ /**
2696
+ * Get a model assigned to a provider-specific role, if configured.
2697
+ *
2698
+ * Roles encode product intent such as "quality" or "fast" without assuming
2699
+ * the provider default is suitable for every outcome strategy.
2700
+ *
2701
+ * @param providerId - Provider identifier
2702
+ * @param role - Model role name
2703
+ * @returns Resolved model ID for the role, or undefined if the role is not configured
2704
+ */
2705
+ static getModelForRole(providerId, role, registryOverride) {
2706
+ const trimmedRole = role.trim();
2707
+ if (!trimmedRole) return void 0;
2708
+ const config = _ProviderRegistry.getProviderConfig(providerId, registryOverride);
2709
+ const configuredModel = config.models.roles?.[trimmedRole];
2710
+ if (!configuredModel) return void 0;
2711
+ return _ProviderRegistry.resolveModel(providerId, configuredModel, registryOverride);
2712
+ }
2713
+ /**
2714
+ * Resolve a reviewer model across all enabled providers, excluding specified providers.
2715
+ *
2716
+ * Implements the cross-provider review rule from the Wave 2 design record:
2717
+ * reviewer != orchestrator provider != executor provider (and any additional
2718
+ * mutation-owner providers the caller passes). Callers pass the provider IDs
2719
+ * already assigned to other stages so this method returns the first remaining
2720
+ * provider that has a model for a role in the role chain.
2721
+ *
2722
+ * Default role chain mirrors judge-tier-selector.ts: `['reviewer', 'quality']`.
2723
+ * Callers that honor a configured `roles.reviewer.modelRole` should pass a
2724
+ * chain starting with that role (then the defaults) so automatic selection
2725
+ * does not silently ignore the configured role.
2726
+ *
2727
+ * Candidate order: when `providerPreference` is provided, those ids are
2728
+ * tried first (skipping excluded / disabled / unknown entries); remaining
2729
+ * enabled providers are then appended in registry `order`. With no
2730
+ * preference, only registry order is used (dormant-compatible).
2731
+ *
2732
+ * Returns null when no qualifying provider is found. Pure and static — reads
2733
+ * only from the loaded registry and applies no side effects.
2734
+ *
2735
+ * @param excludeProviders - Provider IDs to skip (e.g. orchestrator + executor + mutation owners)
2736
+ * @param options.roleChain - Model-role fallback chain (default: reviewer, quality)
2737
+ * @param options.providerPreference - Preferred provider order for selection
2738
+ * @returns Provider + resolved model + winning role, or null if none qualify
2739
+ */
2740
+ static resolveReviewerModel(excludeProviders, options = {}, registryOverride) {
2741
+ const excludeSet = new Set(
2742
+ excludeProviders.map((p) => p.trim().toLowerCase()).filter((p) => p.length > 0)
2743
+ );
2744
+ const roleChain = options.roleChain && options.roleChain.length > 0 ? options.roleChain.map((r) => r.trim()).filter((r) => r.length > 0) : ["reviewer", "quality"];
2745
+ if (roleChain.length === 0) {
2746
+ return null;
2747
+ }
2748
+ const enabled = _ProviderRegistry.getEnabledProviders(registryOverride);
2749
+ const enabledById = new Map(enabled.map((p) => [p.id.toLowerCase(), p]));
2750
+ const ordered = [];
2751
+ const seen = /* @__PURE__ */ new Set();
2752
+ for (const pref of options.providerPreference ?? []) {
2753
+ const key = pref.trim().toLowerCase();
2754
+ if (!key || seen.has(key) || excludeSet.has(key)) continue;
2755
+ const match = enabledById.get(key);
2756
+ if (match) {
2757
+ ordered.push(match);
2758
+ seen.add(key);
2759
+ }
2760
+ }
2761
+ for (const providerConfig of enabled) {
2762
+ const key = providerConfig.id.toLowerCase();
2763
+ if (seen.has(key) || excludeSet.has(key)) continue;
2764
+ ordered.push(providerConfig);
2765
+ seen.add(key);
2766
+ }
2767
+ for (const providerConfig of ordered) {
2768
+ const pid = providerConfig.id;
2769
+ for (const role of roleChain) {
2770
+ const model = _ProviderRegistry.getModelForRole(pid, role, registryOverride);
2771
+ if (model) {
2772
+ return { provider: pid, model, role };
2773
+ }
2774
+ }
2775
+ }
2776
+ return null;
2777
+ }
2778
+ /**
2779
+ * Get the list of available models for a provider, from static registry config.
2780
+ * `getDiscoveredModels()` currently returns this same static inventory.
2781
+ * For observation-backed IDs, call `getCachedProviderModelIds` from
2782
+ * `src/core/providers/model-discovery-cache.ts`.
2783
+ *
2784
+ * @param providerId - Provider identifier
2785
+ * @returns Array of available model IDs from the static registry
2786
+ */
2787
+ static getAvailableModels(providerId) {
2788
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2789
+ return config.models.available.map((m) => m.id);
2790
+ }
2791
+ /**
2792
+ * Get static model mappings for a provider (logical name → native CLI ID).
2793
+ * For Cursor, also check getCachedCanonicalMappings() from
2794
+ * src/core/providers/cursor/model-discovery.ts for discovery-fed mappings.
2795
+ *
2796
+ * @param providerId - Provider identifier
2797
+ * @returns Record mapping logical model names to native CLI IDs
2798
+ */
2799
+ static getMappings(providerId) {
2800
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2801
+ return cloneProviderRegistryValue(config.models.mappings);
2802
+ }
2803
+ /**
2804
+ * Return the static available-model list from this registry.
2805
+ *
2806
+ * Despite the name, this is not live discovery and does not read an
2807
+ * observation cache. It is equivalent to `getAvailableModels()`.
2808
+ *
2809
+ * Callers that need observation-backed IDs should import the cache reader:
2810
+ *
2811
+ * import { getCachedProviderModelIds } from
2812
+ * '../providers/model-discovery-cache.js';
2813
+ * const ids = getCachedProviderModelIds(providerId);
2814
+ *
2815
+ * That reader returns local cache evidence only (empty when none) and does
2816
+ * not fall back to this registry.
2817
+ *
2818
+ * @param providerId - Provider identifier
2819
+ * @returns Array of model IDs from the static registry
2820
+ */
2821
+ static getDiscoveredModels(providerId) {
2822
+ const normalized = normalizeProviderConfigId(providerId);
2823
+ return _ProviderRegistry.getAvailableModels(normalized);
2824
+ }
2825
+ /**
2826
+ * Read a single capability flag for a provider.
2827
+ *
2828
+ * Returns the boolean value when explicitly set in providers.yaml, or
2829
+ * `undefined` when the flag is absent (caller must decide the default).
2830
+ *
2831
+ * @param providerId - Provider identifier
2832
+ * @param name - Capability key (e.g. 'supports_api_judge')
2833
+ * @returns boolean if set, undefined if not declared
2834
+ */
2835
+ static getCapability(providerId, name) {
2836
+ const config = _ProviderRegistry.getProviderConfig(providerId);
2837
+ const value = config.capabilities[name];
2838
+ return typeof value === "boolean" ? value : void 0;
2839
+ }
2840
+ };
2841
+ function loadProviderRegistry(configPath) {
2842
+ return ProviderRegistry.load(configPath);
2843
+ }
2844
+ function getProviderConfig(providerId, registryOverride) {
2845
+ return ProviderRegistry.getProviderConfig(providerId, registryOverride);
2846
+ }
2847
+ function getCapability(providerId, name) {
2848
+ return ProviderRegistry.getCapability(providerId, name);
2849
+ }
2850
+
2851
+ export {
2852
+ PROVIDER_CATALOG_SHA256,
2853
+ REFRESH_OVERLAY_SCHEMA_VERSION,
2854
+ OverlayModelAvailableEntrySchema,
2855
+ OverlayPricingRowSchema,
2856
+ getRefreshOverlayOperatorNotice,
2857
+ emptyRefreshOverlay,
2858
+ serializeRefreshOverlay,
2859
+ resolveRefreshOverlayDisposition,
2860
+ loadRefreshOverlayFile,
2861
+ fingerprintEnvironment,
2862
+ fingerprintFile,
2863
+ fingerprintFiles,
2864
+ combineCacheFingerprints,
2865
+ InvalidExplicitConfigError,
2866
+ isInvalidExplicitConfigError,
2867
+ isConfigValidityError,
2868
+ rethrowConfigValidityError,
2869
+ isRecognizedEnvVar,
2870
+ getEnvVarEntry,
2871
+ validateEnvironmentVars,
2872
+ isTrustedProjectRoot,
2873
+ formatProjectTrustInstruction,
2874
+ registerProviderRegistryReloadInvalidator,
2875
+ getConfiguredProviderRegistryPaths,
2876
+ getProviderRegistryInputPaths,
2877
+ RetryConfigSchema,
2878
+ CircuitBreakerConfigSchema,
2879
+ RateLimitEntrySchema,
2880
+ RateLimitsConfigSchema,
2881
+ MemoryConfigSchema,
2882
+ PollingConfigSchema,
2883
+ CLIConfigSchema,
2884
+ AuthConfigSchema,
2885
+ TemplatedAuthConfigSchema,
2886
+ ProbeExpectationSchema,
2887
+ CommandProbeSchema,
2888
+ ModelsDiscoverySchema,
2889
+ ModelInfoSchema,
2890
+ ModelAccessClassSchema,
2891
+ ModelAccessConfigSchema,
2892
+ ModelsConfigSchema,
2893
+ TemplatedModelsConfigSchema,
2894
+ CapabilitiesConfigSchema,
2895
+ TemplatedCapabilitiesConfigSchema,
2896
+ BotIdentityConfigSchema,
2897
+ EnvConfigSchema,
2898
+ ModelPricingSchema,
2899
+ ToolPricingSchema,
2900
+ SubscriptionPricingSchema,
2901
+ InfrastructurePricingSchema,
2902
+ ProviderPricingSchema,
2903
+ RefreshStrategyConfigSchema,
2904
+ DefaultPricingSchema,
2905
+ ConcurrencyConfigSchema,
2906
+ RouteConfigSchema,
2907
+ WorkspaceEditsConfigSchema,
2908
+ GenerationConfigSchema,
2909
+ TaskSettingsSchema,
2910
+ PluginVerifySchema,
2911
+ PluginConfigureStepSchema,
2912
+ RequirementSchema,
2913
+ PluginSchema,
2914
+ ProviderOptionSchema,
2915
+ ProviderOptionsSchema,
2916
+ ConditionalRequiresSchema,
2917
+ ProviderRequiresSchema,
2918
+ ApiConfigSchema,
2919
+ TemplatedCLIExecutionSchema,
2920
+ NativeProviderConfigSchema,
2921
+ TemplatedProviderConfigSchema,
2922
+ ProviderConfigSchema,
2923
+ DefaultsConfigSchema,
2924
+ MetadataConfigSchema,
2925
+ ProviderRegistryConfigSchema,
2926
+ ProviderRegistry,
2927
+ loadProviderRegistry,
2928
+ getProviderConfig,
2929
+ getCapability
2930
+ };
2931
+ //# sourceMappingURL=chunk-AT4TNPWW.js.map