ryugi-artifacts 1.49.5 → 1.51.1

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 (391) hide show
  1. package/dist/cli.cjs +557 -795
  2. package/dist/server.cjs +5403 -4154
  3. package/dist/viewer/ArtboardLayout-BZVGyDSM.js +12 -0
  4. package/dist/viewer/ArtifactList-DpLf02v3.js +2 -0
  5. package/dist/viewer/{AutoPublishPrompt-Dgg8UZgm.js → AutoPublishPrompt-IPZH2eun.js} +1 -1
  6. package/dist/viewer/{Avatar-D0-gwyZG.js → Avatar-ChKN096x.js} +1 -1
  7. package/dist/viewer/{Canvas-5HDo5Pxm.js → Canvas-m5zHdW7S.js} +1 -1
  8. package/dist/viewer/DocumentLayout-Uhngahx2.js +2 -0
  9. package/dist/viewer/{DocumentPage-DiL0OmQP.js → DocumentPage-BpiHaN96.js} +2 -2
  10. package/dist/viewer/{HtmlLayout-fUN24tVp.js → HtmlLayout-CJTStMvJ.js} +1 -1
  11. package/dist/viewer/MenuSubmenuTrigger-Dbvpvvx7.js +1 -0
  12. package/dist/viewer/PopoverPopup-JF1C63LT.js +1 -0
  13. package/dist/viewer/{PreviewLayout-DCwFkaRV.js → PreviewLayout-VfoLatHx.js} +2 -2
  14. package/dist/viewer/Select-Bi_laIbS.js +1 -0
  15. package/dist/viewer/SelectScrollUpArrow-arh1d92W.js +1 -0
  16. package/dist/viewer/{SettingsDialog-3w2lF7aB.js → SettingsDialog-BIXPa5hx.js} +1 -1
  17. package/dist/viewer/{SnapshotDocument-B-uDb7Ds.js → SnapshotDocument-B-T21B2B.js} +1 -1
  18. package/dist/viewer/{Switch-DPXSJDUl.js → Switch-CGaivD-j.js} +2 -2
  19. package/dist/viewer/TooltipPopup-CeBUFPYY.js +1 -0
  20. package/dist/viewer/{VirtualizedEditor-D9Ivycdp-ej7fgQSc.js → VirtualizedEditor-D9Ivycdp-BJqIIHVA.js} +1 -1
  21. package/dist/viewer/{VirtualizedRenderer-C_d95FXi-CIQCskXB.js → VirtualizedRenderer-C_d95FXi--_gZsY3Q.js} +1 -1
  22. package/dist/viewer/{WarningsBadge-CPgjdvO1.js → WarningsBadge-DYJBrb7z.js} +1 -1
  23. package/dist/viewer/{abnfDiagram-VCTEODGH-IAqL1jFG.js → abnfDiagram-VCTEODGH-DCqbkXDC.js} +1 -1
  24. package/dist/viewer/{ar-SA-G6X2FPQ2-jI8MwFk3.js → ar-SA-G6X2FPQ2-5x9BGsxu.js} +1 -1
  25. package/dist/viewer/{architecture-7GRP2DOG-RpL6RbN0.js → architecture-7GRP2DOG-DuTH02lo.js} +1 -1
  26. package/dist/viewer/{architectureDiagram-5GKGNRK7-DBk0gkh5.js → architectureDiagram-5GKGNRK7-DpKwV7gs.js} +1 -1
  27. package/dist/viewer/atoms-DgyI2Lrt.js +9 -0
  28. package/dist/viewer/{az-AZ-76LH7QW2-DhYgzkfD.js → az-AZ-76LH7QW2-DclUeBkL.js} +1 -1
  29. package/dist/viewer/{bg-BG-XCXSNQG7-DHBLBwwG.js → bg-BG-XCXSNQG7-D3AWNsdt.js} +1 -1
  30. package/dist/viewer/{blockDiagram-I7D4REHJ--XDROtA7.js → blockDiagram-I7D4REHJ-CayLpBs3.js} +1 -1
  31. package/dist/viewer/{bn-BD-2XOGV67Q-D_-hi_Xc.js → bn-BD-2XOGV67Q-CnDo0UsR.js} +1 -1
  32. package/dist/viewer/{c4Diagram-7LVT6UL2-hZBArobY.js → c4Diagram-7LVT6UL2-CQoKWHJL.js} +1 -1
  33. package/dist/viewer/{ca-ES-6MX7JW3Y-KDMNkFE1.js → ca-ES-6MX7JW3Y-CBS3EuHH.js} +1 -1
  34. package/dist/viewer/channel-Bu5V6aal.js +1 -0
  35. package/dist/viewer/{channel-C3YzEkgO.js → channel-Cu2iqf6i.js} +149 -149
  36. package/dist/viewer/{chunk-4HAMMTFA-B2SaMTCK.js → chunk-4HAMMTFA-DyYo8LPZ.js} +1 -1
  37. package/dist/viewer/{chunk-75Z2AOVW-CfpxZFuq.js → chunk-75Z2AOVW-COy2Rylp.js} +1 -1
  38. package/dist/viewer/{chunk-DU6HZSFF-DsOuFfQj.js → chunk-DU6HZSFF-Ba60Pj0Y.js} +1 -1
  39. package/dist/viewer/{chunk-EIO257PC-BayPP-fj.js → chunk-EIO257PC-ZqQ5UFLD.js} +1 -1
  40. package/dist/viewer/{chunk-F27PBJKO-CgTA4UPJ.js → chunk-F27PBJKO-BaBvGKXB.js} +1 -1
  41. package/dist/viewer/{chunk-GMAD6QVW-D4o0GdZ-.js → chunk-GMAD6QVW-BgK7coEn.js} +1 -1
  42. package/dist/viewer/{chunk-GVQU2GXP-CIwk2SWd.js → chunk-GVQU2GXP-DM1eRW5W.js} +1 -1
  43. package/dist/viewer/{chunk-IMKFNOWR-DILouWz8.js → chunk-IMKFNOWR-BMiC32cx.js} +1 -1
  44. package/dist/viewer/{chunk-L3NEJ4N5-D574Vvyw.js → chunk-L3NEJ4N5-D6g2apiI.js} +1 -1
  45. package/dist/viewer/{chunk-OSK3NFVY-7Xvsltco.js → chunk-OSK3NFVY-D254WAh4.js} +1 -1
  46. package/dist/viewer/{chunk-P2QGCYS3-DOfQ1qvV.js → chunk-P2QGCYS3-Bj0rIKyy.js} +1 -1
  47. package/dist/viewer/{chunk-POPQ4Y6H-K0NxOlNk.js → chunk-POPQ4Y6H-FefF0hud.js} +1 -1
  48. package/dist/viewer/{chunk-PWAF6VOD-bNOhbBfc.js → chunk-PWAF6VOD-Dky9lxlw.js} +1 -1
  49. package/dist/viewer/{chunk-SHT3W25Y-B7gff12L.js → chunk-SHT3W25Y-ZrwcdJJV.js} +1 -1
  50. package/dist/viewer/{chunk-SVP7TREG-VSV-4P6H.js → chunk-SVP7TREG-CxiLTFg-.js} +1 -1
  51. package/dist/viewer/{chunk-TICWLB2K-CTdRetzg.js → chunk-TICWLB2K-4tQNk-Y_.js} +1 -1
  52. package/dist/viewer/classDiagram-ZZMXUADV-DhjcP1H1.js +1 -0
  53. package/dist/viewer/classDiagram-v2-VYDZK3BY-DhjcP1H1.js +1 -0
  54. package/dist/viewer/{cs-CZ-2BRQDIVT-U9apbjng.js → cs-CZ-2BRQDIVT-DQskQaNZ.js} +1 -1
  55. package/dist/viewer/{cynefin-OW5HDTMX-Bp_BNehL.js → cynefin-OW5HDTMX-DQ2NYnLq.js} +1 -1
  56. package/dist/viewer/{cynefinDiagram-5FMLGOSQ-C83De6Ud.js → cynefinDiagram-5FMLGOSQ-Byp9vaRG.js} +1 -1
  57. package/dist/viewer/{da-DK-5WZEPLOC-B_w-ZbwP.js → da-DK-5WZEPLOC-10wi0pVH.js} +1 -1
  58. package/dist/viewer/{dagre-GXQ25YYZ-DjS2CJh0.js → dagre-GXQ25YYZ-CpwEDWxD.js} +1 -1
  59. package/dist/viewer/{de-DE-XR44H4JA-CLPxoS2g.js → de-DE-XR44H4JA-BEG4NEM3.js} +1 -1
  60. package/dist/viewer/{diagram-S7CK7UJ4-eHNph8I-.js → diagram-S7CK7UJ4-BD0ok3e_.js} +1 -1
  61. package/dist/viewer/{diagram-UQ7AKVKN-F5QGirBc.js → diagram-UQ7AKVKN-23OBvO1n.js} +1 -1
  62. package/dist/viewer/{diagram-VSXAHHWV-Czw3JSYt.js → diagram-VSXAHHWV-DL4j5yEx.js} +1 -1
  63. package/dist/viewer/{diagram-VX7I27RA-D3AUmBJH.js → diagram-VX7I27RA-BzhA5psf.js} +1 -1
  64. package/dist/viewer/{diagram-Z3DM3KII-CeQSI_Lp.js → diagram-Z3DM3KII-B8XYL8q5.js} +1 -1
  65. package/dist/viewer/{dist-BESISDe_.js → dist-BM1aRtpi.js} +1 -1
  66. package/dist/viewer/{dist-PW__s96V.js → dist-Bg2FmgJo.js} +1 -1
  67. package/dist/viewer/{dist-CvXUA72v.js → dist-BtS4yC3x.js} +1 -1
  68. package/dist/viewer/{dist-BnHF8goh.js → dist-BzyGtYHj.js} +1 -1
  69. package/dist/viewer/{dist-Dw0tKSU6.js → dist-C0hkvJVA.js} +1 -1
  70. package/dist/viewer/{dist-DOGW9H29.js → dist-C7014tiL.js} +1 -1
  71. package/dist/viewer/{dist-CoNAZFJa.js → dist-CCurwbUB.js} +1 -1
  72. package/dist/viewer/{dist-DL7jbuRG.js → dist-CEkCBhMv.js} +1 -1
  73. package/dist/viewer/{dist-DmSelfDR.js → dist-CbWdPfAb.js} +1 -1
  74. package/dist/viewer/{dist-Cb_u9EB2.js → dist-CopZXf2A.js} +1 -1
  75. package/dist/viewer/{dist-3LHm0pGo.js → dist-CqI7ycqg.js} +1 -1
  76. package/dist/viewer/{dist-Dn1JbpqO.js → dist-Cqfmrb6s.js} +1 -1
  77. package/dist/viewer/{dist-BY7qycSS.js → dist-D--ew1J5.js} +1 -1
  78. package/dist/viewer/{dist-DPODEkt6.js → dist-DFfhXGlC.js} +1 -1
  79. package/dist/viewer/{dist-CSs1RHC8.js → dist-DH-H0sq6.js} +1 -1
  80. package/dist/viewer/{dist-C_j7e3Fc.js → dist-DI9AXA7U.js} +1 -1
  81. package/dist/viewer/{dist-D20pZ0Sn.js → dist-DK7UXjZx.js} +1 -1
  82. package/dist/viewer/{dist-DrG5ItaK.js → dist-DZ-PQTiU.js} +1 -1
  83. package/dist/viewer/{dist-BTUc4e6w.js → dist-DkMG8IT4.js} +1 -1
  84. package/dist/viewer/{dist-y1ST9xzc.js → dist-DrZhmQmc.js} +4 -4
  85. package/dist/viewer/{dist-4CLFOTET.js → dist-DvhLkwO7.js} +1 -1
  86. package/dist/viewer/{dist-21Z0O_2u.js → dist-DxWySzrE.js} +1 -1
  87. package/dist/viewer/{dist-Bd7yqWfR.js → dist-QcXz29VN.js} +1 -1
  88. package/dist/viewer/{dist-DpjPLA5w.js → dist-eqRG7hyK.js} +1 -1
  89. package/dist/viewer/{ebnfDiagram-PWID7BFC-CN91SOA0.js → ebnfDiagram-PWID7BFC-DNTkWpp8.js} +1 -1
  90. package/dist/viewer/{el-GR-BZB4AONW-Bq5AUdIh.js → el-GR-BZB4AONW-BhDLqs1x.js} +1 -1
  91. package/dist/viewer/{en-B4ZKOASM-CyRxSMPf.js → en-B4ZKOASM-B_Ezgv2p.js} +1 -1
  92. package/dist/viewer/{erDiagram-RLTQ6QDP-cgNv3ld9.js → erDiagram-RLTQ6QDP-B5Jt5HjK.js} +1 -1
  93. package/dist/viewer/{es-ES-U4NZUMDT-CYPQzBjO.js → es-ES-U4NZUMDT-Volm3CKj.js} +1 -1
  94. package/dist/viewer/{eu-ES-A7QVB2H4-uILb6AeS.js → eu-ES-A7QVB2H4-BmOeCXQ0.js} +1 -1
  95. package/dist/viewer/{eventmodeling-NTZA5JFV-CGX7wgHu.js → eventmodeling-NTZA5JFV-0uikWG90.js} +1 -1
  96. package/dist/viewer/{fa-IR-HGAKTJCU-Sz03KMtk.js → fa-IR-HGAKTJCU-C8o9dVKj.js} +1 -1
  97. package/dist/viewer/{fi-FI-Z5N7JZ37-frhGahbu.js → fi-FI-Z5N7JZ37-WZ-DsWmo.js} +1 -1
  98. package/dist/viewer/flowDiagram-HODETNUW-bbkVHyjQ.js +1 -0
  99. package/dist/viewer/{fr-FR-RHASNOE6-DK7485eH.js → fr-FR-RHASNOE6-DPitHRvA.js} +1 -1
  100. package/dist/viewer/{ganttDiagram-EL5Y4UJY-B7ZYtvS0.js → ganttDiagram-EL5Y4UJY-C0U8ymq7.js} +1 -1
  101. package/dist/viewer/{gitGraph-4MIJSDKK-BJU64oOY.js → gitGraph-4MIJSDKK-Daw_i3tJ.js} +1 -1
  102. package/dist/viewer/{gitGraphDiagram-WWUBYQGX-BzlJNBOl.js → gitGraphDiagram-WWUBYQGX-Dthb-o2D.js} +1 -1
  103. package/dist/viewer/{gl-ES-HMX3MZ6V-Coz8P3nC.js → gl-ES-HMX3MZ6V-D1zxq5pp.js} +1 -1
  104. package/dist/viewer/{he-IL-6SHJWFNN-Bw1C-Lfd.js → he-IL-6SHJWFNN-HcI8Gfi_.js} +1 -1
  105. package/dist/viewer/{hi-IN-IWLTKZ5I-BiL7W4tP.js → hi-IN-IWLTKZ5I-CNtLHhB0.js} +1 -1
  106. package/dist/viewer/{hu-HU-A5ZG7DT2-BdO2CXmc.js → hu-HU-A5ZG7DT2-DbpywuMZ.js} +1 -1
  107. package/dist/viewer/{id-ID-SAP4L64H-DPmtIUTS.js → id-ID-SAP4L64H-C2QNExvG.js} +1 -1
  108. package/dist/viewer/{image-GAAHSSAO-CLpqMfaa.js → image-GAAHSSAO-TyPPpR2i.js} +1 -1
  109. package/dist/viewer/imperative-BoKDIeYO.js +1 -0
  110. package/dist/viewer/index.html +6 -6
  111. package/dist/viewer/index.js +2 -2
  112. package/dist/viewer/index3.css +248 -32
  113. package/dist/viewer/{info-A6RAGUB7-DiEzhTAd.js → info-A6RAGUB7-pdktBRmV.js} +1 -1
  114. package/dist/viewer/{infoDiagram-27XIBGKW-O_KQ5vUR.js → infoDiagram-27XIBGKW-6hKQlvYM.js} +1 -1
  115. package/dist/viewer/{isElementDisabled-B5HhwIRz.js → isElementDisabled-DlOLKm1l.js} +1 -1
  116. package/dist/viewer/{ishikawaDiagram-5VMMS53U-DEzeQl25.js → ishikawaDiagram-5VMMS53U-rWEd0cBR.js} +1 -1
  117. package/dist/viewer/{it-IT-JPQ66NNP-DXIHfZUP.js → it-IT-JPQ66NNP-COrYbkuG.js} +1 -1
  118. package/dist/viewer/{ja-JP-DBVTYXUO-BN-NmmLz.js → ja-JP-DBVTYXUO-Bu0k25Yy.js} +1 -1
  119. package/dist/viewer/{journeyDiagram-3NMN7TZE-DMZCBM5N.js → journeyDiagram-3NMN7TZE-B24CKwTj.js} +1 -1
  120. package/dist/viewer/{kaa-6HZHGXH3-Cf2aRjyQ.js → kaa-6HZHGXH3-Bp6fQD9T.js} +1 -1
  121. package/dist/viewer/{kab-KAB-ZGHBKWFO-DaxQNcuy.js → kab-KAB-ZGHBKWFO-C8AyCneO.js} +1 -1
  122. package/dist/viewer/{kanban-definition-UXKFOSKX-BPvGzWuw.js → kanban-definition-UXKFOSKX-FKdAZ8fK.js} +1 -1
  123. package/dist/viewer/{kk-KZ-P5N5QNE5-CdWRDwAU.js → kk-KZ-P5N5QNE5-ClWVWRrv.js} +1 -1
  124. package/dist/viewer/{km-KH-HSX4SM5Z-DwDKeeQW.js → km-KH-HSX4SM5Z-CmZXvsM-.js} +1 -1
  125. package/dist/viewer/{ko-KR-MTYHY66A-DmoJHfeE.js → ko-KR-MTYHY66A-CPwIJHkW.js} +1 -1
  126. package/dist/viewer/{ku-TR-6OUDTVRD-EbkCBaoM.js → ku-TR-6OUDTVRD-DgjBlS9p.js} +1 -1
  127. package/dist/viewer/{lt-LT-XHIRWOB4-ttiVTTyi.js → lt-LT-XHIRWOB4-m2fbKT4M.js} +1 -1
  128. package/dist/viewer/{lv-LV-5QDEKY6T-Dm2r8CU_.js → lv-LV-5QDEKY6T-utqte3AK.js} +1 -1
  129. package/dist/viewer/{mermaid-parser.core--INiMQUg.js → mermaid-parser.core-CJ_TLs7a.js} +3 -3
  130. package/dist/viewer/{mindmap-definition-YA3MSWOX-BnuGQgIV.js → mindmap-definition-YA3MSWOX-CtlEzi2P.js} +1 -1
  131. package/dist/viewer/motion-mC30FIOF.js +1 -0
  132. package/dist/viewer/{mr-IN-CRQNXWMA-CsijbGQW.js → mr-IN-CRQNXWMA-BlaVAamT.js} +1 -1
  133. package/dist/viewer/{my-MM-5M5IBNSE-Umq4Vjwk.js → my-MM-5M5IBNSE-BJwWEFub.js} +1 -1
  134. package/dist/viewer/{nb-NO-T6EIAALU-Byqsxca5.js → nb-NO-T6EIAALU-D81KeOWy.js} +1 -1
  135. package/dist/viewer/{nl-NL-IS3SIHDZ-BVyuUXlf.js → nl-NL-IS3SIHDZ-Cj2CX_c2.js} +1 -1
  136. package/dist/viewer/{nn-NO-6E72VCQL-WKdXgele.js → nn-NO-6E72VCQL-B6oJZaTv.js} +1 -1
  137. package/dist/viewer/{oc-FR-POXYY2M6-Bp7RcXgc.js → oc-FR-POXYY2M6-GBZCKCVJ.js} +1 -1
  138. package/dist/viewer/{pa-IN-N4M65BXN-KdIB31T7.js → pa-IN-N4M65BXN-Bgw1-57b.js} +1 -1
  139. package/dist/viewer/{packet-AYTQ26CC-DSDWMb02.js → packet-AYTQ26CC-DTFPjbuH.js} +1 -1
  140. package/dist/viewer/{pegDiagram-XKGWAZYB-BON_x692.js → pegDiagram-XKGWAZYB-fsgkJ1ld.js} +1 -1
  141. package/dist/viewer/percentages-BXMCSKIN-BQuQ9kzE.js +1 -0
  142. package/dist/viewer/{pie-WAS4IAKB-B3rcs5dW.js → pie-WAS4IAKB-DdPBzAM_.js} +1 -1
  143. package/dist/viewer/{pieDiagram-E7YTZNPT-CN1Ko9SQ.js → pieDiagram-E7YTZNPT-DP_FPyXM.js} +1 -1
  144. package/dist/viewer/{pl-PL-T2D74RX3-dRV68Yin.js → pl-PL-T2D74RX3-DmyzsXJt.js} +1 -1
  145. package/dist/viewer/preview.html +4 -4
  146. package/dist/viewer/preview.js +1 -1
  147. package/dist/viewer/{prod-BMwCft-P.js → prod-DDiwqUQh.js} +9 -9
  148. package/dist/viewer/{pt-BR-5N22H2LF-CRj89bDT.js → pt-BR-5N22H2LF-Bj9Kj8Ul.js} +1 -1
  149. package/dist/viewer/{pt-PT-UZXXM6DQ-B45uGq70.js → pt-PT-UZXXM6DQ-C_EqQWHm.js} +1 -1
  150. package/dist/viewer/{quadrantDiagram-AXDQQJYC-5ugI62Vp.js → quadrantDiagram-AXDQQJYC-D04blpbC.js} +1 -1
  151. package/dist/viewer/{radar-RG4KPBEZ-CjGn-SXa.js → radar-RG4KPBEZ-BFtZ6ciI.js} +1 -1
  152. package/dist/viewer/{railroad-74A4TZTK-CN75L6wG.js → railroad-74A4TZTK-BeVCUOYi.js} +1 -1
  153. package/dist/viewer/{railroad-abnf-HS5TGJTU-B6W4GDU4.js → railroad-abnf-HS5TGJTU-C3KJFnHO.js} +1 -1
  154. package/dist/viewer/{railroad-ebnf-LZEXJU2U-BCPnXHNN.js → railroad-ebnf-LZEXJU2U-Dt62yu5i.js} +1 -1
  155. package/dist/viewer/{railroad-peg-WCYAUIDC-BISs-jrV.js → railroad-peg-WCYAUIDC-JPoDiBQ4.js} +1 -1
  156. package/dist/viewer/{railroadDiagram-O6MQD6OU-Bv8ldze_.js → railroadDiagram-O6MQD6OU-BTmGIxQj.js} +1 -1
  157. package/dist/viewer/{requirementDiagram-BXWQKSXE-Bjlm3_ci.js → requirementDiagram-BXWQKSXE-BPb6P6dJ.js} +1 -1
  158. package/dist/viewer/{ro-RO-JPDTUUEW-oOac9uH1.js → ro-RO-JPDTUUEW-BFA-iuy6.js} +1 -1
  159. package/dist/viewer/{route-SarJeSGK.js → route-AvpwHtQ0.js} +3 -3
  160. package/dist/viewer/{ru-RU-B4JR7IUQ-BNL720DN.js → ru-RU-B4JR7IUQ-Dm5DHvTI.js} +1 -1
  161. package/dist/viewer/{sankeyDiagram-P5KCCOFB-B094hBX9.js → sankeyDiagram-P5KCCOFB-CngHk6n5.js} +1 -1
  162. package/dist/viewer/{selection-DZJvfcM7.js → selection-CG01cDRg.js} +1 -1
  163. package/dist/viewer/{sequenceDiagram-WJ2MYXX4-DfvHFFgM.js → sequenceDiagram-WJ2MYXX4-DM--FG4f.js} +1 -1
  164. package/dist/viewer/settings-dialog-CKL1Rare.js +1 -0
  165. package/dist/viewer/{si-LK-N5RQ5JYF-EU8NqdhN.js → si-LK-N5RQ5JYF-mQz2qLHL.js} +1 -1
  166. package/dist/viewer/{sk-SK-C5VTKIMK-CWvKfWq2.js → sk-SK-C5VTKIMK-BVCvu4cr.js} +1 -1
  167. package/dist/viewer/{sl-SI-NN7IZMDC-BxRa9VK0.js → sl-SI-NN7IZMDC-B1B_Utop.js} +1 -1
  168. package/dist/viewer/{stateDiagram-D77RDMKH-4po_4TLv.js → stateDiagram-D77RDMKH-C34xM9vZ.js} +1 -1
  169. package/dist/viewer/stateDiagram-v2-MP3YSRHH-CmcHJTDl.js +1 -0
  170. package/dist/viewer/subset-shared.chunk-DGo3GcBn.js +1 -0
  171. package/dist/viewer/{subset-worker.chunk-wq_jSltG.js → subset-worker.chunk-H0E9lZx4.js} +1 -1
  172. package/dist/viewer/{sv-SE-XGPEYMSR-LvNrRcKm.js → sv-SE-XGPEYMSR-CshPFtOd.js} +1 -1
  173. package/dist/viewer/{swimlanes-42K2YHIH-ztwGkPcM.js → swimlanes-42K2YHIH-DKQUSlHr.js} +1 -1
  174. package/dist/viewer/swimlanesDiagram-VR7AAH4N-Bas_dh9E.js +8 -0
  175. package/dist/viewer/{ta-IN-2NMHFXQM-X91v9Hxx.js → ta-IN-2NMHFXQM-BUzjvp6c.js} +1 -1
  176. package/dist/viewer/{th-TH-HPSO5L25-BJKhwfvk.js → th-TH-HPSO5L25-De_beC87.js} +1 -1
  177. package/dist/viewer/{timeline-definition-24CTP7MA-BQIxdGCX.js → timeline-definition-24CTP7MA-n8HUXCcs.js} +1 -1
  178. package/dist/viewer/{tr-TR-DEFEU3FU-Fu3jGGeC.js → tr-TR-DEFEU3FU-BDjzfyI6.js} +1 -1
  179. package/dist/viewer/{treeView-Q6P3EWNA-DjM_2XMh.js → treeView-Q6P3EWNA-CmVlqO-f.js} +1 -1
  180. package/dist/viewer/{treemap-WGGIJYW6-C_eb7yMC.js → treemap-WGGIJYW6-BY6AU_-U.js} +1 -1
  181. package/dist/viewer/type-icons-DIqdHpNs.js +1 -0
  182. package/dist/viewer/{uk-UA-QMV73CPH-C07sMbqL.js → uk-UA-QMV73CPH-D46I3DIU.js} +1 -1
  183. package/dist/viewer/useArtifactFeed-wZCufqRF.js +1 -0
  184. package/dist/viewer/useCloudStatus-BW87y06N.js +1 -0
  185. package/dist/viewer/useOpenInteractionType-BqeMFAmy.js +1 -0
  186. package/dist/viewer/{useTranslation-B-Mo8yST.js → useTranslation-nbxMKAeb.js} +1 -1
  187. package/dist/viewer/useTypeFavicon-DI5lho2O.js +1 -0
  188. package/dist/viewer/{vennDiagram-4TSXK5OY-C_9HjFJz.js → vennDiagram-4TSXK5OY-BLyvow_2.js} +1 -1
  189. package/dist/viewer/{vi-VN-M7AON7JQ-BwsKFTBC.js → vi-VN-M7AON7JQ-DNhl5nmX.js} +1 -1
  190. package/dist/viewer/{view-CplUMkts.js → view-B3xgxhtB.js} +1 -1
  191. package/dist/viewer/{viewport-CFJHn_Y6-DfM_M655.js → viewport-CFJHn_Y6-ChjV1NbS.js} +1 -1
  192. package/dist/viewer/{wardley-WFR3VGLG-C5I_BM43.js → wardley-WFR3VGLG-CBnFUIlR.js} +1 -1
  193. package/dist/viewer/{wardleyDiagram-VM6X3IG4-CwgquM54.js → wardleyDiagram-VM6X3IG4-DyC974XY.js} +1 -1
  194. package/dist/viewer/{xychartDiagram-S5SC5T6Z-CpRK9Uig.js → xychartDiagram-S5SC5T6Z-BHyLgPEE.js} +1 -1
  195. package/dist/viewer/{zh-CN-LNUGB5OW-BLNCLEAr.js → zh-CN-LNUGB5OW-CHQ6BdAL.js} +1 -1
  196. package/dist/viewer/{zh-HK-E62DVLB3-DfitQXFz.js → zh-HK-E62DVLB3-BNrhSeiz.js} +1 -1
  197. package/dist/viewer/{zh-TW-RAJ6MFWO-RINbQ-MK.js → zh-TW-RAJ6MFWO-CFU1WKQr.js} +1 -1
  198. package/dist/viewer-lib/{Canvas-D-rufZfS.js → Canvas-DOK6z2BX.js} +2 -2
  199. package/dist/viewer-lib/{PreviewView-Dd56IDSJ.js → PreviewView-C4H6LbEb.js} +2 -2
  200. package/dist/viewer-lib/{SnapshotDocument-B-EEB3EF.js → SnapshotDocument-xXPe1i3_.js} +30 -30
  201. package/dist/viewer-lib/{VirtualizedEditor-D9Ivycdp-M2EjbiEO.js → VirtualizedEditor-D9Ivycdp-rqZrlTHM.js} +2 -2
  202. package/dist/viewer-lib/{VirtualizedRenderer-C_d95FXi-CrMn0UKy.js → VirtualizedRenderer-C_d95FXi-CDW2p3mp.js} +3 -3
  203. package/dist/viewer-lib/{WarningsBadge-5iaPvvwB.js → WarningsBadge-DU-Jdq4l.js} +101 -91
  204. package/dist/viewer-lib/{abnfDiagram-VCTEODGH-CHvV8PF_.js → abnfDiagram-VCTEODGH-YqykIlJJ.js} +2 -2
  205. package/dist/viewer-lib/{ar-SA-G6X2FPQ2-CMW9_pJR.js → ar-SA-G6X2FPQ2-B0wYqs-G.js} +1 -1
  206. package/dist/viewer-lib/{architectureDiagram-5GKGNRK7-CW6JxzgJ.js → architectureDiagram-5GKGNRK7-BjGzPHZW.js} +3 -3
  207. package/dist/viewer-lib/{az-AZ-76LH7QW2-BbZYXuHB.js → az-AZ-76LH7QW2-fYGdY3sZ.js} +1 -1
  208. package/dist/viewer-lib/{bg-BG-XCXSNQG7-BB6sf3ed.js → bg-BG-XCXSNQG7-CC9O7d06.js} +1 -1
  209. package/dist/viewer-lib/{blockDiagram-I7D4REHJ-RzwJ7VKh.js → blockDiagram-I7D4REHJ-BsRuqk0i.js} +5 -5
  210. package/dist/viewer-lib/{bn-BD-2XOGV67Q-DN8txFKG.js → bn-BD-2XOGV67Q-CYb4pikN.js} +1 -1
  211. package/dist/viewer-lib/{c4Diagram-7LVT6UL2-Dw3Db7Md.js → c4Diagram-7LVT6UL2-44J9M0Fu.js} +3 -3
  212. package/dist/viewer-lib/{ca-ES-6MX7JW3Y-wN9zkQOK.js → ca-ES-6MX7JW3Y-CMvO2x_s.js} +1 -1
  213. package/dist/viewer-lib/{chunk-4HAMMTFA-Suqljc2D.js → chunk-4HAMMTFA-RSuW1tKo.js} +2 -2
  214. package/dist/viewer-lib/{chunk-EIO257PC-CajPjv2S.js → chunk-EIO257PC-C543d4aE.js} +1 -1
  215. package/dist/viewer-lib/{chunk-GMAD6QVW-3SWqmIfw.js → chunk-GMAD6QVW-B4QtFgip.js} +1 -1
  216. package/dist/viewer-lib/{chunk-GVQU2GXP-BXD4pZf8.js → chunk-GVQU2GXP-D-v6Ha7C.js} +1 -1
  217. package/dist/viewer-lib/{chunk-IMKFNOWR-CeX8kqWp.js → chunk-IMKFNOWR-E5LEUINi.js} +1 -1
  218. package/dist/viewer-lib/{chunk-L3NEJ4N5-qNfJ9acg.js → chunk-L3NEJ4N5-CTKrWu0l.js} +3 -3
  219. package/dist/viewer-lib/{chunk-OSK3NFVY-DzdJozJx.js → chunk-OSK3NFVY-AcwuU79x.js} +4 -4
  220. package/dist/viewer-lib/{chunk-PWAF6VOD-Bo4xQ0Dl.js → chunk-PWAF6VOD-456pCZtf.js} +1 -1
  221. package/dist/viewer-lib/{chunk-SHT3W25Y-7hUF9_6b.js → chunk-SHT3W25Y-BT2L-Nq2.js} +2 -2
  222. package/dist/viewer-lib/{chunk-SVP7TREG-BhG1TE-W.js → chunk-SVP7TREG-bbLswzWZ.js} +1 -1
  223. package/dist/viewer-lib/{chunk-TICWLB2K-cmc1gQ3R.js → chunk-TICWLB2K-Cym0r7mq.js} +1 -1
  224. package/dist/viewer-lib/{classDiagram-ZZMXUADV-pcnSFWmE.js → classDiagram-ZZMXUADV-BYTrv6vT.js} +8 -8
  225. package/dist/viewer-lib/{classDiagram-v2-VYDZK3BY-D9mwG0Qg.js → classDiagram-v2-VYDZK3BY-ztGdDzKu.js} +8 -8
  226. package/dist/viewer-lib/core.js +4 -4
  227. package/dist/viewer-lib/{cs-CZ-2BRQDIVT-D9lsZuqm.js → cs-CZ-2BRQDIVT-DYTP0XfM.js} +1 -1
  228. package/dist/viewer-lib/{cynefinDiagram-5FMLGOSQ-CIxTpmjU.js → cynefinDiagram-5FMLGOSQ-CDRd2npA.js} +1 -1
  229. package/dist/viewer-lib/{da-DK-5WZEPLOC-F7FXe8Jt.js → da-DK-5WZEPLOC-Bgl2xnq4.js} +1 -1
  230. package/dist/viewer-lib/{dagre-GXQ25YYZ-CIzeFY9n.js → dagre-GXQ25YYZ-B_E19_Y3.js} +7 -7
  231. package/dist/viewer-lib/{de-DE-XR44H4JA-BU6FjufA.js → de-DE-XR44H4JA-B_9yjTkX.js} +1 -1
  232. package/dist/viewer-lib/{diagram-S7CK7UJ4-CGzjFRWZ.js → diagram-S7CK7UJ4-CLGvhy03.js} +2 -2
  233. package/dist/viewer-lib/{diagram-UQ7AKVKN-CatTh89o.js → diagram-UQ7AKVKN-B8CPJRt_.js} +1 -1
  234. package/dist/viewer-lib/{diagram-VX7I27RA-DtsRUcWB.js → diagram-VX7I27RA-BjvHx1wP.js} +2 -2
  235. package/dist/viewer-lib/{diagram-Z3DM3KII-DdUPStBy.js → diagram-Z3DM3KII-AjK9RwX7.js} +1 -1
  236. package/dist/viewer-lib/{dist-CMRASEhK.js → dist-7znyEIWQ.js} +1 -1
  237. package/dist/viewer-lib/{dist-PReccape.js → dist-BKgXQ0cV.js} +3 -3
  238. package/dist/viewer-lib/{dist-B8AEREoS.js → dist-BO_tdD3l.js} +3 -3
  239. package/dist/viewer-lib/{dist-Drf6OaF1.js → dist-Bbb-o5hb.js} +2 -2
  240. package/dist/viewer-lib/{dist-xyk_hln4.js → dist-BvNA2jeq.js} +1 -1
  241. package/dist/viewer-lib/{dist-BDUqDzy9.js → dist-Bvp56esL.js} +3 -3
  242. package/dist/viewer-lib/{dist-DTl5QCyR.js → dist-C5v55Pj0.js} +4 -4
  243. package/dist/viewer-lib/{dist-BvPIj-qB.js → dist-CFkmA2ex.js} +2 -2
  244. package/dist/viewer-lib/{dist-BFY2ZiYk.js → dist-CLwDFyvt.js} +3 -3
  245. package/dist/viewer-lib/{dist-BcQpARaT.js → dist-CM_tOX0e.js} +4 -4
  246. package/dist/viewer-lib/{dist-CkOJGtUE.js → dist-CSJQOWTJ.js} +2 -2
  247. package/dist/viewer-lib/{dist-zSCKbVng.js → dist-CVUYUORh.js} +3 -3
  248. package/dist/viewer-lib/{dist-BmESdVFb.js → dist-CcsdRQum.js} +2 -2
  249. package/dist/viewer-lib/{dist-DFFAS1Vn.js → dist-Cyw2JYar.js} +3 -3
  250. package/dist/viewer-lib/{dist-C3BcbVCO.js → dist-D5TaRFkk.js} +2 -2
  251. package/dist/viewer-lib/{dist-iPo5zoOe.js → dist-D7x4zJxC.js} +4 -4
  252. package/dist/viewer-lib/{dist-xaHl1532.js → dist-DGW5LdH2.js} +2 -2
  253. package/dist/viewer-lib/{dist-a5INrNFT.js → dist-DegtlHJv.js} +43 -43
  254. package/dist/viewer-lib/{dist-TrwrsGSN.js → dist-Df_KUgHq.js} +2 -2
  255. package/dist/viewer-lib/{dist-DJ3RCCqc.js → dist-Dl_5s-iz.js} +3 -3
  256. package/dist/viewer-lib/{dist-BbsCfdbH.js → dist-RhakSQnk.js} +3 -3
  257. package/dist/viewer-lib/{dist-B5ffmw5h.js → dist-Xd8yIz07.js} +3 -3
  258. package/dist/viewer-lib/{dist-BjQT8nDj.js → dist-kkYu1rRh.js} +3 -3
  259. package/dist/viewer-lib/{dist-DDXUfu7W.js → dist-ldjjGCri.js} +2 -2
  260. package/dist/viewer-lib/document.js +117 -116
  261. package/dist/viewer-lib/{ebnfDiagram-PWID7BFC-Bt3LxZK7.js → ebnfDiagram-PWID7BFC-Bp45Kw0j.js} +2 -2
  262. package/dist/viewer-lib/{el-GR-BZB4AONW-D0_Zd4UO.js → el-GR-BZB4AONW-BC5iT_GL.js} +1 -1
  263. package/dist/viewer-lib/{en-B4ZKOASM-uCqTSYU4.js → en-B4ZKOASM-DsxOsSdR.js} +1 -1
  264. package/dist/viewer-lib/{erDiagram-RLTQ6QDP-BslNHJPz.js → erDiagram-RLTQ6QDP-DSwSrnrb.js} +7 -7
  265. package/dist/viewer-lib/{es-ES-U4NZUMDT-D3CLA_Ev.js → es-ES-U4NZUMDT-DHpnejwp.js} +1 -1
  266. package/dist/viewer-lib/{eu-ES-A7QVB2H4-CQPfruJ_.js → eu-ES-A7QVB2H4-Ba3wZ7fr.js} +1 -1
  267. package/dist/viewer-lib/{fa-IR-HGAKTJCU-C4r09Pgj.js → fa-IR-HGAKTJCU-Op9Vl4qk.js} +1 -1
  268. package/dist/viewer-lib/{fi-FI-Z5N7JZ37-Dmx_csnp.js → fi-FI-Z5N7JZ37-D6gDkilI.js} +1 -1
  269. package/dist/viewer-lib/flowDiagram-HODETNUW-DtKd16OO.js +15 -0
  270. package/dist/viewer-lib/{fr-FR-RHASNOE6-Ckq1aGt3.js → fr-FR-RHASNOE6-BDhchzHk.js} +1 -1
  271. package/dist/viewer-lib/{ganttDiagram-EL5Y4UJY-ZzgHeDnr.js → ganttDiagram-EL5Y4UJY-CSCI-e5l.js} +1 -1
  272. package/dist/viewer-lib/{gl-ES-HMX3MZ6V-q4ah19hZ.js → gl-ES-HMX3MZ6V-jGVTtLtD.js} +1 -1
  273. package/dist/viewer-lib/{he-IL-6SHJWFNN-DGxeq-ys.js → he-IL-6SHJWFNN-Bp_3pC-s.js} +1 -1
  274. package/dist/viewer-lib/{hi-IN-IWLTKZ5I-DVzSm0z0.js → hi-IN-IWLTKZ5I-BoA0Nann.js} +1 -1
  275. package/dist/viewer-lib/{hu-HU-A5ZG7DT2-cxC6ylz_.js → hu-HU-A5ZG7DT2-C9RAdEQY.js} +1 -1
  276. package/dist/viewer-lib/{i18n-C0ysopzN.js → i18n-B_9P4TsB.js} +155 -20
  277. package/dist/viewer-lib/{id-ID-SAP4L64H-ig8IFWIm.js → id-ID-SAP4L64H-C9byTm8s.js} +1 -1
  278. package/dist/viewer-lib/{image-GAAHSSAO-DFlqDwdJ.js → image-GAAHSSAO-CS_zxJfn.js} +1 -1
  279. package/dist/viewer-lib/index.js +2793 -2388
  280. package/dist/viewer-lib/{infoDiagram-27XIBGKW-Bb9WnLmR.js → infoDiagram-27XIBGKW-CZHqVY-5.js} +1 -1
  281. package/dist/viewer-lib/{ishikawaDiagram-5VMMS53U-ilRlDRaV.js → ishikawaDiagram-5VMMS53U-DMNy53oh.js} +1 -1
  282. package/dist/viewer-lib/{it-IT-JPQ66NNP-CkORdMBk.js → it-IT-JPQ66NNP-Bt0vgcSt.js} +1 -1
  283. package/dist/viewer-lib/{ja-JP-DBVTYXUO-BXREoVCO.js → ja-JP-DBVTYXUO-DVll3FiL.js} +1 -1
  284. package/dist/viewer-lib/{journeyDiagram-3NMN7TZE-CluKG8SL.js → journeyDiagram-3NMN7TZE-DTlywGtZ.js} +1 -1
  285. package/dist/viewer-lib/{kaa-6HZHGXH3-Cxa9_wPB.js → kaa-6HZHGXH3-gHd-MfDE.js} +1 -1
  286. package/dist/viewer-lib/{kab-KAB-ZGHBKWFO-C0P1jlHT.js → kab-KAB-ZGHBKWFO-CBHXk5lk.js} +1 -1
  287. package/dist/viewer-lib/{kanban-definition-UXKFOSKX-CJ7FNQUD.js → kanban-definition-UXKFOSKX-DNFILJoS.js} +6 -6
  288. package/dist/viewer-lib/{kk-KZ-P5N5QNE5-B7_der9I.js → kk-KZ-P5N5QNE5-DWDyP_rV.js} +1 -1
  289. package/dist/viewer-lib/{km-KH-HSX4SM5Z-9iHzVgyY.js → km-KH-HSX4SM5Z-CqD9viK7.js} +1 -1
  290. package/dist/viewer-lib/{ko-KR-MTYHY66A-BGtas9i6.js → ko-KR-MTYHY66A-gpdvpFPO.js} +1 -1
  291. package/dist/viewer-lib/{ku-TR-6OUDTVRD-S0qxJ75e.js → ku-TR-6OUDTVRD-DiuznBBd.js} +1 -1
  292. package/dist/viewer-lib/{lt-LT-XHIRWOB4-CtQz9FQW.js → lt-LT-XHIRWOB4-DeLRyed7.js} +1 -1
  293. package/dist/viewer-lib/{lv-LV-5QDEKY6T-DY6FyG8O.js → lv-LV-5QDEKY6T-CcZSIAOy.js} +1 -1
  294. package/dist/viewer-lib/{mindmap-definition-YA3MSWOX-CDw7aNaK.js → mindmap-definition-YA3MSWOX-Bj_SM-mo.js} +7 -7
  295. package/dist/viewer-lib/{motion-BkUMioN-.js → motion-CEJYVOkn.js} +689 -649
  296. package/dist/viewer-lib/{mr-IN-CRQNXWMA-CHxgYQO0.js → mr-IN-CRQNXWMA-BNuoeL_h.js} +1 -1
  297. package/dist/viewer-lib/{my-MM-5M5IBNSE-CrL1Wfhw.js → my-MM-5M5IBNSE-CyXd6yAG.js} +1 -1
  298. package/dist/viewer-lib/{nb-NO-T6EIAALU-D7ArkbmG.js → nb-NO-T6EIAALU-RKryZ1dI.js} +1 -1
  299. package/dist/viewer-lib/{nl-NL-IS3SIHDZ-zUrrv-Zj.js → nl-NL-IS3SIHDZ-a-3oXOgl.js} +1 -1
  300. package/dist/viewer-lib/{nn-NO-6E72VCQL-Cp6Zisx3.js → nn-NO-6E72VCQL-BghfJkWl.js} +1 -1
  301. package/dist/viewer-lib/{oc-FR-POXYY2M6-DyaXh-AY.js → oc-FR-POXYY2M6-DrDJ9kDz.js} +1 -1
  302. package/dist/viewer-lib/{pa-IN-N4M65BXN-GykIyXNX.js → pa-IN-N4M65BXN-BxmLiZX2.js} +1 -1
  303. package/dist/viewer-lib/{pegDiagram-XKGWAZYB-B_IpC9yU.js → pegDiagram-XKGWAZYB-DLIG7VFJ.js} +2 -2
  304. package/dist/viewer-lib/percentages-BXMCSKIN-Cie5TsMd.js +1 -0
  305. package/dist/viewer-lib/{pieDiagram-E7YTZNPT-B3uFhVNF.js → pieDiagram-E7YTZNPT-BwJiW3eQ.js} +2 -2
  306. package/dist/viewer-lib/{pl-PL-T2D74RX3-JFBP8dTN.js → pl-PL-T2D74RX3-BkY8C61G.js} +1 -1
  307. package/dist/viewer-lib/{plugin-_bGVeqI0-CTReX5cX.js → plugin-_bGVeqI0-B-UTFpR1.js} +1 -1
  308. package/dist/viewer-lib/{prod-DonOgEJg.js → prod-D-WDDFnX.js} +61 -61
  309. package/dist/viewer-lib/{pt-BR-5N22H2LF-BeJ3K68L.js → pt-BR-5N22H2LF-COB5WMBI.js} +1 -1
  310. package/dist/viewer-lib/{pt-PT-UZXXM6DQ-bpAwIgzs.js → pt-PT-UZXXM6DQ-CQkAsr3d.js} +1 -1
  311. package/dist/viewer-lib/{quadrantDiagram-AXDQQJYC-DuwRJDS2.js → quadrantDiagram-AXDQQJYC-DJwWtyfa.js} +1 -1
  312. package/dist/viewer-lib/{railroadDiagram-O6MQD6OU-BC811ka0.js → railroadDiagram-O6MQD6OU-mKa56oUm.js} +2 -2
  313. package/dist/viewer-lib/{requirementDiagram-BXWQKSXE-BlLr6i3v.js → requirementDiagram-BXWQKSXE-C3kU2CBH.js} +7 -7
  314. package/dist/viewer-lib/{ro-RO-JPDTUUEW-BbXQ-48M.js → ro-RO-JPDTUUEW-CcfUY_L9.js} +1 -1
  315. package/dist/viewer-lib/{ru-RU-B4JR7IUQ-rNPqFoCj.js → ru-RU-B4JR7IUQ-0fvHk0L6.js} +1 -1
  316. package/dist/viewer-lib/{sequenceDiagram-WJ2MYXX4-BSQHdFJU.js → sequenceDiagram-WJ2MYXX4-DzL_cMRb.js} +1 -1
  317. package/dist/viewer-lib/{si-LK-N5RQ5JYF-Do9hMwvn.js → si-LK-N5RQ5JYF-B1OobMqx.js} +1 -1
  318. package/dist/viewer-lib/{sk-SK-C5VTKIMK-D7qJLrGU.js → sk-SK-C5VTKIMK-BH1u-pYh.js} +1 -1
  319. package/dist/viewer-lib/{sl-SI-NN7IZMDC-yvDTpqM5.js → sl-SI-NN7IZMDC-BneIcNMs.js} +1 -1
  320. package/dist/viewer-lib/{stateDiagram-D77RDMKH-C0apUInt.js → stateDiagram-D77RDMKH-C6LiLgKI.js} +9 -9
  321. package/dist/viewer-lib/{stateDiagram-v2-MP3YSRHH-BFybrknE.js → stateDiagram-v2-MP3YSRHH-dY83WYKA.js} +8 -8
  322. package/dist/viewer-lib/{stylex-CnR9LxNX.css → stylex-Bl4LaHjz.css} +104 -4
  323. package/dist/viewer-lib/subset-shared.chunk-D4W2CNEN.js +2 -0
  324. package/dist/viewer-lib/{subset-worker.chunk-B0Q8BSsN.js → subset-worker.chunk-dfNHPRQ8.js} +2 -2
  325. package/dist/viewer-lib/{sv-SE-XGPEYMSR-CW5GqbYY.js → sv-SE-XGPEYMSR-C8_fTUsA.js} +1 -1
  326. package/dist/viewer-lib/{swimlanes-42K2YHIH-CvSqeKnK.js → swimlanes-42K2YHIH-BLOD4KRS.js} +7 -7
  327. package/dist/viewer-lib/{swimlanesDiagram-VR7AAH4N-D7iw7wmp.js → swimlanesDiagram-VR7AAH4N-DSBK6v86.js} +8 -8
  328. package/dist/viewer-lib/{ta-IN-2NMHFXQM-BYobjfot.js → ta-IN-2NMHFXQM-CwTOoiwr.js} +1 -1
  329. package/dist/viewer-lib/{th-TH-HPSO5L25-BIUgeya6.js → th-TH-HPSO5L25-BeCFc2Z1.js} +1 -1
  330. package/dist/viewer-lib/thumbnail.js +3 -4
  331. package/dist/viewer-lib/{timeline-definition-24CTP7MA-m3UjkMFV.js → timeline-definition-24CTP7MA-DRd5EYAC.js} +2 -2
  332. package/dist/viewer-lib/{tr-TR-DEFEU3FU-DXpS7VfG.js → tr-TR-DEFEU3FU-CQLSLbH4.js} +1 -1
  333. package/dist/viewer-lib/types/src/shared/board-comments.d.ts +6 -0
  334. package/dist/viewer-lib/types/src/shared/choices.d.ts +15 -0
  335. package/dist/viewer-lib/types/src/shared/relay.d.ts +5 -0
  336. package/dist/viewer-lib/types/src/shared/rounds.d.ts +17 -0
  337. package/dist/viewer-lib/types/src/shared/thumbnail.d.ts +1 -1
  338. package/dist/viewer-lib/types/src/shared/types.d.ts +3 -0
  339. package/dist/viewer-lib/types/src/viewer/choices/ChoiceRadio.d.ts +10 -0
  340. package/dist/viewer-lib/types/src/viewer/choices/SubmitBar.d.ts +12 -0
  341. package/dist/viewer-lib/types/src/viewer/components/BoardLabel.d.ts +28 -0
  342. package/dist/viewer-lib/types/src/viewer/components/Labels.d.ts +4 -2
  343. package/dist/viewer-lib/types/src/viewer/components/PhoneBoard.d.ts +4 -1
  344. package/dist/viewer-lib/types/src/viewer/components/QuestionSheet.d.ts +2 -1
  345. package/dist/viewer-lib/types/src/viewer/document/author.d.ts +1 -1
  346. package/dist/viewer-lib/types/src/viewer/document/relayConnection.d.ts +2 -1
  347. package/dist/viewer-lib/types/src/viewer/document/transport.d.ts +1 -0
  348. package/dist/viewer-lib/types/src/viewer/hooks/useChoices.d.ts +42 -0
  349. package/dist/viewer-lib/types/src/viewer/layouts/PhoneArtboard.d.ts +3 -1
  350. package/dist/viewer-lib/types/src/viewer/lib/artifact-list.d.ts +1 -1
  351. package/dist/viewer-lib/types/src/viewer/lib/board-anchor.d.ts +1 -0
  352. package/dist/viewer-lib/types/src/viewer/lib/board-comments.d.ts +1 -0
  353. package/dist/viewer-lib/types/src/viewer/lib/board-label.d.ts +7 -1
  354. package/dist/viewer-lib/{uk-UA-QMV73CPH-zscN4C3R.js → uk-UA-QMV73CPH-tspsj7lk.js} +1 -1
  355. package/dist/viewer-lib/{vennDiagram-4TSXK5OY-CCzjJF79.js → vennDiagram-4TSXK5OY-DrAhlPGY.js} +1 -1
  356. package/dist/viewer-lib/{vi-VN-M7AON7JQ-GJ_XH2TF.js → vi-VN-M7AON7JQ-DwhjyLFP.js} +1 -1
  357. package/dist/viewer-lib/{viewport-CFJHn_Y6-B442wtKK.js → viewport-CFJHn_Y6-DtNjRIak.js} +1 -1
  358. package/dist/viewer-lib/{wardleyDiagram-VM6X3IG4-577p1Wr8.js → wardleyDiagram-VM6X3IG4-0c5s6C9i.js} +1 -1
  359. package/dist/viewer-lib/{xychartDiagram-S5SC5T6Z-DjPcRHP-.js → xychartDiagram-S5SC5T6Z-Dt9pXhuk.js} +4 -4
  360. package/dist/viewer-lib/{zh-CN-LNUGB5OW-D980d-Rm.js → zh-CN-LNUGB5OW-BQIGKedi.js} +1 -1
  361. package/dist/viewer-lib/{zh-HK-E62DVLB3-CoV58WGQ.js → zh-HK-E62DVLB3-DVivPitr.js} +1 -1
  362. package/dist/viewer-lib/{zh-TW-RAJ6MFWO-DyMOsftt.js → zh-TW-RAJ6MFWO-YJDVM1cn.js} +1 -1
  363. package/package.json +1 -1
  364. package/dist/viewer/ArtboardLayout-DN0g3tqG.js +0 -12
  365. package/dist/viewer/ArtifactList-CjMej6_V.js +0 -1
  366. package/dist/viewer/DocumentLayout-B-vlYaaN.js +0 -2
  367. package/dist/viewer/MenuSubmenuTrigger-COe4b38C.js +0 -1
  368. package/dist/viewer/PopoverPopup-RtyfhF97.js +0 -1
  369. package/dist/viewer/Select-BeB2ajQf.js +0 -1
  370. package/dist/viewer/SelectScrollUpArrow-vslZD7J8.js +0 -1
  371. package/dist/viewer/TooltipPopup-eli7sLsm.js +0 -1
  372. package/dist/viewer/atoms-Bbj2Tyfn.js +0 -9
  373. package/dist/viewer/channel-CwEpDiSe.js +0 -1
  374. package/dist/viewer/classDiagram-ZZMXUADV-DBWV1Yip.js +0 -1
  375. package/dist/viewer/classDiagram-v2-VYDZK3BY-DBWV1Yip.js +0 -1
  376. package/dist/viewer/flowDiagram-HODETNUW-DLQL4PsS.js +0 -1
  377. package/dist/viewer/imperative-DWB5xQa6.js +0 -1
  378. package/dist/viewer/motion-CLQKXAki.js +0 -1
  379. package/dist/viewer/percentages-BXMCSKIN-CzowFDuV.js +0 -1
  380. package/dist/viewer/settings-dialog-B0jQFKZD.js +0 -1
  381. package/dist/viewer/stateDiagram-v2-MP3YSRHH-CrEknTVX.js +0 -1
  382. package/dist/viewer/subset-shared.chunk-C8FKvIjV.js +0 -1
  383. package/dist/viewer/swimlanesDiagram-VR7AAH4N-DY94WorZ.js +0 -8
  384. package/dist/viewer/type-icons-DGF0mPDe.js +0 -1
  385. package/dist/viewer/useArtifactFeed-BqkH8-F5.js +0 -1
  386. package/dist/viewer/useCloudStatus-1GLyX_cM.js +0 -1
  387. package/dist/viewer/useOpenInteractionType-Dxl1HuDm.js +0 -1
  388. package/dist/viewer/useTypeFavicon-o3Erb_yo.js +0 -1
  389. package/dist/viewer-lib/flowDiagram-HODETNUW-CvT3GdWt.js +0 -15
  390. package/dist/viewer-lib/percentages-BXMCSKIN-DKTUu1Yp.js +0 -1
  391. package/dist/viewer-lib/subset-shared.chunk-KeVb3Y4d.js +0 -2
