@runcofactor/cli 0.54.0 → 0.56.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 (253) hide show
  1. package/README.md +2 -1
  2. package/dist/{account-6YJAU53I.js → account-CZYZD2JS.js} +5 -5
  3. package/dist/{alert-Z7V2ZUEW.js → alert-JQ4SDEB7.js} +8 -8
  4. package/dist/{api-catalog-UEDTRM6E.js → api-catalog-IWQC35P2.js} +5 -5
  5. package/dist/{api-key-V5GEPRRG.js → api-key-GUDXIIEA.js} +5 -5
  6. package/dist/{attachment-M7VZ6GSE.js → attachment-CPZYOBUB.js} +5 -5
  7. package/dist/{auth-DVTMWJKF.js → auth-DS6MBVEI.js} +3 -3
  8. package/dist/{benchmark-KZJZYUTQ.js → benchmark-6HPCIQHD.js} +5 -5
  9. package/dist/{blackcat-QJXYDE66.js → blackcat-V3L63WFE.js} +3 -3
  10. package/dist/{chunk-FLDIN6VX.js → chunk-2E3STBHS.js} +2 -2
  11. package/dist/{chunk-KNWKOKM7.js → chunk-2OHYMT3A.js} +20 -11
  12. package/dist/chunk-2OHYMT3A.js.map +1 -0
  13. package/dist/{chunk-L4Y5PZUE.js → chunk-3LGCHNBC.js} +2 -2
  14. package/dist/{chunk-ZFN5FWN2.js → chunk-4MFMPC5P.js} +46 -2
  15. package/dist/chunk-4MFMPC5P.js.map +1 -0
  16. package/dist/{chunk-2M4PZK6Q.js → chunk-56HFZHQM.js} +8 -8
  17. package/dist/{chunk-AQOHNAEN.js → chunk-5OYWNS6D.js} +20 -9
  18. package/dist/chunk-5OYWNS6D.js.map +1 -0
  19. package/dist/{chunk-RA2NRAWU.js → chunk-62EXS76C.js} +6 -6
  20. package/dist/{chunk-HGEJHS45.js → chunk-6ILWJFKY.js} +368 -6
  21. package/dist/chunk-6ILWJFKY.js.map +1 -0
  22. package/dist/{chunk-4EWSONHO.js → chunk-BDOL622T.js} +4 -4
  23. package/dist/{chunk-T6EQFICG.js → chunk-C3CXVX2B.js} +4 -4
  24. package/dist/{chunk-33U56YGD.js → chunk-CWICLBLU.js} +2 -1
  25. package/dist/{chunk-33U56YGD.js.map → chunk-CWICLBLU.js.map} +1 -1
  26. package/dist/{chunk-MQQCUU5S.js → chunk-DEVD2WD2.js} +2 -2
  27. package/dist/{chunk-TRC63RSK.js → chunk-EWK44F6V.js} +3 -3
  28. package/dist/chunk-EWK44F6V.js.map +1 -0
  29. package/dist/{chunk-Q7UAEFW5.js → chunk-FNHPTTRF.js} +7 -5
  30. package/dist/chunk-FNHPTTRF.js.map +1 -0
  31. package/dist/{chunk-JAIMLQOU.js → chunk-GCD4EHCD.js} +6 -6
  32. package/dist/{chunk-7MRZWPVC.js → chunk-H6ZMKNP7.js} +3 -3
  33. package/dist/{chunk-ZOPVBINJ.js → chunk-IEWAH7W3.js} +5 -5
  34. package/dist/{chunk-74TU6PGO.js → chunk-IV4HRGKX.js} +77 -12
  35. package/dist/chunk-IV4HRGKX.js.map +1 -0
  36. package/dist/{chunk-ZO5MSM4Q.js → chunk-J2ZQULU3.js} +2 -2
  37. package/dist/{chunk-IVWWYKAM.js → chunk-K2IDR6FR.js} +3 -3
  38. package/dist/{chunk-QGP67JOK.js → chunk-KTZRI27M.js} +4 -4
  39. package/dist/{chunk-HESV3F6U.js → chunk-L644NMDI.js} +3 -3
  40. package/dist/{chunk-HESV3F6U.js.map → chunk-L644NMDI.js.map} +1 -1
  41. package/dist/{chunk-LPQTXBJF.js → chunk-LFT7GUWS.js} +63 -17
  42. package/dist/chunk-LFT7GUWS.js.map +1 -0
  43. package/dist/{chunk-O7MBDOMO.js → chunk-O7B2IYCZ.js} +30 -14
  44. package/dist/chunk-O7B2IYCZ.js.map +1 -0
  45. package/dist/{chunk-R2CVV7QT.js → chunk-RHWPZKRV.js} +28 -1
  46. package/dist/chunk-RHWPZKRV.js.map +1 -0
  47. package/dist/{chunk-3YNR6U6Q.js → chunk-UJSW72LG.js} +3 -3
  48. package/dist/{chunk-G2SCV2CY.js → chunk-VACACCD6.js} +3 -3
  49. package/dist/{chunk-CV22445U.js → chunk-VMAR67FF.js} +2 -2
  50. package/dist/{chunk-QYHJUHL7.js → chunk-VMJ7TBVM.js} +2 -2
  51. package/dist/chunk-WRRA4ATV.js +332 -0
  52. package/dist/chunk-WRRA4ATV.js.map +1 -0
  53. package/dist/{chunk-YACDH6MJ.js → chunk-XHEVDABB.js} +2 -2
  54. package/dist/{chunk-7VBX2M4F.js → chunk-XHGF6VC6.js} +4 -4
  55. package/dist/{credential-546ER7WQ.js → credential-GJW7LGYP.js} +5 -5
  56. package/dist/{credential-template-BWMEBGBN.js → credential-template-UWBYKKWD.js} +5 -5
  57. package/dist/dev-PBW7BSOD.js +605 -0
  58. package/dist/dev-PBW7BSOD.js.map +1 -0
  59. package/dist/{digest-NIVBDDI2.js → digest-XEHGCJM4.js} +8 -8
  60. package/dist/{docs-AK4MDP6K.js → docs-KH4BCEQF.js} +5 -5
  61. package/dist/{doctor-NCLA47EL.js → doctor-FOXXE5SK.js} +3 -3
  62. package/dist/{environment-X3PV5IN2.js → environment-EBDPQTIS.js} +7 -7
  63. package/dist/{eval-5FZKYZ6O.js → eval-QZSSEICV.js} +67 -27
  64. package/dist/eval-QZSSEICV.js.map +1 -0
  65. package/dist/{exploration-2RVGIUKT.js → exploration-LCGKRGOQ.js} +5 -5
  66. package/dist/{exploratory-test-SJ5HFI3L.js → exploratory-test-SGECQGIX.js} +13 -5
  67. package/dist/exploratory-test-SGECQGIX.js.map +1 -0
  68. package/dist/{external-run-4NDVAHQB.js → external-run-2AJAI5O7.js} +9 -9
  69. package/dist/{feature-flag-C4IRE724.js → feature-flag-P7N4WQIH.js} +5 -5
  70. package/dist/{feedback-337OZCKC.js → feedback-LAT7TQ2T.js} +6 -6
  71. package/dist/{flow-D7ZLBKCH.js → flow-NH2DC6AP.js} +5 -5
  72. package/dist/{github-LKXYIALH.js → github-FCEKBLXI.js} +6 -6
  73. package/dist/index.js +106 -408
  74. package/dist/index.js.map +1 -1
  75. package/dist/{init-GKEC6LPH.js → init-5U5EZOAW.js} +5 -5
  76. package/dist/{install-K45SAT2V.js → install-X3UNVXKY.js} +5 -5
  77. package/dist/{issues-2HMTQYWR.js → issues-4P6I3YQW.js} +8 -8
  78. package/dist/{knobs-KUCGLO5Z.js → knobs-JKTWJ6ZG.js} +5 -5
  79. package/dist/{landing-KAET2I73.js → landing-6AGLKI66.js} +7 -7
  80. package/dist/{list-GDV4UYWV.js → list-TWP2RP33.js} +5 -5
  81. package/dist/{local-NFOSJLLV.js → local-D75QE5TB.js} +7 -7
  82. package/dist/{login-Y77HWROY.js → login-RBET4TIP.js} +5 -5
  83. package/dist/{mcp-CPCFMU6B.js → mcp-562SUUMK.js} +11 -11
  84. package/dist/{metrics-Y245ST63.js → metrics-4WF2GEPA.js} +5 -5
  85. package/dist/{monitor-BUDWSC3S.js → monitor-WJXH54H2.js} +5 -5
  86. package/dist/{perf-3JOAXPHP.js → perf-C6N6P7YG.js} +12 -361
  87. package/dist/perf-C6N6P7YG.js.map +1 -0
  88. package/dist/{product-CXL3YTMD.js → product-CYEQ7HOB.js} +5 -5
  89. package/dist/{product-map-656BTU74.js → product-map-MSDLIFZY.js} +7 -7
  90. package/dist/{prompts-3SZ7O5E6.js → prompts-ME53WPN4.js} +5 -5
  91. package/dist/{proofs-4CSCCSNL.js → proofs-D3G6ZUFP.js} +11 -9
  92. package/dist/{property-IEKBXRVY.js → property-5GLJNAVB.js} +29 -10
  93. package/dist/property-5GLJNAVB.js.map +1 -0
  94. package/dist/{psql-M4CM6TSI.js → psql-EXAUDU3W.js} +5 -5
  95. package/dist/{record-QP4TYZBS.js → record-EE7NGNKY.js} +6 -6
  96. package/dist/{redis-KG47IGJV.js → redis-M4EYWKOJ.js} +5 -5
  97. package/dist/{release-QHPSQULK.js → release-4KUWVWWC.js} +5 -5
  98. package/dist/{runbook-YVBG2QK3.js → runbook-AHU77ANQ.js} +5 -5
  99. package/dist/{sandbox-ZXDZTCCN.js → sandbox-FBLJEYA2.js} +1917 -1633
  100. package/dist/sandbox-FBLJEYA2.js.map +1 -0
  101. package/dist/{scenarios-2SX2NUCD.js → scenarios-TU656T2B.js} +5 -5
  102. package/dist/{schedule-P6F7MLXX.js → schedule-DXJI6SYO.js} +8 -8
  103. package/dist/{session-SZMCZTPE.js → session-RUFTJHF4.js} +10 -10
  104. package/dist/{skill-D4XFW6QI.js → skill-ZK76GQ47.js} +111 -13
  105. package/dist/skill-ZK76GQ47.js.map +1 -0
  106. package/dist/skills/cofactor-debug-run/SKILL.md +6 -1
  107. package/dist/skills/cofactor-debug-run/history/2.0.10.md +320 -0
  108. package/dist/skills/cofactor-debug-run/history/2.0.9.md +319 -0
  109. package/dist/skills/cofactor-debug-run/version.json +1 -1
  110. package/dist/{slack-UDXTPOSW.js → slack-M3OKDVMY.js} +6 -6
  111. package/dist/{spec-YCBBIV27.js → spec-5MXEBLYR.js} +5 -5
  112. package/dist/{src-DY7GLRO2.js → src-2X5OQRPJ.js} +4 -4
  113. package/dist/{src-NG7DRE5A.js → src-72EFBA2R.js} +3 -3
  114. package/dist/{src-DEGBASCD.js → src-KH6WSBJV.js} +5 -5
  115. package/dist/{src-ZKVNVLXY.js → src-VLV36QYH.js} +127 -20
  116. package/dist/src-VLV36QYH.js.map +1 -0
  117. package/dist/{start-ZYZSORPY.js → start-PDYBRB5T.js} +5 -5
  118. package/dist/{status-ESIG6A7W.js → status-VMVPVCDA.js} +5 -5
  119. package/dist/{tag-3K5Y25AR.js → tag-7KTDLPVU.js} +6 -6
  120. package/dist/{task-JLNX7O3M.js → task-QLFYZNKR.js} +6 -6
  121. package/dist/{teams-F4IU3EXE.js → teams-Y7BXCY6P.js} +7 -7
  122. package/dist/{test-suite-QHDUW5W5.js → test-suite-6U22AYFG.js} +15 -14
  123. package/dist/test-suite-6U22AYFG.js.map +1 -0
  124. package/dist/{tickets-NBL5WACL.js → tickets-CQDJDNPY.js} +5 -5
  125. package/dist/{trace-ZKYAI5JF.js → trace-QDORWXYX.js} +8 -8
  126. package/dist/{triage-5NWCREUM.js → triage-GY7M3UGG.js} +6 -6
  127. package/dist/{trigger-KXYYY5IR.js → trigger-DLFAORX4.js} +9 -9
  128. package/dist/{update-check-Q2URVJLC.js → update-check-ES6XQ7OF.js} +4 -4
  129. package/dist/{upgrade-4XSASC7U.js → upgrade-WKEOW5GS.js} +5 -5
  130. package/dist/{usage-UY7VZYVY.js → usage-E6FDTR3W.js} +7 -7
  131. package/dist/{utilities-53NXNLA7.js → utilities-4Z6YX3L5.js} +6 -6
  132. package/dist/{visual-IJAT7X7D.js → visual-TA6LPVDJ.js} +5 -5
  133. package/dist/{workflow-OQNH2FIS.js → workflow-B5FXS2CJ.js} +92 -36
  134. package/dist/workflow-B5FXS2CJ.js.map +1 -0
  135. package/dist/{workflow-cache-FP6MKLVR.js → workflow-cache-MNLEMRMM.js} +16 -16
  136. package/dist/{workflow-cache-convergence-resolve-HS5KO7US.js → workflow-cache-convergence-resolve-G5HJM6MF.js} +5 -5
  137. package/dist/{workflow-debug-EM55H2QE.js → workflow-debug-TNBUGSBK.js} +11 -11
  138. package/dist/{workflow-feedback-GNWNWVHH.js → workflow-feedback-G2ZXAUGI.js} +5 -5
  139. package/dist/{workflow-fork-M5AQWST7.js → workflow-fork-6HHOMC2D.js} +5 -5
  140. package/dist/{workflow-promotion-HYULZDYL.js → workflow-promotion-RG7L6JZT.js} +5 -5
  141. package/dist/{workflow-proposals-EN327FSE.js → workflow-proposals-ZNF2F3UE.js} +5 -5
  142. package/dist/{workflow-revisions-ZMTVNWRW.js → workflow-revisions-TP64Z6FO.js} +5 -5
  143. package/dist/{workflow-status-FNAJG34W.js → workflow-status-5RG3JX56.js} +5 -5
  144. package/package.json +3 -2
  145. package/dist/chunk-74TU6PGO.js.map +0 -1
  146. package/dist/chunk-AQOHNAEN.js.map +0 -1
  147. package/dist/chunk-HGEJHS45.js.map +0 -1
  148. package/dist/chunk-KNWKOKM7.js.map +0 -1
  149. package/dist/chunk-LPQTXBJF.js.map +0 -1
  150. package/dist/chunk-O7MBDOMO.js.map +0 -1
  151. package/dist/chunk-Q7UAEFW5.js.map +0 -1
  152. package/dist/chunk-R2CVV7QT.js.map +0 -1
  153. package/dist/chunk-TRC63RSK.js.map +0 -1
  154. package/dist/chunk-ZFN5FWN2.js.map +0 -1
  155. package/dist/eval-5FZKYZ6O.js.map +0 -1
  156. package/dist/exploratory-test-SJ5HFI3L.js.map +0 -1
  157. package/dist/perf-3JOAXPHP.js.map +0 -1
  158. package/dist/property-IEKBXRVY.js.map +0 -1
  159. package/dist/sandbox-ZXDZTCCN.js.map +0 -1
  160. package/dist/skill-D4XFW6QI.js.map +0 -1
  161. package/dist/src-ZKVNVLXY.js.map +0 -1
  162. package/dist/test-suite-QHDUW5W5.js.map +0 -1
  163. package/dist/workflow-OQNH2FIS.js.map +0 -1
  164. /package/dist/{account-6YJAU53I.js.map → account-CZYZD2JS.js.map} +0 -0
  165. /package/dist/{alert-Z7V2ZUEW.js.map → alert-JQ4SDEB7.js.map} +0 -0
  166. /package/dist/{api-catalog-UEDTRM6E.js.map → api-catalog-IWQC35P2.js.map} +0 -0
  167. /package/dist/{api-key-V5GEPRRG.js.map → api-key-GUDXIIEA.js.map} +0 -0
  168. /package/dist/{attachment-M7VZ6GSE.js.map → attachment-CPZYOBUB.js.map} +0 -0
  169. /package/dist/{auth-DVTMWJKF.js.map → auth-DS6MBVEI.js.map} +0 -0
  170. /package/dist/{benchmark-KZJZYUTQ.js.map → benchmark-6HPCIQHD.js.map} +0 -0
  171. /package/dist/{blackcat-QJXYDE66.js.map → blackcat-V3L63WFE.js.map} +0 -0
  172. /package/dist/{chunk-FLDIN6VX.js.map → chunk-2E3STBHS.js.map} +0 -0
  173. /package/dist/{chunk-L4Y5PZUE.js.map → chunk-3LGCHNBC.js.map} +0 -0
  174. /package/dist/{chunk-2M4PZK6Q.js.map → chunk-56HFZHQM.js.map} +0 -0
  175. /package/dist/{chunk-RA2NRAWU.js.map → chunk-62EXS76C.js.map} +0 -0
  176. /package/dist/{chunk-4EWSONHO.js.map → chunk-BDOL622T.js.map} +0 -0
  177. /package/dist/{chunk-T6EQFICG.js.map → chunk-C3CXVX2B.js.map} +0 -0
  178. /package/dist/{chunk-MQQCUU5S.js.map → chunk-DEVD2WD2.js.map} +0 -0
  179. /package/dist/{chunk-JAIMLQOU.js.map → chunk-GCD4EHCD.js.map} +0 -0
  180. /package/dist/{chunk-7MRZWPVC.js.map → chunk-H6ZMKNP7.js.map} +0 -0
  181. /package/dist/{chunk-ZOPVBINJ.js.map → chunk-IEWAH7W3.js.map} +0 -0
  182. /package/dist/{chunk-ZO5MSM4Q.js.map → chunk-J2ZQULU3.js.map} +0 -0
  183. /package/dist/{chunk-IVWWYKAM.js.map → chunk-K2IDR6FR.js.map} +0 -0
  184. /package/dist/{chunk-QGP67JOK.js.map → chunk-KTZRI27M.js.map} +0 -0
  185. /package/dist/{chunk-3YNR6U6Q.js.map → chunk-UJSW72LG.js.map} +0 -0
  186. /package/dist/{chunk-G2SCV2CY.js.map → chunk-VACACCD6.js.map} +0 -0
  187. /package/dist/{chunk-CV22445U.js.map → chunk-VMAR67FF.js.map} +0 -0
  188. /package/dist/{chunk-QYHJUHL7.js.map → chunk-VMJ7TBVM.js.map} +0 -0
  189. /package/dist/{chunk-YACDH6MJ.js.map → chunk-XHEVDABB.js.map} +0 -0
  190. /package/dist/{chunk-7VBX2M4F.js.map → chunk-XHGF6VC6.js.map} +0 -0
  191. /package/dist/{credential-546ER7WQ.js.map → credential-GJW7LGYP.js.map} +0 -0
  192. /package/dist/{credential-template-BWMEBGBN.js.map → credential-template-UWBYKKWD.js.map} +0 -0
  193. /package/dist/{digest-NIVBDDI2.js.map → digest-XEHGCJM4.js.map} +0 -0
  194. /package/dist/{docs-AK4MDP6K.js.map → docs-KH4BCEQF.js.map} +0 -0
  195. /package/dist/{doctor-NCLA47EL.js.map → doctor-FOXXE5SK.js.map} +0 -0
  196. /package/dist/{environment-X3PV5IN2.js.map → environment-EBDPQTIS.js.map} +0 -0
  197. /package/dist/{exploration-2RVGIUKT.js.map → exploration-LCGKRGOQ.js.map} +0 -0
  198. /package/dist/{external-run-4NDVAHQB.js.map → external-run-2AJAI5O7.js.map} +0 -0
  199. /package/dist/{feature-flag-C4IRE724.js.map → feature-flag-P7N4WQIH.js.map} +0 -0
  200. /package/dist/{feedback-337OZCKC.js.map → feedback-LAT7TQ2T.js.map} +0 -0
  201. /package/dist/{flow-D7ZLBKCH.js.map → flow-NH2DC6AP.js.map} +0 -0
  202. /package/dist/{github-LKXYIALH.js.map → github-FCEKBLXI.js.map} +0 -0
  203. /package/dist/{init-GKEC6LPH.js.map → init-5U5EZOAW.js.map} +0 -0
  204. /package/dist/{install-K45SAT2V.js.map → install-X3UNVXKY.js.map} +0 -0
  205. /package/dist/{issues-2HMTQYWR.js.map → issues-4P6I3YQW.js.map} +0 -0
  206. /package/dist/{knobs-KUCGLO5Z.js.map → knobs-JKTWJ6ZG.js.map} +0 -0
  207. /package/dist/{landing-KAET2I73.js.map → landing-6AGLKI66.js.map} +0 -0
  208. /package/dist/{list-GDV4UYWV.js.map → list-TWP2RP33.js.map} +0 -0
  209. /package/dist/{local-NFOSJLLV.js.map → local-D75QE5TB.js.map} +0 -0
  210. /package/dist/{login-Y77HWROY.js.map → login-RBET4TIP.js.map} +0 -0
  211. /package/dist/{mcp-CPCFMU6B.js.map → mcp-562SUUMK.js.map} +0 -0
  212. /package/dist/{metrics-Y245ST63.js.map → metrics-4WF2GEPA.js.map} +0 -0
  213. /package/dist/{monitor-BUDWSC3S.js.map → monitor-WJXH54H2.js.map} +0 -0
  214. /package/dist/{product-CXL3YTMD.js.map → product-CYEQ7HOB.js.map} +0 -0
  215. /package/dist/{product-map-656BTU74.js.map → product-map-MSDLIFZY.js.map} +0 -0
  216. /package/dist/{prompts-3SZ7O5E6.js.map → prompts-ME53WPN4.js.map} +0 -0
  217. /package/dist/{proofs-4CSCCSNL.js.map → proofs-D3G6ZUFP.js.map} +0 -0
  218. /package/dist/{psql-M4CM6TSI.js.map → psql-EXAUDU3W.js.map} +0 -0
  219. /package/dist/{record-QP4TYZBS.js.map → record-EE7NGNKY.js.map} +0 -0
  220. /package/dist/{redis-KG47IGJV.js.map → redis-M4EYWKOJ.js.map} +0 -0
  221. /package/dist/{release-QHPSQULK.js.map → release-4KUWVWWC.js.map} +0 -0
  222. /package/dist/{runbook-YVBG2QK3.js.map → runbook-AHU77ANQ.js.map} +0 -0
  223. /package/dist/{scenarios-2SX2NUCD.js.map → scenarios-TU656T2B.js.map} +0 -0
  224. /package/dist/{schedule-P6F7MLXX.js.map → schedule-DXJI6SYO.js.map} +0 -0
  225. /package/dist/{session-SZMCZTPE.js.map → session-RUFTJHF4.js.map} +0 -0
  226. /package/dist/{slack-UDXTPOSW.js.map → slack-M3OKDVMY.js.map} +0 -0
  227. /package/dist/{spec-YCBBIV27.js.map → spec-5MXEBLYR.js.map} +0 -0
  228. /package/dist/{src-DEGBASCD.js.map → src-2X5OQRPJ.js.map} +0 -0
  229. /package/dist/{src-DY7GLRO2.js.map → src-72EFBA2R.js.map} +0 -0
  230. /package/dist/{src-NG7DRE5A.js.map → src-KH6WSBJV.js.map} +0 -0
  231. /package/dist/{start-ZYZSORPY.js.map → start-PDYBRB5T.js.map} +0 -0
  232. /package/dist/{status-ESIG6A7W.js.map → status-VMVPVCDA.js.map} +0 -0
  233. /package/dist/{tag-3K5Y25AR.js.map → tag-7KTDLPVU.js.map} +0 -0
  234. /package/dist/{task-JLNX7O3M.js.map → task-QLFYZNKR.js.map} +0 -0
  235. /package/dist/{teams-F4IU3EXE.js.map → teams-Y7BXCY6P.js.map} +0 -0
  236. /package/dist/{tickets-NBL5WACL.js.map → tickets-CQDJDNPY.js.map} +0 -0
  237. /package/dist/{trace-ZKYAI5JF.js.map → trace-QDORWXYX.js.map} +0 -0
  238. /package/dist/{triage-5NWCREUM.js.map → triage-GY7M3UGG.js.map} +0 -0
  239. /package/dist/{trigger-KXYYY5IR.js.map → trigger-DLFAORX4.js.map} +0 -0
  240. /package/dist/{update-check-Q2URVJLC.js.map → update-check-ES6XQ7OF.js.map} +0 -0
  241. /package/dist/{upgrade-4XSASC7U.js.map → upgrade-WKEOW5GS.js.map} +0 -0
  242. /package/dist/{usage-UY7VZYVY.js.map → usage-E6FDTR3W.js.map} +0 -0
  243. /package/dist/{utilities-53NXNLA7.js.map → utilities-4Z6YX3L5.js.map} +0 -0
  244. /package/dist/{visual-IJAT7X7D.js.map → visual-TA6LPVDJ.js.map} +0 -0
  245. /package/dist/{workflow-cache-FP6MKLVR.js.map → workflow-cache-MNLEMRMM.js.map} +0 -0
  246. /package/dist/{workflow-cache-convergence-resolve-HS5KO7US.js.map → workflow-cache-convergence-resolve-G5HJM6MF.js.map} +0 -0
  247. /package/dist/{workflow-debug-EM55H2QE.js.map → workflow-debug-TNBUGSBK.js.map} +0 -0
  248. /package/dist/{workflow-feedback-GNWNWVHH.js.map → workflow-feedback-G2ZXAUGI.js.map} +0 -0
  249. /package/dist/{workflow-fork-M5AQWST7.js.map → workflow-fork-6HHOMC2D.js.map} +0 -0
  250. /package/dist/{workflow-promotion-HYULZDYL.js.map → workflow-promotion-RG7L6JZT.js.map} +0 -0
  251. /package/dist/{workflow-proposals-EN327FSE.js.map → workflow-proposals-ZNF2F3UE.js.map} +0 -0
  252. /package/dist/{workflow-revisions-ZMTVNWRW.js.map → workflow-revisions-TP64Z6FO.js.map} +0 -0
  253. /package/dist/{workflow-status-FNAJG34W.js.map → workflow-status-5RG3JX56.js.map} +0 -0
