ryugi-artifacts 1.43.0 → 1.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/dist/cli.cjs +662 -335
  2. package/dist/server.cjs +128 -80
  3. package/dist/viewer/{ArtboardLayout-7_rmu60e.js → ArtboardLayout-v5QCVEaH.js} +1 -1
  4. package/dist/viewer/{ArtifactList-CC5-1ZFP.js → ArtifactList-mxXh57SU.js} +1 -1
  5. package/dist/viewer/{AutoPublishPrompt-B2D53_Kz.js → AutoPublishPrompt-COIe6yz0.js} +1 -1
  6. package/dist/viewer/{Canvas-13klENDh.js → Canvas-DIlI-OTY.js} +1 -1
  7. package/dist/viewer/{DocumentLayout-DZ-2_UTn.js → DocumentLayout-CarX1EiV.js} +2 -2
  8. package/dist/viewer/{DocumentPage-BcgERMV0.js → DocumentPage-BgoMJYd6.js} +1 -1
  9. package/dist/viewer/{HtmlLayout-CtlWM446.js → HtmlLayout-BmYAOIJ4.js} +1 -1
  10. package/dist/viewer/{MenuRoot-CwCVByOp.js → MenuRoot-CCLU8wQR.js} +1 -1
  11. package/dist/viewer/{PopoverPopup-BA537pRU.js → PopoverPopup-By2qMtdn.js} +1 -1
  12. package/dist/viewer/{PreviewLayout-C5OKA9J4.js → PreviewLayout-Dzkz7UOF.js} +2 -2
  13. package/dist/viewer/{Select-D2-94UGe.js → Select-CpRtuH5I.js} +1 -1
  14. package/dist/viewer/{SnapshotDocument-kHyl0dKv.js → SnapshotDocument-D0Lkq1g9.js} +1 -1
  15. package/dist/viewer/{ThreadView-Qlz9Ufo7.js → ThreadView-CmAxKSZ7.js} +1 -1
  16. package/dist/viewer/{TooltipPopup-Cpm4Cwxn.js → TooltipPopup-CdpS4tTR.js} +1 -1
  17. package/dist/viewer/{WarningsBadge-BtRPiCiS.js → WarningsBadge-xIuKcdGp.js} +1 -1
  18. package/dist/viewer/{abnfDiagram-VCTEODGH-Cc589tRO.js → abnfDiagram-VCTEODGH-vYXwOi2L.js} +1 -1
  19. package/dist/viewer/{ar-SA-G6X2FPQ2-qNPFpNYG.js → ar-SA-G6X2FPQ2-9GXzPlrK.js} +1 -1
  20. package/dist/viewer/{architecture-7GRP2DOG-BizmpjHH.js → architecture-7GRP2DOG-Dy3GJfSN.js} +1 -1
  21. package/dist/viewer/{architectureDiagram-5GKGNRK7-BuHdaFmM.js → architectureDiagram-5GKGNRK7-1EQ6eTro.js} +1 -1
  22. package/dist/viewer/{az-AZ-76LH7QW2-CbXvPy4A.js → az-AZ-76LH7QW2-B6E08k0L.js} +1 -1
  23. package/dist/viewer/{bg-BG-XCXSNQG7-DcRkeEZa.js → bg-BG-XCXSNQG7-CT75Hh8J.js} +1 -1
  24. package/dist/viewer/{blockDiagram-I7D4REHJ-BjZAhqNZ.js → blockDiagram-I7D4REHJ-Bots_bLJ.js} +1 -1
  25. package/dist/viewer/{bn-BD-2XOGV67Q-CYG0oQ07.js → bn-BD-2XOGV67Q-CdBG2RJk.js} +1 -1
  26. package/dist/viewer/{c4Diagram-7LVT6UL2-Dw9Lqcc4.js → c4Diagram-7LVT6UL2-C7DksWh5.js} +1 -1
  27. package/dist/viewer/{ca-ES-6MX7JW3Y-DZg7oXog.js → ca-ES-6MX7JW3Y-DDc1wD41.js} +1 -1
  28. package/dist/viewer/channel-ByZrhKcD.js +1 -0
  29. package/dist/viewer/{channel-CgSk2sDt.js → channel-CK8VjRfv.js} +4 -4
  30. package/dist/viewer/{chunk-4HAMMTFA-CmIOM_4n.js → chunk-4HAMMTFA-CFwFBnb7.js} +1 -1
  31. package/dist/viewer/{chunk-75Z2AOVW-Bk3gHz3u.js → chunk-75Z2AOVW-Ckcf4HXf.js} +1 -1
  32. package/dist/viewer/{chunk-DU6HZSFF-Z871Xxjd.js → chunk-DU6HZSFF-DSkKm1Sg.js} +1 -1
  33. package/dist/viewer/{chunk-EIO257PC-BowPlGMj.js → chunk-EIO257PC-Cp5jHH2B.js} +1 -1
  34. package/dist/viewer/{chunk-F27PBJKO-Da_Uy85s.js → chunk-F27PBJKO-CGR7FwkE.js} +1 -1
  35. package/dist/viewer/{chunk-GMAD6QVW-D99eqSu1.js → chunk-GMAD6QVW-CrVyThKY.js} +1 -1
  36. package/dist/viewer/{chunk-GVQU2GXP-DpHE-JHS.js → chunk-GVQU2GXP-DeN7DWg4.js} +1 -1
  37. package/dist/viewer/{chunk-IMKFNOWR-DNlzjXm8.js → chunk-IMKFNOWR-fh_OFrpb.js} +1 -1
  38. package/dist/viewer/{chunk-L3NEJ4N5-CwGjxbjF.js → chunk-L3NEJ4N5-B5ku2yKH.js} +1 -1
  39. package/dist/viewer/{chunk-OSK3NFVY-B4adwKZF.js → chunk-OSK3NFVY-BZxVtLcj.js} +1 -1
  40. package/dist/viewer/{chunk-P2QGCYS3-CR8elxW8.js → chunk-P2QGCYS3-vj5npGX4.js} +1 -1
  41. package/dist/viewer/{chunk-POPQ4Y6H-D5X5fYtJ.js → chunk-POPQ4Y6H-y6gZTjTL.js} +1 -1
  42. package/dist/viewer/{chunk-PWAF6VOD-C52ljaIH.js → chunk-PWAF6VOD-C5U8QIrG.js} +1 -1
  43. package/dist/viewer/{chunk-SHT3W25Y-Bqd2yIYA.js → chunk-SHT3W25Y-CrNt-vdk.js} +1 -1
  44. package/dist/viewer/{chunk-SVP7TREG-B-2E6atr.js → chunk-SVP7TREG-B4H37B9Z.js} +1 -1
  45. package/dist/viewer/{chunk-TICWLB2K-C4hY4B9O.js → chunk-TICWLB2K-DYoGsdJA.js} +1 -1
  46. package/dist/viewer/classDiagram-ZZMXUADV-G09oZdI0.js +1 -0
  47. package/dist/viewer/classDiagram-v2-VYDZK3BY-G09oZdI0.js +1 -0
  48. package/dist/viewer/{cs-CZ-2BRQDIVT-DmUu99ZE.js → cs-CZ-2BRQDIVT-DgBiVbuw.js} +1 -1
  49. package/dist/viewer/{cynefin-OW5HDTMX-CNpCyJlF.js → cynefin-OW5HDTMX-bvMkVO6w.js} +1 -1
  50. package/dist/viewer/{cynefinDiagram-5FMLGOSQ-D_E8exI5.js → cynefinDiagram-5FMLGOSQ-CjPrZzrG.js} +1 -1
  51. package/dist/viewer/{da-DK-5WZEPLOC-DrcqQnR5.js → da-DK-5WZEPLOC-D-yGNnLN.js} +1 -1
  52. package/dist/viewer/{dagre-GXQ25YYZ-B-hQNnoj.js → dagre-GXQ25YYZ-CuRrD3a3.js} +1 -1
  53. package/dist/viewer/{de-DE-XR44H4JA-BwGQ1Bu3.js → de-DE-XR44H4JA-Bgx9Q_D-.js} +1 -1
  54. package/dist/viewer/{diagram-S7CK7UJ4-DyrrPPnW.js → diagram-S7CK7UJ4-d9huVCZC.js} +1 -1
  55. package/dist/viewer/{diagram-UQ7AKVKN-DFdvde_8.js → diagram-UQ7AKVKN-Dw0NgQU7.js} +1 -1
  56. package/dist/viewer/{diagram-VSXAHHWV-BDdvfK3v.js → diagram-VSXAHHWV-BO48ZPAa.js} +1 -1
  57. package/dist/viewer/{diagram-VX7I27RA-Bv2wKJgk.js → diagram-VX7I27RA-CjjLbqAT.js} +1 -1
  58. package/dist/viewer/{diagram-Z3DM3KII-DVbVVBJH.js → diagram-Z3DM3KII-CqSQfWgq.js} +1 -1
  59. package/dist/viewer/{dist-DL1gyV3R.js → dist-96ICyKY0.js} +1 -1
  60. package/dist/viewer/{dist-DRMtu_-x.js → dist-BICCa23f.js} +1 -1
  61. package/dist/viewer/{dist-gv6IdArU.js → dist-BQJ_hgBh.js} +1 -1
  62. package/dist/viewer/{dist-DJjmFLDp.js → dist-BdwcfhMg.js} +1 -1
  63. package/dist/viewer/{dist-nHjoUtlT.js → dist-BohmHXvo.js} +1 -1
  64. package/dist/viewer/{dist-Cp67yPvp.js → dist-Bq5yGCvS.js} +1 -1
  65. package/dist/viewer/{dist-BpMGGlEV.js → dist-Bsxu0shl.js} +4 -4
  66. package/dist/viewer/{dist-C1no3jCb.js → dist-C8DkAQYd.js} +1 -1
  67. package/dist/viewer/{dist-B_G83rKD.js → dist-CACUOSsz.js} +1 -1
  68. package/dist/viewer/{dist-3KIsZmwj.js → dist-CFmM2XV7.js} +1 -1
  69. package/dist/viewer/{dist-C-Ceo6Fq.js → dist-CGDckSlK.js} +1 -1
  70. package/dist/viewer/{dist-BLMq_PiX.js → dist-CNKIbzP5.js} +1 -1
  71. package/dist/viewer/{dist-CLaYa349.js → dist-CoNkk-jP.js} +1 -1
  72. package/dist/viewer/{dist-DDjqhgMa.js → dist-Ct9Rv4Nb.js} +1 -1
  73. package/dist/viewer/{dist-Cs9q7OJl.js → dist-DFqgUaXc.js} +1 -1
  74. package/dist/viewer/{dist-Dril0ai0.js → dist-DHvxE90p.js} +1 -1
  75. package/dist/viewer/{dist-BfMsz_Mq.js → dist-DRVN9BoJ.js} +1 -1
  76. package/dist/viewer/{dist-Ks19j7-h.js → dist-DbTvrrue.js} +1 -1
  77. package/dist/viewer/{dist-DJtATNMP.js → dist-DeTBwAKa.js} +1 -1
  78. package/dist/viewer/{dist-BqBGd2fX.js → dist-DwmGeZQ2.js} +1 -1
  79. package/dist/viewer/{dist-Dbb4bImq.js → dist-PKCsW6uh.js} +1 -1
  80. package/dist/viewer/{dist-DpiVIFsv.js → dist-f6pfIPrl.js} +1 -1
  81. package/dist/viewer/{dist-2N6kKX64.js → dist-iWGU90nm.js} +1 -1
  82. package/dist/viewer/{dist-b6M4YQd0.js → dist-tEmP_1dP.js} +1 -1
  83. package/dist/viewer/{ebnfDiagram-PWID7BFC-BPZEgIKG.js → ebnfDiagram-PWID7BFC-DUuSLOwC.js} +1 -1
  84. package/dist/viewer/{el-GR-BZB4AONW-BHX9PTvB.js → el-GR-BZB4AONW-DBGnJY6B.js} +1 -1
  85. package/dist/viewer/{en-B4ZKOASM-ChdJoy_X.js → en-B4ZKOASM-ChYtA4ee.js} +1 -1
  86. package/dist/viewer/{erDiagram-RLTQ6QDP-teAVgmCA.js → erDiagram-RLTQ6QDP-6atcXUph.js} +1 -1
  87. package/dist/viewer/{es-ES-U4NZUMDT-DGRmVt9a.js → es-ES-U4NZUMDT-CktGk8Tg.js} +1 -1
  88. package/dist/viewer/{eu-ES-A7QVB2H4-6SSWUUs4.js → eu-ES-A7QVB2H4-CFlNXwf5.js} +1 -1
  89. package/dist/viewer/{eventmodeling-NTZA5JFV-B1I1Mylr.js → eventmodeling-NTZA5JFV-C5ZVZEiz.js} +1 -1
  90. package/dist/viewer/{fa-IR-HGAKTJCU-B_-FrT72.js → fa-IR-HGAKTJCU-CQRMDqXN.js} +1 -1
  91. package/dist/viewer/{fi-FI-Z5N7JZ37-C7SiOzZ-.js → fi-FI-Z5N7JZ37-CHKM1WB9.js} +1 -1
  92. package/dist/viewer/flowDiagram-HODETNUW-B9-KDJxc.js +1 -0
  93. package/dist/viewer/{fr-FR-RHASNOE6-B_QvfKMB.js → fr-FR-RHASNOE6-CUyuT7p6.js} +1 -1
  94. package/dist/viewer/{ganttDiagram-EL5Y4UJY-BMv_Q37E.js → ganttDiagram-EL5Y4UJY-DD2E-HAj.js} +1 -1
  95. package/dist/viewer/{gitGraph-4MIJSDKK-Bu1dbHFU.js → gitGraph-4MIJSDKK-BLvljQme.js} +1 -1
  96. package/dist/viewer/{gitGraphDiagram-WWUBYQGX-DUZ8_32F.js → gitGraphDiagram-WWUBYQGX-B0qzhOb6.js} +1 -1
  97. package/dist/viewer/{gl-ES-HMX3MZ6V-CmXVsVrw.js → gl-ES-HMX3MZ6V-CwJG5tWR.js} +1 -1
  98. package/dist/viewer/{he-IL-6SHJWFNN-8kv-3A3Y.js → he-IL-6SHJWFNN-_DosmhM7.js} +1 -1
  99. package/dist/viewer/{hi-IN-IWLTKZ5I-CvpAemRq.js → hi-IN-IWLTKZ5I-CrW9_EjK.js} +1 -1
  100. package/dist/viewer/{hu-HU-A5ZG7DT2-DOiAQ3qh.js → hu-HU-A5ZG7DT2-Dczvo59m.js} +1 -1
  101. package/dist/viewer/{id-ID-SAP4L64H-BK_k3fGY.js → id-ID-SAP4L64H-iSPag4VQ.js} +1 -1
  102. package/dist/viewer/{image-GAAHSSAO-WbKWFRU6.js → image-GAAHSSAO-BVJuAdML.js} +1 -1
  103. package/dist/viewer/{imperative-DfjHJwB9.js → imperative-_CkvZv3L.js} +1 -1
  104. package/dist/viewer/index.html +3 -3
  105. package/dist/viewer/index.js +3 -3
  106. package/dist/viewer/{info-A6RAGUB7-BVW83dCy.js → info-A6RAGUB7-Bhn0w0ii.js} +1 -1
  107. package/dist/viewer/{infoDiagram-27XIBGKW-C7TxtcWL.js → infoDiagram-27XIBGKW-BVSbmxC-.js} +1 -1
  108. package/dist/viewer/{ishikawaDiagram-5VMMS53U-BT-yQVRc.js → ishikawaDiagram-5VMMS53U-DdsbHCoI.js} +1 -1
  109. package/dist/viewer/{it-IT-JPQ66NNP-BNsEQmLq.js → it-IT-JPQ66NNP-8-_iFasU.js} +1 -1
  110. package/dist/viewer/{itemEquality-Dx2kxFQI.js → itemEquality-C3XfrMi2.js} +1 -1
  111. package/dist/viewer/{ja-JP-DBVTYXUO-jEL5Zohm.js → ja-JP-DBVTYXUO-irdMOHqC.js} +1 -1
  112. package/dist/viewer/{journeyDiagram-3NMN7TZE-D56mmWU7.js → journeyDiagram-3NMN7TZE-Cse6N-5p.js} +1 -1
  113. package/dist/viewer/{kaa-6HZHGXH3-B6pyJXZH.js → kaa-6HZHGXH3-DSu-PtX5.js} +1 -1
  114. package/dist/viewer/{kab-KAB-ZGHBKWFO-CLlf3rfz.js → kab-KAB-ZGHBKWFO-Bjc7u2yG.js} +1 -1
  115. package/dist/viewer/{kanban-definition-UXKFOSKX-hi8MCy0F.js → kanban-definition-UXKFOSKX-CdmNcOy5.js} +1 -1
  116. package/dist/viewer/{kk-KZ-P5N5QNE5-D-GnQDUN.js → kk-KZ-P5N5QNE5-CjQwQASw.js} +1 -1
  117. package/dist/viewer/{km-KH-HSX4SM5Z-CvlRaq6r.js → km-KH-HSX4SM5Z-CMslZbL1.js} +1 -1
  118. package/dist/viewer/{ko-KR-MTYHY66A-mYkZX31W.js → ko-KR-MTYHY66A-DBdzdGrw.js} +1 -1
  119. package/dist/viewer/{ku-TR-6OUDTVRD-CeXiI7eX.js → ku-TR-6OUDTVRD-C3zBzgJI.js} +1 -1
  120. package/dist/viewer/{lt-LT-XHIRWOB4-DNl9HTRS.js → lt-LT-XHIRWOB4-DWVw-ffO.js} +1 -1
  121. package/dist/viewer/{lv-LV-5QDEKY6T-_QejX_-F.js → lv-LV-5QDEKY6T-Zl3V2KMV.js} +1 -1
  122. package/dist/viewer/{mermaid-parser.core-8H71iLKg.js → mermaid-parser.core-CJFJTtR4.js} +3 -3
  123. package/dist/viewer/{mindmap-definition-YA3MSWOX-DDgO7tS-.js → mindmap-definition-YA3MSWOX-9mWYfj6-.js} +1 -1
  124. package/dist/viewer/{mr-IN-CRQNXWMA-OIHNnnu8.js → mr-IN-CRQNXWMA-D9aX0Bdo.js} +1 -1
  125. package/dist/viewer/{my-MM-5M5IBNSE-DYrw8pYH.js → my-MM-5M5IBNSE-SPXzrrJR.js} +1 -1
  126. package/dist/viewer/{nb-NO-T6EIAALU-DMd3Sg5d.js → nb-NO-T6EIAALU-C8h-KZrY.js} +1 -1
  127. package/dist/viewer/{nl-NL-IS3SIHDZ-D9AJQvsb.js → nl-NL-IS3SIHDZ-BflXY5YN.js} +1 -1
  128. package/dist/viewer/{nn-NO-6E72VCQL-DNeLg3d9.js → nn-NO-6E72VCQL-CFWc1uPu.js} +1 -1
  129. package/dist/viewer/{oc-FR-POXYY2M6-D6JMp-_j.js → oc-FR-POXYY2M6-BHz8giUr.js} +1 -1
  130. package/dist/viewer/{pa-IN-N4M65BXN-g5Vjsxo8.js → pa-IN-N4M65BXN-KYWN5LeG.js} +1 -1
  131. package/dist/viewer/{packet-AYTQ26CC-Dgk7eBb9.js → packet-AYTQ26CC-DrNZHDt7.js} +1 -1
  132. package/dist/viewer/{pegDiagram-XKGWAZYB-CVIwfqJt.js → pegDiagram-XKGWAZYB-DPszelm4.js} +1 -1
  133. package/dist/viewer/percentages-BXMCSKIN-BgOWZqvL.js +1 -0
  134. package/dist/viewer/{pie-WAS4IAKB-DS_tuosA.js → pie-WAS4IAKB-J0UiOL4B.js} +1 -1
  135. package/dist/viewer/{pieDiagram-E7YTZNPT-4vQIT90F.js → pieDiagram-E7YTZNPT-ClDIExzM.js} +1 -1
  136. package/dist/viewer/{pl-PL-T2D74RX3-CHeYNLpa.js → pl-PL-T2D74RX3-DhMivhiU.js} +1 -1
  137. package/dist/viewer/preview.html +4 -4
  138. package/dist/viewer/preview.js +1 -1
  139. package/dist/viewer/{prod-DiBc1897.js → prod-itzLn3X0.js} +8 -8
  140. package/dist/viewer/{pt-BR-5N22H2LF-taNFaSz0.js → pt-BR-5N22H2LF-gkkaKj42.js} +1 -1
  141. package/dist/viewer/{pt-PT-UZXXM6DQ-CsmK_jBH.js → pt-PT-UZXXM6DQ-NWnJTvgF.js} +1 -1
  142. package/dist/viewer/{quadrantDiagram-AXDQQJYC-BeirbPa5.js → quadrantDiagram-AXDQQJYC-CYy8PwM3.js} +1 -1
  143. package/dist/viewer/{radar-RG4KPBEZ-BsCRiS0D.js → radar-RG4KPBEZ-DQrCAAlO.js} +1 -1
  144. package/dist/viewer/{railroad-74A4TZTK--zO8tvea.js → railroad-74A4TZTK-Bie2KVo4.js} +1 -1
  145. package/dist/viewer/{railroad-abnf-HS5TGJTU-BZWetNTH.js → railroad-abnf-HS5TGJTU-CqHzfM_H.js} +1 -1
  146. package/dist/viewer/{railroad-ebnf-LZEXJU2U-Bdr-nXDi.js → railroad-ebnf-LZEXJU2U-Ba93pI_q.js} +1 -1
  147. package/dist/viewer/{railroad-peg-WCYAUIDC-5QbqtFhr.js → railroad-peg-WCYAUIDC-oFmY9M6i.js} +1 -1
  148. package/dist/viewer/{railroadDiagram-O6MQD6OU-CEc9eC2b.js → railroadDiagram-O6MQD6OU-Bl287Huh.js} +1 -1
  149. package/dist/viewer/{requirementDiagram-BXWQKSXE-gHO3OQpd.js → requirementDiagram-BXWQKSXE-C7qjeIWt.js} +1 -1
  150. package/dist/viewer/{ro-RO-JPDTUUEW-URJMRk3q.js → ro-RO-JPDTUUEW-Ci-CRtV_.js} +1 -1
  151. package/dist/viewer/{ru-RU-B4JR7IUQ-DI6p8dtR.js → ru-RU-B4JR7IUQ-BPm31ic_.js} +1 -1
  152. package/dist/viewer/{sankeyDiagram-P5KCCOFB-BKwmk90Q.js → sankeyDiagram-P5KCCOFB-CSV23yCW.js} +1 -1
  153. package/dist/viewer/{selection-BUarVaVG.js → selection-DiNkp8_u.js} +1 -1
  154. package/dist/viewer/{sequenceDiagram-WJ2MYXX4-DNRtNYaC.js → sequenceDiagram-WJ2MYXX4-BbxTUdX6.js} +1 -1
  155. package/dist/viewer/{si-LK-N5RQ5JYF-CC3Wbwwt.js → si-LK-N5RQ5JYF-7zJDxmel.js} +1 -1
  156. package/dist/viewer/{sk-SK-C5VTKIMK-D4qIYJZm.js → sk-SK-C5VTKIMK-BNbR9mTT.js} +1 -1
  157. package/dist/viewer/{sl-SI-NN7IZMDC-BrX9Kjyd.js → sl-SI-NN7IZMDC-Dzy-6Up_.js} +1 -1
  158. package/dist/viewer/{stateDiagram-D77RDMKH-DFHhwDaw.js → stateDiagram-D77RDMKH-hpVLVGhL.js} +1 -1
  159. package/dist/viewer/stateDiagram-v2-MP3YSRHH-BH2KXEBo.js +1 -0
  160. package/dist/viewer/subset-shared.chunk-Czwfa2VQ.js +1 -0
  161. package/dist/viewer/{subset-worker.chunk-D_1PjTiM.js → subset-worker.chunk-Dgy8sQUD.js} +1 -1
  162. package/dist/viewer/{sv-SE-XGPEYMSR-CrLXWvFy.js → sv-SE-XGPEYMSR-C5bggny3.js} +1 -1
  163. package/dist/viewer/{swimlanes-42K2YHIH-DzGUJWU-.js → swimlanes-42K2YHIH-BRqXz7nV.js} +1 -1
  164. package/dist/viewer/swimlanesDiagram-VR7AAH4N-Blx0nEYQ.js +8 -0
  165. package/dist/viewer/{ta-IN-2NMHFXQM-BjEs1VFY.js → ta-IN-2NMHFXQM-Pw1wRofq.js} +1 -1
  166. package/dist/viewer/{th-TH-HPSO5L25-Cg6PzVXI.js → th-TH-HPSO5L25-Nz-UqtdD.js} +1 -1
  167. package/dist/viewer/{timeline-definition-24CTP7MA-CIpmMJhg.js → timeline-definition-24CTP7MA-Dp3nP8rd.js} +1 -1
  168. package/dist/viewer/{tr-TR-DEFEU3FU-DCEAv9nq.js → tr-TR-DEFEU3FU-DTlGCmld.js} +1 -1
  169. package/dist/viewer/{treeView-Q6P3EWNA-DHjfLsjZ.js → treeView-Q6P3EWNA-z3dPnkjZ.js} +1 -1
  170. package/dist/viewer/{treemap-WGGIJYW6-COOVf8-Y.js → treemap-WGGIJYW6-DeaU4Gxo.js} +1 -1
  171. package/dist/viewer/{type-icons-BonbxUGw.js → type-icons-BhI8cIWS.js} +1 -1
  172. package/dist/viewer/{uk-UA-QMV73CPH-DMWYOkg6.js → uk-UA-QMV73CPH-Bx9vPanC.js} +1 -1
  173. package/dist/viewer/useSystemTheme-Dzqcdh-y.js +64 -0
  174. package/dist/viewer/{useTranslation-Ci5tOdAN.js → useTranslation-B4Q9Bc_u.js} +1 -1
  175. package/dist/viewer/{useTypeFavicon-B--Z-Uwv.js → useTypeFavicon-B01CcUw4.js} +1 -1
  176. package/dist/viewer/{vennDiagram-4TSXK5OY-BWDC-eE0.js → vennDiagram-4TSXK5OY-B2g-6QAa.js} +1 -1
  177. package/dist/viewer/{vi-VN-M7AON7JQ-CVj2nFN-.js → vi-VN-M7AON7JQ-DvU5fCQK.js} +1 -1
  178. package/dist/viewer/{view-D0Odcpdb.js → view-R1KProyl.js} +1 -1
  179. package/dist/viewer/{wardley-WFR3VGLG-CDlPWlPO.js → wardley-WFR3VGLG-hhWao6Ek.js} +1 -1
  180. package/dist/viewer/{wardleyDiagram-VM6X3IG4-C9yxtxg6.js → wardleyDiagram-VM6X3IG4-pFu6p_Rn.js} +1 -1
  181. package/dist/viewer/{xychartDiagram-S5SC5T6Z-Dv4UxBWo.js → xychartDiagram-S5SC5T6Z-GC8fXUaM.js} +1 -1
  182. package/dist/viewer/{zh-CN-LNUGB5OW-i7Vn4Pqy.js → zh-CN-LNUGB5OW-LWpPfppU.js} +1 -1
  183. package/dist/viewer/{zh-HK-E62DVLB3-Cm16SoeD.js → zh-HK-E62DVLB3-BQrPpETb.js} +1 -1
  184. package/dist/viewer/{zh-TW-RAJ6MFWO-Lambeacv.js → zh-TW-RAJ6MFWO-O2w99mPI.js} +1 -1
  185. package/dist/viewer-lib/{Canvas-BdS1Xa5w.js → Canvas-Gv8uEhbb.js} +1 -1
  186. package/dist/viewer-lib/core.js +3 -3
  187. package/dist/viewer-lib/{ids-Crgtnwo0.js → ids-CJH3rRXm.js} +38 -38
  188. package/dist/viewer-lib/index.js +1002 -1002
  189. package/dist/viewer-lib/types/src/shared/ids.d.ts +3 -0
  190. package/package.json +1 -1
  191. package/dist/viewer/channel-DGerhKw9.js +0 -1
  192. package/dist/viewer/classDiagram-ZZMXUADV-DWXc-S98.js +0 -1
  193. package/dist/viewer/classDiagram-v2-VYDZK3BY-DWXc-S98.js +0 -1
  194. package/dist/viewer/flowDiagram-HODETNUW-DWhovppS.js +0 -1
  195. package/dist/viewer/percentages-BXMCSKIN-NLhw_fz5.js +0 -1
  196. package/dist/viewer/stateDiagram-v2-MP3YSRHH-D8ViYn3V.js +0 -1
  197. package/dist/viewer/subset-shared.chunk-Bx9OralH.js +0 -1
  198. package/dist/viewer/swimlanesDiagram-VR7AAH4N-Clea06qq.js +0 -8
  199. package/dist/viewer/useSystemTheme-BVZLLsnc.js +0 -64