package/dist/cli.cjs CHANGED
@@ -5185,7 +5185,7 @@ var require_canvas = __commonJS({
5185
5185
  });
5186
5186
 
5187
5187
  // src/cli/main.ts
5188
- var import_node_child_process7 = require("node:child_process");
5188
+ var import_node_child_process6 = require("node:child_process");
5189
5189
 
5190
5190
  // src/cli/command.ts
5191
5191
  var import_node_util = require("node:util");
@@ -5342,9 +5342,48 @@ function rootHelp(commands, browseOptions = {}) {
5342
5342
  ].join("\n");
5343
5343
  }
5344
5344
 
5345
+ // src/server/machine.ts
5346
+ var import_node_fs2 = __toESM(require("node:fs"), 1);
5347
+ var import_node_os2 = __toESM(require("node:os"), 1);
5348
+ var import_node_path2 = __toESM(require("node:path"), 1);
5349
+ var DORMANT_AFTER_MS = 7 * 24 * 60 * 60 * 1e3;
5350
+ function machinePaths(env = process.env, homedir = import_node_os2.default.homedir()) {
5351
+ const home = env.RYUGI_SERVER_HOME || import_node_path2.default.join(homedir, ".ryugi", "server");
5352
+ return {
5353
+ home,
5354
+ pid: import_node_path2.default.join(home, "server.pid"),
5355
+ serverId: import_node_path2.default.join(home, "server-instance-id"),
5356
+ info: import_node_path2.default.join(home, "server-info"),
5357
+ log: import_node_path2.default.join(home, "server.log"),
5358
+ version: import_node_path2.default.join(home, "server-version"),
5359
+ lock: import_node_path2.default.join(home, "start.lock"),
5360
+ key: import_node_path2.default.join(home, "key"),
5361
+ projects: import_node_path2.default.join(home, "projects.json"),
5362
+ settings: import_node_path2.default.join(home, "settings.json"),
5363
+ stopped: import_node_path2.default.join(home, "server-stopped")
5364
+ };
5365
+ }
5366
+ function ensureHome(home) {
5367
+ import_node_fs2.default.mkdirSync(home, { recursive: true, mode: 448 });
5368
+ import_node_fs2.default.chmodSync(home, 448);
5369
+ }
5370
+ var validEntry = (value) => {
5371
+ const entry = value;
5372
+ return !!entry && typeof entry.dir === "string" && import_node_path2.default.isAbsolute(entry.dir) && Number.isFinite(entry.registeredAt) && Number.isFinite(entry.lastUsedAt);
5373
+ };
5374
+ function readProjects(file) {
5375
+ try {
5376
+ const value = JSON.parse(import_node_fs2.default.readFileSync(file, "utf8"));
5377
+ return Array.isArray(value.projects) ? value.projects.filter(validEntry) : [];
5378
+ } catch {
5379
+ return [];
5380
+ }
5381
+ }
5382
+ var artifactsRootOf = (projectDir) => import_node_path2.default.join(projectDir, ".ryugi", "artifacts");
5383
+
5345
5384
  // src/cli/process.ts
