@runcofactor/cli 0.55.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 (248) hide show
  1. package/dist/{account-RHHS7HT4.js → account-CZYZD2JS.js} +5 -5
  2. package/dist/{alert-B5WEOKHP.js → alert-JQ4SDEB7.js} +8 -8
  3. package/dist/{api-catalog-UXONX3BR.js → api-catalog-IWQC35P2.js} +5 -5
  4. package/dist/{api-key-J3A4TJKN.js → api-key-GUDXIIEA.js} +5 -5
  5. package/dist/{attachment-ZQW7DR4G.js → attachment-CPZYOBUB.js} +5 -5
  6. package/dist/{auth-HQGKUZBS.js → auth-DS6MBVEI.js} +3 -3
  7. package/dist/{benchmark-TIKJA32J.js → benchmark-6HPCIQHD.js} +5 -5
  8. package/dist/{blackcat-Z5LNV2GS.js → blackcat-V3L63WFE.js} +3 -3
  9. package/dist/{chunk-JQG3V5E3.js → chunk-2E3STBHS.js} +2 -2
  10. package/dist/{chunk-KL2ARGH6.js → chunk-2OHYMT3A.js} +3 -3
  11. package/dist/{chunk-KL2ARGH6.js.map → chunk-2OHYMT3A.js.map} +1 -1
  12. package/dist/{chunk-W6DL4IP6.js → chunk-3LGCHNBC.js} +2 -2
  13. package/dist/{chunk-BJHAVM7Z.js → chunk-4MFMPC5P.js} +46 -2
  14. package/dist/chunk-4MFMPC5P.js.map +1 -0
  15. package/dist/{chunk-MB4FS35J.js → chunk-56HFZHQM.js} +8 -8
  16. package/dist/{chunk-CZDQVQ57.js → chunk-5OYWNS6D.js} +20 -9
  17. package/dist/chunk-5OYWNS6D.js.map +1 -0
  18. package/dist/{chunk-YTXZUWMN.js → chunk-62EXS76C.js} +6 -6
  19. package/dist/{chunk-QVMGXMP5.js → chunk-6ILWJFKY.js} +368 -6
  20. package/dist/chunk-6ILWJFKY.js.map +1 -0
  21. package/dist/{chunk-6X6ZTDXP.js → chunk-BDOL622T.js} +4 -4
  22. package/dist/{chunk-L4JQ236V.js → chunk-C3CXVX2B.js} +4 -4
  23. package/dist/{chunk-33U56YGD.js → chunk-CWICLBLU.js} +2 -1
  24. package/dist/{chunk-33U56YGD.js.map → chunk-CWICLBLU.js.map} +1 -1
  25. package/dist/{chunk-XM3WTJ7Y.js → chunk-DEVD2WD2.js} +2 -2
  26. package/dist/{chunk-WWUEKQLR.js → chunk-EWK44F6V.js} +3 -3
  27. package/dist/chunk-EWK44F6V.js.map +1 -0
  28. package/dist/{chunk-CQSQNDMV.js → chunk-FNHPTTRF.js} +7 -5
  29. package/dist/chunk-FNHPTTRF.js.map +1 -0
  30. package/dist/{chunk-Z72GWGH2.js → chunk-GCD4EHCD.js} +6 -6
  31. package/dist/{chunk-3KBYI6RR.js → chunk-H6ZMKNP7.js} +3 -3
  32. package/dist/{chunk-5OKCT6LF.js → chunk-IEWAH7W3.js} +5 -5
  33. package/dist/{chunk-TGI2AAOZ.js → chunk-IV4HRGKX.js} +77 -12
  34. package/dist/chunk-IV4HRGKX.js.map +1 -0
  35. package/dist/{chunk-635IQV6B.js → chunk-J2ZQULU3.js} +2 -2
  36. package/dist/{chunk-ZZZ33KTO.js → chunk-K2IDR6FR.js} +3 -3
  37. package/dist/{chunk-YEH7UIUY.js → chunk-KTZRI27M.js} +4 -4
  38. package/dist/{chunk-RV7FZ4ID.js → chunk-L644NMDI.js} +3 -3
  39. package/dist/{chunk-RV7FZ4ID.js.map → chunk-L644NMDI.js.map} +1 -1
  40. package/dist/{chunk-3TZABC7D.js → chunk-LFT7GUWS.js} +63 -17
  41. package/dist/chunk-LFT7GUWS.js.map +1 -0
  42. package/dist/{chunk-QHRWXCON.js → chunk-O7B2IYCZ.js} +11 -11
  43. package/dist/chunk-O7B2IYCZ.js.map +1 -0
  44. package/dist/{chunk-U3MRXQZS.js → chunk-RHWPZKRV.js} +24 -1
  45. package/dist/chunk-RHWPZKRV.js.map +1 -0
  46. package/dist/{chunk-OU4I3MEH.js → chunk-UJSW72LG.js} +3 -3
  47. package/dist/{chunk-R2CRH6JQ.js → chunk-VACACCD6.js} +3 -3
  48. package/dist/{chunk-EGWVL5XA.js → chunk-VMAR67FF.js} +2 -2
  49. package/dist/{chunk-ZH7HWVEE.js → chunk-VMJ7TBVM.js} +2 -2
  50. package/dist/chunk-WRRA4ATV.js +332 -0
  51. package/dist/chunk-WRRA4ATV.js.map +1 -0
  52. package/dist/{chunk-XWJJYZQC.js → chunk-XHEVDABB.js} +2 -2
  53. package/dist/{chunk-SCQVBLNR.js → chunk-XHGF6VC6.js} +4 -4
  54. package/dist/{credential-2IEZDTH3.js → credential-GJW7LGYP.js} +5 -5
  55. package/dist/{credential-template-S5WSOI3P.js → credential-template-UWBYKKWD.js} +5 -5
  56. package/dist/dev-PBW7BSOD.js +605 -0
  57. package/dist/dev-PBW7BSOD.js.map +1 -0
  58. package/dist/{digest-HQGL7H6E.js → digest-XEHGCJM4.js} +8 -8
  59. package/dist/{docs-CJQZVERZ.js → docs-KH4BCEQF.js} +5 -5
  60. package/dist/{doctor-EGK5AB77.js → doctor-FOXXE5SK.js} +3 -3
  61. package/dist/{environment-MWVXYEDU.js → environment-EBDPQTIS.js} +7 -7
  62. package/dist/{eval-F4NORBQI.js → eval-QZSSEICV.js} +67 -27
  63. package/dist/eval-QZSSEICV.js.map +1 -0
  64. package/dist/{exploration-JC7R7KTJ.js → exploration-LCGKRGOQ.js} +5 -5
  65. package/dist/{exploratory-test-BHK5FTMJ.js → exploratory-test-SGECQGIX.js} +6 -6
  66. package/dist/{external-run-UL5CKG54.js → external-run-2AJAI5O7.js} +9 -9
  67. package/dist/{feature-flag-NMO25TZN.js → feature-flag-P7N4WQIH.js} +5 -5
  68. package/dist/{feedback-3JNPSUXS.js → feedback-LAT7TQ2T.js} +6 -6
  69. package/dist/{flow-AYE4RTZN.js → flow-NH2DC6AP.js} +5 -5
  70. package/dist/{github-DM2DCXRY.js → github-FCEKBLXI.js} +6 -6
  71. package/dist/index.js +106 -408
  72. package/dist/index.js.map +1 -1
  73. package/dist/{init-CPDT5XAU.js → init-5U5EZOAW.js} +5 -5
  74. package/dist/{install-JZRNCHMO.js → install-X3UNVXKY.js} +5 -5
  75. package/dist/{issues-GRFJB52C.js → issues-4P6I3YQW.js} +8 -8
  76. package/dist/{knobs-3Y4QXWAD.js → knobs-JKTWJ6ZG.js} +5 -5
  77. package/dist/{landing-ABYL5WVG.js → landing-6AGLKI66.js} +7 -7
  78. package/dist/{list-WG5QB4NK.js → list-TWP2RP33.js} +5 -5
  79. package/dist/{local-KX24OR5Z.js → local-D75QE5TB.js} +7 -7
  80. package/dist/{login-MLJQAIFK.js → login-RBET4TIP.js} +5 -5
  81. package/dist/{mcp-DDTO54XD.js → mcp-562SUUMK.js} +11 -11
  82. package/dist/{metrics-BJLLOSPQ.js → metrics-4WF2GEPA.js} +5 -5
  83. package/dist/{monitor-E2CKGHPM.js → monitor-WJXH54H2.js} +5 -5
  84. package/dist/{perf-IX7JOMUE.js → perf-C6N6P7YG.js} +12 -361
  85. package/dist/perf-C6N6P7YG.js.map +1 -0
  86. package/dist/{product-2ECWM2JN.js → product-CYEQ7HOB.js} +5 -5
  87. package/dist/{product-map-O542LZQL.js → product-map-MSDLIFZY.js} +7 -7
  88. package/dist/{prompts-Y7O4XJ5P.js → prompts-ME53WPN4.js} +5 -5
  89. package/dist/{proofs-TNOBLSRP.js → proofs-D3G6ZUFP.js} +11 -9
  90. package/dist/{property-TZCGOZQG.js → property-5GLJNAVB.js} +29 -10
  91. package/dist/property-5GLJNAVB.js.map +1 -0
  92. package/dist/{psql-M66YSUXW.js → psql-EXAUDU3W.js} +5 -5
  93. package/dist/{record-3JINBRAR.js → record-EE7NGNKY.js} +6 -6
  94. package/dist/{redis-FOIBINYA.js → redis-M4EYWKOJ.js} +5 -5
  95. package/dist/{release-B4VWMVEI.js → release-4KUWVWWC.js} +5 -5
  96. package/dist/{runbook-EYMSE37E.js → runbook-AHU77ANQ.js} +5 -5
  97. package/dist/{sandbox-R6EMGOKR.js → sandbox-FBLJEYA2.js} +1910 -1629
  98. package/dist/sandbox-FBLJEYA2.js.map +1 -0
  99. package/dist/{scenarios-W7YNLBVO.js → scenarios-TU656T2B.js} +5 -5
  100. package/dist/{schedule-EDHQJUUZ.js → schedule-DXJI6SYO.js} +8 -8
  101. package/dist/{session-4N62APNQ.js → session-RUFTJHF4.js} +10 -10
  102. package/dist/{skill-XFGMNOVM.js → skill-ZK76GQ47.js} +7 -7
  103. package/dist/{skill-XFGMNOVM.js.map → skill-ZK76GQ47.js.map} +1 -1
  104. package/dist/skills/cofactor-debug-run/SKILL.md +2 -1
  105. package/dist/skills/cofactor-debug-run/history/2.0.10.md +320 -0
  106. package/dist/skills/cofactor-debug-run/version.json +1 -1
  107. package/dist/{slack-RUAXG6TB.js → slack-M3OKDVMY.js} +6 -6
  108. package/dist/{spec-ZZKMW7ER.js → spec-5MXEBLYR.js} +5 -5
  109. package/dist/{src-OKSAEHQS.js → src-2X5OQRPJ.js} +4 -4
  110. package/dist/{src-DGIVA22K.js → src-72EFBA2R.js} +3 -3
  111. package/dist/{src-ECZWYNSV.js → src-KH6WSBJV.js} +5 -5
  112. package/dist/{src-CQ2YAW7F.js → src-VLV36QYH.js} +127 -20
  113. package/dist/src-VLV36QYH.js.map +1 -0
  114. package/dist/{start-OCZGILRL.js → start-PDYBRB5T.js} +5 -5
  115. package/dist/{status-YTJ6YITG.js → status-VMVPVCDA.js} +5 -5
  116. package/dist/{tag-KBG4SWRL.js → tag-7KTDLPVU.js} +6 -6
  117. package/dist/{task-O6XRMHYE.js → task-QLFYZNKR.js} +6 -6
  118. package/dist/{teams-NFUHS7XI.js → teams-Y7BXCY6P.js} +7 -7
  119. package/dist/{test-suite-6BH3DESN.js → test-suite-6U22AYFG.js} +15 -14
  120. package/dist/test-suite-6U22AYFG.js.map +1 -0
  121. package/dist/{tickets-JU2STK4B.js → tickets-CQDJDNPY.js} +5 -5
  122. package/dist/{trace-NMSGKASJ.js → trace-QDORWXYX.js} +8 -8
  123. package/dist/{triage-JGECJJU5.js → triage-GY7M3UGG.js} +6 -6
  124. package/dist/{trigger-OSPEVCCQ.js → trigger-DLFAORX4.js} +9 -9
  125. package/dist/{update-check-FNP6RFZO.js → update-check-ES6XQ7OF.js} +4 -4
  126. package/dist/{upgrade-3PPBXFAT.js → upgrade-WKEOW5GS.js} +5 -5
  127. package/dist/{usage-QMCU2JIO.js → usage-E6FDTR3W.js} +7 -7
  128. package/dist/{utilities-7VHWTSJT.js → utilities-4Z6YX3L5.js} +6 -6
  129. package/dist/{visual-WIZSPTVK.js → visual-TA6LPVDJ.js} +5 -5
  130. package/dist/{workflow-23HKTJLS.js → workflow-B5FXS2CJ.js} +58 -31
  131. package/dist/workflow-B5FXS2CJ.js.map +1 -0
  132. package/dist/{workflow-cache-ACGM3BOI.js → workflow-cache-MNLEMRMM.js} +16 -16
  133. package/dist/{workflow-cache-convergence-resolve-KEQDQMKL.js → workflow-cache-convergence-resolve-G5HJM6MF.js} +5 -5
  134. package/dist/{workflow-debug-TVLBNRCB.js → workflow-debug-TNBUGSBK.js} +11 -11
  135. package/dist/{workflow-feedback-GB5VPGE2.js → workflow-feedback-G2ZXAUGI.js} +5 -5
  136. package/dist/{workflow-fork-2IPJNR76.js → workflow-fork-6HHOMC2D.js} +5 -5
  137. package/dist/{workflow-promotion-QEQUXVUT.js → workflow-promotion-RG7L6JZT.js} +5 -5
  138. package/dist/{workflow-proposals-KHGTPMD4.js → workflow-proposals-ZNF2F3UE.js} +5 -5
  139. package/dist/{workflow-revisions-F5KQEEXB.js → workflow-revisions-TP64Z6FO.js} +5 -5
  140. package/dist/{workflow-status-66HC5MEA.js → workflow-status-5RG3JX56.js} +5 -5
  141. package/package.json +3 -2
  142. package/dist/chunk-3TZABC7D.js.map +0 -1
  143. package/dist/chunk-BJHAVM7Z.js.map +0 -1
  144. package/dist/chunk-CQSQNDMV.js.map +0 -1
  145. package/dist/chunk-CZDQVQ57.js.map +0 -1
  146. package/dist/chunk-QHRWXCON.js.map +0 -1
  147. package/dist/chunk-QVMGXMP5.js.map +0 -1
  148. package/dist/chunk-TGI2AAOZ.js.map +0 -1
  149. package/dist/chunk-U3MRXQZS.js.map +0 -1
  150. package/dist/chunk-WWUEKQLR.js.map +0 -1
  151. package/dist/eval-F4NORBQI.js.map +0 -1
  152. package/dist/perf-IX7JOMUE.js.map +0 -1
  153. package/dist/property-TZCGOZQG.js.map +0 -1
  154. package/dist/sandbox-R6EMGOKR.js.map +0 -1
  155. package/dist/src-CQ2YAW7F.js.map +0 -1
  156. package/dist/test-suite-6BH3DESN.js.map +0 -1
  157. package/dist/workflow-23HKTJLS.js.map +0 -1
  158. /package/dist/{account-RHHS7HT4.js.map → account-CZYZD2JS.js.map} +0 -0
  159. /package/dist/{alert-B5WEOKHP.js.map → alert-JQ4SDEB7.js.map} +0 -0
  160. /package/dist/{api-catalog-UXONX3BR.js.map → api-catalog-IWQC35P2.js.map} +0 -0
  161. /package/dist/{api-key-J3A4TJKN.js.map → api-key-GUDXIIEA.js.map} +0 -0
  162. /package/dist/{attachment-ZQW7DR4G.js.map → attachment-CPZYOBUB.js.map} +0 -0
  163. /package/dist/{auth-HQGKUZBS.js.map → auth-DS6MBVEI.js.map} +0 -0
  164. /package/dist/{benchmark-TIKJA32J.js.map → benchmark-6HPCIQHD.js.map} +0 -0
  165. /package/dist/{blackcat-Z5LNV2GS.js.map → blackcat-V3L63WFE.js.map} +0 -0
  166. /package/dist/{chunk-JQG3V5E3.js.map → chunk-2E3STBHS.js.map} +0 -0
  167. /package/dist/{chunk-W6DL4IP6.js.map → chunk-3LGCHNBC.js.map} +0 -0
  168. /package/dist/{chunk-MB4FS35J.js.map → chunk-56HFZHQM.js.map} +0 -0
  169. /package/dist/{chunk-YTXZUWMN.js.map → chunk-62EXS76C.js.map} +0 -0
  170. /package/dist/{chunk-6X6ZTDXP.js.map → chunk-BDOL622T.js.map} +0 -0
  171. /package/dist/{chunk-L4JQ236V.js.map → chunk-C3CXVX2B.js.map} +0 -0
  172. /package/dist/{chunk-XM3WTJ7Y.js.map → chunk-DEVD2WD2.js.map} +0 -0
  173. /package/dist/{chunk-Z72GWGH2.js.map → chunk-GCD4EHCD.js.map} +0 -0
  174. /package/dist/{chunk-3KBYI6RR.js.map → chunk-H6ZMKNP7.js.map} +0 -0
  175. /package/dist/{chunk-5OKCT6LF.js.map → chunk-IEWAH7W3.js.map} +0 -0
  176. /package/dist/{chunk-635IQV6B.js.map → chunk-J2ZQULU3.js.map} +0 -0
  177. /package/dist/{chunk-ZZZ33KTO.js.map → chunk-K2IDR6FR.js.map} +0 -0
  178. /package/dist/{chunk-YEH7UIUY.js.map → chunk-KTZRI27M.js.map} +0 -0
  179. /package/dist/{chunk-OU4I3MEH.js.map → chunk-UJSW72LG.js.map} +0 -0
  180. /package/dist/{chunk-R2CRH6JQ.js.map → chunk-VACACCD6.js.map} +0 -0
  181. /package/dist/{chunk-EGWVL5XA.js.map → chunk-VMAR67FF.js.map} +0 -0
  182. /package/dist/{chunk-ZH7HWVEE.js.map → chunk-VMJ7TBVM.js.map} +0 -0
  183. /package/dist/{chunk-XWJJYZQC.js.map → chunk-XHEVDABB.js.map} +0 -0
  184. /package/dist/{chunk-SCQVBLNR.js.map → chunk-XHGF6VC6.js.map} +0 -0
  185. /package/dist/{credential-2IEZDTH3.js.map → credential-GJW7LGYP.js.map} +0 -0
  186. /package/dist/{credential-template-S5WSOI3P.js.map → credential-template-UWBYKKWD.js.map} +0 -0
  187. /package/dist/{digest-HQGL7H6E.js.map → digest-XEHGCJM4.js.map} +0 -0
  188. /package/dist/{docs-CJQZVERZ.js.map → docs-KH4BCEQF.js.map} +0 -0
  189. /package/dist/{doctor-EGK5AB77.js.map → doctor-FOXXE5SK.js.map} +0 -0
  190. /package/dist/{environment-MWVXYEDU.js.map → environment-EBDPQTIS.js.map} +0 -0
  191. /package/dist/{exploration-JC7R7KTJ.js.map → exploration-LCGKRGOQ.js.map} +0 -0
  192. /package/dist/{exploratory-test-BHK5FTMJ.js.map → exploratory-test-SGECQGIX.js.map} +0 -0
  193. /package/dist/{external-run-UL5CKG54.js.map → external-run-2AJAI5O7.js.map} +0 -0
  194. /package/dist/{feature-flag-NMO25TZN.js.map → feature-flag-P7N4WQIH.js.map} +0 -0
  195. /package/dist/{feedback-3JNPSUXS.js.map → feedback-LAT7TQ2T.js.map} +0 -0
  196. /package/dist/{flow-AYE4RTZN.js.map → flow-NH2DC6AP.js.map} +0 -0
  197. /package/dist/{github-DM2DCXRY.js.map → github-FCEKBLXI.js.map} +0 -0
  198. /package/dist/{init-CPDT5XAU.js.map → init-5U5EZOAW.js.map} +0 -0
  199. /package/dist/{install-JZRNCHMO.js.map → install-X3UNVXKY.js.map} +0 -0
  200. /package/dist/{issues-GRFJB52C.js.map → issues-4P6I3YQW.js.map} +0 -0
  201. /package/dist/{knobs-3Y4QXWAD.js.map → knobs-JKTWJ6ZG.js.map} +0 -0
  202. /package/dist/{landing-ABYL5WVG.js.map → landing-6AGLKI66.js.map} +0 -0
  203. /package/dist/{list-WG5QB4NK.js.map → list-TWP2RP33.js.map} +0 -0
  204. /package/dist/{local-KX24OR5Z.js.map → local-D75QE5TB.js.map} +0 -0
  205. /package/dist/{login-MLJQAIFK.js.map → login-RBET4TIP.js.map} +0 -0
  206. /package/dist/{mcp-DDTO54XD.js.map → mcp-562SUUMK.js.map} +0 -0
  207. /package/dist/{metrics-BJLLOSPQ.js.map → metrics-4WF2GEPA.js.map} +0 -0
  208. /package/dist/{monitor-E2CKGHPM.js.map → monitor-WJXH54H2.js.map} +0 -0
  209. /package/dist/{product-2ECWM2JN.js.map → product-CYEQ7HOB.js.map} +0 -0
  210. /package/dist/{product-map-O542LZQL.js.map → product-map-MSDLIFZY.js.map} +0 -0
  211. /package/dist/{prompts-Y7O4XJ5P.js.map → prompts-ME53WPN4.js.map} +0 -0
  212. /package/dist/{proofs-TNOBLSRP.js.map → proofs-D3G6ZUFP.js.map} +0 -0
  213. /package/dist/{psql-M66YSUXW.js.map → psql-EXAUDU3W.js.map} +0 -0
  214. /package/dist/{record-3JINBRAR.js.map → record-EE7NGNKY.js.map} +0 -0
  215. /package/dist/{redis-FOIBINYA.js.map → redis-M4EYWKOJ.js.map} +0 -0
  216. /package/dist/{release-B4VWMVEI.js.map → release-4KUWVWWC.js.map} +0 -0
  217. /package/dist/{runbook-EYMSE37E.js.map → runbook-AHU77ANQ.js.map} +0 -0
  218. /package/dist/{scenarios-W7YNLBVO.js.map → scenarios-TU656T2B.js.map} +0 -0
  219. /package/dist/{schedule-EDHQJUUZ.js.map → schedule-DXJI6SYO.js.map} +0 -0
  220. /package/dist/{session-4N62APNQ.js.map → session-RUFTJHF4.js.map} +0 -0
  221. /package/dist/{slack-RUAXG6TB.js.map → slack-M3OKDVMY.js.map} +0 -0
  222. /package/dist/{spec-ZZKMW7ER.js.map → spec-5MXEBLYR.js.map} +0 -0
  223. /package/dist/{src-DGIVA22K.js.map → src-2X5OQRPJ.js.map} +0 -0
  224. /package/dist/{src-ECZWYNSV.js.map → src-72EFBA2R.js.map} +0 -0
  225. /package/dist/{src-OKSAEHQS.js.map → src-KH6WSBJV.js.map} +0 -0
  226. /package/dist/{start-OCZGILRL.js.map → start-PDYBRB5T.js.map} +0 -0
  227. /package/dist/{status-YTJ6YITG.js.map → status-VMVPVCDA.js.map} +0 -0
  228. /package/dist/{tag-KBG4SWRL.js.map → tag-7KTDLPVU.js.map} +0 -0
  229. /package/dist/{task-O6XRMHYE.js.map → task-QLFYZNKR.js.map} +0 -0
  230. /package/dist/{teams-NFUHS7XI.js.map → teams-Y7BXCY6P.js.map} +0 -0
  231. /package/dist/{tickets-JU2STK4B.js.map → tickets-CQDJDNPY.js.map} +0 -0
  232. /package/dist/{trace-NMSGKASJ.js.map → trace-QDORWXYX.js.map} +0 -0
  233. /package/dist/{triage-JGECJJU5.js.map → triage-GY7M3UGG.js.map} +0 -0
  234. /package/dist/{trigger-OSPEVCCQ.js.map → trigger-DLFAORX4.js.map} +0 -0
  235. /package/dist/{update-check-FNP6RFZO.js.map → update-check-ES6XQ7OF.js.map} +0 -0
  236. /package/dist/{upgrade-3PPBXFAT.js.map → upgrade-WKEOW5GS.js.map} +0 -0
  237. /package/dist/{usage-QMCU2JIO.js.map → usage-E6FDTR3W.js.map} +0 -0
  238. /package/dist/{utilities-7VHWTSJT.js.map → utilities-4Z6YX3L5.js.map} +0 -0
  239. /package/dist/{visual-WIZSPTVK.js.map → visual-TA6LPVDJ.js.map} +0 -0
  240. /package/dist/{workflow-cache-ACGM3BOI.js.map → workflow-cache-MNLEMRMM.js.map} +0 -0
  241. /package/dist/{workflow-cache-convergence-resolve-KEQDQMKL.js.map → workflow-cache-convergence-resolve-G5HJM6MF.js.map} +0 -0
  242. /package/dist/{workflow-debug-TVLBNRCB.js.map → workflow-debug-TNBUGSBK.js.map} +0 -0
  243. /package/dist/{workflow-feedback-GB5VPGE2.js.map → workflow-feedback-G2ZXAUGI.js.map} +0 -0
  244. /package/dist/{workflow-fork-2IPJNR76.js.map → workflow-fork-6HHOMC2D.js.map} +0 -0
  245. /package/dist/{workflow-promotion-QEQUXVUT.js.map → workflow-promotion-RG7L6JZT.js.map} +0 -0
  246. /package/dist/{workflow-proposals-KHGTPMD4.js.map → workflow-proposals-ZNF2F3UE.js.map} +0 -0
  247. /package/dist/{workflow-revisions-F5KQEEXB.js.map → workflow-revisions-TP64Z6FO.js.map} +0 -0
  248. /package/dist/{workflow-status-66HC5MEA.js.map → workflow-status-5RG3JX56.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sandbox.ts","../src/sandbox-emulation.ts","../src/sandbox-logs.ts","../src/sandbox-preview.ts","../src/sandbox-v2.ts","../../sandbox-helper/src/manifest.ts","../../sandbox-helper/src/object-storage.ts","../../sandbox-helper/src/sync-protocol.ts","../../sandbox-helper/src/emulation-refs.ts","../src/sandbox-push.ts","../src/sandbox-push-syncable.ts","../../sandbox-helper/src/image-archive.ts","../src/sandbox-sync.ts","../src/sandbox-refresh.ts","../src/sandbox-warm.ts","../src/sandbox-secrets.ts"],"sourcesContent":["/**\n * CLI Sandbox Management\n *\n * Create, provision, and manage sandbox templates and instances.\n * Drive template authoring through artifact uploads, command execution,\n * and diagnostics — designed for Claude Code to iterate on sandbox setup.\n */\n\nimport process from 'node:process';\nimport { readFileSync } from 'node:fs';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, getArgValues, getGuideSectionArg, selectProperty } from './cli-helpers.js';\nimport { splitAtSeparator } from './argv.js';\nimport { apiFetch, isTerminalFailure, exitOnFailure } from './api-fetch.js';\nimport { SANDBOX_GUIDE_SECTIONS } from '@chatsdet/content';\nimport { SANDBOX_V2_GUIDE_SECTIONS } from '@chatsdet/content/sandbox-v2-guide';\nimport { printServedGuide } from './guide.js';\nimport {\n INSTANCE_SIZES,\n INSTANCE_SIZE_SPEC,\n SANDBOX_EGRESS_MODES,\n parseInstanceSize,\n type InstanceSize,\n type SandboxEgressAllowlist,\n type SandboxEgressMode,\n} from '@chatsdet/types';\nimport { getPluginIds } from '@chatsdet/emulation/plugins';\nimport { handleEmulation } from './sandbox-emulation.js';\nimport { handleLogs } from './sandbox-logs.js';\nimport { handlePreview } from './sandbox-preview.js';\nimport {\n handleSandboxClaim,\n handleSandboxConnect,\n handleSandboxDestroy,\n handleSandboxEnvs,\n handleSandboxExec,\n handleSandboxRun,\n handleSandboxClaims,\n handleSandboxShow,\n handleSandboxValidate,\n handleSandboxVerifyEnv,\n rejectUnknownSandboxV2Args,\n v2Positionals,\n} from './sandbox-v2.js';\nimport { handleSandboxPush } from './sandbox-push.js';\nimport { handleSandboxSync } from './sandbox-sync.js';\nimport { handleSandboxRefresh } from './sandbox-refresh.js';\nimport { handleSandboxWarm, isSandboxV2WarmCommand } from './sandbox-warm.js';\nimport { handleSandboxSecret } from './sandbox-secrets.js';\nimport { writeRawOutput } from './brand.js';\nexport {\n withEmulationMaster,\n withPluginConfig,\n withPluginEnabled,\n withoutPlugin,\n} from './sandbox-emulation.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype Template = {\n id: string;\n name: string;\n propertyId: string | null;\n repositoryFullName: string | null;\n branch: string;\n subdirectory: string | null;\n status: string;\n checklistProfile: string | null;\n configSchema: Array<{ key: string; description?: string; required: boolean; sensitive: boolean }> | null;\n configDefaults: Record<string, string> | null;\n configuredSensitiveKeys?: string[];\n configuredSensitiveAutoConfigKeys?: string[];\n createdAt: string;\n updatedAt: string;\n};\n\ntype GitHubRepo = {\n id: string;\n repoFullName: string;\n repoName: string;\n defaultBranch: string;\n rootDir: string | null;\n agentHint: string | null;\n};\n\ntype Instance = {\n id: string;\n templateId: string;\n name: string;\n status: string;\n hostUrl: string | null;\n isPrivate: boolean;\n expiresAt: string | null;\n createdAt: string;\n /**\n * What the instance is for. `flow_authoring` is the org-shared instance the\n * Flow Designer auto-spins and that sandbox workflow runs reuse — surfaced in\n * `sandbox list` so agents can find/warm it.\n */\n purpose?: string | null;\n};\n\nexport const parseEgressMode = (value: string | undefined): SandboxEgressMode => {\n if (!value) return 'off';\n if ((SANDBOX_EGRESS_MODES as readonly string[]).includes(value)) {\n return value as SandboxEgressMode;\n }\n console.error(\n `Error: invalid --egress-mode '${value}'. Must be one of: ${SANDBOX_EGRESS_MODES.join(', ')}`\n );\n process.exit(1);\n};\n\nexport const parseEgressAllowlist = (argv: string[]): SandboxEgressAllowlist => {\n const rawEntries = getArgValues(argv, '--egress-allow')\n .flatMap((value) => value.split(','))\n .map((value) => value.trim())\n .filter(Boolean);\n\n return rawEntries.map((entry) => {\n const separator = entry.indexOf(':');\n if (separator <= 0) {\n console.error(\n `Error: invalid --egress-allow '${entry}'. Use domain:example.com or cidr:203.0.113.0/24`\n );\n process.exit(1);\n }\n const kind = entry.slice(0, separator);\n const value = entry.slice(separator + 1);\n if (kind !== 'domain' && kind !== 'cidr') {\n console.error(`Error: invalid --egress-allow kind '${kind}'. Must be domain or cidr.`);\n process.exit(1);\n }\n return { kind, value };\n });\n};\n\ntype Artifact = {\n id: string;\n taskId: string;\n artifactType: string;\n filename: string;\n content?: string;\n createdAt: string;\n updatedAt: string;\n};\n\ntype ChecklistItem = {\n id: string;\n label: string;\n description: string;\n dependsOn: string[];\n producesArtifacts: string[];\n agentAutomatable: boolean;\n itemStatus: { status: string; startedAt?: string; completedAt?: string; summary?: string; error?: string };\n actionable: boolean;\n artifacts: Array<{ artifactType: string; filename: string }>;\n};\n\ntype CommandOrError =\n | { stdout: string; stderr: string; exitCode: number }\n | { error: string; code?: string };\n\ntype DiagnosticsResult = {\n instance: Record<string, unknown>;\n lifecycle?: {\n databaseStatus: string;\n poolStatus: string | null;\n ec2InstanceState: string | null;\n live: boolean;\n message: string | null;\n };\n docker: CommandOrError;\n git: CommandOrError;\n disk: CommandOrError;\n resources?: CommandOrError;\n agentHealth: CommandOrError;\n appHealth: CommandOrError;\n provision?: {\n phase: string;\n jobStatus: string;\n startedAt?: string;\n elapsedSeconds: number | null;\n lastError?: string;\n };\n};\n\ntype ServiceRoute = { service: string; route: string; port: string };\n\nasync function fetchInstanceRoutes(apiUrl: string, token: string, instanceId: string): Promise<ServiceRoute[]> {\n const res = await apiRequest<{ ok: boolean; error?: string; data: { routes: ServiceRoute[] } }>(\n apiUrl, token, 'GET', `/org/environments/instances/${instanceId}/routes`,\n undefined,\n { timeoutMs: 30_000 }\n );\n return res.ok ? res.data.routes : [];\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst STATUS_ICONS: Record<string, string> = {\n completed: '[done]',\n running: '[....]',\n pending: '[ ]',\n failed: '[FAIL]',\n skipped: '[skip]',\n};\n\nfunction formatDate(iso: string): string {\n return new Date(iso).toLocaleString();\n}\n\nfunction pad(s: string, n: number): string {\n return s.padEnd(n);\n}\n\nconst INSTANCE_SIZE_HELP_LINES = INSTANCE_SIZES.map((size) => {\n const spec = INSTANCE_SIZE_SPEC[size];\n return ` ${pad(size, 8)} ${spec.ec2InstanceType} · ${spec.vcpu} vCPU · ${spec.memoryMiB / 1024} GiB`;\n});\n\n// ---------------------------------------------------------------------------\n// Help\n// ---------------------------------------------------------------------------\n\nfunction printHelp(): void {\n console.log(\n [\n 'cofactor sandbox: Live, seeded copies of an application (Sandboxes v2), plus the legacy v1 templates and instances',\n '',\n 'Sandboxes v2 (start here: an application\\'s cofactor.sandbox.yaml — see \"cofactor sandbox guide\"):',\n ' validate [file] [--upload] Offline schema + cross-check (default ./cofactor.sandbox.yaml; --upload: for pushed images)',\n ' connect --application <a> --repo <owner/name> [--dir <path>] Build the application\\'s sandboxes from a GitHub repo',\n ' push --application <a> <image> [options] Push a built image as the application\\'s next version (see \"Push options\" below)',\n ' (connect and push create the application when <a> is a new name; its sandbox is its default environment)',\n ' envs --application <a> The application\\'s delivery, version, environment heads, environments, actions, operations',\n ' refresh --application <a> [--environment <e>] [--wait] [--json] Move the environment\\'s head to the default branch\\'s head / push head now (see \"Refresh options\" below)',\n ' secret set <NAME> --application <a> [--environment <e>] Set a secret from stdin (see \"Secret options\" below)',\n ' secret list --application <a> List an application\\'s secrets (names and scope, never values)',\n ' secret rm <NAME> --application <a> [--environment <e>] Remove a secret',\n ' claim --application <a> [options] Claim a sandbox (see \"Claim options\" below)',\n ' claims [--application <a>] [--json] The sandboxes you claimed that are still live: id, application, environment, status, expiry',\n ' show <id> Status, URLs, logins, seed outputs, actions and operations',\n ' run <id> <action|plugin.op> [options] Run a repo action or emulator operation (see \"Run options\" below)',\n ' exec <id> [--timeout S] [--json] -- <command...> Run one shell command in a claimed sandbox (see \"Exec options\" below)',\n ' sync <id> [--build] [--json] Make a sandbox you claimed match your working tree, uncommitted changes included',\n ' sync <id> <local-dir> --to <path> Mirror local build output into <path> in the sandbox (see \"Sync options\" below)',\n ' destroy <id> Tear a claimed sandbox down',\n ' warm list|set|show|clear [options] Keep an environment warm so claims start in about a second (staff only; see \"Warm options\" below)',\n ' verify-env --application <a> [options] Claim each environment of the current version, sign its personas in, destroy',\n ' preview --application <a> --pr <n> A pull request\\'s preview and its logins',\n ' guide [topic] Show the Sandboxes v2 guide (`guide v2 [topic]` is the same)',\n ` topics: ${SANDBOX_V2_GUIDE_SECTIONS.map((section) => section.slug).join(', ')}`,\n ' (setting up a new application: start with `guide feasibility`;',\n ' pushing a built image: `guide upload`)',\n '',\n 'Refresh options (Sandboxes v2):',\n ' --environment <name> Environment to refresh (default: \"default\")',\n ' --wait Block until the new head\\'s snapshot is ready or failed',\n ' The head is what flow runs, the flow designer, scheduled runs and unpinned claims use: the ready snapshot of the',\n ' default branch\\'s head commit (GitHub) or the newest push tagged main or nightly (the newest push before either). It also refreshes every 6 hours; this does it now.',\n '',\n 'Push options (Sandboxes v2):',\n ' --definition <file> The cofactor.sandbox.yaml to push with the image (default: ./cofactor.sandbox.yaml)',\n ' --tag <tag> Name this push (repeatable); a tag always names the newest push carrying it',\n ' --wait Block until Cofactor has imported (booted) the image',\n '',\n 'Claim options (Sandboxes v2):',\n ' --environment <name> Environment to claim (default: \"default\")',\n ' --at <version> A commit SHA, or a push id or tag (default: the default branch head / push head)',\n ' --timeout <duration> The claim\\'s time limit: not ready by then, it fails (e.g. 45m, 3h; default 2h,',\n ' 1m to 24h). A failure in your own build or seeds fails it at once.',\n ' --wait Block until the sandbox is ready or failed, then print `show`',\n '',\n 'Secret options (Sandboxes v2):',\n ' --environment <name> Set or remove the secret for this environment only (default: all environments)',\n ' The value is read from stdin, never an argument: printf %s \"$KEY\" | cofactor sandbox secret set NAME --application <a>',\n ' Services read it as an environment variable on every claim; it is never shown again.',\n '',\n 'Run options (Sandboxes v2):',\n ' --input <key>=<value> Set an input (repeatable), coerced to the action/operation\\'s declared type',\n ' --json-input \\'{...}\\' Full input as JSON (overrides --input)',\n '',\n 'Warm options (Sandboxes v2, superadmin):',\n ' warm list Every environment kept warm on this stage',\n ' warm set --application <a> --environment <e> --slots <1-12> [--tag <t>] Turn on, or change slots or tag (--tag: pushed applications only, and required)',\n ' warm show --application <a> --environment <e> Filling / On / Switching / Needs attention, and the free warm slots now',\n ' warm clear --application <a> --environment <e> Turn off and release the capacity',\n ' --target-org <id> Act in another org (give the application by id); default: your session\\'s org',\n '',\n 'Exec options (Sandboxes v2):',\n ' --timeout <seconds> Kill the command after this long (default 300, max 1800); exit code 124',\n ' Everything after `--` is the command, joined with spaces (ssh semantics): quote pipes and',\n ' redirects yourself, e.g. -- \\'ls | wc -l\\'. Output is the last 4000 characters of each stream,',\n ' scrubbed of the sandbox\\'s secrets. Exits with the command\\'s exit code. Needs the `sandbox:exec` scope for API keys.',\n '',\n 'Sync options (Sandboxes v2; see \"cofactor sandbox guide local\"):',\n ' Syncs into a sandbox you claimed with `claim`, straight to the sandbox. It lists what it writes (untracked files',\n ' included) and deletes, then applies. A file only the sandbox has is deleted only if it is not ignored here and',\n ' was once tracked at that path; everything else (node_modules/, build output) is kept. Each sync extends the',\n ' sandbox\\'s lease, up to 8 h after the claim. Needs the `sandbox:exec` scope for API keys.',\n ' Root: the repository (GitHub) or the directory holding cofactor.sandbox.yaml (pushed: its WORKDIR mirrors it).',\n ' --build Rerun the definition\\'s build steps whose inputs changed and restart after_build services',\n ' --to <path> With <local-dir>: mirror it into <path> under the sync root, ignore rules aside',\n ' (e.g. `bun run build`, then `sync <id> frontend/dist --to static`)',\n ' Nothing restarts on its own: `cofactor sandbox exec <id> -- cofactor-sandbox restart <service>`.',\n '',\n 'Verify-env options (Sandboxes v2):',\n ' --environment <name> Verify only this environment (default: every environment in the definition)',\n '',\n 'Sandboxes v1 (legacy templates and instances):',\n ' guide v1 [section] Show the v1 sandbox authoring guide',\n ' list List templates and instances',\n ' template [id] Show template details',\n ' repo list --template <id> List repos linked to a template',\n ' repo add --template <id> --property-github-repo-id <uuid> [--role <r>] [--spec <r=owner/name@branch:subdir>]',\n ' repo update --template <id> --link-id <uuid> [--role <r>] [--branch <b>] [--subdirectory <s>] [--service-name <n>]',\n ' repo remove --template <id> --link-id <uuid>',\n ' checklist <template-id> Show checklist state',\n ' checklist skip <template-id> <item-id> Skip a checklist item',\n ' checklist complete <template-id> <item-id> [options] Mark item complete from CLI',\n ' artifacts <template-id> List artifacts',\n ' artifact get <template-id> <type> Get artifact content',\n ' artifact create <template-id> <type> <file> Upload artifact (use --path for file type)',\n ' create [property] [options] Create template from property (triggers provisioning)',\n ' provision <template-id> [options] Create a dedicated instance from a verified template',\n ' warm <template-id> [--wait] [--timeout <sec>] Warm the org-shared flow-authoring instance',\n ' (the one the flow designer auto-spins; sandbox runs reuse it)',\n ' verify <template-id> Verify an authoring template (provision + probe + flip to verified)',\n ' set-size <template-id> <size> Set EC2 size for next provision (see \"Instance sizes\" below)',\n ' pool set-size <template-id> <count> Set the warm stopped-pool size for a template (0 = off)',\n ' build <instance-id> Build and start app services on sandbox',\n ' run-command <instance-id> <command...> Execute shell command on sandbox',\n ' --service <name> Run inside a Docker container instead of on the host VM',\n ' diagnostics <instance-id> Show sandbox diagnostics',\n ' logs <instance-id> [options] Show container logs (live if running, else the captured failure snapshot)',\n ' terminate <instance-id> Terminate an instance',\n ' config list <template-id> Show config schema and defaults',\n ' config set <template-id> <key> <value> Set a config default value',\n ' config unset <template-id> <key> Remove a config default value',\n ' emulation get <template-id> Show emulation config + available plugins',\n ' emulation enable/disable <template-id> [pluginId] Toggle master switch (or one plugin)',\n ' emulation set <template-id> <pluginId> [opts] Configure a plugin entry',\n ' emulation remove <template-id> <pluginId> Drop a plugin entry',\n ' action <list|get|create|delete|execute|executions> Manage template actions (see \"Action sub-commands\" below)',\n ' delete <template-id> Delete template and all instances',\n '',\n 'Create options:',\n ' --property <name|id> Property (prompted if omitted, auto-selected if only one)',\n ' --branch <branch> Branch (default: from linked repo)',\n ' --name <name> Template name (default: repo name)',\n ' --subdirectory <path> Subdirectory (default: from linked repo rootDir)',\n ' --size <size> EC2 size for first authoring sandbox (default: medium; see \"Instance sizes\" below)',\n '',\n 'Provision options:',\n ' --name <name> Instance name',\n ' --ttl <hours> Time to live in hours (default: 8)',\n ' --with-agent Start with sandbox agent',\n ' --private Skip public ALB routing',\n ' --egress-mode <mode> off|observe (observe logs unmatched egress only; default: off)',\n ' --egress-allow <kind:value> Repeat or comma-separate domain:/cidr: entries',\n '',\n 'Artifact get options:',\n ' --output <file> Write to file instead of stdout',\n '',\n 'Logs options:',\n ' --service <name> Service name (default: all services; live path only)',\n ' --tail <n> Number of lines (default: 200; live path only)',\n ' --failure Force the captured failure snapshot (full logs + deploy.log)',\n ' Works for failed/terminated instances after the host is gone.',\n ' Running instances auto-use live logs; failed ones auto-fall back',\n ' to the snapshot when the live tail can\\'t run.',\n '',\n 'Guide sections (v1):',\n ' goal, research, artifacts, actions, verify, checklist',\n '',\n 'Instance sizes:',\n ...INSTANCE_SIZE_HELP_LINES,\n '',\n 'Action sub-commands:',\n ' action list <template-id> List actions for a template',\n ' action get <template-id> <slug> Show action definition + script',\n ' action create <template-id> <slug> [opts] Create or update an action',\n ' action delete <template-id> <slug> Delete an action',\n ' action execute <instance-id> <slug> [opts] Execute action on a running instance',\n ' action executions <instance-id> [opts] List execution history',\n ' action execution get <inst-id> <exec-id> Show one execution (advances a background run)',\n ' action execution cancel <inst-id> <exec-id> Stop a background execution',\n '',\n 'Action execute options:',\n ' --param key=value Set an input param (repeatable)',\n ' --params-file <file> JSON file of input params (--param overrides)',\n ' --async Return once the script is running, without waiting.',\n ' Required for anything longer than the 300s',\n ' synchronous ceiling. Poll `action execution get`',\n ' to reach a terminal status.',\n ' --timeout-ms <ms> Remote ceiling for an --async run (default 1h, max 48h)',\n '',\n 'Action create options:',\n ' --label <label> Display name (default: slug → Title Case)',\n ' --description <text> Description',\n ' --icon <icon> Phosphor icon name',\n ' --script <file> Path to script file (bash)',\n ' --input-schema <file> Path to JSON Schema file for input params',\n ' --output-schema <file> Path to JSON Schema file for output',\n ' --credential-output-config <file> JSON file with ActionCredentialOutputConfig (auto-creates a Canary credential from the action result).',\n ' --output-config <file> JSON file with an array of output slots the action hands back (test-results / artifacts-archive).',\n ' Supports `variableMapping` (persona var name → $output.* token) to fill the persona\\'s declared variables ($var.USER.<NAME>)',\n ' --credential-template <id> Credential template this action provisions; login nodes using it auto-provision',\n ' --provisioning-mode <shared|unique> shared = provision once / reused (default); unique = one credential per run (script must accept a runId input param)',\n ' --run-on-provision Base seed: run automatically once per provisioned instance (not login-triggered). Its --output-schema keys are exposed to flows as $var.SEED.<key>',\n ' --provision-order <n> Order for multiple base seeds on a template (ascending; unset runs first)',\n ' --timeout <ms> Timeout in ms (default: 55000)',\n ' --encrypt-script Encrypt script content at rest',\n '',\n 'Action execute options:',\n ' --param <key>=<value> Set parameter (repeatable)',\n ' --params-file <file> JSON file with all params',\n '',\n 'Emulation sub-commands (third-party service emulation: Slack/Jira/Google-OAuth/email):',\n ' emulation get <template-id> Master switch, configured plugins, available catalog',\n ' emulation enable <template-id> [pluginId] Turn on emulation (or enable a single plugin)',\n ' emulation disable <template-id> [pluginId] Turn off emulation (or disable a single plugin)',\n ' emulation set <template-id> <pluginId> [opts] Create/update a plugin entry (does not flip master switch)',\n ' emulation remove <template-id> <pluginId> Remove a plugin entry',\n ` Available plugins: ${getPluginIds().join(', ')}`,\n '',\n 'Emulation set options:',\n ' --config <file> JSON file with plugin-specific config (e.g. { \"tenant\": \"acme\" })',\n ' --fixture <file> JSON file with seed/fixture data for the plugin',\n ' --env-mapping <file> JSON file mapping logical env-contract keys to the app env var(s)',\n '',\n 'Global options:',\n ' --json Output raw JSON',\n ' --env <env> Environment (prod, dev, local)',\n ' -h, --help Show help',\n ].join('\\n')\n );\n}\n\n// ---------------------------------------------------------------------------\n// Sub-command handlers\n// ---------------------------------------------------------------------------\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n\n const [templatesRes, instancesRes] = await Promise.all([\n apiRequest<{ ok: boolean; error?: string; data: Template[] }>(\n apiUrl, token, 'GET', '/org/environments/templates'\n ),\n apiRequest<{ ok: boolean; error?: string; data: Instance[] }>(\n apiUrl, token, 'GET', '/org/environments/instances'\n ),\n ]);\n\n if (!templatesRes.ok) {\n console.error(`Error: ${templatesRes.error}`);\n process.exit(1);\n }\n if (!instancesRes.ok) {\n console.error(`Error loading instances: ${instancesRes.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify({ templates: templatesRes.data, instances: instancesRes.data }, null, 2));\n return;\n }\n\n const templates = templatesRes.data ?? [];\n const instances = instancesRes.data ?? [];\n\n console.log('Templates:');\n if (templates.length === 0) {\n console.log(' (none)');\n } else {\n console.log(` ${pad('ID', 38)} ${pad('Name', 24)} ${pad('Status', 14)} ${pad('Profile', 12)} Repository`);\n for (const t of templates) {\n console.log(` ${pad(t.id, 38)} ${pad(t.name, 24)} ${pad(t.status, 14)} ${pad(t.checklistProfile ?? '-', 12)} ${t.repositoryFullName ? `${t.repositoryFullName}:${t.branch}` : '(no repository)'}`);\n }\n }\n\n console.log('');\n console.log('Instances:');\n if (instances.length === 0) {\n console.log(' (none)');\n } else {\n console.log(` ${pad('ID', 38)} ${pad('Status', 14)} ${pad('Purpose', 16)} ${pad('Access', 10)} ${pad('Template', 38)} Expires`);\n for (const i of instances) {\n const access = i.isPrivate ? 'private' : 'public';\n // The org-shared flow-authoring instance is the one workflow runs reuse —\n // flag it so it's easy to spot (and warm via `sandbox warm <template>`).\n const purpose =\n i.purpose === 'flow_authoring' ? 'flow_authoring*' : (i.purpose ?? '-');\n console.log(` ${pad(i.id, 38)} ${pad(i.status, 14)} ${pad(purpose, 16)} ${pad(access, 10)} ${pad(i.templateId, 38)} ${i.expiresAt ? formatDate(i.expiresAt) : '-'}`);\n }\n console.log('');\n console.log(' * flow_authoring = org-shared instance the flow designer auto-spins and');\n console.log(' sandbox workflow runs reuse. Warm it with: canary sandbox warm <template-id>');\n }\n}\n\nasync function handleTemplate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = argv.filter((a) => !a.startsWith('-'));\n const json = hasFlag(argv, '--json');\n\n if (!id) {\n await handleList(argv, apiUrl, token);\n return;\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: Template }>(\n apiUrl, token, 'GET', `/org/environments/templates/${id}`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n const t = res.data;\n console.log(`Template: ${t.name}`);\n console.log(` ID: ${t.id}`);\n console.log(` Repository: ${t.repositoryFullName ? `${t.repositoryFullName}:${t.branch}` : '(none)'}`);\n if (t.subdirectory) console.log(` Subdir: ${t.subdirectory}`);\n console.log(` Status: ${t.status}`);\n console.log(` Profile: ${t.checklistProfile ?? 'full-stack (default)'}`);\n console.log(` Created: ${formatDate(t.createdAt)}`);\n console.log(` Updated: ${formatDate(t.updatedAt)}`);\n\n if (t.configSchema && t.configSchema.length > 0) {\n console.log('');\n console.log(' Config Schema:');\n for (const c of t.configSchema) {\n const flags = [c.required ? 'required' : 'optional', c.sensitive ? 'sensitive' : ''].filter(Boolean).join(', ');\n writeRawOutput(` ${c.key} (${flags})${c.description ? ` — ${c.description}` : ''}`);\n }\n }\n}\n\nasync function handleArtifacts(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [templateId] = argv.filter((a) => !a.startsWith('-'));\n const json = hasFlag(argv, '--json');\n\n if (!templateId) {\n console.error('Error: template ID required. Usage: canary sandbox artifacts <template-id>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: Artifact[] }>(\n apiUrl, token, 'GET', `/org/environments/templates/${templateId}/artifacts`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n const artifacts = res.data ?? [];\n if (artifacts.length === 0) {\n console.log('No artifacts found.');\n return;\n }\n\n console.log(`${pad('Type', 22)} ${pad('Filename', 30)} ${pad('Task', 24)} Created`);\n for (const a of artifacts) {\n console.log(`${pad(a.artifactType, 22)} ${pad(a.filename, 30)} ${pad(a.taskId, 24)} ${formatDate(a.createdAt)}`);\n }\n}\n\nasync function handleChecklist(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const json = hasFlag(argv, '--json');\n\n // Handle checklist sub-commands: skip, complete\n if (positional[0] === 'skip') {\n await handleChecklistSkip(argv.slice(1), apiUrl, token);\n return;\n }\n if (positional[0] === 'complete') {\n await handleChecklistComplete(argv.slice(1), apiUrl, token);\n return;\n }\n\n const templateId = positional[0];\n if (!templateId) {\n console.error('Error: template ID required. Usage: canary sandbox checklist <template-id>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: ChecklistItem[] }>(\n apiUrl, token, 'GET', `/org/environments/templates/${templateId}/checklist`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n const items = res.data ?? [];\n if (items.length === 0) {\n console.log('No checklist items.');\n return;\n }\n\n console.log('Checklist:');\n for (const item of items) {\n const icon = STATUS_ICONS[item.itemStatus.status] ?? '[????]';\n const actionable = item.actionable ? ' *' : '';\n console.log(` ${icon} ${item.label}${actionable}`);\n if (item.itemStatus.summary) {\n console.log(` ${item.itemStatus.summary}`);\n }\n if (item.itemStatus.error) {\n console.log(` ERROR: ${item.itemStatus.error}`);\n }\n if (item.artifacts.length > 0) {\n console.log(` Artifacts: ${item.artifacts.map((a) => a.artifactType).join(', ')}`);\n }\n }\n console.log('');\n console.log(' * = actionable (deps met, ready to run)');\n}\n\nasync function handleChecklistSkip(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const itemId = positional[1];\n\n if (!templateId || !itemId) {\n console.error('Error: both template ID and item ID required. Usage: canary sandbox checklist skip <template-id> <item-id>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl, token, 'POST', `/org/environments/templates/${templateId}/checklist/${itemId}/skip`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n console.log(`Skipped checklist item: ${itemId}`);\n}\n\nasync function handleChecklistComplete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const itemId = positional[1];\n\n const json = hasFlag(argv, '--json');\n\n if (!templateId || !itemId) {\n console.error('Error: both template ID and item ID required.');\n console.error('Usage: canary sandbox checklist complete <template-id> <item-id> [--status success|failed] [--summary \"...\"]');\n process.exit(1);\n }\n\n const status = getArgValue(argv, '--status') ?? 'success';\n const summary = getArgValue(argv, '--summary');\n const configSchemaArg = getArgValue(argv, '--config-schema');\n const healthCheckPath = getArgValue(argv, '--health-check-path');\n\n let configSchema: unknown;\n if (configSchemaArg) {\n // Accept inline JSON or a file path\n try {\n configSchema = JSON.parse(configSchemaArg);\n } catch {\n try {\n configSchema = JSON.parse(readFileSync(configSchemaArg, 'utf-8'));\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Error reading config schema from \"${configSchemaArg}\": ${msg}`);\n process.exit(1);\n }\n }\n }\n\n const body: Record<string, unknown> = {\n status: status === 'failed' ? 'failed' : 'completed',\n ...(summary ? { summary } : {}),\n ...(configSchema ? { configSchema } : {}),\n ...(healthCheckPath ? { healthCheckPath } : {}),\n };\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: { itemId: string; status: string } }>(\n apiUrl, token, 'POST', `/org/environments/templates/${templateId}/checklist/${itemId}/complete`, body\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n console.log(`Completed checklist item: ${itemId} (${res.data?.status})`);\n}\n\nasync function handleConfigList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const json = hasFlag(argv, '--json');\n\n if (!templateId) {\n console.error('Error: template ID required. Usage: canary sandbox config list <template-id>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: Template }>(\n apiUrl, token, 'GET', `/org/environments/templates/${templateId}`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n const t = res.data;\n const schema = t.configSchema ?? [];\n const defaults = t.configDefaults ?? {};\n const configuredSensitiveKeys = t.configuredSensitiveKeys ?? [];\n const configuredSensitiveKeySet = new Set(configuredSensitiveKeys);\n\n if (json) {\n writeRawOutput(JSON.stringify(\n { configSchema: schema, configDefaults: defaults, configuredSensitiveKeys },\n null,\n 2\n )\n );\n return;\n }\n\n if (schema.length === 0) {\n console.log('No config schema defined for this template.');\n return;\n }\n\n console.log('Config Schema:');\n for (const item of schema) {\n const value = defaults[item.key];\n const display = item.sensitive\n ? configuredSensitiveKeySet.has(item.key)\n ? '•••••••• (configured)'\n : '(not set)'\n : (value ?? '(not set)');\n const required = item.required ? ' (required)' : '';\n const sensitive = item.sensitive ? ' [sensitive]' : '';\n console.log(` ${item.key}${required}${sensitive}`);\n if (item.description) writeRawOutput(` ${item.description}`);\n console.log(` Value: ${display}`);\n }\n}\n\nexport const configSetPayload = (key: string, value: string) => ({\n configDefaults: { [key]: value },\n unsetKeys: [] as string[],\n});\n\nexport const configUnsetPayload = (key: string) => ({\n configDefaults: {} as Record<string, string>,\n unsetKeys: [key],\n});\n\nasync function handleConfigSet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const fromStdin = hasFlag(argv, '--value-stdin');\n const templateId = positional[0];\n const key = positional[1];\n let value = positional[2];\n\n if (!templateId || !key) {\n console.error('Error: template ID and key required.');\n console.error('Usage: canary sandbox config set <template-id> <key> <value>');\n console.error(' For sensitive values: echo \"sk-ant-...\" | canary sandbox config set <template-id> <key> --value-stdin');\n process.exit(1);\n }\n\n if (fromStdin) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n value = Buffer.concat(chunks).toString('utf-8').trim();\n }\n\n if (value === undefined) {\n console.error('Error: value required. Pass as argument or use --value-stdin');\n process.exit(1);\n }\n\n // The server may take longer than 30s to acknowledge config writes\n // (encrypted columns, audit log). Even when it does the write succeeds —\n // bump the CLI ceiling so the user sees the success rather than a\n // misleading timeout.\n const res = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl, token, 'PATCH', `/org/environments/templates/${templateId}/config`, {\n ...configSetPayload(key, value),\n },\n { timeoutMs: 90_000 }\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n console.log(`Config set: ${key}`);\n}\n\nasync function handleConfigUnset(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [templateId, key] = argv.filter((arg) => !arg.startsWith('-'));\n if (!templateId || !key) {\n console.error('Usage: canary sandbox config unset <template-id> <key>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'PATCH',\n `/org/environments/templates/${templateId}/config`,\n configUnsetPayload(key),\n { timeoutMs: 90_000 }\n );\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n console.log(`Config unset: ${key}`);\n}\n\nasync function handleSetSize(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [templateId, sizeArg] = argv.filter((a) => !a.startsWith('-'));\n\n if (!templateId || !sizeArg) {\n console.error('Error: template ID and size required.');\n console.error(`Usage: canary sandbox set-size <template-id> <${INSTANCE_SIZES.join('|')}>`);\n process.exit(1);\n }\n\n const size = parseInstanceSize(sizeArg);\n if (!size) {\n console.error(`Error: invalid size '${sizeArg}'. Must be one of: ${INSTANCE_SIZES.join(', ')}`);\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; instanceSize?: InstanceSize }>(\n apiUrl,\n token,\n 'PATCH',\n `/org/environments/templates/${templateId}/instance-size`,\n { instanceSize: size }\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n console.log(`Instance size set to ${size}`);\n}\n\nasync function handlePoolSetSize(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [templateId, countArg] = argv.filter((a) => !a.startsWith('-'));\n\n if (!templateId || countArg === undefined) {\n console.error('Error: template ID and count required.');\n console.error('Usage: canary sandbox pool set-size <template-id> <count>');\n process.exit(1);\n }\n\n // Strict decimal-integer parse — reject '1e2', '0x10', '3.5', etc. that\n // Number() would silently accept, so the count the operator typed is exactly\n // what the server receives.\n const poolMinReady = /^\\d+$/.test(countArg) ? Number(countArg) : Number.NaN;\n if (!Number.isInteger(poolMinReady)) {\n console.error(`Error: invalid count '${countArg}'. Must be a non-negative integer.`);\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; poolMinReady?: number }>(\n apiUrl,\n token,\n 'PATCH',\n `/org/environments/templates/${templateId}/pool-min-ready`,\n { poolMinReady }\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n console.log(`Warm stopped-pool size set to ${poolMinReady}`);\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const json = hasFlag(argv, '--json');\n\n // Resolve property — positional arg or --property flag, prompted if omitted\n const propertyHint = positional[0] ?? getArgValue(argv, '--property');\n const property = await selectProperty(apiUrl, token, propertyHint ?? undefined);\n if (!property) process.exit(1);\n\n // Fetch linked repos for the property\n const reposRes = await apiRequest<{ ok: boolean; error?: string; items: GitHubRepo[] }>(\n apiUrl, token, 'GET', `/org/properties/${property.id}/github-repos`\n );\n if (!reposRes.ok || !reposRes.items?.length) {\n console.error(`No GitHub repos linked to property \"${property.name}\". Link one first in the web app.`);\n process.exit(1);\n }\n\n const linkedRepo = reposRes.items[0];\n const branch = getArgValue(argv, '--branch') ?? linkedRepo.defaultBranch ?? 'main';\n const name = getArgValue(argv, '--name') ?? linkedRepo.repoName ?? linkedRepo.repoFullName.split('/').pop() ?? property.name;\n const subdirectory = getArgValue(argv, '--subdirectory') ?? linkedRepo.rootDir ?? undefined;\n\n const sizeArg = getArgValue(argv, '--size');\n const instanceSize = sizeArg ? parseInstanceSize(sizeArg) : undefined;\n if (sizeArg && !instanceSize) {\n console.error(`Error: invalid --size '${sizeArg}'. Must be one of: ${INSTANCE_SIZES.join(', ')}`);\n process.exit(1);\n }\n\n const body: Record<string, unknown> = {\n name,\n propertyId: property.id,\n repositoryFullName: linkedRepo.repoFullName,\n branch,\n };\n if (subdirectory) body.subdirectory = subdirectory;\n if (linkedRepo.agentHint) body.hints = linkedRepo.agentHint;\n if (instanceSize) body.instanceSize = instanceSize;\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: Template }>(\n apiUrl, token, 'POST', '/org/environments/templates', body\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n console.log(`Template created: ${res.data.id}`);\n console.log(` Property: ${property.name}`);\n console.log(` Repository: ${res.data.repositoryFullName ? `${res.data.repositoryFullName}:${res.data.branch}` : '(none)'}`);\n console.log(` Status: ${res.data.status}`);\n console.log('');\n console.log('Authoring job enqueued. Poll status with:');\n console.log(` canary sandbox template ${res.data.id}`);\n}\n\nasync function handleProvision(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const json = hasFlag(argv, '--json');\n\n if (!templateId) {\n console.error('Error: template ID required. Usage: canary sandbox provision <template-id> [--ttl 8]');\n process.exit(1);\n }\n\n const name = getArgValue(argv, '--name') ?? `instance-${Date.now()}`;\n const ttl = parseInt(getArgValue(argv, '--ttl') ?? '8', 10);\n const withAgent = hasFlag(argv, '--with-agent');\n const isPrivate = hasFlag(argv, '--private');\n const egressMode = parseEgressMode(getArgValue(argv, '--egress-mode'));\n const egressAllowlist = parseEgressAllowlist(argv);\n\n const body: Record<string, unknown> = {\n templateId,\n name,\n expiresInHours: ttl,\n userConfig: {},\n withAgent,\n isPrivate,\n egressMode,\n egressAllowlist,\n };\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: Instance }>(\n apiUrl, token, 'POST', '/org/environments/instances', body\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n console.log(`Instance created: ${res.data.id}`);\n console.log(` Status: ${res.data.status}`);\n if (isPrivate) console.log(` Access: private (no public URL)`);\n if (egressMode !== 'off') {\n console.log(` Egress: ${egressMode} (${egressAllowlist.length} allowlist entries)`);\n }\n console.log(` Expires: ${res.data.expiresAt ? formatDate(res.data.expiresAt) : '-'}`);\n}\n\ntype AuthoringInstance = {\n instanceId: string;\n status: string;\n url: string | null;\n expiresAt: string | null;\n createdAt: string | null;\n created: boolean;\n};\n\n/**\n * Warm (get-or-create) the org-shared flow-authoring instance for a template —\n * the same instance the Flow Designer auto-spins and that a sandbox workflow run\n * reuses. Pre-warming avoids the first run blocking on a cold provision.\n *\n * `--wait` polls the idempotent ensure endpoint (safe: it reuses the live\n * instance and just slides the TTL) until the instance is running, fails, or\n * the timeout elapses.\n */\nasync function handleWarm(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const json = hasFlag(argv, '--json');\n const wait = hasFlag(argv, '--wait');\n const timeoutSec = parseInt(getArgValue(argv, '--timeout') ?? '600', 10);\n\n if (!templateId) {\n console.error(\n 'Error: template ID required. Usage: canary sandbox warm <template-id> [--wait] [--timeout <sec>]'\n );\n console.error('Find the template id with: canary sandbox list');\n process.exit(1);\n }\n\n const ensure = (): Promise<{ ok: boolean; error?: string; data?: AuthoringInstance }> =>\n apiRequest<{ ok: boolean; error?: string; data?: AuthoringInstance }>(\n apiUrl,\n token,\n 'POST',\n `/org/environments/templates/${templateId}/authoring-instance`\n );\n\n const first = await ensure();\n if (!first.ok || !first.data) {\n if (json) {\n writeRawOutput(JSON.stringify(first, null, 2));\n } else {\n console.error(`Error: ${first.error ?? 'Failed to warm sandbox'}`);\n }\n process.exit(1);\n }\n\n const terminalOk = new Set(['running']);\n const terminalFail = new Set(['failed', 'terminated', 'stopping']);\n\n let current = first.data;\n if (wait && !terminalOk.has(current.status) && !terminalFail.has(current.status)) {\n const deadline = Date.now() + timeoutSec * 1000;\n if (!json) console.log(`Warming flow-authoring sandbox (${current.status})...`);\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 5000));\n const poll = await ensure();\n if (!poll.ok || !poll.data) {\n console.error(`Error polling sandbox: ${poll.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n current = poll.data;\n if (terminalOk.has(current.status) || terminalFail.has(current.status)) break;\n }\n }\n\n if (json) {\n writeRawOutput(JSON.stringify({ ok: true, data: current }, null, 2));\n } else {\n console.log(`Sandbox ${current.created ? 'created' : 'reused'}: ${current.instanceId}`);\n console.log(` Status: ${current.status}`);\n if (current.url) writeRawOutput(` URL: ${current.url}`);\n if (current.expiresAt) console.log(` Expires: ${formatDate(current.expiresAt)}`);\n if (current.status === 'running') {\n console.log('\\nReady. Run a workflow against it with:');\n console.log(' canary workflow run <workflowId> [--environment <name|id>] --stream');\n } else if (wait && terminalFail.has(current.status)) {\n console.log('\\nSandbox did not reach a ready state.');\n } else if (wait) {\n console.log('\\nTimed out waiting for the sandbox to become ready. Re-run to keep waiting.');\n } else {\n console.log('\\nWarming in the background. Poll with: canary sandbox warm ' + templateId + ' --wait');\n }\n }\n\n if (terminalFail.has(current.status)) process.exit(1);\n if (wait && current.status !== 'running') process.exit(1);\n}\n\nexport interface ContainerLine {\n name: string;\n status: string;\n state: 'up-healthy' | 'up' | 'up-unhealthy' | 'restarting' | 'exited' | 'other';\n}\n\n/**\n * Parse `docker ps --format '{{.Names}}\\t{{.Status}}\\t{{.Ports}}'` output\n * into a structured list. State classification is coarse — the verify loop\n * only needs to know \"is this container healthy / exited / restart-looping\".\n */\nexport function parseDockerPs(stdout: string): ContainerLine[] {\n const lines = stdout.split('\\n').map((l) => l.trim()).filter(Boolean);\n return lines.map((line) => {\n const [name = '', status = ''] = line.split('\\t');\n const lower = status.toLowerCase();\n let state: ContainerLine['state'] = 'other';\n if (lower.startsWith('restarting')) state = 'restarting';\n else if (lower.startsWith('exited')) state = 'exited';\n else if (lower.startsWith('up') && lower.includes('unhealthy')) state = 'up-unhealthy';\n else if (lower.startsWith('up') && lower.includes('healthy')) state = 'up-healthy';\n else if (lower.startsWith('up')) state = 'up';\n return { name, status, state };\n });\n}\n\n/** Containers that aren't cleanly up. Used to decide what to dump logs for. */\nexport function isBrokenContainer(c: ContainerLine): boolean {\n return c.state === 'restarting' || c.state === 'exited' || c.state === 'up-unhealthy';\n}\n\n/**\n * Map a container name back to its compose service.\n *\n * docker-compose names containers `<project>-<service>-<replica>`. The\n * sandbox platform sets the project to `workspace` via\n * `--project-directory /workspace` (see `SANDBOX_COMPOSE_BASE` in\n * apps/api/.../sandbox-cli/service.ts), so the common case is\n * `workspace-<svc>-<n>`. Fall back to stripping the trailing replica\n * index only, so attribution still works if the project name ever\n * changes or someone uses an explicit `container_name:` override.\n */\nexport function containerNameToService(containerName: string): string {\n const withProject = containerName.match(/^workspace-(.+)-\\d+$/);\n if (withProject) return withProject[1]!;\n const withoutProject = containerName.match(/^(.+)-\\d+$/);\n if (withoutProject) return withoutProject[1]!;\n return containerName;\n}\n\nasync function fetchServiceLogs(\n apiUrl: string,\n token: string,\n instanceId: string,\n service: string,\n tail: number\n): Promise<string> {\n const res = await apiRequest<{ ok: boolean; error?: string; data: { logs: string } }>(\n apiUrl,\n token,\n 'POST',\n `/org/environments/instances/${instanceId}/docker/logs`,\n { service, tail }\n );\n if (!res.ok) return `(log fetch failed: ${res.error ?? 'unknown'})`;\n return res.data?.logs ?? '';\n}\n\nasync function handleVerify(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const json = hasFlag(argv, '--json');\n // --keep-instance is kept as a success-path alias (existing behavior).\n // On failure the probe is now preserved by default so the user can debug;\n // pass --auto-terminate-on-failure for CI where you want cleanup anyway.\n const keepInstance = hasFlag(argv, '--keep-instance');\n const autoTerminateOnFailure = hasFlag(argv, '--auto-terminate-on-failure');\n\n if (!templateId) {\n console.error('Error: template ID required. Usage: canary sandbox verify <template-id>');\n process.exit(1);\n }\n\n console.log(`Verifying template ${templateId}...`);\n\n // Kick off a verification instance — server bypasses the \"verified\" gate\n // via verificationMode but otherwise runs the full provisioning flow.\n const verifyRes = await apiRequest<{ ok: boolean; error?: string; data: { instanceId: string; expiresAt: string } }>(\n apiUrl, token, 'POST', `/org/environments/templates/${templateId}/verify`, {}\n );\n if (!verifyRes.ok) {\n console.error(`Error: ${verifyRes.error}`);\n process.exit(1);\n }\n const instanceId = verifyRes.data.instanceId;\n console.log(` Verification instance: ${instanceId}`);\n\n // Poll diagnostics until instance reaches 'running' or a terminal state.\n const POLL_INTERVAL_MS = 10_000;\n const TIMEOUT_MS = 600_000; // 10 minutes\n const DETAIL_DUMP_INTERVAL_MS = 30_000; // rate-limit noisy dumps\n const LOG_TAIL_LINES = 40;\n const startTime = Date.now();\n let finalStatus = '';\n let publicUrl: string | undefined;\n let lastDetailDumpAt = 0;\n let routes: ServiceRoute[] = [];\n let routesFetched = false;\n\n while (Date.now() - startTime < TIMEOUT_MS) {\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\n\n const diag = await apiRequest<{ ok: boolean; error?: string; data: DiagnosticsResult }>(\n apiUrl, token, 'GET', `/org/environments/instances/${instanceId}/diagnostics`,\n undefined,\n { timeoutMs: 60_000 }\n );\n if (!diag.ok) continue;\n\n const now = Date.now();\n const elapsed = Math.round((now - startTime) / 1000);\n const remaining = Math.max(0, Math.round((TIMEOUT_MS - (now - startTime)) / 1000));\n const status = String((diag.data.instance as { status?: string; publicUrl?: string }).status ?? '');\n publicUrl = (diag.data.instance as { publicUrl?: string }).publicUrl;\n const appOutput = 'stdout' in diag.data.appHealth ? diag.data.appHealth.stdout : '';\n const appUp = appOutput.length > 0 && !appOutput.includes('UNREACHABLE');\n const dockerOutput = 'stdout' in diag.data.docker ? diag.data.docker.stdout : '';\n const containers = parseDockerPs(dockerOutput);\n const broken = containers.filter(isBrokenContainer);\n\n // Compact progress line (overwriting, like before) — adds remaining time.\n const ttl = remaining > 60 ? `${elapsed}s elapsed` : `${remaining}s remaining`;\n process.stdout.write(\n `\\r [${ttl}] status: ${status}, app: ${appUp ? 'up' : 'waiting'}, containers: ${containers.length}, unhealthy: ${broken.length} `\n );\n\n if (status === 'running' && appUp) {\n process.stdout.write('\\n');\n finalStatus = 'running';\n break;\n }\n if (status === 'failed' || status === 'terminated') {\n process.stdout.write('\\n');\n finalStatus = status;\n break;\n }\n\n // When the app is still down and at least one container is broken,\n // dump details + log tails once every DETAIL_DUMP_INTERVAL_MS so the\n // user actually sees what's failing instead of staring at a spinner.\n const shouldDump =\n !appUp &&\n broken.length > 0 &&\n now - lastDetailDumpAt >= DETAIL_DUMP_INTERVAL_MS;\n if (shouldDump) {\n lastDetailDumpAt = now;\n process.stdout.write('\\n');\n console.log('');\n console.log(` App unreachable after ${elapsed}s. Container state:`);\n for (const c of containers) {\n console.log(` ${c.name.padEnd(40)} ${c.status}`);\n }\n console.log('');\n // Per-broken-container log tails. Cap to MAX_LOG_CONTAINERS to avoid\n // SSM call amplification on pathological cases (a template with 6\n // restart-looping services would otherwise issue 6 sequential SSM\n // calls every 30s). Fetch in parallel — these are independent.\n const MAX_LOG_CONTAINERS = 3;\n const toFetch = broken.slice(0, MAX_LOG_CONTAINERS);\n const overflow = broken.length - toFetch.length;\n const fetched = await Promise.all(\n toFetch.map((c) =>\n fetchServiceLogs(apiUrl, token, instanceId, containerNameToService(c.name), LOG_TAIL_LINES)\n .then((logs) => ({ c, logs }))\n )\n );\n for (const { c, logs } of fetched) {\n const tail = logs.trim().split('\\n').slice(-LOG_TAIL_LINES).join('\\n ');\n console.log(` --- ${c.name} (${c.state}) ---`);\n console.log(` ${tail || '(no logs)'}`);\n console.log('');\n }\n if (overflow > 0) {\n console.log(\n ` (+${overflow} more broken container${overflow === 1 ? '' : 's'} — re-run with: canary sandbox logs ${instanceId} --service <name>)`\n );\n console.log('');\n }\n // Attribution: if nginx-proxy is looping because of a labeled upstream\n // that's exited, call that out so the user doesn't chase nginx's\n // \"host not found in upstream\" as the root cause.\n if (!routesFetched) {\n routes = await fetchInstanceRoutes(apiUrl, token, instanceId);\n routesFetched = true;\n }\n const nginxProxy = containers.find((c) => containerNameToService(c.name) === 'nginx-proxy');\n if (nginxProxy?.state === 'restarting' && routes.length > 0) {\n const failedUpstreams = routes\n .map((r) => ({\n route: r.route,\n service: r.service,\n container: broken.find((c) => containerNameToService(c.name) === r.service),\n }))\n .filter((x) => x.container);\n if (failedUpstreams.length > 0) {\n for (const fu of failedUpstreams) {\n console.log(\n ` >> nginx-proxy is restart-looping because upstream '${fu.service}' (route '${fu.route}') is ${fu.container!.state}. Read that service's logs above, not nginx's.`\n );\n }\n console.log('');\n }\n }\n }\n }\n\n if (finalStatus !== 'running') {\n console.error('');\n console.error(`Verification failed — instance ended in status '${finalStatus || 'timeout'}'.`);\n if (publicUrl) console.error(` Instance URL: ${publicUrl}`);\n console.error(` Instance ID: ${instanceId}`);\n console.error(` Debug with: canary sandbox diagnostics ${instanceId}`);\n console.error(` canary sandbox logs ${instanceId} --service <name>`);\n console.error(` canary sandbox run-command ${instanceId} 'docker ps -a'`);\n if (autoTerminateOnFailure) {\n await apiRequest(apiUrl, token, 'POST', `/org/environments/instances/${instanceId}/terminate`);\n console.error(` Terminated (--auto-terminate-on-failure).`);\n } else {\n // Default flip (was: auto-terminate). Call it out so CI users don't\n // silently accumulate orphan instances.\n console.error(` Instance preserved by default for debugging. Pass --auto-terminate-on-failure in CI.`);\n console.error(` Terminate manually with:`);\n console.error(` canary sandbox terminate ${instanceId}`);\n }\n process.exit(1);\n }\n\n // We just observed the instance reach status === 'running' && appUp.\n // That's the same observation that backs the server-running and\n // server-accessible checklist items, so flip them too — best-effort\n // (templates without those items in their checklist 404 silently).\n const evidenceSummary = `Verified via canary sandbox verify — fresh instance ${instanceId} came up healthy.`;\n for (const itemId of ['server-running', 'server-accessible']) {\n await apiRequest(\n apiUrl,\n token,\n 'POST',\n `/org/environments/templates/${templateId}/checklist/${itemId}/complete`,\n { status: 'completed', summary: evidenceSummary }\n ).catch(() => {\n // Item not present on this checklist profile — fine.\n });\n }\n\n // Mark the template-verified checklist item complete — this is what flips\n // template.status to 'verified' (via ChecklistService.completeChecklistItem).\n const completeRes = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/org/environments/templates/${templateId}/checklist/template-verified/complete`,\n {\n status: 'completed',\n summary: evidenceSummary,\n }\n );\n if (!completeRes.ok) {\n console.error(`Failed to record verification: ${completeRes.error}`);\n console.error(`Instance ${instanceId} left running for inspection.`);\n process.exit(1);\n }\n\n if (!keepInstance) {\n await apiRequest(apiUrl, token, 'POST', `/org/environments/instances/${instanceId}/terminate`);\n console.log(` Terminated verification instance.`);\n } else {\n console.log(` --keep-instance: instance ${instanceId} left running${publicUrl ? ` at ${publicUrl}` : ''}.`);\n }\n\n // Confirm the template actually flipped to verified. The status flip only\n // happens when every item in the checklist profile is terminal\n // (completed or skipped); if other items are still pending, the probe\n // succeeded but the template stays in its prior status.\n const templateAfter = await apiRequest<{ ok: boolean; data?: { status?: string } }>(\n apiUrl,\n token,\n 'GET',\n `/org/environments/templates/${templateId}`\n ).catch(() => ({ ok: false }) as { ok: boolean; data?: { status?: string } });\n const templateStatus = templateAfter.data?.status;\n const verified = templateStatus === 'verified';\n\n if (json) {\n writeRawOutput(JSON.stringify({ templateId, verified, status: templateStatus, instanceId, publicUrl }, null, 2));\n return;\n }\n\n if (verified) {\n console.log('Template verified.');\n return;\n }\n\n // Probe passed but status didn't flip — surface the pending items so the\n // user knows what to complete/skip before re-running verify.\n console.log(`Verification probe passed (instance ${instanceId} came up healthy),`);\n console.log(`but template status is still '${templateStatus ?? 'unknown'}'.`);\n type ChecklistItemSummary = { id: string; label: string; itemStatus?: { status?: string } };\n const checklistRes = await apiRequest<{ ok: boolean; data?: ChecklistItemSummary[] }>(\n apiUrl,\n token,\n 'GET',\n `/org/environments/templates/${templateId}/checklist`\n ).catch(() => ({ ok: false }) as { ok: boolean; data?: ChecklistItemSummary[] });\n const pending = (checklistRes.data ?? []).filter((it) => {\n const s = it.itemStatus?.status ?? 'pending';\n return s !== 'completed' && s !== 'skipped';\n });\n if (pending.length > 0) {\n console.log('Pending checklist items must be completed or skipped:');\n for (const item of pending) {\n console.log(` - ${item.label} (${item.id})`);\n }\n console.log('');\n console.log('Complete: canary sandbox checklist complete <template-id> <item-id> --status success --summary \"...\"');\n console.log('Skip: canary sandbox checklist skip <template-id> <item-id>');\n }\n process.exit(1);\n}\n\nasync function handleArtifactGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const type = positional[1];\n const outputFile = getArgValue(argv, '--output');\n\n if (!templateId || !type) {\n console.error('Error: template ID and artifact type required. Usage: canary sandbox artifact get <template-id> <type>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: Artifact }>(\n apiUrl, token, 'GET', `/org/environments/templates/${templateId}/artifacts/${type}`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (outputFile) {\n const { writeFileSync } = await import('node:fs');\n writeFileSync(outputFile, res.data.content ?? '', 'utf-8');\n console.log(`Written to ${outputFile}`);\n } else {\n process.stdout.write(res.data.content ?? '');\n }\n}\n\nasync function handleArtifactCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const type = positional[1];\n const filePath = positional[2];\n const json = hasFlag(argv, '--json');\n\n if (!templateId || !type || !filePath) {\n console.error('Error: all args required. Usage: canary sandbox artifact create <template-id> <type> <file>');\n process.exit(1);\n }\n\n // Keep in sync with WellKnownArtifactType in packages/types/src/sandbox-tasks.ts + 'file' (custom with --path)\n const WELL_KNOWN_TYPES = ['docker-compose', 'dockerfile', 'startup-script', 'setup-script', 'seed-script', 'environment-config', 'file'];\n if (!WELL_KNOWN_TYPES.includes(type)) {\n console.error(`Error: invalid artifact type \"${type}\". Valid types: ${WELL_KNOWN_TYPES.join(', ')}`);\n process.exit(1);\n }\n\n // File artifacts require --path <destination>\n const destinationPath = getArgValue(argv, '--path');\n if (type === 'file' && !destinationPath) {\n console.error('Error: file artifacts require --path <destination>. Example: --path /workspace/.canary/vite.sandbox.config.ts');\n process.exit(1);\n }\n if (destinationPath && !destinationPath.startsWith('/workspace/.canary/')) {\n const suggestedName = destinationPath.split('/').filter(Boolean).pop() ?? 'yourfile';\n console.error(\n 'Error: --path must be under /workspace/.canary/ (the repo tree is user-owned — sandbox files live in .canary/).\\n' +\n ` try: --path /workspace/.canary/${suggestedName}`\n );\n process.exit(1);\n }\n\n let content: string;\n try {\n content = readFileSync(filePath, 'utf-8');\n } catch (err) {\n console.error(`Error reading file: ${err}`);\n process.exit(1);\n }\n\n // Derive filename from path\n const filename = filePath.split('/').pop() ?? filePath;\n\n // Artifact upload writes through to the live authoring instance, which on\n // first push (or a large file) can outlast 30s easily. 90s lines up with\n // the slowest legitimate upload we've observed.\n const res = await apiRequest<{\n ok: boolean;\n error?: string;\n data?: { kind: 'created' | 'replaced'; previousPath?: string };\n }>(\n apiUrl, token, 'PUT', `/org/environments/templates/${templateId}/artifacts`, {\n artifactType: type,\n filename,\n content,\n ...(destinationPath ? { destinationPath } : {}),\n },\n { timeoutMs: 90_000 }\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n const kind = res.data?.kind;\n const marker = kind === 'replaced' ? ' (replaced)' : kind === 'created' ? ' (created)' : '';\n console.log(`Artifact uploaded: ${type} (${filename}, ${content.length} bytes)${marker}`);\n if (kind === 'replaced' && res.data?.previousPath) {\n console.log(` previous destination removed: ${res.data.previousPath}`);\n }\n}\n\nasync function handleBuild(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const json = hasFlag(argv, '--json');\n const noWait = hasFlag(argv, '--no-wait');\n const instanceId = positional[0];\n\n if (!instanceId) {\n console.error('Error: instance ID required. Usage: canary sandbox build <instance-id>');\n process.exit(1);\n }\n\n console.log('Building sandbox (this takes a few minutes)...');\n\n // The build is async by design: a single HTTP connection cannot reliably\n // span a multi-minute build (ALB caps, our own client timeouts, flaky\n // networks). Kick the build off with a short timeout — the server has\n // already started the work by the time it would otherwise reply — then\n // move to polling diagnostics for the truth.\n const KICKOFF_TIMEOUT_MS = 8_000;\n\n let buildCompleted = false;\n let buildResult: { stdout: string; stderr: string; exitCode: number } | null = null;\n\n const result = await apiFetch(`${apiUrl}/org/environments/instances/${instanceId}/build`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n token,\n timeoutMs: KICKOFF_TIMEOUT_MS,\n });\n\n if (result.ok) {\n // Fast path: server responded within the kickoff window (cached/no-op build).\n const data = (await result.response.json().catch(() => null)) as\n | { ok: boolean; error?: string; data?: { stdout: string; stderr: string; exitCode: number } }\n | null;\n if (data?.ok && data.data) {\n buildCompleted = true;\n buildResult = data.data;\n } else if (data && !data.ok) {\n console.error(`Error: ${data.error ?? 'build failed'}`);\n process.exit(1);\n }\n } else {\n const { failure } = result;\n // network = our kickoff timeout firing; 502/504 = gateway giving up while\n // the build runs on. Both mean \"watch via polling, not an error\".\n const isExpectedAsync =\n failure.kind === 'network' ||\n (failure.kind === 'http-error' && (failure.status === 502 || failure.status === 504));\n if (!isExpectedAsync) {\n if (isTerminalFailure(failure)) exitOnFailure(failure);\n console.error(`Error: ${failure.message}`);\n process.exit(1);\n }\n }\n\n // If build completed synchronously, print results and exit\n if (buildCompleted && buildResult) {\n if (json) {\n writeRawOutput(JSON.stringify(buildResult, null, 2));\n return;\n }\n\n if (buildResult.stdout) {\n process.stdout.write(buildResult.stdout);\n if (!buildResult.stdout.endsWith('\\n')) process.stdout.write('\\n');\n }\n if (buildResult.stderr) {\n process.stderr.write(`STDERR: ${buildResult.stderr}`);\n if (!buildResult.stderr.endsWith('\\n')) process.stderr.write('\\n');\n }\n\n if (buildResult.exitCode === 0) {\n console.log('Build complete.');\n } else {\n console.error(`Build failed with exit code ${buildResult.exitCode}`);\n process.exit(1);\n }\n return;\n }\n\n // Build is async — poll diagnostics until the app is reachable or timeout\n if (noWait) {\n console.log('Build started. Use diagnostics to monitor progress:');\n console.log(` canary sandbox diagnostics ${instanceId}`);\n return;\n }\n\n console.log('Build started, watching for services...');\n\n const BUILD_POLL_TIMEOUT_MS = 300_000; // 5 minutes\n const POLL_INTERVAL_MS = 10_000;\n const startTime = Date.now();\n\n while (Date.now() - startTime < BUILD_POLL_TIMEOUT_MS) {\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\n\n const diag = await apiRequest<{ ok: boolean; error?: string; data: DiagnosticsResult }>(\n apiUrl, token, 'GET', `/org/environments/instances/${instanceId}/diagnostics`,\n undefined,\n { timeoutMs: 60_000 }\n );\n\n if (!diag.ok) continue;\n\n const elapsed = Math.round((Date.now() - startTime) / 1000);\n const dockerOutput = 'stdout' in diag.data.docker ? diag.data.docker.stdout : '';\n const appOutput = 'stdout' in diag.data.appHealth ? diag.data.appHealth.stdout : '';\n const appUp = appOutput.length > 0 && !appOutput.includes('UNREACHABLE');\n\n // Show a compact progress line\n const containerCount = (dockerOutput.match(/\\n/g) || []).length + (dockerOutput ? 1 : 0);\n const healthyCount = (dockerOutput.match(/\\(healthy\\)/g) || []).length;\n process.stdout.write(`\\r [${elapsed}s] containers: ${containerCount}, healthy: ${healthyCount}, app: ${appUp ? 'up' : 'waiting'} `);\n\n // Trust the HTTP probe: if nginx is serving the app on :3000 or :8000, we're done.\n // Compose healthchecks are optional and most user services don't declare them.\n if (appUp) {\n process.stdout.write('\\n');\n console.log('Build complete.');\n return;\n }\n }\n\n process.stdout.write('\\n');\n console.error('Build timed out waiting for the app to respond. Check diagnostics and logs:');\n console.error(` canary sandbox diagnostics ${instanceId}`);\n console.error(` canary sandbox logs ${instanceId} --service <name>`);\n process.exit(1);\n}\n\nasync function handleRunCommand(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const service = getArgValue(argv, '--service');\n const timeoutFlag = getArgValue(argv, '--timeout');\n\n // Strip our flags (--json, --service <value>, --timeout <value>) so they\n // don't leak into the remote command.\n const filtered = argv.filter((a, i, arr) => {\n if (a === '--json') return false;\n if (a === '--service' || a === '--timeout') return false;\n if (i > 0 && (arr[i - 1] === '--service' || arr[i - 1] === '--timeout')) return false;\n return true;\n });\n\n // First non-flag arg is the instance ID; everything after it is the command\n // (including flags like -la that belong to the remote command, not to us)\n const firstNonFlag = filtered.findIndex((a) => !a.startsWith('-'));\n const instanceId = firstNonFlag >= 0 ? filtered[firstNonFlag] : undefined;\n const command = firstNonFlag >= 0 ? filtered.slice(firstNonFlag + 1).join(' ') : '';\n\n if (!instanceId || !command) {\n console.error('Error: instance ID and command required. Usage: canary sandbox run-command <instance-id> [--service <name>] [--timeout <ms>] <command...>');\n process.exit(1);\n }\n\n // Server-side run-command caps at 55s (SANDBOX_COMMAND_TIMEOUT). Default\n // the CLI just past that so we surface the server's typed timeout rather\n // than an opaque client-side cancel. For longer ops (test suites,\n // playwright), pass a higher value or use first-class actions.\n const timeoutMs = timeoutFlag ? Math.max(parseInt(timeoutFlag, 10), 1000) : 60_000;\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: { stdout: string; stderr: string; exitCode: number } }>(\n apiUrl, token, 'POST', `/org/environments/instances/${instanceId}/run-command`,\n { command, ...(service ? { service } : {}) },\n { timeoutMs }\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n if (res.data.stdout) {\n process.stdout.write(res.data.stdout);\n if (!res.data.stdout.endsWith('\\n')) process.stdout.write('\\n');\n }\n if (res.data.stderr) {\n process.stderr.write(`STDERR: ${res.data.stderr}`);\n if (!res.data.stderr.endsWith('\\n')) process.stderr.write('\\n');\n }\n if (res.data.exitCode !== 0) {\n console.log(`Exit code: ${res.data.exitCode}`);\n }\n}\n\nasync function handleDiagnostics(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const instanceId = positional[0];\n const json = hasFlag(argv, '--json');\n\n if (!instanceId) {\n console.error('Error: instance ID required. Usage: canary sandbox diagnostics <instance-id>');\n process.exit(1);\n }\n\n // Server-side DIAGNOSTICS_TIMEOUT_MS is 30s; the client needs a bit more\n // headroom than that or we race the server and report a misleading client\n // timeout for a server-side timeout.\n const res = await apiRequest<{ ok: boolean; error?: string; data: DiagnosticsResult }>(\n apiUrl, token, 'GET', `/org/environments/instances/${instanceId}/diagnostics`,\n undefined,\n { timeoutMs: 60_000 }\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n const routes = await fetchInstanceRoutes(apiUrl, token, instanceId);\n const data = { ...res.data, routes };\n\n if (json) {\n writeRawOutput(JSON.stringify(data, null, 2));\n return;\n }\n\n const d = data;\n\n console.log('=== Instance ===');\n for (const [key, value] of Object.entries(d.instance)) {\n console.log(` ${key}: ${value}`);\n }\n\n if (d.lifecycle) {\n console.log('');\n console.log('=== Lifecycle ===');\n console.log(` databaseStatus: ${d.lifecycle.databaseStatus}`);\n console.log(` poolStatus: ${d.lifecycle.poolStatus ?? 'missing'}`);\n console.log(` ec2InstanceState: ${d.lifecycle.ec2InstanceState ?? 'unknown'}`);\n console.log(` live: ${d.lifecycle.live}`);\n if (d.lifecycle.message) writeRawOutput(` message: ${d.lifecycle.message}`);\n }\n\n if (d.provision) {\n console.log('');\n console.log('=== Provisioning ===');\n console.log(` phase: ${d.provision.phase}`);\n console.log(` jobStatus: ${d.provision.jobStatus}`);\n if (d.provision.startedAt) console.log(` startedAt: ${d.provision.startedAt}`);\n if (d.provision.elapsedSeconds !== null) console.log(` elapsed: ${d.provision.elapsedSeconds}s`);\n if (d.provision.lastError) console.log(` lastError: ${d.provision.lastError}`);\n }\n\n const sections: Array<[string, CommandOrError]> = [\n ['Docker Containers', d.docker],\n ['Git Status', d.git],\n ['Disk Usage', d.disk],\n ['Agent Health', d.agentHealth],\n ['App Health', d.appHealth],\n ];\n if (d.resources) sections.splice(3, 0, ['Resource Usage', d.resources]);\n\n for (const [title, result] of sections) {\n console.log('');\n console.log(`=== ${title} ===`);\n if ('error' in result) {\n writeRawOutput(` Error${result.code ? ` [${result.code}]` : ''}: ${result.error}`);\n } else {\n if (result.stdout) writeRawOutput(result.stdout);\n if (result.stderr) writeRawOutput(` STDERR: ${result.stderr}`);\n }\n }\n}\n\nasync function handleTerminate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const instanceId = positional[0];\n\n if (!instanceId) {\n console.error('Error: instance ID required. Usage: canary sandbox terminate <instance-id>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl, token, 'POST', `/org/environments/instances/${instanceId}/terminate`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n console.log(`Instance ${instanceId} termination initiated.`);\n}\n\nasync function handleDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n\n if (!templateId) {\n console.error('Error: template ID required. Usage: canary sandbox delete <template-id>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl, token, 'DELETE', `/org/environments/templates/${templateId}`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n console.log(`Template ${templateId} deleted.`);\n}\n\n// ---------------------------------------------------------------------------\n// Action handlers\n// ---------------------------------------------------------------------------\n\ntype ActionDef = {\n id: string;\n slug: string;\n label: string;\n description: string | null;\n icon: string | null;\n enabled: boolean;\n inputSchema: Record<string, unknown>;\n outputSchema: Record<string, unknown> | null;\n /** Declared handover slots — what this action hands back, and of what kind. */\n outputConfig?: Array<Record<string, unknown>> | null;\n scriptContent: string;\n timeoutMs: number;\n createdAt: string;\n updatedAt: string;\n};\n\ntype ActionExecution = {\n id: string;\n actionId: string;\n instanceId: string;\n source: string;\n status: string;\n result: Record<string, unknown> | null;\n stdout: string | null;\n stderr: string | null;\n exitCode: number | null;\n durationMs: number | null;\n error: string | null;\n createdAt: string;\n};\n\nasync function handleActionList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const json = hasFlag(argv, '--json');\n\n if (!templateId) {\n console.error('Error: template ID required. Usage: canary sandbox action list <template-id>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: ActionDef[] }>(\n apiUrl, token, 'GET', `/org/environments/templates/${templateId}/actions`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n const actions = res.data ?? [];\n if (actions.length === 0) {\n console.log('No actions defined for this template.');\n return;\n }\n\n console.log(`Actions (${actions.length}):`);\n for (const a of actions) {\n const status = a.enabled ? '' : ' [disabled]';\n console.log(` ${pad(a.slug, 30)} ${pad(a.label, 25)}${status}`);\n }\n}\n\nasync function handleActionGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const slug = positional[1];\n const json = hasFlag(argv, '--json');\n\n if (!templateId || !slug) {\n console.error('Error: template ID and slug required. Usage: canary sandbox action get <template-id> <slug>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: ActionDef }>(\n apiUrl, token, 'GET', `/org/environments/templates/${templateId}/actions/${slug}`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n const a = res.data;\n console.log(`Action: ${a.slug}`);\n console.log(` Label: ${a.label}`);\n writeRawOutput(` Description: ${a.description ?? '(none)'}`);\n console.log(` Icon: ${a.icon ?? '(none)'}`);\n console.log(` Enabled: ${a.enabled}`);\n console.log(` Timeout: ${a.timeoutMs}ms`);\n console.log(` Input Schema:`);\n console.log(` ${JSON.stringify(a.inputSchema, null, 2).split('\\n').join('\\n ')}`);\n if (a.outputSchema) {\n console.log(` Output Schema:`);\n console.log(` ${JSON.stringify(a.outputSchema, null, 2).split('\\n').join('\\n ')}`);\n }\n // Printed unconditionally when present: \"did the handover slot actually save\"\n // is the first thing to check when a run reports no results.\n if (a.outputConfig && a.outputConfig.length > 0) {\n console.log(` Output Config (handover slots):`);\n console.log(` ${JSON.stringify(a.outputConfig, null, 2).split('\\n').join('\\n ')}`);\n }\n console.log(` Script:`);\n console.log(` ${a.scriptContent.split('\\n').join('\\n ')}`);\n}\n\nasync function handleActionCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const slug = positional[1];\n const json = hasFlag(argv, '--json');\n\n if (!templateId || !slug) {\n console.error('Error: template ID and slug required. Usage: canary sandbox action create <template-id> <slug> [options]');\n process.exit(1);\n }\n\n const scriptPath = getArgValue(argv, '--script');\n const inputSchemaPath = getArgValue(argv, '--input-schema');\n const outputSchemaPath = getArgValue(argv, '--output-schema');\n const credentialOutputConfigPath = getArgValue(argv, '--credential-output-config');\n const outputConfigPath = getArgValue(argv, '--output-config');\n const label = getArgValue(argv, '--label') ?? slug.replace(/-/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n const description = getArgValue(argv, '--description');\n const icon = getArgValue(argv, '--icon');\n const timeoutStr = getArgValue(argv, '--timeout');\n const encryptScript = hasFlag(argv, '--encrypt-script');\n const credentialTemplateId = getArgValue(argv, '--credential-template');\n const provisioningMode = getArgValue(argv, '--provisioning-mode');\n const runOnProvision = hasFlag(argv, '--run-on-provision');\n const provisionOrderStr = getArgValue(argv, '--provision-order');\n\n if (provisioningMode && provisioningMode !== 'shared' && provisioningMode !== 'unique') {\n console.error(\"Error: --provisioning-mode must be 'shared' or 'unique'\");\n process.exit(1);\n }\n\n if (provisionOrderStr && !/^-?\\d+$/.test(provisionOrderStr)) {\n console.error('Error: --provision-order must be an integer');\n process.exit(1);\n }\n\n if (!scriptPath) {\n console.error('Error: --script <file> is required');\n process.exit(1);\n }\n if (!inputSchemaPath) {\n console.error('Error: --input-schema <file> is required');\n process.exit(1);\n }\n\n let scriptContent: string;\n try {\n scriptContent = readFileSync(scriptPath, 'utf-8');\n } catch (err) {\n console.error(`Error reading script file: ${err}`);\n process.exit(1);\n }\n\n let inputSchema: Record<string, unknown>;\n try {\n inputSchema = JSON.parse(readFileSync(inputSchemaPath, 'utf-8'));\n } catch (err) {\n console.error(`Error reading input schema file: ${err}`);\n process.exit(1);\n }\n\n let outputSchema: Record<string, unknown> | undefined;\n if (outputSchemaPath) {\n try {\n outputSchema = JSON.parse(readFileSync(outputSchemaPath, 'utf-8'));\n } catch (err) {\n console.error(`Error reading output schema file: ${err}`);\n process.exit(1);\n }\n }\n\n let credentialOutputConfig: Record<string, unknown> | undefined;\n if (credentialOutputConfigPath) {\n try {\n credentialOutputConfig = JSON.parse(readFileSync(credentialOutputConfigPath, 'utf-8'));\n } catch (err) {\n console.error(`Error reading credential output config file: ${err}`);\n process.exit(1);\n }\n }\n\n // The declared handover: which files this action leaves behind and what kind\n // each one is. Without this flag the column is only reachable through a raw\n // API call, which would make a shipped feature unusable from the tools an\n // operator actually has. Validated server-side against the output-kind\n // registry, so a bad slot is rejected at save time rather than mid-run.\n let outputConfig: unknown;\n if (outputConfigPath) {\n try {\n outputConfig = JSON.parse(readFileSync(outputConfigPath, 'utf-8'));\n } catch (err) {\n console.error(`Error reading output config file: ${err}`);\n process.exit(1);\n }\n if (!Array.isArray(outputConfig)) {\n console.error('Error: --output-config must contain a JSON array of output slots');\n process.exit(1);\n }\n }\n\n const body: Record<string, unknown> = {\n label,\n scriptContent,\n inputSchema,\n ...(description ? { description } : {}),\n ...(icon ? { icon } : {}),\n ...(outputSchema ? { outputSchema } : {}),\n ...(credentialOutputConfig ? { credentialOutputConfig } : {}),\n ...(outputConfig ? { outputConfig } : {}),\n ...(credentialTemplateId ? { credentialTemplateId } : {}),\n ...(provisioningMode ? { provisioningMode } : {}),\n ...(runOnProvision ? { runOnProvision: true } : {}),\n ...(provisionOrderStr ? { provisionOrder: parseInt(provisionOrderStr, 10) } : {}),\n ...(timeoutStr ? { timeoutMs: parseInt(timeoutStr, 10) } : {}),\n ...(encryptScript ? { scriptEncrypted: true } : {}),\n };\n\n const res = await apiRequest<{ ok: boolean; error?: string; data?: ActionDef }>(\n apiUrl, token, 'PUT', `/org/environments/templates/${templateId}/actions/${slug}`, body\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n console.log(`Action '${slug}' saved (${scriptContent.length} bytes script, label: \"${label}\")`);\n}\n\nasync function handleActionDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const templateId = positional[0];\n const slug = positional[1];\n\n if (!templateId || !slug) {\n console.error('Error: template ID and slug required. Usage: canary sandbox action delete <template-id> <slug>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl, token, 'DELETE', `/org/environments/templates/${templateId}/actions/${slug}`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n console.log(`Action '${slug}' deleted.`);\n}\n\nasync function handleActionExecute(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const instanceId = positional[0];\n const slug = positional[1];\n const json = hasFlag(argv, '--json');\n\n if (!instanceId || !slug) {\n console.error('Error: instance ID and slug required. Usage: canary sandbox action execute <instance-id> <slug> [options]');\n process.exit(1);\n }\n\n // Collect params from --param key=value flags\n let params: Record<string, unknown> = {};\n\n const paramsFile = getArgValue(argv, '--params-file');\n if (paramsFile) {\n try {\n params = JSON.parse(readFileSync(paramsFile, 'utf-8'));\n } catch (err) {\n console.error(`Error reading params file: ${err}`);\n process.exit(1);\n }\n }\n\n // --param flags override params-file\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] === '--param' && argv[i + 1]) {\n const [key, ...valueParts] = argv[i + 1]!.split('=');\n if (key && valueParts.length > 0) {\n params[key] = valueParts.join('=');\n }\n i++; // skip value\n }\n }\n\n interface ActionExecuteResponse {\n executionId: string;\n status: string;\n result: unknown;\n stdout: string | null;\n stderr: string | null;\n exitCode: number | null;\n durationMs: number | null;\n error: string | null;\n credentialId?: string | null;\n }\n\n const runAsync = hasFlag(argv, '--async');\n const timeoutArg = getArgValue(argv, '--timeout-ms');\n let executionTimeoutMs: number | undefined;\n if (timeoutArg) {\n const parsed = Number(timeoutArg);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n console.error(`Error: --timeout-ms must be a positive number, got '${timeoutArg}'`);\n process.exit(1);\n }\n if (!runAsync) {\n // The server ignores it without --async, so accepting it quietly would\n // leave the caller believing a long ceiling was applied when it was not.\n console.error('Error: --timeout-ms only applies with --async');\n process.exit(1);\n }\n executionTimeoutMs = parsed;\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data?: ActionExecuteResponse }>(\n apiUrl, token, 'POST', `/org/environments/instances/${instanceId}/actions/${slug}/execute`, {\n params,\n source: 'cli',\n ...(runAsync ? { async: true } : {}),\n ...(executionTimeoutMs !== undefined ? { executionTimeoutMs } : {}),\n }\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n const exec = res.data!;\n\n // A detached run has no outcome yet, so the completion summary below would\n // print a misleading \"exit ?\" line. Tell the caller how to follow it instead.\n if (runAsync) {\n console.log(`[started] Action '${slug}' running in the background.`);\n console.log(`Execution: ${exec.executionId}`);\n console.log(\n `Follow: cofactor sandbox action execution get ${instanceId} ${exec.executionId}`\n );\n console.log(\n `Cancel: cofactor sandbox action execution cancel ${instanceId} ${exec.executionId}`\n );\n return;\n }\n const statusIcon = exec.status === 'completed' ? '[done]' : exec.status === 'failed' ? '[FAIL]' : `[${exec.status}]`;\n console.log(`${statusIcon} Action '${slug}' ${exec.status} (${exec.durationMs ?? 0}ms, exit ${exec.exitCode ?? '?'})`);\n if (exec.result) {\n console.log(`Result: ${JSON.stringify(exec.result, null, 2)}`);\n }\n if (exec.credentialId) {\n console.log(`Credential: ${exec.credentialId} (linked in property vault)`);\n }\n if (exec.status === 'failed' && exec.stderr) {\n // Cap by bytes first so a single multi-MB line doesn't blow up the terminal,\n // then by line count for readability.\n const tail = exec.stderr.slice(-10_000).trim().split('\\n').slice(-20).join('\\n');\n console.log(`Stderr (last 20 lines):\\n${tail}`);\n }\n if (exec.error) {\n console.log(`Error: ${exec.error}`);\n }\n}\n\nasync function handleActionExecutions(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const instanceId = positional[0];\n const json = hasFlag(argv, '--json');\n\n if (!instanceId) {\n console.error('Error: instance ID required. Usage: canary sandbox action executions <instance-id>');\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data: ActionExecution[] }>(\n apiUrl, token, 'GET', `/org/environments/instances/${instanceId}/actions/executions`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n const execs = res.data ?? [];\n if (execs.length === 0) {\n console.log('No executions yet.');\n return;\n }\n\n console.log('Executions:');\n for (const e of execs) {\n const icon = STATUS_ICONS[e.status] ?? `[${e.status}]`;\n const dur = e.durationMs !== null && e.durationMs !== undefined ? `${e.durationMs}ms` : '?ms';\n console.log(` ${icon} ${pad(e.id.slice(0, 8), 10)} ${pad(e.source, 6)} ${pad(e.status, 12)} ${pad(dur, 8)} ${formatDate(e.createdAt)}`);\n }\n}\n\n/** Print one execution the same way `action execute` prints a finished run. */\nfunction printExecutionDetail(exec: ActionExecution): void {\n const icon = STATUS_ICONS[exec.status] ?? `[${exec.status}]`;\n const dur = exec.durationMs !== null && exec.durationMs !== undefined ? `${exec.durationMs}ms` : '?ms';\n console.log(`${icon} ${exec.status} (${dur}, exit ${exec.exitCode ?? '?'})`);\n console.log(`Execution: ${exec.id}`);\n if (exec.result) {\n console.log(`Result: ${JSON.stringify(exec.result, null, 2)}`);\n }\n if (exec.stderr) {\n const tail = exec.stderr.slice(-10_000).trim().split('\\n').slice(-20).join('\\n');\n if (tail) console.log(`Stderr (last 20 lines):\\n${tail}`);\n }\n if (exec.error) {\n console.log(`Error: ${exec.error}`);\n }\n}\n\n/**\n * Read one execution. For a detached run this is also what advances it: the\n * server reconciles a still-`running` row against SSM on read, so polling this\n * is how a background action reaches a terminal state.\n */\nasync function handleActionExecutionGet(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const instanceId = positional[0];\n const executionId = positional[1];\n const json = hasFlag(argv, '--json');\n\n if (!instanceId || !executionId) {\n console.error(\n 'Error: instance ID and execution ID required. Usage: cofactor sandbox action execution get <instance-id> <execution-id>'\n );\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data?: ActionExecution }>(\n apiUrl,\n token,\n 'GET',\n `/org/environments/instances/${instanceId}/actions/executions/${executionId}`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n printExecutionDetail(res.data!);\n}\n\n/** Stop a detached execution. Idempotent; a finished run is reported as-is. */\nasync function handleActionExecutionCancel(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const instanceId = positional[0];\n const executionId = positional[1];\n const json = hasFlag(argv, '--json');\n\n if (!instanceId || !executionId) {\n console.error(\n 'Error: instance ID and execution ID required. Usage: cofactor sandbox action execution cancel <instance-id> <execution-id>'\n );\n process.exit(1);\n }\n\n const res = await apiRequest<{ ok: boolean; error?: string; data?: ActionExecution }>(\n apiUrl,\n token,\n 'POST',\n `/org/environments/instances/${instanceId}/actions/executions/${executionId}/cancel`\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n printExecutionDetail(res.data!);\n}\n\n// ---------------------------------------------------------------------------\n// Multi-repo: manage repos linked to a sandbox template\n// ---------------------------------------------------------------------------\n\ntype TemplateRepoLink = {\n id: string;\n templateId: string;\n propertyGithubRepoId: string;\n role: string | null;\n branch: string;\n subdirectory: string | null;\n serviceName: string;\n};\n\n/**\n * Parse `role=owner/name@branch:subdir` (branch and subdir optional) into the\n * pieces the API expects. Used by `canary sandbox repo add --spec ...`.\n */\nfunction parseRepoSpec(spec: string): {\n role?: string;\n repoFullName: string;\n branch?: string;\n subdirectory?: string;\n} {\n let rest = spec;\n let role: string | undefined;\n const eq = rest.indexOf('=');\n if (eq > -1 && !rest.slice(0, eq).includes('/')) {\n role = rest.slice(0, eq);\n rest = rest.slice(eq + 1);\n }\n let subdirectory: string | undefined;\n const colon = rest.indexOf(':');\n if (colon > -1) {\n subdirectory = rest.slice(colon + 1);\n rest = rest.slice(0, colon);\n }\n let branch: string | undefined;\n const at = rest.indexOf('@');\n if (at > -1) {\n branch = rest.slice(at + 1);\n rest = rest.slice(0, at);\n }\n return { role, repoFullName: rest, branch, subdirectory };\n}\n\nasync function handleRepoList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const templateId = getArgValue(argv, '--template');\n if (!templateId) {\n console.error('Error: --template is required.');\n process.exit(1);\n }\n\n const result = await apiRequest<{ ok: boolean; items?: TemplateRepoLink[]; error?: string }>(\n apiUrl,\n token,\n 'GET',\n `/org/environments/templates/${templateId}/repos`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(result.items ?? [], null, 2));\n return;\n }\n\n const items = result.items ?? [];\n if (items.length === 0) {\n console.log('No repos linked to this template.');\n return;\n }\n for (const r of items) {\n const role = r.role ? ` [${r.role}]` : '';\n const subdir = r.subdirectory ? `:${r.subdirectory}` : '';\n console.log(` ${r.serviceName} → ${r.propertyGithubRepoId}@${r.branch}${subdir}${role} (link=${r.id})`);\n }\n}\n\nasync function handleRepoAdd(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const templateId = getArgValue(argv, '--template');\n const propertyGithubRepoId = getArgValue(argv, '--property-github-repo-id');\n const spec = getArgValue(argv, '--spec');\n const role = getArgValue(argv, '--role');\n const branch = getArgValue(argv, '--branch');\n const subdirectory = getArgValue(argv, '--subdirectory');\n const serviceName = getArgValue(argv, '--service-name');\n\n if (!templateId || !propertyGithubRepoId) {\n console.error('Error: --template and --property-github-repo-id are required.');\n console.error('Tip: link the repo to the property first via `canary property repo link`, then pass its id here.');\n process.exit(1);\n }\n\n const parsed: ReturnType<typeof parseRepoSpec> | { role?: undefined; branch?: undefined; subdirectory?: undefined } = spec ? parseRepoSpec(spec) : {};\n\n const body: Record<string, unknown> = { propertyGithubRepoId };\n const finalRole = role ?? parsed.role;\n const finalBranch = branch ?? parsed.branch;\n const finalSubdir = subdirectory ?? parsed.subdirectory;\n if (finalRole !== undefined) body.role = finalRole;\n if (finalBranch !== undefined) body.branch = finalBranch;\n if (finalSubdir !== undefined) body.subdirectory = finalSubdir;\n if (serviceName !== undefined) body.serviceName = serviceName;\n\n const result = await apiRequest<{ ok: boolean; data?: TemplateRepoLink; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/org/environments/templates/${templateId}/repos`,\n body\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) writeRawOutput(JSON.stringify(result.data, null, 2));\n else console.log(`Linked repo to template ${templateId} (link=${result.data?.id})`);\n}\n\nasync function handleRepoUpdate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const templateId = getArgValue(argv, '--template');\n const linkId = getArgValue(argv, '--link-id');\n const role = getArgValue(argv, '--role');\n const branch = getArgValue(argv, '--branch');\n const subdirectory = getArgValue(argv, '--subdirectory');\n const serviceName = getArgValue(argv, '--service-name');\n\n if (!templateId || !linkId) {\n console.error('Error: --template and --link-id are required.');\n process.exit(1);\n }\n\n const body: Record<string, unknown> = {};\n if (role !== undefined) body.role = role;\n if (branch !== undefined) body.branch = branch;\n if (subdirectory !== undefined) body.subdirectory = subdirectory;\n if (serviceName !== undefined) body.serviceName = serviceName;\n\n const result = await apiRequest<{ ok: boolean; data?: TemplateRepoLink; error?: string }>(\n apiUrl,\n token,\n 'PATCH',\n `/org/environments/templates/${templateId}/repos/${linkId}`,\n body\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) writeRawOutput(JSON.stringify(result.data, null, 2));\n else console.log(`Updated repo link ${linkId}`);\n}\n\nasync function handleRepoRemove(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const templateId = getArgValue(argv, '--template');\n const linkId = getArgValue(argv, '--link-id');\n if (!templateId || !linkId) {\n console.error('Error: --template and --link-id are required.');\n process.exit(1);\n }\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/environments/templates/${templateId}/repos/${linkId}`\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) writeRawOutput(JSON.stringify(result, null, 2));\n else console.log(`Removed repo link ${linkId} from template ${templateId}`);\n}\n\nasync function handleRepo(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [action, ...rest] = argv;\n switch (action) {\n case 'list':\n await handleRepoList(rest, apiUrl, token);\n break;\n case 'add':\n await handleRepoAdd(rest, apiUrl, token);\n break;\n case 'update':\n await handleRepoUpdate(rest, apiUrl, token);\n break;\n case 'remove':\n case 'rm':\n await handleRepoRemove(rest, apiUrl, token);\n break;\n default:\n console.error(\n `Unknown repo action: ${action ?? '(none)'}. Use list/add/update/remove.\\n` +\n 'Examples:\\n' +\n ' canary sandbox repo list --template <template-id>\\n' +\n ' canary sandbox repo add --template <template-id> --property-github-repo-id <uuid> --role frontend\\n' +\n ' canary sandbox repo add --template <template-id> --property-github-repo-id <uuid> --spec frontend=owner/web@main:/apps/web'\n );\n process.exit(1);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main dispatcher\n// ---------------------------------------------------------------------------\n\nexport async function runSandbox(argv: string[]): Promise<void> {\n // `exec` takes a command after `--`, which no flag scanning below may read.\n const { options, passthrough } =\n argv[0] === 'exec' ? splitAtSeparator(argv) : { options: argv, passthrough: [] };\n const [subCommand, ...rest] = options;\n\n if (!subCommand || subCommand === 'help' || hasFlag(options, '--help', '-h')) {\n printHelp();\n return;\n }\n\n // Guide needs no auth: served by the API with a bundled fallback. `guide [topic]` serves the\n // Sandboxes v2 guide (`guide v2 [topic]` is the same); `guide v1 [section]`\n // serves the legacy v1 guide.\n if (subCommand === 'guide') {\n // `v1` / `v2` is the first positional, wherever flags such as --json sit.\n const version = getGuideSectionArg(rest);\n const legacy = version === 'v1';\n const versionAt = legacy || version === 'v2' ? rest.indexOf(version) : -1;\n const guideRest = versionAt === -1 ? rest : [...rest.slice(0, versionAt), ...rest.slice(versionAt + 1)];\n const section = getGuideSectionArg(guideRest);\n const sections = legacy ? SANDBOX_GUIDE_SECTIONS : SANDBOX_V2_GUIDE_SECTIONS;\n // `guide` printed the v1 guide until 2026-11; point an old `guide research` at where it went.\n if (section && !sections.some((s) => s.slug === section) && SANDBOX_GUIDE_SECTIONS.some((s) => s.slug === section)) {\n console.error(`\"${section}\" is a section of the v1 sandbox guide: run \"cofactor sandbox guide v1 ${section}\".`);\n process.exit(1);\n }\n await printServedGuide(legacy ? 'sandbox' : 'sandbox-v2', guideRest);\n return;\n }\n\n // Sandboxes v2 `validate` is purely local (offline schema + cross-check) —\n // no auth needed, same as `guide`.\n if (subCommand === 'validate') {\n handleSandboxValidate(rest);\n return;\n }\n\n const { apiUrl, token, appSubdomain } = await resolveConfig(options);\n\n // Strip global flags consumed by resolveConfig so handlers don't see them as positional args.\n // `--app-url` travels with `--api-url` (a worktree or self-hosted target); the CI push\n // workflow passed it and every v2 command refused it (2026-10-04).\n const globalFlags = new Set(['--env', '--api-url', '--app-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 rejectUnknownSandboxV2Args(subCommand, args);\n\n switch (subCommand) {\n case 'list':\n await handleList(args, apiUrl, token);\n break;\n case 'template':\n await handleTemplate(args, apiUrl, token);\n break;\n case 'repo':\n await handleRepo(args, apiUrl, token);\n break;\n case 'artifacts':\n await handleArtifacts(args, apiUrl, token);\n break;\n case 'checklist':\n await handleChecklist(args, apiUrl, token);\n break;\n case 'create':\n await handleCreate(args, apiUrl, token);\n break;\n case 'provision':\n await handleProvision(args, apiUrl, token);\n break;\n case 'warm':\n // `warm list|set|show|clear` keeps a Sandboxes v2 environment warm; `warm <template-id>` is the v1 template warm-up.\n if (isSandboxV2WarmCommand(args[0])) await handleSandboxWarm(args, apiUrl, token);\n else await handleWarm(args, apiUrl, token);\n break;\n case 'verify':\n await handleVerify(args, apiUrl, token);\n break;\n case 'set-size':\n await handleSetSize(args, apiUrl, token);\n break;\n case 'pool': {\n const [poolAction, ...poolRest] = args;\n if (poolAction === 'set-size') {\n await handlePoolSetSize(poolRest, apiUrl, token);\n } else {\n console.error(`Unknown pool action: ${poolAction}. Use \"set-size\".`);\n process.exit(1);\n }\n break;\n }\n case 'artifact': {\n const [action, ...actionRest] = args;\n if (action === 'get') {\n await handleArtifactGet(actionRest, apiUrl, token);\n } else if (action === 'create') {\n await handleArtifactCreate(actionRest, apiUrl, token);\n } else {\n console.error(`Unknown artifact action: ${action}. Use \"get\" or \"create\".`);\n process.exit(1);\n }\n break;\n }\n case 'config': {\n const [configAction, ...configRest] = args;\n if (configAction === 'list') {\n await handleConfigList(configRest, apiUrl, token);\n } else if (configAction === 'set') {\n await handleConfigSet(configRest, apiUrl, token);\n } else if (configAction === 'unset') {\n await handleConfigUnset(configRest, apiUrl, token);\n } else {\n console.error(`Unknown config action: ${configAction}. Use \"list\", \"set\", or \"unset\".`);\n process.exit(1);\n }\n break;\n }\n case 'emulation':\n await handleEmulation(args, apiUrl, token);\n break;\n case 'action': {\n const [actionSub, ...actionRest] = args;\n switch (actionSub) {\n case 'list':\n await handleActionList(actionRest, apiUrl, token);\n break;\n case 'get':\n await handleActionGet(actionRest, apiUrl, token);\n break;\n case 'create':\n await handleActionCreate(actionRest, apiUrl, token);\n break;\n case 'delete':\n await handleActionDelete(actionRest, apiUrl, token);\n break;\n case 'execute':\n await handleActionExecute(actionRest, apiUrl, token);\n break;\n case 'executions':\n await handleActionExecutions(actionRest, apiUrl, token);\n break;\n case 'execution': {\n const [execSub, ...execRest] = actionRest;\n if (execSub === 'get') {\n await handleActionExecutionGet(execRest, apiUrl, token);\n } else if (execSub === 'cancel') {\n await handleActionExecutionCancel(execRest, apiUrl, token);\n } else {\n console.error(`Unknown execution sub-command: ${execSub}. Use \"get\" or \"cancel\".`);\n process.exit(1);\n }\n break;\n }\n default:\n console.error(`Unknown action sub-command: ${actionSub}. Use \"list\", \"get\", \"create\", \"delete\", \"execute\", \"executions\", or \"execution\".`);\n process.exit(1);\n }\n break;\n }\n case 'build':\n await handleBuild(args, apiUrl, token);\n break;\n case 'run-command':\n await handleRunCommand(args, apiUrl, token);\n break;\n case 'diagnostics':\n await handleDiagnostics(args, apiUrl, token);\n break;\n case 'logs':\n await handleLogs(args, apiUrl, token);\n break;\n case 'preview':\n await handlePreview(args, apiUrl, token, appSubdomain);\n break;\n case 'envs':\n await handleSandboxEnvs(args, apiUrl, token);\n break;\n case 'refresh':\n await handleSandboxRefresh(args, apiUrl, token);\n break;\n case 'connect':\n await handleSandboxConnect(args, apiUrl, token);\n break;\n case 'push':\n await handleSandboxPush(args, apiUrl, token);\n break;\n case 'secret':\n await handleSandboxSecret(args, apiUrl, token);\n break;\n case 'claim':\n await handleSandboxClaim(args, apiUrl, token);\n break;\n case 'claims':\n await handleSandboxClaims(args, apiUrl, token);\n break;\n case 'show':\n await handleSandboxShow(args, apiUrl, token);\n break;\n case 'run':\n await handleSandboxRun(args, apiUrl, token);\n break;\n case 'exec':\n await handleSandboxExec(args, passthrough, apiUrl, token);\n break;\n case 'sync':\n await handleSandboxSync(v2Positionals('sync', args), args, apiUrl, token);\n break;\n case 'verify-env':\n await handleSandboxVerifyEnv(args, apiUrl, token);\n break;\n case 'destroy':\n await handleSandboxDestroy(args, apiUrl, token);\n break;\n case 'terminate':\n await handleTerminate(args, apiUrl, token);\n break;\n case 'delete':\n await handleDelete(args, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printHelp();\n process.exit(1);\n }\n}\n","import process from 'node:process';\nimport { readFileSync } from 'node:fs';\nimport type { EmulationPluginEntry, EmulationTemplateConfig } from '@chatsdet/emulation';\nimport { getAllPlugins, getPluginIds } from '@chatsdet/emulation/plugins';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { writeRawOutput } from './brand.js';\n\n/** One configured plugin as enriched by GET .../emulation (descriptions only, never secret values). */\ntype EmulationCatalogEntry = {\n pluginId: string;\n name: string;\n version: string;\n enabled: boolean;\n envContract: Array<{\n logicalKey: string;\n strategy: string;\n sensitive: boolean;\n description?: string;\n }>;\n inboundEvents: Array<{ id: string; description?: string }>;\n actionInterfaces: Array<{ slug: string; implemented: boolean }>;\n};\n\nconst pad = (value: string, width: number): string => value.padEnd(width);\n\n/**\n * Read the template's stored emulation config + plugin catalog. The GET route\n * returns `{ ok, config, catalog }`, not a `data` wrapper. Falls back to the\n * empty default config when the template has none.\n */\nasync function fetchEmulation(\n apiUrl: string,\n token: string,\n templateId: string\n): Promise<{ config: EmulationTemplateConfig; catalog: EmulationCatalogEntry[] }> {\n const res = await apiRequest<{\n ok: boolean;\n error?: string;\n config?: EmulationTemplateConfig;\n catalog?: EmulationCatalogEntry[];\n }>(apiUrl, token, 'GET', `/org/environments/templates/${templateId}/emulation`);\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n // Fresh literal (not a shared module singleton) so callers/transforms can\n // never accidentally mutate a process-wide default.\n return { config: res.config ?? { enabled: false, plugins: [] }, catalog: res.catalog ?? [] };\n}\n\n/**\n * Write the full emulation config back. The PATCH route is a full replace of\n * `{ enabled, plugins[] }`, so every mutating command must read-modify-write\n * the whole object.\n */\nasync function patchEmulation(\n apiUrl: string,\n token: string,\n templateId: string,\n config: EmulationTemplateConfig\n): Promise<void> {\n const res = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'PATCH',\n `/org/environments/templates/${templateId}/emulation`,\n { enabled: config.enabled, plugins: config.plugins },\n { timeoutMs: 90_000 }\n );\n\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n}\n\n/** Reject a pluginId that is not a known emulation plugin, with the valid list. */\nfunction assertKnownPlugin(pluginId: string): void {\n const ids = getPluginIds();\n if (!ids.includes(pluginId)) {\n console.error(`Error: unknown plugin '${pluginId}'. Available: ${ids.join(', ')}`);\n process.exit(1);\n }\n}\n\nfunction readJsonFileOrExit(path: string, flag: string): unknown {\n let raw: string;\n try {\n raw = readFileSync(path, 'utf-8');\n } catch (err) {\n console.error(\n `Error reading ${flag} file '${path}': ${err instanceof Error ? err.message : String(err)}`\n );\n process.exit(1);\n }\n try {\n return JSON.parse(raw);\n } catch (err) {\n console.error(\n `Error parsing ${flag} file '${path}' as JSON: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n process.exit(1);\n }\n}\n\n/**\n * Like `readJsonFileOrExit` but rejects anything that is not a plain JSON object\n * (arrays, strings, numbers, null all parse fine but would fail the server's\n * `z.record(...)` validation with a cryptic error). Used for `--config` and\n * `--env-mapping`; `--fixture` stays unrestricted since fixtures are arbitrary.\n */\nfunction readJsonObjectOrExit(path: string, flag: string): Record<string, unknown> {\n const parsed = readJsonFileOrExit(path, flag);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n console.error(\n `Error: ${flag} file '${path}' must contain a JSON object, not ${\n Array.isArray(parsed) ? 'an array' : typeof parsed\n }.`\n );\n process.exit(1);\n }\n return parsed as Record<string, unknown>;\n}\n\n// The PATCH route is a full replace, so each mutating command produces a fresh\n// EmulationTemplateConfig from the fetched one. These are pure so the\n// read-modify-write semantics can be tested without network/IO.\n\n/** Flip the master switch, leaving plugin entries untouched. */\nexport function withEmulationMaster(\n config: EmulationTemplateConfig,\n enabled: boolean\n): EmulationTemplateConfig {\n return { enabled, plugins: [...(config.plugins ?? [])] };\n}\n\n/**\n * Toggle one plugin entry's `enabled`. Enabling a not-yet-configured plugin\n * adds a bare entry; enabling any plugin also turns the master switch on.\n * Disabling assumes the entry exists (callers validate first for a friendly error).\n */\nexport function withPluginEnabled(\n config: EmulationTemplateConfig,\n pluginId: string,\n enabled: boolean\n): EmulationTemplateConfig {\n const plugins = [...(config.plugins ?? [])];\n const idx = plugins.findIndex((plugin) => plugin.pluginId === pluginId);\n if (idx === -1) {\n if (enabled) plugins.push({ pluginId, enabled: true, config: {} });\n } else {\n plugins[idx] = { ...plugins[idx], enabled };\n }\n return { enabled: enabled ? true : config.enabled, plugins };\n}\n\n/**\n * Upsert a plugin entry's config/fixture/envMapping, preserving any field not\n * provided in `patch` and the existing `enabled`. New entries default to\n * `enabled: false`: `set` only configures; activation is always explicit.\n */\nexport function withPluginConfig(\n config: EmulationTemplateConfig,\n pluginId: string,\n patch: {\n config?: Record<string, unknown>;\n fixture?: unknown;\n envMapping?: Record<string, string | string[]>;\n }\n): EmulationTemplateConfig {\n const plugins = [...(config.plugins ?? [])];\n const idx = plugins.findIndex((plugin) => plugin.pluginId === pluginId);\n const existing = idx === -1 ? undefined : plugins[idx];\n\n const merged: EmulationPluginEntry = {\n pluginId,\n enabled: existing?.enabled ?? false,\n config: patch.config !== undefined ? patch.config : (existing?.config ?? {}),\n };\n const fixture = patch.fixture !== undefined ? patch.fixture : existing?.fixture;\n if (fixture !== undefined) merged.fixture = fixture;\n const envMapping = patch.envMapping !== undefined ? patch.envMapping : existing?.envMapping;\n if (envMapping !== undefined) merged.envMapping = envMapping;\n\n if (idx === -1) plugins.push(merged);\n else plugins[idx] = merged;\n return { enabled: config.enabled, plugins };\n}\n\n/** Drop a plugin entry (callers validate existence first). */\nexport function withoutPlugin(\n config: EmulationTemplateConfig,\n pluginId: string\n): EmulationTemplateConfig {\n return {\n enabled: config.enabled,\n plugins: (config.plugins ?? []).filter((plugin) => plugin.pluginId !== pluginId),\n };\n}\n\nasync function handleEmulationGet(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const positional = argv.filter((arg) => !arg.startsWith('-'));\n const templateId = positional[0];\n const json = hasFlag(argv, '--json');\n\n if (!templateId) {\n console.error('Error: template ID required. Usage: canary sandbox emulation get <template-id>');\n process.exit(1);\n }\n\n const { config, catalog } = await fetchEmulation(apiUrl, token, templateId);\n const available = getAllPlugins().map((plugin) => ({ id: plugin.id, name: plugin.name }));\n\n if (json) {\n writeRawOutput(JSON.stringify({ config, catalog, availablePlugins: available }, null, 2));\n return;\n }\n\n console.log(`Emulation: ${config.enabled ? 'ENABLED' : 'disabled'} (master switch)`);\n const configured = config.plugins ?? [];\n if (configured.length === 0) {\n console.log(' No plugins configured.');\n } else {\n console.log(` Configured plugins (${configured.length}):`);\n for (const plugin of configured) {\n const status = plugin.enabled ? '' : ' [disabled]';\n console.log(` ${pad(plugin.pluginId, 16)}${status}`);\n const catalogEntry = catalog.find((entry) => entry.pluginId === plugin.pluginId);\n if (catalogEntry && catalogEntry.envContract.length > 0) {\n console.log(\n ` env contract: ${catalogEntry.envContract.map((entry) => entry.logicalKey).join(', ')}`\n );\n }\n if (catalogEntry && catalogEntry.actionInterfaces.length > 0) {\n const implemented = catalogEntry.actionInterfaces.filter((action) => action.implemented).length;\n console.log(\n ` action interfaces: ${implemented}/${catalogEntry.actionInterfaces.length} implemented`\n );\n }\n const keys = Object.keys(plugin.config ?? {});\n if (keys.length > 0) console.log(` config keys: ${keys.join(', ')}`);\n const extras = [\n plugin.fixture !== undefined ? 'fixture' : null,\n plugin.envMapping ? 'envMapping' : null,\n ].filter(Boolean);\n if (extras.length > 0) console.log(` set: ${extras.join(', ')}`);\n }\n }\n console.log(` Available plugins: ${available.map((plugin) => plugin.id).join(', ')}`);\n}\n\n/** Shared enable/disable for the master switch or a single plugin entry. */\nasync function setEmulationEnabled(\n argv: string[],\n apiUrl: string,\n token: string,\n enable: boolean\n): Promise<void> {\n const positional = argv.filter((arg) => !arg.startsWith('-'));\n const templateId = positional[0];\n const pluginId = positional[1];\n const verb = enable ? 'enable' : 'disable';\n\n if (!templateId) {\n console.error(\n `Error: template ID required. Usage: canary sandbox emulation ${verb} <template-id> [pluginId]`\n );\n process.exit(1);\n }\n\n const { config } = await fetchEmulation(apiUrl, token, templateId);\n let next: EmulationTemplateConfig;\n\n if (!pluginId) {\n next = withEmulationMaster(config, enable);\n } else {\n assertKnownPlugin(pluginId);\n const exists = (config.plugins ?? []).some((plugin) => plugin.pluginId === pluginId);\n if (!enable && !exists) {\n console.error(`Error: plugin '${pluginId}' is not configured on this template.`);\n process.exit(1);\n }\n next = withPluginEnabled(config, pluginId, enable);\n }\n\n await patchEmulation(apiUrl, token, templateId, next);\n console.log(pluginId ? `Plugin ${pluginId} ${verb}d` : `Emulation ${verb}d`);\n}\n\nasync function handleEmulationSet(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const positional = argv.filter((arg) => !arg.startsWith('-'));\n const templateId = positional[0];\n const pluginId = positional[1];\n\n if (!templateId || !pluginId) {\n console.error('Error: template ID and pluginId required.');\n console.error(\n 'Usage: canary sandbox emulation set <template-id> <pluginId> [--config <file>] [--fixture <file>] [--env-mapping <file>]'\n );\n process.exit(1);\n }\n assertKnownPlugin(pluginId);\n\n const configPath = getArgValue(argv, '--config');\n const fixturePath = getArgValue(argv, '--fixture');\n const envMappingPath = getArgValue(argv, '--env-mapping');\n\n if (!configPath && !fixturePath && !envMappingPath) {\n console.error('Error: provide at least one of --config, --fixture, --env-mapping');\n process.exit(1);\n }\n\n const pluginConfig = configPath ? readJsonObjectOrExit(configPath, '--config') : undefined;\n const fixture = fixturePath ? readJsonFileOrExit(fixturePath, '--fixture') : undefined;\n const envMapping = envMappingPath\n ? (readJsonObjectOrExit(envMappingPath, '--env-mapping') as Record<\n string,\n string | string[]\n >)\n : undefined;\n\n const { config } = await fetchEmulation(apiUrl, token, templateId);\n const next = withPluginConfig(config, pluginId, {\n ...(pluginConfig !== undefined ? { config: pluginConfig } : {}),\n ...(fixture !== undefined ? { fixture } : {}),\n ...(envMapping !== undefined ? { envMapping } : {}),\n });\n\n await patchEmulation(apiUrl, token, templateId, next);\n // A plugin only runs when BOTH the master switch and its own entry are on.\n // `set` never flips either, so point the user at `enable` unless it is already active.\n const entry = next.plugins.find((plugin) => plugin.pluginId === pluginId);\n const active = next.enabled && entry?.enabled;\n const hint = active ? '' : ` (inactive — run \"emulation enable ${templateId} ${pluginId}\" to activate)`;\n console.log(`Emulation plugin set: ${pluginId}${hint}`);\n}\n\nasync function handleEmulationRemove(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const positional = argv.filter((arg) => !arg.startsWith('-'));\n const templateId = positional[0];\n const pluginId = positional[1];\n\n if (!templateId || !pluginId) {\n console.error(\n 'Error: template ID and pluginId required. Usage: canary sandbox emulation remove <template-id> <pluginId>'\n );\n process.exit(1);\n }\n\n const { config } = await fetchEmulation(apiUrl, token, templateId);\n if (!(config.plugins ?? []).some((plugin) => plugin.pluginId === pluginId)) {\n console.error(`Error: plugin '${pluginId}' is not configured on this template.`);\n process.exit(1);\n }\n\n const next = withoutPlugin(config, pluginId);\n\n await patchEmulation(apiUrl, token, templateId, next);\n console.log(`Emulation plugin removed: ${pluginId}`);\n}\n\nexport async function handleEmulation(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const [action, ...rest] = argv;\n switch (action) {\n case 'get':\n await handleEmulationGet(rest, apiUrl, token);\n break;\n case 'enable':\n await setEmulationEnabled(rest, apiUrl, token, true);\n break;\n case 'disable':\n await setEmulationEnabled(rest, apiUrl, token, false);\n break;\n case 'set':\n await handleEmulationSet(rest, apiUrl, token);\n break;\n case 'remove':\n case 'rm':\n await handleEmulationRemove(rest, apiUrl, token);\n break;\n default:\n console.error(\n `Unknown emulation action: ${action ?? '(none)'}. Use get/enable/disable/set/remove.`\n );\n process.exit(1);\n }\n}\n","import process from 'node:process';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { writeRawOutput } from './brand.js';\n\ntype FailureLogsUrlResponse = {\n ok: boolean;\n error?: string;\n data?: { url: string; key: string };\n};\n\ntype LiveLogsResponse = {\n ok: boolean;\n error?: string;\n data: { logs: string };\n};\n\nexport type FailureLogsBundle = { text: string; key: string } | { error: string };\n\ntype FailureLogsDependencies = {\n requestFailureLogsUrl?: (\n apiUrl: string,\n token: string,\n instanceId: string\n ) => Promise<FailureLogsUrlResponse>;\n fetch?: (url: string) => Promise<Response>;\n};\n\nconst requestFailureLogsUrl = (apiUrl: string, token: string, instanceId: string) =>\n apiRequest<FailureLogsUrlResponse>(\n apiUrl,\n token,\n 'GET',\n `/org/environments/instances/${instanceId}/logs/failure`\n );\n\nexport async function decodeFailureLogsBundle(buf: Buffer): Promise<string> {\n const { gunzipSync } = await import('node:zlib');\n try {\n return gunzipSync(buf).toString('utf8');\n } catch {\n return buf.toString('utf8');\n }\n}\n\n/**\n * Fetch a failed/terminated instance's captured full-log bundle: presign a GET\n * off the API, download the gzip from S3, and return the decompressed text.\n * Returns `{ error }` (never throws) so callers can fall back cleanly.\n */\nexport async function fetchFailureLogsBundle(\n apiUrl: string,\n token: string,\n instanceId: string,\n deps: FailureLogsDependencies = {}\n): Promise<FailureLogsBundle> {\n const res = await (deps.requestFailureLogsUrl ?? requestFailureLogsUrl)(apiUrl, token, instanceId);\n if (!res.ok || !res.data?.url) {\n return { error: res.error ?? 'No captured diagnostic logs' };\n }\n try {\n const resp = await (deps.fetch ?? fetch)(res.data.url);\n if (!resp.ok) return { error: `Failed to download bundle (HTTP ${resp.status})` };\n const buf = Buffer.from(await resp.arrayBuffer());\n return { text: await decodeFailureLogsBundle(buf), key: res.data.key };\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nexport async function handleLogs(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const instanceId = positional[0];\n const json = hasFlag(argv, '--json');\n\n if (!instanceId) {\n console.error('Error: instance ID required. Usage: canary sandbox logs <instance-id>');\n process.exit(1);\n }\n\n const service = getArgValue(argv, '--service');\n const tail = getArgValue(argv, '--tail') ?? '200';\n const source = getArgValue(argv, '--source');\n const forceFailure = hasFlag(argv, '--failure') || source === 'failure';\n\n // Failure snapshot: the durable full-log bundle captured to S3 when the\n // instance failed to provision. Works for `failed`/`terminated` instances\n // (live docker/logs needs a running host). Forced with --failure/--source\n // failure, and used as an automatic fallback when the live tail can't run.\n if (forceFailure) {\n const bundle = await fetchFailureLogsBundle(apiUrl, token, instanceId);\n if ('error' in bundle) {\n console.error(`Error: ${bundle.error}`);\n process.exit(1);\n }\n if (json) {\n writeRawOutput(JSON.stringify(bundle, null, 2));\n return;\n }\n process.stdout.write(bundle.text || '(empty bundle)');\n return;\n }\n\n // Live path: tail the running containers via SSM. Don't send `service: ''`\n // — the server's regex validator rejects empty strings even though the field\n // is optional, and the route then returns 500 instead of an all-services tail.\n const res = await apiRequest<LiveLogsResponse>(\n apiUrl,\n token,\n 'POST',\n `/org/environments/instances/${instanceId}/docker/logs`,\n {\n ...(service ? { service } : {}),\n tail: parseInt(tail, 10),\n }\n );\n\n if (!res.ok) {\n // The instance likely isn't running (failed/terminated). Fall back to the\n // captured failure snapshot so a dead provision is still diagnosable.\n const bundle = await fetchFailureLogsBundle(apiUrl, token, instanceId);\n if (!('error' in bundle)) {\n if (json) {\n writeRawOutput(JSON.stringify(bundle, null, 2));\n return;\n }\n console.error(`(live logs unavailable: ${res.error}; showing captured failure snapshot)\\n`);\n process.stdout.write(bundle.text || '(empty bundle)');\n return;\n }\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n\n process.stdout.write(res.data.logs ?? '(no logs)');\n}\n","import process from 'node:process';\nimport { sandboxPreviewPagePath } from '@chatsdet/types';\nimport { getArgValue, hasFlag, resolveOrgAppUrl } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { writeRawOutput } from './brand.js';\nimport { resolveApplicationId } from './environment.js';\n\ntype PreviewResponse = {\n ok: boolean;\n error?: string;\n data: {\n applicationId: string;\n prNumber: number;\n status: string;\n headSha: string;\n appliedSha: string | null;\n portUrls: Record<string, string>;\n error: string | null;\n readyMs: number | null;\n leaseExpiresAt: string | null;\n personas: { name: string; email: string; password: string }[];\n };\n};\n\n/**\n * `cofactor sandbox preview --application A --pr N`: a pull request's\n * Sandboxes v2 preview of an application, with every service URL and\n * the logins, and the sign-in-required Cofactor page that shows the same\n * (the pull request's GitHub deployment links that page, never the logins).\n */\nexport async function handlePreview(\n argv: string[],\n apiUrl: string,\n token: string,\n appSubdomain: string | null | undefined\n): Promise<void> {\n const pr = getArgValue(argv, '--pr');\n if (!pr) {\n console.error('Usage: cofactor sandbox preview --application <name|id> --pr <number> [--json]');\n process.exit(1);\n }\n const application = await resolveApplicationId(argv, apiUrl, token);\n const query = new URLSearchParams({ application, pr });\n const res = await apiRequest<PreviewResponse>(apiUrl, token, 'GET', `/org/sandboxes-v2/previews?${query}`);\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n const preview = res.data;\n if (hasFlag(argv, '--json')) {\n writeRawOutput(JSON.stringify(preview, null, 2));\n return;\n }\n const lines = [\n `#${preview.prNumber}: ${preview.status}`,\n ` page ${resolveOrgAppUrl(apiUrl, appSubdomain)}${sandboxPreviewPagePath(preview.applicationId, preview.prNumber)}`,\n ` commit ${(preview.appliedSha ?? preview.headSha).slice(0, 12)}${preview.appliedSha && preview.appliedSha !== preview.headSha ? ` (building ${preview.headSha.slice(0, 12)})` : ''}`,\n ...Object.entries(preview.portUrls).map(([name, url]) => ` ${name.padEnd(8)} ${url}`),\n ...preview.personas.map((p) => ` ${p.name.padEnd(8)} ${p.email} ${p.password}`),\n ];\n if (preview.leaseExpiresAt) lines.push(` expires ${preview.leaseExpiresAt}`);\n if (preview.error) lines.push('', preview.error);\n console.log(lines.join('\\n'));\n}\n","/**\n * Sandboxes v2 CLI, addressed by application: connect its repository (or\n * push images — `sandbox-push.ts`), browse what its `cofactor.sandbox.yaml`\n * offers, claim a sandbox, run its actions and emulator operations, and\n * prove an environment's seed chain end to end — all under `cofactor sandbox`.\n *\n * `--env` stays the CLI's global stage flag (dev/prod); a sandbox flavor is\n * always `--environment`. See `packages/content/src/sandbox-v2-guide/` for\n * the full guide (`cofactor sandbox guide v2`).\n *\n * @module\n */\n\nimport process from 'node:process';\nimport { readFileSync } from 'node:fs';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, fetchProperties, getArgValues } from './cli-helpers.js';\nimport { resolveApplicationId, resolveOrCreateSandboxApplication } from './environment.js';\nimport { parseDurationSeconds } from './utilities.js';\nimport { writeRawOutput } from './brand.js';\nimport {\n EXEC_DEFAULT_TIMEOUT_SECONDS,\n EXEC_MAX_TIMEOUT_SECONDS,\n validateDefinition,\n type DefinitionIssue,\n} from '@chatsdet/sandbox-helper/manifest';\nimport { pluginOperations } from '@chatsdet/emulation';\n\n// ---------------------------------------------------------------------------\n// Shared types (mirroring apps/api/src/sandboxes-v2/routes.ts response shapes)\n// ---------------------------------------------------------------------------\n\ntype ActionInputProp = {\n type: 'string' | 'number' | 'integer' | 'boolean' | 'persona';\n description?: string;\n required?: boolean;\n default?: string | number | boolean;\n enum?: Array<string | number>;\n sensitive?: boolean;\n};\n\ntype ActionOutputProp = { type: 'string' | 'number' | 'integer' | 'boolean'; description?: string };\n\ntype ActionEntry = {\n slug: string;\n description: string;\n input: Record<string, ActionInputProp>;\n output: Record<string, ActionOutputProp>;\n timeout: number;\n};\n\ntype OperationEntry = {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n outputSchema: Record<string, unknown>;\n};\n\ntype EnvironmentEntry = {\n name: string;\n description: string;\n extends: string | null;\n seeds: Array<{ id: string; action: string; input: Record<string, unknown> }>;\n envKeys: string[];\n};\n\ntype DefinitionEntry = {\n environments: EnvironmentEntry[];\n actions: ActionEntry[];\n operations: OperationEntry[];\n personas: string[];\n ports: Array<{ name: string; access: string }>;\n emulation: string[];\n};\n\nexport type PushEntry = {\n id: string;\n status: 'uploading' | 'importing' | 'ready' | 'failed';\n tags: string[];\n error: string | null;\n createdAt: string;\n};\n\n/** `GET /org/applications/:id/sandbox`: the application's sandbox setting and its definition at the default version. */\ntype ApplicationSandbox = {\n applicationId: string;\n delivery: 'github' | 'upload';\n repo: string | null;\n definitionDir: string | null;\n sandboxEnvironments: Array<{ id: string; name: string; environment: string }>;\n /** Each environment's head: what flow runs and unpinned claims use (a warm environment switches to it after its warm-up). Absent from an older API. */\n heads?: Array<{\n environment: string;\n status: 'ready' | 'warming' | 'stale' | 'none';\n version: string | null;\n builtAt: string | null;\n error: string | null;\n /** The default branch's head now (GitHub-delivered; null when GitHub could not be asked). */\n mainHead: string | null;\n behindMain: boolean | null;\n }>;\n /** An upload-delivered application's newest pushes; null for a GitHub-delivered one. */\n pushes: PushEntry[] | null;\n /** A commit SHA, or a push id; null before the first push is ready. */\n version: string | null;\n definition: DefinitionEntry | null;\n};\n\ntype Refusal = { ok: boolean; error?: string; code?: string; issues?: DefinitionIssue[] };\n\ntype ApplicationSandboxResponse = Refusal & { data: ApplicationSandbox };\n\ntype ClaimListItem = Pick<SandboxData, 'id' | 'applicationId' | 'environment' | 'status' | 'leaseExpiresAt'> & { createdAt: string };\n\ntype SandboxData = {\n id: string;\n applicationId: string;\n environment: string;\n /** A commit SHA, or a push id. */\n version: string;\n status: 'claiming' | 'ready' | 'failed' | 'destroyed';\n /** Claiming, and waiting on its push's upgrade to the current sandbox platform. */\n upgrading: boolean;\n /** Whether its definition declares `authentication` (native Login nodes). Absent from an older API. */\n nativeLogin?: boolean;\n error: string | null;\n portUrls: Record<string, string>;\n personas: Array<{ name: string; email: string; password: string }>;\n /** Opens the copy's sign-in chooser; only a copy whose definition declares `oidc` has one. */\n signInUrl: string | null;\n /** What `cofactor sandbox sync` last synced into it; absent from an older API. */\n synced?: { tree: string; buildOutput: boolean; at: string } | null;\n seedOutputs: Record<string, Record<string, unknown>>;\n leaseExpiresAt: string | null;\n expired: boolean;\n readyMs: number | null;\n /** Set when ready: waiting for the commit's ready snapshot, restoring the copy, and preparing it. */\n phases: { snapshotMs: number; restoreMs: number; prepareMs: number } | null;\n /** The ready snapshot this sandbox is a copy of: when it was built, and how long each part took. */\n snapshot: {\n builtAt: string;\n buildPhases: {\n buildMs: number;\n /** Absent on snapshots built before step timings were recorded. */\n build?: { steps: { name: string; ran: boolean; ms: number }[]; checkoutMs: number; restartMs: number };\n prepareMs: number;\n seeds: { id: string; action: string; ms: number }[];\n } | null;\n } | null;\n actions: ActionEntry[];\n operations: OperationEntry[];\n};\n\ntype SandboxResponse = { ok: boolean; error?: string; data: SandboxData };\n\ntype RunData = {\n id: string;\n sandboxId: string;\n action: string;\n seedStepId: string | null;\n input: Record<string, unknown>;\n status: 'running' | 'succeeded' | 'failed';\n output: Record<string, unknown> | null;\n exitCode: number | null;\n stdoutTail: string | null;\n stderrTail: string | null;\n error: string | null;\n durationMs: number | null;\n createdAt: string;\n completedAt: string | null;\n};\n\ntype RunResponse = { ok: boolean; error?: string; data: RunData };\n\ntype RunEnqueueResponse = {\n ok: boolean;\n error?: string;\n code?: string;\n issues?: Array<string | { path?: Array<string | number>; message?: string }>;\n data?: { id: string };\n};\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nfunction pad(s: string, n: number): string {\n return s.padEnd(n);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction indentLines(text: string, indent: string): string {\n return text\n .split('\\n')\n .map((line) => `${indent}${line}`)\n .join('\\n');\n}\n\n/** `slug(input1, input2) → output1, output2`, shared by envs/show/run listings. */\nfunction formatActionSignature(a: { slug: string; input: Record<string, unknown>; output: Record<string, unknown> }): string {\n const inputs = Object.keys(a.input).join(', ');\n const outputs = Object.keys(a.output).join(', ');\n return `${a.slug}(${inputs})${outputs ? ` → ${outputs}` : ''}`;\n}\n\nfunction jsonSchemaPropTypes(schema: Record<string, unknown>): Record<string, string> {\n const properties = (schema as { properties?: Record<string, { type?: unknown }> }).properties ?? {};\n return Object.fromEntries(\n Object.entries(properties).map(([key, prop]) => [key, typeof prop.type === 'string' ? prop.type : 'string'])\n );\n}\n\nfunction formatOperationSignature(op: { name: string; inputSchema: Record<string, unknown>; outputSchema: Record<string, unknown> }): string {\n const inputs = Object.keys(jsonSchemaPropTypes(op.inputSchema)).join(', ');\n const outputs = Object.keys(jsonSchemaPropTypes(op.outputSchema)).join(', ');\n return `${op.name}(${inputs})${outputs ? ` → ${outputs}` : ''}`;\n}\n\n/** Exit with the API's reason, and a definition's issues, when it refused. */\nfunction exitOnRefusal(res: Refusal): void {\n if (res.ok) return;\n console.error(`Error: ${res.error}`);\n if (res.code === 'SANDBOX_V2_DEFINITION_INVALID') printIssues(res.issues, ' ');\n process.exit(1);\n}\n\nfunction printIssues(issues: DefinitionIssue[] | undefined, indent: string): void {\n for (const issue of issues ?? []) {\n console.log(`${indent}${issue.path || '(root)'}: ${issue.message}`);\n }\n}\n\n/** A version as people read it: a short commit, or a push id. */\nfunction shortVersion(version: string): string {\n return /^[0-9a-f]{40}$/.test(version) ? version.slice(0, 12) : version;\n}\n\nfunction printApplicationHuman(app: ApplicationSandbox): void {\n console.log(\n app.delivery === 'github'\n ? `Delivered from GitHub: ${app.repo}${app.definitionDir && app.definitionDir !== '.' ? `:${app.definitionDir}` : ''}`\n : 'Delivered as pushed images'\n );\n console.log(` version ${app.version ? shortVersion(app.version) : '(none yet: run `cofactor sandbox push`)'}`);\n if (app.pushes && app.pushes.length > 0) {\n console.log(' pushes:');\n for (const push of app.pushes) {\n const tags = push.tags.length > 0 ? ` [${push.tags.join(', ')}]` : '';\n console.log(` ${push.id} ${pad(push.status, 9)} ${push.createdAt}${tags}${push.error ? `\\n ${push.error}` : ''}`);\n }\n }\n if (app.sandboxEnvironments.length > 0) {\n console.log(' sandbox environments:');\n for (const env of app.sandboxEnvironments) console.log(` ${pad(env.environment, 16)} ${env.name}`);\n }\n if (app.heads && app.heads.length > 0) {\n console.log(' heads (what flow runs and unpinned claims use; a warm environment switches after its warm-up; update with `cofactor sandbox refresh`):');\n for (const head of app.heads) {\n const version = head.version ? shortVersion(head.version) : '(none)';\n const built = head.builtAt ? `, built ${head.builtAt}` : '';\n const behind = head.behindMain && head.mainHead ? ` main has moved: now ${shortVersion(head.mainHead)}` : '';\n console.log(` ${pad(head.environment, 16)} ${version} (${head.status}${built})${behind}`);\n if (head.error) console.log(` ${head.error}`);\n }\n }\n const def = app.definition;\n if (!def) return;\n\n console.log(' Environments:');\n for (const env of def.environments) {\n console.log(` ${env.name}${env.extends ? ` (extends ${env.extends})` : ''}`);\n console.log(indentLines(env.description, ' '));\n if (env.seeds.length > 0) {\n console.log(' seeds:');\n for (const step of env.seeds) console.log(` ${step.id}: ${step.action}`);\n }\n if (env.envKeys.length > 0) console.log(` env: ${env.envKeys.join(', ')}`);\n }\n\n if (def.actions.length > 0) {\n console.log(' Actions:');\n for (const a of def.actions) {\n console.log(` ${formatActionSignature(a)}`);\n console.log(` ${a.description}`);\n }\n }\n\n if (def.operations.length > 0) {\n console.log(' Operations:');\n for (const op of def.operations) {\n console.log(` ${formatOperationSignature(op)}`);\n console.log(` ${op.description}`);\n }\n }\n\n console.log(` Personas: ${def.personas.join(', ') || '(none)'}`);\n console.log(` Ports: ${def.ports.map((p) => `${p.name} (${p.access})`).join(', ') || '(none)'}`);\n}\n\nfunction printSandbox(data: SandboxData): void {\n console.log(`Sandbox ${data.id}: ${data.status}${data.expired ? ' (expired)' : ''}`);\n console.log(` environment ${data.environment}`);\n console.log(` version ${shortVersion(data.version)}`);\n if (data.error) console.log(` error ${data.error}`);\n if (data.readyMs !== null) {\n const seconds = (ms: number) => `${(ms / 1000).toFixed(1)}s`;\n const phases = data.phases\n ? ` (snapshot ${seconds(data.phases.snapshotMs)}, restore ${seconds(data.phases.restoreMs)}, prepare ${seconds(data.phases.prepareMs)})`\n : '';\n console.log(` ready in ${seconds(data.readyMs)}${phases}`);\n }\n if (data.snapshot?.buildPhases) {\n const { buildMs, prepareMs, seeds } = data.snapshot.buildPhases;\n const seedsMs = seeds.reduce((total, step) => total + step.ms, 0);\n console.log(\n ` snapshot built ${data.snapshot.builtAt} (build ${(buildMs / 1000).toFixed(1)}s, prepare ${(prepareMs / 1000).toFixed(1)}s, ${seeds.length} seeds ${(seedsMs / 1000).toFixed(1)}s)`\n );\n for (const step of seeds) console.log(` ${step.id} ${step.action} ${(step.ms / 1000).toFixed(1)}s`);\n const ran = data.snapshot.buildPhases.build?.steps.filter((step) => step.ran) ?? [];\n if (ran.length > 0) {\n console.log(` build steps: ${ran.map((step) => `${step.name} ${(step.ms / 1000).toFixed(1)}s`).join(', ')}`);\n }\n }\n if (data.leaseExpiresAt) console.log(` expires ${data.leaseExpiresAt}`);\n if (data.synced) {\n writeRawOutput(` synced ${data.synced.buildOutput ? 'build output' : 'tree'} ${data.synced.tree} at ${data.synced.at}`);\n }\n\n if (Object.keys(data.portUrls).length > 0) {\n console.log('');\n console.log(' URLs:');\n for (const [name, url] of Object.entries(data.portUrls)) writeRawOutput(` ${pad(name, 10)} ${url}`);\n }\n\n if (data.personas.length > 0) {\n console.log('');\n console.log(' Logins:');\n for (const p of data.personas) writeRawOutput(` ${pad(p.name, 14)} ${p.email} ${p.password}`);\n // Absent from an older API.\n if (data.nativeLogin !== undefined) {\n console.log(\n data.nativeLogin\n ? ' (native Login nodes sign these in via authentication.run)'\n : ' (no authentication.run: native Login nodes fail with script_not_declared)'\n );\n }\n }\n\n if (data.signInUrl) {\n console.log('');\n writeRawOutput(` Open sign-in: ${data.signInUrl}`);\n }\n\n const seedIds = Object.keys(data.seedOutputs);\n if (seedIds.length > 0) {\n console.log('');\n console.log(' Seed outputs:');\n for (const id of seedIds) {\n for (const [key, value] of Object.entries(data.seedOutputs[id]!)) {\n writeRawOutput(` ${id}.${key}: ${JSON.stringify(value)}`);\n }\n }\n }\n\n if (data.actions.length > 0) {\n console.log('');\n console.log(' Actions:');\n for (const a of data.actions) console.log(` ${formatActionSignature(a)}`);\n }\n\n if (data.operations.length > 0) {\n console.log('');\n console.log(' Operations:');\n for (const op of data.operations) console.log(` ${formatOperationSignature(op)}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// validate — offline, no auth\n// ---------------------------------------------------------------------------\n\n/**\n * `cofactor sandbox validate [file] [--upload]`: offline schema + cross-check,\n * no auth required. `--upload` checks a definition for pushed images (no\n * `setup` or build steps); otherwise one built from a GitHub checkout.\n */\nexport function handleSandboxValidate(argv: string[]): void {\n const file = argv.find((a) => !a.startsWith('-')) ?? './cofactor.sandbox.yaml';\n const json = hasFlag(argv, '--json');\n const delivery = hasFlag(argv, '--upload') ? 'upload' : 'github';\n\n let yamlText: string;\n try {\n yamlText = readFileSync(file, 'utf-8');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (json) {\n writeRawOutput(JSON.stringify({ ok: false, issues: [{ path: '', message }] }, null, 2));\n } else {\n console.error(`Error reading \"${file}\": ${message}`);\n }\n process.exit(1);\n }\n\n const { definition, issues } = validateDefinition(yamlText, delivery);\n\n if (json) {\n writeRawOutput(JSON.stringify({ ok: issues.length === 0, issues }, null, 2));\n process.exit(issues.length === 0 ? 0 : 1);\n }\n\n if (issues.length > 0) {\n for (const issue of issues) console.error(`${issue.path || '(root)'}: ${issue.message}`);\n process.exit(1);\n }\n\n const environmentCount = Object.keys(definition!.environments).length;\n const actionCount = Object.keys(definition!.actions).length;\n const operationCount = Object.keys(definition!.emulation).reduce(\n (sum, pluginId) => sum + pluginOperations(pluginId).length,\n 0\n );\n console.log(`✓ ${file} is valid`);\n console.log(` ${environmentCount} environment(s), ${actionCount} action(s), ${operationCount} operation(s)`);\n}\n\n// ---------------------------------------------------------------------------\n// envs\n// ---------------------------------------------------------------------------\n\n/** The application's sandbox setting, or exit with the API's reason. */\nasync function fetchApplicationSandbox(apiUrl: string, token: string, applicationId: string): Promise<ApplicationSandbox> {\n const res = await apiRequest<ApplicationSandboxResponse>(apiUrl, token, 'GET', `/org/applications/${applicationId}/sandbox`);\n exitOnRefusal(res);\n return res.data;\n}\n\n/**\n * The options each Sandboxes v2 command takes (beyond the global ones the\n * dispatcher strips): a value option, a boolean flag, how many positionals.\n */\nconst V2_ARGS: Record<string, { values: string[]; flags: string[]; positionals: number }> = {\n envs: { values: ['--application', '--property'], flags: ['--json'], positionals: 0 },\n refresh: { values: ['--application', '--property', '--environment'], flags: ['--wait', '--json'], positionals: 0 },\n connect: { values: ['--application', '--property', '--repo', '--dir'], flags: ['--json'], positionals: 0 },\n push: { values: ['--application', '--property', '--definition', '--tag'], flags: ['--wait', '--json'], positionals: 1 },\n claim: { values: ['--application', '--property', '--environment', '--at', '--timeout'], flags: ['--wait', '--json'], positionals: 0 },\n show: { values: [], flags: ['--json'], positionals: 1 },\n claims: { values: ['--application', '--property'], flags: ['--json'], positionals: 0 },\n run: { values: ['--input', '--json-input'], flags: ['--json'], positionals: 2 },\n exec: { values: ['--timeout'], flags: ['--json'], positionals: 1 },\n sync: { values: ['--to'], flags: ['--build', '--json'], positionals: 2 },\n 'verify-env': { values: ['--application', '--property', '--environment'], flags: ['--json'], positionals: 0 },\n destroy: { values: [], flags: [], positionals: 1 },\n secret: { values: ['--application', '--property', '--environment'], flags: ['--json'], positionals: 2 },\n};\n\n/**\n * Refuse an argument a Sandboxes v2 command doesn't take, rather than ignore\n * it: a `\"--at accept-a\"` quoted into one word would otherwise claim the\n * newest version without a word.\n */\nexport function rejectUnknownSandboxV2Args(command: string, argv: string[]): void {\n const spec = V2_ARGS[command];\n if (!spec) return;\n let positionals = 0;\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]!;\n if (spec.values.includes(arg)) {\n i++;\n continue;\n }\n // `--tag=nightly`: only the repeatable options (`getArgValues`) read the `=` form;\n // `getArgValue` would ignore `--at=x`, so that one stays refused. `--debug` traces any command.\n if (['--input', '--tag'].some((value) => spec.values.includes(value) && arg.startsWith(`${value}=`))) continue;\n if (spec.flags.includes(arg) || arg === '--debug') continue;\n if (!arg.startsWith('-') && ++positionals <= spec.positionals) continue;\n if (command === 'secret' && !arg.startsWith('-')) {\n // A rejected positional may be a pasted key: never echo it.\n console.error(\n 'Error: `cofactor sandbox secret` takes no value argument: pipe the value on stdin. If you typed a real key on the command line, rotate it.'\n );\n process.exit(1);\n }\n console.error(`Error: \\`cofactor sandbox ${command}\\` does not take ${JSON.stringify(arg)}. See \\`cofactor sandbox --help\\`.`);\n process.exit(1);\n }\n}\n\n/** The positionals of a Sandboxes v2 command: `argv` without its options and the value options' arguments. */\nexport function v2Positionals(command: string, argv: string[]): string[] {\n const values = V2_ARGS[command]?.values ?? [];\n const result: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]!;\n if (values.includes(arg)) i++;\n else if (!arg.startsWith('-')) result.push(arg);\n }\n return result;\n}\n\n/** `cofactor sandbox envs --application A [--json]`: what the application's definition offers. */\nexport async function handleSandboxEnvs(argv: string[], apiUrl: string, token: string): Promise<void> {\n const applicationId = await resolveApplicationId(argv, apiUrl, token);\n const app = await fetchApplicationSandbox(apiUrl, token, applicationId);\n if (hasFlag(argv, '--json')) {\n writeRawOutput(JSON.stringify(app, null, 2));\n return;\n }\n printApplicationHuman(app);\n}\n\n/**\n * `cofactor sandbox connect --application A --repo owner/name [--dir D] [--json]`:\n * build the application's sandboxes from a GitHub repository directory,\n * creating the application when `A` is a new name.\n */\nexport async function handleSandboxConnect(argv: string[], apiUrl: string, token: string): Promise<void> {\n const repo = getArgValue(argv, '--repo');\n if (!repo) {\n console.error('Usage: cofactor sandbox connect --application <name|id> --repo <owner/name> [--dir <path>] [--json]');\n process.exit(1);\n }\n const body = { repo, definitionDir: getArgValue(argv, '--dir') ?? '.' };\n // A new application is created only once the repository could connect, so a refusal leaves none behind.\n const checkCanConnect = async () => {\n exitOnRefusal(await apiRequest<Refusal>(apiUrl, token, 'POST', '/org/sandboxes-v2/connect-check', body));\n };\n const applicationId = await resolveOrCreateSandboxApplication(argv, apiUrl, token, checkCanConnect);\n const res = await apiRequest<ApplicationSandboxResponse>(apiUrl, token, 'PUT', `/org/applications/${applicationId}/sandbox`, body);\n exitOnRefusal(res);\n if (hasFlag(argv, '--json')) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n printApplicationHuman(res.data);\n}\n\n// ---------------------------------------------------------------------------\n// claim / show — shared polling\n// ---------------------------------------------------------------------------\n\nconst CLAIM_POLL_INTERVAL_MS = 3_000;\n/** The API's own default for a claim's time limit (`timeoutSeconds`). */\nconst CLAIM_TIMEOUT_SECONDS = 2 * 3600;\n/** Past the claim's time limit, how long to keep polling for the API to report it failed. */\nconst CLAIM_POLL_GRACE_MS = 2 * 60 * 1000;\n\n/**\n * Wait for a claim to settle. The API fails a claim at its time limit\n * (`timeoutSeconds`), so polling outlasts that by `CLAIM_POLL_GRACE_MS`. A\n * timeout or an API error comes back as `{ error }` rather than exiting, so a\n * caller that owns the sandbox (`verify-env`) can still destroy it.\n */\nasync function pollSandboxUntilReady(\n apiUrl: string,\n token: string,\n id: string,\n timeoutSeconds: number\n): Promise<{ data: SandboxData } | { error: string }> {\n const deadline = Date.now() + timeoutSeconds * 1000 + CLAIM_POLL_GRACE_MS;\n let toldUpgrading = false;\n while (Date.now() < deadline) {\n const res = await apiRequest<SandboxResponse>(apiUrl, token, 'GET', `/org/sandboxes-v2/sandboxes/${id}`);\n if (!res.ok) return { error: res.error ?? 'unknown error' };\n if (res.data.status === 'ready' || res.data.status === 'failed') return { data: res.data };\n if (res.data.upgrading && !toldUpgrading) {\n toldUpgrading = true;\n console.error(' updating this push to the current sandbox platform (once; the claim continues after)...');\n }\n await sleep(CLAIM_POLL_INTERVAL_MS);\n }\n return { error: `timed out waiting for sandbox ${id} to become ready (${Math.round(timeoutSeconds / 60)} min)` };\n}\n\n/** `cofactor sandbox claim --application A [--environment E] [--at V] [--timeout D] [--wait] [--json]`. */\nexport async function handleSandboxClaim(argv: string[], apiUrl: string, token: string): Promise<void> {\n const applicationId = await resolveApplicationId(argv, apiUrl, token);\n const environment = getArgValue(argv, '--environment') ?? 'default';\n // Not `--version`: the CLI answers that flag anywhere on the line with its own version.\n const version = getArgValue(argv, '--at');\n const timeout = parseDurationSeconds(getArgValue(argv, '--timeout'), '--timeout');\n const timeoutSeconds = timeout ?? CLAIM_TIMEOUT_SECONDS;\n const wait = hasFlag(argv, '--wait');\n const json = hasFlag(argv, '--json');\n\n const body: Record<string, unknown> = { applicationId, environment };\n if (version) body.version = version;\n // Only when asked: an API from before `timeoutSeconds` refuses the field, and waited the same 2 h.\n if (timeout !== undefined) body.timeoutSeconds = timeout;\n // The API holds the request a few seconds for a warm claim and answers with the ready sandbox; a claim\n // still going comes back as just its id, and is polled below.\n if (wait) body.wait = true;\n\n const res = await apiRequest<{\n ok: boolean;\n error?: string;\n code?: string;\n issues?: DefinitionIssue[];\n data: { id: string } | SandboxData;\n }>(apiUrl, token, 'POST', '/org/sandboxes-v2/sandboxes', body);\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n // The definition of that version fails validation: say where, as `validate` does.\n if (res.code === 'SANDBOX_V2_DEFINITION_INVALID') printIssues(res.issues, ' ');\n process.exit(1);\n }\n const id = res.data.id;\n\n if (!wait) {\n if (json) {\n writeRawOutput(JSON.stringify({ id }, null, 2));\n } else {\n console.log(`Sandbox claiming: ${id}`);\n console.log(` Poll with: cofactor sandbox show ${id}`);\n }\n return;\n }\n\n const settled = 'status' in res.data && (res.data.status === 'ready' || res.data.status === 'failed') ? res.data : null;\n if (!json && !settled) console.log(`Claiming sandbox ${id}...`);\n const waited = settled ? { data: settled } : await pollSandboxUntilReady(apiUrl, token, id, timeoutSeconds);\n if ('error' in waited) {\n // The sandbox stays yours (its lease still runs): `show` or `destroy` it.\n console.error(`Error: ${waited.error}`);\n process.exit(1);\n }\n const { data } = waited;\n if (json) {\n writeRawOutput(JSON.stringify(data, null, 2));\n } else {\n printSandbox(data);\n }\n if (data.status === 'failed') process.exit(1);\n}\n\n/** `cofactor sandbox show <id> [--json]`. */\nexport async function handleSandboxShow(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = argv.filter((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Usage: cofactor sandbox show <id> [--json]');\n process.exit(1);\n }\n const json = hasFlag(argv, '--json');\n\n const res = await apiRequest<SandboxResponse>(apiUrl, token, 'GET', `/org/sandboxes-v2/sandboxes/${id}`);\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n printSandbox(res.data);\n}\n\n/** `cofactor sandbox claims [--application A] [--json]`: the sandboxes you claimed that are still claiming or ready. */\nexport async function handleSandboxClaims(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const applicationArg = getArgValue(argv, '--application') ?? getArgValue(argv, '--property');\n const applicationId = applicationArg ? await resolveApplicationId(argv, apiUrl, token) : undefined;\n\n const claims: ClaimListItem[] = [];\n let cursor: string | null = null;\n do {\n const query = new URLSearchParams({ mine: 'true', status: 'claiming,ready', limit: '100' });\n if (applicationId) query.set('applicationId', applicationId);\n if (cursor) query.set('cursor', cursor);\n const res: { ok: boolean; error?: string; data: ClaimListItem[]; nextCursor?: string | null } = await apiRequest(\n apiUrl,\n token,\n 'GET',\n `/org/sandboxes-v2/sandboxes?${query}`\n );\n if (!res.ok) {\n console.error(`Error: ${res.error ?? 'could not list sandboxes'}`);\n process.exit(1);\n }\n claims.push(...res.data);\n cursor = res.nextCursor ?? null;\n } while (cursor);\n if (json) {\n writeRawOutput(JSON.stringify(claims, null, 2));\n return;\n }\n if (claims.length === 0) {\n console.log('No live claims.');\n return;\n }\n const names = new Map((await fetchProperties(apiUrl, token)).map((p) => [p.id, p.name]));\n console.log(`${pad('ID', 38)} ${pad('Application', 24)} ${pad('Environment', 14)} ${pad('Status', 10)} ${pad('Claimed', 26)} Expires`);\n for (const c of claims) {\n console.log(\n `${pad(c.id, 38)} ${pad(names.get(c.applicationId) ?? c.applicationId, 24)} ${pad(c.environment, 14)} ${pad(c.status, 10)} ${pad(c.createdAt, 26)} ${c.leaseExpiresAt ?? '-'}`\n );\n }\n console.log('\\nTear one down with: cofactor sandbox destroy <id>');\n}\n\n// ---------------------------------------------------------------------------\n// run\n// ---------------------------------------------------------------------------\n\nfunction coerceInputValue(raw: string, type: string): string | number | boolean {\n switch (type) {\n case 'integer': {\n if (!/^-?\\d+$/.test(raw)) throw new Error(`must be an integer, got \"${raw}\"`);\n return Number(raw);\n }\n case 'number': {\n const value = Number(raw);\n if (Number.isNaN(value)) throw new Error(`must be a number, got \"${raw}\"`);\n return value;\n }\n case 'boolean': {\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n throw new Error(`must be \"true\" or \"false\", got \"${raw}\"`);\n }\n default:\n // string, persona\n return raw;\n }\n}\n\nfunction buildRunInputFromFlags(argv: string[], propTypes: Record<string, string>): Record<string, unknown> {\n const pairs = getArgValues(argv, '--input');\n const input: Record<string, unknown> = {};\n for (const pair of pairs) {\n const eq = pair.indexOf('=');\n if (eq <= 0) {\n console.error(`Error: invalid --input \"${pair}\". Use key=value.`);\n process.exit(1);\n }\n const key = pair.slice(0, eq);\n const raw = pair.slice(eq + 1);\n const type = propTypes[key];\n if (!type) {\n console.error(`Error: unknown input \"${key}\". Known: ${Object.keys(propTypes).join(', ') || '(none)'}`);\n process.exit(1);\n }\n try {\n input[key] = coerceInputValue(raw, type);\n } catch (error) {\n console.error(`Error: --input ${key}: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }\n return input;\n}\n\n/** Poll a run every 2 s until it leaves `running`; exits 1 on a poll error or when `timeoutMs` passes. */\nasync function pollRunUntilDone(\n apiUrl: string,\n token: string,\n runId: string,\n timeoutMs: number,\n timeoutNote = ''\n): Promise<RunData> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n const pollRes = await apiRequest<RunResponse>(apiUrl, token, 'GET', `/org/sandboxes-v2/runs/${runId}`);\n if (!pollRes.ok) {\n console.error(`Error: ${pollRes.error}`);\n process.exit(1);\n }\n if (pollRes.data.status !== 'running') return pollRes.data;\n await sleep(2_000);\n }\n console.error(`Timed out waiting for run ${runId}${timeoutNote}.`);\n process.exit(1);\n}\n\n/** `cofactor sandbox run <id> <action|plugin.op> [--input k=v ...] [--json-input '{...}'] [--json]`. */\nexport async function handleSandboxRun(argv: string[], apiUrl: string, token: string): Promise<void> {\n const positional = argv.filter((a) => !a.startsWith('-'));\n const [id, actionRef] = positional;\n if (!id || !actionRef) {\n console.error('Usage: cofactor sandbox run <id> <action|plugin.op> [--input k=v ...] [--json-input \\'{...}\\'] [--json]');\n process.exit(1);\n }\n const json = hasFlag(argv, '--json');\n const jsonInput = getArgValue(argv, '--json-input');\n\n const showRes = await apiRequest<SandboxResponse>(apiUrl, token, 'GET', `/org/sandboxes-v2/sandboxes/${id}`);\n if (!showRes.ok) {\n console.error(`Error: ${showRes.error}`);\n process.exit(1);\n }\n const sandbox = showRes.data;\n const repoAction = sandbox.actions.find((a) => a.slug === actionRef);\n const operation = sandbox.operations.find((op) => op.name === actionRef);\n if (!repoAction && !operation) {\n console.error(`Error: unknown action or operation \"${actionRef}\".`);\n console.error(` Actions: ${sandbox.actions.map((a) => a.slug).join(', ') || '(none)'}`);\n console.error(` Operations: ${sandbox.operations.map((op) => op.name).join(', ') || '(none)'}`);\n process.exit(1);\n }\n\n let input: Record<string, unknown>;\n if (jsonInput !== undefined) {\n try {\n input = JSON.parse(jsonInput) as Record<string, unknown>;\n } catch (error) {\n console.error(`Error: invalid --json-input: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n } else if (repoAction) {\n const propTypes = Object.fromEntries(Object.entries(repoAction.input).map(([key, prop]) => [key, prop.type]));\n input = buildRunInputFromFlags(argv, propTypes);\n } else {\n input = buildRunInputFromFlags(argv, jsonSchemaPropTypes(operation!.inputSchema));\n }\n\n const enqueueRes = await apiRequest<RunEnqueueResponse>(\n apiUrl,\n token,\n 'POST',\n `/org/sandboxes-v2/sandboxes/${id}/runs`,\n { action: actionRef, input }\n );\n if (!enqueueRes.ok) {\n if (enqueueRes.code === 'SANDBOX_V2_ACTION_INVALID_INPUT') {\n console.error(`Error: invalid input for \"${actionRef}\":`);\n for (const issue of enqueueRes.issues ?? []) {\n if (typeof issue === 'string') console.error(` ${issue}`);\n else console.error(` ${(issue.path ?? []).join('.')}: ${issue.message ?? ''}`);\n }\n console.error('');\n console.error('Input schema:');\n writeRawOutput(JSON.stringify(repoAction ? repoAction.input : operation!.inputSchema, null, 2));\n } else {\n console.error(`Error: ${enqueueRes.error}`);\n }\n process.exit(1);\n }\n const runId = enqueueRes.data!.id;\n\n const run = await pollRunUntilDone(apiUrl, token, runId, ((repoAction?.timeout ?? 60) + 60) * 1000);\n\n if (json) {\n writeRawOutput(JSON.stringify(run, null, 2));\n if (run.status === 'failed') process.exit(1);\n return;\n }\n\n if (run.status === 'failed') {\n console.error(`Run failed: ${run.error ?? 'unknown error'}`);\n if (run.stderrTail) {\n console.error('');\n console.error('stderr:');\n console.error(run.stderrTail);\n }\n process.exit(1);\n }\n\n writeRawOutput(JSON.stringify(run.output ?? {}, null, 2));\n}\n\n// ---------------------------------------------------------------------------\n// exec\n// ---------------------------------------------------------------------------\n\nexport type ExecArgs = { id: string; timeoutSeconds?: number; json: boolean; command: string };\n\nconst EXEC_USAGE = 'Usage: cofactor sandbox exec <id> [--timeout <seconds>] [--json] -- <command...>';\n\n/** Parse `exec`'s words: the id and flags (`options`), and the command words after `--` (joined by spaces, like ssh). */\nexport function parseExecArgs(\n options: string[],\n commandWords: string[]\n): { ok: true; args: ExecArgs } | { ok: false; error: string } {\n const command = commandWords.join(' ');\n if (command.trim() === '') return { ok: false, error: `a command is required after \\`--\\`. ${EXEC_USAGE}` };\n const id = v2Positionals('exec', options)[0];\n if (!id) return { ok: false, error: `sandbox id required. ${EXEC_USAGE}` };\n const timeout = getArgValue(options, '--timeout');\n let timeoutSeconds: number | undefined;\n if (timeout !== undefined) {\n timeoutSeconds = /^\\d+$/.test(timeout) ? Number(timeout) : NaN;\n if (!Number.isInteger(timeoutSeconds) || timeoutSeconds < 1 || timeoutSeconds > EXEC_MAX_TIMEOUT_SECONDS) {\n return { ok: false, error: `--timeout must be a whole number of seconds from 1 to ${EXEC_MAX_TIMEOUT_SECONDS}.` };\n }\n }\n return { ok: true, args: { id, timeoutSeconds, json: hasFlag(options, '--json'), command } };\n}\n\n/** The CLI exit code for a finished exec run: the command's own, or 1 when the failure was not the command's. */\nexport function execExitCode(run: Pick<RunData, 'status' | 'exitCode'>): number {\n if (run.status === 'succeeded') return 0;\n return run.exitCode ?? 1;\n}\n\n/** `cofactor sandbox exec <id> [--timeout S] [--json] -- <command...>`: one shell command in a claimed sandbox. */\nexport async function handleSandboxExec(\n options: string[],\n commandWords: string[],\n apiUrl: string,\n token: string\n): Promise<void> {\n const parsed = parseExecArgs(options, commandWords);\n if (!parsed.ok) {\n console.error(`Error: ${parsed.error}`);\n process.exit(1);\n }\n const { id, timeoutSeconds, json, command } = parsed.args;\n\n const enqueueRes = await apiRequest<RunEnqueueResponse>(\n apiUrl,\n token,\n 'POST',\n `/org/sandboxes-v2/sandboxes/${id}/exec`,\n timeoutSeconds === undefined ? { command } : { command, timeoutSeconds }\n );\n if (!enqueueRes.ok) {\n console.error(`Error: ${enqueueRes.error}`);\n process.exit(1);\n }\n const runId = enqueueRes.data!.id;\n\n const run = await pollRunUntilDone(\n apiUrl,\n token,\n runId,\n ((timeoutSeconds ?? EXEC_DEFAULT_TIMEOUT_SECONDS) + 60) * 1000,\n '; the command may still be running in the sandbox'\n );\n\n const code = execExitCode(run);\n if (json) {\n writeRawOutput(JSON.stringify(run, null, 2));\n process.exit(code);\n }\n if (run.status === 'failed' && run.exitCode === null) {\n // Run text goes out raw: console output is brand-rewritten.\n process.stderr.write(`Error: ${run.error ?? 'unknown error'}\\n`);\n if (run.stdoutTail) process.stderr.write(run.stdoutTail);\n if (run.stdoutTail && !run.stdoutTail.endsWith('\\n') && run.stderrTail) process.stderr.write('\\n');\n if (run.stderrTail) process.stderr.write(run.stderrTail);\n process.exit(1);\n }\n if (run.stdoutTail) process.stdout.write(run.stdoutTail);\n if (run.stderrTail) process.stderr.write(run.stderrTail);\n if (code === 124 && run.error) process.stderr.write(`\\n${run.error}\\n`);\n process.exit(code);\n}\n\n// ---------------------------------------------------------------------------\n// destroy\n// ---------------------------------------------------------------------------\n\n/** `cofactor sandbox destroy <id>`. */\nexport async function handleSandboxDestroy(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = argv.filter((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Usage: cofactor sandbox destroy <id>');\n process.exit(1);\n }\n const res = await apiRequest<{ ok: boolean; error?: string; data: { id: string } }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/sandboxes-v2/sandboxes/${id}`\n );\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n console.log(`Sandbox ${id} destroying.`);\n}\n\n// ---------------------------------------------------------------------------\n// verify-env\n// ---------------------------------------------------------------------------\n\n/** `cofactor sandbox verify-env --application A [--environment E] [--json]`. */\nexport async function handleSandboxVerifyEnv(argv: string[], apiUrl: string, token: string): Promise<void> {\n const applicationId = await resolveApplicationId(argv, apiUrl, token);\n const onlyEnvironment = getArgValue(argv, '--environment');\n const json = hasFlag(argv, '--json');\n // With --json, stdout carries only the result array; progress goes to stderr.\n const log = (line: string) => (json ? console.error(line) : console.log(line));\n\n const app = await fetchApplicationSandbox(apiUrl, token, applicationId);\n if (!app.version || !app.definition) {\n console.error('Error: this application has no version to verify yet: run `cofactor sandbox push` first.');\n process.exit(1);\n }\n const version = app.version;\n const allEnvironments = app.definition.environments.map((e) => e.name);\n if (onlyEnvironment && !allEnvironments.includes(onlyEnvironment)) {\n console.error(`Error: environment \"${onlyEnvironment}\" not found. Known: ${allEnvironments.join(', ')}`);\n process.exit(1);\n }\n const environments = onlyEnvironment ? [onlyEnvironment] : allEnvironments;\n\n type PersonaCheck = { persona: string; ok: boolean; error?: string };\n type Result = { environment: string; ok: boolean; seconds: number; error?: string; personas?: PersonaCheck[] };\n const results: Result[] = [];\n\n // Sequential on purpose — the fleet's placer fails rather than queues.\n for (const environment of environments) {\n log(`\\n=== ${environment} ===`);\n const started = Date.now();\n const claimRes = await apiRequest<{ ok: boolean; error?: string; data: { id: string } }>(\n apiUrl,\n token,\n 'POST',\n '/org/sandboxes-v2/sandboxes',\n { applicationId, environment, version }\n );\n if (!claimRes.ok) {\n const seconds = (Date.now() - started) / 1000;\n console.error(` claim failed: ${claimRes.error}`);\n results.push({ environment, ok: false, seconds, error: claimRes.error });\n continue;\n }\n const id = claimRes.data.id;\n log(` claimed ${id}, waiting...`);\n const waited = await pollSandboxUntilReady(apiUrl, token, id, CLAIM_TIMEOUT_SECONDS);\n const seconds = (Date.now() - started) / 1000;\n if ('error' in waited || waited.data.status !== 'ready') {\n // A timeout or a failed claim still falls through to the destroy below.\n const error = 'error' in waited ? waited.error : (waited.data.error ?? 'failed');\n console.error(` failed: ${error}`);\n results.push({ environment, ok: false, seconds, error });\n } else {\n const { data } = waited;\n log(` ready in ${data.readyMs !== null ? (data.readyMs / 1000).toFixed(1) : '?'}s`);\n for (const [stepId, outputs] of Object.entries(data.seedOutputs)) {\n for (const [key, value] of Object.entries(outputs)) {\n log(` ${stepId}.${key}: ${JSON.stringify(value)}`);\n }\n }\n // Sign every persona in as a Login step would, so a broken login fails here, not in a test.\n const personas: PersonaCheck[] = [];\n if (data.nativeLogin) {\n for (const { name } of data.personas) {\n const checked = await apiRequest<{ ok: boolean; error?: string; data: PersonaCheck }>(\n apiUrl,\n token,\n 'POST',\n `/org/sandboxes-v2/sandboxes/${id}/auth-check`,\n { persona: name },\n // The API waits on the script (up to 60 s) and the sandbox connection.\n { timeoutMs: 90_000 }\n );\n const check = checked.ok ? checked.data : { persona: name, ok: false, error: checked.error ?? 'unknown error' };\n personas.push(check);\n if (check.ok) log(` persona ${name}: signed in`);\n else console.error(` persona ${name}: FAILED\\n${indentLines(check.error ?? '', ' ')}`);\n }\n }\n const failedPersonas = personas.filter((p) => !p.ok).map((p) => p.persona);\n results.push({\n environment,\n ok: failedPersonas.length === 0,\n seconds,\n ...(failedPersonas.length > 0 ? { error: `persona sign-in failed: ${failedPersonas.join(', ')}` } : {}),\n ...(data.nativeLogin ? { personas } : {}),\n });\n }\n log(` destroying ${id}...`);\n await apiRequest(apiUrl, token, 'DELETE', `/org/sandboxes-v2/sandboxes/${id}`);\n }\n\n log('');\n log('Summary:');\n log(` ${pad('Environment', 20)} ${pad('Result', 6)} Seconds`);\n for (const r of results) {\n const errSuffix = r.error ? ` (${r.error})` : '';\n log(` ${pad(r.environment, 20)} ${pad(r.ok ? 'OK' : 'FAIL', 6)} ${r.seconds.toFixed(1)}${errSuffix}`);\n }\n\n if (json) writeRawOutput(JSON.stringify(results, null, 2));\n if (results.some((r) => !r.ok)) process.exit(1);\n}\n","import { createHash, randomBytes } from 'node:crypto';\nimport { parse } from 'yaml';\nimport { z } from 'zod';\nimport { findOperation, getPlugin } from '@chatsdet/emulation';\nimport {\n OBJECT_STORAGE_PORT,\n OBJECT_STORAGE_PORT_NAME,\n OBJECT_STORAGE_PROVIDERS,\n OBJECT_STORAGE_SERVICE_NAMES,\n type ObjectStorageProvider,\n RESERVED_STORAGE_PORTS,\n objectStorageServices,\n} from './object-storage';\nimport { SYNC_PORT, SYNC_PORT_NAME, SYNC_SERVICE_NAME, syncKeySchema } from './sync-protocol';\nimport { emulationParamRefs, emulationReferenceIssues } from './emulation-refs';\n\nexport { emulationConfigFor, emulationSecretRefs, missingEmulationSecret } from './emulation-refs';\n\n// For the API (the helper-layer route presigns each provider's layer; the app URL skips the storage port) and push.\nexport { OBJECT_STORAGE_PORT_NAME, OBJECT_STORAGE_PROVIDERS, type ObjectStorageProvider };\n// For the API (hidden from the app URL like the other implicit ports).\nexport { SYNC_PORT_NAME };\n\n/** The implicit port that carries the emulator's public origin; reserved, never declared. */\nexport const EMULATION_PORT_NAME = 'emulation';\n\n/**\n * The sandbox definition: `cofactor.sandbox.yaml`, at a repository's root or\n * (for a monorepo) under a definition directory. Pure schema and derivations;\n * the guest-side paths live in runtime.ts (the pinned Node binary path also\n * lives here because the API cannot import runtime.ts), so the API can import\n * this module to validate a definition it read from GitHub.\n */\nexport const DEFINITION_FILE = 'cofactor.sandbox.yaml';\n\n/** Node.js runtime bundled by the trusted Playwright runtime installer. */\nexport const PLAYWRIGHT_NODE_VERSION = 'v22.16.0';\nexport const PLAYWRIGHT_NODE_BINARY = `/opt/cofactor/external-tests/node-${PLAYWRIGHT_NODE_VERSION}-linux-x64/bin/node`;\n\n/**\n * How an application's code reaches its sandboxes. `github`: Cofactor clones\n * the repository and the definition installs (`setup`) and builds\n * (`lifecycle.build`) it. `upload`: the customer pushes a built image with\n * `cofactor sandbox push`, so the definition has neither.\n */\nexport type Delivery = 'github' | 'upload';\n\n/**\n * An uploaded image's Cofactor files, layered in by `cofactor sandbox push`:\n * the definition and the image's own config (`ImageConfig`). Their presence\n * is what makes a sandbox an uploaded one.\n *\n * A contract: a push keeps its own layer when the API upgrades it to a newer\n * helper (specs/pending/sandboxes-v2-transparent-upgrades.md), so these paths,\n * `/etc/cofactor` and the uid 1000 sandbox user (runtime.ts) don't move\n * without a contract version.\n */\nexport const IMAGE_DIR = '/cofactor';\nexport const IMAGE_DEFINITION_FILE = `${IMAGE_DIR}/${DEFINITION_FILE}`;\nexport const IMAGE_CONFIG_FILE = `${IMAGE_DIR}/image.json`;\n\n/**\n * Where `image.sh` publishes the helper layer of a platform version, in the\n * API's bucket, for `cofactor sandbox push` to add to an uploaded image.\n * Republishing the same version replaces it.\n */\nexport function helperLayerKey(platformVersion: number): string {\n return `sandbox-v2/helper/v${platformVersion}.tar`;\n}\n\n/**\n * Where `image.sh` publishes a provider's object storage server (one binary\n * under /usr/local/bin) for a platform version, next to the helper layer.\n * `cofactor sandbox push` adds it only when the definition declares that\n * provider, so no push carries a server it doesn't use.\n */\nexport function objectStorageLayerKey(provider: ObjectStorageProvider, platformVersion: number): string {\n return `sandbox-v2/object-storage/${provider}/v${platformVersion}.tar`;\n}\n\n/**\n * The PATH the helper (as root) finds programs on, and every child starts\n * from before the image's and the definition's env. A Blackcat rootfs\n * import does not apply the image's Docker ENV.\n */\nexport const BASE_PATH = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';\n\n/**\n * What root runs, and so what the sandbox account (uid 1000, given the\n * WORKDIR) must never own: a WORKDIR at or above any of these (the programs\n * root finds, the libraries and loader they link), or inside a directory\n * root reads its configuration from, would hand it the means to run code\n * as root.\n */\nconst ROOT_RUN_PATHS = [\n ...BASE_PATH.split(':'),\n '/lib',\n '/lib64',\n '/usr/lib',\n '/usr/lib64',\n '/usr/libexec',\n '/etc',\n // Devices and kernel interfaces, and root's own home.\n '/dev',\n '/proc',\n '/sys',\n '/root',\n IMAGE_DIR,\n];\nconst ROOT_CONFIG_DIRS = ['/etc', IMAGE_DIR];\n\n/** Whether the sandbox account may be given `dir` (an image's WORKDIR, as declared or as resolved). */\nexport function isSafeWorkdir(dir: string): boolean {\n // A canonical absolute path: no `.`/`..` segments, repeated or trailing slashes.\n const segments = dir.split('/').slice(1);\n if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) return false;\n if (ROOT_RUN_PATHS.some((path) => path === dir || path.startsWith(`${dir}/`))) return false;\n return !ROOT_CONFIG_DIRS.some((path) => dir.startsWith(`${path}/`));\n}\n\n/**\n * What an uploaded image's own config would have applied. Blackcat's import\n * keeps the filesystem but drops the image's ENV and WORKDIR, so\n * `cofactor sandbox push` records them at `/cofactor/image.json` and the\n * helper runs every service, prepare command and action with them.\n */\nexport const imageConfigSchema = z.strictObject({\n /** Where children run. The helper gives it to the sandbox account, so never `/` or a system directory. */\n workdir: z\n .string()\n .startsWith('/', 'the image needs an absolute WORKDIR')\n .refine(isSafeWorkdir, 'the image needs a WORKDIR of its own, such as /app (not /, nor a system directory)'),\n env: z.record(z.string(), z.string()),\n});\nexport type ImageConfig = z.infer<typeof imageConfigSchema>;\n\n/**\n * Bumped whenever the helper or its contract with the platform layer changes\n * incompatibly. Old layers keep rejecting the new schema until they are\n * rebuilt from a definition of this version, so it is part of both the\n * platform template's identity and the toolchain key.\n *\n * The deploy pipeline publishes a new version's platform image and helper\n * layers (`image.sh`) before each stage's `sst deploy`, so the older notes\n * below that say to republish them by hand describe what is now automatic.\n *\n * 3: `prepareInputSchema` gained a required `copy` field and the `port` param\n * variant gained `live` — an old helper's `strictObject`s reject both, so\n * every layer built from an older platform version (toolchain, base, ready)\n * must be rebuilt from this one before any `prepare` (full or copy) can\n * succeed. Bumping this forces that rebuild via `toolchainKey`/\n * `platformTemplateName`; the platform image itself must also be republished\n * (`packages/sandbox-helper/image.sh`) as part of rolling this out — see\n * specs/pending/sandboxes-v2-ready-snapshots.md.\n *\n * 4: the helper's contract grew `object_storage` (an old helper's\n * `strictObject` rejects the field, and it has neither the implicit storage\n * services nor the `object-storage-front` command). Same rollout as 3: layers\n * rebuild, the platform image (which now carries both providers' servers) is\n * republished, and every existing push must be pushed again — see\n * specs/pending/sandboxes-v2-object-storage.md.\n *\n * 5: Blackcat's Firecracker 1.17 (alpha.68+) moved the snapshot format (6.0.0\n * to 12.0.0) with no migration, so no template built before it restores. The\n * helper's contract is unchanged; the bump only retires every recorded template\n * row and names the rebuilt platform template anew (`clearStaleToolchain`).\n * Republish the platform image and helper layers with `image.sh` for each stage\n * as part of rolling this out — see docs/features/blackcat-execution-platform.md\n * (\"Rebuilding templates\").\n *\n * 6: the guest helper gained the private `auth` command. Native persona login\n * requires its script; rebuild and republish helper layers and\n * ready snapshots so old helpers cannot silently accept the new contract.\n *\n * 8: the helper installs the pinned Node runtime from the official archive.\n * Its tar entries are owned by uid 1001, so root extraction must not preserve\n * that ownership; publish a fresh immutable helper/platform image with the\n * archive extracted as root before enforcing the existing ownership checks.\n *\n * 9: the pinned Playwright install uses distinct empty npm user/global config\n * files. This avoids npm rejecting a shared config path while keeping config\n * outside the uploaded app and deleting it after installation.\n *\n * 10: install Git because pinned test-source preparation failed on a builder\n * with `spawn git ENOENT`.\n *\n * 11: a service whose command isn't found or can't run (exit 127/126) fails the\n * boot at once instead of crash-looping until the health deadline, and an\n * uploaded image's own PATH survives the login profile (`loginShell`). The\n * first bump after pushed images upgrade themselves on first claim\n * (specs/pending/sandboxes-v2-transparent-upgrades.md): its rollout runs that\n * spec's live check on dev before prod.\n *\n * 12: `authentication` is `run` or `emulated`; the emulator gained the\n * authorize endpoint and per-persona identities; every google-oauth\n * definition needs personas. An old helper's `strictObject` rejects\n * `authentication.emulated`, and an old platform image's emulator has no\n * authorize endpoint. Republish the helper layers and the platform image with\n * `image.sh` for each stage as part of rolling this out; the dev live check\n * runs before prod.\n *\n * 13 is unused: the data fast-forward stack below was planned as 13 and\n * landed after 14.\n *\n * 14: the platform emulator gained the `oidc` plugin, the sign-in gate and\n * public-origin dispatch, and creates its CA at start; the helper's\n * validation (`oidc` provider, `{ port: emulation }` params) and `auth`\n * branch changed. Republish the helper layers, the platform image and ready\n * snapshots (docs/features/blackcat-execution-platform.md, \"Rebuilding\n * templates\"); every existing push must be pushed again.\n *\n * The `exec` subcommand needed no bump; see the comment at `case 'exec'` in\n * cli.ts. Remove the API's SANDBOX_V2_EXEC_NEEDS_UPGRADE detection once every\n * live sandbox is on a platform version that has `exec` (15 or later).\n *\n * 15: the guest helper gained `databases` (a top-level block) and the seed\n * step key `operation`, and the `operation <name>` subcommand that runs the\n * built-in `database.fast-forward` — an old helper's strictObjects reject\n * both fields and it has no such command. Same rollout as 3-6: layers\n * rebuild, republish the platform image (`image.sh`) on dev and prod, and\n * re-push every pushed image — see specs/pending/sandboxes-v2-data-fast-forward.md.\n *\n * 16: the platform emulator's Jira plugin serves `api.atlassian.com` and\n * `auth.atlassian.com` (#4494), which the app calls through the OAuth gateway.\n * The v15 image predates that, so its TLS certificate covered only the tenant\n * host and every Jira call from a sandbox failed the hostname check. The\n * emulator is built into the platform image, so a published v15 never picks the\n * change up. Same rollout as 15: the deploy publishes the v16 image, ready\n * snapshots rebuild, and every pushed image is pushed again.\n *\n * 17: every definition gains the implicit public `sync` port and the\n * `cofactor-sync` service (`cofactor-sandbox sync-server`, sync-server.ts),\n * which syncs a claimer's working tree into the copy; `prepareInputSchema`\n * gained a required `sync: {key}`, and the helper gained the `restart`\n * subcommand. An old helper's strictObject rejects `sync`, and an old layer\n * has neither the port nor the service. Same rollout as 15 and 16: layers rebuild,\n * the deploy publishes the v17 platform image and helper layers (`image.sh`),\n * and every pushed image is pushed again or upgraded transparently on its\n * next claim. A definition already at 8 ports stops validating (the `sync`\n * port counts toward Blackcat's cap).\n *\n * 18: a copy's `prepare` keeps its snapshot's personas (`personas` must be\n * empty, and `lifecycle.prepare` still gets the snapshot's); `prepare`\n * prints the sandbox's personas. An old helper rejects the empty `personas`\n * and prints none. Same rollout as 17: layers and ready snapshots rebuild,\n * and the deploy publishes the v18 platform image and helper layers; every\n * pushed image is pushed again or upgraded transparently on its next claim.\n * A v17 sandbox re-prepared after the deploy fails (a v17 helper rejects the\n * empty `personas`); it is transient, as for the earlier bumps.\n *\n * 19: `auth` reports a failing `authentication.run`'s exit code and stderr\n * tail (`AUTH_SCRIPT_FAILURE_PREFIX`), which the API puts into the Login step\n * error and `verify-env`'s persona check. No contract change: a v18 helper\n * just prints no such line, and its failures read as before. Same rollout as\n * 18: the deploy publishes the v19 platform image and helper layers, ready\n * snapshots rebuild, and every pushed image is upgraded on its next claim.\n *\n * 20: add copy-values/copy-sync-key commands, apply public URLs to live-env.json\n * and prepare.json without restarting services, and read emulator origins per use.\n * Shipping requires publishing the v20 platform image and helper layers. The version\n * changes toolchain keys, so ready snapshots rebuild; pushed images receive the new helper.\n *\n * 21: runtime cold boots skip the build-only checkpoint handshake, keeping the\n * supervisor alive after services start. Publish the v21 platform image and\n * helper layers; ready snapshots rebuild and pushed images receive the new helper.\n *\n * 22: a pushed image's definition may declare `lifecycle.build` and\n * `services.<svc>.after_build` (#5400, `sync --build`). #5400 changed the helper\n * but left the version at 21, whose platform image was already published, so\n * pushed images kept baking the v21 helper and failed at import with\n * `lifecycle: Unrecognized key \"build\"`. Same rollout as 21: the deploy\n * publishes the v22 platform image and helper layers, ready snapshots rebuild,\n * and pushed images receive the new helper. A change to the\n * helper's sources needs a bump if the current version may already be\n * published; platform-version.test.ts fails until the new hash is recorded.\n */\nexport const PLATFORM_VERSION = 22;\n\n/**\n * The browser layer (`/opt/cofactor-browser`, built by\n * `packages/sandbox-helper/browser/build-layer.sh` from `layer.lock.json`):\n * Chromium (the build the worker runs, so captures match the worker's), Node,\n * playwright-core, ffmpeg, fonts and their libraries, for running a test\n * session's browser inside its own copy.\n *\n * It is not part of the platform image and has no bearing on\n * `PLATFORM_VERSION`: `image.sh` publishes it as a second image\n * (`browserImageTag`), the published platform image plus this one layer, and\n * only an org with the in-sandbox browser flag builds its layers on that image\n * (`platformTemplateName`, `toolchainKey`). Every other org's templates, keys\n * and copies are exactly what they were without it.\n *\n * Bump it whenever the layer changes (the lock, the build, what runs from it),\n * including every Playwright bump: Playwright's `connect()` needs the same\n * version on both sides (browser-layer.test.ts checks the pin, and that\n * the layer's inputs never change under a published version). A bump publishes\n * a new browser image on the next deploy and rebuilds only the flagged orgs'\n * toolchains.\n */\nexport const BROWSER_LAYER_VERSION = 2;\n\n/** The browser layer an application's layers build on: its version, or `null` for the platform image alone. */\nexport type BrowserLayer = number | null;\n\n/** Emulator providers `authentication.emulated` can sign in through. */\nexport const EMULATED_PROVIDER_IDS = ['google-oauth', 'oidc'] as const;\nexport type EmulatedProviderId = (typeof EMULATED_PROVIDER_IDS)[number];\n\n/** What the helper's `auth` command prints before a stable category on stderr; the API logs lines of this shape. */\nexport const AUTH_FAILURE_PREFIX = 'authentication failed: ';\n\n/** How long `authentication.run` may take before the helper kills it. */\nexport const AUTH_SCRIPT_TIMEOUT_MS = 60_000;\n/** How much of a failing `authentication.run`'s stderr (its end) the helper reports. */\nexport const AUTH_SCRIPT_STDERR_TAIL_CHARS = 4000;\n\n/**\n * Before `authentication failed: script_failed`, the helper prints one line\n * with this prefix and the failing `authentication.run`'s exit and stderr\n * tail (scrubbed of the copy's secrets in the guest), so the Login step and\n * `verify-env` can say why. Stdout is never included: it is the session\n * state channel. A v18 helper prints no such line.\n */\nexport const AUTH_SCRIPT_FAILURE_PREFIX = 'authentication script failed: ';\nconst authScriptFailureSchema = z.strictObject({\n exitCode: z.number().int(),\n timedOut: z.boolean(),\n stderr: z.string(),\n});\nexport type AuthScriptFailure = z.infer<typeof authScriptFailureSchema>;\n\nexport function formatAuthScriptFailure(failure: AuthScriptFailure): string {\n return `${AUTH_SCRIPT_FAILURE_PREFIX}${JSON.stringify(failure)}`;\n}\n\n/** The helper's script-failure line from its stderr; null when there is none (or it is malformed). */\nexport function parseAuthScriptFailure(helperStderr: string): AuthScriptFailure | null {\n const line = helperStderr.split('\\n').find((candidate) => candidate.startsWith(AUTH_SCRIPT_FAILURE_PREFIX));\n if (!line) return null;\n try {\n const parsed = authScriptFailureSchema.safeParse(JSON.parse(line.slice(AUTH_SCRIPT_FAILURE_PREFIX.length)));\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n}\n\n/** `cofactor-sandbox build`/`action` exit codes its callers act on. */\nexport const EXIT = {\n /** The commit's definition needs another toolchain: build it on a sandbox of that one. */\n TOOLCHAIN_MISMATCH: 3,\n /**\n * The commit declares personas or per-sandbox params (or a resolved\n * environment chain) this prepared sandbox was not given: prepare a new\n * sandbox for it instead.\n */\n PREPARE_MISMATCH: 4,\n /** The action script exited non-zero, or was killed at its timeout. */\n ACTION_FAILED: 5,\n /** The action is unknown, its input failed validation, or the sandbox has not been prepared. */\n INVALID_INPUT: 6,\n /** The action produced no parseable JSON result line, or its result failed the output schema. */\n INVALID_OUTPUT: 7,\n /** Authentication did not return valid, bounded storage state. */\n AUTH_FAILED: 8,\n} as const;\n\n// Every toolchain gets what `build` itself needs to clone and fetch.\nexport const SETUP_PRELUDE = `set -euo pipefail\nexport DEBIAN_FRONTEND=noninteractive\napt-get update -qq\napt-get install -y -qq --no-install-recommends git ca-certificates curl openssl >/dev/null\n`;\n\nconst NAME = /^[a-z][a-z0-9-]{0,31}$/;\nconst PARAM = /^[a-z][a-z0-9_]*$/;\nexport const ENV_NAME = /^[A-Z_][A-Z0-9_]*$/;\n/** An emulated sign-in's start URL: one port param, then a path. */\nconst SIGN_IN_URL = /^\\$\\{params\\.([a-z][a-z0-9_]*)\\}\\/[^\\s$]*$/;\nconst PARAM_REF = /\\$\\{params\\.([a-z][a-z0-9_]*)\\}/g;\n/** Action/operation input and output property names. */\nconst IO_NAME = /^[a-z][a-z0-9_]*$/;\n/** A seed step id, referenced as `${id.key}`. */\nconst STEP_ID = /^[a-z][a-z0-9_]*$/;\n/** A `${stepId.key}` reference, anywhere in a string. */\nconst STEP_REF = /\\$\\{([a-z][a-z0-9_]*)\\.([a-z][a-z0-9_]*)\\}/g;\n/** The whole string is exactly one reference — the value is the raw output, not a string interpolation. */\nconst EXACT_STEP_REF = /^\\$\\{([a-z][a-z0-9_]*)\\.([a-z][a-z0-9_]*)\\}$/;\n/** A bucket name both providers accept: 3–63 lowercase letters, digits, `-` and `.`, starting and ending alphanumeric. */\nconst BUCKET = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;\nconst GCS_RESERVED_BUCKETS = new Set(['storage', 'upload', 'download', 'batch']);\n\nconst health = z.union([\n z.strictObject({ command: z.string().min(1) }),\n z.strictObject({ http: z.number().int().min(1).max(65535), path: z.string().startsWith('/') }),\n]);\n\nconst service = z.strictObject({\n run: z.string().min(1),\n health,\n /** Not started until the build lifecycle has completed (it needs the build's output). */\n after_build: z.boolean().default(false),\n /**\n * Runs with per-sandbox values: never started in a layer (whose params are\n * the definition's defaults), started by the first `prepare`, restarted by\n * every later one.\n */\n reload_on_prepare: z.boolean().default(false),\n});\n\n/**\n * A per-sandbox value. A string is a fixed value. `{port}` is the sandbox's\n * public origin for that port; `{secret: true}` is one random value made when\n * the ready snapshot is built and shared by every copy of it (e.g. a\n * session-signing key); it is not unique per claim. Layers, which no one is\n * handed, see a local origin and a placeholder instead.\n *\n * A `port` param may set `live: true`: its value changes every time a\n * sandbox is restored as a fresh copy (each copy gets its own public URLs),\n * but nothing needs to restart for the sandbox's app to pick up the new\n * value — the app is expected to re-read it at request time instead (see\n * `resolveLiveEnv`). `prepare` writes every live param's resolved env to\n * `LIVE_ENV_FILE` (runtime.ts) on every call, and skips restarting\n * `reload_on_prepare` services when nothing else changed (`restartRequired`).\n * Not offered on `secret` params — see the `auth_secret` row of the per-copy\n * work table in specs/pending/sandboxes-v2-ready-snapshots.md for why.\n */\nconst param = z.union([\n z.string(),\n z.strictObject({ port: z.string().regex(NAME), live: z.boolean().optional() }),\n z.strictObject({ secret: z.literal(true) }),\n]);\n\nconst buildStep = z.strictObject({\n name: z.string().regex(NAME),\n run: z.string().min(1),\n /**\n * Git pathspecs over tracked files (`:(glob)` magic is applied), relative to\n * the definition's directory. The step reruns when the blob ids they match\n * change, or when an earlier step ran.\n */\n inputs: z.array(z.string().min(1)).min(1),\n});\n\nconst literalValue = z.union([z.string(), z.number(), z.boolean()]);\n\n/** A `persona` input takes one of the definition's declared persona names, as a string. */\nconst inputProp = z.strictObject({\n type: z.enum(['string', 'number', 'integer', 'boolean', 'persona']),\n description: z.string().optional(),\n required: z.boolean().optional(),\n default: literalValue.optional(),\n enum: z.array(z.union([z.string(), z.number()])).optional(),\n /** Never echoed back by anything that logs or returns action input. */\n sensitive: z.boolean().optional(),\n});\n\nconst outputProp = z.strictObject({\n type: z.enum(['string', 'number', 'integer', 'boolean']),\n description: z.string().optional(),\n});\n\n/** A repository action: a typed script, the one way data gets into a sandbox. */\nconst action = z.strictObject({\n description: z.string().min(1),\n /** Script path, relative to the definition's directory; run via `bash`. */\n run: z.string().min(1),\n input: z.record(z.string().regex(IO_NAME), inputProp).default({}),\n output: z.record(z.string().regex(IO_NAME), outputProp).default({}),\n timeout: z.number().int().min(1).max(1800).default(60),\n});\n\n/** Database engines `databases:` can declare. One member today; the discriminator MySQL extends. */\nconst DATABASE_ENGINES = ['postgres'] as const;\n\n/** The whole `url` value: one `${env.NAME}` reference, resolved by the operation in the guest. */\nexport const ENV_REF = /^\\$\\{env\\.([A-Z_][A-Z0-9_]*)\\}$/;\n\nconst database = z.strictObject({\n engine: z.enum(DATABASE_ENGINES),\n /** `${env.NAME}`: the connection string is the value of NAME in the env an action would see. */\n url: z.string().regex(ENV_REF, 'must be exactly ${env.NAME}, naming an env var or repository secret'),\n /** When the dump was captured, in UTC (`2026-09-30T00:00:00Z`). The first fast-forward shifts from here. */\n as_of: z.iso.datetime(),\n});\n\n/** The built-in operation's name, as a seed's `operation` and as a `sandbox run` ref. */\nexport const FAST_FORWARD = 'database.fast-forward' as const;\n\nconst seedStep = z\n .strictObject({\n id: z.string().regex(STEP_ID),\n /** A declared action's slug, or `<plugin>.<op>` for an emulator operation. */\n action: z.string().min(1).optional(),\n /** A platform built-in operation. */\n operation: z.literal(FAST_FORWARD).optional(),\n input: z.record(z.string(), literalValue).default({}),\n })\n .refine((step) => (step.action === undefined) !== (step.operation === undefined), {\n message: 'a seed step has exactly one of \"action\" or \"operation\"',\n });\n\nconst environment = z.strictObject({\n description: z.string().min(1),\n extends: z.string().regex(NAME).optional(),\n seeds: z.array(seedStep).default([]),\n /** Merged parent-first, this environment's values last. */\n env: z.record(z.string().regex(ENV_NAME), z.string()).default({}),\n});\n\n/**\n * Run by `prepare` after the sandbox's services have restarted with its\n * values. Each param is also in their env as COFACTOR_PARAM_<NAME>.\n */\nconst prepareCommands = z.array(z.string().min(1));\n\n/** Every field both deliveries share; see `definitionSchema` and `githubDefinitionSchema`. */\nconst sharedFields = {\n version: z.literal(1),\n /** The machine every sandbox of this application gets; a promoted layer keeps it. */\n resources: z.strictObject({\n vcpus: z.number().int().min(1).max(32),\n memory_mib: z.number().int().min(1024).max(65536),\n }),\n ports: z.record(\n z.string().regex(NAME),\n z.strictObject({ port: z.number().int().min(1).max(65535), access: z.enum(['public', 'private']) })\n ),\n /**\n * Per-sandbox values, set by `prepare`. Build steps and layers see the\n * layer value (see `param`); `reload_on_prepare` services and prepare\n * commands see the sandbox's own.\n */\n params: z.record(z.string().regex(PARAM), param),\n /** `${params.NAME}` is replaced by the parameter's value. */\n env: z.record(z.string().regex(ENV_NAME), z.string()),\n services: z.record(z.string().regex(NAME), service),\n /**\n * The users a sandbox is seeded with, by name. Cofactor generates each\n * one's password when the snapshot is built (every copy of it shares them)\n * and hands it to `lifecycle.prepare` only (as COFACTOR_PERSONAS, a JSON\n * map of name to email and password).\n */\n personas: z.record(z.string().regex(NAME), z.strictObject({ email: z.email() })).default({}),\n /**\n * How `cofactor-sandbox auth` mints browser state for one declared persona:\n * a private script (`run`), or a sign-in the helper drives itself through a\n * declared emulator (`emulated`).\n */\n authentication: z.union([\n z.strictObject({\n run: z.string().min(1).refine(\n (path) => !path.startsWith('/') && path.split('/').every((part) => part !== '' && part !== '.' && part !== '..'),\n 'must be a relative script path inside the definition directory'\n ),\n }),\n z.strictObject({\n emulated: z.strictObject({\n provider: z.enum(EMULATED_PROVIDER_IDS),\n /** `${params.<port param>}<path>`: the app URL that starts sign-in. */\n sign_in: z.string().regex(SIGN_IN_URL),\n }),\n }),\n ]).optional(),\n /** Typed scripts: the one way data gets into a sandbox (seeds, the CLI, agents). */\n actions: z.record(z.string().regex(NAME), action).default({}),\n /** Emulator plugin id -> its config. Declaring any plugin adds the implicit `emulation` port. */\n emulation: z.record(z.string().regex(NAME), z.record(z.string(), z.unknown())).default({}),\n /** Databases a built-in operation (`database.fast-forward`) works on, by name. */\n databases: z.record(z.string().regex(NAME), database).default({}),\n /**\n * An emulated S3 or GCS server with these buckets, created before the first\n * prepare. Declaring it adds the implicit public `object-storage` port and\n * the services that run the server (`objectStorageServices`), and gives\n * every child the provider's standard client env (`objectStorageEnv`).\n */\n object_storage: z\n .strictObject({\n provider: z.enum(OBJECT_STORAGE_PROVIDERS),\n buckets: z\n .array(\n z\n .string()\n .regex(BUCKET, '3–63 lowercase letters, digits, \"-\" and \".\", starting and ending with a letter or digit')\n // Names the real services refuse too, so an app's buckets carry over.\n .refine((name) => !name.includes('..'), 'no consecutive dots')\n .refine((name) => !/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(name), 'not shaped like an IP address')\n )\n .min(1)\n .refine((buckets) => new Set(buckets).size === buckets.length, 'bucket names must be unique'),\n })\n // The GCS front reads `/<bucket>/…` as an XML-style upload unless it is a\n // JSON API path (`/storage/v1/…`, `/upload/storage/v1/…`): those first\n // segments can't be buckets.\n .refine(\n (storage) => storage.provider !== 'gcs' || !storage.buckets.some((name) => GCS_RESERVED_BUCKETS.has(name)),\n { message: `a GCS bucket can't be named ${[...GCS_RESERVED_BUCKETS].join(', ')}`, path: ['buckets'] }\n )\n .optional(),\n /**\n * Named flavors of the same sandbox (different starting data and config).\n * Must include `default`; cross-checked, not schema-enforced, so the issue\n * carries a path.\n */\n environments: z.record(z.string().regex(NAME), environment),\n};\n\n/** Playwright storage state returned by `cofactor-sandbox auth`. */\nexport const sandboxAuthResultSchema = z.strictObject({\n cookies: z.array(z.strictObject({\n name: z.string(), value: z.string(), domain: z.string(), path: z.string(),\n expires: z.number(), httpOnly: z.boolean(), secure: z.boolean(),\n sameSite: z.enum(['Strict', 'Lax', 'None']),\n })),\n origins: z.array(z.strictObject({\n origin: z.string(),\n localStorage: z.array(z.strictObject({ name: z.string(), value: z.string() })),\n })),\n}).refine(\n (state) => state.cookies.length > 0 || state.origins.some((origin) => origin.localStorage.length > 0),\n 'must contain at least one cookie or local-storage entry'\n);\nexport type SandboxAuthResult = z.infer<typeof sandboxAuthResultSchema>;\nexport const SANDBOX_AUTH_MAX_BYTES = 1024 * 1024;\n\n/** Reject malformed or overlarge helper results without including state values in diagnostics. */\nexport function parseSandboxAuthResult(value: string): SandboxAuthResult | null {\n if (Buffer.byteLength(value, 'utf8') > SANDBOX_AUTH_MAX_BYTES) return null;\n let parsed: unknown;\n try { parsed = JSON.parse(value); } catch { return null; }\n const result = sandboxAuthResultSchema.safeParse(parsed);\n return result.success ? result.data : null;\n}\n\n/**\n * What every delivery's definition has: how the sandbox runs, prepares and\n * seeds. An uploaded image is already built, so its definition is exactly\n * this; its optional `lifecycle.build` is never run at push or claim, only by\n * a working-tree sync with `--build`.\n */\nconst definitionSchema = z.strictObject({\n ...sharedFields,\n lifecycle: z.strictObject({ prepare: prepareCommands, build: z.array(buildStep).min(1).optional() }),\n});\n\n/** A GitHub-delivered definition also installs and builds the checkout. */\nconst githubDefinitionSchema = definitionSchema.extend({\n /**\n * Root shell script that installs the toolchain (packages, runtimes,\n * database clusters). With the resources, it keys the toolchain layer.\n */\n setup: z.string().min(1),\n lifecycle: z.strictObject({\n build: z.array(buildStep).min(1),\n prepare: prepareCommands,\n }),\n});\n\n/** What every delivery's definition has; everything after the build takes this. */\nexport type Definition = z.infer<typeof definitionSchema>;\n/** A GitHub-delivered definition: a `Definition` plus how to install and build the checkout. */\nexport type GithubDefinition = z.infer<typeof githubDefinitionSchema>;\nexport type ServiceSpec = Definition['services'][string];\nexport type BuildStep = z.infer<typeof buildStep>;\nexport type ActionDef = Definition['actions'][string];\nexport type SeedStep = Definition['environments'][string]['seeds'][number];\n\nexport type Environment = Definition['environments'][string];\n\n/** What a seed step runs, as the string every record of it keeps (the action-run row, `buildPhases.seeds`). */\nexport function seedStepTarget(step: SeedStep): string {\n // The schema guarantees exactly one of the two is set.\n return step.operation ?? step.action!;\n}\n\n/** One problem found while parsing or cross-checking a definition, with a dotted path to it. */\nexport interface DefinitionIssue {\n path: string;\n message: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nconst PROP_TYPES = ['string', 'number', 'integer', 'boolean', 'persona'] as const;\ntype PropType = (typeof PROP_TYPES)[number];\n\n/** Narrows a duck-typed `prop.type` (from raw YAML) to the four/five declared values. */\nfunction isPropType(value: unknown): value is PropType {\n return typeof value === 'string' && (PROP_TYPES as readonly string[]).includes(value);\n}\n\nfunction typeMatches(type: PropType, value: unknown): boolean {\n // A persona reference is a string; whether it names a declared persona is\n // checked separately (validateActionInput, checkSeedInputAgainstAction).\n if (type === 'string' || type === 'persona') return typeof value === 'string';\n if (type === 'boolean') return typeof value === 'boolean';\n if (type === 'integer') return typeof value === 'number' && Number.isInteger(value);\n return typeof value === 'number';\n}\n\nfunction isExactStepRef(value: unknown): boolean {\n return typeof value === 'string' && EXACT_STEP_REF.test(value);\n}\n\n/**\n * A step's declared outputs, keyed by property name, each mapped to whether\n * it is a primitive (string/number/boolean) that `${id.key}` may reference. A\n * repo action's outputs are always primitive (`outputProp.type` has no other\n * option); an emulator operation's may not be (e.g. `email.sent-emails`'s\n * `emails` array).\n */\ntype StepOutputs = Record<string, Record<string, boolean>>;\n\n/** Every `${stepId.key}` in `value` must reference an already-resolved, primitive output. */\nfunction checkStepReferences(value: unknown, outputs: StepOutputs, path: string, issues: DefinitionIssue[]): void {\n if (typeof value !== 'string') return;\n for (const match of value.matchAll(STEP_REF)) {\n const stepId = match[1]!;\n const key = match[2]!;\n const stepOutputs = outputs[stepId];\n if (!stepOutputs) {\n issues.push({ path, message: `references step \"${stepId}\", which has not run yet (or does not exist)` });\n continue;\n }\n if (!(key in stepOutputs)) {\n issues.push({ path, message: `references undeclared output \"${key}\" of step \"${stepId}\"` });\n continue;\n }\n if (!stepOutputs[key]) {\n issues.push({\n path,\n message: `output \"${key}\" of step \"${stepId}\" is not a string/number/boolean and cannot be referenced`,\n });\n }\n }\n}\n\n/** Resolve `environments[name]`'s parent chain (raw, duck-typed), parent-first. Throws on a cycle. */\nfunction resolveRawChain(environments: Record<string, unknown>, name: string): unknown[] {\n const order: string[] = [];\n let current: string | undefined = name;\n const seen = new Set<string>();\n while (current) {\n if (seen.has(current)) throw new Error(`extends cycle at \"${current}\"`);\n seen.add(current);\n order.unshift(current);\n const env: unknown = environments[current];\n current = isRecord(env) && typeof env.extends === 'string' ? env.extends : undefined;\n }\n return order.flatMap((envName) => {\n const env = environments[envName];\n return isRecord(env) && Array.isArray(env.seeds) ? env.seeds : [];\n });\n}\n\n/**\n * Validate a seed's static (literal, non-referencing) input values against a\n * repo action's declared input properties, and check every `${id.key}`\n * reference against outputs resolved so far.\n */\nfunction checkSeedInputAgainstAction(\n input: unknown,\n declaredAction: unknown,\n outputs: StepOutputs,\n personas: Set<string>,\n path: string,\n issues: DefinitionIssue[]\n): void {\n const given = isRecord(input) ? input : {};\n const declaredInputs = isRecord(declaredAction) && isRecord(declaredAction.input) ? declaredAction.input : {};\n for (const [key, value] of Object.entries(given)) {\n checkStepReferences(value, outputs, `${path}.${key}`, issues);\n if (!(key in declaredInputs)) issues.push({ path: `${path}.${key}`, message: `unknown input \"${key}\"` });\n }\n for (const [name, prop] of Object.entries(declaredInputs)) {\n if (!isRecord(prop)) continue;\n const hasValue = name in given;\n const hasDefault = prop.default !== undefined;\n if (!hasValue && prop.required === true && !hasDefault) {\n issues.push({ path: `${path}.${name}`, message: `missing required input \"${name}\"` });\n continue;\n }\n if (!hasValue) continue;\n const value = given[name];\n if (isExactStepRef(value)) continue; // resolved at claim time; skip the literal type/persona/enum check\n if (isPropType(prop.type) && !typeMatches(prop.type, value)) {\n issues.push({ path: `${path}.${name}`, message: `must be ${String(prop.type)}` });\n } else if (prop.type === 'persona' && typeof value === 'string' && !personas.has(value)) {\n issues.push({\n path: `${path}.${name}`,\n message: `must be a declared persona (one of ${[...personas].join(', ') || '(none declared)'})`,\n });\n } else if (Array.isArray(prop.enum) && !(prop.enum as unknown[]).includes(value)) {\n issues.push({ path: `${path}.${name}`, message: `must be one of ${prop.enum.join(', ')}` });\n }\n }\n}\n\n/** Same as above, but against an emulator operation's zod input schema. */\nfunction checkSeedInputAgainstOperation(\n input: unknown,\n operationInput: z.ZodType,\n outputs: StepOutputs,\n path: string,\n issues: DefinitionIssue[]\n): void {\n const given = isRecord(input) ? input : {};\n let anyReference = false;\n for (const [key, value] of Object.entries(given)) {\n checkStepReferences(value, outputs, `${path}.${key}`, issues);\n if (isExactStepRef(value)) anyReference = true;\n }\n // A step's value can only be validated once resolved; skip the schema check\n // when any input references an earlier step (references are still checked above).\n if (anyReference) return;\n const parsed = operationInput.safeParse(given);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) {\n issues.push({ path: [path, ...issue.path.map(String)].join('.'), message: issue.message });\n }\n }\n}\n\nconst PRIMITIVE_JSON_TYPES = new Set(['string', 'number', 'integer', 'boolean']);\n\n/**\n * Declared output keys of an operation, each mapped to whether it is a\n * primitive `${id.key}` may reference (see `StepOutputs`). Read from the\n * output's JSON Schema, the same representation operation inputs are checked\n * against (packages/emulation operations.test.ts).\n */\nfunction operationOutputShape(outputSchema: z.ZodType): Record<string, boolean> {\n const { properties } = z.toJSONSchema(outputSchema) as { properties?: Record<string, { type?: unknown }> };\n if (!properties) return {};\n return Object.fromEntries(\n Object.entries(properties).map(([key, prop]) => [key, typeof prop.type === 'string' && PRIMITIVE_JSON_TYPES.has(prop.type)])\n );\n}\n\n/**\n * Cross-checks that zod cannot express, run against whatever shape parsed\n * (typed `Definition` when schema validation succeeded, or the raw YAML\n * object otherwise) so every problem is reported in one pass.\n */\nfunction crossCheck(data: unknown, delivery: Delivery, issues: DefinitionIssue[]): void {\n if (!isRecord(data)) return;\n const actions = isRecord(data.actions) ? data.actions : {};\n const emulation = isRecord(data.emulation) ? data.emulation : {};\n const databases = isRecord(data.databases) ? data.databases : {};\n const environments = isRecord(data.environments) ? data.environments : {};\n const ports = isRecord(data.ports) ? data.ports : {};\n const personas = isRecord(data.personas) ? new Set(Object.keys(data.personas)) : new Set<string>();\n const hasEmulation = Object.keys(emulation).length > 0;\n\n if (!('default' in environments)) {\n issues.push({ path: 'environments', message: 'must include a \"default\" environment' });\n }\n\n // emulation plugin ids: every declared plugin must be registered, and its\n // config must match the plugin's `configSchema` when it declares one.\n for (const [pluginId, pluginConfig] of Object.entries(emulation)) {\n const plugin = getPlugin(pluginId);\n if (!plugin) {\n issues.push({ path: `emulation.${pluginId}`, message: `unknown emulation plugin \"${pluginId}\"` });\n continue;\n }\n const parsed = plugin.configSchema?.safeParse(pluginConfig);\n for (const issue of parsed?.error?.issues ?? []) {\n issues.push({ path: ['emulation', pluginId, ...issue.path.map(String)].join('.'), message: issue.message });\n }\n }\n\n // Every Google account is a persona: with none, nobody can be signed in.\n if ('google-oauth' in emulation && personas.size === 0) {\n issues.push({ path: 'emulation.google-oauth', message: 'each persona is a Google account; declare at least one' });\n }\n if ('oidc' in emulation && personas.size === 0) {\n issues.push({ path: 'emulation.oidc', message: 'each persona is an account; declare at least one' });\n }\n\n // authentication.emulated: the provider must be declared, and sign_in must\n // start from one of the definition's port params.\n const authentication = isRecord(data.authentication) ? data.authentication : {};\n if (isRecord(authentication.emulated)) {\n const { provider, sign_in: signIn } = authentication.emulated;\n if (typeof provider === 'string' && !(provider in emulation)) {\n issues.push({ path: 'authentication.emulated.provider', message: `\"${provider}\" is not declared in emulation` });\n }\n const paramName = typeof signIn === 'string' ? SIGN_IN_URL.exec(signIn)?.[1] : undefined;\n if (paramName !== undefined) {\n const declared = isRecord(data.params) ? data.params[paramName] : undefined;\n if (declared === undefined) {\n issues.push({ path: 'authentication.emulated.sign_in', message: `references undeclared param \"${paramName}\"` });\n } else if (!(isRecord(declared) && 'port' in declared)) {\n issues.push({ path: 'authentication.emulated.sign_in', message: `param \"${paramName}\" must be a port param (the copy's public URL)` });\n } else {\n const port = typeof declared.port === 'string' ? ports[declared.port] : undefined;\n if (isRecord(port) && port.access !== 'public') {\n issues.push({ path: 'authentication.emulated.sign_in', message: `param \"${paramName}\" is on a private port; sign-in must start on the copy's public URL` });\n }\n }\n }\n }\n\n // extends: existence and cycles. `broken` collects every environment whose\n // own or inherited extends chain is unresolvable, so the seed-chain pass\n // below skips it (its own seeds get no path to validate against).\n const broken = new Set<string>();\n for (const name of Object.keys(environments)) {\n const env = environments[name];\n if (!isRecord(env) || typeof env.extends !== 'string') continue;\n if (!(env.extends in environments)) {\n issues.push({ path: `environments.${name}.extends`, message: `unknown environment \"${env.extends}\"` });\n broken.add(name);\n continue;\n }\n try {\n resolveRawChain(environments, name);\n } catch (error) {\n issues.push({ path: `environments.${name}.extends`, message: error instanceof Error ? error.message : String(error) });\n broken.add(name);\n }\n }\n\n // env keys.\n for (const [name, env] of Object.entries(environments)) {\n if (!isRecord(env) || !isRecord(env.env)) continue;\n for (const key of Object.keys(env.env)) {\n if (!ENV_NAME.test(key)) issues.push({ path: `environments.${name}.env.${key}`, message: 'not a valid env var name' });\n }\n }\n\n /**\n * Validate one environment's OWN seeds (not its inherited ones), labeled\n * with its declaring environment name and local index, and only once no\n * matter how many descendants extend it. Returns the cumulative outputs and\n * step ids after this environment's own seeds, for a child to build on.\n */\n const resolved = new Map<string, { outputs: StepOutputs; seenIds: Set<string> }>();\n function resolveEnvSeeds(name: string): { outputs: StepOutputs; seenIds: Set<string> } {\n const cached = resolved.get(name);\n if (cached) return cached;\n const env = environments[name];\n let outputs: StepOutputs = {};\n let seenIds = new Set<string>();\n if (isRecord(env) && typeof env.extends === 'string' && env.extends in environments && !broken.has(name)) {\n const parent = resolveEnvSeeds(env.extends);\n outputs = { ...parent.outputs };\n seenIds = new Set(parent.seenIds);\n }\n const ownSeeds = isRecord(env) && Array.isArray(env.seeds) ? env.seeds : [];\n ownSeeds.forEach((step: unknown, index: number) => {\n if (!isRecord(step)) return;\n const path = `environments.${name}.seeds[${index}]`;\n const id = typeof step.id === 'string' ? step.id : undefined;\n if (id) {\n if (seenIds.has(id)) issues.push({ path: `${path}.id`, message: `duplicate step id \"${id}\"` });\n seenIds.add(id);\n }\n const actionRef = typeof step.action === 'string' ? step.action : undefined;\n let declaredOutputs: Record<string, boolean> | undefined;\n if (step.operation === FAST_FORWARD) {\n const given = isRecord(step.input) ? step.input : {};\n checkSeedInputAgainstOperation(step.input, fastForwardInput, outputs, `${path}.input`, issues);\n const named = given.database;\n if (typeof named === 'string' && !isExactStepRef(named) && !Object.hasOwn(databases, named)) {\n issues.push({\n path: `${path}.input.database`,\n message: `unknown database \"${named}\" (declared: ${Object.keys(databases).join(', ') || 'none'})`,\n });\n }\n declaredOutputs = operationOutputShape(fastForwardOutput);\n } else if (actionRef?.includes('.')) {\n const [pluginId, opId] = actionRef.split('.', 2) as [string, string];\n if (!(pluginId in emulation)) {\n issues.push({ path: `${path}.action`, message: `plugin \"${pluginId}\" is not declared in emulation` });\n } else {\n const op = findOperation(pluginId, opId);\n if (!op) {\n issues.push({ path: `${path}.action`, message: `unknown operation \"${actionRef}\"` });\n } else {\n declaredOutputs = operationOutputShape(op.output);\n checkSeedInputAgainstOperation(step.input, op.input, outputs, `${path}.input`, issues);\n }\n }\n } else if (actionRef !== undefined) {\n const declared = actions[actionRef];\n if (!declared) {\n issues.push({ path: `${path}.action`, message: `unknown action \"${actionRef}\"` });\n } else {\n const outputProps = isRecord(declared) && isRecord(declared.output) ? declared.output : {};\n declaredOutputs = Object.fromEntries(Object.keys(outputProps).map((key) => [key, true]));\n checkSeedInputAgainstAction(step.input, declared, outputs, personas, `${path}.input`, issues);\n }\n }\n if (id) outputs = { ...outputs, [id]: declaredOutputs ?? {} };\n });\n const result = { outputs, seenIds };\n resolved.set(name, result);\n return result;\n }\n\n // seed chains: duplicate ids, unknown actions/operations, static input and references.\n for (const name of Object.keys(environments)) {\n if (broken.has(name)) continue; // the cycle/unknown-parent is already reported above\n resolveEnvSeeds(name);\n }\n\n // ports: reserved names, and (with emulation or object storage on) no user\n // port on theirs, plus Blackcat's 8-port cap.\n if (EMULATION_PORT_NAME in ports) {\n issues.push({ path: `ports.${EMULATION_PORT_NAME}`, message: `\"${EMULATION_PORT_NAME}\" is a reserved port name` });\n }\n if (OBJECT_STORAGE_PORT_NAME in ports) {\n issues.push({ path: `ports.${OBJECT_STORAGE_PORT_NAME}`, message: `\"${OBJECT_STORAGE_PORT_NAME}\" is a reserved port name` });\n }\n if (SYNC_PORT_NAME in ports) {\n issues.push({ path: `ports.${SYNC_PORT_NAME}`, message: `\"${SYNC_PORT_NAME}\" is a reserved port name` });\n }\n for (const [portName, portValue] of Object.entries(ports)) {\n if (isRecord(portValue) && portValue.port === SYNC_PORT) {\n issues.push({ path: `ports.${portName}.port`, message: `port ${SYNC_PORT} is reserved for syncing a working tree into the sandbox` });\n }\n }\n const storage = isRecord(data.object_storage) ? data.object_storage : undefined;\n const provider = OBJECT_STORAGE_PROVIDERS.find((name) => name === storage?.provider);\n if (provider) {\n for (const [portName, portValue] of Object.entries(ports)) {\n if (!isRecord(portValue) || typeof portValue.port !== 'number') continue;\n if (RESERVED_STORAGE_PORTS[provider].includes(portValue.port)) {\n issues.push({\n path: `ports.${portName}.port`,\n message: `port ${portValue.port} is reserved for the ${provider} object storage server`,\n });\n }\n }\n }\n if (hasEmulation) {\n for (const [portName, portValue] of Object.entries(ports)) {\n if (portName === EMULATION_PORT_NAME || !isRecord(portValue)) continue;\n if (portValue.port === 80 || portValue.port === 443) {\n issues.push({ path: `ports.${portName}.port`, message: 'ports 80 and 443 are reserved for the emulator' });\n }\n }\n }\n // The `sync` port is always implied, so a definition may declare at most 7 of its own.\n const impliedPortCount =\n Object.keys(ports).filter((p) => p !== EMULATION_PORT_NAME && p !== OBJECT_STORAGE_PORT_NAME && p !== SYNC_PORT_NAME).length +\n (hasEmulation ? 1 : 0) +\n (storage ? 1 : 0) +\n 1;\n if (impliedPortCount > 8) {\n issues.push({\n path: 'ports',\n message: `at most 8 ports are allowed (Blackcat's limit), counting the implicit ones (sync${hasEmulation ? ', emulation' : ''}${storage ? ', object-storage' : ''}); got ${impliedPortCount}`,\n });\n }\n\n const services = isRecord(data.services) ? data.services : {};\n for (const name of [...OBJECT_STORAGE_SERVICE_NAMES, SYNC_SERVICE_NAME]) {\n if (name in services) issues.push({ path: `services.${name}`, message: `\"${name}\" is a reserved service name` });\n }\n\n // build steps: duplicates (kept from before actions/environments existed).\n const lifecycle = isRecord(data.lifecycle) ? data.lifecycle : {};\n if (Array.isArray(lifecycle.build)) {\n const seen = new Set<string>();\n lifecycle.build.forEach((step: unknown, index: number) => {\n if (!isRecord(step) || typeof step.name !== 'string') return;\n if (seen.has(step.name)) {\n issues.push({ path: `lifecycle.build[${index}].name`, message: `build step \"${step.name}\" is declared twice` });\n }\n seen.add(step.name);\n });\n }\n\n // An uploaded image is already built: say so where a build is declared.\n if (delivery === 'upload') {\n if ('setup' in data) {\n issues.push({ path: 'setup', message: 'an uploaded image is already built: remove setup (install it in the image)' });\n }\n }\n\n // params referring to undeclared ports, and env referring to undeclared params.\n const params = isRecord(data.params) ? data.params : {};\n for (const [name, value] of Object.entries(params)) {\n if (\n isRecord(value) &&\n 'port' in value &&\n typeof value.port === 'string' &&\n !(value.port in ports) &&\n !(storage && value.port === OBJECT_STORAGE_PORT_NAME) &&\n !(hasEmulation && value.port === EMULATION_PORT_NAME)\n ) {\n issues.push({ path: `params.${name}.port`, message: `refers to undeclared port \"${value.port}\"` });\n }\n }\n const env = isRecord(data.env) ? data.env : {};\n for (const [key, template] of Object.entries(env)) {\n if (typeof template !== 'string') continue;\n for (const match of template.matchAll(PARAM_REF)) {\n const paramName = match[1]!;\n if (!(paramName in params)) issues.push({ path: `env.${key}`, message: `references undeclared param \"${paramName}\"` });\n }\n }\n issues.push(...emulationReferenceIssues(emulation, params));\n}\n\n/** The sync server: started like any service that needs neither a build nor a prepare; it refuses requests until the first prepare gives it a key. */\nconst SYNC_SERVICE = {\n run: 'exec /usr/local/bin/cofactor-sandbox sync-server',\n health: { http: SYNC_PORT, path: '/healthz' },\n after_build: false,\n reload_on_prepare: false,\n} as const;\n\n/**\n * Adds what declarations imply: the public `sync` port and the service that\n * serves it (always), the public, port-80 `emulation` port once any plugin is\n * declared, and with `object_storage` the public `object-storage` port and\n * the services that run its server.\n */\nfunction withImplicitPieces<D extends Definition>(definition: D): D {\n let result: D = {\n ...definition,\n ports: { ...definition.ports, [SYNC_PORT_NAME]: { port: SYNC_PORT, access: 'public' } },\n services: { ...definition.services, [SYNC_SERVICE_NAME]: SYNC_SERVICE },\n };\n if (Object.keys(definition.emulation).length > 0) {\n result = { ...result, ports: { ...result.ports, emulation: { port: 80, access: 'public' } } };\n }\n const storage = definition.object_storage;\n if (storage) {\n result = {\n ...result,\n ports: { ...result.ports, [OBJECT_STORAGE_PORT_NAME]: { port: OBJECT_STORAGE_PORT[storage.provider], access: 'public' } },\n services: { ...result.services, ...objectStorageServices(storage.provider) },\n };\n }\n return result;\n}\n\n/**\n * Parse and cross-check a definition delivered by `delivery`. Schema issues\n * (zod collects every one, not just the first) and cross-checks are both\n * returned with a dotted path; cross-checks also run against the raw YAML\n * object when schema parsing failed, so a structural problem (an extends\n * cycle, a duplicate step id) is still reported.\n */\nexport function validateDefinition(\n yamlText: string,\n delivery: 'github'\n): { definition?: GithubDefinition; issues: DefinitionIssue[] };\nexport function validateDefinition(\n yamlText: string,\n delivery: Delivery\n): { definition?: Definition; issues: DefinitionIssue[] };\nexport function validateDefinition(\n yamlText: string,\n delivery: Delivery\n): { definition?: Definition; issues: DefinitionIssue[] } {\n const issues: DefinitionIssue[] = [];\n let raw: unknown;\n try {\n raw = parse(yamlText);\n } catch (error) {\n return { issues: [{ path: '', message: `invalid YAML: ${error instanceof Error ? error.message : String(error)}` }] };\n }\n const parsed = (delivery === 'github' ? githubDefinitionSchema : definitionSchema).safeParse(raw);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) {\n issues.push({ path: issue.path.map(String).join('.') || '(root)', message: issue.message });\n }\n crossCheck(raw, delivery, issues);\n return { issues };\n }\n crossCheck(parsed.data, delivery, issues);\n return { definition: withImplicitPieces(parsed.data), issues };\n}\n\n/**\n * A stored definition's port names in their declared order, whichever way it\n * was delivered. For text validated when it was stored (a claimed sandbox's\n * `definitionYaml`); it does not validate again.\n */\nexport function declaredPortNames(yamlText: string): string[] {\n const ports = z.object({ ports: z.record(z.string(), z.unknown()) }).parse(parse(yamlText)).ports;\n return Object.keys(ports);\n}\n\n/** `validateDefinition`, throwing an error listing every issue (one per line, `path: message`). */\nexport function parseDefinition(yamlText: string, delivery: 'github'): GithubDefinition;\nexport function parseDefinition(yamlText: string, delivery: Delivery): Definition;\nexport function parseDefinition(yamlText: string, delivery: Delivery): Definition {\n const { definition, issues } = validateDefinition(yamlText, delivery);\n if (issues.length > 0) throw new Error(issues.map((issue) => `${issue.path}: ${issue.message}`).join('\\n'));\n return definition!;\n}\n\n/**\n * Identifies the toolchain layer a definition needs: everything fixed when a\n * layer is made (the platform version, the prelude, the machine, the setup\n * script, the ports a template exposes, and the browser layer of the image\n * it starts from). Anything else in the definition is applied per commit and\n * never needs a new toolchain. The guest helper always passes `null`: it only\n * compares its own keys with each other, and the browser layer changes\n * nothing the helper does.\n */\nexport function toolchainKey(definition: GithubDefinition, browserLayer: BrowserLayer): string {\n const hash = createHash('sha256')\n .update(String(PLATFORM_VERSION))\n .update('\\0')\n .update(SETUP_PRELUDE)\n .update('\\0')\n .update(JSON.stringify(definition.resources))\n .update('\\0')\n .update(definition.setup)\n .update('\\0')\n .update(JSON.stringify(Object.entries(definition.ports).sort(([a], [b]) => a.localeCompare(b))));\n // Only a toolchain on the browser image hashes anything more, so every key\n // without the browser layer is exactly what it was before the layer existed.\n if (browserLayer !== null) hash.update('\\0browser-v').update(String(browserLayer));\n return hash.digest('hex');\n}\n\n/** Param values inside layers: fixed values, local port origins and placeholders for secrets. */\nexport function layerParams(definition: Definition): Record<string, string> {\n return Object.fromEntries(\n Object.entries(definition.params).map(([name, value]) => {\n if (typeof value === 'string') return [name, value];\n if ('port' in value) return [name, `http://127.0.0.1:${definition.ports[value.port]!.port}`];\n return [name, `layer-placeholder-${name}`];\n })\n );\n}\n\n/**\n * Exactly what a prepared sandbox was given values for — never more:\n * personas, per-sandbox params, the chosen environment's name, the resolved\n * chain's ENV (not its seeds, which run once at claim time and are Cofactor's\n * to re-run, not the sandbox's own state), the emulation section and the\n * object storage (whose buckets prepare creates). Seeds\n * run after prepare; a PR that only changes seed data does not need a fresh\n * sandbox. A commit that would change any of this needs a newly prepared\n * sandbox instead (EXIT.PREPARE_MISMATCH).\n */\nexport function preparedShape(definition: Definition, environment: string): string {\n const sorted = <T>(record: Record<string, T>) =>\n Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));\n const perSandbox = Object.fromEntries(Object.entries(definition.params).filter(([, value]) => typeof value !== 'string'));\n const env = environmentChain(definition, environment).env;\n return JSON.stringify({\n personas: sorted(definition.personas),\n params: sorted(perSandbox),\n environment,\n env,\n emulation: sorted(definition.emulation),\n object_storage: definition.object_storage && {\n provider: definition.object_storage.provider,\n buckets: [...definition.object_storage.buckets].sort(),\n },\n });\n}\n\n/**\n * A new sandbox's own param values, for `prepare`: its public port origins\n * and fresh secrets. Fixed values keep the definition's.\n */\nexport function sandboxParams(definition: Definition, portUrls: Record<string, string>): Record<string, string> {\n const values: Record<string, string> = {};\n for (const [name, value] of Object.entries(definition.params)) {\n if (typeof value === 'string') continue;\n if ('port' in value) {\n const url = portUrls[value.port];\n if (!url) throw new Error(`the sandbox has no URL for port \"${value.port}\"`);\n values[name] = url;\n } else {\n values[name] = randomBytes(32).toString('hex');\n }\n }\n return values;\n}\n\n/** Replaces every `${params.NAME}` in `template` with that param's value. */\nexport function substituteParams(template: string, values: Record<string, string>): string {\n return template.replace(PARAM_REF, (_, name: string) => values[name]!);\n}\n\nexport function resolveEnv(definition: Definition, params: Record<string, string>): Record<string, string> {\n const values = { ...layerParams(definition), ...params };\n return Object.fromEntries(\n Object.entries(definition.env).map(([key, template]) => [key, substituteParams(template, values)])\n );\n}\n\n/** The names of every `port` param, live or not: every one of these changes on every copy (each copy has its own port URLs). */\nexport function portParamNames(definition: Definition): Set<string> {\n return new Set(\n Object.entries(definition.params)\n .filter(([, value]) => typeof value !== 'string' && 'port' in value)\n .map(([name]) => name)\n );\n}\n\n/** The names of every param declared `live: true` (see `param`'s doc comment) — necessarily a subset of `portParamNames`. */\nfunction liveParamNames(definition: Definition): Set<string> {\n return new Set(\n Object.entries(definition.params)\n .filter(([, value]) => typeof value !== 'string' && 'port' in value && value.live === true)\n .map(([name]) => name)\n );\n}\n\n/**\n * `definition.env` keys whose template references at least one param and\n * every param it references is live: the subset of the resolved env a\n * sandbox's `reload_on_prepare` services never need a restart to pick up,\n * because `prepare` writes it to `LIVE_ENV_FILE` (runtime.ts) on every call\n * regardless of whether it restarts anything. A key that mixes a live and a\n * non-live param reference is deliberately excluded: it still needs a\n * restart whenever the non-live half changes, so the app cannot treat it as\n * always current.\n */\nfunction liveEnvKeys(definition: Definition): Set<string> {\n const live = liveParamNames(definition);\n const keys = new Set<string>();\n for (const [key, template] of Object.entries(definition.env)) {\n const refs = [...template.matchAll(PARAM_REF)].map((match) => match[1]!);\n if (refs.length > 0 && refs.every((name) => live.has(name))) keys.add(key);\n }\n return keys;\n}\n\n/**\n * The resolved env values a sandbox's live params currently determine — what\n * `prepare` writes to `LIVE_ENV_FILE` for the app to re-read at request time\n * instead of waiting for a restart.\n */\nexport function resolveLiveEnv(definition: Definition, params: Record<string, string>): Record<string, string> {\n const keys = liveEnvKeys(definition);\n const resolved = resolveEnv(definition, params);\n return Object.fromEntries(Object.entries(resolved).filter(([key]) => keys.has(key)));\n}\n\n/** Fast copies require live URL env and no baked emulator config that depends on a port URL. */\nexport function copyRestartRequired(definition: Definition): boolean {\n const ports = portParamNames(definition);\n const live = liveParamNames(definition);\n if ([...ports].some((name) => !live.has(name))) return true;\n const liveKeys = liveEnvKeys(definition);\n for (const [key, template] of Object.entries(definition.env)) {\n if ([...template.matchAll(PARAM_REF)].some((match) => ports.has(match[1]!)) && !liveKeys.has(key)) return true;\n }\n return [...emulationParamRefs(definition)].some((name) => ports.has(name));\n}\n\n/**\n * Whether a sandbox's `reload_on_prepare` services must restart for `next`'s\n * values to take effect, given what they were last prepared with (`previous`\n * is `undefined` the first time a sandbox is prepared, which always needs a\n * restart — the services have not started at all yet).\n *\n * The rule is the resolved env, not the raw params: restart iff the\n * environment, the repository secrets, or the emulation env's resolved\n * values differ, or `resolveEnv(definition, previous.params)` and\n * `resolveEnv(definition, next.params)` differ on any key that is NOT in\n * `liveEnvKeys`. Comparing resolved env keys (rather than looping over param\n * names and skipping the live ones) is what a *mixed* key needs: a key\n * templated from both a live and a non-live param is not in `liveEnvKeys`\n * (see its doc comment), so any change to either param — including the live\n * one alone — changes that key's resolved value and correctly forces a\n * restart; a per-param diff that simply skipped live param names would miss\n * this, since it never looks at the key the live param feeds into.\n *\n * Deliberately does not compare `personas` or `emulation.config` (the\n * control-plane token): neither reaches `reload_on_prepare` services' env —\n * `childEnv`'s `for: 'service'` branch never includes personas, and only\n * `emulation.env` (the plugins' env-contract values, currently always `{}`;\n * see `prepareInputSchema`), not `emulation.config`, is merged in. Rotating\n * the emulator's token on every copy is therefore free: it reconfigures the\n * emulator sidecar (`cofactor-sandbox prepare`'s unconditional `/emulation`\n * control call) and reruns `lifecycle.prepare` (a DB write, not a restart),\n * never the app services this function gates.\n */\nexport function restartRequired(\n definition: Definition,\n previous: PrepareInput | undefined,\n next: PrepareInput\n): boolean {\n if (!previous) return true;\n if (previous.environment !== next.environment) return true;\n if (JSON.stringify(previous.secrets) !== JSON.stringify(next.secrets)) return true;\n if (JSON.stringify(previous.emulation?.env ?? {}) !== JSON.stringify(next.emulation?.env ?? {})) return true;\n const live = liveEnvKeys(definition);\n const previousEnv = resolveEnv(definition, previous.params);\n const nextEnv = resolveEnv(definition, next.params);\n for (const key of Object.keys(definition.env)) {\n if (live.has(key)) continue;\n if (previousEnv[key] !== nextEnv[key]) return true;\n }\n return false;\n}\n\n/**\n * Resolve a copy prepare's full param set: every param the sandbox's previous\n * prepare had, with `given` (a copy's own `port` params — every one of them,\n * live or not: each copy has its own port URLs) applied over it. Any param\n * `given` omits, `secret` params among them, keeps the value the sandbox was\n * previously prepared with rather than a freshly generated one — necessary\n * for `auth_secret` (never reissued per copy) and harmless for a `live` port\n * param the caller happened to leave out (there is no real caller that\n * would: `copyPrepareInput` always sends every port param).\n *\n * Throws when `given` names a param the definition does not declare, or a\n * declared param that is not a `port` param (a `secret`, or a literal string)\n * — a copy prepare's caller (`copyPrepareInput`) must never attempt to change\n * one of those; the caller that wants to is not preparing a copy.\n *\n * Whether the result actually needs a restart is `restartRequired`'s call,\n * not this function's: a definition with no `live: true` params sends every\n * port param here exactly as before, and the resolved env then always\n * differs, so nothing here silently defeats an old definition's restart.\n */\nexport function resolveCopyParams(\n definition: Definition,\n previous: PrepareInput,\n given: Record<string, string>\n): Record<string, string> {\n const undeclared = Object.keys(given).filter((name) => !(name in definition.params));\n if (undeclared.length > 0) throw new Error(`not declared params: ${undeclared.join(', ')}`);\n const ports = portParamNames(definition);\n const notPort = Object.keys(given).filter((name) => !ports.has(name));\n if (notPort.length > 0) {\n throw new Error(`a copy prepare may only set port params, got: ${notPort.join(', ')}`);\n }\n return { ...previous.params, ...given };\n}\n\n/** The resolved seeds (parent first) and merged env (parent first, this environment last) of an environment chain. */\nexport interface ResolvedEnvironment {\n seeds: SeedStep[];\n env: Record<string, string>;\n /** The chain's environment names, ancestors first, `name` last. */\n lineage: string[];\n}\n\nexport function environmentChain(definition: Definition, name: string): ResolvedEnvironment {\n const seen = new Set<string>();\n function resolve(envName: string): ResolvedEnvironment {\n if (seen.has(envName)) throw new Error(`environment \"${envName}\" has an extends cycle`);\n seen.add(envName);\n const env = definition.environments[envName];\n if (!env) throw new Error(`unknown environment \"${envName}\"`);\n const parent = env.extends ? resolve(env.extends) : { seeds: [], env: {}, lineage: [] };\n return {\n seeds: [...parent.seeds, ...env.seeds],\n env: { ...parent.env, ...env.env },\n lineage: [...parent.lineage, envName],\n };\n }\n return resolve(name);\n}\n\n/**\n * Resolve one seed step's input against earlier steps' outputs: a value that\n * is exactly `${id.key}` becomes the raw output value, an embedded reference\n * is string-interpolated, and everything else passes through unchanged.\n */\nexport function resolveSeedInput(\n input: Record<string, string | number | boolean>,\n outputs: Record<string, Record<string, unknown>>\n): Record<string, unknown> {\n const resolveRef = (stepId: string, key: string): string | number | boolean => {\n const stepOutputs = outputs[stepId];\n if (!stepOutputs || !(key in stepOutputs)) throw new Error(`no output \"${key}\" from step \"${stepId}\"`);\n const value = stepOutputs[key];\n if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {\n throw new Error(`output \"${key}\" of step \"${stepId}\" is not a string/number/boolean and cannot be referenced`);\n }\n return value;\n };\n const resolved: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(input)) {\n if (typeof value !== 'string') {\n resolved[key] = value;\n continue;\n }\n const exact = EXACT_STEP_REF.exec(value);\n if (exact) {\n resolved[key] = resolveRef(exact[1]!, exact[2]!);\n continue;\n }\n resolved[key] = value.replace(STEP_REF, (_match, stepId: string, refKey: string) => String(resolveRef(stepId, refKey)));\n }\n return resolved;\n}\n\n/**\n * Apply an action's declared defaults/required/type/enum to raw input; report\n * every issue found. `personas` is the definition's declared persona names,\n * the only valid values for a `persona`-typed input.\n */\nexport function validateActionInput(\n action: ActionDef,\n input: Record<string, unknown>,\n personas: string[]\n): { values: Record<string, string | number | boolean> } | { issues: string[] } {\n const issues: string[] = [];\n for (const key of Object.keys(input)) {\n if (!(key in action.input)) issues.push(`unknown input \"${key}\"`);\n }\n const personaSet = new Set(personas);\n const values: Record<string, string | number | boolean> = {};\n for (const [name, prop] of Object.entries(action.input)) {\n const given = input[name];\n const value = given === undefined ? prop.default : given;\n if (value === undefined) {\n if (prop.required) issues.push(`missing required input \"${name}\"`);\n continue;\n }\n if (!typeMatches(prop.type, value)) {\n issues.push(`input \"${name}\" must be ${prop.type}`);\n continue;\n }\n if (prop.type === 'persona' && !personaSet.has(value as string)) {\n issues.push(`input \"${name}\" must be a declared persona (one of ${personas.join(', ') || '(none declared)'})`);\n continue;\n }\n if (prop.enum && !prop.enum.includes(value as string | number)) {\n issues.push(`input \"${name}\" must be one of ${prop.enum.join(', ')}`);\n continue;\n }\n values[name] = value as string | number | boolean;\n }\n return issues.length > 0 ? { issues } : { values };\n}\n\n/** v1's action-result contract: the last stdout line that starts with `{`, JSON-parsed as an object. */\nexport function parseActionResult(stdout: string): Record<string, unknown> | undefined {\n const lines = stdout.split('\\n');\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i]!.trim();\n if (!line.startsWith('{')) continue;\n try {\n const parsed: unknown = JSON.parse(line);\n return isRecord(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nexport const fastForwardInput = z.strictObject({ database: z.string().regex(NAME) });\nexport const fastForwardOutput = z.strictObject({\n database: z.string(),\n /** Whole days the data moved this run (0: nothing to do). */\n offset_days: z.number().int(),\n tables: z.number().int(),\n rows: z.number().int(),\n /** The data's date before and after (ISO-8601 UTC). */\n from: z.string(),\n to: z.string(),\n});\nexport type FastForwardOutput = z.infer<typeof fastForwardOutput>;\n\nexport const databaseFastForward = {\n name: FAST_FORWARD,\n description:\n \"Moves every date, timestamp and timestamptz column of a declared database forward by the whole days since the data's recorded date, so a restored dump looks current.\",\n input: fastForwardInput,\n output: fastForwardOutput,\n} as const;\n\nexport function isBuiltinOperation(ref: string): boolean {\n return ref === FAST_FORWARD;\n}\n\n/** Validate a run's input against the schema and the definition's declared databases. */\nexport function validateFastForwardInput(\n definition: Definition,\n input: Record<string, unknown>\n): { values: z.infer<typeof fastForwardInput> } | { issues: string[] } {\n const parsed = fastForwardInput.safeParse(input);\n if (!parsed.success) {\n return { issues: parsed.error.issues.map((issue) => `${issue.path.map(String).join('.') || '(root)'}: ${issue.message}`) };\n }\n const name = parsed.data.database;\n if (!Object.hasOwn(definition.databases, name)) {\n return { issues: [`database: unknown database \"${name}\" (declared: ${Object.keys(definition.databases).join(', ') || 'none'})`] };\n }\n return { values: parsed.data };\n}\n\n/**\n * What `cofactor-sandbox action` prints on stdout once the script's result has\n * validated: the result under `output`, plus the script's run time. The one\n * format both the helper (writer) and the API (reader) use.\n */\nexport interface ActionEnvelope {\n output: Record<string, unknown>;\n ms: number;\n}\n\n/**\n * The start of the helper's `default:` usage line. The API recognises a helper\n * without `exec` by this prefix plus exit 2, so it must never change (see the\n * PLATFORM_VERSION note).\n */\nexport const HELPER_USAGE_PREFIX = 'usage: cofactor-sandbox ';\n\n/** Longest command `cofactor-sandbox exec` runs. */\nexport const EXEC_MAX_TIMEOUT_SECONDS = 1800;\n\n/** The timeout `POST .../exec` applies when the caller gives none. */\nexport const EXEC_DEFAULT_TIMEOUT_SECONDS = 300;\n\n/** Longest command the exec route accepts, in characters. */\nexport const EXEC_MAX_COMMAND_LENGTH = 8192;\n\n/** What `cofactor-sandbox exec` reads on stdin. */\nexport const execInputSchema = z.strictObject({\n command: z.string().min(1),\n timeoutSeconds: z.number().int().min(1).max(EXEC_MAX_TIMEOUT_SECONDS),\n});\n\n/**\n * What `cofactor-sandbox exec` prints on stdout (exit 0): the command's own\n * outcome, so its exit codes never collide with the helper's.\n */\nexport const execEnvelopeSchema = z.strictObject({\n exitCode: z.number().int(),\n stdout: z.string(),\n stderr: z.string(),\n timedOut: z.boolean(),\n});\n\nexport function formatActionEnvelope(envelope: ActionEnvelope): string {\n return JSON.stringify(envelope);\n}\n\nexport function parseActionEnvelope(stdout: string): ActionEnvelope | undefined {\n const line = parseActionResult(stdout);\n if (!line || !isRecord(line.output) || typeof line.ms !== 'number') return undefined;\n return { output: line.output, ms: line.ms };\n}\n\n/**\n * What `cofactor-sandbox build` prints on stdout (one JSON line): the commit it\n * built, each `lifecycle.build` step (skipped steps have `ran: false`), and the\n * checkout, reload and service-restart times. Written by the helper, read by\n * the API, which keeps it as a ready snapshot's build timings.\n */\nexport const buildReportSchema = z.object({\n sha: z.string(),\n steps: z.array(z.object({ name: z.string(), ran: z.boolean(), ms: z.number() })),\n checkoutMs: z.number(),\n reloadMs: z.number(),\n restartMs: z.number(),\n totalMs: z.number(),\n});\n\nexport type BuildReport = z.infer<typeof buildReportSchema>;\n\n/** The build report on `build`'s stdout; throws when there is none (the helper always prints one). */\nexport function parseBuildReport(stdout: string): BuildReport {\n const parsed = buildReportSchema.safeParse(parseActionResult(stdout));\n if (!parsed.success) throw new Error(`build printed no valid report: ${parsed.error.message}`);\n return parsed.data;\n}\n\n/** Every declared output key must be present with the right primitive type; extra keys are allowed. */\nexport function validateActionOutput(action: ActionDef, output: Record<string, unknown>): string[] {\n const issues: string[] = [];\n for (const [name, prop] of Object.entries(action.output)) {\n if (!(name in output)) {\n issues.push(`missing output \"${name}\"`);\n continue;\n }\n if (!typeMatches(prop.type, output[name])) issues.push(`output \"${name}\" must be ${prop.type}`);\n }\n return issues;\n}\n\n/** What a sandbox receives at `prepare`: declared params, its environment, persona passwords and the application's secrets. */\nexport const prepareInputSchema = z.strictObject({\n /**\n * `false` for a sandbox's first prepare (a repo base moved to a commit, or\n * the builder a ready snapshot is captured from): `params` is every\n * declared param. `true` for a copy restored from an already-prepared\n * ready snapshot: `params` sets every `port` param (its own URLs — every\n * one of them differs per copy, `live: true` or not; see `portParamNames`)\n * but no `secret` param — those keep the value the snapshot itself was\n * prepared with (`resolveCopyParams`), which is what lets `restartRequired`\n * skip restarting `reload_on_prepare` services when the only params that\n * changed are `live` ones. A copy prepare requires a previous prepare to\n * copy from; there is no default because a caller that gets this wrong\n * needs a loud, specific error, not a silently-full or silently-partial\n * prepare.\n */\n copy: z.boolean(),\n params: z.record(z.string().regex(PARAM), z.string()),\n /**\n * One password per declared persona, generated by Cofactor when the\n * snapshot is built. Empty for a copy (`copy: true`), which keeps its\n * snapshot's, shared by every copy (`lifecycle.prepare` gets them as\n * COFACTOR_PERSONAS). The prepare output echoes the personas the sandbox\n * now has.\n */\n personas: z.record(z.string().regex(NAME), z.strictObject({ password: z.string().min(12) })),\n /**\n * The application's secrets (stored in Cofactor, never in the repo),\n * resolved for the environment chain at claim: runtime env for\n * `reload_on_prepare` services, prepare commands, seeds, actions and\n * `authentication.run`, overriding the definition's env on a name clash.\n * Never injected into build steps or services without `reload_on_prepare`.\n */\n secrets: z.record(z.string().regex(ENV_NAME), z.string()),\n /** The chosen flavor; its resolved chain's seeds ran at claim time. */\n environment: z.string().regex(NAME),\n /**\n * Present iff the definition declares `emulation`. `config` is the\n * `EmulationInstanceConfig` JSON Cofactor built for this sandbox; `env` is\n * the plugins' resolved env-contract values, mapped to this app's env vars.\n */\n emulation: z\n .strictObject({\n config: z.record(z.string(), z.unknown()),\n env: z.record(z.string().regex(ENV_NAME), z.string()),\n })\n .optional(),\n /**\n * The copy's own sync key, fresh on every prepare (a copy never shares its\n * snapshot's): the sync server checks each request's token against it\n * (`verifySyncToken`, sync-protocol.ts). Never in any child's env.\n */\n sync: z.strictObject({ key: syncKeySchema }),\n});\nexport type PrepareInput = z.infer<typeof prepareInputSchema>;\n\n/*\n * Blackcat template names. A template's name is its identity: the jobs and\n * the operator driver find a layer by name, so these are the one definition.\n * A GitHub-delivered application's toolchain and repo base are named by its\n * repository and definition directory, which both fold into their slug.\n */\n\n/**\n * The platform layer for a machine shape. A Blackcat template restores only at\n * the size it was captured at, so there is one per shape in use; the API\n * imports each from the version's one platform image (`platformImageTag`) the\n * first time a toolchain of that shape is built. With a browser layer, it is\n * imported from that layer's image (`browserImageTag`) under its own name.\n */\nexport function platformTemplateName(definition: Definition, browserLayer: BrowserLayer): string {\n const name = `sbv2-platform-v${PLATFORM_VERSION}-${definition.resources.vcpus}c-${definition.resources.memory_mib}m`;\n return browserLayer === null ? name : `${name}-browser-v${browserLayer}`;\n}\n\n/**\n * The platform image's tag in its repository, published once per version by\n * `image.sh`. The repository's tags are immutable, so a version's image never\n * changes under the templates imported from it.\n */\nexport function platformImageTag(platformVersion: number): string {\n return `platform-v${platformVersion}`;\n}\n\n/**\n * The browser image's tag: the platform image of `platformVersion` with the\n * browser layer of `browserLayer` appended, published once per pair by\n * `image.sh` (immutable, like the platform tag).\n */\nexport function browserImageTag(platformVersion: number, browserLayer: number): string {\n return `${platformImageTag(platformVersion)}-browser-v${browserLayer}`;\n}\n\n/**\n * The definition's file, relative to the repo root: `cofactor.sandbox.yaml`\n * at the root, or `<dir>/cofactor.sandbox.yaml` for a monorepo definition.\n * `dir` must be `.` or a relative POSIX path with no leading/trailing slash\n * and no `..` segment.\n */\nexport function definitionFile(dir: string): string {\n if (dir === '.') return DEFINITION_FILE;\n if (dir === '' || dir.startsWith('/') || dir.endsWith('/') || dir.split('/').includes('..')) {\n throw new Error(`invalid definition directory \"${dir}\"`);\n }\n return `${dir}/${DEFINITION_FILE}`;\n}\n\n/** For '.' hashes the repo alone (existing root template names are unchanged); otherwise repo + ':' + dir. */\nfunction repoSlug(repoFullName: string, definitionDir: string): string {\n const key = definitionDir === '.' ? repoFullName : `${repoFullName}:${definitionDir}`;\n return createHash('sha256').update(key).digest('hex').slice(0, 8);\n}\n\nexport function toolchainTemplateName(\n repoFullName: string,\n definitionDir: string,\n definition: GithubDefinition,\n browserLayer: BrowserLayer\n): string {\n return `sbv2-${repoSlug(repoFullName, definitionDir)}-toolchain-${toolchainKey(definition, browserLayer).slice(0, 12)}`;\n}\n\n/**\n * A repo base at `sha`, built on `definition`'s toolchain. The toolchain is in\n * the name so a base built on an older toolchain (a platform bump, a change to\n * setup or resources) never shares a name with its replacement: the rebuild\n * can't adopt the old template, and deleting the old one can't remove the new.\n */\nexport function baseTemplateName(\n repoFullName: string,\n definitionDir: string,\n definition: GithubDefinition,\n browserLayer: BrowserLayer,\n sha: string\n): string {\n return `sbv2-${repoSlug(repoFullName, definitionDir)}-base-${toolchainKey(definition, browserLayer).slice(0, 12)}-${sha.slice(0, 12)}`;\n}\n\n/**\n * A ready snapshot: a version of an application (a commit, for a GitHub-\n * delivered one) built, prepared and seeded for one environment, captured\n * running. Its key on the template row is `readySnapshotKey`. Named by the\n * application, which is one org's: a ready snapshot holds an org's seeded\n * data, so no two orgs ever adopt or delete each other's. `nonce` is fixed\n * when the snapshot's row is first created: a rerun of the same build adopts\n * the template it promoted, but a row created after retention deleted the\n * last one never adopts a template left behind.\n */\nexport function readyTemplateName(applicationId: string, version: string, environment: string, nonce: string): string {\n const slug = createHash('sha256').update(applicationId).digest('hex').slice(0, 8);\n const versionSlug = createHash('sha256').update(version).digest('hex').slice(0, 12);\n return `sbv2-${slug}-ready-${versionSlug}-${environment}-${nonce}`;\n}\n\nexport function readySnapshotKey(version: string, environment: string): string {\n return `${version}/${environment}`;\n}\n\n/** The version a `readySnapshotKey` names. */\nexport function readySnapshotVersion(key: string): string {\n const slash = key.lastIndexOf('/');\n if (slash < 0) throw new Error(`\"${key}\" is not a ready snapshot key`);\n return key.slice(0, slash);\n}\n\n/** A pushed image of an upload-delivered application, imported into Blackcat. */\nexport function uploadTemplateName(applicationId: string, uploadId: string): string {\n const slug = createHash('sha256').update(applicationId).digest('hex').slice(0, 8);\n return `sbv2-${slug}-upload-${uploadId}`;\n}\n\n/**\n * What a pushed image's ready snapshots are compatible with: the helper the\n * CLI layered into it. An upload-delivered application's counterpart of\n * `toolchainKey`; a platform bump makes every older push unusable until it\n * is pushed again.\n */\nexport function uploadCompatibilityKey(platformVersion: number): string {\n return `upload-platform-v${platformVersion}`;\n}\n","/**\n * Built-in object storage (`object_storage` in the definition): one emulated\n * S3 or GCS server per sandbox, run by the supervisor as implicit services so\n * its data is in every snapshot. Pure values, shared by the schema\n * (manifest.ts), the env (runtime.ts) and the guest side\n * (object-storage-server.ts); see specs/pending/sandboxes-v2-object-storage.md.\n */\n\nexport const OBJECT_STORAGE_PROVIDERS = ['s3', 'gcs'] as const;\nexport type ObjectStorageProvider = (typeof OBJECT_STORAGE_PROVIDERS)[number];\n\nexport interface ObjectStorage {\n provider: ObjectStorageProvider;\n buckets: string[];\n}\n\n/** The implicit public port; reserved whether or not storage is declared. */\nexport const OBJECT_STORAGE_PORT_NAME = 'object-storage';\n/** The implicit services' names; reserved whether or not storage is declared. */\nconst OBJECT_STORAGE_SERVICE = 'object-storage';\nconst OBJECT_STORAGE_FRONT_SERVICE = 'object-storage-front';\nexport const OBJECT_STORAGE_SERVICE_NAMES = [OBJECT_STORAGE_SERVICE, OBJECT_STORAGE_FRONT_SERVICE];\n\n/** Where the server keeps buckets: under the helper's state dir, outside any WORKDIR or checkout, owned by the sandbox account. */\nexport const OBJECT_STORAGE_DIR = '/var/lib/cofactor/object-storage';\n\n/** What clients (and the public port) reach: versitygw itself, or the GCS front. */\nexport const OBJECT_STORAGE_PORT: Record<ObjectStorageProvider, number> = { s3: 9000, gcs: 4443 };\n/** fake-gcs-server's own, loopback-only port behind the front. */\nexport const FAKE_GCS_PORT = 4444;\n/** Ports a user port may not take while that provider is declared. */\nexport const RESERVED_STORAGE_PORTS: Record<ObjectStorageProvider, number[]> = {\n s3: [OBJECT_STORAGE_PORT.s3],\n gcs: [OBJECT_STORAGE_PORT.gcs, FAKE_GCS_PORT],\n};\n\n/** Each provider's server, from its per-provider layer (`objectStorageLayerKey`, manifest.ts). */\nexport const OBJECT_STORAGE_BINARY: Record<ObjectStorageProvider, string> = {\n s3: '/usr/local/bin/versitygw',\n gcs: '/usr/local/bin/fake-gcs-server',\n};\n\n/**\n * The S3 root credentials, the same in every sandbox: the server holds only\n * the sandbox's own emulated data, and apps get them through the env.\n */\nexport const S3_ACCESS_KEY = 'cofactor-sandbox';\nexport const S3_SECRET_KEY = 'cofactor-sandbox-secret';\nconst S3_REGION = 'us-east-1';\n/** versitygw's health route. No bucket can be named `_health` (bucket names have no `_`). */\nconst S3_HEALTH_PATH = '/_health';\n\n/**\n * The fixed host fake-gcs-server is told is its public one (`-public-host`):\n * it serves XML-style `/<bucket>/<object>` routes only for that Host, so the\n * front rewrites every request's Host to it, whichever URL the browser used.\n */\nexport const GCS_PUBLIC_HOST = 'storage.cofactor.internal';\nexport const GCS_PROJECT = 'sandbox';\n\nconst SERVICE_DEFAULTS = { after_build: false, reload_on_prepare: false } as const;\n\n/** The implicit services that run the declared provider, started like any service that needs neither a build nor a prepare. */\nexport function objectStorageServices(provider: ObjectStorageProvider) {\n if (provider === 's3') {\n const env = [\n `ROOT_ACCESS_KEY_ID=${S3_ACCESS_KEY}`,\n `ROOT_SECRET_ACCESS_KEY=${S3_SECRET_KEY}`,\n `VGW_REGION=${S3_REGION}`,\n // Browsers upload through presigned URLs on the public port, another\n // origin; without this the preflight 403s (spike, 2026-10-02).\n `VGW_CORS_ALLOW_ORIGIN='*'`,\n `VGW_HEALTH=${S3_HEALTH_PATH}`,\n ].join(' ');\n return {\n [OBJECT_STORAGE_SERVICE]: {\n run: `${env} exec ${OBJECT_STORAGE_BINARY.s3} --port :${OBJECT_STORAGE_PORT.s3} posix ${OBJECT_STORAGE_DIR}`,\n health: { http: OBJECT_STORAGE_PORT.s3, path: S3_HEALTH_PATH },\n ...SERVICE_DEFAULTS,\n },\n };\n }\n return {\n [OBJECT_STORAGE_SERVICE]: {\n run:\n `exec ${OBJECT_STORAGE_BINARY.gcs} -scheme http -host 127.0.0.1 -port ${FAKE_GCS_PORT}` +\n ` -backend filesystem -filesystem-root ${OBJECT_STORAGE_DIR} -public-host ${GCS_PUBLIC_HOST}` +\n // Upload Location headers point at the front (the port clients use), not fake-gcs's own.\n ` -external-url http://127.0.0.1:${OBJECT_STORAGE_PORT.gcs}`,\n health: { http: FAKE_GCS_PORT, path: '/storage/v1/b' },\n ...SERVICE_DEFAULTS,\n },\n [OBJECT_STORAGE_FRONT_SERVICE]: {\n run: 'exec /usr/local/bin/cofactor-sandbox object-storage-front',\n health: { http: OBJECT_STORAGE_PORT.gcs, path: '/storage/v1/b' },\n ...SERVICE_DEFAULTS,\n },\n };\n}\n\n/** The standard client env for the declared provider; a definition's own env overrides it (runtime.ts `childEnv`). */\nexport function objectStorageEnv(storage: ObjectStorage | undefined): Record<string, string> {\n if (!storage) return {};\n if (storage.provider === 's3') {\n return {\n AWS_ENDPOINT_URL_S3: `http://127.0.0.1:${OBJECT_STORAGE_PORT.s3}`,\n AWS_ACCESS_KEY_ID: S3_ACCESS_KEY,\n AWS_SECRET_ACCESS_KEY: S3_SECRET_KEY,\n AWS_REGION: S3_REGION,\n };\n }\n return { STORAGE_EMULATOR_HOST: `http://127.0.0.1:${OBJECT_STORAGE_PORT.gcs}`, GOOGLE_CLOUD_PROJECT: GCS_PROJECT };\n}\n","/**\n * Syncing a working tree into a claimed sandbox: the wire contract between\n * `cofactor sandbox sync` (the CLI), the API that mints a session, and the\n * guest's `cofactor-sandbox sync-server` (sync-server.ts). Pure values and\n * schemas, so all three import the one definition.\n *\n * The CLI talks to the copy directly, over the preview edge, on the implicit\n * public `sync` port. Every request but `/healthz` carries a short-lived\n * token the API minted from the copy's own `sync.key` (its prepare input).\n *\n * @module sandbox-helper/sync-protocol\n * @see ~/.claude/plans/dirty-tree-sandboxes.md (approved 2026-10-13)\n */\nimport { createHash, createHmac, timingSafeEqual } from 'node:crypto';\nimport { z } from 'zod';\n\n/** The implicit public port the sync server answers on; reserved, never declared. */\nexport const SYNC_PORT_NAME = 'sync';\n/** The implicit service that runs the sync server; reserved, never declared. */\nexport const SYNC_SERVICE_NAME = 'cofactor-sync';\n/** The guest port behind `SYNC_PORT_NAME`; a declared port may not take it. */\nexport const SYNC_PORT = 7099;\n\n/** How long a sync token lives: one sync per session. */\nexport const SYNC_TOKEN_TTL_SECONDS = 15 * 60;\n/** Clock skew the guest tolerates between the API that minted a token and itself. */\nconst SYNC_TOKEN_SKEW_SECONDS = 60;\n\n/** The largest apply body the guest reads (`maxRequestBodySize`); the CLI splits a bigger sync into several applies. */\nexport const SYNC_MAX_APPLY_BYTES = 64 * 1024 * 1024;\n\n/** How often a `?build=1` stream sends a heartbeat: well inside the preview edge's 60 s idle timeout. */\nexport const SYNC_HEARTBEAT_MS = 20_000;\n\n/** A sync key: 32 random bytes as hex, one per prepared copy. */\nexport const syncKeySchema = z.string().regex(/^[0-9a-f]{64}$/);\n\nconst mac = (key: string, exp: number) =>\n createHmac('sha256', Buffer.from(key, 'hex')).update(`sync:${exp}`).digest('base64url');\n\n/** `<exp>.<base64url(HMAC-SHA256(key, \"sync:\" + exp))>`, `exp` in Unix seconds. */\nexport function mintSyncToken(key: string, exp: number): string {\n return `${exp}.${mac(key, exp)}`;\n}\n\n/** Why a token was refused, for the 401's body; never says anything about the key. */\nexport type SyncTokenRefusal = 'malformed' | 'expired' | 'too_long' | 'bad_mac';\n\n/**\n * Check a token against the copy's key in constant time. Refuses an expired\n * one, and one whose expiry is further out than a session ever lasts (a\n * token the API never minted).\n */\nexport function verifySyncToken(key: string, token: string, nowSeconds: number): SyncTokenRefusal | null {\n const match = /^(\\d{1,12})\\.([A-Za-z0-9_-]{43})$/.exec(token);\n if (!match) return 'malformed';\n const exp = Number(match[1]);\n if (exp <= nowSeconds) return 'expired';\n if (exp > nowSeconds + SYNC_TOKEN_TTL_SECONDS + SYNC_TOKEN_SKEW_SECONDS) return 'too_long';\n const expected = Buffer.from(mac(key, exp));\n const given = Buffer.from(match[2]!);\n return expected.length === given.length && timingSafeEqual(expected, given) ? null : 'bad_mac';\n}\n\n/** Git's blob id of `bytes`: what `git hash-object` prints, so the CLI can read it straight from an index. */\nexport function gitBlobId(bytes: Uint8Array): string {\n return createHash('sha1').update(`blob ${bytes.length}\\0`).update(bytes).digest('hex');\n}\n\n/**\n * A path relative to the sync root: no leading `/`, no empty, `.` or `..`\n * segment, no `.git` segment, no NUL. Everything the guest writes or deletes\n * passes this first.\n */\nexport function isSafeSyncPath(path: string): boolean {\n if (path === '' || path.length > 4096 || path.includes('\\0') || path.startsWith('/')) return false;\n return path.split('/').every((part) => part !== '' && part !== '.' && part !== '..' && part !== '.git');\n}\n\nconst syncPath = z.string().refine(isSafeSyncPath, 'must be a relative path with no \"..\", \".\" or \".git\" segment');\nconst blobId = z.string().regex(/^[0-9a-f]{40}$/);\n/** Only the executable bit matters, as in git: 0o755 or 0o644. */\nconst fileMode = z.union([z.literal(0o755), z.literal(0o644)]);\n\n/**\n * `POST /sync/plan`: every file the CLI would sync (with its size, so a copy\n * file of another size is needed without being read), and optionally the\n * directory (`--to`) the sync is scoped to. The whole list is one request\n * body, so a tree's list must fit in `SYNC_MAX_APPLY_BYTES`.\n */\nexport const syncPlanRequestSchema = z.strictObject({\n local: z.array(z.strictObject({ path: syncPath, blob: blobId, mode: fileMode, size: z.number().int().nonnegative() })),\n to: syncPath.optional(),\n});\nexport type SyncPlanRequest = z.infer<typeof syncPlanRequestSchema>;\n\n/**\n * The plan: `need` is each local path that is missing in the copy or differs\n * (content or executable bit). `copyOnly` is what the copy has that the CLI\n * didn't list: within `to`, one entry per file; over the whole root, one per\n * file except that a directory holding no local path is one entry ending in\n * `/` with its file count (e.g. `node_modules/`). Plan that directory as `to`\n * to list its files.\n */\nexport const syncPlanResponseSchema = z.strictObject({\n need: z.array(z.string()),\n copyOnly: z.array(z.strictObject({ path: z.string(), files: z.number().int().positive() })),\n});\nexport type SyncPlanResponse = z.infer<typeof syncPlanResponseSchema>;\n\n/**\n * `manifest.json` in an apply body: each file's path, blob id and mode, in the\n * order of the body's `files/<index>` entries, and the paths to delete. A\n * delete of a path the copy doesn't have is a no-op, so applying twice\n * converges.\n */\nexport const syncApplyManifestSchema = z.strictObject({\n files: z.array(z.strictObject({ path: syncPath, blob: blobId, mode: fileMode })),\n delete: z.array(syncPath),\n});\nexport type SyncApplyManifest = z.infer<typeof syncApplyManifestSchema>;\n\n/** The tar entry of the `index`th manifest file (names stay under ustar's 100 bytes whatever the path). */\nexport function syncApplyEntryName(index: number): string {\n return `files/${index}`;\n}\n\n/** What an apply did. */\nexport const syncApplyResultSchema = z.strictObject({\n written: z.number().int().nonnegative(),\n deleted: z.number().int().nonnegative(),\n ms: z.number(),\n});\nexport type SyncApplyResult = z.infer<typeof syncApplyResultSchema>;\n\n/**\n * One NDJSON line of `POST /sync/apply?build=1` (GitHub copies only): the\n * apply, then each build step as it starts and ends and the step's output,\n * then the build's end. A `heartbeat` keeps the preview edge's 60 s idle\n * timeout from closing a quiet step. The last line is `done` or `error`.\n */\nexport const syncBuildEventSchema = z.discriminatedUnion('type', [\n z.strictObject({ type: z.literal('applied'), result: syncApplyResultSchema }),\n z.strictObject({ type: z.literal('step'), name: z.string(), ran: z.boolean(), ms: z.number() }),\n z.strictObject({ type: z.literal('output'), text: z.string() }),\n z.strictObject({ type: z.literal('heartbeat') }),\n z.strictObject({ type: z.literal('done'), restarted: z.array(z.string()), ms: z.number() }),\n z.strictObject({ type: z.literal('error'), message: z.string() }),\n]);\nexport type SyncBuildEvent = z.infer<typeof syncBuildEventSchema>;\n","/**\n * `${params.NAME}` and `${secrets.NAME}` references inside an emulation\n * plugin's config, for plugins that accept them (`configReferences`, e.g.\n * `aws`): a seeded value can be a `{secret: true}` param or one of the\n * application's stored secrets without the value ever being written into the\n * definition.\n *\n * - `validate` checks every reference's shape and that a param is declared\n * (`emulationReferenceIssues`), and refuses references in other plugins,\n * whose domains and env contract the API computes from the raw config.\n * - The API refuses a prepare whose environment lacks a referenced secret\n * (`emulationSecretRefs`, `missingEmulationSecret`) and sends the references\n * unresolved.\n * - The sandbox resolves them at prepare (`emulationConfigFor`), with the same\n * params and secrets its services get, and hands the result only to the\n * emulator's process; prepare.json keeps the references.\n *\n * @module\n */\n\nimport { getPlugin } from '@chatsdet/emulation';\nimport type { Definition, DefinitionIssue, PrepareInput } from './manifest';\n\n/** Any `${...}`: each one inside a reference-accepting plugin's config must be a well-formed reference. */\nconst ANY_REF = /\\$\\{([^}]*)\\}/g;\nconst REFERENCE = /^(?:params\\.([a-z][a-z0-9_]*)|secrets\\.([A-Z_][A-Z0-9_]*))$/;\n/** What makes a string look like an attempted reference, in a plugin that does not accept them. */\nconst REFERENCE_LIKE = /\\$\\{(?:params|secrets)\\./;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Calls `visit` with every string value inside `value` (not object keys) and its dotted path. */\nfunction forEachString(value: unknown, path: string, visit: (text: string, path: string) => void): void {\n if (typeof value === 'string') visit(value, path);\n else if (Array.isArray(value)) value.forEach((item, index) => forEachString(item, `${path}[${index}]`, visit));\n else if (isRecord(value)) for (const [key, item] of Object.entries(value)) forEachString(item, `${path}.${key}`, visit);\n}\n\n/** `value` with every string value (not object keys) replaced by `replace(string)`. */\nfunction mapStrings(value: unknown, replace: (text: string) => string): unknown {\n if (typeof value === 'string') return replace(value);\n if (Array.isArray(value)) return value.map((item) => mapStrings(item, replace));\n if (isRecord(value)) return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, mapStrings(item, replace)]));\n return value;\n}\n\nfunction acceptsReferences(pluginId: string): boolean {\n return getPlugin(pluginId)?.configReferences === true;\n}\n\n/** Definition problems with references in the (raw) `emulation` block, given the declared `params`. */\nexport function emulationReferenceIssues(emulation: Record<string, unknown>, params: Record<string, unknown>): DefinitionIssue[] {\n const issues: DefinitionIssue[] = [];\n for (const [pluginId, pluginConfig] of Object.entries(emulation)) {\n const accepts = acceptsReferences(pluginId);\n forEachString(pluginConfig, `emulation.${pluginId}`, (text, path) => {\n if (!accepts) {\n if (REFERENCE_LIKE.test(text)) issues.push({ path, message: `the ${pluginId} emulator does not resolve \\${params.*} or \\${secrets.*}` });\n return;\n }\n for (const match of text.matchAll(ANY_REF)) {\n const reference = REFERENCE.exec(match[1]!);\n if (!reference) issues.push({ path, message: `\"${match[0]}\" is not \\${params.name} or \\${secrets.NAME}` });\n else if (reference[1] !== undefined && !(reference[1] in params)) {\n issues.push({ path, message: `references undeclared param \"${reference[1]}\"` });\n }\n }\n });\n }\n return issues;\n}\n\n/** Params referenced by emulation config values, including nested records and arrays. */\nexport function emulationParamRefs(definition: Definition): Set<string> {\n const names = new Set<string>();\n forEachString(definition.emulation, 'emulation', (text) => {\n for (const match of text.matchAll(ANY_REF)) {\n const param = REFERENCE.exec(match[1]!)?.[1];\n if (param !== undefined) names.add(param);\n }\n });\n return names;\n}\n\n/** The names of the application's stored secrets the definition's emulation configs reference, sorted. */\nexport function emulationSecretRefs(definition: Definition): string[] {\n const names = new Set<string>();\n for (const [pluginId, pluginConfig] of Object.entries(definition.emulation)) {\n if (!acceptsReferences(pluginId)) continue;\n forEachString(pluginConfig, pluginId, (text) => {\n for (const match of text.matchAll(ANY_REF)) {\n const secret = REFERENCE.exec(match[1]!)?.[2];\n if (secret !== undefined) names.add(secret);\n }\n });\n }\n return [...names].sort();\n}\n\n/** The message for an emulation config referencing a secret the application has not set for an environment. */\nexport function missingEmulationSecret(name: string, environment: string): string {\n return `emulation references the secret \"${name}\", which is not set for environment \"${environment}\"; set it with \\`cofactor sandbox secret set ${name} --application <application>\\``;\n}\n\n/**\n * The emulation instance config with every reference in a reference-accepting\n * plugin's config replaced by its value, in one pass (a substituted value is\n * never scanned again). Throws naming a secret that is not set: the API\n * refused such a prepare already, and this keeps the resolution total.\n */\nexport function resolveEmulationConfig(\n config: Record<string, unknown>,\n params: Record<string, string>,\n secrets: Record<string, string>,\n environment: string\n): Record<string, unknown> {\n if (!Array.isArray(config.plugins)) throw new Error('emulation config needs a \"plugins\" array');\n const resolve = (text: string) =>\n text.replace(ANY_REF, (whole, inner: string) => {\n const reference = REFERENCE.exec(inner);\n if (!reference) return whole;\n const [, param, secret] = reference;\n if (param !== undefined) {\n const value = params[param];\n if (value === undefined) throw new Error(`emulation references undeclared param \"${param}\"`);\n return value;\n }\n const value = secrets[secret!];\n if (value === undefined) throw new Error(missingEmulationSecret(secret!, environment));\n return value;\n });\n return {\n ...config,\n plugins: config.plugins.map((plugin: unknown) =>\n isRecord(plugin) && typeof plugin.pluginId === 'string' && acceptsReferences(plugin.pluginId)\n ? { ...plugin, config: mapStrings(plugin.config, resolve) }\n : plugin\n ),\n };\n}\n\n/**\n * The emulator config a prepare hands the emulator: the prepare input's\n * emulation config resolved with every param (the definition's layer values\n * under this prepare's own) and the environment's secrets. Each resolved\n * plugin config is checked against the plugin's schema again (a reference\n * that resolves to, say, non-base64 KMS plaintext), so prepare fails here\n * naming the field instead of the emulator failing to start.\n */\nexport function emulationConfigFor(\n emulation: NonNullable<PrepareInput['emulation']>,\n input: Pick<PrepareInput, 'params' | 'secrets' | 'environment'>,\n layerParamValues: Record<string, string>\n): Record<string, unknown> {\n const resolved = resolveEmulationConfig(emulation.config, { ...layerParamValues, ...input.params }, input.secrets, input.environment);\n for (const plugin of resolved.plugins as unknown[]) {\n if (!isRecord(plugin) || typeof plugin.pluginId !== 'string' || !acceptsReferences(plugin.pluginId)) continue;\n const issue = getPlugin(plugin.pluginId)?.configSchema?.safeParse(plugin.config).error?.issues[0];\n if (issue) {\n throw new Error(`emulation.${[plugin.pluginId, ...issue.path.map(String)].join('.')}: ${issue.message} (once its references are resolved)`);\n }\n }\n return resolved;\n}\n","/**\n * `cofactor sandbox push`: deliver an application's sandboxes as a built\n * image, with no repository access. The team's image (any glibc\n * linux/amd64 image with a WORKDIR) gets Cofactor's layers on top — its\n * sandbox helper as the entrypoint, the declared object storage server —\n * named by digest and never uploaded, and one small layer of its own: the\n * application's `cofactor.sandbox.yaml` and the image's ENV and WORKDIR at\n * /cofactor. The image goes to Cofactor as content-addressed blobs read\n * straight out of `docker save`, and only the ones Cofactor doesn't hold yet\n * are uploaded, so a re-push sends the layers that changed. Cofactor imports\n * it into the sandbox fleet, where it boots until its services are healthy;\n * the definition's environments then sync onto the application.\n *\n * @module\n * @see specs/pending/sandboxes-v2-incremental-push.md\n */\n\nimport process from 'node:process';\nimport { spawnSync } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { createReadStream, createWriteStream, mkdtempSync, type ReadStream, readFileSync, rmSync } from 'node:fs';\nimport { type FileHandle, open } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { pipeline } from 'node:stream/promises';\nimport { createGunzip } from 'node:zlib';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, getArgValues } from './cli-helpers.js';\nimport { writeRawOutput } from './brand.js';\nimport { resolveOrCreateSandboxApplication } from './environment.js';\nimport type { PushEntry } from './sandbox-v2.js';\nimport { syncabilityLineOrSkipped } from './sandbox-push-syncable.js';\nimport {\n type DefinitionIssue,\n IMAGE_CONFIG_FILE,\n IMAGE_DEFINITION_FILE,\n type ImageConfig,\n imageConfigSchema,\n type ObjectStorageProvider,\n validateDefinition,\n} from '@chatsdet/sandbox-helper/manifest';\nimport {\n type ImageBlob,\n type ImageConfigJson,\n MAX_BLOB_BYTES,\n tarEntries,\n tarOf,\n withSandboxLayers,\n} from '@chatsdet/sandbox-helper/image-archive';\n\nconst USAGE = [\n 'Usage: cofactor sandbox push --application <name|id> <image> [--definition <file>] [--tag <tag>]... [--wait] [--json]',\n '',\n 'Tag main builds `main` (or `nightly`): once an application has a push with either tag, its head is the',\n 'newest such push, and only those runs move the visual-review baseline. Other pushes are claimed with --at.',\n].join('\\n');\n\n/** Blobs uploaded at once. */\nconst UPLOAD_CONCURRENCY = 4;\nconst UPLOAD_ATTEMPTS = 3;\nconst HASH_CHUNK_BYTES = 8 * 1024 * 1024;\n\n/** How long `--wait` follows an import (it boots the image until healthy; a big image takes a while). */\nconst IMPORT_TIMEOUT_MS = 50 * 60_000;\nconst IMPORT_POLL_MS = 5_000;\n\ntype ApiResult<T> = { ok: boolean; error?: string; code?: string; issues?: DefinitionIssue[]; data: T };\n\n/** Why a push stopped; printed once, after the temporary files and image are cleaned up. */\nclass PushError extends Error {\n constructor(\n message: string,\n readonly issues: DefinitionIssue[] = []\n ) {\n super(message);\n }\n}\n\nfunction fail(message: string, issues?: DefinitionIssue[]): never {\n throw new PushError(message, issues);\n}\n\n/** Run docker, failing with its stderr. `quiet` keeps its progress off the terminal (for --json). */\nfunction docker(args: string[], options: { quiet: boolean }): string {\n const result = spawnSync('docker', args, {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', options.quiet ? 'pipe' : 'inherit'],\n maxBuffer: 64 * 1024 * 1024,\n });\n if (result.error) fail(`could not run docker (${result.error.message}); is Docker installed and running?`);\n if (result.status !== 0) fail(`docker ${args.slice(0, 2).join(' ')} failed:\\n${result.stderr ?? ''}`.trimEnd());\n return result.stdout;\n}\n\ntype InspectedImage = {\n Architecture: string;\n Os: string;\n Config: { WorkingDir?: string; Env?: string[] | null; User?: string };\n};\n\n/**\n * What the image's own config would have applied when run: its WORKDIR and\n * ENV, which an import into the fleet otherwise drops. Refuses an image the\n * fleet cannot run.\n */\nfunction imageConfigOf(image: string): ImageConfig {\n const result = spawnSync('docker', ['image', 'inspect', image], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });\n if (result.error) fail(`could not run docker (${result.error.message}); is Docker installed and running?`);\n const [inspected] = result.status === 0 ? (JSON.parse(result.stdout) as InspectedImage[]) : [];\n if (!inspected) fail(`Docker has no local image ${image}: build or pull it first`);\n if (inspected.Os !== 'linux' || inspected.Architecture !== 'amd64') {\n fail(\n `${image} is ${inspected.Os}/${inspected.Architecture}; sandboxes run linux/amd64. Rebuild it with\\n` +\n ` docker buildx build --platform linux/amd64 -t ${image} --load <context>`\n );\n }\n // The sandbox boots as root and drops to uid 1000 itself. An image ending on\n // another USER failed to boot only after its whole upload (seen 2026-10-06:\n // EACCES on /etc/cofactor), so it is refused before the upload.\n const user = inspected.Config.User ?? '';\n // The uid is what matters (a group after `:` doesn't change it).\n if (!['', '0', 'root'].includes(user.split(':')[0]!)) {\n fail(\n `${image} runs as USER ${user}; a sandbox image must leave USER as root (the sandbox drops to uid 1000 itself). ` +\n 'Remove the final `USER` line from the Dockerfile, or end it with `USER root`.'\n );\n }\n const env = Object.fromEntries(\n (inspected.Config.Env ?? []).map((entry) => {\n const separator = entry.indexOf('=');\n return [entry.slice(0, separator), entry.slice(separator + 1)];\n })\n );\n const parsed = imageConfigSchema.safeParse({ workdir: inspected.Config.WorkingDir ?? '', env });\n if (!parsed.success) {\n const workdir = inspected.Config.WorkingDir || '(none)';\n fail(\n `${image}'s WORKDIR ${workdir} can't be used: ${parsed.error.issues[0]?.message ?? 'invalid'}. ` +\n 'Set one for your app in its Dockerfile (e.g. `WORKDIR /app`): services, prepare commands and actions run from it, ' +\n 'and the sandbox makes it writable by the app.'\n );\n }\n return parsed.data;\n}\n\n/** A value for a shell command line, quoted only when it needs to be. */\nfunction shellWord(value: string): string {\n return /^[\\w@%+=:,./-]+$/.test(value) ? value : `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n}\n\nasync function apiOrFail<T>(result: Promise<ApiResult<T>>): Promise<T> {\n const res = await result;\n if (!res.ok) fail(res.error ?? 'unknown error', res.issues);\n return res.data;\n}\n\nconst mib = (bytes: number) => `${(bytes / 1024 / 1024).toFixed(bytes < 10 * 1024 * 1024 ? 1 : 0)} MB`;\n\n/**\n * `size` bytes of the saved archive from `offset`, read at that position.\n * Not `openAsBlob`: Node's (v22) wraps a file's size at 4 GiB, and its\n * slices past that read nothing, so a `docker save` over 4 GiB lost its\n * manifest.json, which comes last (seen 2026-10-22). Short only at the\n * file's end, which `tarEntries` reports as a truncated archive; every entry\n * it returns lies before the archive's end block, so reading one is never short.\n */\nasync function readAt(file: FileHandle, offset: number, size: number): Promise<Uint8Array> {\n const bytes = new Uint8Array(size);\n for (let at = 0; at < size; ) {\n const { bytesRead } = await file.read(bytes, at, size - at, offset + at);\n if (bytesRead === 0) return bytes.subarray(0, at);\n at += bytesRead;\n }\n return bytes;\n}\n\n/**\n * `sha256:<hex>` of a range of the saved archive, read a chunk at a time by\n * position. Not a stream: under Bun, streams of a file-backed blob never\n * settled when several ran at once, and the process exited 0 mid-push (seen\n * 2026-10-04).\n */\nasync function digestOf(file: FileHandle, offset: number, size: number): Promise<string> {\n const hash = createHash('sha256');\n for (let at = 0; at < size; at += HASH_CHUNK_BYTES) {\n hash.update(await readAt(file, offset + at, Math.min(HASH_CHUNK_BYTES, size - at)));\n }\n return `sha256:${hash.digest('hex')}`;\n}\n\n/**\n * A blob of the image as the API names it, and a fresh request body for\n * uploading it (a retry needs a new one).\n */\ntype Part = ImageBlob & { body: () => Uint8Array<ArrayBuffer> | ReadStream };\n\n/** A blob held in memory: the config, the push's own layer. */\nfunction partOf(bytes: Uint8Array<ArrayBuffer>): Part {\n return { digest: `sha256:${createHash('sha256').update(bytes).digest('hex')}`, size: bytes.length, body: () => bytes };\n}\n\n/**\n * PUT a blob to its presigned URL, again after a pause when the network or\n * storage fails. A refusal (4xx: a checksum mismatch, an expired URL) won't\n * change on a retry; a push run again uploads only what is still missing.\n */\nasync function putBlob(url: string, headers: Record<string, string>, part: Part): Promise<void> {\n const digest = part.digest;\n for (let attempt = 1; ; attempt++) {\n let response: Response;\n try {\n // A length, not chunked: S3 refuses a chunked presigned PUT.\n const init: RequestInit & { duplex: 'half' } = {\n method: 'PUT',\n headers: { ...headers, 'content-length': String(part.size) },\n body: part.body() as BodyInit,\n duplex: 'half',\n };\n response = await fetch(url, init);\n } catch (error) {\n if (attempt >= UPLOAD_ATTEMPTS) throw error;\n await new Promise((resolve) => setTimeout(resolve, 2_000 * attempt));\n continue;\n }\n if (response.ok) return;\n const detail = `${response.status}: ${(await response.text()).slice(0, 300)}`;\n if (response.status < 500 || attempt >= UPLOAD_ATTEMPTS) {\n fail(`uploading ${digest} was refused (HTTP ${detail}); run the push again to upload what is still missing`);\n }\n await new Promise((resolve) => setTimeout(resolve, 2_000 * attempt));\n }\n}\n\n/**\n * The image's config and layers as `docker save` wrote them, from its\n * manifest.json (Docker writes one in its OCI layout too). Layer paths are\n * whatever the layout uses; each is named by the digest of its bytes.\n */\nasync function savedImage(archive: string) {\n const file = await open(archive);\n try {\n const entries = await tarEntries((offset, length) => readAt(file, offset, length)).catch((error: unknown) =>\n fail(`reading the saved image: ${error instanceof Error ? error.message : String(error)}`)\n );\n const byName = new Map(entries.map((entry) => [entry.name.replace(/^\\.\\//, ''), entry]));\n const entryOf = (name: string) => {\n const entry = byName.get(name);\n if (!entry) fail(`the saved image has no ${name}; is this a \\`docker save\\` archive?`);\n return entry;\n };\n const json = async (name: string) => {\n const entry = entryOf(name);\n return JSON.parse(new TextDecoder().decode(await readAt(file, entry.offset, entry.size))) as unknown;\n };\n // A layer uploads straight from its range of the archive: not a blob\n // slice, which under Bun hangs with several uploads at once (seen\n // 2026-10-04), and under Node reads nothing past 4 GiB (see `readAt`).\n const layerOf = async (name: string): Promise<Part> => {\n const entry = entryOf(name);\n // Before hashing it: a layer too large to upload fails at once, not after a multi-GB read.\n const tooLarge = (bytes: number) => fail(`a layer of the image is ${(bytes / 1024 ** 3).toFixed(1)} GB; a push takes at most 5 GB per layer. Slim the image.`);\n if (entry.size > MAX_BLOB_BYTES) tooLarge(entry.size);\n const range = { start: entry.offset, end: entry.offset + entry.size - 1 };\n // Docker 29 saves from its containerd image store with gzip-compressed layers; Cofactor takes the\n // uncompressed tar the image config's diff_ids name. Unpack beside the archive (removed with it); this\n // needs disk for every unpacked layer until the push ends.\n const [first, second] = await readAt(file, entry.offset, 2);\n if (first === 0x1f && second === 0x8b) {\n const unpacked = join(dirname(archive), `layer-${entry.offset}.tar`);\n await pipeline(createReadStream(archive, range), createGunzip(), createWriteStream(unpacked)).catch((error: unknown) =>\n fail(`unpacking a compressed layer of the image: ${error instanceof Error ? error.message : String(error)}`)\n );\n const plain = await open(unpacked);\n try {\n const { size } = await plain.stat();\n if (size > MAX_BLOB_BYTES) tooLarge(size);\n return { digest: await digestOf(plain, 0, size), size, body: () => createReadStream(unpacked) };\n } finally {\n await plain.close();\n }\n }\n return { digest: await digestOf(file, entry.offset, entry.size), size: entry.size, body: () => createReadStream(archive, range) };\n };\n const [manifest] = (await json('manifest.json')) as { Config: string; Layers: string[] }[];\n if (!manifest) fail('the saved image lists no image');\n // One at a time: see `digestOf`.\n const layers: Part[] = [];\n for (const name of manifest.Layers) layers.push(await layerOf(name));\n return { config: (await json(manifest.Config)) as ImageConfigJson, layers };\n } finally {\n await file.close();\n }\n}\n\n/**\n * The image a push sends, from the team's saved image: its layers, then\n * Cofactor's (`cofactorLayers`, by digest), then the push's own layer with\n * what the helper reads from /cofactor; and its config, rewritten to name\n * those layers and run the helper. `blobs` holds the bytes of every blob the\n * push may have to upload (all but Cofactor's).\n */\nexport async function pushedImage(\n archive: string,\n cofactorLayers: ImageBlob[],\n definitionYaml: string,\n config: ImageConfig\n): Promise<{ config: ImageBlob; layers: ImageBlob[]; blobs: Map<string, Part> }> {\n const saved = await savedImage(archive);\n const own = partOf(\n tarOf([\n { name: IMAGE_DEFINITION_FILE.slice(1), data: new TextEncoder().encode(definitionYaml) },\n { name: IMAGE_CONFIG_FILE.slice(1), data: new TextEncoder().encode(JSON.stringify(config)) },\n ])\n );\n const added = [...cofactorLayers, own];\n const pushed = withSandboxLayers(saved.config, added, new Date().toISOString());\n const imageConfig = partOf(new TextEncoder().encode(JSON.stringify(pushed)));\n const blob = ({ digest, size }: ImageBlob) => ({ digest, size });\n return {\n config: blob(imageConfig),\n layers: [...saved.layers, ...added].map(blob),\n blobs: new Map([imageConfig, ...saved.layers, own].map((part) => [part.digest, part])),\n };\n}\n\n/** `cofactor sandbox push --application A <image> [--definition F] [--tag T]... [--wait] [--json]`. */\nexport async function handleSandboxPush(argv: string[], apiUrl: string, token: string): Promise<void> {\n try {\n await push(argv, apiUrl, token);\n } catch (error) {\n if (!(error instanceof PushError)) throw error;\n console.error(`Error: ${error.message}`);\n for (const issue of error.issues) console.error(` ${issue.path || '(root)'}: ${issue.message}`);\n process.exit(1);\n }\n}\n\nasync function push(argv: string[], apiUrl: string, token: string): Promise<void> {\n const valueFlags = new Set(['--application', '--property', '--definition', '--tag', '--env', '--org', '--token', '--api-url', '--app-url']);\n const positional = argv.filter((arg, i) => !arg.startsWith('-') && !valueFlags.has(argv[i - 1] ?? ''));\n const image = positional[0];\n if (!image) fail(`an image is required\\n${USAGE}`);\n const definitionFile = getArgValue(argv, '--definition') ?? './cofactor.sandbox.yaml';\n const tags = getArgValues(argv, '--tag');\n // The server's rule, checked before a multi-minute build.\n const badTag = tags.find((tag) => !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(tag));\n if (badTag !== undefined) fail(`--tag ${badTag}: use letters, digits, '.', '_' and '-' (at most 64, starting with a letter or digit)`);\n if (tags.length > 10) fail('a push takes at most 10 tags');\n const wait = hasFlag(argv, '--wait');\n const json = hasFlag(argv, '--json');\n const log = (line: string) => (json ? console.error(line) : console.log(line));\n\n let definitionYaml: string;\n try {\n definitionYaml = readFileSync(definitionFile, 'utf8');\n } catch (error) {\n fail(`reading ${definitionFile}: ${error instanceof Error ? error.message : String(error)}`);\n }\n const { definition, issues } = validateDefinition(definitionYaml, 'upload');\n if (!definition || issues.length > 0) fail(`${definitionFile} is not a valid definition for pushed images:`, issues);\n const storageProvider = definition.object_storage?.provider;\n const applicationId = await resolveOrCreateSandboxApplication(argv, apiUrl, token);\n const config = imageConfigOf(image);\n // Advisory only: whether `cofactor sandbox sync` can write into this image. Never stops the push.\n log(syncabilityLineOrSkipped({ image, workdir: config.workdir, definitionFile }));\n\n const work = mkdtempSync(join(tmpdir(), 'cofactor-push-'));\n const cleanUp = () => rmSync(work, { recursive: true, force: true });\n // A push interrupted mid-save or mid-upload would otherwise leave a multi-GB archive behind.\n const interrupted = (signal: NodeJS.Signals) => {\n cleanUp();\n process.exit(signal === 'SIGINT' ? 130 : 143);\n };\n process.once('SIGINT', interrupted);\n process.once('SIGTERM', interrupted);\n // Red until the push is through: if the event loop ever drains mid-push again\n // (it did under Bun, 2026-10-04), the process exits 1, not a silent 0.\n process.exitCode = 1;\n try {\n // Cofactor's layers for this version, by digest: added to the image, never uploaded.\n const ours = await apiOrFail(\n apiRequest<ApiResult<{ platformVersion: number; helper?: ImageBlob; objectStorage: Record<ObjectStorageProvider, ImageBlob> }>>(\n apiUrl,\n token,\n 'GET',\n '/org/sandboxes-v2/helper-layer'\n )\n );\n // A Cofactor deployed before incremental pushes answers with download URLs instead: the CLI\n // ships to npm ahead of a Cofactor's deploy (prod ran hundreds of commits behind, 2026-10-02).\n if (!ours.helper) fail('this Cofactor takes pushes from an older cofactor CLI; use the version it ships with');\n const cofactorLayers = [ours.helper, ...(storageProvider ? [ours.objectStorage[storageProvider]] : [])];\n\n const archive = join(work, 'image.tar');\n log('Saving the image...');\n docker(['save', '--output', archive, image], { quiet: json });\n const pushing = await pushedImage(archive, cofactorLayers, definitionYaml, config);\n const { layers } = pushing;\n\n const created = await apiOrFail(\n apiRequest<ApiResult<{ id: string; uploads: { digest: string; url: string; headers: Record<string, string> }[] }>>(\n apiUrl,\n token,\n 'POST',\n `/org/applications/${applicationId}/sandbox/uploads`,\n { definitionYaml, platformVersion: ours.platformVersion, tags, image: { config: pushing.config, layers } }\n )\n );\n const partsByDigest = pushing.blobs;\n const uploadBytes = created.uploads.reduce((total, upload) => total + (partsByDigest.get(upload.digest)?.size ?? 0), 0);\n const imageBytes = layers.reduce((total, layer) => total + layer.size, 0);\n log(`Pushing ${created.id}: uploading ${created.uploads.length} of ${layers.length + 1} blobs (${mib(uploadBytes)}); ${mib(imageBytes - uploadBytes)} already in Cofactor`);\n const queue = [...created.uploads];\n let sent = 0;\n await Promise.all(\n Array.from({ length: UPLOAD_CONCURRENCY }, async () => {\n for (let next = queue.shift(); next; next = queue.shift()) {\n const part = partsByDigest.get(next.digest);\n if (!part) fail(`Cofactor asked for ${next.digest}, which this image doesn't have`);\n await putBlob(next.url, next.headers, part);\n sent += part.size;\n if (part.size > 10 * 1024 * 1024) log(` ${mib(sent)} of ${mib(uploadBytes)}`);\n }\n })\n );\n rmSync(archive);\n let pushed = await apiOrFail(\n apiRequest<ApiResult<PushEntry>>(\n apiUrl,\n token,\n 'POST',\n `/org/applications/${applicationId}/sandbox/uploads/${created.id}/complete`\n )\n );\n\n if (wait) {\n log('Importing (Cofactor boots the image until its services are healthy)...');\n const deadline = Date.now() + IMPORT_TIMEOUT_MS;\n const importStarted = Date.now();\n let reported = importStarted;\n while ((pushed.status === 'importing' || pushed.status === 'uploading') && Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, IMPORT_POLL_MS));\n // A large image imports for minutes: say it is still going.\n if (Date.now() - reported >= 60_000) {\n reported = Date.now();\n log(` still importing (${Math.round((reported - importStarted) / 60_000)} min)`);\n }\n pushed = await apiOrFail(\n apiRequest<ApiResult<PushEntry>>(apiUrl, token, 'GET', `/org/applications/${applicationId}/sandbox/uploads/${created.id}`)\n );\n }\n }\n const uploaded = { blobs: created.uploads.length, of: layers.length + 1, bytes: uploadBytes, reusedBytes: imageBytes - uploadBytes };\n\n const application = shellWord(getArgValue(argv, '--application') ?? getArgValue(argv, '--property') ?? applicationId);\n // The dispatcher strips the global options from `argv`; the hints must carry them.\n const target = ['--env', '--org']\n .map((flag) => {\n const value = getArgValue(process.argv, flag);\n return value ? ` ${flag} ${shellWord(value)}` : '';\n })\n .join('');\n if (json) {\n writeRawOutput(JSON.stringify({ ...pushed, uploaded }, null, 2));\n } else {\n console.log(`Push ${pushed.id}: ${pushed.status}${pushed.tags.length > 0 ? ` [${pushed.tags.join(', ')}]` : ''}`);\n if (pushed.status === 'ready') {\n console.log(` Claim it: cofactor sandbox claim --application ${application} --environment default --wait${target}`);\n } else if (pushed.status !== 'failed') {\n console.log(` Importing; follow it with: cofactor sandbox envs --application ${application}${target}`);\n }\n }\n if (pushed.status === 'failed') fail(`push ${pushed.id} failed:\\n${pushed.error ?? 'no reason given'}`);\n process.exitCode = 0;\n } finally {\n process.off('SIGINT', interrupted);\n process.off('SIGTERM', interrupted);\n cleanUp();\n }\n}\n","/**\n * Whether a pushed image can take `cofactor sandbox sync`: the rule is that a\n * syncable image has the definition file at its WORKDIR (`COPY . .` gives you\n * that), so the definition directory's files sit at WORKDIR in the same\n * layout. `push` checks it on the local image and reports; it never fails a\n * push.\n *\n * The anchor is the user's own copy at `<WORKDIR>/cofactor.sandbox.yaml`, never\n * the copy `push` itself adds under `/cofactor`. A sample of the directory's\n * tracked files then says how current the image is: one that isn't in the\n * image is fine (compiled sources aren't shipped), one that differs means the\n * image is older than the working tree, which is fine too.\n *\n * @module\n */\nimport { spawnSync } from 'node:child_process';\nimport { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { gitBlobId } from '@chatsdet/sandbox-helper/sync-protocol';\n\nexport type DockerRun = (args: string[]) => { status: number | null; stdout: string; stderr: string };\n\nconst realDocker: DockerRun = (args) => {\n const result = spawnSync('docker', args, { encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });\n if (result.error) return { status: null, stdout: '', stderr: result.error.message };\n return { status: result.status, stdout: result.stdout, stderr: result.stderr };\n};\n\n/** How many tracked files the check samples. */\nconst SAMPLE = 20;\n\n/** Up to `SAMPLE` paths spread evenly over `paths` (sorted), so one big directory doesn't fill the sample. */\nexport function sampleOf(paths: string[]): string[] {\n const sorted = [...paths].sort();\n if (sorted.length <= SAMPLE) return sorted;\n return Array.from({ length: SAMPLE }, (_, i) => sorted[Math.floor((i * sorted.length) / SAMPLE)]!);\n}\n\nexport const SYNCABLE_RULE = 'a syncable image has your definition file at its WORKDIR, as `COPY . .` gives you';\n\n/**\n * The one line `push` prints. `definitionDir` is the directory holding the\n * definition being pushed; `definitionFile` its path there.\n */\nexport function syncabilityLine(params: {\n image: string;\n workdir: string;\n definitionDir: string;\n definitionFile: string;\n docker?: DockerRun;\n}): string {\n const docker = params.docker ?? realDocker;\n const git = spawnSync('git', ['ls-files', '-s', '-z'], { cwd: params.definitionDir, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });\n if (git.status !== 0) return 'Sync: not checked (the definition is not in a git repository).';\n const tracked = git.stdout\n .split('\\0')\n .flatMap((entry) => /^(100644|100755) [0-9a-f]+ \\d\\t(.*)$/s.exec(entry)?.[2] ?? [])\n .filter((path) => path !== 'cofactor.sandbox.yaml')\n // A tracked file deleted in the working tree has nothing to compare.\n .filter((path) => existsSync(join(params.definitionDir, path)));\n\n const temp = mkdtempSync(join(tmpdir(), 'cofactor-syncable-'));\n const created = docker(['create', params.image]);\n if (created.status !== 0) {\n rmSync(temp, { recursive: true, force: true });\n return `Sync: not checked (docker create failed: ${created.stderr.trim()}).`;\n }\n const container = created.stdout.trim();\n let copies = 0;\n try {\n /** The image's file at WORKDIR/`path` (a symlink followed inside the image), or null when there is no file there. */\n const copyOut = (path: string): Uint8Array | null => {\n const target = join(temp, String(copies++));\n if (docker(['cp', '-L', `${container}:${params.workdir}/${path}`, target]).status !== 0) return null;\n // A directory at that path is not the file.\n return statSync(target).isFile() ? readFileSync(target) : null;\n };\n const anchor = copyOut('cofactor.sandbox.yaml');\n if (!anchor) {\n return `Sync: not syncable: cofactor.sandbox.yaml isn't at ${params.workdir}/cofactor.sandbox.yaml (${SYNCABLE_RULE}).`;\n }\n const sample = sampleOf(tracked);\n let differ = 0;\n let missing = 0;\n for (const path of sample) {\n const bytes = copyOut(path);\n if (!bytes) missing += 1;\n else if (gitBlobId(bytes) !== gitBlobId(readFileSync(join(params.definitionDir, path)))) differ += 1;\n }\n const anchorOlder = gitBlobId(anchor) !== gitBlobId(readFileSync(params.definitionFile));\n const notes = [\n ...(anchorOlder || differ > 0 ? ['the image is older than your working tree, which is fine'] : []),\n ...(missing > 0 ? [`${missing} of ${sample.length} sampled files aren't in the image (fine for sources it doesn't ship)`] : []),\n ];\n return `Sync: syncable${notes.length > 0 ? ` (${notes.join('; ')})` : ''}.`;\n } finally {\n docker(['rm', container]);\n rmSync(temp, { recursive: true, force: true });\n }\n}\n\n/**\n * `syncabilityLine` for the definition at `definitionFile`, as `push` prints\n * it. The check is advice the plan says never stops a push, so a failure of\n * the check itself (docker, git, a file it can't read) is reported as \"not\n * checked\" instead of failing the push.\n */\nexport function syncabilityLineOrSkipped(params: { image: string; workdir: string; definitionFile: string; docker?: DockerRun }): string {\n try {\n const definitionFile = resolve(params.definitionFile);\n return syncabilityLine({ ...params, definitionFile, definitionDir: dirname(definitionFile) });\n } catch (error) {\n return `Sync: not checked (${error instanceof Error ? error.message : String(error)}).`;\n }\n}\n","/**\n * A pushed image as content-addressed blobs, and the small tar reader and\n * writer the push and sync share.\n *\n * `cofactor sandbox push` reads the layers out of a `docker save` archive,\n * uploads only the blobs Cofactor doesn't hold yet, and describes the image\n * as an {@link ImageBlobs}: its config and its layers in order. The API's\n * import hands Blackcat those blobs by URL; Blackcat's node reads them and\n * loads them as the `docker save` archive they make up.\n *\n * @module sandbox-helper/image-archive\n * @see specs/pending/sandboxes-v2-incremental-push.md\n */\nimport { z } from 'zod';\n\n/** One presigned PUT carries a blob, and S3 takes at most 5 GB in one. */\nexport const MAX_BLOB_BYTES = 5 * 1024 ** 3;\n\n/** A blob by content: `sha256:<hex>` of its bytes, and their length. */\nexport const ImageBlob = z.object({\n digest: z.string().regex(/^sha256:[0-9a-f]{64}$/),\n size: z.number().int().nonnegative(),\n});\nexport type ImageBlob = z.infer<typeof ImageBlob>;\n\n/** An image: its config blob, and its layer blobs bottom to top. */\nexport const ImageBlobs = z.object({\n config: ImageBlob,\n // Docker allows at most 127 layers; each costs a storage lookup per push.\n layers: z.array(ImageBlob).min(1).max(128),\n});\nexport type ImageBlobs = z.infer<typeof ImageBlobs>;\n\n/**\n * An image config as Docker writes it, in the parts a push rewrites: the\n * layer diff ids, the history, and the run settings. Everything else is kept\n * as is.\n */\nexport type ImageConfigJson = {\n config?: Record<string, unknown>;\n rootfs: { type: string; diff_ids: string[] };\n history?: Record<string, unknown>[];\n} & Record<string, unknown>;\n\n/**\n * A pushed image's config: the team image's own config with `added` layers on\n * top (Cofactor's, then the push's own), booting Cofactor's helper instead of\n * the image's entrypoint. Each added layer is an uncompressed tar, so its\n * digest is also its diff id. `cofactor sandbox push` makes a push's config\n * with this, and the API makes an upgraded push's (`withoutSandboxLayers`).\n */\nexport function withSandboxLayers(team: ImageConfigJson, added: ImageBlob[], created: string): ImageConfigJson {\n return {\n ...team,\n rootfs: { ...team.rootfs, diff_ids: [...team.rootfs.diff_ids, ...added.map((layer) => layer.digest)] },\n history: [...(team.history ?? []), ...added.map(() => ({ created, created_by: 'cofactor sandbox push' }))],\n config: { ...team.config, Entrypoint: ['/usr/local/bin/cofactor-sandbox', 'boot'], Cmd: [] },\n };\n}\n\n/**\n * The team image's config inside a pushed one: the last `added` layers (the\n * ones {@link withSandboxLayers} put on) and their history entries removed.\n * Its run settings stay the helper's, which {@link withSandboxLayers} sets again.\n */\nexport function withoutSandboxLayers(pushed: ImageConfigJson, added: number): ImageConfigJson {\n const history = pushed.history ?? [];\n if (pushed.rootfs.diff_ids.length <= added || history.length < added) {\n throw new Error(`the image config has fewer than ${added} layers Cofactor added`);\n }\n return {\n ...pushed,\n rootfs: { ...pushed.rootfs, diff_ids: pushed.rootfs.diff_ids.slice(0, -added) },\n history: history.slice(0, -added),\n };\n}\n\nconst BLOCK = 512;\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** A ustar header for a regular file (names here are short: a digest and a suffix). */\nfunction tarHeader(name: string, size: number, mode = 0o644): Uint8Array {\n if (encoder.encode(name).length > 100) throw new Error(`tar entry name too long: ${name}`);\n const header = new Uint8Array(BLOCK);\n const put = (offset: number, length: number, value: string) => header.set(encoder.encode(value).slice(0, length), offset);\n const octal = (offset: number, length: number, value: number) =>\n put(offset, length, `${value.toString(8).padStart(length - 1, '0')}\\0`);\n put(0, 100, name);\n octal(100, 8, mode);\n octal(108, 8, 0);\n octal(116, 8, 0);\n // Sizes past 8 GiB need the base-256 form; tarOf writes small files.\n octal(124, 12, size);\n octal(136, 12, 0);\n put(148, 8, ' ');\n put(156, 1, '0');\n put(257, 6, 'ustar\\0');\n put(263, 2, '00');\n const checksum = header.reduce((sum, byte) => sum + byte, 0);\n put(148, 8, `${checksum.toString(8).padStart(6, '0')}\\0 `);\n return header;\n}\n\n/** The zero bytes that round an entry of `size` up to a whole block. */\nfunction tarPadding(size: number): Uint8Array {\n return new Uint8Array((BLOCK - (size % BLOCK)) % BLOCK);\n}\n\n/** Two zero blocks: the end of an archive. */\nconst TAR_END = new Uint8Array(BLOCK * 2);\n\n/** A complete tar of small in-memory files, in order. */\nexport function tarOf(files: { name: string; data: Uint8Array; mode?: number }[]): Uint8Array<ArrayBuffer> {\n const parts = files.flatMap((file) => [tarHeader(file.name, file.data.length, file.mode), file.data, tarPadding(file.data.length)]);\n parts.push(TAR_END);\n const out = new Uint8Array(parts.reduce((total, part) => total + part.length, 0));\n let at = 0;\n for (const part of parts) {\n out.set(part, at);\n at += part.length;\n }\n return out;\n}\n\ntype TarEntry = { name: string; offset: number; size: number };\n\nconst field = (block: Uint8Array, offset: number, length: number) =>\n decoder.decode(block.subarray(offset, offset + length)).replace(/\\0.*$/s, '');\n\n/**\n * The regular files of a tar on disk, with where each one's bytes are, read\n * header by header so a multi-GB archive is never held in memory. Follows the\n * pax and GNU long-name records `docker save` may write. The archive ends at\n * its zero block; running out of bytes before it means the archive (or the\n * reader) came up short, and fails rather than returning the entries read so\n * far: a reader that wrapped at 4 GiB once lost a `docker save`'s\n * manifest.json, which comes last (seen 2026-10-22).\n */\nexport async function tarEntries(read: (offset: number, length: number) => Promise<Uint8Array>): Promise<TarEntry[]> {\n const entries: TarEntry[] = [];\n let longName: string | null = null;\n for (let offset = 0; ; ) {\n const block = await read(offset, BLOCK);\n if (block.length < BLOCK) throw new Error(`the tar ends at byte ${offset + block.length}, before its end-of-archive block; it is truncated`);\n if (block.every((byte) => byte === 0)) return entries;\n const size = Number.parseInt(field(block, 124, 12).trim() || '0', 8);\n // A negative or unreadable size would never advance `offset` (a tar can come from a sync's client).\n if (!Number.isSafeInteger(size) || size < 0) throw new Error(`tar entry at ${offset} has an invalid size`);\n const type = field(block, 156, 1) || '0';\n const prefix = field(block, 345, 155);\n const name = longName ?? (prefix ? `${prefix}/${field(block, 0, 100)}` : field(block, 0, 100));\n const data = offset + BLOCK;\n longName = null;\n if (type === 'x' || type === 'L') {\n const text = decoder.decode(await read(data, size)).replace(/\\0+$/, '');\n longName = type === 'L' ? text : (/(?:^|\\n)\\d+ path=([^\\n]*)\\n/.exec(text)?.[1] ?? null);\n } else if (type === '0') {\n entries.push({ name, offset: data, size });\n }\n offset = data + size + tarPadding(size).length;\n }\n}\n","/**\n * `cofactor sandbox sync`: make a claimed sandbox's files match the local\n * working tree, uncommitted and untracked changes included, by talking to the\n * copy's own sync server (sync-server.ts in @chatsdet/sandbox-helper) over its\n * public `sync` port with a token the API mints. The claimer then rebuilds\n * and restarts what they choose (`exec`, `cofactor-sandbox restart`), or\n * reruns the definition's changed build steps with `--build`.\n *\n * sync <id> [--build] [--json] the working tree: the repo (GitHub), or the\n * directory holding ./cofactor.sandbox.yaml (pushed)\n * sync <id> <local-dir> --to <path> [--json]\n * mirror build output (ignore rules don't apply)\n * into <path> under the sandbox's sync root\n *\n * The local file list comes from a temporary git index (`git add -A` into a\n * copy of the user's index), so the user's own index is never touched, and\n * its `write-tree` is the identity the sync records.\n *\n * @module\n */\nimport { spawnSync } from 'node:child_process';\nimport process from 'node:process';\nimport { copyFileSync, existsSync, lstatSync, mkdtempSync, readFileSync, realpathSync, rmSync, type Stats } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join, relative, resolve, sep } from 'node:path';\nimport { hasFlag, getArgValue } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { writeRawOutput } from './brand.js';\nimport { tarOf } from '@chatsdet/sandbox-helper/image-archive';\nimport {\n SYNC_MAX_APPLY_BYTES,\n type SyncApplyManifest,\n type SyncApplyResult,\n type SyncPlanResponse,\n gitBlobId,\n syncApplyEntryName,\n syncApplyResultSchema,\n syncBuildEventSchema,\n syncPlanResponseSchema,\n} from '@chatsdet/sandbox-helper/sync-protocol';\n\nexport type LocalFile = { path: string; blob: string; mode: 0o644 | 0o755; size: number };\n\n/** What the API's `POST .../sync-session` returns. */\ntype SyncSession = {\n url: string;\n token: string;\n expiresAt: string;\n delivery: 'github' | 'upload';\n version: string;\n};\n\nclass SyncError extends Error {}\n\nfunction git(args: string[], options: { cwd: string; env?: NodeJS.ProcessEnv; input?: string; okCodes?: number[] }): string {\n const result = spawnSync('git', args, {\n cwd: options.cwd,\n env: options.env ?? process.env,\n input: options.input,\n encoding: 'utf8',\n maxBuffer: 1 << 30, // Node defaults to 1 MiB; this repo's `ls-files -s -z` alone is 1.2 MB\n });\n if (result.error) throw new SyncError(`git ${args[0]} failed: ${result.error.message}`);\n if (!(options.okCodes ?? [0]).includes(result.status ?? -1)) {\n throw new SyncError(`git ${args[0]} failed (${result.signal ?? result.status}): ${result.stderr.trim()}`);\n }\n return result.stdout;\n}\n\nconst toPosix = (path: string) => path.split(sep).join('/');\n\n/** The repository holding `dir`: its top level and its absolute git directory. */\nexport function repositoryOf(dir: string): { top: string; gitDir: string } {\n const top = git(['rev-parse', '--show-toplevel'], { cwd: dir }).trim();\n const gitDir = git(['rev-parse', '--absolute-git-dir'], { cwd: dir }).trim();\n return { top: realpathSync(top), gitDir };\n}\n\n/**\n * `ls-files -s -z` entries: regular files as `LocalFile`s (relative to\n * `strip`, sized from the working tree under `top`), and the paths it skips\n * (symlinks, submodules).\n */\nfunction indexEntries(output: string, strip: string, top: string): { files: LocalFile[]; skipped: string[] } {\n const files: LocalFile[] = [];\n const skipped: string[] = [];\n for (const entry of output.split('\\0')) {\n if (entry === '') continue;\n const match = /^(\\d{6}) ([0-9a-f]+) \\d\\t(.*)$/s.exec(entry);\n if (!match) throw new SyncError(`unexpected git ls-files line: ${entry}`);\n const [, mode, blob, repoPath] = match;\n const path = strip === '' ? repoPath! : repoPath!.slice(strip.length + 1);\n // An entry with no file here (skip-worktree in a sparse checkout) is skipped like a symlink.\n const onDisk = mode === '100644' || mode === '100755' ? lstatOrNull(join(top, repoPath!)) : null;\n if (onDisk?.isFile()) files.push({ path, blob: blob!, mode: mode === '100755' ? 0o755 : 0o644, size: onDisk.size });\n else skipped.push(path);\n }\n return { files, skipped };\n}\n\n/**\n * The working tree under `root` as git would commit it: tracked and untracked\n * files, ignored ones left out. Built in a temporary index (a copy of the\n * user's, so unchanged files aren't re-hashed), never the user's own.\n * `tree` is that index's tree id for `root` (`write-tree --prefix` for a\n * subdirectory), which a later commit matches as `commit:<prefix>`.\n * `untracked` is what isn't tracked yet, so the CLI can say so.\n */\nexport function workingTree(root: string): {\n files: LocalFile[];\n skipped: string[];\n untracked: Set<string>;\n tree: string;\n repo: string;\n prefix: string;\n env: NodeJS.ProcessEnv;\n cleanup: () => void;\n} {\n const { top, gitDir } = repositoryOf(root);\n const prefix = toPosix(relative(top, realpathSync(root)));\n const temp = mkdtempSync(join(tmpdir(), 'cofactor-sync-'));\n const cleanup = () => rmSync(temp, { recursive: true, force: true });\n try {\n const index = join(temp, 'index');\n const env = { ...process.env, GIT_INDEX_FILE: index };\n const userIndex = join(gitDir, 'index');\n if (existsSync(userIndex)) copyFileSync(userIndex, index);\n else if (git(['rev-parse', '--verify', '-q', 'HEAD'], { cwd: top, okCodes: [0, 1] }).trim() !== '') git(['read-tree', 'HEAD'], { cwd: top, env });\n const pathspec = prefix === '' ? '.' : `:(literal)${prefix}`;\n git(['add', '-A', '--', pathspec], { cwd: top, env });\n const entries = indexEntries(git(['ls-files', '-s', '-z', '--', pathspec], { cwd: top, env }), prefix, top);\n const files = withRawBlobs(entries.files, top, prefix);\n const skipped = entries.skipped;\n const tree = git(prefix === '' ? ['write-tree'] : ['write-tree', `--prefix=${prefix}/`], { cwd: top, env }).trim();\n const untracked = new Set(\n git(['ls-files', '--others', '--exclude-standard', '-z', '--', pathspec], { cwd: top })\n .split('\\0')\n .filter(Boolean)\n .map((path) => (prefix === '' ? path : path.slice(prefix.length + 1)))\n );\n return { files, skipped, untracked, tree, repo: top, prefix, env, cleanup };\n } catch (error) {\n cleanup();\n throw error;\n }\n}\n\n/**\n * Build output under `dir`, mirrored as is (ignore rules don't apply), each\n * path under `to`. `tree` is its tree id, recorded with `buildOutput: true`.\n */\nexport function buildOutput(dir: string, to: string): { files: LocalFile[]; skipped: string[]; tree: string } {\n const { gitDir } = repositoryOf(dir);\n const temp = mkdtempSync(join(tmpdir(), 'cofactor-sync-'));\n try {\n const env = { ...process.env, GIT_INDEX_FILE: join(temp, 'index'), GIT_DIR: gitDir, GIT_WORK_TREE: realpathSync(dir) };\n git(['add', '-A', '-f', '--', '.'], { cwd: dir, env });\n const entries = indexEntries(git(['ls-files', '-s', '-z'], { cwd: dir, env }), '', realpathSync(dir));\n const files = withRawBlobs(entries.files, realpathSync(dir), '', env);\n const skipped = entries.skipped;\n const tree = git(['write-tree'], { cwd: dir, env }).trim();\n return { files: files.map((file) => ({ ...file, path: `${to}/${file.path}` })), skipped: skipped.map((path) => `${to}/${path}`), tree };\n } finally {\n rmSync(temp, { recursive: true, force: true });\n }\n}\n\n/** The attributes through which git can run a file's bytes through a filter before storing them. */\nconst FILTER_ATTRIBUTES = ['filter', 'text', 'eol', 'ident', 'working-tree-encoding'];\n\n/**\n * The blob ids of the files' bytes as they are on disk. A clean filter\n * (autocrlf, `.gitattributes` `text`/`eol`/`filter`, LFS) makes the index's\n * blob differ from them, and the copy must get the bytes the app runs\n * locally, so every file git could filter is hashed as it is: all of them\n * with `core.autocrlf` on (`input`, or any of git's true spellings),\n * otherwise those an attribute names. `tree` stays the index's: what a\n * commit of these files would have.\n */\nfunction withRawBlobs(files: LocalFile[], top: string, prefix: string, env?: NodeJS.ProcessEnv): LocalFile[] {\n if (files.length === 0) return files;\n const options = { cwd: top, ...(env ? { env } : {}) };\n const repoPaths = files.map((file) => (prefix === '' ? file.path : `${prefix}/${file.path}`));\n const autocrlf = git(['config', '--get', 'core.autocrlf'], { ...options, okCodes: [0, 1] }).trim();\n const converts =\n autocrlf === 'input' ||\n (autocrlf !== '' && git(['config', '--get', '--type=bool', 'core.autocrlf'], options).trim() === 'true');\n let filtered: Set<string>;\n if (converts) {\n filtered = new Set(repoPaths);\n } else {\n // NUL-separated triples: path, attribute, value.\n const out = git(['check-attr', '-z', '--stdin', ...FILTER_ATTRIBUTES], { ...options, input: repoPaths.map((path) => `${path}\\0`).join('') }).split('\\0');\n filtered = new Set();\n for (let i = 0; i + 2 < out.length; i += 3) if (out[i + 2] !== 'unspecified') filtered.add(out[i]!);\n }\n // Read here, a file at a time: any path name works, and only these files are read.\n return files.map((file, i) =>\n filtered.has(repoPaths[i]!) ? { ...file, blob: gitBlobId(readFileSync(join(top, repoPaths[i]!))) } : file\n );\n}\n\nfunction lstatOrNull(path: string): Stats | null {\n try {\n return lstatSync(path);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw error;\n }\n}\n\n/** Run `fn` over `items` in chunks small enough for one command line. */\nfunction chunked<T>(items: T[], fn: (chunk: T[]) => void): void {\n for (let i = 0; i < items.length; i += 200) fn(items.slice(i, i + 200));\n}\n\n/** Of `paths` (relative to the repo top), the ones local ignore rules match (a trailing `/` marks a directory). */\nfunction ignoredPaths(repo: string, env: NodeJS.ProcessEnv, paths: string[]): Set<string> {\n if (paths.length === 0) return new Set();\n // Exit 1: none of them is ignored.\n const out = git(['check-ignore', '-z', '--stdin'], { cwd: repo, env, input: paths.map((p) => `${p}\\0`).join(''), okCodes: [0, 1] });\n return new Set(out.split('\\0').filter(Boolean));\n}\n\n/** Every path, relative to the repo top, that any local commit ever had under `pathspecs`. */\nfunction everTracked(repo: string, pathspecs: string[]): Set<string> {\n const seen = new Set<string>();\n if (pathspecs.length === 0) return seen;\n if (git(['rev-parse', '--verify', '-q', 'HEAD'], { cwd: repo, okCodes: [0, 1] }).trim() === '') return seen;\n chunked(pathspecs, (chunk) => {\n const out = git(['log', '--all', '--format=', '--name-only', '-z', '--', ...chunk.map((p) => `:(literal)${p}`)], { cwd: repo });\n for (const path of out.split('\\0')) {\n const trimmed = path.replace(/^\\n+/, '');\n if (trimmed) seen.add(trimmed);\n }\n });\n return seen;\n}\n\nexport type KeptEntry = { path: string; files: number; why: 'ignored here' | 'never tracked here' };\n\n/**\n * Which of the copy's extra files a working-tree sync deletes: a path is\n * deleted only when it isn't present locally (every `copyOnly` path isn't),\n * isn't ignored locally, and some local commit once had a file at that path.\n * A collapsed directory (`dir/`) is listed file by file (`listDir`, a plan\n * scoped to it) and each file judged on its own history. Everything else is\n * kept, with why.\n */\nexport async function chooseDeletions(params: {\n copyOnly: SyncPlanResponse['copyOnly'];\n repo: string;\n /** The sync root's path in the repo, '' at the top. */\n prefix: string;\n /** The temporary index's env, where the working tree's files are all tracked. */\n env: NodeJS.ProcessEnv;\n listDir: (dir: string) => Promise<string[]>;\n}): Promise<{ delete: string[]; kept: KeptEntry[] }> {\n const repoPath = (path: string) => (params.prefix === '' ? path : `${params.prefix}/${path}`);\n const ignored = ignoredPaths(params.repo, params.env, params.copyOnly.map((entry) => repoPath(entry.path)));\n const candidates = params.copyOnly.filter((entry) => !ignored.has(repoPath(entry.path)));\n const history = everTracked(params.repo, candidates.map((entry) => repoPath(entry.path)));\n const kept: KeptEntry[] = params.copyOnly\n .filter((entry) => ignored.has(repoPath(entry.path)))\n .map((entry) => ({ ...entry, why: 'ignored here' as const }));\n const remove: string[] = [];\n for (const entry of candidates) {\n if (!entry.path.endsWith('/')) {\n if (history.has(repoPath(entry.path))) remove.push(entry.path);\n else kept.push({ ...entry, why: 'never tracked here' });\n continue;\n }\n const tracked = [...history].some((path) => path.startsWith(repoPath(entry.path)));\n const listed = tracked ? await params.listDir(entry.path.slice(0, -1)) : [];\n // Each file of the directory is judged on its own: not ignored here, and once tracked.\n const ignoredInside = ignoredPaths(params.repo, params.env, listed.map(repoPath));\n const files = listed.filter((path) => !ignoredInside.has(repoPath(path)) && history.has(repoPath(path)));\n remove.push(...files);\n if (files.length < entry.files) kept.push({ path: entry.path, files: entry.files - files.length, why: 'never tracked here' });\n }\n return { delete: remove.sort(), kept: kept.sort((a, b) => a.path.localeCompare(b.path)) };\n}\n\n/** The files to send, split into apply bodies under the copy's limit; deletions ride the first. */\nexport function applyBatches(files: Array<LocalFile & { bytes: Uint8Array }>, remove: string[]): Array<Uint8Array<ArrayBuffer>> {\n const budget = SYNC_MAX_APPLY_BYTES - 1024 * 1024;\n // What a file adds to a body: its tar header, its bytes padded to a block, and its manifest entry.\n const cost = (file: LocalFile & { bytes: Uint8Array }) => 512 + Math.ceil(file.bytes.length / 512) * 512 + 100 + file.path.length;\n const batches: Array<Array<LocalFile & { bytes: Uint8Array }>> = [[]];\n let size = 0;\n for (const file of files) {\n if (cost(file) > budget) throw new SyncError(`${file.path} is ${Math.ceil(file.bytes.length / 1024 / 1024)} MiB; a sync sends files of at most ${budget / 1024 / 1024} MiB`);\n if (size + cost(file) > budget && batches.at(-1)!.length > 0) {\n batches.push([]);\n size = 0;\n }\n batches.at(-1)!.push(file);\n size += cost(file);\n }\n return batches.map((batch, index) => {\n const manifest: SyncApplyManifest = {\n files: batch.map(({ path, blob, mode }) => ({ path, blob, mode })),\n delete: index === 0 ? remove : [],\n };\n return tarOf([\n { name: 'manifest.json', data: new TextEncoder().encode(JSON.stringify(manifest)) },\n ...batch.map((file, i) => ({ name: syncApplyEntryName(i), data: file.bytes })),\n ]);\n });\n}\n\nasync function copyRequest(session: SyncSession, path: string, init: { body: BodyInit; contentType: string }): Promise<Response> {\n let response: Response;\n try {\n response = await fetch(`${session.url}${path}`, {\n method: 'POST',\n headers: { authorization: `Bearer ${session.token}`, 'content-type': init.contentType },\n body: init.body,\n });\n } catch (error) {\n throw new SyncError(`could not reach the sandbox for ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n if (!response.ok) {\n const text = await response.text();\n let message = text;\n try {\n message = (JSON.parse(text) as { error?: string }).error ?? text;\n } catch {\n // Not the sync server's JSON (the edge's own page): show it as is.\n }\n throw new SyncError(`the sandbox refused ${path} (${response.status}): ${message.slice(0, 2000)}`);\n }\n return response;\n}\n\nasync function plan(session: SyncSession, local: LocalFile[], to?: string): Promise<SyncPlanResponse> {\n const body = JSON.stringify(to === undefined ? { local } : { local, to });\n // The whole list is one request, under the copy's body limit.\n if (Buffer.byteLength(body) > SYNC_MAX_APPLY_BYTES) {\n throw new SyncError(\n `the file list (${local.length} files) is over the ${SYNC_MAX_APPLY_BYTES / 1024 / 1024} MiB a sync can plan in one request; ignore what the sandbox doesn't need (.gitignore)`\n );\n }\n const response = await copyRequest(session, '/sync/plan', { body, contentType: 'application/json' });\n return parseAnswer(syncPlanResponseSchema, await response.text(), '/sync/plan');\n}\n\n/** Parse a sync server answer, or fail naming what came back (an edge page, a cut stream). */\nfunction parseAnswer<T>(schema: { safeParse(value: unknown): { success: true; data: T } | { success: false } }, text: string, path: string): T {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n throw new SyncError(`the sandbox answered ${path} with something other than JSON: ${text.slice(0, 300)}`);\n }\n const parsed = schema.safeParse(value);\n if (!parsed.success) throw new SyncError(`the sandbox answered ${path} unexpectedly: ${text.slice(0, 300)}`);\n return parsed.data;\n}\n\n/** Apply each batch; the last runs the build when asked, streaming its progress to stderr. */\nasync function apply(session: SyncSession, batches: Array<Uint8Array<ArrayBuffer>>, build: boolean, json: boolean) {\n let written = 0;\n let deleted = 0;\n let restarted: string[] = [];\n const steps: Array<{ name: string; ran: boolean; ms: number }> = [];\n for (const [index, body] of batches.entries()) {\n const last = index === batches.length - 1;\n const response = await copyRequest(session, `/sync/apply${build && last ? '?build=1' : ''}`, { body, contentType: 'application/x-tar' });\n if (!(build && last)) {\n const result: SyncApplyResult = parseAnswer(syncApplyResultSchema, await response.text(), '/sync/apply');\n written += result.written;\n deleted += result.deleted;\n continue;\n }\n let buffer = '';\n const decoder = new TextDecoder();\n let finished = false;\n for await (const chunk of response.body!) {\n buffer += decoder.decode(chunk, { stream: true });\n let newline = buffer.indexOf('\\n');\n while (newline >= 0) {\n const event = parseAnswer(syncBuildEventSchema, buffer.slice(0, newline), '/sync/apply?build=1');\n buffer = buffer.slice(newline + 1);\n newline = buffer.indexOf('\\n');\n if (event.type === 'applied') {\n written += event.result.written;\n deleted += event.result.deleted;\n } else if (event.type === 'output') {\n if (!json) process.stderr.write(event.text);\n } else if (event.type === 'step') {\n steps.push({ name: event.name, ran: event.ran, ms: event.ms });\n if (!json) process.stderr.write(` build step ${event.name}: ${event.ran ? `ran in ${(event.ms / 1000).toFixed(1)} s` : 'unchanged'}\\n`);\n } else if (event.type === 'done') {\n restarted = event.restarted;\n finished = true;\n } else if (event.type === 'error') {\n throw new SyncError(`the build failed after the files were synced: ${event.message}`);\n }\n }\n }\n if (!finished) throw new SyncError('the build stream ended early; check the copy with `cofactor sandbox exec <id> -- cofactor-sandbox status`');\n }\n return { written, deleted, restarted, steps };\n}\n\nconst SYNC_USAGE =\n 'Usage: cofactor sandbox sync <id> [--build] [--json]\\n cofactor sandbox sync <id> <local-dir> --to <path-in-sandbox> [--json]';\n\n/** How many written paths a human-readable sync lists before summarizing (untracked ones are always listed). */\nconst LIST_LIMIT = 20;\n\n/** `cofactor sandbox sync`: see the module comment. `positionals` are the id and the optional local dir. */\nexport async function handleSandboxSync(positionals: string[], argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id, localDir] = positionals;\n const to = getArgValue(argv, '--to');\n const build = hasFlag(argv, '--build');\n const json = hasFlag(argv, '--json');\n const fail = (message: string): never => {\n console.error(`Error: ${message}`);\n process.exit(1);\n };\n if (!id) return fail(`sandbox id required.\\n${SYNC_USAGE}`);\n if ((localDir === undefined) !== (to === undefined)) return fail(`a local directory and --to go together.\\n${SYNC_USAGE}`);\n if (to !== undefined && build) return fail('--build reruns the build of a working-tree sync; build output is already built (`sync <id> <dir> --to <path>`).');\n if (to !== undefined && (to === '' || to.startsWith('/') || to.split('/').some((part) => part === '' || part === '.' || part === '..'))) {\n return fail('--to is a path under the sandbox\\'s sync root, like `static` or `frontend/dist` (no leading `/`, no `..`).');\n }\n // Before a session is minted: the file list and the synced identity come from git.\n if (localDir !== undefined && (!existsSync(localDir) || !lstatSync(localDir).isDirectory())) return fail(`${localDir} is not a directory`);\n if (!isInsideRepo(to === undefined ? process.cwd() : resolve(localDir!))) {\n return fail('run this inside a git repository: the files to sync and the synced tree come from git.');\n }\n\n const started = Date.now();\n const sessionRes = await apiRequest<{ ok: boolean; error?: string; data: SyncSession }>(\n apiUrl,\n token,\n 'POST',\n `/org/sandboxes-v2/sandboxes/${id}/sync-session`\n );\n if (!sessionRes.ok) return fail(sessionRes.error ?? 'could not start a sync');\n const session = sessionRes.data;\n try {\n let local: { files: LocalFile[]; skipped: string[]; tree: string; untracked: Set<string>; root: string };\n let decide: (planned: SyncPlanResponse) => Promise<{ delete: string[]; kept: KeptEntry[] }>;\n let cleanup = () => {};\n if (to !== undefined) {\n const dir = resolve(localDir!);\n const output = buildOutput(dir, to);\n local = { ...output, untracked: new Set(), root: dir };\n // A mirror: everything the copy has under --to that the directory doesn't.\n decide = async (planned) => ({ delete: planned.copyOnly.map((entry) => entry.path), kept: [] });\n } else {\n // GitHub: the whole repository is the copy's checkout. Pushed: the definition's directory is its WORKDIR.\n const root = session.delivery === 'github' ? repositoryOf(process.cwd()).top : process.cwd();\n if (session.delivery === 'upload' && !existsSync(join(root, 'cofactor.sandbox.yaml'))) {\n return fail('run this from the directory holding cofactor.sandbox.yaml: a pushed image\\'s WORKDIR mirrors it.');\n }\n const tree = workingTree(root);\n cleanup = tree.cleanup;\n local = { ...tree, root };\n decide = (planned) =>\n chooseDeletions({\n copyOnly: planned.copyOnly,\n repo: tree.repo,\n prefix: tree.prefix,\n env: tree.env,\n listDir: async (dir) => (await plan(session, [], dir)).copyOnly.map((entry) => entry.path),\n });\n }\n\n try {\n const planStarted = Date.now();\n const planned = await plan(session, local.files, to);\n // A path that is a symlink or submodule here exists locally: never a deletion.\n // A symlinked directory here is reported as `dir/` by the copy.\n const skipped = new Set(local.skipped.flatMap((path) => [path, `${path}/`]));\n const { delete: remove, kept } = await decide({ ...planned, copyOnly: planned.copyOnly.filter((entry) => !skipped.has(entry.path)) });\n const planMs = Date.now() - planStarted;\n const need = new Set(planned.need);\n const sending = local.files.filter((file) => need.has(file.path));\n\n if (!json) {\n writeRawOutput(`Syncing ${local.root} into sandbox ${id} (${session.delivery === 'github' ? 'GitHub' : 'pushed image'}, version ${session.version.slice(0, 12)})`);\n writeRawOutput(` plan: ${sending.length} to write, ${remove.length} to delete, ${local.files.length - sending.length} unchanged (${(planMs / 1000).toFixed(1)} s)`);\n const untracked = sending.filter((file) => local.untracked.has(file.path));\n const tracked = sending.filter((file) => !local.untracked.has(file.path));\n if (sending.length > 0) writeRawOutput(' write:');\n for (const file of tracked.slice(0, LIST_LIMIT)) writeRawOutput(` ${file.path}`);\n if (tracked.length > LIST_LIMIT) writeRawOutput(` ...and ${tracked.length - LIST_LIMIT} more`);\n for (const file of untracked) writeRawOutput(` ${file.path} (untracked)`);\n if (remove.length > 0) writeRawOutput(' delete:');\n for (const path of remove) writeRawOutput(` ${path}`);\n if (kept.length > 0) {\n writeRawOutput(' kept (only in the sandbox):');\n for (const entry of kept.slice(0, LIST_LIMIT)) {\n writeRawOutput(` ${entry.path}${entry.files > 1 ? ` (${entry.files} files)` : ''}, ${entry.why}`);\n }\n if (kept.length > LIST_LIMIT) writeRawOutput(` ...and ${kept.length - LIST_LIMIT} more`);\n }\n if (local.skipped.length > 0) writeRawOutput(` not synced (symlinks and submodules): ${local.skipped.join(', ')}`);\n }\n\n const applyStarted = Date.now();\n const batches =\n sending.length === 0 && remove.length === 0 && !build\n ? []\n : applyBatches(\n sending.map((file) => ({ ...file, bytes: readFileSync(join(local.root, to === undefined ? file.path : file.path.slice(to.length + 1))) })),\n remove\n );\n const applied = await apply(session, batches, build, json);\n const applyMs = Date.now() - applyStarted;\n const ms = Date.now() - started;\n\n const recorded = await apiRequest<{ ok: boolean; error?: string }>(apiUrl, token, 'POST', `/org/sandboxes-v2/sandboxes/${id}/syncs`, {\n tree: local.tree,\n buildOutput: to !== undefined,\n written: applied.written,\n deleted: applied.deleted,\n ms,\n });\n if (!recorded.ok) throw new SyncError(`the files were synced, but recording the sync failed: ${recorded.error}`);\n\n if (json) {\n writeRawOutput(\n JSON.stringify(\n {\n id,\n tree: local.tree,\n buildOutput: to !== undefined,\n written: sending.map((file) => file.path),\n deleted: remove,\n kept,\n build: build ? { steps: applied.steps, restarted: applied.restarted } : null,\n ms: { total: ms, plan: planMs, apply: applyMs },\n },\n null,\n 2\n )\n );\n return;\n }\n writeRawOutput(` applied: ${applied.written} written, ${applied.deleted} deleted (${(applyMs / 1000).toFixed(1)} s)`);\n if (build) writeRawOutput(` restarted: ${applied.restarted.join(', ') || 'nothing'}`);\n writeRawOutput(`Synced ${to === undefined ? 'tree' : 'build output'} ${local.tree} in ${(ms / 1000).toFixed(1)} s.`);\n if (!build) {\n writeRawOutput(` Restart what runs it: cofactor sandbox exec ${id} -- cofactor-sandbox restart <service>`);\n }\n const shown = await apiRequest<{ ok: boolean; data?: { portUrls: Record<string, string> } }>(apiUrl, token, 'GET', `/org/sandboxes-v2/sandboxes/${id}`);\n for (const [name, url] of Object.entries(shown.data?.portUrls ?? {})) writeRawOutput(` ${name.padEnd(10)} ${url}`);\n } finally {\n cleanup();\n }\n } catch (error) {\n if (error instanceof SyncError) return fail(error.message);\n throw error;\n }\n}\n\nfunction isInsideRepo(dir: string): boolean {\n return git(['rev-parse', '--is-inside-work-tree'], { cwd: dir, okCodes: [0, 128] }).trim() === 'true';\n}\n","/**\n * `cofactor sandbox refresh`: move an environment's head (the default\n * branch's head commit, or a pushed application's head push) to now, so\n * flow runs, the designer and unpinned claims use it without waiting for the\n * 6-hourly background refresh.\n *\n * @module\n */\n\nimport process from 'node:process';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\nimport { writeRawOutput } from './brand.js';\nimport { resolveApplicationId } from './environment.js';\n\ntype HeadStatus = 'ready' | 'building' | 'failed';\n\ntype RefreshData = {\n /** Server time of the request; sent back while polling, so only a failure after it is this refresh's. */\n requestedAt: number;\n /** The head before the refresh: `status` is the environment's readiness (`warming` / `none` have no version). */\n before: { version: string | null; status: 'ready' | 'warming' | 'stale' | 'none' };\n head: { version: string; status: HeadStatus; error: string | null };\n};\n\ntype StatusResponse = { ok: boolean; error?: string; data: { status: HeadStatus; error: string | null; isHead: boolean } };\n\ntype RefreshResponse = { ok: boolean; error?: string; code?: string; data: RefreshData };\n\nconst POLL_INTERVAL_MS = 5_000;\n/** A snapshot build (seeds included) can take a while; the API's own build limit is longer. */\nconst WAIT_TIMEOUT_MS = 50 * 60_000;\n\n/** A version as people read it: a short commit, or a push id. */\nfunction shortVersion(version: string): string {\n return /^[0-9a-f]{40}$/.test(version) ? version.slice(0, 12) : version;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** `cofactor sandbox refresh --application A [--environment E] [--wait] [--json]`. */\nexport async function handleSandboxRefresh(argv: string[], apiUrl: string, token: string): Promise<void> {\n const applicationId = await resolveApplicationId(argv, apiUrl, token);\n const environment = getArgValue(argv, '--environment') ?? 'default';\n const wait = hasFlag(argv, '--wait');\n const json = hasFlag(argv, '--json');\n\n const refresh = async (): Promise<RefreshData> => {\n const res = await apiRequest<RefreshResponse>(apiUrl, token, 'POST', `/org/sandboxes-v2/applications/${applicationId}/refresh`, {\n environment,\n });\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n return res.data;\n };\n\n const first = await refresh();\n let latest = first;\n if (wait && first.head.status === 'building') {\n // Polls only read. A snapshot that finishes without becoming the head (a build of the\n // same commit that was already queued for a claim does not carry the request) is asked\n // for once more, which marks it.\n let askedAgain = false;\n const deadline = Date.now() + WAIT_TIMEOUT_MS;\n while (latest.head.status === 'building' && Date.now() < deadline) {\n await sleep(POLL_INTERVAL_MS);\n const query = new URLSearchParams({ environment, version: latest.head.version, requestedAt: String(latest.requestedAt) });\n const res = await apiRequest<StatusResponse>(\n apiUrl,\n token,\n 'GET',\n `/org/sandboxes-v2/applications/${applicationId}/refresh-status?${query}`\n );\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n if (res.data.status === 'ready' && !res.data.isHead && !askedAgain) {\n askedAgain = true;\n latest = await refresh();\n } else if (res.data.status !== 'building') {\n latest = { ...latest, head: { ...latest.head, status: res.data.status, error: res.data.error } };\n }\n }\n }\n\n if (json) {\n writeRawOutput(JSON.stringify({ environment, before: first.before, head: latest.head }, null, 2));\n } else {\n const { before } = first;\n const { head } = latest;\n const unchanged = before.version === head.version && head.status === 'ready' && before.status === 'ready';\n if (unchanged) {\n console.log(`Environment \"${environment}\" is already at head ${shortVersion(head.version)}.`);\n } else {\n console.log(`Environment \"${environment}\":`);\n console.log(` old head ${before.version ? `${shortVersion(before.version)} (${before.status})` : `(none: ${before.status})`}`);\n console.log(` new head ${shortVersion(head.version)} (${head.status})`);\n if (head.error) console.log(` error ${head.error}`);\n if (head.status === 'building') {\n console.log(\n wait\n ? ' still building: timed out waiting. Check `cofactor sandbox envs`.'\n : ' The head advances when the snapshot is ready. Follow it with `--wait`, or `cofactor sandbox envs`.'\n );\n }\n }\n }\n if (latest.head.status === 'failed' || (wait && latest.head.status === 'building')) process.exit(1);\n}\n","/**\n * `cofactor sandbox warm`: keep a Sandboxes v2 environment warm. Staff only\n * (superadmin): warming holds capacity on the sandbox fleet.\n *\n * warm list every environment kept warm on the stage\n * warm set --application A --environment E --slots N [--tag T]\n * warm show --application A --environment E\n * warm clear --application A --environment E\n *\n * The org acted in is the one the session is signed in to (`--org` picks which\n * of your sessions, as everywhere). `--target-org <id>` names another org\n * instead; its application must then be given by id, since names resolve\n * within the session's own org. `--json` prints the API's data unchanged.\n *\n * @module\n * @see specs/pending/sandboxes-v2-warm-snapshots.md\n */\n\nimport process from 'node:process';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, getTargetOrg, UUID_RE } from './cli-helpers.js';\nimport { resolveApplicationId } from './environment.js';\nimport { writeRawOutput } from './brand.js';\nimport { decodeJwtPayload } from './jwt.js';\n\ntype WarmHeld = { version: string | null; warmFree: number } | null;\n\ntype WarmView = {\n orgId: string;\n applicationId: string;\n environment: string;\n state: 'warming' | 'warm' | 'switching' | 'failed';\n slots: number;\n tag: string | null;\n current: WarmHeld;\n next: WarmHeld;\n /** Set only by `set`, when the row saved but its live state could not be read: `current` and `next` are then unknown, not empty. */\n liveUnavailable?: string;\n since: string;\n lastError: string | null;\n};\n\ntype WarmListed = Pick<WarmView, 'orgId' | 'applicationId' | 'environment' | 'state' | 'slots' | 'tag'> & {\n currentReservationId: string | null;\n nextReservationId: string | null;\n retiringReservationId: string | null;\n};\n\ntype WarmResponse<T> = { ok: boolean; error?: string; data: T };\n\n/** What the loop's state is called to people: `warming` is not `Filling` in the readiness chip's sense. */\nconst STATE_LABELS: Record<WarmView['state'], string> = {\n warming: 'Filling',\n warm: 'On',\n switching: 'Switching',\n failed: 'Needs attention',\n};\n\nconst USAGE = [\n 'Usage: cofactor sandbox warm <command>',\n ' list Every environment kept warm on this stage',\n ' set --application <a> --environment <e> --slots <1-12> [--tag <t>] Turn keep warm on, or change its slots or tag',\n ' show --application <a> --environment <e> State, slots, and the free warm slots now',\n ' clear --application <a> --environment <e> Turn it off and release the capacity',\n ' --target-org <id> Act in another org (the application must then be an id); default: your session org',\n ' --json Print the API data as JSON',\n].join('\\n');\n\nconst COMMANDS: Record<string, { values: string[] }> = {\n list: { values: [] },\n set: { values: ['--application', '--environment', '--slots', '--tag', '--target-org'] },\n show: { values: ['--application', '--environment', '--target-org'] },\n clear: { values: ['--application', '--environment', '--target-org'] },\n};\n\n/** `warm list|set|show|clear` is this file's; anything else after `warm` is the v1 `warm <template-id>`. */\nexport function isSandboxV2WarmCommand(first: string | undefined): boolean {\n return first !== undefined && Object.hasOwn(COMMANDS, first);\n}\n\nfunction fail(message: string): never {\n console.error(`Error: ${message}`);\n process.exit(1);\n}\n\n/** Refuse an argument the command doesn't take, as the other v2 commands do. */\nfunction rejectUnknownWarmArgs(command: string, argv: string[]): void {\n const spec = COMMANDS[command]!;\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]!;\n if (spec.values.includes(arg)) {\n i++;\n continue;\n }\n if (arg === '--json' || arg === '--debug') continue;\n fail(`\\`cofactor sandbox warm ${command}\\` does not take ${JSON.stringify(arg)}.\\n${USAGE}`);\n }\n}\n\n/** The org the command acts in, and the application in it. */\nasync function resolveTarget(argv: string[], apiUrl: string, token: string): Promise<{ orgId: string; applicationId: string; environment: string }> {\n const environment = getArgValue(argv, '--environment');\n if (!environment) fail('--environment <name> is required.');\n const targetOrg = getTargetOrg(argv);\n if (targetOrg) {\n if (!UUID_RE.test(targetOrg)) fail('--target-org takes an organization id.');\n const application = getArgValue(argv, '--application');\n if (!application || !UUID_RE.test(application)) fail('With --target-org, --application must be the application id.');\n return { orgId: targetOrg, applicationId: application, environment };\n }\n const sessionOrg = decodeJwtPayload(token)?.org_id;\n if (typeof sessionOrg !== 'string') fail('Cannot tell which org this token is for: pass --target-org <id>.');\n return { orgId: sessionOrg, applicationId: await resolveApplicationId(argv, apiUrl, token), environment };\n}\n\nconst warmPath = (target: { orgId: string; applicationId: string; environment: string }) =>\n `/superadmin/sandboxes-v2/orgs/${target.orgId}/applications/${target.applicationId}/environments/${encodeURIComponent(target.environment)}/warm`;\n\nfunction printHeld(label: string, held: WarmHeld): void {\n if (!held) return;\n console.log(` ${label}: ${held.version ?? 'unknown version'} (${held.warmFree} warm slot${held.warmFree === 1 ? '' : 's'} free now)`);\n}\n\nfunction printWarm(view: WarmView): void {\n const tag = view.tag ? `, tag ${view.tag}` : '';\n console.log(`Keep warm: ${STATE_LABELS[view.state]} (${view.slots} slot${view.slots === 1 ? '' : 's'}${tag})`);\n console.log(` application ${view.applicationId}, environment ${view.environment}, org ${view.orgId}`);\n if (view.liveUnavailable) console.log(` Saved, but live warm state could not be read, so warm slots are unknown: ${view.liveUnavailable}`);\n printHeld('Serving claims', view.current);\n printHeld('Warming next', view.next);\n console.log(` Since: ${new Date(view.since).toLocaleString()}`);\n if (view.lastError) console.log(` ${view.state === 'failed' ? 'Error' : 'Last error'}: ${view.lastError}`);\n}\n\nfunction printList(rows: WarmListed[]): void {\n if (rows.length === 0) {\n console.log('No environment is kept warm on this stage.');\n return;\n }\n for (const row of rows) {\n const reservations = [row.currentReservationId, row.nextReservationId, row.retiringReservationId].filter(Boolean).join(' ');\n console.log(\n `${STATE_LABELS[row.state].padEnd(15)} ${row.slots} slot${row.slots === 1 ? ' ' : 's'} org ${row.orgId} application ${row.applicationId} ${row.environment}${\n row.tag ? ` tag ${row.tag}` : ''\n }${reservations ? ` reservations ${reservations}` : ''}`\n );\n }\n}\n\nfunction output<T>(argv: string[], res: WarmResponse<T>, print: (data: T) => void): void {\n if (!res.ok) fail(res.error ?? 'request failed');\n if (hasFlag(argv, '--json')) writeRawOutput(JSON.stringify(res.data, null, 2));\n else print(res.data);\n}\n\n/** The PUT body from `--slots` and `--tag` (null when `--tag` is absent), checked here so a bad value fails before the request. */\nexport function parseSetBody(slotsArg: string, tag: string | null): { slots: number; tag?: string } {\n const slots = Number(slotsArg);\n if (slotsArg.trim() === '' || !Number.isInteger(slots) || slots < 1 || slots > 12) {\n throw new Error('--slots must be a whole number from 1 to 12');\n }\n if (tag === '') throw new Error('--tag must not be empty');\n return tag === null ? { slots } : { slots, tag };\n}\n\n/** `cofactor sandbox warm <list|set|show|clear>`: see the file comment. */\nexport async function handleSandboxWarm(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [command, ...rest] = argv;\n if (!command || !isSandboxV2WarmCommand(command)) {\n console.error(command ? `Unknown warm command: ${command}\\n${USAGE}` : USAGE);\n process.exit(1);\n }\n rejectUnknownWarmArgs(command, rest);\n\n if (command === 'list') {\n output(rest, await apiRequest<WarmResponse<WarmListed[]>>(apiUrl, token, 'GET', '/superadmin/sandboxes-v2/warm'), printList);\n return;\n }\n const target = await resolveTarget(rest, apiUrl, token);\n if (command === 'show') {\n output(rest, await apiRequest<WarmResponse<WarmView>>(apiUrl, token, 'GET', warmPath(target)), printWarm);\n } else if (command === 'clear') {\n output(rest, await apiRequest<WarmResponse<{ cleared: true }>>(apiUrl, token, 'DELETE', warmPath(target)), () =>\n console.log(`Keep warm cleared for ${target.environment}; its capacity is released.`)\n );\n } else {\n const slotsArg = getArgValue(rest, '--slots');\n if (slotsArg === undefined) fail('--slots <1-12> is required.');\n // `--tag` as the last argument has no value: an empty tag, refused, rather than silently dropped.\n const tagArg = rest.includes('--tag') ? (getArgValue(rest, '--tag') ?? '') : null;\n let body: ReturnType<typeof parseSetBody>;\n try {\n body = parseSetBody(slotsArg, tagArg);\n } catch (error) {\n return fail(error instanceof Error ? error.message : String(error));\n }\n output(rest, await apiRequest<WarmResponse<WarmView>>(apiUrl, token, 'PUT', warmPath(target), body), printWarm);\n }\n}\n","/**\n * `cofactor sandbox secret set|list|rm`: an application's third-party secrets\n * (API keys and the like) for its sandboxes, for all environments or one.\n * A value comes only from stdin so it never lands in shell history or `ps`,\n * and no command prints it.\n *\n * @module\n */\n\nimport process from 'node:process';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, stripOneTrailingNewline } from './cli-helpers.js';\nimport { resolveApplicationId } from './environment.js';\nimport { writeRawOutput } from './brand.js';\nimport { v2Positionals } from './sandbox-v2.js';\nimport { ENV_NAME } from '@chatsdet/sandbox-helper/manifest';\n\ntype SecretEntry = { name: string; environment: string | null; updatedAt: string };\n\ntype SecretResponse<T> = { ok: boolean; error?: string; data: T };\n\n/** `all environments` or `environment <name>`. */\nexport function scopeText(environment: string | null): string {\n return environment === null ? 'all environments' : `environment ${environment}`;\n}\n\n/** The sentence `set` and `rm` print: `... for all environments of shop` / `... for environment \"staging\" of shop`. */\nfunction scopeSentence(environment: string | null, application: string): string {\n return environment === null ? `for all environments of ${application}` : `for environment \"${environment}\" of ${application}`;\n}\n\nconst base = (applicationId: string, name: string) => `/org/applications/${applicationId}/sandbox/secrets/${encodeURIComponent(name)}`;\n\n/** The request that sets one secret; `environment` is omitted (never empty) when application-wide. */\nexport function setSecretRequest(applicationId: string, name: string, environment: string | null, value: string) {\n return {\n method: 'PUT' as const,\n path: base(applicationId, name),\n body: { value, ...(environment === null ? {} : { environment }) },\n };\n}\n\n/** The request that removes one secret; `environment` is omitted (never empty) when application-wide. */\nexport function rmSecretRequest(applicationId: string, name: string, environment: string | null) {\n const path = base(applicationId, name);\n return { method: 'DELETE' as const, path: environment === null ? path : `${path}?environment=${encodeURIComponent(environment)}` };\n}\n\n/** Why `set` cannot read a value from this stdin, or null when it can. */\nexport function stdinRefusal(isTTY: boolean | undefined): string | null {\n return isTTY ? 'pipe the value on stdin, e.g. printf %s \"$KEY\" | cofactor sandbox secret set NAME --application A' : null;\n}\n\nfunction fail(message: string): never {\n console.error(`Error: ${message}`);\n process.exit(1);\n}\n\n/** The stdin text as the secret value, or the reason it cannot be one. */\nexport function decodeSecretValue(bytes: Uint8Array): { value: string } | { error: string } {\n let text: string;\n try {\n text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);\n } catch {\n return { error: 'the value must be UTF-8 text' };\n }\n const value = stripOneTrailingNewline(text);\n return value === '' ? { error: 'stdin was empty: is the variable set?' } : { value };\n}\n\nasync function readStdin(): Promise<Uint8Array> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks);\n}\n\n/** `environment` as given: omitted means application-wide; a missing or empty value is a mistake, not \"all\". */\nfunction environmentArg(argv: string[]): string | null {\n const index = argv.indexOf('--environment');\n if (index === -1) return null;\n const environment = argv[index + 1];\n if (environment === undefined || environment === '' || environment.startsWith('-')) {\n fail('--environment needs an environment name; omit it for all environments');\n }\n return environment;\n}\n\nfunction printUsage(): never {\n console.error('Usage: cofactor sandbox secret set <NAME> --application <name|id> [--environment <e>] [--json] (value on stdin)');\n console.error(' cofactor sandbox secret list --application <name|id> [--json]');\n console.error(' cofactor sandbox secret rm <NAME> --application <name|id> [--environment <e>] [--json]');\n process.exit(1);\n}\n\nexport async function handleSandboxSecret(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [action, name, ...extra] = v2Positionals('secret', argv);\n if (action !== 'set' && action !== 'list' && action !== 'rm') printUsage();\n const environment = environmentArg(argv);\n if (action === 'list') {\n if (name !== undefined) fail('`secret list` takes no name');\n if (environment !== null) fail('`secret list` shows every scope; --environment is for set and rm');\n } else {\n if (!name || extra.length > 0) printUsage();\n // The server's name rule (ENV_NAME). Never echo the name: it may be a pasted value.\n if (!ENV_NAME.test(name)) fail('NAME must be an environment variable name (A–Z, 0–9, _)');\n }\n const json = hasFlag(argv, '--json');\n const application = getArgValue(argv, '--application') ?? getArgValue(argv, '--property') ?? '';\n\n if (action === 'set') {\n // Refuse before any network call so an interactive terminal never hangs on stdin.\n const refusal = stdinRefusal(process.stdin.isTTY);\n if (refusal) {\n console.error(`Error: ${refusal}`);\n process.exit(1);\n }\n }\n\n // Read and check the value before any network call.\n let value: string | undefined;\n if (action === 'set') {\n const decoded = decodeSecretValue(await readStdin());\n if ('error' in decoded) fail(decoded.error);\n value = decoded.value;\n }\n\n const applicationId = await resolveApplicationId(argv, apiUrl, token);\n\n if (action === 'list') {\n const res = await apiRequest<SecretResponse<{ secrets: SecretEntry[] }>>(\n apiUrl, token, 'GET', `/org/applications/${applicationId}/sandbox/secrets`\n );\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n const { secrets } = res.data;\n if (secrets.length === 0) {\n console.log(`No secrets set for ${application}.`);\n return;\n }\n const rows = secrets.map((s) => [s.name, scopeText(s.environment), s.updatedAt]);\n const nameWidth = Math.max('NAME'.length, ...rows.map((r) => r[0]!.length));\n const scopeWidth = Math.max('SCOPE'.length, ...rows.map((r) => r[1]!.length));\n const line = (cells: string[]) => `${cells[0]!.padEnd(nameWidth)} ${cells[1]!.padEnd(scopeWidth)} ${cells[2]}`;\n console.log(line(['NAME', 'SCOPE', 'UPDATED']));\n for (const row of rows) console.log(line(row));\n return;\n }\n\n const request = value === undefined ? rmSecretRequest(applicationId, name!, environment) : setSecretRequest(applicationId, name!, environment, value);\n const res = await apiRequest<SecretResponse<{ name: string; environment: string | null }>>(\n apiUrl, token, request.method, request.path, 'body' in request ? request.body : undefined\n );\n if (!res.ok) {\n console.error(`Error: ${res.error}`);\n process.exit(1);\n }\n if (json) {\n writeRawOutput(JSON.stringify(res.data, null, 2));\n return;\n }\n console.log(`Secret ${name} ${action === 'set' ? 'set' : 'removed'} ${scopeSentence(environment, application)}.`);\n}\n"],"mappings":"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A,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,sDAAsD,0BAA0B,IAAI,CAAC,YAAY,QAAQ,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,MACzH;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,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,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,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAA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","names":["process","readFileSync","action","process","process","service","process","process","process","readFileSync","createHash","z","z","z","z","z","isRecord","z","provider","env","z","z","z","z","pad","resolve","process","push","readFileSync","environment","seconds","process","spawnSync","createHash","mkdtempSync","readFileSync","rmSync","tmpdir","dirname","join","readFileSync","docker","git","readFileSync","z","spawnSync","createHash","resolve","join","dirname","process","readFileSync","mkdtempSync","tmpdir","rmSync","spawnSync","process","existsSync","mkdtempSync","readFileSync","rmSync","tmpdir","join","resolve","spawnSync","process","output","join","mkdtempSync","tmpdir","rmSync","existsSync","readFileSync","decoder","fail","resolve","process","shortVersion","sleep","resolve","environment","process","process","USAGE","fail","process","environment","process","environment","fail","process","action","res","process","pad","readFileSync","service","POLL_INTERVAL_MS","resolve","a","action"]}