package/dist/cli.cjs CHANGED
@@ -1563,59 +1563,15 @@ var require_canvas = __commonJS({
1563
1563
  });
1564
1564
 
1565
1565
  // src/cli/main.ts
1566
- var import_node_child_process5 = require("node:child_process");
1567
- var import_node_os6 = __toESM(require("node:os"), 1);
1568
- var import_node_path12 = __toESM(require("node:path"), 1);
1569
- var import_node_util2 = require("node:util");
1570
-
1571
- // src/server/credentials.ts
1572
- var import_node_fs2 = __toESM(require("node:fs"), 1);
1573
- var import_node_path2 = __toESM(require("node:path"), 1);
1574
-
1575
- // src/server/state.ts
1576
- var import_node_fs = __toESM(require("node:fs"), 1);
1577
- var import_node_path = __toESM(require("node:path"), 1);
1578
-
1579
- // src/shared/types.ts
1580
- var ARTIFACT_TYPES = ["artboard", "document", "html"];
1581
-
1582
- // src/shared/validate.ts
1583
- var BOARD_NUMBERS = ["x", "y", "w", "h"];
1584
- var BOARD_REQUIRED = ["file", "page", ...BOARD_NUMBERS];
1585
- var MEDIA_REQUIRED = ["src", "page", ...BOARD_NUMBERS];
1566
+ var import_node_child_process7 = require("node:child_process");
1586
1567
 