@@ -24,35 +24,35 @@ import {
24
24
  serializeNodeDecisionLog,
25
25
  timelineActionCode,
26
26
  traceActionWithPreview
27
- } from "./chunk-QGP67JOK.js";
27
+ } from "./chunk-KTZRI27M.js";
28
28
  import {
29
29
  materializeRunWorkspace
30
- } from "./chunk-2M4PZK6Q.js";
31
- import "./chunk-L4Y5PZUE.js";
32
- import "./chunk-JAIMLQOU.js";
30
+ } from "./chunk-56HFZHQM.js";
31
+ import "./chunk-3LGCHNBC.js";
32
+ import "./chunk-GCD4EHCD.js";
33
33
  import "./chunk-PBTGJYM5.js";
34
- import "./chunk-7MRZWPVC.js";
34
+ import "./chunk-H6ZMKNP7.js";
35
35
  import {
36
36
  apiRequest,
37
37
  promptInput
38
- } from "./chunk-TRC63RSK.js";
39
- import "./chunk-IVWWYKAM.js";
38
+ } from "./chunk-EWK44F6V.js";
39
+ import "./chunk-K2IDR6FR.js";
40
40
  import "./chunk-S3Q7MDCS.js";
41
41
  import {
42
42
  getArgValue,
43
43
  hasFlag
44
- } from "./chunk-ZFN5FWN2.js";
44
+ } from "./chunk-4MFMPC5P.js";
45
45
  import {
46
46
  writeRawOutput
47
- } from "./chunk-KNWKOKM7.js";
47
+ } from "./chunk-2OHYMT3A.js";
48
48
  import "./chunk-AK7WEGGB.js";
49
49
  import "./chunk-5QHORHJT.js";
50
50
  import {
51
51
  parseTraceArchive
52
- } from "./chunk-FLDIN6VX.js";
52
+ } from "./chunk-2E3STBHS.js";
53
53
  import {
54
54
  matchAssertionSpecsToVerifySteps
55
- } from "./chunk-R2CVV7QT.js";
55
+ } from "./chunk-RHWPZKRV.js";
56
56
  import "./chunk-TOWZAG3I.js";
57
57
 
58
58
  // src/workflow-cache.ts
@@ -621,7 +621,7 @@ async function handleWorkflowCache(argv, apiUrl, token) {
621
621
  await handleConvergenceReport(rest, apiUrl, token);
622
622
  return;
623
623
  case "convergence-resolve": {
624
- const { handleConvergenceResolve } = await import("./workflow-cache-convergence-resolve-HS5KO7US.js");
624
+ const { handleConvergenceResolve } = await import("./workflow-cache-convergence-resolve-G5HJM6MF.js");
625
625
  await handleConvergenceResolve(rest, apiUrl, token);
626
626
  return;
627
627
  }
@@ -1594,7 +1594,7 @@ async function handleSubstrate(argv) {
1594
1594
  process2.exit(1);
1595
1595
  }
1596
1596
  const actionIndex = Number(actionIndexRaw);
1597
- const { SubstrateMaterializer: SubstrateMaterializer2 } = await import("./src-DEGBASCD.js");
1597
+ const { SubstrateMaterializer: SubstrateMaterializer2 } = await import("./src-KH6WSBJV.js");
1598
1598
  const path3 = await import("path");
1599
1599
  const traceZipPath = path3.join(workspace, "browser", "trace.zip");
1600
1600
  const materializer = new SubstrateMaterializer2({
@@ -1630,8 +1630,8 @@ async function handleLocator(argv) {
1630
1630
  }
1631
1631
  }
1632
1632
  const actionIndex = Number(actionIndexRaw);
1633
- const { HeadlessDomSession: HeadlessDomSession2, SubstrateMaterializer: SubstrateMaterializer2, LocatorVerifier: LocatorVerifier2, buildLocator } = await import("./src-DEGBASCD.js");
1634
- const { parseSnapshot } = await import("./src-DY7GLRO2.js");
1633
+ const { HeadlessDomSession: HeadlessDomSession2, SubstrateMaterializer: SubstrateMaterializer2, LocatorVerifier: LocatorVerifier2, buildLocator } = await import("./src-KH6WSBJV.js");
1634
+ const { parseSnapshot } = await import("./src-2X5OQRPJ.js");
1635
1635
  const path3 = await import("path");
1636
1636
  const session = new HeadlessDomSession2();
1637
1637
  const traceZipPath = path3.join(workspace, "browser", "trace.zip");
@@ -1804,4 +1804,4 @@ export {
1804
1804
  readCacheRecipeFile,
1805
1805
  timelineActionCode
1806
1806
  };
1807
- //# sourceMappingURL=workflow-cache-FP6MKLVR.js.map
1807
+ //# sourceMappingURL=workflow-cache-MNLEMRMM.js.map
@@ -1,16 +1,16 @@
1
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
2
  import {
3
3
  apiRequest
4
- } from "./chunk-TRC63RSK.js";
4
+ } from "./chunk-EWK44F6V.js";
5
5
  import "./chunk-S3Q7MDCS.js";
6
6
  import {
7
7
  getArgValue,
8
8
  hasFlag
9
- } from "./chunk-ZFN5FWN2.js";
9
+ } from "./chunk-4MFMPC5P.js";
10
10
  import {
11
11
  writeRawOutput
12
- } from "./chunk-KNWKOKM7.js";
13
- import "./chunk-R2CVV7QT.js";
12
+ } from "./chunk-2OHYMT3A.js";
13
+ import "./chunk-RHWPZKRV.js";
14
14
  import "./chunk-TOWZAG3I.js";
