@runcofactor/cli 0.52.0 → 0.53.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 (225) hide show
  1. package/README.md +2 -0
  2. package/dist/{account-3ZG24MOE.js → account-MRZ54P5P.js} +5 -5
  3. package/dist/{alert-5G7PTAX2.js → alert-XBHELHEI.js} +8 -8
  4. package/dist/{api-catalog-IBYAFKKQ.js → api-catalog-GWYRX53L.js} +5 -5
  5. package/dist/{api-key-UXC44BDR.js → api-key-FH6JN447.js} +5 -5
  6. package/dist/{attachment-T6IRFQW3.js → attachment-J7GRVT5F.js} +5 -5
  7. package/dist/{auth-SHOCJE6Z.js → auth-VZZQXRDR.js} +3 -3
  8. package/dist/{benchmark-NJ2U6VTC.js → benchmark-A3SNDARF.js} +5 -5
  9. package/dist/{blackcat-RQJVFGXQ.js → blackcat-UM6TBQBN.js} +3 -3
  10. package/dist/{chunk-DHAGRM2F.js → chunk-33U56YGD.js} +14 -5
  11. package/dist/{chunk-DHAGRM2F.js.map → chunk-33U56YGD.js.map} +1 -1
  12. package/dist/{chunk-M752EUK3.js → chunk-3JU4UYYN.js} +5 -5
  13. package/dist/{chunk-G6BCST3G.js → chunk-3ZOUNCA5.js} +7 -7
  14. package/dist/{chunk-76Z6E7XX.js → chunk-4UZN6TVT.js} +74 -131
  15. package/dist/chunk-4UZN6TVT.js.map +1 -0
  16. package/dist/{chunk-ABT3BLRC.js → chunk-5TKXHS3X.js} +3 -3
  17. package/dist/{chunk-QCYSONXI.js → chunk-CRYHWO4M.js} +2 -2
  18. package/dist/{chunk-QTYUM4ZB.js → chunk-EJ3ZPH5U.js} +23 -187
  19. package/dist/chunk-EJ3ZPH5U.js.map +1 -0
  20. package/dist/{chunk-I5RHTCPY.js → chunk-EL6KJ4PO.js} +4 -4
  21. package/dist/{chunk-ZL4O6C42.js → chunk-HXBK3AGD.js} +2 -2
  22. package/dist/{chunk-PRERH4DN.js → chunk-I2SOHQ2C.js} +3 -3
  23. package/dist/{chunk-CYSPCGO6.js → chunk-JEHHEMUL.js} +5 -5
  24. package/dist/{chunk-LIEADTEF.js → chunk-LJFVRJCA.js} +2 -2
  25. package/dist/{chunk-UEJ2HTKU.js → chunk-MJVUMVLO.js} +19 -1
  26. package/dist/chunk-MJVUMVLO.js.map +1 -0
  27. package/dist/chunk-N55RKCGR.js +24 -0
  28. package/dist/chunk-N55RKCGR.js.map +1 -0
  29. package/dist/{chunk-PHNH3CEU.js → chunk-O4Z44BR7.js} +5 -5
  30. package/dist/{chunk-QA37WVF6.js → chunk-OQFCZERZ.js} +6 -6
  31. package/dist/{chunk-EUVB6Y3C.js → chunk-P7L5KELH.js} +8 -8
  32. package/dist/chunk-P7L5KELH.js.map +1 -0
  33. package/dist/{chunk-Z3MDQSZG.js → chunk-PJFFGQSB.js} +2 -2
  34. package/dist/{chunk-IY3ZK46I.js → chunk-QOVJUSSL.js} +2 -2
  35. package/dist/{chunk-RPJMQBB5.js → chunk-QXU4G4YN.js} +3 -3
  36. package/dist/{chunk-SZSTJIYU.js → chunk-RRSUKARV.js} +4 -4
  37. package/dist/{chunk-775FI436.js → chunk-RVD6J6IZ.js} +2 -2
  38. package/dist/{chunk-5UUIBY6E.js → chunk-TAVBFLCR.js} +3 -3
  39. package/dist/{chunk-ROX7N3RK.js → chunk-V7HB5LAU.js} +10 -7
  40. package/dist/chunk-V7HB5LAU.js.map +1 -0
  41. package/dist/{chunk-LL6TSQWV.js → chunk-VKZOHJCE.js} +3 -3
  42. package/dist/chunk-VKZOHJCE.js.map +1 -0
  43. package/dist/{chunk-3HI6QC4V.js → chunk-WRBU6TX7.js} +2 -2
  44. package/dist/{proofs-TXJGAP5F.js → chunk-X7SUSIY3.js} +118 -20
  45. package/dist/chunk-X7SUSIY3.js.map +1 -0
  46. package/dist/{chunk-BF3IPGMP.js → chunk-XSSZMG65.js} +4 -4
  47. package/dist/{credential-TWSWV64F.js → credential-4RFRU6OH.js} +5 -5
  48. package/dist/{credential-template-XO5D5AI3.js → credential-template-36PFUTBN.js} +5 -5
  49. package/dist/{digest-SLEFOLPV.js → digest-THMKFMP7.js} +8 -8
  50. package/dist/{docs-IDC4V4WQ.js → docs-ZGM53L67.js} +5 -5
  51. package/dist/{doctor-SDAYEA6C.js → doctor-Z2XBGBM3.js} +3 -3
  52. package/dist/{environment-VBUIBQ6O.js → environment-5YVZXBN7.js} +7 -7
  53. package/dist/eval-SO5TPD37.js +1177 -0
  54. package/dist/eval-SO5TPD37.js.map +1 -0
  55. package/dist/{exploration-IREIR5PO.js → exploration-GZ4WUJJH.js} +5 -5
  56. package/dist/{exploratory-test-4Q7BMEFT.js → exploratory-test-Y7P4ZDLD.js} +5 -5
  57. package/dist/{external-run-S7LULKPT.js → external-run-IJGGZOGI.js} +7 -7
  58. package/dist/{feature-flag-IASHTUGU.js → feature-flag-UH6Z7774.js} +5 -5
  59. package/dist/{flow-IBEZFZTU.js → flow-MRWAQYZZ.js} +5 -5
  60. package/dist/{github-HAEZRULP.js → github-VDJU3PU3.js} +6 -6
  61. package/dist/index.js +101 -82
  62. package/dist/index.js.map +1 -1
  63. package/dist/{init-LT2TZMQY.js → init-CROSTPA6.js} +5 -5
  64. package/dist/{install-RTEYH6TK.js → install-ECR7OLAY.js} +5 -5
  65. package/dist/{issues-5GE277R2.js → issues-K5TL2S4Z.js} +7 -7
  66. package/dist/{knobs-AMIWGYUZ.js → knobs-OKQFBQLK.js} +5 -5
  67. package/dist/{landing-3VLVVQL5.js → landing-XANIBPVM.js} +7 -7
  68. package/dist/{list-GDJR6UY6.js → list-64GX47Q4.js} +5 -5
  69. package/dist/{local-4R6GVW7U.js → local-QMQY2ZUX.js} +7 -7
  70. package/dist/{login-IXVAWTLO.js → login-I7UQ3GTM.js} +5 -5
  71. package/dist/{mcp-BM2MJWX4.js → mcp-XZV63DX5.js} +11 -11
  72. package/dist/{mcp-BM2MJWX4.js.map → mcp-XZV63DX5.js.map} +1 -1
  73. package/dist/{metrics-SSIP5CEB.js → metrics-KBTQ3KGZ.js} +5 -5
  74. package/dist/{monitor-ESZYHXT2.js → monitor-UGWY43IU.js} +5 -5
  75. package/dist/perf-CCHWHCSR.js +961 -0
  76. package/dist/perf-CCHWHCSR.js.map +1 -0
  77. package/dist/{product-VCGUV5TH.js → product-KLG2ZTHC.js} +5 -5
  78. package/dist/{product-map-AXKZNQDM.js → product-map-AMEZ76EQ.js} +5 -5
  79. package/dist/{prompts-FVPSON2N.js → prompts-ZVQNGL7X.js} +5 -5
  80. package/dist/proofs-QCNSQAPX.js +20 -0
  81. package/dist/{property-XEPCC7KQ.js → property-PJDQFHAL.js} +6 -6
  82. package/dist/{psql-JKF3OYYJ.js → psql-AURAN27C.js} +5 -5
  83. package/dist/{record-REQ37S54.js → record-SYWBTUOB.js} +6 -6
  84. package/dist/{redis-WGHT2GJB.js → redis-2H752SKO.js} +5 -5
  85. package/dist/{release-SNDIVIA6.js → release-OSIYUXSC.js} +5 -5
  86. package/dist/{runbook-XFJG2LFC.js → runbook-7LVHF6KV.js} +5 -5
  87. package/dist/{sandbox-DYCKLCMY.js → sandbox-TJQPMRGS.js} +18 -30
  88. package/dist/sandbox-TJQPMRGS.js.map +1 -0
  89. package/dist/{scenarios-PVHCKP55.js → scenarios-P2ABU4HK.js} +5 -5
  90. package/dist/{schedule-DGC7CX23.js → schedule-XLS56NP5.js} +8 -8
  91. package/dist/{session-ERGUFDDI.js → session-ACSFC3UB.js} +8 -8
  92. package/dist/{skill-6QO2E3TB.js → skill-F7I5P6AI.js} +43 -28
  93. package/dist/{skill-6QO2E3TB.js.map → skill-F7I5P6AI.js.map} +1 -1
  94. package/dist/{slack-WE7THLLH.js → slack-ZEK4GRND.js} +6 -6
  95. package/dist/{spec-SEOY7N3L.js → spec-XPIRRSV6.js} +5 -5
  96. package/dist/{src-CCK3TKBX.js → src-N7ZCYCXU.js} +4 -4
  97. package/dist/{src-AEWV5HYH.js → src-XSBBMVGW.js} +3 -3
  98. package/dist/{start-EPGLHTND.js → start-DKWLOQI6.js} +5 -5
  99. package/dist/{status-DTE2GXM2.js → status-K7KH5DI3.js} +5 -5
  100. package/dist/{tag-GIFEWGBL.js → tag-2Y3OMQQC.js} +6 -6
  101. package/dist/{task-VLJCHSFB.js → task-4PIOC4QV.js} +6 -6
  102. package/dist/{teams-J2OOJBL4.js → teams-KUM56BE2.js} +83 -47
  103. package/dist/teams-KUM56BE2.js.map +1 -0
  104. package/dist/{test-suite-CTACGIAZ.js → test-suite-SW25YGJV.js} +138 -96
  105. package/dist/test-suite-SW25YGJV.js.map +1 -0
  106. package/dist/{trace-RWQDYL4K.js → trace-QPXHYBLA.js} +7 -7
  107. package/dist/{triage-6UAXLCGU.js → triage-EZABRZZM.js} +6 -6
  108. package/dist/trigger-7C7KX5KH.js +137 -0
  109. package/dist/trigger-7C7KX5KH.js.map +1 -0
  110. package/dist/{update-check-QRREAM3N.js → update-check-E3X7UIY6.js} +3 -3
  111. package/dist/{upgrade-5Y655TQ6.js → upgrade-EJGTMW44.js} +4 -4
  112. package/dist/{usage-KCXFY46V.js → usage-GZCQDULF.js} +7 -7
  113. package/dist/{utilities-SUON2KZK.js → utilities-RIITD53A.js} +6 -6
  114. package/dist/{visual-GJZVJC32.js → visual-FH67OKS2.js} +5 -5
  115. package/dist/{workflow-R5QAXWBX.js → workflow-34YJZ2QQ.js} +38 -86
  116. package/dist/workflow-34YJZ2QQ.js.map +1 -0
  117. package/dist/{workflow-cache-PFBTWLGM.js → workflow-cache-YQ3BGJIG.js} +17 -17
  118. package/dist/{workflow-cache-convergence-resolve-UZGRPC3B.js → workflow-cache-convergence-resolve-SPLBRSNK.js} +5 -5
  119. package/dist/{workflow-debug-RACNWWOL.js → workflow-debug-HZB7TJGK.js} +10 -10
  120. package/dist/workflow-debug-HZB7TJGK.js.map +1 -0
  121. package/dist/{workflow-feedback-RJIQ5R3R.js → workflow-feedback-6UOTIWIQ.js} +5 -5
  122. package/dist/{workflow-fork-LINDCYJ3.js → workflow-fork-IDYHAHCX.js} +5 -5
  123. package/dist/workflow-promotion-U6WYFY5U.js +62 -0
  124. package/dist/workflow-promotion-U6WYFY5U.js.map +1 -0
  125. package/dist/{workflow-proposals-E4EXKAGM.js → workflow-proposals-MMVNIQT3.js} +5 -5
  126. package/dist/{workflow-revisions-5M6APN6R.js → workflow-revisions-BPUOLCZB.js} +5 -5
  127. package/dist/{workflow-status-7KL73WS2.js → workflow-status-RA3IEMEW.js} +5 -5
  128. package/package.json +3 -2
  129. package/dist/chat-target-IZ7YLLU3.js +0 -502
  130. package/dist/chat-target-IZ7YLLU3.js.map +0 -1
  131. package/dist/chunk-76Z6E7XX.js.map +0 -1
  132. package/dist/chunk-EUVB6Y3C.js.map +0 -1
  133. package/dist/chunk-LL6TSQWV.js.map +0 -1
  134. package/dist/chunk-QTYUM4ZB.js.map +0 -1
  135. package/dist/chunk-ROX7N3RK.js.map +0 -1
  136. package/dist/chunk-UEJ2HTKU.js.map +0 -1
  137. package/dist/proofs-TXJGAP5F.js.map +0 -1
  138. package/dist/sandbox-DYCKLCMY.js.map +0 -1
  139. package/dist/teams-J2OOJBL4.js.map +0 -1
  140. package/dist/test-suite-CTACGIAZ.js.map +0 -1
  141. package/dist/workflow-R5QAXWBX.js.map +0 -1
  142. /package/dist/{account-3ZG24MOE.js.map → account-MRZ54P5P.js.map} +0 -0
  143. /package/dist/{alert-5G7PTAX2.js.map → alert-XBHELHEI.js.map} +0 -0
  144. /package/dist/{api-catalog-IBYAFKKQ.js.map → api-catalog-GWYRX53L.js.map} +0 -0
  145. /package/dist/{api-key-UXC44BDR.js.map → api-key-FH6JN447.js.map} +0 -0
  146. /package/dist/{attachment-T6IRFQW3.js.map → attachment-J7GRVT5F.js.map} +0 -0
  147. /package/dist/{auth-SHOCJE6Z.js.map → auth-VZZQXRDR.js.map} +0 -0
  148. /package/dist/{benchmark-NJ2U6VTC.js.map → benchmark-A3SNDARF.js.map} +0 -0
  149. /package/dist/{blackcat-RQJVFGXQ.js.map → blackcat-UM6TBQBN.js.map} +0 -0
  150. /package/dist/{chunk-M752EUK3.js.map → chunk-3JU4UYYN.js.map} +0 -0
  151. /package/dist/{chunk-G6BCST3G.js.map → chunk-3ZOUNCA5.js.map} +0 -0
  152. /package/dist/{chunk-ABT3BLRC.js.map → chunk-5TKXHS3X.js.map} +0 -0
  153. /package/dist/{chunk-QCYSONXI.js.map → chunk-CRYHWO4M.js.map} +0 -0
  154. /package/dist/{chunk-I5RHTCPY.js.map → chunk-EL6KJ4PO.js.map} +0 -0
  155. /package/dist/{chunk-ZL4O6C42.js.map → chunk-HXBK3AGD.js.map} +0 -0
  156. /package/dist/{chunk-PRERH4DN.js.map → chunk-I2SOHQ2C.js.map} +0 -0
  157. /package/dist/{chunk-CYSPCGO6.js.map → chunk-JEHHEMUL.js.map} +0 -0
  158. /package/dist/{chunk-LIEADTEF.js.map → chunk-LJFVRJCA.js.map} +0 -0
  159. /package/dist/{chunk-PHNH3CEU.js.map → chunk-O4Z44BR7.js.map} +0 -0
  160. /package/dist/{chunk-QA37WVF6.js.map → chunk-OQFCZERZ.js.map} +0 -0
  161. /package/dist/{chunk-Z3MDQSZG.js.map → chunk-PJFFGQSB.js.map} +0 -0
  162. /package/dist/{chunk-IY3ZK46I.js.map → chunk-QOVJUSSL.js.map} +0 -0
  163. /package/dist/{chunk-RPJMQBB5.js.map → chunk-QXU4G4YN.js.map} +0 -0
  164. /package/dist/{chunk-SZSTJIYU.js.map → chunk-RRSUKARV.js.map} +0 -0
  165. /package/dist/{chunk-775FI436.js.map → chunk-RVD6J6IZ.js.map} +0 -0
  166. /package/dist/{chunk-5UUIBY6E.js.map → chunk-TAVBFLCR.js.map} +0 -0
  167. /package/dist/{chunk-3HI6QC4V.js.map → chunk-WRBU6TX7.js.map} +0 -0
  168. /package/dist/{chunk-BF3IPGMP.js.map → chunk-XSSZMG65.js.map} +0 -0
  169. /package/dist/{credential-TWSWV64F.js.map → credential-4RFRU6OH.js.map} +0 -0
  170. /package/dist/{credential-template-XO5D5AI3.js.map → credential-template-36PFUTBN.js.map} +0 -0
  171. /package/dist/{digest-SLEFOLPV.js.map → digest-THMKFMP7.js.map} +0 -0
  172. /package/dist/{docs-IDC4V4WQ.js.map → docs-ZGM53L67.js.map} +0 -0
  173. /package/dist/{doctor-SDAYEA6C.js.map → doctor-Z2XBGBM3.js.map} +0 -0
  174. /package/dist/{environment-VBUIBQ6O.js.map → environment-5YVZXBN7.js.map} +0 -0
  175. /package/dist/{exploration-IREIR5PO.js.map → exploration-GZ4WUJJH.js.map} +0 -0
  176. /package/dist/{exploratory-test-4Q7BMEFT.js.map → exploratory-test-Y7P4ZDLD.js.map} +0 -0
  177. /package/dist/{external-run-S7LULKPT.js.map → external-run-IJGGZOGI.js.map} +0 -0
  178. /package/dist/{feature-flag-IASHTUGU.js.map → feature-flag-UH6Z7774.js.map} +0 -0
  179. /package/dist/{flow-IBEZFZTU.js.map → flow-MRWAQYZZ.js.map} +0 -0
  180. /package/dist/{github-HAEZRULP.js.map → github-VDJU3PU3.js.map} +0 -0
  181. /package/dist/{init-LT2TZMQY.js.map → init-CROSTPA6.js.map} +0 -0
  182. /package/dist/{install-RTEYH6TK.js.map → install-ECR7OLAY.js.map} +0 -0
  183. /package/dist/{issues-5GE277R2.js.map → issues-K5TL2S4Z.js.map} +0 -0
  184. /package/dist/{knobs-AMIWGYUZ.js.map → knobs-OKQFBQLK.js.map} +0 -0
  185. /package/dist/{landing-3VLVVQL5.js.map → landing-XANIBPVM.js.map} +0 -0
  186. /package/dist/{list-GDJR6UY6.js.map → list-64GX47Q4.js.map} +0 -0
  187. /package/dist/{local-4R6GVW7U.js.map → local-QMQY2ZUX.js.map} +0 -0
  188. /package/dist/{login-IXVAWTLO.js.map → login-I7UQ3GTM.js.map} +0 -0
  189. /package/dist/{metrics-SSIP5CEB.js.map → metrics-KBTQ3KGZ.js.map} +0 -0
  190. /package/dist/{monitor-ESZYHXT2.js.map → monitor-UGWY43IU.js.map} +0 -0
  191. /package/dist/{product-VCGUV5TH.js.map → product-KLG2ZTHC.js.map} +0 -0
  192. /package/dist/{product-map-AXKZNQDM.js.map → product-map-AMEZ76EQ.js.map} +0 -0
  193. /package/dist/{prompts-FVPSON2N.js.map → prompts-ZVQNGL7X.js.map} +0 -0
  194. /package/dist/{src-AEWV5HYH.js.map → proofs-QCNSQAPX.js.map} +0 -0
  195. /package/dist/{property-XEPCC7KQ.js.map → property-PJDQFHAL.js.map} +0 -0
  196. /package/dist/{psql-JKF3OYYJ.js.map → psql-AURAN27C.js.map} +0 -0
  197. /package/dist/{record-REQ37S54.js.map → record-SYWBTUOB.js.map} +0 -0
  198. /package/dist/{redis-WGHT2GJB.js.map → redis-2H752SKO.js.map} +0 -0
  199. /package/dist/{release-SNDIVIA6.js.map → release-OSIYUXSC.js.map} +0 -0
  200. /package/dist/{runbook-XFJG2LFC.js.map → runbook-7LVHF6KV.js.map} +0 -0
  201. /package/dist/{scenarios-PVHCKP55.js.map → scenarios-P2ABU4HK.js.map} +0 -0
  202. /package/dist/{schedule-DGC7CX23.js.map → schedule-XLS56NP5.js.map} +0 -0
  203. /package/dist/{session-ERGUFDDI.js.map → session-ACSFC3UB.js.map} +0 -0
  204. /package/dist/{slack-WE7THLLH.js.map → slack-ZEK4GRND.js.map} +0 -0
  205. /package/dist/{spec-SEOY7N3L.js.map → spec-XPIRRSV6.js.map} +0 -0
  206. /package/dist/{src-CCK3TKBX.js.map → src-N7ZCYCXU.js.map} +0 -0
  207. /package/dist/{tag-GIFEWGBL.js.map → src-XSBBMVGW.js.map} +0 -0
  208. /package/dist/{start-EPGLHTND.js.map → start-DKWLOQI6.js.map} +0 -0
  209. /package/dist/{status-DTE2GXM2.js.map → status-K7KH5DI3.js.map} +0 -0
  210. /package/dist/{trace-RWQDYL4K.js.map → tag-2Y3OMQQC.js.map} +0 -0
  211. /package/dist/{task-VLJCHSFB.js.map → task-4PIOC4QV.js.map} +0 -0
  212. /package/dist/{triage-6UAXLCGU.js.map → trace-QPXHYBLA.js.map} +0 -0
  213. /package/dist/{update-check-QRREAM3N.js.map → triage-EZABRZZM.js.map} +0 -0
  214. /package/dist/{upgrade-5Y655TQ6.js.map → update-check-E3X7UIY6.js.map} +0 -0
  215. /package/dist/{utilities-SUON2KZK.js.map → upgrade-EJGTMW44.js.map} +0 -0
  216. /package/dist/{usage-KCXFY46V.js.map → usage-GZCQDULF.js.map} +0 -0
  217. /package/dist/{workflow-debug-RACNWWOL.js.map → utilities-RIITD53A.js.map} +0 -0
  218. /package/dist/{visual-GJZVJC32.js.map → visual-FH67OKS2.js.map} +0 -0
  219. /package/dist/{workflow-cache-PFBTWLGM.js.map → workflow-cache-YQ3BGJIG.js.map} +0 -0
  220. /package/dist/{workflow-cache-convergence-resolve-UZGRPC3B.js.map → workflow-cache-convergence-resolve-SPLBRSNK.js.map} +0 -0
  221. /package/dist/{workflow-feedback-RJIQ5R3R.js.map → workflow-feedback-6UOTIWIQ.js.map} +0 -0
  222. /package/dist/{workflow-fork-LINDCYJ3.js.map → workflow-fork-IDYHAHCX.js.map} +0 -0
  223. /package/dist/{workflow-proposals-E4EXKAGM.js.map → workflow-proposals-MMVNIQT3.js.map} +0 -0
  224. /package/dist/{workflow-revisions-5M6APN6R.js.map → workflow-revisions-BPUOLCZB.js.map} +0 -0
  225. /package/dist/{workflow-status-7KL73WS2.js.map → workflow-status-RA3IEMEW.js.map} +0 -0
