@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,3063 @@
1
+ import {
2
+ resolveExecutionBoundary
3
+ } from "./chunk-7R2WLDOS.js";
4
+ import {
5
+ describeVerificationCommand,
6
+ detectExitZeroVerifyFailure,
7
+ detectZeroCollectedTests,
8
+ resolveVerificationExitCode
9
+ } from "./chunk-2QLYTVYX.js";
10
+
11
+ // src/core/verification/verify-commands.ts
12
+ import { execa } from "execa";
13
+ var VERIFY_GLOBAL_BUDGET_EXIT_CODE = 124;
14
+ var VERIFY_COMMAND_REJECTED_EXIT_CODE = 126;
15
+ var VERIFY_COMMAND_PROCESS_FAILURE_EXIT_CODE = 1;
16
+ var VERIFY_COMMAND_MAX_BUFFER_BYTES = 128 * 1024 * 1024;
17
+ var VERIFY_COMMAND_RETAINED_TAIL_BYTES = 256 * 1024;
18
+ function boundTailBytes(output, maxBytes) {
19
+ if (output.length <= maxBytes) return output;
20
+ return output.slice(output.length - maxBytes);
21
+ }
22
+ var ALLOWED_VERIFY_EXECUTABLES = /* @__PURE__ */ new Set([
23
+ "ava",
24
+ "biome",
25
+ "black",
26
+ "bundle",
27
+ "bun",
28
+ "cargo",
29
+ "clang-tidy",
30
+ "cmake",
31
+ "composer",
32
+ "ctest",
33
+ "dart",
34
+ "dbt",
35
+ "detekt",
36
+ "dotnet",
37
+ "echo",
38
+ "eslint",
39
+ "env",
40
+ "flutter",
41
+ "git",
42
+ "go",
43
+ "golangci-lint",
44
+ "govulncheck",
45
+ "gradle",
46
+ "gradlew",
47
+ "grep",
48
+ "hadolint",
49
+ "jest",
50
+ "just",
51
+ "ktlint",
52
+ "kubeconform",
53
+ "make",
54
+ "meson",
55
+ "mocha",
56
+ "mvn",
57
+ "mvnw",
58
+ "mypy",
59
+ "node",
60
+ "npm",
61
+ "npx",
62
+ "pnpm",
63
+ "poetic",
64
+ "powershell",
65
+ "powershell.exe",
66
+ "prettier",
67
+ "printf",
68
+ "pwsh",
69
+ "pwsh.exe",
70
+ "pytest",
71
+ "py",
72
+ "php",
73
+ "phpstan",
74
+ "phpunit",
75
+ "pip-audit",
76
+ "psalm",
77
+ "python",
78
+ "python3",
79
+ "R",
80
+ "rake",
81
+ "rspec",
82
+ "ruff",
83
+ "ruby",
84
+ "rubocop",
85
+ "shellcheck",
86
+ "sqlfluff",
87
+ "staticcheck",
88
+ "swift",
89
+ "swiftlint",
90
+ "tap",
91
+ "task",
92
+ "terraform",
93
+ "test",
94
+ "tflint",
95
+ "tsc",
96
+ "turbo",
97
+ "vitest",
98
+ "vue-tsc",
99
+ "yarn"
100
+ ]);
101
+ var REJECTED_VERIFY_EXECUTABLES = /* @__PURE__ */ new Set([
102
+ "bash",
103
+ "dash",
104
+ "fish",
105
+ "ksh",
106
+ "osascript",
107
+ "powershell",
108
+ "powershell.exe",
109
+ "pwsh",
110
+ "pwsh.exe",
111
+ "sh",
112
+ "zsh"
113
+ ]);
114
+ function compactOutputSnippet(value, maxChars = 160) {
115
+ const normalized = String(value ?? "").replace(/\s+/g, " ").trim();
116
+ if (!normalized) return void 0;
117
+ return normalized.length <= maxChars ? normalized : `${normalized.slice(0, maxChars - 1)}...`;
118
+ }
119
+ function summarizeVerifyCommandRun(results, totalCommands) {
120
+ const passedCount = results.filter((result) => result.exitCode === 0).length;
121
+ const failedResult = results.find((result) => result.exitCode !== 0);
122
+ const failedCount = failedResult ? 1 : 0;
123
+ const skippedCount = Math.max(0, totalCommands - results.length);
124
+ if (!failedResult) {
125
+ return `Verify passed: ${passedCount} passed, 0 failed, ${skippedCount} skipped.`;
126
+ }
127
+ const outputSnippet = compactOutputSnippet(
128
+ failedResult.stderrTail || failedResult.stdoutTail || failedResult.outputTail
129
+ );
130
+ return `Verify failed: ${passedCount} passed, ${failedCount} failed, ${skippedCount} skipped. Failed command: ${failedResult.command} (exit ${failedResult.exitCode})` + (outputSnippet ? `. Output: ${outputSnippet}` : ".");
131
+ }
132
+ function validationSurfaceToCommands(surface) {
133
+ return surface.commands;
134
+ }
135
+ function mergeValidationSurfaces(surfaces) {
136
+ const seen = /* @__PURE__ */ new Set();
137
+ const commands = [];
138
+ for (const surface of surfaces) {
139
+ for (const cmd of surface.commands) {
140
+ if (!seen.has(cmd)) {
141
+ seen.add(cmd);
142
+ commands.push(cmd);
143
+ }
144
+ }
145
+ }
146
+ return commands;
147
+ }
148
+ function formatOutputTail(content, maxLines = 80) {
149
+ const lines = String(content ?? "").split(/\r?\n/);
150
+ const tail = lines.slice(-maxLines).join("\n").trim();
151
+ return tail.length > 0 ? tail : "(no output)";
152
+ }
153
+ function errorMessage(value) {
154
+ if (value instanceof Error) return value.message;
155
+ if (typeof value === "string" && value.trim()) return value.trim();
156
+ return void 0;
157
+ }
158
+ function resolveProcessExitCode(command, result) {
159
+ if (result.isCanceled) {
160
+ return VERIFY_GLOBAL_BUDGET_EXIT_CODE;
161
+ }
162
+ return resolveVerificationExitCode(command, result, {
163
+ failureExitCode: VERIFY_COMMAND_PROCESS_FAILURE_EXIT_CODE
164
+ }).exitCode;
165
+ }
166
+ function describeMissingProcessExitCode(result) {
167
+ if (typeof result.exitCode === "number") return void 0;
168
+ const reasons = [];
169
+ if (result.timedOut) reasons.push("timed out");
170
+ if (result.isCanceled) reasons.push("canceled");
171
+ if (result.signal) reasons.push(`signal ${result.signal}`);
172
+ if (result.killed) reasons.push("killed");
173
+ if (result.failed) reasons.push("failed");
174
+ const message = errorMessage(result.error);
175
+ if (message) reasons.push(message);
176
+ return "[verify] Process ended without a numeric exit code" + (reasons.length > 0 ? ` (${reasons.join(", ")})` : "") + ". Treating as failure.";
177
+ }
178
+ function detectTestRunnerFailureSummary(command, output) {
179
+ const failure = detectExitZeroVerifyFailure(command, output)?.message;
180
+ if (failure) return failure;
181
+ if (detectZeroCollectedTests(command, output)) {
182
+ return "Test command exited 0 but collected/ran zero tests; no verification evidence.";
183
+ }
184
+ return void 0;
185
+ }
186
+ function hasShellControlOperators(command) {
187
+ return /(?:\|\||&&|[|;<>])/.test(command);
188
+ }
189
+ function isBaselineComparableTypeScriptCompilerCommand(command) {
190
+ const parsed = parseVerifyCommand(command);
191
+ if (!Array.isArray(parsed) || parsed.length !== 1) return false;
192
+ const argv = parsed[0]?.argv ?? [];
193
+ const executable = getExecutableName(argv[0] ?? "").replace(/\.(?:cmd|exe|ps1)$/i, "");
194
+ let targetIndex = 0;
195
+ if (executable === "npx" || executable === "pnpx" || executable === "bunx") {
196
+ targetIndex = 1;
197
+ while (argv[targetIndex] === "--no-install" || argv[targetIndex] === "--offline") {
198
+ targetIndex += 1;
199
+ }
200
+ }
201
+ const target = argv[targetIndex] ?? "";
202
+ const targetName = getExecutableName(target).replace(/\.(?:cmd|exe|ps1)$/i, "");
203
+ if (targetName !== "tsc" && targetName !== "vue-tsc") return false;
204
+ const args = argv.slice(targetIndex + 1);
205
+ return args.some(
206
+ (arg) => arg === "--noEmit" || arg === "-p" || arg.startsWith("-p=") || arg === "--project" || arg.startsWith("--project=") || arg === "-b" || arg === "--build" || /(?:^|[/\\])tsconfig[^/\\]*\.json$/i.test(arg)
207
+ );
208
+ }
209
+ function makeSignatureNewCount(signatures, count) {
210
+ return (baselineOutput, currentOutput) => {
211
+ const currentCount = count(currentOutput);
212
+ if (currentCount === 0) return 0;
213
+ const baselineSigs = signatures(baselineOutput);
214
+ const currentSigs = signatures(currentOutput);
215
+ if (baselineSigs.size === 0 || currentSigs.size === 0) {
216
+ const delta = currentCount - count(baselineOutput);
217
+ return delta > 0 ? delta : 1;
218
+ }
219
+ let newCount = 0;
220
+ for (const sig of currentSigs) {
221
+ if (!baselineSigs.has(sig)) newCount++;
222
+ }
223
+ return newCount;
224
+ };
225
+ }
226
+ function extractRustErrorSignatures(output) {
227
+ const signatures = /* @__PURE__ */ new Set();
228
+ const lines = output.split(/\r?\n/);
229
+ for (let i = 0; i < lines.length; i += 1) {
230
+ const line = lines[i] ?? "";
231
+ const m = /^error(\[E\d+\])?:\s*(.*)$/.exec(line.trim());
232
+ if (!m) continue;
233
+ if (/could not compile .*due to \d+ previous error/i.test(line)) continue;
234
+ const code = m[1] ?? "";
235
+ const msg = (m[2] ?? "").trim().slice(0, 120);
236
+ const next = (lines[i + 1] ?? "").trim();
237
+ const loc = /^-->\s+(.+)$/.exec(next)?.[1] ?? "";
238
+ signatures.add(`${loc} - error${code}: ${msg}`);
239
+ }
240
+ return signatures;
241
+ }
242
+ function countRustErrorsFromOutput(output) {
243
+ const summaryMatches = [...output.matchAll(/due to (\d+) previous errors?/gi)];
244
+ const lastSummary = summaryMatches.at(-1);
245
+ if (lastSummary?.[1]) {
246
+ const parsed = Number.parseInt(lastSummary[1], 10);
247
+ if (Number.isFinite(parsed)) return parsed;
248
+ }
249
+ const errorLines = output.split(/\r?\n/).filter(
250
+ (line) => /^error(\[E\d+\])?:/.test(line.trim()) && !/could not compile .*due to \d+ previous error/i.test(line)
251
+ );
252
+ return errorLines.length > 0 ? errorLines.length : 1;
253
+ }
254
+ var GO_ERROR_LINE_RE = /^(.+?\.go):(\d+)(?::(\d+))?:\s+(.*)$/;
255
+ function extractGoErrorSignatures(output) {
256
+ const signatures = /* @__PURE__ */ new Set();
257
+ for (const line of output.split(/\r?\n/)) {
258
+ const m = GO_ERROR_LINE_RE.exec(line.trim());
259
+ if (!m) continue;
260
+ const msg = (m[4] ?? "").trim().slice(0, 120);
261
+ signatures.add(`${m[1]}:${m[2]} - ${msg}`);
262
+ }
263
+ return signatures;
264
+ }
265
+ function countGoErrorsFromOutput(output) {
266
+ const matches = output.split(/\r?\n/).filter((line) => GO_ERROR_LINE_RE.test(line.trim()));
267
+ return matches.length > 0 ? matches.length : 1;
268
+ }
269
+ var MYPY_ERROR_LINE_RE = /^(.+?\.py):(\d+)(?::\d+)?:\s+error:\s*(.*)$/;
270
+ function extractPythonErrorSignatures(output) {
271
+ const signatures = /* @__PURE__ */ new Set();
272
+ for (const line of output.split(/\r?\n/)) {
273
+ const m = MYPY_ERROR_LINE_RE.exec(line.trim());
274
+ if (!m) continue;
275
+ const msg = (m[3] ?? "").trim().slice(0, 120);
276
+ signatures.add(`${m[1]}:${m[2]} - error: ${msg}`);
277
+ }
278
+ return signatures;
279
+ }
280
+ function countPythonErrorsFromOutput(output) {
281
+ const summaryMatches = [...output.matchAll(/\bFound\s+(\d+)\s+errors?\b/gi)];
282
+ const lastSummary = summaryMatches.at(-1);
283
+ if (lastSummary?.[1]) {
284
+ const parsed = Number.parseInt(lastSummary[1], 10);
285
+ if (Number.isFinite(parsed)) return parsed;
286
+ }
287
+ const matches = output.split(/\r?\n/).filter((line) => MYPY_ERROR_LINE_RE.test(line.trim()));
288
+ return matches.length > 0 ? matches.length : 1;
289
+ }
290
+ function isSimpleSingleVerifyCommand(command) {
291
+ const parsed = parseVerifyCommand(command);
292
+ if (!Array.isArray(parsed) || parsed.length !== 1) return void 0;
293
+ return parsed[0]?.argv ?? [];
294
+ }
295
+ function matchesCargoErrorCommand(command) {
296
+ const argv = isSimpleSingleVerifyCommand(command);
297
+ if (!argv) return false;
298
+ const executable = getExecutableName(argv[0] ?? "");
299
+ if (executable !== "cargo") return false;
300
+ const verb = argv[1] ?? "";
301
+ return verb === "check" || verb === "build" || verb === "clippy";
302
+ }
303
+ function matchesGoErrorCommand(command) {
304
+ const argv = isSimpleSingleVerifyCommand(command);
305
+ if (!argv) return false;
306
+ const executable = getExecutableName(argv[0] ?? "");
307
+ if (executable !== "go") return false;
308
+ const verb = argv[1] ?? "";
309
+ return verb === "build" || verb === "vet";
310
+ }
311
+ function matchesMypyErrorCommand(command) {
312
+ const argv = isSimpleSingleVerifyCommand(command);
313
+ if (!argv) return false;
314
+ const executable = getExecutableName(argv[0] ?? "");
315
+ if (executable === "mypy") return true;
316
+ if (executable === "python" || executable === "python3" || executable === "py") {
317
+ return argv[1] === "-m" && argv[2] === "mypy";
318
+ }
319
+ return false;
320
+ }
321
+ var BASELINE_ERROR_PARSERS = {
322
+ node: {
323
+ matches: isBaselineComparableTypeScriptCompilerCommand,
324
+ signatures: extractTypeScriptErrorSignatures,
325
+ count: countTypeScriptErrorsFromOutput,
326
+ newCount: computeNewErrorCount
327
+ },
328
+ rust: {
329
+ matches: matchesCargoErrorCommand,
330
+ signatures: extractRustErrorSignatures,
331
+ count: countRustErrorsFromOutput,
332
+ newCount: makeSignatureNewCount(extractRustErrorSignatures, countRustErrorsFromOutput)
333
+ },
334
+ go: {
335
+ matches: matchesGoErrorCommand,
336
+ signatures: extractGoErrorSignatures,
337
+ count: countGoErrorsFromOutput,
338
+ newCount: makeSignatureNewCount(extractGoErrorSignatures, countGoErrorsFromOutput)
339
+ },
340
+ python: {
341
+ matches: matchesMypyErrorCommand,
342
+ signatures: extractPythonErrorSignatures,
343
+ count: countPythonErrorsFromOutput,
344
+ newCount: makeSignatureNewCount(extractPythonErrorSignatures, countPythonErrorsFromOutput)
345
+ }
346
+ };
347
+ function resolveBaselineErrorParser(command) {
348
+ const trimmed = command.trim();
349
+ if (trimmed.length === 0 || hasShellControlOperators(trimmed)) {
350
+ return void 0;
351
+ }
352
+ const language = describeVerificationCommand(trimmed).language;
353
+ const byLanguage = language !== "unknown" ? BASELINE_ERROR_PARSERS[language] : void 0;
354
+ if (byLanguage?.matches(trimmed)) {
355
+ return byLanguage;
356
+ }
357
+ for (const parser of Object.values(BASELINE_ERROR_PARSERS)) {
358
+ if (parser?.matches(trimmed)) {
359
+ return parser;
360
+ }
361
+ }
362
+ return void 0;
363
+ }
364
+ function isBaselineComparableTypeScriptCommand(command) {
365
+ return resolveBaselineErrorParser(command) !== void 0;
366
+ }
367
+ function countTypeScriptErrorsFromOutput(output) {
368
+ const summaryMatches = [...output.matchAll(/\bFound\s+(\d+)\s+errors?/gi)];
369
+ const lastSummary = summaryMatches.at(-1);
370
+ if (lastSummary?.[1]) {
371
+ const parsed = Number.parseInt(lastSummary[1], 10);
372
+ if (Number.isFinite(parsed)) return parsed;
373
+ }
374
+ const tsErrorMatches = output.match(/error TS\d+:/g);
375
+ if (tsErrorMatches && tsErrorMatches.length > 0) {
376
+ return tsErrorMatches.length;
377
+ }
378
+ return 1;
379
+ }
380
+ function extractTypeScriptErrorSignatures(output) {
381
+ const signatures = /* @__PURE__ */ new Set();
382
+ const lineRe = /^(.+?)\((\d+),\d+\):\s+error\s+(TS\d+):\s*(.*)$/gm;
383
+ for (const m of output.matchAll(lineRe)) {
384
+ const msg = (m[4] ?? "").trim().slice(0, 120);
385
+ signatures.add(`${m[1]}:${m[2]} - error ${m[3]}: ${msg}`);
386
+ }
387
+ return signatures;
388
+ }
389
+ function computeNewErrorCount(baselineOutput, currentOutput) {
390
+ const baselineSigs = extractTypeScriptErrorSignatures(baselineOutput);
391
+ const currentSigs = extractTypeScriptErrorSignatures(currentOutput);
392
+ const baselineCount = countTypeScriptErrorsFromOutput(baselineOutput);
393
+ const currentCount = countTypeScriptErrorsFromOutput(currentOutput);
394
+ if (currentCount === 0) {
395
+ return 0;
396
+ }
397
+ if (baselineSigs.size === 0 || currentSigs.size === 0) {
398
+ const countDelta = currentCount - baselineCount;
399
+ if (countDelta > 0) {
400
+ return countDelta;
401
+ }
402
+ return 1;
403
+ }
404
+ let newCount = 0;
405
+ for (const sig of currentSigs) {
406
+ if (!baselineSigs.has(sig)) {
407
+ newCount++;
408
+ }
409
+ }
410
+ return newCount;
411
+ }
412
+ function buildSanitizedEnv() {
413
+ const sensitivePattern = /(?:^|_)(?:API[_-]?KEY|AUTH|CONNECTION[_-]?STRING|CREDENTIALS?|DSN|KEY|OAUTH|PASS(?:WORD)?|PRIVATE[_-]?KEY|SECRET|SESSION|TOKEN)(?:_|$)/i;
414
+ const env = {};
415
+ for (const [key, value] of Object.entries(process.env)) {
416
+ if (sensitivePattern.test(key) || isCredentialedUrlEnv(key, value)) continue;
417
+ env[key] = value;
418
+ }
419
+ return env;
420
+ }
421
+ function isCredentialedUrlEnv(key, value) {
422
+ if (!/(?:^|_)URL(?:_|$)/i.test(key) || !value) return false;
423
+ try {
424
+ const parsed = new URL(value);
425
+ return parsed.username.length > 0 || parsed.password.length > 0;
426
+ } catch {
427
+ return /^[a-z][a-z0-9+.-]*:\/\/[^/?#\s@]+@/i.test(value);
428
+ }
429
+ }
430
+ function splitVerifyCommandSequence(command) {
431
+ const trimmed = command.trim();
432
+ if (trimmed.length === 0) {
433
+ return { error: "Empty verify command rejected." };
434
+ }
435
+ if (/[`]/.test(trimmed) || /\$\(/.test(trimmed)) {
436
+ return {
437
+ error: "Verify command rejected: command substitution is not allowed."
438
+ };
439
+ }
440
+ const segments = [];
441
+ let current = "";
442
+ let inSingle = false;
443
+ let inDouble = false;
444
+ let escaped = false;
445
+ for (let i = 0; i < trimmed.length; i++) {
446
+ const ch = trimmed.charAt(i);
447
+ const next = trimmed.charAt(i + 1);
448
+ if (escaped) {
449
+ current += ch;
450
+ escaped = false;
451
+ continue;
452
+ }
453
+ if (ch === "\\") {
454
+ current += ch;
455
+ escaped = true;
456
+ continue;
457
+ }
458
+ if (ch === "'" && !inDouble) {
459
+ inSingle = !inSingle;
460
+ current += ch;
461
+ continue;
462
+ }
463
+ if (ch === '"' && !inSingle) {
464
+ inDouble = !inDouble;
465
+ current += ch;
466
+ continue;
467
+ }
468
+ if (!inSingle && !inDouble) {
469
+ if (ch === "|" || ch === "<" || ch === ">") {
470
+ return {
471
+ error: "Verify command rejected: pipes and redirection are not allowed."
472
+ };
473
+ }
474
+ if (ch === "&") {
475
+ if (next === "&") {
476
+ const part = current.trim();
477
+ if (!part) return { error: "Verify command rejected: empty command segment." };
478
+ segments.push(part, "&&");
479
+ current = "";
480
+ i++;
481
+ continue;
482
+ }
483
+ return {
484
+ error: "Verify command rejected: background execution is not allowed."
485
+ };
486
+ }
487
+ if (ch === ";") {
488
+ return {
489
+ error: "Verify command rejected: command separators are not allowed. Use && so failed verify steps cannot be hidden by later commands."
490
+ };
491
+ }
492
+ }
493
+ current += ch;
494
+ }
495
+ if (inSingle || inDouble) {
496
+ return { error: "Verify command rejected: unterminated quote." };
497
+ }
498
+ const finalPart = current.trim();
499
+ if (!finalPart) {
500
+ return { error: "Verify command rejected: empty command segment." };
501
+ }
502
+ segments.push(finalPart);
503
+ return segments;
504
+ }
505
+ function parseArgv(segment) {
506
+ const args = [];
507
+ let current = "";
508
+ let inSingle = false;
509
+ let inDouble = false;
510
+ let escaped = false;
511
+ for (let i = 0; i < segment.length; i++) {
512
+ const ch = segment.charAt(i);
513
+ if (escaped) {
514
+ current += ch;
515
+ escaped = false;
516
+ continue;
517
+ }
518
+ if (ch === "\\") {
519
+ escaped = true;
520
+ continue;
521
+ }
522
+ if (ch === "'" && !inDouble) {
523
+ inSingle = !inSingle;
524
+ continue;
525
+ }
526
+ if (ch === '"' && !inSingle) {
527
+ inDouble = !inDouble;
528
+ continue;
529
+ }
530
+ if (/\s/.test(ch) && !inSingle && !inDouble) {
531
+ if (current.length > 0) {
532
+ args.push(current);
533
+ current = "";
534
+ }
535
+ continue;
536
+ }
537
+ current += ch;
538
+ }
539
+ if (escaped) {
540
+ current += "\\";
541
+ }
542
+ if (inSingle || inDouble) {
543
+ return { error: "Verify command rejected: unterminated quote." };
544
+ }
545
+ if (current.length > 0) {
546
+ args.push(current);
547
+ }
548
+ if (args.length === 0) {
549
+ return { error: "Verify command rejected: empty command segment." };
550
+ }
551
+ return args;
552
+ }
553
+ function getExecutableName(executable) {
554
+ return executable.split(/[\\/]/).pop() ?? executable;
555
+ }
556
+ var ALLOWED_PATH_QUALIFIED_EXECUTABLES = /* @__PURE__ */ new Set(["./gradlew", "./mvnw"]);
557
+ function validateVerifyArgv(argv, wrapperDepth = 0) {
558
+ const rawExecutable = argv[0] ?? "";
559
+ const executableName = getExecutableName(rawExecutable);
560
+ if (!executableName) {
561
+ return "Verify command rejected: empty executable.";
562
+ }
563
+ if ((rawExecutable.includes("/") || rawExecutable.includes("\\")) && !ALLOWED_PATH_QUALIFIED_EXECUTABLES.has(rawExecutable)) {
564
+ return `Verify command rejected: path-qualified executable "${rawExecutable}" is not allowed. Use a bare command name (e.g. "git", "npm") resolved from PATH.`;
565
+ }
566
+ if (isPowerShellExecutable(executableName)) {
567
+ const powershellError = validatePowerShellToolArgv(executableName, argv);
568
+ if (powershellError) return powershellError;
569
+ } else if (REJECTED_VERIFY_EXECUTABLES.has(executableName)) {
570
+ return `Verify command rejected: shell executable "${executableName}" is not allowed.`;
571
+ }
572
+ if (!ALLOWED_VERIFY_EXECUTABLES.has(executableName)) {
573
+ return `Verify command rejected: executable "${executableName}" is not in the verify allowlist.`;
574
+ }
575
+ const envError = validateEnvArgv(executableName, argv);
576
+ if (envError) {
577
+ return envError;
578
+ }
579
+ if (executableName === "env") {
580
+ return void 0;
581
+ }
582
+ const inlineExecutionFlags = executableName === "node" ? /* @__PURE__ */ new Set(["-e", "--eval", "--import"]) : /* @__PURE__ */ new Set(["-e", "-c"]);
583
+ if ((executableName === "node" || executableName === "python" || executableName === "python3" || executableName === "py") && argv.some((arg) => inlineExecutionFlags.has(normalizeFlagName(arg) ?? arg))) {
584
+ return `Verify command rejected: inline ${executableName} execution is not allowed. Use a repository script/file or a simple allowlisted command such as grep -Fqx instead.`;
585
+ }
586
+ const nodeError = validateNodeToolArgv(executableName, argv, wrapperDepth);
587
+ if (nodeError) {
588
+ return nodeError;
589
+ }
590
+ const simpleReadToolError = validateSimpleReadToolArgv(executableName, argv);
591
+ if (simpleReadToolError) {
592
+ return simpleReadToolError;
593
+ }
594
+ const directLintToolError = validateDirectLintToolArgv(executableName, argv);
595
+ if (directLintToolError) {
596
+ return directLintToolError;
597
+ }
598
+ const expandedLintToolError = validateExpandedLintToolArgv(executableName, argv);
599
+ if (expandedLintToolError) {
600
+ return expandedLintToolError;
601
+ }
602
+ const packageManagerError = validatePackageManagerArgv(executableName, argv);
603
+ if (packageManagerError) {
604
+ return packageManagerError;
605
+ }
606
+ const auditToolError = validateAuditToolArgv(executableName, argv);
607
+ if (auditToolError) {
608
+ return auditToolError;
609
+ }
610
+ const poeticError = validatePoeticArgv(executableName, argv);
611
+ if (poeticError) {
612
+ return poeticError;
613
+ }
614
+ const gitError = validateGitArgv(executableName, argv);
615
+ if (gitError) {
616
+ return gitError;
617
+ }
618
+ const pythonToolError = validatePythonToolArgv(executableName, argv);
619
+ if (pythonToolError) {
620
+ return pythonToolError;
621
+ }
622
+ const rubyToolError = validateRubyToolArgv(executableName, argv);
623
+ if (rubyToolError) {
624
+ return rubyToolError;
625
+ }
626
+ const phpToolError = validatePhpToolArgv(executableName, argv);
627
+ if (phpToolError) {
628
+ return phpToolError;
629
+ }
630
+ const expandedToolchainError = validateExpandedProjectToolArgv(executableName, argv);
631
+ if (expandedToolchainError) {
632
+ return expandedToolchainError;
633
+ }
634
+ const typescriptToolError = validateTypescriptToolArgv(executableName, argv);
635
+ if (typescriptToolError) {
636
+ return typescriptToolError;
637
+ }
638
+ const jsToolchainError = validateJavaScriptToolchainArgv(executableName, argv);
639
+ if (jsToolchainError) {
640
+ return jsToolchainError;
641
+ }
642
+ const buildToolError = validateBuildToolArgv(executableName, argv);
643
+ if (buildToolError) {
644
+ return buildToolError;
645
+ }
646
+ const iacToolError = validateIacToolArgv(executableName, argv);
647
+ if (iacToolError) {
648
+ return iacToolError;
649
+ }
650
+ const runnerToolError = validateRunnerToolArgv(executableName, argv);
651
+ if (runnerToolError) {
652
+ return runnerToolError;
653
+ }
654
+ return void 0;
655
+ }
656
+ function validateExpandedProjectToolArgv(executableName, argv) {
657
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
658
+ const reject = (detail) => `Verify command rejected: ${detail}. Extended project verify tools may only run conventional read-only build, lint, or test commands.`;
659
+ const rejectUnknownFlag = (tool, token) => reject(`${tool} option "${token}" is not allowlisted`);
660
+ const allowOnlyPathSafePositionals = (tool, tokens, options = {}) => {
661
+ const noValueFlags = options.noValueFlags ?? /* @__PURE__ */ new Set();
662
+ const valueFlags = options.valueFlags ?? /* @__PURE__ */ new Set();
663
+ const pathValueFlags = options.pathValueFlags ?? /* @__PURE__ */ new Set();
664
+ for (let i = 0; i < tokens.length; i += 1) {
665
+ const token = tokens[i] ?? "";
666
+ if (!token.startsWith("-")) {
667
+ if (options.allowPositionals === false) {
668
+ return reject(`${tool} positional "${token}" is not allowlisted`);
669
+ }
670
+ if (isEscapingPathValue(token)) {
671
+ return reject(`${tool} operand "${token}" points outside the repository`);
672
+ }
673
+ continue;
674
+ }
675
+ const name = normalizeFlagName(token) ?? token;
676
+ if (noValueFlags.has(name) && !token.includes("=")) continue;
677
+ if (valueFlags.has(name)) {
678
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : tokens[i + 1];
679
+ if (!value || !token.includes("=") && value.startsWith("-")) {
680
+ return reject(`option "${token}" requires a value`);
681
+ }
682
+ if (pathValueFlags.has(name) && isEscapingPathValue(value)) {
683
+ return reject(`option "${token}" points outside the repository`);
684
+ }
685
+ if (!token.includes("=")) i += 1;
686
+ continue;
687
+ }
688
+ return rejectUnknownFlag(tool, token);
689
+ }
690
+ return void 0;
691
+ };
692
+ if (executableName === "cmake") {
693
+ if (args[0] !== "--build") return reject('"cmake" must use "--build"');
694
+ const safeTargets = /* @__PURE__ */ new Set(["all", "build", "check", "test", "verify"]);
695
+ const target = args[1] ?? "";
696
+ if (!target || target.startsWith("-")) {
697
+ if (target !== "--preset")
698
+ return reject('"cmake --build" requires a build directory or --preset');
699
+ } else if (isEscapingPathValue(target)) {
700
+ return reject(`cmake build directory "${target}" points outside the repository`);
701
+ }
702
+ for (let i = 1; i < args.length; i += 1) {
703
+ const token = args[i] ?? "";
704
+ if (!token.startsWith("-")) continue;
705
+ if (["--preset", "--config", "-j", "--parallel"].includes(token)) {
706
+ const value = args[i + 1];
707
+ if (!value || value.startsWith("-")) return reject(`option "${token}" requires a value`);
708
+ i += 1;
709
+ continue;
710
+ }
711
+ if (token === "--target") {
712
+ const value = args[i + 1];
713
+ if (!value || value.startsWith("-")) return reject('option "--target" requires a value');
714
+ if (!safeTargets.has(value)) {
715
+ return reject(`cmake target "${value}" is not allowlisted`);
716
+ }
717
+ i += 1;
718
+ continue;
719
+ }
720
+ if (token.startsWith("--preset=") || token.startsWith("--config=")) continue;
721
+ if (token.startsWith("--target=")) {
722
+ const value = token.slice(token.indexOf("=") + 1);
723
+ if (!safeTargets.has(value)) return reject(`cmake target "${value}" is not allowlisted`);
724
+ continue;
725
+ }
726
+ if (token === "--verbose" || token === "-v") continue;
727
+ return reject(`cmake option "${token}" is not allowlisted`);
728
+ }
729
+ return void 0;
730
+ }
731
+ if (executableName === "ctest") {
732
+ for (let i = 0; i < args.length; i += 1) {
733
+ const token = args[i] ?? "";
734
+ if (!token.startsWith("-")) return reject(`ctest positional "${token}" is not allowlisted`);
735
+ if (token === "--preset" || token === "--test-dir" || token === "-C" || token === "-R") {
736
+ const value = args[i + 1];
737
+ if (!value || value.startsWith("-")) return reject(`option "${token}" requires a value`);
738
+ if ((token === "--test-dir" || token === "-R") && isEscapingPathValue(value)) {
739
+ return reject(`option "${token}" points outside the repository`);
740
+ }
741
+ i += 1;
742
+ continue;
743
+ }
744
+ if (token.startsWith("--preset=") || token.startsWith("-C=") || token.startsWith("-R=")) {
745
+ continue;
746
+ }
747
+ if (token.startsWith("--test-dir=")) {
748
+ const value = token.slice(token.indexOf("=") + 1);
749
+ if (isEscapingPathValue(value))
750
+ return reject(`option "${token}" points outside the repository`);
751
+ continue;
752
+ }
753
+ if (token === "--output-on-failure" || token === "--no-tests=error") continue;
754
+ return reject(`ctest option "${token}" is not allowlisted`);
755
+ }
756
+ return void 0;
757
+ }
758
+ if (executableName === "meson") {
759
+ const subcommand = args[0] ?? "";
760
+ if (subcommand !== "compile" && subcommand !== "test") {
761
+ return reject(`"meson ${subcommand}" is not an allowlisted verify command`);
762
+ }
763
+ for (let i = 1; i < args.length; i += 1) {
764
+ const token = args[i] ?? "";
765
+ if (token === "-C") {
766
+ const value = args[i + 1];
767
+ if (!value || value.startsWith("-")) return reject("meson -C requires a build directory");
768
+ if (isEscapingPathValue(value))
769
+ return reject(`meson build directory "${value}" points outside the repository`);
770
+ i += 1;
771
+ continue;
772
+ }
773
+ if (token.startsWith("-C")) {
774
+ const value = token.slice(2);
775
+ if (!value || isEscapingPathValue(value)) {
776
+ return reject(`meson build directory "${value}" points outside the repository`);
777
+ }
778
+ continue;
779
+ }
780
+ if (token === "--verbose") continue;
781
+ return reject(`meson option "${token}" is not allowlisted`);
782
+ }
783
+ return void 0;
784
+ }
785
+ if (executableName === "swift") {
786
+ const subcommand = args[0] ?? "";
787
+ if (subcommand !== "build" && subcommand !== "test") {
788
+ return reject(`"swift ${subcommand}" is not an allowlisted verify command`);
789
+ }
790
+ return allowOnlyPathSafePositionals("swift", args.slice(1), {
791
+ noValueFlags: /* @__PURE__ */ new Set(["--verbose", "-v"]),
792
+ valueFlags: /* @__PURE__ */ new Set(["--package-path", "-c", "--configuration"]),
793
+ pathValueFlags: /* @__PURE__ */ new Set(["--package-path"]),
794
+ allowPositionals: false
795
+ });
796
+ }
797
+ if (executableName === "dart" || executableName === "flutter") {
798
+ const subcommand = args[0] ?? "";
799
+ if (subcommand !== "analyze" && subcommand !== "test") {
800
+ return reject(`"${executableName} ${subcommand}" is not an allowlisted verify command`);
801
+ }
802
+ return allowOnlyPathSafePositionals(executableName, args.slice(1), {
803
+ noValueFlags: /* @__PURE__ */ new Set(["--coverage", "--no-pub", "--machine"]),
804
+ valueFlags: /* @__PURE__ */ new Set(["--name", "--plain-name", "--concurrency", "--reporter"]),
805
+ pathValueFlags: /* @__PURE__ */ new Set([]),
806
+ allowPositionals: true
807
+ });
808
+ }
809
+ if (executableName === "shellcheck") {
810
+ for (let i = 0; i < args.length; i += 1) {
811
+ const token = args[i] ?? "";
812
+ const name = normalizeFlagName(token) ?? token;
813
+ if (name !== "-P" && name !== "--source-path") continue;
814
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
815
+ const sourcePath = value?.startsWith("SOURCE=") ? value.slice("SOURCE=".length) : value;
816
+ if (sourcePath && isEscapingPathValue(sourcePath)) {
817
+ return reject(`option "${token}" points outside the repository`);
818
+ }
819
+ if (!token.includes("=")) i += 1;
820
+ }
821
+ return allowOnlyPathSafePositionals("shellcheck", args, {
822
+ noValueFlags: /* @__PURE__ */ new Set([]),
823
+ valueFlags: /* @__PURE__ */ new Set(["-P", "--source-path", "-S", "--severity"]),
824
+ pathValueFlags: /* @__PURE__ */ new Set(["-P", "--source-path"]),
825
+ allowPositionals: true
826
+ });
827
+ }
828
+ if (executableName === "R") {
829
+ if (args[0] !== "CMD" || args[1] !== "check" || args.length !== 3 || args[2] !== ".") {
830
+ return reject('"R" is only allowlisted as "R CMD check ."');
831
+ }
832
+ return void 0;
833
+ }
834
+ if (executableName === "dbt") {
835
+ const subcommand = args[0] ?? "";
836
+ if (subcommand !== "compile" && subcommand !== "test") {
837
+ return reject(`"dbt ${subcommand}" is not an allowlisted verify command`);
838
+ }
839
+ return allowOnlyPathSafePositionals("dbt", args.slice(1), {
840
+ noValueFlags: /* @__PURE__ */ new Set(["--no-version-check"]),
841
+ valueFlags: /* @__PURE__ */ new Set(["--select", "--exclude", "--profiles-dir", "--project-dir"]),
842
+ pathValueFlags: /* @__PURE__ */ new Set(["--profiles-dir", "--project-dir"]),
843
+ allowPositionals: false
844
+ });
845
+ }
846
+ if (executableName === "sqlfluff") {
847
+ if (args[0] !== "lint") {
848
+ return reject('"sqlfluff" must use the lint subcommand');
849
+ }
850
+ return allowOnlyPathSafePositionals("sqlfluff", args.slice(1), {
851
+ noValueFlags: /* @__PURE__ */ new Set([]),
852
+ valueFlags: /* @__PURE__ */ new Set(["--dialect"]),
853
+ pathValueFlags: /* @__PURE__ */ new Set([]),
854
+ allowPositionals: true
855
+ });
856
+ }
857
+ return void 0;
858
+ }
859
+ function validateEnvArgv(executableName, argv) {
860
+ if (executableName !== "env") return void 0;
861
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
862
+ const reject = (detail) => `Verify command rejected: ${detail}. The env wrapper is only allowlisted for repo-relative PYTHONPATH on otherwise safe commands.`;
863
+ if (args.length === 0) return reject('"env" requires a PYTHONPATH assignment and command');
864
+ let index = 0;
865
+ let sawPythonPath = false;
866
+ for (; index < args.length; index += 1) {
867
+ const token = args[index] ?? "";
868
+ if (token.startsWith("-")) {
869
+ return reject(`env option "${token}" is not allowlisted`);
870
+ }
871
+ const assignmentIndex = token.indexOf("=");
872
+ if (assignmentIndex < 0) break;
873
+ const name = token.slice(0, assignmentIndex);
874
+ const value = token.slice(assignmentIndex + 1);
875
+ if (name !== "PYTHONPATH") {
876
+ return reject(`env assignment "${name}" is not allowlisted`);
877
+ }
878
+ if (!value) {
879
+ return reject("PYTHONPATH must not be empty");
880
+ }
881
+ for (const entry of value.split(":")) {
882
+ if (!entry) return reject("PYTHONPATH entries must not be empty");
883
+ if (isEscapingPathValue(entry)) {
884
+ return reject(`PYTHONPATH entry "${entry}" points outside the repository`);
885
+ }
886
+ }
887
+ sawPythonPath = true;
888
+ }
889
+ if (!sawPythonPath) {
890
+ return reject('"env" requires a PYTHONPATH assignment');
891
+ }
892
+ const nestedArgv = args.slice(index);
893
+ const nestedExecutable = getExecutableName(nestedArgv[0] ?? "");
894
+ if (!nestedExecutable) {
895
+ return reject('"env" requires a command after PYTHONPATH');
896
+ }
897
+ if (nestedExecutable === "env") {
898
+ return reject("nested env wrappers are not allowlisted");
899
+ }
900
+ return validateVerifyArgv(nestedArgv);
901
+ }
902
+ function validatePowerShellToolArgv(executableName, argv) {
903
+ if (!isPowerShellExecutable(executableName)) {
904
+ return void 0;
905
+ }
906
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
907
+ const reject = (detail) => `Verify command rejected: ${detail}. PowerShell verify steps are only allowlisted for Pester test execution (Invoke-Pester).`;
908
+ const ALLOWED_POWERSHELL_CMDLETS = /* @__PURE__ */ new Set(["invoke-pester"]);
909
+ const normalized = args.map((arg) => arg.toLowerCase());
910
+ if (!normalized.includes("-noprofile")) {
911
+ return reject(`"${executableName}" must include -NoProfile`);
912
+ }
913
+ const commandIndex = normalized.findIndex((arg) => arg === "-command" || arg === "-c");
914
+ if (commandIndex < 0) {
915
+ return reject(`"${executableName}" must use -Command Invoke-Pester`);
916
+ }
917
+ const command = args[commandIndex + 1];
918
+ if (!command || command.startsWith("-")) {
919
+ return reject("-Command requires Invoke-Pester");
920
+ }
921
+ const cmdletName = command.toLowerCase();
922
+ if (!ALLOWED_POWERSHELL_CMDLETS.has(cmdletName)) {
923
+ return reject(`"${command}" is not an allowlisted PowerShell verify command`);
924
+ }
925
+ for (let index = 0; index < args.length; index += 1) {
926
+ const token = args[index] ?? "";
927
+ const lower = token.toLowerCase();
928
+ if (index === commandIndex) {
929
+ index += 1;
930
+ continue;
931
+ }
932
+ if (lower === "-noprofile" || lower === "-noninteractive") continue;
933
+ if (lower === "-ci" || lower === "-enableexit") continue;
934
+ return reject(`option "${token}" is not allowlisted`);
935
+ }
936
+ return void 0;
937
+ }
938
+ function isPowerShellExecutable(executableName) {
939
+ return executableName === "pwsh" || executableName === "pwsh.exe" || executableName === "powershell" || executableName === "powershell.exe";
940
+ }
941
+ function isVacuousVerifyArgv(argv) {
942
+ const executableName = getExecutableName(argv[0] ?? "");
943
+ return executableName === "echo" || executableName === "printf";
944
+ }
945
+ function isAllowedVerifyCommand(command) {
946
+ const parsed = parseVerifyCommand(command);
947
+ if (!Array.isArray(parsed)) return false;
948
+ return parsed.every((segment) => validateVerifyArgv(segment.argv) === void 0);
949
+ }
950
+ function validatePoeticArgv(executableName, argv) {
951
+ if (executableName !== "poetic") return void 0;
952
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
953
+ const firstPositional = args.find((arg) => !arg.startsWith("-"));
954
+ if (firstPositional === "internal") {
955
+ return validatePoeticInternalArgv(args);
956
+ }
957
+ const reject = (detail) => `Verify command rejected: ${detail}. Use "poetic assert exact-line <path> --content-base64 <value>" for Poetic-managed verify assertions.`;
958
+ const contentFlagIndex = args.indexOf("--content-base64");
959
+ const contentValue = contentFlagIndex >= 0 ? args[contentFlagIndex + 1] : void 0;
960
+ const positionals = [];
961
+ for (let index = 0; index < args.length; index++) {
962
+ const arg = args[index];
963
+ if (arg === void 0) continue;
964
+ if (arg === "--content-base64") {
965
+ index++;
966
+ continue;
967
+ }
968
+ if (arg.startsWith("-")) {
969
+ return reject(`unexpected option "${arg}"`);
970
+ }
971
+ positionals.push(arg);
972
+ }
973
+ if (positionals.length === 0) {
974
+ return reject('bare "poetic" is not an allowlisted verify command');
975
+ }
976
+ if (positionals[0] !== "assert") {
977
+ return reject(`"poetic ${positionals[0]}" is not an allowlisted verify command`);
978
+ }
979
+ if (positionals[1] !== "exact-line") {
980
+ return reject(`"poetic assert ${positionals[1] ?? ""}" is not an allowlisted verify assertion`);
981
+ }
982
+ if (!args.includes("--content-base64")) {
983
+ return reject('"poetic assert exact-line" must use --content-base64');
984
+ }
985
+ if (!contentValue || contentValue.startsWith("-")) {
986
+ return reject('"poetic assert exact-line" must include a --content-base64 value');
987
+ }
988
+ if (positionals.length !== 3) {
989
+ return reject('"poetic assert exact-line" must include exactly one path');
990
+ }
991
+ if (isEscapingPathValue(positionals[2] ?? "")) {
992
+ return reject(
993
+ `"poetic assert exact-line" path "${positionals[2]}" points outside the repository`
994
+ );
995
+ }
996
+ return void 0;
997
+ }
998
+ var POETIC_INTERNAL_SUBCOMMANDS = /* @__PURE__ */ new Map([
999
+ ["review-gate", /* @__PURE__ */ new Set(["--findings", "--threshold", "--mode", "--annotation-out"])],
1000
+ ["findings-schema", /* @__PURE__ */ new Set(["--findings"])]
1001
+ ]);
1002
+ function validatePoeticInternalArgv(args) {
1003
+ const reject = (detail) => `Verify command rejected: ${detail}. Use "poetic internal review-gate --findings <path> [--threshold high|medium|low] [--mode advisory|blocking] [--annotation-out <path>]" or "poetic internal findings-schema --findings <path>".`;
1004
+ const positionals = [];
1005
+ const valueFlags = /* @__PURE__ */ new Set(["--findings", "--threshold", "--mode", "--annotation-out"]);
1006
+ const pathValueFlags = /* @__PURE__ */ new Set(["--findings", "--annotation-out"]);
1007
+ const enumFlagValues = {
1008
+ "--threshold": /* @__PURE__ */ new Set(["high", "medium", "low"]),
1009
+ "--mode": /* @__PURE__ */ new Set(["advisory", "blocking"])
1010
+ };
1011
+ const seen = /* @__PURE__ */ new Set();
1012
+ for (let index = 0; index < args.length; index++) {
1013
+ const arg = args[index];
1014
+ if (arg === void 0) continue;
1015
+ if (!arg.startsWith("-")) {
1016
+ positionals.push(arg);
1017
+ continue;
1018
+ }
1019
+ const name = arg.includes("=") ? arg.slice(0, arg.indexOf("=")) : arg;
1020
+ if (!valueFlags.has(name)) {
1021
+ return reject(`unexpected option "${arg}"`);
1022
+ }
1023
+ const value = arg.includes("=") ? arg.slice(arg.indexOf("=") + 1) : args[++index];
1024
+ if (value === void 0 || value.startsWith("-")) {
1025
+ return reject(`option "${name}" requires a value`);
1026
+ }
1027
+ if (seen.has(name)) {
1028
+ return reject(`option "${name}" specified more than once`);
1029
+ }
1030
+ seen.add(name);
1031
+ if (pathValueFlags.has(name) && isEscapingPathValue(value)) {
1032
+ return reject(`option "${name}" path "${value}" points outside the repository`);
1033
+ }
1034
+ const allowedValues = enumFlagValues[name];
1035
+ if (allowedValues && !allowedValues.has(value)) {
1036
+ return reject(`option "${name}" value "${value}" is not allowlisted`);
1037
+ }
1038
+ }
1039
+ if (positionals[0] !== "internal") {
1040
+ return reject('expected "poetic internal <subcommand>"');
1041
+ }
1042
+ const subcommand = positionals[1] ?? "";
1043
+ const permittedFlags = POETIC_INTERNAL_SUBCOMMANDS.get(subcommand);
1044
+ if (!permittedFlags) {
1045
+ return reject(`"poetic internal ${subcommand}" is not an allowlisted verify command`);
1046
+ }
1047
+ if (positionals.length !== 2) {
1048
+ return reject(`"poetic internal ${subcommand}" does not accept positional arguments`);
1049
+ }
1050
+ for (const flag of seen) {
1051
+ if (!permittedFlags.has(flag)) {
1052
+ return reject(`option "${flag}" is not valid for "poetic internal ${subcommand}"`);
1053
+ }
1054
+ }
1055
+ if (!seen.has("--findings")) {
1056
+ return reject(`"poetic internal ${subcommand}" requires --findings <path>`);
1057
+ }
1058
+ return void 0;
1059
+ }
1060
+ var MAX_NODE_WRAPPER_DEPTH = 4;
1061
+ var NODE_HELP_FLAGS = /* @__PURE__ */ new Set(["--help", "-h", "help"]);
1062
+ function isReadOnlyPoeticHelpArgv(args) {
1063
+ if (args.length === 0) {
1064
+ return false;
1065
+ }
1066
+ if (args.every((arg) => NODE_HELP_FLAGS.has(arg))) {
1067
+ return true;
1068
+ }
1069
+ const positionals = args.filter((arg) => !arg.startsWith("-"));
1070
+ const flags = args.filter((arg) => arg.startsWith("-"));
1071
+ if (positionals.length === 1 && flags.length >= 1 && flags.every((flag) => NODE_HELP_FLAGS.has(flag))) {
1072
+ return true;
1073
+ }
1074
+ return positionals.length === 2 && positionals[1] === "help" && flags.length === 0;
1075
+ }
1076
+ function validateNodeToolArgv(executableName, argv, wrapperDepth = 0) {
1077
+ if (executableName !== "node") return void 0;
1078
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1079
+ const reject = (detail) => `Verify command rejected: ${detail}. Node verify steps must use package scripts or allowlisted local tools, not arbitrary script execution.`;
1080
+ if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
1081
+ return void 0;
1082
+ }
1083
+ const nodeTarget = (args[0] ?? "").replace(/\\/g, "/");
1084
+ if (nodeTarget === "scripts/assert-node-runtime.mjs") {
1085
+ const expectedArgs = ["--root", ".", "--native", "off"];
1086
+ if (args.length !== expectedArgs.length + 1 || !expectedArgs.every((arg, index) => args[index + 1] === arg)) {
1087
+ return reject(
1088
+ '"node scripts/assert-node-runtime.mjs" is only allowlisted with "--root . --native off"'
1089
+ );
1090
+ }
1091
+ return void 0;
1092
+ }
1093
+ if (wrapperDepth >= MAX_NODE_WRAPPER_DEPTH) {
1094
+ return reject("nested node wrapper depth exceeded");
1095
+ }
1096
+ if (nodeTarget === "scripts/dynamic-node-options.mjs") {
1097
+ const nested = args.slice(1);
1098
+ if (nested.length === 0) {
1099
+ return reject('"node scripts/dynamic-node-options.mjs" requires a nested command');
1100
+ }
1101
+ return validateVerifyArgv(nested, wrapperDepth + 1);
1102
+ }
1103
+ if (nodeTarget === "scripts/verify-command-output.mjs") {
1104
+ const separatorIndex = args.indexOf("--");
1105
+ if (separatorIndex <= 1 || separatorIndex === args.length - 1) {
1106
+ return reject(
1107
+ '"node scripts/verify-command-output.mjs" requires <expected> -- <command> [args...]'
1108
+ );
1109
+ }
1110
+ return validateVerifyArgv(args.slice(separatorIndex + 1), wrapperDepth + 1);
1111
+ }
1112
+ if (nodeTarget === "scripts/verify-file-content.mjs") {
1113
+ return void 0;
1114
+ }
1115
+ if (nodeTarget === "dist/entry.js") {
1116
+ const nested = args.slice(1);
1117
+ if (isReadOnlyPoeticHelpArgv(nested)) {
1118
+ return void 0;
1119
+ }
1120
+ return validatePoeticArgv("poetic", ["poetic", ...nested]);
1121
+ }
1122
+ if (args[0] !== "--check" && args[0] !== "-c") {
1123
+ return reject('"node" is only allowlisted for syntax checks via "node --check <file>"');
1124
+ }
1125
+ const target = args[1] ?? "";
1126
+ if (!target || target.startsWith("-")) {
1127
+ return reject('"node --check" requires a file path');
1128
+ }
1129
+ if (args.length > 2) {
1130
+ return reject('"node --check" accepts exactly one file path');
1131
+ }
1132
+ if (isEscapingPathValue(target)) {
1133
+ return reject(`"node --check ${target}" points outside the repository`);
1134
+ }
1135
+ return void 0;
1136
+ }
1137
+ function validateSimpleReadToolArgv(executableName, argv) {
1138
+ if (executableName !== "grep" && executableName !== "test") {
1139
+ return void 0;
1140
+ }
1141
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1142
+ const reject = (detail) => `Verify command rejected: ${detail}. Read-only verify tools may not inspect paths outside the repository.`;
1143
+ if (executableName === "grep") {
1144
+ const patternFileError = validatePathValueFlags(args, /* @__PURE__ */ new Set(["-f", "--file"]), reject);
1145
+ if (patternFileError) return patternFileError;
1146
+ }
1147
+ return validateRepoRelativePositionals(args, reject, executableName);
1148
+ }
1149
+ var LINT_TOOL_PATH_VALUE_FLAGS = /* @__PURE__ */ new Set([
1150
+ "-c",
1151
+ "--config",
1152
+ "--config-path",
1153
+ "--resolve-plugins-relative-to",
1154
+ "--rulesdir"
1155
+ ]);
1156
+ function validateDirectLintToolArgv(executableName, argv) {
1157
+ if (executableName !== "prettier" && executableName !== "eslint" && executableName !== "biome") {
1158
+ return void 0;
1159
+ }
1160
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1161
+ const reject = (detail) => `Verify command rejected: ${detail}. Verify lint/format tools may only run read-only checks.`;
1162
+ const pathFlagError = validatePathValueFlags(args, LINT_TOOL_PATH_VALUE_FLAGS, reject);
1163
+ if (pathFlagError) return pathFlagError;
1164
+ if (executableName === "prettier" && args.some((arg) => arg === "--write" || arg.startsWith("--write="))) {
1165
+ return reject('"prettier --write" can rewrite files');
1166
+ }
1167
+ if (executableName === "prettier" && !args.some((arg) => arg === "--check" || arg === "--list-different")) {
1168
+ return reject('"prettier" must include --check or --list-different');
1169
+ }
1170
+ if (executableName === "eslint" && args.some((arg) => arg === "--fix" || arg.startsWith("--fix="))) {
1171
+ return reject('"eslint --fix" can rewrite files');
1172
+ }
1173
+ if (executableName === "biome") {
1174
+ if (args.some(
1175
+ (arg) => arg === "--write" || arg.startsWith("--write=") || arg === "--fix" || arg.startsWith("--fix=") || arg === "--apply" || arg.startsWith("--apply=") || arg === "--apply-unsafe" || arg.startsWith("--apply-unsafe=")
1176
+ )) {
1177
+ return reject('"biome --write/--fix/--apply" can rewrite files');
1178
+ }
1179
+ if (args[0] === "format") {
1180
+ return reject('"biome format" can rewrite files; use "biome check" for verify steps');
1181
+ }
1182
+ }
1183
+ return validateRepoRelativePositionals(args, reject, executableName);
1184
+ }
1185
+ var EXPANDED_LINT_TOOL_POLICIES = {
1186
+ "golangci-lint": {
1187
+ writeFlags: ["--fix"],
1188
+ noValueFlags: /* @__PURE__ */ new Set([
1189
+ "-v",
1190
+ "--verbose",
1191
+ "--tests",
1192
+ "--allow-parallel-runners",
1193
+ "--new",
1194
+ "--sort-results"
1195
+ ]),
1196
+ valueFlags: /* @__PURE__ */ new Set([
1197
+ "--timeout",
1198
+ "--build-tags",
1199
+ "--go",
1200
+ "--concurrency",
1201
+ "-j",
1202
+ "--issues-exit-code",
1203
+ "--new-from-rev"
1204
+ ]),
1205
+ // `--out-format` is NOT opaque: golangci-lint >=1.51 accepts
1206
+ // `--out-format <format>:<path>` (and comma-joined `format:path` forms)
1207
+ // which WRITES the report to that path — an out-of-repo write bypass. Its
1208
+ // value must be a comma-separated list of BARE format names only; any
1209
+ // segment carrying a `:` or path separator is rejected.
1210
+ bareFormatValueFlags: /* @__PURE__ */ new Set(["--out-format"]),
1211
+ pathValueFlags: /* @__PURE__ */ new Set(["-c", "--config", "--path-prefix"]),
1212
+ allowedSubcommands: /* @__PURE__ */ new Set(["run"]),
1213
+ allowPositionals: true
1214
+ },
1215
+ staticcheck: {
1216
+ writeFlags: [],
1217
+ // staticcheck uses Go-style single-dash flags; `-tests` is a bool switch.
1218
+ noValueFlags: /* @__PURE__ */ new Set(["-tests", "-version"]),
1219
+ valueFlags: /* @__PURE__ */ new Set(["-checks", "-tags", "-f", "-go"]),
1220
+ pathValueFlags: /* @__PURE__ */ new Set([]),
1221
+ allowBareInvocation: true,
1222
+ allowPositionals: true
1223
+ },
1224
+ ktlint: {
1225
+ writeFlags: ["-F", "--format"],
1226
+ noValueFlags: /* @__PURE__ */ new Set(["--relative", "-v", "--version"]),
1227
+ valueFlags: /* @__PURE__ */ new Set(["--log-level"]),
1228
+ pathValueFlags: /* @__PURE__ */ new Set(["--editorconfig"]),
1229
+ allowBareInvocation: true,
1230
+ allowPositionals: true
1231
+ },
1232
+ detekt: {
1233
+ writeFlags: ["--auto-correct", "-ac", "--create-baseline", "--report", "-r"],
1234
+ noValueFlags: /* @__PURE__ */ new Set(["--parallel", "--build-upon-default-config", "--all-rules"]),
1235
+ valueFlags: /* @__PURE__ */ new Set(["--includes", "--excludes", "--jvm-target"]),
1236
+ pathValueFlags: /* @__PURE__ */ new Set(["--config", "-c", "--baseline", "-b", "--input", "-i"]),
1237
+ allowBareInvocation: true,
1238
+ // detekt takes its inputs via -i/--input, not positionals.
1239
+ allowPositionals: false
1240
+ },
1241
+ swiftlint: {
1242
+ writeFlags: ["--fix", "--autocorrect", "--output", "-o"],
1243
+ noValueFlags: /* @__PURE__ */ new Set(["--strict", "--lenient", "--quiet", "--no-cache"]),
1244
+ valueFlags: /* @__PURE__ */ new Set(["--reporter"]),
1245
+ pathValueFlags: /* @__PURE__ */ new Set(["--config"]),
1246
+ allowedSubcommands: /* @__PURE__ */ new Set(["lint", "analyze"]),
1247
+ allowBareInvocation: true,
1248
+ allowPositionals: true
1249
+ },
1250
+ "clang-tidy": {
1251
+ writeFlags: [
1252
+ "-fix",
1253
+ "--fix",
1254
+ "-fix-errors",
1255
+ "--fix-errors",
1256
+ "-fix-notes",
1257
+ "--fix-notes",
1258
+ "-export-fixes",
1259
+ "--export-fixes",
1260
+ "-store-check-profile",
1261
+ "--store-check-profile"
1262
+ ],
1263
+ noValueFlags: /* @__PURE__ */ new Set(["-quiet", "--quiet", "-list-checks", "--list-checks"]),
1264
+ valueFlags: /* @__PURE__ */ new Set([
1265
+ "-checks",
1266
+ "--checks",
1267
+ "-header-filter",
1268
+ "--header-filter",
1269
+ "-warnings-as-errors",
1270
+ "--warnings-as-errors"
1271
+ ]),
1272
+ pathValueFlags: /* @__PURE__ */ new Set(["-p", "--config-file", "-config-file"]),
1273
+ allowBareInvocation: true,
1274
+ allowPositionals: true
1275
+ }
1276
+ };
1277
+ function validateExpandedLintToolArgv(executableName, argv) {
1278
+ const policy = EXPANDED_LINT_TOOL_POLICIES[executableName];
1279
+ if (policy === void 0) return void 0;
1280
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1281
+ const reject = (detail) => `Verify command rejected: ${detail}. Verify lint tools may only run read-only checks.`;
1282
+ for (const arg of args) {
1283
+ if (policy.writeFlags.some((flag) => arg === flag || arg.startsWith(`${flag}=`))) {
1284
+ return reject(`"${executableName} ${arg}" can rewrite or write files`);
1285
+ }
1286
+ }
1287
+ const firstPositional = args.find((arg) => !arg.startsWith("-"));
1288
+ if (policy.allowedSubcommands) {
1289
+ if (firstPositional === void 0) {
1290
+ if (!policy.allowBareInvocation) {
1291
+ return reject(
1292
+ `bare "${executableName}" is not allowlisted; use an explicit read-only subcommand (${[...policy.allowedSubcommands].sort().join(", ")})`
1293
+ );
1294
+ }
1295
+ } else if (!policy.allowedSubcommands.has(firstPositional) && !policy.allowPositionals) {
1296
+ return reject(
1297
+ `"${executableName} ${firstPositional}" is not an allowlisted read-only subcommand`
1298
+ );
1299
+ } else if (!policy.allowedSubcommands.has(firstPositional)) {
1300
+ if (!/[./\\]/.test(firstPositional)) {
1301
+ return reject(
1302
+ `"${executableName} ${firstPositional}" is not an allowlisted read-only subcommand`
1303
+ );
1304
+ }
1305
+ }
1306
+ }
1307
+ let sawSubcommand = false;
1308
+ for (let i = 0; i < args.length; i += 1) {
1309
+ const token = args[i] ?? "";
1310
+ if (!token.startsWith("-")) {
1311
+ const isAllowedSubcommand = !sawSubcommand && policy.allowedSubcommands?.has(token) === true;
1312
+ if (isAllowedSubcommand) {
1313
+ sawSubcommand = true;
1314
+ continue;
1315
+ }
1316
+ if (!policy.allowPositionals) {
1317
+ return reject(`${executableName} positional "${token}" is not allowlisted`);
1318
+ }
1319
+ if (isEscapingPathValue(token)) {
1320
+ return reject(`${executableName} operand "${token}" points outside the repository`);
1321
+ }
1322
+ continue;
1323
+ }
1324
+ const name = normalizeFlagName(token) ?? token;
1325
+ if (policy.noValueFlags.has(name) && !token.includes("=")) {
1326
+ continue;
1327
+ }
1328
+ if (policy.bareFormatValueFlags?.has(name)) {
1329
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
1330
+ if (value === void 0 || !token.includes("=") && value.startsWith("-")) {
1331
+ return reject(`${executableName} option "${token}" requires a value`);
1332
+ }
1333
+ for (const segment of value.split(",")) {
1334
+ if (!/^[A-Za-z0-9-]+$/.test(segment)) {
1335
+ return reject(
1336
+ `${executableName} option "${token}" value "${segment}" is not a bare format name; the "format:path" form can write a report outside the repository`
1337
+ );
1338
+ }
1339
+ }
1340
+ if (!token.includes("=")) i += 1;
1341
+ continue;
1342
+ }
1343
+ if (policy.valueFlags.has(name) || policy.pathValueFlags.has(name)) {
1344
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
1345
+ if (value === void 0 || !token.includes("=") && value.startsWith("-")) {
1346
+ return reject(`${executableName} option "${token}" requires a value`);
1347
+ }
1348
+ if (policy.pathValueFlags.has(name) && isEscapingPathValue(value)) {
1349
+ return reject(`${executableName} option "${token}" points outside the repository`);
1350
+ }
1351
+ if (!token.includes("=")) i += 1;
1352
+ continue;
1353
+ }
1354
+ return reject(`${executableName} option "${token}" is not allowlisted`);
1355
+ }
1356
+ return void 0;
1357
+ }
1358
+ function validateTypescriptToolArgv(executableName, argv) {
1359
+ if (executableName !== "tsc" && executableName !== "vue-tsc") return void 0;
1360
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1361
+ const reject = (detail) => `Verify command rejected: ${detail}. TypeScript verify tools may not point project/config paths outside the repository.`;
1362
+ let buildMode = false;
1363
+ for (let i = 0; i < args.length; i += 1) {
1364
+ const token = args[i] ?? "";
1365
+ if (token === "-p" || token === "--project" || token === "--tsBuildInfoFile") {
1366
+ const value = args[i + 1];
1367
+ if (value !== void 0 && isEscapingPathValue(value)) {
1368
+ return reject(`option "${token}" points outside the repository`);
1369
+ }
1370
+ i += 1;
1371
+ continue;
1372
+ }
1373
+ if (token.startsWith("--project=") || token.startsWith("--tsBuildInfoFile=") || token.startsWith("-p=")) {
1374
+ const value = token.slice(token.indexOf("=") + 1);
1375
+ if (isEscapingPathValue(value))
1376
+ return reject(`option "${token}" points outside the repository`);
1377
+ continue;
1378
+ }
1379
+ if (token.startsWith("-p") && token.length > 2) {
1380
+ const value = token.slice(2);
1381
+ if (isEscapingPathValue(value))
1382
+ return reject(`option "${token}" points outside the repository`);
1383
+ continue;
1384
+ }
1385
+ if (token === "-b" || token === "--build") {
1386
+ buildMode = true;
1387
+ continue;
1388
+ }
1389
+ if (token.startsWith("--build=")) {
1390
+ const value = token.slice(token.indexOf("=") + 1);
1391
+ if (isEscapingPathValue(value))
1392
+ return reject(`option "${token}" points outside the repository`);
1393
+ buildMode = true;
1394
+ continue;
1395
+ }
1396
+ if (token.startsWith("-b") && token.length > 2) {
1397
+ const value = token.slice(2);
1398
+ if (isEscapingPathValue(value))
1399
+ return reject(`option "${token}" points outside the repository`);
1400
+ buildMode = true;
1401
+ continue;
1402
+ }
1403
+ if (buildMode && !token.startsWith("-") && isEscapingPathValue(token)) {
1404
+ return reject(`build project "${token}" points outside the repository`);
1405
+ }
1406
+ }
1407
+ return void 0;
1408
+ }
1409
+ function validateRepoRelativePositionals(args, reject, toolLabel) {
1410
+ for (const arg of args) {
1411
+ if (arg.startsWith("-")) continue;
1412
+ if (isEscapingPathValue(arg)) {
1413
+ return reject(`${toolLabel} operand "${arg}" points outside the repository`);
1414
+ }
1415
+ }
1416
+ return void 0;
1417
+ }
1418
+ var JAVASCRIPT_TOOLCHAIN_PATH_VALUE_FLAGS = /* @__PURE__ */ new Set([
1419
+ "-c",
1420
+ "--cache-dir",
1421
+ "--cacheDir",
1422
+ "--config",
1423
+ "--coverageDirectory",
1424
+ "--file",
1425
+ "--outputFile",
1426
+ "--package",
1427
+ // mocha/ava/tap preload + reporter module flags: a module path outside the
1428
+ // repo would load and execute out-of-repo code, so their values are
1429
+ // repo-escape-checked (bare reporter NAMES like "spec" are unaffected).
1430
+ "-r",
1431
+ "--require",
1432
+ "-R",
1433
+ "--reporter",
1434
+ "--test-reporter",
1435
+ "--testResultsProcessor"
1436
+ ]);
1437
+ var JS_TEST_RUNNER_SNAPSHOT_UPDATE_FLAGS = {
1438
+ jest: ["-u", "--update", "--updateSnapshot", "--update-snapshot"],
1439
+ vitest: ["-u", "--update", "--updateSnapshot", "--update-snapshot"],
1440
+ ava: ["-u", "--update-snapshots"],
1441
+ tap: ["--snapshot"],
1442
+ mocha: []
1443
+ };
1444
+ var JS_TEST_RUNNER_PASSTHROUGH_FLAGS = {
1445
+ jest: [],
1446
+ vitest: [],
1447
+ mocha: ["-n", "--node-option", "-O", "--reporter-option", "--reporter-options"],
1448
+ ava: ["--node-arguments"],
1449
+ tap: ["--node-arg", "--nyc-arg", "--output-file", "-o"]
1450
+ };
1451
+ var JS_TEST_RUNNER_EXIT_SUPPRESSING_FLAGS = {
1452
+ jest: [],
1453
+ vitest: [],
1454
+ mocha: ["--pass-on-failing-test-suite", "--dry-run"],
1455
+ ava: ["--dry-run"],
1456
+ tap: []
1457
+ };
1458
+ var JAVASCRIPT_TOOLCHAIN_EXECUTABLES = /* @__PURE__ */ new Set([
1459
+ "jest",
1460
+ "vitest",
1461
+ "turbo",
1462
+ "mocha",
1463
+ "ava",
1464
+ "tap"
1465
+ ]);
1466
+ function validateJavaScriptToolchainArgv(executableName, argv) {
1467
+ if (!JAVASCRIPT_TOOLCHAIN_EXECUTABLES.has(executableName)) {
1468
+ return void 0;
1469
+ }
1470
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1471
+ const reject = (detail) => `Verify command rejected: ${detail}. JavaScript verify tools may not point project/config paths outside the repository.`;
1472
+ const pathFlagError = validatePathValueFlags(args, JAVASCRIPT_TOOLCHAIN_PATH_VALUE_FLAGS, reject);
1473
+ if (pathFlagError) return pathFlagError;
1474
+ const snapshotUpdateFlags = JS_TEST_RUNNER_SNAPSHOT_UPDATE_FLAGS[executableName];
1475
+ if (snapshotUpdateFlags && args.some((arg) => snapshotUpdateFlags.some((flag) => tokenMatchesFlag(arg, flag)))) {
1476
+ return reject(`"${executableName}" snapshot update options can rewrite files`);
1477
+ }
1478
+ const passthroughFlags = JS_TEST_RUNNER_PASSTHROUGH_FLAGS[executableName];
1479
+ if (passthroughFlags) {
1480
+ for (const arg of args) {
1481
+ if (passthroughFlags.some((flag) => tokenMatchesFlag(arg, flag))) {
1482
+ return reject(
1483
+ `"${executableName} ${arg}" can pass options to the node process or write output files`
1484
+ );
1485
+ }
1486
+ }
1487
+ }
1488
+ const exitSuppressingFlags = JS_TEST_RUNNER_EXIT_SUPPRESSING_FLAGS[executableName];
1489
+ if (exitSuppressingFlags) {
1490
+ for (const arg of args) {
1491
+ if (exitSuppressingFlags.some((flag) => tokenMatchesFlag(arg, flag))) {
1492
+ return reject(
1493
+ `"${executableName} ${arg}" suppresses the failing exit code or skips test execution`
1494
+ );
1495
+ }
1496
+ }
1497
+ }
1498
+ if (executableName === "mocha" && args[0] === "init") {
1499
+ return reject('"mocha init" writes scaffolding files');
1500
+ }
1501
+ if (executableName === "tap") {
1502
+ for (const arg of args) {
1503
+ if (!arg.startsWith("-") && !/[./\\]/.test(arg)) {
1504
+ return reject(
1505
+ `"tap ${arg}" is not a test file path; tap subcommands are not allowlisted verify commands`
1506
+ );
1507
+ }
1508
+ }
1509
+ }
1510
+ if (executableName === "turbo") {
1511
+ const subcommand = args[0] ?? "";
1512
+ if (subcommand !== "run") {
1513
+ return reject('"turbo" must use the run subcommand');
1514
+ }
1515
+ const allowedTasks = /* @__PURE__ */ new Set(["build", "check", "lint", "test", "typecheck", "verify"]);
1516
+ const tasks = args.slice(1).filter((arg) => !arg.startsWith("-"));
1517
+ if (tasks.length === 0) return reject('"turbo run" requires an allowlisted task');
1518
+ for (const task of tasks) {
1519
+ if (!allowedTasks.has(task) && !/^(?:build|check|lint|test|typecheck|verify):/.test(task)) {
1520
+ return reject(`turbo task "${task}" is not allowlisted`);
1521
+ }
1522
+ }
1523
+ }
1524
+ return validateRepoRelativePositionals(args, reject, executableName);
1525
+ }
1526
+ function isExactPythonCoverageUnittestDiscoverArgv(moduleArgs) {
1527
+ return moduleArgs.length === 4 && moduleArgs[0] === "run" && moduleArgs[1] === "-m" && moduleArgs[2] === "unittest" && moduleArgs[3] === "discover";
1528
+ }
1529
+ function validatePythonToolArgv(executableName, argv) {
1530
+ const reject = (detail) => `Verify command rejected: ${detail}. Python verify tools may only run read-only checks.`;
1531
+ if (executableName === "python" || executableName === "python3" || executableName === "py") {
1532
+ const args2 = argv.slice(1).filter((arg) => arg.length > 0);
1533
+ if (args2[0] !== "-m") {
1534
+ return reject(`"${executableName}" must use "-m" with an allowlisted verify module`);
1535
+ }
1536
+ const moduleName = args2[1] ?? "";
1537
+ if (moduleName === "pytest" || moduleName === "unittest")
1538
+ return validatePythonToolArgv(moduleName, [moduleName, ...args2.slice(2)]);
1539
+ if (moduleName === "black" || moduleName === "ruff" || moduleName === "mypy") {
1540
+ return validatePythonToolArgv(moduleName, [moduleName, ...args2.slice(2)]);
1541
+ }
1542
+ if (moduleName === "coverage") {
1543
+ const coverageArgs = args2.slice(2);
1544
+ if (isExactPythonCoverageUnittestDiscoverArgv(coverageArgs)) {
1545
+ return void 0;
1546
+ }
1547
+ return reject(
1548
+ `"${executableName} -m coverage" only allows the exact form "run -m unittest discover"`
1549
+ );
1550
+ }
1551
+ return reject(`"${executableName} -m ${moduleName}" is not an allowlisted verify module`);
1552
+ }
1553
+ if (executableName !== "black" && executableName !== "ruff" && executableName !== "mypy" && executableName !== "pytest" && executableName !== "unittest") {
1554
+ return void 0;
1555
+ }
1556
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1557
+ const pathFlags = new Set(
1558
+ executableName === "pytest" || executableName === "unittest" ? ["-c", "--rootdir", "--confcutdir"] : executableName === "black" || executableName === "ruff" ? ["--config"] : ["--config-file", "--cache-dir"]
1559
+ );
1560
+ const pathFlagError = validatePathValueFlags(args, pathFlags, reject);
1561
+ if (pathFlagError) return pathFlagError;
1562
+ if (executableName === "pytest" || executableName === "unittest") {
1563
+ return validateRepoRelativePositionals(args, reject, executableName);
1564
+ }
1565
+ if (executableName === "black") {
1566
+ if (!args.includes("--check")) {
1567
+ return reject('"black" must include --check');
1568
+ }
1569
+ return validateRepoRelativePositionals(args, reject, "black");
1570
+ }
1571
+ if (executableName === "ruff") {
1572
+ if (!args.includes("check")) {
1573
+ return reject('"ruff" must use the check subcommand');
1574
+ }
1575
+ for (const arg of args) {
1576
+ if (arg === "--fix" || arg === "--unsafe-fixes" || arg.startsWith("--fix=") || arg.startsWith("--unsafe-fixes=")) {
1577
+ return reject(`"${arg}" can rewrite files`);
1578
+ }
1579
+ if (arg === "--exit-zero" || arg.startsWith("--exit-zero=")) {
1580
+ return reject(`"${arg}" makes ruff findings non-blocking`);
1581
+ }
1582
+ }
1583
+ return validateRepoRelativePositionals(args, reject, "ruff");
1584
+ }
1585
+ if (args.some((arg) => arg === "--install-types" || arg.startsWith("--install-types="))) {
1586
+ return reject('"mypy --install-types" can install packages');
1587
+ }
1588
+ return validateRepoRelativePositionals(args, reject, "mypy");
1589
+ }
1590
+ function validateRubyToolArgv(executableName, argv) {
1591
+ if (!["bundle", "rake", "rspec", "rubocop", "ruby"].includes(executableName)) {
1592
+ return void 0;
1593
+ }
1594
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1595
+ const reject = (detail) => `Verify command rejected: ${detail}. Ruby verify tools may only run conventional test or read-only lint commands.`;
1596
+ if (executableName === "bundle") {
1597
+ if (args[0] !== "exec") return reject('"bundle" must use "bundle exec"');
1598
+ const nested = args.slice(1);
1599
+ if (nested.length === 0) return reject('"bundle exec" requires a tool name');
1600
+ const nestedCommand = nested[0] ?? "";
1601
+ const nestedExecutable = getExecutableName(nestedCommand);
1602
+ if (nestedExecutable !== nestedCommand) {
1603
+ return reject(`"bundle exec ${nestedCommand}" must name an allowlisted tool, not a path`);
1604
+ }
1605
+ if (!["rake", "rspec", "rubocop"].includes(nestedExecutable)) {
1606
+ return reject(`"bundle exec ${nestedExecutable}" is not an allowlisted Ruby verify tool`);
1607
+ }
1608
+ return validateRubyToolArgv(nestedExecutable, nested);
1609
+ }
1610
+ if (executableName === "rake") {
1611
+ const pathFlagError = validatePathValueFlags(args, /* @__PURE__ */ new Set(["-f", "--rakefile"]), reject);
1612
+ if (pathFlagError) return pathFlagError;
1613
+ const targets = args.filter((arg) => !arg.startsWith("-"));
1614
+ if (targets.length === 0) return reject('bare "rake" can run arbitrary default tasks');
1615
+ for (const target of targets) {
1616
+ if (target !== "test" && target !== "spec") {
1617
+ return reject(`"rake ${target}" is not an allowlisted test target`);
1618
+ }
1619
+ }
1620
+ return void 0;
1621
+ }
1622
+ if (executableName === "rubocop") {
1623
+ const pathFlagError = validatePathValueFlags(
1624
+ args,
1625
+ /* @__PURE__ */ new Set(["-c", "--config", "-r", "--require"]),
1626
+ reject
1627
+ );
1628
+ if (pathFlagError) return pathFlagError;
1629
+ for (const arg of args) {
1630
+ if (arg === "-a" || arg === "-A" || arg === "--auto-correct" || arg === "--autocorrect") {
1631
+ return reject(`"rubocop ${arg}" can rewrite files`);
1632
+ }
1633
+ }
1634
+ return validateRepoRelativePositionals(args, reject, "rubocop");
1635
+ }
1636
+ if (executableName === "rspec") {
1637
+ const pathFlagError = validatePathValueFlags(
1638
+ args,
1639
+ /* @__PURE__ */ new Set(["-O", "--options", "-r", "--require"]),
1640
+ reject
1641
+ );
1642
+ if (pathFlagError) return pathFlagError;
1643
+ return validateRepoRelativePositionals(args, reject, "rspec");
1644
+ }
1645
+ if (executableName === "ruby") {
1646
+ if (args.some((arg) => arg === "-e")) {
1647
+ return reject('"ruby -e" inline execution is not allowed');
1648
+ }
1649
+ if (args[0] !== "-c" || args.length < 2) {
1650
+ return reject('"ruby" is only allowlisted for syntax checks via "ruby -c <file>"');
1651
+ }
1652
+ if (isEscapingPathValue(args[1] ?? "")) {
1653
+ return reject(`"ruby -c ${args[1]}" points outside the repository`);
1654
+ }
1655
+ return void 0;
1656
+ }
1657
+ return void 0;
1658
+ }
1659
+ function validatePhpToolArgv(executableName, argv) {
1660
+ if (!["composer", "php", "phpunit", "phpstan", "psalm"].includes(executableName)) {
1661
+ return void 0;
1662
+ }
1663
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1664
+ const reject = (detail) => `Verify command rejected: ${detail}. PHP verify tools may only run project scripts or local analyzer/test binaries.`;
1665
+ if (executableName === "composer") {
1666
+ const pathFlagError = validatePathValueFlags(args, /* @__PURE__ */ new Set(["-d", "--working-dir"]), reject);
1667
+ if (pathFlagError) return pathFlagError;
1668
+ const blocked = /* @__PURE__ */ new Set(["install", "update", "require", "remove", "create-project"]);
1669
+ if (args.some((arg) => blocked.has(arg))) {
1670
+ return reject('"composer" install/update commands are not allowlisted verify commands');
1671
+ }
1672
+ const command = args.find((arg) => !arg.startsWith("-"));
1673
+ if (command === "test") {
1674
+ const commandIndex = args.indexOf(command);
1675
+ return validateRepoRelativePositionals(args.slice(commandIndex + 1), reject, "composer test");
1676
+ }
1677
+ if (command === "run" || command === "run-script") {
1678
+ const scriptIndex = args.indexOf(command) + 1;
1679
+ const scriptName = args[scriptIndex] ?? "";
1680
+ if (/^(?:test|tests|phpunit|lint|analyse|analyze|static-analysis|typecheck|check)$/.test(
1681
+ scriptName
1682
+ )) {
1683
+ return validateRepoRelativePositionals(
1684
+ args.slice(scriptIndex + 1),
1685
+ reject,
1686
+ `composer ${command} ${scriptName}`
1687
+ );
1688
+ }
1689
+ return reject(
1690
+ `"composer ${command} ${scriptName}" is not an allowlisted verification script`
1691
+ );
1692
+ }
1693
+ if (command !== "exec") {
1694
+ return reject(`"composer ${command ?? ""}" is not an allowlisted verify command`);
1695
+ }
1696
+ const dashDash = args.indexOf("--");
1697
+ const executableIndex = dashDash >= 0 ? dashDash + 1 : args.indexOf("exec") + 1;
1698
+ const nestedCommand = args[executableIndex] ?? "";
1699
+ const nestedExecutable = getExecutableName(nestedCommand);
1700
+ if (nestedExecutable !== nestedCommand) {
1701
+ return reject(`"composer exec ${nestedCommand}" must name an allowlisted tool, not a path`);
1702
+ }
1703
+ if (!["phpunit", "phpstan", "psalm", "php-cs-fixer"].includes(nestedExecutable)) {
1704
+ return reject(`"composer exec ${nestedExecutable}" is not an allowlisted PHP verify tool`);
1705
+ }
1706
+ if (nestedExecutable === "php-cs-fixer") {
1707
+ const nestedArgs = args.slice(executableIndex + 1);
1708
+ const pathFlagError2 = validatePathValueFlags(nestedArgs, /* @__PURE__ */ new Set(["--config"]), reject);
1709
+ if (pathFlagError2) return pathFlagError2;
1710
+ if (!nestedArgs.includes("fix") || !nestedArgs.includes("--dry-run")) {
1711
+ return reject('"composer exec php-cs-fixer" must run "fix --dry-run"');
1712
+ }
1713
+ return validateRepoRelativePositionals(nestedArgs, reject, "php-cs-fixer");
1714
+ }
1715
+ return validatePhpToolArgv(nestedExecutable, [
1716
+ nestedExecutable,
1717
+ ...args.slice(executableIndex + 1)
1718
+ ]);
1719
+ }
1720
+ if (executableName === "php") {
1721
+ return reject('"php" may not execute arbitrary scripts directly');
1722
+ }
1723
+ if (executableName === "phpunit" || executableName === "phpstan" || executableName === "psalm") {
1724
+ const pathFlags = executableName === "phpunit" ? /* @__PURE__ */ new Set(["-c", "--configuration", "--bootstrap"]) : executableName === "phpstan" ? /* @__PURE__ */ new Set(["-c", "--configuration", "--configuration-file", "--autoload-file"]) : /* @__PURE__ */ new Set(["-c", "--config", "--config-file"]);
1725
+ const pathFlagError = validatePathValueFlags(args, pathFlags, reject);
1726
+ if (pathFlagError) return pathFlagError;
1727
+ return validateRepoRelativePositionals(args, reject, executableName);
1728
+ }
1729
+ return void 0;
1730
+ }
1731
+ var GIT_READONLY_SUBCOMMANDS = /* @__PURE__ */ new Set([
1732
+ "cat-file",
1733
+ "describe",
1734
+ "diff",
1735
+ "grep",
1736
+ "log",
1737
+ "ls-files",
1738
+ "ls-tree",
1739
+ "rev-parse",
1740
+ "show",
1741
+ "status"
1742
+ ]);
1743
+ var GIT_PROGRAM_EXECUTING_OPTIONS = /* @__PURE__ */ new Set([
1744
+ "-c",
1745
+ "-O",
1746
+ "-p",
1747
+ "--config-env",
1748
+ "--exec",
1749
+ "--exec-path",
1750
+ "--ext-diff",
1751
+ "--filters",
1752
+ "--open-files-in-pager",
1753
+ "--output",
1754
+ "--paginate",
1755
+ "--textconv"
1756
+ ]);
1757
+ var GIT_SUBCOMMAND_PROGRAM_OPTIONS = /* @__PURE__ */ new Set([
1758
+ "-O",
1759
+ "--config-env",
1760
+ "--exec",
1761
+ "--exec-path",
1762
+ "--ext-diff",
1763
+ "--filters",
1764
+ // `--help` runs `git help <cmd>`, which spawns the configured man viewer/pager
1765
+ // (an external program). Bare `-h` just prints usage to stderr and is left
1766
+ // alone (it also collides with `git grep -h`, a legitimate read-only flag).
1767
+ "--help",
1768
+ "--open-files-in-pager",
1769
+ "--output",
1770
+ "--textconv"
1771
+ ]);
1772
+ var GIT_EXTERNAL_PATH_OPTIONS = /* @__PURE__ */ new Set(["--pathspec-from-file"]);
1773
+ var GIT_GREP_EXTERNAL_PATTERN_OPTIONS = /* @__PURE__ */ new Set(["-f", "--file"]);
1774
+ var GIT_DIFF_REJECTED_OPTIONS = /* @__PURE__ */ new Set(["--no-index"]);
1775
+ var GIT_REPO_REDIRECT_FLAGS = /* @__PURE__ */ new Set(["-C", "--git-dir", "--namespace", "--work-tree"]);
1776
+ function validateGitArgv(executableName, argv) {
1777
+ if (executableName !== "git") return void 0;
1778
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
1779
+ const reject = (detail) => `Verify command rejected: ${detail}. Verify "git" commands may only read state (diff, status, log, show, rev-parse, ls-files, ls-tree, cat-file, grep, describe).`;
1780
+ const index = 0;
1781
+ while (index < args.length) {
1782
+ const token = args[index];
1783
+ if (token === void 0) break;
1784
+ if (!token.startsWith("-")) break;
1785
+ const name = normalizeFlagName(token) ?? token;
1786
+ if (GIT_PROGRAM_EXECUTING_OPTIONS.has(name)) {
1787
+ return reject(`option "${token}" can execute an external program`);
1788
+ }
1789
+ if (GIT_REPO_REDIRECT_FLAGS.has(name)) {
1790
+ return reject(
1791
+ `option "${token}" retargets the git repository, which can load foreign config`
1792
+ );
1793
+ }
1794
+ return reject(`global option "${token}" is not allowed before a verify git subcommand`);
1795
+ }
1796
+ const subcommand = args[index];
1797
+ if (subcommand === void 0) {
1798
+ return reject('bare "git" is not an allowlisted verify command');
1799
+ }
1800
+ if (!GIT_READONLY_SUBCOMMANDS.has(subcommand)) {
1801
+ return reject(`"git ${subcommand}" is not a read-only git subcommand`);
1802
+ }
1803
+ for (const token of args.slice(index + 1)) {
1804
+ if (tokenMatchesAnyFlag(token, GIT_SUBCOMMAND_PROGRAM_OPTIONS)) {
1805
+ return reject(`option "${token}" can execute an external program`);
1806
+ }
1807
+ if (tokenMatchesAnyFlag(token, GIT_EXTERNAL_PATH_OPTIONS)) {
1808
+ return reject(`option "${token}" can read pathspecs from an external file`);
1809
+ }
1810
+ if (subcommand === "grep" && tokenMatchesAnyFlag(token, GIT_GREP_EXTERNAL_PATTERN_OPTIONS)) {
1811
+ return reject(`option "${token}" can read patterns from an external file`);
1812
+ }
1813
+ if (subcommand === "diff" && tokenMatchesAnyFlag(token, GIT_DIFF_REJECTED_OPTIONS)) {
1814
+ return reject(`"git diff ${token}" can compare arbitrary paths outside the repository`);
1815
+ }
1816
+ }
1817
+ return validateGitPathspecArgs(subcommand, args.slice(index + 1), reject);
1818
+ }
1819
+ function isEscapingGitPathspecValue(value) {
1820
+ let pathspec = value;
1821
+ if (pathspec.startsWith(":(")) {
1822
+ const closingParen = pathspec.indexOf(")");
1823
+ if (closingParen >= 0) {
1824
+ pathspec = pathspec.slice(closingParen + 1);
1825
+ }
1826
+ } else if (pathspec.startsWith(":/") || pathspec.startsWith(":!") || pathspec.startsWith(":^")) {
1827
+ pathspec = pathspec.slice(2);
1828
+ }
1829
+ const objectPathSeparator = pathspec.lastIndexOf(":");
1830
+ if (objectPathSeparator > 0) {
1831
+ const objectPath = pathspec.slice(objectPathSeparator + 1);
1832
+ if (objectPath.length > 0 && isEscapingPathValue(objectPath)) return true;
1833
+ }
1834
+ return isEscapingPathValue(pathspec);
1835
+ }
1836
+ function validateGitPathspecArgs(subcommand, args, reject) {
1837
+ const pathspecSubcommands = /* @__PURE__ */ new Set([
1838
+ "cat-file",
1839
+ "diff",
1840
+ "grep",
1841
+ "log",
1842
+ "ls-files",
1843
+ "ls-tree",
1844
+ "show",
1845
+ "status"
1846
+ ]);
1847
+ if (!pathspecSubcommands.has(subcommand)) return void 0;
1848
+ for (let i = 0; i < args.length; i += 1) {
1849
+ const token = args[i] ?? "";
1850
+ if (token === "--") {
1851
+ for (const pathspec of args.slice(i + 1)) {
1852
+ if (isEscapingGitPathspecValue(pathspec)) {
1853
+ return reject(`pathspec "${pathspec}" points outside the repository`);
1854
+ }
1855
+ }
1856
+ return void 0;
1857
+ }
1858
+ if (token.startsWith("-")) continue;
1859
+ if (isEscapingGitPathspecValue(token)) {
1860
+ return reject(`pathspec "${token}" points outside the repository`);
1861
+ }
1862
+ }
1863
+ return void 0;
1864
+ }
1865
+ var BUILD_TOOL_ALLOWED_GOALS = {
1866
+ cargo: /* @__PURE__ */ new Set([
1867
+ "audit",
1868
+ "build",
1869
+ "check",
1870
+ "test",
1871
+ "clippy",
1872
+ "fmt",
1873
+ "bench",
1874
+ "doc",
1875
+ "tree",
1876
+ "nextest"
1877
+ ]),
1878
+ dotnet: /* @__PURE__ */ new Set(["build", "test", "format"]),
1879
+ go: /* @__PURE__ */ new Set(["build", "test", "vet"]),
1880
+ gradle: /* @__PURE__ */ new Set(["build", "check", "test", "assemble", "lint", "verify"]),
1881
+ gradlew: /* @__PURE__ */ new Set(["build", "check", "test", "assemble", "lint", "verify"]),
1882
+ make: /* @__PURE__ */ new Set(["build", "test", "check", "lint", "verify", "all", "ci"]),
1883
+ mvn: /* @__PURE__ */ new Set(["compile", "test", "verify", "validate", "test-compile"]),
1884
+ mvnw: /* @__PURE__ */ new Set(["compile", "test", "verify", "validate", "test-compile"])
1885
+ };
1886
+ var BUILD_TOOL_SAFE_VALUE_FLAGS = {
1887
+ cargo: /* @__PURE__ */ new Set([
1888
+ "-p",
1889
+ "--package",
1890
+ "--features",
1891
+ "--target",
1892
+ "--profile",
1893
+ "-j",
1894
+ "--jobs",
1895
+ "--manifest-path",
1896
+ "--target-dir"
1897
+ ]),
1898
+ dotnet: /* @__PURE__ */ new Set(["-c", "--configuration", "-f", "--framework", "-v", "--verbosity"]),
1899
+ go: /* @__PURE__ */ new Set(["-p", "-tags", "-timeout", "-run", "-count", "-parallel"]),
1900
+ gradle: /* @__PURE__ */ new Set(["-p", "--project-dir", "--console", "--max-workers", "--warning-mode"]),
1901
+ gradlew: /* @__PURE__ */ new Set(["-p", "--project-dir", "--console", "--max-workers", "--warning-mode"]),
1902
+ make: /* @__PURE__ */ new Set(["-C", "--directory", "-l", "--load-average"]),
1903
+ mvn: /* @__PURE__ */ new Set(["-pl", "--projects", "-P", "--activate-profiles", "-T", "--threads"]),
1904
+ mvnw: /* @__PURE__ */ new Set(["-pl", "--projects", "-P", "--activate-profiles", "-T", "--threads"])
1905
+ };
1906
+ var BUILD_TOOL_PATH_VALUE_FLAGS = {
1907
+ cargo: /* @__PURE__ */ new Set(["--manifest-path", "--target-dir"]),
1908
+ dotnet: /* @__PURE__ */ new Set([]),
1909
+ go: /* @__PURE__ */ new Set([]),
1910
+ // `-p` is Gradle's short form of `--project-dir` (a path), so it must be
1911
+ // path-validated like the long form — not treated as a plain value flag.
1912
+ gradle: /* @__PURE__ */ new Set(["-p", "--project-dir"]),
1913
+ gradlew: /* @__PURE__ */ new Set(["-p", "--project-dir"]),
1914
+ make: /* @__PURE__ */ new Set(["-C", "--directory"]),
1915
+ mvn: /* @__PURE__ */ new Set([]),
1916
+ mvnw: /* @__PURE__ */ new Set([])
1917
+ };
1918
+ var BUILD_TOOL_SAFE_NOVALUE_FLAGS = {
1919
+ cargo: /* @__PURE__ */ new Set([
1920
+ "--release",
1921
+ "--all-features",
1922
+ "--no-default-features",
1923
+ "--workspace",
1924
+ "--all",
1925
+ "--locked",
1926
+ "--frozen",
1927
+ "--offline",
1928
+ "--check",
1929
+ "-v",
1930
+ "--verbose",
1931
+ "-q",
1932
+ "--quiet",
1933
+ "--all-targets",
1934
+ "--lib",
1935
+ "--bins",
1936
+ "--tests",
1937
+ "--doc",
1938
+ "--no-fail-fast"
1939
+ ]),
1940
+ dotnet: /* @__PURE__ */ new Set([
1941
+ "--no-restore",
1942
+ "--no-build",
1943
+ "--verify-no-changes",
1944
+ "--include-generated",
1945
+ "--nologo"
1946
+ ]),
1947
+ go: /* @__PURE__ */ new Set(["-race", "-cover", "-v", "-short", "-json", "-buildvcs", "-vet"]),
1948
+ // NOTE: dry-run flags (gradle/make `--dry-run`, make `-n`) are intentionally
1949
+ // EXCLUDED. They make the tool print actions without running them, so a verify
1950
+ // step would report success without actually verifying — a green gate that
1951
+ // proves nothing. Reject them so an untrusted verify command cannot pass hollow.
1952
+ gradle: /* @__PURE__ */ new Set([
1953
+ "--stacktrace",
1954
+ "--info",
1955
+ "--debug",
1956
+ "-q",
1957
+ "--quiet",
1958
+ "--offline",
1959
+ "--no-daemon"
1960
+ ]),
1961
+ gradlew: /* @__PURE__ */ new Set([
1962
+ "--stacktrace",
1963
+ "--info",
1964
+ "--debug",
1965
+ "-q",
1966
+ "--quiet",
1967
+ "--offline",
1968
+ "--no-daemon"
1969
+ ]),
1970
+ // `-j`/`--jobs`: no-value here (make's jobs arg is optional). `-jN` attached is
1971
+ // handled in the validator; `-j N` separated would leave `N` as a positional
1972
+ // (rejected) which is acceptably conservative for untrusted input. `-n`/
1973
+ // `--dry-run` are excluded (see note above).
1974
+ make: /* @__PURE__ */ new Set([
1975
+ "-j",
1976
+ "--jobs",
1977
+ "-k",
1978
+ "--keep-going",
1979
+ "-s",
1980
+ "--silent",
1981
+ "-w",
1982
+ "-B",
1983
+ "--always-make",
1984
+ "-i"
1985
+ ]),
1986
+ mvn: /* @__PURE__ */ new Set([
1987
+ "-o",
1988
+ "--offline",
1989
+ "-q",
1990
+ "--quiet",
1991
+ "-B",
1992
+ "--batch-mode",
1993
+ "-e",
1994
+ "--errors",
1995
+ "-V",
1996
+ "--show-version"
1997
+ ]),
1998
+ mvnw: /* @__PURE__ */ new Set([
1999
+ "-o",
2000
+ "--offline",
2001
+ "-q",
2002
+ "--quiet",
2003
+ "-B",
2004
+ "--batch-mode",
2005
+ "-e",
2006
+ "--errors",
2007
+ "-V",
2008
+ "--show-version"
2009
+ ])
2010
+ };
2011
+ function isEscapingPathValue(value) {
2012
+ if (value.length === 0) return false;
2013
+ if (value.startsWith("/") || value.startsWith("\\")) return true;
2014
+ if (/^[A-Za-z]:[\\/]/.test(value)) return true;
2015
+ if (value.startsWith("~")) return true;
2016
+ const normalized = value.replace(/\\/g, "/");
2017
+ return normalized.split("/").some((seg) => seg === "..");
2018
+ }
2019
+ function validatePathValueFlags(args, pathFlags, reject) {
2020
+ for (let i = 0; i < args.length; i += 1) {
2021
+ const token = args[i] ?? "";
2022
+ if (!token.startsWith("-")) continue;
2023
+ const name = normalizeFlagName(token) ?? token;
2024
+ if (pathFlags.has(name)) {
2025
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
2026
+ if (value !== void 0 && isEscapingPathValue(value)) {
2027
+ return reject(`option "${token}" points outside the repository`);
2028
+ }
2029
+ if (!token.includes("=")) i += 1;
2030
+ continue;
2031
+ }
2032
+ const shortMatch = /^(-[A-Za-z])(.+)$/.exec(token);
2033
+ if (shortMatch) {
2034
+ const shortFlag = shortMatch[1] ?? "";
2035
+ const attachedValue = shortMatch[2] ?? "";
2036
+ if (pathFlags.has(shortFlag) && isEscapingPathValue(attachedValue)) {
2037
+ return reject(`option "${token}" points outside the repository`);
2038
+ }
2039
+ }
2040
+ }
2041
+ return void 0;
2042
+ }
2043
+ function cargoGoalAllowed(goal, args) {
2044
+ if (goal === "fmt") {
2045
+ return args.includes("--check");
2046
+ }
2047
+ return true;
2048
+ }
2049
+ function tokenMatchesFlag(token, flag) {
2050
+ if (token === flag) return true;
2051
+ if (token.startsWith(`${flag}=`)) return true;
2052
+ if (/^-[A-Za-z]$/.test(flag) && token.startsWith(flag) && token.length > flag.length) {
2053
+ return true;
2054
+ }
2055
+ return false;
2056
+ }
2057
+ function tokenMatchesAnyFlag(token, flags) {
2058
+ for (const flag of flags) {
2059
+ if (tokenMatchesFlag(token, flag)) return true;
2060
+ }
2061
+ return false;
2062
+ }
2063
+ function resolveBuildGoal(executableName, goal) {
2064
+ if (!goal.includes(":")) return { value: goal };
2065
+ if (executableName === "gradle" || executableName === "gradlew") {
2066
+ const last = goal.split(":").filter(Boolean).pop();
2067
+ return last ? { value: last } : { reject: goal };
2068
+ }
2069
+ if (executableName === "mvn" || executableName === "mvnw") {
2070
+ return { reject: goal };
2071
+ }
2072
+ return { value: goal };
2073
+ }
2074
+ function validateBuildToolArgv(executableName, argv) {
2075
+ const allowed = BUILD_TOOL_ALLOWED_GOALS[executableName];
2076
+ if (!allowed) return void 0;
2077
+ const valueFlags = BUILD_TOOL_SAFE_VALUE_FLAGS[executableName] ?? /* @__PURE__ */ new Set();
2078
+ const pathFlags = BUILD_TOOL_PATH_VALUE_FLAGS[executableName] ?? /* @__PURE__ */ new Set();
2079
+ const noValueFlags = BUILD_TOOL_SAFE_NOVALUE_FLAGS[executableName] ?? /* @__PURE__ */ new Set();
2080
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
2081
+ const reject = (detail) => `Verify command rejected: ${detail}. Build-tool verify steps may only run a read-only build/test/check goal (${[...allowed].sort().join(", ")}).`;
2082
+ const goals = [];
2083
+ for (let i = 0; i < args.length; i++) {
2084
+ const token = args[i];
2085
+ if (token === void 0) continue;
2086
+ if (executableName === "cargo" && token === "--") {
2087
+ const remaining = args.slice(i + 1);
2088
+ if (goals[0] === "clippy" && remaining.length === 2 && remaining[0] === "-D" && remaining[1] === "warnings") {
2089
+ break;
2090
+ }
2091
+ return reject(`cargo passthrough "${remaining.join(" ")}" is not allowlisted`);
2092
+ }
2093
+ if (token.startsWith("-")) {
2094
+ const name = normalizeFlagName(token) ?? token;
2095
+ const hasInlineValue = token.includes("=");
2096
+ if (valueFlags.has(name)) {
2097
+ let value;
2098
+ if (hasInlineValue) {
2099
+ value = token.slice(token.indexOf("=") + 1);
2100
+ } else {
2101
+ value = args[i + 1];
2102
+ i += 1;
2103
+ }
2104
+ if (pathFlags.has(name) && value !== void 0 && isEscapingPathValue(value)) {
2105
+ return reject(`option "${token}" points outside the repository`);
2106
+ }
2107
+ continue;
2108
+ }
2109
+ const shortMatch = /^(-[A-Za-z])(.+)$/.exec(token);
2110
+ if (shortMatch) {
2111
+ const shortFlag = shortMatch[1] ?? "";
2112
+ const attachedValue = shortMatch[2] ?? "";
2113
+ if (valueFlags.has(shortFlag)) {
2114
+ if (pathFlags.has(shortFlag) && isEscapingPathValue(attachedValue)) {
2115
+ return reject(`option "${token}" points outside the repository`);
2116
+ }
2117
+ continue;
2118
+ }
2119
+ if (noValueFlags.has(shortFlag) && /^[0-9]+$/.test(attachedValue)) {
2120
+ continue;
2121
+ }
2122
+ }
2123
+ if (noValueFlags.has(name) && !hasInlineValue) {
2124
+ continue;
2125
+ }
2126
+ return reject(`option "${token}" is not an allowlisted read-only build-tool flag`);
2127
+ }
2128
+ goals.push(token);
2129
+ }
2130
+ if (goals.length === 0) {
2131
+ return reject(
2132
+ `bare "${executableName}" runs its default target which can execute arbitrary code`
2133
+ );
2134
+ }
2135
+ const resolvedFirst = resolveBuildGoal(executableName, goals[0] ?? "");
2136
+ if ("reject" in resolvedFirst) {
2137
+ return reject(
2138
+ `"${executableName} ${resolvedFirst.reject}" is not an allowlisted read-only goal`
2139
+ );
2140
+ }
2141
+ const firstGoal = resolvedFirst.value;
2142
+ if (!allowed.has(firstGoal)) {
2143
+ return reject(`"${executableName} ${goals[0]}" is not an allowlisted read-only goal`);
2144
+ }
2145
+ if (executableName === "cargo" && !cargoGoalAllowed(firstGoal, args)) {
2146
+ return reject(`"cargo ${firstGoal}" mutates files unless run with --check`);
2147
+ }
2148
+ if (executableName === "cargo" && firstGoal === "nextest") {
2149
+ if (goals.length !== 2 || goals[1] !== "run") {
2150
+ return reject('"cargo nextest" is only allowed with the read-only "run" subcommand');
2151
+ }
2152
+ return void 0;
2153
+ }
2154
+ if (executableName === "dotnet" && firstGoal === "format" && !args.includes("--verify-no-changes")) {
2155
+ return reject('"dotnet format" mutates files unless run with --verify-no-changes');
2156
+ }
2157
+ if (executableName === "go") {
2158
+ for (const pkg of goals.slice(1)) {
2159
+ if (isEscapingPathValue(pkg)) {
2160
+ return reject(`go package "${pkg}" points outside the repository`);
2161
+ }
2162
+ }
2163
+ } else {
2164
+ for (const goal of goals.slice(1)) {
2165
+ const resolved = resolveBuildGoal(executableName, goal);
2166
+ if ("reject" in resolved || !allowed.has(resolved.value)) {
2167
+ return reject(`"${executableName} ... ${goal}" is not an allowlisted read-only goal`);
2168
+ }
2169
+ }
2170
+ }
2171
+ return void 0;
2172
+ }
2173
+ var RUNNER_TOOL_ALLOWED_TASKS = /* @__PURE__ */ new Set(["test", "lint", "build", "check", "verify"]);
2174
+ function validateRunnerToolArgv(executableName, argv) {
2175
+ if (executableName !== "just" && executableName !== "task") return void 0;
2176
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
2177
+ const reject = (detail) => `Verify command rejected: ${detail}. Task-runner verify steps may only run a single canonical safe task name (${[...RUNNER_TOOL_ALLOWED_TASKS].sort().join(", ")}); recipe bodies and arbitrary task names are never trusted.`;
2178
+ if (args.length === 0) {
2179
+ return reject(
2180
+ `bare "${executableName}" runs its default recipe which can execute arbitrary code`
2181
+ );
2182
+ }
2183
+ if (args.length > 1) {
2184
+ return reject(`"${executableName}" verify steps accept exactly one canonical task name`);
2185
+ }
2186
+ const task = args[0] ?? "";
2187
+ if (task.startsWith("-")) {
2188
+ return reject(`"${executableName}" option "${task}" is not allowlisted`);
2189
+ }
2190
+ if (!RUNNER_TOOL_ALLOWED_TASKS.has(task)) {
2191
+ return reject(`"${executableName} ${task}" is not an allowlisted canonical task name`);
2192
+ }
2193
+ return void 0;
2194
+ }
2195
+ function validateIacToolArgv(executableName, argv) {
2196
+ if (executableName !== "hadolint" && executableName !== "terraform" && executableName !== "tflint" && executableName !== "kubeconform") {
2197
+ return void 0;
2198
+ }
2199
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
2200
+ const reject = (detail) => `Verify command rejected: ${detail}. IaC verify tools may only run static, offline checks (hadolint, terraform fmt -check, tflint, kubeconform).`;
2201
+ if (executableName === "terraform") {
2202
+ const subcommand = args[0] ?? "";
2203
+ if (subcommand !== "fmt") {
2204
+ return reject(
2205
+ `"terraform ${subcommand || "(none)"}" is not allowlisted; only "terraform fmt -check"`
2206
+ );
2207
+ }
2208
+ if (!args.includes("-check")) {
2209
+ return reject('"terraform fmt" must include -check so it cannot rewrite files');
2210
+ }
2211
+ const SAFE_FMT_FLAGS = /* @__PURE__ */ new Set(["-check", "-recursive", "-diff", "-no-color"]);
2212
+ for (let i = 1; i < args.length; i += 1) {
2213
+ const token = args[i] ?? "";
2214
+ if (token.startsWith("-")) {
2215
+ if (!SAFE_FMT_FLAGS.has(token)) {
2216
+ return reject(`"terraform fmt" option "${token}" is not allowlisted`);
2217
+ }
2218
+ continue;
2219
+ }
2220
+ if (isEscapingPathValue(token)) {
2221
+ return reject(`"terraform fmt" operand "${token}" points outside the repository`);
2222
+ }
2223
+ }
2224
+ return void 0;
2225
+ }
2226
+ const IAC_FLAG_POLICIES = {
2227
+ // hadolint: static Dockerfile linter. Allow config (path), format (value),
2228
+ // and the no-color switch, plus Dockerfile positionals. Reject the rest.
2229
+ // `--no-fail` is deliberately NOT allowed: it forces a zero exit even when
2230
+ // violations are found, which would make the lint gate hollow (always green).
2231
+ hadolint: {
2232
+ noValueFlags: /* @__PURE__ */ new Set(["--no-color"]),
2233
+ valueFlags: /* @__PURE__ */ new Set(["-f", "--format"]),
2234
+ pathValueFlags: /* @__PURE__ */ new Set(["-c", "--config"])
2235
+ },
2236
+ // tflint: static Terraform linter. Allow format (value), chdir/config (path),
2237
+ // and the `--recursive` switch so nested Terraform modules (infra/, envs/prod/)
2238
+ // are linted — plain `tflint` lints only the repo root and would skip child
2239
+ // modules. `--recursive` is static/offline-safe: it is local directory
2240
+ // traversal only and does NOT download plugins (unlike `--init`, still
2241
+ // REJECTED). Unknown flags rejected.
2242
+ tflint: {
2243
+ noValueFlags: /* @__PURE__ */ new Set(["--recursive"]),
2244
+ valueFlags: /* @__PURE__ */ new Set(["-f", "--format"]),
2245
+ pathValueFlags: /* @__PURE__ */ new Set(["--chdir", "-c", "--config"])
2246
+ },
2247
+ // kubeconform: offline schema validator. Allow summary/strict switches,
2248
+ // output (value) and -n (value). `-schema-location`/`--schema-location` is a
2249
+ // PATH value flag (repo-relative, non-URL — escaping/URL values rejected
2250
+ // below). Unknown flags rejected. NOTE: kubeconform's DEFAULT schema location
2251
+ // fetches schemas over the network, so a kubeconform command is only admitted
2252
+ // when it pins an explicit offline `-schema-location` (enforced below before
2253
+ // the per-flag loop).
2254
+ kubeconform: {
2255
+ noValueFlags: /* @__PURE__ */ new Set(["-summary", "-strict"]),
2256
+ valueFlags: /* @__PURE__ */ new Set(["-output", "-n"]),
2257
+ pathValueFlags: /* @__PURE__ */ new Set(["-schema-location", "--schema-location"])
2258
+ }
2259
+ };
2260
+ const policy = IAC_FLAG_POLICIES[executableName];
2261
+ if (policy === void 0) {
2262
+ return reject(`"${executableName}" has no static-flag policy`);
2263
+ }
2264
+ if (executableName === "kubeconform") {
2265
+ let schemaLocationCount = 0;
2266
+ for (let i = 0; i < args.length; i += 1) {
2267
+ const token = args[i] ?? "";
2268
+ if (!token.startsWith("-")) continue;
2269
+ const name = normalizeFlagName(token) ?? token;
2270
+ if (name !== "-schema-location" && name !== "--schema-location") continue;
2271
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
2272
+ if (value === void 0 || !token.includes("=") && value.startsWith("-")) {
2273
+ continue;
2274
+ }
2275
+ if (value === "") {
2276
+ return reject("kubeconform -schema-location requires a non-empty repo-relative value");
2277
+ }
2278
+ schemaLocationCount += 1;
2279
+ if (value.includes("://") || isEscapingPathValue(value)) {
2280
+ return reject(
2281
+ `kubeconform -schema-location value "${value}" is not an offline, repo-relative schema source`
2282
+ );
2283
+ }
2284
+ if (value.toLowerCase() === "default") {
2285
+ return reject('kubeconform -schema-location "default" fetches schemas over the network');
2286
+ }
2287
+ }
2288
+ if (schemaLocationCount === 0) {
2289
+ return reject(
2290
+ 'kubeconform requires an explicit repo-relative -schema-location (default location, including the literal value "default", fetches schemas over the network)'
2291
+ );
2292
+ }
2293
+ }
2294
+ for (let i = 0; i < args.length; i += 1) {
2295
+ const token = args[i] ?? "";
2296
+ if (!token.startsWith("-")) {
2297
+ if (token.includes("://")) {
2298
+ return reject(`${executableName} operand "${token}" looks like a URL (not offline)`);
2299
+ }
2300
+ if (isEscapingPathValue(token)) {
2301
+ return reject(`${executableName} operand "${token}" points outside the repository`);
2302
+ }
2303
+ continue;
2304
+ }
2305
+ const name = normalizeFlagName(token) ?? token;
2306
+ if (policy.noValueFlags.has(name)) {
2307
+ if (token.includes("=")) {
2308
+ return reject(`${executableName} switch "${token}" does not take a value`);
2309
+ }
2310
+ continue;
2311
+ }
2312
+ if (policy.valueFlags.has(name) || policy.pathValueFlags.has(name)) {
2313
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
2314
+ if (value === void 0 || !token.includes("=") && value.startsWith("-")) {
2315
+ return reject(`${executableName} option "${token}" requires a value`);
2316
+ }
2317
+ if (value.includes("://")) {
2318
+ return reject(`${executableName} option "${token}" value "${value}" looks like a URL`);
2319
+ }
2320
+ if (policy.pathValueFlags.has(name) && isEscapingPathValue(value)) {
2321
+ return reject(`${executableName} option "${token}" points outside the repository`);
2322
+ }
2323
+ if (!token.includes("=")) i += 1;
2324
+ continue;
2325
+ }
2326
+ return reject(`${executableName} option "${token}" is not allowlisted`);
2327
+ }
2328
+ return void 0;
2329
+ }
2330
+ var NPX_RUNNABLE_BINARY_ALLOWLIST = /* @__PURE__ */ new Set([
2331
+ "ava",
2332
+ "biome",
2333
+ "eslint",
2334
+ "jest",
2335
+ "mocha",
2336
+ "prettier",
2337
+ "tap",
2338
+ "tsc",
2339
+ "turbo",
2340
+ "vitest",
2341
+ "vue-tsc"
2342
+ ]);
2343
+ var PACKAGE_MANAGER_VERIFY_SCRIPTS = /^(?:test|tests|test[:_-][A-Za-z0-9:_-]+|lint|lint[:_-][A-Za-z0-9:_-]+|typecheck|typecheck[:_-][A-Za-z0-9:_-]+|type-check|type-check[:_-][A-Za-z0-9:_-]+|build|build[:_-][A-Za-z0-9:_-]+|coverage|coverage[:_-][A-Za-z0-9:_-]+|test:coverage|check|check[:_-][A-Za-z0-9:_-]+|verify|verify[:_-][A-Za-z0-9:_-]+|validate|validate[:_-][A-Za-z0-9:_-]+|integration|integration[:_-][A-Za-z0-9:_-]+|e2e|e2e[:_-][A-Za-z0-9:_-]+|smoke|smoke[:_-][A-Za-z0-9:_-]+|release:gate|format:check|check:format|fmt:check)$/;
2344
+ var NPM_ALLOWED_SUBCOMMANDS = /* @__PURE__ */ new Set([
2345
+ "run",
2346
+ "run-script",
2347
+ "rum",
2348
+ // npm alias for run-script
2349
+ "urn",
2350
+ // npm alias for run-script
2351
+ "test",
2352
+ "t",
2353
+ "tst",
2354
+ "ls",
2355
+ "list"
2356
+ ]);
2357
+ var PACKAGE_MANAGER_BLOCKED_SUBCOMMANDS = /* @__PURE__ */ new Set([
2358
+ "add",
2359
+ "ci",
2360
+ "create",
2361
+ "dedupe",
2362
+ "dlx",
2363
+ "exec",
2364
+ "i",
2365
+ "import",
2366
+ "init",
2367
+ "install",
2368
+ "link",
2369
+ "rebuild",
2370
+ "up",
2371
+ "update",
2372
+ "upgrade",
2373
+ "x"
2374
+ ]);
2375
+ var PACKAGE_MANAGER_VALUE_FLAGS = /* @__PURE__ */ new Set([
2376
+ "-C",
2377
+ "-F",
2378
+ "-w",
2379
+ "--cache",
2380
+ "--cache-folder",
2381
+ "--cwd",
2382
+ "--dir",
2383
+ "--filter",
2384
+ "--globalconfig",
2385
+ "--include-workspace-root",
2386
+ "--loglevel",
2387
+ "--modules-dir",
2388
+ "--mutex",
2389
+ "--network-timeout",
2390
+ "--prefix",
2391
+ "--registry",
2392
+ "--store-dir",
2393
+ "--tag",
2394
+ "--use-node-version",
2395
+ "--userconfig",
2396
+ "--workspace",
2397
+ "--workspace-root",
2398
+ "--audit-level",
2399
+ "--omit",
2400
+ "--severity"
2401
+ ]);
2402
+ var PACKAGE_MANAGER_PATH_VALUE_FLAGS = /* @__PURE__ */ new Set(["-C", "--cwd", "--dir", "--prefix"]);
2403
+ function extractPackageManagerPositionals(args) {
2404
+ const positionals = [];
2405
+ let pending = "none";
2406
+ for (const token of args) {
2407
+ if (token.startsWith("-")) {
2408
+ const name = normalizeFlagName(token);
2409
+ const bare = !token.includes("=");
2410
+ if (bare && name && PACKAGE_MANAGER_VALUE_FLAGS.has(name)) {
2411
+ pending = "known";
2412
+ } else if (bare) {
2413
+ pending = "unknown";
2414
+ } else {
2415
+ pending = "none";
2416
+ }
2417
+ continue;
2418
+ }
2419
+ if (pending === "known") {
2420
+ pending = "none";
2421
+ continue;
2422
+ }
2423
+ positionals.push({ value: token, definite: pending !== "unknown" });
2424
+ pending = "none";
2425
+ }
2426
+ return positionals;
2427
+ }
2428
+ function normalizeFlagName(token) {
2429
+ if (!token.startsWith("-")) return void 0;
2430
+ const eq = token.indexOf("=");
2431
+ return eq >= 0 ? token.slice(0, eq) : token;
2432
+ }
2433
+ function validateNpmAuditArgv(args, scanned, reject) {
2434
+ const auditPosition = scanned.findIndex((p) => p.value === "audit" && p.definite);
2435
+ if (auditPosition < 0) return void 0;
2436
+ const extraPositional = scanned.find((_p, index) => index !== auditPosition);
2437
+ if (extraPositional) {
2438
+ return reject(`"npm audit ${extraPositional.value}" is not an allowlisted audit command`);
2439
+ }
2440
+ if (args.includes("--")) {
2441
+ return reject('"npm audit" does not allow passthrough arguments');
2442
+ }
2443
+ const valueFlags = /* @__PURE__ */ new Set(["--audit-level", "--omit"]);
2444
+ const noValueFlags = /* @__PURE__ */ new Set(["--json"]);
2445
+ for (let i = 0; i < args.length; i += 1) {
2446
+ const token = args[i] ?? "";
2447
+ if (token === "audit") continue;
2448
+ if (!token.startsWith("-")) continue;
2449
+ const name = normalizeFlagName(token) ?? token;
2450
+ if (noValueFlags.has(name) && !token.includes("=")) {
2451
+ continue;
2452
+ }
2453
+ if (valueFlags.has(name)) {
2454
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
2455
+ if (!value || !token.includes("=") && value.startsWith("-")) {
2456
+ return reject(`option "${token}" requires a value`);
2457
+ }
2458
+ if (!token.includes("=")) i += 1;
2459
+ continue;
2460
+ }
2461
+ return reject(`"npm audit" option "${token}" is not allowlisted`);
2462
+ }
2463
+ return void 0;
2464
+ }
2465
+ function validatePackageManagerAuditArgv(executableName, args, scanned, reject) {
2466
+ const definite = scanned.filter((p) => p.definite).map((p) => p.value);
2467
+ const expected = executableName === "yarn" ? ["npm", "audit"] : executableName === "pnpm" ? ["audit"] : ["audit"];
2468
+ const matched = expected.every((value, index) => definite[index] === value);
2469
+ if (!matched) return { matched: false };
2470
+ const extra = definite.slice(expected.length)[0];
2471
+ if (extra) {
2472
+ return {
2473
+ matched: true,
2474
+ error: reject(
2475
+ `"${executableName} ${expected.join(" ")} ${extra}" is not an allowlisted audit command`
2476
+ )
2477
+ };
2478
+ }
2479
+ if (args.includes("--")) {
2480
+ return {
2481
+ matched: true,
2482
+ error: reject(
2483
+ `"${executableName} ${expected.join(" ")}" does not allow passthrough arguments`
2484
+ )
2485
+ };
2486
+ }
2487
+ const valueFlags = executableName === "pnpm" ? /* @__PURE__ */ new Set(["--audit-level"]) : executableName === "yarn" ? /* @__PURE__ */ new Set(["--severity"]) : /* @__PURE__ */ new Set();
2488
+ const noValueFlags = executableName === "pnpm" ? /* @__PURE__ */ new Set(["--prod", "--json"]) : executableName === "yarn" ? /* @__PURE__ */ new Set(["--recursive", "--json"]) : /* @__PURE__ */ new Set(["--production", "--json"]);
2489
+ const commandTokens = new Set(expected);
2490
+ for (let i = 0; i < args.length; i += 1) {
2491
+ const token = args[i] ?? "";
2492
+ if (commandTokens.has(token)) continue;
2493
+ if (!token.startsWith("-")) continue;
2494
+ const name = normalizeFlagName(token) ?? token;
2495
+ if (noValueFlags.has(name) && !token.includes("=")) {
2496
+ continue;
2497
+ }
2498
+ if (valueFlags.has(name)) {
2499
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
2500
+ if (!value || !token.includes("=") && value.startsWith("-")) {
2501
+ return { matched: true, error: reject(`option "${token}" requires a value`) };
2502
+ }
2503
+ if (!token.includes("=")) i += 1;
2504
+ continue;
2505
+ }
2506
+ return {
2507
+ matched: true,
2508
+ error: reject(
2509
+ `"${executableName} ${expected.join(" ")}" option "${token}" is not allowlisted`
2510
+ )
2511
+ };
2512
+ }
2513
+ return { matched: true };
2514
+ }
2515
+ function validateAuditToolArgv(executableName, argv) {
2516
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
2517
+ const reject = (detail) => `Verify command rejected: ${detail}. Audit verify tools may only run read-only vulnerability checks.`;
2518
+ if (executableName === "pip-audit") {
2519
+ const valueFlags = /* @__PURE__ */ new Set([
2520
+ "-r",
2521
+ "--requirement",
2522
+ "--cache-dir",
2523
+ "--index-url",
2524
+ "--extra-index-url",
2525
+ "--format",
2526
+ "--progress-spinner",
2527
+ "--timeout",
2528
+ "--vulnerability-service",
2529
+ "--ignore-vuln"
2530
+ ]);
2531
+ const pathValueFlags = /* @__PURE__ */ new Set(["-r", "--requirement", "--cache-dir"]);
2532
+ const noValueFlags = /* @__PURE__ */ new Set([
2533
+ "--strict",
2534
+ "--desc",
2535
+ "--aliases",
2536
+ "--disable-pip",
2537
+ "--no-deps",
2538
+ "--skip-editable"
2539
+ ]);
2540
+ for (let i = 0; i < args.length; i += 1) {
2541
+ const token = args[i] ?? "";
2542
+ if (!token.startsWith("-")) {
2543
+ return reject(`pip-audit positional "${token}" is not allowlisted`);
2544
+ }
2545
+ const name = normalizeFlagName(token) ?? token;
2546
+ if (name === "--fix" || name === "--require-hashes" || name === "-o" || name === "--output") {
2547
+ return reject(`pip-audit option "${name}" can mutate or write files`);
2548
+ }
2549
+ if (noValueFlags.has(name) && !token.includes("=")) continue;
2550
+ if (valueFlags.has(name)) {
2551
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
2552
+ if (!value || !token.includes("=") && value.startsWith("-")) {
2553
+ return reject(`option "${token}" requires a value`);
2554
+ }
2555
+ if (pathValueFlags.has(name) && isEscapingPathValue(value)) {
2556
+ return reject(`option "${token}" points outside the repository`);
2557
+ }
2558
+ if (!token.includes("=")) i += 1;
2559
+ continue;
2560
+ }
2561
+ return reject(`pip-audit option "${token}" is not allowlisted`);
2562
+ }
2563
+ return void 0;
2564
+ }
2565
+ if (executableName === "govulncheck") {
2566
+ const valueFlags = /* @__PURE__ */ new Set(["-C", "-db", "-format", "-mode", "-scan", "-show", "-tags"]);
2567
+ const pathValueFlags = /* @__PURE__ */ new Set(["-C"]);
2568
+ const noValueFlags = /* @__PURE__ */ new Set(["-json", "-test", "-version", "-v"]);
2569
+ for (let i = 0; i < args.length; i += 1) {
2570
+ const token = args[i] ?? "";
2571
+ if (!token.startsWith("-")) {
2572
+ if (isEscapingPathValue(token)) {
2573
+ return reject(`govulncheck package "${token}" points outside the repository`);
2574
+ }
2575
+ continue;
2576
+ }
2577
+ const name = normalizeFlagName(token) ?? token;
2578
+ const shortMatch = /^(-[A-Za-z])(.+)$/.exec(token);
2579
+ if (shortMatch && valueFlags.has(shortMatch[1] ?? "")) {
2580
+ const value = shortMatch[2] ?? "";
2581
+ if (pathValueFlags.has(shortMatch[1] ?? "") && isEscapingPathValue(value)) {
2582
+ return reject(`option "${token}" points outside the repository`);
2583
+ }
2584
+ continue;
2585
+ }
2586
+ if (noValueFlags.has(name) && !token.includes("=")) continue;
2587
+ if (valueFlags.has(name)) {
2588
+ const value = token.includes("=") ? token.slice(token.indexOf("=") + 1) : args[i + 1];
2589
+ if (!value || !token.includes("=") && value.startsWith("-")) {
2590
+ return reject(`option "${token}" requires a value`);
2591
+ }
2592
+ if (pathValueFlags.has(name) && isEscapingPathValue(value)) {
2593
+ return reject(`option "${token}" points outside the repository`);
2594
+ }
2595
+ if (!token.includes("=")) i += 1;
2596
+ continue;
2597
+ }
2598
+ return reject(`govulncheck option "${token}" is not allowlisted`);
2599
+ }
2600
+ return void 0;
2601
+ }
2602
+ return void 0;
2603
+ }
2604
+ function validatePackageManagerArgv(executableName, argv) {
2605
+ const args = argv.slice(1).filter((arg) => arg.length > 0);
2606
+ const reject = (detail) => `Verify command rejected: ${detail}. Use a repository script (e.g. "npm run <script>") or an allowlisted locally-installed binary instead.`;
2607
+ if (executableName === "npx" || executableName === "pnpx" || executableName === "bunx") {
2608
+ const downloadFlags = /* @__PURE__ */ new Set(["-p", "--package", "--packages", "-y", "--yes", "-c", "--call"]);
2609
+ const firstNonFlagIndex = args.findIndex((arg) => !arg.startsWith("-"));
2610
+ for (const token of firstNonFlagIndex >= 0 ? args.slice(0, firstNonFlagIndex) : args) {
2611
+ const flag = normalizeFlagName(token);
2612
+ if (flag && downloadFlags.has(flag)) {
2613
+ return reject(`"${executableName} ${flag}" can fetch and execute a remote package`);
2614
+ }
2615
+ }
2616
+ const firstNonFlag = firstNonFlagIndex >= 0 ? args[firstNonFlagIndex] : void 0;
2617
+ if (!firstNonFlag) {
2618
+ return reject(`"${executableName}" requires an explicit allowlisted binary`);
2619
+ }
2620
+ if (firstNonFlag.startsWith("@")) {
2621
+ return reject(
2622
+ `"${executableName} ${firstNonFlag}" is not an allowlisted local binary and may fetch a remote package`
2623
+ );
2624
+ }
2625
+ const binaryName = getExecutableName(firstNonFlag);
2626
+ if (binaryName !== firstNonFlag) {
2627
+ return reject(
2628
+ `"${executableName} ${firstNonFlag}" must name an allowlisted binary, not a path`
2629
+ );
2630
+ }
2631
+ if (!NPX_RUNNABLE_BINARY_ALLOWLIST.has(binaryName)) {
2632
+ return reject(
2633
+ `"${executableName} ${firstNonFlag}" is not an allowlisted local binary and may fetch a remote package`
2634
+ );
2635
+ }
2636
+ const hasLocalOnlyFlag = args.slice(0, firstNonFlagIndex).some((arg) => arg === "--no-install" || arg === "--offline");
2637
+ if (!hasLocalOnlyFlag) {
2638
+ return reject(
2639
+ `"${executableName} ${firstNonFlag}" must use --no-install or --offline so verify cannot fetch a remote package`
2640
+ );
2641
+ }
2642
+ const nestedArgs = args.slice(firstNonFlagIndex + 1);
2643
+ if ((binaryName === "prettier" || binaryName === "biome") && nestedArgs.some((arg) => arg === "--write" || arg.startsWith("--write="))) {
2644
+ return reject(`"${executableName} ${binaryName} --write" can rewrite files`);
2645
+ }
2646
+ if (binaryName === "eslint" && nestedArgs.some((arg) => arg === "--fix" || arg.startsWith("--fix="))) {
2647
+ return reject(`"${executableName} eslint --fix" can rewrite files`);
2648
+ }
2649
+ if (binaryName === "biome" && nestedArgs.some((arg) => arg === "--fix" || arg.startsWith("--fix="))) {
2650
+ return reject(`"${executableName} biome --fix" can rewrite files`);
2651
+ }
2652
+ if (binaryName === "biome" && nestedArgs[0] === "format") {
2653
+ return reject(
2654
+ `"${executableName} biome format" can rewrite files; use "biome check" for verify steps`
2655
+ );
2656
+ }
2657
+ const nestedLintToolError = validateDirectLintToolArgv(binaryName, [binaryName, ...nestedArgs]);
2658
+ if (nestedLintToolError) return nestedLintToolError;
2659
+ const nestedToolError = validateTypescriptToolArgv(binaryName, args.slice(firstNonFlagIndex));
2660
+ if (nestedToolError) return nestedToolError;
2661
+ const nestedJsToolchainError = validateJavaScriptToolchainArgv(
2662
+ binaryName,
2663
+ args.slice(firstNonFlagIndex)
2664
+ );
2665
+ if (nestedJsToolchainError) return nestedJsToolchainError;
2666
+ return void 0;
2667
+ }
2668
+ if (executableName === "npm" || executableName === "pnpm" || executableName === "yarn" || executableName === "bun") {
2669
+ const pathFlagError = validatePathValueFlags(args, PACKAGE_MANAGER_PATH_VALUE_FLAGS, reject);
2670
+ if (pathFlagError) return pathFlagError;
2671
+ const dashDash = args.indexOf("--");
2672
+ const beforeDashDash = dashDash >= 0 ? args.slice(0, dashDash) : args;
2673
+ const afterDashDash = dashDash >= 0 ? args.slice(dashDash + 1) : [];
2674
+ const positionalsBefore = extractPackageManagerPositionals(beforeDashDash);
2675
+ const positionalsAfter = extractPackageManagerPositionals(afterDashDash);
2676
+ const hasDefiniteCommandBefore = positionalsBefore.some((p) => p.definite);
2677
+ const scanned = hasDefiniteCommandBefore ? positionalsBefore : [...positionalsBefore, ...positionalsAfter];
2678
+ for (const { value } of scanned) {
2679
+ if (PACKAGE_MANAGER_BLOCKED_SUBCOMMANDS.has(value)) {
2680
+ return reject(
2681
+ `"${executableName} ${value}" can install, update, or execute remote packages`
2682
+ );
2683
+ }
2684
+ }
2685
+ if (scanned.length === 0) {
2686
+ return reject(`bare "${executableName}" performs an implicit install`);
2687
+ }
2688
+ if (executableName === "npm") {
2689
+ const npmAuditError = validateNpmAuditArgv(args, scanned, reject);
2690
+ if (npmAuditError !== void 0) {
2691
+ return npmAuditError;
2692
+ }
2693
+ if (scanned.some((p) => p.value === "audit" && p.definite)) {
2694
+ return void 0;
2695
+ }
2696
+ const hasSafeVerb = scanned.some((p) => NPM_ALLOWED_SUBCOMMANDS.has(p.value));
2697
+ if (!hasSafeVerb) {
2698
+ return reject(
2699
+ `"npm ${scanned[0]?.value}" is not an allowlisted script command (use "npm run <script>" or "npm test")`
2700
+ );
2701
+ }
2702
+ const verbIndex = scanned.findIndex((p) => NPM_ALLOWED_SUBCOMMANDS.has(p.value));
2703
+ const verb = scanned[verbIndex]?.value;
2704
+ const script = scanned[verbIndex + 1]?.value;
2705
+ if (verb && verb !== "test" && verb !== "t" && verb !== "tst") {
2706
+ if (!script || !PACKAGE_MANAGER_VERIFY_SCRIPTS.test(script)) {
2707
+ return reject(`"npm ${verb} ${script ?? ""}" is not an allowlisted verification script`);
2708
+ }
2709
+ }
2710
+ }
2711
+ if (executableName === "pnpm" || executableName === "yarn" || executableName === "bun") {
2712
+ const auditResult = validatePackageManagerAuditArgv(executableName, args, scanned, reject);
2713
+ if (auditResult.error !== void 0) {
2714
+ return auditResult.error;
2715
+ }
2716
+ if (auditResult.matched) {
2717
+ return void 0;
2718
+ }
2719
+ const firstCommandIndex = scanned.findIndex((p) => p.definite);
2720
+ const firstCommand = scanned[firstCommandIndex]?.value;
2721
+ if (firstCommand !== "run" && firstCommand !== "test") {
2722
+ return reject(
2723
+ `"${executableName} ${firstCommand ?? ""}" is not an allowlisted explicit verify command (use "${executableName} run <script>" or "${executableName} test")`
2724
+ );
2725
+ }
2726
+ if (firstCommand === "run") {
2727
+ const script = scanned[firstCommandIndex + 1]?.value;
2728
+ if (!script || !PACKAGE_MANAGER_VERIFY_SCRIPTS.test(script)) {
2729
+ return reject(
2730
+ `"${executableName} run ${script ?? ""}" is not an allowlisted verification script`
2731
+ );
2732
+ }
2733
+ }
2734
+ }
2735
+ return void 0;
2736
+ }
2737
+ return void 0;
2738
+ }
2739
+ function parseVerifyCommand(command) {
2740
+ const sequence = splitVerifyCommandSequence(command);
2741
+ if (!Array.isArray(sequence)) {
2742
+ return sequence;
2743
+ }
2744
+ const parsed = [];
2745
+ let nextOperator = "always";
2746
+ for (const segment of sequence) {
2747
+ if (segment === ";") {
2748
+ nextOperator = "always";
2749
+ continue;
2750
+ }
2751
+ if (segment === "&&") {
2752
+ nextOperator = "and";
2753
+ continue;
2754
+ }
2755
+ let negate = false;
2756
+ let segmentBody = segment;
2757
+ if (segmentBody.startsWith("!")) {
2758
+ negate = true;
2759
+ segmentBody = segmentBody.slice(1).trim();
2760
+ if (!segmentBody) {
2761
+ return {
2762
+ error: "Verify command rejected: empty command segment after shell negation."
2763
+ };
2764
+ }
2765
+ }
2766
+ const argv = parseArgv(segmentBody);
2767
+ if (!Array.isArray(argv)) {
2768
+ return argv;
2769
+ }
2770
+ if (negate && getExecutableName(argv[0] ?? "") !== "grep") {
2771
+ return {
2772
+ error: "Verify command rejected: shell negation is only allowed for grep absence checks."
2773
+ };
2774
+ }
2775
+ const validationError = validateVerifyArgv(argv);
2776
+ if (validationError) {
2777
+ return { error: validationError };
2778
+ }
2779
+ parsed.push({
2780
+ operator: nextOperator,
2781
+ argv,
2782
+ ...negate ? { negate: true } : {}
2783
+ });
2784
+ nextOperator = "always";
2785
+ }
2786
+ if (parsed.length === 0) {
2787
+ return { error: "Empty verify command rejected." };
2788
+ }
2789
+ if (parsed.every((segment) => isVacuousVerifyArgv(segment.argv))) {
2790
+ return {
2791
+ error: "Verify command rejected: no-op commands do not verify the project."
2792
+ };
2793
+ }
2794
+ return parsed;
2795
+ }
2796
+ function checkVerifyCommandSafety(command) {
2797
+ const parsed = parseVerifyCommand(command);
2798
+ if (Array.isArray(parsed)) {
2799
+ return { safe: true };
2800
+ }
2801
+ return { safe: false, error: parsed.error };
2802
+ }
2803
+ function containsUnsafeVerifyShellSyntax(command) {
2804
+ const parsed = parseVerifyCommand(command);
2805
+ if (Array.isArray(parsed)) return false;
2806
+ const msg = parsed.error.toLowerCase();
2807
+ return msg.includes("pipe") || msg.includes("redirection") || msg.includes("command substitution") || msg.includes("background execution");
2808
+ }
2809
+ async function executeVerifyCommand(cwd, command, timeoutMs, signal) {
2810
+ const parsed = parseVerifyCommand(command);
2811
+ if (!Array.isArray(parsed)) {
2812
+ return {
2813
+ exitCode: VERIFY_COMMAND_REJECTED_EXIT_CODE,
2814
+ stdout: "",
2815
+ stderr: parsed.error,
2816
+ combined: parsed.error
2817
+ };
2818
+ }
2819
+ const stdoutChunks = [];
2820
+ const stderrChunks = [];
2821
+ const combinedChunks = [];
2822
+ let exitCode = 0;
2823
+ let anyOverflow = false;
2824
+ try {
2825
+ for (const part of parsed) {
2826
+ if (part.operator === "and" && exitCode !== 0) {
2827
+ break;
2828
+ }
2829
+ const [executable, ...args] = part.argv;
2830
+ const result = await execa(executable, args, {
2831
+ cwd,
2832
+ stdio: "pipe",
2833
+ all: true,
2834
+ reject: false,
2835
+ timeout: timeoutMs,
2836
+ cancelSignal: signal,
2837
+ env: buildSanitizedEnv(),
2838
+ extendEnv: false,
2839
+ shell: false,
2840
+ maxBuffer: VERIFY_COMMAND_MAX_BUFFER_BYTES
2841
+ });
2842
+ const overflowed = result.isMaxBuffer === true;
2843
+ if (overflowed) anyOverflow = true;
2844
+ const hasNumericExitCode = !overflowed && typeof result.exitCode === "number";
2845
+ exitCode = overflowed ? VERIFY_COMMAND_PROCESS_FAILURE_EXIT_CODE : resolveProcessExitCode(command, result);
2846
+ if (part.negate && hasNumericExitCode) {
2847
+ if (exitCode >= 2) {
2848
+ exitCode = VERIFY_COMMAND_PROCESS_FAILURE_EXIT_CODE;
2849
+ } else {
2850
+ exitCode = exitCode === 0 ? 1 : 0;
2851
+ }
2852
+ }
2853
+ const stdout = boundTailBytes(
2854
+ String(result.stdout ?? ""),
2855
+ VERIFY_COMMAND_RETAINED_TAIL_BYTES
2856
+ );
2857
+ const stderr = boundTailBytes(
2858
+ String(result.stderr ?? ""),
2859
+ VERIFY_COMMAND_RETAINED_TAIL_BYTES
2860
+ );
2861
+ const missingExitCodeDiagnostic = describeMissingProcessExitCode(result);
2862
+ const maxBufferDiagnostic = overflowed ? `[verify] Output exceeded the ${VERIFY_COMMAND_MAX_BUFFER_BYTES}-byte capture buffer; the command was terminated and treated as a failure (its exit code is not trustworthy).` : void 0;
2863
+ const combined = [
2864
+ boundTailBytes(
2865
+ String(result.all ?? [stdout, stderr].filter(Boolean).join("\n")),
2866
+ VERIFY_COMMAND_RETAINED_TAIL_BYTES
2867
+ ),
2868
+ maxBufferDiagnostic,
2869
+ missingExitCodeDiagnostic
2870
+ ].filter(Boolean).join("\n");
2871
+ if (stdout) stdoutChunks.push(stdout);
2872
+ if (stderr || missingExitCodeDiagnostic) {
2873
+ stderrChunks.push([stderr, missingExitCodeDiagnostic].filter(Boolean).join("\n"));
2874
+ }
2875
+ if (combined) combinedChunks.push(combined);
2876
+ }
2877
+ if (anyOverflow && exitCode === 0) {
2878
+ exitCode = VERIFY_COMMAND_PROCESS_FAILURE_EXIT_CODE;
2879
+ }
2880
+ return {
2881
+ exitCode,
2882
+ stdout: stdoutChunks.join("\n"),
2883
+ stderr: stderrChunks.join("\n"),
2884
+ combined: combinedChunks.join("\n"),
2885
+ overflowed: anyOverflow
2886
+ };
2887
+ } catch (error) {
2888
+ const message = error instanceof Error ? error.message : String(error);
2889
+ return {
2890
+ exitCode: 124,
2891
+ stdout: "",
2892
+ stderr: "",
2893
+ combined: `${message}`.trim()
2894
+ };
2895
+ }
2896
+ }
2897
+ async function runVerifyCommands(options) {
2898
+ const verifyCommands = [];
2899
+ const maxOutputLines = options.maxOutputLines ?? 80;
2900
+ const combinedOutputChunks = [];
2901
+ const stdoutChunks = [];
2902
+ const stderrChunks = [];
2903
+ const commandProvenance = options.commandProvenance ?? "workflow-config";
2904
+ const globalDeadline = Date.now() + resolveExecutionBoundary("short-command").hardCeilingMs * 3;
2905
+ let globalBudgetExhausted = false;
2906
+ if (options.commands.length === 0) {
2907
+ const message = "Empty verify command list rejected.";
2908
+ const result = {
2909
+ command: "<empty verify commands>",
2910
+ exitCode: VERIFY_COMMAND_REJECTED_EXIT_CODE,
2911
+ durationMs: 0,
2912
+ provenance: commandProvenance,
2913
+ outputTail: message,
2914
+ stdoutTail: "(no output)",
2915
+ stderrTail: message
2916
+ };
2917
+ return {
2918
+ passed: false,
2919
+ results: [result],
2920
+ combinedOutput: message,
2921
+ stdoutOutput: "",
2922
+ stderrOutput: message
2923
+ };
2924
+ }
2925
+ for (const command of options.commands) {
2926
+ if (Date.now() > globalDeadline) {
2927
+ const remaining = options.commands.length - verifyCommands.length;
2928
+ const message = `[verify] Global budget exhausted; skipping ${remaining} remaining command(s).`;
2929
+ console.warn(message);
2930
+ verifyCommands.push({
2931
+ command: "<global verify budget>",
2932
+ exitCode: VERIFY_GLOBAL_BUDGET_EXIT_CODE,
2933
+ durationMs: 0,
2934
+ provenance: commandProvenance,
2935
+ outputTail: message,
2936
+ stdoutTail: "(no output)",
2937
+ stderrTail: message
2938
+ });
2939
+ combinedOutputChunks.push(message);
2940
+ stderrChunks.push(message);
2941
+ globalBudgetExhausted = true;
2942
+ break;
2943
+ }
2944
+ const commandStartTime = Date.now();
2945
+ const VERIFY_COMMAND_DEFAULT_TIMEOUT_MS = resolveExecutionBoundary("short-command").hardCeilingMs;
2946
+ const envTimeoutMsRaw = Number(process.env.POETIC_VERIFY_COMMAND_TIMEOUT_MS);
2947
+ const envTimeoutMs = Number.isFinite(envTimeoutMsRaw) && envTimeoutMsRaw > 0 ? envTimeoutMsRaw : VERIFY_COMMAND_DEFAULT_TIMEOUT_MS;
2948
+ const timeoutMs = options.timeoutMs ?? envTimeoutMs;
2949
+ if (options.signal?.aborted) {
2950
+ const message = "Verify command aborted before execution.";
2951
+ verifyCommands.push({
2952
+ command,
2953
+ exitCode: 124,
2954
+ durationMs: 0,
2955
+ provenance: commandProvenance,
2956
+ outputTail: message,
2957
+ stdoutTail: "(no output)",
2958
+ stderrTail: message
2959
+ });
2960
+ combinedOutputChunks.push(message);
2961
+ stderrChunks.push(message);
2962
+ globalBudgetExhausted = true;
2963
+ break;
2964
+ }
2965
+ const currentExecution = await executeVerifyCommand(
2966
+ options.cwd,
2967
+ command,
2968
+ timeoutMs,
2969
+ options.signal
2970
+ );
2971
+ const durationMs = Date.now() - commandStartTime;
2972
+ const stdout = currentExecution.stdout;
2973
+ let stderr = currentExecution.stderr;
2974
+ let combined = currentExecution.combined;
2975
+ let exitCode = currentExecution.exitCode;
2976
+ let baselineErrorCount;
2977
+ let currentErrorCount;
2978
+ let newErrorCount;
2979
+ const baselineParser = resolveBaselineErrorParser(command);
2980
+ if (exitCode !== 0 && !currentExecution.overflowed && options.baselineCwd && baselineParser) {
2981
+ const baselineExecution = await executeVerifyCommand(
2982
+ options.baselineCwd,
2983
+ command,
2984
+ timeoutMs,
2985
+ options.signal
2986
+ );
2987
+ if (baselineExecution.exitCode !== 0 && !baselineExecution.overflowed) {
2988
+ baselineErrorCount = baselineParser.count(baselineExecution.combined);
2989
+ currentErrorCount = baselineParser.count(combined);
2990
+ newErrorCount = baselineParser.newCount(baselineExecution.combined, combined);
2991
+ if (newErrorCount === 0 && currentErrorCount <= baselineErrorCount) {
2992
+ exitCode = 0;
2993
+ const baselineNote = `Baseline errors: ${baselineErrorCount}; current: ${currentErrorCount}; new: 0. Treating verify as pass because no new errors were introduced.`;
2994
+ combined = [combined.trim(), baselineNote].filter(Boolean).join("\n");
2995
+ stderr = [stderr.trim(), baselineNote].filter(Boolean).join("\n");
2996
+ }
2997
+ }
2998
+ }
2999
+ if (exitCode === 0) {
3000
+ const failureSummary = detectTestRunnerFailureSummary(command, combined);
3001
+ if (failureSummary) {
3002
+ exitCode = 1;
3003
+ combined = [combined.trim(), `[verify] ${failureSummary}`].filter(Boolean).join("\n");
3004
+ stderr = [stderr.trim(), `[verify] ${failureSummary}`].filter(Boolean).join("\n");
3005
+ }
3006
+ }
3007
+ const outputTail = formatOutputTail(combined, maxOutputLines);
3008
+ const stdoutTail = formatOutputTail(stdout, maxOutputLines);
3009
+ const stderrTail = formatOutputTail(stderr, maxOutputLines);
3010
+ combinedOutputChunks.push(`$ ${command}
3011
+ ${combined}`.trim());
3012
+ stdoutChunks.push(`$ ${command}
3013
+ ${stdout}`.trim());
3014
+ stderrChunks.push(`$ ${command}
3015
+ ${stderr}`.trim());
3016
+ verifyCommands.push({
3017
+ command,
3018
+ exitCode,
3019
+ durationMs,
3020
+ provenance: commandProvenance,
3021
+ outputTail,
3022
+ stdoutTail,
3023
+ stderrTail,
3024
+ baselineErrorCount,
3025
+ currentErrorCount,
3026
+ newErrorCount
3027
+ });
3028
+ if (exitCode !== 0) {
3029
+ return {
3030
+ passed: false,
3031
+ results: verifyCommands,
3032
+ combinedOutput: combinedOutputChunks.filter(Boolean).join("\n\n"),
3033
+ stdoutOutput: stdoutChunks.filter(Boolean).join("\n\n"),
3034
+ stderrOutput: stderrChunks.filter(Boolean).join("\n\n")
3035
+ };
3036
+ }
3037
+ }
3038
+ return {
3039
+ passed: !globalBudgetExhausted,
3040
+ results: verifyCommands,
3041
+ combinedOutput: combinedOutputChunks.filter(Boolean).join("\n\n"),
3042
+ stdoutOutput: stdoutChunks.filter(Boolean).join("\n\n"),
3043
+ stderrOutput: stderrChunks.filter(Boolean).join("\n\n")
3044
+ };
3045
+ }
3046
+
3047
+ export {
3048
+ boundTailBytes,
3049
+ summarizeVerifyCommandRun,
3050
+ validationSurfaceToCommands,
3051
+ mergeValidationSurfaces,
3052
+ resolveBaselineErrorParser,
3053
+ isBaselineComparableTypeScriptCommand,
3054
+ extractTypeScriptErrorSignatures,
3055
+ computeNewErrorCount,
3056
+ buildSanitizedEnv,
3057
+ isAllowedVerifyCommand,
3058
+ parseVerifyCommand,
3059
+ checkVerifyCommandSafety,
3060
+ containsUnsafeVerifyShellSyntax,
3061
+ runVerifyCommands
3062
+ };
3063
+ //# sourceMappingURL=chunk-LO23NABI.js.map