1587
- // src/server/state.ts
1588
- function writeJsonAtomic(file, value) {
1589
- import_node_fs.default.mkdirSync(import_node_path.default.dirname(file), { recursive: true });
1590
- const tmp = `${file}.${process.pid}.tmp`;
1591
- import_node_fs.default.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}
1592
- `, { mode: 384 });
1593
- import_node_fs.default.renameSync(tmp, file);
1594
- }
1595
-
1596
- // src/server/credentials.ts
1597
- function credentialsFile(env, platform, home) {
1598
- if (platform === "win32" && env.APPDATA) return import_node_path2.default.join(env.APPDATA, "ryugi", "credentials.json");
1599
- return import_node_path2.default.join(env.XDG_CONFIG_HOME || import_node_path2.default.join(home, ".config"), "ryugi", "credentials.json");
1600
- }
1601
- function readCredentials(file, origin) {
1602
- let raw;
1603
- try {
1604
- raw = JSON.parse(import_node_fs2.default.readFileSync(file, "utf8"));
1605
- } catch {
1606
- return null;
1607
- }
1608
- if (typeof raw !== "object" || raw === null) return null;
1609
- const { origin: savedOrigin, token, login } = raw;
1610
- if (typeof savedOrigin !== "string" || typeof token !== "string" || typeof login !== "string") return null;
1611
- if (savedOrigin !== origin) return null;
1612
- return { origin: savedOrigin, token, login };
1613
- }
1568
+ // src/cli/command.ts
1569
+ var import_node_util = require("node:util");
1614
1570
 
1615
1571
  // src/cli/paths.ts
1616
- var import_node_fs3 = __toESM(require("node:fs"), 1);
1572
+ var import_node_fs = __toESM(require("node:fs"), 1);
1617
1573
  var import_node_os = __toESM(require("node:os"), 1);
1618
- var import_node_path3 = __toESM(require("node:path"), 1);
1574
+ var import_node_path = __toESM(require("node:path"), 1);
1619
1575
  var CliError = class extends Error {
1620
1576
  constructor(message, fields = {}, code = 1) {
1621
1577
  super(message);
@@ -1629,50 +1585,120 @@ var resolvesRoot = () => !process.env.RYUGI_ARTIFACTS_COMMAND || process.env.RYU
1629
1585
  function projectRoot(dir) {
1630
1586
  let home = "";
1631
1587
  try {
1632
- home = import_node_fs3.default.realpathSync(import_node_os.default.homedir());
1588
+ home = import_node_fs.default.realpathSync(import_node_os.default.homedir());
1633
1589
  } catch {
1634
1590
  }
1635
1591
  const chain = [];
1636
- for (let current = dir; ; current = import_node_path3.default.dirname(current)) {
1592
+ for (let current = dir; ; current = import_node_path.default.dirname(current)) {
1637
1593
  chain.push(current);
1638
- if (import_node_fs3.default.existsSync(import_node_path3.default.join(current, ".git")) && (current !== home || dir === home)) break;
1639
- if (import_node_path3.default.dirname(current) === current) return dir;
1594
+ if (import_node_fs.default.existsSync(import_node_path.default.join(current, ".git")) && (current !== home || dir === home)) break;
1595
+ if (import_node_path.default.dirname(current) === current) return dir;
1640
1596
  }
1641
- return chain.find((candidate) => import_node_fs3.default.existsSync(import_node_path3.default.join(candidate, ".ryugi", "artifacts"))) ?? chain[chain.length - 1];
1597
+ return chain.find((candidate) => import_node_fs.default.existsSync(import_node_path.default.join(candidate, ".ryugi", "artifacts"))) ?? chain[chain.length - 1];
1642
1598
  }
1643
1599
  function projectPaths(dir) {
1644
1600
  let project;
1645
1601
  try {
1646
- project = import_node_fs3.default.realpathSync(import_node_path3.default.resolve(dir));
1647
- if (!import_node_fs3.default.statSync(project).isDirectory()) throw new Error();
1602
+ project = import_node_fs.default.realpathSync(import_node_path.default.resolve(dir));
1603
+ if (!import_node_fs.default.statSync(project).isDirectory()) throw new Error();
1648
1604
  } catch {
1649
1605
  throw new CliError(`Project directory not found: ${dir}`);
1650
1606
  }
1651
1607
  if (resolvesRoot()) project = projectRoot(project);
1652
- const root = import_node_path3.default.join(project, ".ryugi", "artifacts");
1653
- const state = import_node_path3.default.join(root, ".state");
1608
+ const root = import_node_path.default.join(project, ".ryugi", "artifacts");
1609
+ const state = import_node_path.default.join(root, ".state");
1654
1610
  return {
1655
1611
  project,
1656
1612
  root,
1657
1613
  state,
1658
- pid: import_node_path3.default.join(state, "server.pid"),
1659
- log: import_node_path3.default.join(state, "server.log"),
1660
- serverId: import_node_path3.default.join(state, "server-instance-id"),
1661
- info: import_node_path3.default.join(state, "server-info"),
1662
- version: import_node_path3.default.join(state, "server-version"),
1663
- owners: import_node_path3.default.join(state, "owners"),
1664
- agent: import_node_path3.default.join(state, "agent"),
1665
- stopped: import_node_path3.default.join(state, "server-stopped"),
1666
- lock: import_node_path3.default.join(state, "start.lock")
1614
+ pid: import_node_path.default.join(state, "server.pid"),
1615
+ log: import_node_path.default.join(state, "server.log"),
1616
+ serverId: import_node_path.default.join(state, "server-instance-id"),
1617
+ info: import_node_path.default.join(state, "server-info"),
1618
+ version: import_node_path.default.join(state, "server-version"),
1619
+ owners: import_node_path.default.join(state, "owners"),
1620
+ agent: import_node_path.default.join(state, "agent"),
1621
+ stopped: import_node_path.default.join(state, "server-stopped"),
1622
+ lock: import_node_path.default.join(state, "start.lock")
1667
1623
  };
1668
1624
  }
1669
1625
  var invocation = () => process.env.RYUGI_ARTIFACTS_COMMAND || "ryugi-artifacts";
1670
1626
  var ARTIFACT_PATTERN = /^(artboard|document|html)\/[a-z0-9][a-z0-9-]*$/;
1671
1627
  var ARTIFACT_ERROR = "--artifact must be <type>/<id>: type artboard, document or html, id of lowercase letters, digits and hyphens";
1672
1628
 
1629
+ // src/cli/command.ts
1630
+ var BIN = "ryugi-artifacts";
1631
+ var COMMON = {
1632
+ "project-dir": { type: "string", value: "<path>", help: "Project directory (default: current directory)" },
1633
+ json: { type: "boolean", help: "Print one JSON line (default when not in a terminal)" }
1634
+ };
1635
+ var HELP_OPTION = { help: { type: "boolean", short: "h", help: "Show this help" } };
1636
+ function parse(args, options, positionals = 0) {
1637
+ const config2 = Object.fromEntries(Object.entries({ ...COMMON, ...options }).map(([name, { type, short }]) => [name, short ? { type, short } : { type }]));
1638
+ try {
1639
+ const parsed = (0, import_node_util.parseArgs)({ args, options: config2, allowPositionals: positionals > 0, strict: true });
1640
+ if (parsed.positionals.length > positionals) throw new CliError(`Unknown argument: ${parsed.positionals[positionals]}`);
1641
+ return {
1642
+ values: parsed.values,
1643
+ positionals: parsed.positionals,
1644
+ projectDir: parsed.values["project-dir"] ?? process.cwd()
1645
+ };
1646
+ } catch (err) {
1647
+ if (err instanceof CliError) throw err;
1648
+ const flag = /'([^']+)'/.exec(err.message)?.[1];
1649
+ throw new CliError(flag ? `Unknown argument: ${flag.split(" ")[0]}` : err.message);
1650
+ }
1651
+ }
1652
+ function wantsHelp(args) {
1653
+ const end = args.indexOf("--");
1654
+ return (end === -1 ? args : args.slice(0, end)).some((arg) => arg === "--help" || arg === "-h");
1655
+ }
1656
+ function table(rows) {
1657
+ const width = Math.max(...rows.map(([left]) => left.length)) + 2;
1658
+ return rows.map(([left, right]) => ` ${left.padEnd(width)}${right.replace(/\n/g, `
1659
+ ${" ".repeat(width)}`)}`.trimEnd()).join("\n");
1660
+ }
1661
+ function optionRows(options) {
1662
+ return Object.entries(options).filter(([, option]) => option.help !== void 0).map(([name, option]) => [`${option.short ? `-${option.short}, ` : ""}--${name}${option.value ? ` ${option.value}` : ""}`, option.help]);
1663
+ }
1664
+ function commandHelp(command) {
1665
+ const usage = (command.usage ?? ["[options]"]).map((line, index) => `${index ? " " : "Usage: "}${BIN} ${command.name} ${line}`);
1666
+ return [
1667
+ usage.join("\n"),
1668
+ "",
1669
+ command.summary,
1670
+ ...command.details ? ["", command.details] : [],
1671
+ "",
1672
+ "Options:",
1673
+ table(optionRows({ ...command.options, ...COMMON, ...HELP_OPTION }))
1674
+ ].join("\n");
1675
+ }
1676
+ function rootHelp(commands, browseOptions = {}) {
1677
+ return [
1678
+ `Usage: ${BIN} [project-directory] [--no-open]`,
1679
+ ` ${BIN} <command> [options]`,
1680
+ "",
1681
+ "Without a command, opens the project's artifacts in your browser and keeps the server",
1682
+ "running until Ctrl+C.",
1683
+ "",
1684
+ "Commands:",
1685
+ table(commands.map((command) => [command.name, command.summary])),
1686
+ "",
1687
+ `Run \`${BIN} <command> --help\` for a command's options.`,
1688
+ "",
1689
+ "Options:",
1690
+ table(optionRows({
1691
+ ...COMMON,
1692
+ ...browseOptions,
1693
+ version: { type: "boolean", short: "v", help: "Print the version" },
1694
+ ...HELP_OPTION
1695
+ }))
1696
+ ].join("\n");
1697
+ }
1698
+
1673
1699
  // src/cli/process.ts