@@ -0,0 +1,961 @@
1
+ import { createRequire as __cr } from "module"; import { fileURLToPath as __fup } from "url"; import { dirname as __dn } from "path"; const require = __cr(import.meta.url); const __filename = __fup(import.meta.url); const __dirname = __dn(__filename);
2
+ import {
3
+ RULES_PATH,
4
+ buildScheduleTriggerConfig
5
+ } from "./chunk-OQFCZERZ.js";
6
+ import "./chunk-LJFVRJCA.js";
7
+ import {
8
+ resolveApplicationId
9
+ } from "./chunk-JEHHEMUL.js";
10
+ import "./chunk-RVD6J6IZ.js";
11
+ import "./chunk-EJ3ZPH5U.js";
12
+ import "./chunk-DEK6B6LX.js";
13
+ import {
14
+ apiRequest,
15
+ getGuideSectionArg,
16
+ getPositionalArg,
17
+ getScalarArgValue
18
+ } from "./chunk-VKZOHJCE.js";
19
+ import "./chunk-S3Q7MDCS.js";
20
+ import "./chunk-4UZN6TVT.js";
21
+ import {
22
+ GLOBAL_VALUE_FLAGS,
23
+ hasFlag,
24
+ resolveConfig
25
+ } from "./chunk-WRBU6TX7.js";
26
+ import {
27
+ PERF_GUIDE_SECTIONS,
28
+ printGuide,
29
+ writeRawOutput
30
+ } from "./chunk-MJVUMVLO.js";
31
+ import "./chunk-TOWZAG3I.js";
32
+
33
+ // src/perf.ts
34
+ import { readFile } from "fs/promises";
35
+ import { dirname, resolve } from "path";
36
+ import { setTimeout as sleep } from "timers/promises";
37
+ import { parse } from "yaml";
38
+
39
+ // ../ids/src/registry.ts
40
+ var EntityPrefix = {
41
+ agentEval: "aeval",
42
+ agentEvalCase: "aecase",
43
+ agentEvalRun: "aerun",
44
+ agentEvalAttempt: "aeatt",
45
+ organization: "org",
46
+ workflow: "wf",
47
+ workflowTestExecution: "exec",
48
+ workflowTestRun: "trun",
49
+ workflowRun: "wrun",
50
+ adhocTest: "adhoc",
51
+ exploratoryTest: "expt",
52
+ perfTest: "ptest",
53
+ perfRun: "prun",
54
+ issue: "iss",
55
+ property: "prop",
56
+ credential: "cred",
57
+ credentialTemplate: "ctpl",
58
+ syntheticUniverse: "su",
59
+ syntheticUser: "sp",
60
+ syntheticUserRun: "sr",
61
+ userEvent: "uev",
62
+ userEventDashboard: "ued",
63
+ userEventDashboardCard: "uedc",
64
+ triageRun: "trg",
65
+ triageFinding: "trgf",
66
+ phoneNumber: "phn",
67
+ textMessage: "sms",
68
+ productArea: "parea",
69
+ productCapability: "pcap",
70
+ productCapabilityRule: "prule",
71
+ landingPage: "lp",
72
+ prReview: "prr",
73
+ digest: "dig",
74
+ explorationCycle: "excy",
75
+ explorationLead: "exld",
76
+ testSignInProvider: "tsp",
77
+ testSignInClient: "tsc",
78
+ testSignInGrant: "tsg",
79
+ pullRequestProofRecord: "proof"
80
+ };
81
+ var ENTITY_REGISTRY = {
82
+ aeval: { tableName: "agent_evals", orgIdColumn: "org_id", idColumn: "id" },
83
+ aecase: { tableName: "agent_eval_cases", orgIdColumn: "org_id", idColumn: "id" },
84
+ aerun: { tableName: "agent_eval_runs", orgIdColumn: "org_id", idColumn: "id" },
85
+ aeatt: { tableName: "agent_eval_attempts", orgIdColumn: "org_id", idColumn: "id" },
86
+ org: {
87
+ tableName: "organizations",
88
+ orgIdColumn: null,
89
+ idColumn: "id"
90
+ },
91
+ wf: {
92
+ tableName: "workflows",
93
+ orgIdColumn: "org_id",
94
+ idColumn: "id",
95
+ buildUrl: ({ prefixedId }) => `/flows/${prefixedId}`
96
+ },
97
+ exec: {
98
+ tableName: "workflow_test_executions",
99
+ orgIdColumn: "org_id",
100
+ idColumn: "id",
101
+ buildUrl: ({ prefixedId }) => `/runs/test/${prefixedId}`
102
+ },
103
+ trun: {
104
+ tableName: "workflow_test_runs",
105
+ orgIdColumn: "org_id",
106
+ idColumn: "id",
107
+ buildUrl: ({ parentPrefixedId }) => `/runs/test/${parentPrefixedId}`,
108
+ parentLookup: {
109
+ foreignKey: "execution_id",
110
+ parentPrefix: "exec"
111
+ }
112
+ },
113
+ wrun: {
114
+ tableName: "workflow_runs",
115
+ orgIdColumn: "org_id",
116
+ idColumn: "id"
117
+ // Needs propertyId parent — not yet implemented
118
+ },
119
+ adhoc: {
120
+ tableName: "adhoc_tests",
121
+ orgIdColumn: "org_id",
122
+ idColumn: "id",
123
+ buildUrl: ({ prefixedId }) => `/exploratory/${prefixedId}`
124
+ },
125
+ expt: {
126
+ tableName: "exploratory_tests",
127
+ orgIdColumn: "org_id",
128
+ idColumn: "id"
129
+ },
130
+ ptest: {
131
+ tableName: "perf_tests",
132
+ orgIdColumn: "org_id",
133
+ idColumn: "id"
134
+ },
135
+ prun: {
136
+ tableName: "perf_runs",
137
+ orgIdColumn: "org_id",
138
+ idColumn: "id"
139
+ },
140
+ iss: {
141
+ tableName: "issues",
142
+ orgIdColumn: "org_id",
143
+ idColumn: "id",
144
+ buildUrl: ({ prefixedId }) => `/issues?issueId=${prefixedId}`
145
+ },
146
+ prop: {
147
+ tableName: "org_properties",
148
+ orgIdColumn: "org_id",
149
+ idColumn: "id",
150
+ buildUrl: ({ prefixedId }) => `/properties/${prefixedId}`
151
+ },
152
+ cred: {
153
+ tableName: "org_property_credentials",
154
+ orgIdColumn: "org_id",
155
+ idColumn: "id"
156
+ },
157
+ ctpl: {
158
+ tableName: "credential_templates",
159
+ orgIdColumn: "org_id",
160
+ idColumn: "id"
161
+ },
162
+ su: {
163
+ tableName: "synthetic_universes",
164
+ orgIdColumn: "org_id",
165
+ idColumn: "id",
166
+ buildUrl: ({ prefixedId }) => `/synthetic-users/${prefixedId}`
167
+ },
168
+ sp: {
169
+ tableName: "synthetic_users",
170
+ orgIdColumn: "org_id",
171
+ idColumn: "id"
172
+ },
173
+ sr: {
174
+ tableName: "synthetic_user_runs",
175
+ orgIdColumn: "org_id",
176
+ idColumn: "id"
177
+ },
178
+ uev: {
179
+ tableName: "user_events",
180
+ orgIdColumn: "org_id",
181
+ idColumn: "id"
182
+ },
183
+ ued: {
184
+ tableName: "user_event_dashboards",
185
+ orgIdColumn: null,
186
+ idColumn: "id"
187
+ },
188
+ uedc: {
189
+ tableName: "user_event_dashboard_cards",
190
+ orgIdColumn: null,
191
+ idColumn: "id"
192
+ },
193
+ trg: {
194
+ tableName: "triage_runs",
195
+ orgIdColumn: "org_id",
196
+ idColumn: "id",
197
+ buildUrl: ({ parentPrefixedId }) => parentPrefixedId ? `/runs/test/${parentPrefixedId}?tab=triage` : "/runs/test",
198
+ parentLookup: {
199
+ foreignKey: "workflow_test_execution_id",
200
+ parentPrefix: "exec"
201
+ }
202
+ },
203
+ trgf: {
204
+ tableName: "triage_findings",
205
+ orgIdColumn: "org_id",
206
+ idColumn: "id"
207
+ },
208
+ phn: {
209
+ tableName: "messaging_phone_numbers",
210
+ orgIdColumn: "owner_org_id",
211
+ idColumn: "id"
212
+ },
213
+ sms: {
214
+ tableName: "text_messages",
215
+ orgIdColumn: "org_id",
216
+ idColumn: "id"
217
+ },
218
+ parea: {
219
+ tableName: "product_areas",
220
+ orgIdColumn: "org_id",
221
+ idColumn: "id",
222
+ buildUrl: ({ prefixedId }) => `/product-map?area=${prefixedId}`,
223
+ naturalCodePrefix: "ARE"
224
+ },
225
+ pcap: {
226
+ tableName: "product_capabilities",
227
+ orgIdColumn: "org_id",
228
+ idColumn: "id",
229
+ buildUrl: ({ prefixedId }) => `/product-map?capability=${prefixedId}`,
230
+ naturalCodePrefix: "CAP"
231
+ },
232
+ prule: {
233
+ tableName: "product_capability_rules",
234
+ orgIdColumn: "org_id",
235
+ idColumn: "id"
236
+ },
237
+ // No buildUrl: landing pages are authored from the CLI and served at
238
+ // runcofactor.com/lp/<slug> — there is no in-app detail route to link to.
239
+ //
240
+ // Deliberately NO `lpv` prefix for landing_page_variants. That table has no
241
+ // org_id column, and `orgIdColumn: null` does not mean "child table" here —
242
+ // resolveEntityOrg (apps/api/src/middleware/resolve-entity-org.ts) reads it
243
+ // as "the ID *is* the orgId" and compares the UUID against the caller's org,
244
+ // so a variant routed through the generic middleware would be rejected for
245
+ // the wrong reason. Variants are addressed by (page slug, variant name);
246
+ // add a prefix only together with real parent-resolving lookup support.
247
+ lp: {
248
+ tableName: "landing_pages",
249
+ orgIdColumn: "org_id",
250
+ idColumn: "id"
251
+ },
252
+ prr: {
253
+ tableName: "pr_reviews",
254
+ orgIdColumn: "org_id",
255
+ idColumn: "id",
256
+ buildUrl: ({ prefixedId }) => `/pr-reviews/${prefixedId}`
257
+ },
258
+ dig: {
259
+ tableName: "org_digests",
260
+ orgIdColumn: "org_id",
261
+ idColumn: "id",
262
+ buildUrl: ({ prefixedId }) => `/digests/${prefixedId}`
263
+ },
264
+ excy: {
265
+ tableName: "exploration_cycles",
266
+ orgIdColumn: "org_id",
267
+ idColumn: "id",
268
+ buildUrl: ({ prefixedId }) => `/explore/cycles/${prefixedId}`
269
+ },
270
+ exld: {
271
+ tableName: "exploration_leads",
272
+ orgIdColumn: "org_id",
273
+ idColumn: "id"
274
+ },
275
+ tsp: {
276
+ tableName: "test_sign_in_providers",
277
+ orgIdColumn: "org_id",
278
+ idColumn: "id"
279
+ },
280
+ tsc: {
281
+ tableName: "test_sign_in_clients",
282
+ orgIdColumn: "org_id",
283
+ idColumn: "id"
284
+ },
285
+ tsg: {
286
+ tableName: "test_sign_in_grants",
287
+ orgIdColumn: "org_id",
288
+ idColumn: "id"
289
+ },
290
+ proof: {
291
+ tableName: "pull_request_proof_records",
292
+ orgIdColumn: "org_id",
293
+ idColumn: "id",
294
+ buildUrl: ({ prefixedId }) => `/proofs/${prefixedId}`
295
+ }
296
+ };
297
+ Object.freeze(ENTITY_REGISTRY);
298
+ var SAFE_IDENT = /^[a-z_][a-z0-9_]*$/;
299
+ for (const [prefix, entry] of Object.entries(ENTITY_REGISTRY)) {
300
+ for (const field of [entry.tableName, entry.orgIdColumn, entry.idColumn].filter(
301
+ Boolean
302
+ )) {
303
+ if (!SAFE_IDENT.test(field)) {
304
+ throw new Error(`Invalid identifier in ENTITY_REGISTRY['${prefix}']: "${field}"`);
305
+ }
306
+ }
307
+ }
308
+ var VALID_PREFIXES = new Set(Object.keys(ENTITY_REGISTRY));
309
+
310
+ // ../ids/src/base58.ts
311
+ var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
312
+ var BASE = 58;
313
+ var ALPHABET_MAP = /* @__PURE__ */ new Map();
314
+ for (let i = 0; i < ALPHABET.length; i++) {
315
+ ALPHABET_MAP.set(ALPHABET[i], i);
316
+ }
317
+ function decodeBase58(str) {
318
+ if (str.length === 0) return new Uint8Array(0);
319
+ let leadingOnes = 0;
320
+ while (leadingOnes < str.length && str[leadingOnes] === ALPHABET[0]) {
321
+ leadingOnes++;
322
+ }
323
+ const bytes = [];
324
+ for (let i = leadingOnes; i < str.length; i++) {
325
+ const value = ALPHABET_MAP.get(str[i]);
326
+ if (value === void 0) return null;
327
+ let carry = value;
328
+ for (let j = 0; j < bytes.length; j++) {
329
+ carry += bytes[j] * BASE;
330
+ bytes[j] = carry & 255;
331
+ carry >>= 8;
332
+ }
333
+ while (carry > 0) {
334
+ bytes.push(carry & 255);
335
+ carry >>= 8;
336
+ }
337
+ }
338
+ const result = new Uint8Array(leadingOnes + bytes.length);
339
+ for (let i = 0; i < bytes.length; i++) {
340
+ result[leadingOnes + i] = bytes[bytes.length - 1 - i];
341
+ }
342
+ return result;
343
+ }
344
+
345
+ // ../ids/src/prefixed-id.ts
346
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
347
+ var PREFIXED_RE = /^([a-z]{2,6})_([1-9A-HJ-NP-Za-km-z]+)$/;
348
+ function bytesToUuid(bytes) {
349
+ const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
350
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
351
+ }
352
+ function decodePrefixedId(id) {
353
+ const match = id.match(PREFIXED_RE);
354
+ if (!match) return null;
355
+ const prefix = match[1];
356
+ if (!VALID_PREFIXES.has(prefix)) return null;
357
+ const decoded = decodeBase58(match[2]);
358
+ if (!decoded || decoded.length < 16 || decoded.length > 17) return null;
359
+ let normalized = decoded;
360
+ if (decoded.length === 17) {
361
+ if (decoded[0] !== 0) return null;
362
+ normalized = decoded.slice(1);
363
+ }
364
+ return { prefix, uuid: bytesToUuid(normalized) };
365
+ }
366
+ function parseAnyId(input) {
367
+ const decoded = decodePrefixedId(input);
368
+ if (decoded) return { kind: "prefixed", ...decoded };
369
+ if (UUID_RE.test(input)) return { kind: "raw_uuid", uuid: input.toLowerCase() };
370
+ return { kind: "invalid" };
371
+ }
372
+
373
+ // ../ids/src/entity-link.ts
374
+ var prefixAlternation = Object.values(EntityPrefix).sort((left, right) => right.length - left.length).join("|");
375
+ var BARE_ENTITY_ID = new RegExp(
376
+ `(^|[^A-Za-z0-9_])((?:${prefixAlternation})_[1-9A-HJ-NP-Za-km-z]+)(?![A-Za-z0-9_])`,
377
+ "g"
378
+ );
379
+
380
+ // ../ids/src/types.ts
381
+ function extractUuid(raw) {
382
+ if (!raw) return null;
383
+ const parsed = parseAnyId(raw);
384
+ if (parsed.kind === "prefixed") return parsed.uuid.toLowerCase();
385
+ if (parsed.kind === "raw_uuid") return parsed.uuid.toLowerCase();
386
+ return null;
387
+ }
388
+
389
+ // ../types/src/perf-config.ts
390
+ import { z } from "zod";
391
+ var k6Load = {
392
+ vus: z.number().int().min(1).max(200),
393
+ durationSeconds: z.number().int().min(10).max(300),
394
+ as: z.string().min(1).optional()
395
+ };
396
+ var estimatePerfSeconds = (config) => (config.rounds + 1) * ((config.lighthouse?.pages.length ?? 0) * 45 + (config.k6?.durationSeconds ?? 0) + 30) * 2 + 600;
397
+ var perfBase = {
398
+ rounds: z.number().int().min(5).max(15).default(7),
399
+ lighthouse: z.strictObject({
400
+ formFactor: z.enum(["desktop", "mobile"]),
401
+ pages: z.array(z.strictObject({
402
+ name: z.string().min(1).max(40).regex(/^[a-z0-9-]+$/),
403
+ path: z.string().startsWith("/").refine((path) => !path.startsWith("//"), "path must be relative, not protocol-relative").refine((path) => !path.includes("\\"), "path must not contain backslashes"),
404
+ as: z.string().min(1).optional()
405
+ })).min(1).max(10)
406
+ }).optional()
407
+ };
408
+ var withPerfRules = (schema) => schema.refine((config) => config.lighthouse !== void 0 || config.k6 !== void 0, {
409
+ message: "configure at least one of lighthouse or k6"
410
+ }).refine((config) => estimatePerfSeconds(config) <= 5400, {
411
+ message: "estimated run time exceeds 90 minutes; reduce rounds, pages or duration"
412
+ });
413
+ var PerfConfigSchema = withPerfRules(
414
+ z.strictObject({
415
+ ...perfBase,
416
+ k6: z.strictObject({ script: z.string().min(1), ...k6Load }).optional()
417
+ })
418
+ );
419
+ var StoredPerfConfigSchema = withPerfRules(
420
+ z.strictObject({
421
+ ...perfBase,
422
+ k6: z.strictObject({ scriptSource: z.string().min(1).max(2e5), ...k6Load }).optional()
423
+ })
424
+ );
425
+
426
+ // ../types/src/perf-result.ts
427
+ import { z as z2 } from "zod";
428
+ var PerfArmSchema = z2.enum(["base", "head"]);
429
+ var PerfVerdictSchema = z2.enum(["faster", "slower", "no_change"]);
430
+ var PerfRunStatusSchema = z2.enum(["queued", "running", "completed", "failed"]);
431
+ function usesAbsoluteDifference(row) {
432
+ return row.unit === "ratio" || row.base.values.includes(0);
433
+ }
434
+
435
+ // ../types/src/perf-round.ts
436
+ import { z as z3 } from "zod";
437
+ var RunnerConfigSchema = StoredPerfConfigSchema.safeExtend({
438
+ /** HTTPS URL for the claimed sandbox's public app port. */
439
+ baseUrl: z3.url({ protocol: /^https$/ }),
440
+ otelExpected: z3.boolean()
441
+ });
442
+ var LighthousePageRoundSchema = z3.strictObject({
443
+ name: z3.string().min(1),
444
+ lcpMs: z3.number().nonnegative(),
445
+ tbtMs: z3.number().nonnegative(),
446
+ fcpMs: z3.number().nonnegative(),
447
+ cls: z3.number().nonnegative(),
448
+ speedIndexMs: z3.number().nonnegative(),
449
+ bytes: z3.number().nonnegative(),
450
+ finalUrl: z3.string().min(1),
451
+ documentStatus: z3.number().int()
452
+ });
453
+ var K6RoundSchema = z3.strictObject({
454
+ p50Ms: z3.number().nonnegative(),
455
+ p95Ms: z3.number().nonnegative(),
456
+ requestsPerSecond: z3.number().nonnegative(),
457
+ errorRate: z3.number().nonnegative()
458
+ });
459
+ var OtelEndpointRoundSchema = z3.strictObject({
460
+ endpoint: z3.string().min(1),
461
+ count: z3.number().int().nonnegative(),
462
+ p50Ms: z3.number().nonnegative(),
463
+ p95Ms: z3.number().nonnegative()
464
+ });
465
+ var PerfRoundSlowSpanSchema = z3.strictObject({
466
+ name: z3.string().min(1),
467
+ count: z3.number().int().nonnegative(),
468
+ p95Ms: z3.number().nonnegative(),
469
+ totalMs: z3.number().nonnegative()
470
+ });
471
+ var RoundSummarySchema = z3.strictObject({
472
+ round: z3.number().int().positive(),
473
+ arm: PerfArmSchema,
474
+ lighthouse: z3.array(LighthousePageRoundSchema).optional(),
475
+ k6: K6RoundSchema.optional(),
476
+ otel: z3.strictObject({
477
+ endpoints: z3.array(OtelEndpointRoundSchema),
478
+ topSlowSpans: z3.array(PerfRoundSlowSpanSchema)
479
+ }).optional()
480
+ });
481
+
482
+ // ../types/src/perf-render.ts
483
+ function renderPerfResult(input) {
484
+ const heading = input.verdict === "slower" ? "SLOWER" : input.verdict === "faster" ? "faster" : "no change";
485
+ const visibleRows = input.result.rows.filter(
486
+ (row) => row.gated || row.flavor === "otel" && row.id.endsWith(":p95") && (row.base.values.length < input.result.rounds || row.head.values.length < input.result.rounds)
487
+ );
488
+ const omittedUngatedRows = input.result.rows.filter((row) => !visibleRows.includes(row));
489
+ const lines = [
490
+ `## Perf: ${heading} (head ${shortSha(input.headSha)} vs base ${shortSha(input.baseSha)}, ${input.result.rounds} rounds)`,
491
+ "",
492
+ "| Metric | Base | Head | Delta | 95% CI | Verdict |",
493
+ "|---|---|---|---|---|---|",
494
+ ...visibleRows.map((row) => renderRow(row, input.result.rounds))
495
+ ];
496
+ const ungated = omittedUngatedRows.length;
497
+ if (ungated > 0)
498
+ lines.push(
499
+ "",
500
+ `Not gated: ${ungated} more rows (${ungatedLabels(omittedUngatedRows)}). \`--json\` for all rows.`
501
+ );
502
+ const tools = [
503
+ input.result.tools.lighthouse && `lighthouse ${input.result.tools.lighthouse}`,
504
+ input.result.tools.k6 && `k6 ${input.result.tools.k6}`,
505
+ input.result.tools.otelcol && `otelcol-contrib ${input.result.tools.otelcol}`
506
+ ].filter((tool) => tool !== void 0);
507
+ if (ungated === 0) lines.push("");
508
+ lines.push(`Tools: ${tools.length > 0 ? tools.join(", ") : "none"}. Run: ${input.id}.`);
509
+ if (input.verdict === "slower" && input.result.otel) {
510
+ lines.push(
511
+ "",
512
+ "### Slowest server spans (head)",
513
+ "",
514
+ ...renderSpans(input.result.otel.topSlowSpans.head.slice(0, 5))
515
+ );
516
+ const baseByName = new Map(
517
+ input.result.otel.topSlowSpans.base.map((span) => [span.name, span])
518
+ );
519
+ const slower = input.result.otel.topSlowSpans.head.filter((span) => {
520
+ const base = baseByName.get(span.name);
521
+ return !base || span.p95Ms > base.p95Ms;
522
+ });
523
+ if (slower.length > 0)
524
+ lines.push("", "### New or slower than base", "", ...renderSpans(slower));
525
+ }
526
+ return lines.join("\n");
527
+ }
528
+ function ungatedLabels(rows) {
529
+ const labels = rows.map((row) => {
530
+ if (row.id.endsWith(":fcp")) return "FCP";
531
+ if (row.id.endsWith(":cls")) return "CLS";
532
+ if (row.id.endsWith(":speed-index")) return "speed index";
533
+ if (row.id.endsWith(":bytes")) return "bytes";
534
+ if (row.id.endsWith(":p50")) return "p50s";
535
+ return row.label;
536
+ });
537
+ const order = ["FCP", "CLS", "speed index", "bytes", "p50s"];
538
+ const standard = order.filter((label) => labels.includes(label));
539
+ const extra = [...new Set(labels.filter((label) => !order.includes(label)))];
540
+ return [...standard, ...extra].join(", ");
541
+ }
542
+ function renderRow(row, rounds) {
543
+ const sparseEndpoint = row.flavor === "otel" && row.id.endsWith(":p95") && (row.base.values.length < rounds || row.head.values.length < rounds);
544
+ const verdict = row.verdict === "slower" ? "SLOWER" : row.verdict.replace("_", " ");
545
+ const label = sparseEndpoint ? `${row.label} (not gated)` : row.label;
546
+ return `| ${escapeCell(label)} | ${formatArmValue(row.base, row.unit)} | ${formatArmValue(row.head, row.unit)} | ${formatDelta(row)} | ${formatInterval(row)} | ${verdict} |`;
547
+ }
548
+ function formatArmValue(arm, unit) {
549
+ return arm.values.length === 0 ? "-" : formatValue(arm.median, unit);
550
+ }
551
+ function formatValue(value, unit) {
552
+ switch (unit) {
553
+ case "ms":
554
+ return `${round(value)} ms`;
555
+ case "rps":
556
+ return `${round(value)}`;
557
+ case "ratio":
558
+ return `${(value * 100).toFixed(1)}%`;
559
+ case "bytes":
560
+ return `${round(value)} bytes`;
561
+ case "count":
562
+ return `${round(value)}`;
563
+ }
564
+ }
565
+ function formatDelta(row) {
566
+ const missingBase = row.base.values.length === 0;
567
+ const missingHead = row.head.values.length === 0;
568
+ if (missingBase) return "new";
569
+ if (missingHead) return "removed";
570
+ if (row.unit === "ratio") return `${signed(row.deltaPct, 1)} pt`;
571
+ const displayedDelta = row.unit === "rps" ? -row.deltaPct : row.deltaPct;
572
+ if (usesAbsoluteDifference(row)) {
573
+ return `${signed(displayedDelta, 0)}${unitSuffix(row.unit)}`;
574
+ }
575
+ return `${signed(displayedDelta * 100, 1)}%`;
576
+ }
577
+ function formatInterval(row) {
578
+ const missingBase = row.base.values.length === 0;
579
+ const missingHead = row.head.values.length === 0;
580
+ if (missingBase || missingHead) return "-";
581
+ const absolute = usesAbsoluteDifference(row);
582
+ const suffix = row.unit === "ratio" ? " pt" : absolute ? unitSuffix(row.unit) : "%";
583
+ const scale = row.unit === "ratio" || absolute ? 1 : 100;
584
+ const precision = suffix === "%" || row.unit === "ratio" ? 1 : 0;
585
+ const lowerBound = row.unit === "rps" ? -row.ci95[1] : row.ci95[0];
586
+ const upperBound = row.unit === "rps" ? -row.ci95[0] : row.ci95[1];
587
+ const lower = signed(lowerBound * scale, precision);
588
+ const upper = signed(upperBound * scale, precision);
589
+ return suffix === "%" ? `${lower}% .. ${upper}%` : `${lower} .. ${upper}${suffix}`;
590
+ }
591
+ function unitSuffix(unit) {
592
+ switch (unit) {
593
+ case "ms":
594
+ return " ms";
595
+ case "rps":
596
+ return " rps";
597
+ case "ratio":
598
+ return " pt";
599
+ case "bytes":
600
+ return " bytes";
601
+ case "count":
602
+ return "";
603
+ }
604
+ }
605
+ function renderSpans(spans) {
606
+ if (spans.length === 0) return ["No server spans."];
607
+ return [
608
+ "| Name | Count | Worst round p95 | Total duration |",
609
+ "|---|---:|---:|---:|",
610
+ ...spans.map(
611
+ (span) => `| ${escapeCell(span.name)} | ${span.count} | ${round(span.p95Ms)} ms | ${round(span.totalMs)} ms |`
612
+ )
613
+ ];
614
+ }
615
+ function shortSha(sha) {
616
+ return sha.slice(0, 7);
617
+ }
618
+ function signed(value, precision = 1) {
619
+ const rounded = Number(value.toFixed(precision));
620
+ return `${rounded >= 0 ? "+" : ""}${rounded.toFixed(precision)}`;
621
+ }
622
+ function round(value) {
623
+ return Number(value.toFixed(1));
624
+ }
625
+ function escapeCell(value) {
626
+ return value.replaceAll("|", "\\|").replaceAll("\n", " ");
627
+ }
628
+
629
+ // src/perf.ts
630
+ var TESTS = "/org/perf/tests";
631
+ var RUNS = "/org/perf/runs";
632
+ var ACTION = "perf-test.run";
633
+ var TIMING_FLAGS = ["--schedule", "--cron", "--at", "--every", "--timezone"];
634
+ var VALUE_FLAGS = [
635
+ ...GLOBAL_VALUE_FLAGS,
636
+ ...TIMING_FLAGS,
637
+ "--config",
638
+ "--application",
639
+ "--environment",
640
+ "--test",
641
+ "--base",
642
+ "--head",
643
+ "--name",
644
+ "--limit"
645
+ ];
646
+ var USAGE = {
647
+ run: "run (--config perf.yaml --application <app> [--environment E] | --test <name|id>) [--base <version>] --head <version>",
648
+ save: "save --config perf.yaml --name <n> --application <app> [--environment E] [--on-merge] [<timing flag>]",
649
+ guide: "guide",
650
+ list: "list",
651
+ get: "get <test-name|ptest_id|prun_id>",
652
+ runs: "runs <test-name|ptest_id> [--limit N]",
653
+ delete: "delete <test-name|ptest_id>"
654
+ };
655
+ function printHelp(command) {
656
+ const usage = Object.hasOwn(USAGE, command ?? "") ? USAGE[command] : void 0;
657
+ console.log(
658
+ [
659
+ `Usage: cofactor perf ${usage ?? "<sub-command>"} [--json]`,
660
+ "",
661
+ ...Object.values(USAGE).map((line) => ` cofactor perf ${line}`),
662
+ "",
663
+ "guide: prints the offline performance-test guide (no login needed).",
664
+ "run: validates YAML, inlines k6.script relative to perf.yaml, and waits for the run.",
665
+ " --head and --base take a commit SHA, a push id or a tag.",
666
+ " Base defaults to the environment head for GitHub apps, or the ready push before head for uploaded apps.",
667
+ " Polls every 5 seconds for at most 4 hours. A timeout leaves the run available via get.",
668
+ "save: replaces the test and its schedule by name. Without a timing flag or --on-merge, it is manual.",
669
+ " --on-merge runs the test for merges into the repository default branch (GitHub applications only).",
670
+ " Leaving --on-merge off clears the marker.",
671
+ " One timing flag: --schedule <text> | --cron <expr> | --at <HH:mm> | --every <30m|2h>",
672
+ " --timezone <zone> applies to the schedule (default UTC).",
673
+ " Scheduling requires the server automation action perf-test.run.",
674
+ "list: saved tests. get: a prun_ id selects a run; a ptest_ id or name selects a test.",
675
+ "runs: recent runs for a test, newest first; --limit defaults to 20 (1..100).",
676
+ "delete: deletes the test, its automation rules, and its runs (API cascade).",
677
+ "",
678
+ "Common options:",
679
+ " --org <name|id> Logged-in organization; required explicitly for run, save, delete",
680
+ " --env <env> API environment (prod, dev, local); distinct from --environment",
681
+ " --api-url <url> API URL override",
682
+ " --token <key> API token override",
683
+ " --json Raw JSON on every sub-command; runs flatten PerfResult into run metadata",
684
+ " --help, -h Show help without authentication",
685
+ "",
686
+ "Requires the sandbox-v2 organization flag. API-key scopes:",
687
+ " run/save: sandbox:create + sandbox:exec; run/get/runs reads: sandbox:read; delete: sandbox:edit.",
688
+ " save/list/delete also use automation rules routes and require full API-key access (*).",
689
+ "",
690
+ "Exit codes (run):",
691
+ " 0 no_change or faster",
692
+ " 3 slower",
693
+ " 1 Failed run, polling timeout, or any error",
694
+ "Other sub-commands exit 0 on success, 1 on error."
695
+ ].join("\n")
696
+ );
697
+ }
698
+ function required(argv, flag) {
699
+ const value = getScalarArgValue(argv, flag);
700
+ if (!value) throw new Error(`${flag} is required.`);
701
+ return value;
702
+ }
703
+ async function readConfig(file) {
704
+ const config = PerfConfigSchema.parse(parse(await readFile(file, "utf8")));
705
+ const { k6, ...rest } = config;
706
+ if (!k6) return StoredPerfConfigSchema.parse(rest);
707
+ const { script, ...load } = k6;
708
+ const scriptSource = await readFile(resolve(dirname(file), script), "utf8");
709
+ return StoredPerfConfigSchema.parse({ ...rest, k6: { ...load, scriptSource } });
710
+ }
711
+ async function request(apiUrl, token, method, path, body) {
712
+ const response = await apiRequest(apiUrl, token, method, path, body);
713
+ if (!response.ok || response.data === void 0) {
714
+ throw new Error(
715
+ `${response.code ? `${response.code}: ` : ""}${response.error ?? `${method} ${path} failed`}`
716
+ );
717
+ }
718
+ return response.data;
719
+ }
720
+ async function resolveTest(apiUrl, token, name) {
721
+ if (name.startsWith("ptest_"))
722
+ return request(apiUrl, token, "GET", `${TESTS}/${encodeURIComponent(name)}`);
723
+ const tests = await request(apiUrl, token, "GET", TESTS);
724
+ const test = tests.find((test2) => test2.name === name);
725
+ if (!test) throw new Error(`Perf test "${name}" not found.`);
726
+ return test;
727
+ }
728
+ function testUuid(test) {
729
+ const id = extractUuid(test.id);
730
+ if (!id) throw new Error(`Invalid perf test id: ${test.id}`);
731
+ return id;
732
+ }
733
+ async function listRules(apiUrl, token) {
734
+ const rules = [];
735
+ let page = 1;
736
+ let totalPages;
737
+ do {
738
+ const response = await apiRequest(apiUrl, token, "GET", `${RULES_PATH}?actionType=${ACTION}&pageSize=100&page=${page}`);
739
+ if (!response.ok || !response.data)
740
+ throw new Error(response.error ?? "Could not list perf automation rules.");
741
+ rules.push(...response.data);
742
+ totalPages = response.pagination.totalPages;
743
+ page++;
744
+ } while (page <= totalPages);
745
+ return rules;
746
+ }
747
+ function rulesForTest(rules, test) {
748
+ const id = testUuid(test);
749
+ return rules.filter((rule) => rule.actionConfig.perf_test_id === id);
750
+ }
751
+ async function deletePaths(paths, apiUrl, token) {
752
+ for (const path of paths) {
753
+ const response = await apiRequest(
754
+ apiUrl,
755
+ token,
756
+ "DELETE",
757
+ path
758
+ );
759
+ if (!response.ok) throw new Error(response.error ?? `DELETE ${path} failed`);
760
+ }
761
+ }
762
+ function printRun(run2, json) {
763
+ if (json) {
764
+ const { result, ...metadata } = run2;
765
+ writeRawOutput(JSON.stringify({ ...metadata, ...result, rows: result?.rows ?? [] }, null, 2));
766
+ } else if (run2.status === "completed" && run2.result && run2.verdict) {
767
+ writeRawOutput(renderPerfResult({ ...run2, result: run2.result, verdict: run2.verdict }));
768
+ } else {
769
+ writeRawOutput(`${run2.id} ${run2.status}${run2.error ? ` ${run2.error}` : ""}`);
770
+ }
771
+ }
772
+ async function run(argv, apiUrl, token) {
773
+ const configFile = getScalarArgValue(argv, "--config");
774
+ const test = getScalarArgValue(argv, "--test");
775
+ if (Boolean(configFile) === Boolean(test))
776
+ throw new Error("Use exactly one of --config or --test.");
777
+ if (test && (getScalarArgValue(argv, "--application") || getScalarArgValue(argv, "--environment"))) {
778
+ throw new Error("--application and --environment are only valid with --config.");
779
+ }
780
+ const head = required(argv, "--head");
781
+ const base = getScalarArgValue(argv, "--base");
782
+ const target = test ? { perfTestId: (await resolveTest(apiUrl, token, test)).id } : {
783
+ config: await readConfig(configFile),
784
+ applicationId: await resolveApplicationId(argv, apiUrl, token),
785
+ environment: getScalarArgValue(argv, "--environment")
786
+ };
787
+ const { id } = await request(apiUrl, token, "POST", RUNS, {
788
+ ...target,
789
+ head,
790
+ ...base ? { base } : {}
791
+ });
792
+ const deadline = Date.now() + 4 * 60 * 60 * 1e3;
793
+ while (Date.now() < deadline) {
794
+ const current = await request(
795
+ apiUrl,
796
+ token,
797
+ "GET",
798
+ `${RUNS}/${encodeURIComponent(id)}`
799
+ );
800
+ if (current.status === "failed") {
801
+ printRun(current, hasFlag(argv, "--json"));
802
+ return 1;
803
+ }
804
+ if (current.status === "completed") {
805
+ if (!current.result || !current.verdict)
806
+ throw new Error(`Completed perf run ${id} has no result or verdict.`);
807
+ printRun(current, hasFlag(argv, "--json"));
808
+ return current.verdict === "slower" ? 3 : 0;
809
+ }
810
+ await sleep(5e3);
811
+ }
812
+ throw new Error(`Timed out waiting for ${id}. Inspect it with cofactor perf get ${id}.`);
813
+ }
814
+ async function save(argv, apiUrl, token) {
815
+ const name = required(argv, "--name");
816
+ const config = await readConfig(required(argv, "--config"));
817
+ const applicationId = await resolveApplicationId(argv, apiUrl, token);
818
+ const triggerConfig = await buildScheduleTriggerConfig(argv, apiUrl, token);
819
+ const test = await request(apiUrl, token, "POST", TESTS, {
820
+ name,
821
+ config,
822
+ applicationId,
823
+ environment: getScalarArgValue(argv, "--environment"),
824
+ ...hasFlag(argv, "--on-merge") ? { onMerge: true } : {}
825
+ });
826
+ const rules = rulesForTest(await listRules(apiUrl, token), test);
827
+ await deletePaths(
828
+ rules.map((rule2) => `${RULES_PATH}/${encodeURIComponent(rule2.id)}`),
829
+ apiUrl,
830
+ token
831
+ );
832
+ let rule;
833
+ if (triggerConfig) {
834
+ const response = await apiRequest(
835
+ apiUrl,
836
+ token,
837
+ "POST",
838
+ RULES_PATH,
839
+ {
840
+ name,
841
+ enabled: true,
842
+ triggerSource: "schedule",
843
+ triggerEvent: "scheduled",
844
+ triggerConfig,
845
+ actionType: ACTION,
846
+ actionConfig: { perf_test_id: testUuid(test) }
847
+ }
848
+ );
849
+ if (!response.ok || !response.data) {
850
+ throw new Error(
851
+ `Saved ${test.id}, but could not create its schedule: ${response.error ?? "rule creation failed"}`
852
+ );
853
+ }
854
+ rule = response.data;
855
+ }
856
+ if (hasFlag(argv, "--json"))
857
+ writeRawOutput(JSON.stringify({ ...test, ...rule ? { rule } : {} }, null, 2));
858
+ else writeRawOutput(`Saved ${test.id} ${test.name}${rule ? ` schedule ${rule.id}` : ""}`);
859
+ }
860
+ async function remove(test, apiUrl, token) {
861
+ const rules = rulesForTest(await listRules(apiUrl, token), test);
862
+ await deletePaths(
863
+ [
864
+ `${TESTS}/${encodeURIComponent(test.id)}`,
865
+ ...rules.map((rule) => `${RULES_PATH}/${encodeURIComponent(rule.id)}`)
866
+ ],
867
+ apiUrl,
868
+ token
869
+ );
870
+ }
871
+ async function runPerf(argv) {
872
+ const [command, ...rest] = argv;
873
+ if (!command || command === "help" || hasFlag(argv, "--help", "-h")) {
874
+ printHelp(command);
875
+ return;
876
+ }
877
+ if (command === "guide") {
878
+ printGuide(PERF_GUIDE_SECTIONS, getGuideSectionArg(rest), hasFlag(rest, "--json"));
879
+ return;
880
+ }
881
+ let code = 0;
882
+ try {
883
+ if (!Object.hasOwn(USAGE, command)) throw new Error(`Unknown perf command: ${command}`);
884
+ if (["run", "save", "delete"].includes(command)) required(rest, "--org");
885
+ for (const flag of VALUE_FLAGS) {
886
+ const value = getScalarArgValue(rest, flag);
887
+ if (rest.includes(flag) && value === void 0) throw new Error(`${flag} requires a value.`);
888
+ }
889
+ const { apiUrl, token } = await resolveConfig(rest);
890
+ const json = hasFlag(rest, "--json");
891
+ if (command === "run") code = await run(rest, apiUrl, token);
892
+ else if (command === "save") await save(rest, apiUrl, token);
893
+ else if (command === "list") {
894
+ const [tests, rules] = await Promise.all([
895
+ request(apiUrl, token, "GET", TESTS),
896
+ listRules(apiUrl, token)
897
+ ]);
898
+ const listed = tests.map((test) => ({
899
+ ...test,
900
+ schedules: rulesForTest(rules, test)
901
+ }));
902
+ writeRawOutput(
903
+ json ? JSON.stringify(listed, null, 2) : listed.map((test) => {
904
+ const schedules = test.schedules.map(
905
+ (rule) => `${rule.id} [${rule.enabled ? "enabled" : "paused"}] ${JSON.stringify(rule.triggerConfig)}`
906
+ ).join("; ");
907
+ const modes = [
908
+ ...test.onMerge ? ["on-merge"] : [],
909
+ ...schedules ? [schedules] : []
910
+ ];
911
+ return `${test.id} ${test.name} ${test.environment} ${modes.join(" ") || "manual"}`;
912
+ }).join("\n") || "No perf tests found."
913
+ );
914
+ } else {
915
+ const target = getPositionalArg(rest, VALUE_FLAGS);
916
+ if (!target) throw new Error(`Usage: cofactor perf ${USAGE[command]}`);
917
+ if (command === "get" && target.startsWith("prun_")) {
918
+ printRun(
919
+ await request(apiUrl, token, "GET", `${RUNS}/${encodeURIComponent(target)}`),
920
+ json
921
+ );
922
+ } else {
923
+ const test = await resolveTest(apiUrl, token, target);
924
+ if (command === "get")
925
+ writeRawOutput(
926
+ json ? JSON.stringify(test, null, 2) : `${test.id} ${test.name}
927
+ on-merge: ${test.onMerge}
928
+ ${JSON.stringify(test.config, null, 2)}`
929
+ );
930
+ else if (command === "delete") {
931
+ await remove(test, apiUrl, token);
932
+ writeRawOutput(
933
+ json ? JSON.stringify({ id: test.id, deleted: true }) : `Deleted ${test.id}`
934
+ );
935
+ } else {
936
+ const limit = getScalarArgValue(rest, "--limit") ?? "20";
937
+ if (!/^\d+$/.test(limit) || Number(limit) < 1 || Number(limit) > 100)
938
+ throw new Error("--limit must be an integer from 1 to 100.");
939
+ const query = new URLSearchParams({ perfTestId: test.id, limit });
940
+ const page = await request(
941
+ apiUrl,
942
+ token,
943
+ "GET",
944
+ `${RUNS}?${query}`
945
+ );
946
+ writeRawOutput(
947
+ json ? JSON.stringify(page, null, 2) : page.items.map((run2) => `${run2.id} ${run2.status} ${run2.verdict ?? "-"} ${run2.headSha}`).join("\n") || "No perf runs found."
948
+ );
949
+ }
950
+ }
951
+ }
952
+ } catch (error) {
953
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
954
+ code = 1;
955
+ }
956
+ if (code !== 0) process.exit(code);
957
+ }
958
+ export {
959
+ runPerf
960
+ };
961
+ //# sourceMappingURL=perf-CCHWHCSR.js.map