15
15
 
16
16
  // src/workflow-cache-convergence-resolve.ts
@@ -42,4 +42,4 @@ async function handleConvergenceResolve(argv, apiUrl, token) {
42
42
  export {
43
43
  handleConvergenceResolve
44
44
  };
45
- //# sourceMappingURL=workflow-cache-convergence-resolve-HS5KO7US.js.map
45
+ //# sourceMappingURL=workflow-cache-convergence-resolve-G5HJM6MF.js.map
@@ -4,19 +4,19 @@ import {
4
4
  handleWorkflowDebug,
5
5
  materializeRunWorkspace,
6
6
  resolveWorkflowIdForRun
7
- } from "./chunk-2M4PZK6Q.js";
8
- import "./chunk-L4Y5PZUE.js";
9
- import "./chunk-JAIMLQOU.js";
10
- import "./chunk-7MRZWPVC.js";
11
- import "./chunk-TRC63RSK.js";
12
- import "./chunk-IVWWYKAM.js";
7
+ } from "./chunk-56HFZHQM.js";
8
+ import "./chunk-3LGCHNBC.js";
9
+ import "./chunk-GCD4EHCD.js";
10
+ import "./chunk-H6ZMKNP7.js";
11
+ import "./chunk-EWK44F6V.js";
12
+ import "./chunk-K2IDR6FR.js";
13
13
  import "./chunk-S3Q7MDCS.js";
14
- import "./chunk-ZFN5FWN2.js";
15
- import "./chunk-KNWKOKM7.js";
14
+ import "./chunk-4MFMPC5P.js";
15
+ import "./chunk-2OHYMT3A.js";
16
16
  import "./chunk-AK7WEGGB.js";
17
17
  import "./chunk-5QHORHJT.js";
18
- import "./chunk-FLDIN6VX.js";
19
- import "./chunk-R2CVV7QT.js";
18
+ import "./chunk-2E3STBHS.js";
19
+ import "./chunk-RHWPZKRV.js";
20
20
  import "./chunk-TOWZAG3I.js";
21
21
  export {
22
22
  formatRetention,
@@ -24,4 +24,4 @@ export {
24
24
  materializeRunWorkspace,
25
25
  resolveWorkflowIdForRun
26
26
  };
27
- //# sourceMappingURL=workflow-debug-EM55H2QE.js.map
27
+ //# sourceMappingURL=workflow-debug-TNBUGSBK.js.map
@@ -1,16 +1,16 @@
1
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
2
  import {
3
3
  apiRequest
4
- } from "./chunk-TRC63RSK.js";
4
+ } from "./chunk-EWK44F6V.js";
5
5
  import "./chunk-S3Q7MDCS.js";
6
6
  import {
7
7
  getArgValue,
8
8
  hasFlag
9
- } from "./chunk-ZFN5FWN2.js";
9
+ } from "./chunk-4MFMPC5P.js";
10
10
  import {
11
11
  writeRawOutput
12
- } from "./chunk-KNWKOKM7.js";
13
- import "./chunk-R2CVV7QT.js";
12
+ } from "./chunk-2OHYMT3A.js";
13
+ import "./chunk-RHWPZKRV.js";
14
14
  import "./chunk-TOWZAG3I.js";
15
15
 
16
16
  // src/workflow-feedback.ts
@@ -154,4 +154,4 @@ async function handleWorkflowFeedback(argv, apiUrl, token) {
154
154
  export {
155
155
  handleWorkflowFeedback
156
156
  };
157
- //# sourceMappingURL=workflow-feedback-GNWNWVHH.js.map
157
+ //# sourceMappingURL=workflow-feedback-G2ZXAUGI.js.map
@@ -5,16 +5,16 @@ import {
5
5
  import {
6
6
  apiRequest,
7
7
  getPositionalArg
8
- } from "./chunk-TRC63RSK.js";
8
+ } from "./chunk-EWK44F6V.js";
9
9
  import "./chunk-S3Q7MDCS.js";
10
10
  import {
11
11
  getArgValue,
12
12
  hasFlag
13
- } from "./chunk-ZFN5FWN2.js";
13
+ } from "./chunk-4MFMPC5P.js";
14
14
  import {
15
15
  writeRawOutput
16
- } from "./chunk-KNWKOKM7.js";
17
- import "./chunk-R2CVV7QT.js";
16
+ } from "./chunk-2OHYMT3A.js";
17
+ import "./chunk-RHWPZKRV.js";
18
18
  import "./chunk-TOWZAG3I.js";
19
19
 
20
20
  // src/workflow-fork.ts
@@ -239,4 +239,4 @@ export {
239
239
  buildForkNodeMap,
240
240
  handleWorkflowFork
241
241
  };
242
- //# sourceMappingURL=workflow-fork-M5AQWST7.js.map
242
+ //# sourceMappingURL=workflow-fork-6HHOMC2D.js.map
@@ -5,15 +5,15 @@ import {
5
5
  getPositionalArg,
6
6
  getScalarArgValue,
7
7
  resolveTestSuite
8
- } from "./chunk-TRC63RSK.js";
8
+ } from "./chunk-EWK44F6V.js";
9
9
  import "./chunk-S3Q7MDCS.js";
10
- import "./chunk-ZFN5FWN2.js";
10
+ import "./chunk-4MFMPC5P.js";
11
11
  import {
12
12
  writeRawOutput
13
- } from "./chunk-KNWKOKM7.js";
13
+ } from "./chunk-2OHYMT3A.js";
14
14
  import {
15
15
  parsePromoteOn
16
- } from "./chunk-R2CVV7QT.js";
16
+ } from "./chunk-RHWPZKRV.js";
17
17
  import "./chunk-TOWZAG3I.js";
18
18
 
19
19
  // src/workflow-promotion.ts
@@ -59,4 +59,4 @@ function usageError(message) {
59
59
  export {
60
60
  handleWorkflowPromotion
61
61
  };
62
- //# sourceMappingURL=workflow-promotion-HYULZDYL.js.map
62
+ //# sourceMappingURL=workflow-promotion-RG7L6JZT.js.map
@@ -6,16 +6,16 @@ import {
6
6
  } from "./chunk-DEK6B6LX.js";
7
7
  import {
8
8
  apiRequest
9
- } from "./chunk-TRC63RSK.js";
9
+ } from "./chunk-EWK44F6V.js";
10
10
  import "./chunk-S3Q7MDCS.js";
11
11
  import {
12
12
  getArgValue,
13
13
  hasFlag
14
- } from "./chunk-ZFN5FWN2.js";
14
+ } from "./chunk-4MFMPC5P.js";
15
15
  import {
16
16
  writeRawOutput
17
- } from "./chunk-KNWKOKM7.js";
18
- import "./chunk-R2CVV7QT.js";
17
+ } from "./chunk-2OHYMT3A.js";
18
+ import "./chunk-RHWPZKRV.js";
19
19
  import "./chunk-TOWZAG3I.js";
20
20
 
21
21
  // src/workflow-proposals.ts
@@ -379,4 +379,4 @@ export {
379
379
  _internalsForTesting,
380
380
  handleWorkflowProposals
381
381
  };
382
- //# sourceMappingURL=workflow-proposals-EN327FSE.js.map
382
+ //# sourceMappingURL=workflow-proposals-ZNF2F3UE.js.map
@@ -1,16 +1,16 @@
1
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
2
  import {
3
3
  apiRequest
4
- } from "./chunk-TRC63RSK.js";
4
+ } from "./chunk-EWK44F6V.js";
5
5
  import "./chunk-S3Q7MDCS.js";
6
6
  import {
7
7
  getArgValue,
8
8
  hasFlag
9
- } from "./chunk-ZFN5FWN2.js";
9
+ } from "./chunk-4MFMPC5P.js";
10
10
  import {
11
11
  writeRawOutput
12
- } from "./chunk-KNWKOKM7.js";
13
- import "./chunk-R2CVV7QT.js";
12
+ } from "./chunk-2OHYMT3A.js";
13
+ import "./chunk-RHWPZKRV.js";
14
14
  import "./chunk-TOWZAG3I.js";
15
15
 
16
16
  // src/workflow-revisions.ts
@@ -75,4 +75,4 @@ async function handleWorkflowRevisions(argv, apiUrl, token) {
75
75
  export {
76
76
  handleWorkflowRevisions
77
77
  };
78
- //# sourceMappingURL=workflow-revisions-ZMTVNWRW.js.map
78
+ //# sourceMappingURL=workflow-revisions-TP64Z6FO.js.map
@@ -2,18 +2,18 @@ import { createRequire as __cr } from "module"; import { fileURLToPath as __fup
2
2
  import {
3
3
  apiRequest,
4
4
  readTextOrFile
5
- } from "./chunk-TRC63RSK.js";
5
+ } from "./chunk-EWK44F6V.js";
6
6
  import "./chunk-S3Q7MDCS.js";
7
7
  import {
8
8
  getArgValue,
9
9
  hasFlag
10
- } from "./chunk-ZFN5FWN2.js";
10
+ } from "./chunk-4MFMPC5P.js";
11
11
  import {
12
12
  writeRawOutput
13
- } from "./chunk-KNWKOKM7.js";
13
+ } from "./chunk-2OHYMT3A.js";
14
14
  import {
15
15
  WORKFLOW_MANAGEMENT_STATUSES
16
- } from "./chunk-R2CVV7QT.js";
16
+ } from "./chunk-RHWPZKRV.js";
17
17
  import "./chunk-TOWZAG3I.js";
18
18
 
19
19
  // src/workflow-status.ts
@@ -282,4 +282,4 @@ export {
282
282
  handleWorkflowEvents,
283
283
  handleWorkflowStatus
284
284
  };
285
- //# sourceMappingURL=workflow-status-FNAJG34W.js.map
285
+ //# sourceMappingURL=workflow-status-5RG3JX56.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runcofactor/cli",
3
- "version": "0.54.0",
3
+ "version": "0.56.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@firecrawl/pdf-inspector": "1.25.2",
48
- "@modelcontextprotocol/sdk": "^1.31.0",
48
+ "@modelcontextprotocol/sdk": "^1.32.0",
49
49
  "@napi-rs/canvas": "1.0.13",
50
50
  "eventsource-parser": "^4.0.0",
51
51
  "playwright": "1.62.1",
@@ -54,6 +54,7 @@
54
54
  "zod": "^4.4.3"
55
55
  },