5346
5385
  var import_node_child_process = require("node:child_process");
5347
- var import_node_fs2 = __toESM(require("node:fs"), 1);
5386
+ var import_node_fs3 = __toESM(require("node:fs"), 1);
5348
5387
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5349
5388
  function alive(pid) {
5350
5389
  try {
@@ -5356,7 +5395,7 @@ function alive(pid) {
5356
5395
  }
5357
5396
  function commandLine(pid) {
5358
5397
  try {
5359
- return import_node_fs2.default.readFileSync(`/proc/${pid}/cmdline`, "utf8").split("\0");
5398
+ return import_node_fs3.default.readFileSync(`/proc/${pid}/cmdline`, "utf8").split("\0");
5360
5399
  } catch {
5361
5400
  }
5362
5401
  const direct = (0, import_node_child_process.spawnSync)("ps", ["-ww", "-p", String(pid), "-o", "command="], {
@@ -5381,19 +5420,13 @@ function hasServerId(pid, id) {
5381
5420
  if (process.platform === "win32") return windowsNodeAt(pid);
5382
5421
  return commandLine(pid)?.includes(`--artifacts-server-id=${id}`) ?? false;
5383
5422
  }
5384
- function parentOf(pid) {
5385
- if (process.platform === "win32") return null;
5386
- const result = (0, import_node_child_process.spawnSync)("ps", ["-o", "ppid=", "-p", String(pid)], { encoding: "utf8" });
5387
- const parent = Number(result.stdout.trim());
5388
- return Number.isInteger(parent) && parent > 1 ? parent : null;
5389
- }
5390
5423
  async function waitForExit(pid, ms) {
5391
5424
  for (let waited = 0; waited < ms && alive(pid); waited += 100) await sleep(100);
5392
5425
  return !alive(pid);
5393
5426
  }
5394
5427
  var readText = (file) => {
5395
5428
  try {
5396
- return import_node_fs2.default.readFileSync(file, "utf8").replace(/[\r\n]+$/, "");
5429
+ return import_node_fs3.default.readFileSync(file, "utf8").replace(/[\r\n]+$/, "");
5397
5430
  } catch {
5398
5431
  return null;
5399
5432
  }
@@ -5401,15 +5434,28 @@ var readText = (file) => {
5401
5434
 
5402
5435
  // src/cli/server.ts
5403
5436
  var notRunning = (project) => `No artifacts server is running for this project. Start it with \`${invocation()} start --project-dir ${project}\`, then run this again.`;
5404
- function serverClient(projectDir) {
5405
- const paths = projectPaths(projectDir);
5406
- let info;
5437
+ var readUrl = (file) => {
5407
5438
  try {
5408
- info = JSON.parse(readText(paths.info) ?? "");
5439
+ const { url } = JSON.parse(readText(file) ?? "");
5440
+ return typeof url === "string" ? url : null;
5409
5441
  } catch {
5410
- throw new CliError(notRunning(paths.project));
5442
+ return null;
5411
5443
  }
5412
- const base = new URL(info.url);
5444
+ };
5445
+ function serverUrl(project, projectInfo) {
5446
+ const machine = machinePaths();
5447
+ const machineUrl = readUrl(machine.info);
5448
+ if (machineUrl) {
5449
+ const registered = readProjects(machine.projects).some((entry) => entry.dir === project);
5450
+ return registered ? machineUrl : null;
5451
+ }
5452
+ return readUrl(projectInfo);
5453
+ }
5454
+ function serverClient(projectDir) {
5455
+ const paths = projectPaths(projectDir);
5456
+ const url = serverUrl(paths.project, paths.info);
5457
+ if (!url) throw new CliError(notRunning(paths.project));
5458
+ const base = new URL(url);
5413
5459
  const key2 = base.searchParams.get("key") ?? "";
5414
5460
  if (base.hostname === "localhost") base.hostname = "127.0.0.1";
5415
5461
  return {
@@ -5419,7 +5465,10 @@ function serverClient(projectDir) {
5419
5465
  try {
5420
5466
  res = await fetch(`${base.origin}${route}?key=${encodeURIComponent(key2)}`, {
5421
5467
  method,
5422
- headers: body ? { "Content-Type": "application/json" } : {},
5468
+ headers: {
5469
+ "X-Ryugi-Project": encodeURIComponent(paths.project),
5470
+ ...body ? { "Content-Type": "application/json" } : {}
5471
+ },
5423
5472
  body: body ? JSON.stringify(body) : void 0
5424
5473
  });
5425
5474
  } catch {
@@ -5480,7 +5529,7 @@ var checkCommand = {
5480
5529
  };
5481
5530
 
5482
5531
  // src/cli/comment.ts
5483
- var import_node_fs3 = __toESM(require("node:fs"), 1);
5532
+ var import_node_fs4 = __toESM(require("node:fs"), 1);
5484
5533
 
5485
5534
  // src/server/agent.ts
5486
5535
  var NAMES = {
@@ -5568,17 +5617,18 @@ function detectAgent(env) {
5568
5617
  }
5569
5618
 
5570
5619
  // src/cli/comment.ts
5571
- var COMMENT_ACTIONS = ["list", "add", "reply", "resolve"];
5620
+ var COMMENT_ACTIONS = ["list", "add", "reply", "resolve", "choose", "submit"];
5572
5621
  var ARTIFACT = /^(?:document|artboard)\/[a-z0-9][a-z0-9-]*$/;
5573
5622
  var WRITTEN = {
5574
5623
  add: "comment-added",
5575
5624
  reply: "comment-replied",
5576
5625
  resolve: "comment-resolved"
5577
5626
  };
5627
+ var RECORDED = { choose: "choice-recorded", submit: "round-submitted" };
5578
5628
  function readStdin() {
5579
5629
  if (process.stdin.isTTY) return "";
5580
5630
  try {
5581
- return import_node_fs3.default.readFileSync(0, "utf8");
5631
+ return import_node_fs4.default.readFileSync(0, "utf8");
5582
5632
  } catch {
5583
5633
  return "";
5584
5634
  }
@@ -5596,6 +5646,18 @@ function coordinate(value, flag) {
5596
5646
  }
5597
5647
  function requestOf(options, action, type) {
5598
5648
  if (action === "list") return { op: "list", all: !!options.all };
5649
+ if ((action === "choose" || action === "submit") && type !== "artboard")
5650
+ throw new CliError(`comment ${action} works on artboards only`);
5651
+ if (action === "choose") {
5652
+ if (!options.group) throw new CliError("comment choose needs --group <groupId>");
5653
+ if (!options.clear && !options.board)
5654
+ throw new CliError("comment choose needs --board <boardId>, or --clear");
5655
+ return { op: "choose", group: options.group, board: options.clear ? null : options.board };
5656
+ }
5657
+ if (action === "submit") {
5658
+ if (!options.round) throw new CliError("comment submit needs --round <roundId>");
5659
+ return { op: "submit", round: options.round, submit: !options.withdraw };
5660
+ }
5599
5661
  if (action === "add" && type === "artboard") {
5600
5662
  if (!options.board) throw new CliError("comment add on an artboard needs --board <boardId>");
5601
5663
  const x = coordinate(options.x, "--x");
@@ -5622,7 +5684,8 @@ function requestOf(options, action, type) {
5622
5684
  }
5623
5685
  async function comment(options, emit) {
5624
5686
  const action = COMMENT_ACTIONS.find((name) => name === options.action);
5625
- if (!action) throw new CliError("comment needs an action: list, add, reply or resolve");
5687
+ if (!action)
5688
+ throw new CliError("comment needs an action: list, add, reply, resolve, choose or submit");
5626
5689
  if (!options.artifact || !ARTIFACT.test(options.artifact))
5627
5690
  throw new CliError("--artifact must be document/<id> or artboard/<id>");
5628
5691
  const [type, id] = options.artifact.split("/");
@@ -5645,8 +5708,25 @@ async function comment(options, emit) {
5645
5708
  artifact: options.artifact,
5646
5709
  threads: json.threads,
5647
5710
  ...json.groups ? { groups: json.groups } : {},
5711
+ ...json.rounds ? { rounds: json.rounds } : {},
5648
5712
  ...options.all ? { all: true } : {}
5649
5713
  });
5714
+ else if (action === "choose")
5715
+ emit({
5716
+ type: RECORDED.choose,
5717
+ artifact: options.artifact,
5718
+ group: request.group,
5719
+ board: request.board,
5720
+ threadId: json.threadId
5721
+ });
5722
+ else if (action === "submit")
5723
+ emit({
5724
+ type: RECORDED.submit,
5725
+ artifact: options.artifact,
5726
+ round: request.round,
5727
+ submitted: request.submit,
5728
+ threadId: json.threadId
5729
+ });
5650
5730
  else
5651
5731
  emit({
5652
5732
  type: WRITTEN[action],
@@ -5656,6 +5736,15 @@ async function comment(options, emit) {
5656
5736
  });
5657
5737
  return 0;
5658
5738
  }
5739
+ function choiceText(group) {
5740
+ const answer = group.choice ? `${group.choice}${group.byRecommendation ? " by recommendation" : ""}` : "no choice";
5741
+ const comments = group.threads ? ` (${plural(group.threads, "comment")})` : "";
5742
+ return ` ${group.id} \u2192 ${answer}${comments}`;
5743
+ }
5744
+ function roundText(round) {
5745
+ const state = round.state === "submitted" && round.submitted ? `submitted ${round.submitted}` : round.state;
5746
+ return ` ${round.id}${round.title ? ` (${round.title})` : ""}: ${state}`;
5747
+ }
5659
5748
  var VERDICT_TEXT = { pass: "passed", reject: "rejected", pending: "waiting for a verdict" };
5660
5749
  var plural = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
5661
5750
  function groupText(group) {
@@ -5705,18 +5794,30 @@ function threadText(thread) {
5705
5794
  function commentText(value) {
5706
5795
  if (value.type === "comments") {
5707
5796
  const threads = value.threads ?? [];
5708
- const groups = value.groups ?? [];
5797
+ const all = value.groups ?? [];
5798
+ const groups = all.filter((g) => g.kind !== "choose");
5799
+ const choices = all.filter((g) => g.kind === "choose");
5800
+ const rounds = value.rounds ?? [];
5709
5801
  const head = threads.length ? threads.map(threadText).join("\n\n") : value.all ? `No comments on ${value.artifact}.` : `No new comments on ${value.artifact}.`;
5710
- return groups.length ? `${head}
5711
-
5712
- Verify groups:
5713
- ${groups.map(groupText).join("\n")}` : head;
5802
+ return [
5803
+ head,
5804
+ groups.length ? `Verify groups:
5805
+ ${groups.map(groupText).join("\n")}` : "",
5806
+ choices.length ? `Choice groups:
5807
+ ${choices.map(choiceText).join("\n")}` : "",
5808
+ rounds.length ? `Rounds:
5809
+ ${rounds.map(roundText).join("\n")}` : ""
5810
+ ].filter(Boolean).join("\n\n");
5714
5811
  }
5715
5812
  if (value.type === "comment-added")
5716
5813
  return `Added thread ${value.threadId} (message ${value.messageId})`;
5717
5814
  if (value.type === "comment-replied")
5718
5815
  return `Replied in thread ${value.threadId} (message ${value.messageId})`;
5719
5816
  if (value.type === "comment-resolved") return `Resolved thread ${value.threadId}`;
5817
+ if (value.type === "choice-recorded")
5818
+ return value.board ? `Recorded ${value.board} for ${value.group}` : `Cleared the choice in ${value.group}`;
5819
+ if (value.type === "round-submitted")
5820
+ return `${value.submitted ? "Submitted" : "Withdrew"} round ${value.round}`;
5720
5821
  return null;
5721
5822
  }
5722
5823
  var commentCommand = {
@@ -5727,7 +5828,9 @@ var commentCommand = {
5727
5828
  "add --artifact document/<id> --block <blockId> [--quote <text>] [--text <text>]",
5728
5829
  "add --artifact artboard/<id> --board <boardId> [--x <px> --y <px>] [--text <text>]",
5729
5830
  "reply --artifact <document|artboard>/<id> --thread <threadId> [--text <text>]",
5730
- "resolve --artifact <document|artboard>/<id> --thread <threadId>"
5831
+ "resolve --artifact <document|artboard>/<id> --thread <threadId>",
5832
+ "choose --artifact artboard/<id> --group <groupId> (--board <boardId> | --clear)",
5833
+ "submit --artifact artboard/<id> --round <roundId> [--withdraw]"
5731
5834
  ],
5732
5835
  details: "list prints what changed since you last listed. Without --text, add and reply read the message from stdin.",
5733
5836
  options: {
@@ -5743,7 +5846,11 @@ var commentCommand = {
5743
5846
  x: { type: "string", value: "<px>", help: "add: horizontal position on the board" },
5744
5847
  y: { type: "string", value: "<px>", help: "add: vertical position on the board" },
5745
5848
  thread: { type: "string", value: "<threadId>", help: "reply, resolve: the thread" },
5746
- text: { type: "string", value: "<text>", help: "add, reply: the message" }
5849
+ text: { type: "string", value: "<text>", help: "add, reply: the message" },
5850
+ group: { type: "string", value: "<groupId>", help: "choose: the choice group" },
5851
+ clear: { type: "boolean", help: "choose: clear the choice instead of naming a board" },
5852
+ round: { type: "string", value: "<roundId>", help: "submit: the round" },
5853
+ withdraw: { type: "boolean", help: "submit: withdraw the submission" }
5747
5854
  },
5748
5855
  positionals: 1,
5749
5856
  run: ({ values, positionals, projectDir }, emit) => comment(
@@ -5757,6 +5864,10 @@ var commentCommand = {
5757
5864
  thread: values.thread,
5758
5865
  text: values.text,
5759
5866
  board: values.board,
5867
+ group: values.group,
5868
+ clear: values.clear,
5869
+ round: values.round,
5870
+ withdraw: values.withdraw,
5760
5871
  x: values.x,
5761
5872
  y: values.y
5762
5873
  },
@@ -5766,19 +5877,19 @@ var commentCommand = {
5766
5877
  };
5767
5878
 
5768
5879
  // src/cli/config.ts
5769
- var import_node_os2 = __toESM(require("node:os"), 1);
5770
- var import_node_path6 = __toESM(require("node:path"), 1);
5880
+ var import_node_os3 = __toESM(require("node:os"), 1);
5881
+ var import_node_path7 = __toESM(require("node:path"), 1);
5771
5882
 
5772
5883
  // src/server/config.ts
5773
- var import_node_fs5 = __toESM(require("node:fs"), 1);
5774
- var import_node_path3 = __toESM(require("node:path"), 1);
5884
+ var import_node_fs6 = __toESM(require("node:fs"), 1);
5885
+ var import_node_path4 = __toESM(require("node:path"), 1);
5775
5886
 
5776
5887
  // src/shared/cloud.ts
5777
5888
  var isVisibility = (value) => value === "private" || value === "public";
5778
5889
 
5779
5890
  // src/server/state.ts
5780
- var import_node_fs4 = __toESM(require("node:fs"), 1);
5781
- var import_node_path2 = __toESM(require("node:path"), 1);
5891
+ var import_node_fs5 = __toESM(require("node:fs"), 1);
5892
+ var import_node_path3 = __toESM(require("node:path"), 1);
5782
5893
 
5783
5894
  // src/shared/types.ts
5784
5895
  var ARTIFACT_TYPES = ["artboard", "document", "html"];
@@ -5790,11 +5901,11 @@ var MEDIA_REQUIRED = ["src", "page", ...BOARD_NUMBERS];
5790
5901
 
5791
5902
  // src/server/state.ts
5792
5903
  function writeJsonAtomic(file, value) {
5793
- import_node_fs4.default.mkdirSync(import_node_path2.default.dirname(file), { recursive: true });
5904
+ import_node_fs5.default.mkdirSync(import_node_path3.default.dirname(file), { recursive: true });
5794
5905
  const tmp = `${file}.${process.pid}.tmp`;
5795
- import_node_fs4.default.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}
5906
+ import_node_fs5.default.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}
5796
5907
  `, { mode: 384 });
5797
- import_node_fs4.default.renameSync(tmp, file);
5908
+ import_node_fs5.default.renameSync(tmp, file);
5798
5909
  }
5799
5910
 
5800
5911
  // src/server/config.ts
@@ -5835,7 +5946,7 @@ function normalize(raw) {
5835
5946
  function readConfig(file) {
5836
5947
  let text2;
5837
5948
  try {
5838
- text2 = import_node_fs5.default.readFileSync(file, "utf8");
5949
+ text2 = import_node_fs6.default.readFileSync(file, "utf8");
5839
5950
  } catch {
5840
5951
  return { config: defaults() };
5841
5952
  }
@@ -5855,47 +5966,47 @@ var IGNORED = [
5855
5966
  "artifacts/document/*/.artifact-id"
5856
5967
  ];
5857
5968
  function ensureGitignore(dir) {
5858
- const file = import_node_path3.default.join(dir, ".gitignore");
5969
+ const file = import_node_path4.default.join(dir, ".gitignore");
5859
5970
  let current = "";
5860
5971
  try {
5861
- current = import_node_fs5.default.readFileSync(file, "utf8");
5972
+ current = import_node_fs6.default.readFileSync(file, "utf8");
5862
5973
  } catch {
5863
5974
  }
5864
5975
  const present = new Set(current.split(/\r?\n/).map((line) => line.trim()));
5865
5976
  const missing = IGNORED.filter((line) => !present.has(line));
5866
5977
  if (missing.length === 0) return;
5867
- import_node_fs5.default.writeFileSync(
5978
+ import_node_fs6.default.writeFileSync(
5868
5979
  file,
5869
5980
  `${current}${current === "" || current.endsWith("\n") ? "" : "\n"}${missing.join("\n")}
5870
5981
  `
5871
5982
  );
5872
5983
  }
5873
5984
  function ensureConfig(file) {
5874
- import_node_fs5.default.mkdirSync(import_node_path3.default.dirname(file), { recursive: true });
5875
- ensureGitignore(import_node_path3.default.dirname(file));
5876
- if (!import_node_fs5.default.existsSync(file)) writeJsonAtomic(file, defaults());
5985
+ import_node_fs6.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
5986
+ ensureGitignore(import_node_path4.default.dirname(file));
5987
+ if (!import_node_fs6.default.existsSync(file)) writeJsonAtomic(file, defaults());
5877
5988
  }
5878
5989
  function setProjectAutoPublish(file, value) {
5879
5990
  const { config: config2, warning } = readConfig(file);
5880
5991
  if (warning) throw new Error(warning);
5881
5992
  if (value === null) delete config2.autoPublish;
5882
5993
  else config2.autoPublish = value;
5883
- import_node_fs5.default.mkdirSync(import_node_path3.default.dirname(file), { recursive: true });
5994
+ import_node_fs6.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
5884
5995
  writeJsonAtomic(file, config2);
5885
5996
  }
5886
5997
 
5887
5998
  // src/server/credentials.ts
5888
- var import_node_fs6 = __toESM(require("node:fs"), 1);
5889
- var import_node_path4 = __toESM(require("node:path"), 1);
5999
+ var import_node_fs7 = __toESM(require("node:fs"), 1);
6000
+ var import_node_path5 = __toESM(require("node:path"), 1);
5890
6001
  function credentialsFile(env, platform, home) {
5891
6002
  if (platform === "win32" && env.APPDATA)
5892
- return import_node_path4.default.join(env.APPDATA, "ryugi", "credentials.json");
5893
- return import_node_path4.default.join(env.XDG_CONFIG_HOME || import_node_path4.default.join(home, ".config"), "ryugi", "credentials.json");
6003
+ return import_node_path5.default.join(env.APPDATA, "ryugi", "credentials.json");
6004
+ return import_node_path5.default.join(env.XDG_CONFIG_HOME || import_node_path5.default.join(home, ".config"), "ryugi", "credentials.json");
5894
6005
  }
5895
6006
  function readCredentials(file, origin) {
5896
6007
  let raw;
5897
6008
  try {
5898
- raw = JSON.parse(import_node_fs6.default.readFileSync(file, "utf8"));
6009
+ raw = JSON.parse(import_node_fs7.default.readFileSync(file, "utf8"));
5899
6010
  } catch {
5900
6011
  return null;
5901
6012
  }
@@ -5908,12 +6019,12 @@ function readCredentials(file, origin) {
5908
6019
  }
5909
6020
 
5910
6021
  // src/server/settings.ts
5911
- var import_node_fs7 = __toESM(require("node:fs"), 1);
5912
- var import_node_path5 = __toESM(require("node:path"), 1);
5913
- var settingsFileFor = (credentialsFile2) => import_node_path5.default.join(import_node_path5.default.dirname(credentialsFile2), "config.json");
6022
+ var import_node_fs8 = __toESM(require("node:fs"), 1);
6023
+ var import_node_path6 = __toESM(require("node:path"), 1);
6024
+ var settingsFileFor = (credentialsFile2) => import_node_path6.default.join(import_node_path6.default.dirname(credentialsFile2), "config.json");
5914
6025
  function readSettings(file) {
5915
6026
  try {
5916
- const raw = JSON.parse(import_node_fs7.default.readFileSync(file, "utf8"));
6027
+ const raw = JSON.parse(import_node_fs8.default.readFileSync(file, "utf8"));
5917
6028
  return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
5918
6029
  } catch {
5919
6030
  return {};
@@ -5924,15 +6035,15 @@ function readGlobalAutoPublish(file) {
5924
6035
  return typeof value === "boolean" ? value : void 0;
5925
6036
  }
5926
6037
  function writeGlobalAutoPublish(file, value) {
5927
- import_node_fs7.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true, mode: 448 });
6038
+ import_node_fs8.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true, mode: 448 });
5928
6039
  writeJsonAtomic(file, { ...readSettings(file), autoPublish: value });
5929
6040
  }
5930
6041
 
5931
6042
  // src/cli/config.ts
5932
6043
  var VALUES = { on: true, off: false, inherit: null };
5933
6044
  function config(options, emit) {
5934
- const globalFile = settingsFileFor(credentialsFile(process.env, process.platform, import_node_os2.default.homedir()));
5935
- const projectFile = import_node_path6.default.join(import_node_path6.default.dirname(projectPaths(options.projectDir).root), "config.json");
6045
+ const globalFile = settingsFileFor(credentialsFile(process.env, process.platform, import_node_os3.default.homedir()));
6046
+ const projectFile = import_node_path7.default.join(import_node_path7.default.dirname(projectPaths(options.projectDir).root), "config.json");
5936
6047
  if (options.autoPublish !== void 0) {
5937
6048
  const value = VALUES[options.autoPublish];
5938
6049
  if (value === void 0)
@@ -5975,9 +6086,9 @@ var configCommand = {
5975
6086
  };
5976
6087
 
5977
6088
  // src/cli/get.ts
5978
- var import_node_fs8 = __toESM(require("node:fs"), 1);
5979
- var import_node_os3 = __toESM(require("node:os"), 1);
5980
- var import_node_path7 = __toESM(require("node:path"), 1);
6089
+ var import_node_fs9 = __toESM(require("node:fs"), 1);
6090
+ var import_node_os4 = __toESM(require("node:os"), 1);
6091
+ var import_node_path8 = __toESM(require("node:path"), 1);
5981
6092
 
5982
6093
  // node_modules/.pnpm/nanoid@6.0.2/node_modules/nanoid/url-alphabet/index.js
5983
6094
  var urlAlphabet = "57X6y3wQZNzYjJB2L_10pxbackgroundhimselfUTF-8DEMOGRAPHICSVqvt4KW9";
@@ -6554,10 +6665,10 @@ function registerCustomReaders(registry2) {
6554
6665
  };
6555
6666
  });
6556
6667
  registry2.registerReader("grid", (el, ctx) => {
6557
- const cells2 = [];
6668
+ const cells = [];
6558
6669
  for (const child of el.children) if (child.tagName.toLowerCase() === "cell") {
6559
6670
  const children = ctx.parseChildren(child);
6560
- cells2.push({ root: {
6671
+ cells.push({ root: {
6561
6672
  type: "root",
6562
6673
  children,
6563
6674
  direction: "ltr",
@@ -6571,7 +6682,7 @@ function registerCustomReaders(registry2) {
6571
6682
  ...extractBlockId(el),
6572
6683
  cols: numAttr(el, "cols") ?? 2,
6573
6684
  gap: el.getAttribute("gap") ?? "16px",
6574
- cells: cells2,
6685
+ cells,
6575
6686
  version: 1
6576
6687
  };
6577
6688
  });
@@ -7017,7 +7128,7 @@ function registerCustomWriters(registry2) {
7017
7128
  });
7018
7129
  registry2.registerWriter("grid-container", (node, ctx) => {
7019
7130
  const n = node;
7020
- const cells2 = (n.cells ?? []).map((cellState) => ({
7131
+ const cells = (n.cells ?? []).map((cellState) => ({
7021
7132
  tag: "cell",
7022
7133
  children: ctx.serializeNestedState(cellState)
7023
7134
  }));
@@ -7028,7 +7139,7 @@ function registerCustomWriters(registry2) {
7028
7139
  cols: n.cols != null ? String(n.cols) : void 0,
7029
7140
  gap: n.gap
7030
7141
  }),
7031
- children: cells2
7142
+ children: cells
7032
7143
  };
7033
7144
  });
7034
7145
  registry2.registerWriter("agent-diff", (node) => {
@@ -18154,15 +18265,15 @@ var ID = /^[\w-]{1,64}$/;
18154
18265
  var LINK_PATH = /^\/a\/([\w-]{1,64})(?:\/(?:view|preview))?\/?$/;
18155
18266
  var TARGET_ERROR = "Expected a Ryugi Cloud link (https://<host>/a/<id>) or an artifact id.";
18156
18267
  var LOGIN_MESSAGE = "Not found, or private and you are not signed in. Sign in once with `ryugi-artifacts start` then `ryugi-artifacts publish --login` in any project, then run this command again.";
18157
- var safePath = (file) => !file.includes("\\") && !file.includes("\0") && !import_node_path7.default.posix.isAbsolute(file) && file.split("/").every((part) => part !== "" && part !== "." && part !== "..");
18268
+ var safePath = (file) => !file.includes("\\") && !file.includes("\0") && !import_node_path8.default.posix.isAbsolute(file) && file.split("/").every((part) => part !== "" && part !== "." && part !== "..");
18158
18269
  async function download(contentBase, files, dir, fresh) {
18159
18270
  const unsafe = files.find((file) => !safePath(file));
18160
18271
  if (unsafe !== void 0)
18161
18272
  throw new CliError(
18162
18273
  `Refusing to write ${unsafe}: it is not a path inside the download directory.`
18163
18274
  );
18164
- if (fresh) import_node_fs8.default.rmSync(dir, { recursive: true, force: true });
18165
- import_node_fs8.default.mkdirSync(dir, { recursive: true });
18275
+ if (fresh) import_node_fs9.default.rmSync(dir, { recursive: true, force: true });
18276
+ import_node_fs9.default.mkdirSync(dir, { recursive: true });
18166
18277
  for (const file of files) {
18167
18278
  const res = await fetch(
18168
18279
  `${contentBase}${file.split("/").map(encodeURIComponent).join("/")}`
@@ -18170,10 +18281,10 @@ async function download(contentBase, files, dir, fresh) {
18170
18281
  throw new CliError(`Could not download ${file}: ${err.message}`);
18171
18282
  });
18172
18283
  if (!res.ok) throw new CliError(`Could not download ${file}: HTTP ${res.status}`);
18173
- const target = import_node_path7.default.join(dir, ...file.split("/"));
18174
- import_node_fs8.default.mkdirSync(import_node_path7.default.dirname(target), { recursive: true });
18284
+ const target = import_node_path8.default.join(dir, ...file.split("/"));
18285
+ import_node_fs9.default.mkdirSync(import_node_path8.default.dirname(target), { recursive: true });
18175
18286
  const data = Buffer.from(await res.arrayBuffer());
18176
- import_node_fs8.default.writeFileSync(target, file.endsWith(".html") ? stripRuntime(data.toString("utf8")) : data);
18287
+ import_node_fs9.default.writeFileSync(target, file.endsWith(".html") ? stripRuntime(data.toString("utf8")) : data);
18177
18288
  }
18178
18289
  }
18179
18290
  function parseTarget(target, defaultOrigin) {
@@ -18231,7 +18342,7 @@ async function getArtifact({
18231
18342
  const files = (json.files ?? []).filter(
18232
18343
  (file) => json.type !== "document" || file !== "doc.xml"
18233
18344
  );
18234
- const dir = out ? import_node_path7.default.resolve(out) : import_node_path7.default.join(cacheRoot, id);
18345
+ const dir = out ? import_node_path8.default.resolve(out) : import_node_path8.default.join(cacheRoot, id);
18235
18346
  if (json.type === "document") {
18236
18347
  result.content = serializeDocument(json.payload.state);
18237
18348
  result.comments = json.payload.comments?.threads ?? [];
@@ -18241,8 +18352,8 @@ async function getArtifact({
18241
18352
  result.dir = dir;
18242
18353
  result.files = files;
18243
18354
  if (json.type === "artboard" && !files.includes("canvas.json")) {
18244
- import_node_fs8.default.writeFileSync(
18245
- import_node_path7.default.join(dir, "canvas.json"),
18355
+ import_node_fs9.default.writeFileSync(
18356
+ import_node_path8.default.join(dir, "canvas.json"),
18246
18357
  `${JSON.stringify(json.payload.canvas, null, 2)}
18247
18358
  `
18248
18359
  );
@@ -18300,9 +18411,9 @@ var getCommand = {
18300
18411
  /\/+$/,
18301
18412
  ""
18302
18413
  ),
18303
- credentialsFile: credentialsFile(process.env, process.platform, import_node_os3.default.homedir()),
18304
- cacheRoot: import_node_path7.default.join(
18305
- process.env.XDG_CACHE_HOME || import_node_path7.default.join(import_node_os3.default.homedir(), ".cache"),
18414
+ credentialsFile: credentialsFile(process.env, process.platform, import_node_os4.default.homedir()),
18415
+ cacheRoot: import_node_path8.default.join(
18416
+ process.env.XDG_CACHE_HOME || import_node_path8.default.join(import_node_os4.default.homedir(), ".cache"),
18306
18417
  "ryugi",
18307
18418
  "get"
18308
18419
  ),
@@ -18321,557 +18432,6 @@ var getCommand = {
18321
18432
  }
18322
18433
  };
18323
18434
 
18324
- // src/cli/monitor-ui.ts
18325
- var import_node_child_process2 = require("node:child_process");
18326
- var import_node_fs11 = __toESM(require("node:fs"), 1);
18327
- var import_node_os6 = __toESM(require("node:os"), 1);
18328
- var import_node_readline = __toESM(require("node:readline"), 1);
18329
-
18330
- // src/server/lifecycle.ts
18331
- var DEFAULT_IDLE_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
18332
- var DEFAULT_LIFECYCLE_CHECK_MS = 60 * 1e3;
18333
- function browserLauncher(platform, url) {
18334
- if (platform === "darwin") return { bin: "open", args: [url] };
18335
- if (platform === "win32") return { bin: "cmd", args: ["/c", "start", '""', url] };
18336
- if (platform === "linux" || platform === "freebsd" || platform === "openbsd")
18337
- return { bin: "xdg-open", args: [url] };
18338
- return null;
18339
- }
18340
-
18341
- // src/cli/monitor-view.ts
18342
- var import_node_os4 = __toESM(require("node:os"), 1);
18343
- var REFRESH_SECONDS = 2;
18344
- var BOLD = "\x1B[1m";
18345
- var DIM = "\x1B[2m";
18346
- var INVERSE = "\x1B[7m";
18347
- var RESET = "\x1B[0m";
18348
- var HELP = "\u2191\u2193 select o open c copy URL l logs x stop X stop all safe q quit";
18349
- var COLUMNS = [
18350
- ["PORT", 6],
18351
- ["PID", 8],
18352
- ["UP", 7],
18353
- ["TABS", 5],
18354
- ["IDLE", 7],
18355
- ["VERSION", 13]
18356
- ];
18357
- var FIXED = 2 + COLUMNS.reduce((sum, [, width]) => sum + width + 2, 0);
18358
- var TAGS_WIDTH = 26;
18359
- function duration(ms) {
18360
- const minutes = Math.max(0, Math.floor(ms / 6e4));
18361
- if (minutes < 60) return `${minutes}m`;
18362
- const hours = Math.floor(minutes / 60);
18363
- if (hours < 24) return `${hours}h${minutes % 60 ? `${minutes % 60}m` : ""}`;
18364
- return `${Math.floor(hours / 24)}d${hours % 24 ? `${hours % 24}h` : ""}`;
18365
- }
18366
- var shortPath = (project, home = import_node_os4.default.homedir()) => project === home || project.startsWith(`${home}/`) ? `~${project.slice(home.length)}` : project;
18367
- function tags(row) {
18368
- return [
18369
- row.safeToStop && "safe to stop",
18370
- row.oldRelease && "old release",
18371
- row.status === "no-status" && "no status"
18372
- ].filter(Boolean);
18373
- }
18374
- var initialView = () => ({
18375
- mode: "list",
18376
- selected: 0,
18377
- confirm: null,
18378
- target: null,
18379
- message: null
18380
- });
18381
- var fit = (text2, width) => text2.length > width ? text2.slice(0, width) : text2;
18382
- var pad2 = (text2, width) => fit(text2, width).padEnd(width);
18383
- var cutLeft = (text2, width) => text2.length > width ? `\u2026${text2.slice(text2.length - width + 1)}` : text2;
18384
- function header(left, right, width) {
18385
- const gap = width - left.length - right.length;
18386
- return `${BOLD}${fit(gap >= 2 ? `${left}${" ".repeat(gap)}${right}` : left, width)}${RESET}`;
18387
- }
18388
- function cells(row, now) {
18389
- return [
18390
- row.port === null ? "-" : String(row.port),
18391
- String(row.pid),
18392
- duration(now - row.startedAt),
18393
- row.clients === null ? "-" : String(row.clients),
18394
- row.lastActivity === null ? "-" : duration(now - row.lastActivity),
18395
- row.version ?? "-"
18396
- ];
18397
- }
18398
- function footer(rows, state, home) {
18399
- if (state.confirm === "stop" && state.target)
18400
- return `Stop ${shortPath(state.target, home)}? y to confirm`;
18401
- if (state.confirm === "stop-safe") {
18402
- const count = rows.filter((row) => row.safeToStop).length;
18403
- return `Stop ${count} server${count === 1 ? "" : "s"} that ${count === 1 ? "is" : "are"} safe to stop? y to confirm`;
18404
- }
18405
- return state.message ?? HELP;
18406
- }
18407
- function renderList(rows, state, screen) {
18408
- const { width, height, now, home } = screen;
18409
- const count = `${rows.length} server${rows.length === 1 ? "" : "s"} \xB7 refreshes every ${REFRESH_SECONDS}s`;
18410
- const lines = [header("ryugi-artifacts monitor", count, width)];
18411
- if (!rows.length) {
18412
- lines.push("", fit("No artifacts servers are running.", width), "");
18413
- } else {
18414
- const projectWidth = Math.max(12, width - FIXED - TAGS_WIDTH);
18415
- const columns = [
18416
- " ",
18417
- pad2("PROJECT", projectWidth),
18418
- ...COLUMNS.map(([name, w]) => ` ${pad2(name, w)}`)
18419
- ].join("");
18420
- lines.push(`${DIM}${fit(columns.trimEnd(), width)}${RESET}`);
18421
- const visible = Math.max(1, height - 4);
18422
- const first = Math.min(
18423
- Math.max(0, state.selected - visible + 1),
18424
- Math.max(0, rows.length - visible)
18425
- );
18426
- rows.slice(first, first + visible).forEach((row, offset) => {
18427
- const selected = first + offset === state.selected;
18428
- const text2 = [
18429
- selected ? "\u203A " : " ",
18430
- pad2(cutLeft(shortPath(row.project, home), projectWidth), projectWidth),
18431
- ...cells(row, now).map((cell, i) => ` ${pad2(cell, COLUMNS[i][1])}`),
18432
- tags(row).length ? ` ${tags(row).join(", ")}` : ""
18433
- ].join("");
18434
- const line = fit(text2.trimEnd(), width);
18435
- lines.push(selected ? `${INVERSE}${line}${RESET}` : line);
18436
- });
18437
- lines.push("");
18438
- }
18439
- lines.push(`${DIM}${fit(footer(rows, state, home), width)}${RESET}`);
18440
- return lines;
18441
- }
18442
- function renderLog(row, text2, screen) {
18443
- const { width, height, home } = screen;
18444
- const lines = [header(`Log \xB7 ${shortPath(row.project, home)}`, row.log, width)];
18445
- const body = text2 === null ? [
18446
- "No log file: this server runs in the foreground, so its output is in the terminal that started it."
18447
- ] : text2.replace(/\n+$/, "").split("\n").slice(-Math.max(1, height - 2));
18448
- lines.push(...body.map((line) => fit(line, width)));
18449
- lines.push(`${DIM}${fit("Esc back Ctrl+C quit", width)}${RESET}`);
18450
- return lines;
18451
- }
18452
- function handleKey(state, key2, rows) {
18453
- if (key2.ctrl && key2.name === "c") return { state, action: { type: "quit" } };
18454
- const next = { ...state, confirm: null, target: null, message: null };
18455
- if (state.mode === "log")
18456
- return { state: key2.name === "escape" || key2.name === "q" ? { ...next, mode: "list" } : state };
18457
- if (state.confirm) {
18458
- if (key2.name !== "y") return { state: next };
18459
- const targets = state.confirm === "stop" ? rows.filter((row) => row.project === state.target) : rows.filter((row) => row.safeToStop);
18460
- if (targets.length) return { state: next, action: { type: "stop", rows: targets } };
18461
- return {
18462
- state: {
18463
- ...next,
18464
- message: state.target ? `${shortPath(state.target)} is no longer running.` : "Nothing is safe to stop any more."
18465
- }
18466
- };
18467
- }
18468
- const selected = rows[state.selected];
18469
- if (key2.sequence === "X" || key2.name === "x" && key2.shift) {
18470
- if (rows.some((row) => row.safeToStop)) return { state: { ...next, confirm: "stop-safe" } };
18471
- return {
18472
- state: {
18473
- ...next,
18474
- message: "Nothing is safe to stop: every server has an open tab or was used in the last 30 minutes."
18475
- }
18476
- };
18477
- }
18478
- switch (key2.name) {
18479
- case "q": {
18480
- return { state, action: { type: "quit" } };
18481
- }
18482
- case "up":
18483
- case "k": {
18484
- return { state: { ...next, selected: Math.max(0, state.selected - 1) } };
18485
- }
18486
- case "down":
18487
- case "j": {
18488
- return {
18489
- state: { ...next, selected: Math.min(Math.max(0, rows.length - 1), state.selected + 1) }
18490
- };
18491
- }
18492
- case "o":
18493
- case "c": {
18494
- if (!selected) return { state: next };
18495
- if (!selected.url) return { state: { ...next, message: "This server has no URL yet." } };
18496
- return { state: next, action: { type: key2.name === "o" ? "open" : "copy", row: selected } };
18497
- }
18498
- case "l": {
18499
- return { state: selected ? { ...next, mode: "log" } : next };
18500
- }
18501
- case "x": {
18502
- return { state: selected ? { ...next, confirm: "stop", target: selected.project } : next };
18503
- }
18504
- default: {
18505
- return { state: next };
18506
- }
18507
- }
18508
- }
18509
-
18510
- // src/cli/servers.ts
18511
- var import_node_path9 = __toESM(require("node:path"), 1);
18512
-
18513
- // src/server/registry.ts
18514
- var import_node_crypto = __toESM(require("node:crypto"), 1);
18515
- var import_node_fs9 = __toESM(require("node:fs"), 1);
18516
- var import_node_os5 = __toESM(require("node:os"), 1);
18517
- var import_node_path8 = __toESM(require("node:path"), 1);
18518
- function registryDir(env = process.env, platform = process.platform, uid = process.getuid?.() ?? -1, tmpdir = import_node_os5.default.tmpdir()) {
18519
- if (env.RYUGI_RUNTIME_DIR) return import_node_path8.default.join(env.RYUGI_RUNTIME_DIR, "servers");
18520
- if (platform === "win32") return import_node_path8.default.join(tmpdir, "ryugi", "servers");
18521
- return `/tmp/ryugi-${uid}/servers`;
18522
- }
18523
- var fileFor = (dir, project) => import_node_path8.default.join(dir, `${import_node_crypto.default.createHash("sha256").update(project).digest("hex").slice(0, 16)}.json`);
18524
- function verifyDir(dir) {
18525
- if (process.platform === "win32") return;
18526
- for (const target of [import_node_path8.default.dirname(dir), dir]) {
18527
- const stat = import_node_fs9.default.lstatSync(target);
18528
- if (!stat.isDirectory() || stat.uid !== process.getuid() || stat.mode & 18)
18529
- throw new Error(`Unsafe registry directory: ${target}`);
18530
- }
18531
- }
18532
- function readEntry(file) {
18533
- try {
18534
- const value = JSON.parse(import_node_fs9.default.readFileSync(file, "utf8"));
18535
- if (typeof value.project !== "string" || typeof value.root !== "string" || typeof value.serverId !== "string")
18536
- return null;
18537
- if (!Number.isInteger(value.pid) || !Number.isFinite(value.startedAt)) return null;
18538
- if (value.root !== import_node_path8.default.join(value.project, ".ryugi", "artifacts")) return null;
18539
- return value;
18540
- } catch {
18541
- return null;
18542
- }
18543
- }
18544
- function readEntries(dir) {
18545
- let names;
18546
- try {
18547
- verifyDir(dir);
18548
- names = import_node_fs9.default.readdirSync(dir);
18549
- } catch {
18550
- return [];
18551
- }
18552
- return names.filter((name) => name.endsWith(".json")).flatMap((name) => readEntry(import_node_path8.default.join(dir, name)) ?? []);
18553
- }
18554
- function removeEntry(dir, entry) {
18555
- const file = fileFor(dir, entry.project);
18556
- if (readEntry(file)?.serverId === entry.serverId) import_node_fs9.default.rmSync(file, { force: true });
18557
- }
18558
-
18559
- // src/cli/servers.ts
18560
- var SAFE_IDLE_MS = 30 * 6e4;
18561
- var STATUS_TIMEOUT_MS = 1e3;
18562
- var safeToStop = (status, now) => !!status && status.clients === 0 && now - status.lastActivity >= SAFE_IDLE_MS;
18563
- async function fetchStatus(url) {
18564
- const base = new URL(url);
18565
- if (base.hostname === "localhost") base.hostname = "127.0.0.1";
18566
- try {
18567
- const res = await fetch(
18568
- `${base.origin}/api/status?key=${encodeURIComponent(base.searchParams.get("key") ?? "")}`,
18569
- { signal: AbortSignal.timeout(STATUS_TIMEOUT_MS) }
18570
- );
18571
- if (!res.ok) return null;
18572
- const json = await res.json();
18573
- if (typeof json.pid !== "number" || typeof json.clients !== "number" || typeof json.lastActivity !== "number")
18574
- return null;
18575
- return { pid: json.pid, clients: json.clients, lastActivity: json.lastActivity };
18576
- } catch {
18577
- return null;
18578
- }
18579
- }
18580
- function serverUrl(root) {
18581
- try {
18582
- const { url } = JSON.parse(readText(import_node_path9.default.join(root, ".state", "server-info")) ?? "");
18583
- return typeof url === "string" ? url : null;
18584
- } catch {
18585
- return null;
18586
- }
18587
- }
18588
- async function listServers(now = Date.now(), platform = process.platform) {
18589
- const dir = registryDir();
18590
- const current = process.env.RYUGI_ARTIFACTS_VERSION;
18591
- const live = readEntries(dir).filter((entry) => {
18592
- if (hasServerId(entry.pid, entry.serverId)) return true;
18593
- try {
18594
- removeEntry(dir, entry);
18595
- } catch {
18596
- }
18597
- return false;
18598
- });
18599
- const rows = await Promise.all(
18600
- live.map(async (entry) => {
18601
- const url = serverUrl(entry.root);
18602
- const status = url ? await fetchStatus(url) : null;
18603
- if (status && status.pid !== entry.pid) return null;
18604
- if (!status && platform === "win32") return null;
18605
- const version = readText(import_node_path9.default.join(entry.root, ".state", "server-version")) || null;
18606
- return {
18607
- project: entry.project,
18608
- root: entry.root,
18609
- pid: entry.pid,
18610
- url,
18611
- port: url ? Number(new URL(url).port) : null,
18612
- startedAt: entry.startedAt,
18613
- version,
18614
- oldRelease: !!current && !!version && version !== current,
18615
- clients: status?.clients ?? null,
18616
- lastActivity: status?.lastActivity ?? null,
18617
- safeToStop: safeToStop(status, now),
18618
- status: status ? "ok" : "no-status",
18619
- log: import_node_path9.default.join(entry.root, ".state", "server.log")
18620
- };
18621
- })
18622
- );
18623
- return rows.filter((row) => row !== null).sort((a, b) => a.project.localeCompare(b.project));
18624
- }
18625
-
18626
- // src/cli/stop.ts
18627
- var import_node_fs10 = __toESM(require("node:fs"), 1);
18628
- async function stop(projectDir, emit) {
18629
- const paths = projectPaths(projectDir);
18630
- const markStopped = (reason) => {
18631
- import_node_fs10.default.rmSync(paths.info, { force: true });
18632
- import_node_fs10.default.mkdirSync(paths.state, { recursive: true });
18633
- import_node_fs10.default.writeFileSync(
18634
- paths.stopped,
18635
- `${JSON.stringify({ reason, timestamp: Math.floor(Date.now() / 1e3) })}
18636
- `
18637
- );
18638
- };
18639
- const pid = Number(readText(paths.pid));
18640
- if (readText(paths.pid) === null) {
18641
- emit({ status: "not_running" });
18642
- return 0;
18643
- }
18644
- const id = readText(paths.serverId) ?? "";
18645
- if (!Number.isInteger(pid) || pid <= 0 || !/^[\w-]{32,64}$/.test(id) || !hasServerId(pid, id)) {
18646
- import_node_fs10.default.rmSync(paths.pid, { force: true });
18647
- import_node_fs10.default.rmSync(paths.serverId, { force: true });
18648
- markStopped("stale_pid");
18649
- emit({ status: "stale_pid" });
18650
- return 0;
18651
- }
18652
- try {
18653
- process.kill(pid, "SIGTERM");
18654
- } catch {
18655
- }
18656
- if (!await waitForExit(pid, 2e3)) {
18657
- try {
18658
- process.kill(pid, "SIGKILL");
18659
- } catch {
18660
- }
18661
- await waitForExit(pid, 1e3);
18662
- }
18663
- if (alive(pid)) {
18664
- emit({ status: "failed", error: "process still running" });
18665
- return 1;
18666
- }
18667
- for (const file of [paths.pid, paths.serverId, paths.log, paths.owners])
18668
- import_node_fs10.default.rmSync(file, { force: true });
18669
- markStopped("stop");
18670
- emit({ status: "stopped" });
18671
- return 0;
18672
- }
18673
- var stopCommand = {
18674
- name: "stop",
18675
- summary: "Stop the project's artifacts server; the artifacts are kept",
18676
- usage: ["[project-directory] [options]"],
18677
- options: {},
18678
- positionals: 1,
18679
- run: ({ values, positionals }, emit) => stop(values["project-dir"] ?? positionals[0] ?? process.cwd(), emit)
18680
- };
18681
-
18682
- // src/cli/monitor-ui.ts
18683
- var LOG_TAIL_BYTES = 64 * 1024;
18684
- var LOG_REFRESH_MS = 500;
18685
- function readTail(file) {
18686
- let fd;
18687
- try {
18688
- fd = import_node_fs11.default.openSync(file, "r");
18689
- } catch {
18690
- return null;
18691
- }
18692
- try {
18693
- const size = import_node_fs11.default.fstatSync(fd).size;
18694
- const length = Math.min(size, LOG_TAIL_BYTES);
18695
- const buffer = Buffer.alloc(length);
18696
- import_node_fs11.default.readSync(fd, buffer, 0, length, size - length);
18697
- return buffer.toString("utf8");
18698
- } finally {
18699
- import_node_fs11.default.closeSync(fd);
18700
- }
18701
- }
18702
- function clipboardCommands() {
18703
- if (process.platform === "darwin") return [["pbcopy", []]];
18704
- if (process.platform === "win32") return [["clip", []]];
18705
- return [
18706
- ["wl-copy", []],
18707
- ["xclip", ["-selection", "clipboard"]],
18708
- ["xsel", ["--clipboard", "--input"]]
18709
- ];
18710
- }
18711
- function copy(text2, commands = clipboardCommands()) {
18712
- const [first, ...rest] = commands;
18713
- if (!first) return Promise.resolve(false);
18714
- return new Promise((resolve) => {
18715
- const child = (0, import_node_child_process2.spawn)(first[0], first[1], { stdio: ["pipe", "ignore", "ignore"] });
18716
- child.on("error", () => resolve(copy(text2, rest)));
18717
- child.on("close", (code) => code === 0 ? resolve(true) : resolve(copy(text2, rest)));
18718
- child.stdin.end(text2);
18719
- });
18720
- }
18721
- async function runMonitorUi() {
18722
- const { stdin, stdout } = process;
18723
- let rows = await listServers();
18724
- let state = initialView();
18725
- let busy = false;
18726
- let closed = false;
18727
- const restore = () => {
18728
- if (closed) return;
18729
- closed = true;
18730
- try {
18731
- stdin.setRawMode(false);
18732
- } catch {
18733
- }
18734
- stdout.write("\x1B[?25h\x1B[?1049l");
18735
- };
18736
- process.on("exit", restore);
18737
- const draw = () => {
18738
- if (closed) return;
18739
- const screen = {
18740
- width: stdout.columns || 80,
18741
- height: stdout.rows || 24,
18742
- now: Date.now(),
18743
- home: import_node_os6.default.homedir()
18744
- };
18745
- const row = rows[state.selected];
18746
- const lines = state.mode === "log" && row ? renderLog(row, readTail(row.log), screen) : renderList(rows, state, screen);
18747
- stdout.write(`\x1B[H${lines.join("\x1B[K\n")}\x1B[K\x1B[J`);
18748
- };
18749
- const refresh = async () => {
18750
- if (busy || closed) return;
18751
- busy = true;
18752
- const selected = rows[state.selected]?.project;
18753
- try {
18754
- rows = await listServers();
18755
- } finally {
18756
- busy = false;
18757
- }
18758
- const index = rows.findIndex((row) => row.project === selected);
18759
- state = {
18760
- ...state,
18761
- selected: index >= 0 ? index : Math.min(state.selected, Math.max(0, rows.length - 1))
18762
- };
18763
- if (state.mode === "log" && !rows[state.selected]) state = { ...state, mode: "list" };
18764
- draw();
18765
- };
18766
- const say = (message) => {
18767
- state = { ...state, message };
18768
- draw();
18769
- };
18770
- const run = async (action) => {
18771
- if (action.type === "open") {
18772
- const launcher = browserLauncher(process.platform, action.row.url);
18773
- if (launcher) (0, import_node_child_process2.execFile)(launcher.bin, launcher.args, () => {
18774
- });
18775
- say(launcher ? `Opened ${action.row.url}` : `Open ${action.row.url}`);
18776
- return;
18777
- }
18778
- if (action.type === "copy") {
18779
- say(
18780
- await copy(action.row.url) ? `Copied ${action.row.url}` : `No clipboard tool found; the URL is ${action.row.url}`
18781
- );
18782
- return;
18783
- }
18784
- if (action.type === "stop") {
18785
- say(
18786
- `Stopping ${action.rows.length === 1 ? shortPath(action.rows[0].project) : `${action.rows.length} servers`}\u2026`
18787
- );
18788
- const failed = [];
18789
- for (const row of action.rows) {
18790
- let status = "failed";
18791
- try {
18792
- await stop(row.project, (value) => {
18793
- status = String(value.status ?? "failed");
18794
- });
18795
- } catch {
18796
- }
18797
- if (status === "failed") failed.push(shortPath(row.project));
18798
- }
18799
- await refresh();
18800
- say(
18801
- failed.length ? `Could not stop ${failed.join(", ")}` : `Stopped ${action.rows.length === 1 ? shortPath(action.rows[0].project) : `${action.rows.length} servers`}`
18802
- );
18803
- }
18804
- };
18805
- return new Promise((resolve) => {
18806
- const timers = [
18807
- setInterval(() => void refresh(), REFRESH_SECONDS * 1e3),
18808
- setInterval(() => {
18809
- if (state.mode === "log") draw();
18810
- }, LOG_REFRESH_MS)
18811
- ];
18812
- const quit = (code) => {
18813
- timers.forEach(clearInterval);
18814
- stdin.off("keypress", onKey);
18815
- stdout.off("resize", draw);
18816
- stdin.pause();
18817
- restore();
18818
- resolve(code);
18819
- };
18820
- const onKey = (_, key2) => {
18821
- const result = handleKey(state, key2 ?? {}, rows);
18822
- state = result.state;
18823
- if (result.action?.type === "quit") return quit(0);
18824
- draw();
18825
- if (result.action) void run(result.action);
18826
- };
18827
- for (const [signal, code] of [
18828
- ["SIGINT", 130],
18829
- ["SIGTERM", 143],
18830
- ["SIGHUP", 129]
18831
- ])
18832
- process.once(signal, () => quit(code));
18833
- stdout.write("\x1B[?1049h\x1B[?25l");
18834
- import_node_readline.default.emitKeypressEvents(stdin);
18835
- stdin.setRawMode(true);
18836
- stdin.resume();
18837
- stdin.on("keypress", onKey);
18838
- stdout.on("resize", draw);
18839
- draw();
18840
- });
18841
- }
18842
-
18843
- // src/cli/monitor.ts
18844
- function monitorText(value, now = Date.now()) {
18845
- if (value.type !== "servers") return null;
18846
- const rows = value.servers;
18847
- if (!rows.length) return "No artifacts servers are running.";
18848
- return rows.map(
18849
- (row) => [
18850
- shortPath(row.project),
18851
- row.url ?? "starting",
18852
- `pid ${row.pid}`,
18853
- row.clients === null ? null : `tabs ${row.clients}`,
18854
- row.lastActivity === null ? null : `idle ${duration(now - row.lastActivity)}`,
18855
- ...tags(row).map((tag) => `[${tag}]`)
18856
- ].filter(Boolean).join(" ")
18857
- ).join("\n");
18858
- }
18859
- async function monitor(options, emit) {
18860
- if (options.json || !process.stdout.isTTY || !process.stdin.isTTY) {
18861
- emit({ type: "servers", servers: await listServers() });
18862
- return 0;
18863
- }
18864
- return runMonitorUi();
18865
- }
18866
- var monitorCommand = {
18867
- name: "monitor",
18868
- summary: "List every running artifacts server on this machine and manage them",
18869
- details: "In a terminal it opens a live view (open, copy URL, logs, stop); otherwise, or with --json, prints the list once.",
18870
- options: {},
18871
- run: ({ values }, emit) => monitor({ json: !!values.json }, emit),
18872
- text: (value) => monitorText(value)
18873
- };
18874
-
18875
18435
  // src/cli/publish.ts
18876
18436
  async function publish(options, emit) {
18877
18437
  if (options.action === "publish" || options.action === "unpublish") {
@@ -18985,15 +18545,15 @@ ${value.url}`;
18985
18545
  };
18986
18546
 
18987
18547
  // src/cli/start.ts
18988
- var import_node_child_process4 = require("node:child_process");
18548
+ var import_node_child_process3 = require("node:child_process");
18989
18549
  var import_node_crypto2 = __toESM(require("node:crypto"), 1);
18990
- var import_node_fs14 = __toESM(require("node:fs"), 1);
18550
+ var import_node_fs13 = __toESM(require("node:fs"), 1);
18991
18551
  var import_node_path12 = __toESM(require("node:path"), 1);
18992
- var import_node_readline2 = __toESM(require("node:readline"), 1);
18552
+ var import_node_readline = __toESM(require("node:readline"), 1);
18993
18553
 
18994
18554
  // src/server/artifact-address.ts
18995
- var import_node_fs12 = __toESM(require("node:fs"), 1);
18996
- var import_node_path10 = __toESM(require("node:path"), 1);
18555
+ var import_node_fs10 = __toESM(require("node:fs"), 1);
18556
+ var import_node_path9 = __toESM(require("node:path"), 1);
18997
18557
 
18998
18558
  // src/shared/ids.ts
18999
18559
  var SLUG_SOURCE = "[a-z0-9][a-z0-9-]*";
@@ -19031,15 +18591,15 @@ function artifactKeyOf(relative, isId = isArtifactId) {
19031
18591
 
19032
18592
  // src/server/artifact-address.ts
19033
18593
  function artifactId(dir) {
19034
- const file = import_node_path10.default.join(dir, ".artifact-id");
18594
+ const file = import_node_path9.default.join(dir, ".artifact-id");
19035
18595
  let id;
19036
18596
  try {
19037
- id = import_node_fs12.default.readFileSync(file, "utf8").trim();
18597
+ id = import_node_fs10.default.readFileSync(file, "utf8").trim();
19038
18598
  } catch (err) {
19039
18599
  if (err.code !== "ENOENT") throw err;
19040
18600
  id = mintArtifactId();
19041
18601
  try {
19042
- import_node_fs12.default.writeFileSync(file, `${id}
18602
+ import_node_fs10.default.writeFileSync(file, `${id}
19043
18603
  `, { flag: "wx" });
19044
18604
  } catch (writeError) {
19045
18605
  if (writeError.code !== "EEXIST") throw writeError;
@@ -19051,15 +18611,26 @@ function artifactId(dir) {
19051
18611
  }
19052
18612
  function artifactPath(root, type, slug) {
19053
18613
  if (!isArtifactType(type) || !isArtifactId(slug)) throw new Error("Invalid artifact locator");
19054
- const dir = import_node_path10.default.join(root, type, slug);
19055
- import_node_fs12.default.mkdirSync(dir, { recursive: true });
18614
+ const dir = import_node_path9.default.join(root, type, slug);
18615
+ import_node_fs10.default.mkdirSync(dir, { recursive: true });
19056
18616
  return `/${type}/${artifactId(dir)}`;
19057
18617
  }
19058
18618
 
19059
18619
  // src/server/browser-focus.ts
19060
- var import_node_child_process3 = require("node:child_process");
18620
+ var import_node_child_process2 = require("node:child_process");
19061
18621
  var import_node_util2 = require("node:util");
19062
- var execute = (0, import_node_util2.promisify)(import_node_child_process3.execFile);
18622
+
18623
+ // src/server/lifecycle.ts
18624
+ function browserLauncher(platform, url) {
18625
+ if (platform === "darwin") return { bin: "open", args: [url] };
18626
+ if (platform === "win32") return { bin: "cmd", args: ["/c", "start", '""', url] };
18627
+ if (platform === "linux" || platform === "freebsd" || platform === "openbsd")
18628
+ return { bin: "xdg-open", args: [url] };
18629
+ return null;
18630
+ }
18631
+
18632
+ // src/server/browser-focus.ts
18633
+ var execute = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
19063
18634
  var MAC_FOCUS_SCRIPT = String.raw`
19064
18635
  function run(urls) {
19065
18636
  function key(url) {
@@ -19109,18 +18680,64 @@ async function openBrowser(url, aliases2 = []) {
19109
18680
  if (launcher) await execute(launcher.bin, launcher.args);
19110
18681
  }
19111
18682
 
18683
+ // src/server/registry.ts
18684
+ var import_node_crypto = __toESM(require("node:crypto"), 1);
18685
+ var import_node_fs11 = __toESM(require("node:fs"), 1);
18686
+ var import_node_os5 = __toESM(require("node:os"), 1);
18687
+ var import_node_path10 = __toESM(require("node:path"), 1);
18688
+ function registryDir(env = process.env, platform = process.platform, uid = process.getuid?.() ?? -1, tmpdir = import_node_os5.default.tmpdir()) {
18689
+ if (env.RYUGI_RUNTIME_DIR) return import_node_path10.default.join(env.RYUGI_RUNTIME_DIR, "servers");
18690
+ if (platform === "win32") return import_node_path10.default.join(tmpdir, "ryugi", "servers");
18691
+ return `/tmp/ryugi-${uid}/servers`;
18692
+ }
18693
+ var fileFor = (dir, project) => import_node_path10.default.join(dir, `${import_node_crypto.default.createHash("sha256").update(project).digest("hex").slice(0, 16)}.json`);
18694
+ function verifyDir(dir) {
18695
+ if (process.platform === "win32") return;
18696
+ for (const target of [import_node_path10.default.dirname(dir), dir]) {
18697
+ const stat = import_node_fs11.default.lstatSync(target);
18698
+ if (!stat.isDirectory() || stat.uid !== process.getuid() || stat.mode & 18)
18699
+ throw new Error(`Unsafe registry directory: ${target}`);
18700
+ }
18701
+ }
18702
+ function readEntry(file) {
18703
+ try {
18704
+ const value = JSON.parse(import_node_fs11.default.readFileSync(file, "utf8"));
18705
+ if (typeof value.project !== "string" || typeof value.root !== "string" || typeof value.serverId !== "string")
18706
+ return null;
18707
+ if (!Number.isInteger(value.pid) || !Number.isFinite(value.startedAt)) return null;
18708
+ if (value.root !== import_node_path10.default.join(value.project, ".ryugi", "artifacts")) return null;
18709
+ return value;
18710
+ } catch {
18711
+ return null;
18712
+ }
18713
+ }
18714
+ function readEntries(dir) {
18715
+ let names;
18716
+ try {
18717
+ verifyDir(dir);
18718
+ names = import_node_fs11.default.readdirSync(dir);
18719
+ } catch {
18720
+ return [];
18721
+ }
18722
+ return names.filter((name) => name.endsWith(".json")).flatMap((name) => readEntry(import_node_path10.default.join(dir, name)) ?? []);
18723
+ }
18724
+ function removeEntry(dir, entry) {
18725
+ const file = fileFor(dir, entry.project);
18726
+ if (readEntry(file)?.serverId === entry.serverId) import_node_fs11.default.rmSync(file, { force: true });
18727
+ }
18728
+
19112
18729
  // src/cli/login-hint.ts
19113
- var import_node_fs13 = __toESM(require("node:fs"), 1);
19114
- var import_node_os7 = __toESM(require("node:os"), 1);
18730
+ var import_node_fs12 = __toESM(require("node:fs"), 1);
18731
+ var import_node_os6 = __toESM(require("node:os"), 1);
19115
18732
  var import_node_path11 = __toESM(require("node:path"), 1);
19116
18733
  function takeLoginHint(projectDir) {
19117
- const file = credentialsFile(process.env, process.platform, import_node_os7.default.homedir());
18734
+ const file = credentialsFile(process.env, process.platform, import_node_os6.default.homedir());
19118
18735
  const origin = (process.env.RYUGI_CLOUD_ORIGIN || "https://ryugi.innei.dev").replace(/\/+$/, "");
19119
18736
  if (readCredentials(file, origin)) return;
19120
18737
  const marker = import_node_path11.default.join(import_node_path11.default.dirname(file), "login-hint-shown");
19121
18738
  try {
19122
- import_node_fs13.default.mkdirSync(import_node_path11.default.dirname(marker), { recursive: true, mode: 448 });
19123
- import_node_fs13.default.writeFileSync(marker, "1\n", { flag: "wx", mode: 384 });
18739
+ import_node_fs12.default.mkdirSync(import_node_path11.default.dirname(marker), { recursive: true, mode: 448 });
18740
+ import_node_fs12.default.writeFileSync(marker, "1\n", { flag: "wx", mode: 384 });
19124
18741
  } catch (error) {
19125
18742
  if (error.code === "EEXIST") return;
19126
18743
  }
@@ -19138,32 +18755,69 @@ function loginHintText(value) {
19138
18755
  In ${hint.projectDir}, run \`${hint.command}\` to sign in.`;
19139
18756
  }
19140
18757
 
18758
+ // src/cli/upgrade-rule.ts
18759
+ var isLocal = (version) => version.startsWith("local-");
18760
+ function compare(a, b) {
18761
+ const pa = a.split(/[.-]/).slice(0, 3).map(Number);
18762
+ const pb = b.split(/[.-]/).slice(0, 3).map(Number);
18763
+ for (let i = 0; i < 3; i++) {
18764
+ const diff = (pa[i] || 0) - (pb[i] || 0);
18765
+ if (diff) return Math.sign(diff);
18766
+ }
18767
+ return 0;
18768
+ }
18769
+ function replaceDecision(running, cli) {
18770
+ if (!cli) return "keep";
18771
+ if (!running) return "replace";
18772
+ if (running === cli) return "keep";
18773
+ if (isLocal(cli)) return "replace";
18774
+ if (isLocal(running)) return "keep";
18775
+ return compare(cli, running) > 0 ? "replace" : "keep-older-cli";
18776
+ }
18777
+
19141
18778
  // src/cli/start.ts
19142
- var windowsLike = () => process.platform === "win32";
19143
- function withLink(info, artifact, reused) {
19144
- const out = { ...info };
19145
- if (reused) out.reused = true;
19146
- if (artifact && typeof out.url === "string") {
19147
- const url = new URL(out.url);
18779
+ var DEFAULT_CLOUD_ORIGIN = "https://ryugi.innei.dev";
18780
+ var RESERVE_TIMEOUT_MS = 5e3;
18781
+ var REGISTER_TIMEOUT_MS = 15e3;
18782
+ var STATUS_TIMEOUT_MS = 1e3;
18783
+ var START_TIMEOUT_MS = 1e4;
18784
+ var SETTLE_MS = 6e3;
18785
+ var cloudOriginOf = (env) => (env.RYUGI_CLOUD_ORIGIN || DEFAULT_CLOUD_ORIGIN).replace(/\/+$/, "");
18786
+ var loopbackUrl = (url) => {
18787
+ const parsed = new URL(url);
18788
+ if (parsed.hostname === "localhost") parsed.hostname = "127.0.0.1";
18789
+ return parsed;
18790
+ };
18791
+ var apiUrl = (info, pathname) => {
18792
+ const base = loopbackUrl(info.url);
18793
+ const target = new URL(pathname, base.origin);
18794
+ const key2 = base.searchParams.get("key");
18795
+ if (key2) target.searchParams.set("key", key2);
18796
+ return target.toString();
18797
+ };
18798
+ function withLink(info, paths, artifact) {
18799
+ const out = {
18800
+ type: "server-started",
18801
+ url: info.url,
18802
+ port: info.port,
18803
+ root: paths.root
18804
+ };
18805
+ if (artifact) {
18806
+ const url = new URL(info.url);
19148
18807
  const ref = artifactKeyOf(artifact);
19149
18808
  const key2 = url.searchParams.get("key");
19150
- out.link = `${url.origin}${artifactPath(String(out.root), ref.type, ref.id)}${key2 ? `?key=${key2}` : ""}`;
18809
+ out.link = `${url.origin}${artifactPath(paths.root, ref.type, ref.id)}${key2 ? `?key=${key2}` : ""}`;
19151
18810
  }
19152
18811
  return out;
19153
18812
  }
19154
- var RESERVE_TIMEOUT_MS = 5e3;
19155
- async function withCloudLink(out, artifact) {
19156
- if (!artifact || typeof out.url !== "string") return out;
19157
- const server = new URL(out.url);
19158
- if (server.hostname === "localhost") server.hostname = "127.0.0.1";
18813
+ async function withCloudLink(out, info, paths, artifact) {
18814
+ if (!artifact) return out;
19159
18815
  try {
19160
- const res = await fetch(
19161
- `${server.origin}/api/cloud/reserve/${artifact}?key=${encodeURIComponent(server.searchParams.get("key") ?? "")}`,
19162
- {
19163
- method: "POST",
19164
- signal: AbortSignal.timeout(RESERVE_TIMEOUT_MS)
19165
- }
19166
- );
18816
+ const res = await fetch(apiUrl(info, `/api/cloud/reserve/${artifact}`), {
18817
+ method: "POST",
18818
+ headers: { "X-Ryugi-Project": encodeURIComponent(paths.project) },
18819
+ signal: AbortSignal.timeout(RESERVE_TIMEOUT_MS)
18820
+ });
19167
18821
  const { url, limit } = await res.json();
19168
18822
  if (typeof url === "string") return { ...out, cloudLink: url };
19169
18823
  if (typeof limit?.upgradeUrl === "string")
@@ -19176,13 +18830,13 @@ async function withCloudLink(out, artifact) {
19176
18830
  async function acquireLock(lock) {
19177
18831
  for (let attempt = 0; attempt < 150; attempt++) {
19178
18832
  try {
19179
- import_node_fs14.default.mkdirSync(lock);
18833
+ import_node_fs13.default.mkdirSync(lock);
19180
18834
  return true;
19181
18835
  } catch {
19182
18836
  }
19183
18837
  try {
19184
- if (Date.now() - import_node_fs14.default.statSync(lock).mtimeMs > 6e4) {
19185
- import_node_fs14.default.rmdirSync(lock);
18838
+ if (Date.now() - import_node_fs13.default.statSync(lock).mtimeMs > 6e4) {
18839
+ import_node_fs13.default.rmdirSync(lock);
19186
18840
  continue;
19187
18841
  }
19188
18842
  } catch {
@@ -19191,142 +18845,195 @@ async function acquireLock(lock) {
19191
18845
  }
19192
18846
  return false;
19193
18847
  }
19194
- function runningPid(paths) {
19195
- const pid = Number(readText(paths.pid));
19196
- const id = readText(paths.serverId);
18848
+ function runningPid(machine) {
18849
+ const pid = Number(readText(machine.pid));
18850
+ const id = readText(machine.serverId);
19197
18851
  if (!Number.isInteger(pid) || pid <= 0 || !id) return null;
19198
18852
  return hasServerId(pid, id) ? pid : null;
19199
18853
  }
19200
- function ownerPid() {
19201
- if (windowsLike()) return null;
19202
- const given = Number(process.env.RYUGI_ARTIFACTS_OWNER);
19203
- if (Number.isInteger(given) && given > 1) return given;
19204
- return parentOf(process.ppid) ?? process.ppid;
19205
- }
19206
- function registerOwner(paths) {
19207
- const owners = /* @__PURE__ */ new Set();
19208
- for (const line of (readText(paths.owners) ?? "").split("\n")) {
19209
- const pid = Number(line.trim());
19210
- if (Number.isInteger(pid) && pid > 1 && alive(pid)) owners.add(pid);
19211
- }
19212
- const owner = ownerPid();
19213
- if (owner) owners.add(owner);
19214
- const tmp = `${paths.owners}.${process.pid}`;
19215
- import_node_fs14.default.writeFileSync(
19216
- tmp,
19217
- [...owners].sort((a, b) => a - b).map((pid) => `${pid}
19218
- `).join("")
19219
- );
19220
- import_node_fs14.default.renameSync(tmp, paths.owners);
18854
+ function readInfo(machine) {
18855
+ try {
18856
+ const info = JSON.parse(readText(machine.info) ?? "");
18857
+ return typeof info.url === "string" && Number.isInteger(info.port) ? info : null;
18858
+ } catch {
18859
+ return null;
18860
+ }
19221
18861
  }
19222
- function recordAgent(paths) {
19223
- const markers = Object.fromEntries(
19224
- AGENT_MARKERS.flatMap((key2) => process.env[key2] ? [[key2, process.env[key2]]] : [])
19225
- );
19226
- if (Object.keys(markers).length) import_node_fs14.default.writeFileSync(paths.agent, `${JSON.stringify(markers)}
19227
- `);
18862
+ async function answers(info) {
18863
+ try {
18864
+ const res = await fetch(apiUrl(info, "/api/status"), {
18865
+ signal: AbortSignal.timeout(STATUS_TIMEOUT_MS)
18866
+ });
18867
+ return res.ok;
18868
+ } catch {
18869
+ return false;
18870
+ }
19228
18871
  }
19229
- async function replace2(pid, paths) {
18872
+ async function stopPid(pid, what) {
19230
18873
  try {
19231
18874
  process.kill(pid, "SIGTERM");
19232
18875
  } catch {
19233
18876
  }
19234
- if (await waitForExit(pid, 5e3)) return;
18877
+ if (await waitForExit(pid, 7e3)) return;
19235
18878
  try {
19236
18879
  process.kill(pid, "SIGKILL");
19237
18880
  } catch {
19238
18881
  }
19239
18882
  if (await waitForExit(pid, 2e3)) return;
19240
18883
  throw new CliError(
19241
- `The running server (pid ${pid}) is on another release and did not stop; stop it with \`${invocation()} stop --project-dir ${paths.project}\` and retry`
18884
+ `The ${what} (pid ${pid}) did not stop; stop it with \`${invocation()} stop\` and retry`
18885
+ );
18886
+ }
18887
+ async function stopOldProjectServers() {
18888
+ const dir = registryDir();
18889
+ for (const entry of readEntries(dir)) {
18890
+ if (hasServerId(entry.pid, entry.serverId)) {
18891
+ try {
18892
+ process.kill(entry.pid, "SIGTERM");
18893
+ } catch {
18894
+ }
18895
+ await waitForExit(entry.pid, 5e3);
18896
+ }
18897
+ try {
18898
+ removeEntry(dir, entry);
18899
+ } catch {
18900
+ }
18901
+ }
18902
+ }
18903
+ function recordAgent(paths) {
18904
+ const markers = Object.fromEntries(
18905
+ AGENT_MARKERS.flatMap((key2) => process.env[key2] ? [[key2, process.env[key2]]] : [])
19242
18906
  );
18907
+ if (Object.keys(markers).length) import_node_fs13.default.writeFileSync(paths.agent, `${JSON.stringify(markers)}
18908
+ `);
19243
18909
  }
19244
- function serverEnv(paths, options) {
18910
+ function serverEnv(options) {
19245
18911
  const env = {
19246
18912
  ...process.env,
19247
- ARTIFACTS_ROOT: paths.root,
19248
18913
  ARTIFACTS_HOST: options.host,
19249
- ARTIFACTS_URL_HOST: options.urlHost,
19250
- ARTIFACTS_OPEN: options.open ? "1" : "0"
18914
+ ARTIFACTS_URL_HOST: options.urlHost
19251
18915
  };
19252
- if (options.artifact) env.ARTIFACTS_OPEN_ARTIFACT = options.artifact;
19253
- if (options.idleTimeoutMinutes)
19254
- env.ARTIFACTS_IDLE_TIMEOUT_MS = String(Number(options.idleTimeoutMinutes) * 6e4);
19255
- delete env.RYUGI_ARTIFACTS_OWNER;
19256
- delete env.RYUGI_ARTIFACTS_VERSION;
19257
- delete env.RYUGI_ARTIFACTS_COMMAND;
18916
+ if (process.env.RYUGI_ARTIFACTS_COMMAND)
18917
+ env.RYUGI_ARTIFACTS_LAUNCHER = process.env.RYUGI_ARTIFACTS_COMMAND;
18918
+ for (const key2 of [
18919
+ "RYUGI_ARTIFACTS_OWNER",
18920
+ "RYUGI_ARTIFACTS_VERSION",
18921
+ "RYUGI_ARTIFACTS_COMMAND",
18922
+ "ARTIFACTS_OPEN_CMD",
18923
+ "ARTIFACTS_ROOT"
18924
+ ])
18925
+ delete env[key2];
19258
18926
  return env;
19259
18927
  }
18928
+ var startedLine = (text2) => text2.split("\n").find((line) => line.includes('"server-started"'));
18929
+ var errorLine = (text2) => text2.split("\n").find((line) => line.includes('"server-error"'));
18930
+ async function register(info, paths, open) {
18931
+ const res = await fetch(apiUrl(info, "/api/hub/projects"), {
18932
+ method: "POST",
18933
+ headers: { "Content-Type": "application/json" },
18934
+ body: JSON.stringify({
18935
+ dir: paths.project,
18936
+ ...open ? { open } : {},
18937
+ ...open && process.env.ARTIFACTS_OPEN_CMD ? { openCmd: process.env.ARTIFACTS_OPEN_CMD } : {}
18938
+ }),
18939
+ signal: AbortSignal.timeout(REGISTER_TIMEOUT_MS)
18940
+ });
18941
+ if (!res.ok) throw new CliError(`The artifacts server refused this project: ${await res.text()}`);
18942
+ }
19260
18943
  async function start(options, emit) {
19261
18944
  if (options.artifact !== void 0 && !ARTIFACT_PATTERN.test(options.artifact))
19262
18945
  throw new CliError(ARTIFACT_ERROR);
19263
- if (options.idleTimeoutMinutes !== void 0 && (!/^\d+$/.test(options.idleTimeoutMinutes) || Number(options.idleTimeoutMinutes) < 1))
19264
- throw new CliError("--idle-timeout-minutes must be a positive integer");
18946
+ if (options.port !== void 0 && (!/^\d+$/.test(options.port) || Number(options.port) < 1 || Number(options.port) > 65535))
18947
+ throw new CliError("--port must be a port number");
19265
18948
  options.urlHost ||= options.host === "127.0.0.1" || options.host === "localhost" ? "localhost" : options.host;
19266
- const foreground = options.foreground || !options.background && (!!process.env.CODEX_CI || windowsLike());
19267
18949
  process.umask(63);
19268
18950
  const paths = projectPaths(options.projectDir);
19269
- const emitStarted = (out) => {
18951
+ const machine = machinePaths();
18952
+ ensureHome(machine.home);
18953
+ import_node_fs13.default.mkdirSync(paths.state, { recursive: true });
18954
+ if (!import_node_fs13.default.existsSync(import_node_path12.default.join(paths.state, ".gitignore")))
18955
+ import_node_fs13.default.writeFileSync(import_node_path12.default.join(paths.state, ".gitignore"), "*\n");
18956
+ const cliVersion = process.env.RYUGI_ARTIFACTS_VERSION || (true ? "1.51.1" : "");
18957
+ const known = readProjects(machine.projects).some((entry) => entry.dir === paths.project);
18958
+ const finish = async (info, reused, hint) => {
18959
+ recordAgent(paths);
18960
+ const wantsOpen = options.open && (!reused || !known);
18961
+ await register(info, paths, wantsOpen ? options.artifact ?? true : void 0);
18962
+ const base = withLink(info, paths, options.artifact);
18963
+ if (reused) base.reused = true;
18964
+ if (hint) base.hint = hint;
18965
+ const out = await withCloudLink(base, info, paths, options.artifact);
19270
18966
  const loginHint = takeLoginHint(paths.project);
19271
18967
  emit(loginHint ? { ...out, loginHint } : out);
18968
+ if (reused && known && process.platform === "darwin" && options.open && options.openExisting && options.artifact && !process.env.ARTIFACTS_OPEN_CMD) {
18969
+ const local = out.link;
18970
+ await openBrowser(typeof out.cloudLink === "string" ? out.cloudLink : local, [local]).catch(
18971
+ (error) => console.error(error.message)
18972
+ );
18973
+ }
19272
18974
  };
19273
- import_node_fs14.default.mkdirSync(paths.state, { recursive: true });
19274
- if (!import_node_fs14.default.existsSync(import_node_path12.default.join(paths.state, ".gitignore")))
19275
- import_node_fs14.default.writeFileSync(import_node_path12.default.join(paths.state, ".gitignore"), "*\n");
19276
- const server = import_node_path12.default.join(__dirname, "server.cjs");
19277
- const version = process.env.RYUGI_ARTIFACTS_VERSION ?? "";
19278
- if (!await acquireLock(paths.lock))
19279
- throw new CliError("Another start for this project is still starting; retry in a moment");
18975
+ if (!await acquireLock(machine.lock))
18976
+ throw new CliError("Another start is still starting the artifacts server; retry in a moment");
19280
18977
  let locked = true;
19281
18978
  const unlock = () => {
19282
18979
  if (!locked) return;
19283
18980
  locked = false;
19284
18981
  try {
19285
- import_node_fs14.default.rmdirSync(paths.lock);
18982
+ import_node_fs13.default.rmdirSync(machine.lock);
19286
18983
  } catch {
19287
18984
  }
19288
18985
  };
19289
18986
  try {
19290
- const running = runningPid(paths);
19291
- const info = readText(paths.info);
18987
+ const running = runningPid(machine);
18988
+ let info = readInfo(machine);
18989
+ if (running && !info) {
18990
+ for (let waited = 0; waited < SETTLE_MS && alive(running) && !info; waited += 100) {
18991
+ await sleep(100);
18992
+ info = readInfo(machine);
18993
+ }
18994
+ if (!info && alive(running)) await stopPid(running, "stopping artifacts server");
18995
+ }
19292
18996
  if (running && info) {
19293
- if (!version || readText(paths.version) === version) {
19294
- registerOwner(paths);
19295
- recordAgent(paths);
19296
- const out = await withCloudLink(
19297
- withLink(JSON.parse(info), options.artifact, true),
19298
- options.artifact
18997
+ const runningVersion = readText(machine.version) ?? "";
18998
+ const decision = replaceDecision(runningVersion, cliVersion);
18999
+ const mismatch = (info.host ?? "127.0.0.1") !== options.host || (info.urlHost ?? "localhost") !== options.urlHost || (info.cloudOrigin ?? DEFAULT_CLOUD_ORIGIN) !== cloudOriginOf(process.env) || options.port !== void 0 && String(info.port) !== options.port;
19000
+ if (decision !== "replace" && !mismatch && await answers(info)) {
19001
+ unlock();
19002
+ await finish(
19003
+ info,
19004
+ true,
19005
+ decision === "keep-older-cli" ? `The running server is ${runningVersion}, newer than this CLI (${cliVersion}); kept it` : void 0
19299
19006
  );
19300
- emitStarted(out);
19301
- if (process.platform === "darwin" && options.open && options.openExisting && options.artifact && !process.env.ARTIFACTS_OPEN_CMD) {
19302
- const local = out.link;
19303
- await openBrowser(typeof out.cloudLink === "string" ? out.cloudLink : local, [
19304
- local
19305
- ]).catch((error) => {
19306
- console.error(error.message);
19307
- });
19308
- }
19309
19007
  return 0;
19310
19008
  }
19311
- await replace2(running, paths);
19009
+ await stopPid(running, "running artifacts server");
19312
19010
  }
19313
- registerOwner(paths);
19314
- recordAgent(paths);
19315
- import_node_fs14.default.rmSync(paths.info, { force: true });
19011
+ await stopOldProjectServers();
19012
+ import_node_fs13.default.rmSync(machine.info, { force: true });
19316
19013
  const id = import_node_crypto2.default.randomBytes(24).toString("hex");
19317
- import_node_fs14.default.writeFileSync(paths.serverId, `${id}
19014
+ import_node_fs13.default.writeFileSync(machine.serverId, `${id}
19318
19015
  `);
19319
- import_node_fs14.default.writeFileSync(paths.version, `${version}
19016
+ import_node_fs13.default.writeFileSync(machine.version, `${cliVersion}
19320
19017
  `);
19321
- const env = serverEnv(paths, options);
19322
- const args = [server, `--artifacts-server-id=${id}`];
19018
+ const server = import_node_path12.default.join(__dirname, "server.cjs");
19019
+ const args = [
19020
+ server,
19021
+ `--artifacts-server-id=${id}`,
19022
+ ...options.port ? [`--port=${options.port}`] : []
19023
+ ];
19024
+ const env = serverEnv(options);
19025
+ const foreground = options.foreground || !options.background && !!process.env.CODEX_CI;
19323
19026
  if (foreground) {
19324
- const child2 = (0, import_node_child_process4.spawn)(process.execPath, args, { env, stdio: ["ignore", "pipe", "inherit"] });
19325
- import_node_fs14.default.writeFileSync(paths.pid, `${child2.pid}
19027
+ const child2 = (0, import_node_child_process3.spawn)(process.execPath, args, { env, stdio: ["ignore", "pipe", "inherit"] });
19028
+ import_node_fs13.default.writeFileSync(machine.pid, `${child2.pid}
19326
19029
  `);
19327
19030
  for (const signal of ["SIGINT", "SIGTERM"])
19328
19031
  process.on(signal, () => child2.kill("SIGTERM"));
19329
- import_node_readline2.default.createInterface({ input: child2.stdout }).on("line", (line) => {
19032
+ const exited = new Promise(
19033
+ (resolve) => child2.on("close", (code) => resolve(code ?? 1))
19034
+ );
19035
+ let announced = false;
19036
+ import_node_readline.default.createInterface({ input: child2.stdout }).on("line", (line) => {
19330
19037
  let value;
19331
19038
  try {
19332
19039
  value = JSON.parse(line);
@@ -19335,64 +19042,59 @@ async function start(options, emit) {
19335
19042
  `);
19336
19043
  return;
19337
19044
  }
19338
- if (value.type !== "server-started") emit(value);
19339
- else
19340
- void withCloudLink(withLink(value, options.artifact, false), options.artifact).then(
19341
- emitStarted
19342
- );
19045
+ if (value.type !== "server-started" || announced) {
19046
+ emit(value);
19047
+ return;
19048
+ }
19049
+ announced = true;
19050
+ unlock();
19051
+ void finish(value, false).catch(
19052
+ (error) => emit({ type: "error", error: error.message })
19053
+ );
19343
19054
  });
19344
- const exited = new Promise(
19345
- (resolve) => child2.on("close", (code) => resolve(code ?? 1))
19346
- );
19347
- for (let waited = 0; waited < 5e3 && !import_node_fs14.default.existsSync(paths.info); waited += 100)
19348
- await sleep(100);
19349
- unlock();
19350
19055
  return await exited;
19351
19056
  }
19352
- const log = import_node_fs14.default.openSync(paths.log, "w");
19353
- const child = (0, import_node_child_process4.spawn)(process.execPath, args, {
19057
+ const log = import_node_fs13.default.openSync(machine.log, "w");
19058
+ const child = (0, import_node_child_process3.spawn)(process.execPath, args, {
19354
19059
  env,
19355
19060
  detached: true,
19061
+ windowsHide: true,
19356
19062
  stdio: ["ignore", log, log]
19357
19063
  });
19358
- import_node_fs14.default.closeSync(log);
19064
+ import_node_fs13.default.closeSync(log);
19359
19065
  child.unref();
19360
- import_node_fs14.default.writeFileSync(paths.pid, `${child.pid}
19066
+ import_node_fs13.default.writeFileSync(machine.pid, `${child.pid}
19361
19067
  `);
19362
- for (let waited = 0; waited < 5e3; waited += 100) {
19363
- const lines = (readText(paths.log) ?? "").split("\n");
19364
- const started = lines.find((line) => line.includes('"server-started"'));
19068
+ for (let waited = 0; waited < START_TIMEOUT_MS; waited += 100) {
19069
+ const text2 = readText(machine.log) ?? "";
19070
+ const started = startedLine(text2);
19365
19071
  if (started) {
19366
- for (let check2 = 0; check2 < 20; check2++) {
19072
+ for (let check2 = 0; check2 < 10; check2++) {
19367
19073
  if (!alive(child.pid))
19368
19074
  throw new CliError(
19369
19075
  `Server started but was killed. Retry in a persistent terminal with: ${invocation()} start --project-dir ${paths.project}${options.artifact ? ` --artifact ${options.artifact}` : ""} --host ${options.host} --url-host ${options.urlHost} --foreground`
19370
19076
  );
19371
19077
  await sleep(100);
19372
19078
  }
19373
- emitStarted(
19374
- await withCloudLink(
19375
- withLink(JSON.parse(started), options.artifact, false),
19376
- options.artifact
19377
- )
19378
- );
19079
+ unlock();
19080
+ await finish(JSON.parse(started), false);
19379
19081
  return 0;
19380
19082
  }
19381
- const failed = lines.find((line) => line.includes('"server-error"'));
19083
+ const failed = errorLine(text2);
19382
19084
  if (failed) {
19383
19085
  emit(JSON.parse(failed));
19384
19086
  return 1;
19385
19087
  }
19386
19088
  await sleep(100);
19387
19089
  }
19388
- throw new CliError("Server failed to start within 5 seconds");
19090
+ throw new CliError(`Server failed to start within ${START_TIMEOUT_MS / 1e3} seconds`);
19389
19091
  } finally {
19390
19092
  unlock();
19391
19093
  }
19392
19094
  }
19393
19095
  var startCommand = {
19394
19096
  name: "start",
19395
- summary: "Start the project's artifacts server, or reuse the running one",
19097
+ summary: "Start this machine's artifacts server if needed and register the project with it",
19396
19098
  options: {
19397
19099
  "artifact": {
19398
19100
  type: "string",
@@ -19409,10 +19111,10 @@ var startCommand = {
19409
19111
  value: "<host>",
19410
19112
  help: "Host in printed URLs (default: localhost for a loopback --host)"
19411
19113
  },
19412
- "idle-timeout-minutes": {
19114
+ "port": {
19413
19115
  type: "string",
19414
19116
  value: "<n>",
19415
- help: "Stop after this many idle minutes (default: 240)"
19117
+ help: "Port to listen on (default: the first free of 27319-27321)"
19416
19118
  },
19417
19119
  "open": {
19418
19120
  type: "boolean",
@@ -19433,7 +19135,7 @@ var startCommand = {
19433
19135
  artifact: values.artifact,
19434
19136
  host: values.host ?? "127.0.0.1",
19435
19137
  urlHost: values["url-host"],
19436
- idleTimeoutMinutes: values["idle-timeout-minutes"],
19138
+ port: values.port,
19437
19139
  open: values["no-open"] ? false : values.open ? true : process.env.ARTIFACTS_OPEN !== "0",
19438
19140
  openExisting: !!values.open,
19439
19141
  foreground: !!(values.foreground || values["no-daemon"]),
@@ -19444,15 +19146,76 @@ var startCommand = {
19444
19146
  text: (value) => value.type === "server-started" ? `${value.cloudLink ?? value.link ?? value.url}${value.reused ? " (already running)" : ""}` : null
19445
19147
  };
19446
19148
 
19149
+ // src/cli/stop.ts
19150
+ var import_node_fs14 = __toESM(require("node:fs"), 1);
19151
+ var import_node_path13 = __toESM(require("node:path"), 1);
19152
+ function clearCompatInfo(projectsFile) {
19153
+ for (const entry of readProjects(projectsFile))
19154
+ import_node_fs14.default.rmSync(import_node_path13.default.join(artifactsRootOf(entry.dir), ".state", "server-info"), { force: true });
19155
+ }
19156
+ async function stop(emit) {
19157
+ const machine = machinePaths();
19158
+ const markStopped = (reason) => {
19159
+ import_node_fs14.default.rmSync(machine.info, { force: true });
19160
+ clearCompatInfo(machine.projects);
19161
+ import_node_fs14.default.mkdirSync(machine.home, { recursive: true, mode: 448 });
19162
+ import_node_fs14.default.writeFileSync(
19163
+ machine.stopped,
19164
+ `${JSON.stringify({ reason, timestamp: Math.floor(Date.now() / 1e3) })}
19165
+ `
19166
+ );
19167
+ };
19168
+ if (readText(machine.pid) === null) {
19169
+ emit({ status: "not_running" });
19170
+ return 0;
19171
+ }
19172
+ const pid = Number(readText(machine.pid));
19173
+ const id = readText(machine.serverId) ?? "";
19174
+ if (!Number.isInteger(pid) || pid <= 0 || !/^[\w-]{32,64}$/.test(id) || !hasServerId(pid, id)) {
19175
+ import_node_fs14.default.rmSync(machine.pid, { force: true });
19176
+ import_node_fs14.default.rmSync(machine.serverId, { force: true });
19177
+ markStopped("stale_pid");
19178
+ emit({ status: "stale_pid" });
19179
+ return 0;
19180
+ }
19181
+ try {
19182
+ process.kill(pid, "SIGTERM");
19183
+ } catch {
19184
+ }
19185
+ if (!await waitForExit(pid, 7e3)) {
19186
+ try {
19187
+ process.kill(pid, "SIGKILL");
19188
+ } catch {
19189
+ }
19190
+ await waitForExit(pid, 1e3);
19191
+ }
19192
+ if (alive(pid)) {
19193
+ emit({ status: "failed", error: "process still running" });
19194
+ return 1;
19195
+ }
19196
+ for (const file of [machine.pid, machine.serverId]) import_node_fs14.default.rmSync(file, { force: true });
19197
+ markStopped("stop");
19198
+ emit({ status: "stopped" });
19199
+ return 0;
19200
+ }
19201
+ var stopCommand = {
19202
+ name: "stop",
19203
+ summary: "Stop this machine's artifacts server; the artifacts are kept",
19204
+ usage: ["[options]"],
19205
+ options: {},
19206
+ positionals: 1,
19207
+ run: (_args, emit) => stop(emit)
19208
+ };
19209
+
19447
19210
  // src/cli/update.ts
19448
- var import_node_child_process6 = require("node:child_process");
19211
+ var import_node_child_process5 = require("node:child_process");
19449
19212
  var import_node_fs16 = __toESM(require("node:fs"), 1);
19450
19213
 
19451
19214
  // src/cli/update-hint.ts
19452
- var import_node_child_process5 = require("node:child_process");
19215
+ var import_node_child_process4 = require("node:child_process");
19453
19216
  var import_node_fs15 = __toESM(require("node:fs"), 1);
19454
- var import_node_os8 = __toESM(require("node:os"), 1);
19455
- var import_node_path13 = __toESM(require("node:path"), 1);
19217
+ var import_node_os7 = __toESM(require("node:os"), 1);
19218
+ var import_node_path14 = __toESM(require("node:path"), 1);
19456
19219
  var CHECK_MS = 24 * 60 * 60 * 1e3;
19457
19220
  var RELEASE = /^\d+\.\d+\.\d+$/;
19458
19221
  function newer(a, b) {
@@ -19469,8 +19232,8 @@ function updateCheck({ current, cached, now, env, tty, json, argv = [] }) {
19469
19232
  const hint = !quiet && RELEASE.test(current) && RELEASE.test(latest) && newer(latest, current) ? `ryugi-artifacts ${latest} is available (you have ${current}). Run \`ryugi-artifacts update\` to install it.` : null;
19470
19233
  return { hint, refresh: !cached || now - cached.checkedAt >= CHECK_MS };
19471
19234
  }
19472
- var latestFile = (env) => import_node_path13.default.join(
19473
- env.XDG_CACHE_HOME || import_node_path13.default.join(import_node_os8.default.homedir(), ".cache"),
19235
+ var latestFile = (env) => import_node_path14.default.join(
19236
+ env.XDG_CACHE_HOME || import_node_path14.default.join(import_node_os7.default.homedir(), ".cache"),
19474
19237
  "ryugi",
19475
19238
  "artifacts",
19476
19239
  "latest.json"
@@ -19485,7 +19248,7 @@ function readLatest(file) {
19485
19248
  }
19486
19249
  function writeLatest(file, version, checkedAt) {
19487
19250
  try {
19488
- import_node_fs15.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
19251
+ import_node_fs15.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true });
19489
19252
  const tmp = `${file}.${process.pid}`;
19490
19253
  import_node_fs15.default.writeFileSync(tmp, JSON.stringify({ version, checkedAt }));
19491
19254
  import_node_fs15.default.renameSync(tmp, file);
@@ -19509,7 +19272,7 @@ fetch(new URL('ryugi-artifacts/latest', registry), { signal: AbortSignal.timeout
19509
19272
  `;
19510
19273
  function refreshLatest(file, registry2) {
19511
19274
  const base = registry2.endsWith("/") ? registry2 : `${registry2}/`;
19512
- const child = (0, import_node_child_process5.spawn)(process.execPath, ["-e", REFRESH, file, base], {
19275
+ const child = (0, import_node_child_process4.spawn)(process.execPath, ["-e", REFRESH, file, base], {
19513
19276
  detached: true,
19514
19277
  stdio: "ignore"
19515
19278
  });
@@ -19619,7 +19382,7 @@ or run \`${PACKAGE} update --pm <${PMS.join("|")}>\`.`
19619
19382
  return 0;
19620
19383
  }
19621
19384
  const windows = process.platform === "win32";
19622
- const result = windows ? (0, import_node_child_process6.spawnSync)(commandLine2(command), { stdio: ["inherit", 2, 2], env: options.env, shell: true }) : (0, import_node_child_process6.spawnSync)(command.cmd, command.args, { stdio: ["inherit", 2, 2], env: options.env });
19385
+ const result = windows ? (0, import_node_child_process5.spawnSync)(commandLine2(command), { stdio: ["inherit", 2, 2], env: options.env, shell: true }) : (0, import_node_child_process5.spawnSync)(command.cmd, command.args, { stdio: ["inherit", 2, 2], env: options.env });
19623
19386
  if (result.error)
19624
19387
  throw new CliError(`Could not run ${commandLine2(command)}: ${result.error.message}`);
19625
19388
  if (result.status !== 0)
@@ -19646,7 +19409,7 @@ var updateCommand = {
19646
19409
  },
19647
19410
  run: ({ values }, emit) => update2(
19648
19411
  {
19649
- current: "1.49.5",
19412
+ current: "1.51.1",
19650
19413
  file: __filename,
19651
19414
  env: process.env,
19652
19415
  registry: process.env.npm_config_registry || "https://registry.npmjs.org/",
@@ -19672,7 +19435,6 @@ var COMMANDS = [
19672
19435
  publishCommand,
19673
19436
  commentCommand,
19674
19437
  getCommand,
19675
- monitorCommand,
19676
19438
  configCommand,
19677
19439
  updateCommand
19678
19440
  ];
@@ -19694,7 +19456,7 @@ function text(value) {
19694
19456
  function openBrowser2(url) {
19695
19457
  const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
19696
19458
  const args = process.platform === "win32" ? ["/c", "start", '""', url] : [url];
19697
- (0, import_node_child_process7.execFile)(command, args, () => {
19459
+ (0, import_node_child_process6.execFile)(command, args, () => {
19698
19460
  });
19699
19461
  }
19700
19462
  async function browse(argv) {
@@ -19727,7 +19489,7 @@ async function main(argv) {
19727
19489
  const [name, ...rest] = argv;
19728
19490
  const command = COMMANDS.find((candidate) => candidate.name === name);
19729
19491
  const json = argv.includes("--json") || !command?.explicitJson && !process.stdout.isTTY;
19730
- notifyUpdate("1.49.5", json, argv);
19492
+ notifyUpdate("1.51.1", json, argv);
19731
19493
  const emit = (value) => {
19732
19494
  const line = json ? JSON.stringify(value) : text(value);
19733
19495
  if (!json && typeof value.error === "string") console.error(line);
@@ -19746,7 +19508,7 @@ async function main(argv) {
19746
19508
  return await command.run(parse(rest, command.options, command.positionals), emit);
19747
19509
  }
19748
19510
  if (name === "--version" || name === "-v") {
19749
- console.info("1.49.5");
19511
+ console.info("1.51.1");
19750
19512
  return 0;
19751
19513
  }
19752
19514
  if (name === "--help" || name === "-h") {