1674
1700
  var import_node_child_process = require("node:child_process");
1675
- var import_node_fs4 = __toESM(require("node:fs"), 1);
1701
+ var import_node_fs2 = __toESM(require("node:fs"), 1);
1676
1702
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1677
1703
  function alive(pid) {
1678
1704
  try {
@@ -1684,7 +1710,7 @@ function alive(pid) {
1684
1710
  }
1685
1711
  function commandLine(pid) {
1686
1712
  try {
1687
- return import_node_fs4.default.readFileSync(`/proc/${pid}/cmdline`, "utf8").split("\0");
1713
+ return import_node_fs2.default.readFileSync(`/proc/${pid}/cmdline`, "utf8").split("\0");
1688
1714
  } catch {
1689
1715
  }
1690
1716
  const direct = (0, import_node_child_process.spawnSync)("ps", ["-ww", "-p", String(pid), "-o", "command="], { encoding: "utf8" });
@@ -1716,7 +1742,7 @@ async function waitForExit(pid, ms) {
1716
1742
  }
1717
1743
  var readText = (file) => {
1718
1744
  try {
1719
- return import_node_fs4.default.readFileSync(file, "utf8").replace(/[\r\n]+$/, "");
1745
+ return import_node_fs2.default.readFileSync(file, "utf8").replace(/[\r\n]+$/, "");
1720
1746
  } catch {
1721
1747
  return null;
1722
1748
  }
@@ -1781,9 +1807,19 @@ function checkText(value) {
1781
1807
  return lines.length ? `${value.artifact}
1782
1808
  ${lines.join("\n")}` : `${value.artifact}: no warnings`;
1783
1809
  }
1810
+ var checkCommand = {
1811
+ name: "check",
1812
+ summary: "Wait until the server has checked the latest write, then print its warnings (needs a running server)",
1813
+ usage: ["--artifact <type>/<id> [options]"],
1814
+ options: {
1815
+ artifact: { type: "string", value: "<type>/<id>", help: "The artifact to check" }
1816
+ },
1817
+ run: ({ values, projectDir }, emit) => check({ projectDir, artifact: values.artifact }, emit),
1818
+ text: checkText
1819
+ };
1784
1820
 
1785
1821
  // src/cli/comment.ts
1786
- var import_node_fs5 = __toESM(require("node:fs"), 1);
1822
+ var import_node_fs3 = __toESM(require("node:fs"), 1);
1787
1823
 
1788
1824
  // src/server/agent.ts
1789
1825
  var NAMES = {
@@ -1877,7 +1913,7 @@ var WRITTEN = { add: "comment-added", reply: "comment-replied", resolve: "commen
1877
1913
  function readStdin() {
1878
1914
  if (process.stdin.isTTY) return "";
1879
1915
  try {
1880
- return import_node_fs5.default.readFileSync(0, "utf8");
1916
+ return import_node_fs3.default.readFileSync(0, "utf8");
1881
1917
  } catch {
1882
1918
  return "";
1883
1919
  }
@@ -1970,18 +2006,77 @@ ${groups.map(groupText).join("\n")}` : head;
1970
2006
  if (value.type === "comment-resolved") return `Resolved thread ${value.threadId}`;
1971
2007
  return null;
1972
2008
  }
2009
+ var commentCommand = {
2010
+ name: "comment",
2011
+ summary: "Read and answer comments on a document or artboard (needs a running server)",
2012
+ usage: [
2013
+ "list --artifact <document|artboard>/<id> [--all]",
2014
+ "add --artifact document/<id> --block <blockId> [--quote <text>] [--text <text>]",
2015
+ "add --artifact artboard/<id> --board <boardId> [--x <px> --y <px>] [--text <text>]",
2016
+ "reply --artifact <document|artboard>/<id> --thread <threadId> [--text <text>]",
2017
+ "resolve --artifact <document|artboard>/<id> --thread <threadId>"
2018
+ ],
2019
+ details: "list prints what changed since you last listed. Without --text, add and reply read the message from stdin.",
2020
+ options: {
2021
+ artifact: { type: "string", value: "<type>/<id>", help: "The document or artboard" },
2022
+ all: { type: "boolean", help: "list: every thread, not only what changed" },
2023
+ block: { type: "string", value: "<blockId>", help: "add: the document block to comment on" },
2024
+ quote: { type: "string", value: "<text>", help: "add: the text in the block the comment is about" },
2025
+ board: { type: "string", value: "<boardId>", help: "add: the artboard board to comment on" },
2026
+ x: { type: "string", value: "<px>", help: "add: horizontal position on the board" },
2027
+ y: { type: "string", value: "<px>", help: "add: vertical position on the board" },
2028
+ thread: { type: "string", value: "<threadId>", help: "reply, resolve: the thread" },
2029
+ text: { type: "string", value: "<text>", help: "add, reply: the message" }
2030
+ },
2031
+ positionals: 1,
2032
+ run: ({ values, positionals, projectDir }, emit) => comment({
2033
+ projectDir,
2034
+ action: positionals[0],
2035
+ artifact: values.artifact,
2036
+ all: values.all,
2037
+ block: values.block,
2038
+ quote: values.quote,
2039
+ thread: values.thread,
2040
+ text: values.text,
2041
+ board: values.board,
2042
+ x: values.x,
2043
+ y: values.y
2044
+ }, emit),
2045
+ text: commentText
2046
+ };
1973
2047
 
1974
2048
  // src/cli/config.ts
1975
2049
  var import_node_os2 = __toESM(require("node:os"), 1);
1976
2050
  var import_node_path6 = __toESM(require("node:path"), 1);
1977
2051
 
1978
2052
  // src/server/config.ts
1979
- var import_node_fs6 = __toESM(require("node:fs"), 1);
1980
- var import_node_path4 = __toESM(require("node:path"), 1);
2053
+ var import_node_fs5 = __toESM(require("node:fs"), 1);
2054
+ var import_node_path3 = __toESM(require("node:path"), 1);
1981
2055
 
1982
2056
  // src/shared/cloud.ts
1983
2057
  var isVisibility = (value) => value === "private" || value === "public";
1984
2058
 
2059
+ // src/server/state.ts
2060
+ var import_node_fs4 = __toESM(require("node:fs"), 1);
2061
+ var import_node_path2 = __toESM(require("node:path"), 1);
2062
+
2063
+ // src/shared/types.ts
2064
+ var ARTIFACT_TYPES = ["artboard", "document", "html"];
2065
+
2066
+ // src/shared/validate.ts
2067
+ var BOARD_NUMBERS = ["x", "y", "w", "h"];
2068
+ var BOARD_REQUIRED = ["file", "page", ...BOARD_NUMBERS];
2069
+ var MEDIA_REQUIRED = ["src", "page", ...BOARD_NUMBERS];
2070
+
2071
+ // src/server/state.ts
2072
+ function writeJsonAtomic(file, value) {
2073
+ import_node_fs4.default.mkdirSync(import_node_path2.default.dirname(file), { recursive: true });
2074
+ const tmp = `${file}.${process.pid}.tmp`;
2075
+ import_node_fs4.default.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}
2076
+ `, { mode: 384 });
2077
+ import_node_fs4.default.renameSync(tmp, file);
2078
+ }
2079
+
1985
2080
  // src/server/config.ts
1986
2081
  var defaults = () => ({ version: 1, artifacts: {} });
1987
2082
  function isCloudRecord(value) {
@@ -2014,7 +2109,7 @@ function normalize(raw) {
2014
2109
  function readConfig(file) {
2015
2110
  let text2;
2016
2111
  try {
2017
- text2 = import_node_fs6.default.readFileSync(file, "utf8");
2112
+ text2 = import_node_fs5.default.readFileSync(file, "utf8");
2018
2113
  } catch {
2019
2114
  return { config: defaults() };
2020
2115
  }
@@ -2026,32 +2121,53 @@ function readConfig(file) {
2026
2121
  }
2027
2122
  var IGNORED = ["config.json", "artifacts/*", "!artifacts/document/", "artifacts/document/*/.artifact-id"];
2028
2123
  function ensureGitignore(dir) {
2029
- const file = import_node_path4.default.join(dir, ".gitignore");
2124
+ const file = import_node_path3.default.join(dir, ".gitignore");
2030
2125
  let current = "";
2031
2126
  try {
2032
- current = import_node_fs6.default.readFileSync(file, "utf8");
2127
+ current = import_node_fs5.default.readFileSync(file, "utf8");
2033
2128
  } catch {
2034
2129
  }
2035
2130
  const present = new Set(current.split(/\r?\n/).map((line) => line.trim()));
2036
2131
  const missing = IGNORED.filter((line) => !present.has(line));
2037
2132
  if (missing.length === 0) return;
2038
- import_node_fs6.default.writeFileSync(file, `${current}${current === "" || current.endsWith("\n") ? "" : "\n"}${missing.join("\n")}
2133
+ import_node_fs5.default.writeFileSync(file, `${current}${current === "" || current.endsWith("\n") ? "" : "\n"}${missing.join("\n")}
2039
2134
  `);
2040
2135
  }
2041
2136
  function ensureConfig(file) {
2042
- import_node_fs6.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
2043
- ensureGitignore(import_node_path4.default.dirname(file));
2044
- if (!import_node_fs6.default.existsSync(file)) writeJsonAtomic(file, defaults());
2137
+ import_node_fs5.default.mkdirSync(import_node_path3.default.dirname(file), { recursive: true });
2138
+ ensureGitignore(import_node_path3.default.dirname(file));
2139
+ if (!import_node_fs5.default.existsSync(file)) writeJsonAtomic(file, defaults());
2045
2140
  }
2046
2141
  function setProjectAutoPublish(file, value) {
2047
2142
  const { config: config2, warning } = readConfig(file);
2048
2143
  if (warning) throw new Error(warning);
2049
2144
  if (value === null) delete config2.autoPublish;
2050
2145
  else config2.autoPublish = value;
2051
- import_node_fs6.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
2146
+ import_node_fs5.default.mkdirSync(import_node_path3.default.dirname(file), { recursive: true });
2052
2147
  writeJsonAtomic(file, config2);
2053
2148
  }
2054
2149
 
2150
+ // src/server/credentials.ts
2151
+ var import_node_fs6 = __toESM(require("node:fs"), 1);
2152
+ var import_node_path4 = __toESM(require("node:path"), 1);
2153
+ function credentialsFile(env, platform, home) {
2154
+ if (platform === "win32" && env.APPDATA) return import_node_path4.default.join(env.APPDATA, "ryugi", "credentials.json");
2155
+ return import_node_path4.default.join(env.XDG_CONFIG_HOME || import_node_path4.default.join(home, ".config"), "ryugi", "credentials.json");
2156
+ }
2157
+ function readCredentials(file, origin) {
2158
+ let raw;
2159
+ try {
2160
+ raw = JSON.parse(import_node_fs6.default.readFileSync(file, "utf8"));
2161
+ } catch {
2162
+ return null;
2163
+ }
2164
+ if (typeof raw !== "object" || raw === null) return null;
2165
+ const { origin: savedOrigin, token, login } = raw;
2166
+ if (typeof savedOrigin !== "string" || typeof token !== "string" || typeof login !== "string") return null;
2167
+ if (savedOrigin !== origin) return null;
2168
+ return { origin: savedOrigin, token, login };
2169
+ }
2170
+
2055
2171
  // src/server/settings.ts
2056
2172
  var import_node_fs7 = __toESM(require("node:fs"), 1);
2057
2173
  var import_node_path5 = __toESM(require("node:path"), 1);
@@ -2090,9 +2206,26 @@ function config(options, emit) {
2090
2206
  emit({ type: "auto-publish", global: readGlobalAutoPublish(globalFile) ?? null, project: readConfig(projectFile).config.autoPublish ?? null });
2091
2207
  return 0;
2092
2208
  }
2209
+ var configCommand = {
2210
+ name: "config",
2211
+ summary: "Auto-publish changed artifacts as private cloud copies when the agent's turn ends",
2212
+ usage: ["[--auto-publish on|off] [options]", "--auto-publish on|off|inherit --project [options]"],
2213
+ details: "Without --auto-publish, prints the current values.",
2214
+ options: {
2215
+ "auto-publish": { type: "string", value: "on|off|inherit", help: "Turn auto-publish on or off; inherit (with --project) drops the override" },
2216
+ project: { type: "boolean", help: "Set it for this project only instead of every project" }
2217
+ },
2218
+ run: ({ values, projectDir }, emit) => config({
2219
+ projectDir,
2220
+ autoPublish: values["auto-publish"],
2221
+ project: !!values.project
2222
+ }, emit),
2223
+ text: (value) => value.type === "auto-publish" ? `Auto-publish: ${value.global === null ? "not decided" : value.global ? "on" : "off"} for every project${value.project === null ? "" : `, ${value.project ? "on" : "off"} for this project`}.` : null
2224
+ };
2093
2225
 
2094
2226
  // src/cli/get.ts
2095
2227
  var import_node_fs8 = __toESM(require("node:fs"), 1);
2228
+ var import_node_os3 = __toESM(require("node:os"), 1);
2096
2229
  var import_node_path7 = __toESM(require("node:path"), 1);
2097
2230
 
2098
2231
  // node_modules/.pnpm/nanoid@6.0.2/node_modules/nanoid/url-alphabet/index.js
@@ -2163,14 +2296,14 @@ function customAlphabet(alphabet, defaultSize = 21) {
2163
2296
  });
2164
2297
  let alphabetLen = alphabet.length;
2165
2298
  let mask = (2 << 31 - Math.clz32(alphabetLen - 1 | 1)) - 1;
2166
- let pool = "";
2167
- let poolOffset = 0;
2299
+ let pool2 = "";
2300
+ let poolOffset2 = 0;
2168
2301
  let poolNext = 0;
2169
2302
  return (size = defaultSize) => {
2170
2303
  size |= 0;
2171
2304
  if (size < 0) throw new RangeError("Wrong ID size");
2172
2305
  if (size === 0) return "";
2173
- if (poolOffset + size > pool.length) {
2306
+ if (poolOffset2 + size > pool2.length) {
2174
2307
  let target = Math.max(poolNext, size);
2175
2308
  poolNext = Math.min(target * 16, POOL_MAX);
2176
2309
  let buffer = Buffer.allocUnsafe(target);
@@ -2195,11 +2328,11 @@ function customAlphabet(alphabet, defaultSize = 21) {
2195
2328
  }
2196
2329
  }
2197
2330
  }
2198
- pool = buffer.toString("latin1");
2199
- poolOffset = 0;
2331
+ pool2 = buffer.toString("latin1");
2332
+ poolOffset2 = 0;
2200
2333
  }
2201
- poolOffset += size;
2202
- return pool.substring(poolOffset - size, poolOffset);
2334
+ poolOffset2 += size;
2335
+ return pool2.substring(poolOffset2 - size, poolOffset2);
2203
2336
  };
2204
2337
  }
2205
2338
  var nanoid = customAlphabet(urlAlphabet);
@@ -3509,11 +3642,11 @@ function isTextRun(node) {
3509
3642
  }
3510
3643
  function serializeTextRun(run) {
3511
3644
  if (run.length === 1) return wrapWithFormatTags(run[0].text, run[0].format);
3512
- const common2 = run.reduce((acc, node) => acc & node.format, -1);
3513
- if (common2 !== 0) return wrapContentWithFormatTags(serializeTextRun(run.map((node) => ({
3645
+ const common = run.reduce((acc, node) => acc & node.format, -1);
3646
+ if (common !== 0) return wrapContentWithFormatTags(serializeTextRun(run.map((node) => ({
3514
3647
  ...node,
3515
- format: node.format & ~common2
3516
- }))), common2);
3648
+ format: node.format & ~common
3649
+ }))), common);
3517
3650
  const groups = [];
3518
3651
  let current;
3519
3652
  let previous;
@@ -8380,7 +8513,7 @@ function isQuote(c) {
8380
8513
  function isWhitespace2(c) {
8381
8514
  return c === CharCode.Space || c === CharCode.Tab || c === CharCode.NewLine || c === CharCode.FormFeed || c === CharCode.CarriageReturn;
8382
8515
  }
8383
- function parse(selector) {
8516
+ function parse2(selector) {
8384
8517
  const subselects2 = [];
8385
8518
  const endIndex = parseSelector(subselects2, `${selector}`, 0);
8386
8519
  if (endIndex < selector.length) {
@@ -9788,7 +9921,7 @@ function compile(parsed) {
9788
9921
  var whitespace = /* @__PURE__ */ new Set([9, 10, 12, 13, 32]);
9789
9922
  var ZERO = "0".charCodeAt(0);
9790
9923
  var NINE = "9".charCodeAt(0);
9791
- function parse2(formula) {
9924
+ function parse3(formula) {
9792
9925
  formula = formula.trim().toLowerCase();
9793
9926
  switch (formula) {
9794
9927
  case "even": {
@@ -9849,7 +9982,7 @@ function parse2(formula) {
9849
9982
 
9850
9983
  // node_modules/.pnpm/nth-check@3.0.1/node_modules/nth-check/dist/index.js
9851
9984
  function nthCheck(formula) {
9852
- return compile(parse2(formula));
9985
+ return compile(parse3(formula));
9853
9986
  }
9854
9987
 
9855
9988
  // node_modules/.pnpm/css-select@7.0.0/node_modules/css-select/dist/helpers/cache.js
@@ -9914,7 +10047,7 @@ function compileNth(reverse, ofType) {
9914
10047
  const nthCheck2 = nthCheck(ofMatch ? ofMatch[1].trim() : rule);
9915
10048
  if (nthCheck2 === falseFunc)
9916
10049
  return falseFunc;
9917
- const ofSelector = ofMatch && compileToken2 ? compileToken2(parse(ofMatch[2].trim()), copyOptions(options), context) : void 0;
10050
+ const ofSelector = ofMatch && compileToken2 ? compileToken2(parse2(ofMatch[2].trim()), copyOptions(options), context) : void 0;
9918
10051
  if (ofSelector === falseFunc)
9919
10052
  return falseFunc;
9920
10053
  if (nthCheck2 === trueFunc && !ofSelector) {
@@ -10245,7 +10378,7 @@ function compilePseudoSelector(next, selector, options, context, compileToken2)
10245
10378
  if (data != null) {
10246
10379
  throw new Error(`Pseudo ${name} doesn't have any arguments`);
10247
10380
  }
10248
- const alias = parse(stringPseudo);
10381
+ const alias = parse2(stringPseudo);
10249
10382
  return subselects["is"](next, alias, options, context, compileToken2);
10250
10383
  }
10251
10384
  if (typeof userPseudo === "function") {
@@ -10489,7 +10622,7 @@ function compile2(selector, options, context) {
10489
10622
  return next === falseFunc ? falseFunc : (element) => convertedOptions.adapter.isTag(element) && next(element);
10490
10623
  }
10491
10624
  function _compileUnsafe(selector, options, context) {
10492
- return compileToken(typeof selector === "string" ? parse(selector) : selector, convertOptionFormats(options), context);
10625
+ return compileToken(typeof selector === "string" ? parse2(selector) : selector, convertOptionFormats(options), context);
10493
10626
  }
10494
10627
  function getSelectorFunction(searchFunction) {
10495
10628
  return function select(query2, elements, options) {
@@ -14137,7 +14270,7 @@ var DOMParser = class _DOMParser {
14137
14270
  };
14138
14271
 
14139
14272
  // node_modules/.pnpm/linkedom@0.18.13/node_modules/linkedom/esm/shared/parse-json.js
14140
- var { parse: parse4 } = JSON;
14273
+ var { parse: parse5 } = JSON;
14141
14274
 
14142
14275
  // node_modules/.pnpm/linkedom@0.18.13/node_modules/linkedom/esm/index.js
14143
14276
  var parseHTML = (html, globals = null) => new DOMParser().parseFromString(
@@ -14153,6 +14286,69 @@ setPrototypeOf(Document4, Document2).prototype = Document2.prototype;
14153
14286
  // node_modules/.pnpm/@haklex+rich-litexml@0.58.0_typescript@5.9.3/node_modules/@haklex/rich-litexml/dist/node.mjs
14154
14287
  registerParseHTML((html) => parseHTML(html).document);
14155
14288
 
14289
+ // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
14290
+ var import_node_crypto = require("node:crypto");
14291
+ var POOL_SIZE_MULTIPLIER = 128;
14292
+ var pool;
14293
+ var poolOffset;
14294
+ function fillPool(bytes) {
14295
+ if (bytes < 0) throw new RangeError("Wrong ID size");
14296
+ try {
14297
+ if (!pool || pool.length < bytes) {
14298
+ pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
14299
+ import_node_crypto.webcrypto.getRandomValues(pool);
14300
+ poolOffset = 0;
14301
+ } else if (poolOffset + bytes > pool.length) {
14302
+ import_node_crypto.webcrypto.getRandomValues(pool);
14303
+ poolOffset = 0;
14304
+ }
14305
+ } catch (e) {
14306
+ pool = void 0;
14307
+ throw e;
14308
+ }
14309
+ poolOffset += bytes;
14310
+ }
14311
+ function random2(bytes) {
14312
+ fillPool(bytes |= 0);
14313
+ return pool.subarray(poolOffset - bytes, poolOffset);
14314
+ }
14315
+ function customRandom2(alphabet, defaultSize, getRandom) {
14316
+ let safeByteCutoff = 256 - 256 % alphabet.length;
14317
+ if (safeByteCutoff === 256) {
14318
+ let mask = alphabet.length - 1;
14319
+ return (size = defaultSize) => {
14320
+ if (!size) return "";
14321
+ let id = "";
14322
+ while (true) {
14323
+ let bytes = getRandom(size);
14324
+ let i = size;
14325
+ while (i--) {
14326
+ id += alphabet[bytes[i] & mask];
14327
+ if (id.length >= size) return id;
14328
+ }
14329
+ }
14330
+ };
14331
+ }
14332
+ let step = Math.ceil(1.6 * 256 * defaultSize / safeByteCutoff);
14333
+ return (size = defaultSize) => {
14334
+ if (!size) return "";
14335
+ let id = "";
14336
+ while (true) {
14337
+ let bytes = getRandom(step);
14338
+ let i = step;
14339
+ while (i--) {
14340
+ if (bytes[i] < safeByteCutoff) {
14341
+ id += alphabet[bytes[i] % alphabet.length];
14342
+ if (id.length >= size) return id;
14343
+ }
14344
+ }
14345
+ }
14346
+ };
14347
+ }
14348
+ function customAlphabet2(alphabet, size = 21) {
14349
+ return customRandom2(alphabet, size, random2);
14350
+ }
14351
+
14156
14352
  // src/server/document-codec.ts
14157
14353
  var BLOCK_TAGS = [
14158
14354
  "doc",
@@ -14323,9 +14519,44 @@ ${threads.join("\n\n")}
14323
14519
  `);
14324
14520
  return parts.join("");
14325
14521
  }
14522
+ var getCommand = {
14523
+ name: "get",
14524
+ summary: "Read a published Ryugi Cloud artifact by link or id, signed in as this machine's cloud account",
14525
+ usage: ["<link-or-id> [--out <dir>] [--no-comments] [options]"],
14526
+ details: "Prints the source (a document's LiteXML and comments) unless --json; artboard and HTML files, and files a document uses, are downloaded to --out or ~/.cache/ryugi/get/<id>/.",
14527
+ options: {
14528
+ out: { type: "string", value: "<dir>", help: "Download files here instead of ~/.cache/ryugi/get/<id>/" },
14529
+ "no-comments": { type: "boolean", help: "Leave a document's comments out" }
14530
+ },
14531
+ positionals: 1,
14532
+ // Agents run commands without a TTY and the signpost's command has no --json, so get prints the source unless --json is explicit.
14533
+ explicitJson: true,
14534
+ run: async ({ values, positionals }) => {
14535
+ const json = !!values.json;
14536
+ try {
14537
+ if (!positionals[0]) throw new CliError("Give a Ryugi Cloud link or artifact id.");
14538
+ const result = await getArtifact({
14539
+ target: positionals[0],
14540
+ defaultOrigin: (process.env.RYUGI_CLOUD_ORIGIN || "https://ryugi.innei.dev").replace(/\/+$/, ""),
14541
+ credentialsFile: credentialsFile(process.env, process.platform, import_node_os3.default.homedir()),
14542
+ cacheRoot: import_node_path7.default.join(process.env.XDG_CACHE_HOME || import_node_path7.default.join(import_node_os3.default.homedir(), ".cache"), "ryugi", "get"),
14543
+ out: values.out
14544
+ });
14545
+ if (json) console.log(JSON.stringify(result));
14546
+ else process.stdout.write(getText4(result, { comments: !values["no-comments"] }));
14547
+ return 0;
14548
+ } catch (caught) {
14549
+ const err = caught instanceof CliError ? caught : new CliError(caught.message);
14550
+ const fields = err.message ? { error: err.message, ...err.fields } : err.fields;
14551
+ if (json) console.log(JSON.stringify(fields));
14552
+ else console.error(err.message ? `Error: ${err.message}` : String(err.fields.message));
14553
+ return err.code;
14554
+ }
14555
+ }
14556
+ };
14326
14557
 
14327
14558
  // src/cli/monitor-view.ts
14328
- var import_node_os3 = __toESM(require("node:os"), 1);
14559
+ var import_node_os4 = __toESM(require("node:os"), 1);
14329
14560
  var REFRESH_SECONDS = 2;
14330
14561
  var BOLD = "\x1B[1m";
14331
14562
  var DIM = "\x1B[2m";
@@ -14342,7 +14573,7 @@ function duration(ms) {
14342
14573
  if (hours < 24) return `${hours}h${minutes % 60 ? `${minutes % 60}m` : ""}`;
14343
14574
  return `${Math.floor(hours / 24)}d${hours % 24 ? `${hours % 24}h` : ""}`;
14344
14575
  }
14345
- var shortPath = (project, home = import_node_os3.default.homedir()) => project === home || project.startsWith(`${home}/`) ? `~${project.slice(home.length)}` : project;
14576
+ var shortPath = (project, home = import_node_os4.default.homedir()) => project === home || project.startsWith(`${home}/`) ? `~${project.slice(home.length)}` : project;
14346
14577
  function tags(row) {
14347
14578
  return [row.safeToStop && "safe to stop", row.oldRelease && "old release", row.status === "no-status" && "no status"].filter(Boolean);
14348
14579
  }
@@ -14449,7 +14680,7 @@ function handleKey(state, key2, rows) {
14449
14680
  // src/cli/monitor-ui.ts
14450
14681
  var import_node_child_process2 = require("node:child_process");
14451
14682
  var import_node_fs11 = __toESM(require("node:fs"), 1);
14452
- var import_node_os5 = __toESM(require("node:os"), 1);
14683
+ var import_node_os6 = __toESM(require("node:os"), 1);
14453
14684
  var import_node_readline = __toESM(require("node:readline"), 1);
14454
14685
 
14455
14686
  // src/server/lifecycle.ts
@@ -14466,16 +14697,16 @@ function browserLauncher(platform, url) {
14466
14697
  var import_node_path9 = __toESM(require("node:path"), 1);
14467
14698
 
14468
14699
  // src/server/registry.ts
14469
- var import_node_crypto = __toESM(require("node:crypto"), 1);
14700
+ var import_node_crypto2 = __toESM(require("node:crypto"), 1);
14470
14701
  var import_node_fs9 = __toESM(require("node:fs"), 1);
14471
- var import_node_os4 = __toESM(require("node:os"), 1);
14702
+ var import_node_os5 = __toESM(require("node:os"), 1);
14472
14703
  var import_node_path8 = __toESM(require("node:path"), 1);
14473
- function registryDir(env = process.env, platform = process.platform, uid = process.getuid?.() ?? -1, tmpdir = import_node_os4.default.tmpdir()) {
14704
+ function registryDir(env = process.env, platform = process.platform, uid = process.getuid?.() ?? -1, tmpdir = import_node_os5.default.tmpdir()) {
14474
14705
  if (env.RYUGI_RUNTIME_DIR) return import_node_path8.default.join(env.RYUGI_RUNTIME_DIR, "servers");
14475
14706
  if (platform === "win32") return import_node_path8.default.join(tmpdir, "ryugi", "servers");
14476
14707
  return `/tmp/ryugi-${uid}/servers`;
14477
14708
  }
14478
- var fileFor = (dir, project) => import_node_path8.default.join(dir, `${import_node_crypto.default.createHash("sha256").update(project).digest("hex").slice(0, 16)}.json`);
14709
+ var fileFor = (dir, project) => import_node_path8.default.join(dir, `${import_node_crypto2.default.createHash("sha256").update(project).digest("hex").slice(0, 16)}.json`);
14479
14710
  function verifyDir(dir) {
14480
14711
  if (process.platform === "win32") return;
14481
14712
  for (const target of [import_node_path8.default.dirname(dir), dir]) {
@@ -14613,6 +14844,14 @@ async function stop(projectDir, emit) {
14613
14844
  emit({ status: "stopped" });
14614
14845
  return 0;
14615
14846
  }
14847
+ var stopCommand = {
14848
+ name: "stop",
14849
+ summary: "Stop the project's artifacts server; the artifacts are kept",
14850
+ usage: ["[project-directory] [options]"],
14851
+ options: {},
14852
+ positionals: 1,
14853
+ run: ({ values, positionals }, emit) => stop(values["project-dir"] ?? positionals[0] ?? process.cwd(), emit)
14854
+ };
14616
14855
 
14617
14856
  // src/cli/monitor-ui.ts
14618
14857
  var LOG_TAIL_BYTES = 64 * 1024;
@@ -14667,7 +14906,7 @@ async function runMonitorUi() {
14667
14906
  process.on("exit", restore);
14668
14907
  const draw = () => {
14669
14908
  if (closed) return;
14670
- const screen = { width: stdout.columns || 80, height: stdout.rows || 24, now: Date.now(), home: import_node_os5.default.homedir() };
14909
+ const screen = { width: stdout.columns || 80, height: stdout.rows || 24, now: Date.now(), home: import_node_os6.default.homedir() };
14671
14910
  const row = rows[state.selected];
14672
14911
  const lines = state.mode === "log" && row ? renderLog(row, readTail(row.log), screen) : renderList(rows, state, screen);
14673
14912
  stdout.write(`\x1B[H${lines.join("\x1B[K\n")}\x1B[K\x1B[J`);
@@ -14773,6 +15012,85 @@ async function monitor(options, emit) {
14773
15012
  }
14774
15013
  return runMonitorUi();
14775
15014
  }
15015
+ var monitorCommand = {
15016
+ name: "monitor",
15017
+ summary: "List every running artifacts server on this machine and manage them",
15018
+ details: "In a terminal it opens a live view (open, copy URL, logs, stop); otherwise, or with --json, prints the list once.",
15019
+ options: {},
15020
+ run: ({ values }, emit) => monitor({ json: !!values.json }, emit),
15021
+ text: (value) => monitorText(value)
15022
+ };
15023
+
15024
+ // src/cli/publish.ts
15025
+ async function publish(options, emit) {
15026
+ if (options.action === "publish" || options.action === "unpublish") {
15027
+ if (!options.artifact) throw new CliError("--artifact <type>/<id> is required");
15028
+ if (!ARTIFACT_PATTERN.test(options.artifact)) throw new CliError(ARTIFACT_ERROR);
15029
+ }
15030
+ if (options.action === "delete" && !/^[A-Za-z0-9_-]{1,64}$/.test(options.cloudId ?? "")) throw new CliError("--delete needs a cloud artifact id from --list");
15031
+ const server = serverClient(options.projectDir);
15032
+ const call = async (method, route, body) => {
15033
+ const { status, json } = await server.call(method, route, body);
15034
+ if (status === 401) throw new CliError("", { type: "login-required", url: json.loginUrl, message: "Open url to sign in to the Ryugi cloud, then run the same command again." }, 2);
15035
+ const details = cloudErrorDetails(json);
15036
+ if (status === 402 && details.code === "plan_limit") throw new CliError("", { type: "plan-limit", message: json.error, status, ...details }, 2);
15037
+ if (status < 200 || status >= 300) throw new CliError(json.error || `HTTP ${status}`, { status, ...details, ...json.reasons ? { reasons: json.reasons } : {} });
15038
+ return json;
15039
+ };
15040
+ const { action, artifact, cloudId } = options;
15041
+ if (action === "list") emit({ type: "cloud-artifacts", artifacts: (await call("GET", "/api/cloud/artifacts")).artifacts });
15042
+ else if (action === "delete") {
15043
+ await call("DELETE", `/api/cloud/artifacts/${cloudId}`);
15044
+ emit({ type: "deleted", id: cloudId });
15045
+ } else if (action === "login") emit({ type: "login", url: (await call("POST", "/api/cloud/login")).url, message: "Open url to sign in to the Ryugi cloud." });
15046
+ else if (action === "logout") {
15047
+ await call("POST", "/api/cloud/logout");
15048
+ emit({ type: "logged-out" });
15049
+ } else if (action === "unpublish") {
15050
+ await call("DELETE", `/api/cloud/publish/${artifact}`);
15051
+ emit({ type: "unpublished", artifact });
15052
+ } else {
15053
+ const published = await call("POST", `/api/cloud/publish/${artifact}`, options.visibility ? { visibility: options.visibility } : void 0);
15054
+ emit({ type: "published", artifact, url: published.url, visibility: published.visibility });
15055
+ }
15056
+ return 0;
15057
+ }
15058
+ var ACTIONS = ["unpublish", "list", "delete", "login", "logout"];
15059
+ var publishCommand = {
15060
+ name: "publish",
15061
+ summary: "Publish an artifact to the Ryugi cloud (needs a running server)",
15062
+ usage: [
15063
+ "--artifact <type>/<id> [--public | --private] [--unpublish] [options]",
15064
+ "--list | --delete <cloud-id> | --login | --logout [options]"
15065
+ ],
15066
+ options: {
15067
+ artifact: { type: "string", value: "<type>/<id>", help: "The artifact to publish or unpublish" },
15068
+ public: { type: "boolean", help: "Anyone with the link can open it" },
15069
+ private: { type: "boolean", help: "Only you can open it" },
15070
+ unpublish: { type: "boolean", help: "Remove the artifact's cloud copy" },
15071
+ list: { type: "boolean", help: "List your cloud artifacts" },
15072
+ delete: { type: "string", value: "<cloud-id>", help: "Delete a cloud artifact by its id from --list" },
15073
+ login: { type: "boolean", help: "Sign in to the Ryugi cloud" },
15074
+ logout: { type: "boolean", help: "Sign out of the Ryugi cloud" }
15075
+ },
15076
+ run: ({ values, projectDir }, emit) => {
15077
+ const actions = ACTIONS.filter((name) => values[name] !== void 0 && values[name] !== false);
15078
+ if (actions.length > 1) throw new CliError(`Choose one of --${actions.join(", --")}`);
15079
+ return publish({
15080
+ projectDir,
15081
+ action: actions[0] ?? "publish",
15082
+ artifact: values.artifact,
15083
+ visibility: values.public ? "public" : values.private ? "private" : void 0,
15084
+ cloudId: values.delete
15085
+ }, emit);
15086
+ },
15087
+ text: (value) => {
15088
+ if (value.type === "login-required" || value.type === "login") return `${value.message}
15089
+ ${value.url}`;
15090
+ if (value.type === "published") return `${value.url} (${value.visibility})`;
15091
+ return null;
15092
+ }
15093
+ };
14776
15094
 
14777
15095
  // src/cli/start.ts
14778
15096
  var import_node_child_process4 = require("node:child_process");
@@ -14782,23 +15100,28 @@ var import_node_path11 = __toESM(require("node:path"), 1);
14782
15100
  var import_node_readline2 = __toESM(require("node:readline"), 1);
14783
15101
 
14784
15102
  // src/server/artifact-address.ts
14785
- var import_node_crypto2 = __toESM(require("node:crypto"), 1);
14786
15103
  var import_node_fs12 = __toESM(require("node:fs"), 1);
14787
15104
  var import_node_path10 = __toESM(require("node:path"), 1);
14788
15105
 
14789
15106
  // src/shared/ids.ts
14790
- var ID_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
15107
+ var SLUG_SOURCE = "[a-z0-9][a-z0-9-]*";
15108
+ var ADDRESS_SOURCE = "(?:[A-Za-z0-9_-]{21}|[a-f0-9]{32})";
15109
+ var ARTIFACT_LOCATOR_SOURCE = `(?:${SLUG_SOURCE}|${ADDRESS_SOURCE})`;
15110
+ var ID_PATTERN = new RegExp(`^${SLUG_SOURCE}$`);
15111
+ var ADDRESS_PATTERN = new RegExp(`^${ADDRESS_SOURCE}$`);
14791
15112
  var isArtifactId = (id) => ID_PATTERN.test(id);
15113
+ var isArtifactAddress = (id) => ADDRESS_PATTERN.test(id);
14792
15114
  var isArtifactType = (type) => ARTIFACT_TYPES.includes(type);
14793
15115
 
14794
15116
  // src/server/artifacts.ts
14795
- function artifactKeyOf(relative) {
15117
+ function artifactKeyOf(relative, isId = isArtifactId) {
14796
15118
  const [type, id] = relative.split("/");
14797
- if (!type || !id || !isArtifactType(type) || !isArtifactId(id)) return null;
15119
+ if (!type || !id || !isArtifactType(type) || !isId(id)) return null;
14798
15120
  return { type, id };
14799
15121
  }
14800
15122
 
14801
15123
  // src/server/artifact-address.ts
15124
+ var newArtifactId = customAlphabet2("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 21);
14802
15125
  function artifactId(dir) {
14803
15126
  const file = import_node_path10.default.join(dir, ".artifact-id");
14804
15127
  let id;
@@ -14806,7 +15129,7 @@ function artifactId(dir) {
14806
15129
  id = import_node_fs12.default.readFileSync(file, "utf8").trim();
14807
15130
  } catch (err) {
14808
15131
  if (err.code !== "ENOENT") throw err;
14809
- id = import_node_crypto2.default.randomBytes(16).toString("hex");
15132
+ id = newArtifactId();
14810
15133
  try {
14811
15134
  import_node_fs12.default.writeFileSync(file, `${id}
14812
15135
  `, { flag: "wx" });
@@ -14815,7 +15138,7 @@ function artifactId(dir) {
14815
15138
  return artifactId(dir);
14816
15139
  }
14817
15140
  }
14818
- if (!/^[a-f0-9]{32}$/.test(id)) throw new Error(`Invalid artifact ID in ${file}`);
15141
+ if (!isArtifactAddress(id)) throw new Error(`Invalid artifact ID in ${file}`);
14819
15142
  return id;
14820
15143
  }
14821
15144
  function artifactPath(root, type, slug) {
@@ -14827,8 +15150,8 @@ function artifactPath(root, type, slug) {
14827
15150
 
14828
15151
  // src/server/browser-focus.ts
14829
15152
  var import_node_child_process3 = require("node:child_process");
14830
- var import_node_util = require("node:util");
14831
- var execute = (0, import_node_util.promisify)(import_node_child_process3.execFile);
15153
+ var import_node_util2 = require("node:util");
15154
+ var execute = (0, import_node_util2.promisify)(import_node_child_process3.execFile);
14832
15155
  var MAC_FOCUS_SCRIPT = String.raw`
14833
15156
  function run(urls) {
14834
15157
  function key(url) {
@@ -15074,118 +15397,232 @@ async function start(options, emit) {
15074
15397
  unlock();
15075
15398
  }
15076
15399
  }
15077
-
15078
- // src/cli/publish.ts
15079
- async function publish(options, emit) {
15080
- if (options.action === "publish" || options.action === "unpublish") {
15081
- if (!options.artifact) throw new CliError("--artifact <type>/<id> is required");
15082
- if (!ARTIFACT_PATTERN.test(options.artifact)) throw new CliError(ARTIFACT_ERROR);
15400
+ var startCommand = {
15401
+ name: "start",
15402
+ summary: "Start the project's artifacts server, or reuse the running one",
15403
+ options: {
15404
+ artifact: { type: "string", value: "<type>/<id>", help: "Also print a link that opens this artifact" },
15405
+ host: { type: "string", value: "<host>", help: "Interface to listen on (default: 127.0.0.1)" },
15406
+ "url-host": { type: "string", value: "<host>", help: "Host in printed URLs (default: localhost for a loopback --host)" },
15407
+ "idle-timeout-minutes": { type: "string", value: "<n>", help: "Stop after this many idle minutes (default: 240)" },
15408
+ open: { type: "boolean", help: "Open the artifact in a browser even when ARTIFACTS_OPEN=0" },
15409
+ "no-open": { type: "boolean", help: "Do not open a browser" },
15410
+ foreground: { type: "boolean", help: "Run the server in this process until Ctrl+C" },
15411
+ "no-daemon": { type: "boolean" },
15412
+ background: { type: "boolean", help: "Detach the server even where it would run in the foreground" },
15413
+ daemon: { type: "boolean" }
15414
+ },
15415
+ run: ({ values, projectDir }, emit) => start({
15416
+ projectDir,
15417
+ artifact: values.artifact,
15418
+ host: values.host ?? "127.0.0.1",
15419
+ urlHost: values["url-host"],
15420
+ idleTimeoutMinutes: values["idle-timeout-minutes"],
15421
+ open: values["no-open"] ? false : values.open ? true : process.env.ARTIFACTS_OPEN !== "0",
15422
+ foreground: !!(values.foreground || values["no-daemon"]),
15423
+ background: !!(values.background || values.daemon)
15424
+ }, emit),
15425
+ text: (value) => value.type === "server-started" ? `${value.cloudLink ?? value.link ?? value.url}${value.reused ? " (already running)" : ""}` : null
15426
+ };
15427
+
15428
+ // src/cli/update.ts
15429
+ var import_node_child_process6 = require("node:child_process");
15430
+ var import_node_fs15 = __toESM(require("node:fs"), 1);
15431
+
15432
+ // src/cli/update-hint.ts
15433
+ var import_node_child_process5 = require("node:child_process");
15434
+ var import_node_fs14 = __toESM(require("node:fs"), 1);
15435
+ var import_node_os7 = __toESM(require("node:os"), 1);
15436
+ var import_node_path12 = __toESM(require("node:path"), 1);
15437
+ var CHECK_MS = 24 * 60 * 60 * 1e3;
15438
+ var RELEASE = /^\d+\.\d+\.\d+$/;
15439
+ function newer(a, b) {
15440
+ const x = a.split(".").map(Number);
15441
+ const y = b.split(".").map(Number);
15442
+ for (let i = 0; i < 3; i++) if (x[i] !== y[i]) return x[i] > y[i];
15443
+ return false;
15444
+ }
15445
+ function updateCheck({ current, cached, now, env, tty, json, argv = [] }) {
15446
+ if (!tty || json || env.CI || env.NO_UPDATE_NOTIFIER || env.RYUGI_ARTIFACTS_COMMAND) return { hint: null, refresh: false };
15447
+ const latest = cached?.version ?? "";
15448
+ const quiet = argv[0] === "update" || wantsHelp(argv);
15449
+ 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;
15450
+ return { hint, refresh: !cached || now - cached.checkedAt >= CHECK_MS };
15451
+ }
15452
+ var latestFile = (env) => import_node_path12.default.join(env.XDG_CACHE_HOME || import_node_path12.default.join(import_node_os7.default.homedir(), ".cache"), "ryugi", "artifacts", "latest.json");
15453
+ function readLatest(file) {
15454
+ try {
15455
+ const { version, checkedAt } = JSON.parse(import_node_fs14.default.readFileSync(file, "utf8"));
15456
+ return typeof version === "string" && typeof checkedAt === "number" ? { version, checkedAt } : null;
15457
+ } catch {
15458
+ return null;
15083
15459
  }
15084
- if (options.action === "delete" && !/^[A-Za-z0-9_-]{1,64}$/.test(options.cloudId ?? "")) throw new CliError("--delete needs a cloud artifact id from --list");
15085
- const server = serverClient(options.projectDir);
15086
- const call = async (method, route, body) => {
15087
- const { status, json } = await server.call(method, route, body);
15088
- if (status === 401) throw new CliError("", { type: "login-required", url: json.loginUrl, message: "Open url to sign in to the Ryugi cloud, then run the same command again." }, 2);
15089
- const details = cloudErrorDetails(json);
15090
- if (status === 402 && details.code === "plan_limit") throw new CliError("", { type: "plan-limit", message: json.error, status, ...details }, 2);
15091
- if (status < 200 || status >= 300) throw new CliError(json.error || `HTTP ${status}`, { status, ...details, ...json.reasons ? { reasons: json.reasons } : {} });
15092
- return json;
15093
- };
15094
- const { action, artifact, cloudId } = options;
15095
- if (action === "list") emit({ type: "cloud-artifacts", artifacts: (await call("GET", "/api/cloud/artifacts")).artifacts });
15096
- else if (action === "delete") {
15097
- await call("DELETE", `/api/cloud/artifacts/${cloudId}`);
15098
- emit({ type: "deleted", id: cloudId });
15099
- } else if (action === "login") emit({ type: "login", url: (await call("POST", "/api/cloud/login")).url, message: "Open url to sign in to the Ryugi cloud." });
15100
- else if (action === "logout") {
15101
- await call("POST", "/api/cloud/logout");
15102
- emit({ type: "logged-out" });
15103
- } else if (action === "unpublish") {
15104
- await call("DELETE", `/api/cloud/publish/${artifact}`);
15105
- emit({ type: "unpublished", artifact });
15106
- } else {
15107
- const published = await call("POST", `/api/cloud/publish/${artifact}`, options.visibility ? { visibility: options.visibility } : void 0);
15108
- emit({ type: "published", artifact, url: published.url, visibility: published.visibility });
15460
+ }
15461
+ function writeLatest(file, version, checkedAt) {
15462
+ try {
15463
+ import_node_fs14.default.mkdirSync(import_node_path12.default.dirname(file), { recursive: true });
15464
+ const tmp = `${file}.${process.pid}`;
15465
+ import_node_fs14.default.writeFileSync(tmp, JSON.stringify({ version, checkedAt }));
15466
+ import_node_fs14.default.renameSync(tmp, file);
15467
+ } catch {
15109
15468
  }
15110
- return 0;
15111
15469
  }
15112
-
15113
- // src/cli/main.ts
15114
- var HELP2 = `Usage: ryugi-artifacts [project-directory] [--no-open]
15115
- ryugi-artifacts <command> [options]
15116
-
15117
- Without a command, opens the project's artifacts in your browser and keeps the server
15118
- running until Ctrl+C.
15119
-
15120
- Commands:
15121
- start Start the project's artifacts server, or reuse the running one
15122
- stop Stop the project's artifacts server; the artifacts are kept
15123
- check Wait until the server has checked the latest write, then print its warnings (needs a running server):
15124
- --artifact <type>/<id>
15125
- publish Publish an artifact to the Ryugi cloud (needs a running server):
15126
- --artifact <type>/<id> [--public | --private] [--unpublish]
15127
- --list | --delete <cloud-id> | --login | --logout
15128
- comment Read and answer comments on a document or artboard (needs a running server):
15129
- list --artifact <document|artboard>/<id> [--all] what changed since you last listed
15130
- add --artifact document/<id> --block <blockId> [--quote <text>] [--text <text>]
15131
- add --artifact artboard/<id> --board <boardId> [--x <px> --y <px>] [--text <text>]
15132
- reply --artifact <document|artboard>/<id> --thread <threadId> [--text <text>]
15133
- resolve --artifact <document|artboard>/<id> --thread <threadId>
15134
- Without --text, add and reply read the message from stdin.
15135
- get Read a published Ryugi Cloud artifact by link or id, signed in as this machine's
15136
- cloud account. Prints the source (a document's LiteXML and comments) unless --json;
15137
- artboard and HTML files, and files a document uses, are downloaded to --out
15138
- or ~/.cache/ryugi/get/<id>/:
15139
- <link-or-id> [--out <dir>] [--no-comments]
15140
- monitor List every running artifacts server on this machine and manage them. In a terminal it
15141
- opens a live view (open, copy URL, logs, stop); otherwise, or with --json, prints the list once.
15142
- config Auto-publish changed artifacts as private cloud copies when the agent's turn ends:
15143
- --auto-publish on|off for every project
15144
- --auto-publish on|off|inherit --project override for this project only
15145
- Without --auto-publish, prints the current values.
15146
-
15147
- Options:
15148
- --project-dir <path> Project directory (default: current directory)
15149
- --json Print one JSON line (default when not in a terminal)
15150
- -v, --version Print the version
15151
- --no-open Print the URL without opening a browser
15152
- -h, --help Show this help`;
15153
- var common = { "project-dir": { type: "string" }, json: { type: "boolean" } };
15154
- function parse5(args, options, positionals = 0) {
15470
+ var REFRESH = `
15471
+ const fs = require('node:fs');
15472
+ const path = require('node:path');
15473
+ const [file, registry] = process.argv.slice(1);
15474
+ fetch(new URL('ryugi-artifacts/latest', registry), { signal: AbortSignal.timeout(10000) })
15475
+ .then((res) => res.json())
15476
+ .then(({ version }) => {
15477
+ if (!/^\\d+\\.\\d+\\.\\d+/.test(version || '')) return;
15478
+ fs.mkdirSync(path.dirname(file), { recursive: true });
15479
+ const tmp = file + '.' + process.pid;
15480
+ fs.writeFileSync(tmp, JSON.stringify({ version, checkedAt: Date.now() }));
15481
+ fs.renameSync(tmp, file);
15482
+ })
15483
+ .catch(() => {});
15484
+ `;
15485
+ function refreshLatest(file, registry2) {
15486
+ const base = registry2.endsWith("/") ? registry2 : `${registry2}/`;
15487
+ const child = (0, import_node_child_process5.spawn)(process.execPath, ["-e", REFRESH, file, base], { detached: true, stdio: "ignore" });
15488
+ child.on("error", () => {
15489
+ });
15490
+ child.unref();
15491
+ }
15492
+ function notifyUpdate(current, json, argv) {
15493
+ const file = latestFile(process.env);
15494
+ const { hint, refresh } = updateCheck({ current, cached: readLatest(file), now: Date.now(), env: process.env, tty: !!process.stderr.isTTY, json, argv });
15495
+ if (hint) console.error(hint);
15496
+ if (refresh) refreshLatest(file, process.env.npm_config_registry || "https://registry.npmjs.org/");
15497
+ }
15498
+
15499
+ // src/cli/update.ts
15500
+ var PACKAGE = "ryugi-artifacts";
15501
+ var PMS = ["npm", "pnpm", "yarn", "bun"];
15502
+ var TRANSIENT = [
15503
+ ["npx", ["/_npx/"]],
15504
+ ["pnpm dlx", ["/pnpm/dlx/", "/.pnpm-store/dlx/"]],
15505
+ ["bunx", ["/bunx-", "/.bun/install/cache/"]]
15506
+ ];
15507
+ var GLOBAL = [
15508
+ ["pnpm", ["/pnpm/global/"]],
15509
+ ["yarn", ["/yarn/global/"]],
15510
+ ["bun", ["/.bun/install/global/"]],
15511
+ ["npm", [`/lib/node_modules/${PACKAGE}/`, `/npm/node_modules/${PACKAGE}/`]]
15512
+ ];
15513
+ function detectInstall(file, env) {
15514
+ if (env.RYUGI_ARTIFACTS_COMMAND) return { kind: "launcher" };
15515
+ let real = file;
15155
15516
  try {
15156
- const parsed = (0, import_node_util2.parseArgs)({ args, options: { ...common, ...options }, allowPositionals: positionals > 0, strict: true });
15157
- if (parsed.positionals.length > positionals) throw new CliError(`Unknown argument: ${parsed.positionals[positionals]}`);
15158
- return parsed;
15517
+ real = import_node_fs15.default.realpathSync(file);
15518
+ } catch {
15519
+ }
15520
+ const normalized = real.replace(/\\/g, "/").toLowerCase();
15521
+ const has = (markers) => markers.some((marker) => normalized.includes(marker));
15522
+ for (const [runner, markers] of TRANSIENT) if (has(markers)) return { kind: "transient", runner };
15523
+ for (const [pm, markers] of GLOBAL) if (has(markers)) return { kind: "global", pm };
15524
+ return normalized.includes("/node_modules/") ? { kind: "unknown" } : { kind: "local" };
15525
+ }
15526
+ function installCommand(pm, version) {
15527
+ const target = `${PACKAGE}@${version}`;
15528
+ const args = pm === "npm" ? ["install", "-g", target] : pm === "yarn" ? ["global", "add", target] : ["add", "-g", target];
15529
+ return { cmd: pm, args };
15530
+ }
15531
+ var commandLine2 = ({ cmd, args }) => [cmd, ...args].join(" ");
15532
+ async function fetchLatest(registry2) {
15533
+ const base = registry2.endsWith("/") ? registry2 : `${registry2}/`;
15534
+ try {
15535
+ const res = await fetch(new URL(`${PACKAGE}/latest`, base), { signal: AbortSignal.timeout(1e4) });
15536
+ const { version } = await res.json();
15537
+ if (res.ok && typeof version === "string" && /^\d+\.\d+\.\d+/.test(version)) return version;
15538
+ throw new Error(`registry returned ${res.status}`);
15159
15539
  } catch (err) {
15160
- if (err instanceof CliError) throw err;
15161
- const flag = /'([^']+)'/.exec(err.message)?.[1];
15162
- throw new CliError(flag ? `Unknown argument: ${flag.split(" ")[0]}` : err.message);
15540
+ throw new CliError(`Could not get the latest ${PACKAGE} version from ${base}: ${err.message}`);
15163
15541
  }
15164
15542
  }
15543
+ function advice(install, latest) {
15544
+ if (install.kind === "transient") return `You ran ${PACKAGE} through ${install.runner}, which keeps no install to update. Run \`${install.runner} ${PACKAGE}@latest\` to get ${latest}.`;
15545
+ if (install.kind === "local") return "This is a local build from a Ryugi checkout. Update it with `git pull`, then `pnpm build` in artifacts/.";
15546
+ if (install.kind === "launcher") return `The Ryugi skill runs ${PACKAGE} through its launcher, which moves to ${latest} within a day of its release.`;
15547
+ return null;
15548
+ }
15549
+ async function update2(options, emit) {
15550
+ if (options.pm !== void 0 && !PMS.includes(options.pm)) throw new CliError(`--pm must be one of ${PMS.join(", ")}`);
15551
+ const install = options.pm ? { kind: "global", pm: options.pm } : detectInstall(options.file, options.env);
15552
+ const latest = await fetchLatest(options.registry);
15553
+ writeLatest(latestFile(options.env), latest, Date.now());
15554
+ const report = { type: "update-check", current: options.current, latest, install: install.kind };
15555
+ if (!newer(latest, options.current)) {
15556
+ emit({ ...report, upToDate: true, command: null });
15557
+ return 0;
15558
+ }
15559
+ if (install.kind === "unknown") {
15560
+ const commands = PMS.map((pm) => ` ${commandLine2(installCommand(pm, latest))}`).join("\n");
15561
+ throw new CliError(`Could not tell how ${PACKAGE} was installed (${options.file}). Install ${latest} with one of:
15562
+ ${commands}
15563
+ or run \`${PACKAGE} update --pm <${PMS.join("|")}>\`.`);
15564
+ }
15565
+ if (install.kind !== "global") {
15566
+ emit({ ...report, upToDate: false, command: null, message: advice(install, latest) });
15567
+ return 0;
15568
+ }
15569
+ const command = installCommand(install.pm, latest);
15570
+ if (options.check) {
15571
+ emit({ ...report, upToDate: false, command: commandLine2(command) });
15572
+ return 0;
15573
+ }
15574
+ const windows = process.platform === "win32";
15575
+ 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 });
15576
+ if (result.error) throw new CliError(`Could not run ${commandLine2(command)}: ${result.error.message}`);
15577
+ if (result.status !== 0) throw new CliError(`${commandLine2(command)} exited with ${result.status ?? result.signal}`);
15578
+ emit({ type: "updated", from: options.current, to: latest, pm: install.pm, command: commandLine2(command) });
15579
+ return 0;
15580
+ }
15581
+ var updateCommand = {
15582
+ name: "update",
15583
+ summary: "Install the newest ryugi-artifacts release with the package manager that installed this one",
15584
+ options: {
15585
+ check: { type: "boolean", help: "Compare versions only; do not install" },
15586
+ pm: { type: "string", value: "<npm|pnpm|yarn|bun>", help: "Use this package manager instead of detecting it" }
15587
+ },
15588
+ run: ({ values }, emit) => update2({
15589
+ current: "1.44.0",
15590
+ file: __filename,
15591
+ env: process.env,
15592
+ registry: process.env.npm_config_registry || "https://registry.npmjs.org/",
15593
+ check: !!values.check,
15594
+ pm: values.pm
15595
+ }, emit),
15596
+ text: (value) => {
15597
+ if (value.type === "updated") return `Updated ${PACKAGE} ${value.from} \u2192 ${value.to} with ${value.pm}. Running servers keep the old version until you run \`${PACKAGE} stop\`.`;
15598
+ if (value.type !== "update-check") return null;
15599
+ if (value.upToDate) return `${PACKAGE} ${value.current} is the latest release.`;
15600
+ return value.message ?? `${PACKAGE} ${value.latest} is available (you have ${value.current}). Run: ${value.command}`;
15601
+ }
15602
+ };
15603
+
15604
+ // src/cli/commands.ts
15605
+ var COMMANDS = [startCommand, stopCommand, checkCommand, publishCommand, commentCommand, getCommand, monitorCommand, configCommand, updateCommand];
15606
+
15607
+ // src/cli/main.ts
15608
+ var BROWSE_OPTIONS = { "no-open": { type: "boolean", help: "Print the URL without opening a browser" } };
15165
15609
  function text(value) {
15166
15610
  if (typeof value.error === "string") return `Error: ${value.error}`;
15167
- if (value.type === "server-started") return `${value.cloudLink ?? value.link ?? value.url}${value.reused ? " (already running)" : ""}`;
15168
- if (value.type === "login-required" || value.type === "login") return `${value.message}
15169
- ${value.url}`;
15170
- if (value.type === "published") return `${value.url} (${value.visibility})`;
15171
- if (value.type === "auto-publish") return `Auto-publish: ${value.global === null ? "not decided" : value.global ? "on" : "off"} for every project${value.project === null ? "" : `, ${value.project ? "on" : "off"} for this project`}.`;
15172
- const checked = checkText(value);
15173
- if (checked !== null) return checked;
15174
- const servers = monitorText(value);
15175
- if (servers !== null) return servers;
15176
- const commented = commentText(value);
15177
- if (commented !== null) return commented;
15611
+ for (const command of COMMANDS) {
15612
+ const line = command.text?.(value);
15613
+ if (line != null) return line;
15614
+ }
15178
15615
  if (typeof value.status === "string") return value.status === "stopped" ? "Stopped." : value.status.replace(/_/g, " ");
15179
15616
  return JSON.stringify(value);
15180
15617
  }
15181
15618
  function openBrowser2(url) {
15182
15619
  const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
15183
15620
  const args = process.platform === "win32" ? ["/c", "start", '""', url] : [url];
15184
- (0, import_node_child_process5.execFile)(command, args, () => {
15621
+ (0, import_node_child_process7.execFile)(command, args, () => {
15185
15622
  });
15186
15623
  }
15187
15624
  async function browse(argv) {
15188
- const { values, positionals } = parse5(argv, { "no-open": { type: "boolean" } }, 1);
15625
+ const { values, positionals } = parse(argv, BROWSE_OPTIONS, 1);
15189
15626
  if (positionals.length && values["project-dir"]) throw new CliError("Specify one project directory.");
15190
15627
  return start({
15191
15628
  projectDir: values["project-dir"] ?? positionals[0] ?? process.cwd(),
@@ -15204,140 +15641,30 @@ async function browse(argv) {
15204
15641
  if (!values["no-open"]) openBrowser2(value.url);
15205
15642
  });
15206
15643
  }
15207
- async function getCommand(argv) {
15208
- const json = argv.includes("--json");
15209
- try {
15210
- const { values, positionals } = parse5(argv, { "no-comments": { type: "boolean" }, out: { type: "string" } }, 1);
15211
- if (!positionals[0]) throw new CliError("Give a Ryugi Cloud link or artifact id.");
15212
- const result = await getArtifact({
15213
- target: positionals[0],
15214
- defaultOrigin: (process.env.RYUGI_CLOUD_ORIGIN || "https://ryugi.innei.dev").replace(/\/+$/, ""),
15215
- credentialsFile: credentialsFile(process.env, process.platform, import_node_os6.default.homedir()),
15216
- cacheRoot: import_node_path12.default.join(process.env.XDG_CACHE_HOME || import_node_path12.default.join(import_node_os6.default.homedir(), ".cache"), "ryugi", "get"),
15217
- out: values.out
15218
- });
15219
- if (json) console.log(JSON.stringify(result));
15220
- else process.stdout.write(getText4(result, { comments: !values["no-comments"] }));
15221
- return 0;
15222
- } catch (caught) {
15223
- const err = caught instanceof CliError ? caught : new CliError(caught.message);
15224
- const fields = err.message ? { error: err.message, ...err.fields } : err.fields;
15225
- if (json) console.log(JSON.stringify(fields));
15226
- else console.error(err.message ? `Error: ${err.message}` : String(err.fields.message));
15227
- return err.code;
15228
- }
15229
- }
15230
15644
  async function main(argv) {
15231
- const [command, ...rest] = argv;
15232
- if (command === "get") return getCommand(rest);
15233
- const json = argv.includes("--json") || !process.stdout.isTTY;
15645
+ const [name, ...rest] = argv;
15646
+ const command = COMMANDS.find((candidate) => candidate.name === name);
15647
+ const json = argv.includes("--json") || !command?.explicitJson && !process.stdout.isTTY;
15648
+ notifyUpdate("1.44.0", json, argv);
15234
15649
  const emit = (value) => {
15235
15650
  const line = json ? JSON.stringify(value) : text(value);
15236
15651
  if (!json && typeof value.error === "string") console.error(line);
15237
15652
  else console.log(line);
15238
15653
  };
15239
15654
  try {
15240
- if (command === "start") {
15241
- const { values } = parse5(rest, {
15242
- artifact: { type: "string" },
15243
- host: { type: "string" },
15244
- "url-host": { type: "string" },
15245
- "idle-timeout-minutes": { type: "string" },
15246
- open: { type: "boolean" },
15247
- "no-open": { type: "boolean" },
15248
- foreground: { type: "boolean" },
15249
- "no-daemon": { type: "boolean" },
15250
- background: { type: "boolean" },
15251
- daemon: { type: "boolean" }
15252
- });
15253
- return await start({
15254
- projectDir: values["project-dir"] ?? process.cwd(),
15255
- artifact: values.artifact,
15256
- host: values.host ?? "127.0.0.1",
15257
- urlHost: values["url-host"],
15258
- idleTimeoutMinutes: values["idle-timeout-minutes"],
15259
- open: values["no-open"] ? false : values.open ? true : process.env.ARTIFACTS_OPEN !== "0",
15260
- foreground: !!(values.foreground || values["no-daemon"]),
15261
- background: !!(values.background || values.daemon)
15262
- }, emit);
15263
- }
15264
- if (command === "stop") {
15265
- const { values, positionals } = parse5(rest, {}, 1);
15266
- return await stop(values["project-dir"] ?? positionals[0] ?? process.cwd(), emit);
15267
- }
15268
- if (command === "check") {
15269
- const { values } = parse5(rest, { artifact: { type: "string" } });
15270
- return await check({
15271
- projectDir: values["project-dir"] ?? process.cwd(),
15272
- artifact: values.artifact
15273
- }, emit);
15274
- }
15275
- if (command === "publish") {
15276
- const { values } = parse5(rest, {
15277
- artifact: { type: "string" },
15278
- public: { type: "boolean" },
15279
- private: { type: "boolean" },
15280
- unpublish: { type: "boolean" },
15281
- list: { type: "boolean" },
15282
- delete: { type: "string" },
15283
- login: { type: "boolean" },
15284
- logout: { type: "boolean" }
15285
- });
15286
- const actions = ["unpublish", "list", "delete", "login", "logout"].filter((name) => values[name] !== void 0 && values[name] !== false);
15287
- if (actions.length > 1) throw new CliError(`Choose one of --${actions.join(", --")}`);
15288
- const action = actions[0] ?? "publish";
15289
- return await publish({
15290
- projectDir: values["project-dir"] ?? process.cwd(),
15291
- action,
15292
- artifact: values.artifact,
15293
- visibility: values.public ? "public" : values.private ? "private" : void 0,
15294
- cloudId: values.delete
15295
- }, emit);
15296
- }
15297
- if (command === "comment") {
15298
- const { values, positionals } = parse5(rest, {
15299
- artifact: { type: "string" },
15300
- all: { type: "boolean" },
15301
- block: { type: "string" },
15302
- quote: { type: "string" },
15303
- thread: { type: "string" },
15304
- text: { type: "string" },
15305
- board: { type: "string" },
15306
- x: { type: "string" },
15307
- y: { type: "string" }
15308
- }, 1);
15309
- return await comment({
15310
- projectDir: values["project-dir"] ?? process.cwd(),
15311
- action: positionals[0],
15312
- artifact: values.artifact,
15313
- all: values.all,
15314
- block: values.block,
15315
- quote: values.quote,
15316
- thread: values.thread,
15317
- text: values.text,
15318
- board: values.board,
15319
- x: values.x,
15320
- y: values.y
15321
- }, emit);
15322
- }
15323
- if (command === "config") {
15324
- const { values } = parse5(rest, { "auto-publish": { type: "string" }, project: { type: "boolean" } });
15325
- return config({
15326
- projectDir: values["project-dir"] ?? process.cwd(),
15327
- autoPublish: values["auto-publish"],
15328
- project: !!values.project
15329
- }, emit);
15330
- }
15331
- if (command === "monitor") {
15332
- const { values } = parse5(rest, {});
15333
- return await monitor({ json: !!values.json }, emit);
15334
- }
15335
- if (command === "--version" || command === "-v") {
15336
- console.log("1.43.0");
15655
+ if (command) {
15656
+ if (wantsHelp(rest)) {
15657
+ console.log(commandHelp(command));
15658
+ return 0;
15659
+ }
15660
+ return await command.run(parse(rest, command.options, command.positionals), emit);
15661
+ }
15662
+ if (name === "--version" || name === "-v") {
15663
+ console.log("1.44.0");
15337
15664
  return 0;
15338
15665
  }
15339
- if (command === "--help" || command === "-h") {
15340
- console.log(HELP2);
15666
+ if (name === "--help" || name === "-h") {
15667
+ console.log(rootHelp(COMMANDS, BROWSE_OPTIONS));
15341
15668
  return 0;
15342
15669
  }
15343
15670
  return await browse(argv);