56
56
  "devDependencies": {
57
+ "@chatsdet/ade-relay-protocol": "workspace:*",
57
58
  "@chatsdet/browser-core": "workspace:*",
58
59
  "@chatsdet/canary-spec": "workspace:*",
59
60
  "@chatsdet/content": "workspace:*",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utilities.ts"],"sourcesContent":["/**\n * CLI Utilities Commands — a freeform agent toolkit.\n *\n * Three primitives for building and sharing reports:\n * - object: upload images/videos/files to the CDN (public or private), with\n * optional TTL, and get shareable / signed links.\n * - gist: publish text/markdown viewable in the Cofactor web app.\n * - email / slack: send one-off messages to ORG MEMBERS (looked up by email\n * or name). Use `cofactor org members` to see who can receive them.\n *\n * @module utilities\n */\n\nimport fs from 'node:fs/promises';\nimport { writeRawOutput } from './brand.js';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, readStdin } from './cli-helpers.js';\n\n// ── shared helpers ─────────────────────────────────────────────────────────\n\n/** Collect every value for a repeated flag, e.g. `--to a --to b`. */\nfunction getAllArgValues(argv: string[], key: string): string[] {\n const out: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] === key && i + 1 < argv.length) out.push(argv[i + 1]!);\n }\n return out;\n}\n\n/** Parse `flag`'s human duration (`30s`, `15m`, `24h`, `7d`, or bare seconds) → seconds. */\nexport function parseDurationSeconds(raw: string | undefined, flag: string): number | undefined {\n if (!raw) return undefined;\n const m = raw.trim().match(/^(\\d+)\\s*(s|m|h|d)?$/i);\n if (!m) {\n console.error(`Error: invalid ${flag} '${raw}'. Use e.g. 30s, 15m, 24h, 7d, or seconds.`);\n process.exit(1);\n }\n const n = Number(m[1]);\n const unit = (m[2] ?? 's').toLowerCase();\n const mult = unit === 'd' ? 86400 : unit === 'h' ? 3600 : unit === 'm' ? 60 : 1;\n return n * mult;\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n/** Resolve message/gist body from --body, --body-file, or --stdin. */\nasync function resolveBody(argv: string[]): Promise<string> {\n const inline = getArgValue(argv, '--body');\n if (inline !== undefined) return inline;\n const file = getArgValue(argv, '--body-file');\n if (file) {\n try {\n return await fs.readFile(file, 'utf-8');\n } catch (err) {\n console.error(`Error: failed to read ${file}: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n }\n if (hasFlag(argv, '--stdin')) return readStdin();\n console.error('Error: provide a body via --body <text>, --body-file <path>, or --stdin.');\n process.exit(1);\n}\n\n// ── help ───────────────────────────────────────────────────────────────────\n\nfunction printHelp(): void {\n console.log(\n [\n 'Usage: cofactor utilities <group> <sub-command> [options]',\n '',\n 'A freeform toolkit for building and sharing reports.',\n '',\n 'Objects (images / videos / files):',\n ' object upload <file> [--public] [--ttl 7d] [--name <n>] [--json]',\n ' object list [--kind image|video|data|all] [--search <q>] [--json]',\n ' object url <id> [--download] Print a shareable/signed link',\n ' object delete <id>',\n '',\n 'Gists (text / markdown, viewable in the web app):',\n ' gist create [<file> | --stdin] [--title <t>] [--format markdown|text]',\n ' [--public] [--ttl 7d] [--json]',\n ' gist list [--search <q>] [--json]',\n ' gist get <id> [--raw] --raw prints content; default shows metadata + link',\n ' gist delete <id>',\n '',\n 'Messaging (org members only — see `cofactor org members`):',\n ' email --to <member> [--to ...] --subject <s> (--body <t> | --body-file <f> | --stdin)',\n ' slack --to <member> [--to ...] (--body <t> | --body-file <f> | --stdin)',\n '',\n 'Common options:',\n ' --env <prod|dev|local> Target environment',\n ' --json Machine-readable output',\n '',\n 'Recipe — build & share a report:',\n ' 1. Upload evidence: cofactor utilities object upload chart.png --public',\n ' 2. Write a report: cofactor utilities gist create report.md --public --title \"Run 42\"',\n ' (embed the object URLs from step 1 as markdown images)',\n ' 3. Share the link: cofactor utilities slack --to alex@acme.com --body \"Report: <gist url>\"',\n ].join('\\n')\n );\n}\n\n// ── objects ──────────────────────────────────────────────────────────────\n\ntype ObjectItem = {\n id: string;\n visibility: 'public' | 'private';\n filename: string;\n contentType: string;\n sizeBytes: number;\n expiresAt: string | null;\n createdAt: string;\n publicUrl: string | null;\n};\n\nasync function objectUpload(argv: string[], apiUrl: string, token: string): Promise<void> {\n const filePath = argv.find((a) => !a.startsWith('-'));\n if (!filePath) {\n console.error('Error: missing file path. Usage: utilities object upload <file> [--public] [--ttl 7d]');\n process.exit(1);\n }\n const isPublic = hasFlag(argv, '--public');\n const ttlSeconds = parseDurationSeconds(getArgValue(argv, '--ttl'), '--ttl');\n const overrideName = getArgValue(argv, '--name');\n const jsonOutput = hasFlag(argv, '--json');\n\n let buf: Buffer;\n try {\n buf = await fs.readFile(filePath);\n } catch (err) {\n console.error(`Error: failed to read ${filePath}: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n const filename = overrideName ?? path.basename(filePath);\n\n const form = new FormData();\n form.append('file', new Blob([new Uint8Array(buf)]), filename);\n form.append('visibility', isPublic ? 'public' : 'private');\n if (ttlSeconds) form.append('ttlSeconds', String(ttlSeconds));\n if (overrideName) form.append('filename', overrideName);\n\n const res = await fetch(`${apiUrl}/org/utilities/objects`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: form,\n });\n if (res.status === 401) {\n console.error('Error: Unauthorized. Run: cofactor login');\n process.exit(1);\n }\n let body: { ok: boolean; error?: string; data?: ObjectItem & { url: string } };\n try {\n body = (await res.json()) as typeof body;\n } catch {\n console.error(`Error: invalid JSON response (${res.status})`);\n process.exit(1);\n }\n if (!body.ok || !body.data) {\n console.error(`Error: ${body.error ?? `upload failed (${res.status})`}`);\n process.exit(1);\n }\n\n const created = body.data;\n if (jsonOutput) {\n writeRawOutput(JSON.stringify(created, null, 2));\n return;\n }\n console.log(`✓ Uploaded ${created.filename} (${created.visibility})`);\n console.log(` ID: ${created.id}`);\n console.log(` Type: ${created.contentType} Size: ${formatSize(created.sizeBytes)}`);\n if (created.expiresAt) console.log(` Expires: ${created.expiresAt}`);\n console.log(` Link: ${created.url}`);\n if (created.visibility === 'private') {\n console.log(' (private link is short-lived — re-mint with: utilities object url ' + created.id + ')');\n }\n}\n\nasync function objectList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const params = new URLSearchParams();\n const kind = getArgValue(argv, '--kind');\n const search = getArgValue(argv, '--search');\n if (kind) params.set('kind', kind);\n if (search) params.set('search', search);\n const qs = params.toString();\n\n const result = await apiRequest<{ ok: boolean; error?: string; data: ObjectItem[] }>(\n apiUrl,\n token,\n 'GET',\n `/org/utilities/objects${qs ? `?${qs}` : ''}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n if (hasFlag(argv, '--json')) {\n writeRawOutput(JSON.stringify(result.data, null, 2));\n return;\n }\n if (result.data.length === 0) {\n console.log('No objects.');\n return;\n }\n for (const o of result.data) {\n console.log(`${o.id} ${o.visibility.padEnd(7)} ${formatSize(o.sizeBytes).padStart(8)} ${o.filename}`);\n }\n}\n\nasync function objectUrl(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing object id. Usage: utilities object url <id> [--download]');\n process.exit(1);\n }\n const dl = hasFlag(argv, '--download') ? '?dl=1' : '';\n const result = await apiRequest<{ ok: boolean; error?: string; url?: string }>(\n apiUrl,\n token,\n 'GET',\n `/org/utilities/objects/${id}/url${dl}`\n );\n if (!result.ok || !result.url) {\n console.error(`Error: ${result.error ?? 'failed to get URL'}`);\n process.exit(1);\n }\n console.log(result.url);\n}\n\nasync function objectDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing object id. Usage: utilities object delete <id>');\n process.exit(1);\n }\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/utilities/objects/${id}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`✓ Deleted ${id}`);\n}\n\n// ── gists ────────────────────────────────────────────────────────────────\n\ntype GistItem = {\n id: string;\n slug: string;\n title: string;\n content?: string;\n format: 'text' | 'markdown';\n visibility: 'public' | 'private';\n expiresAt: string | null;\n createdAt: string;\n viewUrl?: string | null;\n};\n\nasync function gistCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const filePath = argv.find((a) => !a.startsWith('-'));\n let content: string;\n if (filePath) {\n try {\n content = await fs.readFile(filePath, 'utf-8');\n } catch (err) {\n console.error(`Error: failed to read ${filePath}: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n } else if (hasFlag(argv, '--stdin')) {\n content = await readStdin();\n } else {\n const inline = getArgValue(argv, '--content');\n if (inline === undefined) {\n console.error('Error: provide content via a <file> arg, --stdin, or --content <text>.');\n process.exit(1);\n }\n content = inline;\n }\n\n const title =\n getArgValue(argv, '--title') ?? (filePath ? path.basename(filePath) : 'Untitled gist');\n const format = (getArgValue(argv, '--format') as 'text' | 'markdown') ?? 'markdown';\n const visibility = hasFlag(argv, '--public') ? 'public' : 'private';\n const ttlSeconds = parseDurationSeconds(getArgValue(argv, '--ttl'), '--ttl');\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: GistItem }>(\n apiUrl,\n token,\n 'POST',\n '/org/utilities/gists',\n { title, content, format, visibility, ...(ttlSeconds ? { ttlSeconds } : {}) }\n );\n if (!result.ok || !result.data) {\n console.error(`Error: ${result.error ?? 'failed to create gist'}`);\n process.exit(1);\n }\n if (hasFlag(argv, '--json')) {\n writeRawOutput(JSON.stringify(result.data, null, 2));\n return;\n }\n console.log(`✓ Created gist \"${result.data.title}\" (${result.data.visibility})`);\n console.log(` ID: ${result.data.id}`);\n if (result.data.viewUrl) console.log(` Public link: ${result.data.viewUrl}`);\n else console.log(' View in the web app under Utilities → Gists.');\n}\n\nasync function gistList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const search = getArgValue(argv, '--search');\n const qs = search ? `?search=${encodeURIComponent(search)}` : '';\n const result = await apiRequest<{ ok: boolean; error?: string; data: GistItem[] }>(\n apiUrl,\n token,\n 'GET',\n `/org/utilities/gists${qs}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n if (hasFlag(argv, '--json')) {\n writeRawOutput(JSON.stringify(result.data, null, 2));\n return;\n }\n if (result.data.length === 0) {\n console.log('No gists.');\n return;\n }\n for (const g of result.data) {\n console.log(`${g.id} ${g.visibility.padEnd(7)} ${g.format.padEnd(8)} ${g.title}`);\n }\n}\n\nasync function gistGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing gist id. Usage: utilities gist get <id> [--raw]');\n process.exit(1);\n }\n const result = await apiRequest<{ ok: boolean; error?: string; data?: GistItem }>(\n apiUrl,\n token,\n 'GET',\n `/org/utilities/gists/${id}`\n );\n if (!result.ok || !result.data) {\n console.error(`Error: ${result.error ?? 'gist not found'}`);\n process.exit(1);\n }\n if (hasFlag(argv, '--raw')) {\n process.stdout.write(result.data.content ?? '');\n return;\n }\n if (hasFlag(argv, '--json')) {\n writeRawOutput(JSON.stringify(result.data, null, 2));\n return;\n }\n // Title, id, link and body are all stored customer content — render raw.\n writeRawOutput(`${result.data.title} (${result.data.visibility}, ${result.data.format})`);\n writeRawOutput(` ID: ${result.data.id}`);\n if (result.data.viewUrl) writeRawOutput(` Public link: ${result.data.viewUrl}`);\n writeRawOutput('');\n writeRawOutput(result.data.content ?? '');\n}\n\nasync function gistDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing gist id. Usage: utilities gist delete <id>');\n process.exit(1);\n }\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/utilities/gists/${id}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`✓ Deleted ${id}`);\n}\n\n// ── messaging ──────────────────────────────────────────────────────────────\n\nasync function sendEmail(argv: string[], apiUrl: string, token: string): Promise<void> {\n const recipients = getAllArgValues(argv, '--to');\n const subject = getArgValue(argv, '--subject');\n if (recipients.length === 0 || !subject) {\n console.error('Error: usage: utilities email --to <member> [--to ...] --subject <s> (--body <t> | --body-file <f> | --stdin)');\n process.exit(1);\n }\n const body = await resolveBody(argv);\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: { sent: number } }>(\n apiUrl,\n token,\n 'POST',\n '/org/utilities/email',\n { recipients, subject, body }\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`✓ Email sent to ${result.data?.sent ?? recipients.length} recipient(s).`);\n}\n\nasync function sendSlack(argv: string[], apiUrl: string, token: string): Promise<void> {\n const recipients = getAllArgValues(argv, '--to');\n if (recipients.length === 0) {\n console.error('Error: usage: utilities slack --to <member> [--to ...] (--body <t> | --body-file <f> | --stdin)');\n process.exit(1);\n }\n const body = await resolveBody(argv);\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: { sent: number } }>(\n apiUrl,\n token,\n 'POST',\n '/org/utilities/slack',\n { recipients, body }\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`✓ Slack message sent to ${result.data?.sent ?? recipients.length} recipient(s).`);\n}\n\n// ── dispatch ─────────────────────────────────────────────────────────────\n\nasync function runObject(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [sub, ...rest] = argv;\n switch (sub) {\n case 'upload':\n return objectUpload(rest, apiUrl, token);\n case 'list':\n return objectList(rest, apiUrl, token);\n case 'url':\n return objectUrl(rest, apiUrl, token);\n case 'delete':\n return objectDelete(rest, apiUrl, token);\n default:\n console.error(`Unknown object sub-command: ${sub ?? '(none)'}`);\n printHelp();\n process.exit(1);\n }\n}\n\nasync function runGist(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [sub, ...rest] = argv;\n switch (sub) {\n case 'create':\n return gistCreate(rest, apiUrl, token);\n case 'list':\n return gistList(rest, apiUrl, token);\n case 'get':\n return gistGet(rest, apiUrl, token);\n case 'delete':\n return gistDelete(rest, apiUrl, token);\n default:\n console.error(`Unknown gist sub-command: ${sub ?? '(none)'}`);\n printHelp();\n process.exit(1);\n }\n}\n\nexport async function runUtilities(argv: string[]): Promise<void> {\n const [group, ...rest] = argv;\n\n if (!group || group === 'help' || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(rest);\n\n switch (group) {\n case 'object':\n return runObject(rest, apiUrl, token);\n case 'gist':\n return runGist(rest, apiUrl, token);\n case 'email':\n return sendEmail(rest, apiUrl, token);\n case 'slack':\n return sendSlack(rest, apiUrl, token);\n default:\n console.error(`Unknown utilities group: ${group}`);\n printHelp();\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAaA,OAAO,QAAQ;AAEf,OAAO,UAAU;AACjB,OAAO,aAAa;AAOpB,SAAS,gBAAgB,MAAgB,KAAuB;AAC9D,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,MAAM,OAAO,IAAI,IAAI,KAAK,OAAQ,KAAI,KAAK,KAAK,IAAI,CAAC,CAAE;AAAA,EACnE;AACA,SAAO;AACT;AAGO,SAAS,qBAAqB,KAAyB,MAAkC;AAC9F,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,IAAI,IAAI,KAAK,EAAE,MAAM,uBAAuB;AAClD,MAAI,CAAC,GAAG;AACN,YAAQ,MAAM,kBAAkB,IAAI,KAAK,GAAG,4CAA4C;AACxF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,IAAI,OAAO,EAAE,CAAC,CAAC;AACrB,QAAM,QAAQ,EAAE,CAAC,KAAK,KAAK,YAAY;AACvC,QAAM,OAAO,SAAS,MAAM,QAAQ,SAAS,MAAM,OAAO,SAAS,MAAM,KAAK;AAC9E,SAAO,IAAI;AACb;AAEA,SAAS,WAAW,OAAuB;AACzC,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;AAGA,eAAe,YAAY,MAAiC;AAC1D,QAAM,SAAS,YAAY,MAAM,QAAQ;AACzC,MAAI,WAAW,OAAW,QAAO;AACjC,QAAM,OAAO,YAAY,MAAM,aAAa;AAC5C,MAAI,MAAM;AACR,QAAI;AACF,aAAO,MAAM,GAAG,SAAS,MAAM,OAAO;AAAA,IACxC,SAAS,KAAK;AACZ,cAAQ,MAAM,yBAAyB,IAAI,KAAK,eAAe,QAAQ,IAAI,UAAU,GAAG,EAAE;AAC1F,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACA,MAAI,QAAQ,MAAM,SAAS,EAAG,QAAO,UAAU;AAC/C,UAAQ,MAAM,0EAA0E;AACxF,UAAQ,KAAK,CAAC;AAChB;AAIA,SAAS,YAAkB;AACzB,UAAQ;AAAA,IACN;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAeA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,WAAW,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AACpD,MAAI,CAAC,UAAU;AACb,YAAQ,MAAM,uFAAuF;AACrG,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,WAAW,QAAQ,MAAM,UAAU;AACzC,QAAM,aAAa,qBAAqB,YAAY,MAAM,OAAO,GAAG,OAAO;AAC3E,QAAM,eAAe,YAAY,MAAM,QAAQ;AAC/C,QAAM,aAAa,QAAQ,MAAM,QAAQ;AAEzC,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,GAAG,SAAS,QAAQ;AAAA,EAClC,SAAS,KAAK;AACZ,YAAQ,MAAM,yBAAyB,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,GAAG,EAAE;AAC9F,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,WAAW,gBAAgB,KAAK,SAAS,QAAQ;AAEvD,QAAM,OAAO,IAAI,SAAS;AAC1B,OAAK,OAAO,QAAQ,IAAI,KAAK,CAAC,IAAI,WAAW,GAAG,CAAC,CAAC,GAAG,QAAQ;AAC7D,OAAK,OAAO,cAAc,WAAW,WAAW,SAAS;AACzD,MAAI,WAAY,MAAK,OAAO,cAAc,OAAO,UAAU,CAAC;AAC5D,MAAI,aAAc,MAAK,OAAO,YAAY,YAAY;AAEtD,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,0BAA0B;AAAA,IACzD,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,IAC5C,MAAM;AAAA,EACR,CAAC;AACD,MAAI,IAAI,WAAW,KAAK;AACtB,YAAQ,MAAM,0CAA0C;AACxD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI;AACJ,MAAI;AACF,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,YAAQ,MAAM,iCAAiC,IAAI,MAAM,GAAG;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,CAAC,KAAK,MAAM,CAAC,KAAK,MAAM;AAC1B,YAAQ,MAAM,UAAU,KAAK,SAAS,kBAAkB,IAAI,MAAM,GAAG,EAAE;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,KAAK;AACrB,MAAI,YAAY;AACd,mBAAe,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC/C;AAAA,EACF;AACA,UAAQ,IAAI,mBAAc,QAAQ,QAAQ,KAAK,QAAQ,UAAU,GAAG;AACpE,UAAQ,IAAI,WAAW,QAAQ,EAAE,EAAE;AACnC,UAAQ,IAAI,WAAW,QAAQ,WAAW,WAAW,WAAW,QAAQ,SAAS,CAAC,EAAE;AACpF,MAAI,QAAQ,UAAW,SAAQ,IAAI,cAAc,QAAQ,SAAS,EAAE;AACpE,UAAQ,IAAI,WAAW,QAAQ,GAAG,EAAE;AACpC,MAAI,QAAQ,eAAe,WAAW;AACpC,YAAQ,IAAI,8EAAyE,QAAQ,KAAK,GAAG;AAAA,EACvG;AACF;AAEA,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,SAAS,IAAI,gBAAgB;AACnC,QAAM,OAAO,YAAY,MAAM,QAAQ;AACvC,QAAM,SAAS,YAAY,MAAM,UAAU;AAC3C,MAAI,KAAM,QAAO,IAAI,QAAQ,IAAI;AACjC,MAAI,OAAQ,QAAO,IAAI,UAAU,MAAM;AACvC,QAAM,KAAK,OAAO,SAAS;AAE3B,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,yBAAyB,KAAK,IAAI,EAAE,KAAK,EAAE;AAAA,EAC7C;AACA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,QAAQ,MAAM,QAAQ,GAAG;AAC3B,mBAAe,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC,CAAC;AACnD;AAAA,EACF;AACA,MAAI,OAAO,KAAK,WAAW,GAAG;AAC5B,YAAQ,IAAI,aAAa;AACzB;AAAA,EACF;AACA,aAAW,KAAK,OAAO,MAAM;AAC3B,YAAQ,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,OAAO,CAAC,CAAC,KAAK,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE;AAAA,EACzG;AACF;AAEA,eAAe,UAAU,MAAgB,QAAgB,OAA8B;AACrF,QAAM,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAC9C,MAAI,CAAC,IAAI;AACP,YAAQ,MAAM,yEAAyE;AACvF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,KAAK,QAAQ,MAAM,YAAY,IAAI,UAAU;AACnD,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,0BAA0B,EAAE,OAAO,EAAE;AAAA,EACvC;AACA,MAAI,CAAC,OAAO,MAAM,CAAC,OAAO,KAAK;AAC7B,YAAQ,MAAM,UAAU,OAAO,SAAS,mBAAmB,EAAE;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,OAAO,GAAG;AACxB;AAEA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAC9C,MAAI,CAAC,IAAI;AACP,YAAQ,MAAM,+DAA+D;AAC7E,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,0BAA0B,EAAE;AAAA,EAC9B;AACA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,kBAAa,EAAE,EAAE;AAC/B;AAgBA,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,WAAW,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AACpD,MAAI;AACJ,MAAI,UAAU;AACZ,QAAI;AACF,gBAAU,MAAM,GAAG,SAAS,UAAU,OAAO;AAAA,IAC/C,SAAS,KAAK;AACZ,cAAQ,MAAM,yBAAyB,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,GAAG,EAAE;AAC9F,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,WAAW,QAAQ,MAAM,SAAS,GAAG;AACnC,cAAU,MAAM,UAAU;AAAA,EAC5B,OAAO;AACL,UAAM,SAAS,YAAY,MAAM,WAAW;AAC5C,QAAI,WAAW,QAAW;AACxB,cAAQ,MAAM,wEAAwE;AACtF,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,cAAU;AAAA,EACZ;AAEA,QAAM,QACJ,YAAY,MAAM,SAAS,MAAM,WAAW,KAAK,SAAS,QAAQ,IAAI;AACxE,QAAM,SAAU,YAAY,MAAM,UAAU,KAA6B;AACzE,QAAM,aAAa,QAAQ,MAAM,UAAU,IAAI,WAAW;AAC1D,QAAM,aAAa,qBAAqB,YAAY,MAAM,OAAO,GAAG,OAAO;AAE3E,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,OAAO,SAAS,QAAQ,YAAY,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC,EAAG;AAAA,EAC9E;AACA,MAAI,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;AAC9B,YAAQ,MAAM,UAAU,OAAO,SAAS,uBAAuB,EAAE;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,QAAQ,MAAM,QAAQ,GAAG;AAC3B,mBAAe,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC,CAAC;AACnD;AAAA,EACF;AACA,UAAQ,IAAI,wBAAmB,OAAO,KAAK,KAAK,MAAM,OAAO,KAAK,UAAU,GAAG;AAC/E,UAAQ,IAAI,SAAS,OAAO,KAAK,EAAE,EAAE;AACrC,MAAI,OAAO,KAAK,QAAS,SAAQ,IAAI,kBAAkB,OAAO,KAAK,OAAO,EAAE;AAAA,MACvE,SAAQ,IAAI,qDAAgD;AACnE;AAEA,eAAe,SAAS,MAAgB,QAAgB,OAA8B;AACpF,QAAM,SAAS,YAAY,MAAM,UAAU;AAC3C,QAAM,KAAK,SAAS,WAAW,mBAAmB,MAAM,CAAC,KAAK;AAC9D,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,uBAAuB,EAAE;AAAA,EAC3B;AACA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,QAAQ,MAAM,QAAQ,GAAG;AAC3B,mBAAe,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC,CAAC;AACnD;AAAA,EACF;AACA,MAAI,OAAO,KAAK,WAAW,GAAG;AAC5B,YAAQ,IAAI,WAAW;AACvB;AAAA,EACF;AACA,aAAW,KAAK,OAAO,MAAM;AAC3B,YAAQ,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE;AAAA,EACrF;AACF;AAEA,eAAe,QAAQ,MAAgB,QAAgB,OAA8B;AACnF,QAAM,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAC9C,MAAI,CAAC,IAAI;AACP,YAAQ,MAAM,gEAAgE;AAC9E,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,wBAAwB,EAAE;AAAA,EAC5B;AACA,MAAI,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;AAC9B,YAAQ,MAAM,UAAU,OAAO,SAAS,gBAAgB,EAAE;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,QAAQ,MAAM,OAAO,GAAG;AAC1B,YAAQ,OAAO,MAAM,OAAO,KAAK,WAAW,EAAE;AAC9C;AAAA,EACF;AACA,MAAI,QAAQ,MAAM,QAAQ,GAAG;AAC3B,mBAAe,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC,CAAC;AACnD;AAAA,EACF;AAEA,iBAAe,GAAG,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,UAAU,KAAK,OAAO,KAAK,MAAM,GAAG;AACxF,iBAAe,SAAS,OAAO,KAAK,EAAE,EAAE;AACxC,MAAI,OAAO,KAAK,QAAS,gBAAe,kBAAkB,OAAO,KAAK,OAAO,EAAE;AAC/E,iBAAe,EAAE;AACjB,iBAAe,OAAO,KAAK,WAAW,EAAE;AAC1C;AAEA,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAC9C,MAAI,CAAC,IAAI;AACP,YAAQ,MAAM,2DAA2D;AACzE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,wBAAwB,EAAE;AAAA,EAC5B;AACA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,kBAAa,EAAE,EAAE;AAC/B;AAIA,eAAe,UAAU,MAAgB,QAAgB,OAA8B;AACrF,QAAM,aAAa,gBAAgB,MAAM,MAAM;AAC/C,QAAM,UAAU,YAAY,MAAM,WAAW;AAC7C,MAAI,WAAW,WAAW,KAAK,CAAC,SAAS;AACvC,YAAQ,MAAM,+GAA+G;AAC7H,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,OAAO,MAAM,YAAY,IAAI;AAEnC,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,YAAY,SAAS,KAAK;AAAA,EAC9B;AACA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,wBAAmB,OAAO,MAAM,QAAQ,WAAW,MAAM,gBAAgB;AACvF;AAEA,eAAe,UAAU,MAAgB,QAAgB,OAA8B;AACrF,QAAM,aAAa,gBAAgB,MAAM,MAAM;AAC/C,MAAI,WAAW,WAAW,GAAG;AAC3B,YAAQ,MAAM,iGAAiG;AAC/G,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,OAAO,MAAM,YAAY,IAAI;AAEnC,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,YAAY,KAAK;AAAA,EACrB;AACA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,gCAA2B,OAAO,MAAM,QAAQ,WAAW,MAAM,gBAAgB;AAC/F;AAIA,eAAe,UAAU,MAAgB,QAAgB,OAA8B;AACrF,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO,aAAa,MAAM,QAAQ,KAAK;AAAA,IACzC,KAAK;AACH,aAAO,WAAW,MAAM,QAAQ,KAAK;AAAA,IACvC,KAAK;AACH,aAAO,UAAU,MAAM,QAAQ,KAAK;AAAA,IACtC,KAAK;AACH,aAAO,aAAa,MAAM,QAAQ,KAAK;AAAA,IACzC;AACE,cAAQ,MAAM,+BAA+B,OAAO,QAAQ,EAAE;AAC9D,gBAAU;AACV,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;AAEA,eAAe,QAAQ,MAAgB,QAAgB,OAA8B;AACnF,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO,WAAW,MAAM,QAAQ,KAAK;AAAA,IACvC,KAAK;AACH,aAAO,SAAS,MAAM,QAAQ,KAAK;AAAA,IACrC,KAAK;AACH,aAAO,QAAQ,MAAM,QAAQ,KAAK;AAAA,IACpC,KAAK;AACH,aAAO,WAAW,MAAM,QAAQ,KAAK;AAAA,IACvC;AACE,cAAQ,MAAM,6BAA6B,OAAO,QAAQ,EAAE;AAC5D,gBAAU;AACV,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;AAEA,eAAsB,aAAa,MAA+B;AAChE,QAAM,CAAC,OAAO,GAAG,IAAI,IAAI;AAEzB,MAAI,CAAC,SAAS,UAAU,UAAU,QAAQ,MAAM,UAAU,IAAI,GAAG;AAC/D,cAAU;AACV;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,cAAc,IAAI;AAElD,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO,UAAU,MAAM,QAAQ,KAAK;AAAA,IACtC,KAAK;AACH,aAAO,QAAQ,MAAM,QAAQ,KAAK;AAAA,IACpC,KAAK;AACH,aAAO,UAAU,MAAM,QAAQ,KAAK;AAAA,IACtC,KAAK;AACH,aAAO,UAAU,MAAM,QAAQ,KAAK;AAAA,IACtC;AACE,cAAQ,MAAM,4BAA4B,KAAK,EAAE;AACjD,gBAAU;AACV,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/remote-test.ts","../src/remote-test-config.ts","../src/remote-test-format.ts"],"sourcesContent":["/**\n * Remote Test Command\n *\n * Triggers workflow tests on the Canary platform and streams results via SSE.\n * Designed for CI/CD pipelines. Exit codes: 0 every runnable test settled with\n * no failures, 1 one or more hard failures, 2 no failures but at least one\n * workflow was inconclusive (the platform never produced a verdict).\n *\n * Usage:\n * canary test-suite run [options]\n *\n * Options:\n * --token <key> API key (or set CANARY_API_TOKEN env var)\n * --api-url <url> API URL (default: https://api.runcofactor.com)\n * --tag <tag> Filter workflows by tag\n * --name-pattern <pat> Filter workflows by name pattern\n * --external-host-shape <shape> Reserve one exact dedicated host for an external v2 suite\n * --verbose, -v Show all events (not just results)\n */\n\nimport process from 'node:process';\nimport { createParser, type EventSourceMessage } from 'eventsource-parser';\nimport type {\n WorkflowTestEvent,\n WorkflowTestStatus,\n WorkflowTestSuiteEvent,\n} from '@chatsdet/types';\nimport { resolveConfig } from './auth';\nimport { resolveTestConfig, type ResolvedConfig } from './remote-test-config';\nimport { resolveTestSuite, UUID_RE } from './cli-helpers.js';\nimport { writeRawOutput } from './brand.js';\nimport {\n buildQueryParams,\n extractWorkflowName,\n formatFailedTests,\n formatExternalRunSummary,\n formatStreamClosedBeforeCompletion,\n formatStreamReadFailure,\n formatSummary,\n formatTestResultLine,\n getArgValue,\n hasFlag,\n trackFailedTest,\n type FailedTestTracker,\n type SuiteSummaryStats,\n} from './remote-test-format';\n\n/** No suite event seen yet — `formatSummary` reads this as \"no workflows\". */\nconst EMPTY_SUITE_STATS: SuiteSummaryStats = {\n totalWorkflows: 0,\n completedWorkflows: 0,\n successfulWorkflows: 0,\n failedWorkflows: 0,\n inconclusiveWorkflows: 0,\n skippedWorkflows: 0,\n degradedWorkflows: 0,\n waitingWorkflows: 0,\n};\n\n\ntype TriggerResponse = {\n ok: boolean;\n jobId?: string;\n suiteId?: string;\n startedAt?: string;\n appUrl?: string;\n error?: string;\n};\n\n/**\n * The message for a refused trigger: a typed user error's own sentence (e.g. why\n * no workflows matched), otherwise the status and raw body.\n */\nfunction formatTriggerFailure(status: number, body: string): string {\n try {\n const parsed = JSON.parse(body) as { userError?: boolean; error?: unknown };\n if (parsed.userError === true && typeof parsed.error === 'string') {\n return `Error: ${parsed.error}`;\n }\n } catch {\n // Not JSON (a proxy error page, say) — fall through to the raw body.\n }\n return `Failed to start tests: ${status}\\n${body}`;\n}\n\n// Export internals for testing\nexport const __internals = {\n getArgValue,\n hasFlag,\n buildQueryParams,\n extractWorkflowName,\n formatSummary,\n formatTestResultLine,\n trackFailedTest,\n formatExternalRunSummary,\n formatFailedTests,\n formatStreamReadFailure,\n formatStreamClosedBeforeCompletion,\n resolveTestConfig,\n UUID_RE,\n triggerNamedSuiteRun,\n};\n\ntype NamedSuiteTrigger =\n | { kind: 'native'; executionId: string; jobId: string; pinnedCommit: string | null }\n | { kind: 'external'; runId: string; jobId: string; runUrl: string };\n\n/**\n * Resolve a `--suite <name|id>` argument to a suite id and trigger a layered\n * run via POST /test-suites/:id/run. Returns the execution id (used as the SSE\n * stream key) and the orchestrator job id.\n */\nasync function triggerNamedSuiteRun(\n apiUrl: string,\n token: string,\n suiteArg: string,\n environmentId: string | undefined,\n environmentMode: 'mixed' | 'force',\n verbose: boolean,\n externalSelection?: { specPath?: string; grep?: string },\n externalAreas?: string[],\n pinnedCommit?: string,\n externalHostShape?: string\n): Promise<NamedSuiteTrigger> {\n const authHeaders = {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n };\n\n // Resolve name → id (exact id is accepted as-is; otherwise match by name).\n const match = await resolveTestSuite(suiteArg, apiUrl, token);\n\n // The name came from the database, so it must bypass console branding — a\n // suite really named \"Canary Smoke\" would otherwise print as \"Cofactor\n // Smoke\". See writeRawOutput's contract in brand.ts.\n writeRawOutput(`Starting test suite: ${match.name}`);\n console.log(` Env mode: ${environmentMode}`);\n if (environmentMode === 'force' && environmentId) console.log(` Environment: ${environmentId}`);\n if (pinnedCommit) console.log(` Pinned at: ${pinnedCommit} (never feeds visual baselines)`);\n console.log('');\n\n const runBody: {\n environmentId?: string;\n environmentMode: 'mixed' | 'force';\n externalSelection?: { specPath?: string; grep?: string };\n externalAreas?: string[];\n externalHostShape?: string;\n at?: string;\n } = {\n environmentMode,\n };\n // `!== undefined`, not truthiness: an empty value must reach the server and be refused, never run unpinned.\n if (pinnedCommit !== undefined) runBody.at = pinnedCommit;\n if (environmentMode === 'force' && environmentId) runBody.environmentId = environmentId;\n if (externalSelection) runBody.externalSelection = externalSelection;\n if (externalAreas) runBody.externalAreas = externalAreas;\n if (externalHostShape !== undefined) runBody.externalHostShape = externalHostShape;\n const runRes = await fetch(`${apiUrl}/test-suites/${match.id}/run`, {\n method: 'POST',\n headers: authHeaders,\n body: JSON.stringify(runBody),\n });\n if (!runRes.ok) {\n const body = await runRes.text();\n // A refused pin says why in `reason`; show it rather than the raw body.\n try {\n const refused = JSON.parse(body) as { userError?: boolean; error?: string; reason?: string };\n if (refused.userError === true && refused.reason) {\n console.error(`Error: ${refused.error ?? 'The suite cannot run'}: ${refused.reason}`);\n process.exit(1);\n }\n } catch {\n // Not JSON (a proxy error page, say): fall through to the raw body.\n }\n console.error(`Failed to start suite: ${runRes.status}`);\n console.error(body);\n process.exit(1);\n }\n const runJson = (await runRes.json()) as {\n ok: boolean;\n data?: NamedSuiteTrigger;\n error?: string;\n };\n if (!runJson.ok || !runJson.data) {\n console.error(`Failed to start suite: ${runJson.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n if (verbose) {\n console.log(\n runJson.data.kind === 'external'\n ? `External run ID: ${runJson.data.runId}`\n : `Execution ID: ${runJson.data.executionId}`\n );\n console.log(`Job ID: ${runJson.data.jobId}`);\n console.log('');\n }\n return runJson.data;\n}\n\nexport async function streamExternalRun(\n apiUrl: string,\n token: string,\n run: Extract<NamedSuiteTrigger, { kind: 'external' }>,\n verbose: boolean\n): Promise<never> {\n const response = await fetch(`${apiUrl}/jobs/${run.runId}/stream`, {\n headers: { Authorization: `Bearer ${token}`, Accept: 'text/event-stream' },\n });\n if (!response.ok || !response.body) {\n console.error(`Failed to connect to external run stream: ${response.status}`);\n process.exit(1);\n }\n\n let sealed = false;\n let exitCode = 1;\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n if (!event.data || !event.event?.startsWith('external-run.')) return;\n try {\n const data = JSON.parse(event.data) as Record<string, unknown>;\n if (verbose) console.log(`[${event.event}] ${JSON.stringify(data)}`);\n if (event.event === 'external-run.shard' && !verbose) {\n console.log(\n ` shard ${String(data.shardIndex)}/${String(data.shardTotal)}: ${String(data.phase)} (attempt ${String(data.attempt)})`\n );\n }\n if (event.event === 'external-run.status' && data.status === 'canceled') {\n sealed = true;\n exitCode = 1;\n console.error('External test run was canceled.');\n }\n if (event.event === 'external-run.sealed') {\n sealed = true;\n const total = Number(data.total ?? 0);\n const passed = Number(data.passed ?? 0);\n const failed = Number(data.failed ?? 0);\n const flaky = Number(data.flaky ?? 0);\n const skipped = Number(data.skipped ?? 0);\n const summary = formatExternalRunSummary({\n total,\n passed,\n failed,\n flaky,\n skipped,\n resultsTruncated: data.resultsTruncated === true,\n });\n console.log('');\n console.log('─'.repeat(50));\n console.log(summary.message);\n console.log(`Run: ${apiUrl.replace(/\\/api\\/?$/, '')}${run.runUrl}`);\n exitCode = summary.exitCode;\n }\n } catch (error) {\n if (verbose) console.error(`Ignored malformed stream event: ${String(error)}`);\n }\n },\n });\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n try {\n while (!sealed) {\n const { done, value } = await reader.read();\n if (done) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n } catch (error) {\n console.error(formatStreamReadFailure(error));\n } finally {\n reader.releaseLock();\n }\n if (!sealed) console.error(formatStreamClosedBeforeCompletion());\n process.exit(exitCode);\n}\n\nexport async function runRemoteTest(argv: string[]): Promise<void> {\n if (argv.some((arg) => arg.startsWith('--external-host-shape='))) {\n console.error('Error: use --external-host-shape <shape> with a space; equals syntax is not supported.');\n process.exit(1);\n }\n const { apiUrl, token } = await resolveConfig(argv);\n\n const tag = getArgValue(argv, '--tag');\n const namePattern = getArgValue(argv, '--name-pattern');\n // \"--application\" is the user-facing flag; \"--property\" stays as a backwards-compat alias.\n const propertyArg = getArgValue(argv, '--application') ?? getArgValue(argv, '--property');\n const environmentArg = getArgValue(argv, '--environment');\n const suiteArg = getArgValue(argv, '--suite');\n const externalSpec = getArgValue(argv, '--external-spec');\n const externalGrep = getArgValue(argv, '--external-grep');\n const externalHostShape = getArgValue(argv, '--external-host-shape');\n if (hasFlag(argv, '--external-host-shape') && (!externalHostShape || externalHostShape.startsWith('--'))) {\n console.error('Error: --external-host-shape needs a provider shape.');\n process.exit(1);\n }\n const areaArg = getArgValue(argv, '--area');\n const verbose = hasFlag(argv, '--verbose', '-v');\n const pinnedCommitArg = getArgValue(argv, '--at');\n // A pin that fails open would run an unpinned suite the caller never asked for.\n if (hasFlag(argv, '--at') && !pinnedCommitArg) {\n console.error('Error: --at needs <sha|pushId|tag>.');\n process.exit(1);\n }\n if (pinnedCommitArg !== undefined && !suiteArg) {\n console.error('Error: --at requires --suite <name|id>.');\n process.exit(1);\n }\n if ((externalSpec || externalGrep || areaArg !== undefined || externalHostShape !== undefined) && !suiteArg) {\n console.error('Error: --area, --external-spec, --external-grep and --external-host-shape require --suite <name|id>.');\n process.exit(1);\n }\n // A spec path already names the tests to run, so it cannot also be narrowed\n // to areas. A title regex can: it is applied inside each area.\n if (areaArg !== undefined && externalSpec) {\n console.error(\n 'Error: --area cannot be combined with --external-spec (a spec path picks its own tests). ' +\n 'Use --external-grep to filter within an area.'\n );\n process.exit(1);\n }\n // One area or several: `--area a,b` fans out one sandbox per area, exactly as\n // a full run does, so the run page still groups by area.\n //\n // Tested for `undefined`, not truthiness: `--area \"\"` parses to the empty\n // string, and treating that as \"no selection\" would quietly run the whole\n // suite when the user plainly asked to narrow it.\n const externalAreas =\n areaArg === undefined\n ? undefined\n : areaArg\n .split(',')\n .map((area) => area.trim())\n .filter((area) => area.length > 0);\n if (externalAreas && externalAreas.length === 0) {\n console.error('Error: --area needs at least one area name.');\n process.exit(1);\n }\n\n // Env mode: 'mixed' (default) runs each flow on its own preferred env; 'force'\n // pins the whole suite to --environment (which then becomes required).\n const envModeArg = getArgValue(argv, '--env-mode');\n if (envModeArg !== undefined && envModeArg !== 'mixed' && envModeArg !== 'force') {\n console.error(`Error: --env-mode must be \"mixed\" or \"force\" (got \"${envModeArg}\").`);\n process.exit(1);\n }\n const environmentMode: 'mixed' | 'force' =\n (envModeArg as 'mixed' | 'force' | undefined) ?? (environmentArg ? 'force' : 'mixed');\n if (environmentMode === 'force' && !environmentArg) {\n console.error('Error: --env-mode force requires --environment <name|id>.');\n process.exit(1);\n }\n\n // 0. Resolve property/environment if specified\n let resolvedConfig: ResolvedConfig = {};\n if (propertyArg || environmentArg) {\n try {\n resolvedConfig = await resolveTestConfig(apiUrl, token, propertyArg, environmentArg);\n } catch (err) {\n console.error(`${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n }\n\n console.log('Starting remote workflow tests...');\n if (resolvedConfig.propertyId) console.log(` Application: ${propertyArg}`);\n if (resolvedConfig.environmentId) console.log(` Environment: ${environmentArg}`);\n if (tag) console.log(` Filtering by tag: ${tag}`);\n if (namePattern) console.log(` Filtering by name pattern: ${namePattern}`);\n console.log('');\n\n let suiteId: string;\n let jobId: string | undefined;\n let appUrl: string | undefined;\n let pinnedCommit: string | null = null;\n\n if (suiteArg) {\n // Named, layered suite run. Resolve name→id, then POST /test-suites/:id/run.\n const triggered = await triggerNamedSuiteRun(\n apiUrl,\n token,\n suiteArg,\n resolvedConfig.environmentId,\n environmentMode,\n verbose,\n externalSpec || externalGrep\n ? { ...(externalSpec ? { specPath: externalSpec } : {}), ...(externalGrep ? { grep: externalGrep } : {}) }\n : undefined,\n externalAreas,\n pinnedCommitArg,\n externalHostShape\n );\n if (triggered.kind === 'external') {\n return await streamExternalRun(apiUrl, token, triggered, verbose);\n }\n pinnedCommit = triggered.pinnedCommit;\n suiteId = triggered.executionId;\n jobId = triggered.jobId;\n } else {\n // 1. Trigger test run\n const queryParams = new URLSearchParams();\n if (tag) queryParams.set('tag', tag);\n if (namePattern) queryParams.set('namePattern', namePattern);\n\n const triggerUrl = `${apiUrl}/workflows/test-runs${queryParams.toString() ? `?${queryParams}` : ''}`;\n\n const body: Record<string, string> = { environmentMode };\n if (resolvedConfig.propertyId) body.propertyId = resolvedConfig.propertyId;\n if (environmentMode === 'force' && resolvedConfig.environmentId)\n body.environmentId = resolvedConfig.environmentId;\n\n let triggerRes: Response;\n try {\n triggerRes = await fetch(triggerUrl, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n });\n } catch (err) {\n console.error(`Failed to connect to API: ${err}`);\n process.exit(1);\n }\n\n if (!triggerRes.ok) {\n console.error(formatTriggerFailure(triggerRes.status, await triggerRes.text()));\n process.exit(1);\n }\n\n const triggerData = (await triggerRes.json()) as TriggerResponse;\n if (!triggerData.ok || !triggerData.suiteId) {\n console.error(`Failed to start tests: ${triggerData.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n suiteId = triggerData.suiteId;\n jobId = triggerData.jobId;\n appUrl = triggerData.appUrl;\n }\n\n if (verbose) {\n console.log(`Suite ID: ${suiteId}`);\n console.log(`Job ID: ${jobId}`);\n console.log('');\n }\n\n // 2. Subscribe to SSE stream\n const streamUrl = `${apiUrl}/workflows/test-runs/stream?suiteId=${suiteId}`;\n\n let streamRes: Response;\n try {\n streamRes = await fetch(streamUrl, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'text/event-stream',\n },\n });\n } catch (err) {\n console.error(`Failed to connect to event stream: ${err}`);\n process.exit(1);\n }\n\n if (!streamRes.ok || !streamRes.body) {\n console.error(`Failed to connect to event stream: ${streamRes.status}`);\n process.exit(1);\n }\n\n // Track state\n let hasCompleted = false;\n const workflowNames = new Map<string, string>();\n const failedTests: FailedTestTracker = new Map();\n // The last suite event wins: its counters are recomputed server-side from the\n // deduplicated latest attempt per test, so they are authoritative over\n // anything this process could tally from the individual test events.\n let suiteStats: SuiteSummaryStats = EMPTY_SUITE_STATS;\n let streamInterrupted = false;\n\n // 3. Parse SSE events\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n if (!event.data) return;\n\n try {\n const data = JSON.parse(event.data) as\n | WorkflowTestEvent\n | WorkflowTestSuiteEvent\n | { error?: string };\n\n if (verbose) {\n console.log(`[${event.event}] ${JSON.stringify(data)}`);\n }\n\n if (event.event === 'workflow-test') {\n const testEvent = data as WorkflowTestEvent;\n const { status, workflowId, message } = testEvent;\n const name =\n workflowNames.get(workflowId) ||\n message?.replace(/^Flow \"(.+)\" .*$/, '$1') ||\n workflowId;\n\n if (message?.startsWith('Flow \"')) {\n const match = message.match(/^Flow \"(.+?)\" /);\n if (match) workflowNames.set(workflowId, match[1]);\n }\n\n // Tracked regardless of verbosity: the \"Failed tests\" section at the\n // end is built from this, and a later attempt's pass retracts an\n // earlier failure here.\n trackFailedTest(failedTests, {\n status,\n workflowId,\n name,\n testRunId: testEvent.testRunId,\n });\n\n if (!verbose) {\n const line = formatTestResultLine({\n status,\n name,\n errorMessage: testEvent.errorMessage,\n skipReason: testEvent.skipReason,\n });\n if (line) console.log(line);\n }\n }\n\n if (event.event === 'workflow-test-suite') {\n const suiteEvent = data as WorkflowTestSuiteEvent;\n suiteStats = suiteEvent;\n\n if (suiteEvent.status === 'completed') {\n hasCompleted = true;\n }\n }\n\n if (event.event === 'error') {\n const errorData = data as { error?: string };\n console.error(`Stream error: ${errorData.error ?? 'Unknown error'}`);\n streamInterrupted = true;\n }\n } catch {\n // Ignore parse errors for keepalive, etc.\n }\n },\n });\n\n const reader = streamRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (!hasCompleted) {\n const { done, value } = await reader.read();\n if (done) {\n if (!hasCompleted) {\n streamInterrupted = true;\n console.error(formatStreamClosedBeforeCompletion());\n }\n break;\n }\n parser.feed(decoder.decode(value, { stream: true }));\n }\n } catch (err) {\n streamInterrupted = true;\n console.error(formatStreamReadFailure(err));\n } finally {\n reader.releaseLock();\n }\n\n // 4. Print summary\n console.log('');\n console.log('─'.repeat(50));\n\n // One rule for the verdict, shared with the unit tests, instead of a second\n // copy of it inline here — the no-workflows case included.\n const summary = formatSummary(suiteStats);\n console.log(summary.message);\n if (pinnedCommit) console.log(`Pinned at: ${pinnedCommit}`);\n\n // A truncated stream makes every counter above a partial read: a workflow\n // that would have failed may simply not have reported yet. Collapse to a\n // plain failure rather than keeping a verdict the partial read cannot\n // support, and say so, so the printed summary and the exit code agree\n // instead of pairing \"PASSED\" with a non-zero exit.\n let exitCode = summary.exitCode;\n if (streamInterrupted) {\n console.log('Result stream did not complete — the summary above is a partial read.');\n exitCode = 1;\n }\n\n const failedSection = formatFailedTests([...failedTests.values()], appUrl);\n if (failedSection) {\n console.log(failedSection);\n }\n\n if (suiteStats.failedWorkflows > 0) {\n console.log('');\n console.log(`Triage: canary triage wait ${suiteId}`);\n }\n\n process.exit(exitCode);\n}\n","import { UUID_RE } from './cli-helpers.js';\n\ntype TestConfigProperty = {\n id: string;\n name: string;\n baseUrl: string;\n environments: Array<{\n id: string;\n name: string;\n url: string;\n isDefault: boolean;\n environmentKindId?: string | null;\n environmentKindName?: string | null;\n }>;\n};\n\ntype TestConfigResponse = {\n ok: boolean;\n properties: TestConfigProperty[];\n error?: string;\n};\n\nexport type ResolvedConfig = {\n propertyId?: string;\n environmentId?: string;\n};\n\nexport async function resolveTestConfig(\n apiUrl: string,\n token: string,\n propertyArg?: string,\n environmentArg?: string\n): Promise<ResolvedConfig> {\n if (!propertyArg && !environmentArg) return {};\n\n const res = await fetch(`${apiUrl}/workflows/test-config`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to fetch test config: ${res.status} ${text}`);\n }\n\n const data = (await res.json()) as TestConfigResponse;\n if (!data.ok || !data.properties) {\n throw new Error(`Failed to fetch test config: ${data.error ?? 'Unknown error'}`);\n }\n\n const { properties } = data;\n let property: TestConfigProperty | undefined;\n\n if (propertyArg) {\n if (UUID_RE.test(propertyArg)) {\n property = properties.find((p) => p.id === propertyArg);\n } else {\n property = properties.find((p) => p.name.toLowerCase() === propertyArg.toLowerCase());\n }\n if (!property) {\n const available = properties.map((p) => ` - ${p.name} (${p.id})`).join('\\n');\n throw new Error(\n `Application \"${propertyArg}\" not found.\\nAvailable applications:\\n${available}`\n );\n }\n } else if (environmentArg) {\n // --environment without --application: auto-resolve if single application\n if (properties.length === 0) {\n throw new Error('No applications found in your organization.');\n }\n if (properties.length > 1) {\n const available = properties.map((p) => ` - ${p.name} (${p.id})`).join('\\n');\n throw new Error(\n `--environment requires --application when multiple applications exist.\\nAvailable applications:\\n${available}`\n );\n }\n property = properties[0];\n }\n\n const result: ResolvedConfig = {};\n if (property) {\n result.propertyId = property.id;\n\n if (environmentArg) {\n let env: TestConfigProperty['environments'][number] | undefined;\n if (UUID_RE.test(environmentArg)) {\n env = property.environments.find((e) => e.id === environmentArg);\n } else {\n env = property.environments.find(\n (e) =>\n e.name.toLowerCase() === environmentArg.toLowerCase() ||\n e.environmentKindName?.toLowerCase() === environmentArg.toLowerCase()\n );\n }\n if (!env) {\n const available = property.environments\n .map((e) => ` - ${e.name}${e.isDefault ? ' (default)' : ''} (${e.id})`)\n .join('\\n');\n throw new Error(\n `Environment \"${environmentArg}\" not found for application \"${property.name}\".\\nAvailable environments:\\n${available}`\n );\n }\n result.environmentId = env.id;\n }\n }\n\n return result;\n}\n","import {\n WORKFLOW_TEST_FAILED_STATUSES,\n WORKFLOW_TEST_SUCCESS_STATUSES,\n type WorkflowTestStatus,\n type WorkflowTestSuiteEvent,\n} from '@chatsdet/types';\n\nexport function getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1 || index >= argv.length - 1) return undefined;\n return argv[index + 1];\n}\n\nexport function hasFlag(argv: string[], ...flags: string[]): boolean {\n return flags.some((flag) => argv.includes(flag));\n}\n\nexport function buildQueryParams(tag?: string, namePattern?: string): string {\n const params = new URLSearchParams();\n if (tag) params.set('tag', tag);\n if (namePattern) params.set('namePattern', namePattern);\n return params.toString();\n}\n\nexport function extractWorkflowName(message: string | undefined, workflowId: string): string {\n if (!message) return workflowId;\n const match = message.match(/^Flow \"(.+?)\" /);\n return match ? match[1] : workflowId;\n}\n\nexport type FailedTest = { name: string; testRunId: string };\n\n/**\n * Failed tests keyed by `workflowId` rather than accumulated in a list.\n *\n * A retried test arrives as a `failed` event followed by a `flaky_success`\n * event for the SAME workflow. Keying by workflow is what lets the later pass\n * remove the earlier failure — an append-only list left the run listed under\n * \"Failed tests\" while the summary line directly above it counted the workflow\n * as a pass.\n *\n * KNOWN LIMITATION: suite scenario expansion fans one workflow out to several\n * test runs in the same execution, which share a `workflowId` and differ only\n * by `scenarioId`. A failing scenario followed by a passing one would therefore\n * retract the failure from this list. The CLI cannot key more precisely today —\n * `WorkflowTestEvent` carries no `scenarioId` over SSE — and keying by\n * `testRunId` instead would break the retry case above, which is the one that\n * actually occurs: of 7,847 production test runs in the 30 days to 2026-09-11,\n * zero had a `scenario_id`. Closing this properly means adding `scenarioId` to\n * the SSE payload, not guessing here. Note the summary COUNTS come from the\n * suite event and stay correct either way; only this list is affected.\n */\nexport type FailedTestTracker = Map<string, FailedTest>;\n\n/**\n * Record or clear one workflow's failure state from a single test event.\n *\n * Only hard failures are listed: `inconclusive`, `skipped` and `degraded` are\n * terminal without being failures (see `WORKFLOW_TEST_FAILED_STATUSES`), and\n * listing them under \"Failed tests\" would overstate what actually broke.\n */\nexport function trackFailedTest(\n tracker: FailedTestTracker,\n event: { status: WorkflowTestStatus; workflowId: string; name: string; testRunId: string }\n): void {\n if (WORKFLOW_TEST_SUCCESS_STATUSES.has(event.status)) {\n tracker.delete(event.workflowId);\n return;\n }\n if (WORKFLOW_TEST_FAILED_STATUSES.has(event.status)) {\n tracker.set(event.workflowId, { name: event.name, testRunId: event.testRunId });\n }\n}\n\n/** Keep a failure message from swamping the result line it annotates. */\nconst ERROR_EXCERPT_LIMIT = 200;\n\nconst excerpt = (text: string | null | undefined): string | null => {\n const trimmed = text?.trim();\n if (!trimmed) return null;\n return trimmed.length > ERROR_EXCERPT_LIMIT\n ? `${trimmed.slice(0, ERROR_EXCERPT_LIMIT)}\\u2026`\n : trimmed;\n};\n\n/**\n * Render one test's result line, or null while the test is still in flight.\n *\n * The `switch` is exhaustive over `WorkflowTestStatus` on purpose: the previous\n * if/else chain covered 4 of the 11 statuses and silently printed nothing for\n * the other 7, so a suite could finish having shown the operator fewer results\n * than it ran. The `never` assignment in the default makes adding a status to\n * the enum a typecheck failure here rather than another silent omission.\n */\nexport function formatTestResultLine(event: {\n status: WorkflowTestStatus;\n name: string;\n errorMessage?: string | null;\n skipReason?: string | null;\n}): string | null {\n const { status, name } = event;\n const detail = excerpt(event.errorMessage);\n const reason = excerpt(event.skipReason);\n\n switch (status) {\n case 'queued':\n case 'running':\n // In-flight: the terminal event for this test is still coming.\n return null;\n case 'waiting':\n return ` \\u23F3 ${name} (waiting for scheduled time)`;\n case 'success':\n return ` \\u2713 ${name}`;\n case 'flaky_success':\n return ` \\u2713 ${name} (flaky \\u2014 passed on retry)`;\n case 'failed':\n return detail ? ` \\u2717 ${name}\\n Error: ${detail}` : ` \\u2717 ${name}`;\n case 'timeout':\n return detail\n ? ` \\u2717 ${name} (timed out)\\n Error: ${detail}`\n : ` \\u2717 ${name} (timed out)`;\n case 'canceled':\n return ` \\u2717 ${name} (canceled)`;\n case 'inconclusive':\n return detail\n ? ` ? ${name} (inconclusive \\u2014 no verdict)\\n Reason: ${detail}`\n : ` ? ${name} (inconclusive \\u2014 no verdict)`;\n case 'skipped':\n return reason ? ` \\u2013 ${name} (skipped: ${reason})` : ` \\u2013 ${name} (skipped)`;\n case 'degraded':\n return ` \\u2013 ${name} (degraded \\u2014 not run)`;\n default: {\n // Compile-time exhaustiveness; at runtime a status from a server newer\n // than this CLI reaches here, and a bare status word is a worse line than\n // none. The suite counters still force exit 2 for it (see formatSummary).\n const exhaustive: never = status;\n void exhaustive;\n return null;\n }\n }\n}\n\nexport function formatFailedTests(\n failedTests: FailedTest[],\n appUrl: string | undefined\n): string | null {\n if (failedTests.length === 0 || !appUrl) return null;\n\n const lines = ['', 'Failed tests:'];\n for (const t of failedTests) {\n lines.push(` \\u2717 ${t.name}`);\n lines.push(` ${appUrl}/runs/tests/${t.testRunId}`);\n }\n return lines.join('\\n');\n}\n\n/** A suite ran, but at least one workflow produced no verdict. */\nexport const EXIT_INCONCLUSIVE = 2;\n\n/**\n * Counters the verdict is computed from — read straight off one\n * `workflow-test-suite` event, so this cannot drift from the wire shape.\n */\nexport type SuiteSummaryStats = Pick<\n WorkflowTestSuiteEvent,\n | 'totalWorkflows'\n | 'completedWorkflows'\n | 'successfulWorkflows'\n | 'failedWorkflows'\n | 'inconclusiveWorkflows'\n | 'skippedWorkflows'\n | 'degradedWorkflows'\n | 'waitingWorkflows'\n>;\n\n/**\n * Summarize a finished suite and decide the process exit code.\n *\n * Three outcomes, not two. A run that produced no verdict — the platform\n * errored before it could check the product — is neither a pass nor a failure;\n * calling it a pass is how production suites that ran 9/9, 10/10 and 12/12\n * inconclusive each reported a green CI build having verified nothing. A real\n * failure still outranks one: a suite with both exits 1, because a product bug\n * is the more actionable signal.\n *\n * The green test is deliberately an INVARIANT rather than a list of the\n * statuses we currently know about: a suite is clean only when every workflow\n * is accounted for as passed, skipped, degraded, or still scheduled. Asking\n * instead whether `inconclusiveWorkflows > 0` would reopen this very bug the\n * day a new no-verdict status gets its own counter column — it would land in\n * neither term and exit 0 silently. Stated this way, anything the CLI cannot\n * account for forces exit 2, including a counter an older server never sent.\n *\n * The explicit `inconclusiveWorkflows` check is kept ALONGSIDE the invariant\n * rather than replaced by it, because the two fail in opposite directions and\n * neither can produce a false green alone. 24 of 2,164 production executions\n * in the 60 days to 2026-09-11 report counters summing ABOVE `totalWorkflows`\n * (overlapping counters), which zeroes `noVerdict` — and would hide a known\n * inconclusive behind an arithmetic artifact if the invariant were the only\n * test. No such execution has a non-zero inconclusive count today; this keeps\n * that from being load-bearing.\n */\nexport function formatSummary(stats: SuiteSummaryStats): { message: string; exitCode: number } {\n const {\n totalWorkflows,\n successfulWorkflows,\n failedWorkflows,\n completedWorkflows,\n inconclusiveWorkflows,\n skippedWorkflows,\n degradedWorkflows,\n waitingWorkflows,\n } = stats;\n\n if (totalWorkflows === 0) {\n return { message: 'No workflows found matching the filter criteria.', exitCode: 0 };\n }\n\n // Clamped per counter, not just on the total: production emits a NEGATIVE\n // `waitingWorkflows` on some executions (six in the 60 days to 2026-09-11,\n // e.g. total 31 / successful 31 / waiting -2 — a server-side counter\n // decremented past zero). Summed raw, that corrupt counter drags the total\n // below `totalWorkflows` and fails an all-green suite, which is a far worse\n // outcome than the miscount it comes from.\n const accountedFor =\n Math.max(0, successfulWorkflows) +\n Math.max(0, failedWorkflows) +\n Math.max(0, skippedWorkflows) +\n Math.max(0, degradedWorkflows) +\n Math.max(0, waitingWorkflows);\n const noVerdict = Math.max(0, totalWorkflows - accountedFor);\n\n const passRate = Math.round((successfulWorkflows / totalWorkflows) * 100);\n const stillWaiting = totalWorkflows - completedWorkflows;\n\n let message: string;\n let exitCode: number;\n\n if (failedWorkflows > 0) {\n message = `FAILED: ${failedWorkflows} of ${totalWorkflows} workflows failed (${passRate}% pass rate)`;\n if (inconclusiveWorkflows > 0) {\n message += `, ${inconclusiveWorkflows} inconclusive`;\n }\n exitCode = 1;\n } else if (noVerdict > 0 || inconclusiveWorkflows > 0) {\n // Whichever term actually fired: when overlapping counters zero `noVerdict`,\n // the inconclusive count is the only honest number left to report.\n const withoutVerdict = Math.max(noVerdict, inconclusiveWorkflows);\n message =\n `INCONCLUSIVE: ${withoutVerdict} of ${totalWorkflows} workflows produced no verdict ` +\n `(${successfulWorkflows} passed)`;\n exitCode = EXIT_INCONCLUSIVE;\n } else {\n message = `PASSED: ${successfulWorkflows} of ${totalWorkflows} workflows passed`;\n exitCode = 0;\n }\n\n if (stillWaiting > 0) {\n message += `\\nNote: ${stillWaiting} workflow(s) are still waiting (scheduled for later)`;\n }\n\n // Counters that sum past the total are impossible, so the verdict above rests\n // on numbers that disagree with each other. Surfaced rather than acted on: all\n // 24 such executions in the 60 days to 2026-09-11 also had failures and so\n // exit 1 regardless, and promoting an overcount to a failure on its own would\n // redden builds over a server-side miscount with no evidence anything is\n // actually wrong with the run.\n if (accountedFor > totalWorkflows) {\n message += `\\nNote: the server reported ${accountedFor} outcomes for ${totalWorkflows} workflows — counters disagree.`;\n }\n\n return { message, exitCode };\n}\n\nexport function formatExternalRunSummary(stats: {\n total: number;\n passed: number;\n failed: number;\n flaky: number;\n skipped: number;\n resultsTruncated: boolean;\n}): { message: string; exitCode: number } {\n const { total, passed, failed, flaky, skipped, resultsTruncated } = stats;\n\n if (resultsTruncated) {\n return {\n message: `FAILED: external run ended with incomplete results (${total} collected)`,\n exitCode: 1,\n };\n }\n if (total === 0) {\n return { message: 'FAILED: external run produced no test results', exitCode: 1 };\n }\n if (failed > 0) {\n return { message: `FAILED: ${failed} of ${total} external tests failed`, exitCode: 1 };\n }\n return {\n message: `PASSED: ${passed} passed, ${flaky} flaky, ${skipped} skipped`,\n exitCode: 0,\n };\n}\n\nexport function formatStreamReadFailure(error: unknown): string {\n const detail = error instanceof Error && error.message.trim() ? ` (${error.message})` : '';\n return [\n `Test result stream ended unexpectedly${detail}.`,\n 'The test suite may still be running in Canary.',\n 'Re-run the command or check the test suite in the app for final status.',\n ].join(' ');\n}\n\nexport function formatStreamClosedBeforeCompletion(): string {\n return [\n 'Test result stream ended before the suite completed.',\n 'The test suite may still be running in Canary.',\n 'Re-run the command or check the test suite in the app for final status.',\n ].join(' ');\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/environment.ts"],"sourcesContent":["/**\n * CLI Environment Management\n *\n * List, create, and set the default environment for an application, including\n * `type='sandbox'` environments backed by a verified sandbox template or by a\n * Sandboxes v2 environment (a repo's `cofactor.sandbox.yaml`). Reuses the\n * existing `/org/properties/:id/environments` endpoints — no new API.\n */\n\nimport process from 'node:process';\nimport { resolveConfig, hasFlag, getArgValue } from './auth.js';\nimport {\n fetchProperties,\n apiRequest,\n UUID_RE,\n readStdin,\n stripOneTrailingNewline,\n} from './cli-helpers.js';\nimport { writeRawOutput } from './brand.js';\nimport { ENV_VAR_NAME, updateEnvVarDefinitions } from './env-var-definitions.js';\n\nexport type EnvironmentItem = {\n id: string;\n name: string;\n type: 'permanent' | 'ephemeral' | 'local' | 'sandbox';\n url: string;\n isDefault: boolean;\n sandboxTemplateId: string | null;\n /** The application definition's environment a Sandboxes v2 environment runs; null for any other. */\n sandboxV2Environment: string | null;\n environmentKindId: string | null;\n environmentKindName: string | null;\n /**\n * Values this environment supplies for the application's declared variables,\n * injected at run time as `$var.ENV.<name>`. Values of variables the property\n * marks sensitive arrive masked, not in the clear.\n */\n envVarValues: Record<string, string>;\n};\n\n/**\n * Flags in `set-var` that consume the following argv entry as their value.\n * Keep in lockstep with the `Set-var options` block in `printHelp` — a\n * value-taking flag missing here has its value parsed as a `NAME=value` pair.\n */\nconst SET_VAR_VALUE_FLAGS = new Set(['--application', '--property', '--environment']);\n\n/**\n * Collect the positional `NAME=value` pairs of a `set-var` invocation, skipping\n * flags and the values they consume (a flag value may itself contain `=`).\n *\n * An empty value is legal — `NAME=` sets the variable to the empty string, which\n * is distinct from leaving it unset.\n */\nexport function parseEnvVarAssignments(argv: string[]): Record<string, string> {\n const assignments: Record<string, string> = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (SET_VAR_VALUE_FLAGS.has(arg)) {\n i++;\n continue;\n }\n if (arg.startsWith('--')) continue;\n\n const separator = arg.indexOf('=');\n if (separator <= 0) {\n throw new Error(`Expected NAME=value, got \"${arg}\".`);\n }\n const name = arg.slice(0, separator);\n // Mirrors the server's `EnvVarValues` name regex so an obvious typo fails\n // before the round trip. The server remains the authority and additionally\n // caps name and value length, which is left to it rather than duplicated.\n if (!ENV_VAR_NAME.test(name)) {\n throw new Error(\n `Invalid variable name \"${name}\" — names must be alphanumeric/underscore and may not start with a digit.`\n );\n }\n // A repeated name is last-wins, matching how the shell treats repeated flags.\n assignments[name] = arg.slice(separator + 1);\n }\n return assignments;\n}\n\n/**\n * `set-var --stdin NAME`: the value of the one bare NAME, read from stdin, so a\n * secret never appears in the command line or shell history. One trailing\n * newline (`\\n` from `echo`, or `\\r\\n`) is dropped; anything else is kept.\n */\nexport function stdinAssignment(argv: string[], stdin: string): Record<string, string> {\n const names: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (SET_VAR_VALUE_FLAGS.has(arg)) {\n i++;\n continue;\n }\n if (!arg.startsWith('--')) names.push(arg);\n }\n if (names.length !== 1 || names[0].includes('=')) {\n throw new Error(\n '--stdin takes one bare NAME (not NAME=value) and reads its value from stdin, e.g. ' +\n '`printf %s \"$TOKEN\" | canary env set-var --application A --environment E --stdin API_TOKEN`.'\n );\n }\n const name = names[0];\n if (!ENV_VAR_NAME.test(name)) {\n throw new Error(\n `Invalid variable name \"${name}\" — names must be alphanumeric/underscore and may not start with a digit.`\n );\n }\n const value = stripOneTrailingNewline(stdin);\n // An empty pipe is far more often an unset shell variable than an intended\n // empty value, and writing it would wipe the stored secret. `NAME=` sets \"\".\n if (value === '') {\n throw new Error(`stdin was empty; nothing to set for ${name}. To set an empty value, pass ${name}= instead.`);\n }\n return { [name]: value };\n}\n\nfunction pad(s: string, n: number): string {\n return s.padEnd(n);\n}\n\nfunction printHelp(): void {\n console.log(\n [\n 'canary environment: Manage application environments (alias: canary env)',\n '',\n 'Sub-commands:',\n ' list [options] List environments for an application',\n ' create [options] Create an environment (incl. sandbox)',\n ' set-default [options] Set an environment as the application default',\n ' set-var [options] NAME=value ... Set per-environment variable values',\n ' set-var [options] --stdin NAME Set one value read from stdin (keeps secrets out of shell history)',\n '',\n 'List options:',\n ' --application <name|id> Application (required; alias: --property)',\n '',\n 'Create options:',\n ' --application <name|id> Application (required; alias: --property)',\n ' --name <name> Environment name (required)',\n ' --stage <name|id> Shared deployment stage (e.g. staging)',\n ' --type <permanent|ephemeral|local|sandbox> Environment type (default: permanent)',\n ' --url <url> Base URL (required unless --type sandbox)',\n ' --sandbox-template <uuid> Backing template (required with --type sandbox)',\n ' --login-path </path> Per-env login path override',\n ' --description <text> Optional description',\n ' --default Set this environment as the application default',\n '',\n 'Set-default options:',\n ' --application <name|id> Application (required; alias: --property)',\n ' --environment <name|id> Environment to make default (required)',\n '',\n 'Set-var options:',\n ' --application <name|id> Application (required; alias: --property)',\n ' --environment <name|id> Environment to update (required)',\n ' --stdin Read the value of the one NAME from stdin',\n ' --sensitive Mark the named variables sensitive on the application',\n ' first (declaring them if needed); their values then',\n ' read back masked. Applies to every environment.',\n '',\n ' Values merge into the environment; variables you do not name keep their',\n ' current value. Injected at run time as $var.ENV.<name>.',\n '',\n ' canary env set-var --application \"Acme Web\" --environment Staging \\\\',\n ' salesforce_url=https://example.my.salesforce.com',\n ' printf %s \"$API_TOKEN\" | canary env set-var --application \"Acme Web\" \\\\',\n ' --environment Staging --sensitive --stdin API_TOKEN',\n '',\n ' To mark an existing variable sensitive without changing its values:',\n ' canary application update \"Acme Web\" --env-var API_TOKEN:sensitive',\n '',\n 'Common options:',\n ' --json Output as JSON',\n '',\n \"Sandboxes v2 environments are not created here: each environment in the application's\",\n 'cofactor.sandbox.yaml becomes one when you run `cofactor sandbox connect` or `cofactor sandbox push`.',\n ].join('\\n')\n );\n}\n\n/** The `--application`/`--property` argument and the application it names, if any. */\nasync function findApplication(argv: string[], apiUrl: string, token: string) {\n const arg = getArgValue(argv, '--application') ?? getArgValue(argv, '--property');\n if (!arg) {\n console.error('Error: --application <name|id> is required.');\n process.exit(1);\n }\n const properties = await fetchProperties(apiUrl, token);\n const match = properties.find((p) => p.id === arg || p.name.toLowerCase() === arg.toLowerCase());\n const notFound = (): never => {\n console.error(`Error: Application \"${arg}\" not found.`);\n if (properties.length > 0) {\n console.error('Available applications:');\n for (const p of properties) console.error(` - ${p.name} (${p.id})`);\n }\n process.exit(1);\n };\n return { arg, match, notFound, names: properties.map((p) => p.name) };\n}\n\n/** Resolve `--application`/`--property` (name or id) to a property id. */\nexport async function resolveApplicationId(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<string> {\n const { match, notFound } = await findApplication(argv, apiUrl, token);\n return match ? match.id : notFound();\n}\n\n/**\n * Resolve `--application`/`--property` for `cofactor sandbox push` and\n * `connect`, creating the application when the name is new: its default\n * environment is its sandbox `default` environment, so no base URL is asked\n * for. An id that matches no application is still an error, not the name of\n * a new one.\n */\nexport async function resolveOrCreateSandboxApplication(\n argv: string[],\n apiUrl: string,\n token: string,\n // `connect` checks what it needs (GitHub, the repository) here, so a refusal creates nothing; `push` has no check.\n beforeCreate?: () => Promise<void>\n): Promise<string> {\n const { arg, match, notFound, names } = await findApplication(argv, apiUrl, token);\n if (match) return match.id;\n // An application id, raw or prefixed (`prop_…`), names an existing application.\n if (UUID_RE.test(arg) || arg.startsWith('prop_')) notFound();\n await beforeCreate?.();\n const created = await apiRequest<{ ok: boolean; id?: string; error?: string }>(apiUrl, token, 'POST', '/org/properties', {\n name: arg,\n defaultEnvironment: { sandboxV2Environment: 'default' },\n });\n if (!created.ok || !created.id) {\n console.error(`Error: creating application \"${arg}\": ${created.error ?? 'unknown error'}`);\n process.exit(1);\n }\n // Said even with --json: a mistyped name makes a new application rather than failing, and if\n // what follows fails, the application stays (a retry under another name may exceed the quota).\n const others = names.length > 0 ? ` The organization's other applications: ${names.join(', ')}.` : '';\n console.error(\n `Created application \"${arg}\"; its sandbox environment \\`default\\` is its default environment. If this fails, re-run with the same --application.${others}`\n );\n return created.id;\n}\n\nexport async function fetchEnvironments(\n propertyId: string,\n apiUrl: string,\n token: string\n): Promise<EnvironmentItem[]> {\n const res = await apiRequest<{ ok: boolean; items?: EnvironmentItem[]; error?: string }>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${propertyId}/environments`\n );\n if (!res.ok) {\n console.error(`Error: ${res.error ?? 'Failed to list environments'}`);\n process.exit(1);\n }\n return res.items ?? [];\n}\n\n/** The Template column: a v1 template id, or the definition environment a v2 one runs. */\nfunction sandboxBacking(e: EnvironmentItem): string {\n if (e.sandboxV2Environment) return `v2 #${e.sandboxV2Environment}`;\n return e.sandboxTemplateId ?? '';\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = await resolveApplicationId(argv, apiUrl, token);\n const items = await fetchEnvironments(propertyId, apiUrl, token);\n\n if (json) {\n writeRawOutput(JSON.stringify(items, null, 2));\n return;\n }\n if (items.length === 0) {\n console.log('No environments found.');\n return;\n }\n console.log(\n `${pad('Name', 28)} ${pad('Stage', 14)} ${pad('Type', 11)} ${pad('Default', 8)} ${pad('URL', 36)} Template`\n );\n for (const e of items) {\n console.log(\n `${pad(e.name, 28)} ${pad(e.environmentKindName ?? '', 14)} ${pad(e.type, 11)} ${pad(e.isDefault ? 'yes' : '', 8)} ` +\n `${pad(e.url || '(none)', 36)} ${sandboxBacking(e)}`\n );\n }\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = await resolveApplicationId(argv, apiUrl, token);\n const name = getArgValue(argv, '--name');\n const type = (getArgValue(argv, '--type') ?? 'permanent') as EnvironmentItem['type'];\n const url = getArgValue(argv, '--url');\n const sandboxTemplateId = getArgValue(argv, '--sandbox-template');\n const loginPath = getArgValue(argv, '--login-path');\n const description = getArgValue(argv, '--description');\n const stage = getArgValue(argv, '--stage');\n const isDefault = hasFlag(argv, '--default');\n\n if (!name) {\n console.error('Error: --name is required.');\n process.exit(1);\n }\n if (type === 'sandbox' && !sandboxTemplateId) {\n console.error(\n \"Error: --type sandbox needs --sandbox-template <uuid>. (A Sandboxes v2 environment comes from the application's cofactor.sandbox.yaml: `cofactor sandbox connect` or `cofactor sandbox push`.)\"\n );\n process.exit(1);\n }\n if (type !== 'sandbox' && !url) {\n console.error(`Error: --url is required for --type ${type}.`);\n process.exit(1);\n }\n\n const body: Record<string, unknown> = { name, type };\n if (url !== undefined) body.url = url;\n if (sandboxTemplateId !== undefined) body.sandboxTemplateId = sandboxTemplateId;\n if (loginPath !== undefined) body.loginPath = loginPath;\n if (description !== undefined) body.description = description;\n if (stage !== undefined) {\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(stage)) {\n body.environmentKindId = stage;\n } else {\n body.environmentKindName = stage;\n }\n }\n if (isDefault) body.isDefault = true;\n\n const result = await apiRequest<{\n ok: boolean;\n item?: EnvironmentItem;\n error?: string;\n /** A Sandboxes v2 definition that failed validation, one entry per problem. */\n issues?: Array<{ path: string; message: string }>;\n }>(apiUrl, token, 'POST', `/org/properties/${propertyId}/environments`, body);\n\n if (!result.ok) {\n if (json) writeRawOutput(JSON.stringify(result, null, 2));\n else {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n for (const issue of result.issues ?? []) console.error(` ${issue.path}: ${issue.message}`);\n }\n process.exit(1);\n }\n if (json) {\n writeRawOutput(JSON.stringify(result, null, 2));\n return;\n }\n console.log(`Created ${type} environment \"${name}\" (${result.item?.id ?? '?'})`);\n}\n\nasync function handleSetDefault(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = await resolveApplicationId(argv, apiUrl, token);\n const envArg = getArgValue(argv, '--environment');\n if (!envArg) {\n console.error('Error: --environment <name|id> is required.');\n process.exit(1);\n }\n\n const items = await fetchEnvironments(propertyId, apiUrl, token);\n const match = resolveEnvironment(items, envArg);\n\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/org/properties/${propertyId}/environments/${match.id}/set-default`\n );\n\n if (!result.ok) {\n if (json) writeRawOutput(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n if (json) {\n writeRawOutput(JSON.stringify({ ok: true, environmentId: match.id }, null, 2));\n return;\n }\n console.log(`Set \"${match.name}\" (${match.id}) as the default environment.`);\n}\n\n/** Resolve `--environment` (name or id) against the application's environments. */\nexport function resolveEnvironment(items: EnvironmentItem[], envArg: string): EnvironmentItem {\n const match = items.find((e) => e.id === envArg || e.name.toLowerCase() === envArg.toLowerCase());\n if (!match) {\n console.error(`Error: Environment \"${envArg}\" not found for this application.`);\n if (items.length > 0) {\n console.error('Available environments:');\n for (const e of items) console.error(` - ${e.name} (${e.id})`);\n }\n process.exit(1);\n }\n return match;\n}\n\nexport async function handleSetVar(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = await resolveApplicationId(argv, apiUrl, token);\n const envArg = getArgValue(argv, '--environment');\n if (!envArg) {\n console.error('Error: --environment <name|id> is required.');\n process.exit(1);\n }\n\n if (hasFlag(argv, '--stdin') && process.stdin.isTTY) {\n console.error('Error: --stdin reads the value from a pipe, e.g. `printf %s \"$TOKEN\" | canary env set-var ... --stdin NAME`.');\n process.exit(1);\n }\n\n let assignments: Record<string, string>;\n try {\n assignments = hasFlag(argv, '--stdin')\n ? stdinAssignment(argv, await readStdin())\n : parseEnvVarAssignments(argv);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n if (Object.keys(assignments).length === 0) {\n console.error('Error: at least one NAME=value assignment is required.');\n process.exit(1);\n }\n\n // Resolved first, so a mistyped --environment changes nothing.\n const items = await fetchEnvironments(propertyId, apiUrl, token);\n const match = resolveEnvironment(items, envArg);\n\n // Marked before the values are written: a value written first would be\n // readable in the clear from the environment list until it was marked.\n if (hasFlag(argv, '--sensitive')) {\n await updateEnvVarDefinitions(\n propertyId,\n Object.keys(assignments).map((name) => ({ name, sensitive: true })),\n apiUrl,\n token\n );\n }\n\n // The update endpoint replaces `envVarValues` wholesale, so the full map goes\n // back or every unlisted variable is destroyed. Masked sensitive values ride\n // along untouched — the server substitutes the stored plaintext for any entry\n // equal to the mask, the same round-trip the UI relies on.\n //\n // This read-then-write is last-writer-wins: a concurrent edit landing between\n // the two calls is overwritten with this snapshot. The endpoint offers no\n // compare-and-swap, so avoid setting variables on one environment from two\n // places at once.\n const envVarValues = { ...match.envVarValues, ...assignments };\n\n const result = await apiRequest<{ ok: boolean; item?: EnvironmentItem; error?: string }>(\n apiUrl,\n token,\n 'PUT',\n `/org/properties/${propertyId}/environments/${match.id}`,\n { envVarValues }\n );\n\n if (!result.ok) {\n if (json) writeRawOutput(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n if (json) {\n writeRawOutput(JSON.stringify(\n { ok: true, environmentId: match.id, envVarValues: result.item?.envVarValues ?? {} },\n null,\n 2\n )\n );\n return;\n }\n const names = Object.keys(assignments).join(', ');\n console.log(`Set ${names} on \"${match.name}\" (${match.id}).`);\n}\n\nexport async function runEnvironment(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n const globalFlags = new Set(['--env', '--api-url', '--token', '--org']);\n const args = rest.filter((arg, i) => {\n if (globalFlags.has(arg)) return false;\n if (i > 0 && globalFlags.has(rest[i - 1])) return false;\n return true;\n });\n\n switch (subCommand) {\n case 'list':\n await handleList(args, apiUrl, token);\n break;\n case 'create':\n await handleCreate(args, apiUrl, token);\n break;\n case 'set-default':\n await handleSetDefault(args, apiUrl, token);\n break;\n case 'set-var':\n await handleSetVar(args, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}